diff --git a/App/App.js b/App/App.js index 1d53106..ee478d3 100644 --- a/App/App.js +++ b/App/App.js @@ -14,15 +14,19 @@ import { Provider } from 'react-redux'; import { Navigation } from './navigation'; import NavigationService from './utils/navigationService'; +import { ThemeContextProvider } from './theme/themeProvider'; + const App = () => { return ( + { NavigationService.setTopLevelNavigator(navigatorRef); }} /> + ); }; diff --git a/App/components/content.js b/App/components/content.js index 0bb8830..ba88f3a 100644 --- a/App/components/content.js +++ b/App/components/content.js @@ -7,10 +7,10 @@ export const Content = ({style,children}) => { return ( {children} diff --git a/App/components/footer.js b/App/components/footer.js index 9827982..2fcdad1 100644 --- a/App/components/footer.js +++ b/App/components/footer.js @@ -15,7 +15,7 @@ export const Footer = ({ style, children }) => { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', - backgroundColor: 'transparent' + backgroundColor: 'white' }, style]}> {children} diff --git a/App/components/header.js b/App/components/header.js index 2255d56..5ea3df3 100644 --- a/App/components/header.js +++ b/App/components/header.js @@ -3,7 +3,6 @@ import { View,StatusBar } from 'react-native'; import { BarStyle } from '../theme/global'; export const Header = ({style,statusbarColor,barStyle = BarStyle ,children}) => { - console.log(children) return ( - + - About Screen + About Screen - - - ) + const { isDarkMode } = this.state; + const { theme } = this.props; + return ( + +
+ + + Boilerplate + + +
+ + Switch Theme + + {'Light Mode'} + this.onThemeChange()} + value={isDarkMode} /> + {'Dark Mode'} + + +
+ +
+
+ ) } } +export const SidemenuScreen = wrapTheme(Sidemenu); const styles = StyleSheet.create({ container: { flex: 1, }, + switchContainer: { + flexDirection: 'row', + justifyContent: 'space-evenly', + alignItems: 'center', + } }); diff --git a/App/theme/themeProvider.js b/App/theme/themeProvider.js index d80d1eb..c3e2370 100644 --- a/App/theme/themeProvider.js +++ b/App/theme/themeProvider.js @@ -1,4 +1,38 @@ -import THEMES from './themes.json'; +import React, { useContext, useState, useEffect } from 'react'; -export const themes = THEMES; -export const theme = THEMES[1]; +export const ThemeContext = React.createContext(); + +import storageService from '../utils/storageService'; + + +import Themes from './themes.json'; + + + +export const ThemeContextProvider = ({ children }) => { + const [themeID, setThemeID] = useState(); + + useEffect(() => { + (async () => { + const storedThemeID = await storageService.getThemeId(); + if (storedThemeID) setThemeID(storedThemeID); + else setThemeID(Themes[0].key); + })(); + }, []); + return ( + + {!!themeID ? children : null} + + ); + }; + + export function wrapTheme(Component) { + return props => { + const { themeID, setThemeID } = useContext(ThemeContext); + const getTheme = themeID => Themes.find(theme => theme.key === themeID); + const setTheme = themeID => setThemeID(themeID); + + return ; + }; + } \ No newline at end of file diff --git a/App/theme/themes.json b/App/theme/themes.json index bb8b7b1..4dd3572 100644 --- a/App/theme/themes.json +++ b/App/theme/themes.json @@ -1,22 +1,12 @@ [ { - "key": "MAASTRICHT BLUE", - "backgroundColor": "#011627", - "color": "#ffffff" + "key": "Light Mode", + "backgroundColor": "white", + "color": "black" }, { - "key": "MAXIMUM BLUE GREEN", - "backgroundColor": "#2EC4B6", - "color": "#ffffff" - }, - { - "key": "ROSE MADDER", - "backgroundColor": "#E71D36", - "color": "#ffffff" - }, - { - "key": "BRIGHT YELLOW (CRAYOLA)", - "backgroundColor": "#FF9F1C", - "color": "#1F2D3D" + "key": "Dark Mode", + "backgroundColor": "#24292e", + "color": "white" } ] \ No newline at end of file diff --git a/App/utils/storageService.js b/App/utils/storageService.js index c7f284b..7ae5d5d 100644 --- a/App/utils/storageService.js +++ b/App/utils/storageService.js @@ -14,6 +14,19 @@ const getApiKey = async () => { } }; +const setThemeId = id =>{ + AsyncStorage.setItem('theme_id', id); +} + +const getThemeId = async () => { + try { + const themeId = await AsyncStorage.getItem('theme_id'); + return themeId; + } catch (error) { + return error; + } +}; + const clearApiKey = async () => { await AsyncStorage.removeItem('api_key'); } @@ -21,5 +34,7 @@ const clearApiKey = async () => { export default { setApiKey, getApiKey, - clearApiKey + clearApiKey, + setThemeId, + getThemeId }; diff --git a/README.md b/README.md index 762cb58..d93a3ed 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@
Start Your Next React Native Project In Seconds
-
A highly scalable, redux state management, sagas middleware integrated setup focus on performance and best practices
+
A highly scalable, redux state management, sagas middleware, Dark/Light theme mode integrated setup focus on performance and best practices

@@ -33,7 +33,7 @@ # React Native Boilerplate -React Native boilerplate using react-native-cli with react-navigation, redux state management, redux-saga middleware and auth flow mechanism with drawer-tab navigation layout. +React Native boilerplate using react-native-cli with react-navigation, redux state management, redux-saga middleware and auth flow mechanism with drawer-tab navigation layout. Dark & Light theme switch mechanism using react context and useState Hooks. ## Prerequisites @@ -83,7 +83,7 @@ react-native run - redux - react-redux - redux-saga - +- React Hooks ### React-Native Debugger ![React Native Debugger](https://user-images.githubusercontent.com/3001525/29451479-6621bf1a-83c8-11e7-8ebb-b4e98b1af91c.png)