Combobox
Narrows a long list as you type, so you find the right item fast.
Examples
Buttons
triggerdefault
showClear
hideTrigger
States
rest
chosen
hover
focus
invalid
disabled
open
Usage
Rules
10 rules
- Must
- Put a Combobox in a form inside Field with a FieldLabel; use aria-label only where there is no visible label, such as a toolbar. Because the visible label names the input for everyone, and a placeholder vanishes once the person types.
- Must
- Pass aria-label to ComboboxInput when there is no visible label; the placeholder is not a name. Because without it a screen reader announces an unnamed combobox once typing hides the placeholder.
- Must
- Include a ComboboxEmpty that says what was searched. Because ComboboxList hides itself when empty, so the popup opens on nothing.
- Must
- Pass items to the root and render ComboboxList with a function; do not map the array yourself. Because a mapped array skips the root's filter, so typing never narrows the list.
- Should
- Filter on the server and control inputValue when the list is too large to send.
- Must
- Set itemToStringLabel when items are objects. Because an object with no label key shows and filters on its serialized JSON.
- Should
- Name the thing to find in the placeholder, not Search...
- Never
- Write an input with a datalist; use this Combobox. Because a datalist draws browser chrome that ignores Lime's tokens and has no empty message.
- Should
- Use hideTrigger on phones; the 28px buttons are under the touch guideline and typing opens the list.
- Never
- Remove the list max height; it scrolls at 288px. Because 200 countries then run past the screen edge with no scroll inside the popup.
Accessibility
4 checks
- The input is role combobox with aria-expanded, aria-controls and aria-activedescendant; the list is a listbox of options.
- Typing filters; Arrow Down and Up open and move the highlight; Enter chooses; Escape closes, then clears.
- Focus stays in the input while the list is open.
- The clear and caret buttons are named "Clear" and "Show options".
Edge cases
7 edge cases
- Long names
- Items truncate with an ellipsis and no tooltip; keep names short.
- 500 items
- Render and scroll inside the 288px list; the popup follows the input width.
- Right to left
- The buttons and the check move to the end edge on the left.
- No items
- The list hides and ComboboxEmpty shows; an empty query shows the whole list.
- Server filtering
- No loading row; keep the previous items until the new ones arrive.
- Inside a dialog
- The popup portals into the Lime scope; Escape closes the list first.
- Forced colors
- The input keeps its border; the highlighted item takes Highlight.
API
7 props
itemsArrayvalue, defaultValue, onValueChangeValueinputValue, onInputValueChangestringitemToStringLabel(item) => stringComboboxInput showClearbooleandefaultfalseComboboxInput hideTriggerbooleandefaultfalsedisabledbooleandefaultfalse
Tokens
19 tokens
--field- #f6f5f2
--line-strong- #cfcdc6
--control- #85827a
--accent-line- #7c8700
--ring- var(--accent-line)
--danger- #d93636
--radius-field- 12px
--fg-3- #6b6a63
--surface-2- #efeeea
--fg- #0f0f0d
--raised- #ffffff
--shadow-menu- 0 8px 24px -6px rgb(var(--shadow-ink) / 0.16), 0 2px 6px rgb(var(--shadow-ink) / 0.06)
--radius-panel- 16px
--radius-md- 10px
--fg-disabled- #a6a49b
--dur-base- 200ms
--dur-fast- 140ms
--ease-out- cubic-bezier(0.16, 1, 0.3, 1)
--scale-enter- 0.97