Field
A form field wrapper that renders a label, description, control slot, and validation status.
Examples
Section titled “Examples”Default
Section titled “Default”We'll never share your email.
<Field {...args} description="We'll never share your email."> <input id="field-story" /></Field>Required
Section titled “Required”<Field {...args}> <input id="field-story" /></Field>Optional
Section titled “Optional”<Field {...args}> <input id="field-story" /></Field>Disabled
Section titled “Disabled”<Field {...args}> <input disabled id="field-story" /></Field>Label Hidden
Section titled “Label Hidden”The label is visually hidden but still accessible.
<Field {...args}> <input id="field-story" placeholder="Email" /></Field>Label as span
Section titled “Label as span”Preference
<Field {...args}> <div aria-labelledby="pref-label" role="radiogroup"> <label> <input name="pref" type="radio" /> Email </label> <label> <input name="pref" type="radio" /> Phone </label> </div></Field>With Label Icon
Section titled “With Label Icon”<Field {...args}> <input id="field-story" /></Field>With Label Tooltip
Section titled “With Label Tooltip”<Field {...args}> <input id="field-story" /></Field>With Label End
Section titled “With Label End”<Field {...args}> <input id="field-story" type="password" /></Field>Label End With Hidden Label
Section titled “Label End With Hidden Label”<Field {...args}> <input id="field-story" placeholder="Password" type="password" /></Field>Status — error
Section titled “Status — error”This field is required.
<Field {...args}> <input id="field-story" /></Field>Status — warning
Section titled “Status — warning”This email is already in use.
<Field {...args}> <input id="field-story" /></Field>Status — success
Section titled “Status — success”Email is available.
<Field {...args}> <input id="field-story" /></Field>Status — detached
Section titled “Status — detached”This field is required.
<Field {...args}> <input id="field-story" /></Field>Kitchen Sink
Section titled “Kitchen Sink”Your primary contact email.
Please enter a valid email.
<Field {...args}> <input id="field-story" /></Field>A form field wrapper that renders a label, description, control slot, and validation status.
When isOptional: false, isRequired: false
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | The form control rendered inside the field. |
className | string | — | Additional CSS class names applied to the root element. |
data-testid | string | — | Test ID applied to the root element. |
description | ReactNode | — | Supporting text rendered between the label and control. |
descriptionID | string | — | ID for the description element. |
inputId* | string | — | ID of the associated control. |
isDisabled | boolean | false | Whether the associated control is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label and description. |
isReadOnly | boolean | false | Whether the associated control is read-only. |
label* | string | — | Field label text. |
labelAs | 'label' | 'span' | 'label' | HTML element used for the label. Use 'span' for group controls (e.g., radiogroup) where htmlFor cannot target a labelable element. |
labelEnd | ReactNode | — | Content shown at the end of the label row, such as a "Forgot password?" link. It renders outside the label element, so interacting with it does not focus the control and it is not part of the control's accessible name. It stays visible when isLabelHidden is true, on a row of its own. |
labelIcon | IconComponent | — | Optional icon shown before the label. |
labelId | string | — | ID applied to the label element, useful for aria-labelledby. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
ref | Ref<HTMLDivElement> | — | Ref forwarded to the root element. |
status | FieldStatus | — | Validation status displayed below the control. |
statusVariant | "attached" | "detached" | 'attached' | How the status message is positioned. |
style | CSSProperties | — | Inline styles applied to the root element. |
isOptional | false | — | |
isRequired | false | — |
When isOptional: true, isRequired: false
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | The form control rendered inside the field. |
className | string | — | Additional CSS class names applied to the root element. |
data-testid | string | — | Test ID applied to the root element. |
description | ReactNode | — | Supporting text rendered between the label and control. |
descriptionID | string | — | ID for the description element. |
inputId* | string | — | ID of the associated control. |
isDisabled | boolean | false | Whether the associated control is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label and description. |
isReadOnly | boolean | false | Whether the associated control is read-only. |
label* | string | — | Field label text. |
labelAs | 'label' | 'span' | 'label' | HTML element used for the label. Use 'span' for group controls (e.g., radiogroup) where htmlFor cannot target a labelable element. |
labelEnd | ReactNode | — | Content shown at the end of the label row, such as a "Forgot password?" link. It renders outside the label element, so interacting with it does not focus the control and it is not part of the control's accessible name. It stays visible when isLabelHidden is true, on a row of its own. |
labelIcon | IconComponent | — | Optional icon shown before the label. |
labelId | string | — | ID applied to the label element, useful for aria-labelledby. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
ref | Ref<HTMLDivElement> | — | Ref forwarded to the root element. |
status | FieldStatus | — | Validation status displayed below the control. |
statusVariant | "attached" | "detached" | 'attached' | How the status message is positioned. |
style | CSSProperties | — | Inline styles applied to the root element. |
isOptional* | true | — | |
isRequired | false | — |
When isOptional: false, isRequired: true
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | The form control rendered inside the field. |
className | string | — | Additional CSS class names applied to the root element. |
data-testid | string | — | Test ID applied to the root element. |
description | ReactNode | — | Supporting text rendered between the label and control. |
descriptionID | string | — | ID for the description element. |
inputId* | string | — | ID of the associated control. |
isDisabled | boolean | false | Whether the associated control is disabled. |
isLabelHidden | boolean | false | Whether to visually hide the label and description. |
isReadOnly | boolean | false | Whether the associated control is read-only. |
label* | string | — | Field label text. |
labelAs | 'label' | 'span' | 'label' | HTML element used for the label. Use 'span' for group controls (e.g., radiogroup) where htmlFor cannot target a labelable element. |
labelEnd | ReactNode | — | Content shown at the end of the label row, such as a "Forgot password?" link. It renders outside the label element, so interacting with it does not focus the control and it is not part of the control's accessible name. It stays visible when isLabelHidden is true, on a row of its own. |
labelIcon | IconComponent | — | Optional icon shown before the label. |
labelId | string | — | ID applied to the label element, useful for aria-labelledby. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
ref | Ref<HTMLDivElement> | — | Ref forwarded to the root element. |
status | FieldStatus | — | Validation status displayed below the control. |
statusVariant | "attached" | "detached" | 'attached' | How the status message is positioned. |
style | CSSProperties | — | Inline styles applied to the root element. |
isOptional | false | — | |
isRequired* | true | — |