123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- import { useRef, useEffect, useCallback, useState, useMemo } from 'react';
- function useResolvedElement(subscriber, refOrElement) {
- var lastReportRef = useRef(null);
- var refOrElementRef = useRef(null);
- refOrElementRef.current = refOrElement;
- var cbElementRef = useRef(null);
-
- useEffect(function () {
- evaluateSubscription();
- });
- var evaluateSubscription = useCallback(function () {
- var cbElement = cbElementRef.current;
- var refOrElement = refOrElementRef.current;
- var element = cbElement ? cbElement : refOrElement ? refOrElement instanceof Element ? refOrElement : refOrElement.current : null;
- if (lastReportRef.current && lastReportRef.current.element === element && lastReportRef.current.subscriber === subscriber) {
- return;
- }
- if (lastReportRef.current && lastReportRef.current.cleanup) {
- lastReportRef.current.cleanup();
- }
- lastReportRef.current = {
- element: element,
- subscriber: subscriber,
-
-
- cleanup: element ? subscriber(element) : undefined
- };
- }, [subscriber]);
- useEffect(function () {
- return function () {
- if (lastReportRef.current && lastReportRef.current.cleanup) {
- lastReportRef.current.cleanup();
- lastReportRef.current = null;
- }
- };
- }, []);
- return useCallback(function (element) {
- cbElementRef.current = element;
- evaluateSubscription();
- }, [evaluateSubscription]);
- }
- function extractSize(entry, boxProp, sizeType) {
- if (!entry[boxProp]) {
- if (boxProp === "contentBoxSize") {
-
-
-
-
-
- return entry.contentRect[sizeType === "inlineSize" ? "width" : "height"];
- }
- return undefined;
- }
- return entry[boxProp][0] ? entry[boxProp][0][sizeType] :
-
-
- entry[boxProp][sizeType];
- }
- function useResizeObserver(opts) {
- if (opts === void 0) {
- opts = {};
- }
-
-
-
- var onResize = opts.onResize;
- var onResizeRef = useRef(undefined);
- onResizeRef.current = onResize;
- var round = opts.round || Math.round;
- var resizeObserverRef = useRef();
- var _useState = useState({
- width: undefined,
- height: undefined
- }),
- size = _useState[0],
- setSize = _useState[1];
-
- var didUnmount = useRef(false);
- useEffect(function () {
- didUnmount.current = false;
- return function () {
- didUnmount.current = true;
- };
- }, []);
- var previous = useRef({
- width: undefined,
- height: undefined
- });
-
-
- var refCallback = useResolvedElement(useCallback(function (element) {
-
-
- if (!resizeObserverRef.current || resizeObserverRef.current.box !== opts.box || resizeObserverRef.current.round !== round) {
- resizeObserverRef.current = {
- box: opts.box,
- round: round,
- instance: new ResizeObserver(function (entries) {
- var entry = entries[0];
- var boxProp = opts.box === "border-box" ? "borderBoxSize" : opts.box === "device-pixel-content-box" ? "devicePixelContentBoxSize" : "contentBoxSize";
- var reportedWidth = extractSize(entry, boxProp, "inlineSize");
- var reportedHeight = extractSize(entry, boxProp, "blockSize");
- var newWidth = reportedWidth ? round(reportedWidth) : undefined;
- var newHeight = reportedHeight ? round(reportedHeight) : undefined;
- if (previous.current.width !== newWidth || previous.current.height !== newHeight) {
- var newSize = {
- width: newWidth,
- height: newHeight
- };
- previous.current.width = newWidth;
- previous.current.height = newHeight;
- if (onResizeRef.current) {
- onResizeRef.current(newSize);
- } else {
- if (!didUnmount.current) {
- setSize(newSize);
- }
- }
- }
- })
- };
- }
- resizeObserverRef.current.instance.observe(element, {
- box: opts.box
- });
- return function () {
- if (resizeObserverRef.current) {
- resizeObserverRef.current.instance.unobserve(element);
- }
- };
- }, [opts.box, round]), opts.ref);
- return useMemo(function () {
- return {
- ref: refCallback,
- width: size.width,
- height: size.height
- };
- }, [refCallback, size.width, size.height]);
- }
- export { useResizeObserver as default };
|