1. Components
  2. Menus and selection
  3. ListBox

ListBox

A list of options that can allow selection of one or more.

Next.js
Remix
Astro
Gatsby
<ListBox>
  <Item>Next.js</Item>
  <Item>Remix</Item>
  <Item>Astro</Item>
  <Item>Gatsby</Item>
</ListBox>

Installation

npx dotui-cli@latest add list-box

Usage

Use ListBox to display a list of options and allow a user to select one or more of them.

ListBox Options

Orientation

By default, ListBox expects items to be arranged in a vertical stack, and implements keyboard navigation and drag and drop accordingly. Use the orientation prop to change the layout to a horizontal stack.

ReadRead Only
WriteRead and Write Only
AdminFull access
<ListBox orientation="horizontal" selectionMode="single">
  <Item textValue="Read" label="Read" description="Read Only" />
  <Item textValue="Write" label="Write" description="Read and Write Only" />
  <Item textValue="Admin" label="Admin" description="Full access" />
</ListBox>

Layout

The layout prop can be set to "grid" to enable two-dimensional keyboard navigation.

Next.js
Remix
Astro
Gatsby
<ListBox layout="grid">
  <Item>Next.js</Item>
  <Item>Remix</Item>
  <Item>Astro</Item>
  <Item>Gatsby</Item>
</ListBox>

Selection mode

ListBox supports multiple selection modes. By default, selection is disabled, however this can be changed using the selectionMode prop.

Next.js
Remix
Astro
Gatsby
Next.js
Remix
Astro
Gatsby
<ListBox selectionMode="single">
  <Item>Next.js</Item>
  <Item>Remix</Item>
  <Item>Astro</Item>
  <Item>Gatsby</Item>
</ListBox>
<ListBox selectionMode="multiple">
  <Item>Next.js</Item>
  <Item>Remix</Item>
  <Item>Astro</Item>
  <Item>Gatsby</Item>
</ListBox>

Selection behavior

When selectionBehavior is set to "replace", clicking a row with the mouse replaces the selection with only that row. Using the arrow keys moves both focus and selection. To select multiple rows, modifier keys such as Ctrl, Cmd, and Shift can be used. On touch screen devices, selection always behaves as toggle since modifier keys may not be available.

Next.js
Remix
Astro
Gatsby
<ListBox selectionMode="multiple" selectionBehavior="replace">
  <Item>Next.js</Item>
  <Item>Remix</Item>
  <Item>Astro</Item>
  <Item>Gatsby</Item>
</ListBox>

Loading

Use the isLoading prop to indicate that the list is loading.

User 1
User 2
User 3
<ListBox isLoading>
  <Item>User 1</Item>
  <Item>User 2</Item>
  <Item>User 3</Item>
</ListBox>

Empty state

Use the renderEmptyState prop to customize what the ListBox will display if there are no items.

No results found.
<ListBox renderEmptyState={() => "No results found."} />

Item options

Variant

Use the variant prop to set the visual style of the item.

View logs
Manage domains
Transfer project
Delete project
<ListBox>
  <Item>View logs</Item>
  <Item>Manage domains</Item>
  <Item>Transfer project</Item>
  <Item variant="danger">Delete project</Item>
</ListBox>

Label and description

By default, items in a ListBox are labeled by their text contents for accessibility. Items also support the "label" and "description" props to separate primary and secondary content.

ReadRead Only
WriteRead and Write Only
AdminFull access
<ListBox>
  <Item textValue="Read" label="Read" description="Read Only" />
  <Item textValue="Write" label="Write" description="Read and Write Only" />
  <Item textValue="Admin" label="Admin" description="Full access" />
</ListBox>

Prefix and suffix

To add additional context for the item, such as icons, use the prefix and suffix props.

New fileCreate a new file
Copy linkCopy the file link
Edit fileAllows you to edit the file
<ListBox>
  <Item label="New file" description="Create a new file" prefix={<PlusSquareIcon />} />
  <Item label="Copy link" description="Copy the file link" prefix={<CopyIcon />} />
  <Item label="Edit file" description="Allows you to edit the file" prefix={<SquarePenIcon />}/>
</ListBox>

Items may be links to another page or website. This can be achieved by passing the href prop to the Item component.

<ListBox>
  <Item href="https://github.com/mehdibha">GitHub</Item>
  <Item href="https://linkedin.com/in/mehdibha">LinkedIn</Item>
  <Item href="https://x.com/mehdibha_" target="_blank">X</Item>
</ListBox>

Disabled

An Item can be disabled with the isDisabled prop.

Next.js
Remix
Gatsby
Astro
<ListBox>
  <Item>Next.js</Item>
  <Item>Remix</Item>
  <Item isDisabled>Gatsby</Item>
  <Item>Astro</Item>
</ListBox>

Sections

ListBox supports sections in order to group options. Sections can be used by wrapping groups of items in a Section element.
Sections without a title must provide an aria-label for accessibility.

Signature sauce
BBQ sauce
Honey mustard
Tartar sauce
Pepperjack
Mozzarella
Blue cheese
Bacon
Sauteed onions
Green pepper
<ListBox selectionMode="multiple">
  <Section title="Sauces">
    <Item id="signature-sauce">Signature sauce</Item>
    <Item id="bbq-sauce">BBQ sauce</Item>
    <Item id="honey-mustard">Honey mustard</Item>
    <Item id="tartar-sauce">Tartar sauce</Item>
  </Section>
  <Section title="Cheese">
    <Item id="pepperjack">Pepperjack</Item>
    <Item id="mozzarella">Mozzarella</Item>
    <Item id="blue-cheese">Blue cheese</Item>
  </Section>
  <Section title="Extras">
    <Item id="bacon">Bacon</Item>
    <Item id="sauteed-onions">Sauteed onions</Item>
    <Item id="green-pepper">Green pepper</Item>
  </Section>
</ListBox>

Separator

Separators may be added between items or sections in order to create non-labeled groupings.

New...
Badges
Save
Save as...
Rename...
Page setup…
Print…
<ListBox>
  <Item>New...</Item>
  <Item>Badges</Item>
  <Separator />
  <Item>Save</Item>
  <Item>Save as...</Item>
  <Item>Rename...</Item>
  <Separator />
  <Item>Page setup…</Item>
  <Item>Print…</Item>
</ListBox>

Uncontrolled

Use defaultSelectedKey to set a default selected item.

Next.js
Remix
Astro
Gatsby
<ListBox
  selectionMode="multiple"
  defaultSelectedKeys={["nextjs", "remix", "astro"]}
>
  <Item id="nextjs">Next.js</Item>
  <Item id="remix">Remix</Item>
  <Item id="astro">Astro</Item>
  <Item id="gatsby">Gatsby</Item>
</ListBox>

Controlled

Use selectedKey and onChange props to control the selected item.

Next.js
Remix
Astro
Gatsby

Selected items: nextjs, remix, astro

const [selected, setSelected] = React.useState<Selection>(new Set(["nextjs", "remix", "astro"]));
return (
  <ListBox
    selectionMode="multiple"
    selectedKeys={selected}
    onSelectionChange={setSelected}
  >
    <Item id="nextjs">Next.js</Item>
    <Item id="remix">Remix</Item>
    <Item id="astro">Astro</Item>
    <Item id="gatsby">Gatsby</Item>
  </ListBox>
)

Composition

If you need to customize things further, you can drop down to the composition level.

Next.jsReact-based SSR and static site framework.
RemixFull-stack framework with efficient data loading.
AstroLightweight static site builder for performance.
<ListBox selectionMode="multiple">
  <Item>
    <Text slot="label">Next.js</Text>
    <Text slot="description">React-based SSR and static site framework.</Text>
  </Item>
  <Item>
    <Text slot="label">Remix</Text>
    <Text slot="description">Full-stack framework with efficient data loading.</Text>
  </Item>
  <Item>
    <Text slot="label">Astro</Text>
    <Text slot="description">Lightweight static site builder for performance.</Text>
  </Item>
</ListBox>

Examples

Asynchronous loading

This example uses the useAsyncList hook to handle asynchronous loading of data from a server.

const list = useAsyncList<Character>({
  async load({ signal }) {
    const res = await fetch(`https://pokeapi.co/api/v2/pokemon`, { signal })
    const json = (await res.json()) as { results: Character[] }
    return {
      items: json.results,
    }
  }
})

return (
  <ListBox
    aria-label="Pick a Pokemon"
    items={list.items}
    isLoading={list.isLoading}
    selectionMode="single"
  >
    {(item) => <Item id={item.name}>{item.name}</Item>}
  </ListBox>
)

API Reference

ListBox

PropTypeDefaultDescription
selectionBehavior'toggle' | 'replace'-How multiple selection should behave in the collection.
dragAndDropHooksDragAndDropHooks-The drag and drop hooks returned by useDragAndDrop used to enable drag and drop behavior for the ListBox.
renderEmptyState(props: ListBoxRenderProps) => ReactNode-Provides content to display when there are no items in the list.
layout'stack' | 'grid''stack'Whether the items are arranged in a stack or grid.
orientation'horizontal' | 'vertical''vertical'The primary orientation of the items. Usually this is the direction that the collection scrolls.
autoFocusboolean | 'first' | 'last'-Whether to auto focus the listbox or an option.
shouldFocusWrapboolean-Whether focus should wrap around when the end/start is reached.
itemsIterable<T>-Item objects in the collection.
disabledKeysIterable<Key>-The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.
selectionMode'none' | 'single' | 'multiple'-The type of selection that is allowed in the collection.
disallowEmptySelectionboolean-Whether the collection allows empty selection.
selectedKeys'all' | Iterable<Key>-The currently selected keys in the collection (controlled).
defaultSelectedKeys'all' | Iterable<Key>-The initial selected keys in the collection (uncontrolled).
childrenReactNode | (item: object) => ReactNode-The contents of the collection.
dependenciesany[]-Values that should invalidate the item cache when using dynamic collections.
classNamestring | (values: ListBoxRenderProps & {defaultClassName: string | undefined}) => string-The CSS className for the element. A function may be provided to compute the class based on component state.
styleCSSProperties | (values: ListBoxRenderProps & {defaultStyle: CSSProperties}) => CSSProperties-The inline style for the element. A function may be provided to compute the style based on component state.
EventTypeDescription
onAction(key: Key) => voidHandler that is called when an item is selected.
onSelectionChange(keys: Selection) => voidHandler that is called when the selection changes.
onFocus(e: FocusEvent<Target>) => voidHandler that is called when the element receives focus.
onBlur(e: FocusEvent<Target>) => voidHandler that is called when the element loses focus.
onFocusChange(isFocused: boolean) => voidHandler that is called when the element's focus status changes.
onScroll(e: UIEvent<Element>) => voidHandler that is called when a user scrolls.

Item

PropTypeDefaultDescription
idKey-The unique id of the item.
variant'default' | 'success' | 'warning' | 'danger' | 'accent'"default"The visual style of the menu item.
valueobject-The object value that this item represents. When using dynamic collections, this is set automatically.
textValuestring-A string representation of the item's contents, used for features like typeahead.
isDisabledboolean-Whether the item is disabled.
childrenReactNode | (values: ListBoxItemRenderProps & {defaultChildren: ReactNode | undefined}) => ReactNode-The children of the component. A function may be provided to alter the children based on component state.
classNamestring-The CSS className for the element.
styleCSSProperties | (values: ListBoxItemRenderProps & {defaultStyle: CSSProperties}) => CSSProperties-The inline style for the element. A function may be provided to compute the style based on component state.
hrefHref-A URL to link to.
hrefLangstring-Hints at the human language of the linked URL.
targetHTMLAttributeAnchorTarget-The target window for the link.
relstring-The relationship between the linked resource and the current page.
downloadboolean | string-Causes the browser to download the linked URL. A string may be provided to suggest a file name.
pingstring-A space-separated list of URLs to ping when the link is followed.
referrerPolicyHTMLAttributeReferrerPolicy-How much of the referrer to send when following the link.
routerOptionsRouterOptions-Options for the configured client side router.
EventTypeDescription
onAction() => voidHandler that is called when the item is selected.
onHoverStart(e: HoverEvent) => voidHandler that is called when a hover interaction starts.
onHoverEnd(e: HoverEvent) => voidHandler that is called when a hover interaction ends.
onHoverChange(isHovering: boolean) => voidHandler that is called when the hover state changes.

Accessibility

Keyboard interactions

KeyDescription
TabFocuses the first item.
ArrowDownWhen focus is on an item, moves focus to the next item.
ArrowUpWhen focus is on an item, moves focus to the previous item.

Last updated on 10/11/2024

dotUI

Bringing singularity to the web.

Built by mehdibha. The source code is available on GitHub.