Components
Select
Token-driven dropdown built on the WAI-ARIA listbox pattern with full keyboard support.
Behavior
Select follows the WAI-ARIA listbox pattern: a trigger button
(aria-haspopup="listbox") opens a focusable role="listbox", with the active
option tracked via aria-activedescendant. It is fully keyboard-operable and
has no runtime dependencies.
| Key | Action |
|---|---|
Enter / Space / ↓ | Open the menu |
↑ / ↓ | Move between options (skips disabled) |
Home / End | Jump to first / last enabled option |
Enter / Space | Select the active option |
Escape | Close and restore focus to the trigger |
Clicking outside the control closes it. Disabled options are skipped by keyboard navigation and cannot be selected.
Usage
import { Select } from '@cajon-ui/react';
const [period, setPeriod] = useState('year');
<Select
aria-label="Period"
options={[
{ value: 'year', label: 'This Year' },
{ value: 'quarter', label: 'This Quarter' },
{ value: 'month', label: 'This Month' },
]}
value={period}
onChange={setPeriod}
/>Props
| Prop | Type | Default | Notes |
|---|---|---|---|
options | SelectOption[] | — | { value, label, disabled? } choices, in display order |
value | string | — | Currently-selected value (controlled) |
onChange | (value: string) => void | — | Called with the chosen option's value |
placeholder | string | Select… | Trigger text when nothing is selected |
variant | pill | outlined | pill | Trigger shape |
size | sm | md | md | Trigger size |
leadingIcon | ReactNode | — | Rendered before the trigger label |
fullWidth | boolean | false | Stretch to fill the container |
disabled | boolean | false | Disable the control |
aria-label | string | — | Accessible label for the trigger + listbox |