@react-aria/utils
Version:
Spectrum UI components in React
98 lines (90 loc) • 4.19 kB
JavaScript
var $78605a5d7424e31b$exports = require("./useLayoutEffect.main.js");
var $bsryd$reactdom = require("react-dom");
var $bsryd$react = require("react");
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
$parcel$export(module.exports, "useEnterAnimation", () => $5bd06107f98811f5$export$6d3443f2c48bfc20);
$parcel$export(module.exports, "useExitAnimation", () => $5bd06107f98811f5$export$45fda7c47f93fd48);
/*
* Copyright 2020 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
function $5bd06107f98811f5$export$6d3443f2c48bfc20(ref, isReady = true) {
let [isEntering, setEntering] = (0, $bsryd$react.useState)(true);
let isAnimationReady = isEntering && isReady;
// There are two cases for entry animations:
// 1. CSS @keyframes. The `animation` property is set during the isEntering state, and it is removed after the animation finishes.
// 2. CSS transitions. The initial styles are applied during the isEntering state, and removed immediately, causing the transition to occur.
//
// In the second case, cancel any transitions that were triggered prior to the isEntering = false state (when the transition is supposed to start).
// This can happen when isReady starts as false (e.g. popovers prior to placement calculation).
(0, $78605a5d7424e31b$exports.useLayoutEffect)(()=>{
if (isAnimationReady && ref.current && 'getAnimations' in ref.current) {
for (let animation of ref.current.getAnimations())if (animation instanceof CSSTransition) animation.cancel();
}
}, [
ref,
isAnimationReady
]);
$5bd06107f98811f5$var$useAnimation(ref, isAnimationReady, (0, $bsryd$react.useCallback)(()=>setEntering(false), []));
return isAnimationReady;
}
function $5bd06107f98811f5$export$45fda7c47f93fd48(ref, isOpen) {
let [exitState, setExitState] = (0, $bsryd$react.useState)(isOpen ? 'open' : 'closed');
switch(exitState){
case 'open':
// If isOpen becomes false, set the state to exiting.
if (!isOpen) setExitState('exiting');
break;
case 'closed':
case 'exiting':
// If we are exiting and isOpen becomes true, the animation was interrupted.
// Reset the state to open.
if (isOpen) setExitState('open');
break;
}
let isExiting = exitState === 'exiting';
$5bd06107f98811f5$var$useAnimation(ref, isExiting, (0, $bsryd$react.useCallback)(()=>{
// Set the state to closed, which will cause the element to be unmounted.
setExitState((state)=>state === 'exiting' ? 'closed' : state);
}, []));
return isExiting;
}
function $5bd06107f98811f5$var$useAnimation(ref, isActive, onEnd) {
(0, $78605a5d7424e31b$exports.useLayoutEffect)(()=>{
if (isActive && ref.current) {
if (!('getAnimations' in ref.current)) {
// JSDOM
onEnd();
return;
}
let animations = ref.current.getAnimations();
if (animations.length === 0) {
onEnd();
return;
}
let canceled = false;
Promise.all(animations.map((a)=>a.finished)).then(()=>{
if (!canceled) (0, $bsryd$reactdom.flushSync)(()=>{
onEnd();
});
}).catch(()=>{});
return ()=>{
canceled = true;
};
}
}, [
ref,
isActive,
onEnd
]);
}
//# sourceMappingURL=animation.main.js.map