You have a custom select or a combobox in your applications which performs a multiple selection. You want the whole experience to be accessible, including adding and removing items from selection, navigating between the items and back to the dropdown. You also want this solution to be simple to use and flexible enough so you can tailor it further to your specific needs.
useMultipleSelection is a React hook that manages all the stateful logic needed to make the multiple selection dropdown functional and accessible. It returns a set of props that are meant to be called and their results destructured on the dropdown's elements that involve the multiple selection experience: the dropdown main element itself, which can be either an input (if you are building a combobox) or a button (if you are building a select), and the selected items. The props are similar to the ones provided by vanilla Downshift to the children render prop.
These props are called getter props and their return values are destructured as a set of ARIA attributes and event listeners. Together with the action props and state props, they create all the stateful logic needed for the dropdown to become accessible. Every functionality needed should be provided out of the box: arrow navigation between dropdown and items, navigation between the items themselves, removing and adding items, and also a helpful aria-live message when an item has been removed from the selection.
Props used in examples
In the examples below, we use the useMultipleSelection hook with both useSelect and useCombobox, destructure from its result the getter props and state variables. The getDropdownProps can be called with a preventKeyAction parameter. In some cases you may not want the user to navigate from the dropdown to the selected items or to delete them with Backspace. For example you can pass isOpen as its value in order to keep removal and navigation actions from occuring while the dropdown is open. The returned props are used as follows:
|Call optionally with preventKeyAction and destructure its returned object on the toggle button (select) or input (combobox) element.|
|Call and destructure its returned object on the selected item element.|
|State value with the items currently selected. Used to render the Tags.|
|Action prop that adds the item to the selection. Best used in useSelect and useCombobox prop onStateChange or onSelectedItemChange|
|Action prop that removes the item from the selection. Used in the X icon/button onClick handler.|
For a complete documentation on all the returned props, hook props and more information check out the Github Page.
Usage with combobox
A combobox with multiple selection can be created in a similar way to a single selection equivalent, with the addition of rendering the selected items. The UI is completely up to the developer, as the selected items can be created using span elements or custom Components from UI libraries, within an inline-block or flex display.
In the example below, each item has an X icon attached to it, with a removeSelectedItem callback in the onClick handler. Items are added using the setSelectedItems function inside the onStateChange handler of useCombobox, and selectedItems are passed to useMultipleSelection as a control prop. selectedItem of useCombobox is also controlled and being passed a null value since useMultipleSelection will handle the items selection in this case.
CodeSandbox for combobox usage example.
Usage with select
A select with multiple selection is similar to the combobox equivalent. We use the basic useSelect example and add the selected items as span elements. Custom components from UI libraries can be used as well, since the UI is up to the developer.
CodeSandbox for select usage example.
The hook can be used with React Native as well. The HTML elements and styles are replaced with React Native equivalents, but the useMultipleSelection usage is exactly the same as on React web.
Other usage examples
To see more cool stuff you can build with useMultipleSelection, explore the examples repository.