Step 9 · Scaffold a Core Component Set

Scaffold a Core Component Set

play · scaffold-core-components
You are implementing the core component set for this design system, consuming the token system you have generated. The token system (color, type, shape, spacing) must be compiled before this play begins. **Step 1 — Read the living brief:** Read `LIVING_BRIEF.md`. Confirm the technology stack, token naming convention, shape scale, and approved visual direction. Fetch and read the following from the Sistema knowledge base: - Token architecture synthesis: `/raw/principles/tokens/architecture` - Accessibility floor: `/raw/principles/accessibility/floor` **Step 2 — Confirm component library:** Ask the user: 1. Do you want to use shadcn/ui as the component base? (Recommended for Tailwind-based projects — Radix UI primitives with Tailwind, highly customizable, widely adopted. Components are copied into your project and owned by you.) 2. Alternatives: Base UI (unstyled Radix-compatible primitives), Radix UI directly, or no library (build from scratch). If the stack doesn't use Tailwind, adapt the approach to the actual styling layer — don't force Tailwind-specific integration on a non-Tailwind project. **Step 3 — Wire the token system into the framework:** Before installing any components, establish the token integration layer. Without it, component code that references token-named utilities won't resolve. **For Tailwind-based projects:** Generate `tailwind.config.ts` extending the theme with every token from the token system. Every compiled CSS custom property must have a corresponding Tailwind utility class: ```ts import type { Config } from 'tailwindcss' const config: Config = { content: ['./src/**/*.{ts,tsx,js,jsx}', './app/**/*.{ts,tsx,js,jsx}'], theme: { extend: { colors: { primary: 'var(--color-primary)', 'on-primary': 'var(--color-on-primary)', 'primary-container': 'var(--color-primary-container)', secondary: 'var(--color-secondary)', 'on-secondary': 'var(--color-on-secondary)', surface: 'var(--color-surface)', 'surface-raised': 'var(--color-surface-raised)', 'surface-overlay': 'var(--color-surface-overlay)', 'on-surface': 'var(--color-on-surface)', 'on-surface-muted': 'var(--color-on-surface-muted)', border: 'var(--color-border)', 'border-focus': 'var(--color-border-focus)', error: 'var(--color-error)', 'on-error': 'var(--color-on-error)', success: 'var(--color-success)', warning: 'var(--color-warning)', // add any additional roles from the color token file }, borderRadius: { none: 'var(--radius-none)', sm: 'var(--radius-sm)', md: 'var(--radius-md)', lg: 'var(--radius-lg)', xl: 'var(--radius-xl)', full: 'var(--radius-full)', }, spacing: { // Add all stops from tokens/src/spacing.json 1: 'var(--space-1)', 2: 'var(--space-2)', 3: 'var(--space-3)', 4: 'var(--space-4)', 5: 'var(--space-5)', 6: 'var(--space-6)', 8: 'var(--space-8)', 10: 'var(--space-10)', 12: 'var(--space-12)', 16: 'var(--space-16)', }, } } } export default config ``` Verify the import path for compiled token CSS in the global stylesheet against the actual project directory structure — the path differs based on whether a `src/` directory is present. If using **Next.js**, load fonts via `next/font` — not a CDN `@import` in the global stylesheet. `next/font` self-hosts the font, eliminates render-blocking requests, and prevents layout shift. If the stack uses a different framework, use its idiomatic font loading approach. **For non-Tailwind projects:** establish the token integration layer appropriate to the CSS approach in use — CSS modules, vanilla CSS with custom properties, or the framework's theming API. **Step 4 — Define the component file structure:** Before writing any component code, establish the file organization. Organize by functional group — not a catch-all file: ``` components/ui/ button.tsx — Button, IconButton input.tsx — Input, Textarea select.tsx — Select, Combobox form.tsx — Checkbox, Radio, Switch, FormField feedback.tsx — Badge, Toast, Alert overlay.tsx — Dialog, Popover, Tooltip, Drawer surface.tsx — Card, Separator, Divider index.ts — barrel export: re-exports every public component ``` Adjust groupings to match the actual component set. The `index.ts` barrel must re-export every public component so consumers always import from `@/components/ui`, never from individual files. **Step 5 — Install and scaffold components:** If shadcn/ui: initialize with `npx shadcn@latest init`, then generate at minimum: Button, Input, Select, Checkbox, Badge, Card, Dialog, Popover, Separator, Tooltip. For each component, verify: - Token consumption: no hardcoded hex values or raw px for anything covered by a token - All interactive states present (hover, focus, active, disabled) - Focus indicator meets 3:1 contrast per the accessibility floor - Touch target ≥ 44×44px for interactive elements **Step 6 — Customize to the visual direction:** Apply the approved visual direction from `style-preview.html`: - Radius values match the shape token scale - Color variable mappings use semantic role tokens - Typography references the type scale tokens - Composite card specimen from `style-preview.html` serves as the visual target **Step 7 — Generate component-preview.html:** Generate a self-contained `component-preview.html` showing all core components in default, hover, and focus states. Pause for user review before proceeding. **Step 8 — Update the living brief:** Update the Components implemented list. Append to the Decision Log: ``` [date] — Core component set scaffolded — [library used, components generated, any notable customizations] ``` ---
Step 9 of 11 · Scaffold a Core Component Set
paste intoClaude CodeCursor