Popover
A floating surface anchored to the control that opened it.
Popover is the container that positions transient content next to its trigger — a Menu, a form, a bit of detail. It handles anchoring, flipping, and dismissal; what goes inside is yours. For a modal that blocks the page, use Dialog.
DialogTrigger pairs the trigger with the Popover; the popover opens on press
and closes on Escape or an outside press.
import { DialogTrigger } from 'react-aria-components';
import { Button } from '@base-org/bds-web/product/button';
import { Popover } from '@base-org/bds-web/product/popover';DialogTrigger comes from react-aria-components; BDS does not re-export it.
<DialogTrigger>
<Button variant="outline">Open Popover</Button>
<Popover>
<div className="p-4 text-body text-bds-gray-80">Popover content</div>
</Popover>
</DialogTrigger>offset defaults to 8px of gap between the trigger and the surface. The popover
flips to the opposite side when there is no room, so treat placement as a
preference rather than a guarantee.
Entrance
entrance sets how the surface appears. The default, scale, grows it from
the trigger. drop also slides it 6px in from the trigger's side, down when it
opens below and up when it opens above, so a list feels attached to a compact
trigger such as a pill Select. Both leave with the same short fade.
<DialogTrigger>
<Button variant="outline">Open Popover</Button>
<Popover entrance="drop">
<div className="p-4 text-body text-bds-gray-80">Popover content</div>
</Popover>
</DialogTrigger>When to use
Use Popover for transient content anchored to its trigger — a short form, a bit of detail — that the reader can dismiss with an outside press.
Use something else when:
- The content is required or must not be lost by accident. Use Dialog.
- It only names a control. Use Tooltip.
- It is a list of actions. Use Menu, which renders inside a Popover for you.
Usage
Do
Give the surface its own padding. Popover clips its content but adds no inset, so lay out the children as you want them.
Don't
Put a required step or a destructive confirmation in a popover. It dismisses on an outside press — anything the reader must not lose belongs in a Dialog.
Props
| Prop | Type | Default |
|---|---|---|
arrowBoundaryOffsetThe minimum distance the arrow's edge should be from the edge of the overlay element. | Typenumber | Default0 |
arrowRefA ref for the popover arrow element. | TypeRefObject<Element | null> | Default— |
boundaryElementElement that that serves as the positioning boundary. | TypeElement | Defaultdocument.body |
childrenThe children of the component. A function may be provided to alter the children based on | TypeChildrenOrFunction<PopoverRenderProps> | Default— |
classNameThe CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the | TypeClassNameOrFunction<PopoverRenderProps> | Default— |
containerPaddingThe placement padding that should be applied between the element and its | Typenumber | Default12 |
crossOffsetThe additional offset applied along the cross axis between the element and its | Typenumber | Default0 |
defaultOpenWhether the overlay is open by default (uncontrolled). | Typeboolean | Default— |
entranceHow the surface enters. `scale` grows it from the trigger; `drop` also | Type"scale" | "drop" | Defaultscale |
getTargetRectOverrides the target element's bounding rectangle. Useful for positioning relative to | Type((target: Element) => DOMRect | null) | Defaulttarget.getBoundingClientRect() |
isEnteringWhether the popover is currently performing an entry animation. | Typeboolean | Default— |
isExitingWhether the popover is currently performing an exit animation. | Typeboolean | Default— |
isKeyboardDismissDisabledWhether pressing the escape key to close the popover should be disabled. | Typeboolean | Defaultfalse |
isNonModalWhether the popover is non-modal, i.e. elements outside the popover may be | Typeboolean | Default— |
isOpenWhether the overlay is open by default (controlled). | Typeboolean | Default— |
maxHeightThe maxHeight specified for the overlay element. | Typenumber | Default— |
offsetThe additional offset applied along the main axis between the element and its | Typenumber | Default8 |
placementThe placement of the element with respect to its anchor element. | Typeenum | Default'bottom' |
scrollRefA ref for the scrollable region within the overlay. | TypeRefObject<Element | null> | DefaultoverlayRef |
shouldCloseOnInteractOutsideWhen user interacts with the argument element outside of the popover ref, | Type((element: Element) => boolean) | Default— |
shouldFlipWhether the element should flip its orientation (e.g. top to bottom or left to right) when | Typeboolean | Defaulttrue |
shouldSkipAnimationWhether the popover should appear and disappear without an entry or exit animation. This is | Typeboolean | Default— |
shouldUpdatePositionWhether the overlay should update its position automatically. | Typeboolean | Defaulttrue |
triggerThe name of the component that triggered the popover. This is reflected on the element | Typestring | Default— |
triggerRefThe ref for the element which the popover positions itself with respect to. | TypeRefObject<Element | null> | Default— |
UNSTABLE_portalContainerThe container element in which the overlay portal will be placed. This may have unknown | TypeElement | Defaultdocument.body |
Accessibility
Popover wraps React Aria's Popover, which is modal by default: while open it
hides the rest of the page from assistive technology, dismisses on Escape or
an outside press, and returns focus to the trigger on close. Interactive
content inside, such as a Menu, carries its own roles, focus handling, and
keyboard behaviour.
The surface grows from the trigger as it opens, dropping in slightly with
entrance="drop", and leaves with a shorter, smaller fade. When the reader
prefers reduced motion, it appears and disappears without animating or moving.