tweak-tools
Version:
Tweak your React projects until awesomeness
49 lines (48 loc) • 1.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useToggle = void 0;
const react_1 = require("react");
function useToggle(toggled) {
const wrapperRef = (0, react_1.useRef)(null);
const contentRef = (0, react_1.useRef)(null);
const firstRender = (0, react_1.useRef)(true);
// this should be fine for SSR since the store is set in useEffect and
// therefore the pane doesn't show on first render.
(0, react_1.useLayoutEffect)(() => {
if (!toggled) {
wrapperRef.current.style.height = '0px';
wrapperRef.current.style.overflow = 'hidden';
}
// we only want to do this once so that's ok to break the rules of hooks.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
(0, react_1.useEffect)(() => {
// prevents first animation
if (firstRender.current) {
firstRender.current = false;
return;
}
let timeout;
const ref = wrapperRef.current;
const fixHeight = () => {
if (toggled) {
ref.style.removeProperty('height');
ref.style.removeProperty('overflow');
contentRef.current.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
};
ref.addEventListener('transitionend', fixHeight, { once: true });
const { height } = contentRef.current.getBoundingClientRect();
ref.style.height = height + 'px';
if (!toggled) {
ref.style.overflow = 'hidden';
timeout = window.setTimeout(() => (ref.style.height = '0px'), 50);
}
return () => {
ref.removeEventListener('transitionend', fixHeight);
clearTimeout(timeout);
};
}, [toggled]);
return { wrapperRef, contentRef };
}
exports.useToggle = useToggle;