Anchored floating panel for contextual content next to a trigger, without blocking the page.
Description
Popover is a compound component built on Radix Popover. It renders a portal-anchored floating panel next to whatever opened it, composed from a root plus sub-parts: PopoverTrigger, PopoverAnchor, PopoverContent, PopoverArrow, PopoverClose, PopoverImage, PopoverBody, PopoverHeader, PopoverTitle, PopoverDescription, PopoverFooter, PopoverActions, and PopoverActionText.
PopoverContent owns the size and hands it to every child through context, so setting size once there cascades to the width, radius, shadow, and the title, description, body, and footer text. Reach for it for contextual mini-forms, rich tooltips, anchored option panels, and profile hovercards, anything that adds detail next to a trigger without interrupting the page. For a blocking interaction that traps focus, use Modal; for a plain text hint, use Tooltip; for a list of actions, use Dropdown Menu.
Popover is a Create UI Pro component. With a Pro seat, npx @create-ui/cli add popover installs it. The previews below are marked with a Pro badge.
Installation
Anatomy
PopoverContent renders the portal itself, so it sits directly under the trigger (or anchor). Put the image above PopoverBody, and the header, footer inside it.
PopoverAnchor is optional: omit it and the panel anchors to PopoverTrigger. Include it only when the panel should point at a different element than the one that opens it.
Usage
Examples
Every example below is a Pro preview (marked with a Pro badge). Each renders a trigger button; open it to see the panel.
Sizes
size sets the width, radius, and shadow on PopoverContent, and cascades to every child's spacing and type scale. sm, md, and lg cover most contextual panels; sm is the default.
Placement
side sets which edge of the trigger the panel opens from: top, right, bottom, or left. bottom is the default.
Alignment
align sets how the panel lines up along that edge: start, center, or end. For start and end, the offset auto-derives from size so the panel doesn't overhang the trigger.
With Image
PopoverImage renders above PopoverBody and clips its child to the content's radius. Use it for release notes, media previews, or anything with a banner image.
With Close Button
showClose renders a built-in top-right soft-pill close button, no extra wiring needed. Leave it off (the default) when the panel closes on outside click, Escape, or a PopoverClose you place yourself.
With Footer
PopoverFooter lays out a row: PopoverActionText is the muted status text on the left, PopoverActions groups the buttons on the right. Wrap a dismiss control in PopoverClose asChild to close on click.
No Arrow
showArrow={false} drops the little tail pointing at the trigger and nudges sideOffset out to compensate. Use this for panels that shouldn't read as "attached" to a specific point.
Anchor
Render PopoverAnchor around an element other than PopoverTrigger to position the panel against it. The trigger inside still controls open state; only the positioning target moves.
Controlled
Pass open and onOpenChange on the root to drive the panel from your own state, useful when something outside the trigger (a keyboard shortcut, another control) needs to open or close it.
Accessibility
Popover is built on Radix Popover, which provides dismiss-on-outside-click, Escape-to-close, and focus return to the trigger on close.
ARIA notes:
PopoverTriggersetsaria-expandedandaria-haspopupon the underlying trigger element automatically.PopoverTitleandPopoverDescriptionare plain styleddiv/pelements, not Radix-labelled primitives, so nothing is auto-announced. If the panel needs a programmatic label, addaria-labeloraria-labelledbyyourself.- When
showCloseistrue, the renderedCloseButtonprovides its ownaria-label. - Opening does not trap focus or lock scroll (unlike
Modal); closing returns focus to the trigger.
Styling
Tailwind override: pass className to merge Tailwind classes with the component's CVA classes (via cn()):
Data slots and attributes: the components set these for CSS targeting:
data-slot="popover"on the root.data-slot="popover-trigger"on the trigger.data-slot="popover-anchor"onPopoverAnchor.data-slot="popover-arrow"on the arrow.data-slot="popover-close"onPopoverClose.data-slot="popover-content"on the panel, with Radix'sdata-stateanddata-sidefor open/close and placement animations.sizeis not exposed as adata-*attribute; it only drives styling throughPopoverSizeContext.data-slot="popover-image"on the image wrapper.data-slot="popover-body"on the content column.data-slot="popover-header"on the header.data-slot="popover-title"anddata-slot="popover-description"on the text.data-slot="popover-footer"on the footer row.data-slot="popover-actions"on the button cluster anddata-slot="popover-action-text"on the status text.
Target a specific state in CSS:
Related Components
- Modal: use this for a blocking interaction that traps focus, not anchored contextual content.
- Tooltip: use this for a passive text hint, not interactive content.
- Dropdown Menu: use this for a list of actions, not free-form content.
- Close Button: the control
PopoverCloserenders whenshowCloseistrue.
API Reference
Popover
Root that forwards to Radix Popover.Root. Extends React.ComponentProps<typeof PopoverPrimitive.Root>, so open, defaultOpen, onOpenChange, and modal are accepted.
Props
PopoverTrigger
The element that opens the panel. Wraps Radix Popover.Trigger; use asChild to render your own Button. Renders <button data-slot="popover-trigger">.
PopoverAnchor
Optional positioning target when the panel should point at something other than the trigger. Wraps Radix Popover.Anchor. Extends React.ComponentProps<typeof PopoverPrimitive.Anchor>.
PopoverContent
The floating panel. Renders the Radix portal, then your children. Extends React.ComponentProps<typeof PopoverPrimitive.Content> (minus children, className, side, align, sideOffset, alignOffset, which are redeclared below).
Props
PopoverArrow
Decorative tail pointing at the trigger. Rendered automatically by PopoverContent when showArrow is true; you don't render it directly.
PopoverClose
Wraps Radix Popover.Close and renders a CloseButton via asChild. Use your own asChild child (a footer Button) to make any control dismiss the panel.
PopoverImage
Banner slot rendered above PopoverBody. Clips its child image to the content's radius. Extends React.ComponentProps<"div">.
PopoverBody
Content column below the image. Extends React.ComponentProps<"div"> (padding and gap come from context).
PopoverHeader
Stacks the title and description. Extends React.ComponentProps<"div">.
PopoverTitle / PopoverDescription
Plain styled div (title) and p (description). Not Radix-labelled primitives, so add aria-label yourself if the panel needs a programmatic label.
PopoverFooter
Action row below the body. Extends React.ComponentProps<"div">.
PopoverActions
Trailing button cluster inside PopoverFooter. Extends React.ComponentProps<"div">.
PopoverActionText
Muted, left-aligned status text inside PopoverFooter. Extends React.ComponentProps<"p">.