Morphing Modal
Dialog that moves between several views inside one panel.
Installation
pnpm dlx shadcn@latest add @paneui/morphing-modalUsage
Composition
Examples
Motion
The panel springs to each view's height while views slide 28px and blur in the direction of travel. With reduced motion the height snaps and views cross-fade in 150ms.
Accessibility
After navigating, focus moves to the first focusable control in the new view (or the view itself). Closing resets to the first view once the exit finishes.
Related
See also Select Morph, Popover Morph, Morphing Search and Morphing Tabs.
API Reference
Built on the Dialog primitive. Only the props this library adds or changes are listed; everything else passes through.
MorphingModal
Dialog root that also holds the view stack. Also accepts every prop of Dialog.Root.
- defaultView= "main"
- string
- The view shown when the modal opens.
- onViewChange
- (view: string) => void
- Called once with the new view whenever it changes, including the reset to
defaultViewwhen the modal finishes closing.
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultView | string | "main" | The view shown when the modal opens. |
| onViewChange | (view: string) => void | — | Called once with the new view whenever it changes, including the reset to defaultView when the modal finishes closing. |
MorphingModalTrigger
Dialog.Trigger, re-exported unchanged. Also accepts every prop of Dialog.Trigger.
MorphingModalContent
Backdrop and centred popup (max 384px wide). Renders the active MorphingModalView child; other children render after it. Also accepts every prop of Dialog.Popup.
- showCloseButton= true
- boolean
- Show the round × in the top-right corner.
| Prop | Type | Default | Description |
|---|---|---|---|
| showCloseButton | boolean | true | Show the round × in the top-right corner. |
MorphingModalView
One screen of the modal. Must be a direct child of MorphingModalContent. Also accepts every prop of div.
- name*
- string
- Identifier other parts navigate to.
| Prop | Type | Default | Description |
|---|---|---|---|
| name* | string | — | Identifier other parts navigate to. |
- data-view
- The view's
name.
| Data attribute | Description |
|---|---|
| data-view | The view's name. |
MorphingModalHeader
Title block; shows MorphingModalBack automatically when there is a view to go back to. Also accepts every prop of div.
MorphingModalTitle
Also accepts every prop of Dialog.Title.
MorphingModalDescription
Also accepts every prop of Dialog.Description.
MorphingModalLink
A full-width row button that pushes another view. Also accepts every prop of button.
- to*
- string
- Name of the view to open.
| Prop | Type | Default | Description |
|---|---|---|---|
| to* | string | — | Name of the view to open. |
MorphingModalBack
Round back chevron labelled Back. Renders nothing on the first view. Also accepts every prop of button.
MorphingModalClose
Dialog.Close, re-exported unchanged. Also accepts every prop of Dialog.Close.
useMorphingModal
Navigation state for custom controls. Use inside MorphingModal.
- view
- string
- The active view.
- canGoBack
- boolean
- Whether there is a previous view.
- direction
- 1 | -1
- Direction of the last navigation.
- push
- (view: string) => void
- Go to a view (pushes it onto the back stack).
- back
- () => void
- Return to the previous view.
- reset
- () => void
- Jump back to the first view and clear the stack (calls
onViewChangeif the view changes).
| Prop | Type | Default | Description |
|---|---|---|---|
| view | string | — | The active view. |
| canGoBack | boolean | — | Whether there is a previous view. |
| direction | 1 | -1 | — | Direction of the last navigation. |
| push | (view: string) => void | — | Go to a view (pushes it onto the back stack). |
| back | () => void | — | Return to the previous view. |
| reset | () => void | — | Jump back to the first view and clear the stack (calls onViewChange if the view changes). |