Skip to main content

MultiSelect

Choose multiple options from a collapsible list of options.

http://localhost:3000
<MultiSelect aria-label="Country Select">
  <SelectItem>United States</SelectItem>
  <SelectItem>Canada</SelectItem>
  <SelectItem>Mexico</SelectItem>
</MultiSelect>

Usage​

Selection​

The listbox components supports either no selection, single and multiple selection modes using the selectionMode prop.

http://localhost:3000
function Selection() {
  const options = [
    { id: 1, name: 'United States' },
    { id: 2, name: 'Canada' },
    { id: 3, name: 'Mexico' },
    { id: 4, name: 'United Kingdom' },
    { id: 5, name: 'France' },
    { id: 6, name: 'China' },
    { id: 7, name: 'India' },
    { id: 8, name: 'Turkey' },
  ];

  const [selected, setSelected] = React.useState(new Set(['Turkey']));

  return (
    <MultiSelect
      aria-label="Country Select"
      selectedKeys={selected}
      onSelectionChange={setSelected}
    >
      {options.map((item) => (
        <SelectItem key={item.name}>{item.name}</SelectItem>
      ))}
    </MultiSelect>
  );
}

Sections​

Group items within a dropdown using a section.

http://localhost:3000
<MultiSelect aria-label="Country Select">
  <SelectSection title="North America">
    <SelectItem>United States</SelectItem>
    <SelectItem>Canada</SelectItem>
    <SelectItem>Mexico</SelectItem>
  </SelectSection>
  <SelectSection title="Europe">
    <SelectItem>United Kingdom</SelectItem>
    <SelectItem>France</SelectItem>
  </SelectSection>
  <SelectSection title="Asia">
    <SelectItem>China</SelectItem>
    <SelectItem>India</SelectItem>
  </SelectSection>
</MultiSelect>

Async​

Items can be loaded asynchronously use the useAsyncData hook. It also supports infinite scrolling to load more data on demand as the user scrolls, via the onLoadMore prop.

http://localhost:3000
function Async() {
  const list = useAsyncList({
    async load({ signal }) {
      const res = await fetch('https://restcountries.com/v3.1/alpha?codes=US,CA,MX,GB,FR,CN,IN', {
        signal,
      });

      const items = await res.json();

      return { items };
    },
  });

  return (
    <MultiSelect aria-label="Country Select" items={list.items}>
      {(item) => <SelectItem key={item.name.common}>{item.name.common}</SelectItem>}
    </MultiSelect>
  );
}

Label​

Attach a label to the combobox using the label prop.

http://localhost:3000
<MultiSelect label="Country">
  <SelectItem>United States</SelectItem>
  <SelectItem>Canada</SelectItem>
  <SelectItem>Mexico</SelectItem>
</MultiSelect>

HelperText​

Add additional context as well as display error messages with the helperText prop.

http://localhost:3000
<MultiSelect label="Country" helperText="Please select a country">
  <SelectItem>United States</SelectItem>
  <SelectItem>Canada</SelectItem>
  <SelectItem>Mexico</SelectItem>
</MultiSelect>

Small​

A small select is used when vertical spacing is limited.

http://localhost:3000
<MultiSelect aria-label="Country Select" size="small">
  <SelectItem>United States</SelectItem>
  <SelectItem>Canada</SelectItem>
  <SelectItem>Mexico</SelectItem>
</MultiSelect>

Start Icon​

Include an icon before the input text.

http://localhost:3000
<MultiSelect aria-label="status" startIcon={<Search />}>
  <SelectItem>United States</SelectItem>
  <SelectItem>Canada</SelectItem>
  <SelectItem>Mexico</SelectItem>
</MultiSelect>

Item Icon​

Include an icon before the item label on each item.

http://localhost:3000
<MultiSelect aria-label="status">
  <SelectItem startIcon={<Truck />}>Truck</SelectItem>
  <SelectItem startIcon={<Train />}>Train</SelectItem>
  <SelectItem startIcon={<Airplane />}>Airplane</SelectItem>
  <SelectItem startIcon={<Boat />}>Ship</SelectItem>
</MultiSelect>

Controlled​

A select's state can be controlled using the selectedKeys prop and onSelectionChange handler.

http://localhost:3000
function ControlledExample() {
  const data = [
    { id: 1, name: 'United States' },
    { id: 2, name: 'Canada' },
    { id: 3, name: 'Mexico' },
    { id: 4, name: 'United Kingdom' },
    { id: 5, name: 'France' },
    { id: 6, name: 'China' },
    { id: 7, name: 'India' },
    { id: 8, name: 'Turkey' },
  ];

  const [selected, setSelected] = React.useState(new Set(['Turkey']));

  return (
    <MultiSelect
      aria-label="status"
      items={data}
      onSelectionChange={setSelected}
      selectedKeys={selected}
    >
      {(item) => <SelectItem key={item.name}>{item.name}</SelectItem>}
    </MultiSelect>
  );
}

Disabled State​

Set the isDisabled prop to prevent a user from interacting with the select.

http://localhost:3000
<MultiSelect aria-label="status" isDisabled>
  <SelectItem>United States</SelectItem>
  <SelectItem>Canada</SelectItem>
  <SelectItem>Mexico</SelectItem>
</MultiSelect>

Disabled items​

Set the disabledKeys prop to disable certain items in the select list.

http://localhost:3000
<MultiSelect aria-label="status" disabledKeys={['canada']}>
  <SelectItem key="united_states">United States</SelectItem>
  <SelectItem key="canada">Canada</SelectItem>
  <SelectItem key="mexico">Mexico</SelectItem>
</MultiSelect>

Invalid State​

Set the validationState prop to invalid to render the select in an invalid state.

http://localhost:3000
<MultiSelect aria-label="status" helperText="A selection is required" validationState="invalid">
  <SelectItem>United States</SelectItem>
  <SelectItem>Canada</SelectItem>
  <SelectItem>Mexico</SelectItem>
</MultiSelect>

Accessibility​

Labeling​

If a visible label isn't specified, an aria-label must be provided to the select for accessibility. If the field is labeled by a separate element, an aria-labelledby prop must be provided using the id of the labeling element instead.

Props​

MultiSelect Props​


as?The root element to be rendered

SelectItem Props​


as?The root element to be rendered

SelectSection Props​


as?The root element to be rendered