Select
A listbox that unfolds in place — the trigger's near corners flatten while the panel pinches away, then items cascade in. Use Select for short known lists (assets, fee tiers); use Combobox when the list is long enough to need filtering.
Trigger states
Placeholder, selected value, and disabled. The trigger flips the panel above itself automatically when there is no room below.
Static replica: border lifts to border-strong.
Static replica of the trigger's focus ring.
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@coldharbor/ui";
<Select defaultValue="btc" onValueChange={setAsset}>
<SelectTrigger>
<SelectValue placeholder="Select asset" />
</SelectTrigger>
<SelectContent>
<SelectItem value="btc">Bitcoin (BTC)</SelectItem>
<SelectItem value="xmr">Monero (XMR)</SelectItem>
</SelectContent>
</Select>--ch-border--ch-border-strong--ch-bg--ch-bg-raised--ch-fg--ch-fg-muted--ch-focus
Open panel — item states
The Select API has no open prop, so this specimen force-opens the real component by clicking its trigger on mount — the panel renders inline (no portal). It shows the selected item (check mark), default items, and a disabled item. Escape or an outside click dismisses it, as in product.
Selected: Standard. Disabled: Custom rate. Items stagger in with a blur-out cascade.
<SelectContent>
<SelectItem value="economy">Economy — 2 sat/vB · ~2 hours</SelectItem>
<SelectItem value="standard">Standard — 6 sat/vB · ~30 minutes</SelectItem>
<SelectItem value="priority">Priority — 14 sat/vB · ~10 minutes</SelectItem>
<SelectItem value="custom" disabled>Custom rate — unlock in Settings</SelectItem>
</SelectContent>--ch-border--ch-border-strong--ch-bg--ch-bg-raised--ch-fg--ch-fg-muted--ch-focus
Combobox — filterable lists
Same family, plus a search input in the trigger. The open panel portals to <body> but anchors to the trigger, so it reads inline; the open specimen reserves the space it floats over.
Live — click or focus to open and type to filter.
Typing a non-matching query reveals the empty state: “No asset matches that search.”
import { Combobox, ComboboxContent, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxTrigger } from "@coldharbor/ui";
<Combobox defaultValue="btc" onValueChange={setAsset}>
<ComboboxTrigger>
<ComboboxInput placeholder="Search assets…" />
</ComboboxTrigger>
<ComboboxContent>
<ComboboxList>
<ComboboxGroup>
<ComboboxLabel>Assets</ComboboxLabel>
<ComboboxItem value="btc">Bitcoin (BTC)</ComboboxItem>
</ComboboxGroup>
</ComboboxList>
</ComboboxContent>
</Combobox>--ch-border--ch-border-strong--ch-bg--ch-bg-raised--ch-fg--ch-fg-muted--ch-focus
Themes
The valued trigger under all three layers.
--ch-border--ch-border-strong--ch-bg--ch-bg-raised--ch-fg--ch-fg-muted--ch-focus