themesx
Version:
<h1 align="center">ThemesX</h1>
86 lines (85 loc) • 3.35 kB
JavaScript
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 };