Select

Two field types, not six (AD decision, 2 Sep 2026 — review ACRM-76–81, pick ACRM-105). The four approved dropdown types A–D (Petr, 21 Aug 2026 — docs/PLAN-dropdown-sjednoceni.md in acrm) are two axes — search yes/no × multiple yes/no — so the family has Select (closed list) and Record select (searchable list of records), each with a multiple mode, plus Nav select (context switch in the top bar, different trigger) and Picker menu (action menu, not a field).

Everything else that used to be its own entry is a mode or a usage of those two and is now deprecated: MultiSelect = Select with multiple (1 usage), Combobox = Record select with free text (1 usage), CheckMenu = the multiple mode drawn as a menu (2), RailPickerMenu = Record select anchored in a rail row (2), EntityPicker = Record select with async search (12), ProductPicker = the same limited to products (2). They stay listed until their usages are migrated; nothing new is built on them. Rule that binds the family (docs/DS-USAGE.md): dropdowns are always the DS popover, never a native <select>.

Values measured from apps/web/src/ds.css and apps/web/src/ds/inputs.css on main: shell .acrm-popover (or .acrm-recordselect-pop for search panels) = --surface-100, 1px --border-strong, --radius-md, --shadow-pop, padding --sp-2, z-index 101 over a scrim at 85; row = 500 13px/20px var(--font-sans), padding --sp-2 --sp-3 → 32px, hover --hover-surface; select-one check = .chk in --accent, hidden with visibility; multi = .acrm-checkbox 16px, 1.5px --border-strong, --radius-xs, on the RIGHT; search row = borderless input 400 14px, 18px icon, hairline --border below; list scrolls inside max-height: 264px. Field triggers (.acrm-select-trigger, .acrm-recordselect-trigger, .acrm-combobox) are 32px, --radius-sm, open state = --accent border + 3px accent halo (16%). Top-bar trigger .tchip = --control-h 30px, --radius-md, --shadow-xs, open = --active-surface.

Which field for which need

NeedUseNot
One value from a closed list (≈10 options or fewer)Select — <Select> / .acrm-select-triggernative <select>, a radio group with 10+ options
Several values from a closed listSelect with multiple (checkbox on the right, menu stays open)MultiSelect, a bespoke checkbox menu, several selects
More than ~10 items, or records (people, companies, products), single or multipleRecord select — <RecordSelect> (search row, list ≤ 264px)Select with a long list, an ad-hoc dropdown
Free text with suggestions (address, ARES)Record select with free text allowedCombobox, <datalist>
Search that hits the server as you typeRecord select (async)EntityPicker, ProductPicker
Picking a value inside a record railRecord select anchored to the rail valueRailPickerMenu
Switching context in the top bar (pipeline, entity)Nav select — <NavSelect> / .tchipSelect in the bar, a heading that opens a menu on its own
A menu of actions (not a value)Picker menu — <PickerMenu> / .acrm-popoverSelect, a kebab that renders its own menu
TypeAnatomyPackage primitiveApp pickers on it
A · plain menurows with optional 18px icon or stage dot, one line (ellipsis), accent check on the selected row, no trailing tag; closes on pickPickerMenu, NavSelect, SelectRecordActionsMenu, ContextVariablesMenu, AccountingEntityPicker, TemplateMenu (under 10 templates)
B · searchsticky search row + list ≤ 264px + empty text; single value, check on the rightRecordSelect (single), Combobox (free text)RailPickerMenu single (OwnerPickerEditor), TemplateMenu, DialCodePicker, RecordSearchSelect, AssignPicker, ProductPicker
C · multiselectrows with the DS checkbox on the right; the menu stays open on toggle; optional reorder by dragMultiSelectCheckMenu (LayoutMenu, CategoryFilterChip), FilterBar
D · search + multiB + C, selection pinned on top, hairline between groups, optional footerRecordSelect multiRailPickerMenu multi (TagsEditor), EntityPicker

The story Components / Select → Dropdown types shows the four side by side.

Where each picker sits

PickerTypePrimitive it usesVerdict
Select (@acrm/ui)A.acrm-select-trigger + Popover + .acrm-popover-item .chkcanon
MultiSelect (@acrm/ui)C.acrm-select-trigger + Popover + .acrm-checkbox rightcanon
Combobox (@acrm/ui)B (free text).acrm-combobox + .acrm-combobox-pop via useAnchoredMenucanon
RecordSelect (@acrm/ui)B / D.acrm-recordselect-* via useAnchoredMenucanon — single mode still draws .acrm-checkbox, not the F261 accent check .acrm-recordselect-ck that RailPickerMenu emits; align in the package
NavSelect (@acrm/ui)A.tchip + PickerMenucanon (composition)
PickerMenu (@acrm/ui)APopover + .acrm-popover-itemcanon
CheckMenu (components/CheckMenu.tsx, ds/check-menu.css)CPopover + .acrm-popover-item[menuitemcheckbox] + .acrm-checkbox right, .cm-reorder / .cm-drop-linecanon type C, app-side — promote to the package when a second consumer outside the app appears
RailPickerMenu (components/RailPickerMenu.tsx)B / D.acrm-recordselect-pop/-search/-list/-opt, .acrm-popover-sep, useAnchoredMenu; anchor .rr-ev.rpk-anchor, footer .rpk-foot (record-rail.css)canon in the rail (F194/F195) — composition of canonical rows, no own shell
EntityPicker (components/EntityPicker.tsx)DAddRefMenu shell (.acrm-popover.eref-add-pop, useAnchoredPanel) + .acrm-recordselect-search/-list/-opt rows; server typeaheadduplicate shell — rows are canonical, shell and anchoring re-implement Popover/useAnchoredMenu; consolidation candidate (plan MR 15)
ProductPicker (components/ProductPicker.tsx)B (+ free-text row)same as EntityPicker (AddRefMenu + record-select rows), group heading pending AD gate V2duplicate shell — consolidation candidate (plan MR 15)
RecordSearchSelect (components/RecordSearchSelect.tsx)B.acrm-recordselect trigger + AddRefMenu + record-select rows; server typeaheadduplicate — exists only because RecordSelect filters in memory; give RecordSelect async options and retire it (plan MR 15)
AddRefMenu (components/AddRefMenu.tsx)shell for B/DcreatePortal + useAnchoredPanel, .acrm-popover.eref-add-popduplicate of Popover + useAnchoredMenu — consolidation candidate
DialCodePicker (components/multivalue/DialCodePicker.tsx)BPopover shell + .acrm-recordselect-search; rows .phe-ccrow (multi-value.css)partial — shell canonical (plan MR 10), rows bespoke; consolidation candidate
TemplateMenu (components/mail/compose/TemplateMenu.tsx)B (A under 10)Popover + .acrm-recordselect-search + .acrm-popover-item, .acrm-popover-emptycomposition — fine (.mc-tplstick keeps the search row sticky)
LayoutMenu (components/record/LayoutMenu.tsx)CCheckMenu with onReordercomposition — fine
ContextVariablesMenu (pages/settings/ContextVariablesMenu.tsx)APopover + .acrm-popover-item (tag removed 28 Sep 2026)composition — fine
AccountingEntityPicker (components/accounting/AccountingEntityPicker.tsx)ANavSelect; SectionTopBarChip when there is one entitycomposition — fine
AssignPicker (components/mail/AssignPicker.tsx)Bbespoke .rcpt-menu / .rcpt-opt (mail.css) via createPortal + useAnchoredPanelduplicate — consolidation candidate (plan MR 7)
PlaudPickerDialog (components/meetings/PlaudPickerDialog.tsx)—Dialog + ItemList + .acrm-checkboxnot a dropdown; a dialog list — fine, outside the family
OwnerPickerEditor (components/record/OwnerPickerEditor.tsx)BRailPickerMenu mode="single"composition — fine
RecordActionsMenu (components/record/RecordActionsMenu.tsx)APopover + .acrm-popover-item (.danger last)composition — fine
TagsEditor (components/TagsEditor.tsx)DRailPickerMenu mode="multi" + .rpk-create footercomposition — fine
ChannelsPopoverEditor (components/multivalue/ChannelsPopoverEditor.tsx)A (type cell)native <select class="phe-type">native — violation; the only native select left in the app (the ds-ok comment argues the box does not fit the row — the fix is a quiet type A trigger, not a native control)

Consolidation notes

  • One shell: AddRefMenu + useAnchoredPanel (EntityPicker, ProductPicker, RecordSearchSelect) and .rcpt-menu (AssignPicker) re-implement what Popover and useAnchoredMenu already do. Plan MR 7 and MR 15 fold them into type B.
  • One row: DialCodePicker rows (.phe-ccrow) should become .acrm-popover-item (the code in the name, no trailing tag).
  • One check: RecordSelect single should draw .acrm-recordselect-ck like RailPickerMenu — a checkbox promises multi-select (F261).
  • Async options on RecordSelect remove the reason for RecordSearchSelect.
  • CheckMenu and RailPickerMenu are canonical by anatomy but live app-side; the catalog renders their markup, not the components.
  • Zero native selects is the target: ChannelsPopoverEditor type cell is the last one.

Legacy card Inputs — what still holds

Harvested from legacy/Inputs.html ("Výběr & rozbalovací nabídky", "Rozbalovací nabídky") and legacy/popover.html, checked against apps/web/src/ds.css and apps/web/src/ds/inputs.css:

  • Still true: "No headings inside menus — never an eyebrow above the items; the only exception is a hairline group separator." "Menu, combobox and popover carry --shadow-pop over a hairline ring and --radius-md." "The active item in a single select carries the check on the right; in a multi select the filled checkbox on the right (D6, 22 Aug 2026)." "Record select opens with a search box on top (hairline), the list scrolls inside 264px; use it whenever the list has more than ~10 items." "The LIST scrolls, not the panel — a scrolling panel with a sticky header produced F257." "One-line items 500 13/20 → 32px; .sub descriptions removed 21 Aug 2026; the trailing .tag removed 28 Sep 2026 (ACRM-375–377) — a row is its name only." "Fields are flat at rest; the shadow belongs to the open menu." Record select variants "single (check, closes on pick) · text-only (no avatar, code lists) · in menu (no trigger, search is the first row) · search without list (hairline disappears)".
  • Superseded or ahead of code: the card's Record select "single" check is only implemented app-side (RailPickerMenu); RecordSelect in the package still draws a checkbox in single mode (F261 alignment pending). The card's "text-only" Record select rows have no package prop — RecordSelect always renders an avatar; the text-only row exists in RailPickerMenu (avatar omitted). The card's "Nadpis-dropdown (s ikonou)" is the .pipe-btn screen switch (family Section top bar), not a member of this family. The registry summary "native select on mobile" for Select is not in code — the native element is sr-only form backing on every viewport.

Sub-components

Current

Deprecated — listed for migration, never for new work

DeprecatedReplace withUsages to migrate
Multi-selectSelect with multiple1 (PersonRail)
ComboboxRecord select with free text1 (ChartAccountDialogs)
Check menuSelect with multiple / Record select multi2
Rail pickerRecord select anchored in a rail row2
Entity pickerRecord select with async search12
Product pickerRecord select, async, products2

Migration order (largest first): Entity picker → Product picker → Check menu → Rail picker → Multi-select → Combobox. Each step is a separate merge request; the deprecated entry disappears from the registry once its last usage is gone.

Source: docs/select/index.usage.md · GitLab