mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-14 16:52:26 +08:00
more stories
This commit is contained in:
30
core/package-lock.json
generated
30
core/package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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 (
|
||||
<div>
|
||||
<ion-accordion-group>
|
||||
<ion-accordion value="first">
|
||||
<ion-item slot="header" color="light">
|
||||
<ion-label>First Accordion</ion-label>
|
||||
</ion-item>
|
||||
<div class="ion-padding" slot="content">First Content</div>
|
||||
</ion-accordion>
|
||||
<ion-accordion value="second">
|
||||
<ion-item slot="header" color="light">
|
||||
<ion-label>Second Accordion</ion-label>
|
||||
</ion-item>
|
||||
<div class="ion-padding" slot="content">Second Content</div>
|
||||
</ion-accordion>
|
||||
<ion-accordion value="third">
|
||||
<ion-item slot="header" color="light">
|
||||
<ion-label>Third Accordion</ion-label>
|
||||
</ion-item>
|
||||
<div class="ion-padding" slot="content">Third Content</div>
|
||||
</ion-accordion>
|
||||
</ion-accordion-group>
|
||||
|
||||
<ion-button class="ion-margin-top" onClick={() => toggleAccordion()}>Toggle Second Accordion</ion-button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const Disabled: Story = {
|
||||
args: {
|
||||
disabled: true,
|
||||
|
368
core/src/components/action-sheet/action-sheet.stories.tsx
Normal file
368
core/src/components/action-sheet/action-sheet.stories.tsx
Normal file
@ -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<ActionSheet> = {
|
||||
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<ActionSheet>;
|
||||
|
||||
/**
|
||||
* 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) => (
|
||||
<div>
|
||||
<ion-action-sheet {...props} trigger="open-action-sheet"></ion-action-sheet>
|
||||
<ion-button id="open-action-sheet">Show Action Sheet</ion-button>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 (
|
||||
<div>
|
||||
<ion-button onClick={() => {
|
||||
const actionSheet = document.querySelector('ion-action-sheet')!
|
||||
actionSheet.isOpen = true
|
||||
}}>Click Me</ion-button>
|
||||
<ion-action-sheet
|
||||
overlayIndex={1000}
|
||||
buttons={[
|
||||
{
|
||||
text: 'Delete',
|
||||
role: 'destructive',
|
||||
data: {
|
||||
action: 'delete',
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 'Share',
|
||||
data: {
|
||||
action: 'share',
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
data: {
|
||||
action: 'cancel',
|
||||
},
|
||||
},
|
||||
]}
|
||||
header="Actions"
|
||||
onIonActionSheetDidDismiss={() => {
|
||||
console.log('Action Sheet dismissed');
|
||||
const actionSheet = document.querySelector('ion-action-sheet')!
|
||||
actionSheet.isOpen = false;
|
||||
}}
|
||||
></ion-action-sheet>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) => (
|
||||
<div>
|
||||
<ion-action-sheet {...props} trigger="open-buttons-action-sheet"></ion-action-sheet>
|
||||
<ion-button id="open-buttons-action-sheet">Show Action Sheet with Roles</ion-button>
|
||||
<p>Check the console to see button handler messages.</p>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) => (
|
||||
<div>
|
||||
<ion-action-sheet {...props} trigger="open-icons-action-sheet"></ion-action-sheet>
|
||||
<ion-button id="open-icons-action-sheet">Show Action Sheet with Icons</ion-button>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) => (
|
||||
<div>
|
||||
<ion-action-sheet
|
||||
{...props}
|
||||
trigger="open-data-action-sheet"
|
||||
onIonActionSheetDidDismiss={(e) => {
|
||||
const { data, role } = e.detail;
|
||||
console.log(`Dismissed with role: ${role}, data: ${JSON.stringify(data)}`);
|
||||
}}
|
||||
></ion-action-sheet>
|
||||
<ion-button id="open-data-action-sheet">Show Action Sheet with Data</ion-button>
|
||||
<p>Check the console to see dismiss data.</p>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) => (
|
||||
<div>
|
||||
<style>
|
||||
{`
|
||||
ion-action-sheet.my-custom-class {
|
||||
--background: #f58840;
|
||||
--backdrop-opacity: 0.6;
|
||||
--button-background-selected: #e97223;
|
||||
--button-color: #000000;
|
||||
--color: #fff;
|
||||
/* role: "destructive" button iOS styling override */
|
||||
--ion-color-danger: #000000;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<ion-button id="open-action-sheet">Open</ion-button>
|
||||
<ion-action-sheet class="my-custom-class" {...props}></ion-action-sheet>
|
||||
</div>
|
||||
)
|
||||
};
|
@ -8,19 +8,7 @@ const meta: Meta<Badge & { text: string }> = {
|
||||
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<Badge & { text: string }>;
|
||||
|
||||
export const Primary: Story = {
|
||||
render: (props) => (
|
||||
<div>
|
||||
<ion-badge {...props}>{props.text}</ion-badge>
|
||||
</div>
|
||||
render: () => (
|
||||
<ion-list style={{ width: '300px' }}>
|
||||
<ion-item>
|
||||
<ion-badge slot="start">11</ion-badge>
|
||||
<ion-label>Badge in start slot</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="end">22</ion-badge>
|
||||
<ion-label>Badge in end slot</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
),
|
||||
};
|
||||
|
||||
export const BadgesInTabButtons: Story = {
|
||||
render: () => (
|
||||
<ion-tab-bar color="light" style={{ width: '500px' }}>
|
||||
<ion-tab-button tab="1">
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-label>Favorites</ion-label>
|
||||
<ion-badge color="danger"></ion-badge>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="2">
|
||||
<ion-icon name="musical-note"></ion-icon>
|
||||
<ion-label>Music</ion-label>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="3">
|
||||
<ion-icon name="calendar"></ion-icon>
|
||||
<ion-label>Calendar</ion-label>
|
||||
<ion-badge color="danger">47</ion-badge>
|
||||
</ion-tab-button>
|
||||
</ion-tab-bar>
|
||||
)
|
||||
}
|
||||
|
||||
export const Theming: Story = {
|
||||
render: () => (
|
||||
<ion-list style={{ width: '300px' }}>
|
||||
<ion-item>
|
||||
<ion-label>Followers</ion-label>
|
||||
<ion-badge color="primary">22k</ion-badge>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Likes</ion-label>
|
||||
<ion-badge color="secondary">118k</ion-badge>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Stars</ion-label>
|
||||
<ion-badge color="tertiary">34k</ion-badge>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Completed</ion-label>
|
||||
<ion-badge color="success">80</ion-badge>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Warnings</ion-label>
|
||||
<ion-badge color="warning">70</ion-badge>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Notifications</ion-label>
|
||||
<ion-badge color="danger">1000</ion-badge>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
)
|
||||
}
|
||||
|
||||
export const CSSProperties: Story = {
|
||||
render: () => (
|
||||
<div style={{ width: '300px' }}>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Badges styled</ion-label>
|
||||
<ion-badge>1</ion-badge>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<style>{`
|
||||
ion-badge {
|
||||
--background: purple;
|
||||
--color: white;
|
||||
--padding-end: 20px;
|
||||
--padding-start: 20px;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
}
|
262
core/src/components/breadcrumbs/breadcrumbs.stories.tsx
Normal file
262
core/src/components/breadcrumbs/breadcrumbs.stories.tsx
Normal file
@ -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<Breadcrumbs & { text: string }> = {
|
||||
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<Breadcrumbs & { text: string }>;
|
||||
|
||||
export const Primary: Story = {
|
||||
render: () => (
|
||||
<ion-breadcrumbs style={{ width: '500px' }}>
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...lastBreadcrumbProps}>Film</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
),
|
||||
};
|
||||
|
||||
export const UsingIcons: Story = {
|
||||
render: () => (
|
||||
<div style={{ width: '500px', display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
||||
<ion-label style={{ marginInline: 'auto' }}>Icons at Start</ion-label>
|
||||
<ion-breadcrumbs>
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>
|
||||
<ion-icon slot="start" name="home"></ion-icon>
|
||||
Home
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>
|
||||
<ion-icon slot="start" name="flash"></ion-icon>
|
||||
Electronics
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>
|
||||
<ion-icon slot="start" name="camera"></ion-icon>
|
||||
Cameras
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...lastBreadcrumbProps}>
|
||||
<ion-icon slot="start" name="film"></ion-icon>
|
||||
Film
|
||||
</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
|
||||
<ion-label style={{ marginInline: 'auto' }}>Icons at End</ion-label>
|
||||
<ion-breadcrumbs>
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>
|
||||
Home
|
||||
<ion-icon slot="end" name="home"></ion-icon>
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>
|
||||
Electronics
|
||||
<ion-icon slot="end" name="flash"></ion-icon>
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>
|
||||
Cameras
|
||||
<ion-icon slot="end" name="camera"></ion-icon>
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...lastBreadcrumbProps}>
|
||||
Film
|
||||
<ion-icon slot="end" name="film"></ion-icon>
|
||||
</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
export const CustomSeparator: Story = {
|
||||
render: () => (
|
||||
<ion-breadcrumbs>
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>
|
||||
Home
|
||||
<ion-icon slot="separator" name="arrow-forward-circle"></ion-icon>
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>
|
||||
Electronics
|
||||
<ion-icon slot="separator" name="arrow-forward-circle"></ion-icon>
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>
|
||||
Cameras
|
||||
<ion-icon slot="separator" name="arrow-forward-circle"></ion-icon>
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...lastBreadcrumbProps}>
|
||||
Film
|
||||
<ion-icon slot="separator" name="arrow-forward-circle"></ion-icon>
|
||||
</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
),
|
||||
};
|
||||
|
||||
export const CustomCollapse: Story = {
|
||||
render: () => (
|
||||
<ion-breadcrumbs max-items="4">
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#photography" {...breadcrumbProps}>Photography</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...breadcrumbProps}>Film</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#35mm" {...lastBreadcrumbProps}>35 mm</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
),
|
||||
};
|
||||
|
||||
export const ItemsBeforeAfterCollapse: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
||||
<div style={{ marginInline: 'auto' }}>Before Collapse = 2</div>
|
||||
<ion-breadcrumbs max-items="4" items-before-collapse="2">
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#photography" {...breadcrumbProps}>Photography</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...breadcrumbProps}>Film</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#35mm" {...lastBreadcrumbProps}>35 mm</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
|
||||
<div style={{ marginInline: 'auto' }}>Before Collapse = 0</div>
|
||||
<ion-breadcrumbs max-items="4" items-before-collapse="0">
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#photography" {...breadcrumbProps}>Photography</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...breadcrumbProps}>Film</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#35mm" {...lastBreadcrumbProps}>35 mm</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
|
||||
<div style={{ marginInline: 'auto' }}>After Collapse = 2</div>
|
||||
<ion-breadcrumbs max-items="4" items-after-collapse="2">
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#photography" {...breadcrumbProps}>Photography</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...breadcrumbProps}>Film</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#35mm" {...lastBreadcrumbProps}>35 mm</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
|
||||
<div style={{ marginInline: 'auto' }}>Before Collapse = 2, After Collapse = 2</div>
|
||||
<ion-breadcrumbs max-items="4" items-before-collapse="2" items-after-collapse="2">
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#photography" {...breadcrumbProps}>Photography</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...breadcrumbProps}>Film</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#35mm" {...lastBreadcrumbProps}>35 mm</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
export const CustomCollapsedIndicator: Story = {
|
||||
render: () => {
|
||||
function collapsedIndicator() {
|
||||
const breadcrumbs = document.querySelector('ion-breadcrumbs') as HTMLIonBreadcrumbsElement;
|
||||
breadcrumbs.maxItems = undefined;
|
||||
}
|
||||
return (
|
||||
<ion-breadcrumbs max-items="4" onIonCollapsedClick={collapsedIndicator}>
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#photography" {...breadcrumbProps}>Photography</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...breadcrumbProps}>Film</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#35mm" {...lastBreadcrumbProps}>35 mm</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
export const CustomCollapsedIndicatorClick: Story = {
|
||||
render: () => {
|
||||
function collapsedIndicator(e: CustomEvent<BreadcrumbCollapsedClickEventDetail>) {
|
||||
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 += `
|
||||
<ion-item
|
||||
${i === e.detail.collapsedBreadcrumbs.length - 1 ? `lines="none"` : ''}
|
||||
href="${breadcrumb.href}"
|
||||
>
|
||||
<ion-label>${breadcrumb.textContent}</ion-label>
|
||||
</ion-item>
|
||||
`;
|
||||
});
|
||||
|
||||
popoverList.innerHTML = listHTML;
|
||||
popover.event = e;
|
||||
popover.isOpen = true;
|
||||
}
|
||||
|
||||
function popoverDismiss() {
|
||||
const popover = document.querySelector('ion-popover') as HTMLIonPopoverElement;
|
||||
popover.isOpen = false;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ion-breadcrumbs max-items="4" onIonCollapsedClick={collapsedIndicator}>
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#photography" {...breadcrumbProps}>Photography</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...breadcrumbProps}>Film</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#35mm" {...lastBreadcrumbProps}>35 mm</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
<ion-popover overlayIndex={1000} onDidDismiss={popoverDismiss}>
|
||||
<ion-content>
|
||||
<ion-list></ion-list>
|
||||
</ion-content>
|
||||
</ion-popover>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
export const CustomCSSProperties: Story = {
|
||||
render: () => (
|
||||
<div>
|
||||
<ion-breadcrumbs>
|
||||
<ion-breadcrumb href="#home" {...breadcrumbProps}>Home</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#electronics" {...breadcrumbProps}>Electronics</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#cameras" {...breadcrumbProps}>Cameras</ion-breadcrumb>
|
||||
<ion-breadcrumb href="#film" {...lastBreadcrumbProps}>Film</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
|
||||
<style>{`
|
||||
ion-breadcrumb {
|
||||
--color: rgb(81, 155, 198);
|
||||
--color-active: rgb(150, 112, 220);
|
||||
--color-hover: rgb(103, 61, 180);
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
),
|
||||
};
|
@ -8,45 +8,159 @@ const meta: Meta<Button> = {
|
||||
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<Button>;
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {
|
||||
fill: 'outline',
|
||||
expand: 'full',
|
||||
size: 'small',
|
||||
},
|
||||
render: (props) => <ion-button {...props}>Primary Button</ion-button>,
|
||||
export const BasicUsage: Story = {
|
||||
render: () => (<div>
|
||||
<ion-button>Default</ion-button>
|
||||
<ion-button disabled={true}>Disabled</ion-button>
|
||||
</div>),
|
||||
};
|
||||
|
||||
/**
|
||||
* Storybook story without custom render function
|
||||
*/
|
||||
export const Secondary: Story = {
|
||||
args: {
|
||||
fill: 'solid',
|
||||
expand: 'block',
|
||||
size: 'large',
|
||||
},
|
||||
render: (props) => <ion-button {...props}>Secondary Button</ion-button>,
|
||||
export const Expand: Story = {
|
||||
render: () => <div style={{ width: '500px' }}>
|
||||
<ion-button expand="block">Block</ion-button>
|
||||
<ion-button expand="full">Full</ion-button>
|
||||
</div>,
|
||||
};
|
||||
|
||||
export const Shape: Story = {
|
||||
render: () => <div>
|
||||
<ion-button>Default</ion-button>
|
||||
<ion-button shape="round">Round</ion-button>
|
||||
<ion-button>
|
||||
<ion-icon slot="icon-only" name="heart"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-button shape="round">
|
||||
<ion-icon slot="icon-only" name="heart"></ion-icon>
|
||||
</ion-button>
|
||||
</div>,
|
||||
};
|
||||
|
||||
export const Fill: Story = {
|
||||
render: () => <div>
|
||||
<ion-button>Default</ion-button>
|
||||
<ion-button fill="clear">Clear</ion-button>
|
||||
<ion-button fill="outline">Outline</ion-button>
|
||||
<ion-button fill="solid">Solid</ion-button>
|
||||
</div>,
|
||||
};
|
||||
|
||||
export const Size: Story = {
|
||||
render: () => <div>
|
||||
<ion-button size="small">Small</ion-button>
|
||||
<ion-button size="default">Default</ion-button>
|
||||
<ion-button size="large">Large</ion-button>
|
||||
</div>,
|
||||
};
|
||||
|
||||
export const Icons: Story = {
|
||||
render: () => <div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(3, auto)',
|
||||
justifyItems: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '100%',
|
||||
}}>
|
||||
<ion-button size="small">
|
||||
<ion-icon slot="icon-only" ios="logo-apple" md="settings-sharp"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-button>
|
||||
<ion-icon slot="icon-only" ios="logo-apple" md="settings-sharp"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-button size="large">
|
||||
<ion-icon slot="icon-only" ios="logo-apple" md="settings-sharp"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-button size="small">
|
||||
<ion-icon slot="start" name="star"></ion-icon>
|
||||
Left Icon
|
||||
</ion-button>
|
||||
|
||||
<ion-button>
|
||||
<ion-icon slot="start" name="star"></ion-icon>
|
||||
Left Icon
|
||||
</ion-button>
|
||||
|
||||
<ion-button size="large">
|
||||
<ion-icon slot="start" name="star"></ion-icon>
|
||||
Left Icon
|
||||
</ion-button>
|
||||
|
||||
<ion-button size="small">
|
||||
Right Icon
|
||||
<ion-icon slot="end" name="heart"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-button>
|
||||
Right Icon
|
||||
<ion-icon slot="end" name="heart"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-button size="large">
|
||||
Right Icon
|
||||
<ion-icon slot="end" name="heart"></ion-icon>
|
||||
</ion-button>
|
||||
</div>,
|
||||
};
|
||||
|
||||
export const Theming: Story = {
|
||||
render: () => <div style={{
|
||||
flexWrap: 'wrap',
|
||||
width: '350px',
|
||||
margin: '0 auto',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '100%',
|
||||
}}>
|
||||
<ion-button>Default</ion-button>
|
||||
<ion-button color="primary">Primary</ion-button>
|
||||
<ion-button color="secondary">Secondary</ion-button>
|
||||
<ion-button color="tertiary">Tertiary</ion-button>
|
||||
<ion-button color="success">Success</ion-button>
|
||||
<ion-button color="warning">Warning</ion-button>
|
||||
<ion-button color="danger">Danger</ion-button>
|
||||
<ion-button color="light">Light</ion-button>
|
||||
<ion-button color="medium">Medium</ion-button>
|
||||
<ion-button color="dark">Dark</ion-button>
|
||||
</div>,
|
||||
};
|
||||
|
||||
export const CustomCSSProperties: Story = {
|
||||
render: () => <div>
|
||||
<style>{`
|
||||
ion-button {
|
||||
--background: #93e9be;
|
||||
--background-hover: #9ce0be;
|
||||
--background-activated: #88f4be;
|
||||
--background-focused: #88f4be;
|
||||
|
||||
--color: blue;
|
||||
|
||||
--border-radius: 0;
|
||||
--border-color: #000;
|
||||
--border-style: solid;
|
||||
--border-width: 1px;
|
||||
|
||||
--box-shadow: 0 2px 6px 0 rgb(0, 0, 0, 0.25);
|
||||
|
||||
--ripple-color: deeppink;
|
||||
|
||||
--padding-top: 10px;
|
||||
--padding-bottom: 10px;
|
||||
}
|
||||
`}</style>
|
||||
|
||||
<ion-button>Custom Button</ion-button>
|
||||
</div>,
|
||||
};
|
||||
|
||||
|
82
core/src/components/ripple-effect/ripple-effect.stories.tsx
Normal file
82
core/src/components/ripple-effect/ripple-effect.stories.tsx
Normal file
@ -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<RippleEffect> = {
|
||||
title: 'Ripple Effect',
|
||||
component: RippleEffect,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
}
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<RippleEffect>;
|
||||
|
||||
export const BasicUsage: Story = {
|
||||
render: () => (<div>
|
||||
<div class="wrapper">
|
||||
<b>Click on a shape to see the ripple</b>
|
||||
|
||||
<div class="ion-activatable ripple-parent rectangle">
|
||||
<ion-ripple-effect></ion-ripple-effect>
|
||||
</div>
|
||||
|
||||
<div class="ion-activatable ripple-parent rounded-rectangle">
|
||||
<ion-ripple-effect></ion-ripple-effect>
|
||||
</div>
|
||||
|
||||
<div class="ion-activatable ripple-parent circle">
|
||||
<ion-ripple-effect></ion-ripple-effect>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>{`
|
||||
.wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
text-align: center;
|
||||
|
||||
height: 300px;
|
||||
width: 300px;
|
||||
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
b {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ripple-parent {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.rectangle {
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.rounded-rectangle {
|
||||
width: 185px;
|
||||
height: 65px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
`}</style>
|
||||
</div>),
|
||||
};
|
Reference in New Issue
Block a user