DEV Community

compsult
compsult

Posted on

I built a picker widget that works with one line of code

I kept running into the same problem: HTML elements are ugly, hard to style, and painful on mobile. Custom dropdown libraries are either React-only or require a ton of configuration.

So I built https://github.com/compsult/Quickpick-ui — a picker that works as a React component or a vanilla JS one-liner.

The simplest possible API

<br> Quickpick(&#39;#picker&#39;, [&#39;January&#39;, &#39;February&#39;, &#39;March&#39;, &#39;April&#39;,<br> &#39;May&#39;, &#39;June&#39;, &#39;July&#39;, &#39;August&#39;, &#39;September&#39;, &#39;October&#39;,<br> &#39;November&#39;, &#39;December&#39;]);<br>

That's it. No build step, no config files, no CSS imports.

It adapts to the device

  • Desktop: hover to open, type to filter the grid instantly, Enter selects the first match
  • Mobile: tap to open, large touch targets, tap backdrop to close

I didn't want two separate code paths for this. The widget detects hover: none via media query and switches behavior automatically.

Type to filter is the killer feature

With a long list (say, all 50 US states), you don't want to scroll through a grid. Just start typing "new" and you instantly see New Hampshire, New Jersey, New Mexico, and New York. Enter selects the
first match.

https://compsult.github.io/Quickpick-ui/ — the 50 states demo is the best way to see this in action.

Works as a React component too

import { AppointmentTimeSelector } from './components';

items={[
{ value: 'CA', label: 'California' },
{ value: 'NY', label: 'New York' },
{ value: 'TX', label: 'Texas' },
]}
selectedValue={selected}
onTimeChange={(item) => setSelected(item.value)}
placeholder="Choose a state"
label="US State"
/>

There's also a BusinessHoursTimeSelector for dual start/end time pickers, and a loading prop that shows a shimmer skeleton while you fetch data.

What's under the hood

  • Web Components with Shadow DOM for the vanilla JS build
  • Full keyboard navigation (arrows, Home/End, Tab, Escape)
  • role="listbox" / role="option" with aria-selected for screen readers
  • Auto-positioning (flips above/below based on viewport space)
  • prefers-reduced-motion support
  • 128 tests
  • MIT licensed

Links

I'd love feedback — especially on the API design. Is the Quickpick('#el', data) pattern intuitive enough? Anything you'd want added?

Top comments (0)