bit Bheadless

Listbox

An accessible custom select with single/multi-select, full keyboard navigation, and typeahead.

Implementation: CSS Tailwind

Basic Listbox

Click the button or press Space / Enter / arrow keys to open. Use Up / Down to navigate, Home / End to jump, Enter / Space to select, Escape to close, or simply type to jump to an option. ARIA wiring (combobox, listbox, aria-activedescendant) is handled for you.

Selected: (none)

Multi-select

Set Multiple="true" to allow selecting many values. The panel stays open after each selection. The button label here renders the joined names.

Selected:

Disabled Options

Mark individual options with Disabled="true". They render with data-disabled for CSS, are skipped by arrow-key nav, and ignore typeahead matches.

Custom Option Content

Options can render any markup. Use the data-active and data-selected hooks to drive the highlighted and selected styles. Provide a Label string when your content is rich so typeahead still matches sensibly.

Anchor Positioning

Set Anchor on BitBhListboxOptions to automatically position the dropdown relative to the button using position: fixed. The panel flips to the opposite side when there's not enough space, shifts to stay within the viewport, and auto-updates on scroll/resize. The CSS variable --button-width is exposed so you can match the dropdown width to the trigger. No position: relative on the parent is needed.

Bottom Start (width matched)

Top Start (flips down if no space)

Selected: (none)

Form Submission

Set Name on the listbox and the selection participates in plain HTML form posts. In multi-select mode a separate hidden input is rendered for each value.

Large lists (virtualized)

For thousands of options, pass the data through Items and render each option with an ItemTemplate. Virtualize="true" renders only the options in view — give the panel a fixed height with overflow-y: auto and make every option exactly ItemSize pixels tall. Options still get aria-setsize / aria-posinset, and arrow keys, Home / End and typeahead reach all 10,000. With no content, BitBhListboxButton shows the selected option's text or its Placeholder (and emits data-placeholder).

Selected: (none)
An unhandled error has occurred. Reload 🗙