Component

A floating surface anchored to a trigger. Use it for secondary content and controls that should not interrupt the current task.

preview
React
"use client"; import Popover from "@radui/ui/Popover"; import Button from "@radui/ui/Button"; const PopoverExample = () => { return ( <Popover.Root> <Popover.Trigger asChild> <Button>Open popover</Button> </Popover.Trigger> <Popover.Portal> <Popover.Content sideOffset={12}> <Popover.Arrow /> <Popover.Close asChild> <Button>Close</Button> </Popover.Close> </Popover.Content> </Popover.Portal> </Popover.Root> ) } export default PopoverExample
  • Positions against the trigger with viewport collision handling
  • Escape, outside pointer press and outside focus all dismiss
  • Controlled and uncontrolled open state via open, defaultOpen and onOpenChange
  • Optional modal mode that traps focus while open
  • Focus returns to the trigger when the popover closes

Import all parts of the component and piece them together

React
import Popover from "@radui/ui/Popover"; export default () => { return ( <Popover.Root> <Popover.Trigger>Open popover</Popover.Trigger> <Popover.Portal> <Popover.Content> <Popover.Close>Close</Popover.Close> <Popover.Arrow /> </Popover.Content> </Popover.Portal> </Popover.Root> ) }

The root component for the Popover. Owns the open state and the parts rendered inside it.

PropTypeDefault
open
boolean
--
defaultOpen
boolean
false
onOpenChange
(open: boolean) => void
--
modal
boolean
false
className
string
--
customRootClass
string
""

The button that toggles the popover open and closed.

PropTypeDefault
asChild
boolean
false
className
string
--
children
ReactNode
--

Renders the popover content into a portal so it escapes the trigger's overflow and stacking context.

PropTypeDefault
children
ReactNode
--
container
Element | null
--
forceMount
boolean
false

The floating surface. Positions itself against the trigger and owns dismissal behaviour.

PropTypeDefault
aria-label
string
--
aria-labelledby
string
--
side
"top" | "right" | "bottom" | "left"
"bottom"
sideOffset
number
0
align
"start" | "center" | "end"
"center"
alignOffset
number
0
avoidCollisions
boolean
true
collisionPadding
number
0
collisionBoundary
Element | null | Array<Element | null>
--
arrowPadding
number
0
sticky
"partial" | "always"
"partial"
hideWhenDetached
boolean
false
forceMount
boolean
false
asChild
boolean
false
onOpenAutoFocus
(event) => void
--
onCloseAutoFocus
(event) => void
--
onEscapeKeyDown
(event: KeyboardEvent) => void
--
onPointerDownOutside
(event) => void
--
onFocusOutside
(event) => void
--
onInteractOutside
(event) => void
--

Closes the popover and returns focus to the trigger.

PropTypeDefault
asChild
boolean
false
className
string
--
children
ReactNode
--

An optional pointer that tracks the trigger. Render it inside Content.

PropTypeDefault
className
string
--
width
number
--
height
number
--

Positions the popover against a specific element instead of the trigger.

PropTypeDefault
className
string
--
children
ReactNode
--
ShortcutDescription
Escape

Closes the popover and returns focus to the trigger.

Tab

Moves focus to the next focusable element inside the popover content.

Shift + Tab

Moves focus to the previous focusable element inside the popover content.

ReferenceWhat Rad UI follows

Content uses dialog semantics with labelling, focus containment and dismiss behaviour.