MediaRouter / docs /design-system.md
basyx's picture
Upload 794 files
1b2323a verified
|
Raw
History Blame Contribute Delete
8.76 kB

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

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/:

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.