---
title: "Field"
description: "The parts every field is made of: Label, Description, FieldError and FieldHelp (the description, replaced by the error while invalid). Field wraps a control that is not a React Aria field with them, and nativeFieldBox styles a native select or text area like the rest; FieldGroup holds an input and the buttons that act on it in one box."
---

> Documentation Index
> Fetch the complete documentation index at: https://epidermis.getarbol.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Field

## Plain children

The short form: an Input or TextArea inside is tied to the label, the help and the error by itself.

```tsx
import { Field, Input, TextArea } from '@arbol-ai/ui';

<div className="grid max-w-xs gap-4">
  <Field description="The patient sees it in the reminder." label="Reason">
    <Input defaultValue="Follow-up visit" />
  </Field>
  <Field errorMessage="Write at most 500 characters." isInvalid label="Note for the front desk">
    <TextArea defaultValue="Bring the authorization." />
  </Field>
</div>
```

## A native select or text area

nativeFieldBox gives a native control the look of the fields beside it, from the theme tokens; the Field’s id goes on the control.

```tsx
import { Field, nativeFieldBox } from '@arbol-ai/ui';

<div className="grid max-w-xs gap-4">
  <Field description="Only active agendas are listed." id="example-agenda" label="Agenda">
    <select className={nativeFieldBox()} defaultValue="ruiz" id="example-agenda">
      <option value="ruiz">Dr. Ruiz</option>
      <option value="room-2">Room 2</option>
    </select>
  </Field>
  <Field id="example-instructions" label="Instructions">
    <textarea className={nativeFieldBox({ control: 'textarea' })} id="example-instructions" />
  </Field>
</div>
```

## A control of your own

Field gives the control the ids that tie it to its label, help and error. Here an input with suggestions validates what was typed.

```tsx
import { useId, useState } from 'react';
import { Field, Input } from '@arbol-ai/ui';

const USUAL_DURATIONS = ['15m', '30m', '45m', '1h', '1h30', '2h'];

const DurationExample = () => {
  const [text, setText] = useState('30m');
  const suggestions = useId();
  const isValid = text === '' || /^\d+(?:m|h(?:\d+)?)$/u.test(text);
  return (
    <div className="max-w-xs">
      <Field
        description="Like 30m, 1h or 1h30."
        errorMessage="Write the length like 30m, 1h or 1h30."
        isInvalid={!isValid}
        label="Appointment length"
      >
        {(control) => (
          <>
            <Input
              {...control}
              list={suggestions}
              onChange={(event) => {
                setText(event.target.value);
              }}
              value={text}
            />
            <datalist id={suggestions}>
              {USUAL_DURATIONS.map((duration) => (
                <option key={duration} value={duration}>
                  {duration}
                </option>
              ))}
            </datalist>
          </>
        )}
      </Field>
    </div>
  );
};

<DurationExample />
```

## An input with a button

FieldGroup draws one box around the input and its button, with one focus ring.

```tsx
import { EyeIcon, EyeSlashIcon } from '@phosphor-icons/react';
import { useState } from 'react';
import { TextField as AriaTextField } from 'react-aria-components';
import { Button, FieldGroup, FieldGroupInput, FieldHelp, Label } from '@arbol-ai/ui';

const PasswordExample = () => {
  const [isVisible, setIsVisible] = useState(false);
  const label = 'Password';
  return (
    <AriaTextField className="flex max-w-xs flex-col gap-1.5" defaultValue="clinic-2026">
      <Label>{label}</Label>
      <FieldGroup>
        <FieldGroupInput type={isVisible ? 'text' : 'password'} />
        <Button
          aria-label={isVisible ? 'Hide password' : 'Show password'}
          className="me-0.5"
          onPress={() => {
            setIsVisible((visible) => !visible);
          }}
          size="icon-sm"
          variant="ghost"
        >
          {isVisible ? <EyeSlashIcon aria-hidden /> : <EyeIcon aria-hidden />}
        </Button>
      </FieldGroup>
      <FieldHelp description="At least 12 characters." />
    </AriaTextField>
  );
};

<PasswordExample />
```

## Source

The examples above are [`src/components/field/field.examples.tsx`](https://github.com/getarbol/project-arbol-ui/blob/main/src/components/field/field.examples.tsx), which the library's tests render too.

Source: https://epidermis.getarbol.com/components/forms/field/index.mdx
