Select

Single-choice field with a triggered list of options.

Overview

  • Use Select when users can scan the options without filtering. Use Combobox for search within the list.

Aliases

dropdown

When to use

  • Use Select for finite single-choice option sets where the user can comfortably scan the list.
  • Provide a visible label. Use description for guidance and error for validation failures.

When not to use

  • Do not use Select when the list is long enough to require filtering; use Combobox.
  • Do not use Select for multi-select.

Structural parts

field wrapper

root

Provides the label, helper text, and validation shell.

field button

trigger

Opens the listbox and reflects the current value.

options surface

listbox

Anchored list of available options.

selectable row

option

Single option row with label and optional description.

Public interface

Props
NameTypeDefaultDescription
valuestring—Controlled selected value.
itemsArray<{ value: string; label: string; description?: string; disabled?: boolean }>—Available options.
labelstring—Visible field label.
descriptionstring—Supporting helper copy.
errorstring—Validation message.
placeholderstring—Text shown before a selection is made.
requiredbooleanfalseMarks the field as required.
disabledbooleanfalseDisables the field.
namestring—Native form field name.
idstring—Optional field ID.
size'sm' | 'md' | 'lg''md'Chooses the size recipe.
onChange(detail: { value: string | undefined }) => void—Runs when a value is selected.
themeThemeContract—Sets the theme used to resolve component styles.
Events
NamePayloadDescription
change{ value: string | undefined }Fires when the component commits a new value.
Slots
NameDescription
defaultSelect is data-driven and does not expose custom option slots.

Variants, sizes, and states

Variants

  • default: Select uses one single-choice field shell and varies by size.

Sizes

  • sm: Compact select
  • md: Default select
  • lg: Larger select

States

  • closed: Listbox hidden
  • open: Listbox visible
  • selected: Value selected
  • invalid: Validation state

Accessibility

Semantics

  • Uses a button-trigger plus listbox relationship to expose the selectable options.

Keyboard

  • Arrow keys move through options when the listbox is open and Enter commits the active option.

Screen readers

  • Selected value, listbox state, and option movement remain explicit.

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-select-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

trigger

--dk-select-trigger-bg
#f2f5fb
--dk-select-trigger-fg
#16181c
--dk-select-trigger-border
#95989d
--dk-select-trigger-block-size
48px
--dk-select-trigger-inline-padding
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-select-trigger-radius
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-select-trigger-font-size
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)

icon

--dk-select-icon-size
1rem
--dk-select-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-select-surface-bg
#f2f5fb
--dk-select-surface-fg
#16181c
--dk-select-surface-border
#95989d
--dk-select-surface-radius
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-select-surface-shadow
0 10px 15px rgba(0, 0, 0, 0.06), 0 4px 6px rgba(0, 0, 0, 0.04)
--dk-select-surface-width
300px
--dk-select-surface-padding
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)

item

--dk-select-item-bg
transparent
--dk-select-item-fg
#16181c
--dk-select-item-radius
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-select-item-min-height
44px
--dk-select-item-inline-padding
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)

itemLabel

--dk-select-item-label-size
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-select-item-label-weight
550

itemDescription

--dk-select-item-description-size
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)

Implementation notes

  • Select supports one value and does not filter options.

Examples

Starter

Environment selector

A standard single-select field.

<Select label="Environment" description="Choose the deployment target." placeholder="Select an environment" items={items} />

Common patterns

Required selection

Set the error prop to explain a validation failure.

<Select label="Environment" error="Choose an environment." placeholder="Select an environment" items={items} />

Edge cases

Externally controlled listbox

Control the selected value when surrounding state owns the workflow.

<Select label="Environment" items={items} value={selectedEnvironment} onChange={(detail) => selectedEnvironment = 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: 300 × 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: 300 × 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: 300 × 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: 300 × 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: 300 × 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: 300 × 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: 300 × 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: 300 × 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: 300 × 280 px