Popover
A floating panel triggered by a click, containing interactive content.
CMS Demo
See how content editors configure popovers in a CMS:
Loading...
CMS ConfigurationSimulates Payload CMS popover configuration
Basic Usage
Loading...
PopoverClick-triggered floating panel
Installation
pnpm add @corew500/uiUsage
import {
Popover,
PopoverTrigger,
PopoverContent,
} from "@mordecai-design-system/ui"<Popover>
<PopoverTrigger>Open Popover</PopoverTrigger>
<PopoverContent>
Interactive content goes here
</PopoverContent>
</Popover>Examples
With Header
<PopoverContent>
<PopoverHeader>
<PopoverTitle>Dimensions</PopoverTitle>
<PopoverDescription>
Set the dimensions for the layer.
</PopoverDescription>
</PopoverHeader>
<form className="space-y-4">
<Input placeholder="Width" />
<Input placeholder="Height" />
</form>
</PopoverContent>Positioning
<Popover>
<PopoverTrigger>Open</PopoverTrigger>
<PopoverContent side="right" align="start">
Positioned to the right
</PopoverContent>
</Popover>Controlled
const [open, setOpen] = useState(false)
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger>Open</PopoverTrigger>
<PopoverContent>
<Button onClick={() => setOpen(false)}>
Close
</Button>
</PopoverContent>
</Popover>Sub-components
| Component | Description |
|-----------|-------------|
| Popover | Root component managing open state |
| PopoverTrigger | Button that opens the popover |
| PopoverContent | The floating panel |
| PopoverHeader | Optional header container |
| PopoverTitle | Header title |
| PopoverDescription | Header description |
Props
PopoverContent
| Prop | Type | Default | Description |
|---|---|---|---|
| initialFocus | enum | — | Determines the element to focus when the popover is opened. - `false`: Do not move focus. - `true`: Move focus based on the default behavior (first tabbable element or popup). - `RefObject`: Move focus to the ref element. - `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`). Return an element to focus, `true` to use the default behavior, or `false`/`undefined` to do nothing. |
| finalFocus | enum | — | Determines the element to focus when the popover is closed. - `false`: Do not move focus. - `true`: Move focus based on the default behavior (trigger or previously focused element). - `RefObject`: Move focus to the ref element. - `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`). Return an element to focus, `true` to use the default behavior, or `false`/`undefined` to do nothing. |
| style | enum | — | Style applied to the element, or a function that returns a style object based on the component’s state. |
| className | enum | — | CSS class applied to the element, or a function that returns a class based on the component’s state. |
| render | enum | — | Allows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| align | enum | center | How to align the popup relative to the specified side. |
| alignOffset | enum | 0 | Additional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. - `data.side`: which side of the anchor element the positioner is aligned against. - `data.align`: how the positioner is aligned relative to the specified side. @example ```jsx <Positioner alignOffset={({ side, align, anchor, positioner }) => { return side === 'top' || side === 'bottom' ? anchor.width : anchor.height; }} /> ``` |
| side | enum | bottom | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. |
| sideOffset | enum | 4 | Distance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. - `data.side`: which side of the anchor element the positioner is aligned against. - `data.align`: how the positioner is aligned relative to the specified side. @example ```jsx <Positioner sideOffset={({ side, align, anchor, positioner }) => { return side === 'top' || side === 'bottom' ? anchor.height : anchor.width; }} /> ``` |
Popover
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultOpen | enum | false | Whether the popover is initially open. To render a controlled popover, use the `open` prop instead. |
| open | enum | — | Whether the popover is currently open. |
| onOpenChange | (open: boolean, eventDetails: PopoverRootChangeEventDetails) => void | — | Event handler called when the popover is opened or closed. |
| onOpenChangeComplete | (open: boolean) => void | — | Event handler called after any animations complete when the popover is opened or closed. |
| actionsRef | RefObject<PopoverRootActions> | — | A ref to imperative actions. - `unmount`: When specified, the popover will not be unmounted when closed. Instead, the `unmount` function must be called to unmount the popover manually. Useful when the popover's animation is controlled by an external library. - `close`: Closes the dialog imperatively when called. |
| modal | enum | false | Determines if the popover enters a modal state when open. - `true`: user interaction is limited to the popover: document page scroll is locked, and pointer interactions on outside elements are disabled. - `false`: user interaction with the rest of the document is allowed. - `'trap-focus'`: focus is trapped inside the popover, but document page scroll is not locked and pointer interactions outside of it remain enabled. |
| triggerId | string | — | ID of the trigger that the popover is associated with. This is useful in conjunction with the `open` prop to create a controlled popover. There's no need to specify this prop when the popover is uncontrolled (i.e. when the `open` prop is not set). |
| defaultTriggerId | string | — | ID of the trigger that the popover is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open popover. |
| handle | PopoverHandle<unknown> | — | A handle to associate the popover with a trigger. If specified, allows external triggers to control the popover's open state. |
Accessibility
- Focus is trapped within the popover
- Escape key closes the popover
- Clicking outside closes the popover
- Title and description are announced to screen readers