import React from 'react'; import { Theme as MaterialTheme, ThemeOptions as MaterialThemeOptions, createTheme as createMaterialTheme, ThemeProvider } from "@mui/material/styles"; import { NoData } from '../services'; type CustomTheme = { name: string, custom?: { infoText: string, successText: string, warningText: string, errorText: string, } } export type Theme = MaterialTheme & CustomTheme; export type ThemeOptions = MaterialThemeOptions & CustomTheme; export namespace Themes { /************************************* PROVIDER *************************************/ interface ContextProps { themes: { [name: string]: Theme }, theme: Theme, setTheme: (name: string) => void, } export const Context = React.createContext({ themes: {}, theme: NoData, setTheme: () => { }, }); interface ProviderProps { defaultTheme?: string, themes: ThemesMap, children?: React.ReactNode | React.ReactNode[] | any, } export const Provider: React.FC = ({ defaultTheme, themes, children }) => { const currentDefaultTheme = defaultTheme && themes ? Object.values(themes).find(x => x.name === defaultTheme) : { name: 'light' }; const [themeName, setThemeName] = React.useState( (localStorage && localStorage.getItem('app-theme') && localStorage.getItem('app-theme') !== 'null') ? localStorage.getItem('app-theme') : (currentDefaultTheme?.name ?? '') ); const getTheme = (name: string) => { return name && themes ? Object.values(themes).find(x => x.name === name) : Object.values(themes).length > 0 ? Object.values(themes)[0] : null; } const handleThemeNameChange = (name: string) => { const theme = getTheme(name); if (localStorage) { localStorage.setItem('app-theme', theme?.name ?? ''); } setThemeName(theme?.name ?? 'light'); } const theme = getTheme(themeName); return ( {children} ); } /************************************* THEMES *************************************/ export interface ThemesMap { [name: string]: any, } } export default Themes; export function createTheme(options?: ThemeOptions | undefined, ...args: object[]): Theme { const innerOptions = { ...options, custom: undefined as any } const result = createMaterialTheme(innerOptions, ...args) as Theme; result.name = options?.name ?? ''; result.custom = options?.custom; return result; }