Acronis UIKit
Components

Popover

A floating panel anchored to a trigger, for secondary content or quick actions.

Usage

import {
  Popover,
  PopoverTrigger,
  PopoverContent,
  PopoverBody,
  PopoverFooter,
} from '@acronis-platform/ui-react';

Popover is a compound component built on Base UI's Popover primitive (positioning, focus management, outside-press / Esc dismissal). Popover owns the open state; PopoverTrigger toggles and anchors it; PopoverContent is the portaled, positioned popup (side / align / sideOffset), themed by the --ui-popover-* container tokens (color, border, radius, min/max width). PopoverBody and PopoverFooter are optional parts for the body-rhythm and default action-row footer recipe shown in Figma — themed by --ui-popover-body-* and the shared --ui-footer-* tier respectively.

Examples

A popover with a heading and description:

<Popover>
  <PopoverTrigger render={<Button variant="secondary">Open</Button>} />
  <PopoverContent>
    <PopoverBody>
      <h4 className="font-medium leading-none">Dimensions</h4>
      <p className="text-sm text-muted-foreground">
        Set the dimensions for the layer.
      </p>
    </PopoverBody>
  </PopoverContent>
</Popover>

With the default action-row footer (Cancel + Apply):

<Popover>
  <PopoverTrigger render={<Button variant="secondary">Open</Button>} />
  <PopoverContent>
    <PopoverBody>Drop any content into this slot.</PopoverBody>
    <PopoverFooter>
      <Button variant="secondary">Cancel</Button>
      <Button>Apply</Button>
    </PopoverFooter>
  </PopoverContent>
</Popover>

Position it with side / align:

<PopoverContent side="right" align="start">
  {/* … */}
</PopoverContent>

Controlled — drive open and react to onOpenChange:

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

<Popover open={open} onOpenChange={setOpen}>
  {/* …trigger + content… */}
</Popover>;

When the popover renders inside an isolated container (e.g. a shadow root), pass a portalContainer so the popup inherits that scope's styles. Whenever a portalContainer is resolved (explicit prop, or the nearest PortalContainerProvider), PopoverContent defaults to fixed positioning instead of the platform default (absolute) — otherwise a constrained container (e.g. a Shadow DOM host with overflow: hidden) would clip the popup at its own edge, since an absolute popup shares that ancestor's containing block. fixed escapes a plain overflow-clipping ancestor: for a fixed-positioned popup, collision detection drops an overflow ancestor that doesn't establish its own containing block, so the platform's default collision boundary already resolves to the real viewport — no explicit collisionBoundary override is needed for this case. Note fixed isn't an absolute guarantee, though: an ancestor with a transform, filter, will-change, backdrop-filter, perspective, or contain: paint/layout does establish its own containing block, so a fixed popup can still be clipped inside one. Override via positionMethod / collisionBoundary for either case. This only applies to portaled content — portal={false} keeps the platform default.

API Reference

PopoverContent

Prop

Type

Popover (root) accepts the Base UI Popover root props — open / defaultOpen, onOpenChange. PopoverTrigger and PopoverPortal wrap the matching Base UI parts. PopoverBody and PopoverFooter accept the standard attributes of the <div> they render. See the Base UI Popover docs for the full prop surface.

Edit on GitHub

On this page