@wise/components-theming
Version:
Provides theming support for the Wise Design system components
55 lines (52 loc) • 1.98 kB
JavaScript
import { useContext, useState, useEffect, useMemo } from 'react';
import { ThemedChildren } from './ThemedChildren.mjs';
import { DEFAULT_SCREEN_MODE, DEFAULT_BASE_THEME } from './const.mjs';
import { normalizeTheme, getThemeClassName } from './helpers.mjs';
import { ThemeContext } from './ThemeProviderContext.mjs';
import { jsx } from 'react/jsx-runtime';
const themeClass = /\bnp-theme-[a-z-]+\b/g;
const ThemeProvider = ({
theme: initialTheme = DEFAULT_BASE_THEME,
screenMode: initialScreenMode = DEFAULT_SCREEN_MODE,
isNotRootProvider: isLocal = false,
children,
className = undefined
}) => {
const isContextRoot = useContext(ThemeContext) === undefined;
const [theme, setTheme] = useState(normalizeTheme(initialTheme));
const [screenMode, setScreenMode] = useState(initialScreenMode);
// Update state when props change (for controlled usage)
useEffect(() => {
setTheme(normalizeTheme(initialTheme));
}, [initialTheme]);
useEffect(() => {
setScreenMode(initialScreenMode);
}, [initialScreenMode]);
// useEffect hook used to apply the theme class to the HTML element
useEffect(() => {
if (!isLocal && isContextRoot) {
// Remove all the theme classes from the documentElement
document.documentElement.className.match(themeClass)?.forEach(item => {
document.documentElement.classList.remove(item);
});
getThemeClassName(theme, screenMode).split(' ').forEach(item => {
document.documentElement.classList.add(item);
});
}
}, [isLocal, isContextRoot, theme, screenMode]);
const contextValue = useMemo(() => ({
theme,
screenMode,
setTheme,
setScreenMode
}), [theme, screenMode, setTheme, setScreenMode]);
return /*#__PURE__*/jsx(ThemeContext.Provider, {
value: contextValue,
children: /*#__PURE__*/jsx(ThemedChildren, {
className: className,
children: children
})
});
};
export { ThemeProvider };
//# sourceMappingURL=ThemeProvider.mjs.map