# Text Input Field (/components/forms/text-input-field)

Use `TextInputField` to collect a single line of text. It combines an input with a label,
description, and validation message.

apps/docs/src/examples/text-input-field/basic.tsx

```tsx
import { TextInputField } from '@luke-ui/react/text-input-field';

export default () => {
	return (
		<TextInputField
			description="Use the address you check most often."
			label="Email address"
			name="emailAddress"
			placeholder="you@example.com"
		/>
	);
};
```

## Labels and placeholders [#labels-and-placeholders]

Give the field a visible `label` where possible. Use `placeholder` for an example value or input
format, not as the label. A placeholder disappears while someone types and is not a reliable
accessible name.

When a nearby heading already names the field, omit `label`. Use `aria-label` or `aria-labelledby`
instead.

```tsx
<TextInputField aria-label="Search" name="search" placeholder="Search" />
```

## Required fields [#required-fields]

Set `isRequired` when the field must have a value. By default, a required text input shows a marker
after its `label`. Read [Required fields](/docs/forms#required-fields) for the `necessityIndicator`
values.

apps/docs/src/examples/text-input-field/required.tsx

```tsx
import { Stack } from '@luke-ui/react/stack';
import { TextInputField } from '@luke-ui/react/text-input-field';

export default () => {
	return (
		<Stack gap="space.16">
			<TextInputField
				isRequired
				label="First name"
				name="firstName"
				necessityIndicator="required-asterisk"
			/>
			<TextInputField
				isRequired
				label="Last name"
				name="lastName"
				necessityIndicator="required-label"
			/>
			<TextInputField label="Middle name" name="middleName" necessityIndicator="optional-label" />
		</Stack>
	);
};
```

## Validation [#validation]

Set `isRequired`, `type`, or `pattern`, or pass `validate` to check the value. `TextInputField`
shows its validation message after validation fails. Pass `errorMessage` only for an error you
already have, such as one from a form library or your server. A non-empty message marks the field
invalid. Read [Validation](/docs/validation) for where messages come from, server errors, and how to
write them.

apps/docs/src/examples/text-input-field/validation.tsx

```tsx
import { Button } from '@luke-ui/react/button';
import { Cluster } from '@luke-ui/react/cluster';
import { Stack } from '@luke-ui/react/stack';
import { TextInputField } from '@luke-ui/react/text-input-field';
import type { SubmitEvent } from 'react';

function handleSubmit(event: SubmitEvent<HTMLFormElement>) {
	event.preventDefault();
}

export default () => {
	return (
		<form onSubmit={handleSubmit}>
			<Stack gap="space.16">
				<TextInputField isRequired label="Email address" name="emailAddress" type="email" />
				<Cluster>
					<Button type="submit">Submit</Button>
				</Cluster>
			</Stack>
		</form>
	);
};
```

## Prefix and suffix [#prefix-and-suffix]

Use `prefix` and `suffix` for content inside the input, such as a search icon, currency code, or URL
scheme. Both accept any `ReactNode`. Give an interactive prefix or suffix an accessible name and
keyboard behaviour.

apps/docs/src/examples/text-input-field/prefix-and-suffix.tsx

```tsx
import { Icon } from '@luke-ui/react/icon';
import { Stack } from '@luke-ui/react/stack';
import { TextInputField } from '@luke-ui/react/text-input-field';

export default () => {
	return (
		<Stack gap="space.16">
			<TextInputField
				label="Search documentation"
				name="documentationSearch"
				placeholder="Search components"
				prefix={<Icon name="search" size="small" />}
			/>
			<TextInputField label="Website" name="website" placeholder="example.com" prefix="https://" />
			<TextInputField label="Budget" name="budget" placeholder="0.00" suffix="AUD" />
		</Stack>
	);
};
```

## Size [#size]

Use `size` to set the input height and typography. Use `small` in compact layouts. `medium` is the
default. The HTML numeric `size` attribute is unavailable because `size` is the Luke UI variant. On
touch devices, `small` uses the body text size so iOS Safari doesn't zoom into the field on focus.

apps/docs/src/examples/text-input-field/sizes.tsx

```tsx
import { TextInputField } from '@luke-ui/react/text-input-field';
import { Comparison, ComparisonItem } from '#docs';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="small">
				<TextInputField
					label="Example field"
					name="example"
					placeholder="Example input"
					size="small"
				/>
			</ComparisonItem>
			<ComparisonItem label="medium">
				<TextInputField
					label="Example field"
					name="example"
					placeholder="Example input"
					size="medium"
				/>
			</ComparisonItem>
		</Comparison>
	);
};
```

## IDs and refs [#ids-and-refs]

`id`, `className`, and `ref` target the field's root element. Pass `inputId` to set the input's id,
and `inputRef` to reach the input.

## Accessibility [#accessibility]

Luke UI associates the label, description, and error message with the control.

## API [#api]

### TextInputFieldProps

Props for `TextInputField`.

`TextInputFieldProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

| Prop                     | Type                                                                                  | Description                                                                                                                                                                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `aria-describedby?`      | `string`                                                                              | Identifies the element (or elements) that describes the object.                                                                                                                                                                                  |
| `aria-details?`          | `string`                                                                              | Identifies the element (or elements) that provide a detailed, extended description for the object.                                                                                                                                               |
| `aria-errormessage?`     | `string`                                                                              | Identifies the element that provides an error message for the object.                                                                                                                                                                            |
| `onCopy?`                | `React.ClipboardEventHandler<HTMLInputElement>`                                       | Handler that is called when the user copies text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncopy).                                                                                                                |
| `onCut?`                 | `React.ClipboardEventHandler<HTMLInputElement>`                                       | Handler that is called when the user cuts text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncut).                                                                                                                   |
| `onPaste?`               | `React.ClipboardEventHandler<HTMLInputElement>`                                       | Handler that is called when the user pastes text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/onpaste).                                                                                                               |
| `onCompositionStart?`    | `React.CompositionEventHandler<HTMLInputElement>`                                     | Handler that is called when a text composition system starts a new text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event).                                                         |
| `onCompositionEnd?`      | `React.CompositionEventHandler<HTMLInputElement>`                                     | Handler that is called when a text composition system completes or cancels the current text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionend_event).                                       |
| `onCompositionUpdate?`   | `React.CompositionEventHandler<HTMLInputElement>`                                     | Handler that is called when a new character is received in the current text composition session. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionupdate_event).                                                    |
| `onSelect?`              | `React.ReactEventHandler<HTMLInputElement>`                                           | Handler that is called when text in the input is selected. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event).                                                                                                     |
| `onBeforeInput?`         | `React.FormEventHandler<HTMLInputElement>`                                            | Handler that is called when the input value is about to be modified. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/beforeinput_event).                                                                                  |
| `onInput?`               | `React.FormEventHandler<HTMLInputElement>`                                            | Handler that is called when the input value is modified. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event).                                                                                                    |
| `autoComplete?`          | `string`                                                                              | Describes the type of autocomplete functionality the input should provide if any. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautocomplete).                                                            |
| `maxLength?`             | `number`                                                                              | The maximum number of characters supported by the input. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefmaxlength).                                                                                        |
| `minLength?`             | `number`                                                                              | The minimum number of characters required by the input. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefminlength).                                                                                         |
| `pattern?`               | `string`                                                                              | Regex pattern that the value of the input must match to be valid. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefpattern).                                                                                 |
| `type?`                  | `'text' \| 'search' \| 'url' \| 'tel' \| 'email' \| 'password' \| (string & {})`      | The type of input to render. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdeftype). Default: `'text'`                                                                                                       |
| `inputMode?`             | `'none' \| 'text' \| 'tel' \| 'url' \| 'email' \| 'numeric' \| 'decimal' \| 'search'` | Hints at the type of data that might be entered by the user while editing the element or its contents. See [MDN](https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute).                             |
| `autoCorrect?`           | `string`                                                                              | An attribute that takes as its value a space-separated string that describes what, if any, type of autocomplete functionality the input should provide. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autocomplete). |
| `spellCheck?`            | `string`                                                                              | An enumerated attribute that defines whether the element may be checked for spelling errors. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck).                                                          |
| `onKeyDown?`             | `(e: KeyboardEvent) => void`                                                          | Handler that is called when a key is pressed.                                                                                                                                                                                                    |
| `onKeyUp?`               | `(e: KeyboardEvent) => void`                                                          | Handler that is called when a key is released.                                                                                                                                                                                                   |
| `onFocus?`               | `(e: React.FocusEvent<HTMLInputElement, Element>) => void`                            | Handler that is called when the element receives focus.                                                                                                                                                                                          |
| `onBlur?`                | `(e: React.FocusEvent<HTMLInputElement, Element>) => void`                            | Handler that is called when the element loses focus.                                                                                                                                                                                             |
| `onFocusChange?`         | `(isFocused: boolean) => void`                                                        | Handler that is called when the element's focus status changes.                                                                                                                                                                                  |
| `autoFocus?`             | `boolean`                                                                             | Whether the element should receive focus on render.                                                                                                                                                                                              |
| `description?`           | `ReactNode`                                                                           | Optional helper text shown below the control.                                                                                                                                                                                                    |
| `necessityIndicator?`    | `NecessityIndicator`                                                                  | Controls how the label identifies required or optional values. Inherits from `Form`, or uses `'required-asterisk'` when unset.                                                                                                                   |
| `label?`                 | `Exclude<ReactNode, boolean \| null \| undefined>`                                    | Visible label. Pass non-empty, textual, non-interactive content. Place links and buttons outside it, and associate external label content with `aria-labelledby` instead.                                                                        |
| `aria-label?`            | `string`                                                                              |                                                                                                                                                                                                                                                  |
| `aria-labelledby?`       | `string`                                                                              |                                                                                                                                                                                                                                                  |
| `aria-activedescendant?` | `string`                                                                              | Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application.                                                                                                                                 |
| `aria-autocomplete?`     | `'none' \| 'inline' \| 'list' \| 'both'`                                              | Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be presented if they are made.                                                   |
| `enterKeyHint?`          | `'enter' \| 'done' \| 'go' \| 'next' \| 'previous' \| 'search' \| 'send'`             | An enumerated attribute that defines what action label or icon to preset for the enter key on virtual keyboards. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint).                                    |
| `className?`             | `ClassNameOrFunction<TextFieldRenderProps> \| undefined`                              | Class name for the root element.                                                                                                                                                                                                                 |
| `form?`                  | `string \| undefined`                                                                 | The `<form>` element to associate the input with, by id.                                                                                                                                                                                         |
| `isRequired?`            | `boolean \| undefined`                                                                | Whether a value is required before the form can submit.                                                                                                                                                                                          |
| `name?`                  | `string \| undefined`                                                                 | The name of the input, used when submitting an HTML form.                                                                                                                                                                                        |
| `validate?`              | `((value: string) => true \| ValidationError \| null \| undefined) \| undefined`      | Custom validation function run against the current value. Return a message, or `true`/`null` when valid.                                                                                                                                         |
| `validationBehavior?`    | `"aria" \| "native" \| undefined`                                                     | When native HTML form validation runs. Default: `'native'`                                                                                                                                                                                       |
| `defaultValue?`          | `string \| undefined`                                                                 | Initial value (uncontrolled).                                                                                                                                                                                                                    |
| `isDisabled?`            | `boolean \| undefined`                                                                | Whether the field is disabled.                                                                                                                                                                                                                   |
| `isReadOnly?`            | `boolean \| undefined`                                                                | Whether the field is read-only.                                                                                                                                                                                                                  |
| `onChange?`              | `((value: string) => void) \| undefined`                                              | Called when the value changes.                                                                                                                                                                                                                   |
| `value?`                 | `string \| undefined`                                                                 | Controlled input value.                                                                                                                                                                                                                          |
| `errorMessage?`          | `ReactNode`                                                                           | Validation message for a controlled error. A non-empty message marks the field invalid.                                                                                                                                                          |
| `id?`                    | `string \| undefined`                                                                 | Element id for the field's root element. Use `inputId` for the input.                                                                                                                                                                            |
| `inputClassName?`        | `ClassNameOrFunction<InputRenderProps> \| undefined`                                  | Class name forwarded to the inner input element.                                                                                                                                                                                                 |
| `inputId?`               | `string \| undefined`                                                                 | Element id for the input. The field generates one when omitted.                                                                                                                                                                                  |
| `inputRef?`              | `Ref<HTMLInputElement>`                                                               | Forwarded to the inner `<input>` element. Accepts a callback ref or a ref object. Use `ref` for the root element.                                                                                                                                |
| `placeholder?`           | `string`                                                                              | Placeholder text for the input.                                                                                                                                                                                                                  |
| `prefix?`                | `ReactNode`                                                                           | Element shown before the input value.                                                                                                                                                                                                            |
| `ref?`                   | `Ref<HTMLDivElement> \| undefined`                                                    | Forwarded to the field's root element. Use `inputRef` for the input.                                                                                                                                                                             |
| `size?`                  | `TextInputSize`                                                                       | Control size. Default: `'medium'`                                                                                                                                                                                                                |
| `suffix?`                | `ReactNode`                                                                           | Element shown after the input value.                                                                                                                                                                                                             |

#### Type definitions

These are the types that this table's signatures and the definitions below name. TypeScript's built-in types, such as `Omit` and `ReadonlyArray`, are not listed.

##### `NecessityIndicator`

```ts
type NecessityIndicator = 'required-asterisk'
  | 'required-label'
  | 'optional-label';
```

##### `TextInputSize`

```ts
type TextInputSize = NonNullable<TextInputRecipeVariants['size']>;
```

Which resolves to:

```ts
"medium" | "small"
```

Refers to `TextInputRecipeVariants['size']`.

##### `TextInputRecipeVariants['size']`

Resolves to:

```ts
"medium"
  | "small"
  | undefined
```

##### `ClipboardEventHandler`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type ClipboardEventHandler<T = Element> = EventHandler<ClipboardEvent<T>>;
```

Refers to `EventHandler` and `ClipboardEvent`.

##### `EventHandler`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `ClipboardEvent`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `CompositionEventHandler`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type CompositionEventHandler<T = Element> = EventHandler<CompositionEvent<T>>;
```

Refers to `EventHandler` and `CompositionEvent`.

##### `CompositionEvent`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `ReactEventHandler`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;
```

Refers to `EventHandler` and `SyntheticEvent`.

##### `SyntheticEvent`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `FormEventHandler`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type FormEventHandler<T = Element> = EventHandler<FormEvent<T>>;
```

Refers to `EventHandler` and `FormEvent`.

##### `FormEvent`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `KeyboardEvent`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/events.d.ts`).

```ts
type KeyboardEvent = BaseEvent<ReactKeyboardEvent<any>>;
```

Refers to `BaseEvent` and `KeyboardEvent` from `@types/react`.

##### `BaseEvent`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/events.d.ts`).

##### `KeyboardEvent` from `@types/react` (written as `ReactKeyboardEvent`)

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `FocusEvent`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `ReactNode`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type ReactNode = ReactElement
  | string
  | number
  | bigint
  | Iterable<ReactNode>
  | ReactPortal
  | boolean
  | null
  | undefined
  | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES[keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES]
  | Promise<AwaitedReactNode>;
```

Refers to `ReactElement`, `ReactPortal`, `DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES`, and `AwaitedReactNode`.

##### `ReactElement`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `ReactPortal`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `AwaitedReactNode`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `ClassNameOrFunction`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/utils.d.ts`).

```ts
type ClassNameOrFunction<T> = string | ((values: T & {
  defaultClassName: string | undefined;
}) => string);
```

##### `TextFieldRenderProps`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/TextField.d.ts`).

##### `ValidationError`

Declared in [`@react-types/shared`](https://www.npmjs.com/package/@react-types/shared) (`src/inputs.d.ts`).

```ts
type ValidationError = string | string[];
```

##### `InputRenderProps`

Declared in [`react-aria-components`](https://www.npmjs.com/package/react-aria-components) (`dist/types/src/Input.d.ts`).

##### `Ref`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

```ts
type Ref<T> = RefCallback<T>
  | RefObject<T | null>
  | null;
```

Refers to `RefCallback` and `RefObject`.

##### `RefCallback`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).

##### `RefObject`

Declared in [`@types/react`](https://www.npmjs.com/package/@types/react) (`index.d.ts`).
