Skip to content
SevenUI
Esc
navigateopen⌘Jpreview
Sign in
On this page

Popover

Displays rich content in a portal, positioned relative to an anchor element, built on the Base UI Popover primitive.

"use client";

import { Button } from "@/registry/base/ui/button";
import { Input } from "@/registry/base/ui/input";
import { Label } from "@/registry/base/ui/label";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/registry/base/ui/popover";

export default function PopoverDemo() {
  return (
    <Popover>
      <PopoverTrigger
        render={<Button variant="outline">Open popover</Button>}
      />
      <PopoverContent className="grid gap-4">
        <div className="space-y-2">
          <div className="font-medium text-sm">Dimensions</div>
          <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="height">Height</Label>
            <Input
              id="height"
              defaultValue="25px"
              className="col-span-2 h-8"
            />
          </div>
        </div>
      </PopoverContent>
    </Popover>
  );
}

Installation

npx shadcn@latest add https://sevenui.dev/r/popover.json

Usage

"use client";

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 default function PopoverDemo() {
  return (
    <Popover>
      <PopoverTrigger
        render={<Button variant="outline">Open popover</Button>}
      />
      <PopoverContent className="grid gap-4">
        <div className="space-y-2">
          <div className="font-medium text-sm">Dimensions</div>
          <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="height">Height</Label>
            <Input id="height" defaultValue="25px" className="col-span-2 h-8" />
          </div>
        </div>
      </PopoverContent>
    </Popover>
  );
}

API reference

Popover

Extends the Base UI Popover Root — all its props apply.

Prop Type Default
open / defaultOpen boolean false
onOpenChange (open: boolean) => void
modal true | false | "trap-focus" false

modal: true only traps focus if a Close part is rendered inside PopoverContent — otherwise there’s no way to dismiss with the keyboard.

PopoverTrigger

Hover-opening lives here, not on the Root.

Prop Type Default
openOnHover boolean false
delay number 300 (ms)
closeDelay number 0 (ms)

PopoverContent

Prop Type Default
side / align positioner placement "bottom" / "center"
initialFocus / finalFocus focus target on open/close

For custom anchoring (a rect, or a different element than the trigger), compose the Popover primitive directly and pass anchor to its Positioner instead of using PopoverContent.

PopoverHeader, PopoverTitle, PopoverDescription

Styled layout parts extending div/the Base UI Title and Description.

Was this page helpful?