9.6 KiB
AI UI Roadmap
Goal
Build a long-term maintainable component system inspired by shadcn/ui, but owned by this repo:
- keep the
Radix + Tailwind + source-owned componentsmodel - replace default styling with our own tokens and component rules
- make motion a first-class system layer, not ad hoc transitions
- support theming, accessibility, testing, and future internal registry distribution
Product Principles
- Source owned Components live in our codebase and are modified directly.
- Token first Visual and motion decisions are defined as tokens before being embedded in components.
- Component contract over component count Stable API patterns matter more than shipping many components quickly.
- Accessibility by default Keyboard, focus, ARIA, and reduced motion are baseline requirements.
- Motion with purpose Animation must communicate state, feedback, and hierarchy.
- Incremental adoption Start from a small core and expand only after patterns are stable.
Recommended Stack
Core
ReactTypeScriptpnpm workspaceTailwind CSSCSS variablesRadix UIclass-variance-authorityclsxtailwind-merge
Motion
- CSS transitions and keyframes for default interactions
motionorframer-motionfor advanced choreography onlyprefers-reduced-motionsupport from day one
Docs and DX
StorybookLucide Reactreact-hook-formzod
Quality and Release
Vitest@testing-library/reactPlaywrightaxe-coreorjest-axetsupChangesets
Target Repository Structure
apps/
docs/ # Storybook or docs app
packages/
ui/ # component source
tokens/ # design + motion tokens
icons/ # optional icon wrappers
config/ # shared ts/eslint/tailwind config, optional
registry/ # future internal shadcn-like registry
packages/ui structure
src/
lib/
cn.ts
cva.ts
motion.ts
styles/
base.css
tokens.css
motion.css
primitives/
components/
button/
input/
dialog/
dropdown-menu/
tabs/
toast/
patterns/
form/
data-table/
System Layers
1. Tokens
Define semantic tokens instead of hardcoded visual values.
Visual token groups:
- colors
- typography
- radius
- shadow
- border
- spacing when needed beyond Tailwind defaults
Motion token groups:
--dur-fast--dur-base--dur-slow--ease-standard--ease-emphasized--distance-xs--distance-sm--scale-press
2. Primitives
Use Radix UI as the accessibility and interaction base where appropriate.
Examples:
- dialog
- popover
- dropdown-menu
- tabs
- toast
- checkbox
- radio-group
- switch
3. Motion Recipes
Reusable motion patterns that components consume instead of redefining animation logic.
Initial recipe set:
fade-infade-outslide-up-smslide-down-smoverlay-enteroverlay-exitpress-feedbackfocus-ring-transitionaccordion-expandtoast-entertoast-exit
4. Components
Components compose tokens, primitives, and motion recipes into a stable public API.
Component Contract
All components should follow a consistent contract where relevant:
- support
className - forward
ref - use
variantonly where it adds actual semantic value - use
sizeonly where it is meaningful - support
asChildfor composable primitives - expose controlled and uncontrolled APIs when appropriate
- expose stable states through attributes such as
data-state,data-disabled, anddata-invalid - include loading, disabled, error, and focus behaviors where applicable
Design Rules
Keep from shadcn
- source-distributed component ownership model
- composable React API patterns
Radix + Tailwind + CVAimplementation style- pragmatic developer experience
Replace from shadcn
- default visual tokens
- default component variants
- default color and radius assumptions
- default animation choices
- package and registry conventions when our patterns stabilize
Motion Rules
Default timing guidance:
- press feedback:
100-140ms - hover and focus:
160-200ms - popover, dropdown, tooltip:
180-240ms - dialog and drawer:
220-320ms - section entrance:
320-480ms - exits should generally be faster than entrances
Implementation rules:
- prefer animating
transformandopacity - avoid
transition-all - avoid animating
width,height,top,left,padding,margin - use
data-statedriven animation where possible - support
prefers-reduced-motion - use JS animation only for interactions CSS cannot express cleanly
Delivery Phases
Phase 0: Foundation Setup
Objective: Create the monorepo foundation and install the baseline tooling.
Deliverables:
pnpm workspace- root
package.json packages/uipackages/tokensapps/docs- Tailwind, TypeScript, ESLint, and build setup
Exit criteria:
- workspace installs cleanly
- docs app boots
packages/uibuilds
Phase 1: Token System
Objective: Define the first stable visual and motion token layer.
Deliverables:
tokens.cssmotion.css- semantic color scale
- radius, shadow, border, typography tokens
- motion duration, easing, distance, and scale tokens
- light theme baseline
- dark theme baseline
- one optional brand theme scaffold
Exit criteria:
- components can consume tokens without hardcoded brand values
- theme switching works at token level
- reduced motion rules exist globally
Phase 2: Core Utilities and Contracts
Objective: Standardize the implementation patterns every component will use.
Deliverables:
cn.tscva.tsconventions- shared component authoring guidelines
- state naming and slot naming conventions
- motion helper conventions
Exit criteria:
- new components can follow one repeatable implementation pattern
- API expectations are documented
Phase 3: Core Component Set
Objective: Ship the first stable component layer.
Priority components:
ButtonInputTextareaCheckboxRadio GroupSwitchSelectDialogDropdown MenuTabsToastForm
Exit criteria:
- all core components support tokens and motion recipes
- all core components have docs stories
- all core components have baseline tests
Phase 4: Documentation and QA
Objective: Make the system safe to use and safe to evolve.
Deliverables:
- Storybook stories for all component states
- accessibility checks
- interaction tests
- visual review process
- contribution guide for new components
Exit criteria:
- docs cover variants, sizes, states, themes, and reduced motion
- core components pass accessibility and interaction checks
Phase 5: Advanced Patterns
Objective: Build higher-level patterns only after the base layer is stable.
Candidate patterns:
FormData TableCommandComboboxDate PickerDrawerSheetEmpty State
Exit criteria:
- patterns reuse existing component contracts
- no pattern introduces a competing API style
Phase 6: Internal Registry and Distribution
Objective:
Create an internal distribution model similar to shadcn, but based on our own rules.
Deliverables:
- internal registry format
- code generation or copy-in workflow
- documentation for install and upgrade paths
- versioning and release process
Exit criteria:
- consumers can pull components from our registry
- upgrades are documented and reproducible
Testing Strategy
Unit and Interaction
Vitest@testing-library/react- state and variant coverage
- controlled and uncontrolled behavior coverage
Accessibility
axe-coreorjest-axe- keyboard and focus-path checks
- reduced motion validation
End-to-End
Playwright- open and close behavior
- keyboard navigation
- form submission flows
Documentation Requirements
Every core component should document:
- purpose
- anatomy
- variants
- sizes
- states
- accessibility notes
- motion behavior
- reduced motion fallback
- example usage
Risks to Manage
- over-customizing too early before contracts stabilize
- building too many components before token patterns settle
- letting business code create parallel component wrappers
- tying all animation to a JS library unnecessarily
- skipping docs and tests until later
Initial Execution Plan
Sprint 1
Goal: Set up the workspace and foundation.
Tasks:
- initialize
pnpm workspace - create
apps/docs - create
packages/ui - create
packages/tokens - add Tailwind and TypeScript setup
- add Storybook
Sprint 2
Goal: Lock the first token layer and first motion layer.
Tasks:
- create
tokens.css - create
motion.css - define base semantic palette
- define duration and easing tokens
- add global reduced motion rules
Sprint 3
Goal: Ship the first reference components.
Tasks:
- implement
Button - implement
Input - implement
Dialog - add stories
- add tests
Sprint 4
Goal: Expand the core set using the same contract.
Tasks:
- implement
Dropdown Menu - implement
Tabs - implement
Toast - validate API consistency
Definition of Done
A component is considered done only when:
- implementation is in
packages/ui - tokens are used instead of hardcoded presentation values
- motion follows shared recipes or shared timing rules
- documentation exists
- tests exist
- accessibility behavior is validated
- reduced motion behavior is defined
First Build Target
The first meaningful milestone is:
- monorepo running
- tokens and motion tokens defined
Button,Input, andDialogshipped- Storybook stories available
- baseline tests passing
This is the point where the system stops being an idea and becomes a reusable foundation.