Menu & popover
Transient surfaces that hold actions or detail. Both hide things behind a click, which is fine for the secondary and never acceptable for the urgent.
Overview
A menu holds actions. A popover holds content. A split button is a primary action with a menu of alternatives attached, and a menu button is a menu with no default. All four share one property that governs everything below: they are closed most of the time.
| Use | For | Never for |
|---|---|---|
| Menu button | A list of secondary actions with no obvious default | The primary action of a screen |
| Split button | A clear default plus alternatives — "Export PDF" with other formats | Actions of equal weight; that is a menu button |
| Popover | Supporting detail too long for a tooltip — a reference range, an explanation of a model's scope | Anything needed to act; anything requiring a decision |
| Dialog | — | See Dialog when a decision must be made before continuing |
Secondary only
Nothing behind a click is the only route to something a clinician needs. If it matters, it is on the screen.
Shallow
One level. Submenus cannot be held under interruption and are unreachable on touch with any reliability.
Yields
Positions itself clear of the alert region, closes on outside click and on Esc, and never blocks anything clinical.
Anatomy
Split button — a real default, alternatives attached.
Rules
- Never hide a primary action in a menu. The screen's main action is on the screen — see Button.
- Never put an alarm or a finding in either. Clinical signals are persistent and cannot live behind a click — see Alert Banner.
- Destructive items sit below a separator, last, and never adjacent to a routine action.
- Menu items are actions, not navigation. Places belong in Navigation; a menu that navigates loses the back button.
- No submenus. If a menu needs nesting it is a panel or a screen.
- Disabled items say why, inline — the same rule as Interaction states.
- Popovers close on outside click and on Esc, and never contain a form that submits. That is a Dialog.
- Repositions to stay clear of the alert region rather than overlapping it — see Elevation.
Do's and don'ts
The primary action is on the screen; the menu holds the secondary ones.
The action the screen exists for, one click down. Under time pressure it may as well not be there.
Destructive item last, below a separator, visually distinct.
Permanent deletion between two routine actions, styled identically. One slip on a moving cart.
Supporting explanation. The finding and its confidence are already on the screen behind it.
Reliance information behind a click. On a touch display, at the moment of the decision, it is not there.
Accessibility
- Radix Menu and Popover primitives, giving roles, focus trapping, outside dismissal and return focus correctly.
- Trigger carries
aria-haspopupandaria-expanded; the surface is labelled by its trigger. - Arrow keys move between menu items, Home and End jump to the ends, type-ahead selects, Esc closes and returns focus.
- Split button is two controls with separate accessible names — "Export PDF" and "Other export formats" — not one control with a hidden second target.
- Items meet the physical touch floor, which on a cart means fewer visible at once — see Scaling.
- Never
role="menu"for navigation. A list of links is anav, and screen-reader users navigate them differently.
Outcomes of use
What this contributes to, in the terms of Usability & context of use. These are attributes believed to contribute to an outcome; the outcome itself is settled by observing real use in a specified context, not by this page.
- Effectiveness — the action taken is the one intended, and nothing needed is unreachable because it was hidden.
- Efficiency — secondary actions available without occupying screen space that clinical content needs.
- Satisfaction — confidence that nothing important is concealed. A clinician who opens every menu to check has been given the wrong container.
Clinical safety notes
Trace these in your risk file (ISO 14971) and usability engineering file (IEC 62366-1).
- No alarm or finding inside a menu or popover. Mitigates: a clinical signal behind a click, invisible until sought.
- No primary action hidden. Mitigates: delay in a time-critical pathway.
- Destructive items separated and last. Mitigates: irreversible action from a mis-tap on an adjacent item.
- Repositions clear of the alert region. Mitigates: an open surface obscuring an active alarm.
- No submenus. Mitigates: structure that cannot be held under interruption or operated reliably by touch.
- Popovers never hold decision-relevant data. Mitigates: reliance information absent on touch surfaces and in print.
Implementation
$ npx shadcn@latest add https://md.notjustany.tech/r/menu.json
<MenuButton label="More">
<MenuItem onSelect={compare}>Compare with prior</MenuItem>
<MenuItem disabled reason="needs a new ECG">Re-analyse</MenuItem>
<MenuSeparator />
<MenuItem destructive onSelect={discard}>Discard draft report</MenuItem>
</MenuButton>
// Enforced: clinical signals cannot be hidden behind a click.
if (containsAlarm(children)) {
throw new Error(
"[Menu] alarms and findings cannot render inside a menu or popover. " +
"Use AlertBanner in the docked alert region."
)
}
// Destructive items are always sorted last, below a separator.