UNPKG

@atlaskit/renderer

Version:
95 lines (88 loc) 3.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useStableScroll = void 0; var _react = require("react"); /** * Hook that provides functionality to wait for layout stability before performing an action. * Uses ResizeObserver to detect when a container has stopped resizing (e.g., images finished loading). */ var useStableScroll = exports.useStableScroll = function useStableScroll() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var _options$stabilityWai = options.stabilityWaitTime, stabilityWaitTime = _options$stabilityWai === void 0 ? 200 : _options$stabilityWai, _options$maxStability = options.maxStabilityWaitTime, maxStabilityWaitTime = _options$maxStability === void 0 ? 10000 : _options$maxStability; var stabilityTimeoutRef = (0, _react.useRef)(null); var resizeObserverRef = (0, _react.useRef)(null); var lastStableTimeRef = (0, _react.useRef)(0); var onStableCallbackRef = (0, _react.useRef)(null); var cleanup = (0, _react.useCallback)(function () { if (stabilityTimeoutRef.current) { clearTimeout(stabilityTimeoutRef.current); stabilityTimeoutRef.current = null; } if (resizeObserverRef.current) { resizeObserverRef.current.disconnect(); resizeObserverRef.current = null; } onStableCallbackRef.current = null; lastStableTimeRef.current = 0; }, []); var scheduleStabilityCheck = (0, _react.useCallback)(function () { // Clear any existing stability timeout. if (stabilityTimeoutRef.current) { clearTimeout(stabilityTimeoutRef.current); stabilityTimeoutRef.current = null; } // Check if we've exceeded the maximum stability wait time. var now = Date.now(); if (lastStableTimeRef.current === 0) { lastStableTimeRef.current = now; } else if (now - lastStableTimeRef.current > maxStabilityWaitTime) { // We've waited too long for stability, call the callback now. if (onStableCallbackRef.current) { onStableCallbackRef.current(); cleanup(); } return; } // Set a timeout to call the callback after the stability wait time. stabilityTimeoutRef.current = setTimeout(function () { if (onStableCallbackRef.current) { onStableCallbackRef.current(); cleanup(); } }, stabilityWaitTime); }, [stabilityWaitTime, maxStabilityWaitTime, cleanup]); var waitForStability = (0, _react.useCallback)(function (container, onStable) { // Clean up any existing observer cleanup(); // Store the callback onStableCallbackRef.current = onStable; // Check if ResizeObserver is available if (typeof ResizeObserver === 'undefined') { // Fallback: just call the callback after the stability wait time stabilityTimeoutRef.current = setTimeout(function () { if (onStableCallbackRef.current) { onStableCallbackRef.current(); cleanup(); } }, stabilityWaitTime); return; } // Create a ResizeObserver to monitor the container for size changes. resizeObserverRef.current = new ResizeObserver(function () { // Container size changed, reset stability timer. scheduleStabilityCheck(); }); resizeObserverRef.current.observe(container); // Start the initial stability check scheduleStabilityCheck(); }, [stabilityWaitTime, scheduleStabilityCheck, cleanup]); return { waitForStability: waitForStability, cleanup: cleanup }; };