Skip to content

Design System Cheat Sheet

A design system packages tokens, components, documentation, and governance so product teams ship consistent, accessible UI faster.

How to use this Design System cheat sheet

Design tokens store color, spacing, typography, and elevation as platform-agnostic variables consumed by CSS, iOS, and Android. Components compose tokens into buttons, inputs, and modals with documented props, states, and usage guidelines.

Semantic versioning communicates breaking API changes. Storybook or similar docs sites show live examples. An a11y checklist—focus order, contrast, labels, keyboard support—is part of definition of done for every component.

Quick Design System example

:root {
  --color-text-primary: #1a1a1a;
  --color-bg-surface: #ffffff;
  --space-md: 16px;
  --font-body: system-ui, sans-serif;
  --radius-md: 8px;
}

.ds-button {
  padding: var(--space-md);
  font-family: var(--font-body);
  border-radius: var(--radius-md);
  background: var(--color-brand-500);
  color: var(--color-text-on-brand);
}

Design Tokens

Category Example Notes
Color primitive blue-500: #2563eb Raw palette values
Color semantic color.text.primary Meaning-based; theme can swap primitives
Spacing space.4: 16px 4/8pt grid common
Typography font.size.body, font.weight.medium Scale + family + line-height
Elevation shadow.sm, shadow.lg Layered box-shadow tokens
Border radius radius.sm, radius.full Consistent corner treatment
Motion duration.fast, easing.standard Animation consistency
Breakpoints screen.md: 768px Responsive layout tokens

Components & API

Practice Example Notes
Variants variant="primary" | "secondary" CVA or prop enums over boolean soup
Sizes size="sm" | "md" | "lg" Touch targets ≥44px on mobile
Composition <Button asChild><a href> Polymorphic rendering for a11y
Slots iconLeft, iconRight Document which slots affect layout
States hover, focus, active, disabled, loading Visual + aria-busy for loading
Controlled vs uncontrolled value + onChange documented Match platform expectations
Forward refs forwardRef on inputs Focus management from parent forms
Deprecations @deprecated use variant="outline" Changelog before removal

Theming & Versioning

Topic Example Notes
Theme provider <ThemeProvider theme={light}> Inject tokens via CSS variables or context
Dark mode data-theme="dark" on root Swap semantic token values
Multi-brand Brand A / Brand B token sets Same components, different primitive maps
Semver major Remove prop or rename token Breaking; migration guide required
Semver minor New optional prop or token Backward compatible
Semver patch Bug fix, visual tweak within spec Safe to upgrade
Changelog Keep a CHANGELOG.md per release Link PRs and codemods
Codemods jscodeshift for renames Automate consumer upgrades on major bumps

Documentation & A11y Checklist

Item Example Notes
Storybook stories Default, Disabled, WithIcon stories Visual regression + manual QA
Props table Auto-generated from TypeScript Single source of truth
Do / Don't Use primary once per view Prevent design drift in docs
Keyboard Tab, Enter, Space, Escape Document expected keys per component
Focus visible :focus-visible ring token Never remove outline without replacement
Labels aria-label or visible <label> Every input has accessible name
Contrast 4.5:1 text, 3:1 large text Test light and dark themes
Live regions role="status" for toasts Announce async updates

Token JSON for Style Dictionary

{
  "color": {
    "brand": { "500": { "value": "#2563eb" } },
    "text": { "primary": { "value": "{color.neutral.900}" } }
  },
  "space": { "md": { "value": "16px" } }
}

Style Dictionary compiles tokens to CSS, SCSS, iOS, and Android outputs.

Component with variant API (React)

type ButtonProps = {
  variant?: 'primary' | 'ghost';
  size?: 'sm' | 'md';
  disabled?: boolean;
  children: React.ReactNode;
};

export function Button({ variant = 'primary', size = 'md', ...props }: ButtonProps) {
  return <button className={cn(styles.base, styles[variant], styles[size])} {...props} />;
}

Limit variant combinations—document supported matrix in Storybook.

A11y smoke test in Storybook

import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);

it('Button has no a11y violations', async () => {
  const { container } = render(<Button>Save</Button>);
  expect(await axe(container)).toHaveNoViolations();
});

Run axe in CI for each component story baseline.

Common mistakes

  • Publishing components without documented props, states, and accessibility behavior.
  • Hard-coding hex values in products instead of consuming semantic tokens.
  • Breaking changes in patch releases, eroding consumer trust.
  • Shipping icon-only controls without accessible names.

Key takeaways

  • Tokens separate raw values from semantic meaning for theming.
  • Components expose small, documented variant APIs with forward refs.
  • Semver and changelogs govern adoption across multiple product teams.
  • Docs and a11y checks are part of the component, not an afterthought.

Pro Tip

Publish token changes separately from component releases so brand updates do not force a major component bump unless APIs change.