# Select

> One choice among several: a button holding the current choice, which opens the options in a list.

A select holds one choice among several, shown as a button with the current
choice that opens the options in a list. It takes little room, and shows the
alternatives only when they are wanted.

## When to use

Use a select for a choice of one among more options than fit comfortably in
view, where the current choice matters more than the alternatives. When people
benefit from seeing all the options, or choose several, use a
[listbox](https://ui.publictheta.com/components/listbox.md). For commands rather than a value, use a
[menu](https://ui.publictheta.com/components/menu.md).

## Best practices

**Show the current choice on the button**, in the option's own words. With
nothing chosen, say what is being chosen.

**Open on the current choice.** The list opens with the chosen option under
focus, so the alternatives nearest it are a key press away.

**Let people look without choosing.** Moving through the options changes
nothing; Return, Space or a click chooses. Escape, Tab and a press outside close
the list and leave the choice as it was.

**Mark the choice; fill the highlight.** In the open list the chosen option
carries a mark, and the filled highlight follows the pointer or the keys, so
the two are never mistaken for each other.

**Choose without opening.** On the closed button, typing the start of an
option's name chooses it, as a platform's own popup button does.

**Show a choice that cannot be changed as one.** A select that is read-only
shows its choice, says that it is read-only, and does not open.

**Take part in a form.** A select with a name submits its chosen value, and a
label that names the button names the list too.

**Order options meaningfully**, and group them under headings when they fall
into kinds.

**Disable rather than hide** an option that is unavailable at the moment.

## Interaction

| Intent                    | Pointer                                          | Keyboard                              | Touch          |
| ------------------------- | ------------------------------------------------ | ------------------------------------- | -------------- |
| Open                      | Press the button                                 | Return, Space, Down Arrow or Up Arrow | Tap the button |
| Move between options      | Move the pointer                                 | Up and Down Arrow, Home, End          | —              |
| Move to an option by name | —                                                | Type its first letters                | —              |
| Choose                    | Click, or release after dragging from the button | Return or Space                       | Tap an option  |
| Choose while closed       | —                                                | Type an option's first letters        | —              |
| Close without choosing    | Click outside, or the button                     | Escape; Tab also moves on             | Tap outside    |

## Platform considerations

**Pointer and keyboard.** The list opens beneath its button, at least as wide.

**Touch.** On a phone the list rises from the bottom edge as a sheet; options
are at least 44 CSS pixels tall.

**Assistive technology.** The button states its name, its current choice and
that it opens a list; the options are a listbox of the same name, with the
chosen option selected.

See also [Overlays](https://ui.publictheta.com/foundations/overlay.md) and [Listbox](https://ui.publictheta.com/components/listbox.md).

## Behaviour

Each statement is verified by a test in Chromium, Chromium (touch), Firefox, WebKit, WebKit (touch), unless it names the environments it applies to or is marked open.

### Semantics

- The button names what is chosen from, shows the current choice, and says it opens a list.
- With nothing chosen, it shows its placeholder.
- The options are a listbox with the same name, the chosen one selected.
- The button states which list it controls.
- A label that names the button names the list too.
- Pressing the label of an open list closes it, rather than closing and reopening.
- Has no accessibility violations, closed or open.

### Opening

- A click opens the list with focus on the chosen option.
- Opened again, it is on the chosen option, not where the pointer last was. *(Chromium, Firefox, WebKit)*
- With nothing chosen, focus is on the first option.
- Enter, Space, Down Arrow and Up Arrow open it from the keyboard.
- The list is at least as wide as its button. *(Chromium, Firefox, WebKit)*

### Choosing

- Moving through the options chooses nothing.
- Enter chooses the focused option, closes the list and returns focus to the button.
- Space chooses too.
- A click chooses an option and closes the list.
- Choosing the option already chosen changes nothing and closes the list.
- An unavailable option is passed over and cannot be chosen.
- Typing moves to the option that starts with what was typed.
- The pointer moves the highlight with it.
- A space is part of a word being typed, and chooses nothing.
- A key held down opens the list and chooses nothing.
- Pressing the button, dragging to an option and releasing chooses it. *(Chromium, Firefox, WebKit)*
- Pressing the button and releasing it leaves the list open. *(Chromium, Firefox, WebKit)*
- Typing on the closed button changes the choice without opening the list.
- A click that no press came before, as assistive technology makes, chooses the option.

### Dismissal

- Escape closes the list without choosing, and returns focus to the button.
- Tab closes the list without choosing, and moves on.
- A press outside closes the list without choosing.

### Touch

- A tap opens the list as a sheet, and a tap on an option chooses it. *(Chromium (touch), WebKit (touch))*

## Reference implementation

React: `npx shadcn@latest add https://ui.publictheta.com/r/select.json`
