@gravity-ui/uikit
Version:
Gravity UI base styling and components
52 lines (51 loc) • 2.23 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.useAnimateHeight = useAnimateHeight;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const useResizeObserver_1 = require("../../useResizeObserver/index.js");
function useAnimateHeight({ ref, enabled, }) {
const previousHeight = React.useRef(null);
const isTransitioningHeight = React.useRef(false);
React.useEffect(() => {
if (!enabled) {
previousHeight.current = null;
isTransitioningHeight.current = false;
}
}, [enabled]);
const handleResize = React.useCallback(() => {
const node = ref?.current;
if (!node || isTransitioningHeight.current || !enabled) {
return;
}
const contentHeight = node.clientHeight;
if (!previousHeight.current || previousHeight.current === contentHeight) {
previousHeight.current = contentHeight;
return;
}
// Set previous height first for the transition to work, because it doesn't work with 'auto'
node.style.height = `${previousHeight.current}px`;
isTransitioningHeight.current = true;
const overflowY = node.style.overflowY;
node.style.overflowY = 'clip';
const handleTransitionEnd = (event) => {
if (event.propertyName !== 'height') {
return;
}
node.removeEventListener('transitionend', handleTransitionEnd);
// ResizeObserver final resize event fires before this, so we have to delay with timeout
setTimeout(() => {
node.style.height = 'auto';
node.style.overflowY = overflowY;
isTransitioningHeight.current = false;
}, 0);
};
node.addEventListener('transitionend', handleTransitionEnd);
requestAnimationFrame(() => {
node.style.height = `${contentHeight}px`;
previousHeight.current = contentHeight;
});
}, [ref, enabled]);
(0, useResizeObserver_1.useResizeObserver)({ ref: enabled ? ref : undefined, onResize: handleResize });
}
//# sourceMappingURL=useAnimateHeight.js.map
;