Form page pattern
patterns specs/patterns/form-page.kmd
A single editing surface with section-grouped fields and a sticky save/discard bar that appears when the form is dirty — the edit-a-record / settings page (as opposed to a step-by-step wizard). An unsaved-changes guard and a validation summary keep edits safe. Modeled after Polaris (Page + Form + ContextualSaveBar). Used by settings, record edit, and admin detail-edit surfaces.
When this pattern applies
Primary triggers
- Design a section-grouped edit/settings form page
All triggers
- Build a settings or record-edit page with many fields
- Add a sticky save bar that appears on unsaved changes
- Group a long form into sections on one page
Specification body
Pattern — Form page
Status: v0.1.0 — Draft. Promoted from the Shopify Polaris parity scan (meta/docs/stack #091). Source: https://polaris.shopify.com/patterns (Page + ContextualSaveBar).
R1 — When to use (vs wizard / inline edit / one-thing)
- Form page (this): the user edits many related fields of one record on one page, saving as a unit (settings, profile, product edit).
- Wizard (
specs/patterns/wizard-multistep.kmd): a sequential first-time flow with per-step gates. - Inline edit (
specs/patterns/inline-edit.kmd): change one value in place without a save bar. - One-thing-per-page governs the granularity within a step, not this all-at-once editing surface.
R2 — Section grouping
Fields are grouped into titled sections (each an <h2> + optional
description) that chunk a long form into scannable units. Sections are
visual grouping, not separate submits — the page saves as a whole (R3).
R3 — Sticky save bar (dirty-driven)
- The form starts clean; a save/discard bar appears only when the form becomes dirty (a value changed), and pins to the top or bottom so it is always reachable while scrolling.
- It holds a primary Save and a secondary Discard; Save is disabled while invalid (R5) and shows a pending state while saving.
- Discard reverts all fields to the last-saved state (with a confirm if changes are substantial).
R4 — Unsaved-changes guard
Navigating away (back, link, close, route change) while dirty prompts a
confirm ("You have unsaved changes") — never lose edits silently. Pairs
with specs/navigation/back-behavior.kmd. A successful Save clears the
dirty state and the guard.
R5 — Validation
- Validate on Save (and optionally on blur per field). On failure, show a
validation summary that links to the first offending field (the
GOV.UK/koder_web_kit error-summary), plus inline messages per
specs/errors/user-facing-messages.kmd. - Focus moves to the summary / first error on a failed save.
R6 — Accessibility & i18n
- Sections use real headings; each field has an associated label; the save bar is keyboard-reachable and its state (disabled/pending) is announced.
- The dirty→save-bar appearance is announced politely (not a focus steal).
- All chrome (Save/Discard, section titles, the unsaved-changes prompt) is
translatable per
specs/i18n/contract.kmd.
Não-escopo
- Step-by-step flows (
specs/patterns/wizard-multistep.kmd). - Single-value editing (
specs/patterns/inline-edit.kmd). - Individual field components (text field, money input, selects).
- Autosave-without-a-save-bar surfaces (a different model).
References
specs/patterns/one-thing-per-page.kmdspecs/patterns/inline-edit.kmdspecs/errors/user-facing-messages.kmdspecs/navigation/back-behavior.kmdspecs/i18n/contract.kmd