feat(ui): add Storybook for @bytelyst/ui component library
- Storybook 8 with React Vite framework + a11y addon - Stories for Button (7 variants), Badge (6), Input (5), Card (4) - Dark/elevated/light background presets - Run: pnpm --filter @bytelyst/ui storybook
This commit is contained in:
parent
a5d1c5f0b9
commit
11a832e271
12
packages/ui/.storybook/main.ts
Normal file
12
packages/ui/.storybook/main.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { StorybookConfig } from '@storybook/react-vite';
|
||||||
|
|
||||||
|
const config: StorybookConfig = {
|
||||||
|
stories: ['../src/**/*.stories.@(ts|tsx)'],
|
||||||
|
addons: ['@storybook/addon-essentials', '@storybook/addon-a11y'],
|
||||||
|
framework: {
|
||||||
|
name: '@storybook/react-vite',
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
16
packages/ui/.storybook/preview.ts
Normal file
16
packages/ui/.storybook/preview.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import type { Preview } from '@storybook/react';
|
||||||
|
|
||||||
|
const preview: Preview = {
|
||||||
|
parameters: {
|
||||||
|
backgrounds: {
|
||||||
|
default: 'dark',
|
||||||
|
values: [
|
||||||
|
{ name: 'dark', value: '#06070A' },
|
||||||
|
{ name: 'elevated', value: '#0E1118' },
|
||||||
|
{ name: 'light', value: '#F8F9FC' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default preview;
|
||||||
@ -2,6 +2,10 @@
|
|||||||
"name": "@bytelyst/ui",
|
"name": "@bytelyst/ui",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"storybook": "storybook dev -p 6006",
|
||||||
|
"build-storybook": "storybook build"
|
||||||
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./src/index.ts",
|
".": "./src/index.ts",
|
||||||
"./button": "./src/components/Button.tsx",
|
"./button": "./src/components/Button.tsx",
|
||||||
@ -31,6 +35,12 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.7.0",
|
"typescript": "^5.7.0",
|
||||||
"@types/react": "^19.0.0",
|
"@types/react": "^19.0.0",
|
||||||
"@types/react-dom": "^19.0.0"
|
"@types/react-dom": "^19.0.0",
|
||||||
|
"@storybook/react-vite": "^8.5.0",
|
||||||
|
"@storybook/react": "^8.5.0",
|
||||||
|
"@storybook/addon-essentials": "^8.5.0",
|
||||||
|
"@storybook/addon-a11y": "^8.5.0",
|
||||||
|
"storybook": "^8.5.0",
|
||||||
|
"vite": "^6.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
packages/ui/src/components/Badge.stories.tsx
Normal file
22
packages/ui/src/components/Badge.stories.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { Badge } from './Badge.js';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Badge> = {
|
||||||
|
title: 'Components/Badge',
|
||||||
|
component: Badge,
|
||||||
|
argTypes: {
|
||||||
|
variant: { control: 'select', options: ['success', 'warning', 'error', 'info', 'neutral'] },
|
||||||
|
size: { control: 'select', options: ['sm', 'md'] },
|
||||||
|
dot: { control: 'boolean' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Badge>;
|
||||||
|
|
||||||
|
export const Success: Story = { args: { children: 'Active', variant: 'success' } };
|
||||||
|
export const Warning: Story = { args: { children: 'Pending', variant: 'warning' } };
|
||||||
|
export const Error: Story = { args: { children: 'Failed', variant: 'error' } };
|
||||||
|
export const Info: Story = { args: { children: 'Info', variant: 'info' } };
|
||||||
|
export const Neutral: Story = { args: { children: 'Draft', variant: 'neutral' } };
|
||||||
|
export const WithDot: Story = { args: { children: 'Online', variant: 'success', dot: true } };
|
||||||
44
packages/ui/src/components/Button.stories.tsx
Normal file
44
packages/ui/src/components/Button.stories.tsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { Button } from './Button.js';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Button> = {
|
||||||
|
title: 'Components/Button',
|
||||||
|
component: Button,
|
||||||
|
argTypes: {
|
||||||
|
variant: { control: 'select', options: ['primary', 'secondary', 'ghost', 'danger'] },
|
||||||
|
size: { control: 'select', options: ['sm', 'md', 'lg'] },
|
||||||
|
loading: { control: 'boolean' },
|
||||||
|
disabled: { control: 'boolean' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Button>;
|
||||||
|
|
||||||
|
export const Primary: Story = {
|
||||||
|
args: { children: 'Primary Button', variant: 'primary' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Secondary: Story = {
|
||||||
|
args: { children: 'Secondary Button', variant: 'secondary' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Ghost: Story = {
|
||||||
|
args: { children: 'Ghost Button', variant: 'ghost' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Danger: Story = {
|
||||||
|
args: { children: 'Danger Button', variant: 'danger' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Loading: Story = {
|
||||||
|
args: { children: 'Loading...', variant: 'primary', loading: true },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Small: Story = {
|
||||||
|
args: { children: 'Small', variant: 'primary', size: 'sm' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Large: Story = {
|
||||||
|
args: { children: 'Large', variant: 'primary', size: 'lg' },
|
||||||
|
};
|
||||||
38
packages/ui/src/components/Card.stories.tsx
Normal file
38
packages/ui/src/components/Card.stories.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { Card, CardHeader, CardTitle, CardDescription } from './Card.js';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Card> = {
|
||||||
|
title: 'Components/Card',
|
||||||
|
component: Card,
|
||||||
|
argTypes: {
|
||||||
|
padding: { control: 'select', options: ['none', 'sm', 'md', 'lg'] },
|
||||||
|
hover: { control: 'boolean' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Card>;
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
args: { children: 'Card content goes here' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithHeader: Story = {
|
||||||
|
render: args => (
|
||||||
|
<Card {...args}>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Card Title</CardTitle>
|
||||||
|
<CardDescription>A short description of this card.</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<p style={{ color: 'var(--bl-text-secondary, #a0a0b0)', fontSize: 14 }}>Body content</p>
|
||||||
|
</Card>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Hoverable: Story = {
|
||||||
|
args: { hover: true, children: 'Hover me to see the border effect' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LargePadding: Story = {
|
||||||
|
args: { padding: 'lg', children: 'Large padding card' },
|
||||||
|
};
|
||||||
20
packages/ui/src/components/Input.stories.tsx
Normal file
20
packages/ui/src/components/Input.stories.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { Input } from './Input.js';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Input> = {
|
||||||
|
title: 'Components/Input',
|
||||||
|
component: Input,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Input>;
|
||||||
|
|
||||||
|
export const Default: Story = { args: { placeholder: 'Enter text...' } };
|
||||||
|
export const WithLabel: Story = { args: { label: 'Email', placeholder: 'you@example.com' } };
|
||||||
|
export const WithError: Story = {
|
||||||
|
args: { label: 'Email', value: 'bad', error: 'Invalid email address' },
|
||||||
|
};
|
||||||
|
export const WithHint: Story = {
|
||||||
|
args: { label: 'Username', placeholder: 'johndoe', hint: '3-20 characters, no spaces' },
|
||||||
|
};
|
||||||
|
export const Disabled: Story = { args: { label: 'Read Only', value: 'locked', disabled: true } };
|
||||||
Loading…
Reference in New Issue
Block a user