GitHub

Form section

A titled group of esa-form-field-wrapped controls that ends in an action row — the unit intake forms, settings panels, and dialog bodies are assembled from.

When to use: Any screen that collects more than a couple of values — intake forms, settings panels, dialog bodies. One section per topic; stack sections to build a full form.

Default

A project-details section from an environmental review intake. Each control sits in an esa-form-field wrapper, which owns the label, required asterisk, and help text — the controls themselves render chrome-free. Short, related fields (lead agency / county) pair on one row; everything else runs single column. The action row closes the section: primary submit first, ghost cancel beside it.

Project details

Tell us about the project under review. Fields marked * are required.

As it appears on the notice of preparation.

Summarize the location, scope, and anticipated construction activity.

Validation state

The same section after a failed submit: the name is missing and no pathway is selected. Errors attach at the lowest level that can render them. Self-chromed controls (esa-text-field, esa-select, esa-textarea) take error-text — one attribute turns the border red, sets aria-invalid, and renders the message in place of help text. Option groups have no error prop, so an esa-field-error line goes directly after the control, inside the same wrapper.

Project details

Tell us about the project under review. Fields marked * are required.

Summarize the location, scope, and anticipated construction activity.

Composition notes

  • Every control gets an esa-form-field wrapper, and the wrapper owns the field chrome — label, required asterisk, help text. Leave the control's own label / help-text attributes unset so the field isn't labeled twice.
  • Error messages live in components, never ad-hoc styled spans: error-text on controls with built-in chrome, an esa-field-error directly after controls without one (radio and checkbox groups). The error replaces the field's help text — don't stack both.
  • The action row belongs to the section, not to any field: primary action first, ghost cancel second, left-aligned on the same axis as the labels, separated from the fields by a divider.
  • Single column by default. Only pair short, related fields on one row, and collapse the pair on narrow viewports. Controls run full width — the section's max-width sets the measure, not the individual control.
  • One size across the section: everything defaults to md on the shared scale, so inputs, selects, and buttons share heights and line up when they meet on a row.