"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { getRTLRootMargin: function() { return getRTLRootMargin; }, useIntersectionObserver: function() { return useIntersectionObserver; } }); const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); const _reactutilities = require("@fluentui/react-utilities"); const _reactsharedcontexts = require("@fluentui/react-shared-contexts"); const _useMutationObserver = require("./useMutationObserver"); const { useCallback, useState, useRef } = _react; const getRTLRootMargin = (ltrRootMargin, target, win)=>{ if (target && win) { // get the computed dir for the target element const newDir = win.getComputedStyle(target).direction; // If we're in rtl reading direction, we might need to flip the margins on the left/right sides if (newDir === 'rtl') { let newMargin = ltrRootMargin; const splitMargins = ltrRootMargin.split(' '); // We only need to do this if we get four values, otherwise the sides are equal and don't require flipping. if (splitMargins.length === 4) { newMargin = `${splitMargins[0]} ${splitMargins[3]} ${splitMargins[2]} ${splitMargins[1]}`; } return newMargin; } else { return ltrRootMargin; } } return ltrRootMargin; }; const useIntersectionObserver = (callback, options)=>{ 'use no memo'; // TODO: exclude types from this lint rule: https://github.com/microsoft/fluentui/issues/31286 // eslint-disable-next-line no-restricted-globals const observer = useRef(); const [observerList, setObserverList] = useState(); const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)(); const win = targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.defaultView; var _options_rootMargin; // set the initial init with corrected margins based on the observed root's calculated reading direction. const [observerInit, setObserverInit] = useState(options && { ...options, rootMargin: getRTLRootMargin((_options_rootMargin = options.rootMargin) !== null && _options_rootMargin !== void 0 ? _options_rootMargin : '0px', options.root, win) }); var _options_rootMargin1; // We have to assume that any values passed in for rootMargin by the consuming app are ltr values. As such we will store the ltr value. const ltrRootMargin = useRef((_options_rootMargin1 = options === null || options === void 0 ? void 0 : options.rootMargin) !== null && _options_rootMargin1 !== void 0 ? _options_rootMargin1 : '0px'); // Callback function to execute when mutations are observed const mutationObserverCallback = useCallback((mutationList)=>{ for (const mutation of mutationList){ // Ensuring that the right attribute is being observed and that the root is within the tree of the element being mutated. if (mutation.type === 'attributes' && mutation.attributeName === 'dir' && (options === null || options === void 0 ? void 0 : options.root) && mutation.target.contains(options === null || options === void 0 ? void 0 : options.root)) { setObserverInit({ ...observerInit, rootMargin: getRTLRootMargin(ltrRootMargin.current, observerInit === null || observerInit === void 0 ? void 0 : observerInit.root, win) }); } } }, [ ltrRootMargin, observerInit, options === null || options === void 0 ? void 0 : options.root, win ]); // Mutation observer for dir attribute changes in the document (0, _useMutationObserver.useMutationObserver)(targetDocument, mutationObserverCallback, { attributes: true, subtree: true, attributeFilter: [ 'dir' ] }); // Observer elements in passed in list and clean up previous list // This effect is only triggered when observerList is updated (0, _reactutilities.useIsomorphicLayoutEffect)(()=>{ if (!win) { return; } observer.current = new win.IntersectionObserver(callback, { ...observerInit, rootMargin: getRTLRootMargin(ltrRootMargin.current, observerInit === null || observerInit === void 0 ? void 0 : observerInit.root, win) }); // If we have an instance of IO and a list with elements, observer the elements if (observer.current && observerList && observerList.length > 0) { observerList.forEach((element)=>{ var _observer_current; (_observer_current = observer.current) === null || _observer_current === void 0 ? void 0 : _observer_current.observe(element); }); } // clean up previous elements being listened to return ()=>{ if (observer.current) { observer.current.disconnect(); } }; }, [ observerList, observerInit, callback, win ]); // Do not use internally, we need to track external settings only here const setObserverInitExternal = useCallback((newInit)=>{ var _newInit_rootMargin; // Since we know this is coming from consumers, we can store this value as LTR somewhat safely. ltrRootMargin.current = (_newInit_rootMargin = newInit === null || newInit === void 0 ? void 0 : newInit.rootMargin) !== null && _newInit_rootMargin !== void 0 ? _newInit_rootMargin : '0px'; // Call the internal setter to update the value and ensure if our calculated direction is rtl, we flip the margin setObserverInit({ ...newInit, rootMargin: getRTLRootMargin(ltrRootMargin.current, newInit === null || newInit === void 0 ? void 0 : newInit.root, win) }); }, [ ltrRootMargin, setObserverInit, win ]); return { setObserverList, setObserverInit: setObserverInitExternal, observer }; };