Created
June 18, 2017 18:22
-
-
Save erictraut/d76393a4f3131e9ef62cc2c22ad6c251 to your computer and use it in GitHub Desktop.
ReactXPDrawer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This file demonstrates a basic ReactXP app. | |
*/ | |
import RX = require('reactxp'); | |
import ContentPanel from './ContentPanel'; | |
import DrawerControl = require('./DrawerControl'); | |
import DrawerPanel from './DrawerPanel'; | |
const _drawerRef = 'drawer'; | |
class App extends RX.Component<{}, null> { | |
render() { | |
return ( | |
<DrawerControl | |
ref={ _drawerRef } | |
renderContent={ () => { return <ContentPanel onToggleDrawer={ this._onToggleDrawer } /> } } | |
renderDrawer={ () => { return <DrawerPanel /> } } | |
/> | |
); | |
} | |
private _onToggleDrawer = () => { | |
let drawer = this.refs[_drawerRef] as DrawerControl; | |
if (drawer) { | |
drawer.toggleDrawer(); | |
} | |
} | |
} | |
export = App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RX = require('reactxp'); | |
interface ContentPanelProps { | |
onToggleDrawer: () => void; | |
} | |
const styles = { | |
container: RX.Styles.createViewStyle({ | |
flex: 1, | |
alignSelf: 'stretch', | |
backgroundColor: 'red' | |
}), | |
drawerText: RX.Styles.createTextStyle({ | |
fontSize: 16, | |
textAlign: 'center', | |
marginTop: 12, | |
color: 'black' | |
}), | |
scroll: RX.Styles.createScrollViewStyle({ | |
alignSelf: 'stretch', | |
backgroundColor: 'red', | |
flex: 1 | |
}) | |
}; | |
export default class ContentPanel extends RX.Component<ContentPanelProps, {}> { | |
render() { | |
return ( | |
<RX.View style={{ flex: 1, alignSelf: 'stretch' }}> | |
<RX.View style={{ paddingTop: 20, backgroundColor: 'blue' }}> | |
<RX.Button | |
style={{ margin: 2, borderRadius: 10, backgroundColor: 'black', | |
width: 20, height: 20, alignItems: 'center' }} | |
onPress={ this.props.onToggleDrawer } | |
> | |
<RX.Text style={{ color: 'white'}}> | |
H | |
</RX.Text> | |
</RX.Button> | |
</RX.View> | |
<RX.ScrollView style={ styles.scroll }> | |
<RX.View style={ styles.container }> | |
<RX.Text style={{ fontSize: 14 }}>1. This content panel has red background that should fill screen, but does not even with flex: 1 on container</RX.Text> | |
<RX.Text style={{ fontSize: 14 }}>2. This in turn affects the drawer height to not fill the entire available height</RX.Text> | |
<RX.Text style={{ fontSize: 14 }}>3. My animation does not seem to be smooth, especially on the first click</RX.Text> | |
</RX.View> | |
</RX.ScrollView> | |
</RX.View> | |
); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This file implements a basic drawer control. | |
*/ | |
import RX = require('reactxp'); | |
interface MainPanelProps extends RX.CommonStyledProps<RX.Types.ViewStyleRuleSet> { | |
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<MainPanelProps, null> { | |
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 ( | |
<RX.View style={ [styles.container, this.props.style] } onLayout={ this._onLayout }> | |
<RX.Animated.View style={ [styles.drawerContainer, this._animatedDrawerStyle] }> | |
{ this.props.renderDrawer() } | |
</RX.Animated.View> | |
<RX.Animated.View style={ [styles.contentContainer, this._animatedContentStyle] }> | |
{ this.props.renderContent() } | |
</RX.Animated.View> | |
</RX.View> | |
); | |
} | |
} | |
export = MainPanel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RX = require('reactxp'); | |
const styles = { | |
container: RX.Styles.createViewStyle({ | |
flex: 1, | |
alignSelf: 'stretch', | |
backgroundColor: 'green' | |
}), | |
drawerText: RX.Styles.createTextStyle({ | |
fontSize: 16, | |
textAlign: 'center', | |
marginTop: 12, | |
color: 'black' | |
}) | |
}; | |
export default class DrawerPanel extends RX.Component<{}, {}> { | |
render() { | |
return ( | |
<RX.View style={ styles.container }> | |
<RX.Text style={ styles.drawerText }> | |
Here is a drawer | |
</RX.Text> | |
</RX.View> | |
); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment