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

When not to use it

Keyboard interactions

Role dialog, verified at WCAG 2.2-AA.

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>

See the full Popover reference →