Me
Germany

Though, this one is a lot inspired by Family's mobile wallet, I tried to achieve the effect simply for "learning" purposes.

The secret lays within the animation of the dialog. Basically you would start with a simple dialog, and add a wrapper component in there, which is going to hold all the other pages. See the code example below.

After this, the only secret sauce is that you are having a shared ref (did you know, that ref's can be simple functions?). This ref is going to be used to update the height dynamically based on the content of the page.

import * as Dialog from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
import { AnimatePresence, MotionConfig, motion } from "motion/react";
import { useState } from "react";
import { WalletConnectButton } from "./WalletConnectButton";
import { WalletConnectConnectorsPage } from "./WalletConnectConnectorsPage";
import { WalletConnectQrPage } from "./WalletConnectQrPage";
import { WalletConnectSuccessPage } from "./WalletConnectSuccessPage";
import { WalletConnectWaitingPage } from "./WalletConnectWaitingPage";
import { useWalletConnectStore } from "./state";

export function WalletConnect() {
  const [initialHeight, setInitialHeight] = useState<number | undefined>(
    undefined,
  );
  const [height, setHeight] = useState(0);
  const { isOpen, setIsOpen, page } = useWalletConnectStore();

  const pageRef = (element: HTMLDivElement) => {
    if (!element) {
      return;
    }

    if (!initialHeight) {
      setInitialHeight(element.clientHeight);
    }

    setHeight(element.clientHeight);
  };

  return (
    <MotionConfig transition={{ type: "spring", duration: 0.5 }}>
      <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
        <Dialog.Trigger asChild>
          <WalletConnectButton />
        </Dialog.Trigger>

        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 bg-stone-800/50 backdrop-blur-sm data-[state=closed]:animate-modalOverlayOut data-[state=open]:animate-modalOverlayIn">
            <Dialog.Content
              asChild
              className="fixed top-[50%] left-[50%] w-[90%] max-w-sm translate-x-[-50%] translate-y-[-50%] overflow-hidden rounded-3xl bg-gray-100 text-stone-800 shadow-md ring-1 ring-black/5 data-[state=closed]:animate-modalOut data-[state=open]:animate-modalIn"
            >
              <motion.div initial={false} animate={{ height }}>
                <AnimatePresence initial={false}>
                  {page === "connectors" ? (
                    <motion.div
                      key="connectors"
                      ref={pageRef}
                      className="absolute inset-x-0 top-0 p-1"
                      initial={{ opacity: 0, scale: 0.95 }}
                      animate={{ opacity: 1, scale: 1 }}
                      exit={{ opacity: 0, scale: 0.95 }}
                    >
                      <WalletConnectConnectorsPage />
                    </motion.div>
                  ) : null}

                  {page === "qr" ? (
                    <motion.div
                      key="qr"
                      ref={pageRef}
                      className="absolute inset-x-0 top-0 p-1"
                      initial={{ opacity: 0, scale: 0.95 }}
                      animate={{ opacity: 1, scale: 1 }}
                      exit={{ opacity: 0, scale: 0.95 }}
                    >
                      <WalletConnectQrPage />
                    </motion.div>
                  ) : null}

                  {page === "waiting" ? (
                    <motion.div
                      key="waiting"
                      ref={pageRef}
                      className="absolute inset-x-0 top-0 p-1"
                      initial={{ opacity: 0, scale: 0.95 }}
                      animate={{ opacity: 1, scale: 1 }}
                      exit={{ opacity: 0, scale: 0.95 }}
                    >
                      <WalletConnectWaitingPage />
                    </motion.div>
                  ) : null}

                  {page === "success" ? (
                    <motion.div
                      key="success"
                      ref={pageRef}
                      className="absolute inset-x-0 top-0 p-1"
                      initial={{ opacity: 0, scale: 0.95 }}
                      animate={{ opacity: 1, scale: 1 }}
                      exit={{ opacity: 0, scale: 0.95 }}
                    >
                      <WalletConnectSuccessPage />
                    </motion.div>
                  ) : null}
                </AnimatePresence>

                <Dialog.Close asChild>
                  <button className="absolute top-5 right-5 size-8 cursor-pointer rounded-md p-2 transition hover:bg-stone-100">
                    <XIcon className="size-4 stroke-[1.75px] opacity-70" />
                  </button>
                </Dialog.Close>
              </motion.div>
            </Dialog.Content>
          </Dialog.Overlay>
        </Dialog.Portal>
      </Dialog.Root>
    </MotionConfig>
  );
}
Manifesto

Design is more than aesthetics – it's the invisible force that shapes how we experience the digital world. For 16 years, I've been driven by the belief that exceptional frontend development can transform good design into unforgettable experiences. Every pixel, every interaction, every line of code serves a purpose in this greater vision.

I operate at the intersection of creativity and technology, where design principles meet development expertise. This convergence isn't just about making things look beautiful – it's about crafting interfaces that feel natural, intuitive, and effortless. As both designer and developer, I bridge the gap between imagination and implementation, ensuring nothing is lost in translation.

My work is guided by a simple truth: the best digital experiences are those that users don't have to think about. They just work, seamlessly and beautifully, across every device and platform. This is what I strive for in every project, pushing the boundaries of what's possible while maintaining rock-solid reliability.