Tinyrack

Combobox

Filters a collection through a text input and commits one semantic item value from the popup.

Contract

AxisBehavior
stateinput text, selected value, and open state are separate controlled or uncontrolled axes
input anatomyField.Root wraps Field.Label and Combobox.Root; inside Root, InputGroup holds optional InputAdornment + Input + Clear + Trigger, and Icon belongs inside Trigger
multiple anatomyChips → Value → Chip + ChipRemove; grid collections compose Collection → Row → Item
popup anatomyPortal → optional Backdrop + Positioner → Popup → Arrow + Status + List; groups, indicators, separators, Collection, and Empty cover collection feedback
interactionpointer, Arrow keys, Home/End, Enter, Escape, type-ahead filtering, focus restoration, disabled items, and read-only roots are delegated to Base UI
formsname, form, required, disabled, readOnly, object serialization, native validation, submission, and reset are supported by Root

Install

pnpm add @tinyrack/ui

Scroll inside the code area to read long lines.

Styles

@import '@tinyrack/ui/components/combobox.css';

Scroll inside the code area to read long lines.

Imports

import { TRCombobox } from '@tinyrack/ui/components/combobox';
import { TRForm } from '@tinyrack/ui/components/form';
import { TRField } from '@tinyrack/ui/components/field';
import { TRButton } from '@tinyrack/ui/components/button';

Scroll inside the code area to read long lines.

Playground

Usage

Examples

Sizes permalink

Pass uiSize to InputGroup to align the Combobox control with neighboring Input, NumberField, or Button heights.

Filter semantics permalink

Compare contains, startsWith, and no built-in filtering while keeping selection separate from the input query.

Multiple chips and grid collection permalink

Value renders removable chips while Collection and Row expose the public grid anatomy.

Controlled state and filter hooks permalink

The query, selected value, and open state remain independent. useFilteredItems reads the collection after the locale-aware filter runs.

Overlay composition permalink

Portal and Positioner keep the popup anchored without changing the input layout. Escape dismisses it and restores focus.

Keyboard selection permalink

Type to filter, move with Arrow keys, commit the highlighted option with Enter, and dismiss with Escape.

API

SurfacePurpose
RootOwns items, filtering, single/multiple value, input text, open state, validation, form serialization, locale, and equality/string conversion for object values.
InputGroup, InputAdornment, Input, Clear, Trigger, IconCompose an editable control. InputAdornment is decorative; Icon belongs in Trigger. InputGroup forwards uiSize?: 'md' | 'lg' to scale the input, adornment, clear, and trigger together.
Portal, Backdrop, Positioner, Popup, ArrowMount and position the dismissible overlay. Portal accepts a custom container and may be omitted for inline rendering.
Status, List, Group, GroupLabel, Collection, Row, Item, ItemIndicator, Separator, EmptyRender list or grid collections and accessible feedback.
Chips, Value, Chip, ChipRemoveRender and remove multiple selections.
useFilter, useFilteredItemsBuild locale-aware contains, startsWith, and endsWith predicates and read the filtered generic item array inside Root.

Every part also has a named TRCombobox* export and matching props/state types. Root additionally exports action and open/value/highlight event detail and reason types, plus TRComboboxFilter and TRComboboxFilterOptions.

Wrap an editable Input in TRField.Root and name it with TRField.Label. The label resolves its own htmlFor from the registered control, so no manual id or useId is needed. TRCombobox.Label names a trigger-only select anatomy. InputGroup accepts uiSize?: 'md' | 'lg' (default md) to align the input, adornment, clear, and trigger heights with neighboring controls. Disabled roots and items cannot be changed; read-only roots remain focusable but cannot edit or clear. Keep popup content mounted only when needed, preserve stable item identity for object values, and supply itemToStringLabel, itemToStringValue, or isItemEqualToValue when the automatic { label, value } object convention is insufficient.

Combobox modules are SSR-safe. Interactive files are client boundaries, portals mount after hydration, and controlled server/client initial values must match. Styling ships separately through combobox.css; customize --tr-combobox-input-background, --tr-combobox-content-background, --tr-combobox-content-max-height, --tr-combobox-content-max-width, and --tr-combobox-option-min-height, which fall back to semantic Tinyrack tokens in light and dark themes.