mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-04 00:37:08 +00:00
179 lines
5.3 KiB
JavaScript
179 lines
5.3 KiB
JavaScript
import React, { Component, Children } from 'react';
|
||
import PropTypes from 'prop-types';
|
||
import { TransitionGroup } from 'react-transition-group';
|
||
import AnimateChild from './child';
|
||
|
||
const noop = () => {};
|
||
const FirstChild = props => {
|
||
const childrenArray = React.Children.toArray(props.children);
|
||
return childrenArray[0] || null;
|
||
};
|
||
|
||
/**
|
||
* Animate
|
||
*/
|
||
class Animate extends Component {
|
||
static propTypes = {
|
||
/**
|
||
* 动画 className
|
||
*/
|
||
animation: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||
/**
|
||
* 子元素第一次挂载时是否执行动画
|
||
*/
|
||
animationAppear: PropTypes.bool,
|
||
/**
|
||
* 包裹子元素的标签
|
||
*/
|
||
component: PropTypes.any,
|
||
/**
|
||
* 是否只有单个子元素,如果有多个子元素,请设置为 false
|
||
*/
|
||
singleMode: PropTypes.bool,
|
||
/**
|
||
* 子元素
|
||
*/
|
||
children: PropTypes.oneOfType([
|
||
PropTypes.element,
|
||
PropTypes.arrayOf(PropTypes.element),
|
||
]),
|
||
/**
|
||
* 执行第一次挂载动画前触发的回调函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
beforeAppear: PropTypes.func,
|
||
/**
|
||
* 执行第一次挂载动画,添加 xxx-appear-active 类名后触发的回调函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
onAppear: PropTypes.func,
|
||
/**
|
||
* 执行完第一次挂载动画后触发的函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
afterAppear: PropTypes.func,
|
||
/**
|
||
* 执行进场动画前触发的回调函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
beforeEnter: PropTypes.func,
|
||
/**
|
||
* 执行进场动画,添加 xxx-enter-active 类名后触发的回调函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
onEnter: PropTypes.func,
|
||
/**
|
||
* 执行完进场动画后触发的回调函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
afterEnter: PropTypes.func,
|
||
/**
|
||
* 执行离场动画前触发的回调函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
beforeLeave: PropTypes.func,
|
||
/**
|
||
* 执行离场动画,添加 xxx-leave-active 类名后触发的回调函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
onLeave: PropTypes.func,
|
||
/**
|
||
* 执行完离场动画后触发的回调函数
|
||
* @param {HTMLElement} node 执行动画的 dom 元素
|
||
*/
|
||
afterLeave: PropTypes.func,
|
||
};
|
||
|
||
static defaultProps = {
|
||
animationAppear: true,
|
||
component: 'div',
|
||
singleMode: true,
|
||
beforeAppear: noop,
|
||
onAppear: noop,
|
||
afterAppear: noop,
|
||
beforeEnter: noop,
|
||
onEnter: noop,
|
||
afterEnter: noop,
|
||
beforeLeave: noop,
|
||
onLeave: noop,
|
||
afterLeave: noop,
|
||
};
|
||
|
||
normalizeNames(names) {
|
||
if (typeof names === 'string') {
|
||
return {
|
||
appear: `${names}-appear`,
|
||
appearActive: `${names}-appear-active`,
|
||
enter: `${names}-enter`,
|
||
enterActive: `${names}-enter-active`,
|
||
leave: `${names}-leave`,
|
||
leaveActive: `${names}-leave-active`,
|
||
};
|
||
}
|
||
if (typeof names === 'object') {
|
||
return {
|
||
appear: names.appear,
|
||
appearActive: `${names.appear}-active`,
|
||
enter: `${names.enter}`,
|
||
enterActive: `${names.enter}-active`,
|
||
leave: `${names.leave}`,
|
||
leaveActive: `${names.leave}-active`,
|
||
};
|
||
}
|
||
}
|
||
|
||
render() {
|
||
/* eslint-disable no-unused-vars */
|
||
const {
|
||
animation,
|
||
children,
|
||
animationAppear,
|
||
singleMode,
|
||
component,
|
||
beforeAppear,
|
||
onAppear,
|
||
afterAppear,
|
||
beforeEnter,
|
||
onEnter,
|
||
afterEnter,
|
||
beforeLeave,
|
||
onLeave,
|
||
afterLeave,
|
||
...others
|
||
} = this.props;
|
||
/* eslint-enable no-unused-vars */
|
||
|
||
const animateChildren = Children.map(children, child => {
|
||
return (
|
||
<AnimateChild
|
||
key={child.key}
|
||
names={this.normalizeNames(animation)}
|
||
onAppear={beforeAppear}
|
||
onAppearing={onAppear}
|
||
onAppeared={afterAppear}
|
||
onEnter={beforeEnter}
|
||
onEntering={onEnter}
|
||
onEntered={afterEnter}
|
||
onExit={beforeLeave}
|
||
onExiting={onLeave}
|
||
onExited={afterLeave}
|
||
>
|
||
{child}
|
||
</AnimateChild>
|
||
);
|
||
});
|
||
|
||
return (
|
||
<TransitionGroup
|
||
appear={animationAppear}
|
||
component={singleMode ? FirstChild : component}
|
||
{...others}
|
||
>
|
||
{animateChildren}
|
||
</TransitionGroup>
|
||
);
|
||
}
|
||
}
|
||
|
||
export default Animate;
|