Building a Search Autocomplete BigDesign component

This week I wanted to build a 🔍 search box within my app that would show product results as you typed.

That’s not a component available in the #BigCommerce #BigDesign component library so I thought I’d do try something new and record a #developer diary where you can follow along and all the challenges I face along the way: starting out with the out of the box search component through to building a custom integration with downshift.js and adding the BigCommerce presentation layer back in.

Transcript

The BigDesign component library enables you to create an admin interface that looks and feels like BigCommerce’s own admin, which is great. And I mentioned it a couple of times before, today, I want to show you right in the weeds of React, how to customize it and create your own version of components while still trying to keep in keeping with the rest of the BigDesign library.

I feel like I’m ready. I have all of my BigCommerce swag. I have my BigCommerce hoodie, my BigCommerce sunglasses with bottle openers on and my BigCommerce spork as well as my daughter’s dinosaur. So we should be ready, we’re going to go through, how are we going to create search autocomplete component. The recent update to BigDesign gave you a search component, which I will take you through.

And then all the way through to building it into actual product search. So you can build that into any of your admin areas where you might need to enable the user to search for products and then act on a product selection. So yeah, I have no idea how this is going to go very rough and ready, roll tape.

Hey everyone today, I wanted to do a follow along with Tom sort of technical episode where I’m going to be sharing a lot more about working on my second app for BigCommerce, which is a visual merchandiser app. I’m just going to dive in really quickly – here you can see we’re in a category page.

We’ve pinned some products that we want to be shown at the top of the category and we can drag and drop and reorder them. But I want to add a search box and to this page, you can search and quickly pin new products. If you might have a very large categories. Rightfully BigDesign, the react design system and component library has just had another update which included this search box.

So I can quickly put out onto the page. I’ve been able to very quickly sort of integrate that so that when you type in a search here, say hat. I’m then showing the search results. The component itself is just the input and the search button. And then I was kind of seeing if I could, I could create some sort of autocomplete and show products.

I was initially pretty happy with that. But then once I started getting into it, realizing that, you know, it’s a good first version. But there were some, some limitations. So. Some things I noticed straight away is the way that I built it. There’s no sort of onBlur event. So when you click outside the box, the box doesn’t disappear.

And that’s kind of like I’ve raised an issue with BigDesign and that if you do want to customize the way this search component works you know, it’s very much sort of a first version for what they’ve done so far. It’s more meant for filtering a table of results, rather than autocomplete.

So I noticed that it was going to be a bit of an issue to resolve, and then once you get into it, you look into accessibility, there’s a little bit of accessibility built in, but from reading up there’s, there’s a lot, I don’t know. So I’d much rather use a dependency that I know is gonna build out an auto complete box well, from an accessibility point of view. So even things like keyboard control that I know we’re going to need something like that. So I feel like that was good for a first version, but I want to take you through now is going on to actually build it a little bit more, how a BigCommerce might.

So for their select component going into BigDesign, they have Select. Which is almost what we want. We want all our list, but we don’t want the kind of the right-hand toggle. We want to have a button instead. And so they use downshift, which is a popular library for building component boxes or they have combo boxes as they’re called.

So yeah, I’m gonna take you through kind of what I’m doing here. So this was the first version which was kind of nice. Liking the fact I could quickly use the the box and panel and shadow styling from the BigDesign library. But now we’re going to switch it out and go in at the deep end with downshift and useComboBox hook

Okay then for my next step, I was looking through BigDesign and how they implemented the select box and how they’d use downshift and use the component combo box component or hook of downshift. And that was good for inspiration. But after reading the downshift library, I felt like actually probably the best first next step is actually to follow the tutorial, learn the library a little bit better and start with them sort of more basic version of the tutorial and then kind of build up the BigCommerce layer on top from a UI perspective,

I took pretty much exactly the basic usage example here, and, and dropped it into my search auto complete component, which I’ll take you through in a second.

But very quickly we recognized it was functional. So we have immediately, we have the, obviously it’s very basic styling, but we have hover over for mouse. We have on blurred disappearing. We have keyboard controls and selection. So, you know, obviously it doesn’t look as nice anymore, but very quickly recognize that this is, this is going to work.

It’s got the functionality we, we want out of the box leaving us just to worry about integrating it in terms of knowing when a particular option has been chosen, and making it look nicer, adding that, that BigDesign component to it or layer to it. So then the.

the tutorial is almost just copy and pasted. All I needed to do was when instantiating combo box I needed to make sure that it passed the, when the input value changes, pass that back up to my the parent component. And even the on selected, I’m not really doing anything with I was just testing it out.

And then this middle bit is essentially lifted from the tutorial. You have your label right now. We have a div with our input in the button for toggling the dropdown and then their list of results, which is simply just sort of mapped through. And I think I’ve done a one line change, really to remove some styles, to make it even more basic and say that we want to show the product name in the results.

And that’s all, we’re all we’re showing right now. So very, very basic version. [We] know we’ve been able to move this over to the downshift. Next up, I want to figure out how to start adding back in the different, Big Design components. Can I add, add it to make it look like an input box? I think that’s what I’m gonna do next

So I’ve got the Big Design input element in. That was like a fairly easy change. Just swapping out the regular old input for a Big Design input. But then I actually decided that I quite liked the chevron icon on the right-hand side for opening, closing the menu. So if you have performed a search and then have chosen to get rid of it, obviously forgive the work in progress styling, but that’s actually quite a nice feature. And from a UX perspective is then sort of consistent with the select. But the problem I’ve run into now is that, you see, it’s much bigger than you expect. And that’s because from the Big Design component library, they do provide or they do set a certain amount of restrictions so that you can’t mess up the styling, understandably. So I can’t customize this button as it stands to make it smaller. So yeah, I’m gonna look into how am I might solve that?

Ok, it wasn’t pretty the route I’ve gone for is, you know, composition over inheritance when it comes to react. I have essentially copy and pasted everything I need. So like out of Big Design component library, the button component to be able to customize the style. So yeah, albeit that the dropdown is changing the width of the input box, we now can open, close the window with the arrow. It’s the right color. It’s the right size. And code wise, this needs a lot of cleanup, and it’s certainly not ideal from a point of view of efficiency. And so the, the route you have to go is copy and pasting. I’m afraid to say it.

So style button, all of the button definitions are currently at the top of this file. And then we get into our search components. So yeah, there’s what there’s about 200 lines, 250 odd lines that I’ve essentially copied and pasted sort of the inner workings of the button component to be able to modify the styles.

So, yeah, I guess, you know, this year has really been my first year learning react. It’s a, it’s a trade off closing down your design system so that people can’t kind of shoot themselves in the foot. But if there are ways in which people can adjust it then, you know, there’s certainly advantages to avoiding this sort of situation where I’ve got duplicated code.

So yeah, I can see the benefits but certainly experienced the trade offs now as well. This can obviously be cleaned up so it’s not all, not all in one file. I’ll do that in due course. Next, I imagine adding in the button is going to be fairly simple in terms of just making it look like a search box.

So I probably do that and then move on to the dropdown itself and making that actually look and feel like the select box dropdown. Let’s see how we get on

So lucky for you, this has only been a couple of seconds, for me, it’s taken me a good couple of hours to progress to the next step. Getting kind of in deep with, with ripping out the parts that I wanted from the Big Design library to build out a list and list items for the auto complete. Immediately you can see I’ve got a few other sort of minor style changes, as well as adding icons and things make it look a bit more like a search box but we’re back to our position of being able to enter a search term and now we have our new list and list items which are very, very similar to the select list items dropdown. And we are showing our products,, product name, product SKU, and image that so I’m really, really happy with, with that. We’ve got the hover effect there with the mouse, as well as being able to navigate up and down with, with keyboard.

So very happy with that. Then we have on right now, I’ve got a version of onClick or onEnter, just indicating here you can see with the alert box. We getting the information that we expect. The problem I have have now is, and the next step for me, programming isn’t, everything is a problem. And onto the next one.

So yeah. This currently, because it’s a combo box, it’s a select box by default. And that’s what it’s optimized for. I’ve had to do a little bit of, of jiggery pokery in terms of it wants to choose one of these items and update the input box. So kind of very quickly going into, into code. This is my search auto complete component and one of the things you can do is provide a stringified version of your item, where my item is a product. So you might say that I could do item.name to show the name once you’ve selected it, the search field is updated to be a product name, but actually I really want it to stay as it is. So right now, sort of my, my way of doing that is just making sure that we always kind of keep the search term.

So value here is, is search term. So, because I felt like that’s a better user experience. You don’t want your search term to change just because you’ve chosen a product you might want to change your selection. So that’s fair enough. But the next challenge I’ve got is the combo box is all around handling selection changes, and that works in the first instance where I choose say the black mug, but you can see that I didn’t get an alert the second time around because the item selection hasn’t actually changed. So what you would expect in a drop down. Is when you’re choosing the same item as you’ve already selected, it shouldn’t do anything, it should just close the menu. So in that instance, it’s, it’s working as expect.

So almost like the final change here before actually sort of integrating it with the pinned items functionality on the page is to make sure that I know whenever an item is chosen, even if that is even if that means that it hasn’t been changed, if that makes sense. So not just on the, like right now, I know when an item is first selected, I want to know when it’s second selected.

So I know that I can sort of repeat actions and repeatedly choose products. So that’s, that’s my next challenge to look into. I don’t know there’s much else I want to pull out. There was quite a lot from the Big Design library that I’ve sort of copied and pasted to try and make as kind of identical as experience as possible, and I keep the code similar. So we have our top level kind of search autocomplete box, which manages opening and closing the menu, rendering the items in a, in a popper. Sort of fly over, the drop down itself into a list. And we, then we have our list component, which handles rendering the items themselves.

So nothing too strenuous there. It’s mainly, as I say, taking the select item component and stripping it back a little bit, obviously that does, that does a lot more. The power multi-select and things like that as well. So our use case is a bit simpler. That’s my next challenge. I feel like we’re, we’re very much on the home straight now.

And then we’ll have a really nice looking search box.

I have gotten to the next stage where I can put in my search term, get my list of results, and then when I click on an item with mouse or keyboard, I’ve actually integrated it with the grid as well. So if I click on an, a item that isn’t pinned yet – bottle one, it becomes pinned and I can click on it again and it becomes unpinned.

So I’m really happy with this search box now decided to update the search button to open and close and be, kind of have the same functionality as the toggle. And you have also noticed I’ve got the loading indicator when it’s actually performing a search as well. So yeah, that’s yeah, dead chuffed, I think, I think it’s fair to say. Uh, I’m sure there’s plenty to do to tidy this code up, but things to point out: search autocomplete. So this is my top level component for, which uses the combo box. So something to call out, if I can find the right tab, is that there are a bunch of event handlers that you can hook into for when certain things happen.

So enter, on the input box. So if you’ve got a highlighted index and you hit enter, then it will select that item. And then also click on an item. So those are the two real sort of onSelection events that occur on an event handler level. So I decided to hook in with those because going back through this documentation.

There are sort of on selection item changes, which we’ve sort of already listed wasn’t gonna be good enough for us because we also want to know when an item has clicked, but it was already selected. onStateChange I had a look into and gives you an awful lot of opportunity to hook into the various events that happen.

But again, because the state isn’t really changing at that point internally in combo box, that wasn’t gonna be suitable. So I went a little bit lower level and went down to the events. So on here, the Big Design already has a onKeyDown custom handler that it passes to the input field, already doing some work in terms of opening and closing the menu when you hit enter. If it isn’t already open. I’ve hooked into that. So you get the highlighted index if there is one. And so I should probably do a little check there to see whether or not that is going to be an error and that array index doesn’t exist, but it passes that item, so that product, to the function that I pass into search complete. So that’s for when the input field when you’re manually selecting a highlighted item with the enter key and kind of arrow keys going up and down them, then I pass the same function all the way down to list item and use that same function on a list item click. When you actually click on with, with a mouse, the same event occur. So that leaves me at a top level, I’ve got my product search component, which uses search autocomplete. One other thing I’ve done here is pull out the actual item render to a prop as well, so that I can pass in this product micro row.

So I can have complete customizability at it outside of the search autocomplete component how to render the item information. So yeah, so maybe I’ll do some cleaning up of these, these edge cases to make sure I don’t ever get any out of bounds errors and things.

But yeah, I’m pretty happy here and I’ve probably spent long enough, I should move on to something else, but yeah. Happy with how it’s going. I’ll go into a bit more detail in terms of what visual merchandiser is and what’s coming in another video. So this was something a bit different hope you enjoyed and I’ll speak to you soon.

Tom Robertshaw
Stay up to date with Hypa news and features