↩ Experiments

Search

November 2023

Description

I built this search bar as a demonstration of how I think data can be organized and accessed quickly and intuitively for users on an application. Giving the user keyboard access to a search for the site not only gives them a quick overview of the site at a glance, but also allows them to navigate unfamiliar territory with ease.

React's Portals

A common issue with modals is that your stacking context is limited to the parent element, which can cause issues with z-indexing if your project isn't structured in that way. This can be avoided using React's Portals. Portals allow you to inject a component into any DOM element on the page.

The function looks like this: createPortal(children, domNode, key?), where children is the component you want to inject,domNode is the DOM element you want to inject it into, and key is an optional key for the component.

For modals, I usually inject the modal into the document.body element, which is the root element of the page. This allows you to avoid any z-index issues and gives you a clean slate to work with.

Categories

It's important to not just dump every option available to the user in the search results. This can create as much confusion as it solves. In this case, I split each result category into a separate Map so I could efficiently filter and index results. As the user types, I can create a filtered Map of results and update the list:

setFilteredExperimentLinks(new Map(Array.from(experimentLinks).filter(([key, value]) => value.toLowerCase().includes(text.toLowerCase()))));

I also added a label to each category to a give the user a visual indicator of what they're looking and visually separate the results.

Keyboard Navigation

The keyboard navigation of this search implementation kills two birds with one stone. It is accessible for users without pointer devices, and it also speedy for users who are quicker with their keyboard than their mouse. The user can use the arrow keys to navigate the results, and the enter key to select results and navigate to them. The user can also open and close the modal with keyboard shorcuts, specific to their OS.

To detect the OS of a user, you can use their browser's user-agent string:

setIsMac(window.navigator.userAgent.toLowerCase().includes('mac'));

For navigating the results with the arrow keys, I came across an issue where the results container wouldn't scroll if the selected result was out of view. To fix this, I used a ref for the selected result, and scrollIntoView to scroll the selected result into view when the selected result changed (inside of a useEffect hook).