"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.DISABLE_CSS_TRANSITION = void 0; exports.default = createCssVarsProvider; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _formatMuiErrorMessage2 = _interopRequireDefault(require("@mui/utils/formatMuiErrorMessage")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _deepmerge = _interopRequireDefault(require("@mui/utils/deepmerge")); var _styledEngine = require("@mui/styled-engine"); var _privateTheming = require("@mui/private-theming"); var _ThemeProvider = _interopRequireDefault(require("../ThemeProvider")); var _getInitColorSchemeScript = _interopRequireWildcard(require("./getInitColorSchemeScript")); var _useCurrentColorScheme = _interopRequireDefault(require("./useCurrentColorScheme")); var _jsxRuntime = require("react/jsx-runtime"); const _excluded = ["colorSchemes", "components", "generateCssVars", "cssVarPrefix"]; function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const DISABLE_CSS_TRANSITION = exports.DISABLE_CSS_TRANSITION = '*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}'; function createCssVarsProvider(options) { const { themeId, /** * This `theme` object needs to follow a certain structure to * be used correctly by the finel `CssVarsProvider`. It should have a * `colorSchemes` key with the light and dark (and any other) palette. * It should also ideally have a vars object created using `prepareCssVars`. */ theme: defaultTheme = {}, attribute: defaultAttribute = _getInitColorSchemeScript.DEFAULT_ATTRIBUTE, modeStorageKey: defaultModeStorageKey = _getInitColorSchemeScript.DEFAULT_MODE_STORAGE_KEY, colorSchemeStorageKey: defaultColorSchemeStorageKey = _getInitColorSchemeScript.DEFAULT_COLOR_SCHEME_STORAGE_KEY, defaultMode: designSystemMode = 'light', defaultColorScheme: designSystemColorScheme, disableTransitionOnChange: designSystemTransitionOnChange = false, resolveTheme, excludeVariablesFromRoot } = options; if (!defaultTheme.colorSchemes || typeof designSystemColorScheme === 'string' && !defaultTheme.colorSchemes[designSystemColorScheme] || typeof designSystemColorScheme === 'object' && !defaultTheme.colorSchemes[designSystemColorScheme == null ? void 0 : designSystemColorScheme.light] || typeof designSystemColorScheme === 'object' && !defaultTheme.colorSchemes[designSystemColorScheme == null ? void 0 : designSystemColorScheme.dark]) { console.error(`MUI: \`${designSystemColorScheme}\` does not exist in \`theme.colorSchemes\`.`); } const ColorSchemeContext = /*#__PURE__*/React.createContext(undefined); if (process.env.NODE_ENV !== 'production') { ColorSchemeContext.displayName = 'ColorSchemeContext'; } const useColorScheme = () => { const value = React.useContext(ColorSchemeContext); if (!value) { throw new Error(process.env.NODE_ENV !== "production" ? `MUI: \`useColorScheme\` must be called under ` : (0, _formatMuiErrorMessage2.default)(19)); } return value; }; function CssVarsProvider(props) { const { children, theme: themeProp = defaultTheme, modeStorageKey = defaultModeStorageKey, colorSchemeStorageKey = defaultColorSchemeStorageKey, attribute = defaultAttribute, defaultMode = designSystemMode, defaultColorScheme = designSystemColorScheme, disableTransitionOnChange = designSystemTransitionOnChange, storageWindow = typeof window === 'undefined' ? undefined : window, documentNode = typeof document === 'undefined' ? undefined : document, colorSchemeNode = typeof document === 'undefined' ? undefined : document.documentElement, colorSchemeSelector = ':root', disableNestedContext = false, disableStyleSheetGeneration = false } = props; const hasMounted = React.useRef(false); const upperTheme = (0, _privateTheming.useTheme)(); const ctx = React.useContext(ColorSchemeContext); const nested = !!ctx && !disableNestedContext; const scopedTheme = themeProp[themeId]; const _ref = scopedTheme || themeProp, { colorSchemes = {}, components = {}, generateCssVars = () => ({ vars: {}, css: {} }), cssVarPrefix } = _ref, restThemeProp = (0, _objectWithoutPropertiesLoose2.default)(_ref, _excluded); const allColorSchemes = Object.keys(colorSchemes); const defaultLightColorScheme = typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.light; const defaultDarkColorScheme = typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.dark; // 1. Get the data about the `mode`, `colorScheme`, and setter functions. const { mode: stateMode, setMode, systemMode, lightColorScheme, darkColorScheme, colorScheme: stateColorScheme, setColorScheme } = (0, _useCurrentColorScheme.default)({ supportedColorSchemes: allColorSchemes, defaultLightColorScheme, defaultDarkColorScheme, modeStorageKey, colorSchemeStorageKey, defaultMode, storageWindow }); let mode = stateMode; let colorScheme = stateColorScheme; if (nested) { mode = ctx.mode; colorScheme = ctx.colorScheme; } const calculatedMode = (() => { if (mode) { return mode; } // This scope occurs on the server if (defaultMode === 'system') { return designSystemMode; } return defaultMode; })(); const calculatedColorScheme = (() => { if (!colorScheme) { // This scope occurs on the server if (calculatedMode === 'dark') { return defaultDarkColorScheme; } // use light color scheme, if default mode is 'light' | 'system' return defaultLightColorScheme; } return colorScheme; })(); // 2. Create CSS variables and store them in objects (to be generated in stylesheets in the final step) const { css: rootCss, vars: rootVars } = generateCssVars(); // 3. Start composing the theme object const theme = (0, _extends2.default)({}, restThemeProp, { components, colorSchemes, cssVarPrefix, vars: rootVars, getColorSchemeSelector: targetColorScheme => `[${attribute}="${targetColorScheme}"] &` }); // 4. Create color CSS variables and store them in objects (to be generated in stylesheets in the final step) // The default color scheme stylesheet is constructed to have the least CSS specificity. // The other color schemes uses selector, default as data attribute, to increase the CSS specificity so that they can override the default color scheme stylesheet. const defaultColorSchemeStyleSheet = {}; const otherColorSchemesStyleSheet = {}; Object.entries(colorSchemes).forEach(([key, scheme]) => { const { css, vars } = generateCssVars(key); theme.vars = (0, _deepmerge.default)(theme.vars, vars); if (key === calculatedColorScheme) { // 4.1 Merge the selected color scheme to the theme Object.keys(scheme).forEach(schemeKey => { if (scheme[schemeKey] && typeof scheme[schemeKey] === 'object') { // shallow merge the 1st level structure of the theme. theme[schemeKey] = (0, _extends2.default)({}, theme[schemeKey], scheme[schemeKey]); } else { theme[schemeKey] = scheme[schemeKey]; } }); if (theme.palette) { theme.palette.colorScheme = key; } } const resolvedDefaultColorScheme = (() => { if (typeof defaultColorScheme === 'string') { return defaultColorScheme; } if (defaultMode === 'dark') { return defaultColorScheme.dark; } return defaultColorScheme.light; })(); if (key === resolvedDefaultColorScheme) { if (excludeVariablesFromRoot) { const excludedVariables = {}; excludeVariablesFromRoot(cssVarPrefix).forEach(cssVar => { excludedVariables[cssVar] = css[cssVar]; delete css[cssVar]; }); defaultColorSchemeStyleSheet[`[${attribute}="${key}"]`] = excludedVariables; } defaultColorSchemeStyleSheet[`${colorSchemeSelector}, [${attribute}="${key}"]`] = css; } else { otherColorSchemesStyleSheet[`${colorSchemeSelector === ':root' ? '' : colorSchemeSelector}[${attribute}="${key}"]`] = css; } }); theme.vars = (0, _deepmerge.default)(theme.vars, rootVars); // 5. Declaring effects // 5.1 Updates the selector value to use the current color scheme which tells CSS to use the proper stylesheet. React.useEffect(() => { if (colorScheme && colorSchemeNode) { // attaches attribute to because the css variables are attached to :root (html) colorSchemeNode.setAttribute(attribute, colorScheme); } }, [colorScheme, attribute, colorSchemeNode]); // 5.2 Remove the CSS transition when color scheme changes to create instant experience. // credit: https://github.com/pacocoursey/next-themes/blob/b5c2bad50de2d61ad7b52a9c5cdc801a78507d7a/index.tsx#L313 React.useEffect(() => { let timer; if (disableTransitionOnChange && hasMounted.current && documentNode) { const css = documentNode.createElement('style'); css.appendChild(documentNode.createTextNode(DISABLE_CSS_TRANSITION)); documentNode.head.appendChild(css); // Force browser repaint (() => window.getComputedStyle(documentNode.body))(); timer = setTimeout(() => { documentNode.head.removeChild(css); }, 1); } return () => { clearTimeout(timer); }; }, [colorScheme, disableTransitionOnChange, documentNode]); React.useEffect(() => { hasMounted.current = true; return () => { hasMounted.current = false; }; }, []); const contextValue = React.useMemo(() => ({ allColorSchemes, colorScheme, darkColorScheme, lightColorScheme, mode, setColorScheme, setMode, systemMode }), [allColorSchemes, colorScheme, darkColorScheme, lightColorScheme, mode, setColorScheme, setMode, systemMode]); let shouldGenerateStyleSheet = true; if (disableStyleSheetGeneration || nested && (upperTheme == null ? void 0 : upperTheme.cssVarPrefix) === cssVarPrefix) { shouldGenerateStyleSheet = false; } const element = /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, { children: [shouldGenerateStyleSheet && /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_styledEngine.GlobalStyles, { styles: { [colorSchemeSelector]: rootCss } }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_styledEngine.GlobalStyles, { styles: defaultColorSchemeStyleSheet }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_styledEngine.GlobalStyles, { styles: otherColorSchemesStyleSheet })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ThemeProvider.default, { themeId: scopedTheme ? themeId : undefined, theme: resolveTheme ? resolveTheme(theme) : theme, children: children })] }); if (nested) { return element; } return /*#__PURE__*/(0, _jsxRuntime.jsx)(ColorSchemeContext.Provider, { value: contextValue, children: element }); } process.env.NODE_ENV !== "production" ? CssVarsProvider.propTypes = { /** * The body attribute name to attach colorScheme. */ attribute: _propTypes.default.string, /** * The component tree. */ children: _propTypes.default.node, /** * The node used to attach the color-scheme attribute */ colorSchemeNode: _propTypes.default.any, /** * The CSS selector for attaching the generated custom properties */ colorSchemeSelector: _propTypes.default.string, /** * localStorage key used to store `colorScheme` */ colorSchemeStorageKey: _propTypes.default.string, /** * The initial color scheme used. */ defaultColorScheme: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.object]), /** * The initial mode used. */ defaultMode: _propTypes.default.string, /** * If `true`, the provider creates its own context and generate stylesheet as if it is a root `CssVarsProvider`. */ disableNestedContext: _propTypes.default.bool, /** * If `true`, the style sheet won't be generated. * * This is useful for controlling nested CssVarsProvider behavior. */ disableStyleSheetGeneration: _propTypes.default.bool, /** * Disable CSS transitions when switching between modes or color schemes. */ disableTransitionOnChange: _propTypes.default.bool, /** * The document to attach the attribute to. */ documentNode: _propTypes.default.any, /** * The key in the local storage used to store current color scheme. */ modeStorageKey: _propTypes.default.string, /** * The window that attaches the 'storage' event listener. * @default window */ storageWindow: _propTypes.default.any, /** * The calculated theme object that will be passed through context. */ theme: _propTypes.default.object } : void 0; const defaultLightColorScheme = typeof designSystemColorScheme === 'string' ? designSystemColorScheme : designSystemColorScheme.light; const defaultDarkColorScheme = typeof designSystemColorScheme === 'string' ? designSystemColorScheme : designSystemColorScheme.dark; const getInitColorSchemeScript = params => (0, _getInitColorSchemeScript.default)((0, _extends2.default)({ attribute: defaultAttribute, colorSchemeStorageKey: defaultColorSchemeStorageKey, defaultMode: designSystemMode, defaultLightColorScheme, defaultDarkColorScheme, modeStorageKey: defaultModeStorageKey }, params)); return { CssVarsProvider, useColorScheme, getInitColorSchemeScript }; }