Skip to main content

Form

Form state and validation wired to the fields.

In Accessible first

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

In Accessible first: Every form that checks answers, with the error next to the field. Not errors shown by color alone.

  • Use it when: Any form that checks answers and shows errors next to the fields.
  • Not when: A single control that saves at once (a switch).

Instead:

  • Field: How one control is laid out.

How Accessible first uses it​

An error message
Use color.status.danger, an icon and a sentence next to the field
Not Color alone
People must know what went wrong and where.
The words of an error
Use Say what is wrong, where, and exactly how to fix it
Not "Invalid input"
People must be able to fix the error without help. Example: “Enter your date of birth. For example, 27 3 1980.”

Words​

  • Use common words. Explain any term you must use.
  • One idea per sentence. Put the action first.
  • Never blame the person.
  • Use: Continue, Change, Start, You. Avoid: Invalid, Utilise, Submit, Error code.

The labels components use, from the voice tokens:

  • content.action.commit: Continue
  • content.action.cancel: Go back
  • content.action.destroy: Delete
  • content.action.retry: Try again
  • content.action.empty-action: Start a new application

See Voice and tone for the whole voice.

Accessibility and keyboard​

Test before you ship:

  • Errors are announced, linked to their fields, and the first one gets focus on submit. undefined

Use it in code​

npx open-ds add form

The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.

Tokens it reads​

Form reads 6 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Form's tokens to change Form alone.

Changes with theme

Accessible first decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.

PartIts token and the semantic it aliasesValue
Item
Gapcomponent.form.item.gapspace.gap.defaultvar(--form-item-gap)space.16:1rem
Text
Text
Changes with theme
component.form.label.labelcolor.status.dangervar(--form-label-label)Lightred.light.600:#C42B2BDarkred.dark.600:#F28B8B
Description
Text sizecomponent.form.description.font-sizetype.body.font-sizevar(--form-description-font-size)font.size.19:1.1875rem
Text
Changes with theme
component.form.description.labelcolor.text.mutedvar(--form-description-label)Lightgray.light.500:#595959Darkgray.dark.500:#949494
Message
Text sizecomponent.form.message.font-sizetype.body.font-sizevar(--form-message-font-size)font.size.19:1.1875rem
Text
Changes with theme
component.form.message.labelcolor.status.dangervar(--form-message-label)Lightred.light.600:#C42B2BDarkred.dark.600:#F28B8B