Tom Southall
Published on

Turnstone - A React Search Component

Turnstone - A React Search Component
Turnstone in action

Announcing v1 of TURNSTONE my new open source React component. A fully customisable searchbox with autocomplete dropdown, typeahead, the ability to group results from multiple data sources, WAI-ARIA compliance and much more.

How Turnstone came to be

For some reason, I really like search boxes as an example of UI. The success that is Google basically started as a search box. A much more aesthetically pleasing one than all the other search boxes on offer at the time. It helped that it worked very well too. Arguably much better than it does today but that's a different topic.

In travel metasearch, an area where I have a fair amount of experience, a good search box is also really important. I've built several over the years and I really enjoy putting them together.

So I recently decided to build a new one as a side project. I thought it would be a good exercise to use proper React Functional Components (not sorry to say goodbye forever to Class Components) and React Hooks.

It's a great front-end programming exercise because for something so seemingly simple, there turns out to be a whole lot to think about, especially with some of the features I wanted in mine.

I wanted typeahead (aka predictive text inside the input you're typing into). It's such a nice feature to be able to have your most likely search result pre-filled and you then just hit Tab or Enter to complete.

I also wanted to be able to combine results from multiple data sources into one dropdown. For instance imagine on a travel site, you may wish to combine cities and airports, grouped and displayed separately.

What began as an exercise, ended up as a fully featured and completely customisable component which I've released as an open source project. It's a great search box for all sorts of applications, not just travel. E-commerce, general search, anything.

I called it Turnstone, a) because I didn't want to call it something like "another-react-autocomplete" and b) as a subtle reference to "leaving no stone unturned", because of how easily it allows a user to combine results from lots of data sources/APIs.

Demo and Features

I've put together a little demo site so you can play with it yourself.

Much thanks go to Vercel and MongoDB Atlas for their free service plans which enabled me to put these examples together using real location data. Both are superb.

Full documentation for Turnstone is available in the Github README.

At some point I hope to put together a few tutorial posts with how to use Turnstone to build your own rich autocomplete search input.

But for now, here is a list of Turnstone's best features:

  • Display typeahead autosuggest text beneath entered text

  • Group search results from multiple APIs or other data sources with customisable headings

  • Specify the maximum number of listbox options as well as weighted display ratios for each group. This allows you to say show 8 cities and two airports, but if there are not enough cities to fill 8 slots, then more airports will be automatically displayed. This is a pretty nice feature that I haven't seen in any of the other autocomplete components out there. Everyone allows you to display a maximum but when you have multiple groups of results, the interplay between them becomes important.

  • Completely customise listbox options with your own React component. Add images, icons, additional sub-options, differing visual treatments by group or index and much more. This is what really makes Turnstone powerful. Search results can pretty much look however you want. You can see this working in the screengrab above with New York. As a user narrows down their search, they start to see richer neighbourhood and attraction data appear beneath the New York result. These are clickable "sub-results".

  • Easily styled with various CSS methods including CSS Modules and Tailwind CSS

  • Mobile first. It's really easy to style the component so that it works beautifully at mobile screen widths so that when the input receives focus the search component morphs into a full screen mode. Here's what the example above looks like on mobile:

    Turnstone on a mobile screen
  • Provides multiple callbacks including: onSelect, onChange, onTab, onEnter and more so that you can easily have /Turnstone interact with your other components.

  • Built in WAI-ARIA accessibility

  • Keyboard highlighting and selection using arrow, Tab and Enter keys

  • Automated caching and Debounce to reduce data fetches

  • Optional Clear button (customisable)

  • Customisable placeholder text

  • And finally, you can add more functionality with plugins. This is also really powerful. I've tried to keep the core of Turnstone as lightweight as possible even though it does a lot right out of the box. However, I've also launched the first Turnstone plugin which enables Recent Searches. You can see it working in the example above when the input receives focus before anything is typed.

If you do use Turnstone for any projects I'd love to hear about it. Send me a tweet.

Happy searching!