Design system Inputs

Dropdown

A field that reads and changes one stored value or a compact set. Long closed sets may filter directly through the same dropdown face.

.mk-select-face

Overview

The dropdown is a menu button dressed as the field it is: it shows its value and changes it. The value renders as what the product wears for it — a status shows its pill, a plain value shows text — and the trailing filled triangle flips while the attached list is open. Press it.

Usage

  • Select a stored value from a closed setThe field shows the current value and opens the available options. Use Search instead when choosing a result should navigate rather than populate a field.
  • Use Multi-select for a compact value setEvery selected value remains visible in the field and carries its own removal control. When a long closed set needs filtering, use the Searchable dropdown variant.
  • Preserve the value's visual meaningWhen the selected value has a defined label treatment, keep that treatment in the closed field and in the option list.

Anatomy

1
2 3
  1. 1The face. White always, the strong grey edge, control radius, M height like every field — it shipped S once and the family never sat on one line.
  2. 2Value area. A placeholder occupies this seat until a choice is made; afterwards the selected value replaces it. A status value arrives as its own pill.
  3. 3Trailing chevron. Filled, 20px, trailing. It flips while the menu is open — the openness is visible from the control itself.

Variants and states

The size ladder

Shared with the input and the date field — .mk-ctl-s / -m / -l, so a mixed row of controls sits on one line to the pixel. Dense rows opt into S.

States

Every state below is the real component wearing that state, not a picture of it.

StateSpecimenWhat changes
Rest White face, the strong grey edge — the same resting dress on every ground; the warm resting variant is a retired no-op.
Hover The border warms to the accent hairline; the fill stays white — one interaction voice for the whole field family.
Keyboard focus The standard 2px camel outline at 2px offset.
Open The attribute says expanded: the border warms, the engaged ring appears and the triangle flips — openness is visible from the control itself.
Empty An unchosen dropdown rests on a muted ask — a placeholder value in the quiet voice, never a blank.
Blocked The whole face fades and the press refuses; the value stays readable in place.

Multi-select dropdown

The multi-select dropdown wears its chosen values as chips inside the face — the filter-chip component, each removable by its own cross without opening the list. The face grows by wrapping, never by hiding the choice behind a count. In the open list a chosen option keeps the selection fill and stays in place: choosing does not close a multi list.

Searchable dropdown

Past roughly seven options the same dropdown face becomes editable. Typing filters its closed set; choosing a result commits that value and returns the face to its ordinary closed state. It is not the Search component: there is no magnifier, clear action, or second field inside the panel.

Choosing a status

A status arrives in the list the same way it rests in the face: as its own pill. The open list is the status's whole vocabulary, and the option being left is marked chosen — the agent sees where the object stands while choosing where it goes.

  • Changing a stateA dropdown that changes an object's state keeps the confirm step: the list swaps to the sentence naming the object and the destination before committing.
  • The phone stretches the faceFull width in the row; the list stays attached — a chevron never answers with a bottom sheet.

Do and don't

Do

The status wears its own pill inside the face — one face for the status everywhere, whether it rests or chooses.

Don't

The same status as bare text makes the value's kind invisible — the agent reads the word twice to learn it is a state.

Copy

  • The value verbatimThe face shows the chosen value as the product writes it — nothing prepended.
  • Options carry consequencesA choice with a cost says it in its own note line inside the menu, before the press.
  • The empty ask is quietA muted "Choose …" in the value's own vocabulary.

Accessibility

  • The control declares its popupThe standard face uses aria-haspopup and aria-expanded. The Searchable dropdown uses an editable combobox with aria-autocomplete="list" and owns the same attached listbox.
  • The name includes the valueRead together: what this chooses and what is chosen now.
  • The triangle is decorationThe attribute carries the openness; the flip only draws it.

When to reach for something else

  • Free entryUse Text input — the dropdown's shape promises a closed list.
  • Find a destination without setting a field valueUse Search; Search results navigate or reveal records, while a Searchable dropdown commits one value from its closed set.
  • Acting, not choosingUse the Split button; a dropdown never performs.
  • How a value is writtenUse the Unit toggle.

Markup

<span class="mk-menu-wrap">
  <button class="mk-select-face" type="button"
          aria-haspopup="menu" aria-expanded="false">
    <span>Selected value</span>
    <svg class="caret" data-mk-icon="caret" aria-hidden="true"></svg>
  </button>
  <div class="mk-menu" role="menu" aria-label="Options" hidden>
    <button class="mk-menu-item" role="menuitem" type="button">First option</button>
  </div>
</span>

<!-- multi: chips in the face, a listbox that stays open while choosing -->
<span class="mk-menu-wrap">
  <button class="mk-select-face mk-select-multi" type="button"
          aria-haspopup="listbox" aria-expanded="false">
    <span class="mk-chip">First value
      <svg class="mk-chip-x" data-mk-icon="close" aria-hidden="true"></svg></span>
    <svg class="caret" data-mk-icon="caret" aria-hidden="true"></svg>
  </button>
  <div class="mk-menu" role="listbox" aria-multiselectable="true"
       aria-label="Options" hidden>
    <ul class="mk-optlist">
      <li><button class="mk-opt" role="option" aria-selected="true" type="button">
        <span class="mk-opt-main"><span class="mk-opt-name">First value</span></span>
      </button></li>
    </ul>
  </div>
</span>

<!-- searchable: the dropdown face itself accepts the filtering query -->
<span class="mk-menu-wrap">
  <span class="mk-select-face mk-select-searchable is-open">
    <input class="mk-select-query" type="text" role="combobox"
           aria-autocomplete="list" aria-expanded="true"
           aria-controls="available-values" autocomplete="off">
    <svg class="caret" data-mk-icon="caret" aria-hidden="true"></svg>
  </span>
  <div class="mk-menu" role="listbox" aria-label="Available values">
    <ul class="mk-optlist" id="available-values">…</ul>
  </div>
</span>