List
Shared primitive for option lists. Used internally by Select, Dropdown (combobox), MultiSelect, Menu, the Phone input's country picker, and Datepicker's month/year selects. The slots, modes, and keyboard behaviour documented below are what each of those consumers inherits.
a11y (built in): LB.List applies the roles itself — role="listbox" (or menu under data-lb-list-mode="menu") on the items container, role="option"/menuitem per item, aria-multiselectable in multi mode, aria-disabled mirrored from the item's disabled class at mount, and aria-selected kept in sync on every toggle; auto-inserted separators get role="separator" like the authored ones. Keyboard is ↑/↓ (wrapping), Home/End and Enter/Space to select, and it skips disabled and filtered-out items — on a filterable list the same keys are bound to the search field so you can type and arrow without re-tabbing. Items are given stable ids and each highlight move fires lb-list-active-change, so the owning combobox (Command Palette) points aria-activedescendant at the active option while focus stays in the input — the list never steals it.
Usage: Root .lb-list on a <ul> (or <div>). Items are .lb-list__item — <li>, <button>, or <a>. Opt-in keyboard + selection behaviour with data-lb-list; set mode via data-lb-list-mode="single|multi|menu". Filterable lists add data-lb-list-filterable. The container is not focusable on its own — put tabindex="0" and an aria-label on it when the list itself is the tab stop, as the demos below do.
Simple
Plain items. No interactions unless wired. Use when rendering read-only lists (recent activity, navigation options).
With icons
Leading icon slot (.lb-list__icon). Useful for category lists, country pickers, or menus with visual hints.
Single-select
Arrow keys navigate, Enter/Space selects, Home/End jump. Dispatches lb-list-select with { value, item }. Tab into the list to try it.
Last selected: banana
Multi-select
Checkbox on each item. Clicking toggles, keyboard Enter toggles. Dispatches lb-list-select; consumers call list.getSelected(). This demo also opts into data-lb-list-sort-selected — selected items float to the top with an auto-separator, alphabetical within each group; order stays stable while you toggle (re-sorts only on mount + list.refresh()).
Selected: basil, cheese
Filterable
Pinned search input at top filters items by textContent substring. Keyboard nav stays on the search input so you can type + arrow-select without re-tabbing. Empty result renders .lb-list__no-results. Uses our regular .lb-input + data-lb-clearable so the X button is the same custom component used everywhere else in the DS.
Stacked items (label + subtext)
Use .lb-list__stack instead of .lb-list__label when you need a primary + secondary line (team members, contacts, search results).
Menu-style (separator + danger + hint)
For action-menu styling. data-lb-list-mode="menu" swaps the roles to menu/menuitem and moves a highlight class — it never moves focus and does not handle Esc; use Menu for a popup menu with focus management. Add .lb-list__separator between groups, --danger for destructive, .lb-list__hint for keyboard shortcuts.