Playground
Overview
- Use
Combobox when typing helps users find an option within a moderate list.
When to use
- Use
Combobox when the option set is long enough that filtering is faster than scanning. - Use it when people may know part of the label but not the exact final option.
When not to use
- Use
Select when users can scan the options without filtering. - Do not use it for async search or multi-select.
Structural parts
field wrapper
root Provides label, description, and shell treatment.
combobox input
input Receives the typed filter text and current selection label.
anchored options surface
listbox Shows the filtered option set.
list option
option Selectable option row with label and optional description.
Public interface
Props| Name | Type | Default | Description |
|---|
label | string | — | Visible label used for the field or control. |
description | string | — | Provides field guidance associated with the control. |
error | string | — | Shows a validation error associated with the control. |
placeholder | string | — | Placeholder text shown before a user makes a selection or enters text. |
required | boolean | false | Marks the control as required. |
disabled | boolean | false | Prevents interaction and exposes the disabled state. |
name | string | — | Form field name used for native form submission. |
id | string | — | Sets the control ID for external labels and descriptions. |
size | 'sm' | 'md' | 'lg' | 'md' | Sets the component size. |
items | Array<{ value: string; label: string; description?: string; disabled?: boolean }> | — | Available options rendered inside the listbox. |
value | string | — | Controlled selected value. |
onChange | (detail: { value: string | undefined }) => void | — | Runs when a selection is committed. |
theme | ThemeContract | — | Sets the theme used to resolve component styles. |
Events| Name | Payload | Description |
|---|
change | { value: string | undefined } | Fires when the component commits a new value. |
Slots| Name | Description |
|---|
default | Combobox is data-driven and does not expose option slots. |
Variants, sizes, and states
Variants
default: Combobox uses one searchable shell and varies by size.
Sizes
sm: Compact searchable field.md: Default searchable field.lg: Larger searchable field.
States
closed: Input focused or idle without the list surface visible.open: Anchored listbox is visible.highlighted: One option is active for keyboard navigation.selected: A value has been committed into the field.
Accessibility
Semantics
- Associates the control with its visible label, description, and error.
- Exposes disabled and required semantics through the underlying form control.
- Uses combobox and listbox semantics through the searchable input and anchored option surface.
Keyboard
- Supports native focus and text entry behavior.
- Arrow keys move through options when the listbox is open.
- Enter commits the highlighted option and Escape closes the listbox.
Screen readers
- Connects visible label, helper text, and error text to the native control.
- The input exposes its value, associated listbox, and active option.
Checklist
- Verify that the control has an accessible name.
- Verify that keyboard focus is visible in every state and size.
- Identify disabled, selected, and error states with text or symbols as well as color.
Tokens and CSS variables
root
- --dk-field-stack-gap
- 0.45rem
- --dk-motion-duration
- 200ms
- --dk-combobox-offset
- 8px
label
- --dk-field-label-color
- #16181c
- --dk-field-label-size
- clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
- --dk-field-label-weight
- 600
input
- --dk-combobox-input-bg
- #f2f5fb
- --dk-combobox-input-fg
- #16181c
- --dk-combobox-input-border
- #95989d
- --dk-combobox-input-block-size
- 48px
- --dk-combobox-input-inline-padding
- clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
- --dk-combobox-input-radius
- clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
- --dk-combobox-input-font-size
- clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
icon
- --dk-combobox-icon-size
- 1rem
- --dk-combobox-icon-color
- #16181c
description
- --dk-field-description-color
- #16181c
- --dk-field-description-size
- clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
error
- --dk-field-error-color
- #cc272e
- --dk-field-error-size
- clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
surface
- --dk-combobox-surface-bg
- #f2f5fb
- --dk-combobox-surface-fg
- #16181c
- --dk-combobox-surface-border
- #95989d
- --dk-combobox-surface-radius
- clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
- --dk-combobox-surface-shadow
- 0 10px 15px rgba(0, 0, 0, 0.06), 0 4px 6px rgba(0, 0, 0, 0.04)
- --dk-combobox-surface-width
- 320px
- --dk-combobox-surface-padding
- clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
item
- --dk-combobox-item-bg
- transparent
- --dk-combobox-item-fg
- #16181c
- --dk-combobox-item-radius
- clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
- --dk-combobox-item-min-height
- 44px
- --dk-combobox-item-inline-padding
- clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
itemLabel
- --dk-combobox-item-label-size
- clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
- --dk-combobox-item-label-weight
- 550
itemDescription
- --dk-combobox-item-description-size
- clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
Implementation notes
Combobox supports one value and local filtering. It does not provide asynchronous search or freeform entry.
Examples
Starter
Searchable preset picker
A searchable field for moderate preset lists.
<Combobox label="Choose a system" description="Filter by name." items={systems} />
Common patterns
Compact tool picker
Smaller size works well in dense operational tools.
<Combobox size="sm" label="Preset" placeholder="Find preset" items={systems} />
Edge cases
Controlled selection
Control the selected value when the surrounding app owns the state.
<Combobox label="Preset" items={systems} value={selectedPreset} onChange={(detail) => selectedPreset = detail.value} />
Mathematical fixtures
Calculated fixtures; browser evidence is not collected. Layout estimates use declared text behavior and maximum token values.
default (size=sm)
pass size=sm
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 44 px
- Rows: 44 px
- Surface: 320 × 280 px
default (size=md)
pass size=md
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 48 px
- Rows: 44 px
- Surface: 320 × 280 px
default (size=lg)
pass size=lg
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 52 px
- Rows: 44 px
- Surface: 320 × 280 px
selected (size=sm)
pass size=sm
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 44 px
- Rows: 44 px
- Surface: 320 × 280 px
selected (size=md)
pass size=md
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 48 px
- Rows: 44 px
- Surface: 320 × 280 px
selected (size=lg)
pass size=lg
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 52 px
- Rows: 44 px
- Surface: 320 × 280 px
invalid (size=sm)
pass size=sm
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 44 px
- Rows: 44 px
- Surface: 320 × 280 px
invalid (size=md)
pass size=md
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 48 px
- Rows: 44 px
- Surface: 320 × 280 px
invalid (size=lg)
pass size=lg
- Evidence: mathematical
- Coverage: complete (4 / 4 declared kinds evaluated)
- Declared: contrast, target, optionRow, anchoredSurface
- Evaluated: contrast, target, optionRow, anchoredSurface
- Contrast: 98.5 Lc
- Target: 52 px
- Rows: 44 px
- Surface: 320 × 280 px