Popover

Anchored panel for mid-range tasks such as share sheets and short forms. Prefer Options Panel for denser inspectors, and Tooltip for hover-only hints.

Also known as: simple popover, light popover, lightweight popover, anchored popover, flyout

Installation

Install with the CLI, or copy the component source into your project.

Add popover (npm)

npx --yes -p @default-file/ui df-ui add popover

Share board

Mid-range composition: header bar, link field, access toggle, switch, and footer actions.

Tour step

Footer justify between places Previous and Next on opposite ends.

Variants

Surface styles for paper, muted, elevated, and inverse panels.

Sizes

Density ladder for padding, type, radius, and max width.

Chrome overrides

Token-backed overrides for surface, radius, shadow, border, padding, and type.

Arrow

Optional caret on each side with filter elevation.

Motion

animated defaults to true. Set false for an instant panel. prefers-reduced-motion disables motion.

Title badge

badge is an open ReactNode slot. badgePosition below stacks under the title; end places it on the title row.

Controlled

Parent state owns open. The panel always anchors to PopoverTrigger.

Offset

Distance from the trigger along the placement side.

Placement

start, center, and end on bottom and top. align auto picks the best fit; collision avoidance can flip the side.

Bottom

Top

Content-aware

Properties

Anchored panel for mid-range tasks such as share sheets and short forms. Compose header, body, and footer with kit controls. Prefer Options Panel for denser inspectors, and Tooltip for hover-only hints.

Popover

PropTypeDefaultNotes
openboolean-Controlled open state. Placement still uses PopoverTrigger when something else sets open.
defaultOpenbooleanfalseInitial open state when open is not passed. The popover manages open after that.
onOpenChange(open: boolean) => void-Called when open changes from the trigger, dismiss, PopoverClose, or parent updates.
childrenReactNode-Usually PopoverTrigger and PopoverContent.

PopoverTrigger

Placement anchor and usual toggle. The panel positions relative to this element when open.

PropTypeDefaultNotes
renderReactElement-Host element for the trigger. Toggles open and marks the anchor.
childrenReactNode-Trigger content when not using render.
classNamestring-Additional styles on the trigger host.

PopoverContent

PropTypeDefaultNotes
variant"default" | "muted" | "elevated" | "inverse""default"Surface recipe. muted softens fill and caret elevation. elevated strengthens shadow. inverse flips against the nearest .dark theme. Chrome props override recipe tokens.
size"sm" | "md" | "lg""md"Density for padding, type, radius, and max width. Padding and radius props override the size recipe.
showArrowbooleanfalseShow a caret toward the trigger. The anchoring engine keeps the caret aimed at the trigger after collision clamping. Uses filter elevation so the shadow includes the caret silhouette.
animatedbooleantrueOpen motion with opacity, scale, and short travel from the placement side. Set false for an instant panel. prefers-reduced-motion disables motion.
backgroundstring-Panel fill. Prefer tokens such as var(--popover). Sets --df-popover-surface.
foregroundstring-Panel text color. Prefer tokens such as var(--popover-foreground). Sets --df-popover-surface-fg.
borderColorstring-Border color. Prefer tokens such as var(--border). Sets --df-popover-border-color.
borderWidth"none" | "hairline" | "thin" | "thick""hairline"Border width step. Maps to --border-width-* via --df-popover-border-width.
shadowstring-Elevation override. Without showArrow, prefer box-shadow tokens and sets --df-popover-shadow. With showArrow, prefer filter tokens such as var(--df-shadow-popover) and sets --df-popover-elevation.
radius"none" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "full"-Corner radius step. Maps to --radius-* via --df-popover-radius.
cornerShape"round" | "smooth"-Instance corner curve. Omit to inherit --df-corner-shape from the theme (set at create/init).
paddingstring-Inset on all sides. Prefer spacing tokens. Sets each --df-popover-inset-*.
paddingXstring-Horizontal inset. Sets --df-popover-inset-left and --df-popover-inset-right.
paddingYstring-Vertical inset. Sets --df-popover-inset-top and --df-popover-inset-bottom.
paddingTopstring-Top inset. Sets --df-popover-inset-top. Wins over paddingY and padding.
paddingRightstring-Right inset. Sets --df-popover-inset-right. Wins over paddingX and padding.
paddingBottomstring-Bottom inset. Sets --df-popover-inset-bottom. With a direct PopoverFooter child, applied as footer bottom padding.
paddingLeftstring-Left inset. Sets --df-popover-inset-left. Wins over paddingX and padding.
gapstring-Gap between header, body, and footer. Prefer spacing tokens. Sets --df-popover-gap.
side"top" | "bottom" | "left" | "right""bottom"Preferred side. bottom and top are the usual bi-directional pair. left and right are supported. With collisionAvoidance, the panel can flip when space is tight.
align"start" | "center" | "end" | "auto""center"Alignment along the side. start, center, and end pin the panel. auto picks the best of those from available space.
sideOffsetnumber8Distance in pixels between the trigger and the panel along the placement side.
alignOffsetnumber0Shift in pixels along the alignment axis. Positive values move toward the end edge.
matchTriggerWidthbooleanfalseLock the panel width to the trigger. Off by default so the panel sizes to content within the size max width.
portalbooleantrueWhen true, render in document.body and copy the nearest .dark ancestor from the trigger. When false, render inline in the trigger tree.
dismissOnScrollbooleantrueClose when the page or an ancestor scrolls. Set false for panels with drag or scrollable controls.
followScrollbooleantrueReposition while the page or an ancestor scrolls. Set false to keep the last placement until the next open.
collisionAvoidancebooleantrueFlip and shift the panel to stay in view. Set false to keep the requested side and align.
classNamestring-Additional styles on the panel.
childrenReactNode-Panel content. Compose PopoverHeader, PopoverBody, and PopoverFooter as needed.

PopoverHeader

Stacks the title row and description. Use PopoverHeaderBar when the title shares a row with close.

PropTypeDefaultNotes
gapstring-Space between the title row and description. Prefer spacing tokens. Sets --df-popover-header-gap.
childrenReactNode-Usually PopoverHeaderBar then PopoverDescription, or title and description alone.
classNamestring-Additional styles on the header.

PopoverHeaderBar

Title row with an end-aligned close or action on one midline.

PropTypeDefaultNotes
gapstring-Space between the title and trailing control. Prefer spacing tokens. Sets --df-popover-header-bar-gap.
childrenReactNode-PopoverTitle first, then PopoverClose (often a ghost icon-xs Button).
classNamestring-Additional styles on the title row.

PopoverTitle

Panel title and accessible name. badge is an open ReactNode slot for status or meta.

PropTypeDefaultNotes
colorstring-Title color. Prefer tokens. Sets --df-popover-title-color.
fontSizestring-Title size. Prefer type tokens. Sets --df-popover-title-size.
fontWeightstring-Title weight. Prefer tokens. Sets --df-popover-title-weight.
fontFamilystring-Title font family. Prefer theme font tokens. Sets --df-popover-title-font.
lineHeightstring-Title line height. Prefer tokens. Sets --df-popover-title-leading.
letterSpacingstring-Title letter spacing. Prefer tokens. Sets --df-popover-title-tracking.
badgeReactNode-Open slot beside or under the title. Any ReactNode; Badge is common but not required.
badgePosition"end" | "below""end"end places the slot on the title row. below stacks it under the title.
childrenReactNode-Title text. Sets the accessible name on the panel.
classNamestring-Additional styles on the title.

PopoverDescription

PropTypeDefaultNotes
colorstring-Description color. Prefer tokens. Sets --df-popover-description-color.
fontSizestring-Description size. Prefer type tokens. Sets --df-popover-description-size.
fontWeightstring-Description weight. Prefer tokens. Sets --df-popover-description-weight.
fontFamilystring-Description font family. Prefer theme font tokens. Sets --df-popover-description-font.
lineHeightstring-Description line height. Prefer tokens. Sets --df-popover-description-leading.
letterSpacingstring-Description letter spacing. Prefer tokens. Sets --df-popover-description-tracking.
childrenReactNode-Supporting copy. Wired as aria-describedby when present.
classNamestring-Additional styles on the description.

PopoverBody

Main content region between header and footer.

PropTypeDefaultNotes
childrenReactNode-Kit controls such as Input, Toggle Group, and Switch.
classNamestring-Additional styles on the body.

PopoverClose

Dismisses the panel and returns focus to the trigger.

PropTypeDefaultNotes
renderReactElement-Host element to merge onto, usually a Button. Prefer ghost icon-xs in PopoverHeaderBar.
childrenReactNode-Label or icon for the close control.
classNamestring-Additional styles on the close host.

Keyboard and accessibility

Behavior for portaled panels. Dismiss (Escape / outside click): Closes the panel and returns focus to the trigger when focus was inside. Role (disclosure): Non-modal anchored panel with no dialog role and no focus trap. The trigger exposes aria-expanded and aria-controls while open. Use PopoverTitle for an accessible name via aria-labelledby, or aria-label on PopoverContent. High contrast (forced-colors): Under forced-colors, the panel keeps a visible border and the trigger keeps a focus outline.

Tokens

Theme defaults live on :root. Override these globally or on a local host.

TokenTypeDefaultNotes
--df-popover-width-smCSS length14remMax width for size sm.
--df-popover-widthCSS length18remMax width for size md.
--df-popover-width-lgCSS length22remMax width for size lg.
--df-popover-width-safeCSS lengthmin(var(--df-popover-width), calc(100vw - 8 * var(--spacing-unit)))Viewport-clamped md width for consumers.
--df-popover-arrow-sizeCSS lengthcalc(2 * var(--spacing-unit))Caret edge length.
--df-popover-arrow-offsetCSS lengthvar(--df-tooltip-arrow-offset)Caret overlap on the panel edge. Shared with Tooltip.
--df-popover-arrow-align-nudgeCSS lengthvar(--df-tooltip-arrow-align-nudge)Half-caret optical nudge for the trigger-tracked caret. Shared with Tooltip.
--df-anchor-arrow-crossCSS length50%Trigger-centered caret offset on the cross axis. Set by the anchoring engine after collision clamping.
--df-anchor-arrow-cross-insetCSS lengthcalc(3 * var(--spacing-unit))Minimum inset that keeps the trigger-tracked caret on the panel edge.
--df-popover-surfaceCSS colorvar(--popover)Panel fill. Set by background or variant.
--df-popover-surface-fgCSS colorvar(--popover-foreground)Panel text. Set by foreground or variant.
--df-popover-border-colorCSS colorvar(--border)Border and caret edge color. Set by borderColor.
--df-popover-border-widthCSS lengthvar(--border-width-hairline)Border width. Set by borderWidth.
--df-popover-shadowCSS box-shadowvar(--df-shadow-md)Box shadow when showArrow is false. Set by shadow or variant.
--df-popover-elevationCSS filtervar(--df-shadow-popover)Filter elevation when showArrow is true. Default var(--df-shadow-popover); muted uses var(--df-shadow-tooltip); elevated uses var(--df-shadow-popover-elevated).
--df-shadow-popoverCSS filterdrop-shadow(0 4px 6px rgb(0 0 0 / 0.1)) drop-shadow(0 2px 4px rgb(0 0 0 / 0.08))Default drop-shadow for caret popovers.
--df-shadow-popover-elevatedCSS filterdrop-shadow(0 12px 18px rgb(0 0 0 / 0.14)) drop-shadow(0 4px 8px rgb(0 0 0 / 0.1))Stronger drop-shadow for elevated caret popovers.
--df-popover-radiusCSS lengthvar(--radius-2xl)Corner radius. Set by radius or size.
--df-popover-inset-topCSS lengthcalc(3 * var(--spacing-unit))Shared top inset. Set by padding, paddingY, or paddingTop.
--df-popover-inset-rightCSS lengthcalc(4 * var(--spacing-unit))Shared right inset. Set by padding, paddingX, or paddingRight.
--df-popover-inset-bottomCSS lengthcalc(3 * var(--spacing-unit))Shared bottom inset. Set by padding, paddingY, or paddingBottom. Applied to Content or Footer when a footer is present.
--df-popover-inset-leftCSS lengthcalc(4 * var(--spacing-unit))Shared left inset. Set by padding, paddingX, or paddingLeft.
--df-popover-padding-topCSS lengthvar(--df-popover-inset-top)Resolved top padding. Defaults to --df-popover-inset-top.
--df-popover-padding-rightCSS lengthvar(--df-popover-inset-right)Resolved right padding. Defaults to --df-popover-inset-right.
--df-popover-padding-bottomCSS lengthvar(--df-popover-inset-bottom)Resolved bottom padding. Defaults to --df-popover-inset-bottom; 0 with a direct footer child.
--df-popover-padding-leftCSS lengthvar(--df-popover-inset-left)Resolved left padding. Defaults to --df-popover-inset-left.
--df-popover-gapCSS lengthcalc(3 * var(--spacing-unit))Gap between header, body, and footer. Set by gap.
--df-popover-header-gapCSS lengthcalc(1.5 * var(--spacing-unit))Gap between title row and description. Set by PopoverHeader gap.
--df-popover-header-bar-gapCSS lengthcalc(2 * var(--spacing-unit))Gap between title and close in PopoverHeaderBar. Set by PopoverHeaderBar gap.
--df-popover-footer-padding-topCSS length0pxFooter top padding. Set by PopoverFooter paddingTop.
--df-popover-footer-padding-bottomCSS length0pxFooter bottom padding. Defaults to --df-popover-inset-bottom with a direct footer child.
--df-popover-footer-padding-xCSS length0pxFooter horizontal padding. Set by PopoverFooter paddingX.
--df-popover-footer-gapCSS lengthcalc(2 * var(--spacing-unit))Gap between footer actions. Set by PopoverFooter gap.
--df-popover-title-colorCSS colorvar(--df-popover-surface-fg)Title color. Set by PopoverTitle color.
--df-popover-title-sizeCSS lengthinheritTitle font size. Set by PopoverTitle fontSize.
--df-popover-title-weightCSS font-weightvar(--df-font-weight-semibold)Title weight. Set by PopoverTitle fontWeight.
--df-popover-title-fontCSS font-familyinheritTitle font family. Set by PopoverTitle fontFamily.
--df-popover-title-leadingCSS line-heightvar(--df-leading-5)Title line height. Set by PopoverTitle lineHeight.
--df-popover-title-trackingCSS letter-spacingvar(--df-tracking-snug)Title letter spacing. Set by PopoverTitle letterSpacing.
--df-popover-description-colorCSS colorvar(--muted-foreground)Description color. Set by PopoverDescription color.
--df-popover-description-sizeCSS lengthvar(--df-text-13)Description font size. Set by PopoverDescription fontSize.
--df-popover-description-weightCSS font-weightvar(--df-font-weight-normal)Description weight. Set by PopoverDescription fontWeight.
--df-popover-description-fontCSS font-familyinheritDescription font family. Set by PopoverDescription fontFamily.
--df-popover-description-leadingCSS line-heightvar(--df-leading-5)Description line height. Set by PopoverDescription lineHeight.
--df-popover-description-trackingCSS letter-spacingnormalDescription letter spacing. Set by PopoverDescription letterSpacing.