Popover Morph
Popover that grows out of its trigger and folds back.
Installation
pnpm dlx shadcn@latest add @paneui/popover-morphUsage
Composition
Examples
Motion
The surface grows from a copy of the trigger across the 8px gap over 450ms, and the content settles in 150ms later. Closing folds it back in 300ms. With reduced motion it only cross-fades, in 150ms.
Keyboard
Enter or Space opens it, focus moves into the panel, Escape or an outside press closes it and returns focus to the trigger.
Related
See also Select Morph, Morphing Modal, Morphing Search and Morphing Tabs.
API Reference
Built on the Popover primitive. Only the props this library adds or changes are listed; everything else passes through.
MorphPopover
Popover.Root, re-exported unchanged. Also accepts every prop of Popover.Root.
MorphPopoverTrigger
A raised trigger (32px, rounded-lg). Also accepts every prop of Popover.Trigger.
MorphPopoverContent
Portal, positioner and popup, anchored to the trigger like Popover (8px side offset) with the standard popover surface (rounded-2xl, bg-popover, shadow-surface). A 288px panel by default. Also accepts every prop of Popover.Popup.
- side= "bottom"
- "top" | "bottom"
- Which side of the trigger the panel opens on (and grows towards).
- sideOffset= 8
- number
- Gap between trigger and panel in px, as in Popover.
- collisionPadding= 8
- number
- Viewport margin kept when the panel flips or shifts.
- align= "center"
- "start" | "center" | "end"
- Which trigger edge the panel lines up with, as in Popover.
- triggerRadius= "var(--radius-lg)"
- string
- Corner radius (CSS length) of the trigger shape the panel starts from. The default matches
MorphPopoverTrigger'srounded-lg; change it only if you reshape the trigger.
| Prop | Type | Default | Description |
|---|---|---|---|
| side | "top" | "bottom" | "bottom" | Which side of the trigger the panel opens on (and grows towards). |
| sideOffset | number | 8 | Gap between trigger and panel in px, as in Popover. |
| collisionPadding | number | 8 | Viewport margin kept when the panel flips or shifts. |
| align | "start" | "center" | "end" | "center" | Which trigger edge the panel lines up with, as in Popover. |
| triggerRadius | string | "var(--radius-lg)" | Corner radius (CSS length) of the trigger shape the panel starts from. The default matches MorphPopoverTrigger's rounded-lg; change it only if you reshape the trigger. |
- data-side / data-align
- The resolved placement (on the positioner and popup), used to work out where the morph starts.
- data-starting-style / data-ending-style
- Present while the panel opens or closes.
| Data attribute | Description |
|---|---|
| data-side / data-align | The resolved placement (on the positioner and popup), used to work out where the morph starts. |
| data-starting-style / data-ending-style | Present while the panel opens or closes. |
MorphPopoverHeader
Title and description stack; leaves room on the right for the close button. Also accepts every prop of div.
MorphPopoverTitle
Also accepts every prop of Popover.Title.
MorphPopoverDescription
Also accepts every prop of Popover.Description.
MorphPopoverClose
Unstyled close part; pass render to turn any element (e.g. a Button) into a close control. Also accepts every prop of Popover.Close.
MorphPopoverCloseButton
Round × button pinned to the panel's top-right corner, labelled Close. Also accepts every prop of Popover.Close.