Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by imskyleen
Edit on GitHub

Popover

Displays rich content in a portal, triggered by a button.

Installation

bash
npx shadcn@latest add @redpanda/popover
bash
pnpm dlx shadcn@latest add @redpanda/popover
bash
yarn dlx shadcn@latest add @redpanda/popover
bash
bunx shadcn@latest add @redpanda/popover
bash
nubx shadcn@latest add @redpanda/popover
bash
aube dlx shadcn@latest add @redpanda/popover

Positioning

Controlled

When to use

The Popover component displays rich content in a positioned overlay triggered by user interaction. Use this decision tree to determine when it’s appropriate:

Usage

tsx
<Popover>  <PopoverTrigger>Open Popover</PopoverTrigger>  <PopoverContent>Popover Content</PopoverContent></Popover>

Examples

Date Picker Example

Props

Content padding

Use PopoverContent padding="none" for a calendar or another component that owns its own inset. padding="sm" supplies 8 pixels and the default padding="md" supplies 16 pixels. Keep placement and width classes on the popup; do not override its padding with utilities.

Keyboard interactions

Key Action
Enter / Space on PopoverTrigger Toggles the popover open/closed.
Tab / Shift+Tab Cycles focus between focusable elements inside the popover.
Escape Closes the popover and restores focus to the trigger.
Click outside PopoverContent Closes the popover.

Accessibility

  • PopoverTrigger exposes aria-expanded / aria-controls for the screen-reader state of the popover.
  • PopoverContent is focusable and traps focus while open — pressing Tab past the last focusable control wraps back to the first.
  • The trigger must be a real button (or another interactive element via the render prop). Static <div> triggers lose focus behaviour.
  • onOpenChange uses Base UI’s native (open, eventDetails) => void signature.

Controlled vs uncontrolled

Uncontrolled — the popover owns open state:

tsx
<Popover onOpenChange={(open) => console.log('open:', open)}>  <PopoverTrigger>Open</PopoverTrigger>  <PopoverContent>{/* ... */}</PopoverContent></Popover>

Controlled — drive open from parent state (e.g. to open the popover programmatically or close it after a form submission):

tsx
const [open, setOpen] = useState(false);
<Popover open={open} onOpenChange={setOpen}>  <PopoverTrigger    render={      <Button onClick={() => undefined} variant="outline">        Open      </Button>    }  />  <PopoverContent>    <Button onClick={() => setOpen(false)}>Done</Button>  </PopoverContent></Popover>;

Credits

  • We use Base UI for the popover component.
  • We take our inspiration from Shadcn UI for the popover style.

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • patchv0.3.1## 🚧 Updated#112
See full history →

Last updated on

Was this page helpful?