Popover
A small anchored surface for contextual information.
overlaymenu
Preview
Popover preview
Live · keyboard ready
When to use
- Click-opened panels with interactive content, like share settings or a small filter form.
- Non-modal helpers that should stay open while people interact with the rest of the page.
- Custom pickers built from your own controls anchored to a button.
When not to use
- Use tooltip for short hover labels.
- Use hover-card for read-only previews that open on hover.
- Use dialog when the choice must block the page, and dropdown-menu for a list of commands.
shadcn CLI
Also installs (1)
- manicat-foundation
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "popover",
"type": "registry:ui",
"title": "Popover",
"description": "A small anchored surface for contextual information.",
"categories": [
"disclosure"
],
"dependencies": [
"@radix-ui/react-popover"
],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json"
],
"files": [
{
"path": "registry/components/popover/popover.tsx",
"type": "registry:component",
"target": "@components/manicat/popover/popover.tsx"
},
{
"path": "registry/components/popover/popover.module.css",
"type": "registry:component",
"target": "@components/manicat/popover/popover.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/popover",
"meta": {
"tier": "free",
"kind": "component",
"docs": "https://manicat.viraza.net/components/popover",
"markdown": "https://uiarc.dev/components/popover/markdown",
"tags": [
"overlay",
"menu"
]
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { Popover, PopoverClose, PopoverContent, PopoverTrigger } from "@/components/manicat/popover/popover";
import { Button } from "@/components/manicat/button/button";
export function PopoverExample() {
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="secondary">Column settings</Button>
</PopoverTrigger>
<PopoverContent className="w-64 rounded-[var(--radius-panel)] border border-(color:--border) bg-fd-popover p-4 text-sm shadow-lg">
<p className="font-medium">Visible columns</p>
<p className="mt-1 text-(color:--text-muted)">The panel stays anchored to the trigger while the trigger springs back.</p>
<PopoverClose asChild>
<Button size="sm" className="mt-4 w-full">Done</Button>
</PopoverClose>
</PopoverContent>
</Popover>
);
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Column settings A small panel anchored to its trigger, closable from inside.
Column settings
A small panel anchored to its trigger, closable from inside. preview
Live · keyboard ready
column-settings-a-small-panel-anchored-to-its-trigger-closable-from-inside-.tsxtsx
"use client";
import { Settings2 } from "lucide-react";
import { Button } from "@/components/manicat/button/button";
import { Popover, PopoverClose, PopoverContent, PopoverTrigger } from "@/components/manicat/popover/popover";
export function PopoverColumnsExample() {
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="secondary">
<Settings2 size={16} /> Columns
</Button>
</PopoverTrigger>
<PopoverContent className="w-64 rounded-[var(--radius-panel)] border border-(color:--border) bg-fd-popover p-4 text-sm shadow-lg">
<p className="font-medium">Visible columns</p>
<p className="mt-1 text-(color:--text-muted)">Choose which columns appear in the table.</p>
<PopoverClose asChild>
<Button size="sm" className="mt-4 w-full">
Done
</Button>
</PopoverClose>
</PopoverContent>
</Popover>
);
}
Keyboard interactions
| Keys | Action |
|---|---|
| Enter / Space | Opens the popover from the trigger. |
| Escape | Closes the popover and returns focus to the trigger. |
Accessibility
- Radix sets aria-expanded, aria-controls, and aria-haspopup="dialog" on the trigger.
- Focus moves into the content on open and back to the trigger on close.
- Content is non-modal by default; give it a heading or aria-label when it holds controls.
Motion
- CSS transitions: the panel fades and settles from 5px toward its trigger at 0.97 scale on a spring; it leaves in 140ms.
- Transitions instead of keyframes, so a reopen mid-close reverses from where the panel is.
- Reduced motion drops the transform and keeps a short opacity fade.
Responsive behavior
- The panel is at least 12rem and at most min(22rem, 100vw minus 20px), so it never overflows a phone screen.
- Radix collision handling keeps it 10px from viewport edges by default and flips sides when needed.
Performance
- Pure CSS transitions with no motion runtime; content mounts in a portal only while open.
Notes for AI
- Use for click-opened, non-modal panels with interactive content. Use tooltip for short hover labels, hover-card for read-only previews, dialog when the choice must block.
- Compose Popover > PopoverTrigger asChild + PopoverContent. Pass side for placement.