import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="Forms/SelectInput/Accessibility" />

# Accessibility

## Keyboard navigation

The component uses [Headless UI Listbox](https://headlessui.com/react/listbox) under the hood, which provides full keyboard support out of the box.

<table>
  <thead>
    <tr>
      <th>Key</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <code>Tab</code> / click
      </td>
      <td>Focus the trigger button</td>
    </tr>
    <tr>
      <td>
        <code>Enter</code> / <code>Space</code>
      </td>
      <td>Open the listbox</td>
    </tr>
    <tr>
      <td>
        <code>↑</code> / <code>↓</code>
      </td>
      <td>Navigate options</td>
    </tr>
    <tr>
      <td>
        <code>Enter</code>
      </td>
      <td>Select the focused option</td>
    </tr>
    <tr>
      <td>
        <code>Escape</code> / <code>Tab</code>
      </td>
      <td>Close without selecting</td>
    </tr>
    <tr>
      <td>
        Typing (when <code>filterable</code>)
      </td>
      <td>
        Narrows the list in the search input; <code>↑</code> / <code>↓</code> still navigate the
        filtered results
      </td>
    </tr>
  </tbody>
</table>

## Labelling

In order for the `<SelectInput />` to be considered accessible, it must be provided with a matching label, preferably via the <a href="/?path=/docs/field--docs">Field</a> component.

Additionally, the `listbox` container that holds all the options is also expected to have its own label, which the component will attempt to resolve by looking in the following places:

1. `UNSAFE_triggerButtonProps['aria-label']` prop, which reuses the custom label provided for the trigger button.
   <br /> A good example of this strategy is the `<MoneyInput />` component, internally setting
   `"Select currency"` as a trigger button label, which then gets automatically applied to the
   `listbox`.
2. `UNSAFE_triggerButtonProps['aria-labelledby']` prop, which holds the id of the element labelling the trigger button.
3. Correctly paired input `<label />` text, ideally via the `Field` component.

> Using option group heading is possible but complicated as we can have multiple groups, and those are not necessarily rendered consistently if search or virtualisation are enabled.

## Custom triggers

When using `renderTrigger`, the interactive element **must** be `SelectInputTriggerButton`. A plain `<button>` will not receive the ARIA attributes (`aria-expanded`, `aria-haspopup`, `aria-controls`) that the component manages, breaking screen reader announcements for the listbox state.

## Multiple selection

With `multiple`, selected items show a visible checkmark in the list. The trigger content is **consumer-controlled** via the `withinTrigger` boolean passed to `renderValue` — consumers are responsible for communicating the current selection accessibly inside the trigger (e.g. `"USD, EUR"` or `"3 currencies selected"`).
