Popover
Accessible, unstyled Popover compound primitive.
|
|
| Package |
@vizejs/ui/popover |
| Maturity |
stable |
| Own the source |
vize lib pull popover |
| Requires |
context, controllable-state, dismissable-layer, focus-guards, focus-scope, id, inert-outside, portal, positioner, presence, scroll-lock |
| Aliases |
floating dialog, disclosure layer, coach mark shell, anchored popup |
| Covers |
WAI-ARIA dialog pattern, HTML Popover API authoring model, Radix Popover, Reka UI Popover |
Usage
import { Popover, PopoverRoot, PopoverArrow, PopoverContent, PopoverTrigger } from "@vizejs/ui/popover";
Or copy the source into your project with vize lib pull popover (see Source Distribution).
API
Popover
Source: src/families/overlays/popover/popover-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned Popover base id. null and undefined select a deterministic fallback. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
modal |
boolean |
false |
Whether the popover makes outside content inert and focus-contained while open. |
disabled |
boolean |
false |
Disable trigger-driven opening and request closure when already open. |
Events
| Event |
Payload |
Description |
update:open |
[value: boolean] |
Fired when the Popover requests a controlled open value. |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request. |
Slots
| Slot |
Slot props |
Description |
default |
PopoverSlotState |
Compound Popover children. Receives the current open, modal, and disabled state. |
Exposed
| Member |
Type |
Description |
close |
— |
|
contentId |
— |
|
disabled |
— |
|
id |
— |
|
modal |
— |
|
open |
— |
|
openPopover |
— |
|
setOpen |
— |
|
state |
— |
|
toggle |
— |
|
triggerId |
— |
|
PopoverRoot
Source: src/families/overlays/popover/popover-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned Popover base id. null and undefined select a deterministic fallback. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
modal |
boolean |
false |
Whether the popover makes outside content inert and focus-contained while open. |
disabled |
boolean |
false |
Disable trigger-driven opening and request closure when already open. |
Events
| Event |
Payload |
Description |
update:open |
[value: boolean] |
Fired when the Popover requests a controlled open value. |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request. |
Slots
| Slot |
Slot props |
Description |
default |
PopoverSlotState |
Compound Popover children. Receives the current open, modal, and disabled state. |
Exposed
| Member |
Type |
Description |
open |
boolean |
Whether the popover content is currently visible and interactive. |
modal |
boolean |
Whether outside content is inert and focus-contained. |
disabled |
boolean |
Whether trigger-driven opening is disabled by the root. |
state |
PopoverState |
Stable state token for styling and tests. |
id |
string |
Root-owned base id for the compound popover family. |
triggerId |
string |
Id wired to the native trigger button. |
contentId |
string |
Id wired from PopoverTrigger to PopoverContent. |
setOpen |
(value: boolean, event?: Event | null) => boolean |
Request a specific open value and report whether it differs. |
openPopover |
(event?: Event | null) => boolean |
Request the open state. |
close |
(event?: Event | null) => boolean |
Request the closed state. |
toggle |
(event?: Event | null) => boolean |
Request the opposite open state. |
PopoverArrow
Source: src/families/overlays/popover/popover-arrow.vue
Slots
| Slot |
Slot props |
Description |
default |
PopoverArrowSlotState |
Decorative arrow contents. Receives coordinates for optional custom drawing. |
Exposed
| Member |
Type |
Description |
x |
number | null |
Current arrow x coordinate when the positioner can measure it. |
y |
number | null |
Current arrow y coordinate when the positioner can measure it. |
element |
HTMLDivElement | null |
Rendered arrow element. |
PopoverContent
Source: src/families/overlays/popover/popover-content.vue
Props
| Prop |
Type |
Default |
Description |
forceMount |
boolean |
false |
Keep the content mounted while the popover is closed. |
to |
string | HTMLElement |
"body" |
CSS selector or element the popover layer is moved into. |
portalDisabled |
boolean |
false |
Render in place instead of teleporting. |
defer |
boolean |
true |
Keep content in place until the target exists, avoiding SSR mismatch. |
placement |
Placement |
"bottom" |
Preferred placement before collision handling. |
strategy |
PositionerStrategy |
"fixed" |
CSS positioning mode published on the floating host. |
offset |
number |
8 |
Gap on the main axis between trigger and content. |
collisionPadding |
number |
4 |
Viewport padding the floating element should not cross. |
arrowPadding |
number |
0 |
Inset kept between the arrow and floating edges. |
direction |
"ltr" | "rtl" |
"ltr" |
Writing direction used to resolve start/end alignment. |
flip |
boolean |
true |
Flip to the opposite side when the preferred side overflows more. |
shift |
boolean |
true |
Shift the floating box back into the viewport after flip. |
size |
boolean |
false |
Constrain the host and publish positioner available-size CSS variables. |
safeArea |
boolean |
false |
Keep floating content clear of safe-area insets. |
hide |
boolean |
true |
Hide when the trigger no longer intersects the viewport. |
updateOnScroll |
boolean |
true |
Recalculate while ancestors scroll. |
updateOnResize |
boolean |
true |
Recalculate when the document or visual viewport resizes. |
viewport |
Rect |
undefined |
Viewport used for flip, shift, and hide. |
trapFocus |
boolean |
true |
Contain focus inside an open modal popover. |
autoFocus |
boolean |
true |
Move focus into content when it opens. |
restoreFocus |
boolean |
true |
Restore focus when content closes. |
inertOutside |
boolean |
true |
Make outside content inert while the modal popover is open. |
lockScroll |
boolean |
true |
Lock document scroll while the modal popover is open. |
closeOnEscape |
boolean |
true |
Let Escape request dismissal while the popover is open. |
closeOnPointerDownOutside |
boolean |
true |
Let outside pointer-down request dismissal. |
closeOnFocusOutside |
boolean |
true |
Let outside focus movement request dismissal. |
initialFocus |
() => HTMLElement | null | undefined |
undefined |
Preferred initial focus target inside the content. |
ariaLabel |
string |
undefined |
Accessible name when visible text is not enough. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the popover dialog. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe the popover dialog. |
role |
"alertdialog" | "dialog" |
"dialog" |
Content role. Use "alertdialog" for confirmations that interrupt the user and need a response. |
Events
| Event |
Payload |
Description |
open-auto-focus |
[event: PopoverAutoFocusEvent] |
Fired before automatic entry focus is applied. |
close-auto-focus |
[event: PopoverAutoFocusEvent] |
Fired before automatic focus restoration is applied. |
escape-key-down |
[event: DismissableLayerEscapeKeyDownEvent] |
Fired before Escape requests dismissal. |
pointer-down-outside |
[event: DismissableLayerPointerDownOutsideEvent] |
Fired before an outside pointer-down requests dismissal. |
focus-outside |
[event: DismissableLayerFocusOutsideEvent] |
Fired before outside focus movement requests dismissal. |
interact-outside |
[event: DismissableLayerInteractOutsideEvent] |
Fired before outside pointer or focus interaction requests dismissal. |
dismiss |
[event: DismissableLayerDismissEvent] |
Fired after an unprevented dismissal request. |
Slots
| Slot |
Slot props |
Description |
default |
PopoverContentSlotState |
Popover content. Receives open state and resolved placement. |
Exposed
| Member |
Type |
Description |
open |
boolean |
Whether the popover content is currently visible and interactive. |
modal |
boolean |
Whether outside content is inert and focus-contained. |
disabled |
boolean |
Whether trigger-driven opening is disabled by the root. |
state |
PopoverState |
Stable state token for styling and tests. |
element |
HTMLDivElement | null |
Rendered popover content element. |
focusFirst |
() => HTMLElement | null |
Focus the first eligible descendant in the popover content. |
focusContent |
(options?: FocusOptions) => void |
Move focus to the content fallback target. |
PopoverTrigger
Source: src/families/overlays/popover/popover-trigger.vue
Props
| Prop |
Type |
Default |
Description |
type |
"button" | "reset" | "submit" |
"button" |
Native button submission behavior. |
disabled |
boolean |
false |
Remove the trigger from activation and sequential keyboard focus. |
ariaLabel |
string |
undefined |
Accessible name when no visible label supplies one. |
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before the trigger toggles the popover. Call preventDefault() to keep state unchanged. |
Slots
| Slot |
Slot props |
Description |
default |
PopoverSlotState |
Trigger contents. Receives the current Popover state and trigger availability. |
Exposed
| Member |
Type |
Description |
element |
HTMLButtonElement | null |
Rendered native button. |
focus |
(options?: FocusOptions) => void |
Move focus to the trigger. |
Behavior
| Surface |
Contract |
| State |
PopoverRoot supports uncontrolled defaultOpen and controlled open with update:open and open-change events; disabled roots request closure and publish data-disabled. |
| Trigger |
PopoverTrigger renders a native button with deterministic ids, aria-haspopup="dialog", aria-expanded, aria-controls, part="trigger", data-state, and disabled data hooks. |
| Content |
PopoverContent composes Portal, Presence, Positioner, DismissableLayer, and optional focus/isolation controllers; it renders role="dialog" (or "alertdialog" via role) with deterministic content ids. |
| Dismissal |
Escape, outside pointer-down, and outside focus request closing unless the preventable callback was canceled; trigger interaction is treated as an inside branch and toggles through state. |
| Focus |
Open content auto-focuses the provided initialFocus, the first eligible descendant, or the content fallback; close restores focus to the trigger when focus restoration is enabled. |
| Modal |
modal content may contain focus, add focus guards, inert outside content, and lock scroll; non-modal content skips those document-isolating effects while preserving dialog semantics. |
| Portal |
Content teleports to to after hydration by default; portalDisabled renders in place and forceMount keeps closed content hidden without activating document controllers. |
| Position |
placement, direction, collision, arrow, safe-area, and size props forward to Positioner; content publishes data-placement, data-side, data-align, and data-top-layer. |
| Arrow |
PopoverArrow is a measured Positioner arrow with part="arrow", Popover state data hooks, and slot coordinates; it is decorative and emits no role or label of its own. |
| Styling |
Popover emits no component CSS beyond scoped empty blocks; consumers style with data-vize-ui, part, data-state, data-side, data-align, and Positioner CSS variables. |
| CSS vars |
PopoverContent forwards Positioner sizing variables, including --vize-ui-positioner-available-width and --vize-ui-positioner-available-height, when size is enabled. |
| SSR |
Server output is deterministic, renders portal content in place, includes no document listeners, and activates dismissal, focus, inert, and scroll-lock controllers only after mount. |
| Component |
State x input |
Outcome |
popover-root.vue |
controlled or uncontrolled open request |
Publishes open, modal, disabled, ids, and data-state; emits state requests only for distinct open changes. |
popover-trigger.vue |
enabled click |
Emits click, then toggles the root when the event was not canceled. |
popover-content.vue |
open |
Renders positioned dialog content, activates dismissable layer, applies focus lifecycle, and exposes focus helpers. |
popover-content.vue |
open modal |
Adds focus guards, inert outside, focus containment, and scroll lock through shared foundation primitives. |
popover-content.vue |
closed and force-mounted |
Keeps content in the DOM with hidden state while document controllers remain inactive. |
popover-arrow.vue |
inside positioned content |
Registers with Positioner, publishes arrow geometry to CSS, and exposes slot coordinates. |
| Event |
Dispatch timing and payload |
open-auto-focus |
Before automatic entry focus; payload is a preventable focus-scope event. |
close-auto-focus |
Before automatic focus restoration; payload is a preventable focus-scope event. |
escape-key-down |
Before Escape dismissal; payload is the preventable dismissable-layer Escape event. |
pointer-down-outside |
Before pointer dismissal; payload is the preventable outside pointer event. |
focus-outside |
Before focus dismissal; payload is the preventable outside focus event. |
interact-outside |
Before pointer or focus dismissal; payload is the preventable outside interaction event. |
dismiss |
After an unprevented dismissal request; payload records reason, target, and native event. |