diff --git a/README.md b/README.md index a324daf..3ad81ae 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ class ContentView extends React.Component { render() { return ( + + Open menu + Welcome to React Native! @@ -38,12 +41,26 @@ class ContentView extends React.Component { } class Application extends React.Component { + state = { + isOpen: false, + }; + + closeMenu() { + this.setState({ isOpen: false }); + } + + toggleMenu() { + this.setState({ isOpen: !this.state.isOpen }); + } + render() { - const menu = ; + const menu = ; return ( - - + this.closeMenu()}> + this.toggleMenu()}/> ); } @@ -58,9 +75,9 @@ class Application extends React.Component { - `edgeHitWidth` (Number) - Edge distance on content view to open side menu, defaults to 60 - `toleranceX` (Number) - X axis tolerance - `toleranceY` (Number) - Y axis tolerance -- `disableGestures` (Bool) - Disable whether the menu can be opened with gestures or not -- `onStartShouldSetResponderCapture` (Function) - Function that accepts event as an argument and specify if side-menu should react on the touch or not. Check https://facebook.github.io/react-native/docs/gesture-responder-system.html for more details -- `onChange` (Function) - Callback on menu open/close. Is passed `isOpen` as an argument +- `onSwipe` (Function) - Function that handles gestures, receives boolean argument indicating whether menu should be opened or not based on the drag. When not defined, gestures are disabled +- `onStartShouldSetResponderCapture` (Function) - Function that accepts event as an argument and specify if side-menu should react on the touch or not. Check https://facebook.github.io/react-native/docs/gesture-responder-system.html for more details. Typically you would like to set `isOpen` value to the passed argument (see examples/Basic.js) +- `onContentPress` (Function) - Function that handles content press when menu is opened. Typically you would set isOpen to false inside it (see examples/Basic.js). When not present, content is accessible when menu is opened and there's no `touchToClose` behavior - `menuPosition` (String) - either 'left' or 'right', defaults to 'left' - `animationFunction` (Function -> Object) - Function that accept 2 arguments (prop, value) and return an object: - `prop` you should use at the place you specify parameter to animate diff --git a/examples/Basic/Basic.js b/examples/Basic/Basic.js index 0fc393c..1a1fa07 100644 --- a/examples/Basic/Basic.js +++ b/examples/Basic/Basic.js @@ -78,7 +78,8 @@ module.exports = class Basic extends Component { } isOpen={this.state.isOpen} - onChange={(isOpen) => this.updateMenuState(isOpen)}> + onSwipe={isOpen => this.updateMenuState(isOpen)} + onContentPress={() => this.toggle()}> Welcome to React Native! diff --git a/index.js b/index.js index 2be5826..52e6c51 100644 --- a/index.js +++ b/index.js @@ -37,7 +37,6 @@ class SideMenu extends Component { * @type {Number} */ this.prevLeft = 0; - this.isOpen = props.isOpen; this.state = { width: deviceScreen.width, @@ -61,24 +60,18 @@ class SideMenu extends Component { }); } - componentWillReceiveProps(props) { - if (this.isOpen !== props.isOpen) { - this.openMenu(props.isOpen); - } + componentWillReceiveProps(newProps) { + const { isOpen, hiddenMenuOffset, openMenuOffset, } = newProps; + this.moveLeft(isOpen ? openMenuOffset : hiddenMenuOffset); } /** - * Determines if gestures are enabled, based off of disableGestures prop + * Determines if gestures are enabled, based off the presence of gesture handler * @return {Boolean} */ - gesturesAreEnabled() { - let { disableGestures, } = this.props; - - if (typeof disableGestures === 'function') { - return !disableGestures(); - } - - return !disableGestures; + areGesturesEnabled() { + const { onSwipe, } = this.props; + return !!this.props.onSwipe; } /** @@ -86,13 +79,13 @@ class SideMenu extends Component { * @return {Boolean} */ handleMoveShouldSetPanResponder(e: Object, gestureState: Object) { - if (this.gesturesAreEnabled()) { + if (this.areGesturesEnabled()) { const x = Math.round(Math.abs(gestureState.dx)); const y = Math.round(Math.abs(gestureState.dy)); const touchMoved = x > this.props.toleranceX && y < this.props.toleranceY; - if (this.isOpen) { + if (this.props.isOpen) { return touchMoved; } @@ -129,7 +122,7 @@ class SideMenu extends Component { const offsetLeft = this.menuPositionMultiplier() * (this.state.left.__getValue() + gestureState.dx); - this.openMenu(shouldOpenMenu(offsetLeft)); + this.props.onSwipe(shouldOpenMenu(offsetLeft)); } /** @@ -150,19 +143,6 @@ class SideMenu extends Component { this.prevLeft = newOffset; } - /** - * Toggle menu - * @return {Void} - */ - openMenu(isOpen) { - const { hiddenMenuOffset, openMenuOffset, } = this.props; - this.moveLeft(isOpen ? openMenuOffset : hiddenMenuOffset); - this.isOpen = isOpen; - - this.forceUpdate(); - this.props.onChange(isOpen); - } - /** * Get content view. This view will be rendered over menu * @return {React.Component} @@ -170,9 +150,9 @@ class SideMenu extends Component { getContentView() { let overlay = null; - if (this.isOpen) { + if (this.props.isOpen && this.props.onContentPress) { overlay = ( - this.openMenu(false)}> + this.props.onContentPress()}> ); @@ -220,10 +200,10 @@ SideMenu.propTypes = { toleranceX: React.PropTypes.number, toleranceY: React.PropTypes.number, menuPosition: React.PropTypes.oneOf(['left', 'right', ]), - onChange: React.PropTypes.func, + onContentPress: React.PropTypes.func, openMenuOffset: React.PropTypes.number, hiddenMenuOffset: React.PropTypes.number, - disableGestures: React.PropTypes.oneOfType([React.PropTypes.func, React.PropTypes.bool, ]), + onSwipe: React.PropTypes.func, animationFunction: React.PropTypes.func, onStartShouldSetResponderCapture: React.PropTypes.func, isOpen: React.PropTypes.bool, @@ -236,7 +216,6 @@ SideMenu.defaultProps = { openMenuOffset: deviceScreen.width * 2 / 3, hiddenMenuOffset: 0, onStartShouldSetResponderCapture: () => true, - onChange: () => {}, animationStyle: (value) => { return { transform: [{