Popover
StableNon-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 closeVariants
With decorative arrow
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. |
defaultOpen | boolean | false | Default open state for uncontrolled usage. |
onOpenChange | (open: boolean) => void | — | Called when the open state changes. |
contract | Partial<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
| Key | Action |
|---|---|
| EnterorSpace | Toggle the popover open/close. |
| Escape | Close the popover and return focus to the trigger. |
| Tab | Move focus through popover content (focus NOT trapped). |
| Shift + Tab | Move 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>