Collections

ListBox

A listbox displays a list of options and allows a user to select one or more of them

Completeness: behavior-required

The stylesheet is only the visible half of this component. It also needs a keyboard map, focus managed across more than one element, ARIA attributes that point at other nodes, and [data-*] attributes that only running code sets — so a CSS-only port will not reproduce it. Use @blakeui/react, or read the interaction contract from the MCP server with get_component_behavior("ListBox") and build the behaviour yourself.

Import

import { ListBox } from '@blakeui/react';

Usage

B
bob@blakeui.com
F
fred@blakeui.com
M
martha@blakeui.com
import {Avatar, Description, Label, ListBox} from "@blakeui/react";

export function Default() {
  return (
    <ListBox aria-label="Users" className="w-[220px]" selectionMode="single">

Anatomy

Import the ListBox component and access all parts using dot notation.

import { ListBox, Label, Description, Header } from '@blakeui/react';

export default () => (
  <ListBox>
    <ListBox.Item>
      <Label />
      <Description />
      <ListBox.ItemIndicator />
    </ListBox.Item>
    <ListBox.Section>
      <Header />
      <ListBox.Item>
        <Label />
      </ListBox.Item>
    </ListBox.Section>
  </ListBox>
)

With Sections

Create a new file
⌘N
Make changes
⌘E
Move to trash
⌘⇧D
"use client";

import {Description, Header, Kbd, Label, ListBox, Separator, Surface} from "@blakeui/react";
import {Pencil, SquarePlus, TrashBin} from "@gravity-ui/icons";

Multi Select

B
bob@blakeui.com
F
fred@blakeui.com
M
martha@blakeui.com
import {Avatar, Description, Label, ListBox, Surface} from "@blakeui/react";

export function MultiSelect() {
  return (
    <Surface className="w-[256px] rounded-3xl shadow-surface">

With Disabled Items

Create a new file
⌘N
Make changes
⌘E
Move to trash
⌘⇧D
"use client";

import {Description, Header, Kbd, Label, ListBox, Separator, Surface} from "@blakeui/react";
import {Pencil, SquarePlus, TrashBin} from "@gravity-ui/icons";

Custom Check Icon

B
bob@blakeui.com
F
fred@blakeui.com
M
martha@blakeui.com
"use client";

import {Avatar, Description, Label, ListBox, Surface} from "@blakeui/react";
import {Check} from "@gravity-ui/icons";

Controlled

B
bob@blakeui.com
F
fred@blakeui.com
M
martha@blakeui.com

Selected: 1

"use client";

import type {Selection} from "@blakeui/react";

import {Avatar, Description, Label, ListBox, Surface} from "@blakeui/react";

Custom Render Function

B
bob@blakeui.com
F
fred@blakeui.com
M
martha@blakeui.com
"use client";

import {Avatar, Description, Label, ListBox} from "@blakeui/react";

export function CustomRenderFunction() {

Virtualization

ListBox supports virtualization through Virtualizer, enabling efficient rendering of large datasets by displaying only the rows visible within the viewport.

"use client";

import {Description, Label, ListBox, ListLayout, Virtualizer} from "@blakeui/react";

interface User {

Styling

Passing Tailwind CSS classes

import { ListBox } from '@blakeui/react';

function CustomListBox() {
  return (
    <ListBox className="border rounded-lg p-2 bg-surface">
      <ListBox.Item id="1" textValue="Item 1" className="hover:bg-surface-secondary">
        Item 1
      </ListBox.Item>
    </ListBox>
  );
}

Customizing the component classes

To customize the ListBox component classes, you can use the @layer components directive.
Learn more.

A worked example is in Styling.

blakeUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The ListBox component uses these CSS classes (View source styles):

Base Classes

  • .list-box - Base listbox container
  • .list-box-item - Individual listbox item
  • .list-box-item__indicator - Selection indicator icon
  • .list-box-section - Section container for grouping items

Variant Classes

  • .list-box--default - Default variant styling
  • .list-box--danger - Danger variant styling
  • .list-box-item--default - Default item variant
  • .list-box-item--danger - Danger item variant

State Classes

  • .list-box-item[data-selected="true"] - Selected item state
  • .list-box-item[data-focus-visible="true"] - Focused item state
  • .list-box-item[data-disabled="true"] - Disabled item state
  • .list-box-item__indicator[data-visible="true"] - Visible indicator state

Interactive States

The component supports both CSS pseudo-classes and data attributes for flexibility:

  • Hover: :hover or [data-hovered="true"] on item
  • Focus: :focus-visible or [data-focus-visible="true"] on item
  • Selected: [data-selected="true"] on item
  • Disabled: :disabled or [data-disabled="true"] on item

API Reference

ListBox Props

PropTypeDefaultDescription
aria-labelstring-Accessibility label for the listbox
aria-labelledbystring-ID of element that labels the listbox
selectionMode"none" | "single" | "multiple""single"Selection behavior
selectedKeysSelection-Controlled selected keys
defaultSelectedKeysSelection-Initial selected keys
onSelectionChange(keys: Selection) => void-Handler called when selection changes
disabledKeysIterable<Key>-Keys of disabled items
onAction(key: Key) => void-Handler called when an item is activated
variant"default" | "danger""default"Visual variant
classNamestring-Additional CSS classes
childrenReactNode-ListBox items and sections
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, ListBoxRenderProps>-Overrides the default DOM element with a custom render function.

ListBox.Item Props

PropTypeDefaultDescription
idKey-Unique identifier for the item
textValuestring-Text value for accessibility and typeahead
isDisabledbooleanfalseWhether this item is disabled
variant"default" | "danger""default"Visual variant
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Item content or render function
render(props: DetailedHTMLProps<LinkWithRequiredHref, HTMLAnchorElement> | React.JSX.IntrinsicElements[keyof React.JSX.IntrinsicElements], renderProps: ListBoxItemRenderProps) => ReactElement-Overrides the default DOM element with a custom render function.

ListBox.ItemIndicator Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Custom indicator content or render function

ListBox.Section Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode-Section content including Header and Items

RenderProps

When using render functions with ListBox.Item or ListBox.ItemIndicator, these values are provided:

PropTypeDescription
isSelectedbooleanWhether the item is selected
isFocusedbooleanWhether the item is focused
isDisabledbooleanWhether the item is disabled
isPressedbooleanWhether the item is being pressed

ListLayout

NameTypeDefaultDescription
rowHeightnumber | undefined48The fixed height of a row in px.
estimatedRowHeightnumber | undefined—The estimated height of a row, when row heights are variable.
headingHeightnumber | undefined48The fixed height of a section header in px.
estimatedHeadingHeightnumber | undefined—The estimated height of a section header, when the height is variable.
loaderHeightnumber | undefined48The fixed height of a loader element in px. This loader is specifically for "load more" elements rendered when loading more rows at the root level or inside nested row/sections.
dropIndicatorThicknessnumber | undefined2The thickness of the drop indicator.
gapnumber | undefined0The gap between items.
paddingnumber | undefined0The padding around the list.

Examples

Basic Usage

import { ListBox, Label, Description } from '@blakeui/react';

<ListBox aria-label="Users" selectionMode="single">
  <ListBox.Item id="1" textValue="Bob">
    <Label>Bob</Label>
    <Description>bob@blakeui.com</Description>
  </ListBox.Item>
  <ListBox.Item id="2" textValue="Alice">
    <Label>Alice</Label>
    <Description>alice@blakeui.com</Description>
  </ListBox.Item>
</ListBox>

With Sections

import { ListBox, Header, Separator } from '@blakeui/react';

<ListBox aria-label="Actions" selectionMode="none" onAction={(key) => console.log(key)}>
  <ListBox.Section>
    <Header>Actions</Header>
    <ListBox.Item id="new" textValue="New file">New file</ListBox.Item>
    <ListBox.Item id="edit" textValue="Edit file">Edit file</ListBox.Item>
  </ListBox.Section>
  <Separator />
  <ListBox.Section>
    <Header>Danger zone</Header>
    <ListBox.Item id="delete" textValue="Delete" variant="danger">Delete</ListBox.Item>
  </ListBox.Section>
</ListBox>

Controlled Selection

import { ListBox, Selection } from '@blakeui/react';
import { useState } from 'react';

function ControlledListBox() {
  const [selected, setSelected] = useState<Selection>(new Set(["1"]));

  return (
    <ListBox
      aria-label="Options"
      selectedKeys={selected}
      selectionMode="multiple"
      onSelectionChange={setSelected}
    >
      <ListBox.Item id="1" textValue="Option 1">Option 1</ListBox.Item>
      <ListBox.Item id="2" textValue="Option 2">Option 2</ListBox.Item>
      <ListBox.Item id="3" textValue="Option 3">Option 3</ListBox.Item>
    </ListBox>
  );
}

Custom Indicator

import { ListBox, ListBoxItemIndicator } from '@blakeui/react';
import { Icon } from '@iconify/react';

<ListBox aria-label="Options" selectionMode="multiple">
  <ListBox.Item id="1" textValue="Option 1">
    Option 1
    <ListBox.ItemIndicator>
      {({isSelected}) =>
        isSelected ? <Icon icon="gravity-ui:check" /> : null
      }
    </ListBox.ItemIndicator>
  </ListBox.Item>
</ListBox>

Accessibility

The ListBox component implements the ARIA listbox pattern and provides:

  • Full keyboard navigation support
  • Screen reader announcements for selection changes
  • Proper focus management
  • Support for disabled states
  • Typeahead search functionality

For more information, see the React Aria ListBox documentation.

On this page