/* eslint no-use-before-define: 0 */ import React, { FC, ReactNode, createContext, useContext, useState, } from 'react'; import windowExists from '@/helpers/window-exists'; export type Mode = string | undefined | 'light' | 'dark'; interface ThemeContextProps { mode?: Mode; toggleMode?: () => void; } export const ThemeContext = createContext({ mode: 'light', }); interface ThemeProviderProps { children: ReactNode; } export const isSystemDarkMode = () => { if (!windowExists()) return false; const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); return ( darkModeMediaQuery.matches && (!window.localStorage.isDarkMode || window.localStorage.isDarkMode === 'true') ); }; export const ThemeProvider: FC = ({ children }) => { const [mode, setMode] = useState(isSystemDarkMode() ? 'dark' : 'light'); function disableTransitionsTemporarily() { document.documentElement.classList.add('[&_*]:!transition-none'); window.setTimeout(() => { document.documentElement.classList.remove('[&_*]:!transition-none'); }, 0); } function toggleMode() { disableTransitionsTemporarily(); const isDarkMode = document.documentElement.classList.toggle('dark'); if (isDarkMode === isSystemDarkMode()) { delete window.localStorage.isDarkMode; setMode('light'); } else { window.localStorage.isDarkMode = isDarkMode; setMode('dark'); } } return ( {children} ); }; export function useTheme(): ThemeContextProps { return useContext(ThemeContext); }