Picker menu
canonAnchored menu of items with optional check marks and icons.
Slots added 27 Sep 2026 (acrm !3909, wave D): separator rows `{ key, sep: true }` with role=separator (edge/double separators dropped, same rule as Menu button), per-item `ariaLabel` for rows whose visible text is shorter than the full sentence, and a clear row (`clearLabel`/`clearIcon`/`onClear`) — role=menuitem, no check, NOT danger (clearing a value is reversible; red is only for deleting data). No group headings. Registry repaired 17 Oct 2026 (review F6): added exported PickerMenuPanel to react[].
Used in 51 files · 36 areas · 64× — components/AppShell, components/FilterBar, components/ai-employees, components/assistant, components/calendar, components/callwrapup …
@acrm/ui <PickerMenu> <PickerMenuPanel>.acrm-popover .acrm-popover-item .acrm-popover-sep .acrm-popover-emptySourceStoryLegacy card popover.htmlSelect-one menu on any trigger. React <PickerMenu> (packages/ui/src/components/PickerMenu.tsx) takes the trigger as a render prop (it receives open), anchors the DS <Popover> to it and renders .acrm-popover-item rows: optional 18px icon or stage dot · name (one line, ellipsis) · accent check on the current item — dropdown type A. It closes on pick and ignores a pick of the current value.
When to use
- Switching a view, stage, mode or layout from a button that is not a form field: record view switch, deal stage from a tile, sort key.
- A row needs an icon or a colour dot (
dot→.stagedot,var(--ic-*)). No identifier or note on the right — no grey trailing tag (owner 28 Sep 2026, ACRM-375–377); thedescprop is gone. - Any trigger shape —
.tchip(Nav select),.pipe-btn, a tile, a section title — the menu is the same.
When not to use
- A form field with a framed trigger — use Select.
- Composing a set — use Check menu (
menuitemcheckbox, stays open). - Records (people, companies, deals) — Record select. A long closed list of options (fields, templates) stays a Picker menu with
searchPlaceholder. - Actions rather than a value — Menu button (or
MenuPanel), never a barePopover.
Anatomy
- Anchor:
span[display:inline-flex]wrapping the caller's trigger; click toggles unlessdisabled. - Shell
<Popover role="menu">:.acrm-popoverfixed,z-index: 101,min-width: 180px,max-width: min(360px, 100vw − 16px),max-height: min(60vh, 420px),padding: var(--sp-2),--surface-100,1px --border-strong,--radius-md,--shadow-pop;alignstart/end to the anchor edge; scrim at 85. - Row
button.acrm-popover-item[role=menuitemradio]: 500 13px/20px,padding: var(--sp-2) var(--sp-3)→ 32px,gap: var(--sp-3),--radius-sm, hover--hover-surface. - Slots:
.ic18px grid,--fg-secondary,--ico-sm— holds<Icon>or.stagedot9px circle;.tx > .nm(ellipsis,--ink-900);.chk--accent--ico-xs,.off=visibility: hidden. - Groups:
.acrm-popover-sep1px--border— the only allowed separator; no eyebrow, no title (headeris only the invisiblearia-label). - Empty / loading:
.acrm-popover-empty(400 13px--fg-muted, centered) instead of rows — passitems=[]and the sentence inemptyLabel(„Načítám…", „Šablony se nepodařilo načíst."); a menu is never blank. - Search (optional,
searchPlaceholder, acrm !4312): the canonical.acrm-recordselect-searchrow above the rows; on desktop the list scrolls under a standing search. Filtering folds diacritics („mest" finds „Město"), a separator stays only between two non-empty groups, Enter picks the first visible row, no match showsemptyLabel(default „Nic nenalezeno"). The query resets when the menu closes; focus lands in the search even when it appears after the menu opened (items loaded on open). Use it for a long closed list (filter fields, mail templates), not for records. width: fixed desktop width for a searchable list, so the menu does not jump while typing.- Phone (< 720px):
BottomSheet— grab, title (=header, now--h2), the search at the same left edge as the row icons, rows, full-width Hotovo. Inside another sheet (a picker opened from a sheet) it stays an anchored panel above it — never a sheet over a sheet.
PickerMenuPanel — the same menu without its own trigger
PickerMenuPanel is the body of Picker menu with a host-owned anchor and open state (anchorEl, open, onClose) — for two triggers of one menu (mail templates: the footer tool and the rail header) or a trigger that must stay the host's. value={null} makes it a menu with no current value (no check), e.g. inserting a template is an action that may be repeated.
Best practices
- Use
dotfor stage menus so the colour matches the stage tile and rail (var(--ic-blue)etc.). - Don't add a grey note to a row (count, IČO, „neaktivní", „výchozí") — the row is its name only.
- Style the trigger's open state from the render-prop
open(.tchip.open,.rvsw-btn.open). - Put a destructive item last after a
.acrm-popover-sepwhen a menu mixes a value with an action — better: split into a Picker menu and an action popover.
- A heading, section label or search row inside a Picker menu — that is a Record select "in menu" variant.
- Two check marks or a check on action rows — the check is selection state only.
- Bold names or a
.subsecond line — removed 21 Aug 2026, not coming back. - A page-level copy (
.rvsw-menu,.xyz-menu) — this component replaces them.
Content
- Item names: nouns in sentence case ("Aktivity", "Profil", "Nabídka"); no trailing period.
- Menu name (
header) is only for assistive tech: a noun that names the choice ("Zobrazení", "Fáze"). - Empty text: one line, "Žádné položky".
Related
popover(family Popover) — the shell and action menus.nav-select—.tchip+ Picker menu.check-menu— the multi counterpart.select— same rows on a form trigger.- Stories:
components--picker-menu--default,components--picker-menu--variants(plain / icon / stage dot / tag),components--picker-menu--states(trigger rest & disabled, open, danger + separator),components--picker-menu--with-icon-kbd,components--picker-menu--composition(section title trigger + kebab); legacycomponents--popover-menu--picker-menu.
Source: docs/select/picker-menu.usage.md · GitLab