Files
Amruth Pillai a28e3baa61 chore(design-sync): add Reactive Resume UI sync inputs (#3216)
* chore(design-sync): add Reactive Resume UI sync inputs

Sync inputs for the claude.ai/design "Reactive Resume" project — the
@reactive-resume/ui design system (39 primary components).

- .design-sync/config.json — converter config (synth-entry, 202->39 card
  prune, overlay/grid cardMode overrides, cssEntry, tsconfig, buildCmd)
- .design-sync/build-css.mjs + tw-entry.css — compile Tailwind v4 globals.css
  to a self-contained stylesheet (inlined IBM Plex font), emit real .d.ts,
  and create the workspace self-symlink the converter needs
- .design-sync/previews/*.tsx — 39 authored preview compositions
- .design-sync/conventions.md — design-agent usage header (readmeHeader)
- .design-sync/NOTES.md — re-sync notes, gotchas, and risks
- packages/ui/tsconfig.emit.json — declaration emit for real prop contracts

Build artifacts (dist/types, .ds-compiled.css, ds-bundle, .cache) are gitignored.

Claude-Session: https://claude.ai/code/session_01R8Aq8F1nTuvJwfut7g3DVE

* chore(knip): ignore .design-sync inputs and drop stale es-toolkit ignore

- Ignore .design-sync/** (design-sync tooling: build-css.mjs + authored
  previews are standalone, not part of the app import graph — knip --fix was
  deleting them and failing the autofix job).
- Remove es-toolkit from apps/server ignoreDependencies: it's now really used
  (apps/server/src/http/health.ts imports withTimeout), so the ignore is stale.

Claude-Session: https://claude.ai/code/session_01R8Aq8F1nTuvJwfut7g3DVE
2026-07-05 06:25:51 +02:00

3.3 KiB

Reactive Resume UI — how to build with it

This is @reactive-resume/ui: a shadcn-style React component library built on Base UI primitives and Tailwind CSS v4. Every component is real upstream code, bundled to the window.RRUI global; the 39 cards are the primary components, but all their compound sub-parts (e.g. DialogContent, AccordionItem, SidebarMenuButton) are also on RRUI.

Setup & wrapping

  • No global provider is required. All design tokens live on :root in styles.css (loaded for you), so components are styled out of the box. For dark mode, add class="dark" to a wrapping element — the same tokens flip to their dark values.
  • A few components need their own provider — wrap only where you use them:
    • Tooltip* → wrap in RRUI.TooltipProvider.
    • Sidebar* → wrap in RRUI.SidebarProvider.
    • MessageScroller* → wrap in RRUI.MessageScrollerProvider and give it a bounded height.
    • Form fields → RRUI.FormItem provides the field context for FormLabel/FormControl/FormMessage.
  • Compose compound components from their parts, e.g. Dialog = DialogTrigger + DialogContent (+ DialogHeader/DialogTitle/DialogDescription/DialogFooter). Overlay parts (Dialog, Sheet, Popover, DropdownMenu, ContextMenu, Tooltip, HoverCard) render into a portal. Menu labels must sit inside a *Group (DropdownMenuGroup, ContextMenuGroup).
  • Icons come from @phosphor-icons/react (the *Icon suffix, e.g. PlusIcon).

Styling idiom — Tailwind utilities on semantic tokens

Components style themselves; for your own layout and surfaces, use Tailwind utility classes bound to the design system's semantic color tokens (never raw hex — these adapt to light/dark):

Purpose Utilities
Surfaces bg-background, bg-card, bg-popover, bg-muted, bg-sidebar
Brand / actions bg-primary + text-primary-foreground, bg-secondary + text-secondary-foreground
Accents / hover bg-accent + text-accent-foreground, hover:bg-muted
Danger bg-destructive, text-destructive
Text text-foreground (primary), text-muted-foreground (secondary)
Borders / focus border, border-input, ring-ring, outline-ring
Radius rounded-md, rounded-lg (driven by --radius)

Each token is also a CSS variable (var(--primary), var(--muted-foreground), var(--border), var(--radius), --font-body = IBM Plex Sans) if you need it in inline styles.

Where the truth lives

  • Styling: styles.css and its @import closure (_ds_bundle.css = component styles; the token definitions on :root/.dark). Read these before inventing a class or color.
  • Per component: components/<group>/<Name>/<Name>.prompt.md (usage) and <Name>.d.ts (props — variant/size unions where a named type exists; some fall back to a permissive shape).

Idiomatic snippet

// A confirm action, styled with the DS's own tokens for the surrounding layout.
<div className="flex flex-col gap-3 rounded-lg border bg-card p-4">
  <p className="text-sm text-muted-foreground">Publish this resume to your public profile?</p>
  <div className="flex justify-end gap-2">
    <RRUI.Button variant="outline">Cancel</RRUI.Button>
    <RRUI.Button>Publish</RRUI.Button>
  </div>
</div>