Popover
Non-modal floating panel for menus, forms, and custom UI. Closes on Escape and outside click.
Preview
Switch the framework picker (top-right of the panel) to render the same demo live in React, Vue, or Angular — same class names, ARIA, and visual output across all three.
Installation
Sisyphos UI ships unified packages for React, Vue, and Angular. Pick the one that matches your stack — every framework exports the same component classes, ARIA semantics, and CSS tokens.
$ pnpm add @sisyphos-ui/reactThen import the bundled stylesheet once at app entry: import "@sisyphos-ui/react/styles.css";
Usage
import { Popover, Button } from "@sisyphos-ui/react";
export const Help = () => (
<Popover content={<div>Popovers carry rich interactive content.</div>}>
<Button variant="outlined">Help</Button>
</Popover>
);Hover trigger
`trigger="hover"` shows the popover on hover/focus like a richer tooltip.
Manual trigger
`trigger="manual"` hands full open/close control to the parent — ideal for form flows and shortcuts.
Placements
Auto-flipping placement reroutes the popover when it doesn't fit.
API
| Prop | Type | Default | Description |
|---|---|---|---|
| content* | ReactNode | — | Floating content rendered inside the popover. |
| children* | ReactElement | — | Single focusable React element used as the trigger. |
| trigger | "click" | "hover" | "manual" | "click" | Interaction that opens the popover; `manual` only opens via the `open` prop. |
| placement | "top" | "bottom" | "left" | "right" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "bottom" | Preferred placement; auto-flips to the opposite side if it doesn't fit the viewport. |
| open | boolean | — | Controlled open state. |
| defaultOpen | boolean | false | Initial open state when uncontrolled. |
| onOpenChange | (open: boolean) => void | — | Called whenever the open state changes. |
| closeOnEscape | boolean | true | Close when Escape is pressed. |
| closeOnOutsideClick | boolean | true | Close when a click lands outside the trigger and panel. |
| openDelay | number | 100 | Delay before opening on the hover trigger. |
| closeDelay | number | 150 | Delay before closing on the hover trigger. |
| arrow | boolean | true | Render an arrow pointing at the trigger. |
The full API including refs, ARIA attributes, and HTML passthroughs lives in the package README on npm.
Accessibility
Adheres to the Disclosure WAI-ARIA design pattern.
- The panel renders with
role="dialog"; the trigger is wired witharia-haspopup="dialog",aria-expanded, andaria-controlspointing at the open panel. - Closes on Escape (
closeOnEscape) and on pointer-down outside both the trigger and the panel (closeOnOutsideClick). - Non-modal by design: focus is not trapped inside the panel, so keyboard users can Tab past it — reach for
Dialogwhen you need a modal flow. - With
trigger="hover", keyboard focus of the trigger also opens the panel (and blur closes it), matching the pointer behavior. - The arrow is
aria-hidden.
Keyboard interactions
| Key | Action |
|---|---|
| Enter | On a native button trigger, toggles the popover (click trigger). |
| Space | On a native button trigger, toggles the popover (click trigger). |
| Esc | Closes the popover when `closeOnEscape` is enabled. |