Flab UIv0.0.2
MobileA2UI

Select

A single choice from a longer list, in a popup. Built on Base UI Select, which owns the popup, keyboard typeahead and the listbox ARIA wiring. Exposed as composable parts; pass items to the root so the trigger shows the chosen label. Add searchable when the list gets long enough that scanning is slower than typing.

<Select items={fonts} defaultValue="inter">  <SelectTrigger><SelectValue placeholder="Pick a font" /></SelectTrigger>  <SelectContent>    <SelectItem value="inter">Inter</SelectItem>    <SelectItem value="system">System</SelectItem>    <SelectItem value="georgia">Georgia</SelectItem>    <SelectItem value="mono">JetBrains Mono</SelectItem>  </SelectContent></Select>

With a label and placeholder

<Label htmlFor="font">Body font</Label><Select items={fonts}>  <SelectTrigger id="font"><SelectValue placeholder="Choose…" /></SelectTrigger>  <SelectContent>{/* items */}</SelectContent></Select>

Searchable

Pass searchable to add a live-filtering search field at the top of the popup. Flab swaps the underlying primitive to Base UI Combobox so keyboard focus stays in the input while ↑/↓ move the highlight and Enter selects. Items are matched against their rendered text; supply textValue when the label is non-textual.

<Select  searchable  items={fonts}  defaultValue="inter">  <SelectTrigger><SelectValue placeholder="Pick a font" /></SelectTrigger>  <SelectContent searchPlaceholder="Search fonts" emptyMessage="No fonts match">    <SelectItem value="inter">Inter</SelectItem>    <SelectItem value="system">System</SelectItem>    <SelectItem value="georgia">Georgia</SelectItem>    <SelectItem value="mono">JetBrains Mono</SelectItem>  </SelectContent></Select>

Searchable with many items

Once the list gets longer than a screen-worth, search stops being optional. This one filters over 30 timezones as you type.

<Select searchable items={timezones}>  <SelectTrigger><SelectValue placeholder="Timezone" /></SelectTrigger>  <SelectContent searchPlaceholder="Search timezones">    {timezones.map((tz) => (      <SelectItem key={tz.value} value={tz.value}>{tz.label}</SelectItem>    ))}  </SelectContent></Select>

Grouped options

<Select items={fonts}>  <SelectTrigger><SelectValue placeholder="Pick a font" /></SelectTrigger>  <SelectContent>    <SelectGroup>      <SelectGroupLabel>Sans-serif</SelectGroupLabel>      <SelectItem value="inter">Inter</SelectItem>      <SelectItem value="system">System</SelectItem>    </SelectGroup>    <SelectSeparator />    <SelectGroup>      <SelectGroupLabel>Serif & mono</SelectGroupLabel>      <SelectItem value="georgia">Georgia</SelectItem>      <SelectItem value="mono">JetBrains Mono</SelectItem>    </SelectGroup>  </SelectContent></Select>

Parts

PropTypeDefaultNotes
SelectRoot—Holds value/defaultValue, onValueChange, name, items.
Select.searchablebooleanfalseSwaps to Combobox internals and adds the search field.
SelectTriggerbutton—The field; renders a chevron.
SelectValueelement—Shows the selected label (from items) or the placeholder.
SelectContentpopup—Portals and positions the list.
SelectContent.searchPlaceholderstring'Search…'Placeholder for the search field when `searchable`.
SelectContent.emptyMessageReactNode'No results'Shown when the query matches nothing.
SelectItemoption—One choice; needs a value.
SelectItem.textValuestring—Search-matching text when the label is non-textual.
SelectGroup / SelectGroupLabel / SelectSeparatorgrouping—Optional sectioning within the list.