Components
Popover
View in FigmaPortalled popover surface for small contextual content anchored to a trigger.
Install
npx shadcn@latest add @alix/popoverPreview
Usage
<Popover>
<PopoverTrigger render={<Button variant="outline">Review status</Button>} />
<PopoverContent align="start" className="w-72">
<p className="text-sm text-muted-foreground">
The final deck is due Friday.
</p>
<PopoverClose render={<Button size="sm">Done</Button>} />
</PopoverContent>
</Popover>Examples
01
Side-aligned context
Side placement keeps a short explanation attached to the exact control it clarifies.
<Popover>
<PopoverTrigger
render={
<IconButton variant="ghost" aria-label="Explain review status">
<Info />
</IconButton>
}
/>
<PopoverContent side="right" align="start" className="w-72 rounded-none">
<div className="flex flex-col gap-2">
<h3 className="text-sm font-medium text-foreground">Review status</h3>
<p className="text-sm text-muted-foreground text-pretty">
Strategy, finance, and legal notes are combined before the final client review.
</p>
</div>
</PopoverContent>
</Popover>02
Dismissible decision card
PopoverClose and ButtonGroup keep a lightweight acknowledgement anchored to its trigger.
<Popover>
<PopoverTrigger render={<Button variant="outline">Decision needed</Button>} />
<PopoverContent align="start" className="w-80 rounded-none">
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Badge variant="warning" dot>Client input</Badge>
<h3 className="text-sm font-medium text-foreground">Confirm the working capital scenario</h3>
<p className="text-sm text-muted-foreground text-pretty">
The team needs a base-case assumption before publishing the next cash bridge.
</p>
</div>
<ButtonGroup
primaryAction={<PopoverClose render={<Button size="sm">Done</Button>} />}
secondaryAction={<PopoverClose render={<Button variant="outline" size="sm">Later</Button>} />}
/>
</div>
</PopoverContent>
</Popover>03
Small form helper
A compact Field and Input can live in a popover when the edit is local and non-blocking.
<Popover>
<PopoverTrigger render={<Button variant="outline">Edit label</Button>} />
<PopoverContent align="start" className="w-80 rounded-none">
<div className="flex flex-col gap-4">
<Field label="Workspace label">
<Input defaultValue="Board update" />
</Field>
<PopoverClose render={<Button size="sm">Save label</Button>} />
</div>
</PopoverContent>
</Popover>When to use it
Use it for
- Anchored contextual content that is longer than a tooltip but lighter than a modal.
- Small local edits, explanations, or acknowledgement cards tied to one trigger.
- Dismissible content where the user can keep working in the page behind it.
Reach for something else
- One-line hover hints — use Tooltip instead.
- Command lists, links, or radio choices — use Menu instead.
- Blocking decisions or multi-step forms — use Dialog instead.
- Large side panels that need scrollable space — use Drawer instead.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| Popover | open?, defaultOpen?, onOpenChange? | — | The Base UI state root for the popover. |
| PopoverTrigger / PopoverClose | render: ReactElement | — | Open and close slots rendered through Base UI's render prop, so the passed element keeps its full API. |
| PopoverContent | side?, align?, sideOffset?, alignOffset? | side "bottom", align "center", sideOffset 8 | The portalled popup surface and positioning options. |