Ark UI Logo
Components
Field

Field

Provides a flexible container for form inputs, labels, and helper text.

Loading...

Examples

The Field component provides contexts such as invalid, disabled, required, and readOnly for form elements. While most Ark UI components natively support these contexts, you can also use the Field component with standard HTML form elements.

Input

This example shows how to use the Field component with a standard input field.

import { Field } from '@ark-ui/react/field'
import styles from 'styles/field.module.css'

export const Input = () => (
  <Field.Root className={styles.Root}>
    <Field.Label className={styles.Label}>Label</Field.Label>
    <Field.Input className={styles.Input} />
    <Field.HelperText className={styles.HelperText}>Some additional Info</Field.HelperText>
    <Field.ErrorText className={styles.ErrorText}>Error Info</Field.ErrorText>
  </Field.Root>
)

Textarea

This example illustrates how to use the Field component with a textarea element.

import { Field } from '@ark-ui/react/field'
import styles from 'styles/field.module.css'

export const Textarea = () => (
  <Field.Root className={styles.Root}>
    <Field.Label className={styles.Label}>Label</Field.Label>
    <Field.Textarea className={styles.Textarea} />
    <Field.HelperText className={styles.HelperText}>Some additional Info</Field.HelperText>
    <Field.ErrorText className={styles.ErrorText}>Error Info</Field.ErrorText>
  </Field.Root>
)

Textarea Autoresize

Pass the autoresize prop to the Textarea component to enable automatic resizing as the user types.

import { Field } from '@ark-ui/react/field'
import styles from 'styles/field.module.css'

export const TextareaAutoresize = () => (
  <Field.Root className={styles.Root}>
    <Field.Label className={styles.Label}>Label</Field.Label>
    <Field.Textarea className={styles.Textarea} autoresize />
    <Field.HelperText className={styles.HelperText}>Some additional Info</Field.HelperText>
    <Field.ErrorText className={styles.ErrorText}>Error Info</Field.ErrorText>
  </Field.Root>
)

Select

This example demonstrates how to integrate the Field component with a select dropdown.

import { Field } from '@ark-ui/react/field'
import styles from 'styles/field.module.css'

export const Select = () => (
  <Field.Root className={styles.Root}>
    <Field.Label className={styles.Label}>Label</Field.Label>
    <Field.Select className={styles.Select}>
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
      <option value="3">Option 3</option>
    </Field.Select>
    <Field.HelperText className={styles.HelperText}>Some additional Info</Field.HelperText>
    <Field.ErrorText className={styles.ErrorText}>Error Info</Field.ErrorText>
  </Field.Root>
)

Checkbox

This example demonstrates how to integrate the Field and Checkbox components.

import { Checkbox } from '@ark-ui/react/checkbox'
import { Field } from '@ark-ui/react/field'
import { CheckIcon, MinusIcon } from 'lucide-react'
import styles from 'styles/checkbox.module.css'
import field from 'styles/field.module.css'

export const WithField = () => (
  <Field.Root className={field.Root}>
    <Checkbox.Root className={styles.Root}>
      <Checkbox.Control className={styles.Control}>
        <Checkbox.Indicator className={styles.Indicator}>
          <CheckIcon />
        </Checkbox.Indicator>
        <Checkbox.Indicator className={styles.Indicator} indeterminate>
          <MinusIcon />
        </Checkbox.Indicator>
      </Checkbox.Control>
      <Checkbox.Label className={styles.Label}>Label</Checkbox.Label>
      <Checkbox.HiddenInput />
    </Checkbox.Root>
    <Field.HelperText className={field.HelperText}>Additional Info</Field.HelperText>
    <Field.ErrorText className={field.ErrorText}>Error Info</Field.ErrorText>
  </Field.Root>
)

Root Provider

Use the useField hook to create the field store and pass it to the Field.RootProvider component. This allows you to have maximum control over the field programmatically.

import { Field, useField } from '@ark-ui/react/field'
import { useState } from 'react'
import styles from 'styles/field.module.css'
import button from 'styles/button.module.css'

export const RootProvider = () => {
  const [invalid, setInvalid] = useState(false)
  const field = useField({ invalid })

  return (
    <>
      <button className={button.Root} style={{ marginBottom: '1rem' }} onClick={() => setInvalid((prev) => !prev)}>
        Toggle Invalid
      </button>
      <Field.RootProvider className={styles.Root} value={field}>
        <Field.Label className={styles.Label}>Label</Field.Label>
        <Field.Input className={styles.Input} />
        <Field.HelperText className={styles.HelperText}>Some additional Info</Field.HelperText>
        <Field.ErrorText className={styles.ErrorText}>Error Info</Field.ErrorText>
      </Field.RootProvider>
    </>
  )
}

If you're using the Field.RootProvider component, you don't need to use the Field.Root component.

Custom Control

Use the Field.Context or useFieldContext hook to access the internal state of the field.This can help you wire up custom controls with the Field component.

import { Field } from '@ark-ui/react/field'
import styles from 'styles/field.module.css'

export const CustomControl = () => (
  <Field.Root className={styles.Root} invalid>
    <Field.Label className={styles.Label}>Any Control</Field.Label>
    <Field.Context>{(context) => <input {...context.getInputProps()} />}</Field.Context>
    <Field.HelperText className={styles.HelperText}>Uses getInputProps() for maximum flexibility</Field.HelperText>
    <Field.ErrorText className={styles.ErrorText}>This field has an error</Field.ErrorText>
  </Field.Root>
)

API Reference

Root

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
disabled
boolean

Indicates whether the field is disabled.

ids
ElementIds

The ids of the field parts.

invalid
boolean

Indicates whether the field is invalid.

readOnly
boolean

Indicates whether the field is read-only.

required
boolean

Indicates whether the field is required.

ErrorText

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

HelperText

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Input

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Label

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

RequiredIndicator

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
fallback
string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<...>

RootProvider

PropDefaultType
value
{ ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: RefObject<HTMLDivElement | null>; }; ... 11 more ...; getRequiredIndicatorProps: () => Omit<...>; }

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Select

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Textarea

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
autoresizefalse
boolean

Whether the textarea should autoresize