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.
renderis supported on every part that renders an element.refis forwarded on every part.classNameis merged withcn(), 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-motionfallback that is observable. reviewedandreviewer: designset 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.
PageTemplatefails the build otherwise. - Enforced: the body is inside the word budget.
assert-iarule LEAN001 fails the build past a thousand words, or twelve hundred and fifty on ahealth-*page. - Enforced: the "when not to use" list names an alternative for every entry.
- Enforced:
governedByis present when the category starts withhealth-, and the named doctrine pages list this component inimplements. - Content guidelines written, with one approved and one rejected phrasing, where the component renders copy the product writes.
- An
Anatomysection 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
revieweddate. - 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
shippedwith aTodoon the page.Todois 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. implementsandgovernedByare 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
revieweddate expiring does not fail the build, it appears in the freshness report. That means it is easy to let slide. See Docs freshness.
Related
- Proposing a component is the stage before this one.
- Anatomy of a component page covers the lean outline and what each status requires.
- Release phases says what each status promises.
- Safety review checklist is the pre-ship check for any screen showing a health value.
Proposing a component
The intake questions a proposal must answer before an API is worth discussing. The four reasons a proposal is normally rejected.
Documentation templates
Twelve page kinds, each with a fixed set of headings the build enforces. The outlines are published verbatim, so a contributor fills in a template.