{"version":3,"file":"PopChild.mjs","sources":["../../../../src/components/AnimatePresence/PopChild.tsx"],"sourcesContent":["\"use client\"\n\nimport { isHTMLElement } from \"motion-dom\"\nimport * as React from \"react\"\nimport { useContext, useId, useInsertionEffect, useRef } from \"react\"\n\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport { useComposedRefs } from \"../../utils/use-composed-ref\"\n\ninterface Size {\n    width: number\n    height: number\n    top: number\n    left: number\n    right: number\n    bottom: number\n}\n\ninterface Props {\n    children: React.ReactElement\n    isPresent: boolean\n    anchorX?: \"left\" | \"right\"\n    anchorY?: \"top\" | \"bottom\"\n    root?: HTMLElement | ShadowRoot\n    pop?: boolean\n}\n\ninterface MeasureProps extends Props {\n    childRef: React.RefObject<HTMLElement | null>\n    sizeRef: React.RefObject<Size>\n}\n\n/**\n * Measurement functionality has to be within a separate component\n * to leverage snapshot lifecycle.\n */\nclass PopChildMeasure extends React.Component<MeasureProps> {\n    getSnapshotBeforeUpdate(prevProps: MeasureProps) {\n        const element = this.props.childRef.current\n        if (isHTMLElement(element) && prevProps.isPresent && !this.props.isPresent && this.props.pop !== false) {\n            const parent = element.offsetParent\n            const parentWidth = isHTMLElement(parent)\n                ? parent.offsetWidth || 0\n                : 0\n            const parentHeight = isHTMLElement(parent)\n                ? parent.offsetHeight || 0\n                : 0\n\n            const computedStyle = getComputedStyle(element)\n            const size = this.props.sizeRef.current!\n            size.height = parseFloat(computedStyle.height)\n            size.width = parseFloat(computedStyle.width)\n            size.top = element.offsetTop\n            size.left = element.offsetLeft\n            size.right = parentWidth - size.width - size.left\n            size.bottom = parentHeight - size.height - size.top\n        }\n\n        return null\n    }\n\n    /**\n     * Required with getSnapshotBeforeUpdate to stop React complaining.\n     */\n    componentDidUpdate() {}\n\n    render() {\n        return this.props.children\n    }\n}\n\nexport function PopChild({ children, isPresent, anchorX, anchorY, root, pop }: Props) {\n    const id = useId()\n    const ref = useRef<HTMLElement>(null)\n    const size = useRef<Size>({\n        width: 0,\n        height: 0,\n        top: 0,\n        left: 0,\n        right: 0,\n        bottom: 0,\n    })\n    const { nonce } = useContext(MotionConfigContext)\n    /**\n     * In React 19, refs are passed via props.ref instead of element.ref.\n     * We check props.ref first (React 19) and fall back to element.ref (React 18).\n     */\n    const childRef =\n        (children.props as { ref?: React.Ref<HTMLElement> })?.ref ??\n        (children as unknown as { ref?: React.Ref<HTMLElement> })?.ref\n    const composedRef = useComposedRefs(ref, childRef)\n\n    /**\n     * We create and inject a style block so we can apply this explicit\n     * sizing in a non-destructive manner by just deleting the style block.\n     *\n     * We can't apply size via render as the measurement happens\n     * in getSnapshotBeforeUpdate (post-render), likewise if we apply the\n     * styles directly on the DOM node, we might be overwriting\n     * styles set via the style prop.\n     */\n    useInsertionEffect(() => {\n        const { width, height, top, left, right, bottom } = size.current\n        if (isPresent || pop === false || !ref.current || !width || !height) return\n\n        const x = anchorX === \"left\" ? `left: ${left}` : `right: ${right}`\n        const y = anchorY === \"bottom\" ? `bottom: ${bottom}` : `top: ${top}`\n\n        ref.current.dataset.motionPopId = id\n\n        const style = document.createElement(\"style\")\n        if (nonce) style.nonce = nonce\n\n        const parent = root ?? document.head\n        parent.appendChild(style)\n\n        if (style.sheet) {\n            style.sheet.insertRule(`\n          [data-motion-pop-id=\"${id}\"] {\n            position: absolute !important;\n            width: ${width}px !important;\n            height: ${height}px !important;\n            ${x}px !important;\n            ${y}px !important;\n          }\n        `)\n        }\n\n        return () => {\n            ref.current?.removeAttribute(\"data-motion-pop-id\")\n            if (parent.contains(style)) {\n                parent.removeChild(style)\n            }\n        }\n    }, [isPresent])\n\n    return (\n        <PopChildMeasure isPresent={isPresent} childRef={ref} sizeRef={size} pop={pop}>\n            {pop === false\n                ? children\n                : React.cloneElement(children as any, { ref: composedRef })}\n        </PopChildMeasure>\n    )\n}\n"],"names":[],"mappings":";;;;;;;;AAgCA;;;AAGG;AACH;AACI;;;AAGQ;AACA;AACI;;AAEJ;AACI;;AAGJ;;;;AAIA;AACA;AACA;AACA;;AAGJ;;AAGJ;;AAEG;AACH;;AAGI;;AAEP;AAEK;AACF;AACA;;AAEI;AACA;AACA;AACA;AACA;AACA;AACH;;AAED;;;AAGG;AACH;;;AAKA;;;;;;;;AAQG;;AAEC;AACA;;AAEA;AACA;;;AAKA;AAAW;AAEX;AACA;AAEA;AACI;;;;;;;;AAQH;;AAGD;AACI;AACA;AACI;;AAER;AACJ;;AAKY;AACA;AAGhB;;"}