Skip to content
Primitives

Popover

Floating panel with a hard offset shadow.

● LIVE

[ interactive — use the trigger to open ]

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

Installation

Install the theme first, then add the component:

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

Install the required dependencies:

npm install @radix-ui/react-popover

Copy the source from the Code tab above into components/ui/popover.tsx. It uses the cn helper and the okibi theme tokens — install the theme first if you haven't.

Usage

import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"

<Popover>
  <PopoverTrigger>Open</PopoverTrigger>
  <PopoverContent>Settings panel…</PopoverContent>
</Popover>

Anatomy

<Popover>
  <PopoverTrigger />   {/* anchor that opens the panel */}
  <PopoverContent />   {/* portaled HUD panel — name it with a heading */}
</Popover>

Examples

Form

Anchor a compact settings form to a trigger — labeled fields on the hard-shadow surface, dismissed on outside click.

● LIVE

[ interactive — use the trigger to open ]

API Reference

Popover

PropTypeDefaultDescription
openbooleanControlled open state.
onOpenChange(open: boolean) => voidFires when the panel opens or closes.
defaultOpenbooleanfalseInitial open state (uncontrolled).
modalbooleanfalseTrap focus and block background interaction while open.

PopoverContent

PropTypeDefaultDescription
align"start" | "center" | "end""center"Alignment against the trigger.
side"top" | "right" | "bottom" | "left""bottom"Preferred side to open on.
sideOffsetnumber4Gap in pixels between the trigger and the panel.

Accessibility

  • Radix moves focus into the panel on open, traps it while open, and returns focus to the trigger on close.
  • Dismisses on Escape and on outside click; modal can be toggled to control background interaction.
  • PopoverContent sets outline-none — correct, since focus lands inside the panel, not on the surface itself.
  • An anonymous panel has no accessible name — give it a heading or an aria-label so it's announced.

Guidelines

Do

  • Name the panel — lead with a heading or pass an aria-label to PopoverContent.
  • Override className to size the panel; the default is a fixed w-72.
  • For long content add max-h-[var(--radix-popover-content-available-height)] overflow-y-auto so it scrolls instead of overflowing.

Don't

  • Don't use a popover for a short hint that only labels its trigger — reach for a Tooltip.
  • Don't pack a popover with so much content it needs its own scroll region by default; that's a Dialog or Drawer.
  • Don't leave the panel unnamed when there's no visible heading.

On this page