Skip to main content

MultiSelect

Choose multiple options from a collapsible list of options.

http://localhost:3000
expand_more
<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
expand_more
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
expand_more
<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
expand_more
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
expand_more
<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
expand_more
Please select a country
<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
expand_more
<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
expand_more
<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
expand_more
<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
expand_more
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
expand_more
<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
expand_more
<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
expand_more
A selection is required
<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

childrenReactNode & CollectionChildren<object>The contents of the collection.

containerRef?RefObject<HTMLElement>The ref of the element to append the overlay to.

helperText?ReactNodeHelper text to append to the form control input element.

helperTextProps?HTMLAttributes<HTMLElement>Props passed to the helper text.

label?ReactNodeLabel of the input element

labelProps?HTMLAttributes<HTMLElement>Props passed to the label.

maxHeight?numberThe maxHeight specified for the overlay element. By default, it will take all space up to the current viewport height.

offset?numberThe additional offset applied along the main axis between the element and its anchor element.Defaults to 4

placement?PlacementThe placement of the element with respect to its anchor element.Defaults to 'bottom'

shouldFlip?booleanWhether the element should flip its orientation (e.g. top to bottom or left to right) when there is insufficient room for it to render completely.Defaults to true

startIcon?ReactElement<any, string | JSXElementConstructor<any>>Icon displayed at the start of the text field.

as?NonNullable<T>

autoComplete?stringDescribes the type of autocomplete functionality the input should provide if any. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautocomplete).

name?stringThe name of the input, used when submitting an HTML form.

isOpen?booleanSets the open state of the menu.

defaultOpen?booleanSets the default open state of the menu.

onOpenChange?(isOpen: boolean) => voidMethod that is called when the open state of the menu changes.

css?CSSTheme aware style object.

SelectItem Props


as?The root element to be rendered

as?"div"

css?CSSTheme aware style object.

startIcon?ReactElement<any, string | JSXElementConstructor<any>>Icon added before the item text.

SelectSection Props


as?The root element to be rendered

as?"div"

childrenReactNode & (ItemElement<object> | ItemElement<object>[] | ItemRenderer<object>)Static child items or a function to render children.

css?CSSTheme aware style object.