āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/directory/ibelick/motion-primitives/morphing-popover/page ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
export const metadata = { title: 'Morphing Popover - Motion-Primitives', description: 'A popover that transforms from its trigger into the content using layout animations. It visually morphs instead of appearing as a separate element. Built for React, Next.js, and Tailwind CSS.', };
import { MorphingPopoverBasic } from './morphing-popover-basic'; import { MorphingPopoverCustomTransitionVariants } from './morphing-popover-custom-transition-variants'; import { MorphingPopoverTextarea } from './morphing-popover-textarea'; import ComponentCodePreview from '@/components/website/component-code-preview';
A popover that transforms from its trigger into the content using layout animations. It visually morphs instead of appearing as a separate element.
<ComponentCodePreview component={<MorphingPopoverBasic />} filePath='app/docs/morphing-popover/morphing-popover-basic.tsx' />
You can pass a custom transition and variants to the popover with the variants and transition props.
<ComponentCodePreview component={<MorphingPopoverCustomTransitionVariants />} filePath='app/docs/morphing-popover/morphing-popover-custom-transition-variants.tsx' />
<ComponentCodePreview component={<MorphingPopoverTextarea />} filePath='app/docs/morphing-popover/morphing-popover-textarea.tsx' />
<Step>Copy and paste the following code into your project.</Step>
<CodeBlock filePath='components/core/morphing-popover.tsx' /><Step>Update the import paths to match your project setup.</Step>
</Steps> </TabsContent> </Tabs>| Prop | Type | Default | Description |
| :------------- | :------------------------ | :----------------------------------------------- | :----------------------------------------------- |
| children | React.ReactNode | Required | The content of the popover (trigger and content) |
| transition | Transition | { type: 'spring', bounce: 0.1, duration: 0.4 } | Custom transition settings for the animations |
| defaultOpen | boolean | false | Whether the popover is open by default |
| open | boolean | undefined | Controlled open state |
| onOpenChange | (open: boolean) => void | undefined | Callback fired when open state changes |
| variants | Variants | undefined | Custom variants for the animation |
| className | string | undefined | Additional CSS classes |
| Prop | Type | Default | Description |
| :---------- | :---------------- | :---------- | :-------------------------------------------- |
| children | React.ReactNode | Required | The trigger element content |
| asChild | boolean | false | Whether to merge props onto the child element |
| className | string | undefined | Additional CSS classes |
| Prop | Type | Default | Description |
| :---------- | :---------------- | :---------- | :------------------------------------ |
| children | React.ReactNode | Required | The content to display in the popover |
| className | string | undefined | Additional CSS classes |
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā