Autocompletes

The Autocomplete component comes in two forms: Menu and Inline completions.

The Menu completion view is default. When the user types, any filtered (or best match) will appear in a menu. The user can then select a value by:

  • Using the up and down arrow keys to select a completion and then press enter or space to select the value
  • Using the mouse or touch to select a value

The Inline completion view can be enabled by setting the prop inline to true. This will allow a single best match to appear inline and the user can autocomplete by using the tab key.

Since there are many different ways to filter or sort data, there are only two basic filters included. A caseInsensitiveFilter and a fuzzyFilter. They are both pretty basic so you might want to include another library like fuse.js or something else. I didn't want to force a library dependency, so it was not included. The Inline completion view uses a simple find by best match ignoring case by default.

This example shows how a completion can be done inline instead. By default, the autocomplete will find the first match and display it. It can be autocompleted by either:

  • pressing the tab key on desktops
  • tapping the selection text on touch devices

The default findInlineSuggestion function just does a simple ignore case matching. See the propTypes tab for more information.

Never Gonna Bake You Up



This example uses the GitHub API and is subject to rate limiting. The current rate limits are listed below (and automatically updated).

Rate Limits

CoreSearch
Limit6010
Remaining
Resets in

Since the Autocomplete also accepts valid React elements in the data prop, it is possible to create a lazy loading list of suggestions in the Autocomplete. This is really nice when the Autocomplete plugs into a nice API that paginates results.

The site's search uses pagination for its search results using react-waypoint. By default, only 10 search results are returned at a time so when a user scrolls near the bottom of the suggestion list, the next 10 results will be fetched as well. You can view the source code for the search by clicking on the source icon button. When the Autocomplete has paginated results, it is recommended to provide the total prop. This will update each list item in the results with the aria-setsize and aria-setpos.

NOTE: Any item in the list that is a React Element will be ignored when typing in the autocomplete.

Starting with 1.1.0, Menus have been updated with some additional logic to "smartly" position themselves within the viewport. This feature is disabled by default due to weird mobile issues and backwards compatibility.

The "smart" menus are pretty fantastic on desktop devices and works like a charm. The autocomplete menu will either display below the text field (default) or above the text field if it is near the bottom of the page. As the user types, the list size might shrink and automatically position itself below the text field when there is enough space below.

Mobile devices are a pain on the other hand. Android and iOS calculate the viewport height differently and iOS doesn't shrink the viewport height when the soft keyboard is visible while Android does. This means that the default behavior would make Android devices automatically close their list or position the list off the screen when the user types or focuses the text field. It works decently on iOS but most of the list items will not be visible. It becomes even worse if the Autocomplete is fixed in a toolbar. This website's search component actually uses the "smart" menu due to the fact that most of my traffic is developers and desktop users.

Since I actually prefer the Android calculation of viewport height and the majority of this website's mobile traffic is Android, the main search works pretty well with some additional props applied to the "smart" menu. The Autocomplete can attempt to fill the entire viewport (left, right, top, bottom) by enabling the fillViewportWidth and fillViewportHeight props. This will apply the following styles to the list (with some additional checks for page positioning):

const styles = {
  left: this.props.minLeft,
  right: this.props.minRight,
  top: this.props.minTop,
  bottom: this.props.minBottom,
};

Since Android decreases the viewport height to exclude the soft keyboard, the autocomplete list will fill the entire viewport. iOS will have the menu items flow underneath the keyboard limiting the amount of scrolling the user can do.

Summing it up

  • "smart" menus pretty great desktop
  • "smart" menus unpredictable between mobile OS due to viewport height calculation

Check out how this programming autocomplete interacts compared to the first example and the differences the main website works on desktop vs mobile.