A floating panel anchored to a trigger element, ideal for displaying rich content on demand.
A popover component built on Base UI's Popover primitive. It renders content in a portal, positioned relative to a trigger element, with entry and exit animations. Useful for forms, settings panels, or any non-modal content that should appear near its trigger.
import {
Popover,
PopoverTrigger,
PopoverContent,
PopoverHeader,
PopoverTitle,
PopoverDescription,
} from "@/components/ui/popover"
import { Button } from "@/components/ui/button"
export default function PopoverDemo() {
return (
<Popover>
<PopoverTrigger render={<Button variant="outline" />}>
Open Popover
</PopoverTrigger>
<PopoverContent>
<PopoverHeader>
<PopoverTitle>Popover Title</PopoverTitle>
<PopoverDescription>
This is a simple popover with a title and description.
</PopoverDescription>
</PopoverHeader>
</PopoverContent>
</Popover>
)
}
import {
Popover,
PopoverTrigger,
PopoverContent,
PopoverHeader,
PopoverTitle,
PopoverDescription,
} from "@/components/ui/popover"<Popover>
<PopoverTrigger>Open</PopoverTrigger>
<PopoverContent>
<PopoverHeader>
<PopoverTitle>Settings</PopoverTitle>
<PopoverDescription>Adjust your preferences.</PopoverDescription>
</PopoverHeader>
{/* Content here */}
</PopoverContent>
</Popover><Popover>
<PopoverTrigger>
<Button variant="outline">Open popover</Button>
</PopoverTrigger>
<PopoverContent>
<p>This is the popover content.</p>
</PopoverContent>
</Popover><Popover>
<PopoverTrigger>
<Button variant="outline">Dimensions</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverHeader>
<PopoverTitle>Dimensions</PopoverTitle>
<PopoverDescription>Set the dimensions for the layer.</PopoverDescription>
</PopoverHeader>
<div className="grid gap-2">
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="width">Width</Label>
<input id="width" defaultValue="100%" className="col-span-2 h-8" />
</div>
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="height">Height</Label>
<input id="height" defaultValue="25px" className="col-span-2 h-8" />
</div>
</div>
</PopoverContent>
</Popover>Control where the popover appears relative to its trigger using the side, align, and offset props.
<Popover>
<PopoverTrigger>
<Button variant="outline">Right-aligned</Button>
</PopoverTrigger>
<PopoverContent side="right" align="start" sideOffset={8}>
<p>Content aligned to the right.</p>
</PopoverContent>
</Popover>The root component that manages open/close state. Does not render any DOM element itself.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. |
onOpenChange | (open: boolean) => void | — | Callback when the open state changes. |
children | ReactNode | — |
The element that toggles the popover. Renders its child and attaches click and accessibility handlers.
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | ReactNode | — |
The floating panel rendered in a portal. Wraps Base UI's Popup inside a Positioner.
| Prop | Type | Default | Description |
|---|---|---|---|
align | "start" | "center" | "end" | "center" | Horizontal alignment relative to the trigger. |
alignOffset | number | 0 | Offset from the aligned edge in pixels. |
side | "top" | "bottom" | "left" | "right" | "bottom" | Which side of the trigger the popover appears on. |
sideOffset | number | 4 | Distance from the trigger in pixels. |
className | string | — | |
children | ReactNode | — |
A flex column container for the title and description, with small text and a vertical gap.
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | ReactNode | — |
Renders the popover heading with font-medium.
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | ReactNode | — |
Renders secondary text in text-muted-foreground.
| Prop | Type | Default |
|---|---|---|
className | string | — |
children | ReactNode | — |