React Native Theme Provider .Simple Theme Provider for React Native
yarn add @pavelgric/react-native-theme-provider
// themes.js
const blueTheme = {
colors: {
primary: 'blue'
}
}
const redTheme = {
colors: {
primary: 'red'
}
}
// you can have as many themes as you want
export const themes = {
blue: blueTheme,
red: redTheme,
};
// App.js
import React from 'react';
import { ThemeProvider } from '@pavelgric/react-native-theme-provider';
import { themes } from './themes';
export default App = () => {
return(
<ThemeProvider
themes={themes}
initialTheme="red"
>
<InnerComponent />
</ThemeProvider>
)
}
// InnerComponent.js
import React from 'react';
import { View } from 'react-native';
import { createStyle, useStyle } from '@pavelgric/react-native-theme-provider';
// create styleCreator, the passed 't' is current theme object
const styleCreator = createStyle((t) => ({
container: {
backgroundColor: t.colors.primary
},
}));
export default InnerComponent = () => {
// pass the styleCreator
const styles = useStyle(styleCreator);
return (
<View style={styles.container} />
)
}
Alternatively you can use createUseStyle
helper function to remove few lines of code
// InnerComponent.js
import React from 'react';
import { View } from 'react-native';
import { createUseStyle } from '@pavelgric/react-native-theme-provider';
// createUseStyle basically returns (fn) => useStyle(fn)
const useStyle = createUseStyle((t) => ({
container: {
backgroundColor: t.colors.primary
},
}));
export default InnerComponent = () => {
const styles = useStyle();
return (
<View style={styles.container} />
)
}
// SomeComponent.js
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { useThemeDispatch, useTheme } from '@pavelgric/react-native-theme-provider';
export default SomeComponent = () => {
// selectedTheme is the key of selected theme
// themes is the whole themes object
// t is current theme object
const { selectedTheme, themes, t } = useTheme();
// to change theme
const { setTheme } = useThemeDispatch();
// to access current theme object, or use t
const themeObj = themes[selectedTheme];
return(
<View>
<Text>{`current theme is ${selectedTheme}`}</Text>
<TouchableOpacity onPress={() => {
const nextTheme = selectedTheme === 'red'? 'blue' : 'red'
setTheme(nextTheme)
}}>
<Text>Change theme</Text>
</TouchableOpacity>
</View>
)
}
The library provides few functions to help passing down the Theme type
Define your themes and use creator functions
// themes.js
import {
createStyleCreator,
createUseStyleCreator,
createUseTheme,
createUseThemeDispatch,
useStyle,
} from '@pavelgric/react-native-theme-provider';
const blueTheme = {
colors: {
primary: 'blue'
}
}
const redTheme = {
colors: {
primary: 'red'
}
}
// you can have as many themes as you want
export const themes = {
blue: blueTheme,
red: redTheme,
};
export type Themes = typeof themes;
// useStyle does not depend on Theme, this is just to make it also accessible from here
export { useStyle };
export const createStyle = createStyleCreator<Themes>();
export const createUseStyle = createUseStyleCreator<Themes>();
export const useTheme = createUseTheme<Themes>();
export const useThemeDispatch = createUseThemeDispatch<Themes>();
now instead of importing the functions directly from this package
import { createStyle, createUseStyle, useTheme, useThemeDispatch, useStyle } from '@pavelgric/react-native-theme-provider';
you import them from the themes.js
file
import { createStyle, createUseStyle, useTheme, useThemeDispatch, useStyle } from './path/to/themes.js';
now these functions are typed
import { createStyle, /* or createUseStyle */ } from './path/to/themes.js';
// t is now of type Theme
const styleCreator = createStyle((t) => ({
container: {
backgroundColor: t.colors.primary
},
}));
Use creator function to ensure all theme objects have same shape, otherwise keys that are not present in all theme objects will be excluded by Typescript.
// color pallete
const pallete = {
red: 'red',
blue: 'blue'
}
type Color =
| 'primary'
type Props = {
colors: Record<Color, string>;
};
export const createTheme = (props: Props) => ({
colors: props.colors
})
const redThemeColors = {
primary: pallete.red
};
const blueThemeColors = {
primary: pallete.blue
};
export const redTheme = createTheme({colors: redThemeColors});
export const blueTheme = createTheme({colors: blueThemeColors});
export const themes = {
redTheme,
blueTheme
}
It would be nice to have function that would warn about missing keys, but I didn't find way how to do that. Ideally something like:
const blueTheme = {
colors: {
primary: 'blue',
secondary: 'yellow'
}
}
const redTheme = {
colors: {
primary: 'red'
}
}
export const themes = createThemes({
blueTheme,
redTheme, // warn red theme is missing key 'secondary'
})
See example for semi-complete solution
to run example, you need to install dependencies on package level, so navigate to this package in terminal and run
yarn && cd example && yarn && cd ios && pod install
;
Author: CptFabulouso
Source Code: https://github.com/CptFabulouso/react-native-theme-provider
Article covers: How native is react native?, React Native vs (Ionic, Cordova), Similarities and difference between React Native and Native App Development.
Skenix is providing React Native Development Services with qualified React Native App Developers. Get the best React Native App Development Services.
Are you a mobile app developer looking for more efficient tools for your projects? Mobile app development is getting tougher and tougher as the market continues to grow. As a developer, you need to develop Apps which meet the demands of your users. To achieve this, adopt the right tools, like the React Native development framework.
Looking for top React Native mobile app development company in USA for Startups & Enterprise? Find out the top list of React Native mobile app development company in USA.
Hire top react native app development company in New York to build and develop custom react native mobile apps for Android & iOS with the latest features.