Fieldcomponent

Field({ title, description, message, half, children }: FieldProps): ReactElement
ParamType
propsFieldProps
Props for Field, a labelled wrapper around a form control. required
    .titleReactNode
    .descriptionReactNode
    .messageReactNode
    .requiredboolean
    .halfboolean
Render at half width (50%) so two fields sit side-by-side; defaults to full width (one per row).
Return
ReactElement

A <Field> wraps around a form control/input, to shows a small <label> above it.

The visual wrapper for a single form control. Field renders a <label> with an optional title and description above the input, and an inline error message below it. Use it when composing inputs by hand rather than relying on the automatic fields rendered by <Form>.

Things to know:

  • Full width by default (one field per row). Pass half to render at 50% so two fields sit side-by-side.
  • The message prop renders below the input as an error <Message> — wire it to the field's error string.
  • <FormInput> combines a field's value, error, and schema lookup from the surrounding FormContext; reach for Field directly when you want explicit control over the label and layout.

Usage

Standalone field

tsx
import { Field, TextInput } from "shelving/ui";

<Field title="Email address" message={emailError}>
  <TextInput name="email" value={email} onValue={setEmail} required />
</Field>

Two-up layout

tsx
import { Field, TextInput } from "shelving/ui";

<Field title="First name" half>
  <TextInput name="first" value={first} onValue={setFirst} />
</Field>
<Field title="Last name" half>
  <TextInput name="last" value={last} onValue={setLast} />
</Field>

Styling

Field paints its label, description, and message text. Override these hooks at :root or any ancestor scope.

VariableStylesDefault
--field-spaceOuter block margin (top + bottom)var(--space-paragraph) (16px)
--field-gapGap between label, control, and messagevar(--space-xsmall)
--field-title-sizeTitle font sizevar(--size-normal)
--field-title-weightTitle font weightvar(--weight-strong)
--field-color-titleTitle colourvar(--tint-00)
--field-description-sizeDescription font sizevar(--size-normal)
--field-description-weightDescription font weightvar(--weight-normal)
--field-color-descriptionDescription colourvar(--shade-dark)
--field-message-weightMessage font weightvar(--weight-strong)
--field-color-messageMessage colourvar(--color-red)

Global tokens it reads: the tint ladder --tint-00, plus --space-paragraph, --space-xsmall, --size-normal, --weight-strong, --weight-normal, --shade-dark, and --color-red.