Skip to content
ArcadiaDesign
Try it

TSX

Click-opened and non-modal by default, on the shared popup surface with 12px padding. It may hold controls: switches, a field, a pair of buttons. PopoverClose wraps any button that should close it.

Which overlay? A Popover holds content you act on. A Menu lists actions or choices. A Hover Card previews what a link points to, and a Tooltip names a control in a few words.

Examples

Sizes

Three widths with the same padding, shrinking to fit their preview frame on a narrow screen.

240 wide
320 wide, the default
400 wide

A list

With padding="list" the rows sit 6 in, their corners concentric with the frame.

Rows with a title

A title and a description start on the first ink of the rows, 12 from the edge, clear of the corner. A label too long for the width takes its meta's place first and then ends on a whole word, as in any ListRow.

Use collisionBoundary for a clipped frame. Placement and width stay inside it; rootStyle controls the preferred width and layout.

--popover-w
TokenRef<Measure>Default 320px
Width (240 / 320 / 400 by size), capped by the available boundary.

A non-modal dialog: the trigger gets aria-expanded, the title and description name and describe the popup, focus moves in on open and returns to the trigger on close. Pass modal (or modal="trap-focus") when it holds a task that must be finished or cancelled before going back to the page.

Esc
Closes the popover
Tab
Moves through its controls

Popover

modal
boolean | "trap-focus"Default false
false: focus may leave, which closes it. true: focus is trapped and the page behind is inert. "trap-focus": focus is trapped, the page stays as it is.
open
boolean
Controlled open state.
defaultOpen
booleanDefault false
Initial open state when uncontrolled.
onOpenChange
(open: boolean, details: OpenChangeDetails) => void
Called when the popup opens or closes, with why (details.reason) and the event.
onOpenChangeComplete
(open: boolean) => void
Called once the open or close transition has finished.

render
RenderProp<{ disabled: boolean }>
Replace the rendered element, e.g. render={<a href="/settings" />}, or a function of props and state.
disabled
boolean
Native disabled: no pointer events, no tooltip, skipped by Tab.
focusableWhenDisabled
boolean
Keep a disabled control focusable and hoverable (aria-disabled), so a tooltip can say why.
nativeButton
boolean
Button semantics, inferred from what renders: a <button> is native, an <a> stays a link, anything else gets role="button" and key handling. false forces button semantics on whatever renders (a link acting as a button).

Rest props go to <button> props.

rootStyle
RootStyle<PopoverKnobs>
Typed StyleX override: where the popover sits (layout) and --popover-w.
side
"top" | "bottom" | "left" | "right" | "inline-start" | "inline-end"Default "bottom"
align
"start" | "center" | "end"Default "center"
sideOffset
numberDefault 6
alignOffset
number
collisionBoundary
Element | null
The clipping boundary for placement and available width; defaults to the viewport.
collisionAvoidance
{ side?: "flip" | "none"; align?: "flip" | "shift" | "none"; fallbackAxisSide?: "start" | "end" | "none" }
Placement corrections; a growing preview can keep its preferred side while shifting horizontally.
size
"sm" | "md" | "lg"Default "md"
Width 240 / 320 / 400.
padding
"default" | "list"Default "default"
default: content padded 12, 15 above and below. list: rows (ListRow) padded 6, their corners concentric with the popover's; a PopoverTitle and PopoverDescription start where the rows' text does, 12 from the frame.
container
PortalContainerDefault document.body
Portal container.
instant
boolean
Skip the open/close transition.
initialFocus
FocusTarget
Where focus goes on open: an element, false to stay, or a function of how it opened. Default: the first field or button inside (the popup itself on touch).
finalFocus
FocusTarget
Where focus goes on close. Default: the trigger.
className
string
A product's hook class for its own rules (being retired: new code sets rootStyle).

Rest props go to <div> props.