Popover
Installation
Install the component via the CLI in one command.
npx shadcn@latest add @intentui/popover
Composed components
When you install this component via the CLI, it automatically loads all composed components, so you don’t need to add them individually.
Manual installation
Use this approach if you prefer to install and wire up the component yourself instead of using the CLI.
npm install react-aria-components
Anatomy
PopoverTrigger wraps a Button and Popover. It manages the trigger interaction and open state, so you do not need to pass a button ref or manage state for an uncontrolled popover. PopoverTrigger is an alias of DialogTrigger.
"use client"
import { Button } from "@/components/ui/button"
import {
Popover,
PopoverBody,
PopoverDescription,
PopoverFooter,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
export function Example() {
return (
<PopoverTrigger>
<Button>Open popover</Button>
<Popover aria-labelledby="" aria-label="Project details">
<PopoverHeader>
<PopoverTitle>Project details</PopoverTitle>
<PopoverDescription>Review your project before continuing.</PopoverDescription>
</PopoverHeader>
<PopoverBody>Popover body</PopoverBody>
<PopoverFooter>
Review your project details before continuing.
</PopoverFooter>
</Popover>
</PopoverTrigger>
)
}PopoverTrigger labels the popover from its opening button by default. To provide a separate aria-label, clear the inherited label with aria-labelledby="" as shown above.
Popover provides the dialog semantics itself. Do not wrap its content in the Intent UI Dialog, which creates a separate overlay.
Examples
Controlled
Pass isOpen and onOpenChange to PopoverTrigger to control the popover programmatically. Placement and appearance props stay on Popover.
Overlay arrow
Popovers come with an arrow that points to the trigger element, but it’s hidden by default. To display it, pass the arrow prop.
Placement
You can change the placement of the popover by passing the placement prop.
The list above shows the primary directions, but you can also use specific placements like bottom left or top right. Here are all the available placement options:
| Primary Direction | Placement |
|---|---|
bottom | bottom, bottom left, bottom right, bottom start, bottom end |
top | top, top left, top right, top start, top end |
left | left, left top, left bottom |
start | start, start top, start bottom |
right | right, right top, right bottom |
end | end, end top, end bottom |
Custom close
Use a button with onPress={() => setIsOpen(false)} to close a controlled popover. Escape and clicking outside also close it through onOpenChange.
Custom trigger
Place your custom button inside PopoverTrigger. For an avatar trigger, put Avatar inside Button and give the button an aria-label. The wrapper handles the trigger ref and ARIA state.
Component API
PopoverTrigger
PopoverTrigger is an alias of the Intent UI DialogTrigger, which uses React Aria Components DialogTrigger. It wraps the opening button and popover.
isOpenbooleandefaultOpenbooleanonOpenChange(isOpen: boolean) => voidPopover
Popover extends the React Aria Components <Popover> component.
triggerRefReact.RefObject<HTMLElement | null>isOpenbooleanonOpenChange(isOpen: boolean) => voidarrowbooleanfalseclassNamestringPopoverHeader
PopoverHeader extends the Intent UI <DialogHeader> component.
classNamestringdescriptionstringtitlestringPopoverTitle
PopoverTitle extends the Intent UI <DialogTitle> component.
classNamestringPopoverDescription
PopoverDescription extends the Intent UI <DialogDescription> component.
classNamestringPopoverBody
PopoverBody extends the Intent UI <DialogBody> component.
classNamestringPopoverFooter
PopoverFooter extends the Intent UI <DialogFooter> component.
classNamestringPopoverClose
PopoverClose is an alias of DialogClose and uses the close slot. That slot requires a content-only React Aria Dialog inside the popover; PopoverTrigger alone does not provide it. With the default composition shown above, use a controlled PopoverTrigger and a Button that calls setIsOpen(false) to close the popover. It extends the Intent UI <DialogClose> component.
classNamestringintent"primary" | "secondary" | "warning" | "danger" | "success" | "outline" | "plain"plainSee the React Aria for the full API reference.
