-
Notifications
You must be signed in to change notification settings - Fork 0
Forms
For package-based application forms, start with Vue integration, Themed controls and Package and copy. This page explains the broader validation/recovery and bounded form-builder patterns.
What the theme specifies about validation, error recovery and form composition — and the two local tools that demonstrate it. For anyone building a form, and anyone reviewing one.
Contents: The recovery contract · Implementing it · Try it · The form builder · Definitions · Limits
The validation and recovery pattern composes admin-form, text-field, textarea, select, checkbox, alert, button and table into one workflow. It is a reference composition under the proposed decision D-020 — the existing component rules stay normative — and it follows the GOV.UK validation pattern for submit-time feedback.
The rules it demonstrates:
- Validate on submit, not on every keystroke. Editing does not announce a new error per character, and it does not silently delete the last submitted error summary either.
- Show every error together, in a focused summary, with links to the affected fields. Focus moves to the summary so a keyboard user finds the problem without hunting.
- Preserve every entered value through validation — including the notes and choices that were not the problem. Losing a long textarea because a hostname was wrong is the failure this contract exists to prevent.
- Offer an explicit return to editing from the review step.
- Busy is not success. Confirming the review enters a busy state with the controls disabled and an explicit pending message. A separate completion produces the success state. A submit click alone is never success.
- Busy, disabled, invalid and success keep distinct meanings, visually and semantically. Do not express one with the styling of another.
- Reset clears in-memory values and errors — and there is nothing to recover afterwards, because nothing was stored.
The states, roles and messages come from the component contracts — text-field, textarea, select, checkbox, alert — not from this page. Read Components for how to pull them.
The parts a form has to get right on top of those:
| Concern | Requirement |
|---|---|
| Label association | Canonical label/for, aria-describedby chaining help text and the error message, required markers exposed to assistive technology as well as visually |
| Group semantics | Radio groups are a fieldset with a legend
|
| Error summary | Receives focus on submit; each entry links to a stable field control ID |
| Stable IDs | Survive reordering and round trips, so links and ARIA references do not break |
| Invalid appearance | 2px border in color.status.danger.border, and the focus ring moves to the −4px offset so it stays visible inside that border |
| Status channel | Status colour is never the only channel — glyph, underline pattern or border style carries it too |
| Imported strings | Treated as text, never markup |
Ten minutes on the validation and recovery page, under Try the local workflow. Nothing leaves your browser; "save" creates no record.
- Enter
ws-07as both Name and Hostname, choose a Role, and type something into Notes. The example deliberately reservesws-07so there is a real error to recover from — it is a named local fixture, not a server uniqueness check. - Select Review values. You should get an error summary with links to Name and Hostname, focus moved to it, and your notes and choices untouched.
- Follow each error link and correct both values to
ws-08. Hostnames here are lowercase letters, digits and single hyphens between segments. - Review values again, read the review table, then use Edit values if you want to change something.
- Simulate save — note the busy message and the disabled controls — then Complete simulation for the success message.
The same page keeps static normal, invalid, busy and success examples that stay readable without JavaScript. Those show the states; the exercise shows the journey between them.
The form builder composes canonical fields into a small form so you can see and share a layout. It is a draft reference tool: no account, no backend, no autosave.
Add a field, give it a label and help text, mark it required if it needs to be, and save the definition. Text, textarea, select, checkbox and radio are supported. Choice fields take their options as JSON:
[
{ "id": "email", "label": "Email" },
{ "id": "phone", "label": "Phone" }
]The id is the stable identity and the label is what a person reads. When you reword a choice later, keep the id and change the label — that is what keeps a definition comparable across revisions.
Reorder with Move up / Move down (no drag operation is required, and focus stays on the moved field's controls), switch Preview density between compact and comfortable, then exercise the preview the same way as the pattern above: leave a required field empty, submit, follow an error link, correct, review.
Changing the definition clears the preview's answers and errors. That is deliberate — finish the design before typing a long set of sample answers.
Transfer definition shows the JSON and downloads it as theme-form.json. The definition contains the field design and no entered values; preview answers never enter a download and are never persisted.
To reopen one, paste the whole file into Definition JSON and import. The import validates atomically — it either replaces the definition or leaves the current one entirely alone.
| Limit | Value |
|---|---|
| Definition size | 64 KiB |
| Fields | 20 |
| Options per choice field | 20 |
| Label length | 120 characters |
| Help text length | 400 characters |
| Preview text | 2000 characters |
Rejected outright: unknown keys, duplicate IDs, unsupported field kinds, invalid choices, and a mismatched theme identity. Definition schema version 1 pins the theme name, version, default profile and the constituent components' content digest — which is why a definition made against an older build may need a deliberate migration. Do not delete the identity fields to force an import; that discards the only record of what the definition was designed against.
Everything on both pages stays in memory. Only an explicit download creates a file. There is no autosave, no network submission, no schema execution, and no imported validation expression — and no arbitrary HTML, CSS or JavaScript is accepted from a definition.
What these tools are not: a production backend, a conditional-logic engine, a drag-only editor, a code generator, a persistent account form, or a native application port.
Automated protocols cover keyboard submission, summary navigation, correction, value preservation, review, busy and success, plus narrow layout and no-JS content. As everywhere in this project, a test existing is not a test passing — read the verification report for actual runs. No manual screen-reader pass is claimed.
Sources: spec/form-patterns.md and spec/components/form-builder.md at v1.1.0.
Next: Components · Accessibility · Web integration
Wiki home · Agent workflow · Portal · Vue demo · v1.1.0 release
This handbook explains consumption of v1.1.0. The pinned repository's tokens, specification, implementation contracts and evidence remain authoritative. The live site may advance; keep your application's pin explicit. Preserve the material's license notices.