Popover

Displays rich content in a floating panel, triggered by a button.

Examples

Basic

Sides

Alignment

Close button

Controlled

State: closed

Rich content

Overview

Popover displays rich interactive content anchored to a trigger element. Built on Base UI. Unlike tooltips, popovers can contain interactive elements like forms, buttons, and links.

tsx
import { Popover, PopoverContent, PopoverTrigger } from "@rogo-technologies/ui/popover";

<Popover>
  <PopoverTrigger>Open</PopoverTrigger>
  <PopoverContent>Content goes here</PopoverContent>
</Popover>;

Usage

Sides

Use side on PopoverContent to position the popover. It auto-flips if there isn't enough space.

tsx
<PopoverContent side="bottom">Appears below</PopoverContent>

Alignment

align controls position along the cross axis.

tsx
<PopoverContent side="bottom" align="start"></PopoverContent>

Close button

Render PopoverClose inside the content to give the user an explicit dismiss control.

tsx
<PopoverContent className="relative">
  <PopoverClose className="absolute top-2 right-2 …">
    <IconCrossMedium className="size-4" />
  </PopoverClose>
  <p>Content here</p>
</PopoverContent>

Controlled

tsx
const [open, setOpen] = useState(false);

<Popover open={open} onOpenChange={setOpen}>
  <PopoverTrigger>Toggle</PopoverTrigger>
  <PopoverContent>
    <Button onClick={() => setOpen(false)}>Dismiss</Button>
  </PopoverContent>
</Popover>;

Composition

For advanced cases, compose lower-level primitives instead of using PopoverContent.

tsx
import {
  Popover,
  PopoverTrigger,
  PopoverPortal,
  PopoverPositioner,
  PopoverPopup,
} from "@rogo-technologies/ui/popover";

<Popover>
  <PopoverTrigger>Click me</PopoverTrigger>
  <PopoverPortal>
    <PopoverPositioner side="bottom" sideOffset={8}>
      <PopoverPopup>Custom popover content</PopoverPopup>
    </PopoverPositioner>
  </PopoverPortal>
</Popover>;

API

Popover (Root)

PropTypeDefaultDescription
openbooleanControlled open state.
defaultOpenbooleanfalseInitial open state (uncontrolled).
onOpenChange(open: boolean) => voidCallback when open state changes.
modalbooleanfalseLimits interaction to popover content when open.

PopoverTrigger

PropTypeDefaultDescription
asChildbooleanfalseMerges props onto child element instead of wrapping.
renderReactElementBase UI render prop — alternative to asChild.
disabledbooleanfalsePrevents the popover from opening.

PopoverContent

Convenience wrapper composing PopoverPortal, PopoverPositioner, and PopoverPopup.

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""bottom"Which side of the trigger to position on.
sideOffsetnumber4Distance from the trigger in pixels.
align"start" | "center" | "end""center"Alignment along the cross axis.
alignOffsetnumber0Offset along the alignment axis.
collisionPaddingnumberDistance from viewport edge before flipping.
classNamestringAdditional CSS classes for the popup.

PopoverClose

PropTypeDefaultDescription
asChildbooleanfalseMerges props onto child element.

PopoverAnchor

Positions the popover relative to this element instead of the trigger.

PropTypeDefaultDescription
classNamestringCSS classes for the anchor wrapper.

All components accept standard HTML attributes for their underlying elements.

Guidelines

Do

  • Use popovers for interactive content that requires user action (forms, settings, menus)
  • Keep popover content focused on a single task
  • Provide a clear way to dismiss the popover (close button or clicking outside)
  • Use PopoverTitle and PopoverDescription for accessible labeling
  • Use asChild when wrapping interactive elements like buttons

Don't

  • Don't use popovers for simple non-interactive text — use a tooltip instead
  • Don't nest popovers inside popovers
  • Don't put critical workflow steps only inside a popover
  • Don't make popover content wider than the viewport on mobile
  • Don't use modal unless you need to trap focus for accessibility reasons
PreviousInput
Made in NYC© 2026 Rogo Technologies Inc.