UNPKG

@wordpress/components

Version:
8 lines (7 loc) 6.4 kB
{ "version": 3, "sources": ["../../../src/navigator/navigator-screen/use-screen-animate-presence.ts"], "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useState, useEffect, useLayoutEffect, useCallback } from '@wordpress/element';\nimport { useReducedMotion } from '@wordpress/compose';\nimport { isRTL as isRTLFn } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport * as styles from '../styles';\n\n// Possible values:\n// - 'INITIAL': the initial state\n// - 'ANIMATING_IN': start enter animation\n// - 'IN': enter animation has ended\n// - 'ANIMATING_OUT': start exit animation\n// - 'OUT': the exit animation has ended\n\n// Allow an extra 20% of the total animation duration to account for potential\n// event loop delays.\nconst ANIMATION_TIMEOUT_MARGIN = 1.2;\nconst isEnterAnimation = (animationDirection, animationStatus, animationName) => animationStatus === 'ANIMATING_IN' && animationName === styles.ANIMATION_END_NAMES[animationDirection].in;\nconst isExitAnimation = (animationDirection, animationStatus, animationName) => animationStatus === 'ANIMATING_OUT' && animationName === styles.ANIMATION_END_NAMES[animationDirection].out;\nexport function useScreenAnimatePresence({\n isMatch,\n skipAnimation,\n isBack,\n onAnimationEnd\n}) {\n const isRTL = isRTLFn();\n const prefersReducedMotion = useReducedMotion();\n const [animationStatus, setAnimationStatus] = useState('INITIAL');\n\n // Start enter and exit animations when the screen is selected or deselected.\n // The animation status is set to `IN` or `OUT` immediately if the animation\n // should be skipped.\n const becameSelected = animationStatus !== 'ANIMATING_IN' && animationStatus !== 'IN' && isMatch;\n const becameUnselected = animationStatus !== 'ANIMATING_OUT' && animationStatus !== 'OUT' && !isMatch;\n useLayoutEffect(() => {\n if (becameSelected) {\n setAnimationStatus(skipAnimation || prefersReducedMotion ? 'IN' : 'ANIMATING_IN');\n } else if (becameUnselected) {\n setAnimationStatus(skipAnimation || prefersReducedMotion ? 'OUT' : 'ANIMATING_OUT');\n }\n }, [becameSelected, becameUnselected, skipAnimation, prefersReducedMotion]);\n\n // Animation attributes (derived state).\n const animationDirection = isRTL && isBack || !isRTL && !isBack ? 'end' : 'start';\n const isAnimatingIn = animationStatus === 'ANIMATING_IN';\n const isAnimatingOut = animationStatus === 'ANIMATING_OUT';\n let animationType;\n if (isAnimatingIn) {\n animationType = 'in';\n } else if (isAnimatingOut) {\n animationType = 'out';\n }\n const onScreenAnimationEnd = useCallback(e => {\n onAnimationEnd?.(e);\n if (isExitAnimation(animationDirection, animationStatus, e.animationName)) {\n // When the exit animation ends on an unselected screen, set the\n // status to 'OUT' to remove the screen contents from the DOM.\n setAnimationStatus('OUT');\n } else if (isEnterAnimation(animationDirection, animationStatus, e.animationName)) {\n // When the enter animation ends on a selected screen, set the\n // status to 'IN' to ensure the screen is rendered in the DOM.\n setAnimationStatus('IN');\n }\n }, [onAnimationEnd, animationStatus, animationDirection]);\n\n // Fallback timeout to ensure that the logic is applied even if the\n // `animationend` event is not triggered.\n useEffect(() => {\n let animationTimeout;\n if (isAnimatingOut) {\n animationTimeout = window.setTimeout(() => {\n setAnimationStatus('OUT');\n animationTimeout = undefined;\n }, styles.TOTAL_ANIMATION_DURATION.OUT * ANIMATION_TIMEOUT_MARGIN);\n } else if (isAnimatingIn) {\n animationTimeout = window.setTimeout(() => {\n setAnimationStatus('IN');\n animationTimeout = undefined;\n }, styles.TOTAL_ANIMATION_DURATION.IN * ANIMATION_TIMEOUT_MARGIN);\n }\n return () => {\n if (animationTimeout) {\n window.clearTimeout(animationTimeout);\n animationTimeout = undefined;\n }\n };\n }, [isAnimatingOut, isAnimatingIn]);\n return {\n animationStyles: styles.navigatorScreenAnimation,\n // Render the screen's contents in the DOM not only when the screen is\n // selected, but also while it is animating out.\n shouldRenderScreen: isMatch || animationStatus === 'IN' || animationStatus === 'ANIMATING_OUT',\n screenProps: {\n onAnimationEnd: onScreenAnimationEnd,\n 'data-animation-direction': animationDirection,\n 'data-animation-type': animationType,\n 'data-skip-animation': skipAnimation || undefined\n }\n };\n}"], "mappings": ";AAGA,SAAS,UAAU,WAAW,iBAAiB,mBAAmB;AAClE,SAAS,wBAAwB;AACjC,SAAS,SAAS,eAAe;AAKjC,YAAY,YAAY;AAWxB,IAAM,2BAA2B;AACjC,IAAM,mBAAmB,CAAC,oBAAoB,iBAAiB,kBAAkB,oBAAoB,kBAAkB,kBAAyB,2BAAoB,kBAAkB,EAAE;AACxL,IAAM,kBAAkB,CAAC,oBAAoB,iBAAiB,kBAAkB,oBAAoB,mBAAmB,kBAAyB,2BAAoB,kBAAkB,EAAE;AACjL,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAG;AACD,QAAM,QAAQ,QAAQ;AACtB,QAAM,uBAAuB,iBAAiB;AAC9C,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,SAAS;AAKhE,QAAM,iBAAiB,oBAAoB,kBAAkB,oBAAoB,QAAQ;AACzF,QAAM,mBAAmB,oBAAoB,mBAAmB,oBAAoB,SAAS,CAAC;AAC9F,kBAAgB,MAAM;AACpB,QAAI,gBAAgB;AAClB,yBAAmB,iBAAiB,uBAAuB,OAAO,cAAc;AAAA,IAClF,WAAW,kBAAkB;AAC3B,yBAAmB,iBAAiB,uBAAuB,QAAQ,eAAe;AAAA,IACpF;AAAA,EACF,GAAG,CAAC,gBAAgB,kBAAkB,eAAe,oBAAoB,CAAC;AAG1E,QAAM,qBAAqB,SAAS,UAAU,CAAC,SAAS,CAAC,SAAS,QAAQ;AAC1E,QAAM,gBAAgB,oBAAoB;AAC1C,QAAM,iBAAiB,oBAAoB;AAC3C,MAAI;AACJ,MAAI,eAAe;AACjB,oBAAgB;AAAA,EAClB,WAAW,gBAAgB;AACzB,oBAAgB;AAAA,EAClB;AACA,QAAM,uBAAuB,YAAY,OAAK;AAC5C,qBAAiB,CAAC;AAClB,QAAI,gBAAgB,oBAAoB,iBAAiB,EAAE,aAAa,GAAG;AAGzE,yBAAmB,KAAK;AAAA,IAC1B,WAAW,iBAAiB,oBAAoB,iBAAiB,EAAE,aAAa,GAAG;AAGjF,yBAAmB,IAAI;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,gBAAgB,iBAAiB,kBAAkB,CAAC;AAIxD,YAAU,MAAM;AACd,QAAI;AACJ,QAAI,gBAAgB;AAClB,yBAAmB,OAAO,WAAW,MAAM;AACzC,2BAAmB,KAAK;AACxB,2BAAmB;AAAA,MACrB,GAAU,gCAAyB,MAAM,wBAAwB;AAAA,IACnE,WAAW,eAAe;AACxB,yBAAmB,OAAO,WAAW,MAAM;AACzC,2BAAmB,IAAI;AACvB,2BAAmB;AAAA,MACrB,GAAU,gCAAyB,KAAK,wBAAwB;AAAA,IAClE;AACA,WAAO,MAAM;AACX,UAAI,kBAAkB;AACpB,eAAO,aAAa,gBAAgB;AACpC,2BAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,gBAAgB,aAAa,CAAC;AAClC,SAAO;AAAA,IACL,iBAAwB;AAAA;AAAA;AAAA,IAGxB,oBAAoB,WAAW,oBAAoB,QAAQ,oBAAoB;AAAA,IAC/E,aAAa;AAAA,MACX,gBAAgB;AAAA,MAChB,4BAA4B;AAAA,MAC5B,uBAAuB;AAAA,MACvB,uBAAuB,iBAAiB;AAAA,IAC1C;AAAA,EACF;AACF;", "names": [] }