UniqueUI

Morphing Modal

Modal that expands from the trigger element with spring physics and backdrop blur.

npx uniqueui add morphing-modal

Preview

Click to open modal

This card morphs into a modal with spring physics.

Usage

"use client";
import { useState } from "react";
import { MorphingModal, MorphingModalTrigger } from "@/components/ui/morphing-modal";

export default function Example() {
  const [modalOpen, setModalOpen] = useState(false);
  return (
    <>
      <div className="flex items-center justify-center p-20">
        <MorphingModalTrigger
          layoutId="modal-demo"
          onClick={() => setModalOpen(true)}
          className="p-6 rounded-xl bg-neutral-900/50 border border-neutral-800 hover:border-neutral-700 transition-colors max-w-xs text-white"
        >
          <h3 className="text-lg font-bold mb-2">Click to open modal</h3>
          <p className="text-neutral-400 text-sm">
            This card morphs into a modal with spring physics.
          </p>
        </MorphingModalTrigger>
      </div>
      <MorphingModal
        isOpen={modalOpen}
        onClose={() => setModalOpen(false)}
        layoutId="modal-demo"
      >
        <div className="pt-4 text-white">
          <h3 className="text-2xl font-bold mb-4">Morphing Modal</h3>
          <p className="text-neutral-400 mb-6">
            This modal expands from the trigger element with spring-based animation. It supports
            Escape key to close, click-outside to dismiss, and an animated close button.
          </p>
          <div className="flex gap-3">
            <button
              onClick={() => setModalOpen(false)}
              className="px-4 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 transition-colors text-sm font-medium"
            >
              Got it
            </button>
            <button
              onClick={() => setModalOpen(false)}
              className="px-4 py-2 rounded-lg bg-neutral-800 hover:bg-neutral-700 transition-colors text-sm font-medium text-neutral-300"
            >
              Cancel
            </button>
          </div>
        </div>
      </MorphingModal>
    </>
  );
}

Props

PropTypeDescription
childrenReact.ReactNodeThe payload rendering inside the physical boundaries of the modal dialog box.
classNamestringTailwind definitions passing specific sizes and visuals onto the dialog constraint.
layoutIdstringUnique arbitrary string utilized by Framer Motion to tie trigger layout transitions.
onClick() => voidDescription coming soon