mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 14:59:27 +08:00
feat: Add close button option to toast component
- Add `closeButton` prop to BaseToastProps interface - Update dismissable prop description for clarity - Add close button styling to classNames - Pass closeButton prop to external toast configuration - Update Storybook stories to include closeButton control - Rename "Dismissable Control" story to "Close Button Control"
This commit is contained in:
parent
a8801e58f3
commit
d89fa3cb54
@ -18,12 +18,14 @@ interface BaseToastProps {
|
|||||||
colored?: boolean
|
colored?: boolean
|
||||||
/** Duration in milliseconds before auto-dismissal */
|
/** Duration in milliseconds before auto-dismissal */
|
||||||
duration?: number
|
duration?: number
|
||||||
/** Whether the toast can be manually dismissed */
|
/** If 'false', it'll prevent the user from dismissing the toast. Defaults to false. */
|
||||||
dismissable?: boolean
|
dismissable?: boolean
|
||||||
/** Callback function when toast is dismissed */
|
/** Callback function when toast is dismissed */
|
||||||
onDismiss?: () => void
|
onDismiss?: () => void
|
||||||
/** Action button or custom React node */
|
/** Action button or custom React node */
|
||||||
button?: Action | ReactNode
|
button?: Action | ReactNode
|
||||||
|
/** Whether to show a close button. Defaults to false */
|
||||||
|
closeButton?: boolean
|
||||||
/** Custom class names for toast sub-components */
|
/** Custom class names for toast sub-components */
|
||||||
classNames?: ToastClassnames
|
classNames?: ToastClassnames
|
||||||
}
|
}
|
||||||
|
|||||||
@ -316,12 +316,14 @@ interface BaseToastProps {
|
|||||||
colored?: boolean
|
colored?: boolean
|
||||||
/** Duration in milliseconds before auto-dismissal */
|
/** Duration in milliseconds before auto-dismissal */
|
||||||
duration?: number
|
duration?: number
|
||||||
/** Whether the toast can be manually dismissed */
|
/** If 'false', it'll prevent the user from dismissing the toast. Defaults to false. */
|
||||||
dismissable?: boolean
|
dismissable?: boolean
|
||||||
/** Callback function when toast is dismissed */
|
/** Callback function when toast is dismissed */
|
||||||
onDismiss?: () => void
|
onDismiss?: () => void
|
||||||
/** Action button or custom React node */
|
/** Action button or custom React node */
|
||||||
button?: Action | ReactNode
|
button?: Action | ReactNode
|
||||||
|
/** Whether to show a close button. Defaults to false */
|
||||||
|
closeButton?: boolean
|
||||||
/** Custom class names for toast sub-components */
|
/** Custom class names for toast sub-components */
|
||||||
classNames?: ToastClassnames
|
classNames?: ToastClassnames
|
||||||
}
|
}
|
||||||
@ -388,7 +390,8 @@ function toast(props: ToastProps) {
|
|||||||
props.classNames?.actionButton
|
props.classNames?.actionButton
|
||||||
),
|
),
|
||||||
icon: cn('size-6 min-w-6', props.description && 'self-start'),
|
icon: cn('size-6 min-w-6', props.description && 'self-start'),
|
||||||
loader: cn('!static ![--size:24px]')
|
loader: cn('!static ![--size:24px]'),
|
||||||
|
closeButton: cn('absolute size-5 min-w-5 top-[5px] right-1.5 [&_svg]:size-5')
|
||||||
}
|
}
|
||||||
const { classNames: externalClassNames, ...rest } = props
|
const { classNames: externalClassNames, ...rest } = props
|
||||||
delete externalClassNames?.toast
|
delete externalClassNames?.toast
|
||||||
@ -400,7 +403,8 @@ function toast(props: ToastProps) {
|
|||||||
duration: rest.duration,
|
duration: rest.duration,
|
||||||
action: rest.button,
|
action: rest.button,
|
||||||
dismissible: rest.dismissable,
|
dismissible: rest.dismissable,
|
||||||
onDismiss: rest.onDismiss
|
onDismiss: rest.onDismiss,
|
||||||
|
closeButton: rest.closeButton
|
||||||
} satisfies ExternalToast
|
} satisfies ExternalToast
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -10,6 +10,7 @@ interface PlaygroundArgs {
|
|||||||
colored: boolean
|
colored: boolean
|
||||||
duration: number
|
duration: number
|
||||||
dismissable: boolean
|
dismissable: boolean
|
||||||
|
closeButton: boolean
|
||||||
withButton: boolean
|
withButton: boolean
|
||||||
buttonLabel: string
|
buttonLabel: string
|
||||||
}
|
}
|
||||||
@ -49,6 +50,7 @@ export const Playground: StoryObj<PlaygroundArgs> = {
|
|||||||
colored: false,
|
colored: false,
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
dismissable: true,
|
dismissable: true,
|
||||||
|
closeButton: false,
|
||||||
withButton: false,
|
withButton: false,
|
||||||
buttonLabel: 'Action'
|
buttonLabel: 'Action'
|
||||||
},
|
},
|
||||||
@ -76,7 +78,11 @@ export const Playground: StoryObj<PlaygroundArgs> = {
|
|||||||
},
|
},
|
||||||
dismissable: {
|
dismissable: {
|
||||||
control: 'boolean',
|
control: 'boolean',
|
||||||
description: 'Whether the toast can be manually dismissed'
|
description: 'Whether the toast can be dismissed by user interaction (click, swipe)'
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
control: 'boolean',
|
||||||
|
description: 'Whether to show a close button'
|
||||||
},
|
},
|
||||||
withButton: {
|
withButton: {
|
||||||
control: 'boolean',
|
control: 'boolean',
|
||||||
@ -95,6 +101,7 @@ export const Playground: StoryObj<PlaygroundArgs> = {
|
|||||||
colored: args.colored,
|
colored: args.colored,
|
||||||
duration: args.duration,
|
duration: args.duration,
|
||||||
dismissable: args.dismissable,
|
dismissable: args.dismissable,
|
||||||
|
closeButton: args.closeButton,
|
||||||
...(args.withButton && {
|
...(args.withButton && {
|
||||||
button: {
|
button: {
|
||||||
label: args.buttonLabel || 'Action',
|
label: args.buttonLabel || 'Action',
|
||||||
@ -608,30 +615,30 @@ export const CustomToast: Story = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dismissable Control
|
// Close Button Control
|
||||||
export const DismissableControl: Story = {
|
export const CloseButtonControl: Story = {
|
||||||
render: () => {
|
render: () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
toast.info('Dismissable toast', {
|
toast.info('With close button', {
|
||||||
description: 'You can close this manually',
|
description: 'Click the X to close this toast',
|
||||||
dismissable: true,
|
closeButton: true,
|
||||||
duration: Number.POSITIVE_INFINITY
|
duration: Number.POSITIVE_INFINITY
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
Dismissable (Default)
|
With Close Button
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
toast.warning('Non-dismissable toast', {
|
toast.warning('Without close button', {
|
||||||
description: 'This will auto-close after 3 seconds',
|
description: 'This will auto-close after 3 seconds',
|
||||||
dismissable: false,
|
closeButton: false,
|
||||||
duration: 3000
|
duration: 3000
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
Non-dismissable
|
Without Close Button (Default)
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user