Skip to main content

Popover

Stable

Non-modal overlay for rich contextual content. Focus is NOT trapped — unlike Dialog. Escape and click-outside close it. Use for forms, menus, and content panels anchored to a trigger.

OverlayCompoundVhyxSeal

Interactive example

Filter options popover

Import

tsx
import { Popover } from '@vhyxui/react'

// Sub-components
// Popover.Trigger — the element that toggles the popover
// Popover.Content — the floating panel
// Popover.Arrow   — decorative arrow pointing to trigger
// Popover.Close   — button to close

Variants

With decorative arrow

Props

PropTypeDefaultDescription
openbooleanControlled open state.
defaultOpenbooleanfalseDefault open state for uncontrolled usage.
onOpenChange(open: boolean) => voidCalled when the open state changes.
contractPartial<ComponentContract>VhyxSeal contract override.

Popover.Trigger accepts asChild. Popover.Content accepts standard HTMLDivElement attributes.

Accessibility

  • Content has role="dialog", aria-modal="false" — non-modal per ARIA spec.
  • Trigger has aria-haspopup="dialog", aria-expanded, aria-controls.
  • Focus is NOT trapped — use Dialog for scenarios requiring a focus trap.
  • Escape closes and returns focus to trigger. Click outside closes.
  • Rendered in a portal — not clipped by overflow containers.

Keyboard navigation

KeyAction
EnterorSpaceToggle the popover open/close.
EscapeClose the popover and return focus to the trigger.
TabMove focus through popover content (focus NOT trapped).
Shift + TabMove focus backwards through popover content.

Agent contract

Default VhyxSeal contract shipped with every Popover.

Default contract
{
  "type": "display",
  "intent": "open-popover",
  "description": "Opens a non-modal floating panel anchored to a trigger element",
  "requires": [],
  "requiredPermissions": [],
  "consequence": "Renders a floating panel — underlying page remains fully interactive",
  "affects": [
    "view"
  ],
  "reversible": true,
  "safetyLevel": "low",
  "requiresConfirmation": false,
  "destructive": false,
  "contractVersion": "0.0.1",
  "fingerprint": "vhyxs_68d1a0c9"
}

Theming

Override these CSS tokens to theme Popover.

--vhyx-z-popoverZ-index (450)
--vhyx-color-surface-raisedPanel background
--vhyx-shadow-lgPanel shadow
--vhyx-radius-lgPanel border radius
--vhyx-duration-normalScale-in animation duration
--vhyx-easing-springEntry easing

Examples

Color picker

Color swatch grid in a popover

Controlled popover

tsx
const [open, setOpen] = useState(false)

<Popover open={open} onOpenChange={setOpen}>
  <Popover.Trigger asChild>
    <Button>Open</Button>
  </Popover.Trigger>
  <Popover.Content>
    Content here
    <Popover.Close asChild>
      <Button size="sm">Close</Button>
    </Popover.Close>
  </Popover.Content>
</Popover>