@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
224 lines (223 loc) • 8.87 kB
JavaScript
"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