From 4ed5d1e7090088c737bee2bfdf98fed7c909ad79 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Fri, 8 Jun 2018 16:21:37 -0700 Subject: [PATCH] Stop depending on internal functions in react-navigation --- packages/drawer/src/routers/DrawerRouter.js | 11 +++- packages/drawer/src/utils/invariant.js | 58 +++++++++++++++++++ .../drawer/src/views/DrawerNavigatorItems.js | 2 +- packages/drawer/src/views/DrawerSidebar.js | 2 +- packages/drawer/src/views/TouchableItem.js | 58 +++++++++++++++++++ 5 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 packages/drawer/src/utils/invariant.js create mode 100644 packages/drawer/src/views/TouchableItem.js diff --git a/packages/drawer/src/routers/DrawerRouter.js b/packages/drawer/src/routers/DrawerRouter.js index de97594c..f0e51772 100644 --- a/packages/drawer/src/routers/DrawerRouter.js +++ b/packages/drawer/src/routers/DrawerRouter.js @@ -1,8 +1,15 @@ import { SwitchRouter } from 'react-navigation'; -import withDefaultValue from 'react-navigation/src/utils/withDefaultValue'; - import DrawerActions from './DrawerActions'; +function withDefaultValue(obj, key, defaultValue) { + if (obj.hasOwnProperty(key)) { + return obj; + } + + obj[key] = defaultValue; + return obj; +} + const getActiveRouteKey = route => { if (route.routes && route.routes[route.index]) { return getActiveRouteKey(route.routes[route.index]); diff --git a/packages/drawer/src/utils/invariant.js b/packages/drawer/src/utils/invariant.js new file mode 100644 index 00000000..b9c478c0 --- /dev/null +++ b/packages/drawer/src/utils/invariant.js @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + +var validateFormat = function(format) {}; + +if (__DEV__) { + validateFormat = function(format) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + }; +} + +function invariant(condition, format, a, b, c, d, e, f) { + validateFormat(format); + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { + return args[argIndex++]; + }) + ); + error.name = 'Invariant Violation'; + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +} + +module.exports = invariant; \ No newline at end of file diff --git a/packages/drawer/src/views/DrawerNavigatorItems.js b/packages/drawer/src/views/DrawerNavigatorItems.js index cfbda36d..c2181e94 100644 --- a/packages/drawer/src/views/DrawerNavigatorItems.js +++ b/packages/drawer/src/views/DrawerNavigatorItems.js @@ -1,7 +1,7 @@ import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import { SafeAreaView } from 'react-navigation'; -import TouchableItem from 'react-navigation/src/views/TouchableItem'; +import TouchableItem from './TouchableItem'; /** * Component that renders the navigation list in the drawer. diff --git a/packages/drawer/src/views/DrawerSidebar.js b/packages/drawer/src/views/DrawerSidebar.js index c7b29190..05d0a1b0 100644 --- a/packages/drawer/src/views/DrawerSidebar.js +++ b/packages/drawer/src/views/DrawerSidebar.js @@ -2,7 +2,7 @@ import React from 'react'; import { StyleSheet, View } from 'react-native'; import { NavigationActions, StackActions } from 'react-navigation'; -import invariant from 'react-navigation/src/utils/invariant'; +import invariant from '../utils/invariant'; /** * Component that renders the sidebar screen of the drawer. diff --git a/packages/drawer/src/views/TouchableItem.js b/packages/drawer/src/views/TouchableItem.js new file mode 100644 index 00000000..c7a19b77 --- /dev/null +++ b/packages/drawer/src/views/TouchableItem.js @@ -0,0 +1,58 @@ +/** + * TouchableItem renders a touchable that looks native on both iOS and Android. + * + * It provides an abstraction on top of TouchableNativeFeedback and + * TouchableOpacity. + * + * On iOS you can pass the props of TouchableOpacity, on Android pass the props + * of TouchableNativeFeedback. + */ +import React from 'react'; +import { + Platform, + TouchableNativeFeedback, + TouchableOpacity, + View, +} from 'react-native'; + +const ANDROID_VERSION_LOLLIPOP = 21; + +export default class TouchableItem extends React.Component { + static defaultProps = { + borderless: false, + pressColor: 'rgba(0, 0, 0, .32)', + }; + + render() { + /* + * TouchableNativeFeedback.Ripple causes a crash on old Android versions, + * therefore only enable it on Android Lollipop and above. + * + * All touchables on Android should have the ripple effect according to + * platform design guidelines. + * We need to pass the background prop to specify a borderless ripple effect. + */ + if ( + Platform.OS === 'android' && + Platform.Version >= ANDROID_VERSION_LOLLIPOP + ) { + const { style, ...rest } = this.props; + return ( + + {React.Children.only(this.props.children)} + + ); + } + + return ( + {this.props.children} + ); + } +}