2025-08-05 12:35:40 +07:00

121 lines
3.3 KiB
TypeScript

'use client'
// React Imports
import { useMemo } from 'react'
// MUI Imports
import { deepmerge } from '@mui/utils'
import { ThemeProvider, lighten, darken, createTheme } from '@mui/material/styles'
import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter'
import CssBaseline from '@mui/material/CssBaseline'
import type {} from '@mui/material/themeCssVarsAugmentation' //! Do not remove this import otherwise you will get type errors while making a production build
import type {} from '@mui/lab/themeAugmentation' //! Do not remove this import otherwise you will get type errors while making a production build
// Third-party Imports
import { useMedia } from 'react-use'
import stylisRTLPlugin from 'stylis-plugin-rtl'
// Type Imports
import type { ChildrenType, Direction, SystemMode } from '@core/types'
// Component Imports
import ModeChanger from './ModeChanger'
// Config Imports
import themeConfig from '@configs/themeConfig'
// Hook Imports
import { useSettings } from '@core/hooks/useSettings'
// Core Theme Imports
import defaultCoreTheme from '@core/theme'
type Props = ChildrenType & {
direction: Direction
systemMode: SystemMode
}
const CustomThemeProvider = (props: Props) => {
// Props
const { children, direction, systemMode } = props
// Hooks
const { settings } = useSettings()
const isDark = useMedia('(prefers-color-scheme: dark)', systemMode === 'dark')
// Vars
const isServer = typeof window === 'undefined'
let currentMode: SystemMode
if (isServer) {
currentMode = systemMode
} else {
if (settings.mode === 'system') {
currentMode = isDark ? 'dark' : 'light'
} else {
currentMode = settings.mode as SystemMode
}
}
// Merge the primary color scheme override with the core theme
const theme = useMemo(() => {
const newTheme = {
colorSchemes: {
light: {
palette: {
primary: {
main: settings.primaryColor,
light: lighten(settings.primaryColor as string, 0.2),
dark: darken(settings.primaryColor as string, 0.1)
}
}
},
dark: {
palette: {
primary: {
main: settings.primaryColor,
light: lighten(settings.primaryColor as string, 0.2),
dark: darken(settings.primaryColor as string, 0.1)
}
}
}
},
cssVariables: {
colorSchemeSelector: 'data'
}
}
const coreTheme = deepmerge(defaultCoreTheme(settings, currentMode, direction), newTheme)
return createTheme(coreTheme)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [settings.primaryColor, settings.skin, currentMode])
return (
<AppRouterCacheProvider
options={{
prepend: true,
...(direction === 'rtl' && {
key: 'rtl',
stylisPlugins: [stylisRTLPlugin]
})
}}
>
<ThemeProvider
theme={theme}
defaultMode={systemMode}
modeStorageKey={`${themeConfig.templateName.toLowerCase().split(' ').join('-')}-mui-template-mode`}
>
<>
<ModeChanger systemMode={systemMode} />
<CssBaseline />
{children}
</>
</ThemeProvider>
</AppRouterCacheProvider>
)
}
export default CustomThemeProvider