function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
import { afterEach, jest } from "@jest/globals";
import { resizeObserverManager } from "../useResizeObserver.js";
/**
 * This is mostly an internal function to be used with the {@link ResizeObserverMock}
 * and {@link setupResizeObserverMock}
 *
 * @since 6.0.0
 */ export const createResizeObserverEntry = (target, size)=>{
    const contentRect = target.getBoundingClientRect();
    if (typeof size?.height === "number") {
        contentRect.height = size.height;
    }
    if (typeof size?.width === "number") {
        contentRect.width = size.width;
    }
    const boxSize = {
        blockSize: contentRect.height,
        inlineSize: contentRect.width
    };
    return {
        target,
        contentRect,
        borderBoxSize: [
            boxSize
        ],
        contentBoxSize: [
            boxSize
        ],
        devicePixelContentBoxSize: []
    };
};
/**
 * This is the default ResizeObserver implementation if it does not already
 * exist in jsdom. You normally should not use this directly and instead use the
 * {@link setupResizeObserverMock} instead.
 *
 * @since 6.0.0
 */ export class ResizeObserverMock {
    constructor(callback){
        _define_property(this, "callback", void 0);
        _define_property(this, "elements", void 0);
        _define_property(this, "observe", void 0);
        _define_property(this, "unobserve", void 0);
        _define_property(this, "disconnect", void 0);
        /**
   * Triggers the resize event for a specific element. This must be wrapped in
   * `act`.
   *
   * @example Main Usage
   * ```tsx
   * import {
   *   cleanupResizeObserverAfterEach,
   *   setupResizeObserverMock,
   * } from "@react-md/core/test-utils";
   * import { useResizeObserver } from "@react-md/core";
   * import { ExampleComponent } from "../ExampleComponent.js";
   *
   * cleanupResizeObserverAfterEach();
   *
   * describe("ExampleComponent", () => {
   *   it("should do stuff", () => {
   *     const observer = setupResizeObserverMock();
   *     render(<ExampleComponent />)
   *
   *     const resizeTarget = screen.getByTestId("resize-target")
   *
   *     // you can trigger with a custom change
   *     act(() => {
   *       observer.resizeElement(resizeTarget, { height: 100, width: 100 });
   *     });
   *     // expect resize changes
   *   });
   * })
   * ```
   */ _define_property(this, "resizeElement", void 0);
        /**
   * You'll normally want to use {@link resizeElement} instead, but this can be
   * used to resize all the watched elements at once.
   *
   * @example
   * ```tsx
   * import {
   *   act,
   *   createResizeObserverEntry,
   *   render,
   *   screen,
   *   setupResizeObserverMock,
   * } from "@react-md/core/test-utils";
   *
   * const observer = setupResizeObserverMock();
   * const { container } = render(<Test />)
   * expect(container).toMatchSnapshot()
   *
   * const target1 = screen.getByTestId('target-1');
   * const target2 = screen.getByTestId('target-2');
   * const target3 = screen.getByTestId('target-3');
   *
   * act(() => {
   *   observer.resizeAllElements((element) => {
   *     let height: number | undefined;
   *     let width: number | undefined;
   *     switch (element) {
   *       case target1:
   *         height = 400;
   *         width = 250;
   *         break;
   *       case target2:
   *         height = 100;
   *         width = 380;
   *         break;
   *       case target3:
   *         height = 24;
   *         width = 24;
   *         break;
   *     }
   *
   *     return createResizeObserverEntry(element, { height, width });
   *   });
   * });
   * expect(container).toMatchSnapshot()
   * ```
   */ _define_property(this, "resizeAllElements", void 0);
        this.callback = callback;
        this.observe = (target)=>{
            this.elements.add(target);
            this.resizeAllElements(createResizeObserverEntry);
        };
        this.unobserve = (target)=>{
            this.elements.delete(target);
        };
        this.disconnect = ()=>{
            this.elements.clear();
        };
        this.resizeElement = (target, changesOrGetEntry = createResizeObserverEntry)=>{
            if (!this.elements.has(target)) {
                throw new Error("The `ResizeObserverMock` is not watching the target element and cannot be resized");
            }
            let entry;
            if (typeof changesOrGetEntry === "function") {
                entry = changesOrGetEntry(target);
            } else if (!("contentRect" in changesOrGetEntry)) {
                entry = createResizeObserverEntry(target, changesOrGetEntry);
            } else {
                entry = changesOrGetEntry;
            }
            this.callback([
                entry
            ], this);
        };
        this.resizeAllElements = (getEntry = createResizeObserverEntry)=>{
            const entries = [
                ...this.elements
            ].map((element)=>getEntry(element));
            this.callback(entries, this);
        };
        this.elements = new Set();
    }
}
/**
 * Initializes the `ResizeObserverMock` to be used for tests.
 *
 * @example Main Usage
 * ```tsx
 * import { useCallback, useState } from "react";
 * import {
 *   cleanupResizeObserverAfterEach,
 *   render,
 *   screen,
 *   setupResizeObserverMock,
 * } from "@react-md/core/test-utils";
 * import { useResizeObserver } from "@react-md/core";
 *
 * function ExampleComponent() {
 *   const [size, setSize] = useState({ height: 0, width: 0 });
 *   const ref = useResizeObserver({
 *     onUpdate: useCallback((entry) => {
 *       setSize({
 *         height: entry.contentRect.height,
 *         width: entry.contentRect.width,
 *       });
 *     });
 *   });
 *
 *   return (
 *     <>
 *       <div data-testid="size">{JSON.stringify(size)}</div>
 *       <div data-testid="resize-target" ref={ref} />
 *     </>
 *   );
 * }
 *
 * cleanupResizeObserverAfterEach();
 *
 * describe("ExampleComponent", () => {
 *   it("should do stuff", () => {
 *     const observer = setupResizeObserverMock();
 *     render(<ExampleComponent />)
 *
 *     const size = screen.getByTestId("size");
 *     const resizeTarget = screen.getByTestId("resize-target")
 *
 *     // jsdom sets all element sizes to 0 by default
 *     expect(size).toHaveTextContent(JSON.stringify({ height: 0, width: 0 }));
 *
 *     // you can trigger with a custom change
 *     act(() => {
 *       observer.resizeElement(resizeTarget, { height: 100, width: 100 });
 *     });
 *     expect(size).toHaveTextContent(JSON.stringify({ height: 100, width: 100 }));
 *
 *     // or you can mock the `getBoundingClientRect` result
 *     jest.spyOn(resizeTarget, "getBoundingClientRect")
 *       .mockReturnValue({
 *         ...document.body.getBoundingClientRect(),
 *         height: 200,
 *         width: 200,
 *       }):
 *
 *     act(() => {
 *       observer.resizeElement(resizeTarget);
 *     });
 *     expect(size).toHaveTextContent(JSON.stringify({ height: 200, width: 200 }));
 *   });
 * })
 * ```
 *
 * @since 6.0.0
 */ export function setupResizeObserverMock(options = {}) {
    const { raf, manager = resizeObserverManager } = options;
    const resizeObserver = new ResizeObserverMock((entries)=>{
        if (raf) {
            window.cancelAnimationFrame(manager.frame);
            manager.frame = window.requestAnimationFrame(()=>{
                manager.handleResizeEntries(entries);
            });
        } else {
            manager.handleResizeEntries(entries);
        }
    });
    manager.sharedObserver = resizeObserver;
    return resizeObserver;
}
/**
 * @see {@link setupResizeObserverMock}
 * @since 6.0.0
 */ export function cleanupResizeObserverAfterEach(restoreAllMocks = true) {
    afterEach(()=>{
        resizeObserverManager.frame = 0;
        resizeObserverManager.subscriptions = new Map();
        resizeObserverManager.sharedObserver = undefined;
        if (restoreAllMocks) {
            jest.restoreAllMocks();
        }
    });
}

//# sourceMappingURL=ResizeObserver.js.map