sc1m/design
ComponentsField

Field

Field component built on Base UI, styled with sc1m tokens.

StableBase UI

Live preview

We'll never share your email.

Installation

pnpm dlx shadcn@latest add @sc1m/field

This also merges the token layer and installs src/lib/cn.ts plus @base-ui/react. For the manual route — prerequisites, components.json, and app-level setup — see Installation.

Usage

import {
  Field,
  FieldLabel,
  FieldDescription,
  FieldError,
  FieldControl,
} from "@/components/ui/field";

Composition

Every part is a separate export. Field owns state; the rest are presentational and must appear in this order.

Field├── FieldLabel├── FieldControl└── FieldDescription

Example

The preview above, with its source. This is the demo module verbatim, so the code and the thing it renders cannot drift apart.

We'll never share your email.

<Field name="email">
  <FieldLabel>Email</FieldLabel>
  <FieldControl type="email" placeholder="you@example.com" />
  <FieldDescription>We&apos;ll never share your email.</FieldDescription>
</Field>

API reference

Each part forwards every prop of its Base UI counterpart; the tables list the ones declared on the part itself. See Base UI's reference for the inherited element props.

Field

PropTypeDefaultDescription
disabledbooleanfalseWhether the component should ignore user interaction.
namestringIdentifies the field when a form is submitted.
validate((value: unknown, formValues: Form.Values) => string | string[] | null | Promise<string | string[] | null>)A function for custom validation.
validationModeForm.ValidationMode'onSubmit'Determines when the field should be validated.
validationDebounceTimenumber0How long to wait between validate callbacks if validationMode="onChange" is used.
invalidbooleanWhether the field is invalid.
dirtybooleanWhether the field's value has been changed from its initial value.
touchedbooleanWhether the field has been touched.
actionsRefReact.RefObject<FieldRoot.Actions | null>A ref to imperative actions.

FieldLabel

PropTypeDefaultDescription
nativeLabelbooleantrueWhether the component renders a native <label> element when replacing it via the render prop.

FieldError

PropTypeDefaultDescription
matchboolean | keyof ValidityStateDetermines whether to show the error message according to the field's [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState).

FieldControl

PropTypeDefaultDescription
onValueChange((value: string, eventDetails: FieldControl.ChangeEventDetails) => void)Callback fired when the value changes.
defaultValueReact.ComponentProps<'input'>['defaultValue']

Accessibility

Behaviour, focus management, and ARIA wiring come from Base UI's Field — see its reference for the full keyboard map.

  • Disabled parts mute their contents rather than the element, keeping the focus ring at full strength where the part stays focusable.

Design tokens

The component reads semantic tokens only — no raw colour, radius, or duration appears in its source. Override the token, not the component.

TokenApplied to
--brand-radius-mdFieldControl
--dangerFieldError
--fgFieldLabel, FieldControl
--fg-subtleFieldDescription, FieldControl
--lineFieldControl
--ringFieldControl
--surfaceFieldControl
--surface-raisedFieldControl

Source

src/components/ui/field/field.tsx — no next/* imports, so it drops into any React 19 + Tailwind v4 app.