Skip to content

Combobox

Combobox - ComboboxInput - ComboboxPopover - ComboboxList - ComboboxOption - ComboboxOptionText

Accessible combobox (autocomplete or autosuggest) component for React.

A combobox is the combination of an <input type="text"/> and a list. The list is designed to help the user arrive at a value, but the value does not necessarily have to come from that list. Don't think of it like a <select/>, but more of an <input type="text"/> with some suggestions. You can, however, validate that the value comes from the list, that's up to your app.

Installation

npm install @reach/combobox
# or
yarn add @reach/combobox

And then import the components:

import {
  Combobox,
  ComboboxInput,
  ComboboxPopover,
  ComboboxList,
  ComboboxOption,
  ComboboxOptionText
} from "@reach/combobox";

Examples

To get you started, let's take a look at a few examples that grow from simple to complex, after the examples you can see the API for each component.

Basic, Fixed List Combobox

Like a <table><tr><td/></tr></table>, a full combobox is made up of multiple components. This example demonstrates all of the pieces you need in the simplest form possible.

Basic, Fixed List Combobox

Custom Rendering in ComboboxOption

Sometimes your items need to be more than just text, in these cases you can pass children to ComboboxOption, and then render a <ComboboxOptionText/> to keep the built-in text highlighting. Only the value is used to match, not the children.

This demo searches a client-side list of all US Cities. Combobox does not implement any matching on your list (aside from highlighting the matched phrases in an option). Instead, you render an Option for each result you want in the list. So your job is to:

  • Establish the search term state
  • Match the search to your list
  • Render a ComboboxOption for each match

There is nothing special about managing state for a combobox, it's like managing state for any other list in your app. As the input changes, you figure out what state you need, then render as many ComboboxOption elements as you want.

Clientside Search

This is the same demo as above, except this time we're going to a server to get the match. This is recommended as the previous example had to download 350kb of city text! Again, there is nothing special about a ComboboxList as any other list in React. As the input changes, fetch data, set state, render options.

Lots of arbitrary elements

Sometimes your list is a bit more complicated, like categories of results, and lots of elements besides options inside the popover.

You can even have other interactive elements inside the popover, it won't close when the user interacts with them.

Lots of stuff going on

Custom styling

This demo shows how you can control a lot about the styling. It uses portal={false} on the ComboboxPopover which allows us to create a continuous outline around the entire thing.

CSS Selectors

Please see the styling guide.

[data-reach-combobox] {
}
[data-reach-combobox-input] {
}
[data-reach-combobox-popover] {
}
[data-reach-combobox-list] {
}
[data-reach-combobox-option] {
}
[data-reach-combobox-option][data-highlighted] {
}
[data-reach-combobox-button] {
}

/* the string portions that match what the user has typed */
[data-user-value] {
}
/* the string portions are suggested */
[data-suggested-value] {
}

Combobox

Parent component that sets up the proper aria roles and context for the rest of the components.

Combobox openOnFocus

<Combobox openOnFocus />

Defaults to false.

If true, the popover opens when focus is on the text box.

Combobox onSelect

Called with the selection value when the user makes a selection from the list.

<Combobox onSelect={item => {}} />

ComboboxInput

Wraps an <input/> with a couple extra props that work with the combobox.

ComboboxInput selectOnClick

<ComboboxInput selectOnClick />

Defaults to false.

If true, when the user clicks inside the text box the current value will be selected. Use this if the user is likely to delete all the text anyway (like the URL bar in browsers).

However, if the user is likely to want to tweak the value, leave this false, like a google search--the user is likely wanting to edit their search, not replace it completely.

ComboboxInput autocomplete

Defaults to true.

Determines if the value in the input changes or not as the user navigates with the keyboard. If true, the value changes, if false the value doesn't change.

Set this to false when you don't really need the value from the input but want to populate some other state (like the recipient selector in Gmail). But if your input is more like a normal <input type="text"/>, then leave the true default.

<ComboboxInput autocomplete={false} />

ComboboxPopover

Contains the popup that renders the list. Because some UI needs to render more than the list in the popup, you need to render one of these around the list. For example, maybe you want to render the number of results suggested.

ComboboxPopover portal

If you pass <ComboboxPopover portal={false} /> the popover will not render inside of a portal, but in the same order as the React tree. This is mostly useful for styling the entire component together, like the pink focus outline in the example earlier in this page.

ComboboxList

Contains the ComboboxOption elements and sets up the proper aria attributes for the list.

ComboboxList persistSelectionRef

<ComboboxList persistSelection />

Defaults to false. When true and the list is opened, if an option's value matches the value in the input, it will automatically be highlighted and be the starting point for any keyboard navigation of the list.

This allows you to treat a Combobox more like a <select> than an <input/>, but be mindful that the user is still able to put any arbitrary value into the input, so if the only valid values for the input are from the list, your app will need to do that validation on blur or submit of the form.

ComboboxOption

An option that is suggested to the user as they interact with the combobox.

ComboboxOption value

The value to match against when suggesting.

<ComboboxOption value="Salt Lake City, Utah" />

ComboboxOption children

Optional. If omitted, the value will be used as the children like this:

<ComboboxOption value="Seattle, Tacoma, Washington" />

But if you need to control a bit more, you can put whatever children you want, but make sure to render a ComboboxOptionText as well, so the value is still displayed with the text highlighting on the matched portions.

<ComboboxOption value="Apple" />
🍎 <ComboboxOptionText/>
</ComboboxOption>

ComboboxOptionText

Renders the value of a ComboboxOption as text but with spans wrapping the matching and non-matching segments of text.

So given an option like this:

<ComboboxOption value="Seattle">
  🌧 <ComboboxOptionText />
</ComboboxOption>

And the user typed Sea, the out would be:

<span data-user-value>Sea</span><span data-suggested-value>ttle</span>

ComboboxOptionText CSS Selectors

/* the matching segments of text */
[data-user-value] {
}
/* the unmatching segments */
[data-suggested-value] {
}