/* * This file implements a basic drawer control. */ import RX = require('reactxp'); interface MainPanelProps extends RX.CommonStyledProps { renderDrawer: () => JSX.Element; renderContent: () => JSX.Element; } // Duration (in ms) of drawer animation. const animationDuration = 250; // Amount that the content panel should "peek out" when the // drawer is open, measured in pixels. const contentPeekAmount = 100; const styles = { container: RX.Styles.createViewStyle({ flex: 1, alignSelf: 'stretch' }), drawerContainer: RX.Styles.createViewStyle({ position: 'absolute', marginLeft: contentPeekAmount, top: 0, right: 0, bottom: 0, left: 0 }), contentContainer: RX.Styles.createViewStyle({ position: 'absolute', top: 0, right: 0, bottom: 0, left: 0 }) }; class MainPanel extends RX.Component { private _drawerShown = false; private _viewWidth: number = 0; private _animation: RX.Types.Animated.CompositeAnimation; private _drawerTranslationValue: RX.Animated.Value; private _contentTranslationValue: RX.Animated.Value; private _animatedDrawerStyle: RX.Types.AnimatedViewStyleRuleSet; private _animatedContentStyle: RX.Types.AnimatedViewStyleRuleSet; toggleDrawer() { this._drawerShown = !this._drawerShown; if (this._animation) { this._animation.stop(); } this._animation = RX.Animated.parallel([ RX.Animated.timing(this._drawerTranslationValue, { toValue: this._drawerShown ? -contentPeekAmount : -this._viewWidth, easing: RX.Animated.Easing.InOut(), duration: animationDuration }), RX.Animated.timing(this._contentTranslationValue, { toValue: this._drawerShown ? this._viewWidth - contentPeekAmount : 0, easing: RX.Animated.Easing.InOut(), duration: animationDuration }) ]); this._animation.start(() => { this._animation = null; }); } constructor(props: MainPanelProps) { super(props); this._drawerTranslationValue = new RX.Animated.Value(0); this._animatedDrawerStyle = RX.Styles.createAnimatedViewStyle({ transform: [ { translateX: this._drawerTranslationValue } ] }); this._contentTranslationValue = new RX.Animated.Value(0); this._animatedContentStyle = RX.Styles.createAnimatedViewStyle({ transform: [ { translateX: this._contentTranslationValue } ] }); } private _onLayout = (layoutInfo: RX.Types.LayoutInfo) => { this._viewWidth = layoutInfo.width; // Stop any animation. if (this._animation) { this._animation.stop(); } // Immediately update animation values for new width. this._drawerTranslationValue.setValue(this._drawerShown ? -contentPeekAmount : -this._viewWidth); this._contentTranslationValue.setValue(this._drawerShown ? this._viewWidth - contentPeekAmount : 0); } render() { return ( { this.props.renderDrawer() } { this.props.renderContent() } ); } } export = MainPanel;