@flexnative/theme-context
Version:
React ThemeContext
133 lines (132 loc) • 5.21 kB
TypeScript
/**
* @file ThemeProvider.tsx
* @author Redon Alla <redon.alla@gmail.com>
* @createDate 2023-06-04 21:29:02
* @modifyDate 2025-03-02 18:36:42
* @description Provides theming capabilities to the application through a React Context.
*
* This file defines the `ThemeProvider` component, which is responsible for
* managing the application's theme and making it available to child components
* via a React Context. It allows for dynamic theme switching, color scheme
* management, and persisting theme preferences.
*/
import React from 'react';
import { ColorSchemeName } from 'react-native';
import { BaseTheme, ThemeProviderProps } from './props';
/**
* Defines the state properties for the ThemeProvider component.
*
* This type combines the base theme state with any additional custom state
* properties defined by the consumer of the ThemeProvider.
*
* @template TColors The type for the custom colors in the theme.
* @template TState An optional type for additional state properties, defaulting to an empty object.
* @property {BaseTheme<TColors>} [theme] - The current theme object. It is optional to allow for asynchronous loading.
*/
type StateProps<TColors, TState = {}> = {
theme?: BaseTheme<TColors>;
} & TState;
/**
* ThemeProvider Component
*
* Provides a React Context for managing the application's theme. This component
* allows you to define, switch, and persist themes and color schemes.
*
* @template TColors - An optional type to extend the base colors with custom color properties.
* @extends React.PureComponent<ThemeProviderProps<TColors>, StateProps<TColors>>
* @example
* ```typescript
* // Example of extending the BaseColors
* interface MyColors {
* myCustomColor: ColorValue;
* }
*
* // Example of using the ThemeProvider
* <ThemeProvider<MyColors>
* onLoad={async () => {
* // Implement your logic to load the theme from storage
* const savedTheme = await AsyncStorage.getItem('theme');
* if (savedTheme) {
* this.setState({ theme: JSON.parse(savedTheme) });
* }
* return Promise.resolve();
* }}
* onChangeColorScheme={async (scheme) => {
* // Implement your logic to persist the color scheme
* await AsyncStorage.setItem('colorScheme', scheme);
* console.log('colorScheme saved:', scheme);
* return Promise.resolve();
* }}
* onChangeTheme={async (theme) => {
* // Implement your logic to persist the theme
* await AsyncStorage.setItem('theme', JSON.stringify(theme));
* console.log('Theme saved:', theme);
* return Promise.resolve();
* }}
* setColors={async (colors) => {
* //Implement your logic to update only the colors of the theme.
* const newTheme = {...this.state.theme, colors}
* this.onChangeTheme(newTheme)
* return Promise.resolve()
* }}
* >
* <MyApp />
* </ThemeProvider>
* ```
*/
export default abstract class ThemeProvider<TColors, TState> extends React.PureComponent<ThemeProviderProps<TColors>, StateProps<TColors, TState>> {
constructor(props: ThemeProviderProps<TColors>);
componentDidMount(): Promise<void>;
/**
* onLoad - Lifecycle method called when the component is mounted.
*
* This abstract method should be implemented to load the theme from storage.
* It allows you to fetch and apply a previously saved theme.
*
* @see Example <https://redonalla.github.io/flexnative/docs/theme/examples>
*
* @abstract
* @returns {Promise<void>} A promise that resolves when the theme has been loaded.
* @example
* ```typescript
* async onLoad() {
* const savedTheme = await AsyncStorage.getItem('theme');
* if (savedTheme) {
* this.setState({ theme: JSON.parse(savedTheme) });
* }
* }
* ```
*/
protected abstract onLoad(): Promise<void>;
/**
* onChangeColorScheme - Method to change the color scheme.
*
* This abstract method should be implemented to handle changes in the color scheme
* (e.g., 'light' or 'dark'). It allows you to update the color scheme and persist
* the user's preference.
*
* @abstract
* @param {ColorSchemeName} colorScheme - The new color scheme to apply.
* @returns {Promise<void>} A promise that resolves when the color scheme has been changed.
* @example
* ```typescript
* async onChangeColorScheme(colorScheme: ColorSchemeName) {
* await AsyncStorage.setItem('colorScheme', colorScheme);
* console.log('colorScheme saved:', colorScheme);
* }
* ```
*/
protected abstract onChangeColorScheme(colorScheme: ColorSchemeName): Promise<void>;
/**
* onChangeTheme - Method to change the theme.
*
* This method can be overridden to handle changes in the theme.
* It enables you to update the theme object and persist the user's chosen theme.
*
* @param {T} arg - The new theme to apply.
* @returns {Promise<void>} A promise that resolves when the theme has been changed.
*/
protected abstract onChangeTheme<T>(arg: T): Promise<void>;
render(): React.JSX.Element;
}
export {};