From 833fa467ba80bce29d64c41e8530cdfe32e6b5dc Mon Sep 17 00:00:00 2001 From: icarus Date: Mon, 5 Jan 2026 20:34:40 +0800 Subject: [PATCH] feat: Update Sonner stories with new features and examples - Add dismissable control to playground - Add custom toast example with JSX rendering - Add dismissable control showcase - Add custom class names example - Update component description for clarity - Import CheckIcon for custom toast example --- .../components/primitives/Sonner.stories.tsx | 131 +++++++++++++++--- 1 file changed, 111 insertions(+), 20 deletions(-) diff --git a/packages/ui/stories/components/primitives/Sonner.stories.tsx b/packages/ui/stories/components/primitives/Sonner.stories.tsx index f561fd72d0..92562c120e 100644 --- a/packages/ui/stories/components/primitives/Sonner.stories.tsx +++ b/packages/ui/stories/components/primitives/Sonner.stories.tsx @@ -1,6 +1,7 @@ import { Button } from '@cherrystudio/ui' import { toast, Toaster } from '@cherrystudio/ui' import type { Meta, StoryObj } from '@storybook/react' +import { CheckIcon } from 'lucide-react' interface PlaygroundArgs { type: 'info' | 'success' | 'warning' | 'error' | 'loading' @@ -8,6 +9,7 @@ interface PlaygroundArgs { description: string colored: boolean duration: number + dismissable: boolean withButton: boolean buttonLabel: string } @@ -20,7 +22,7 @@ const meta: Meta = { docs: { description: { component: - 'A custom toast notification component built on sonner. Features custom icons, action buttons, links, and support for info, success, warning, error, and loading states.' + 'A toast notification component built on Sonner with custom icons and styling. Supports info, success, warning, error, loading, and custom toast types with discriminated union types for type-safe APIs.' } } }, @@ -46,6 +48,7 @@ export const Playground: StoryObj = { description: 'This is a description that provides more details about the notification.', colored: false, duration: 4000, + dismissable: true, withButton: false, buttonLabel: 'Action' }, @@ -65,12 +68,16 @@ export const Playground: StoryObj = { }, colored: { control: 'boolean', - description: 'Enable colored background' + description: 'Enable colored background with backdrop blur' }, duration: { control: { type: 'number', min: 1000, max: 10000, step: 1000 }, description: 'Duration in milliseconds (use Infinity for persistent)' }, + dismissable: { + control: 'boolean', + description: 'Whether the toast can be manually dismissed' + }, withButton: { control: 'boolean', description: 'Show action button' @@ -83,26 +90,17 @@ export const Playground: StoryObj = { }, render: (args: PlaygroundArgs) => { const handleToast = () => { - const toastOptions: { - description?: string - colored: boolean - duration: number - button?: { - label: string - onClick: () => void - } - promise?: Promise - } = { + const toastOptions = { description: args.description || undefined, colored: args.colored, - duration: args.duration - } - - if (args.withButton) { - toastOptions.button = { - label: args.buttonLabel || 'Action', - onClick: () => toast.info('Button clicked!') - } + duration: args.duration, + dismissable: args.dismissable, + ...(args.withButton && { + button: { + label: args.buttonLabel || 'Action', + onClick: () => toast.info('Button clicked!') + } + }) } switch (args.type) { @@ -572,3 +570,96 @@ export const RealWorldExamples: Story = { ) } } + +// Custom Toast with JSX +export const CustomToast: Story = { + render: () => { + const showCustomToast = () => { + toast.custom({ + jsx: (id) => ( +
+ +
+
Custom Design
+
This is a fully customized toast with JSX
+
+ +
+ ), + data: { + duration: 5000 + } + }) + } + + return ( +
+ +
+ Custom toasts allow you to render any JSX content with full styling control. +
+
+ ) + } +} + +// Dismissable Control +export const DismissableControl: Story = { + render: () => { + return ( +
+ + +
+ ) + } +} + +// With Custom Class Names +export const WithCustomClassNames: Story = { + render: () => { + return ( +
+ +
+ You can customize specific parts of the toast using the classNames prop. +
+
+ ) + } +}