Contractor‑Ready Component Spec: 20 UI Components with Props, States, and Acceptance Tests
Written by AppWispr editorial
Return to blogCONTRACTOR‑READY COMPONENT SPEC: 20 UI COMPONENTS WITH PROPS, STATES, AND ACCEPTANCE TESTS
If you build products, you already know that vague “hand‑off” artifacts cause rework. This post gives founders and product teams a drop‑in catalog of 20 common components — each with exact props, visual states, accessibility notes, and a one‑sentence acceptance test. Included: practical tips and small JSON examples you can export from Figma to hand designers and engineers a truly contractor‑ready spec.
Section 1
How to use this catalog and what “contractor‑ready” means
A contractor‑ready component spec removes ambiguity by listing (1) the precise API/props the component accepts, (2) all visual states and interaction rules, (3) accessibility requirements (role, ARIA, keyboard), and (4) a compact acceptance test that QA or an engineer can run. Use the same structure for every component to avoid repeated design reviews and reduce implementation drift.
This article assumes your team can export component metadata from Figma into JSON (layers, variant names, tokens). Exporting a small JSON payload with names, props, and default values gives engineers a machine‑readable starting point; many Figma plugins and community tools support JSON exports of components and tokens so you can attach real artifact files to tickets.
- Spec content: props, default values, allowed values, states, accessibility notes, one‑line acceptance test
- Deliverables: design file with named variants + JSON export, storybook example URL (if available), acceptance test in ticket
Section 2
The catalog: 20 components (structure and one example)
Each component in the full downloadable catalog (below) follows a strict template: name, props (type + example), visual states, accessibility notes (role, ARIA, keyboard), and a one‑line acceptance test. That structure makes it possible to generate a JSON object a Figma plugin can export and a developer can read into Storybook or a test harness.
Here’s a fully worked example (Button — primary): you’ll find this pattern repeated for 20 components in the catalog: name: Button.Primary; props: label:string ("Save"), size: 'sm'|'md'|'lg', kind: 'primary'|'secondary'|'ghost', loading:boolean, disabled:boolean, iconLeft?:string, iconRight?:string; states: default, hover, pressed, focus, disabled, loading; accessibility: element <button> with accessible name from label or aria-label, support aria-pressed for toggle variants, keyboard focusable (Enter/Space), visible focus indicator; acceptance test: “Label reads 'Save', click triggers onClick once when enabled, visually shows loading state and disables input.”
Repeat that spec for each component type (inputs, selects, toggles, lists, modals, toasts, cards, chips, avatars). The point is exactness: name every prop type and allowed values — not “color” or “size” generically. That makes the JSON deterministic and testable.
- Template fields: name, props (type, default), visual states, accessibility notes, one‑line acceptance test
- Example components included: Button, IconButton, TextField, TextArea, Select, Checkbox, Radio, Toggle/Switch, Avatar, Badge, Chip, Card, Modal, Tooltip, Toast, ListItem, TableRow, Pagination, DatePicker, Progress
Sources used in this section
Section 3
Accessibility: what to specify in every component
For each component, include the programmatic role, required accessible name source (visible label or aria‑label), which ARIA state attributes must change (for example aria-checked, aria-pressed, aria-expanded), and keyboard behavior (tab order, activation keys). These are not optional notes — they belong in the spec so a contractor cannot omit them.
Reference WCAG/WAI‑ARIA guidance when specifying attributes. For example, toggle buttons should expose aria-pressed or role='switch' with aria-checked, and interactive elements must be reachable by keyboard and announce state changes. A single sentence in the acceptance test should verify the correct ARIA attribute update after user interaction.
- Always list: role, accessible name source, ARIA attributes changed on interaction, keyboard keys to support (Enter/Space/Escape), required focus style contrast
- Keep acceptance tests simple: verify visible state + programmatic state (e.g., aria-checked === 'true')
Section 4
Exportable JSON: minimal shapes designers can drop into Figma or hand to engineers
Practical JSON shape: keep it flat and predictable. Example minimal payload for a Button variant: { "component": "Button.Primary", "props": { "label": "Save", "size": "md", "kind": "primary", "loading": false, "disabled": false }, "states": ["default","hover","pressed","focus","disabled","loading"], "accessibility": { "role": "button", "nameSource": "label", "aria": {} }, "acceptanceTest": "Click triggers onClick once when enabled and loading shows spinner" }.
Generate this JSON from Figma using available community plugins or small scripts that read variant names, text layers, and token references. Embedding this JSON into tickets or the design file ensures the contractor receives both a visual and a machine‑readable contract for behavior.
- Keep each component JSON under 1KB when possible — it should be human readable in PRs and tickets
- Use consistent keys across components (component, props, states, accessibility, acceptanceTest) so parsers and Storybook generators can be trivial
Sources used in this section
Section 5
Practical handoff checklist and acceptance test examples
Before assigning a contractor, attach three artifacts to the ticket: (1) Figma file with named component variants and text layers, (2) exported JSON artifact per component, (3) one‑line acceptance tests that QA or the contractor can run locally. Use your ticket template to require a passing screenshot or Storybook link.
Examples of one‑line acceptance tests (you should include many of these verbatim): Button.Primary — “With label 'Save' enabled, a click calls onClick once and button shows loading spinner and becomes disabled.” Toggle/Switch — “Pressing space toggles aria-checked between 'true' and 'false' and the visible thumb moves to the correct side.” Modal — “Opening the modal traps focus inside, pressing Escape closes it, and aria-hidden is set on the background.”
- Ticket attachments required: visual variants, exported JSON, acceptance test(s), reference Storybook or test page if available
- QA step: verify visible state and programmatic state (use devtools to check ARIA) for at least one critical path per component
Sources used in this section
FAQ
Common follow-up questions
Can I generate the JSON spec automatically from Figma?
Yes — several Figma community plugins and open source tools export component metadata, tokens, and variant names as JSON. Use a consistent naming convention for variants and layer names so the export maps directly to the JSON fields in your spec.
How detailed should acceptance tests be?
Keep each acceptance test to one clear behavior that’s easy to run manually or script: state before, interaction, expected visual result, and expected programmatic state (for accessibility). For complex components add a couple of edge‑case lines.
What accessibility checks must I include for contractors?
At minimum include role, accessible name source, ARIA attributes changed on interaction, keyboard activation keys, and whether focus must be visibly distinct. Tests should verify both visible and programmatic state changes (e.g., aria-checked, aria-expanded).
Should this be used for web and mobile?
Yes. The same structure works for both; mobile specs must emphasize touch targets, hit areas, and platform conventions (e.g., native accessibility roles). Include pixel or dp sizes for touch targets in the props for mobile components.
Sources
Research used in this article
Each generated article keeps its own linked source list so the underlying reporting is visible and easy to verify.
Handoff
Figma Schema Exportables | Handoff Design System
https://www.handoff.com/docs/customization/exportables/
Referenced source
Figma to JSON - Plugin
https://www.figma2json.com/plugin
W3C
ARIA5: Using WAI-ARIA state and property attributes to expose the state of a user interface component
https://www.w3.org/WAI/WCAG20/Techniques/aria/ARIA5
MDN
ARIA attributes - MDN Web Docs
https://developer.mozilla.org/docs/Web/Accessibility/ARIA/Attributes
WebAIM
WCAG 2 Checklist (WebAIM)
https://webaim.org/standards/wcag/WCAG2Checklist.pdf
Figma Elements
Free JSON Exporter Figma Plugin | Figma Elements
https://figmaelements.com/plugins/json-exporter/
Next step
Turn the idea into a build-ready plan.
AppWispr takes the research and packages it into a product brief, mockups, screenshots, and launch copy you can use right away.