Skip to content

Popover

Popover opens a panel next to its trigger button. The panel holds whatever you put in it, which is why it is a role="dialog" and not a menu: a reader told “menu” expects a list of commands. Open it, then press Escape, click outside it, or Tab out of it:

PopoverDemo.tsx
import { Paragraph } from '@hozo/core'
import { Button, Popover } from '@hozo/ui'
export function PopoverDemo() {
return (
<Popover trigger="Shipping" accessibilityLabel="Shipping">
<Paragraph className="text-sm text-hozo-text-body">
Two days, or four to an island. Orders placed before noon leave the same day.
</Paragraph>
<Button tone="quiet" size="sm" href="#returns">
Read the returns policy
</Button>
</Popover>
)
}
  • trigger is what the button says. The component draws the button itself and wires aria-expanded and aria-controls to the panel.
  • accessibilityLabel names the panel, or accessibilityLabelledBy points at a heading inside it. A dialog with no name is one a screen reader announces and can say nothing about.
  • Not modal by default. The rest of the page stays reachable, and the panel closes when focus leaves it, so it is never left open behind the page. Pass modal when the contents need the keyboard to stay inside, as a date grid does: it then traps Tab and announces aria-modal together.
  • open and onOpenChange control it, or defaultOpen opens it on mount and leaves it uncontrolled.
  • placement and offset say where the panel goes. It flips to the other side when there is no room.