wp_back/wp-content/plugins/visual-portfolio/gutenberg/components/setup-wizard/steps-wizard.js
2024-05-20 15:37:46 +03:00

93 lines
2.2 KiB
JavaScript

import classnames from 'classnames/dedupe';
import { debounce } from 'throttle-debounce';
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
const { ResizeObserver, MutationObserver } = window;
function stepsWizard(props) {
const { step, children } = props;
const $ref = useRef();
const [newStep, setNewStep] = useState(step);
const [height, setHeight] = useState(0);
const maybeUpdateHeight = useCallback(() => {
let newHeight = 0;
$ref.current.childNodes.forEach(($child) => {
const styles = window.getComputedStyle($child);
const margin =
parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
newHeight += Math.ceil($child.offsetHeight + margin);
});
setHeight(`${newHeight}px`);
}, [$ref]);
useEffect(() => {
if (step !== newStep) {
setNewStep(step);
}
}, [step, newStep]);
useEffect(() => {
maybeUpdateHeight();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [newStep]);
useEffect(() => {
const $element = $ref.current;
const calculateHeight = debounce(100, () => {
maybeUpdateHeight();
});
// Resize observer is used to properly set height
// when selected images, saved post and reloaded page.
const resizeObserver = new ResizeObserver(calculateHeight);
const mutationObserver = new MutationObserver(calculateHeight);
resizeObserver.observe($element);
mutationObserver.observe($element, {
attributes: true,
characterData: true,
childList: true,
subtree: true,
attributeOldValue: true,
characterDataOldValue: true,
});
return () => {
resizeObserver.disconnect();
mutationObserver.disconnect();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [$ref.current]);
return typeof children[newStep] !== 'undefined' ? (
<div
ref={$ref}
className={classnames(
'vpf-component-steps-wizard',
step !== newStep
? `vpf-component-steps-wizard-animate-${
newStep > step ? 'left' : 'right'
}`
: false
)}
style={height ? { height } : {}}
>
{children[newStep]}
</div>
) : null;
}
stepsWizard.Step = function (props) {
const { children } = props;
return children;
};
export default stepsWizard;