# Select Field (/components/forms/select-field)



Use `SelectField` when someone chooses one option from a predefined list. It combines a trigger
button, label, description, validation message, popover, and listbox. Use
[`ComboboxField`](/components/forms/combobox-field) instead when searching or filtering the options
helps.

apps/docs/src/examples/select-field/basic.tsx

```tsx
import { SelectField, SelectItem } from '@luke-ui/react/select-field';
import { Stack } from '@luke-ui/react/stack';

const themes = [
	{ id: 'system', label: 'System' },
	{ id: 'light', label: 'Light' },
	{ id: 'dark', label: 'Dark' },
];

export default () => {
	return (
		<Stack gap="sp16" maxInlineSize="20rem">
			<SelectField
				defaultValue="system"
				items={themes}
				label="Theme"
				name="theme"
				placeholder="Choose a theme"
			>
				{(item) => <SelectItem>{item.label}</SelectItem>}
			</SelectField>
		</Stack>
	);
};
```

## Items and selection [#items-and-selection]

Pass `items` and a render function that returns a `SelectItem` for each one. Import `SelectItem`
from `@luke-ui/react/select-field`.

Each option needs a stable id. Give each item in `items` an `id` or `key`, or give each `SelectItem`
an `id` when your data has neither. When the items carry an `id` or `key`, `value`, `onChange`, and
`validate` use the inferred key type, so string ids give `string | null` for `value` and `string`
for `validate`. Otherwise selection values use `Key | null`, and `validate` receives `Key`. React
Aria doesn't call `validate` while nothing is selected.

For a fixed set of options, pass `SelectItem` children with an `id` each instead of `items`.

`SelectField` holds one selected option and has no clear button. An option labelled “None” is a
choice like any other: selecting it selects its key and doesn't empty the field.

Pass `defaultValue` to start with an option selected. Pass `value` and `onChange` to control the
selection yourself. `onChange` receives the selected key, or `null` when nothing is selected, and
`value` takes the same type.

apps/docs/src/examples/select-field/controlled.tsx

```tsx
import { SelectField, SelectItem } from '@luke-ui/react/select-field';
import { Stack } from '@luke-ui/react/stack';
import { Text } from '@luke-ui/react/text';
import { useState } from 'react';

const sizes = [
	{ id: 'small', label: 'Small' },
	{ id: 'default', label: 'Default' },
	{ id: 'large', label: 'Large' },
];

export default () => {
	const [size, setSize] = useState<string | null>('default');

	return (
		<Stack gap="sp16" maxInlineSize="20rem">
			<SelectField items={sizes} label="Text size" onChange={setSize} value={size}>
				{(item) => <SelectItem>{item.label}</SelectItem>}
			</SelectField>
			<Text color="secondary" elementType="p" role="status">
				{`Selected key: ${size ?? 'none'}`}
			</Text>
		</Stack>
	);
};
```

## Required fields [#required-fields]

Set `isRequired` to make a selection mandatory. Use `necessityIndicator` to choose how it appears
beside the label.

apps/docs/src/examples/select-field/required.tsx

```tsx
import { SelectField, SelectItem } from '@luke-ui/react/select-field';

const countries = [
	{ id: 'australia', label: 'Australia' },
	{ id: 'canada', label: 'Canada' },
	{ id: 'new-zealand', label: 'New Zealand' },
];

export default () => {
	return (
		<SelectField
			description="Choose the country where you work."
			isRequired
			items={countries}
			label="Work location"
			name="workLocation"
			necessityIndicator="icon"
			placeholder="Choose a country"
		>
			{(item) => <SelectItem>{item.label}</SelectItem>}
		</SelectField>
	);
};
```

## Validation [#validation]

Set `isRequired` or pass `validate` to check the selected key. `SelectField` 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/select-field/validation.tsx

```tsx
import { Button } from '@luke-ui/react/button';
import { Cluster } from '@luke-ui/react/cluster';
import { SelectField, SelectItem } from '@luke-ui/react/select-field';
import { Stack } from '@luke-ui/react/stack';
import type { SubmitEvent } from 'react';

const countries = [
	{ id: 'australia', label: 'Australia' },
	{ id: 'canada', label: 'Canada' },
	{ id: 'new-zealand', label: 'New Zealand' },
];

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

	return (
		<form onSubmit={handleSubmit}>
			<Stack gap="sp16" maxInlineSize="20rem">
				<Stack minBlockSize="5.5rem">
					<SelectField
						isRequired
						items={countries}
						label="Work location"
						name="workLocation"
						placeholder="Choose a country"
					>
						{(item) => <SelectItem>{item.label}</SelectItem>}
					</SelectField>
				</Stack>
				<Cluster>
					<Button type="submit">Create account</Button>
				</Cluster>
			</Stack>
		</form>
	);
};
```

To move focus to the trigger yourself, pass `triggerRef`. `ref` reaches the root element.

## Disabled, pending, and fixed values [#disabled-pending-and-fixed-values]

`SelectField` has no read-only state. Show a value that can't change as text instead.

Set `isDisabled` to block the field. A disabled field can't take focus and doesn't submit its value.

Pass `isPending` while a change is saving. The trigger keeps focus but can't be pressed or opened,
and can't change the value from the trigger, until pending ends.

## Size [#size]

Use `size` to set the control height and typography. Use `small` in compact layouts. `medium` is the
default.

apps/docs/src/examples/select-field/sizes.tsx

```tsx
import { SelectField, SelectItem } from '@luke-ui/react/select-field';
import { Comparison, ComparisonItem } from '#docs';

const options = [
	{ id: 'one', label: 'Example option' },
	{ id: 'two', label: 'Another option' },
];

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Small">
				<SelectField
					items={options}
					label="Example field"
					name="example"
					placeholder="Choose an option"
					size="small"
				>
					{(item) => <SelectItem>{item.label}</SelectItem>}
				</SelectField>
			</ComparisonItem>
			<ComparisonItem label="Medium">
				<SelectField
					items={options}
					label="Example field"
					name="example"
					placeholder="Choose an option"
					size="medium"
				>
					{(item) => <SelectItem>{item.label}</SelectItem>}
				</SelectField>
			</ComparisonItem>
		</Comparison>
	);
};
```

## Accessibility [#accessibility]

The select needs an accessible name. Use the visible `label`. Without one, pass `aria-labelledby` to
point at content already on the page, or `aria-label` to supply the name directly. A `placeholder`
doesn't name the field.

## API [#api]

### SelectFieldProps [#selectfieldprops]

### SelectFieldProps

Props for `SelectField`.

`SelectFieldProps` 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.                                                                        |
| `onKeyDown?`          | `function`  | Handler that is called when a key is pressed.                                                                                                                             |
| `onKeyUp?`            | `function`  | Handler that is called when a key is released.                                                                                                                            |
| `onFocus?`            | `function`  | Handler that is called when the element receives focus.                                                                                                                   |
| `onBlur?`             | `function`  | Handler that is called when the element loses focus.                                                                                                                      |
| `onFocusChange?`      | `function`  | Handler that is called when the element's focus status changes.                                                                                                           |
| `description?`        | `ReactNode` | Optional helper text shown below the control.                                                                                                                             |
| `necessityIndicator?` | `union`     | Label necessity style. Default: `'icon'`                                                                                                                                  |
| `label?`              | `union`     | 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`    |                                                                                                                                                                           |
| `autoComplete?`       | `string`    | Describes the type of autocomplete the browser may offer for the hidden form control.                                                                                     |
| `autoFocus?`          | `union`     | Whether the select should receive focus on render.                                                                                                                        |
| `form?`               | `string`    | The `<form>` element to associate the select with, by id.                                                                                                                 |
| `isDisabled?`         | `union`     | Whether the select is disabled.                                                                                                                                           |
| `isRequired?`         | `union`     | Whether a selection is required before the form can submit.                                                                                                               |
| `name?`               | `string`    | The name of the select, used when submitting an HTML form.                                                                                                                |
| `validationBehavior?` | `union`     | When native HTML form validation runs. Default: `'native'`                                                                                                                |
| `id?`                 | `string`    | Element id for the root element. Use `triggerId` for the trigger button.                                                                                                  |
| `placeholder?`        | `string`    | Text shown in the `SelectValue` while nothing is selected.                                                                                                                |
| `size?`               | `union`     | Sets the size of the trigger, indicator, and items. Default: `'medium'`                                                                                                   |
| `triggerId?`          | `string`    | Element id for the trigger button. The root generates one when omitted.                                                                                                   |
| `children`            | `union`     | The options. Pass a render function that returns a `SelectItem` for each of `items`, or pass static `SelectItem` children.                                                |
| `defaultValue?`       | `union`     | The initially selected key (uncontrolled). The key type follows the `id` or `key` of the items in `items`.                                                                |
| `errorMessage?`       | `ReactNode` | Validation message for a controlled error. A non-empty message marks the field invalid.                                                                                   |
| `isPending?`          | `union`     | Whether the field is pending. The trigger keeps focus but can't be pressed or opened, and can't change the value from the trigger, until pending ends.                    |
| `items?`              | `object`    | Options for the render function in `children`.                                                                                                                            |
| `onChange?`           | `function`  | Called with the new key when the selection changes.                                                                                                                       |
| `ref?`                | `union`     | Forwarded to the field's root element. Use `triggerRef` for the trigger.                                                                                                  |
| `triggerRef?`         | `union`     | Forwarded to the trigger `<button>` element. Accepts a callback ref or a ref object. Use `ref` for the root element.                                                      |
| `validate?`           | `function`  | Custom validation function run against the selected key. Return a message, or `true`/`null` when valid. The key type follows the `id` or `key` of the items in `items`.   |
| `value?`              | `union`     | The selected key (controlled). Pass `null` for no selection.                                                                                                              |


### SelectItemProps [#selectitemprops]

### SelectItemProps

Props for `SelectItem`.

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

| Prop              | Type                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ----------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `href?`           | `string`                     | A URL to link to. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#href).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `hrefLang?`       | `string`                     | Hints at the human language of the linked URL. See[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#hreflang).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `target?`         | `union`                      | The target window for the link. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `rel?`            | `string`                     | The relationship between the linked resource and the current page. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel).                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `download?`       | `union`                      | Causes the browser to download the linked URL. A string may be provided to suggest a file name. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download).                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `ping?`           | `string`                     | A space-separated list of URLs to ping when the link is followed. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#ping).                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `referrerPolicy?` | `union`                      | How much of the referrer to send when following the link. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#referrerpolicy).                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `onKeyDown?`      | `function`                   | Handler that is called when a key is pressed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `onKeyUp?`        | `function`                   | Handler that is called when a key is released.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `onFocus?`        | `function`                   | Handler that is called when the element receives focus.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `onBlur?`         | `function`                   | Handler that is called when the element loses focus.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `onFocusChange?`  | `function`                   | Handler that is called when the element's focus status changes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `onHoverStart?`   | `function`                   | Handler that is called when a hover interaction starts.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `onHoverEnd?`     | `function`                   | Handler that is called when a hover interaction ends.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `onHoverChange?`  | `function`                   | Handler that is called when the hover state changes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `onPress?`        | `function`                   | Handler that is called when the press is released over the target.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `onPressStart?`   | `function`                   | Handler that is called when a press interaction starts.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `onPressEnd?`     | `function`                   | Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `onPressChange?`  | `function`                   | Handler that is called when the press state changes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `onPressUp?`      | `function`                   | Handler that is called when a press is released over the target, regardless of whether it started on the target or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `children?`       | `ChildrenOrFunction<object>` | The children of the component. A function may be provided to alter the children based on component state.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `render?`         | `function`                   | Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Note: You can check if `'href' in props` in order to tell whether to render an `<a>` element. Requirements: - You must render the expected element type (e.g. if `<a>` is expected, you cannot render a `<button>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate. |
| `id?`             | `union`                      | The unique id of the item.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `textValue?`      | `string`                     | A string representation of the item's contents, used for features like typeahead.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `aria-label?`     | `string`                     | An accessibility label for this item.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `isDisabled?`     | `union`                      | Whether the item is disabled.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `onAction?`       | `function`                   | Handler that is called when a user performs an action on the item. The exact user event depends on the collection's `selectionBehavior` prop and the interaction modality.                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `className?`      | `union`                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
