Skip to content

Form

X-10 · Composites · App components

All elements · Form on the Composites page

Last checked 2026-10-22 · Awaiting approval · Accessibility tests

Copies the bun run a11y:approve command for Form.

Form

X-10WCAG 2.2 AA · Passed #454

Form shell: sections with titles, a 12-column row grid, an error summary and a sticky action bar. Field binding and validation come from react-hook-form in the binding.

The specimen below is copied from form.html, which shows it inside the app shell, by bun scripts/design-pages/build-composite-pages.mjs — edit that file, not this one; --check fails when they drift.

Axis Values
.qf-form · __section · __section-title · __section-hint · __row · __actions[data-sticky] · __errors regions
[data-span] 3 · 4 · 6 · 8 · (12) columns; collapses to full width on mobile
Customer form with a validation error
CompanyLegal entity details
Enter a valid email address.
Ownership
Required.
Visible to your team only.0 / 500

Guidance

When to use

  • Use it to create or edit a record with more than a handful of fields, such as a customer with company and ownership details.
  • Use sections with titles and hints when fields fall into groups users recognize.
  • Use the 12-column row grid (data-span 3, 4, 6, 8 or 12) to size fields to their expected content.
  • Use the sticky action bar when the form scrolls and Save must stay in reach.
  • Use the error summary when a submit fails validation on more than one field.

When to consider something else

  • Use ObjectDisplay click-to-edit when users mostly read values and change one at a time. See ObjectDisplay.
  • Use an Overlay for a short form of two or three fields that interrupts the current task. See Overlay.
  • Use InputFieldMapper inside the form when the control depends on each property's FieldType. See InputFieldMapper.
  • Use a Banner outside forms for page-level messages that are not validation errors. See Banner.

Usability

Do
  • Give each section a short .qf-form__section-title and, where useful, a .qf-form__section-hint.
  • Mark required fields (data-required) visibly and in the control (required or aria-required).
  • Put each error in the field's helper text and list every error in .qf-form__errors at the top on submit.
  • Put the primary action last in .qf-form__actions, with Cancel and Save draft before it.
  • Let fields collapse to full width on mobile; do not fix widths.
Don’t
  • Do not validate on every keystroke; validate on blur and on submit.
  • Do not disable the submit button to signal errors; let submit show the summary.
  • Do not use placeholder text as the only label or instruction.
  • Do not put more than one primary action in the action bar.

Accessibility

Keyboard

Form keyboard
Keys Action
Tab Moves through fields in section order, then the action bar buttons.
Enter In a single-line field, submits the form through the submit button; in a textarea, inserts a line break.
Enter On an error summary link, the binding must move focus to that field.

Roles and names

  • The form is a native <form>; the primary action is type="submit" and the others are type="button".
  • Each control has a <label for>; invalid controls carry aria-invalid="true" and aria-describedby pointing at the helper text.
  • The reference marks the second invalid field only with data-invalid on the Field; the binding must also set aria-invalid and aria-describedby on its control.
  • The error summary is a .qf-banner with role="alert"; the binding should list each error as a link to its field.
  • Section titles are divs in the reference; the binding should render each section as a <fieldset> with a <legend>, or as a heading, so the grouping is exposed (1.3.1).

Focus

  • On a failed submit, move focus to the error summary.
  • Focus order follows the visual grid left to right, top to bottom; data-span must not reorder fields.
  • The sticky action bar must not cover the focused field when users Tab near the bottom (2.4.11).

Other requirements

  • Errors must be described in text and say how to fix them (3.3.1, 3.3.3).
  • Required and invalid states must not rely on color or an asterisk alone (1.4.1, 3.3.2).
  • Do not ask again for data already entered in the same process (3.3.7).
  • The 12-column grid collapses to one column on mobile, which supports 1.4.10 Reflow.

Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.

Accessibility tests

WCAG 2.2 AA · Passed

Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.

Form test checklist
Area Automated A person checks
General Passed Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme.
Zoom Passed At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping.
Keyboard Passed Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (3 rows)
Screen reader Passed With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (5 items)

Approving. When the checklist passes on the checked run, record it with bun run a11y:approve -- form --by "Your name" and commit a11y/approvals.json with the rebuilt pages. All test status

Package

Consumers link one stylesheet, css/classic/index.css, which includes every element. The files below are where this element is defined.

Form package
Source css/classic/composites/feedback.css
Specimens also use Banner · Box · Button · Card · Chip · Control · Field · Icon · Select · Table · Text · Toggle · Toolbar
Sprites sprites/icons.svg
React Not yet available: the React binding has not started.

Latest updates

No recorded changes yet.

All release notes