{
"$type": "site.standard.document",
"canonicalUrl": "https://bradestey.com/writing/base-ui-combobox/",
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreibvftwljfeastqvgpc7fzgmwlvd5rwgt4y76xpilovckbxcbqsave"
},
"mimeType": "image/png",
"size": 171452
},
"description": "Building a combobox component using Base UI and Tailwind CSS",
"path": "/writing/writing/base-ui-combobox",
"publishedAt": "2025-08-04T04:00:00.000Z",
"site": "at://did:plc:gjryzxv62p6dfiy4knry3mzt/site.standard.publication/3mn73eclrks2d",
"tags": [
"design"
],
"textContent": "> At the time of writing this, the current version of Base <abbr title=\"User interface\">UI</abbr> is 1.0.0-beta.2 and an official combobox component is still in development.\n\nOver the past week, I’ve been trying out Base <abbr title=\"User interface\">UI</abbr>, a collection of headless <abbr title=\"User interface\">UI</abbr> components from the creators of Radix, Floating <abbr title=\"User interface\">UI</abbr>, and Material <abbr title=\"User interface\">UI</abbr>. I’ve used a few headless component libraries, like Headless <abbr title=\"User interface\">UI</abbr> from Tailwind <abbr title=\"Cascading style sheet\">CSS</abbr>, Reach <abbr title=\"User interface\">UI</abbr> from Ryan Florence and Radix by way of shadcn/<abbr title=\"User interface\">ui</abbr>. Each of these have had their pros and cons. It’s difficult to find a library of components that can toe the line between opinionated and customizability. You’re never going to make everyone happy.\n\nI really enjoyed working with Popper and followed it over to Floating <abbr title=\"User interface\">UI</abbr>, which I currently use every day. But, Floating <abbr title=\"User interface\">UI</abbr> is on the customizable side of the spectrum, which means it can come with a pretty dense amount of boilerplate.\n\nWhile trying out Base <abbr title=\"User interface\">UI</abbr> and swapping out the Tooltip and Dialog components on this site, I noticed that Base <abbr title=\"User interface\">UI</abbr> didn’t have a combobox component yet. But, they do have an Input and a Select component. So I figured, why not try to Frankenstein together a passable combobox?\n\nDesign Spec\n\nThe <abbr title=\"User experience\">UX</abbr> for this is heavily based on Headless <abbr title=\"User interface\">UI</abbr>’s Combobox. Some of those design decisions are as follows:\n\n- No error states, an invalid input reverts to an empty state.\n- Pressing the down arrow should change focus from the input to the options list.\n- Pressing the up arrow while highlighting the first option should return focus to the input.\n- Pressing escape mid-input returns to an empty state.\n- Pressing enter with an input that matches an option label (regardless of casing) sets that option as the selection.\n\nDemo\n\n<iframe src=\"https://codesandbox.io/embed/cyzqt6?view=preview&module=%2Fsrc%2Fcombobox.tsx&hidenavigation=1\"\n style=\"width:100%; height: 500px; border:0; border-radius: 4px; overflow:hidden;\"\n title=\"base-ui-combobox\"\n allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n ></iframe>\n\nProcess\n\nOne of the challenges was not having access to the active item state to control which select options were highlighted and when. This meant I needed to do some ugly <abbr title=\"Document Object Model\">DOM</abbr> tree climbing to check data-highlighted and data-selected props. There was also some fighting with the select component’s management of that state and some awful setTimeout functions that run clean-up. Maybe there’s a way to access additional state. I didn’t dig much deeper than the docs to look for a context or clever use of render props. These are very much \"me\" problems and not a knock on Base <abbr title=\"User interface\">UI</abbr>.\n\nAll this is to say, the code to make this work is not great. But, the end result is not bad. Honestly, I wouldn’t think twice about using this in a production app. The benefits that come with Base <abbr title=\"User interface\">UI</abbr>, even in beta, far exceed anything I could build on my own from scratch.\n\nCode\n\nI’ve thrown the code on CodeSandbox for anyone to fork. Maybe don’t look too closely.",
"title": "Base UI Combobox"
}