Spaces:
Running
Running
| # 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. | |