Field
Form-field wrapper combining label + control + description + error. Mirrors shadcn Field (the modern replacement for Form).
Purpose
Form-field wrapper combining label + control + description + error. Mirrors shadcn Field (the modern replacement for Form).
Island model
island: true. Validation state and aria-invalid flip dynamically on user input.
The Field itself owns no logic — it composes a Label, the control, and a message slot — but because the message visibility depends on validation, it lives in the same island as the control.
Peer dependencies
@radix-ui/react-label@^2.1
Public API
export function Field(props: React.ComponentProps<"div"> & { orientation?: "vertical" | "horizontal" }): JSX.Element
export function FieldLabel(props: React.ComponentProps<typeof LabelPrimitive.Root>): JSX.Element
export function FieldDescription(props: React.ComponentProps<"p">): JSX.Element
export function FieldError(props: React.ComponentProps<"p"> & { errors?: string[] }): JSX.Element
export function FieldGroup(props: React.ComponentProps<"div">): JSX.Element
export function FieldSet(props: React.ComponentProps<"fieldset">): JSX.Element
export function FieldLegend(props: React.ComponentProps<"legend">): JSX.Element
export const island = true
Patties adjustments
FieldErroraccepts astring[]so server-rendered validation can hydrate the same DOM.- IDs are auto-generated via
React.useIdand wired across Label/control/description/error.
Acceptance criteria
- Server forms with pre-filled
errorsrender correctly without JS. - Client validation updates
aria-invalidandaria-describedbyafter hydration. - Horizontal orientation lays out label + control on one row at
md+.