Popover
An accessible popup anchored to a button.
import * as React from 'react';
import { Popover } from '@base-ui-components/react/popover';
import styles from './index.module.css';
export default function ExamplePopover() {
return (
<Popover.Root>
<Popover.Trigger className={styles.IconButton}>
<BellIcon aria-label="Notifications" className={styles.Icon} />
</Popover.Trigger>
<Popover.Portal>
<Popover.Positioner sideOffset={8}>
<Popover.Popup className={styles.Popup}>
<Popover.Arrow className={styles.Arrow}>
<ArrowSvg />
</Popover.Arrow>
<Popover.Title className={styles.Title}>Notifications</Popover.Title>
<Popover.Description className={styles.Description}>
You are all caught up. Good job!
</Popover.Description>
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
</Popover.Root>
);
}
function ArrowSvg(props: React.ComponentProps<'svg'>) {
return (
<svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}>
<path
d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z"
className={styles.ArrowFill}
/>
<path
d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z"
className={styles.ArrowOuterStroke}
/>
<path
d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z"
className={styles.ArrowInnerStroke}
/>
</svg>
);
}
function BellIcon(props: React.ComponentProps<'svg'>) {
return (
<svg fill="currentcolor" width="20" height="20" viewBox="0 0 16 16" {...props}>
<path d="M 8 1 C 7.453125 1 7 1.453125 7 2 L 7 3.140625 C 5.28125 3.589844 4 5.144531 4 7 L 4 10.984375 C 4 10.984375 3.984375 11.261719 3.851563 11.519531 C 3.71875 11.78125 3.558594 12 3 12 L 3 13 L 13 13 L 13 12 C 12.40625 12 12.253906 11.78125 12.128906 11.53125 C 12.003906 11.277344 12 11.003906 12 11.003906 L 12 7 C 12 5.144531 10.71875 3.589844 9 3.140625 L 9 2 C 9 1.453125 8.546875 1 8 1 Z M 8 13 C 7.449219 13 7 13.449219 7 14 C 7 14.550781 7.449219 15 8 15 C 8.550781 15 9 14.550781 9 14 C 9 13.449219 8.550781 13 8 13 Z M 8 4 C 9.664063 4 11 5.335938 11 7 L 11 10.996094 C 11 10.996094 10.988281 11.472656 11.234375 11.96875 C 11.238281 11.980469 11.246094 11.988281 11.25 12 L 4.726563 12 C 4.730469 11.992188 4.738281 11.984375 4.742188 11.980469 C 4.992188 11.488281 5 11.015625 5 11.015625 L 5 7 C 5 5.335938 6.335938 4 8 4 Z" />
</svg>
);
}
API reference
Import the component and assemble its parts:
import { Popover } from '@base-ui-components/react/popover';
<Popover.Root>
<Popover.Trigger />
<Popover.Portal>
<Popover.Backdrop />
<Popover.Positioner>
<Popover.Popup>
<Popover.Arrow />
<Popover.Title />
<Popover.Description />
<Popover.Close />
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
</Popover.Root>
Root
Groups all parts of the popover.
Doesn’t render its own HTML element.
Prop | Type | Default | |
---|
defaultOpen | boolean
| false
| |
---|
open | boolean
| undefined
| |
---|
onOpenChange | (open, event, reason) => void
| undefined
| |
---|
openOnHover | boolean
| false
| |
---|
delay | number
| 300
| |
---|
closeDelay | number
| 0
| |
---|
Trigger
A button that opens the popover.
Renders a <button>
element.
Prop | Type | Default | |
---|
className | string | (state) => string
| undefined
| |
---|
render | | React.ReactElement | (props, state) => React.ReactElement
| undefined
| |
---|
Attribute | Description | |
---|
data-popup-open | Present when the corresponding popover is open. |
---|
data-pressed | Present when the trigger is pressed. |
---|
Backdrop
An overlay displayed beneath the popover.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string
| undefined
| |
---|
keepMounted | boolean
| false
| |
---|
render | | React.ReactElement | (props, state) => React.ReactElement
| undefined
| |
---|
Attribute | Description | |
---|
data-open | Present when the popup is open. |
---|
data-closed | Present when the popup is closed. |
---|
data-starting-style | Present when the popup is animating in. |
---|
data-ending-style | Present when the popup is animating out. |
---|
Portal
A portal element that moves the popup to a different part of the DOM.
By default, the portal element is appended to <body>
.
Prop | Type | Default | |
---|
container | React.Ref | HTMLElement | null
| undefined
| |
---|
keepMounted | boolean
| false
| |
---|
Positioner
Positions the popover against the trigger.
Renders a <div>
element.
Prop | Type | Default | |
---|
align | 'start' | 'center' | 'end'
| 'center'
| |
---|
alignOffset | number
| 0
| |
---|
side | | 'bottom' | 'inline-end' | 'inline-start' | 'left' | 'right' | 'top'
| 'bottom'
| |
---|
sideOffset | number
| 0
| |
---|
arrowPadding | number
| 5
| |
---|
anchor | | React.Ref | Element | VirtualElement | (() => Element | VirtualElement | null) | null
| undefined
| |
---|
collisionBoundary | | 'clipping-ancestors' | Element | Element[] | Rect
| 'clipping-ancestors'
| |
---|
collisionPadding | number | Rect
| 5
| |
---|
sticky | boolean
| false
| |
---|
positionMethod | 'absolute' | 'fixed'
| 'absolute'
| |
---|
className | string | (state) => string
| undefined
| |
---|
keepMounted | boolean
| false
| |
---|
render | | React.ReactElement | (props, state) => React.ReactElement
| undefined
| |
---|
Attribute | Description | |
---|
data-open | Present when the popup is open. |
---|
data-closed | Present when the popup is closed. |
---|
data-anchor-hidden | Present when the anchor is hidden. |
---|
data-side | Indicates which side the popup is positioned relative to the trigger. |
---|
CSS Variable | Description | |
---|
--anchor-height | |
---|
--anchor-width | |
---|
--available-height | The available height between the trigger and the edge of the viewport. |
---|
--available-width | The available width between the trigger and the edge of the viewport. |
---|
--transform-origin | The coordinates that this element is anchored to. Used for animations and transitions. |
---|
A container for the popover contents.
Renders a <div>
element.
Prop | Type | Default | |
---|
initialFocus | | React.Ref | (interactionType => HTMLElement | null)
| undefined
| |
---|
finalFocus | React.Ref
| undefined
| |
---|
className | string | (state) => string
| undefined
| |
---|
render | | React.ReactElement | (props, state) => React.ReactElement
| undefined
| |
---|
Attribute | Description | |
---|
data-open | Present when the popup is open. |
---|
data-closed | Present when the popup is closed. |
---|
data-side | Indicates which side the popup is positioned relative to the trigger. |
---|
data-starting-style | Present when the popup is animating in. |
---|
data-ending-style | Present when the popup is animating out. |
---|
Arrow
Displays an element positioned against the popover anchor.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string
| undefined
| |
---|
render | | React.ReactElement | (props, state) => React.ReactElement
| undefined
| |
---|
Attribute | Description | |
---|
data-open | Present when the popup is open. |
---|
data-closed | Present when the popup is closed. |
---|
data-uncentered | Present when the popover arrow is uncentered. |
---|
data-anchor-hidden | Present when the anchor is hidden. |
---|
data-side | Indicates which side the popup is positioned relative to the trigger. |
---|
Title
A heading that labels the popover.
Renders an <h2>
element.
Prop | Type | Default | |
---|
className | string | (state) => string
| undefined
| |
---|
render | | React.ReactElement | (props, state) => React.ReactElement
| undefined
| |
---|
Description
A paragraph with additional information about the popover.
Renders a <p>
element.
Prop | Type | Default | |
---|
className | string | (state) => string
| undefined
| |
---|
render | | React.ReactElement | (props, state) => React.ReactElement
| undefined
| |
---|
Close
A button that closes the popover.
Renders a <button>
element.
Prop | Type | Default | |
---|
className | string | (state) => string
| undefined
| |
---|
render | | React.ReactElement | (props, state) => React.ReactElement
| undefined
| |
---|