For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Popover

A floating panel anchored to a trigger — for non-modal overlays, forms, and contextual detail.

import { Settings2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";

export const PopoverDemo = () => (
    <Popover>
      <PopoverTrigger asChild><Button variant="outline"><Settings2 />Open settings</Button></PopoverTrigger>
      <PopoverContent className="w-80">
        <div className="flex flex-col gap-4">
          <div className="space-y-1">
            <h4 className="text-sm font-medium leading-none">Dimensions</h4>
            <p className="text-muted-foreground text-sm">Set the dimensions for the layer.</p>
          </div>
          <div className="grid gap-2">
            <div className="grid grid-cols-3 items-center gap-4">
              <Label htmlFor="width">Width</Label>
              <Input id="width" defaultValue="100%" className="col-span-2 h-8" />
            </div>
            <div className="grid grid-cols-3 items-center gap-4">
              <Label htmlFor="max-width">Max. width</Label>
              <Input id="max-width" defaultValue="300px" className="col-span-2 h-8" />
            </div>
            <div className="grid grid-cols-3 items-center gap-4">
              <Label htmlFor="height">Height</Label>
              <Input id="height" defaultValue="25px" className="col-span-2 h-8" />
            </div>
          </div>
        </div>
      </PopoverContent>
    </Popover>
  );

Placement

Control placement with side and align on PopoverContent. Defaults to side="bottom" align="center".

<PopoverContent side="right" align="start">
  ...
</PopoverContent>

Controlled

Manage open state externally with open and onOpenChange.

const [open, setOpen] = useState(false);
 
<Popover open={open} onOpenChange={setOpen}>
  <PopoverTrigger asChild>
    <Button onClick={() => setOpen(true)}>Open</Button>
  </PopoverTrigger>
  <PopoverContent>
    <Button variant="ghost" onClick={() => setOpen(false)}>Close</Button>
  </PopoverContent>
</Popover>

With sounds

Pass sounds to play open/close audio feedback (uses dropdownOpen / dropdownClose).

<Popover sounds>
  ...
</Popover>

Custom anchor

Use PopoverAnchor when the popover should be positioned relative to a different element than the trigger.

<Popover>
  <PopoverAnchor asChild>
    <div className="border rounded-md p-4">Anchor element</div>
  </PopoverAnchor>
  <PopoverTrigger asChild>
    <Button>Open</Button>
  </PopoverTrigger>
  <PopoverContent>Content positioned relative to the anchor.</PopoverContent>
</Popover>

Popover vs Dialog

PopoverDialog
InteractionNon-modal — background stays interactiveModal — background blocked
DismissClick outside or EscapeExplicit close button or Escape
Use forContextual forms, filters, detailConfirmations, focused tasks

Props

Popover

PropTypeDefaultDescription
openboolean—Controlled open state
defaultOpenbooleanfalseUncontrolled initial state
onOpenChange(open: boolean) => void—Callback when state changes
soundsbooleanfalsePlays open/close audio feedback

PopoverContent

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""bottom"Preferred side
align"start" | "center" | "end""center"Alignment relative to trigger
sideOffsetnumber4Gap between trigger and panel
classNamestring—Default width is w-72 — override as needed

Usage

import { Button } from "@/components/ui/button";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
 
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">Open</Button>
  </PopoverTrigger>
  <PopoverContent>
    <p className="text-sm">Popover content here.</p>
  </PopoverContent>
</Popover>

Specs

# Mint — Popover Specs
 
## Component
- name: popover
- file: registry/mint/popover.tsx
- installs to: components/ui/popover.tsx
- dependencies: radix-ui
- registryDependencies: none
 
## What is it
A non-modal floating panel anchored to a trigger element, rendered in a Portal
via Radix UI Popover. Use it for contextual forms, filters, and detail overlays
that must not block the rest of the UI. Prefer Dialog when the task requires
full user attention or a modal backdrop.
 
## Visual identity
Floating surface uses --popover (white in light, dark grey in dark) with a
subtle shadow-md and 0.625rem border radius, giving a clean and contained feel.
Default width is w-72 with p-4 padding — compact but readable.
 
## Design tokens
--popover: oklch(1 0 0) / oklch(0.269 0 0)           — panel background
--popover-foreground: oklch(0.145 0 0) / oklch(0.985 0 0) — panel text
--border: oklch(0.88 0.04 155 / 60%) / oklch(0.32 0.05 155 / 40%)      — panel border
 
## Sub-components
- Popover        → Root; accepts sounds prop for open/close audio feedback
- PopoverTrigger → wraps the trigger element; use asChild to forward to a Button
- PopoverContent → floating panel rendered in Portal; default w-72, p-4, sideOffset=4
- PopoverAnchor  → optional alternative positioning anchor, independent of trigger
 
## States
- data-[state=open]:   fade-in-0 + zoom-in-95 + slide-in-from-{side}-2
- data-[state=closed]: fade-out-0 + zoom-out-95
- data-[side=bottom]:  slides in from top-2
- data-[side=top]:     slides in from bottom-2
- data-[side=left]:    slides in from right-2
- data-[side=right]:   slides in from left-2
 
## Conventions
- Default placement is side="bottom" align="center" — override via PopoverContent props
- sideOffset defaults to 4px; increase for more visual separation from the trigger
- PopoverContent default width is w-72 — pass className to override
- Use PopoverAnchor when the panel should be positioned relative to a different element than the trigger
- Sub-components expose data-slot="popover", data-slot="popover-trigger", data-slot="popover-content", data-slot="popover-anchor" for CSS targeting
- sounds / haptic: GIN Design exclusive — plays audio (dropdownOpen / dropdownClose) on open and close via useFeedback hook

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/popover