diff --git a/core/package-lock.json b/core/package-lock.json
index 9c4e9f82fa..4d0b1f0a43 100644
--- a/core/package-lock.json
+++ b/core/package-lock.json
@@ -28,7 +28,7 @@
"@stencil/core": "^4.30.0",
"@stencil/react-output-target": "0.5.3",
"@stencil/sass": "^3.0.9",
- "@stencil/storybook-plugin": "^0.0.11",
+ "@stencil/storybook-plugin": "^0.0.12",
"@stencil/vue-output-target": "0.10.7",
"@storybook/addon-essentials": "^8.6.12",
"@storybook/addon-interactions": "^8.6.12",
@@ -2608,9 +2608,9 @@
}
},
"node_modules/@stencil/storybook-plugin": {
- "version": "0.0.11",
- "resolved": "https://registry.npmjs.org/@stencil/storybook-plugin/-/storybook-plugin-0.0.11.tgz",
- "integrity": "sha512-sfTgNBGtIru0CvZ5243t4Ew2wrdvnd6iWDRWLrr2R17lUs3RWEh2/W8E1SX/lXFJVwCqENwPh95W6jS4eyJOUA==",
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/@stencil/storybook-plugin/-/storybook-plugin-0.0.12.tgz",
+ "integrity": "sha512-mBz6wYE/getEnDn9TkciyOTR2ZO+mz5bBAjN4YEAG/sjesgBGvxB0NKVHTtLTqLGEv/wtQo/nh/zjsPmwoHqxw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2624,7 +2624,7 @@
"@storybook/types": "^8.6.12",
"preact-render-to-string": "^6.5.13",
"react-docgen-typescript": "^2.2.2",
- "unplugin-stencil": "^0.2.5"
+ "unplugin-stencil": "^0.2.6"
},
"engines": {
"node": ">=20"
@@ -2916,9 +2916,9 @@
}
},
"node_modules/@stencil/storybook-plugin/node_modules/unplugin-stencil": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/unplugin-stencil/-/unplugin-stencil-0.2.5.tgz",
- "integrity": "sha512-4/wufyqIRkcYfWlWvfUBtPm2/z0EuhWfHbBUKSL0dcAGpgC65LhH05jfwVpfrlSuc44Tp1rFx3ciaIFsjpXDsg==",
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/unplugin-stencil/-/unplugin-stencil-0.2.6.tgz",
+ "integrity": "sha512-buLzEBcTLE9B+6/5N0OjFItEFifK19QBj80a4oPuX82K6+/kb3ooHmQiklcam9Y6L8/tyAfjj2ADQbhg0GaM2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -15288,9 +15288,9 @@
"requires": {}
},
"@stencil/storybook-plugin": {
- "version": "0.0.11",
- "resolved": "https://registry.npmjs.org/@stencil/storybook-plugin/-/storybook-plugin-0.0.11.tgz",
- "integrity": "sha512-sfTgNBGtIru0CvZ5243t4Ew2wrdvnd6iWDRWLrr2R17lUs3RWEh2/W8E1SX/lXFJVwCqENwPh95W6jS4eyJOUA==",
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/@stencil/storybook-plugin/-/storybook-plugin-0.0.12.tgz",
+ "integrity": "sha512-mBz6wYE/getEnDn9TkciyOTR2ZO+mz5bBAjN4YEAG/sjesgBGvxB0NKVHTtLTqLGEv/wtQo/nh/zjsPmwoHqxw==",
"dev": true,
"requires": {
"@storybook/addon-actions": "^8.6.12",
@@ -15303,7 +15303,7 @@
"@storybook/types": "^8.6.12",
"preact-render-to-string": "^6.5.13",
"react-docgen-typescript": "^2.2.2",
- "unplugin-stencil": "^0.2.5"
+ "unplugin-stencil": "^0.2.6"
},
"dependencies": {
"@rollup/rollup-darwin-arm64": {
@@ -15462,9 +15462,9 @@
}
},
"unplugin-stencil": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/unplugin-stencil/-/unplugin-stencil-0.2.5.tgz",
- "integrity": "sha512-4/wufyqIRkcYfWlWvfUBtPm2/z0EuhWfHbBUKSL0dcAGpgC65LhH05jfwVpfrlSuc44Tp1rFx3ciaIFsjpXDsg==",
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/unplugin-stencil/-/unplugin-stencil-0.2.6.tgz",
+ "integrity": "sha512-buLzEBcTLE9B+6/5N0OjFItEFifK19QBj80a4oPuX82K6+/kb3ooHmQiklcam9Y6L8/tyAfjj2ADQbhg0GaM2Q==",
"dev": true,
"requires": {
"mlly": "^1.7.4",
diff --git a/core/package.json b/core/package.json
index c6678605d0..55684b3509 100644
--- a/core/package.json
+++ b/core/package.json
@@ -50,7 +50,7 @@
"@stencil/core": "^4.30.0",
"@stencil/react-output-target": "0.5.3",
"@stencil/sass": "^3.0.9",
- "@stencil/storybook-plugin": "^0.0.11",
+ "@stencil/storybook-plugin": "^0.0.12",
"@stencil/vue-output-target": "0.10.7",
"@storybook/addon-essentials": "^8.6.12",
"@storybook/addon-interactions": "^8.6.12",
diff --git a/core/src/components/accordion/accordion.stories.tsx b/core/src/components/accordion/accordion.stories.tsx
index 3eb6ba56ad..1fb11b9706 100644
--- a/core/src/components/accordion/accordion.stories.tsx
+++ b/core/src/components/accordion/accordion.stories.tsx
@@ -77,6 +77,46 @@ export const Default: Story = {
),
};
+export const CustomToggle: Story = {
+ render: () => {
+ function toggleAccordion() {
+ const accordionGroup = document.querySelector('ion-accordion-group') as HTMLIonAccordionGroupElement
+ if (accordionGroup.value === 'second') {
+ accordionGroup.value = undefined;
+ } else {
+ accordionGroup.value = 'second';
+ }
+ }
+
+ return (
+
+
+
+
+ First Accordion
+
+ First Content
+
+
+
+ Second Accordion
+
+ Second Content
+
+
+
+ Third Accordion
+
+ Third Content
+
+
+
+
toggleAccordion()}>Toggle Second Accordion
+
+ )
+ }
+}
+
export const Disabled: Story = {
args: {
disabled: true,
diff --git a/core/src/components/action-sheet/action-sheet.stories.tsx b/core/src/components/action-sheet/action-sheet.stories.tsx
new file mode 100644
index 0000000000..e41d67deb5
--- /dev/null
+++ b/core/src/components/action-sheet/action-sheet.stories.tsx
@@ -0,0 +1,368 @@
+import { h } from '@stencil/core';
+import type { Meta, StoryObj } from '@stencil/storybook-plugin';
+
+import { ActionSheet } from './action-sheet';
+
+const meta: Meta = {
+ title: 'Action Sheet',
+ component: ActionSheet,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ header: {
+ control: 'text',
+ description: 'Title for the action sheet',
+ },
+ subHeader: {
+ control: 'text',
+ description: 'Subtitle for the action sheet',
+ },
+ buttons: {
+ control: 'object',
+ description: 'An array of buttons for the action sheet',
+ },
+ backdropDismiss: {
+ control: 'boolean',
+ description: 'If true, the action sheet will be dismissed when the backdrop is clicked',
+ },
+ translucent: {
+ control: 'boolean',
+ description: 'If true, the action sheet will be translucent in iOS mode',
+ },
+ animated: {
+ control: 'boolean',
+ description: 'If true, the action sheet will animate',
+ },
+ cssClass: {
+ control: 'text',
+ description: 'Additional classes to apply for custom CSS',
+ },
+ isOpen: {
+ control: 'boolean',
+ description: 'If true, the action sheet will open. If false, the action sheet will close',
+ },
+ },
+ args: {
+ backdropDismiss: true,
+ animated: true,
+ isOpen: false,
+ },
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+/**
+ * Basic inline action sheet example as shown in the documentation
+ */
+export const InlineActionSheet: Story = {
+ args: {
+ header: 'Actions',
+ buttons: [
+ {
+ text: 'Delete',
+ role: 'destructive',
+ data: {
+ action: 'delete',
+ },
+ },
+ {
+ text: 'Share',
+ data: {
+ action: 'share',
+ },
+ },
+ {
+ text: 'Cancel',
+ role: 'cancel',
+ data: {
+ action: 'cancel',
+ },
+ },
+ ],
+ },
+ render: (props) => (
+
+
+ Show Action Sheet
+
+ )
+};
+
+/**
+ * Example of using isOpen property to control the action sheet state
+ */
+export const UsingIsOpen: Story = {
+ args: {
+ header: 'Actions',
+ buttons: [
+ {
+ text: 'Delete',
+ role: 'destructive',
+ data: {
+ action: 'delete',
+ },
+ },
+ {
+ text: 'Share',
+ data: {
+ action: 'share',
+ },
+ },
+ {
+ text: 'Cancel',
+ role: 'cancel',
+ data: {
+ action: 'cancel',
+ },
+ },
+ ],
+ isOpen: true
+ },
+ render: () => {
+ return (
+
+ {
+ const actionSheet = document.querySelector('ion-action-sheet')!
+ actionSheet.isOpen = true
+ }}>Click Me
+ {
+ console.log('Action Sheet dismissed');
+ const actionSheet = document.querySelector('ion-action-sheet')!
+ actionSheet.isOpen = false;
+ }}
+ >
+
+ )
+ }
+};
+
+/**
+ * Example with role buttons, showing destructive and cancel roles
+ */
+export const ButtonsWithRoles: Story = {
+ args: {
+ header: 'Actions',
+ buttons: [
+ {
+ text: 'Delete',
+ role: 'destructive',
+ handler: () => {
+ console.log('Delete clicked');
+ }
+ },
+ {
+ text: 'Share',
+ handler: () => {
+ console.log('Share clicked');
+ }
+ },
+ {
+ text: 'Play',
+ handler: () => {
+ console.log('Play clicked');
+ }
+ },
+ {
+ text: 'Favorite',
+ handler: () => {
+ console.log('Favorite clicked');
+ }
+ },
+ {
+ text: 'Cancel',
+ role: 'cancel',
+ handler: () => {
+ console.log('Cancel clicked');
+ }
+ }
+ ]
+ },
+ render: (props) => (
+
+
+
Show Action Sheet with Roles
+
Check the console to see button handler messages.
+
+ )
+};
+
+/**
+ * Example with icons and handler functions
+ */
+export const WithIcons: Story = {
+ args: {
+ header: 'Albums',
+ buttons: [
+ {
+ text: 'Delete',
+ role: 'destructive',
+ icon: 'trash',
+ handler: () => {
+ console.log('Delete clicked');
+ }
+ },
+ {
+ text: 'Share',
+ icon: 'share',
+ handler: () => {
+ console.log('Share clicked');
+ }
+ },
+ {
+ text: 'Play',
+ icon: 'play-circle',
+ handler: () => {
+ console.log('Play clicked');
+ }
+ },
+ {
+ text: 'Favorite',
+ icon: 'heart',
+ handler: () => {
+ console.log('Favorite clicked');
+ }
+ },
+ {
+ text: 'Cancel',
+ role: 'cancel',
+ icon: 'close',
+ handler: () => {
+ console.log('Cancel clicked');
+ }
+ }
+ ]
+ },
+ render: (props) => (
+
+
+ Show Action Sheet with Icons
+
+ )
+};
+
+/**
+ * Example showing how to collect data from action sheet dismissal
+ */
+export const CollectingDismissData: Story = {
+ args: {
+ header: 'Actions',
+ buttons: [
+ {
+ text: 'Delete',
+ role: 'destructive',
+ data: {
+ action: 'delete'
+ }
+ },
+ {
+ text: 'Share',
+ data: {
+ action: 'share'
+ }
+ },
+ {
+ text: 'Cancel',
+ role: 'cancel',
+ data: {
+ action: 'cancel'
+ }
+ }
+ ]
+ },
+ render: (props) => (
+
+
{
+ const { data, role } = e.detail;
+ console.log(`Dismissed with role: ${role}, data: ${JSON.stringify(data)}`);
+ }}
+ >
+
Show Action Sheet with Data
+
Check the console to see dismiss data.
+
+ )
+};
+
+/**
+ * Example with custom CSS class for styling
+ */
+export const WithCustomStyling: Story = {
+ args: {
+ overlayIndex: 1000,
+ trigger: 'open-action-sheet',
+ header: 'Example header',
+ subHeader: 'Example subheader',
+ buttons: [
+ {
+ text: 'Delete',
+ role: 'destructive',
+ data: {
+ action: 'delete',
+ },
+ },
+ {
+ text: 'Share',
+ data: {
+ action: 'share',
+ },
+ },
+ {
+ text: 'Cancel',
+ role: 'cancel',
+ data: {
+ action: 'cancel',
+ },
+ },
+ ],
+ translucent: false
+ },
+ render: (props) => (
+
+
+ Open
+
+
+ )
+};
diff --git a/core/src/components/badge/badge.stories.tsx b/core/src/components/badge/badge.stories.tsx
index 8982f03fef..4130e2d74f 100644
--- a/core/src/components/badge/badge.stories.tsx
+++ b/core/src/components/badge/badge.stories.tsx
@@ -8,19 +8,7 @@ const meta: Meta = {
component: Badge,
parameters: {
layout: 'centered',
- },
- argTypes: {
- color: {
- control: 'select',
- options: ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'],
- },
- text: {
- control: 'text',
- },
- },
- args: {
- text: 'NEW',
- },
+ }
};
export default meta;
@@ -28,9 +16,92 @@ export default meta;
type Story = StoryObj;
export const Primary: Story = {
- render: (props) => (
-
- {props.text}
-
+ render: () => (
+
+
+ 11
+ Badge in start slot
+
+
+ 22
+ Badge in end slot
+
+
),
};
+
+export const BadgesInTabButtons: Story = {
+ render: () => (
+
+
+
+ Favorites
+
+
+
+
+
+ Music
+
+
+
+
+ Calendar
+ 47
+
+
+ )
+}
+
+export const Theming: Story = {
+ render: () => (
+
+
+ Followers
+ 22k
+
+
+ Likes
+ 118k
+
+
+ Stars
+ 34k
+
+
+ Completed
+ 80
+
+
+ Warnings
+ 70
+
+
+ Notifications
+ 1000
+
+
+ )
+}
+
+export const CSSProperties: Story = {
+ render: () => (
+
+
+
+ Badges styled
+ 1
+
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/core/src/components/breadcrumbs/breadcrumbs.stories.tsx b/core/src/components/breadcrumbs/breadcrumbs.stories.tsx
new file mode 100644
index 0000000000..a960f8f1a7
--- /dev/null
+++ b/core/src/components/breadcrumbs/breadcrumbs.stories.tsx
@@ -0,0 +1,262 @@
+import { h } from '@stencil/core';
+import type { Meta, StoryObj } from '@stencil/storybook-plugin';
+
+import type { BreadcrumbCollapsedClickEventDetail } from '../breadcrumb/breadcrumb-interface';
+
+import { Breadcrumbs } from './breadcrumbs';
+
+const meta: Meta = {
+ title: 'Breadcrumbs',
+ component: Breadcrumbs,
+ parameters: {
+ layout: 'centered',
+ }
+};
+
+const breadcrumbProps = {
+ last: false,
+ showCollapsedIndicator: false
+} as const;
+const lastBreadcrumbProps = {
+ ...breadcrumbProps,
+ last: true
+} as const;
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Primary: Story = {
+ render: () => (
+
+ Home
+ Electronics
+ Cameras
+ Film
+
+ ),
+};
+
+export const UsingIcons: Story = {
+ render: () => (
+
+ Icons at Start
+
+
+
+ Home
+
+
+
+ Electronics
+
+
+
+ Cameras
+
+
+
+ Film
+
+
+
+ Icons at End
+
+
+ Home
+
+
+
+ Electronics
+
+
+
+ Cameras
+
+
+
+ Film
+
+
+
+
+ ),
+};
+
+export const CustomSeparator: Story = {
+ render: () => (
+
+
+ Home
+
+
+
+ Electronics
+
+
+
+ Cameras
+
+
+
+ Film
+
+
+
+ ),
+};
+
+export const CustomCollapse: Story = {
+ render: () => (
+
+ Home
+ Electronics
+ Photography
+ Cameras
+ Film
+ 35 mm
+
+ ),
+};
+
+export const ItemsBeforeAfterCollapse: Story = {
+ render: () => (
+
+
Before Collapse = 2
+
+ Home
+ Electronics
+ Photography
+ Cameras
+ Film
+ 35 mm
+
+
+
Before Collapse = 0
+
+ Home
+ Electronics
+ Photography
+ Cameras
+ Film
+ 35 mm
+
+
+
After Collapse = 2
+
+ Home
+ Electronics
+ Photography
+ Cameras
+ Film
+ 35 mm
+
+
+
Before Collapse = 2, After Collapse = 2
+
+ Home
+ Electronics
+ Photography
+ Cameras
+ Film
+ 35 mm
+
+
+ ),
+};
+
+export const CustomCollapsedIndicator: Story = {
+ render: () => {
+ function collapsedIndicator() {
+ const breadcrumbs = document.querySelector('ion-breadcrumbs') as HTMLIonBreadcrumbsElement;
+ breadcrumbs.maxItems = undefined;
+ }
+ return (
+
+ Home
+ Electronics
+ Photography
+ Cameras
+ Film
+ 35 mm
+
+ )
+ },
+};
+
+export const CustomCollapsedIndicatorClick: Story = {
+ render: () => {
+ function collapsedIndicator(e: CustomEvent) {
+ const popover = document.querySelector('ion-popover') as HTMLIonPopoverElement;
+ const popoverList = document.querySelector('ion-popover ion-list') as HTMLIonListElement;
+
+ if (!e.detail.collapsedBreadcrumbs) {
+ return;
+ }
+
+ let listHTML = ``;
+ e.detail.collapsedBreadcrumbs.forEach((breadcrumb, i) => {
+ if (!e.detail.collapsedBreadcrumbs) {
+ return;
+ }
+
+ listHTML += `
+
+ ${breadcrumb.textContent}
+
+ `;
+ });
+
+ popoverList.innerHTML = listHTML;
+ popover.event = e;
+ popover.isOpen = true;
+ }
+
+ function popoverDismiss() {
+ const popover = document.querySelector('ion-popover') as HTMLIonPopoverElement;
+ popover.isOpen = false;
+ }
+
+ return (
+
+
+ Home
+ Electronics
+ Photography
+ Cameras
+ Film
+ 35 mm
+
+
+
+
+
+
+
+ )
+ },
+};
+
+export const CustomCSSProperties: Story = {
+ render: () => (
+
+
+ Home
+ Electronics
+ Cameras
+ Film
+
+
+
+
+ ),
+};
\ No newline at end of file
diff --git a/core/src/components/button/button.stories.tsx b/core/src/components/button/button.stories.tsx
index 0dbd42fbbe..4b95389c0a 100644
--- a/core/src/components/button/button.stories.tsx
+++ b/core/src/components/button/button.stories.tsx
@@ -8,45 +8,159 @@ const meta: Meta = {
component: Button,
parameters: {
layout: 'centered',
- },
- argTypes: {
- fill: {
- control: 'select',
- options: ['solid', 'outline', 'clear']
- },
- expand: {
- control: 'select',
- options: ['full', 'block']
- },
- size: {
- control: 'select',
- options: ['small', 'default', 'large']
- },
- },
- args: { fill: 'outline', expand: 'full', size: 'small' },
+ }
};
export default meta;
type Story = StoryObj;
-export const Primary: Story = {
- args: {
- fill: 'outline',
- expand: 'full',
- size: 'small',
- },
- render: (props) => Primary Button ,
+export const BasicUsage: Story = {
+ render: () => (
+ Default
+ Disabled
+
),
};
-/**
- * Storybook story without custom render function
- */
-export const Secondary: Story = {
- args: {
- fill: 'solid',
- expand: 'block',
- size: 'large',
- },
- render: (props) => Secondary Button ,
+export const Expand: Story = {
+ render: () =>
+ Block
+ Full
+
,
};
+
+export const Shape: Story = {
+ render: () =>
+ Default
+ Round
+
+
+
+
+
+
+
,
+};
+
+export const Fill: Story = {
+ render: () =>
+ Default
+ Clear
+ Outline
+ Solid
+
,
+};
+
+export const Size: Story = {
+ render: () =>
+ Small
+ Default
+ Large
+
,
+};
+
+export const Icons: Story = {
+ render: () =>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Left Icon
+
+
+
+
+ Left Icon
+
+
+
+
+ Left Icon
+
+
+
+ Right Icon
+
+
+
+
+ Right Icon
+
+
+
+
+ Right Icon
+
+
+
,
+};
+
+export const Theming: Story = {
+ render: () =>
+ Default
+ Primary
+ Secondary
+ Tertiary
+ Success
+ Warning
+ Danger
+ Light
+ Medium
+ Dark
+
,
+};
+
+export const CustomCSSProperties: Story = {
+ render: () =>
+
+
+ Custom Button
+
,
+};
+
diff --git a/core/src/components/ripple-effect/ripple-effect.stories.tsx b/core/src/components/ripple-effect/ripple-effect.stories.tsx
new file mode 100644
index 0000000000..7d100ad7c0
--- /dev/null
+++ b/core/src/components/ripple-effect/ripple-effect.stories.tsx
@@ -0,0 +1,82 @@
+import { h } from '@stencil/core';
+import type { Meta, StoryObj } from '@stencil/storybook-plugin';
+
+import type { BreadcrumbCollapsedClickEventDetail } from '../breadcrumb/breadcrumb-interface';
+
+import { RippleEffect } from './ripple-effect';
+
+const meta: Meta = {
+ title: 'Ripple Effect',
+ component: RippleEffect,
+ parameters: {
+ layout: 'centered',
+ }
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const BasicUsage: Story = {
+ render: () => (
+
+
Click on a shape to see the ripple
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
),
+};