Forms

Forms should feel consistent regardless of who built them. These are the decisions that come up most often.

Layout

The default is a single column, labels above their inputs, following the Form component's header / content / footer structure. Cap content width at 480–560 px so no line runs too long.

Side panel = preview. Educational and reference content goes in the header description and a link.

Required markers

Mark required fields with Required to the right of the label, the same way in every form. Don't mark optional fields — no marker means optional.

Today only Storage and Monitor show it and Chart leaves it out, so the rule reads differently from form to form. That inconsistency is the thing to fix, not a precedent to follow.

Choosing the control

Use the same control for the same job. Let the decision the reader is making drive the choice — how many options, and when the change takes effect.

ControlUse whenExample in product
Radio groupOne choice from 2–5 mutually exclusive options, all worth showing at onceDraw NULL as 0 / Draw NULL as NULL
Select (single)One choice from a longer or predefined list, or when the value drives other content on the pageGraph display, Data format
Select (multiple)Several values from a predefined list, stored as one fieldEnvironments, tags
ComboboxA select with a search field, for a long or data-driven listApps, members, namespaces
Checkbox (multiple)Several independent on/off optionsNotify me through: Email, Slack
Checkbox (single)A single on/off setting submitted with the formCompress exports, Start Y-axis at 0
ToggleAn on/off setting that applies instantly, no submitEnable a feature in settings
MenuActions or navigation — not form dataRow actions (⋯), contextual menus

The short version: mutually exclusive → radio (few) or select (many). Long or data-driven list → combobox. Independent on/off → checkbox. Instant on/off → toggle. Actions → menu.

Field help

Before adding supporting text, ask whether someone can complete the field correctly without it. Then pick the weakest mechanism that works.

  1. Can't be filled correctly without it (format, constraints, result) → an explanation, below the label or input, always visible. "Lowercase, numbers, _ and - only". "Stored encrypted." This is the default.
  2. Nice to know, field works without it → a tooltip on a single (i) icon next to the label. Never hide required guidance here. Standardise on (i); drop (?).
  3. Needs context or a warning at form or group level → the header description (1–2 sentences) or a Message: beta notices, destructive-action warnings. Trim long explanations to one line plus Learn more.
  4. Needs an example of the value → a placeholder, prefixed e.g. so it isn't mistaken for a real value: e.g. background_job. Never a placeholder in place of a label or required guidance.

Previews

Add a preview panel only when both are true:

Don't add one where the result is text or config (storage credentials, a monitor identifier). Keep the preview sticky, with any controls it needs such as a time range. When it has nothing to show, use the empty state pattern.

Dividers and grouping

Group the fields by meaning first, then decide how to separate the groups.

SituationHow to separate
4 fields or fewer, one groupSpacing only. No divider, no label
5+ fields and 2+ distinct groupsDivider + section label
The group's purpose changesDivider + section label
A group has more than 6 fieldsConsider splitting it

⚠️ Don't over-segment. A divider signals "the purpose changes here". With one group, leave it out.

Input sizing

Input width predicts how long the value should be. Don't put a short value — a number plus a unit — in a full-width input. Narrow it to match, and keep the unit beside the input.