chowa
Version:
UI component library based on React
123 lines (122 loc) • 4.35 kB
JavaScript
/**
* @license chowa v1.1.3
*
* Copyright (c) Chowa Techonlogies Co.,Ltd.(http://www.chowa.cn).
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const React = require("react");
const ReactDom = require("react-dom");
const PropTypes = require("prop-types");
const classNames = require("classnames");
const utils_1 = require("../utils");
class Transition extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
selfVisible: props.visible,
inTransition: false,
wrapperWidth: 0,
wrapperHeight: 0
};
this.onTransitionFinishHandler = this.onTransitionFinishHandler.bind(this);
}
componentDidMount() {
this.wrapperEle = ReactDom.findDOMNode(this);
}
componentDidUpdate(preProps) {
if (this.props.visible !== preProps.visible && this.state.selfVisible !== this.props.visible) {
this.updateVisible(this.props.visible);
}
}
updateVisible(visible) {
const { onEnter, onLeave } = this.props;
let wrapperWidth;
let wrapperHeight;
if (!visible) {
const beforeHidenOffset = utils_1.doms.rect(this.wrapperEle);
wrapperWidth = beforeHidenOffset.width;
wrapperHeight = beforeHidenOffset.height;
}
this.setState({
selfVisible: visible,
wrapperWidth,
wrapperHeight,
inTransition: !visible
}, () => {
if (visible && utils_1.isExist(onEnter)) {
onEnter();
}
else if (!visible && utils_1.isExist(onLeave)) {
onLeave();
}
if (visible) {
const afterShowOffset = utils_1.doms.rect(this.wrapperEle);
wrapperWidth = afterShowOffset.width;
wrapperHeight = afterShowOffset.height;
this.setState({
wrapperWidth,
wrapperHeight,
inTransition: true
});
}
});
}
onTransitionFinishHandler(e) {
if (e.target !== e.currentTarget) {
return;
}
const { visible, onShow, onHide } = this.props;
this.setState({
inTransition: false
}, () => {
if (visible && utils_1.isExist(onShow)) {
onShow();
}
else if (!visible && utils_1.isExist(onHide)) {
onHide();
}
});
}
render() {
const { children, enter, appear, leave } = this.props;
const { selfVisible, inTransition, wrapperWidth, wrapperHeight } = this.state;
if (!utils_1.isReactElement(children)) {
throw new Error('Transition elements must be wrapped in an enclosing tag');
}
const child = children;
const transitionClass = classNames({
[appear]: inTransition,
[leave]: !selfVisible && inTransition,
[enter]: selfVisible && inTransition,
[child.props.className]: utils_1.isExist(child.props.className)
});
const transitionStyle = Object.assign(Object.assign(Object.assign({}, (utils_1.isExist(child.props.style) ? child.props.style : {})), (inTransition ? { width: wrapperWidth, height: wrapperHeight } : {})), (!selfVisible && !inTransition ? { display: 'none' } : {}));
return React.cloneElement(child, {
className: transitionClass,
style: transitionStyle,
onTransitionEnd: this.onTransitionFinishHandler,
onAnimationEnd: this.onTransitionFinishHandler
});
}
}
Transition.propTypes = {
children: PropTypes.node,
enter: PropTypes.string,
appear: PropTypes.string,
leave: PropTypes.string,
visible: PropTypes.bool.isRequired,
onEnter: PropTypes.func,
onLeave: PropTypes.func,
onShow: PropTypes.func,
onHide: PropTypes.func
};
Transition.defaultProps = {
enter: utils_1.preClass('fade-enter'),
appear: utils_1.preClass('default-appear'),
leave: utils_1.preClass('fade-leave')
};
exports.default = Transition;