Yugen UI

Combobox

Combobox combines a text input with a listbox: type to filter, then pick one or more options.

Filtering ignores diacritics (typing “da nang” finds “Đà Nẵng”). Keyboard: arrow keys to move, Enter to select, Esc to close. multiselect shows a checkbox for each option; freeform keeps typed text that isn't in the list as the value.

Import

Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.

TSX
// npm install yugen-uiimport { Combobox } from "yugen-ui";

Variants

Each tile is a standalone example: hover to copy, or press Code to see the source.

Multiple selection

multiselect: the listbox stays open after each pick and the input lists the selected items.

Groups & disabled options

Options with a group are listed under that group's heading.

Value: (empty)

Freeform (controlled)

Type a value that isn't in the list, then press Enter or leave the input to keep it.

Appearance, size & disabled

Same appearance / size options as Input.

Usage

Do
  • Use it for long lists (more than ~10 items) when people know what they are looking for.
  • Write a placeholder that tells people they can type to search.
  • Turn on freeform when valid values aren't limited to the list.
Don't
  • Don't use it for a few short options. Use Dropdown or RadioGroup.
  • Don't use multiselect when each selected value needs to stay clearly visible. Use TagPicker.

Props

Prop · TypeDefaultDescription
options(string | { value, label?, disabled?, group? })[]Default: —List of options.
value / defaultValuestring | string[]Default: —string for single selection; string[] with multiselect.
onValueChange(value: string | string[]) => voidDefault: —Called when an option is selected.
multiselectbooleanDefault: falseAllows multiple selection (options get a checkbox).
freeformbooleanDefault: falseKeeps typed text as the value.
noResultsTextReactNodeDefault: "No results found"Shown when filtering matches no options.
appearance"outline" | "underline" | "filled-darker" | "filled-lighter"Default: "outline"Control style.
size"small" | "medium" | "large"Default: "medium"Height 24 / 32 / 40px.
className / listboxClassNamestringDefault: —Class for the input / the listbox surface.

Messages

Text built into the component: labels, aria-labels, screen reader announcements.

English by default. Change it with the messages prop of YugenProvider, by the namespace below; messagesVi has the Vietnamese set. See Interface language.

messages.combobox

Key · TypeDefault (English)messagesVi
noResultsstring

Nội dung khi không có kết quả lọc.

Default (English)"No results found"messagesVi"Không tìm thấy kết quả"
useFreeform(query: string) => string

Gợi ý khi freeform và chữ gõ không khớp option nào.

Default (English)(query) => `Press Enter to use “${query}”`messagesVi(query) => `Nhấn Enter để dùng “${query}”`
closeListstring

aria-label nút mũi tên khi listbox đang mở.

Default (English)"Close list"messagesVi"Đóng danh sách"
openListstring

aria-label nút mũi tên khi listbox đang đóng.

Default (English)"Open list"messagesVi"Mở danh sách"
listLabelstring

Tên của listbox khi ô nhập không có nhãn hiển thị (Field nối nhãn qua aria-labelledby).

Default (English)"Suggestions"messagesVi"Gợi ý"