Skip to content

Pattern

Form layout

A single-column form in grouped sections, with paired short fields side by side on wider screens and actions at the end.

.b-wrapper[data-max="sm"].b-region.b-flow.b-layout-grid.b-repel.b-cluster

Use for create/edit screens. Keep one column; pair fields only when they’re short and belong together (city + postal code). Put the primary action last, on the right, and never disable it silently — show what’s missing instead.

Preview

Acuity Brands Lighting

Each kit renders in its own frame and follows the theme and density set in the header. Open full-size ↗

HTML

Layout uses Beam compositions and utilities only. Buttons, inputs, toggles, badges and tables here are stand-ins so the preview renders — in product, use the Cantina components below.

<div class="[ b-wrapper b-region b-flow ]" data-max="sm" data-space="lg">
  <header class="[ b-flow ]" data-space="xs">
    <h1>New site</h1>
    <p class="[ u-text-neutral-secondary ]">Add a building so you can assign devices to it.</p>
  </header>
  <form class="[ b-flow ]" data-space="xl">
    <fieldset class="[ b-flow ] [ b-formsection ]" data-space="sm">
      <legend class="[ u-type-h5 ]">Details</legend>
      <label class="[ b-field ]"><span class="[ u-type-label ]">Site name</span><input class="[ b-input ]" type="text" value="Atlanta HQ"></label>
      <div class="[ b-layout-grid ]" data-gap="sm">
        <label class="[ b-field ]" data-span="6"><span class="[ u-type-label ]">City</span><input class="[ b-input ]" type="text"></label>
        <label class="[ b-field ]" data-span="6"><span class="[ u-type-label ]">Postal code</span><input class="[ b-input ]" type="text"></label>
      </div>
      <label class="[ b-field ]"><span class="[ u-type-label ]">Time zone</span>
        <select class="[ b-input ]"><option>America/New_York</option><option>America/Chicago</option></select>
        <span class="[ u-type-body-sm u-text-neutral-tertiary ]">Schedules run in this time zone.</span>
      </label>
    </fieldset>
    <fieldset class="[ b-flow ] [ b-formsection ]" data-space="sm">
      <legend class="[ u-type-h5 ]">Notifications</legend>
      <label class="[ b-cluster ]" data-gap="sm"><input type="checkbox" checked> <span>Email me when a device goes offline</span></label>
      <label class="[ b-field ]"><span class="[ u-type-label ]">Contact email</span><input class="[ b-input ]" type="email" aria-invalid="true" value="ops@"><span class="[ u-type-body-sm u-text-error ]">Enter a full email address.</span></label>
    </fieldset>
    <div class="[ b-repel ]">
      <span></span>
      <div class="[ b-cluster ]" data-gap="sm">
        <button class="[ b-button ]" data-variant="outline" type="button">Cancel</button>
        <button class="[ b-button ]" data-variant="solid" type="submit">Create site</button>
      </div>
    </div>
  </form>
</div>

Cantina components

  • form-section
  • labeled-input
  • labeled-dropdown
  • checkbox
  • button

Open Cantina ↗

Recipe

The rules an agent follows to build this pattern. This is what goes into beam.skill.

  1. Width: .b-wrapper[data-max="sm"] — forms should not stretch to the page width.
  2. Group related fields in sections (Cantina <FormSection> or <fieldset class="[ b-flow ]">) with a heading and optional description.
  3. Fields stack with .b-flow[data-space="sm"]; pair short related fields with .b-layout-grid[data-cols="12"] and data-span="6" (full width below md).
  4. Label above input, helper text below in type-body-sm text-neutral-tertiary; errors use text-error and ring-error on the input.
  5. Actions: .b-repel at the end — secondary (Cancel) left of primary (Save) inside a .b-cluster on the right.
beam.skill recipe (Markdown)
## Pattern: Form layout
A single-column form in grouped sections, with paired short fields side by side on wider screens and actions at the end.

Compositions: .b-wrapper[data-max="sm"], .b-region, .b-flow, .b-layout-grid, .b-repel, .b-cluster
Cantina: form-section, labeled-input, labeled-dropdown, checkbox, button

1. Width: .b-wrapper[data-max="sm"] — forms should not stretch to the page width.
2. Group related fields in sections (Cantina <FormSection> or <fieldset class="[ b-flow ]">) with a heading and optional description.
3. Fields stack with .b-flow[data-space="sm"]; pair short related fields with .b-layout-grid[data-cols="12"] and data-span="6" (full width below md).
4. Label above input, helper text below in type-body-sm text-neutral-tertiary; errors use text-error and ring-error on the input.
5. Actions: .b-repel at the end — secondary (Cancel) left of primary (Save) inside a .b-cluster on the right.