@ -1,7 +1,13 @@
import { createContext , useEffect , useState , useCallback , type ReactNode } from 'react' ;
import {
import { type Theme , themes } from '~/styles/themes.css' ;
createContext ,
import { themeVars } from '~/styles/vars.css' ;
useEffect ,
import { useAppContext } from './AppProvider' ;
useState ,
useCallback ,
type ReactNode ,
} from "react" ;
import { type Theme , themes } from "~/styles/themes.css" ;
import { themeVars } from "~/styles/vars.css" ;
import { useAppContext } from "./AppProvider" ;
interface ThemeContextValue {
interface ThemeContextValue {
themeName : string ;
themeName : string ;
@ -15,13 +21,13 @@ interface ThemeContextValue {
const ThemeContext = createContext < ThemeContextValue | undefined > ( undefined ) ;
const ThemeContext = createContext < ThemeContextValue | undefined > ( undefined ) ;
function toKebabCase ( str : string ) {
function toKebabCase ( str : string ) {
return str . replace ( /[A-Z]/g , m = > '-' + m . toLowerCase ( ) ) ;
return str . replace ( /[A-Z]/g , ( m ) = > "-" + m . toLowerCase ( ) ) ;
}
}
function applyCustomThemeVars ( theme : Theme ) {
function applyCustomThemeVars ( theme : Theme ) {
const root = document . documentElement ;
const root = document . documentElement ;
for ( const [ key , value ] of Object . entries ( theme ) ) {
for ( const [ key , value ] of Object . entries ( theme ) ) {
if ( key === 'name' ) continue ;
if ( key === "name" ) continue ;
root . style . setProperty ( ` --color- ${ toKebabCase ( key ) } ` , value ) ;
root . style . setProperty ( ` --color- ${ toKebabCase ( key ) } ` , value ) ;
}
}
}
}
@ -33,7 +39,7 @@ function clearCustomThemeVars() {
}
}
function getStoredCustomTheme ( ) : Theme | undefined {
function getStoredCustomTheme ( ) : Theme | undefined {
const themeStr = localStorage . getItem ( 'custom-theme' ) ;
const themeStr = localStorage . getItem ( "custom-theme" ) ;
if ( ! themeStr ) return undefined ;
if ( ! themeStr ) return undefined ;
try {
try {
const parsed = JSON . parse ( themeStr ) ;
const parsed = JSON . parse ( themeStr ) ;
@ -44,93 +50,62 @@ function getStoredCustomTheme(): Theme | undefined {
}
}
}
}
export function ThemeProvider ( {
export function ThemeProvider ( { children } : { children : ReactNode } ) {
children ,
let defaultTheme = useAppContext ( ) . defaultTheme ;
} : {
let initialTheme = localStorage . getItem ( "theme" ) ? ? defaultTheme ;
children : ReactNode ;
} ) {
<< << << < HEAD
let defaultTheme = useAppContext ( ) . defaultTheme
let initialTheme = localStorage . getItem ( "theme" ) ? ? defaultTheme
=== === =
>>> >>> > fbaa6a6 ( Rework theme provider to provide the actual Theme object throughtout the app , in addition to the name )
const [ themeName , setThemeName ] = useState ( initialTheme ) ;
const [ themeName , setThemeName ] = useState ( initialTheme ) ;
const [ currentTheme , setCurrentTheme ] = useState < Theme > ( ( ) = > {
const [ currentTheme , setCurrentTheme ] = useState < Theme > ( ( ) = > {
if ( initialTheme === 'custom' ) {
if ( initialTheme === "custom" ) {
const customTheme = getStoredCustomTheme ( ) ;
const customTheme = getStoredCustomTheme ( ) ;
<< << << < HEAD
return customTheme || themes [ defaultTheme ] ;
return customTheme || themes [ defaultTheme ] ;
}
}
return themes [ initialTheme ] || themes [ defaultTheme ] ;
return themes [ initialTheme ] || themes [ defaultTheme ] ;
=== === =
return customTheme || themes . yuu ;
}
return themes [ initialTheme ] || themes . yuu ;
>>> >>> > fbaa6a6 ( Rework theme provider to provide the actual Theme object throughtout the app , in addition to the name )
} ) ;
} ) ;
const setTheme = ( newThemeName : string ) = > {
const setTheme = ( newThemeName : string ) = > {
setThemeName ( newThemeName ) ;
setThemeName ( newThemeName ) ;
if ( newThemeName === 'custom' ) {
if ( newThemeName === "custom" ) {
const customTheme = getStoredCustomTheme ( ) ;
const customTheme = getStoredCustomTheme ( ) ;
if ( customTheme ) {
if ( customTheme ) {
setCurrentTheme ( customTheme ) ;
setCurrentTheme ( customTheme ) ;
} else {
} else {
// Fallback to default theme if no custom theme found
// Fallback to default theme if no custom theme found
<< << << < HEAD
setThemeName ( defaultTheme ) ;
setThemeName ( defaultTheme ) ;
setCurrentTheme ( themes [ defaultTheme ] ) ;
setCurrentTheme ( themes [ defaultTheme ] ) ;
=== === =
setThemeName ( 'yuu' ) ;
setCurrentTheme ( themes . yuu ) ;
>>> >>> > fbaa6a6 ( Rework theme provider to provide the actual Theme object throughtout the app , in addition to the name )
}
}
} else {
} else {
const foundTheme = themes [ newThemeName ] ;
const foundTheme = themes [ newThemeName ] ;
if ( foundTheme ) {
if ( foundTheme ) {
<< << << < HEAD
localStorage . setItem ( "theme" , newThemeName ) ;
localStorage . setItem ( 'theme' , newThemeName )
setCurrentTheme ( foundTheme ) ;
setCurrentTheme ( foundTheme ) ;
}
}
}
}
}
} ;
const resetTheme = ( ) = > {
const resetTheme = ( ) = > {
setThemeName ( defaultTheme )
setThemeName ( defaultTheme ) ;
localStorage . removeItem ( 'theme' )
localStorage . removeItem ( "theme" ) ;
setCurrentTheme ( themes [ defaultTheme ] )
setCurrentTheme ( themes [ defaultTheme ] ) ;
=== === =
} ;
setCurrentTheme ( foundTheme ) ;
}
}
>>> >>> > fbaa6a6 ( Rework theme provider to provide the actual Theme object throughtout the app , in addition to the name )
}
const setCustomTheme = useCallback ( ( customTheme : Theme ) = > {
const setCustomTheme = useCallback ( ( customTheme : Theme ) = > {
localStorage . setItem ( 'custom-theme' , JSON . stringify ( customTheme ) ) ;
localStorage . setItem ( "custom-theme" , JSON . stringify ( customTheme ) ) ;
applyCustomThemeVars ( customTheme ) ;
applyCustomThemeVars ( customTheme ) ;
setThemeName ( 'custom' ) ;
setThemeName ( "custom" ) ;
<< << << < HEAD
localStorage . setItem ( "theme" , "custom" ) ;
localStorage . setItem ( 'theme' , 'custom' )
=== === =
>>> >>> > fbaa6a6 ( Rework theme provider to provide the actual Theme object throughtout the app , in addition to the name )
setCurrentTheme ( customTheme ) ;
setCurrentTheme ( customTheme ) ;
} , [ ] ) ;
} , [ ] ) ;
const getCustomTheme = ( ) : Theme | undefined = > {
const getCustomTheme = ( ) : Theme | undefined = > {
return getStoredCustomTheme ( ) ;
return getStoredCustomTheme ( ) ;
}
} ;
useEffect ( ( ) = > {
useEffect ( ( ) = > {
const root = document . documentElement ;
const root = document . documentElement ;
root . setAttribute ( 'data-theme' , themeName ) ;
root . setAttribute ( "data-theme" , themeName ) ;
<< << << < HEAD
=== === =
localStorage . setItem ( 'theme' , themeName ) ;
>>> >>> > fbaa6a6 ( Rework theme provider to provide the actual Theme object throughtout the app , in addition to the name )
if ( themeName === 'custom' ) {
if ( themeName === "custom" ) {
applyCustomThemeVars ( currentTheme ) ;
applyCustomThemeVars ( currentTheme ) ;
} else {
} else {
clearCustomThemeVars ( ) ;
clearCustomThemeVars ( ) ;
@ -138,18 +113,16 @@ export function ThemeProvider({
} , [ themeName , currentTheme ] ) ;
} , [ themeName , currentTheme ] ) ;
return (
return (
<< << << < HEAD
< ThemeContext.Provider
< ThemeContext.Provider value = { {
value = { {
themeName ,
themeName ,
theme : currentTheme ,
theme : currentTheme ,
setTheme ,
setTheme ,
resetTheme ,
resetTheme ,
setCustomTheme ,
setCustomTheme ,
getCustomTheme
getCustomTheme ,
} } >
} }
=== === =
>
< ThemeContext.Provider value = { { themeName , theme : currentTheme , setTheme , setCustomTheme , getCustomTheme } } >
>>> >>> > fbaa6a6 ( Rework theme provider to provide the actual Theme object throughtout the app , in addition to the name )
{ children }
{ children }
< / ThemeContext.Provider >
< / ThemeContext.Provider >
) ;
) ;