Overlay decisions
The overlays family (see /design-system/overlays) gives you a tooltip, a menu, a popover, a confirm dialog, a modal, a drawer/inspector and a floating panel — plus two ways to acknowledge a result (an inline alert and a toast). This page is the rule for choosing between them. The governing principle: use the lightest surface that does the job. Start at the top of the ladder and only step down to something heavier or more interrupting when the lighter option genuinely can't carry the need — a modal that should have been a popover steals focus for no reason.
- the rule
- Reach for the lightest, least-interrupting surface that works. Heavier surfaces (Modal, ConfirmDialog) trap focus and block the page — spend that cost only when the task truly demands it.
- anchored vs centred
- Tooltip / Menu / Popover hang off a trigger (contextual). Modal / ConfirmDialog sit centred over a backdrop (full attention). Drawer / Inspector / Floating panel sit beside the work (keep context).
- blocking vs non-blocking
- Modal and ConfirmDialog block until resolved. Everything else is dismissible by outside-press / Esc and never holds the user hostage.
- acknowledgement is separate
- Telling the user something happened is a different decision: an inline Alert (persists, tied to a region) or a Toast (transient, global, auto-dismiss). See the sub-flow below.
- this page vs Overlays
- Overlays shows each surface live with its props. This page is the WHICH — a decision tree + a use-which-when table. No live overlays here.
Reach for the lightest
Ordered by how much the surface interrupts. Prefer something on the left; step right only when forced. A red destructive ConfirmDialog and a focus-trapping Modal are the heaviest tools you have — they should feel like a deliberate choice, not a default.
Decision tree
Walk it top to bottom. The first question you answer “yes” to is your surface — that's why the lighter options are asked first. Fall through every question and you land on a floating panel.
Start · you need a transient or floating surface
Is it a passive hint or extra label — shown on hover / focus, with nothing interactive inside?
Tooltip
A short, non-interactive hint. Must never be the only label.
Is it a short list of actions to pick from, hung off a trigger?
Menu (dropdown)
Row / card overflow (⋮), a toolbar's secondary actions.
Is it a small chunk of interactive content anchored to a control — a mini-form, a settings cluster, a help panel?
Popover
Richer than a tooltip, lighter than a modal. Closes on outside-press / Esc.
Is it a destructive or irreversible yes / no the user must confirm first?
ConfirmDialog
The guardrail before delete / discard. danger paints the confirm red.
Does it demand full attention and block the page until resolved — a focused task or a short form?
Modal
Centred, focus-trapping, dimmed backdrop. Use sparingly.
Is it a secondary flow, detail view, or quick-edit you want beside the work, keeping the page's context?
Drawer / Inspector
Slides in from an edge; docks to a bottom sheet on mobile.
No to all of the above — it's a tool the user keeps open while working.
Floating panel
A persistent, movable, non-blocking surface the user keeps open while working (Flyout / HoverCard / FloatingPanel).
Acknowledgement — alert in region vs toast
A separate decision: once an action has happened, how do you tell the user? Don't reach for a modal to say “Saved”. The question is whether the message is tied to a place and must stay, or whether it's a transient confirmation that can fade on its own.
You just need to tell the user a result happened
Alert in region (inline)
The message is tied to a specific area and must persist until the user deals with it — a form's validation summary, a section that failed to load, a standing warning at the top of a page.
role="alert" for errors; stays put, no auto-dismiss.
Toast
A transient, global confirmation that can safely auto-dismiss — “Saved”, “Copied”, “Couldn't reach the server”. Non-blocking, pauses on hover, easy to miss — never gate a flow on it.
useToast().add({ title, type }); auto-times-out.
- must the user act on it?
- If they have to fix something, keep it visible in place — an inline Alert. A toast that carries an action the user must take is the wrong tool; it can vanish before they reach it.
- is it tied to a place?
- Region-bound message (this field, this section) → Alert there. App-level, place-agnostic result → Toast.
- can it disappear?
- Safe to fade after a few seconds → Toast. Must stay until resolved → Alert.
Use which when
The whole decision collapsed into a lookup. “Blocks” = does it stop the user until resolved; “Anchored” = is it pinned to a trigger / inline, or centred / free-floating.
| Surface | Reach for it when | Blocks? | Anchored? |
|---|---|---|---|
| Tooltip | Add a passive hint or name on hover / focus. | No | Yes |
| Menu | Offer a short list of actions from a trigger. | No | Yes |
| Popover | Show small interactive content tied to a control. | No | Yes |
| ConfirmDialog | Gate a destructive / irreversible action. | Yes | No |
| Modal | Demand full attention for a focused task / short form. | Yes | No |
| Drawer / Inspector | Run a secondary flow beside the work, keeping context. | Partly | No |
| Floating panel | Keep a movable tool open while the user works. | No | No |
| Alert (in region) | State a result tied to a region that must persist. | No | Inline |
| Toast | Confirm a transient, global result that can auto-dismiss. | No | No |
- see them live
- Every surface here is demoed with its props on /design-system/overlays — this page only decides which one.
- when in doubt, go lighter
- If a popover would do, don't reach for a modal. If an inline alert would do, don't reach for a dialog. Interruption is a cost you pay on the user's behalf.