The Downshift component has been developed in order to provide accessibility and functionality to a combobox or autocomplete input, described by its corresponding ARIA accessibility pattern.
This is a component that controls user interactions and state for you so you can create autocomplete/combobox or select components. It uses a render prop which gives you maximum flexibility with a minimal API because you are responsible for the rendering of everything and you simply apply props to what you're rendering.
This differs from other solutions which render things for their use case and then expose many options to allow for extensibility resulting in a bigger API that is less flexible as well as making the implementation more complicated and harder to contribute to.
Props used in examples
In the examples below, we use the Downshift component and destructure from its result the getter props and state variables. The props returned by Downshift are used as follows:
|Call and destructure its returned object on the label element.|
|Call and destructure its returned object on the toggle button (if any).|
|Call and destructure its returned object on the input and toggle button parent.|
|Call and destructure its returned object on the input element.|
|Call and destructure its returned object on the menu element.|
|Call with |
|State value with the open state of the menu. Used below for conditionally showing the items.|
|State value with the index of thehighlighted menu item. Used below for styling.|
|State value with the item that is selected. Used below for styling.|
|State value with the search query. Used below for filtering the items.|
For a complete documentation on all the returned props, component props and more information check out the Github Page.
If you are new to Downshift then maybe you should first check useCombobox which should provide the same functionality but as a hook. Also, if you need just a select dropdown without a text input, then check useSelect. Finally, for multiple selection support, you can check the useMultipleSelection hook.
As far as the Downshift component is concerned, you can use it in two ways, both of them illustrated below.
There is a (straightforward way, which allows you to wrap your whole _combobox HTML in Downshift. The drawback of this way is that the combobox HTML structure suggested by ARIA is not achieved, and screen readers will not widely support it.
There is also the not-so-straightforward-way which allows you to follow the combobox HTML structure and you should aim to implement this one. Here you will use getRootProps on the element that wraps your input and then you will add the ul element as a sibling to the wrapper element. See the examples below.
A combobox element can be created with HTML elements such as a: label, ul, li, button, input and a div or something similar to contain the input and the toggle button. It is absolutely important to follow the HTML structure below, as it will allow all screen readers to properly work with the widget. Most importantly, the input needs to be contained by the combobox div and the ul needs to be at the same level with the combobox div.
It is possible to achieve the correct HTML structure only if you use getRootProps getter prop from Downshift. You apply getRootProps on the wrapper element that contains the input and optionally the trigger button.
CodeSandbox for usage with getRootProps.
Using Downshift without the getRootProps will add the combobox role to the child element rendered. This way forces your widget into having all elements (menu, input, button, label) as children of the combobox, which is not compatible with the ARIA combobox HTML structure. It will still work but this structure is not supported by all screen readers. Since this is how the usage was advertised in the past, we are still supporting it, but we strongly suggest to move either to the structure with the getRootProps or even better to use the useCombobox hook.
CodeSandbox for usage without getRootProps.
The component can be used with React Native as well. The HTML elements and styles are replaced with React Native equivalents, but the Downshift usage is exactly the same as on React web.
Other usage examples
To see more cool stuff you can build with Downshift, explore the examples repository.