X-10 · Composites · App components
All elements · Form on the Composites page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve Form
Approving as
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 |
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-span3, 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
-
Give each section a short
.qf-form__section-titleand, where useful, a.qf-form__section-hint. -
Mark required fields (
data-required) visibly and in the control (requiredoraria-required). -
Put each error in the field's helper text and list every error in
.qf-form__errorsat 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.
- 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
| 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 istype="submit"and the others aretype="button". -
Each control has a
<label for>; invalid controls carryaria-invalid="true"andaria-describedbypointing at the helper text. -
The reference marks the second invalid field only with
data-invalidon the Field; the binding must also setaria-invalidandaria-describedbyon its control. -
The error summary is a
.qf-bannerwithrole="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-spanmust 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
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| 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.
Latest updates
No recorded changes yet.