A package that allows you to create React Native StyleSheets with support for Dark/Light/Auto Themes.
- Simple API
- Fully typed
- Builds on top of StyleSheets and Hooks
- Storybook addon to change Theme Mode
Using Yarn
yarn add react-native-themed-stylesheet
Using NPM
npm install --save react-native-themed-stylesheet
Create a type declaration file to merge BaseTheme declaration:
// react-native-themed-stylesheet.d.ts
import 'react-native-themed-stylesheet'
declare module 'react-native-themed-stylesheet' {
export interface BaseTheme {
theme: {
colors: {
primary: string
}
},
constants: { // This is optional. If declared/defined, it will be merge with the current theme.
colors: {
accent: string
}
}
}
}
Using the theme:
// App.tsx
import React from 'react'
import { View, Text, Button } from 'react-native'
import { ThemeProvider, useCreateStyles, useMode, useTheme, useThemes } from 'react-native-themed-stylesheet'
const DefaultComponent: React.FC = () => {
const { colors } = useTheme()
const [mode, setMode] = useMode()
const [themes, setThemes] = useThemes()
console.log('Current Mode:', mode)
console.log('Themes:', themes)
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: colors.primary, backgroundColor: colors.accent }}>Hello World</Text>
<Button title='Dark Mode' onPress={() => setMode('dark')}/>
<Button title='Light Mode' onPress={() => setMode('light')}/>
<Button title='Auto Mode' onPress={() => setMode('auto')}/>
<Button title='Change Themes' onPress={
() => setThemes({
light: {
colors: { primary: '#c1c1c1' }
},
dark: {
colors: { primary: '#c2c2c2' }
},
constants: {
colors: { accent: '#c3c3c3' }
}
})
}
/>
</View>
)
}
const ComponentWithUseCreateStyles: React.FC = () => {
const [styles, theme] = useCreateStyles(({ colors }) => {
text: {
color: colors.primary,
backgroundColor: colors.accent
}
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={styles.text}>Hello World</Text>
<Text style={{ color: theme.colors.accent }}>Hello World 2</Text>
</View>
)
}
const themes = {
dark: {
colors: {
primary: '#000'
}
},
light: {
colors: {
primary: '#fff'
}
},
constants: {
colors: {
accent: '#c0c0c0'
}
}
}
const App: React.FC = () => (
<ThemeProvider themes={themes}>
<DefaultComponent />
<ComponentWithUseCreateStyles />
</ThemeProvider>
)
export default App
// storybook.js
import {
getStorybookUI,
configure
} from '@storybook/react-native'
import 'react-native-themed-stylesheet/storybook/register'
configure(() => {
require('path/to/some/story')
}, module)
const StorybookUIRoot = getStorybookUI()
export default StorybookUIRoot // Make sure to use this component within ThemeProvider.
Component to provide ThemeContext.
Props
themes
: An object of typeThemes
:
type Themes = {
dark: BaseTheme['theme']
light: BaseTheme['theme']
constants?: BaseTheme['constants']
}
mode
: An optional string of typeThemeMode
: (Default: 'auto')
type ThemeMode = 'auto' | 'dark' | 'light'
Hook to create themed stylesheets.
Parameters
createStyles
: A function that receives the current theme and returns an object of typeStyles
.
type Styles = {
[prop: string]: ViewStyle | TextStyle | ImageStyle
}
type Theme = (BaseTheme['constants'] & BaseTheme['theme']) | BaseTheme['theme']
Returns
[styles, theme]: [StyleSheet.NamedStyles<Styles>, Theme]
Hook to get access to current mode.
Returns
[mode, setMode]: [ThemeMode, (newMode: ThemeMode) => void]
Hook to get access to current theme.
Returns
theme: Theme
Hook to get access to themes.
Returns
[themes, setThemes]: [Themes, (newThemes: Themes) => void]