Popover
Displays rich content in a floating panel, triggered by a button.
Overview
The Popover component displays rich interactive content anchored to a trigger element. It's built on Base UI for full accessibility and composability. Unlike tooltips, popovers can contain interactive elements like forms, buttons, and links.
import { Popover, PopoverContent, PopoverTrigger } from "@rogo-technologies/ui/popover"
<Popover>
<PopoverTrigger>Open</PopoverTrigger>
<PopoverContent>Content goes here</PopoverContent>
</Popover>Basic
A popover with a trigger button and rich content. Click the trigger to toggle the popover.
Sides
Use the side prop on PopoverContent to position the popover relative to the trigger. The popover will automatically flip to the opposite side if there isn't enough space.
<Popover>
<PopoverTrigger>Bottom</PopoverTrigger>
<PopoverContent side="bottom">Appears below</PopoverContent>
</Popover>Alignment
Use the align prop on PopoverContent to control where the popover aligns relative to the trigger along the cross axis.
Controlled
Use the open and onOpenChange props on Popover to control the popover state externally. This is useful when you need to close the popover programmatically.
const [open, setOpen] = useState(false)
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger>Toggle</PopoverTrigger>
<PopoverContent>
<Button onClick={() => setOpen(false)}>Dismiss</Button>
</PopoverContent>
</Popover>Close Button
Use PopoverClose inside the content to render a close button that dismisses the popover.
<PopoverContent className="relative">
<PopoverClose className="absolute top-2 right-2 ...">
<IconCrossMedium className="size-4" />
</PopoverClose>
<p>Content here</p>
</PopoverContent>Rich Content
Popovers can contain any React content — forms, inputs, buttons, and more.
Props
Popover (Root)
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. |
defaultOpen | boolean | false | Initial open state (uncontrolled). |
onOpenChange | (open: boolean) => void | — | Callback when open state changes. |
modal | boolean | false | Limits interaction to popover content when open. |
PopoverTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Merges props onto child element instead of wrapping. |
render | ReactElement | — | Base UI render prop — alternative to asChild. |
disabled | boolean | false | Prevents the popover from opening. |
PopoverContent
PopoverContent is a convenience wrapper that composes PopoverPortal, PopoverPositioner, and PopoverPopup into a single component.
| Prop | Type | Default | Description |
|---|---|---|---|
side | "top" | "right" | "bottom" | "left" | "bottom" | Which side of the trigger to position on. |
sideOffset | number | 4 | Distance from the trigger in pixels. |
align | "start" | "center" | "end" | "center" | Alignment along the cross axis. |
alignOffset | number | 0 | Offset along the alignment axis. |
collisionPadding | number | — | Distance from viewport edge before flipping. |
className | string | — | Additional CSS classes for the popup. |
PopoverClose
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Merges props onto child element. |
PopoverAnchor
Positions the popover relative to this element instead of the trigger. Wrap any element with PopoverAnchor to anchor the popover to it.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | CSS classes for the anchor wrapper. |
Additionally, all components accept standard HTML attributes for their underlying elements.
Composition
For advanced use cases, you can compose the lower-level primitives directly instead of using PopoverContent:
import {
Popover,
PopoverTrigger,
PopoverPortal,
PopoverPositioner,
PopoverPopup,
} from "@rogo-technologies/ui/popover"
<Popover>
<PopoverTrigger>Click me</PopoverTrigger>
<PopoverPortal>
<PopoverPositioner side="bottom" sideOffset={8}>
<PopoverPopup>
Custom popover content
</PopoverPopup>
</PopoverPositioner>
</PopoverPortal>
</Popover>Usage Guidelines
Do
- Use popovers for interactive content that requires user action (forms, settings, menus)
- Keep popover content focused on a single task
- Provide a clear way to dismiss the popover (close button or clicking outside)
- Use
PopoverTitleandPopoverDescriptionfor accessible labeling - Use the
asChildprop when wrapping interactive elements like buttons
Don't
- Don't use popovers for simple non-interactive text — use a tooltip instead
- Don't nest popovers inside popovers
- Don't put critical workflow steps only inside a popover
- Don't make popover content wider than the viewport on mobile
- Don't use
modalunless you need to trap focus for accessibility reasons