11import { createContext , useContext , useEffect , useState , useMemo } from 'react'
2+ import { getCookie , setCookie , removeCookie } from '@/lib/cookies'
23
34type Theme = 'dark' | 'light' | 'system'
45type ResolvedTheme = Exclude < Theme , 'system' >
56
67const DEFAULT_THEME = 'system'
8+ const THEME_COOKIE_NAME = 'vite-ui-theme'
9+ const THEME_COOKIE_MAX_AGE = 60 * 60 * 24 * 365 // 1 year
710
811type ThemeProviderProps = {
912 children : React . ReactNode
@@ -27,16 +30,16 @@ const initialState: ThemeProviderState = {
2730 resetTheme : ( ) => { } ,
2831}
2932
30- const ThemeProviderContext = createContext < ThemeProviderState > ( initialState )
33+ const ThemeContext = createContext < ThemeProviderState > ( initialState )
3134
3235export function ThemeProvider ( {
3336 children,
3437 defaultTheme = DEFAULT_THEME ,
35- storageKey = 'vite-ui-theme' ,
38+ storageKey = THEME_COOKIE_NAME ,
3639 ...props
3740} : ThemeProviderProps ) {
3841 const [ theme , _setTheme ] = useState < Theme > (
39- ( ) => ( localStorage . getItem ( storageKey ) as Theme ) || defaultTheme
42+ ( ) => ( getCookie ( storageKey ) as Theme ) || defaultTheme
4043 )
4144
4245 // Optimized: Memoize the resolved theme calculation to prevent unnecessary re-computations
@@ -73,16 +76,16 @@ export function ThemeProvider({
7376 } , [ theme , resolvedTheme ] )
7477
7578 const setTheme = ( theme : Theme ) => {
76- localStorage . setItem ( storageKey , theme )
79+ setCookie ( storageKey , theme , THEME_COOKIE_MAX_AGE )
7780 _setTheme ( theme )
7881 }
7982
8083 const resetTheme = ( ) => {
81- localStorage . removeItem ( storageKey )
84+ removeCookie ( storageKey )
8285 _setTheme ( DEFAULT_THEME )
8386 }
8487
85- const value = {
88+ const contextValue = {
8689 defaultTheme,
8790 resolvedTheme,
8891 resetTheme,
@@ -91,15 +94,15 @@ export function ThemeProvider({
9194 }
9295
9396 return (
94- < ThemeProviderContext . Provider { ...props } value = { value } >
97+ < ThemeContext value = { contextValue } { ...props } >
9598 { children }
96- </ ThemeProviderContext . Provider >
99+ </ ThemeContext >
97100 )
98101}
99102
100103// eslint-disable-next-line react-refresh/only-export-components
101104export const useTheme = ( ) => {
102- const context = useContext ( ThemeProviderContext )
105+ const context = useContext ( ThemeContext )
103106
104107 if ( context === undefined )
105108 throw new Error ( 'useTheme must be used within a ThemeProvider' )
0 commit comments