import { useState, useEffect } from 'react'; export type ThemeSelectOptions = 'light' | 'dark' | 'auto'; export type StoredThemeOptions = ThemeSelectOptions | null; export type UseThemeResult = [ ThemeSelectOptions, (selectedTheme: ThemeSelectOptions) => void, ]; export const useTheme = (): UseThemeResult => { const prefersDarkScheme = window.matchMedia( '(prefers-color-scheme: dark)' ).matches; const storedTheme = localStorage.getItem( '--theme-palette' ) as StoredThemeOptions; const [theme, changeTheme] = useState( storedTheme || 'auto' ); useEffect(() => { document.documentElement.classList.remove('dark', 'light', 'auto'); if (theme === 'auto') { document.documentElement.classList.add( prefersDarkScheme ? 'dark' : 'light' ); } else { document.documentElement.classList.add(theme); } localStorage.setItem('--theme-palette', theme); }, [theme]); useEffect(() => { const beforePrintListener = () => { document.documentElement.classList.remove('dark'); document.documentElement.classList.add('light'); }; const afterPrintListener = () => { document.documentElement.classList.remove('light'); let localtheme; if (localStorage.getItem('--theme-palette') === 'auto') { localtheme = prefersDarkScheme ? 'dark' : 'light'; } else { localtheme = localStorage.getItem('--theme-palette'); } document.documentElement.classList.add(localtheme || theme); }; window.addEventListener('beforeprint', beforePrintListener); window.addEventListener('afterprint', afterPrintListener); return () => { window.removeEventListener('beforeprint', beforePrintListener); window.removeEventListener('afterprint', afterPrintListener); }; }, []); return [theme, changeTheme]; }; export default useTheme;