# @bytelyst/ui

Shared component library for the ByteLyst ecosystem. Built with Radix UI primitives, Lucide icons, and CSS custom properties from `@bytelyst/design-tokens`.

## Install

```bash
pnpm add @bytelyst/ui
```

Peer dependencies: `react`, `react-dom`.

## Components (15)

### Button

5 variants (`primary`, `secondary`, `ghost`, `destructive`, `outline`), 3 sizes, loading state with spinner.

```tsx
import { Button } from '@bytelyst/ui';

<Button variant="primary" size="md" loading={saving}>Save</Button>
<Button variant="destructive" onClick={onDelete}>Delete</Button>
<Button variant="ghost" size="sm">Cancel</Button>
```

### Input

Text input with error/success states. Supports `aria-invalid` automatically when `error` is truthy.

```tsx
import { Input } from '@bytelyst/ui';

<Input placeholder="Email" type="email" />
<Input error="Required field" />
```

### Textarea

Auto-resize textarea with error states.

```tsx
import { Textarea } from '@bytelyst/ui';

<Textarea placeholder="Description" rows={4} />;
```

### Select

Styled `<select>` with keyboard navigation.

```tsx
import { Select } from '@bytelyst/ui';

<Select
  options={[
    { value: 'a', label: 'Option A' },
    { value: 'b', label: 'Option B' },
  ]}
  value={selected}
  onChange={setSelected}
/>;
```

### Modal / Dialog

Radix `@radix-ui/react-dialog` with focus trap, Esc close, and `aria-modal`.

```tsx
import { Modal } from '@bytelyst/ui';

<Modal open={isOpen} onOpenChange={setOpen} title="Edit item">
  <p>Modal content here</p>
</Modal>;
```

### ConfirmDialog

Radix AlertDialog for destructive/warning confirmations. Supports async `onConfirm`.

```tsx
import { ConfirmDialog } from '@bytelyst/ui';

<ConfirmDialog
  open={showConfirm}
  onOpenChange={setShowConfirm}
  title="Delete item?"
  description="This action cannot be undone."
  onConfirm={handleDelete}
  variant="destructive"
/>;
```

### Toast

4 types (`success`, `error`, `warning`, `info`), auto-dismiss, `role="alert"`. Use `ToastProvider` in your root layout and `toast()` anywhere.

```tsx
import { ToastProvider, toast } from '@bytelyst/ui';

// In providers.tsx
<ToastProvider>{children}</ToastProvider>;

// Anywhere in app
toast('Saved successfully', 'success');
toast('Something went wrong', 'error');
```

### Card

Container with `default`, `elevated`, and `interactive` variants. Includes `CardHeader`, `CardTitle`, `CardDescription` sub-components.

```tsx
import { Card, CardHeader, CardTitle, CardDescription } from '@bytelyst/ui';

<Card>
  <CardHeader>
    <CardTitle>Dashboard</CardTitle>
    <CardDescription>Overview of your data</CardDescription>
  </CardHeader>
  {children}
</Card>;
```

### Badge

Status/count/risk-level badges, color-coded by semantic tokens.

```tsx
import { Badge } from '@bytelyst/ui';

<Badge variant="success">Active</Badge>
<Badge variant="danger">Critical</Badge>
<Badge variant="warning" count={5} />
```

### EmptyState

Placeholder for empty lists with icon, description, and optional CTA.

```tsx
import { EmptyState } from '@bytelyst/ui';

<EmptyState
  icon={<FileText size={48} />}
  title="No items yet"
  description="Create your first item to get started."
  action={<Button onClick={onCreate}>Create</Button>}
/>;
```

### Label

Styled form label.

```tsx
import { Label } from '@bytelyst/ui';

<Label htmlFor="email">Email address</Label>;
```

### Separator

Horizontal/vertical divider.

```tsx
import { Separator } from '@bytelyst/ui';

<Separator />
<Separator orientation="vertical" />
```

### Sidebar

Responsive collapsible sidebar with mobile toggle, overlay, and navigation items.

```tsx
import { Sidebar, SidebarItem } from '@bytelyst/ui';

<Sidebar
  collapsed={collapsed}
  onToggle={() => setCollapsed(!collapsed)}
  header={<span>MyApp</span>}
  footer="v1.0.0"
>
  <SidebarItem href="/dashboard" label="Dashboard" icon={<Home size={18} />} active />
  <SidebarItem href="/settings" label="Settings" icon={<Settings size={18} />} />
</Sidebar>;
```

### StatCard

Dashboard metric card with trend indicator.

```tsx
import { StatCard } from '@bytelyst/ui';

<StatCard label="Total Users" value="1,234" trend="up" trendValue="+12%" />
<StatCard label="Errors" value={42} trend="down" trendValue="-8%" icon={<AlertCircle />} />
```

### LoadingSpinner

Accessible loading indicator with `aria-busy` and `prefers-reduced-motion` support.

```tsx
import { LoadingSpinner } from '@bytelyst/ui';

<LoadingSpinner size="md" label="Loading data…" />
<LoadingSpinner size="sm" label="" />  {/* spinner only, no text */}
```

## Design Token Integration

All components use CSS custom properties with `--bl-` prefix and sensible fallbacks. Override them per-product:

```css
:root {
  --bl-accent: var(--jj-accent); /* JarvisJr */
  --bl-surface-card: var(--fm-surface); /* FlowMonk */
}
```

## Accessibility

Every component includes:

- `focus-visible` ring styles
- ARIA attributes (`aria-label`, `aria-modal`, `aria-busy`, `aria-invalid`, `aria-current`)
- Keyboard navigation (Esc to close, Tab focus trap in modals)
- `prefers-reduced-motion` respected via Tailwind's `animate-spin`

## Storybook

```bash
pnpm --filter @bytelyst/ui storybook
```

Storybook is configured with `@storybook/addon-a11y` for automated accessibility checks.
