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

61 lines
3.3 KiB
Markdown

# 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
```jsx
// 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>
```