Popover
A positioned popup built on Base UI’s Popover primitive. Includes built-in Floating UI positioning, an optional arrow, and scale/fade enter/exit transitions.
Import
import { Popover } from "chunks-ui";Basic Usage
<Popover.Root>
<Popover.Trigger>More info</Popover.Trigger>
<Popover.Content>
<Popover.Title>Details</Popover.Title>
<Popover.Description>
This is additional context about the feature.
</Popover.Description>
</Popover.Content>
</Popover.Root>With Arrow
Popover.Arrow draws a small arrow on the popup edge that faces the trigger, filled with the popup’s --popover background and edged with its --border colour. Place it inside Popover.Content. The popup moves out by the arrow’s length, so sideOffset stays the gap between the trigger and the arrow’s tip. The arrow stays at least arrowPadding pixels from the popup’s ends, clear of the rounded corner. The default is the popup’s corner radius plus 0.21 × the arrow’s size (about 10 in the default theme). It is read when the popup mounts and again when a Popover.Arrow mounts or unmounts in it (not after a runtime --radius change), so it follows --radius, --spacing and a rounded-* class on Popover.Content. With align start or end next to a smaller trigger, the popup shifts so the arrow still points at the trigger’s centre (with the default center, near a viewport edge, the arrow can be held at the padding instead). With an arrow, the focus ring is drawn on the popup’s ::after, above the arrow. It is the same ring as without an arrow, and the ::after takes the popup’s border width, so restyle it with classes under the same has-[.PopupArrow]:focus-visible:after: prefix (for example has-[.PopupArrow]:focus-visible:after:outline-destructive), or remove it with focus-visible:after:hidden. In RTL, set dir="rtl" on <html> or <body>: the popup is portalled there, so a dir on a wrapper element doesn’t reach the arrow.
<Popover.Root>
<Popover.Trigger>Help</Popover.Trigger>
<Popover.Content>
<Popover.Arrow />
<Popover.Title>Need help?</Popover.Title>
<Popover.Description>
Contact support at help@example.com.
</Popover.Description>
</Popover.Content>
</Popover.Root>With Close Button
<Popover.Root>
<Popover.Trigger>Open</Popover.Trigger>
<Popover.Content>
<div className="flex items-center justify-between">
<Popover.Title>Settings</Popover.Title>
<Popover.Close>Close</Popover.Close>
</div>
<Popover.Description>
Configure your preferences here.
</Popover.Description>
</Popover.Content>
</Popover.Root>Positioning
The Popover.Content uses Base UI’s built-in Floating UI integration. It has a default sideOffset of 8px. You can customize placement via side and align props:
<Popover.Content side="bottom" align="start">
...
</Popover.Content>Animation
The popup enters with a scale-up and fade (from scale-95 and opacity-0): the popup spring (springs.popup) with Motion installed, a CSS transition of opacity and scale without it; reduced motion turns off both. The popup grows out of its trigger (origin-(--transform-origin)); a className such as origin-top replaces it.
render on Popover.Content replaces the element the spring animates, so a popup with render uses the CSS transition even with Motion installed. To restyle the popup, pass className.
Compound Parts
| Part | Description |
|---|---|
Popover.Root | State container. Manages open/close. |
Popover.Trigger | Element that toggles the popover. |
Popover.Content | Portal + positioner + popup panel. Default sideOffset={8}. Accepts side, align, alignOffset, arrowPadding props. With nothing tabbable inside, the popup takes focus itself. After keyboard use it then shows the library focus ring: 2px of --ring, 2px outside its edge. |
Popover.Arrow | Arrow on the popup edge that faces the trigger, in the popup’s --popover background and --border colour. Place it inside Popover.Content. |
Popover.Title | Popover heading. Semibold text-sm. |
Popover.Description | Supporting text. text-muted-foreground. |
Popover.Close | Button that closes the popover. |
Popover.Root Props
All props are forwarded to the underlying Base UI Popover.Root.
Disabling Popover.Trigger does not close an open popover. When you disable it, close the popover yourself (set open to false).
Popover.Content Props
All other props are forwarded to the underlying Base UI Popover.Popup.