Choosing the right overlay
Match the overlay to the job: a tooltip names, a popover explains, a dialog asks, a modal or drawer holds a task.
A tooltip names, a popover explains, a drawer holds details.
The problem
Overlays get picked by how they look. Forms end up in tooltips that vanish when the mouse moves, a whole edit screen is squeezed into a popover, and a yes-or-no question takes over the page in a full-size modal. Each mismatch either blocks people for no reason or loses their work.
When to use it
Use it for
- Content that belongs to the current screen but doesn't need to be visible all the time.
- A short task or a decision that should keep the page behind it in view.
Not for
- Long or multi-step tasks, like onboarding or a full employee record: give them their own page and URL.
- Errors and warnings: show them inline, where the problem is, not in a popup.
- Content people need while they fill in the page: keep it on the page.
Anatomy
- TooltipNames an icon-only control. One short line, no links or buttons inside.
- PopoverNon-modal. A short explanation or a few quick controls anchored to a trigger.
- DialogModal. One question with two clear answers, such as a confirmation.
- ModalModal. A short, focused task, such as a 3 to 6 field form.
- DrawerA side panel for details, filters or a secondary task, keeping the list in view.
- BottomSheet and ActionSheetThe mobile versions: a sheet for a short task, an action sheet for a list of actions.
How to build it
- Ask if people must answer before they continue. If yes, it's modal: Dialog or Modal. If no: Popover, Drawer or Tooltip.
- Size the content. One line: Tooltip. A paragraph or a few controls: Popover. A form: Modal or Drawer.
- Use a Drawer when people need to see the list behind it, such as details of a selected row.
- On small screens, swap Modal and Drawer for BottomSheet, and Menu for ActionSheet.
- Never stack overlays. If a modal needs another modal, the task needs its own page.
- Return focus to the trigger when the overlay closes.
import { Button, Drawer, IconButton, Popover, Tooltip, TooltipTrigger } from "@nexera-ui/react";
import { LuInfo, LuSettings } from "react-icons/lu";
// Names an icon-only button
<TooltipTrigger>
<IconButton variant="ghost" icon={<LuSettings />} aria-label="Settings" />
<Tooltip>Settings</Tooltip>
</TooltipTrigger>
// Explains, without blocking the page
<Popover variant="with-header" title="How balances work" body="You earn 1.67 days a month.">
<IconButton variant="ghost" icon={<LuInfo />} aria-label="How balances work" />
</Popover>
// Details of a row, with the table still in view
<Drawer
title={person.name}
subtitle={person.role}
trigger={<Button variant="secondary">View details</Button>}
>
<PersonDetails person={person} />
</Drawer>Accessibility
| Key | Action |
|---|---|
| Escape | Closes the topmost overlay and returns focus to its trigger. |
| Tab | Stays inside a Dialog, Modal, Drawer or sheet; moves on past a Tooltip. |
| Focus | Shows a Tooltip on keyboard focus, not just on hover. |
- Modal overlays trap focus and hide the page behind them from screen readers.
- A Popover is non-modal: focus moves into it, but Escape or a click outside closes it.
- Tooltips are read as a description of their trigger. They can't hold interactive content.
- Overlays are portalled to the end of the body but keep the reading direction of the page.
Do and don't
DoUse a Drawer for details so people keep their place in the list.
Don'tOpen a modal on top of a modal.
DoKeep tooltips to a name or a shortcut: “Settings (S)”.
Don'tPut links, buttons or form fields in a tooltip.
DoUse a BottomSheet on phones, within reach of the thumb.
Don'tShow a centred desktop modal on a 360 px screen.