Overlays/Popover

Popover

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

Themed

When to Use

Use Popover when you need to:

  • Display interactive content like forms, settings, or filters in a floating panel
  • Show rich multi-element content triggered by a button click
  • Provide inline editing without navigating away from the current context
  • Present secondary controls or options without cluttering the main interface
  • Build date pickers, color pickers, or other compound input patterns

When Not to Use

Default

Popover with form inputs for setting dimensions. Demonstrates a common pattern for inline editing.

Simple

Basic popover with text content. The simplest usage pattern.

Positions

Popover can be positioned on any side of the trigger using the side prop: top, right, bottom, or left.

UX & Design Guidelines

Content Strategy

Keep popover content focused on a single task or group of related settings. Avoid deeply nested layouts or excessive scrolling inside popovers. If the content grows beyond what fits comfortably in a floating panel, consider using a Dialog or Sheet instead. Include a clear heading so users understand the popover's purpose at a glance.

Positioning & Overflow

The popover automatically flips to the opposite side when there is not enough viewport space. Use sideOffset to control the gap between the trigger and the panel (default is 4px). For alignment fine-tuning, combine align with alignOffset. The default width is w-72 (288px); override it with a className when needed.

Trigger Design

Always use asChild on PopoverTrigger to render a styled Button rather than a plain element. The trigger should clearly indicate that it opens additional content, for example by including a chevron icon or descriptive label.

Color & Contrast

The popover surface uses bg-popover with text-popover-foreground for consistent theming across light and dark modes. Borders, shadows, and rounded corners are applied by default. Inner content should continue to use semantic tokens like text-muted-foreground for descriptions and border-border for dividers.

Accessibility

Keyboard Navigation

  • Tab — Move focus to the popover trigger
  • Enter or Space — Open or close the popover
  • Tab — When open, move focus through interactive elements inside the popover
  • Escape — Close the popover and return focus to the trigger

Screen Reader Support

  • The trigger automatically receives aria-expanded reflecting the open state
  • The trigger is linked to the content via aria-controls
  • Icon-only triggers require aria-label for screen reader users
  • Use aria-describedby for additional context about what the popover contains

Focus Management

When the popover opens, focus moves to the first focusable element inside the content panel. When modal is set to true, focus is trapped within the popover until it is dismissed. On close, focus returns to the trigger element automatically.

Dismiss Behavior

The popover closes when pressing Escape, clicking outside the content, or when another popover opens. In modal mode, only Escape and explicit close actions dismiss the popover.

ARIA Attributes

{/* Standard popover with descriptive trigger */}
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline" aria-label="Edit dimensions">
      <Settings className="size-4" />
    </Button>
  </PopoverTrigger>
  <PopoverContent>
    {/* Interactive content receives focus */}
  </PopoverContent>
</Popover>

{/* Modal popover - traps focus within */}
<Popover modal>
  <PopoverTrigger asChild>
    <Button>Open modal popover</Button>
  </PopoverTrigger>
  <PopoverContent>
    {/* Focus is trapped until popover is dismissed */}
  </PopoverContent>
</Popover>

{/* Popover with explicit description */}
<Popover>
  <PopoverTrigger asChild>
    <Button aria-describedby="filter-hint">Filters</Button>
  </PopoverTrigger>
  <PopoverContent>
    <span id="filter-hint" className="sr-only">
      Opens a panel to configure search filters
    </span>
    {/* Filter form content */}
  </PopoverContent>
</Popover>

API Reference

The Popover component is composed of four sub-components. Each accepts the props listed below in addition to standard HTML attributes.

Popover (Root)

PropTypeDefaultDescription
openbooleanControlled open state of the popover.
onOpenChange(open: boolean) => voidEvent handler called when the open state changes.
defaultOpenbooleanfalseThe initial open state when uncontrolled.
modalbooleanfalseWhen true, interaction with outside elements is disabled and only popover content is visible to screen readers.

PopoverTrigger

PropTypeDefaultDescription
asChildbooleanfalseWhen true, the trigger renders its child as the root element, merging props and behavior.

PopoverContent

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""bottom"The preferred side of the trigger to render against.
sideOffsetnumber4Distance in pixels from the trigger element.
align"start" | "center" | "end""center"Alignment relative to the trigger element.
alignOffsetnumber0Offset in pixels from the aligned edge.
classNamestringAdditional CSS classes to apply to the popover content.

PopoverAnchor

PropTypeDefaultDescription
asChildbooleanfalseWhen true, uses the child element as the anchor reference for positioning.