Zetta v0.10

Components · Forms & selection

Multi-select

A control for picking several options at once: chosen values become removable pills inside a wrapping trigger, with a typeahead input and a checkable dropdown list. The trigger grows to fit its tags; the open list reuses the popover surface.

Preview

The trigger with tags and the open list, across the three themes.

Light
Design close Research close
check Design
Engineering
Marketing
Dark
Design close Research close
check Design
Engineering
Marketing
Accessibility
Design close Research close
check Design
Engineering
Marketing

Spec

Values and token references straight from the Zetta spec.

multi-select-trigger
backgroundColor
{colors.surface-card}
borderColor
{colors.border-strong}
borderWidth
1px
borderRadius
{rounded.base}
minHeight
32px
paddingX
14px
paddingY
6px
display
flex
flexWrap
wrap
alignItems
center
gap
6px
cursor
text
multi-select-trigger-hover
borderColor
{colors.border-strong}
boxShadow
{shadows.sm}
multi-select-trigger-focus
borderColor
{colors.border-focus}
outline
2px solid {colors.border-focus}
outlineOffset
2px
multi-select-trigger-invalid
borderColor
{colors.danger}
multi-select-trigger-invalid-focus
borderColor
{colors.danger}
outline
2px solid {colors.danger}
outlineOffset
2px
multi-select-trigger-disabled
backgroundColor
{colors.disabled-bg}
borderColor
{colors.disabled-border}
cursor
not-allowed
multi-select-tag
backgroundColor
{colors.surface-secondary}
textColor
{colors.ink}
borderRadius
{rounded.full}
fontFamily
Geist
fontSize
12px
fontWeight
400
lineHeight
1.5
paddingX
10px
paddingY
2px
display
flex
alignItems
center
gap
4px
multi-select-tag-remove
iconSize
12px
iconColor
{colors.muted}
cursor
pointer
borderRadius
{rounded.full}
padding
2px
multi-select-tag-remove-hover
iconColor
{colors.ink}
backgroundColor
{colors.surface-pressed}
multi-select-input
fontFamily
Geist
fontSize
14px
fontWeight
400
textColor
{colors.ink}
placeholderColor
{colors.placeholder}
placeholderStyle
italic
flex
1
minWidth
80px
height
20px
backgroundColor
transparent
multi-select-content
backgroundColor
{colors.popover}
textColor
{colors.popover-foreground}
borderColor
{colors.hairline}
borderWidth
1px
borderRadius
{rounded.base}
padding
6px
shadow
{shadows.md}
multi-select-item
textColor
{colors.ink}
fontFamily
Geist
fontSize
14px
fontWeight
400
borderRadius
{rounded.base}
paddingX
12px
paddingY
10px
cursor
pointer
display
flex
alignItems
center
gap
8px
multi-select-item-hover
backgroundColor
{colors.accent}
multi-select-item-selected
textColor
{colors.brand}
fontWeight
500
checkIconColor
{colors.brand}
checkIconSize
16px
multi-select-item-disabled
textColor
{colors.disabled-text}
cursor
not-allowed
multi-select-empty
textColor
{colors.muted}
fontFamily
Geist
fontSize
14px
textAlign
center
paddingX
12px
paddingY
16px

Build with the skill

No package to install — hand this to your AI to generate the multi-select in your stack.

Prompt for your AI
Implement the Zetta "Multi-select" component in this project's stack using the zetta-design-md skill.

- Apply the `multi-select` spec from the skill (variants: default, invalid, disabled).
- Use this project's own component conventions and framework idioms.
- Reference the Zetta design tokens (CSS variables) for every color, radius, and shadow — never hardcode values.
- Implement all states (hover, focus, active, disabled, and invalid where applicable) with a visible 2px focus ring.
- Honor the Zetta guardrails (brand never shifts hue, shadows for overlays only, etc.) and verify in Light, Dark, and Accessibility.

Anatomy & rules

  • Wrapping trigger (min-height 32px), pill tags on surface-secondary with a full radius and a removable icon, and a flexible typeahead input. The list marks selected items with a brand check.
  • Tags wrap to new rows as they accumulate; the trigger never truncates the selection silently.

Accessibility

  • Each tag's remove control needs an accessible name and must be keyboard operable (Backspace from the input removes the last tag). The list follows the multi-select listbox pattern with aria-multiselectable.