Forms overview

A complete set of form controls — text inputs, selects, checks, switches, and ranges — plus the small scaffolding pieces (FormLabel, FormText, FormGroup) and a self-contained grid for laying them out. Every control is themeable through the standard —bs-* form tokens.

Import

Each control and helper is a named export:

tsx
import {
FormControl,
FormSelect,
FormCheck,
FormRange,
FormLabel,
FormText,
FormGroup,
FormRow,
FormCol,
ColFormLabel,
} from '@metatoy/bootstrap-styled';

Building blocks

FormGroup is a vertical-spacing wrapper (≈ a 1rem bottom margin). FormLabel and FormText carry no color or weight of their own — they inherit the surrounding type, so they adapt to light and dark mode automatically. Wire each label to its control with htmlFor / id.

Layout

Forms stack vertically by default. For a horizontal form, drop the control into the built-in 12-column grid: FormRow + FormCol, with ColFormLabel as a column-aligned label. The grid is self-contained — it needs nothing beyond these three parts.

FormRow exposes gx / gy gutters (0–5) and an align prop; FormCol takes a base span and an sm span for the ≥576px breakpoint. ColFormLabel has a size (sm / lg) that matches its paired control’s padding.

Sizing

Text inputs and selects share a size prop — sm or lg — that scales padding, font-size, and height together. See Form control and Select for live size demos.

Disabled & readonly

Every control accepts the native disabled and readOnly attributes. disabled dims the control and blocks interaction; readOnly keeps the default styling but prevents edits. FormControl also has a plaintext prop that renders a borderless, read-only display value — useful for review screens.

A composed form

Putting the pieces together — groups, labels, help text, a select, and a check:

Props

The scaffolding parts (FormLabel, FormText, FormGroup) are thin styled elements that accept all native attributes for their tag (<label>, <small>, <div>). The layout parts carry the grid props documented above:

PropTypeDefaultDescription
gxGutterScale`.gx-*` — horizontal gutter between columns (0–5). Default 3 (1.5rem).
gyGutterScale`.gy-*` — vertical gutter between wrapped rows (0–5). Default 0.
align"center" | "start" | "end" | "baseline" | "stretch"Cross-axis alignment — `center` gives a classic horizontal form.
PropTypeDefaultDescription
spanColSpan | 'auto' | trueColumn span at the base breakpoint: 1–12, `'auto'`, or `true` (equal-width).
smColSpan | 'auto'Column span at ≥576px (the usual horizontal-form breakpoint).
PropTypeDefaultDescription
size"sm" | "lg"Match the paired control's size so vertical padding lines the label up.
smColSpan | 'auto'Column span at ≥576px, e.g. `sm={2}` → `col-sm-2 col-form-label`.

Theming

Form controls read a shared set of --bs-* tokens, so overriding them — via a theme or a scoped inline style — reshades every control inside the scope without touching the components. The common ones:

  • --bs-body-bg, --bs-body-color — control fill and text.
  • --bs-border-color, --bs-border-width, --bs-border-radius — borders.
  • --bs-primary / --bs-primary-rgb — focus ring, checked checks, range track.
  • --bs-secondary-color — help-text (FormText) color.
  • --bs-form-valid-border-color, --bs-form-invalid-border-color — validation.

Because the tokens cascade, you can re-skin a subtree by setting them on a plain wrapper — no extra provider required:

Accessibility

Always pair a control with a label. Use FormLabel with htmlFor pointing at the control’s id (FormCheck wires its own label via its label + id props). When a control has help or error text, reference it with aria-describedby so assistive tech announces it. Validation colors alone don’t convey state — always include a text message (see Form control validation).

Explore in Ladle

Browse the form layout stories in the interactive component gallery: Open in Ladle.