RoadieRoadie
  • Home
  • Brand
  • Foundations
  • Content
  • Tokens
  • Components
  • Charts
  • Widgets
  • Appearance
HomeBrandFoundations
Appearance

Components

  • Navigation

    • Breadcrumb
    • LinkBeta
    • NavigatorAlpha
    • Steps
    • Tabs
  • Layout

    • Accordion
    • CollapsibleBeta
    • PaneAlpha
    • ScrollArea
    • Separator
  • Actions

    • Button
    • IconButton
    • ToggleBeta
    • Toggle groupBeta
    • ToolbarBeta
  • Fields

    • EditorAlpha
    • Field
    • Fieldset
    • Input
    • Label
    • Number fieldBeta
    • OTP fieldBeta
    • Query fieldAlpha
    • Textarea
  • Choices

    • Autocomplete
    • CheckboxBeta
    • Combobox
    • Radio group
    • Select
    • SliderBeta
    • SwitchBeta
  • Date and time

    • CalendarBeta
    • CalendarTile
    • Countdown
    • Dashboard periodBeta
    • Date fieldBeta
    • Date pickerBeta
    • Date range pickerBeta
    • DateTime
    • Duration
    • Time fieldBeta
  • Collections

    • Card
    • Carousel
    • DataTableBeta
    • ListAlpha
    • Marquee
    • RecordGridAlpha
    • RecordTableAlpha
    • SortableAlpha
    • TableBeta
  • Overlays

    • Dialog
    • Drawer
    • MenuBeta
    • Popover
    • ToastBeta
    • Tooltip
  • Status

    • Badge
    • CalloutBeta
    • DeltaBeta
    • Empty state
    • MeterBeta
    • ProgressBeta
    • SkeletonBeta
    • SparklineBeta
    • StatTileBeta
  • Media & brand

    • AvatarBeta
    • Icon Tile
    • Image
    • Logo
    • PatternBeta
    • QR codeBeta
    • SpotIllustration
  • Text

    • Code
    • Highlight
    • KbdBeta
    • Mark
    • Prose

Field

Status
Stable
Added
Components 2.0.08 Apr 2026
Updated
Components 2.16.020 Oct 2026
Docs updated
19 Oct 2026

A compound wrapper for labelled form fields with helper and error text.

Import

import { Field } from '@oztix/roadie-components/field'

Examples

Default

<Field>
<Field.Label>Name</Field.Label>
<Field.Input placeholder='Enter your name' />
</Field>

With indicators

Use showIndicator on Field.Label to automatically render a required or optional indicator based on the Field's required prop. This eliminates the need to manually import and place RequiredIndicator or OptionalIndicator.

<Field required>
<Field.Label showIndicator>Email</Field.Label>
<Field.Input type='email' placeholder='you@example.com' />
</Field>
<Field>
<Field.Label showIndicator>Phone number</Field.Label>

States

Fields inherit input interaction states. Focus shows accent colouring, invalid shows danger colouring with error text. The invalid and disabled props flow through context to child inputs automatically.

{/* Default */}
<Field>
<Field.Label>Label</Field.Label>
<Field.Input placeholder='Click to focus' />
<Field.HelperText>Helper text appears below the input.</Field.HelperText>
</Field>

Composition

Field exposes sub-components for label, input, textarea, helper text, and error text.

With helper text

<Field>
<Field.Label>Email</Field.Label>
<Field.Input type='email' placeholder='you@example.com' />
<Field.HelperText>We'll never share your email.</Field.HelperText>
</Field>

With error text

Set invalid on the Field root to activate the danger state. The input border and focus ring automatically switch to danger colours, and aria-invalid is set on the input automatically.

<Field invalid>
<Field.Label>Password</Field.Label>
<Field.Input type='password' />
<Field.ErrorText>Use at least eight characters.</Field.ErrorText>
</Field>

Controls that read typed text, such as DateField, also show their own error in Field.ErrorText when the text names nothing, such as "Enter a date, like 14 Mar or next Fri". It shows even when invalid isn't set, and wins over the error text's children until the text is fixed.

With textarea

<Field>
<Field.Label>Bio</Field.Label>
<Field.Textarea placeholder='Tell us about yourself' />
<Field.HelperText>Maximum 200 characters.</Field.HelperText>
</Field>

Guidelines

Write labels, helper text, and error text with Interface copy.

Accessibility

  • Auto-wired IDs: Field auto-generates matching IDs for the label, input, helper text, and error text. You don't need to set htmlFor or id manually.
  • Context-driven aria: The invalid, required, and disabled props on Field automatically set aria-invalid, aria-required, and disabled on child inputs via context.
  • Error announcements: Field.ErrorText renders with role="alert" and only appears when invalid is true or a control reports its own error, so screen readers announce errors immediately.
  • Description linking: aria-describedby is automatically wired to the helper text (or error text when invalid).

Hooks

useFieldContext

function useFieldContext(): {
invalid?: boolean
required?: boolean
disabled?: boolean
fieldId: string
labelId: string

Reads the nearest Field's state. Use it when building a custom control that needs to react to the same invalid / required / disabled state as Field.Input, without reimplementing Field's own sub-components. Outside a Field, every value comes back empty or undefined.

FieldTypeDescription
invalidboolean | undefinedWhether the field is invalid.
requiredboolean | undefinedWhether the field is required.
disabledboolean | undefinedWhether the field is disabled.
fieldIdstringThe id wired to the input and its label.
labelIdstringThe label's id.
helperTextIdstringField.HelperText's id.
errorTextIdstringField.ErrorText's id.

useFieldInputProps

function useFieldInputProps(): {
id: string | undefined
disabled: boolean | undefined
'aria-invalid': boolean | undefined
'aria-required': boolean | undefined
'aria-describedby': string | undefined

Derives the DOM attributes a custom input needs from the nearest Field's context: this is what Field.Input and Field.Textarea spread onto their own element. Reach for it when building a control Field.Input doesn't cover.

FieldTypeDescription
idstring | undefinedMatches Field.Label's htmlFor.
disabledboolean | undefinedThe field's disabled state.
aria-invalidboolean | undefinedThe field's invalid state.
aria-requiredboolean | undefinedThe field's required state.
aria-describedbystring | undefinedThe error text's id when invalid, otherwise the helper text's id.

useFieldControlError

function useFieldControlError(message: string | null): void

Shows a control's own error in Field.ErrorText while the control is mounted, such as a date it can't read or a file it couldn't upload. Pass null once the problem is fixed. The control's message wins over the error text's children, and shows even when the field isn't invalid. With several controls in one field, the first to mount shows its error first. Outside a Field it does nothing. It returns nothing.

It doesn't mark the control itself, and useFieldInputProps follows only the field's invalid. While the control has an error, set aria-invalid on it and point its aria-describedby at errorTextId from useFieldContext, as Roadie's date and time fields do.

API reference

Field

invalidboolean
requiredboolean
disabledboolean

Field.ErrorText

Shows when the field is invalid, or when its control can't read what was typed. The control's message, such as a date it can't read, wins over `children`, since it says exactly what to fix.

No additional props. It forwards all standard HTML attributes to the underlying element.

Field.HelperText

No additional props. It forwards all standard HTML attributes to the underlying element.

Field.Input

size"sm" | "md" | "lg" | null
emphasis"normal" | "subtle" | null

Inherited from InputProps

intent"neutral" | "brand" | "brand-secondary" | "brand-blue" | "brand-orange" | "brand-purple" | "accent" | "danger" | "success" | "warning" | "info" | null
Deprecated

Deprecated: Form controls take their colour from state; `is-interactive-field` handles it. Will be removed in v3.0.0.

Field.Label

showIndicatorboolean

Field.Textarea

size"sm" | "md" | "lg" | null
emphasis"normal" | "subtle" | null

Inherited from TextareaProps

intent"neutral" | "brand" | "brand-secondary" | "brand-blue" | "brand-orange" | "brand-purple" | "accent" | "danger" | "success" | "warning" | "info" | null
Deprecated

Deprecated: Form controls take their colour from state; `is-interactive-field` handles it. Will be removed in v3.0.0.

autoResizeboolean
Previous page← EditorNext pageFieldset →