figma guide

Designing combobox and autocomplete UI in Figma: patterns, states, and handoff

Design comboboxes, typeahead search, and multi-select autocomplete in Figma with list states, empty results, async loading, and Dev Mode specs for forms and filters.

Published
Updated
Jun 14, 2026
Read time
8 min
Level
Beginner

Quick answer

A combobox combines a text input with a filterable suggestion list—unlike a static dropdown, users type to narrow options. Build a Combobox component with variants for mode=single | multi, state=default | open | loading | empty | error, and size=sm | md. Pair with forms, search UI, and tables. Document debounce delay, min characters to search, async vs local data, create-new option, and keyboard navigation in Dev Mode. Start from the Figma guides hub for input and list patterns.


Who this is for

  • Product designers shipping assignee pickers, address lookup, tag fields, and command palettes.
  • Design system teams distinguishing combobox from select and search bar—three patterns that often get merged incorrectly.
  • Engineers implementing ARIA combobox patterns, virtualized lists, and API-backed suggestions.

PatternUser types?List behaviorBest for
Combobox (single)YesFilters as you type; pick oneCountry, user assignee, repo name
Combobox (multi)YesAdds chips; remove per tagTags, recipients, skills
Select / dropdownNo (click only)Static list<15 fixed options
Search barYesNavigates results page or live filterGlobal search, search UI
Command paletteYesActions + pages; keyboard-firstPower users, ⌘K shortcuts
Autocomplete onlyYesInserts inline text; no pick listEmail addresses in some clients

Verdict: use a combobox when the option set is too large to scan but users still pick from known values. Use a search bar when results are pages or records, not a closed option list.


Component anatomy

PartPurposeSpec tip
Input fieldType query; shows selected valueReuse form text field
Chevron / clearOpen list or resetClear visible when value exists
Listbox popoverSuggestions below inputMax height 240–320px; scroll
Option rowOne selectable item36–40px row height
HighlightMatch substring in bold”California”
Group labelSection header in list”Recent”, “All users”
Checkbox (multi)Selected state per rowLeading or trailing—pick one
Chip tray (multi)Selected values inside inputWrap with auto layout
Loading rowSpinner + “Searching…”Min 1 row height
Empty stateNo matchesLink to empty state copy
Create option”Add …” rowWhen user can create new tag
Combobox
├── Variant: mode=single | multi
├── Variant: state=default | open | loading | empty | error
├── Variant: size=sm | md
├── Layer: InputContainer
│   ├── Chips (multi only)
│   ├── Text input
│   ├── Clear button
│   └── Chevron
├── Layer: Listbox (popover)
│   ├── GroupLabel (optional)
│   ├── OptionRow × N
│   │   ├── Icon / avatar (optional)
│   │   ├── Primary label + highlight
│   │   ├── Secondary text (optional)
│   │   └── Checkmark / checkbox
│   ├── LoadingRow
│   ├── EmptyStateRow
│   └── CreateNewRow (optional)
└── Layer: Helper / error text

Use avatars in assignee pickers; use icons for country flags or file types. Bind list row hover to interactive components.


List and input states

StateInputListboxNotes
ClosedShows selected label or placeholderHiddenChevron down
Open / typingCaret active; query visibleFiltered optionsOpens on focus or after 1 char—document
Hover optionUnchangedRow background highlightArrow keys move highlight
SelectedField shows value; list closesSingle mode
Multi with chipsChips + cursor for more typingStays open until blurBackspace removes last chip
LoadingInput activeSpinner rowAfter debounce
EmptyQuery with no matches”No results” + optional createDo not leave blank popover
ErrorRed borderMay stay closed”Invalid selection”
DisabledMutedNo openEntire field inactive

For async data, always design loading and empty frames—engineers will ship them even if you only mock the happy path.


Single-select combobox flow

StepUISpec
1User focuses inputList opens with full or recent set
2User typesList filters; highlight matching substring
3Arrow down / upMoves active option
4Enter or clickSelects; list closes; input shows label
5EscCloses list; restores previous value or clears query
6BlurCommit selection or revert—document

Free text: if the user can submit a value not in the list (e.g., custom tag when allowCreate=true), show a Create ”…” row as the last option.


Multi-select and chips

ConcernDesign decisionHandoff note
Chip placementInside input (inline) vs belowInline is standard for tags
Max visible chips+N overflow chip”3 more” when >5 selected
Remove chipX on chip; Backspace removes lastBoth supported in most libs
Duplicate preventionNo duplicate chipsCase sensitivity rule
List stays openYes until blurFaster multi-pick
Select allRare; checkbox in group headerBulk assign only

Align chip styles with badges and chips tokens—sm size inside inputs.


Async and performance patterns

PatternWhenUI to design
Local filter<100 static optionsInstant list filter
Debounced APILarge remote setLoading row after 300ms
Min charsExpensive queriesHelper: “Type 2+ characters”
PaginationLong lists”Load more” row at bottom
Recent + allFrequent picksGroup “Recent” above “All”
Virtualized list1000+ itemsSame row design; note in spec

Document debounceMs (e.g., 300), minQueryLength (2), and maxResults (20) in the component description.


Pairing with other patterns

NeedPatternLink
Form fieldLabel + combobox + helperForms guide
Filter barCombobox for category / ownerSearch UI
Table cell editsm combobox in cellTables
Modal create flowCombobox for parent folderModals
Inline validationError + alertRequired assignee
No resultsEmpty state illustration in panelFirst-time tag creation

Accessibility checklist

RequirementImplementation
Rolerole="combobox" on input; role="listbox" on list
Expandedaria-expanded="true" when open
Active optionaria-activedescendant points to highlighted row
LabelVisible <label> or aria-label
KeyboardUp/Down navigate; Enter selects; Esc closes
MultiAnnounce selection count in live region
Loadingaria-busy="true" on listbox
Group labelsrole="group" + aria-label

Run accessibility plugins on list row contrast and focus visibility.


Prototyping limits

Figma cannot filter a real list. For demos:

  1. Build frames: closed, open with results, open empty, loading, multi with chips, error.
  2. Show highlighted substring as bold text in option rows (static examples).
  3. Use sticky notes for debounce, API, and keyboard behavior.

Wire input focus → open list frame if you need a clickable demo; organize with sections.


Handoff to engineering

DeliverableWhere it lives
modesingle vs multi
Data sourcelocal array vs API endpoint
debounceMse.g., 300
minQueryLengthe.g., 2
value / label fieldsid vs display string
allowCreateboolean + create row copy
clearableShow clear button when
closeOnSelectfalse for multi
maxSelectionsnumber or unlimited
Option templateicon, title, subtitle slots
Empty / loading copyExact strings
Popover placementFlip above if needed

Include comboboxes in your Dev Mode handoff checklist. Publish under Patterns / Forms in your team library.


Real-world examples

Assignee picker (issue tracker)

Multi combobox with avatars, type to filter teammates, recent group at top. Chips inside input; max 5 assignees with error toast if exceeded.

Address lookup

Single combobox, async loading after 3 characters, debounced 400ms. Secondary line shows city/state. Empty state: “No addresses found—check spelling.”

Skills tag field

Multi combobox with allowCreate=true. Create row: Add "GraphQL". Chips use neutral style; duplicate skills blocked.


Common mistakes

MistakeConsequenceFix
Combobox vs select confusionWrong component shippedFlowchart in design system doc
No loading stateBlank popover flashAlways design loading row
List taller than viewportClipped optionsMax-height + scroll
Highlight only colorMatch text unclearBold matched substring
Multi closes on each pickSlow taggingcloseOnSelect=false
Tiny option rows (<36px)Miss taps40px minimum
Async with no min charsAPI spamminQueryLength + helper text
Free text without create rowUsers think pick failedExplicit “Add …” option
Same UI as global searchWrong mental modelSeparate components

FAQ

Combobox or dropdown?

Dropdown when users pick from a short fixed list without typing. Combobox when the list is long or remote and filtering helps.

Show all options before typing?

Recent + browse all is common. For huge sets, require min characters before showing API results.

Icons in every row?

Use when options are visually distinct (users, countries, file types). Skip for plain text enums.

Combobox inside a modal?

Yes—ensure listbox z-index above modal footer and flip placement if near bottom edge.


Bottom line

Design comboboxes as input + listbox systems: typing, filtering, loading, empty, selection, and chip behavior—not a select with a search icon pasted on. Document async rules, multi-select, and create-new flows in Dev Mode. Continue with forms, dropdowns, search UI, and the tutorials hub.

Share on X

§ Keep reading

Related guides.