Jump to a component
Core · Forms
Select
A labelled single-choice control that opens a list. Shows the chosen value with an optional leading icon.
Live, from @anicanon/sakuga 2.0.0
Sakuga for iOS and Android is coming
iOS
Coming soon
Select for iOS is in the roughs. The tokens it will read are the ones on this page, the same on every platform.
Android
Coming soon
Select for Android is in the roughs. The tokens it will read are the ones on this page, the same on every platform.
- Use it for
- One choice from a short list of plain values, in a labelled field that opens the list: a faction, with its icon.
- Not for
- One thing among many, with search and groupsPicker
- Two to four named values seen at onceSegmentedControl
- A choice that is clearer seen than readOptionTiles
- A colour chosen by eyeSwatchPicker
Guidelines
States
- Closed: the field shows the chosen value and a chevron.
- Open: the field edge turns
select-open-border, the chevron flips, and a menu drops in under it onselect-menu-bg. The chosen option sits onselect-option-selected-bgwith a check; hover isselect-option-hover-bg. The menu is alistboxand each row anoption, so arrow keys and screen readers work as a native select. - Empty: the placeholder in
field-placeholder.
On phones, prefer the platform picker (an iOS menu or an Android dropdown menu) and keep this field as its trigger.
Motion: the menu drops from the field on motion-fast with ease-enter and leaves on motion-instant with ease-exit. Escape or a press outside closes it. Sound: with sound on, the menu plays the open sound as it drops and the close sound as it leaves; picking an option plays the choose sound instead of the close (README · Sound).
import { Select } from '@anicanon/sakuga/ui';
const factions = [
{ label: 'Heros', icon: 'faction-hero', hint: '8' },
{ label: 'E.R.A.', icon: 'faction-villain', hint: '8' },
{ label: 'Unaligned', icon: 'faction-independent', hint: '7' },
];
export default function SelectExample() {
return (
<>
<Select
label="Faction · closed"
value="Heros"
options={factions}
hint="Who he stands with."
/>
<Select label="Faction · open" value="Heros" options={factions} open />
</>
);
}PropsSelectProps
valuestringplaceholderstringiconIconNameoptionsSelectOption[]highlightbooleanopenbooleanonChange(value: string) => voididstringFrom FieldShellProps
labelstringhintstringoptionalbooleanhelp{ title?: string; text: ReactNode; }maxWidthnumberclassNamestringAn IconName is any of the names Icon lists.
Types
interface SelectOption { label: string; value?: string; icon?: IconName; hint?: string; }
Each token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.
Colour
select-open-borderSelect: the edge of a select whose menu is open.accentcamellia-600#c2335faccentcamellia-400#f4779fselect-menu-bgSelect: the open menu.bg-surface-raisedneutral-100#ececf0bg-surface-raisedneutral-875#1a1a21select-menu-borderSelect: the open menu edge.border-dividershade-a12rgba(11,10,16,0.12)border-dividerwhite-a12rgba(255,255,255,0.12)select-option-hover-bgSelect: an option under the pointer.bg-fill-subtleshade-a06rgba(11,10,16,0.06)bg-fill-subtlewhite-a08rgba(255,255,255,0.08)select-option-selected-bgSelect: the chosen option.bg-fill-selectedshade-a08rgba(11,10,16,0.08)bg-fill-selectedwhite-a12rgba(255,255,255,0.12)select-option-checkSelect: the check beside the chosen option.accentcamellia-600#c2335faccentcamellia-400#f4779fSpace and shape
select-gapgap-mdselect-value-gapgap-mdselect-expanded-inset-ring-widthline-strongselect-menu-topinset-xsselect-menu-paddinginset-xsselect-menu-max-heightselect-menu-radiusradius-mdselect-menu-inset-ring-widthline-hairlineselect-option-active-scalescale-press-lgselect-option-gapgap-mdselect-option-min-heightsize-control-smselect-option-padding-xinset-smselect-option-radiusradius-smselect-option-small-check-margin-leftgap-mdselect-value-icon-sizeicon-size-mdselect-chevron-icon-sizeicon-size-smselect-option-icon-sizeicon-size-smselect-check-icon-sizeicon-size-smselect-forced-edge-widthline-hairlineselect-forced-open-widthline-strongType
select-option-fonttext-bodyselect-option-selected-font-weightweight-strongselect-option-small-fonttext-smallMotion
select-chevron-durationmotion-fastselect-chevron-easingease-standardselect-menu-drop-in-animationmotion-drop-inselect-option-easingease-standardselect-option-active-durationmotion-instantselect-option-durationmotion-instantselect-menu-leaving-drop-out-animationmotion-drop-outChecked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.
- Result
- No issues found, in light or in dark.
- By design
- A select-only combobox named by the words of
labeltogether with its value ("Faction Heros"), else byplaceholder, and described byhint; Tab reaches it, and focus stays on it while its list is open. Down, Up, Enter or Space open the list, the arrows, Home, End and a first letter move the active option (read as the active descendant, "selected" on the chosen one), Enter or Space picks it, and Escape or Tab closes the list. The active option is kept in view, and with nooptionsthe field is unavailable. - Not tested
- The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.