diff --git a/README.md b/README.md index 18e45958..ba0461f2 100644 --- a/README.md +++ b/README.md @@ -92,17 +92,18 @@ There's a complete and functional example at the `example` folder, with more tho The props below are used to configure the drawer and are to be used in RNN `passProps:`. Any aditional props will be passed to your custom drawer component. -| Prop | Type | Optional | Default | Description | -| ------------------- | ------------- | --------- | ------- | --------------------------------------------------------------------------------------- | -| animationOpenTime | float | Yes | 300 | Time in milliseconds to execute the drawer opening animation. | -| animationCloseTime | float | Yes | 300 | Time in milliseconds to execute the drawer closing animation. | -| direction | string | Yes | left | Direction to open the collage, one of: ["left", "right", "top", "bottom"]. | -| dismissWhenTouchOutside | bool | Yes | true | Should the drawer be dismissed when a click is registered outside? | -| fadeOpacity | number | Yes | 0.6 | Opacity of the screen outside the drawer. | -| drawerScreenWidth | number | Yes | 0.8 | 0 - 1, width of drawer in relation to the screen. | -| drawerScreenHeight | number | Yes | 1 | 0 - 1, height of drawer in relation to the screen. | -| disableDragging | boolean | Yes | false | Whether you want to disable dragging of the drawer. Useful if you have ScrollView inside the drawer (addresses #62).| -| disableSwiping | boolean | Yes | false | Whether you want to disable swiping gesture. Use it only in pair with disableDragging.| +| Prop | Type | Optional | Default | Description | +| ---------------------------- | ------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| animationOpenTime | float | Yes | 300 | Time in milliseconds to execute the drawer opening animation. | +| animationCloseTime | float | Yes | 300 | Time in milliseconds to execute the drawer closing animation. | +| direction | string | Yes | left | Direction to open the collage, one of: ["left", "right", "top", "bottom"]. | +| dismissWhenTouchOutside | bool | Yes | true | Should the drawer be dismissed when a click is registered outside? | +| fadeOpacity | number | Yes | 0.6 | Opacity of the screen outside the drawer. | +| drawerScreenWidth | number/string | Yes | 80% | Width of drawer on portrait orientation. Pass a string containing '%' (e.g. "80%") for setting the width in relation to the screen or a number for absolute width (e.g. 300) | +| drawerScreenWidthOnLandscape | number/string | Yes | 30% | Width of drawer on landscape orientation. Pass a string containing '%' (e.g. "80%") for setting the width in relation to the screen or a number for absolute width (e.g. 300) | +| drawerScreenHeight | number/string | Yes | 100% | Height of drawer. Pass a string containing '%' (e.g. "30%") for setting the height in relation to the screen or a number for absolute height (e.g. 300) +| disableDragging | boolean | Yes | false | Whether you want to disable dragging of the drawer. Useful if you have ScrollView inside the drawer (addresses #62).| +| disableSwiping | boolean | Yes | false | Whether you want to disable swiping gesture. Use it only in pair with disableDragging. | ## SideMenuView diff --git a/lib/RNNDrawer.d.ts b/lib/RNNDrawer.d.ts index c9b67016..c1a21019 100644 --- a/lib/RNNDrawer.d.ts +++ b/lib/RNNDrawer.d.ts @@ -17,7 +17,7 @@ declare interface RNNDrawerOptions { * If not provided, drawer might have * a weird effect when closing */ - direction: DirectionType; + direction?: DirectionType; /** * Time in milliseconds to execute the drawer opening animation */ @@ -35,13 +35,22 @@ declare interface RNNDrawerOptions { */ fadeOpacity?: number; /** - * Width of drawer in relation to the screen (0 to 1) + * Width of drawer on portrait orientation. Pass a string containing '%' (e.g. "80%") + * for setting the width in relation to the screen or a number for absolute width (e.g. 300) */ - drawerScreenWidth?: number; + drawerScreenWidth?: number | string; /** - * Height of drawer in relation to the screen (0 to 1) + * Width of drawer on landscape orientation. Pass a string containing '%' (e.g. "80%") + * for setting the width in relation to the screen or a number for absolute width (e.g. 300) */ - drawerScreenHeight?: number; + drawerScreenWidthOnLandscape?: number | string; + /** + * Height of drawer. Pass a string containing '%' (e.g. "30%") + * for setting the height in relation to the screen or a number for absolute height (e.g. 300) + */ + drawerScreenHeight?: number | string; + disableDragging?: boolean; + disableSwiping?: boolean; } export declare enum DirectionType { left = "left", diff --git a/lib/RNNDrawer.js b/lib/RNNDrawer.js index 970139e6..a94aae19 100644 --- a/lib/RNNDrawer.js +++ b/lib/RNNDrawer.js @@ -35,7 +35,6 @@ var react_native_1 = require("react-native"); var react_native_navigation_1 = require("react-native-navigation"); /* Utils - Project Utilities */ var events_1 = require("./events"); -var MaxWidthOnLandscapeMode = 300; var DirectionType; (function (DirectionType) { DirectionType["left"] = "left"; @@ -64,18 +63,36 @@ var RNNDrawer = /** @class */ (function () { */ function WrappedDrawer(props) { var _this = _super.call(this, props) || this; + _this.panningStartedPoint = { moveX: 0, moveY: 0 }; + _this.startedFromSideMenu = false; + _this.onOrientationChange = function (_a) { + var window = _a.window; + var screenHeight = window.height; + _this.setState({ screenHeight: screenHeight }); + // Apply correct position if opened from right + if (_this.props.direction === 'right') { + // Calculates the position of the drawer from the left side of the screen + var alignedMovementValue = window.width - _this.drawerWidth; + _this.state.sideMenuOpenValue.setValue(alignedMovementValue); + } + }; _this.screenWidth = react_native_1.Dimensions.get('window').width; _this.screenHeight = react_native_1.Dimensions.get('window').height; _this.panResponder = react_native_1.PanResponder.create({ onStartShouldSetPanResponder: function (_evt, _gestureState) { return false; }, onStartShouldSetPanResponderCapture: function (_evt, _gestureState) { return false; }, onMoveShouldSetPanResponder: function (_evt, _gestureState) { - var dx = _gestureState.dx; - return Math.abs(dx) > 5; + var dx = _gestureState.dx, dy = _gestureState.dy; + if (_this.props.direction === DirectionType.left || + _this.props.direction === DirectionType.right) + return Math.abs(dx) > 5; + else + return Math.abs(dy) > 5; }, onMoveShouldSetPanResponderCapture: function (_evt, _gestureState) { return false; }, onPanResponderGrant: function (_evt, _gestureState) { - events_1.dispatch('SWIPE_START'); + var moveX = _gestureState.moveX, moveY = _gestureState.moveY; + events_1.dispatch('SWIPE_START', { moveX: moveX, moveY: moveY }); }, onPanResponderRelease: function (_evt, gestureState) { var vx = gestureState.vx; @@ -85,9 +102,9 @@ var RNNDrawer = /** @class */ (function () { onPanResponderTerminationRequest: function (_evt, _gestureState) { return false; }, onShouldBlockNativeResponder: function (_evt, _gestureState) { return false; }, onPanResponderMove: function (_evt, _gestureState) { - var moveX = _gestureState.moveX; + var moveX = _gestureState.moveX, moveY = _gestureState.moveY; var direction = _this.props.direction || 'left'; - events_1.dispatch('SWIPE_MOVE', { value: moveX, direction: direction }); + events_1.dispatch('SWIPE_MOVE', { value: { moveX: moveX, moveY: moveY }, direction: direction }); }, }); /* @@ -108,25 +125,25 @@ var RNNDrawer = /** @class */ (function () { return value; }; /** Component Variables */ - _this.drawerWidth = _this.isLandscape() - ? MaxWidthOnLandscapeMode - : _resolveDrawerSize(props.drawerScreenWidth, _this.screenWidth); + _this.drawerWidth = _resolveDrawerSize(_this.isLandscape() + ? props.drawerScreenWidthOnLandscape + : props.drawerScreenWidth, _this.screenWidth); _this.drawerHeight = _resolveDrawerSize(props.drawerScreenHeight, _this.screenHeight); _this.drawerOpenedValues = { left: 0, right: _this.screenWidth - _this.drawerWidth, - top: 0, + top: _this.drawerHeight - _this.screenHeight, bottom: _this.screenHeight - _this.drawerHeight, }; - var initialValues = { + _this.initialValues = { left: -_this.drawerWidth, right: _this.screenWidth, - top: -_this.drawerHeight, + top: -_this.screenHeight, bottom: _this.screenHeight, }; /** Component State */ _this.state = { - sideMenuOpenValue: new react_native_1.Animated.Value(initialValues[props.direction]), + sideMenuOpenValue: new react_native_1.Animated.Value(_this.initialValues[props.direction]), sideMenuOverlayOpacity: new react_native_1.Animated.Value(0), sideMenuSwipingStarted: false, sideMenuIsDismissing: false, @@ -155,18 +172,21 @@ var RNNDrawer = /** @class */ (function () { */ WrappedDrawer.prototype.componentDidMount = function () { /** Props */ - var _a = this.props, direction = _a.direction, fadeOpacity = _a.fadeOpacity; + var _a = this.props, direction = _a.direction, fadeOpacity = _a.fadeOpacity, animateDrawerExpanding = _a.animateDrawerExpanding; + if (typeof animateDrawerExpanding !== 'undefined' && + !animateDrawerExpanding) + this.startedFromSideMenu = true; // Animate side menu open this.animatedDrawer = react_native_1.Animated.timing(this.state.sideMenuOpenValue, { toValue: this.drawerOpenedValues[direction], duration: this.props.animationOpenTime, - useNativeDriver: false, + useNativeDriver: true, }); // Animate outside side menu opacity this.animatedOpacity = react_native_1.Animated.timing(this.state.sideMenuOverlayOpacity, { toValue: fadeOpacity, duration: this.props.animationOpenTime, - useNativeDriver: false, + useNativeDriver: true, }); }; /** @@ -177,7 +197,8 @@ var RNNDrawer = /** @class */ (function () { WrappedDrawer.prototype.componentDidAppear = function () { this.registerListeners(); // If there has been no Swiping, and this component appears, then just start the open animations - if (!this.state.sideMenuSwipingStarted) { + if (!this.state.sideMenuSwipingStarted && + this.props.animateDrawerExpanding) { this.animatedDrawer.start(); this.animatedOpacity.start(); } @@ -199,19 +220,11 @@ var RNNDrawer = /** @class */ (function () { /** Props */ var _a = this.props, direction = _a.direction, fadeOpacity = _a.fadeOpacity; // Adapt the drawer's size on orientation change - react_native_1.Dimensions.addEventListener('change', function (_a) { - var window = _a.window; - var screenHeight = window.height; - _this.setState({ screenHeight: screenHeight }); - // Apply correct position if opened from right - if (_this.props.direction === 'right') { - // Calculates the position of the drawer from the left side of the screen - var alignedMovementValue = window.width - _this.drawerWidth; - _this.state.sideMenuOpenValue.setValue(alignedMovementValue); - } - }); + react_native_1.Dimensions.addEventListener('change', this.onOrientationChange); // Executes when the side of the screen interaction starts - this.unsubscribeSwipeStart = events_1.listen('SWIPE_START', function () { + this.unsubscribeSwipeStart = events_1.listen('SWIPE_START', function (value) { + _this.panningStartedPoint.moveX = value.moveX; + _this.panningStartedPoint.moveY = value.moveY; _this.setState({ sideMenuSwipingStarted: true, }); @@ -219,43 +232,75 @@ var RNNDrawer = /** @class */ (function () { // Executes when the side of the screen is interacted with this.unsubscribeSwipeMove = events_1.listen('SWIPE_MOVE', function (_a) { var value = _a.value, swipeDirection = _a.direction; - if (swipeDirection === 'left') { - // Calculates the position of the drawer from the left side of the screen - var alignedMovementValue = value - _this.drawerWidth; - // Calculates the percetage 0 - 100 of which the drawer is open - var openedPercentage = Math.abs((Math.abs(alignedMovementValue) / _this.drawerWidth) * 100 - 100); - // Calculates the opacity to set of the screen based on the percentage the drawer is open - var normalizedOpacity = Math.min(openedPercentage / 100, fadeOpacity); - // Does allow the drawer to go further than the maximum width - if (_this.drawerOpenedValues[direction] > alignedMovementValue) { - // Sets the animation values, we use this so we can resume animation from any point - _this.state.sideMenuOpenValue.setValue(alignedMovementValue); - _this.state.sideMenuOverlayOpacity.setValue(normalizedOpacity); + // Cover special case when we are swiping from the edge of the screen + if (_this.startedFromSideMenu) { + if (direction === 'left' && value.moveX < _this.drawerWidth) { + _this.state.sideMenuOpenValue.setValue(value.moveX - _this.drawerWidth); + var normalizedOpacity_1 = Math.min((value.moveX / _this.drawerWidth) * fadeOpacity, fadeOpacity); + _this.state.sideMenuOverlayOpacity.setValue(normalizedOpacity_1); + } + if (direction === 'right' && + _this.screenWidth - value.moveX < _this.drawerWidth) { + _this.state.sideMenuOpenValue.setValue(value.moveX); + var normalizedOpacity_2 = Math.min(((_this.screenWidth - value.moveX) / _this.drawerWidth) * + fadeOpacity, fadeOpacity); + _this.state.sideMenuOverlayOpacity.setValue(normalizedOpacity_2); } + return; + } + if (_this.props.disableDragging) + return; + // Calculates the translateX / translateY value + var alignedMovementValue = 0; + // To swap the direction if needed + var directionModifier = 1; + // Whether we use the height of the drawer or the width + var drawerDimension = _this.drawerWidth; + if (swipeDirection === 'left') { + alignedMovementValue = + value.moveX - _this.panningStartedPoint.moveX; } else if (swipeDirection === 'right') { - // Works out the distance from right of screen to the finger position - var normalizedValue = _this.screenWidth - value; - // Calculates the position of the drawer from the left side of the screen - var alignedMovementValue = _this.screenWidth - normalizedValue; - // Calculates the percetage 0 - 100 of which the drawer is open - var openedPercentage = Math.abs((Math.abs(normalizedValue) / _this.drawerWidth) * 100); - // Calculates the opacity to set of the screen based on the percentage the drawer is open - var normalizedOpacity = Math.min(openedPercentage / 100, fadeOpacity); - // Does allow the drawer to go further than the maximum width - if (_this.drawerOpenedValues[direction] < alignedMovementValue) { - // Sets the animation values, we use this so we can resume animation from any point - _this.state.sideMenuOpenValue.setValue(alignedMovementValue); - _this.state.sideMenuOverlayOpacity.setValue(normalizedOpacity); - } + alignedMovementValue = + _this.panningStartedPoint.moveX - value.moveX; + directionModifier = -1; + } + else if (swipeDirection === 'bottom') { + alignedMovementValue = + _this.panningStartedPoint.moveY - value.moveY; + directionModifier = -1; + drawerDimension = _this.drawerHeight; + } + else if (swipeDirection === 'top') { + alignedMovementValue = + value.moveY - _this.panningStartedPoint.moveY; + drawerDimension = _this.drawerHeight; + } + // Calculates the percentage 0 - 1 of which the drawer is open + var openedPercentage = Math.abs(drawerDimension + alignedMovementValue) / + drawerDimension; + // Calculates the opacity to set of the screen based on the percentage the drawer is open + var normalizedOpacity = Math.min(openedPercentage * fadeOpacity, fadeOpacity); + // Does not allow the drawer to go further than the maximum width / height + if (0 > alignedMovementValue) { + // Sets the animation values, we use this so we can resume animation from any point + _this.state.sideMenuOpenValue.setValue(_this.drawerOpenedValues[direction] + + alignedMovementValue * directionModifier); + _this.state.sideMenuOverlayOpacity.setValue(normalizedOpacity); } }); // Executes when the side of the screen interaction ends this.unsubscribeSwipeEnd = events_1.listen('SWIPE_END', function (swipeDirection) { + if (_this.props.disableSwiping && !_this.startedFromSideMenu) + return; var reverseDirection = { right: 'left', left: 'right', + top: 'bottom', + bottom: 'top', }; + // In case the drawer started by dragging the edge of the screen reset the flag + _this.startedFromSideMenu = false; if (swipeDirection === reverseDirection[direction]) { _this.animatedDrawer.start(); _this.animatedOpacity.start(); @@ -281,7 +326,7 @@ var RNNDrawer = /** @class */ (function () { * Removes all the listenrs from this component */ WrappedDrawer.prototype.removeListeners = function () { - react_native_1.Dimensions.removeEventListener('change', function () { }); + react_native_1.Dimensions.removeEventListener('change', this.onOrientationChange); if (this.unsubscribeSwipeStart) this.unsubscribeSwipeStart(); if (this.unsubscribeSwipeMove) @@ -305,8 +350,8 @@ var RNNDrawer = /** @class */ (function () { var _b = this.state, sideMenuOpenValue = _b.sideMenuOpenValue, sideMenuOverlayOpacity = _b.sideMenuOverlayOpacity; /** Variables */ var animatedValue = direction === DirectionType.left || direction === DirectionType.right - ? { marginLeft: sideMenuOpenValue } - : { marginTop: sideMenuOpenValue }; + ? { translateX: sideMenuOpenValue } + : { translateY: sideMenuOpenValue }; return (React.createElement(react_native_1.View, __assign({ style: sideMenuContainerStyle }, this.panResponder.panHandlers), React.createElement(react_native_1.TouchableWithoutFeedback, { onPress: this.touchedOutside }, React.createElement(react_native_1.Animated.View, { style: [ @@ -316,7 +361,11 @@ var RNNDrawer = /** @class */ (function () { React.createElement(react_native_1.Animated.View, { style: [ { backgroundColor: '#FFF' }, style, - __assign({ height: this.state.screenHeight, width: this.drawerWidth }, animatedValue), + { + height: this.state.screenHeight, + width: this.drawerWidth, + transform: [animatedValue], + }, ] }, React.createElement(Component, __assign({}, this.props))))); }; @@ -339,14 +388,14 @@ var RNNDrawer = /** @class */ (function () { var closeValues = { left: -this.drawerWidth, right: this.screenWidth, - top: -this.drawerHeight, + top: -this.screenHeight, bottom: this.screenHeight, }; // Animate side menu close react_native_1.Animated.timing(this.state.sideMenuOpenValue, { toValue: closeValues[direction], duration: this.props.animationCloseTime, - useNativeDriver: false, + useNativeDriver: true, }).start(function () { react_native_navigation_1.Navigation.dismissOverlay(_this.props.componentId); _this.setState({ sideMenuIsDismissing: false }); @@ -355,7 +404,7 @@ var RNNDrawer = /** @class */ (function () { react_native_1.Animated.timing(this.state.sideMenuOverlayOpacity, { toValue: 0, duration: this.props.animationCloseTime, - useNativeDriver: false, + useNativeDriver: true, }).start(); }; WrappedDrawer.defaultProps = { @@ -365,7 +414,11 @@ var RNNDrawer = /** @class */ (function () { dismissWhenTouchOutside: true, fadeOpacity: 0.6, drawerScreenWidth: '80%', + drawerScreenWidthOnLandscape: '30%', drawerScreenHeight: '100%', + animateDrawerExpanding: true, + disableDragging: false, + disableSwiping: false, }; return WrappedDrawer; }(React.Component)); diff --git a/lib/SideMenuView.js b/lib/SideMenuView.js index 95cb5690..a9c578bd 100644 --- a/lib/SideMenuView.js +++ b/lib/SideMenuView.js @@ -83,7 +83,7 @@ var SideMenuView = /** @class */ (function (_super) { _this._leftPanResponder = react_native_1.PanResponder.create(__assign(__assign({}, _this._panResponderMethods), { onPanResponderMove: function (_evt, gestureState) { var moveX = gestureState.moveX, vx = gestureState.vx; // Emit this event on movement - events_1.dispatch('SWIPE_MOVE', { value: moveX, direction: 'left' }); + events_1.dispatch('SWIPE_MOVE', { value: { moveX: moveX }, direction: 'left' }); // Left Swipe if (typeof swipeSensitivity !== 'undefined') { if (vx > swipeSensitivity && !_this.isOpened && directionIsLeft) { @@ -91,7 +91,7 @@ var SideMenuView = /** @class */ (function (_super) { RNNDrawer_1.default.showDrawer({ component: { name: drawerName, - passProps: __assign({ direction: RNNDrawer_2.DirectionType.left, parentComponentId: passProps === null || passProps === void 0 ? void 0 : passProps.parentComponentId }, passProps), + passProps: __assign({ direction: RNNDrawer_2.DirectionType.left, parentComponentId: passProps === null || passProps === void 0 ? void 0 : passProps.parentComponentId, animateDrawerExpanding: false }, passProps), options: __assign({}, options), }, }); @@ -102,7 +102,7 @@ var SideMenuView = /** @class */ (function (_super) { _this._rightPanResponder = react_native_1.PanResponder.create(__assign(__assign({}, _this._panResponderMethods), { onPanResponderMove: function (_evt, gestureState) { var moveX = gestureState.moveX, vx = gestureState.vx; // Emit this event on movement - events_1.dispatch('SWIPE_MOVE', { value: moveX, direction: 'right' }); + events_1.dispatch('SWIPE_MOVE', { value: { moveX: moveX }, direction: 'right' }); // Right Swipe if (typeof swipeSensitivity !== 'undefined') { if (vx > -swipeSensitivity && !_this.isOpened && !directionIsLeft) { @@ -110,7 +110,7 @@ var SideMenuView = /** @class */ (function (_super) { RNNDrawer_1.default.showDrawer({ component: { name: drawerName, - passProps: __assign({ direction: RNNDrawer_2.DirectionType.right, parentComponentId: passProps === null || passProps === void 0 ? void 0 : passProps.parentComponentId }, passProps), + passProps: __assign({ direction: RNNDrawer_2.DirectionType.right, parentComponentId: passProps === null || passProps === void 0 ? void 0 : passProps.parentComponentId, animateDrawerExpanding: false }, passProps), options: __assign({}, options), }, }); diff --git a/src/RNNDrawer.tsx b/src/RNNDrawer.tsx index bd844a7f..c88ee3f7 100755 --- a/src/RNNDrawer.tsx +++ b/src/RNNDrawer.tsx @@ -22,8 +22,6 @@ import { Navigation, Layout } from 'react-native-navigation'; /* Utils - Project Utilities */ import { listen, dispatch } from './events'; -const MaxWidthOnLandscapeMode = 300; - declare interface RNNDrawerOptions { /** * Id of parent component of the drawer. @@ -38,7 +36,7 @@ declare interface RNNDrawerOptions { * If not provided, drawer might have * a weird effect when closing */ - direction: DirectionType; + direction?: DirectionType; /** * Time in milliseconds to execute the drawer opening animation @@ -61,14 +59,22 @@ declare interface RNNDrawerOptions { fadeOpacity?: number; /** - * Width of drawer in relation to the screen (0 to 1) + * Width of drawer on portrait orientation. Pass a string containing '%' (e.g. "80%") + * for setting the width in relation to the screen or a number for absolute width (e.g. 300) */ - drawerScreenWidth?: number; + drawerScreenWidth?: number | string; /** - * Height of drawer in relation to the screen (0 to 1) + * Width of drawer on landscape orientation. Pass a string containing '%' (e.g. "80%") + * for setting the width in relation to the screen or a number for absolute width (e.g. 300) */ - drawerScreenHeight?: number; + drawerScreenWidthOnLandscape?: number | string; + + /** + * Height of drawer. Pass a string containing '%' (e.g. "30%") + * for setting the height in relation to the screen or a number for absolute height (e.g. 300) + */ + drawerScreenHeight?: number | string; disableDragging?: boolean; @@ -83,8 +89,8 @@ export enum DirectionType { } interface Point { - moveX: number; - moveY: number; + moveX: number; + moveY: number; } interface IState { @@ -105,6 +111,7 @@ interface IProps { dismissWhenTouchOutside: boolean; fadeOpacity: number; drawerScreenWidth: number | string; + drawerScreenWidthOnLandscape: number | string; drawerScreenHeight: number | string; animateDrawerExpanding?: boolean; disableDragging?: boolean; @@ -162,7 +169,7 @@ class RNNDrawer { private unsubscribeSwipeMove!: () => void; private unsubscribeSwipeEnd!: () => void; private unsubscribeDismissDrawer!: () => void; - private panningStartedPoint: Point = { moveX: 0 , moveY: 0 }; + private panningStartedPoint: Point = { moveX: 0, moveY: 0 }; private startedFromSideMenu: boolean = false; static defaultProps = { @@ -172,10 +179,11 @@ class RNNDrawer { dismissWhenTouchOutside: true, fadeOpacity: 0.6, drawerScreenWidth: '80%', + drawerScreenWidthOnLandscape: '30%', drawerScreenHeight: '100%', animateDrawerExpanding: true, disableDragging: false, - disableSwiping: false + disableSwiping: false, }; /** @@ -206,10 +214,12 @@ class RNNDrawer { ) => { const { dx, dy } = _gestureState; - if (this.props.direction === DirectionType.left || this.props.direction === DirectionType.right) + if ( + this.props.direction === DirectionType.left || + this.props.direction === DirectionType.right + ) return Math.abs(dx) > 5; - else - return Math.abs(dy) > 5; + else return Math.abs(dy) > 5; }, onMoveShouldSetPanResponderCapture: ( _evt: GestureResponderEvent, @@ -221,7 +231,7 @@ class RNNDrawer { ) => { const { moveX, moveY } = _gestureState; - dispatch('SWIPE_START', {moveX, moveY}); + dispatch('SWIPE_START', { moveX, moveY }); }, onPanResponderRelease: ( _evt: GestureResponderEvent, @@ -275,9 +285,12 @@ class RNNDrawer { }; /** Component Variables */ - this.drawerWidth = this.isLandscape() - ? MaxWidthOnLandscapeMode - : _resolveDrawerSize(props.drawerScreenWidth, this.screenWidth); + this.drawerWidth = _resolveDrawerSize( + this.isLandscape() + ? props.drawerScreenWidthOnLandscape + : props.drawerScreenWidth, + this.screenWidth, + ); this.drawerHeight = _resolveDrawerSize( props.drawerScreenHeight, this.screenHeight, @@ -299,7 +312,9 @@ class RNNDrawer { /** Component State */ this.state = { - sideMenuOpenValue: new Animated.Value(this.initialValues[props.direction]), + sideMenuOpenValue: new Animated.Value( + this.initialValues[props.direction], + ), sideMenuOverlayOpacity: new Animated.Value(0), sideMenuSwipingStarted: false, sideMenuIsDismissing: false, @@ -335,8 +350,11 @@ class RNNDrawer { /** Props */ const { direction, fadeOpacity, animateDrawerExpanding } = this.props; - if (typeof animateDrawerExpanding !== 'undefined' && !animateDrawerExpanding) - this.startedFromSideMenu = true; + if ( + typeof animateDrawerExpanding !== 'undefined' && + !animateDrawerExpanding + ) + this.startedFromSideMenu = true; // Animate side menu open this.animatedDrawer = Animated.timing(this.state.sideMenuOpenValue, { @@ -365,7 +383,10 @@ class RNNDrawer { this.registerListeners(); // If there has been no Swiping, and this component appears, then just start the open animations - if (!this.state.sideMenuSwipingStarted && this.props.animateDrawerExpanding) { + if ( + !this.state.sideMenuSwipingStarted && + this.props.animateDrawerExpanding + ) { this.animatedDrawer.start(); this.animatedOpacity.start(); } @@ -382,7 +403,7 @@ class RNNDrawer { dispatch('DRAWER_CLOSED'); } - onOrientationChange = ({window}: any) => { + onOrientationChange = ({ window }: any) => { const screenHeight = window.height; this.setState({ screenHeight }); @@ -394,7 +415,7 @@ class RNNDrawer { this.state.sideMenuOpenValue.setValue(alignedMovementValue); } - } + }; /** * Registers all the listenrs for this component @@ -422,19 +443,25 @@ class RNNDrawer { ({ value, direction: swipeDirection }: SwipeMoveInterface) => { // Cover special case when we are swiping from the edge of the screen if (this.startedFromSideMenu) { - if (direction === "left" && value.moveX < this.drawerWidth) { - this.state.sideMenuOpenValue.setValue(value.moveX - this.drawerWidth); + if (direction === 'left' && value.moveX < this.drawerWidth) { + this.state.sideMenuOpenValue.setValue( + value.moveX - this.drawerWidth, + ); const normalizedOpacity = Math.min( - (value.moveX / this.drawerWidth) * fadeOpacity, - fadeOpacity, + (value.moveX / this.drawerWidth) * fadeOpacity, + fadeOpacity, ); this.state.sideMenuOverlayOpacity.setValue(normalizedOpacity); } - if (direction === "right" && (this.screenWidth - value.moveX) < this.drawerWidth) { + if ( + direction === 'right' && + this.screenWidth - value.moveX < this.drawerWidth + ) { this.state.sideMenuOpenValue.setValue(value.moveX); const normalizedOpacity = Math.min( - ((this.screenWidth - value.moveX) / this.drawerWidth) * fadeOpacity, + ((this.screenWidth - value.moveX) / this.drawerWidth) * fadeOpacity, + fadeOpacity, ); this.state.sideMenuOverlayOpacity.setValue(normalizedOpacity); } @@ -442,8 +469,7 @@ class RNNDrawer { return; } - if (this.props.disableDragging) - return; + if (this.props.disableDragging) return; // Calculates the translateX / translateY value let alignedMovementValue = 0; // To swap the direction if needed @@ -452,31 +478,40 @@ class RNNDrawer { let drawerDimension = this.drawerWidth; if (swipeDirection === 'left') { - alignedMovementValue = value.moveX - this.panningStartedPoint.moveX; + alignedMovementValue = + value.moveX - this.panningStartedPoint.moveX; } else if (swipeDirection === 'right') { - alignedMovementValue = this.panningStartedPoint.moveX - value.moveX; + alignedMovementValue = + this.panningStartedPoint.moveX - value.moveX; directionModifier = -1; } else if (swipeDirection === 'bottom') { - alignedMovementValue = this.panningStartedPoint.moveY - value.moveY; + alignedMovementValue = + this.panningStartedPoint.moveY - value.moveY; directionModifier = -1; drawerDimension = this.drawerHeight; } else if (swipeDirection === 'top') { - alignedMovementValue = value.moveY - this.panningStartedPoint.moveY; + alignedMovementValue = + value.moveY - this.panningStartedPoint.moveY; drawerDimension = this.drawerHeight; } // Calculates the percentage 0 - 1 of which the drawer is open - const openedPercentage = Math.abs(drawerDimension + alignedMovementValue) / drawerDimension; + const openedPercentage = + Math.abs(drawerDimension + alignedMovementValue) / + drawerDimension; // Calculates the opacity to set of the screen based on the percentage the drawer is open const normalizedOpacity = Math.min( - openedPercentage * fadeOpacity, - fadeOpacity, + openedPercentage * fadeOpacity, + fadeOpacity, ); // Does not allow the drawer to go further than the maximum width / height if (0 > alignedMovementValue) { // Sets the animation values, we use this so we can resume animation from any point - this.state.sideMenuOpenValue.setValue(this.drawerOpenedValues[direction] + alignedMovementValue * directionModifier); + this.state.sideMenuOpenValue.setValue( + this.drawerOpenedValues[direction] + + alignedMovementValue * directionModifier, + ); this.state.sideMenuOverlayOpacity.setValue(normalizedOpacity); } }, @@ -486,14 +521,13 @@ class RNNDrawer { this.unsubscribeSwipeEnd = listen( 'SWIPE_END', (swipeDirection: string) => { - if (this.props.disableSwiping && !this.startedFromSideMenu) - return; + if (this.props.disableSwiping && !this.startedFromSideMenu) return; const reverseDirection: DrawerReverseDirectionInterface = { right: 'left', left: 'right', top: 'bottom', - bottom: 'top' + bottom: 'top', }; // In case the drawer started by dragging the edge of the screen reset the flag this.startedFromSideMenu = false; @@ -573,9 +607,7 @@ class RNNDrawer { { height: this.state.screenHeight, width: this.drawerWidth, - transform:[ - animatedValue - ] + transform: [animatedValue], }, ]} > @@ -680,4 +712,3 @@ const styles = StyleSheet.create({ backgroundColor: '#000', }, }); - diff --git a/src/SideMenuView.tsx b/src/SideMenuView.tsx index b588a15d..5a3d1bcf 100755 --- a/src/SideMenuView.tsx +++ b/src/SideMenuView.tsx @@ -21,7 +21,7 @@ import { Options } from 'react-native-navigation'; /* Utils - Project Utilities */ import RNNDrawer from './RNNDrawer'; import { listen, dispatch } from './events'; -import { DirectionType } from "./RNNDrawer"; +import { DirectionType } from './RNNDrawer'; const screenHeight: number = Dimensions.get('screen').height;