Skip to content

Instantly share code, notes, and snippets.

@ixahmedxi
Created September 25, 2023 23:23
Show Gist options
  • Select an option

  • Save ixahmedxi/27c5e9cfd5fb00c8566d35ecb64da717 to your computer and use it in GitHub Desktop.

Select an option

Save ixahmedxi/27c5e9cfd5fb00c8566d35ecb64da717 to your computer and use it in GitHub Desktop.

Revisions

  1. ixahmedxi created this gist Sep 25, 2023.
    45 changes: 45 additions & 0 deletions component.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    import { AnimatePresence, motion } from "framer-motion";
    import { PropsWithChildren } from "react";
    import useResizeObserver from "use-resize-observer";

    const ignoreCircularReferences = () => {
    const seen = new WeakSet();
    return (key: string, value: Record<string, unknown>) => {
    if (key.startsWith("_")) return;
    if (typeof value === "object" && value !== null) {
    if (seen.has(value)) return;
    seen.add(value);
    }
    return value;
    };
    };

    export function ResizablePanel({ children }: PropsWithChildren) {
    const { ref, height } = useResizeObserver<HTMLDivElement>();

    return (
    <motion.div
    animate={{ height: height || "auto" }}
    className="relative w-full overflow-hidden"
    >
    <AnimatePresence initial={false}>
    <motion.div
    key={JSON.stringify(children, ignoreCircularReferences())}
    initial={{
    opacity: 0,
    }}
    animate={{
    opacity: 1,
    }}
    exit={{
    opacity: 0,
    }}
    >
    <div ref={ref} className={height ? "absolute" : "relative"}>
    {children}
    </div>
    </motion.div>
    </AnimatePresence>
    </motion.div>
    );
    }