opsinjs
HandbookContributing

Component checklist

The definition of done across design, code, tokens, tests, accessibility, documentation and safety. The items that are actually enforced are marked as such.

The short version

A component is done when it can be used by somebody who has not met the team. That decomposes into seven groups. Items marked enforced fail the build or the CI check; the rest are review items, and the distinction is deliberate. A checklist where everything is equally important is a checklist nobody reads.

How it works

Design

  • The plain-English definition is written for a patient, not an engineer.
  • Every state is designed: default, hover, press, focus-visible, disabled, loading, selected.
  • Every one of the five data states has a designed answer. They are empty, loading, error, stale and partial.
  • The component works at the narrowest supported width and at the widest without a special case. See Responsive modes.
  • It reads correctly in both themes and under increased contrast.

Code

  • Enforced: a named exported props interface, <Component>Props. Without it the API table generates empty. See TypeScript.
  • Enforced: no raw colour values anywhere in the source.
  • Every public prop has a JSDoc line.
  • render is supported on every part that renders an element.
  • ref is forwarded on every part.
  • className is merged with cn(), caller last.
  • Client boundary is on the leaf, not the module.

Tokens

  • Enforced: every value comes from a token; no literals.
  • The component reads semantic tokens, never primitives. See Token architecture.
  • Enforced: no token crosses the axes. A status token in a category role fails.
  • Any new component-level CSS variable is documented in the component's CSS variables table.

Tests

  • Roles and accessible names asserted, not class names.
  • Keyboard behaviour asserted against the documented contract.
  • Focus position asserted after every interaction that moves it.
  • The five data states rendered and asserted.
  • No DOM snapshots. See Testing.

Accessibility

  • Enforced: every token pair used by the component passes the published contrast floor in both themes, measured by check-contrast.mts.
  • Enforced: status is distinguishable in grayscale. The CVD audit runs in CI.
  • Keyboard contract documented in the component's KeyboardTable.
  • Screen-reader announcement contract written down and tested on at least one real combination.
  • Touch targets meet the 44pt floor. See Density and touch targets.
  • Readable and operable at 200% text.
  • Every motion has a defined prefers-reduced-motion fallback that is observable.
  • reviewed and reviewer: design set in frontmatter, on the day somebody ran the checks above rather than on the day the page was edited.

Documentation

  • Enforced: every section required at the declared status is present. PageTemplate fails the build otherwise.
  • Enforced: the body is inside the word budget. assert-ia rule LEAN001 fails the build past a thousand words, or twelve hundred and fifty on a health-* page.
  • Enforced: the "when not to use" list names an alternative for every entry.
  • Enforced: governedBy is present when the category starts with health-, and the named doctrine pages list this component in implements.
  • Content guidelines written, with one approved and one rejected phrasing, where the component renders copy the product writes.
  • An Anatomy section for any component with two or more parts.
  • Aliases added to registry/catalogue.ts.

Safety

  • Enforced for health-* categories: the Clinical meaning section exists and states what the component asserts, what it must never be read as, which axis it may use, and who owns the thresholds.
  • The component cannot be made to state something it does not know: no interpolation, no carried-forward values, no zero standing in for absence.
  • A clinical reviewer has signed the page, with a reviewed date.
  • Every claim is either cited or marked evidence: opinion.

Do this

  • Work through the list before opening the pull request, and paste it into the description with the boxes ticked. It is faster than three review rounds.
  • Do the accessibility items first, not last. Retrofitting a keyboard contract is a rewrite; designing to one is an afternoon.
  • Regenerate and commit the generated artefacts in the same change.
  • Ask for the clinical review early if the component is health-*. It is the longest lead time on the list.

Not this

  • Do not mark an item done because it is "handled upstream". Accessibility is mandatory on every page and is never delegated to Base UI. Base UI gives you a correct primitive, not a correct component.
  • Do not ship a measured number you typed. Every figure is generated; a hand-typed contrast ratio is wrong the moment a token moves.
  • Do not promote to shipped with a Todo on the page. Todo is counted in the coverage report precisely so that this is visible.
  • Do not skip the empty and stale states because "the product always has data". It does not, at exactly the moment it matters.

Gotchas

  • The enforced items fail at different points. Some at build (PageTemplate, assert-ia), some in CI (check-contrast, the CVD audit), some at lint. A green local build is not the whole list.
  • implements and governedBy are checked in both directions, so adding a component to a doctrine page's list without updating the component page fails.
  • The contrast check covers token pairs, not rendered pixels. A component whose text sits on a translucent material needs the scrim rules too; see The contrast floor.
  • A reviewed date expiring does not fail the build, it appears in the freshness report. That means it is easy to let slide. See Docs freshness.

On this page