Popover
AlphaA non-modal, anchored overlay for contextual information, actions, or forms. Semantically distinct from Dialog — no focus trap, no scroll lock.
Import
import { Popover } from "@compa11y/react";Usage
Example.tsx
import { Popover, Button, Text, Switch } from "@compa11y/react";
function Example() {
return (
<Popover>
<Popover.Trigger>
<Button variant="outline">More info</Button>
</Popover.Trigger>
<Popover.Content>
<Text size="sm">Non-modal overlay. Press Escape or click outside to dismiss.</Text>
<Popover.Close>
<Button variant="ghost" size="sm">Dismiss</Button>
</Popover.Close>
</Popover.Content>
</Popover>
);
}
// Controlled settings popover
function SettingsPopover() {
const [open, setOpen] = useState(false);
return (
<Popover open={open} onOpenChange={setOpen}>
<Popover.Trigger>
<Button variant="outline">Settings</Button>
</Popover.Trigger>
<Popover.Content placement="bottom-start">
<Text size="sm" weight="semibold">Preferences</Text>
<Switch>Enable dark mode</Switch>
<Switch>Show notifications</Switch>
</Popover.Content>
</Popover>
);
}Features
- aria-haspopup='dialog' on the trigger
- aria-expanded toggled on open/close
- role='dialog' with aria-modal='false' on content
- First focusable element receives focus on open
- Focus returns to trigger on close
- Escape key closes and returns focus
- Outside click to dismiss
- Automatic viewport positioning with flip
- Controlled and uncontrolled modes
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | - | Controlled open state |
defaultOpen | boolean | false | Uncontrolled default open state |
onOpenChange | (open: boolean) => void | - | Called when open state changes |
Sub-components
Popover.Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | - | Trigger button content |
Popover.Content
| Prop | Type | Default | Description |
|---|---|---|---|
placement | 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end' | 'bottom' | Preferred placement relative to the trigger |
children* | ReactNode | - | Popover content |
Popover.Close
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | - | Close button content |
Keyboard Interactions
Accessibility
All keyboard interactions follow WAI-ARIA best practices and work without any additional configuration.
| Key | Action |
|---|---|
| Enter / Space | Toggles the popover open/closed |
| Escape | Closes the popover and returns focus to trigger |
| Tab | Moves focus through focusable elements inside the popover |