Prodular UI

Field

The way to build forms: a label, a control, a description and an error, linked for assistive technology without passing ids.

npx prodular-ui add field

Settings form

A complete workspace settings form: text, URL prefix, select, switches and a textarea.

Workspace
Settings for Northbeam Studio. Changes apply to all 24 members.

Shown in the sidebar, in emails and on invoices.

tidewater.app/

Changing it breaks existing links. Old links redirect for 30 days.

Used for due dates, digests and reports.

Email notifications

Every Monday at 9:00, a recap of what shipped and what slipped.

When someone mentions you or replies to your comment.

Sent to workspace owners when a card is declined.

New members see this the first time they sign in.

Validation

Set invalid on Field and swap the description for a FieldError.

Responsive

Label on the left from medium container widths, stacked below.

How you appear in comments and mentions.

Used to estimate project cost in reports.

$
per hour

Anatomy

<Field>  <FieldLabel>Workspace name</FieldLabel>  <Input defaultValue="Northbeam Studio" />  <FieldDescription>Shown in the sidebar and on invoices.</FieldDescription>  <FieldError>Enter a name.</FieldError></Field>

Guidance

Use it when

  • Every form control that has a visible label.
  • FieldSet and FieldLegend for a group of related controls, such as notification switches.
  • orientation="responsive" for settings pages with the label column on the left.

Avoid

  • Wrapping a Field in another bordered box inside a card. Use FieldSeparator between sections.

Rules for AI agents

Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.

  • Build every form control as Field > FieldLabel + control + FieldDescription or FieldError. Field links them, so skip id, htmlFor and aria-describedby for Base UI controls (Input, Textarea, Select, Combobox, Checkbox, RadioGroup, Switch, Slider).
  • NativeSelect and InputOTP are not Base UI controls: give them an id and a matching FieldLabel htmlFor. Explicit ids also keep working for every other control.
  • Show errors by setting invalid on Field and rendering FieldError with a sentence that says how to fix it. Replace the description with the error rather than showing both.
  • Use orientation="horizontal" for checkboxes and switches. Put switches last and checkboxes first.
  • Group fields with FieldGroup and separate sections with FieldSeparator, not with nested cards.
  • Write descriptions as one short sentence about consequences (Old links redirect for 30 days), not a restatement of the label.

API

Field

PropTypeDefaultDescription
orientation"vertical" | "horizontal" | "responsive""vertical"Stacked, inline, or inline from the @md container width.
invalidbooleanMarks the control invalid and shows FieldError. data-invalid also works.
disabledbooleanDisables the control and dims the label. data-disabled also works.
validate(value) => string | nullBase UI validation. Return an error message or null.

FieldError

PropTypeDefaultDescription
errors{ message?: string }[]Messages from a form library. Duplicates are removed.

FieldLegend

PropTypeDefaultDescription
variant"legend" | "label""legend"Section heading or label sized legend.

FieldLabel

PropTypeDefaultDescription
htmlForstringOnly needed for controls Field cannot link, such as NativeSelect.

Installation

The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.

npx prodular-ui add field# or, with the registry in components.jsonnpx shadcn@latest add @prodular/field