UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

224 lines (223 loc) 8.87 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useHeightAnimation = useHeightAnimation; require("core-js/modules/web.dom-collections.iterator.js"); var _react = _interopRequireWildcard(require("react")); var _HeightAnimationInstance = _interopRequireDefault(require("./HeightAnimationInstance")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const useLayoutEffect = typeof window === 'undefined' ? _react.default.useEffect : _react.default.useLayoutEffect; function useHeightAnimation(targetRef) { var _instRef$current2; let { open = true, animate = true, children = null, compensateForGap, onInit = null, onOpen = null, onAnimationStart = null, onAnimationEnd = null } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; const instRef = (0, _react.useRef)(null); const isInitialRenderRef = (0, _react.useRef)(typeof globalThis !== 'undefined' ? globalThis.readjustTime !== -1 : true); const [isOpen, setIsOpen] = (0, _react.useState)(open); const [isVisible, setIsVisible] = (0, _react.useState)(false); const [isAnimating, setIsAnimating] = (0, _react.useState)(false); const [isVisibleParallax, setParallax] = (0, _react.useState)(open); const eventsRef = (0, _react.useRef)({ onInit, onAnimationEnd, onAnimationStart, onOpen }); eventsRef.current.onInit = onInit; eventsRef.current.onAnimationEnd = onAnimationEnd; eventsRef.current.onAnimationStart = onAnimationStart; eventsRef.current.onOpen = onOpen; useLayoutEffect(() => { var _eventsRef$current$on, _eventsRef$current; instRef.current = new _HeightAnimationInstance.default(); (_eventsRef$current$on = (_eventsRef$current = eventsRef.current).onInit) === null || _eventsRef$current$on === void 0 ? void 0 : _eventsRef$current$on.call(_eventsRef$current, instRef.current); return () => { var _instRef$current; (_instRef$current = instRef.current) === null || _instRef$current === void 0 ? void 0 : _instRef$current.remove(); instRef.current = null; }; }, []); useLayoutEffect(() => { instRef.current.setOptions({ animate }); if (typeof global !== 'undefined' && globalThis.IS_TEST) { instRef.current.setOptions({ animate: false }); } }, [animate]); const handleCompensateForGap = (0, _react.useCallback)(() => { if (compensateForGap) { let gap = compensateForGap; const { elem } = instRef.current; if (compensateForGap === 'auto') { gap = window.getComputedStyle(elem.parentElement).getPropertyValue('row-gap'); } elem.style.marginTop = `calc(${gap} * -1)`; const inner = elem.querySelector('.compensateForGap'); inner.style.marginTop = gap; } }, [compensateForGap]); useLayoutEffect(() => { instRef.current.onStart(state => { switch (state) { case 'opening': handleCompensateForGap(); setIsVisible(true); setParallax(true); setIsAnimating(true); break; case 'closing': setParallax(false); setIsAnimating(true); break; case 'adjusting': setIsAnimating(true); break; } if (!isInitialRenderRef.current) { var _eventsRef$current$on2, _eventsRef$current2; (_eventsRef$current$on2 = (_eventsRef$current2 = eventsRef.current).onAnimationStart) === null || _eventsRef$current$on2 === void 0 ? void 0 : _eventsRef$current$on2.call(_eventsRef$current2, state); } }); instRef.current.onEnd(state => { var _eventsRef$current$on3, _eventsRef$current3, _eventsRef$current$on4, _eventsRef$current4; switch (state) { case 'opened': setIsVisible(true); setIsOpen(true); setIsAnimating(false); (_eventsRef$current$on3 = (_eventsRef$current3 = eventsRef.current).onOpen) === null || _eventsRef$current$on3 === void 0 ? void 0 : _eventsRef$current$on3.call(_eventsRef$current3, true); break; case 'closed': setIsVisible(false); setIsOpen(false); setParallax(false); setIsAnimating(false); (_eventsRef$current$on4 = (_eventsRef$current4 = eventsRef.current).onOpen) === null || _eventsRef$current$on4 === void 0 ? void 0 : _eventsRef$current$on4.call(_eventsRef$current4, false); break; case 'adjusted': setIsAnimating(false); break; } if (!isInitialRenderRef.current) { var _eventsRef$current$on5, _eventsRef$current5; (_eventsRef$current$on5 = (_eventsRef$current5 = eventsRef.current).onAnimationEnd) === null || _eventsRef$current$on5 === void 0 ? void 0 : _eventsRef$current$on5.call(_eventsRef$current5, state); } }); }, [compensateForGap, handleCompensateForGap]); useOpenClose({ open, instRef, isInitialRenderRef, targetRef }); useAdjust({ children, instRef, isInitialRenderRef, targetRef }); const firstPaintStyle = open && !isVisible && !isAnimating && ((_instRef$current2 = instRef.current) === null || _instRef$current2 === void 0 ? void 0 : _instRef$current2.firstPaintStyle) || {}; const isInDOM = open || isVisible; return { open, isOpen, isInDOM, isVisible, isVisibleParallax, isAnimating, firstPaintStyle }; } function useOpenClose(_ref) { let { open, instRef, isInitialRenderRef, targetRef } = _ref; const isTest = typeof process !== 'undefined' && process.env.NODE_ENV === 'test' && typeof globalThis.IS_TEST === 'undefined'; useLayoutEffect(() => { instRef.current.setElement(targetRef.current); if (!targetRef.current || instRef.current.state === 'init' && isInitialRenderRef.current) { if (open) { instRef.current.setAsOpen(); } else { instRef.current.setAsClosed(); } } else { if (open) { instRef.current.open(); } else { instRef.current.close(); } } if (isTest) { var _targetRef$current; const event = new CustomEvent('transitionend'); (_targetRef$current = targetRef.current) === null || _targetRef$current === void 0 ? void 0 : _targetRef$current.dispatchEvent(event); } }, [open, targetRef, instRef, isInitialRenderRef, isTest]); useLayoutEffect(() => { const run = () => { isInitialRenderRef.current = false; }; if (globalThis.bypassTime === -1 || isTest) { run(); } else { var _window$requestAnimat, _window; (_window$requestAnimat = (_window = window).requestAnimationFrame) === null || _window$requestAnimat === void 0 ? void 0 : _window$requestAnimat.call(_window, run); } }, [isInitialRenderRef, isTest]); } function useAdjust(_ref2) { let { children, instRef, isInitialRenderRef, targetRef } = _ref2; const fromHeight = (0, _react.useRef)(0); const [timer] = (0, _react.useState)(() => Date.now()); const shouldAdjust = () => { var _instRef$current3; switch ((_instRef$current3 = instRef.current) === null || _instRef$current3 === void 0 ? void 0 : _instRef$current3.state) { case 'opened': case 'adjusted': case 'adjusting': return !isInitialRenderRef.current && Date.now() - timer > (globalThis.readjustTime || 100); } return false; }; (0, _react.useMemo)(() => { if (shouldAdjust()) { var _instRef$current4; fromHeight.current = (_instRef$current4 = instRef.current) === null || _instRef$current4 === void 0 ? void 0 : _instRef$current4.getHeight(); } }, [children]); useLayoutEffect(() => { if (shouldAdjust()) { instRef.current.setElement(targetRef.current); instRef.current.elem.style.height = ''; const toHeight = instRef.current.getHeight(); instRef.current.adjustTo(fromHeight.current, toHeight); } }, [children]); } //# sourceMappingURL=useHeightAnimation.js.map