feat: add theme support

This commit is contained in:
Brent Vatne
2019-09-04 16:08:51 -07:00
parent 7097d60131
commit 1e8279ae18
20 changed files with 3524 additions and 3879 deletions

View File

@@ -1,6 +0,0 @@
[android]
target = Google Inc.:Google APIs:23
[maven_repositories]
central = https://repo1.maven.org/maven2

View File

@@ -1,14 +1,11 @@
{
'extends': '../.eslintrc',
"extends": '../.eslintrc',
'settings':
{
'import/core-modules':
[
'react-navigation-drawer',
'react-native-gesture-handler',
'react-native-reanimated',
'react-native-vector-icons/MaterialIcons',
],
},
"settings": {
"import/core-modules": [ "expo", "react-navigation-drawer" ]
},
"rules": {
"react/prop-types": "off",
}
}

View File

@@ -1 +0,0 @@
{}

View File

@@ -1,11 +1,12 @@
import * as React from 'react';
// eslint-disable-next-line no-unused-vars
import { FlatList, I18nManager } from 'react-native';
import { createAppContainer } from '@react-navigation/native';
// eslint-disable-next-line import/named
import { View, TouchableOpacity, FlatList, I18nManager } from 'react-native';
import { ThemeContext, ThemeColors } from '@react-navigation/core';
import { Themed, createAppContainer } from '@react-navigation/native';
import { createStackNavigator } from 'react-navigation-stack';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { List, Divider } from 'react-native-paper';
import { SimpleDrawer, SimpleDrawerUnmountInactive } from './src/SimpleDrawer';
import { ParallaxDrawer } from './src/ParallaxDrawer';
import StyledDrawer from './src/StyledDrawer';
@@ -43,29 +44,46 @@ const data = [
},
];
class Row extends React.PureComponent {
static contextType = ThemeContext;
render() {
let { item, navigation } = this.props;
return (
<List.Item
title={item.title}
onPress={() => navigation.navigate(item.routeName)}
style={{ backgroundColor: ThemeColors[this.context].bodyContent }}
titleStyle={{ color: ThemeColors[this.context].label }}
/>
);
}
}
class Home extends React.Component {
static contextType = ThemeContext;
static navigationOptions = {
title: 'Examples',
};
_renderItem = ({ item }) => (
<List.Item
title={item.title}
onPress={() => this.props.navigation.navigate(item.routeName)}
/>
);
_keyExtractor = item => item.routeName;
_renderItem = ({ item }) => {
return <Row item={item} navigation={this.props.navigation} />;
};
render() {
return (
<FlatList
ItemSeparatorComponent={Divider}
renderItem={this._renderItem}
keyExtractor={this._keyExtractor}
style={{ backgroundColor: '#fff' }}
data={data}
/>
<>
<Themed.StatusBar />
<FlatList
ItemSeparatorComponent={Divider}
renderItem={this._renderItem}
keyExtractor={this._keyExtractor}
data={data}
/>
</>
);
}
}
@@ -93,4 +111,52 @@ const MainNavigator = createStackNavigator(
}
);
export default createAppContainer(MainNavigator);
const Navigation = createAppContainer(MainNavigator);
const App = () => {
let [theme, setTheme] = React.useState('light');
return (
<View style={{ flex: 1 }}>
<Navigation theme={theme} />
<View style={{ position: 'absolute', bottom: 60, right: 20 }}>
<TouchableOpacity
onPress={() => {
setTheme(theme === 'light' ? 'dark' : 'light');
}}
>
<View
style={{
backgroundColor: ThemeColors[theme].bodyContent,
borderRadius: 25,
width: 50,
height: 50,
alignItems: 'center',
justifyContent: 'center',
borderColor: ThemeColors[theme].bodyBorder,
borderWidth: 1,
shadowColor: ThemeColors[theme].label,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.4,
shadowRadius: 2,
elevation: 5,
}}
>
<MaterialCommunityIcons
name="theme-light-dark"
size={30}
color={ThemeColors[theme].label}
/>
</View>
</TouchableOpacity>
</View>
</View>
);
};
export default App;

View File

@@ -3,10 +3,11 @@
"name": "React Navigation Drawer Example",
"description": "Demonstrates the various capabilities of react-navigation-drawer",
"slug": "react-navigation-drawer-demo",
"sdkVersion": "32.0.0",
"sdkVersion": "34.0.0",
"version": "1.0.0",
"primaryColor": "#2196f3",
"packagerOpts": {
"assetExts": ["ttf"],
"config": "./metro.config.js",
"projectRoots": ""
}

View File

@@ -1,14 +1,12 @@
/* eslint-disable import/no-extraneous-dependencies, import/no-commonjs */
/* eslint-disable import/no-commonjs, import/no-extraneous-dependencies */
const path = require('path');
const blacklist = require('metro-config/src/defaults/blacklist');
const project = require('../package.json');
const pak = require('../package.json');
const escape = require('escape-string-regexp');
const projectDependencies = Object.keys({
...project.dependencies,
...project.peerDependencies,
});
const dependencies = Object.keys(pak.dependencies);
const peerDependencies = Object.keys(pak.peerDependencies);
module.exports = {
projectRoot: __dirname,
@@ -16,11 +14,6 @@ module.exports = {
resolver: {
blacklistRE: blacklist([
new RegExp(
`^${escape(
path.resolve(__dirname, 'node_modules', project.name)
)}\\/.*$`
),
new RegExp(
`^${escape(path.resolve(__dirname, '..', 'node_modules'))}\\/.*$`
),
@@ -29,7 +22,12 @@ module.exports = {
providesModuleNodeModules: [
'@expo/vector-icons',
'@babel/runtime',
...projectDependencies,
'@react-navigation/core',
'@react-navigation/native',
'react-native-gesture-handler',
'react-native-reanimated',
...dependencies,
...peerDependencies,
],
},
};

View File

@@ -6,26 +6,27 @@
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
"ios": "expo start --ios"
},
"dependencies": {
"@react-navigation/core": "^3.4.0",
"@react-navigation/native": "^3.4.1",
"expo": "32.0.6",
"hoist-non-react-statics": "^3.3.0",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
"react-native-paper": "^2.15.2",
"react-navigation-stack": "^1.2.0"
"@expo/vector-icons": "^10.0.0",
"@react-navigation/core": "^3.5.0",
"@react-navigation/native": "^3.6.0",
"expo": "^34.0.0",
"expo-asset": "^6.0.0",
"expo-constants": "~6.0.0",
"react": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz",
"react-native-gesture-handler": "~1.3.0",
"react-native-maps": "~0.24.0",
"react-native-paper": "^2.2.0",
"react-native-reanimated": "~1.1.0",
"react-native-webview": "~5.12.0",
"react-navigation-stack": "^1.4.0"
},
"devDependencies": {
"babel-plugin-module-resolver": "^3.2.0"
},
"resolutions": {
"**/prop-types": "15.6.0",
"**/react-lifecycles-compat": "3.0.4",
"**/hoist-non-react-statics": "3.3.0",
"**/react-native-screens": "1.0.0-alpha.22"
"babel-plugin-module-resolver": "^3.2.0",
"babel-preset-expo": "^5.0.0",
"glob-to-regexp": "^0.4.0"
}
}

View File

@@ -1,11 +1,12 @@
import * as React from 'react';
import { Button, WebView, View } from 'react-native';
import { MapView } from 'expo';
import { Button, View } from 'react-native';
import { withNavigation } from '@react-navigation/core';
import {
createDrawerNavigator,
DrawerGestureContext,
} from 'react-navigation-drawer';
import MapView from 'react-native-maps';
import { WebView } from 'react-native-webview';
import { NativeViewGestureHandler } from 'react-native-gesture-handler';
@withNavigation
@@ -44,13 +45,13 @@ class ContainerWithButtons extends React.Component {
const MapScreen = () => (
<ContainerWithButtons>
<DrawerGestureContext>
<DrawerGestureContext.Consumer>
{ref => (
<NativeViewGestureHandler waitFor={ref}>
<MapView style={{ flex: 1 }} />
</NativeViewGestureHandler>
)}
</DrawerGestureContext>
</DrawerGestureContext.Consumer>
</ContainerWithButtons>
);
@@ -60,7 +61,7 @@ MapScreen.navigationOptions = {
const WebViewScreen = () => (
<ContainerWithButtons>
<DrawerGestureContext>
<DrawerGestureContext.Consumer>
{ref => (
<NativeViewGestureHandler waitFor={ref}>
<WebView
@@ -69,7 +70,7 @@ const WebViewScreen = () => (
/>
</NativeViewGestureHandler>
)}
</DrawerGestureContext>
</DrawerGestureContext.Consumer>
</ContainerWithButtons>
);

View File

@@ -1,111 +1,115 @@
import * as React from 'react';
import React from 'react';
import {
Button,
Dimensions,
TextInput,
TouchableOpacity,
ScrollView,
StatusBar,
StyleSheet,
Text,
View,
} from 'react-native';
// eslint-disable-next-line import/named
import { createStackNavigator } from 'react-navigation-stack';
import { SafeAreaView } from '@react-navigation/native';
import { ThemeColors, useTheme } from '@react-navigation/core';
import { Themed, SafeAreaView } from '@react-navigation/native';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { createDrawerNavigator } from 'react-navigation-drawer';
import Animated from 'react-native-reanimated';
import { KeepAwake } from 'expo';
import { createDrawerNavigator } from 'react-navigation-drawer';
const SampleText = ({ children }) => <Text>{children}</Text>;
const SampleText = ({ children }) => <Themed.Text>{children}</Themed.Text>;
const MyNavScreen = ({ navigation, banner }) => (
<ScrollView>
<SafeAreaView forceInset={{ top: 'always' }}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<SampleText>{banner}</SampleText>
</View>
<TextInput
style={{
flex: 1,
height: 35,
marginHorizontal: 10,
marginVertical: 10,
borderWidth: StyleSheet.hairlineWidth,
borderColor: '#eee',
textAlign: 'center',
}}
placeholder="Focus this TextInput then drag the drawer!"
/>
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
<Button onPress={() => navigation.toggleDrawer()} title="Toggle drawer" />
<Button
onPress={() => {
navigation.openDrawer();
navigation.closeDrawer();
}}
title="Open and immediately close"
/>
<Button
onPress={() => {
navigation.closeDrawer();
navigation.openDrawer();
}}
title="Close and immediately open"
/>
<Button
onPress={() => {
navigation.openDrawer();
setTimeout(() => {
const MyNavScreen = ({ navigation, banner }) => {
let theme = useTheme();
return (
<ScrollView>
<SafeAreaView forceInset={{ top: 'always' }}>
<View
style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}
>
<SampleText>{banner}</SampleText>
</View>
<Themed.TextInput
style={{
flex: 1,
height: 35,
marginHorizontal: 10,
marginVertical: 10,
borderWidth: StyleSheet.hairlineWidth,
borderColor: ThemeColors[theme].bodyBorder,
textAlign: 'center',
}}
placeholder="Focus this TextInput then drag the drawer!"
/>
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
<Button
onPress={() => navigation.toggleDrawer()}
title="Toggle drawer"
/>
<Button
onPress={() => {
navigation.openDrawer();
navigation.closeDrawer();
}, 150);
}}
title="Open then close drawer shortly after"
/>
<Button
onPress={() => navigation.navigate('Email')}
title="Open other screen"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
<Button
onPress={() => navigation.navigate('Home')}
title="Go back to list"
/>
{
}}
title="Open and immediately close"
/>
<Button
onPress={() => {
navigation.closeDrawer();
navigation.openDrawer();
}}
title="Close and immediately open"
/>
<Button
onPress={() => {
navigation.openDrawer();
setTimeout(() => {
navigation.closeDrawer();
}, 150);
}}
title="Open then close drawer shortly after"
/>
<Button
onPress={() => navigation.navigate('Email')}
title="Open other screen"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
<Button
onPress={() => navigation.navigate('Home')}
title="Go back to list"
/>
{
'locked-open': (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'locked-closed' })
}
title="Set locked-closed"
/>
),
'locked-closed': (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'unlocked' })
}
title="Set unlocked"
/>
),
unlocked: (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'locked-open' })
}
title="Set locked-open"
/>
),
}[navigation.getParam('drawerLockMode', 'unlocked')]
}
</SafeAreaView>
<StatusBar barStyle="default" />
<KeepAwake />
</ScrollView>
);
{
'locked-open': (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'locked-closed' })
}
title="Set locked-closed"
/>
),
'locked-closed': (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'unlocked' })
}
title="Set unlocked"
/>
),
unlocked: (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'locked-open' })
}
title="Set locked-open"
/>
),
}[navigation.getParam('drawerLockMode', 'unlocked')]
}
</SafeAreaView>
<Themed.StatusBar />
</ScrollView>
);
};
const InboxScreen = ({ navigation }) => (
<MyNavScreen banner="Inbox Screen" navigation={navigation} />
@@ -188,9 +192,9 @@ const DrawerContents = ({ drawerOpenProgress, navigation }) => {
const DrawerItem = props => {
return (
<TouchableOpacity onPress={() => props.navigation.navigate(props.item)}>
<Text style={{ padding: 10, fontSize: 18, fontWeight: '600' }}>
<Themed.Text style={{ padding: 10, fontSize: 18, fontWeight: '600' }}>
{props.item}
</Text>
</Themed.Text>
</TouchableOpacity>
);
};
@@ -210,7 +214,11 @@ function createDrawerExample(options = {}) {
{
overlayColor: 'rgba(0,0,0,0)',
drawerType: 'back',
sceneContainerStyle: {
drawerBackgroundColor: {
light: '#eee',
dark: '#888',
},
screenContainerStyle: {
shadowColor: '#000000',
shadowOpacity: 0.4,
shadowRadius: 8,

View File

@@ -1,4 +1,4 @@
import * as React from 'react';
import React, { Component } from 'react';
import {
Text,
View,
@@ -7,11 +7,11 @@ import {
TouchableOpacity,
} from 'react-native';
// eslint-disable-next-line import/named
import { Themed } from '@react-navigation/native';
import { createStackNavigator } from 'react-navigation-stack';
import { createDrawerNavigator } from 'react-navigation-drawer';
class RightDrawer extends React.Component {
class RightDrawer extends Component {
state = {
categories: [{ i: 'c1', n: 'name1' }, { i: 'c2', n: 'name2' }],
};
@@ -58,6 +58,7 @@ class RightDrawer extends React.Component {
);
})}
</ScrollView>
<Themed.StatusBar barStyle="light-content" />
</View>
);
}
@@ -66,7 +67,7 @@ class RightDrawer extends React.Component {
const CategoryScreen = ({ navigation }) => {
return (
<View>
<Text>CategoryScreen {navigation.getParam('title')}</Text>
<Themed.Text>CategoryScreen {navigation.getParam('title')}</Themed.Text>
</View>
);
};

View File

@@ -1,108 +1,106 @@
import * as React from 'react';
import {
Button,
TextInput,
ScrollView,
StatusBar,
StyleSheet,
Text,
View,
} from 'react-native';
// eslint-disable-next-line import/named
import React from 'react';
import { Button, ScrollView, StyleSheet, View } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack';
import { SafeAreaView } from '@react-navigation/native';
import { ThemeColors, useTheme } from '@react-navigation/core';
import { Themed, SafeAreaView } from '@react-navigation/native';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { createDrawerNavigator } from 'react-navigation-drawer';
import { KeepAwake } from 'expo';
const SampleText = ({ children }) => <Text>{children}</Text>;
const SampleText = ({ children }) => <Themed.Text>{children}</Themed.Text>;
const MyNavScreen = ({ navigation, banner }) => (
<ScrollView>
<SafeAreaView forceInset={{ top: 'always' }}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<SampleText>{banner}</SampleText>
</View>
<TextInput
style={{
flex: 1,
height: 35,
marginHorizontal: 10,
marginVertical: 10,
borderWidth: StyleSheet.hairlineWidth,
borderColor: '#eee',
textAlign: 'center',
}}
placeholder="Focus this TextInput then drag the drawer!"
/>
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
<Button onPress={() => navigation.toggleDrawer()} title="Toggle drawer" />
<Button
onPress={() => {
navigation.openDrawer();
navigation.closeDrawer();
}}
title="Open and immediately close"
/>
<Button
onPress={() => {
navigation.closeDrawer();
navigation.openDrawer();
}}
title="Close and immediately open"
/>
<Button
onPress={() => {
navigation.openDrawer();
setTimeout(() => {
const MyNavScreen = ({ navigation, banner }) => {
let theme = useTheme();
return (
<ScrollView>
<SafeAreaView forceInset={{ top: 'always' }}>
<View
style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}
>
<SampleText>{banner}</SampleText>
</View>
<Themed.TextInput
style={{
flex: 1,
height: 35,
marginHorizontal: 10,
marginVertical: 10,
borderWidth: StyleSheet.hairlineWidth,
borderColor: ThemeColors[theme].bodyBorder,
textAlign: 'center',
}}
placeholder="Focus this TextInput then drag the drawer!"
/>
<Button onPress={() => navigation.openDrawer()} title="Open drawer" />
<Button
onPress={() => navigation.toggleDrawer()}
title="Toggle drawer"
/>
<Button
onPress={() => {
navigation.openDrawer();
navigation.closeDrawer();
}, 150);
}}
title="Open then close drawer shortly after"
/>
<Button
onPress={() => navigation.navigate('Email')}
title="Open other screen"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
<Button
onPress={() => navigation.navigate('Home')}
title="Go back to list"
/>
{
}}
title="Open and immediately close"
/>
<Button
onPress={() => {
navigation.closeDrawer();
navigation.openDrawer();
}}
title="Close and immediately open"
/>
<Button
onPress={() => {
navigation.openDrawer();
setTimeout(() => {
navigation.closeDrawer();
}, 150);
}}
title="Open then close drawer shortly after"
/>
<Button
onPress={() => navigation.navigate('Email')}
title="Open other screen"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
<Button
onPress={() => navigation.navigate('Home')}
title="Go back to list"
/>
{
'locked-open': (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'locked-closed' })
}
title="Set locked-closed"
/>
),
'locked-closed': (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'unlocked' })
}
title="Set unlocked"
/>
),
unlocked: (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'locked-open' })
}
title="Set locked-open"
/>
),
}[navigation.getParam('drawerLockMode', 'unlocked')]
}
</SafeAreaView>
<StatusBar barStyle="default" />
<KeepAwake />
</ScrollView>
);
{
'locked-open': (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'locked-closed' })
}
title="Set locked-closed"
/>
),
'locked-closed': (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'unlocked' })
}
title="Set unlocked"
/>
),
unlocked: (
<Button
onPress={() =>
navigation.setParams({ drawerLockMode: 'locked-open' })
}
title="Set locked-open"
/>
),
}[navigation.getParam('drawerLockMode', 'unlocked')]
}
</SafeAreaView>
<Themed.StatusBar />
</ScrollView>
);
};
const InboxScreen = ({ navigation }) => (
<MyNavScreen banner="Inbox Screen" navigation={navigation} />
@@ -176,7 +174,7 @@ function createDrawerExample(options = {}) {
},
{
initialRouteName: 'Drafts',
drawerWidth: '60%',
drawerWidth: 210,
navigationOptions: {
header: null,
},

View File

@@ -1,14 +1,11 @@
import * as React from 'react';
import { Button, ScrollView, StatusBar, Text } from 'react-native';
// eslint-disable-next-line import/named
import React from 'react';
import { Button, ScrollView } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack';
import { SafeAreaView } from '@react-navigation/native';
import { Themed, SafeAreaView } from '@react-navigation/native';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { createDrawerNavigator } from 'react-navigation-drawer';
const SampleText = ({ children }) => <Text>{children}</Text>;
const SampleText = ({ children }) => <Themed.Text>{children}</Themed.Text>;
const MyNavScreen = ({ navigation, banner }) => (
<ScrollView>
@@ -21,7 +18,7 @@ const MyNavScreen = ({ navigation, banner }) => (
/>
<Button onPress={() => navigation.navigate('Home')} title="Go back" />
</SafeAreaView>
<StatusBar barStyle="default" />
<Themed.StatusBar />
</ScrollView>
);
@@ -83,12 +80,16 @@ const DrawerExample = createDrawerNavigator(
},
},
{
drawerBackgroundColor: {
light: '#eee',
dark: 'rgba(40,40,40,1)',
},
initialRouteName: 'Drafts',
contentOptions: {
activeTintColor: '#e91e63',
},
drawerType: 'back',
overlayColor: 'rgba(233, 30, 99, 0.5)',
overlayColor: '#00000000',
hideStatusBar: true,
}
);

File diff suppressed because it is too large Load Diff