Select

A listbox, not a native <select>. That buys grouping, status dots and consistent styling across platforms — and costs the keyboard and dismissal behaviour that the native element gives away for free, so those are implemented rather than skipped.

Basic

Arrow keys move, Enter or Space commits, Escape closes, and a click anywhere outside dismisses. Those four are what people mean when they say a custom select 'feels broken'.

Groups and disabled options

Group headings come from the option data — a heading is never a selectable row, which is a common failure in hand-rolled listboxes.

Status dots

dotColor takes a token reference, not a hex. Pass var(--data-positive) and the dot follows the theme like everything else.

Sizes and disabled