UNPKG

themesx

Version:
86 lines (85 loc) 3.35 kB
import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"; const ThemeContext = /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__.createContext(void 0); const ThemeProvider = ({ children, enableSystemTheme = true, defaultTheme = 'system' })=>{ const [theme, setTheme] = __WEBPACK_EXTERNAL_MODULE_react__.useState('system'); const [mounted, setMounted] = __WEBPACK_EXTERNAL_MODULE_react__.useState(false); __WEBPACK_EXTERNAL_MODULE_react__.useEffect(()=>{ const styleElement = document.createElement('style'); styleElement.innerHTML = ` :root { --background-color: #ffffff; --text-color: #000000; } [XtrixUI-theme="dark"] { --background-color: #000000; --text-color: #ffffff; } body { background-color: var(--background-color); color: var(--text-color); transition: background-color 0.3s, color 0.3s; } `; document.head.appendChild(styleElement); const savedTheme = 'undefined' != typeof window && localStorage.getItem('theme'); const initialTheme = savedTheme || defaultTheme; setTheme(initialTheme); applyTheme(initialTheme); setMounted(true); return ()=>{ document.head.removeChild(styleElement); }; }, [ defaultTheme ]); const applyTheme = __WEBPACK_EXTERNAL_MODULE_react__.useCallback((newTheme)=>{ const root = document.documentElement; if ('dark' === newTheme) { root.setAttribute('XtrixUI-theme', 'dark'); root.classList.add('dark'); } else if ('light' === newTheme) { root.setAttribute('XtrixUI-theme', 'light'); root.classList.remove('dark'); } else if (enableSystemTheme) { const systemDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; root.setAttribute('XtrixUI-theme', systemDarkMode ? 'dark' : 'light'); root.classList.toggle('dark', systemDarkMode); } }, [ enableSystemTheme ]); __WEBPACK_EXTERNAL_MODULE_react__.useEffect(()=>{ if (!mounted) return; const handleSystemThemeChange = (e)=>{ if ('system' === theme && enableSystemTheme) applyTheme('system'); }; const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); if ('system' === theme && enableSystemTheme) mediaQuery.addEventListener('change', handleSystemThemeChange); return ()=>{ mediaQuery.removeEventListener('change', handleSystemThemeChange); }; }, [ theme, applyTheme, enableSystemTheme, mounted ]); const updateTheme = (newTheme)=>{ setTheme(newTheme); if ('undefined' != typeof window) localStorage.setItem('theme', newTheme); applyTheme(newTheme); }; if (!mounted) return null; return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__.createElement(ThemeContext.Provider, { value: { theme, setTheme: updateTheme } }, children); }; const useTheme = ()=>{ const context = __WEBPACK_EXTERNAL_MODULE_react__.useContext(ThemeContext); if (!context) throw new Error('useTheme must be used within a ThemeProvider'); return context; }; export { ThemeProvider, useTheme };