Components
Displays rich content in a portal, triggered by a button.
Playground
w-72) by default — override with className. PopoverHeader, PopoverTitle and PopoverDescription give the body its standard heading stack.import {
Popover,
PopoverContent,
PopoverDescription,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@workspace/ui/components/popover"
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">Open popover</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverHeader>
<PopoverTitle>Dimensions</PopoverTitle>
<PopoverDescription>
Set the dimensions for the layer.
</PopoverDescription>
</PopoverHeader>
</PopoverContent>
</Popover>Field parts; the content's own gap-4 stacks the header and the field group.<Popover>
<PopoverTrigger asChild>
<Button variant="outline">Open form</Button>
</PopoverTrigger>
<PopoverContent className="w-80" align="start">
<PopoverHeader>
<PopoverTitle>Dimensions</PopoverTitle>
<PopoverDescription>
Set the dimensions for the layer.
</PopoverDescription>
</PopoverHeader>
<FieldGroup className="gap-3">
<Field orientation="horizontal">
<FieldLabel htmlFor="width">Width</FieldLabel>
<Input id="width" defaultValue="100%" className="h-8 w-36" />
</Field>
<Field orientation="horizontal">
<FieldLabel htmlFor="max-width">Max. width</FieldLabel>
<Input id="max-width" defaultValue="300px" className="h-8 w-36" />
</Field>
<Field orientation="horizontal">
<FieldLabel htmlFor="height">Height</FieldLabel>
<Input id="height" defaultValue="25px" className="h-8 w-36" />
</Field>
</FieldGroup>
</PopoverContent>
</Popover>align positions the content along the trigger's edge — start, center (the default) or end. It combines with side, and when there is not enough room Radix flips the popover to the opposite side automatically.<Popover>
<PopoverTrigger asChild>
<Button variant="outline">Start</Button>
</PopoverTrigger>
<PopoverContent align="start" className="w-56">
Aligned to the start of the trigger.
</PopoverContent>
</Popover>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">Center</Button>
</PopoverTrigger>
<PopoverContent align="center" className="w-56">
Centered on the trigger.
</PopoverContent>
</Popover>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">End</Button>
</PopoverTrigger>
<PopoverContent align="end" className="w-56">
Aligned to the end of the trigger.
</PopoverContent>
</Popover>align is logical — start hugs the right edge of the trigger in RTL. side stays physical: "left" is the left regardless of direction.<div dir="rtl">
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">افتح النافذة</Button>
</PopoverTrigger>
<PopoverContent align="start">
<PopoverHeader>
<PopoverTitle>الأبعاد</PopoverTitle>
<PopoverDescription>حدد أبعاد الطبقة.</PopoverDescription>
</PopoverHeader>
</PopoverContent>
</Popover>
</div>aria-haspopup="dialog", aria-expanded and aria-controls; the content is a role="dialog" panel. Focus moves into the content on open and returns to the trigger on close. Escape or an outside interaction dismisses it. Both parts carry data-state="open|closed" for styling.<button data-slot="popover-trigger" data-state="open" aria-haspopup="dialog" aria-expanded="true" aria-controls="radix-:r1:" > Open popover </button> <div data-slot="popover-content" data-state="open" role="dialog" id="radix-:r1:"> Popover content </div>
| Part | Prop | Type | Default |
|---|---|---|---|
| Popover | open | boolean | — |
| Popover | defaultOpen | boolean | false |
| Popover | onOpenChange | (open: boolean) => void | — |
| Popover | modal | boolean | false |
| PopoverTrigger | asChild | boolean | false |
| PopoverContent | side | "top" | "right" | "bottom" | "left" | "bottom" |
| PopoverContent | align | "start" | "center" | "end" | "center" |
| PopoverContent | sideOffset | number | 4 |
<Popover data-slot="popover" /> // Root — state container, renders nothing <PopoverTrigger data-slot="popover-trigger" /> // <button>, toggles the popover <PopoverAnchor data-slot="popover-anchor" /> // optional — position against this instead of the trigger <PopoverContent data-slot="popover-content" /> // portaled panel (w-72, bg-popover) <PopoverHeader data-slot="popover-header" /> // title + description stack <PopoverTitle data-slot="popover-title" /> <PopoverDescription data-slot="popover-description" />
Tokens used
8 design tokens consumed by the Popover component.
--popover
Popover
--popover-foreground
Popover Foreground
--foreground
Foreground
--muted-foreground
Muted Foreground
--font-weight-medium
Font weight Medium (500)
--text-sm
Text Small (14px)
--radius-md
Radius 0.8× (8px)
--spacing
Spacing unit (4px)