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.