UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

178 lines (177 loc) 5.64 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ThemeWrapper = ThemeWrapper; exports.default = Theme; exports.getTheme = getTheme; exports.getThemeClasses = getThemeClasses; exports.setTheme = setTheme; var _parse = _interopRequireDefault(require("core-js-pure/stable/json/parse.js")); var _react = require("react"); var _clsx = _interopRequireDefault(require("clsx")); var _Context = _interopRequireDefault(require("./Context.js")); var _Provider = _interopRequireDefault(require("./Provider.js")); var _componentHelper = require("./component-helper.js"); var _withComponentMarkers = _interopRequireDefault(require("./helpers/withComponentMarkers.js")); var _useMediaQuery = _interopRequireDefault(require("./useMediaQuery.js")); var _useIsomorphicLayoutEffect = _interopRequireDefault(require("./helpers/useIsomorphicLayoutEffect.js")); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function Theme(themeProps) { const context = (0, _react.useContext)(_Context.default); const { children, element, name, variant, size, contrastMode, colorScheme, surface, ...restProps } = themeProps; const prefersDarkColorScheme = (0, _useMediaQuery.default)({ query: '(prefers-color-scheme: dark)', disabled: colorScheme !== 'auto' }); const activeColorScheme = colorScheme === 'auto' ? globalThis.__eufemiaColorScheme || (prefersDarkColorScheme ? 'dark' : 'light') : colorScheme; (0, _useIsomorphicLayoutEffect.default)(() => { delete globalThis.__eufemiaColorScheme; }, []); const theme = (0, _componentHelper.extendPropsWithContext)({ name, variant, size, contrastMode, colorScheme: activeColorScheme, surface }, null, context === null || context === void 0 ? void 0 : context.theme); if (surface === 'initial') { theme.surface = undefined; } return (0, _jsxRuntime.jsx)(_Provider.default, { theme: theme, children: (0, _jsxRuntime.jsx)(ThemeWrapper, { element: element, theme: theme, ...restProps, children: children }) }); } Theme.Context = ({ element, ...themeProps }) => { return (0, _jsxRuntime.jsx)(Theme, { ...themeProps, element: false }); }; (0, _withComponentMarkers.default)(Theme.Context, { _supportsSpacingProps: 'passthrough' }); function ThemeWrapper({ children, theme, element = null, className = null, ...rest }) { const Wrapper = element === false ? _react.Fragment : element || 'div'; const ref = (0, _react.useRef)(null); useSyncBodyColorScheme(theme); useSyncElementColorScheme(ref, theme); const classNames = getThemeClasses(theme, className); const { name, variant, size } = theme; if (Wrapper === _react.Fragment) { return children; } rest['ref'] = ref; return (0, _jsxRuntime.jsx)(Wrapper, { "data-name": name, "data-variant": variant, "data-size": size, className: classNames, ...rest, children: children }); } function getThemeClasses(theme, className = null) { if (!theme) { return className; } const { name, variant, size, contrastMode, colorScheme } = theme; return (0, _clsx.default)(className, 'eufemia-theme', name && `eufemia-theme__${name}` + (variant ? ` eufemia-theme__${name}--${variant}` : ""), contrastMode && 'eufemia-theme__contrast-mode', colorScheme && `eufemia-theme__color-scheme--${colorScheme}`, size && `eufemia-theme__size--${size}`); } function useSyncElementColorScheme(ref, theme) { const colorScheme = theme === null || theme === void 0 ? void 0 : theme.colorScheme; (0, _useIsomorphicLayoutEffect.default)(() => { const el = ref.current; if (!el || !colorScheme) { return; } el.classList.remove('eufemia-theme__color-scheme--light', 'eufemia-theme__color-scheme--dark'); el.classList.add(`eufemia-theme__color-scheme--${colorScheme}`); }, [colorScheme]); } function useSyncBodyColorScheme(theme) { const colorScheme = theme === null || theme === void 0 ? void 0 : theme.colorScheme; (0, _useIsomorphicLayoutEffect.default)(() => { if (typeof document === 'undefined' || !colorScheme) { return; } document.body.classList.remove('eufemia-theme__color-scheme--light', 'eufemia-theme__color-scheme--dark'); document.body.classList.add(`eufemia-theme__color-scheme--${colorScheme}`); }, [colorScheme]); } const STORAGE_KEY = 'eufemia-theme'; function getTheme(defaultTheme = 'ui') { if (typeof window === 'undefined') { return { name: defaultTheme }; } try { const data = window.localStorage.getItem(STORAGE_KEY); const theme = (0, _parse.default)(data !== null && data !== void 0 && data.startsWith('{') ? data : '{}'); const regex = /.*eufemia-theme=([^&]*).*/; const query = window.location.search; const fromQuery = regex.test(query) && (query === null || query === void 0 ? void 0 : query.replace(regex, '$1')) || null; const name = fromQuery || (theme === null || theme === void 0 ? void 0 : theme.name) || defaultTheme; return { ...theme, name }; } catch { return { name: defaultTheme }; } } function setTheme(themeProps, callback) { if (typeof window === 'undefined') { return; } try { const theme = { ...getTheme(), ...themeProps }; window.localStorage.setItem(STORAGE_KEY, JSON.stringify(theme)); callback === null || callback === void 0 || callback(theme); } catch {} } //# sourceMappingURL=Theme.js.map