Noctis

Field

Wire a control to its label, helper text, and validation message so assistive tech reads them as one unit. Field manages the aria-labelledby and aria-describedby relationships; Fieldset groups related fields under a legend; Form consolidates submission and validation.

A labelled field

A Field.Root stacks a Field.Label, the control, and an optional Field.Description. Drop a styled control — here an Input — inside it and its control auto-wires: the label associates (clicking it focuses the control) and the description links through aria-describedby. For a no-chrome control, use the bare Field.Control, which renders a native <input>.

We never share your address.

Validation

Add a Field.Error per validity rule and tie it to a ValidityState key with match (valueMissing, tooShort, …). The error renders into the DOM only while that rule fails, reads in the danger colour, and is wired to the control. Set validationMode on Field.Root (or Form) to choose when validation runs — here, on blur.

Grouping with a fieldset

Fieldset.Root groups related fields under a shared Fieldset.Legend, so a screen reader announces the group name on each control. Use it for an address block, a set of preferences, or any cluster that reads as one section.

Shipping address

Form submission

Form is a native <form> with consolidated error handling. It collects the values of its named fields, validates them together, and calls onFormSubmit with the collected values once valid. Pass errors keyed by field name to surface server-side validation.

Composing controls

Field is control-agnostic, so the whole family drops into it with one grammar. Place a styled Input or Textarea inside Field.Root — its control auto-wires, so the labelling, description, and validation all follow (that's how the examples above are built). For a no-chrome control, use the bare Field.Control; pass its render to swap the native input for a <textarea>, a <select>, or another Base UI input primitive.

Anatomy

Compose a field from its parts; Fieldset and Form wrap groups of them.

  • Field.Root — the container for one field. Set name to identify it on submit, validate for custom validation, validationMode to choose when it runs, and disabled to opt the whole field out.
  • Field.Label — the associated label; clicking it focuses the control. Set nativeLabel={false} when the label wraps a non-<label> element.
  • Field.Control — the bare control seam for a no-chrome field; renders a native <input> (pass render for any other element). For a styled field, drop an Input/Textarea in instead — its control auto-wires.
  • Field.Description — supporting text, linked via aria-describedby.
  • Field.Error — the validation message, shown only while the field is invalid; pair with match for per-rule messages.
  • Fieldset.Root / Fieldset.Legend — a group of related fields under one accessible legend.
  • Form — a native <form> with consolidated validation, error reporting, and an onFormSubmit callback.

Every part carries a data-slot (noctis-field, noctis-field-label, noctis-field-control, noctis-field-description, noctis-field-error, noctis-field-fieldset, noctis-field-fieldset-legend, noctis-field-form) for host-side styling — pair it with the Base UI state attributes (data-disabled, data-touched, data-dirty, data-invalid, data-valid, data-focused, data-filled). The wiring is RTL-aware by construction.

On surfaces

The same control re-tuned across the elevation scopes — the root canvas, an elevated panel, a menu, and a sunken well. It stays legible on every layer.

root

We never share your address.

elevated

We never share your address.

menu

We never share your address.

sunken

We never share your address.

Design tokens

Generated from the component's declaration — the same graph that mints the CSS, so a variable name or its resolution default can't drift. The minted tokens are the public override seam: set one on any ancestor and every field in that region retunes — e.g. .compact { --noctis-field-gap: var(--noctis-space-1); } tightens the rhythm between a field's parts. Colour stays with the semantic roles (the error reads danger). See Customization for the full override ladder and Tokens for the whole graph.

Token

API reference

Generated from the component's types — every prop, type, default, and description comes straight from the source. Each part gets its own table; parts that only forward to Base UI list just the props they pass through. Expand a row for the full type and description.

Field.Root

Prop

Field.Label

Prop

Field.Control

Prop

Field.Description

Prop

Field.Error

Prop

Field.Action

Prop

Field.Count

Prop

AttributeDescription
data-slotMarks each rendered field part.
data-disabledPresent on every part of a disabled field (and on a disabled fieldset).
data-touchedPresent on the parts of a field whose control has been blurred at least once.
data-dirtyPresent on the parts of a field whose value differs from its initial value.
data-invalidPresent on the parts of a field that currently fails validation.
data-validPresent on the parts of a field that currently passes validation.
data-focusedPresent on the parts of a field whose control is focused.
data-filledPresent on the parts of a field whose control holds a value.
data-sideWhich edge an action sits on — `start` (leading) | `end` (trailing).
data-revealOpt-in on an action: `filled` collapses it until the host field's control is filled (CSS `:has()`).
data-nearPresent on the count when the value nears its limit — escalates to the warning colour.
data-overPresent on the count when the value passes its limit — escalates to the danger colour.

Fieldset.Root

Prop

Fieldset.Legend

Prop

Prop