Back to list
zzoohub

design-system

by zzoohub

diet-diary & sharing app made with react-native

0🍴 0📅 Jan 23, 2026

SKILL.md


name: design-system description: | Design token systems and component architecture for web and React Native. Use when: implementing design-system, building UI components, defining tokens, creating themed interfaces. Do not use for: UX decisions (use ux-design), business logic, data fetching. Workflow: ux-design (what/why) → this skill (tokens, components) → nextjs/expo-react-native (integration). references:

  • token-examples.md # W3C DTCG format examples, theme files
  • examples.md # Headless hooks, Compound components examples

Design System

Token Architecture

Multi-Tier Hierarchy

Tier 1: Primitive     →  Raw values, no meaning
Tier 2: Semantic      →  Intent/purpose ← USE THIS
Tier 3: Component     →  (Optional) Component-specific overrides
color.blue.500              (primitive) - NEVER use directly
    ↓
color.interactive.primary   (semantic) ← use this in components
    ↓
button.bg.primary           (component, optional)

Rule: Components only reference Semantic tokens. Never Primitive.

Why 3 Tiers?

ChangeWhat to updateImpact
Brand refreshTier 1 (Primitive)All semantics auto-update
Dark modeTier 2 (Semantic)Components unchanged
One-off exceptionTier 3 (Component)Isolated change

Semantic Token Categories

CategoryPurposeExamples
color.bg.*Backgroundsprimary, secondary, inverse
color.text.*Typographyprimary, secondary, link
color.interactive.*Actionsprimary, primaryHover, primaryActive
color.border.*Bordersdefault, strong, focus
color.status.*Feedbackerror, success, warning
spacing.component.*Inside componentsxs, sm, md, lg, xl
spacing.layout.*Between sectionsxs, sm, md, lg, xl

Component Architecture

Headless + Styled Separation

┌──────────────────────────────────────┐
│  Headless Layer                      │
│  Behavior + A11y + Keyboard          │
│  No styles, reusable across brands   │
└──────────────────────────────────────┘
                 ↓
┌──────────────────────────────────────┐
│  Styled Layer                        │
│  Headless + Tokens = UI Component    │
└──────────────────────────────────────┘

Rule: Headless handles behavior. Styled handles appearance. Never mix.

Why Separate?

ChangeWhat to updateOther layer
Keyboard navigation fixHeadless hookStyled unchanged
Brand color changeStyled componentHeadless unchanged
New accessibility requirementHeadless hookStyled unchanged

File Structure

src/shared/ui/
├── tokens/          # primitive, semantic, themes
├── headless/        # useButton, useToggle, useDialog
├── styled/          # Button, Toggle, Dialog (uses headless)
├── primitives/      # Box, Text, Stack
└── patterns/        # FormField, ConfirmDialog

Preferred Patterns

PatternPreferredAvoidWhy
Propsvariant="primary" size="lg"primary large (booleans)Explicit, mutually exclusive
Composition<Card><Card.Header><Card showHeader headerTitle="">Flexible, readable
Polymorphic<Box as="section">Separate <Section> componentSemantic HTML, less components
StateHeadless hook + StyledMixed logic/stylesSeparation of concerns

Rule: Variant props over booleans. Composition over configuration.


Platform Output

Web (CSS Custom Properties)

:root {
  --color-bg-primary: #ffffff;
  --color-text-primary: #0f172a;
  --color-interactive-primary: #2563eb;
}

[data-theme="dark"] {
  --color-bg-primary: #0f172a;
  --color-text-primary: #f9fafb;
}

React Native (TypeScript)

export const tokens = {
  color: {
    bg: { primary: '#ffffff', secondary: '#f9fafb' },
    text: { primary: '#0f172a', secondary: '#475569' },
    interactive: { primary: '#2563eb' },
  },
  spacing: {
    component: { xs: 4, sm: 8, md: 12, lg: 16, xl: 24 },
  },
} as const;

Accessibility Requirements

RequirementValueNon-negotiable
Text contrast4.5:1 minimum
UI component contrast3:1 minimum
Focus indicator2px+ visible outline
Touch targets44×44pt minimum

Rule: Color is never the only indicator. Always pair with icon, text, or pattern.

Focus States

:focus-visible {
  outline: 2px solid var(--color-border-focus);
  outline-offset: 2px;
}

:focus:not(:focus-visible) {
  outline: none;
}

Reduced Motion

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Quick Checklist

Tokens

  • No hardcoded values in components (colors, spacing, etc.)
  • Using Semantic tokens, not Primitive
  • Dark theme remaps Semantic tokens only

Components

  • Headless hook for behavior + a11y
  • Styled component uses tokens only
  • Using variant / size / colorScheme props (not booleans)
  • All states defined: default, hover, focus, active, disabled, loading

Accessibility

  • Color not sole indicator
  • Focus visible (2px+ outline)
  • Touch targets 44pt+
  • Reduced motion respected
  • ARIA attributes correct

Score

Total Score

40/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon