@shopify/polaris
Version:
Shopify’s product component library
88 lines (76 loc) • 3.48 kB
JavaScript
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
import React$1, { useContext, useMemo, useEffect } from 'react';
import DefaultThemeColors$1 from '@shopify/polaris-tokens/dist-modern/theme/base.json';
import { ThemeContext } from '../../utilities/theme/context.js';
import { buildCustomProperties, buildThemeContext, toString } from '../../utilities/theme/utils.js';
import { Tokens } from '../../utilities/theme/tokens.js';
import { useFeatures } from '../../utilities/features/hooks.js';
function ThemeProvider({
theme: themeConfig,
alwaysRenderCustomProperties = false,
children
}) {
const {
newDesignLanguage
} = useFeatures();
const parentContext = useContext(ThemeContext);
const isParentThemeProvider = parentContext === undefined;
const parentColorScheme = parentContext && parentContext.colorScheme && parentContext.colorScheme;
const parentColors = parentContext && parentContext.colors && parentContext.colors;
const [customProperties, theme] = useMemo(() => {
const {
colors,
colorScheme
} = themeConfig,
rest = _objectWithoutProperties(themeConfig, ["colors", "colorScheme"]);
const processedThemeConfig = _objectSpread2(_objectSpread2(_objectSpread2({}, rest), {
colorScheme: getColorScheme(colorScheme, parentColorScheme)
}), {}, {
colors: _objectSpread2(_objectSpread2(_objectSpread2({}, isParentThemeProvider && DefaultThemeColors$1), parentColors != null && parentColors), colors)
});
const customProperties = buildCustomProperties(processedThemeConfig, newDesignLanguage, Tokens);
const theme = _objectSpread2(_objectSpread2({}, buildThemeContext(processedThemeConfig, newDesignLanguage ? customProperties : undefined)), {}, {
textColor: customProperties['--p-text'] || ''
});
return [customProperties, theme];
}, [isParentThemeProvider, newDesignLanguage, parentColorScheme, parentColors, themeConfig]); // We want these values to be empty string instead of `undefined` when not set.
// Otherwise, setting a style property to `undefined` does not remove it from the DOM.
const backgroundColor = customProperties['--p-background'] || '';
const color = customProperties['--p-text'] || '';
useEffect(() => {
if (isParentThemeProvider) {
document.body.style.backgroundColor = backgroundColor;
document.body.style.color = color;
}
}, [backgroundColor, color, isParentThemeProvider]);
let style;
if (isParentThemeProvider) {
style = customProperties;
} else if (alwaysRenderCustomProperties || !isParentThemeProvider && parentContext.cssCustomProperties !== toString(customProperties)) {
style = _objectSpread2(_objectSpread2({}, customProperties), {
color
});
} else {
style = {
color
};
}
return /*#__PURE__*/React$1.createElement(ThemeContext.Provider, {
value: theme
}, /*#__PURE__*/React$1.createElement("div", {
style: style
}, children));
}
function isInverseColorScheme(colorScheme) {
return colorScheme === 'inverse';
}
function getColorScheme(colorScheme, parentColorScheme) {
if (colorScheme == null) {
return parentColorScheme || 'light';
} else if (isInverseColorScheme(colorScheme)) {
return parentColorScheme === 'dark' || parentColorScheme === undefined ? 'light' : 'dark';
} else {
return colorScheme;
}
}
export { ThemeProvider };