Kanzo UI
Overlays & feedback

Popover

A floating panel anchored to a trigger, for secondary controls that do not warrant a dialog.

Ark UI

Usage

import {
  Popover,
  PopoverBody,
  PopoverContent,
  PopoverFooter,
  PopoverHeader,
  PopoverTrigger,
} from "@kanzo-tech/ui";
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">Filters</Button>
  </PopoverTrigger>
  <PopoverContent className="w-72">
    <PopoverHeader title="Filters" description="Narrow the contracts shown on the board." />
    <PopoverBody>…</PopoverBody>
  </PopoverContent>
</Popover>

PopoverContent supplies its own Portal and positioner. The content has no fixed width — it is w-auto min-w-32 — so size it with a className when the panel holds a form.

Popover, Hover card or Tooltip

Three surfaces float beside a trigger, and the difference is not how much they hold — it is what the machine promises assistive technology, which is checkable rather than a matter of taste:

RoleWiringOpens on
Tooltiprole="tooltip"aria-describedby on the triggerhover and focus
HoverCardnonenonehover only
Popoverrole="dialog"aria-haspopup, aria-expanded, aria-controlsclick

Read down the last column and the rule falls out:

  • A tooltip describes its trigger. It is announced as part of the control, so it must be a short label and it must never hold anything focusable — a link inside a role="tooltip" is unreachable by keyboard and is read out as part of the button's name.
  • A hover card carries no semantics at all, which is the honest shape for a preview: content a mouse user gets as a bonus and nobody depends on. If a keyboard user needs it, it is the wrong component.
  • A popover is a dialog, so it is the only one of the three that may contain controls — a form, a menu, a button. It opens on click because a surface you can tab into needs an intentional way in and out.

Anatomy

PopoverContent portals and positions itself, so PopoverPositioner — the box Ark places against the trigger — is only needed when you are composing the floating layer by hand.

Popover
├── PopoverTrigger      (or PopoverAnchor, to position against something else)
└── PopoverContent      (portal + positioner)
    ├── PopoverArrow
    ├── PopoverHeader
    │   ├── PopoverTitle
    │   └── PopoverDescription
    ├── PopoverBody
    ├── PopoverFooter
    └── PopoverClose

Use PopoverAnchor when the panel should be positioned against an element other than the one that opens it — a highlighted table row opened from a toolbar button, for instance.

With a close button

Unlike Dialog, the X is off by default: a popover already closes on outside click and Escape, so the button is only worth its space when the panel holds a form the user might be mid-way through. When it is on, PopoverTitle reserves inline-end padding so the two never collide.

Placement

API Reference

Popover

PropTypeDefault
modalbooleantrue
lazyMountbooleantrue
unmountOnExitbooleantrue

Extends React.ComponentProps<typeof ArkPopover.Root>, so positioning, open, onOpenChange and the rest of the Ark API pass through.

PopoverContent

PropTypeDefault
showCloseButtonbooleanfalse

PopoverHeader

PropTypeDefault
titlestring
descriptionstring

On this page