"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReactResizeObserver = exports.useResizeObserver = exports.setupResizeObserver = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const react_1 = require("react");
const getResizeObserverObject_1 = require("./getResizeObserverObject");
const setupResizeObserver = (node, callback) => {
    const RO = (0, getResizeObserverObject_1.getResizeObserverObject)();
    if (!RO) {
        return () => { };
    }
    const observer = new RO((entries) => {
        const entry = entries[0];
        let { width, height } = entry.contentRect;
        if (entry.borderBoxSize?.[0]) {
            height = entry.borderBoxSize[0].blockSize;
            width = entry.borderBoxSize[0].inlineSize;
        }
        else {
            // this is needed for Safari and other browsers that don't have borderBoxSize on the entry object
            const rect = node.getBoundingClientRect();
            height = rect.height;
            width = rect.width;
        }
        callback({ width, height });
    });
    observer.observe(node);
    return () => {
        observer.disconnect();
    };
};
exports.setupResizeObserver = setupResizeObserver;
/**
 * A hook that notifies you when a certain DOM element has changed it's size
 *
 * @param ref A React ref to a DOM element
 * @param callback The function to be called when the element is resized.
 */
const useResizeObserver = (ref, callback, config = { earlyAttach: false }) => {
    const sizeRef = (0, react_1.useRef)({
        width: 0,
        height: 0,
    });
    const effectFn = (callback) => {
        let disconnect;
        if (ref.current) {
            disconnect = (0, exports.setupResizeObserver)(ref.current, (size) => {
                size = {
                    width: Math.round(size.width),
                    height: Math.round(size.height),
                };
                const prevSize = sizeRef.current;
                if (prevSize.width !== size.width || prevSize.height !== size.height) {
                    sizeRef.current = size;
                    callback(size);
                }
            });
        }
        return () => {
            if (disconnect) {
                disconnect();
            }
        };
    };
    (0, react_1.useEffect)(() => {
        if (!config.earlyAttach) {
            return effectFn(callback);
        }
        return () => { };
    }, [ref.current, callback, config.earlyAttach]);
    (0, react_1.useLayoutEffect)(() => {
        if (config.earlyAttach) {
            return effectFn(callback);
        }
        return () => { };
    }, [ref.current, callback, config.earlyAttach]);
};
exports.useResizeObserver = useResizeObserver;
const ReactResizeObserver = ({ notifyOnMount = true, earlyAttach = false, ...props }) => {
    const style = (0, react_1.useMemo)(() => ({
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        boxSizing: 'border-box',
    }), []);
    const firstTime = (0, react_1.useRef)(true);
    const ref = (0, react_1.useRef)(null);
    const onResize = (0, react_1.useCallback)((size) => {
        if (firstTime.current && !notifyOnMount) {
            firstTime.current = false;
            return;
        }
        props.onResize(size);
    }, [props.onResize]);
    (0, exports.useResizeObserver)(ref, onResize, { earlyAttach: earlyAttach || false });
    return React.createElement("div", { ref: ref, style: style });
};
exports.ReactResizeObserver = ReactResizeObserver;
