From 14dff141c6bc27e495e9b3c2a46f39e1c62f7cb6 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 15:57:30 +0100 Subject: [PATCH 01/10] Initial commit --- examples/Basic/Basic.js | 11 ++++++++-- index.js | 46 ++++++++++++----------------------------- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/examples/Basic/Basic.js b/examples/Basic/Basic.js index 0fc393c..0c284d3 100644 --- a/examples/Basic/Basic.js +++ b/examples/Basic/Basic.js @@ -69,7 +69,13 @@ module.exports = class Basic extends Component { }); } - updateMenuState(isOpen) { + toggleMenu() { + this.setState({ + isOpen: !this.state.isOpen, + }); + } + + handleMenuSwipe(isOpen) { this.setState({ isOpen, }); } @@ -78,7 +84,8 @@ module.exports = class Basic extends Component { } isOpen={this.state.isOpen} - onChange={(isOpen) => this.updateMenuState(isOpen)}> + onSwipe={isOpen => this.handleMenuSwipe(isOpen)} + onBackDropPressed={() => this.toggleMenu()}> Welcome to React Native! diff --git a/index.js b/index.js index 2be5826..b60addf 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; + const { onSwipe, } = this.props; + return !!this.props.onSwipe; } /** @@ -92,7 +85,7 @@ class SideMenu extends Component { 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) { overlay = ( - this.openMenu(false)}> + this.props.onBackDropPressed()}> ); @@ -220,10 +200,10 @@ SideMenu.propTypes = { toleranceX: React.PropTypes.number, toleranceY: React.PropTypes.number, menuPosition: React.PropTypes.oneOf(['left', 'right', ]), - onChange: React.PropTypes.func, + onBackDropPressed: 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,7 @@ SideMenu.defaultProps = { openMenuOffset: deviceScreen.width * 2 / 3, hiddenMenuOffset: 0, onStartShouldSetResponderCapture: () => true, - onChange: () => {}, + onBackDropPressed: () => {}, animationStyle: (value) => { return { transform: [{ From 8f93442fc6c7813b08fcdd06328f12714846c91c Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:01:03 +0100 Subject: [PATCH 02/10] Use better name --- examples/Basic/Basic.js | 2 +- index.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Basic/Basic.js b/examples/Basic/Basic.js index 0c284d3..b77f7af 100644 --- a/examples/Basic/Basic.js +++ b/examples/Basic/Basic.js @@ -85,7 +85,7 @@ module.exports = class Basic extends Component { menu={} isOpen={this.state.isOpen} onSwipe={isOpen => this.handleMenuSwipe(isOpen)} - onBackDropPressed={() => this.toggleMenu()}> + onContentPress={() => this.toggleMenu()}> Welcome to React Native! diff --git a/index.js b/index.js index b60addf..3f823cc 100644 --- a/index.js +++ b/index.js @@ -152,7 +152,7 @@ class SideMenu extends Component { if (this.props.isOpen) { overlay = ( - this.props.onBackDropPressed()}> + this.props.onContentPress()}> ); @@ -200,7 +200,7 @@ SideMenu.propTypes = { toleranceX: React.PropTypes.number, toleranceY: React.PropTypes.number, menuPosition: React.PropTypes.oneOf(['left', 'right', ]), - onBackDropPressed: React.PropTypes.func, + onContentPress: React.PropTypes.func, openMenuOffset: React.PropTypes.number, hiddenMenuOffset: React.PropTypes.number, onSwipe: React.PropTypes.func, @@ -216,7 +216,7 @@ SideMenu.defaultProps = { openMenuOffset: deviceScreen.width * 2 / 3, hiddenMenuOffset: 0, onStartShouldSetResponderCapture: () => true, - onBackDropPressed: () => {}, + onContentPress: () => {}, animationStyle: (value) => { return { transform: [{ From d8509d7b5a5ccc1bf411d4ab6508f6d9fd6e7280 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:04:07 +0100 Subject: [PATCH 03/10] Use the same method from Example --- examples/Basic/Basic.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/examples/Basic/Basic.js b/examples/Basic/Basic.js index b77f7af..13d516e 100644 --- a/examples/Basic/Basic.js +++ b/examples/Basic/Basic.js @@ -69,12 +69,6 @@ module.exports = class Basic extends Component { }); } - toggleMenu() { - this.setState({ - isOpen: !this.state.isOpen, - }); - } - handleMenuSwipe(isOpen) { this.setState({ isOpen, }); } @@ -85,7 +79,7 @@ module.exports = class Basic extends Component { menu={} isOpen={this.state.isOpen} onSwipe={isOpen => this.handleMenuSwipe(isOpen)} - onContentPress={() => this.toggleMenu()}> + onContentPress={() => this.toggle()}> Welcome to React Native! From b90e0ff73350c7e2628cb489bda2c888090e9025 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:04:48 +0100 Subject: [PATCH 04/10] Bring back old name --- examples/Basic/Basic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Basic/Basic.js b/examples/Basic/Basic.js index 13d516e..1a1fa07 100644 --- a/examples/Basic/Basic.js +++ b/examples/Basic/Basic.js @@ -69,7 +69,7 @@ module.exports = class Basic extends Component { }); } - handleMenuSwipe(isOpen) { + updateMenuState(isOpen) { this.setState({ isOpen, }); } @@ -78,7 +78,7 @@ module.exports = class Basic extends Component { } isOpen={this.state.isOpen} - onSwipe={isOpen => this.handleMenuSwipe(isOpen)} + onSwipe={isOpen => this.updateMenuState(isOpen)} onContentPress={() => this.toggle()}> From 613e9dc5c1dada136bca9aa406eee5b7e919453a Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:06:09 +0100 Subject: [PATCH 05/10] contentPress is required for the menu to close --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index 3f823cc..cd97800 100644 --- a/index.js +++ b/index.js @@ -200,7 +200,7 @@ SideMenu.propTypes = { toleranceX: React.PropTypes.number, toleranceY: React.PropTypes.number, menuPosition: React.PropTypes.oneOf(['left', 'right', ]), - onContentPress: React.PropTypes.func, + onContentPress: React.PropTypes.func.isRequired, openMenuOffset: React.PropTypes.number, hiddenMenuOffset: React.PropTypes.number, onSwipe: React.PropTypes.func, @@ -216,7 +216,6 @@ SideMenu.defaultProps = { openMenuOffset: deviceScreen.width * 2 / 3, hiddenMenuOffset: 0, onStartShouldSetResponderCapture: () => true, - onContentPress: () => {}, animationStyle: (value) => { return { transform: [{ From 926596657ee824da68273850bd8bf76ec5acd07c Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:14:08 +0100 Subject: [PATCH 06/10] Make overlay optional --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index cd97800..6321f6d 100644 --- a/index.js +++ b/index.js @@ -150,7 +150,7 @@ class SideMenu extends Component { getContentView() { let overlay = null; - if (this.props.isOpen) { + if (this.props.isOpen && this.props.onContentPress) { overlay = ( this.props.onContentPress()}> @@ -200,7 +200,7 @@ SideMenu.propTypes = { toleranceX: React.PropTypes.number, toleranceY: React.PropTypes.number, menuPosition: React.PropTypes.oneOf(['left', 'right', ]), - onContentPress: React.PropTypes.func.isRequired, + onContentPress: React.PropTypes.func, openMenuOffset: React.PropTypes.number, hiddenMenuOffset: React.PropTypes.number, onSwipe: React.PropTypes.func, From e3e6903ffe51bf2cb76b8826b26f098f62132dbc Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:19:21 +0100 Subject: [PATCH 07/10] Use proper english form --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 6321f6d..52e6c51 100644 --- a/index.js +++ b/index.js @@ -69,7 +69,7 @@ class SideMenu extends Component { * Determines if gestures are enabled, based off the presence of gesture handler * @return {Boolean} */ - gesturesAreEnabled() { + areGesturesEnabled() { const { onSwipe, } = this.props; return !!this.props.onSwipe; } @@ -79,7 +79,7 @@ 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)); From a659f110ac781b441d1c43ab9e3bb51d7fb54307 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:24:40 +0100 Subject: [PATCH 08/10] Update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a324daf..a233adb 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,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 +- `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 -- `onChange` (Function) - Callback on menu open/close. Is passed `isOpen` as an argument +- `onContentPress` (Function) - Function that handles content press. 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 From 0ad70cfec86d6f9b36a0813972c3cd6f9dd6c8ce Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:25:48 +0100 Subject: [PATCH 09/10] Update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a233adb..02c6b0a 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,8 @@ class Application extends React.Component { - `toleranceX` (Number) - X axis tolerance - `toleranceY` (Number) - Y axis tolerance - `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 -- `onContentPress` (Function) - Function that handles content press. 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 +- `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 From d9dccf232c3d50678c41e5f24f207606eb67b613 Mon Sep 17 00:00:00 2001 From: Mike Grabowski Date: Fri, 8 Jan 2016 16:28:32 +0100 Subject: [PATCH 10/10] Update readme example --- README.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 02c6b0a..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()}/> ); }