chore: sync mui theme mode with document

This commit is contained in:
2025-12-27 17:57:45 +00:00
parent 4a12a6f2dd
commit 15d8fa4aff
2 changed files with 18 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
'use client'
import { useMemo, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { CssBaseline, ThemeProvider as MuiThemeProvider } from '@mui/material'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { lightTheme, darkTheme } from '@/theme/mui-theme'
@@ -21,17 +21,25 @@ export function Providers({ children }: { children: React.ReactNode }) {
const [mode, setMode] = useState<ThemeMode>('system')
const theme = useMemo(() => {
const resolvedMode = useMemo<Exclude<ThemeMode, 'system'>>(() => {
if (mode === 'system') {
// Detect system preference
const isDark = typeof window !== 'undefined'
? window.matchMedia('(prefers-color-scheme: dark)').matches
: false
return isDark ? darkTheme : lightTheme
return typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light'
}
return mode === 'dark' ? darkTheme : lightTheme
return mode
}, [mode])
const theme = useMemo(() => (resolvedMode === 'dark' ? darkTheme : lightTheme), [resolvedMode])
useEffect(() => {
const root = document.documentElement
root.dataset.theme = resolvedMode
root.style.colorScheme = resolvedMode
}, [resolvedMode])
const toggleTheme = () => {
setMode(current => {
if (current === 'light') return 'dark'
@@ -41,7 +49,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
}
return (
<ThemeContext.Provider value={{ mode, setMode, toggleTheme }}>
<ThemeContext.Provider value={{ mode, resolvedMode, setMode, toggleTheme }}>
<MuiThemeProvider theme={theme}>
<CssBaseline />
<QueryClientProvider client={queryClient}>

View File

@@ -4,6 +4,7 @@ export type ThemeMode = 'light' | 'dark' | 'system'
export interface ThemeContextType {
mode: ThemeMode
resolvedMode: Exclude<ThemeMode, 'system'>
setMode: (mode: ThemeMode) => void
toggleTheme: () => void
}