Skip to content
michaelmartinhoPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Coverd Design System — proof of concept

A working technical foundation for design + engineering to review together and decide: do we adopt this architecture for the real design system, on web and native?

Not the final design system. Token values are placeholders drawn from the v1.1 spec and the Figma typography page; the architecture is the thing under review.

apps/
  web/       Storybook 10 (React + Vite)         → Foundations · Components · Patterns
  mobile/    Expo 57 + React Native Storybook    → same organisation, on device

packages/
  tokens/    DTCG JSON → generated TS + CSS vars  (primitive → semantic, light + dark)
  motion/    springs / durations / behaviours + per-platform adapters
  icons/     one path source, SVG on web, react-native-svg on native
  components/ Button · Pill · Card · List Item · Sheet · Text · ThemeProvider

Run it

pnpm install                 # Node ≥ 20, pnpm 10
pnpm web                     # Storybook → http://localhost:6006
pnpm mobile                  # Expo dev server; press i for iOS simulator
pnpm mobile:ios              # native build (Reanimated + Gesture Handler need a dev build, not Expo Go)
pnpm typecheck               # every package, web and native tsconfigs
pnpm tokens:build            # regenerate packages/tokens/src/generated + dist/tokens.css

TestFlight later: cd apps/mobile && eas build --profile testflight --platform ios (fill in the EAS project id in app.json; eas.json already has preview (internal) and testflight profiles).

The one idea

Share meaning, not implementation.

Shared (one source) Per platform (*.web.tsx / *.native.tsx)
token names + values (color.action.primary) how a colour reaches a pixel (CSS var vs style)
semantic typography (type.action.lg) font loading, line-height units
spacing, radius, opacity numbers —
motion physics (motion.spring.snappy) Reanimated withSpring vs CSS linear()
behaviours (motion.behavior.button-press) gesture handling, haptics
component props and state names press handling, focus rings, a11y plumbing
the recipe: props → which tokens apply —

Each component has three files:

button/
  Button.types.ts     the conceptual API (mirrors Figma component properties)
  Button.recipe.ts    props → token paths + geometry; imported by BOTH platforms
  Button.web.tsx      <button>, CSS custom properties, :active/:focus-visible, spring-derived transition
  Button.native.tsx   Pressable + Reanimated spring + Expo Haptics, min-height not fixed height

Bundlers pick the file: Metro resolves .native.tsx, Vite is configured for .web.tsx (apps/web/.storybook/main.ts), and each package type-checks twice via tsconfig moduleSuffixes.

Token pipeline

Figma variables  ──(later: export)──▶  packages/tokens/src/tokens/*.json   (DTCG format)
                                              │  node scripts/build.mjs
                                              ▼
                     src/generated/*.ts  (typed objects)   +   dist/tokens.css  (--coverd-* vars)
                                              │                         │
                                       native components          web components

Three tiers, references flow one way: primitive → semantic → component. Components import only the semantic tier. Light and dark are two files with the same names pointing at different primitives; the Theme toolbar in Storybook (and the Theme control on device) proves components never change.

Naming follows the spec grammar {category}.{concept}.{variant}.{state} so it maps 1:1 to Figma (color.text.primary ⇄ color/text/primary) and to CSS (--coverd-color-text-primary). One deliberate deviation: where a token has states, the JSON keeps an explicit default leaf (color.action.primary.default / .pressed) because a JSON key can't be both a value and a group; the generator drops .default in CSS names so the spec rule still holds where people read it.

Decisions worth arguing about

See docs/ARCHITECTURE.md for the reasoning behind each choice and the questions this prototype is meant to surface for the review.

What is deliberately not here

No production build/publish of packages (apps consume TS source directly), no tests beyond type-checking and visual review, no Style Dictionary (the JSON is already in its format; swap the 60-line generator when you want multi-platform exports like SwiftUI/Compose), no Cera Round font bundling, no full variant matrix (3 of the spec's 7 button variants, 3 of 5 sizes).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages