ProComponents, templates & AI tooling
HeroUI
27.7k

ListBox

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

Import

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

Usage

Anatomy

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

import { ListBox, Label, Description, Header } from '@heroui/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

Multi Select

With Disabled Items

Custom Check Icon

Controlled

Custom Render Function

Virtualization

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

Styling

Passing Tailwind CSS classes

import { ListBox } from '@heroui/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.

@layer components {
  .list-box {
    @apply rounded-lg border border-border bg-surface p-2;
  }

  .list-box-item {
    @apply rounded px-2 py-1 cursor-pointer;
  }

  .list-box-item--danger {
    @apply text-danger;
  }

  .list-box-item__indicator {
    @apply text-accent;
  }
}

HeroUI 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 | undefinedThe estimated height of a row, when row heights are variable.
headingHeightnumber | undefined48The fixed height of a section header in px.
estimatedHeadingHeightnumber | undefinedThe 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 '@heroui/react';

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

With Sections

import { ListBox, Header, Separator } from '@heroui/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 '@heroui/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 '@heroui/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