import { useEffect , useMemo , useState } from 'react' ; import * as themes from '../themes' ; import { nicinabox as defaultDarkScheme } from 'redux-devtools-themes' ; import * as baseSchemes from 'base16' ; import * as additionalSchemes from '../colorSchemes' ; import invertColors from '../utils/invertColors' ; import { Theme as ThemeBase } from '../themes/default' ; export const schemes = { ... baseSchemes , ... additionalSchemes } ; export const listSchemes = ( ) => Object . keys ( schemes ) . slice ( 1 ) . sort ( ) ; export const listThemes = ( ) => Object . keys ( themes ) ; export type ThemeName = keyof typeof themes ; export type SchemeName = keyof typeof schemes ; export interface ThemeData { theme : keyof typeof themes ; scheme : keyof typeof schemes ; colorPreference : 'auto' | 'light' | 'dark' ; } export interface ThemeFromProvider extends ThemeBase { type : keyof typeof themes ; light : boolean ; } const getTheme = ( type , scheme , light ) : ThemeFromProvider => { let colors ; if ( scheme === 'default' ) { colors = light ? schemes . default : defaultDarkScheme ; } else { colors = schemes [ scheme ] ; if ( light ) colors = invertColors ( colors ) ; } let theme = { type , light , ... themes . default ( colors ) , } ; if ( type !== 'default' ) { theme = { ... theme , ... themes [ type ] ( colors ) } ; } return theme ; } ; export const useTheme = ( { theme : type , scheme , colorPreference , } ) : ThemeFromProvider => { const [ prefersDarkColorScheme , setPrefersDarkColorScheme ] = useState ( window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ) ; useEffect ( ( ) => { const mediaQuery = window . matchMedia ( '(prefers-color-scheme: dark)' ) ; const handleChange = ( { matches } ) => { setPrefersDarkColorScheme ( matches ) ; } ; mediaQuery . addEventListener ( 'change' , handleChange ) ; return ( ) => mediaQuery . removeEventListener ( 'change' , handleChange ) ; } , [ ] ) ; const light = useMemo ( ( ) => colorPreference === 'auto' ? ! prefersDarkColorScheme : colorPreference === 'light' , [ colorPreference , prefersDarkColorScheme ] ) ; return getTheme ( type , scheme , light ) ; } ;