Spaces:
Running
Running
File size: 8,760 Bytes
1b2323a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | # MediaRouter Design System v1
## Purpose
The MediaRouter Design System is the backend-agnostic UI foundation for the
workspace product. It is intentionally not a collection of application pages:
future Dashboard, Projects, AI, media, publishing, analytics, and automation
experiences compose these primitives instead of adding one-off visual rules.
The implementation lives in `frontend/` and works with the Next.js App Router,
TypeScript, Tailwind CSS, shadcn-compatible Radix primitives, CVA,
Framer Motion, Lucide, React Hook Form, Zod, TanStack Table/Virtual/Query,
Zustand, `next-themes`, and Storybook.
## Architecture
```text
design-system/
tokens/ typed references to CSS semantic tokens
themes/ theme provider and high-contrast control
foundations/ shared conventions and accessibility rules
motion/ Framer Motion presets
icons/ the only Lucide import boundary for new system components
components/
ui/ accessible Radix/shadcn-compatible primitives
layout/ workspace, panel, split-pane and responsive layout primitives
navigation/ navigation, breadcrumbs, switchers and quick actions
feedback/ alerts, toast API, loading/empty/error/offline/progress states
forms/ composable RHF/Zod-ready controls
charts/ backend-neutral chart frame
timeline/ timeline primitives
media/ backend-neutral media and asset cards
hooks/ interaction, reduced-motion, Zod form and table hooks
stories/ Storybook component catalog
```
No primitive makes a REST, MCP, n8n, SDK, storage, or provider call. Data and
actions are injected by a consuming feature.
## Tokens and theming
`app/globals.css` owns CSS custom-property values. Tailwind maps only semantic
names such as `bg-surface`, `text-text-secondary`, `border-border`,
`bg-ai`, `text-success`, and `bg-timeline-track`. Component source must never
add a literal color value.
Semantic color tokens cover background, surface, elevated surface, border,
primary, secondary, accent, success, warning, danger, info, muted, three text
levels, overlay, focus ring, selection, timeline track/marker/cursor, and AI,
publishing, analytics, and automation accents. Each has light, dark, and
high-contrast values.
The standardized spacing scale is 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80,
and 96 pixels (`space-1` through `space-24`). New components use classes such
as `gap-space-3`, `p-space-6`, and `px-space-4`, not arbitrary spacing.
Radius tokens are `ds-sm`, `ds-md`, `ds-lg`, `ds-xl`, `ds-2xl`, and `ds-full`.
Shadow tokens are `ds-sm`, `ds-md`, `ds-lg`, `floating`, `modal`, and
`popover`.
`ThemeProvider` in `design-system/themes/theme-provider.tsx` wraps
`next-themes` and supports `light`, `dark`, `system`, and `high-contrast`.
Theme preferences are client-side presentation preferences only; no backend
state is required. `ThemeToggle` cycles all modes.
## Typography, icons, and motion
`components/typography/typography.tsx` provides Display, Heading, Title,
Subtitle, Body, Caption, LabelText, Code, and the composable `Typography`
primitive. The scale uses semantic font-size tokens and balances dense
workspace information with readable hierarchy.
New design-system components import icons only from
`design-system/icons/icon.tsx`. `Icon` uses size tokens, a consistent 1.8
stroke, and is decorative unless a `label` is supplied. This prevents raw
Lucide usage from fragmenting icon weights and accessibility behavior.
`design-system/motion/presets.ts` supplies page, sidebar, dialog, popover,
tooltip, toast, hover, press, accordion, tabs, card, list, timeline, drawer,
bottom-sheet, loading, skeleton, and progress presets. Use
`useMediaRouterReducedMotion()` for interactive Framer Motion consumers. The
global stylesheet also reduces native/Tailwind motion when the operating system
requests reduced motion.
## Component inventory
### Core UI
- Button, IconButton, ToggleButton, SplitButton, DropdownMenu
- Card, Panel, Section, Container, Stack, Grid, Page, ContentArea
- Dialog, Drawer, BottomSheet, Popover, Tooltip, Tabs, Accordion
- Badge, StatusBadge, ProviderBadge, AIBadge, Avatar, Separator
- Command/CommandPalette/Spotlight, Combobox, Pagination, Calendar/DatePicker
- Progress and Skeleton
### Forms
- Input, Textarea, Select, Checkbox, RadioGroup, Switch, Slider
- Email, URL, phone, number, currency, search, password, OTP, and color inputs
- Field shell with helper, success, required, disabled, and error states
- FileDropzone, TagInput, MediaSelector, RHF `Form`, and `useZodForm`
### Data, media, and feedback
- `useDataTable`, DataTable, and VirtualTable (sorting, filtering, grouping,
selection, visibility, sticky headers, responsive overflow)
- MetricCard, StatCard, KPICard, Timeline, ActivityItem
- MediaCard, AssetCard, ProjectCard, ChartContainer
- Alert, Error/Retry/Success banners, toast API, Empty/Error/Offline states,
and job/upload/AI/publishing progress
### Navigation and workspace layout
- WorkspaceShell, Sidebar, Topbar, Inspector, SplitPane, ResizablePanel,
Toolbar, Dock, FloatingPanel
- Sidebar/Mobile navigation, Breadcrumb, WorkspaceSwitcher, ProjectSwitcher,
and QuickActions
## Accessibility standard
The minimum target is WCAG 2.2 AA:
- Radix primitives provide focus traps, escape handling, menu/listbox/dialog
keyboard behavior, and screen-reader relationships.
- Interactive controls have visible semantic focus rings and disabled states.
- Icon-only controls require a text label; decorative icons are hidden.
- Form fields offer label, helper, required, success, and `role=alert` error
affordances.
- Tables use semantic headers and rows; loading and progress use `aria-busy`,
`progress`, status regions, and live text where appropriate.
- High-contrast theme tokens increase contrast without changing component
source. Reduced-motion preferences disable decorative motion.
- Storybook includes `@storybook/addon-a11y` configured to fail accessibility
checks in the component catalog.
Consumers remain responsible for meaningful labels, error copy, logical tab
order across a composed page, and testing real content contrast.
## Responsive behavior
The system is mobile-first. `xs`, tablet, laptop, desktop, wide, and
ultra-wide breakpoints are available. Grid and workspace primitives collapse
to a single column before sidebars/inspectors appear. Tables retain semantics
with horizontal overflow; consuming features may use their own compact-card
renderer for intentionally collapsed mobile views. The bottom dock and bottom
sheet are mobile-ready, including safe-area padding.
## Storybook
Run from `frontend/`:
```bash
npm run storybook
npm run storybook:build
```
Stories cover UI foundations, interactive overlays and controls, forms,
feedback, layout/navigation, data display, media, states, sizes, loading,
dark/high-contrast controls, and responsive composition. The Storybook toolbar
selects light, dark, and high-contrast themes.
## Best practices
1. Compose primitives; do not introduce page-local UI primitives.
2. Use semantic Tailwind tokens and spacing/radius/shadow tokens.
3. Keep backend queries, mutation logic, API URLs, and provider credentials
outside the design system.
4. Add closed typed props and CVA variants before adding a visual state.
5. Use `forwardRef` for DOM controls and primitives intended for composition.
6. Use `Icon` rather than raw Lucide imports in all new system code.
7. Use `loading`, empty, error, offline, and disabled states intentionally.
8. Do not animate state merely because it changed; apply motion presets only
when they clarify hierarchy or progress.
## Contribution guide
For each new primitive:
1. Confirm that it cannot be composed from an existing primitive.
2. Add semantic tokens only when the state has a cross-product meaning.
3. Implement typed props, CVA variants, focus/keyboard behavior, high
contrast, reduced motion, loading/empty/error where applicable, and a
`forwardRef` when it owns a DOM element.
4. Add a Storybook story that covers variants, sizes, disabled/loading, dark
mode, high contrast, keyboard behavior, and responsive behavior.
5. Run `npm run lint`, `npm run typecheck`, `npm test`, `npm run build`, and
`npm run storybook:build` before merging.
## Future extensions
The foundations intentionally leave backend-bound concerns for future feature
work: workspace data adapters, project data, provider-specific visual
metadata, server-driven chart schemas, persisted user layout preferences,
internationalization, more date-range/calendar behavior, and advanced grid
column personalization. Those additions must consume this system rather than
add page-local visual foundations.
|