Skip to content

Popover

Non-modal floating content anchored to a trigger — rich detail or a small form.

Stablev0.4.2added in v0.1.0@garn/ui/popover
On this page

Installation

garn is copy-in — the garn CLI writes this component's source into your project, so you own and can edit it. It resolves any base files and installs the npm dependencies below for you.

terminal
npx garn-ui add popover
First time? Set up garn in your project
Registry
popover
Deps
@radix-ui/react-popover
Registry deps
utilsframe

Import

import { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } from "@garn/ui/popover";

Anatomy

The parts this component is built from — compose them to assemble it.

PopoverRequired

Root — owns the open state.

PopoverTriggerRequired[data-slot="popover-trigger"]

The control that toggles the popover (asChild to wrap your own button).

PopoverContentRequired[data-slot="popover-content"]

The floating, portaled surface (side/align/sideOffset configurable).

PopoverAnchor[data-slot="popover-anchor"]

Optional positioning anchor when it differs from the trigger.

Props

The component's public props and their types.

No component-specific props — this is a thin wrapper over its native element.

Styling

Target these data-slots and states, and remap these tokens, to restyle without forking the component.

[data-slot="popover-content"]

States

SelectorState
[data-state=open]open
[data-state=closed]closed
PropertyTokenTier
padding--garn-pad-panelsemantic · air

When to use

Show contextual detail or a small interactive form anchored to a control, without blocking the page.

Reach for something else when

  • A task that must be completed/acknowledged first (use dialog)
  • a static text hint (use tooltip)
  • a list of commands/actions (use dropdown-menu).

Overview

Popover floats a small, interactive surface anchored to a control without blocking the page behind it — a quick form, a settings cluster, a date picker. Popover owns open state, PopoverTrigger toggles it, and PopoverContent is the portaled surface (configurable side/align/sideOffset). Unlike a Dialog it's non-modal: the rest of the page stays live. For a non-interactive text hint use Tooltip; for a list of commands use DropdownMenu; for a focused, page-blocking task use Dialog.

Guidelines

Use a popover for interactive content, not a passive hint. If the surface only shows a sentence of help, that's a Tooltip; reserve Popover for things the user clicks into. Open on click/press — never on hover, which makes the content impossible to reach.

Keep it small and self-contained. A popover is for one quick task; if it grows into a multi-section form or needs its own scroll, promote it to a Dialog or Sheet. Position it near its trigger and let it flip to stay on-screen rather than forcing a side.

Preserve focus and dismissal. Move focus into the content on open and return it to the trigger on close; Escape and outside-click should both dismiss. Give the content an accessible name when it isn't obvious from context.

Leave the surface solid. The panel is a solid, opaque surface by default — the right look for a popover anchored over ordinary page content. appearance="glass" is an opt-in frosted-translucent treatment reserved for a panel shown over a dimmed backdrop (e.g. inside a Dialog), where the frost has something to read against; over the open page it only looks muddy.

Best practices

Do
  • Anchor to the control that opened it; keep the content compact.
  • Allow click-away and Escape to dismiss.
  • Keep the default solid surface; reach for appearance="glass" only over a dimmed backdrop.
Don't
  • Don't put a long, blocking workflow in a popover — that's a dialog.
  • Don't use a popover for a plain text hint — that's a tooltip.

Content guidelines

  • Keep the content brief and focused; lead with the most useful control or fact.
  • If it has a title, make it specific to the popover's purpose.

Troubleshooting

A Select/Combobox/DatePicker popup — or any popover over the page — looks frosted and muddy.

Cause. An older build made the frosted glass surface the default; a popover anchored over ordinary page content has no dimmed backdrop for the frost to read against.

Fix. The surface is solid by default now — leave appearance unset. Pass appearance="glass" only for a panel shown over a dimmed backdrop (e.g. inside a Dialog).

Accessibility

Role
dialog
ARIA APG
dialog (non-modal)
Focus
Non-modal: focus enters the content but the rest of the page stays interactive.

Keyboard

EnterSpaceToggle the popover from the trigger.
EscapeClose and return focus to the trigger.
TabMove through the content; focus is NOT trapped (non-modal).
A2.1.1KeyboardA2.4.3Focus OrderA4.1.2Name, Role, Value
  • Trigger gets aria-expanded / aria-controls; focus moves into the content on open and back on close.