UNPKG

wix-style-react

Version:
370 lines • 12.4 kB
import { easingMap, timingMap, } from '../constants'; export const getPercentageValue = (percentage) => { const percentRegex = /^((100)|(\d{1,2}(\.\d*)?))%$/g; if (percentage.match(percentRegex)) { const percentNumber = Number(percentage.split('%')[0]); if (Number.isFinite(percentNumber)) { return percentNumber / 100; } } return 0; }; const getFadeProps = (fade) => { if (fade === true) { return { duration: 'medium01', }; } return fade; }; const getMoveProps = (move) => { if (move === true) { return { duration: 'medium01', direction: 'bottomToTop', distance: '10px', }; } return move; }; const getToggleProps = (toggle) => { if (toggle === true) { return { duration: 'medium01', direction: 'bottomToTop', }; } return toggle; }; const getScaleProps = (scale, isExiting) => { if (scale === true) { return { duration: 'medium01', direction: 'center', scale: isExiting ? '0' : '1', }; } return { ...scale, scale: `${getPercentageValue(scale.scale)}` }; }; const getDefaultStyles = (props) => { const easing = props.easing ? { transitionTimingFunction: easingMap[props.easing], } : undefined; const delay = props.delay ? { transitionDelay: `${timingMap[props.delay]}ms`, } : undefined; return { ...easing, ...delay, }; }; const getFadeStyles = (fadeProps, isExiting) => { const { duration } = fadeProps; const defaultStyles = getDefaultStyles(fadeProps); return { [isExiting ? 'exiting' : 'entering']: { opacity: 0, transitionProperty: 'opacity', transitionDuration: `${timingMap[duration]}ms`, ...(isExiting ? defaultStyles : {}), }, [isExiting ? 'exited' : 'entered']: { opacity: 1, transitionProperty: 'opacity', transitionDuration: `${timingMap[duration]}ms`, ...(!isExiting ? defaultStyles : {}), }, }; }; export const getMoveStyles = (moveProps, isExiting) => { const { direction, distance, duration } = moveProps; const defaultStyles = getDefaultStyles(moveProps); let transform = ''; switch (direction) { case 'topToBottom': transform = `translateY(${isExiting ? distance : `-${distance}`})`; break; case 'bottomToTop': transform = `translateY(${isExiting ? `-${distance}` : distance})`; break; case 'leftToRight': transform = `translateX(${isExiting ? distance : `-${distance}`})`; break; case 'rightToLeft': transform = `translateX(${isExiting ? `-${distance}` : distance})`; break; default: throw new Error('unsupported direction'); } return { [isExiting ? 'exiting' : 'entering']: { transform, transitionProperty: 'transform', transitionDuration: `${timingMap[duration]}ms`, ...(isExiting ? defaultStyles : {}), }, [isExiting ? 'exited' : 'entered']: { transform: 'none', transitionProperty: 'transform', transitionDuration: `${timingMap[duration]}ms`, ...(!isExiting ? defaultStyles : {}), }, }; }; const isDirectionVertical = (direction) => { return direction === 'bottomToTop' || direction === 'topToBottom'; }; const getToggleStyles = (toggleProps, isExiting, height, width, oppositeProps) => { const { direction, duration } = toggleProps; const defaultStyles = getDefaultStyles(toggleProps); const isVertical = isDirectionVertical(direction); const transitionOrigin = isVertical ? 'bottom' : 'left'; const isOppositeVertical = oppositeProps?.direction && isDirectionVertical(oppositeProps?.direction); const isOppositeOnAnotherAxis = isOppositeVertical !== undefined && isOppositeVertical !== isVertical; const transitionOriginOutValue = oppositeProps?.direction === 'bottomToTop' || oppositeProps?.direction === 'leftToRight' ? '-100%' : '100%'; const oppositeTransitionOrigin = isOppositeVertical ? 'bottom' : 'left'; let transitionOriginIn = ''; switch (direction) { case 'topToBottom': case 'rightToLeft': transitionOriginIn = isExiting ? '-100%' : '100%'; break; case 'bottomToTop': case 'leftToRight': transitionOriginIn = isExiting ? '100%' : '-100%'; break; default: throw new Error('unsupported direction'); } const commonStyles = { height: isVertical ? `${height}px` : '100%', width: isVertical ? '100%' : `${width}px`, position: 'relative', overflow: 'hidden', transitionProperty: 'bottom, left', transitionDuration: `${timingMap[duration]}ms`, }; const styles = { in: { ...commonStyles, [transitionOrigin]: transitionOriginIn, ...(isExiting ? defaultStyles : {}), }, out: { ...commonStyles, [transitionOrigin]: oppositeProps?.direction === direction || isOppositeVertical === isVertical ? transitionOriginOutValue : '0%', ...(isOppositeOnAnotherAxis ? { [oppositeTransitionOrigin]: transitionOriginOutValue, } : {}), ...(!isExiting ? defaultStyles : {}), }, }; if (isExiting) { return { entered: { ...commonStyles, [transitionOrigin]: '0%', ...(isOppositeOnAnotherAxis ? { [oppositeTransitionOrigin]: '0%', } : {}), ...defaultStyles, }, exiting: styles.in, exited: styles.out, }; } return { entering: styles.in, entered: styles.out, }; }; const getScaleStyles = (scaleProps, isExiting) => { const { direction, scale, duration } = scaleProps; const defaultStyles = getDefaultStyles(scaleProps); let transformOrigin = ''; switch (direction) { case 'bottom': transformOrigin = '50% 100%'; break; case 'bottomEnd': transformOrigin = '100% 100%'; break; case 'bottomStart': transformOrigin = '0% 100%'; break; case 'center': transformOrigin = '50% 50%'; break; case 'left': transformOrigin = '0% 50%'; break; case 'right': transformOrigin = '100% 50%'; break; case 'top': transformOrigin = '50% 0%'; break; case 'topEnd': transformOrigin = '100% 0%'; break; case 'topStart': transformOrigin = '0% 0%'; break; default: throw new Error('unsupported direction'); } return { [isExiting ? 'exiting' : 'entering']: { transform: 'scale(0, 0)', transitionProperty: 'transform', transitionDuration: `${timingMap[duration]}ms`, transformOrigin, ...(isExiting ? defaultStyles : {}), }, [isExiting ? 'exited' : 'entered']: { transform: `scale(${scale}, ${scale})`, transitionProperty: 'transform', transitionDuration: `${timingMap[duration]}ms`, transformOrigin, ...(!isExiting ? defaultStyles : {}), }, }; }; const getToggleWrapperStyles = (expandProps, collapseProps, height, width) => { if (expandProps?.direction === 'topToBottom' && collapseProps?.direction === 'bottomToTop') { return {}; } const commonStyles = { overflow: 'hidden', height, width }; return { entering: commonStyles, entered: commonStyles, exiting: commonStyles, exited: commonStyles, }; }; const getMergedStyles = (target, source) => { return { entering: { ...target.entering, ...source.entering, }, entered: { ...target.entered, ...source.entered, }, exiting: { ...target.exiting, ...source.exiting, }, exited: { ...target.exited, ...source.exited, }, }; }; export const getTransitionStyles = ({ width, height }, enterAnimation, exitAnimation) => { const transitionStyles = { fade: {}, move: {}, scale: {}, toggle: {}, }; if (enterAnimation?.fadeIn) { const props = getFadeProps(enterAnimation?.fadeIn); const styles = getFadeStyles(props, false); Object.assign(transitionStyles.fade, styles); } if (exitAnimation?.fadeOut) { const props = getFadeProps(exitAnimation?.fadeOut); const styles = getFadeStyles(props, true); Object.assign(transitionStyles.fade, styles); } if (enterAnimation?.moveIn) { const props = getMoveProps(enterAnimation?.moveIn); const styles = getMoveStyles(props, false); Object.assign(transitionStyles.move, styles); } if (exitAnimation?.moveOut) { const props = getMoveProps(exitAnimation?.moveOut); const styles = getMoveStyles(props, true); Object.assign(transitionStyles.move, styles); } const expandProps = enterAnimation?.expand ? getToggleProps(enterAnimation?.expand) : undefined; const collapseProps = exitAnimation?.collapse ? getToggleProps(exitAnimation?.collapse) : undefined; if (expandProps) { const styles = getToggleStyles(expandProps, false, height, width, collapseProps); Object.assign(transitionStyles.toggle, styles); } if (collapseProps) { const styles = getToggleStyles(collapseProps, true, height, width, expandProps); Object.assign(transitionStyles.toggle, styles); } if (enterAnimation?.scaleUp) { const props = getScaleProps(enterAnimation?.scaleUp); const styles = getScaleStyles(props, false); Object.assign(transitionStyles.scale, styles); } if (exitAnimation?.scaleDown) { const props = getScaleProps(exitAnimation?.scaleDown, true); const styles = getScaleStyles(props, true); Object.assign(transitionStyles.scale, styles); } if (!!expandProps || !!collapseProps) { const wrapperStyles = getToggleWrapperStyles(expandProps, collapseProps, height, width); const mergedStyles = getMergedStyles(transitionStyles.scale, wrapperStyles); Object.assign(transitionStyles.scale, mergedStyles); } return transitionStyles; }; const getTiming = (type, animation) => { if (!animation) { return 0; } const entry = Object.entries(animation).find(([key]) => key === type); if (entry) { const [_, value] = entry; if (typeof value !== 'boolean') { const delay = value.delay ? timingMap[value.delay] : 0; return timingMap[value.duration] + delay; } else if (value === true) { // Setting default duration to medium01 return timingMap.medium01; } } return 0; }; export const getTimeout = (enterAnimation, exitAnimation) => { const fadeEnter = getTiming('fadeIn', enterAnimation); const fadeExit = getTiming('fadeOut', exitAnimation); const moveEnter = getTiming('moveIn', enterAnimation); const moveExit = getTiming('moveOut', exitAnimation); const expand = getTiming('expand', enterAnimation); const collapse = getTiming('collapse', exitAnimation); const scaleUp = getTiming('scaleUp', enterAnimation); const scaleDown = getTiming('scaleDown', exitAnimation); return { enter: Math.max(fadeEnter, moveEnter, expand, scaleUp), exit: Math.max(fadeExit, moveExit, collapse, scaleDown), }; }; //# sourceMappingURL=utils.js.map