Skip to the content
BooleanPress UI

Form

Field

Lays out a control with its label, description and error, and groups fields into sets.

Import

import { Field, FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSeparator, FieldSet, FieldContent, FieldTitle } from "@booleanpress/ui/field"

Usage

Field wraps one control. Put FieldLabel, the control, FieldDescription and FieldError inside it. Group several fields with FieldGroup, and wrap a related set in FieldSet with a FieldLegend.

import { Field, FieldDescription, FieldError, FieldLabel } from "@booleanpress/ui/field"
import { Input } from "@booleanpress/ui/input"

export function Port() {
  return (
    <Field data-invalid="true">
      <FieldLabel htmlFor="port">Port</FieldLabel>
      <Input id="port" aria-invalid aria-describedby="port-help port-error" />
      <FieldDescription id="port-help">Usually 587.</FieldDescription>
      <FieldError id="port-error">Use a port between 1 and 65535.</FieldError>
    </Field>
  )
}

Field only lays out and styles: it does not connect anything. You set htmlFor/id, aria-invalid and aria-describedby yourself. data-invalid="true" turns the label and text destructive; data-disabled="true" dims the label and description. orientation is vertical (default), horizontal or responsive (horizontal once the FieldGroup is 28 rem wide). FieldError takes children, or errors, an array of { message } that it de-duplicates (one message as text, several as a list). FieldContent stacks a label and description beside a checkbox or switch; FieldTitle is label-styled text that is not a label; FieldSeparator draws a rule, with optional text.

Examples

Basic

A label, an input and a description, tied together with htmlFor and aria-describedby.

Error

data-invalid colours the field; FieldError is announced as an alert and read with the name.

Horizontal

A checkbox beside its label and description, aligned with FieldContent.

Group and set

FieldSet and FieldLegend name the group; FieldGroup spaces the fields; FieldSeparator divides them.

Disabled

data-disabled dims the label and the description; disabled on the control stops input.

Accessibility

Semantics
Field is a div with role="group"; FieldSet is a fieldset and FieldLegend a legend, so a set is named by its legend. FieldError has role="alert", so it is announced when it appears.
Labels
Name each control with FieldLabel htmlFor. Give an error and a description an id and list them in the control's aria-describedby. Name a set with FieldLegend.
Focus
Nothing in a field takes focus except the control. The label forwards a click to it.
Known limits
  • A Field's role="group" has no name of its own; only a FieldSet takes its name from the legend.
  • data-invalid and data-disabled change colour only. Set aria-invalid and disabled on the control.

Keyboard

Keyboard
KeyBehaviour

API

Field

Renders a div and passes it every other prop.

FieldLabel

FieldLabel props
PropTypeDefaultDescription
asChildboolean

FieldDescription

Renders a p and passes it every other prop.

FieldError

Renders a div and passes it every other prop.

FieldError props
PropTypeDefaultDescription
errors({ message?: string; })[] | undefined

FieldGroup

Renders a div and passes it every other prop.

FieldLegend

Renders a legend and passes it every other prop.

FieldLegend props
PropTypeDefaultDescription
variant"label" | "legend"legendlegend is the larger group title; label is the size of a field label.

FieldSeparator

Renders a div and passes it every other prop.

FieldSet

Renders a fieldset and passes it every other prop.

FieldContent

Renders a div and passes it every other prop.

FieldTitle

Renders a div and passes it every other prop.

Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.

Data attributes: data-slot="field" (Field), data-slot="field-label" (FieldLabel), data-slot="field-description" (FieldDescription), data-slot="field-error" (FieldError), data-slot="field-group" (FieldGroup), data-slot="field-legend" (FieldLegend), data-slot="field-separator" (FieldSeparator), data-slot="field-set" (FieldSet), data-slot="field-content" (FieldContent), data-slot="field-label" (FieldTitle), and data-variant, data-orientation, data-content.

Theming

The tokens its classes read. Change their values in your theme, and it follows.

Theme tokens
TokenUsed for
--backgroundbackground
--destructivetext
--muted-foregroundtext
--primaryborder, background, text