Components
Popover
Displays rich content — text, controls, or a small form — in a floating panel anchored to a trigger, dismissed by clicking away or pressing Escape.
Basic usage
Wrap a PopoverTrigger and PopoverContent in a Popover. Use asChild on the trigger to render a Button.
With a form
Popovers are ideal for compact, inline editing. Widen the panel by passing a width utility to className.
Placement
Control where the panel appears with side and align on PopoverContent. It automatically flips to stay in the viewport.
Props
Popover — the root container that manages open state.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. Omit for uncontrolled, Radix-managed behavior. |
defaultOpen | boolean | false | Open state when initially rendered (uncontrolled). |
onOpenChange | (open: boolean) => void | — | Called when the open state changes via interaction. |
modal | boolean | false | When true, interaction outside the content is blocked and scroll is locked. |
PopoverTrigger — the element that toggles the panel.
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Merges props onto the single child instead of rendering a button — use to wire up a Button. |
PopoverContent — the floating panel, portaled to the body.
| Prop | Type | Default | Description |
|---|---|---|---|
side | 'top' | 'right' | 'bottom' | 'left' | 'bottom' | Preferred side of the trigger to render against. |
align | 'start' | 'center' | 'end' | 'center' | Alignment of the content against the trigger. |
sideOffset | number | 4 | Distance in pixels between the content and the trigger. |
className | string | — | Additional Tailwind classes to merge (e.g. override the default w-72 width). |
Accessibility
Built on Radix Popover — the trigger and content are linked via aria-controls and aria-expanded automatically.
Focus moves into the panel on open and returns to the trigger on close, so keyboard users never lose their place.
Pressing Escape or clicking outside dismisses the panel; Tab cycles through focusable content inside it.
Always render the trigger as an interactive element (a Button via asChild) so it is reachable and operable by keyboard.