2017-07-22 21:27:38 +05:30
|
|
|
// @flow
|
|
|
|
import React, { Component } from 'react';
|
|
|
|
|
|
|
|
import { Motion, spring } from 'react-motion';
|
|
|
|
import MeasureHeight from 'components/MeasureHeight';
|
|
|
|
|
2017-11-19 23:46:15 +05:30
|
|
|
import styles from './slide-motion.scss';
|
2017-07-22 21:27:38 +05:30
|
|
|
|
2017-11-19 23:46:15 +05:30
|
|
|
export default class SlideMotion extends Component<{
|
2017-08-23 02:01:41 +05:30
|
|
|
activeStep: number,
|
|
|
|
children: *
|
|
|
|
}, {
|
|
|
|
version: number
|
|
|
|
}> {
|
2017-07-22 21:27:38 +05:30
|
|
|
state: {
|
|
|
|
version: number
|
|
|
|
} = {
|
|
|
|
version: 0
|
|
|
|
};
|
|
|
|
|
|
|
|
isHeightMeasured: bool;
|
|
|
|
|
|
|
|
componentWillReceiveProps() {
|
|
|
|
// mark this view as dirty to re-measure height
|
|
|
|
this.setState({
|
|
|
|
version: this.state.version + 1
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
activeStep,
|
|
|
|
children
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
const {version} = this.state;
|
|
|
|
|
|
|
|
const activeStepHeight = this.state[`step${activeStep}Height`] || 0;
|
|
|
|
|
|
|
|
// a hack to disable height animation on first render
|
|
|
|
const isHeightMeasured = this.isHeightMeasured;
|
|
|
|
this.isHeightMeasured = isHeightMeasured || activeStepHeight > 0;
|
|
|
|
|
|
|
|
const motionStyle = {
|
|
|
|
transform: spring(activeStep * 100, {stiffness: 500, damping: 50, precision: 0.5}),
|
|
|
|
height: isHeightMeasured ? spring(activeStepHeight, {stiffness: 500, damping: 20, precision: 0.5}) : activeStepHeight
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Motion style={motionStyle}>
|
|
|
|
{(interpolatingStyle: {height: number, transform: string}) => (
|
|
|
|
<div style={{
|
|
|
|
overflow: 'hidden',
|
|
|
|
height: `${interpolatingStyle.height}px`
|
|
|
|
}}>
|
|
|
|
<div className={styles.container} style={{
|
|
|
|
WebkitTransform: `translateX(-${interpolatingStyle.transform}%)`,
|
|
|
|
transform: `translateX(-${interpolatingStyle.transform}%)`
|
|
|
|
}}>
|
|
|
|
{React.Children.map(children, (child, index) => (
|
|
|
|
<MeasureHeight
|
|
|
|
className={styles.item}
|
|
|
|
onMeasure={this.onStepMeasure(index)}
|
|
|
|
state={version}
|
|
|
|
key={index}
|
|
|
|
>
|
|
|
|
{child}
|
|
|
|
</MeasureHeight>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</Motion>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
onStepMeasure(step: number) {
|
|
|
|
return (height: number) => this.setState({
|
|
|
|
[`step${step}Height`]: height
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|