TASK-DS-001: Migrated packages/design-system/ from legacy Kōdō to SUMI v2.0 - New src/ structure with proper TypeScript exports - Component type registry documenting all 40+ UI components - cn() utility re-export - package.json with exports map for tokens subpaths TASK-DS-002: Extracted design tokens as TypeScript objects - tokens/colors.ts: backgrounds, surfaces, text, pigments, semantic, glass, shadows, light theme - tokens/typography.ts: font families, sizes, weights, line heights, letter spacings - tokens/spacing.ts: spacing scale, radius, z-index, layout - tokens/motion.ts: durations and easing functions TASK-DS-003: Added missing Storybook stories - EmptyState.stories.tsx (8 variants: default, icon, action, search, sizes, card, centered) - ButtonLoading.stories.tsx (6 variants: default, loading, text, destructive, outline, small) - ContentFadeIn.stories.tsx (2 variants: default, card) - DesignTokens.stories.tsx (visual token reference: pigments, backgrounds, text, typography, spacing, radius) - Total: 42 → 46 stories for UI components + design token showcase Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
99 lines
2.3 KiB
TypeScript
99 lines
2.3 KiB
TypeScript
import type { Meta, StoryObj } from '@storybook/react';
|
|
import { EmptyState } from './empty-state';
|
|
import { Inbox, Search, Music, Users } from 'lucide-react';
|
|
|
|
const meta: Meta<typeof EmptyState> = {
|
|
title: 'UI/EmptyState',
|
|
component: EmptyState,
|
|
tags: ['autodocs'],
|
|
argTypes: {
|
|
size: { control: 'select', options: ['sm', 'md', 'lg'] },
|
|
variant: { control: 'select', options: ['default', 'centered', 'card'] },
|
|
},
|
|
};
|
|
export default meta;
|
|
|
|
type Story = StoryObj<typeof EmptyState>;
|
|
|
|
export const Default: Story = {
|
|
args: {
|
|
title: 'No items found',
|
|
description: 'There are no items to display yet.',
|
|
},
|
|
};
|
|
|
|
export const WithIcon: Story = {
|
|
args: {
|
|
icon: <Inbox className="w-full h-full" />,
|
|
title: 'Your inbox is empty',
|
|
description: 'New messages will appear here when you receive them.',
|
|
},
|
|
};
|
|
|
|
export const WithAction: Story = {
|
|
args: {
|
|
icon: <Music className="w-full h-full" />,
|
|
title: 'No tracks uploaded',
|
|
description: 'Upload your first track to get started.',
|
|
action: {
|
|
label: 'Upload a track',
|
|
onClick: () => {},
|
|
},
|
|
},
|
|
};
|
|
|
|
export const SearchEmpty: Story = {
|
|
args: {
|
|
icon: <Search className="w-full h-full" />,
|
|
title: 'No results found',
|
|
description: 'Try adjusting your search criteria or browse by genre.',
|
|
action: {
|
|
label: 'Clear search',
|
|
onClick: () => {},
|
|
variant: 'outline',
|
|
},
|
|
},
|
|
};
|
|
|
|
export const Small: Story = {
|
|
args: {
|
|
size: 'sm',
|
|
title: 'No followers yet',
|
|
icon: <Users className="w-full h-full" />,
|
|
},
|
|
};
|
|
|
|
export const Large: Story = {
|
|
args: {
|
|
size: 'lg',
|
|
icon: <Music className="w-full h-full" />,
|
|
title: 'Your library is empty',
|
|
description: 'Discover music and add it to your library.',
|
|
action: { label: 'Explore', onClick: () => {} },
|
|
},
|
|
};
|
|
|
|
export const CardVariant: Story = {
|
|
args: {
|
|
variant: 'card',
|
|
icon: <Inbox className="w-full h-full" />,
|
|
title: 'Drop files here',
|
|
description: 'Drag and drop files to upload.',
|
|
},
|
|
};
|
|
|
|
export const CenteredVariant: Story = {
|
|
args: {
|
|
variant: 'centered',
|
|
icon: <Music className="w-full h-full" />,
|
|
title: 'Nothing playing',
|
|
description: 'Select a track to start listening.',
|
|
},
|
|
decorators: [
|
|
(Story) => (
|
|
<div className="h-96 flex items-stretch">
|
|
<Story />
|
|
</div>
|
|
),
|
|
],
|
|
};
|