How to build an accessible Popover in React
The trigger is a real <button> with aria-haspopup="dialog" and aria-expanded reflecting open state, and the panel uses role="dialog" via the native Popover API so Escape-to-close and light-dismiss come from the platform rather than custom handlers.
When to use a Popover
- Showing rich, interactive content anchored to a trigger that the user must explicitly open by clicking
- Lightweight transient panels (forms, pickers, detail cards) that do not need to block the rest of the page
When not to use it
- A short, non-interactive text hint on hover/focus — use Tooltip
- A task that must capture focus and block interaction with the page — use Modal
- Preview content revealed on hover without a click — use HoverCard
Keyboard interactions
Role dialog, verified at WCAG 2.2-AA.
Escape
Common mistakes
Avoid: <Tooltip content={<form>...</form>}>
Prefer: <Popover><PopoverTrigger>…</PopoverTrigger><PopoverContent><form>…</form></PopoverContent></Popover>
Tooltips are non-interactive and hover-driven; interactive content needs a click-opened dialog popover that users can move focus into
Example
<Popover>
<PopoverTrigger>Open settings</PopoverTrigger>
<PopoverContent>
<form>…</form>
</PopoverContent>
</Popover>