dynamic-theme-context2
v1.0.9
Published
Custom theme with provider
Downloads
485
Maintainers
Readme
Dynamic Theme Context
Dynamic Theme Context is a lightweight library designed to handle dynamic theming for both React and React Native projects. This library allows developers to manage multiple themes effortlessly with support for dark mode, user preferences, and system themes.
Features
- Dynamic theming: Easily switch between themes like light and dark mode.
- TypeScript support: Fully typed for a better development experience.
- Customizable: Extendable theme structure to meet your project's needs.
- Async storage (React Native): Saves user preferences persistently.
Installation
Install the library via npm or yarn:
npm install dynamic-theme-context @react-native-async-storage/async-storage
# or
yarn add dynamic-theme-context @react-native-async-storage/async-storage
Requirements
Below are the library's requirements for React, React Native, and TypeScript environments:
| Dependency | Minimum Version | | ---------------- | --------------- | | React | 16.3.1 | | React Native | 0.64.0 | | TypeScript | 4.4.0 |
Usage Example
Add Your Theme
You can pass your theme data like this:
import React from "react";
import { ThemeProvider } from "dynamic-theme-context";
import { ThemeColorsType } from "dynamic-theme-context/lib/types";
const lightTheme: ThemeColorsType = {
general: {
primary: "#3498db", // Blue
secondary: "#2ecc71", // Green
background: "#ffffff", // White
text: "#2c3e50", // Dark Gray
border: "#bdc3c7", // Light Gray
shadow: "rgba(0, 0, 0, 0.1)",
},
status: {
success: "#27ae60", // Green
error: "#e74c3c", // Red
warning: "#f1c40f", // Yellow
info: "#8e44ad", // Purple
},
components: {
button: {
default: "#2980b9", // Darker blue
hover: "#1abc9c", // Turquoise
disabled: "#95a5a6", // Gray
},
input: {
background: "#ecf0f1", // Light gray
text: "#2c3e50", // Dark gray
border: "#bdc3c7", // Light gray
focus: "#3498db", // Blue
},
card: {
background: "#ffffff", // White
shadow: "rgba(0, 0, 0, 0.1)",
border: "#bdc3c7", // Light gray
},
},
};
const darkTheme: ThemeColorsType = {
general: {
primary: "#9b59b6", // Purple
secondary: "#e67e22", // Orange
background: "#34495e", // Dark blue-gray
text: "#ecf0f1", // Light gray
border: "#7f8c8d", // Gray
shadow: "rgba(0, 0, 0, 0.5)",
},
status: {
success: "#2ecc71", // Green
error: "#e74c3c", // Red
warning: "#f39c12", // Yellow
info: "#3498db", // Blue
},
components: {
button: {
default: "#8e44ad", // Purple
hover: "#9b59b6", // Lighter purple
disabled: "#95a5a6", // Gray
},
input: {
background: "#2c3e50", // Dark gray
text: "#ecf0f1", // Light gray
border: "#7f8c8d", // Gray
focus: "#9b59b6", // Purple
},
card: {
background: "#2c3e50", // Dark gray
shadow: "rgba(0, 0, 0, 0.5)",
border: "#7f8c8d", // Gray
},
},
};
export const themes = [
{ name: "light", themes: lightTheme },
{ name: "dark", themes: darkTheme },
];
function App(): React.JSX.Element {
return (
<ThemeProvider
themes={themes}
defaultTheme="light" // it's optional
>
<Home />
</ThemeProvider>
);
}
export default App;
Extend Theme Colors
If you want to add new colors to current colors;
- create Global.d.ts file and move to src/types location
- open your tsconfig.json file and add these lines
{
"compilerOptions": {
...
"typeRoots": ["./node_modules/@types", "./src/types"]
},
"include": ["src/**/*"]
}
- and add these lines to Global.d.ts file
import "dynamic-theme-context/lib/types";
declare module "dynamic-theme-context/lib/types" {
interface ThemeColorsType {
primarytText?: string; // new color
}
}
Get Theme Data From useTheme hook
Here’s a basic example of how to use dynamic-theme-context
in a React Native project:
import { ThemeProvider, useTheme } from "dynamic-theme-context";
const App = () => {
const { theme, activeTheme, toggleTheme, setTheme } = useTheme();
return (
<View style={{ backgroundColor: theme.general.background }}>
<Text style={{ color: theme.general.text }}>
Current Theme: {activeTheme}
</Text>
<Button onPress={toggleTheme} title="Toggle Theme" />
</View>
);
};
Get Theme Data from StyleSheet
You can access theme data from StyleSheet:
import React from "react";
import { getStyles, useTheme } from "dynamic-theme-context";
import { Button, StyleSheet, Text, View } from "react-native";
import { ThemeColorsType } from "dynamic-theme-context/lib/types";
const App: React.FC = () => {
const { activeTheme, toggleTheme } = useTheme();
const styles = getStyles(createStyles); // it's only rerender when theme changed
return (
<View style={styles.container}>
<Text>Current Theme: {activeTheme}</Text>
<Button onPress={toggleTheme} title="Toggle Theme" />
</View>
);
};
const createStyles = (
theme: ThemeColorsType, // get access theme
activeTheme: string, // get access active theme
isDark: boolean // get access isDark or not info
) =>
StyleSheet.create({
container: {
flex: 1,
backgroundColor: theme.general.background,
alignItems: "center",
justifyContent: "center",
},
});
export default App;
With HOC
If you want, you can access styles with HOC:
import React from "react";
import { useTheme, withStyles } from "dynamic-theme-context";
import { Button, StyleSheet, Text, View } from "react-native";
import { ThemeColorsType } from "dynamic-theme-context/lib/types";
import { WithDynamicStylesProps } from "dynamic-theme-context/lib/hocs/withStyles";
const App: React.FC<
WithDynamicStylesProps<ReturnType<typeof createStyles>>
> = ({ styles }) => {
const { activeTheme, toggleTheme } = useTheme();
return (
<View style={styles.container}>
<Text>Current Theme: {activeTheme}</Text>
<Button onPress={toggleTheme} title="Toggle Theme" />
</View>
);
};
const createStyles = (
theme: ThemeColorsType,
activeTheme: string,
isDark: boolean
) =>
StyleSheet.create({
container: {
flex: 1,
backgroundColor: theme.general.background,
alignItems: "center",
justifyContent: "center",
},
});
export default withStyles(App, createStyles);
License
Dynamic Theme Context is licensed under the MIT License.