@wordpress/components
Version:
UI components for WordPress.
63 lines (62 loc) • 2.35 kB
JavaScript
import { useReducedMotion } from "@wordpress/compose";
import { useCallback, useRef, useState } from "@wordpress/element";
import { CONFIG } from "../utils";
import warning from "@wordpress/warning";
const FRAME_ANIMATION_DURATION = CONFIG.transitionDuration;
const FRAME_ANIMATION_DURATION_NUMBER = Number.parseInt(CONFIG.transitionDuration);
const EXIT_ANIMATION_NAME = "components-modal__disappear-animation";
function useModalExitAnimation() {
const frameRef = useRef();
const [isAnimatingOut, setIsAnimatingOut] = useState(false);
const isReducedMotion = useReducedMotion();
const closeModal = useCallback(() => new Promise((closeModalResolve) => {
const frameEl = frameRef.current;
if (isReducedMotion) {
closeModalResolve();
return;
}
if (!frameEl) {
globalThis.SCRIPT_DEBUG === true ? warning("wp.components.Modal: the Modal component can't be closed with an exit animation because of a missing reference to the modal frame element.") : void 0;
closeModalResolve();
return;
}
let handleAnimationEnd;
const startAnimation = () => new Promise((animationResolve) => {
handleAnimationEnd = (e) => {
if (e.animationName === EXIT_ANIMATION_NAME) {
animationResolve();
}
};
frameEl.addEventListener("animationend", handleAnimationEnd);
setIsAnimatingOut(true);
});
const animationTimeout = () => new Promise((timeoutResolve) => {
setTimeout(
() => timeoutResolve(),
// Allow an extra 20% of the animation duration for the
// animationend event to fire, in case the animation frame is
// slightly delayes by some other events in the event loop.
FRAME_ANIMATION_DURATION_NUMBER * 1.2
);
});
Promise.race([startAnimation(), animationTimeout()]).then(() => {
if (handleAnimationEnd) {
frameEl.removeEventListener("animationend", handleAnimationEnd);
}
setIsAnimatingOut(false);
closeModalResolve();
});
}), [isReducedMotion]);
return {
overlayClassname: isAnimatingOut ? "is-animating-out" : void 0,
frameRef,
frameStyle: {
"--modal-frame-animation-duration": `${FRAME_ANIMATION_DURATION}`
},
closeModal
};
}
export {
useModalExitAnimation
};
//# sourceMappingURL=use-modal-exit-animation.js.map