@bimetal/picker-headless
v0.42.0
Published
Canonical, framework-agnostic picker/combobox controller (createPickerController) on @bimetal/headless-core. The family's first CONTROLLER-ONLY component — NO aggregate, NO event-sourcing: options are injected, selection is transient. Single/multi select,
Maintainers
Readme
@bimetal/picker-headless
The canonical, framework-agnostic picker controller — instance #8 of the
BIMETAL component family. Built on @bimetal/headless-core, so it shares the
identity-stable getSnapshot/subscribe contract and the errors-as-state
surface; the framework packages are pure bindings.
createPickerController is the family's first controller-only component:
NO aggregate, NO event sourcing. Options are injected, selection is transient —
because "which option is highlighted" is not a domain fact.
Single/multi select, type-to-filter, keyboard navigation, a max cap, grouped and
virtualized lists, create-new, async loading, and the combobox/listbox a11y
contract (aria-activedescendant, never roving focus).
The selection can also be controlled from outside: setSelection(ids) replaces
it without rebuilding the picker (focus, open popup and query stay), and
onSelectionChange(ids, origin) reports it with origin: 'external' — never
'user' — so a consumer can tell its own changes from user input. In multi mode,
config.maxVisibleChips: n collapses everything past the first n chips into one
+k marker (snapshot.visibleChips / snapshot.chipOverflow, with an accessible
label naming the hidden values).
The cut line is the family's: DOM measurement and listener registration belong
to the framework; every if belongs here.
