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:
saravanakumardb1 2026-03-28 00:59:25 -07:00
parent a5d1c5f0b9
commit 11a832e271
7 changed files with 163 additions and 1 deletions

View 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;

View 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;

View File

@ -2,6 +2,10 @@
"name": "@bytelyst/ui",
"version": "0.1.0",
"type": "module",
"scripts": {
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"exports": {
".": "./src/index.ts",
"./button": "./src/components/Button.tsx",
@ -31,6 +35,12 @@
"devDependencies": {
"typescript": "^5.7.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"
}
}

View 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 } };

View 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' },
};

View 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' },
};

View 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 } };