@shopify/polaris
Version:
Shopify’s product component library
61 lines (60 loc) • 3.33 kB
JavaScript
import { __rest } from "tslib";
import React, { useMemo, useEffect, useContext } from 'react';
import { ThemeContext, buildThemeContext, buildCustomProperties, DefaultThemeColors, DefaultColorScheme, Tokens, } from '../../utilities/theme';
import { useFeatures } from '../../utilities/features';
export function ThemeProvider({ theme: themeConfig, children, }) {
const { unstableGlobalTheming = false } = useFeatures();
const parentContext = useContext(ThemeContext);
const isParentThemeProvider = parentContext === undefined;
const parentColorScheme = parentContext && parentContext.colorScheme && parentContext.colorScheme;
const parentColors = parentContext &&
parentContext.UNSTABLE_colors &&
parentContext.UNSTABLE_colors;
const { UNSTABLE_colors, colorScheme } = themeConfig, rest = __rest(themeConfig, ["UNSTABLE_colors", "colorScheme"]);
const processedThemeConfig = Object.assign(Object.assign(Object.assign({}, rest), { colorScheme: getColorScheme(colorScheme, parentColorScheme) }), { UNSTABLE_colors: Object.assign(Object.assign(Object.assign({}, (isParentThemeProvider && DefaultThemeColors)), (shouldInheritParentColors(isParentThemeProvider, colorScheme, parentColorScheme) && parentColors)), UNSTABLE_colors) });
const customProperties = useMemo(() => buildCustomProperties(processedThemeConfig, unstableGlobalTheming, Tokens), [processedThemeConfig, unstableGlobalTheming]);
const theme = useMemo(() => buildThemeContext(processedThemeConfig, unstableGlobalTheming ? customProperties : undefined), [customProperties, processedThemeConfig, unstableGlobalTheming]);
// 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]);
const style = Object.assign(Object.assign({}, customProperties), (!isParentThemeProvider && { color }));
return (<ThemeContext.Provider value={Object.assign(Object.assign({}, theme), { textColor: color })}>
<div style={style}>{children}</div>
</ThemeContext.Provider>);
}
function isInverseColorScheme(colorScheme) {
return colorScheme === 'inverse';
}
function getColorScheme(colorScheme, parentColorScheme) {
if (colorScheme == null) {
return parentColorScheme || DefaultColorScheme;
}
else if (isInverseColorScheme(colorScheme)) {
return parentColorScheme === 'dark' || parentColorScheme === undefined
? 'light'
: 'dark';
}
else {
return colorScheme;
}
}
function shouldInheritParentColors(isParentThemeProvider, colorScheme, parentColorScheme) {
if (isParentThemeProvider) {
return false;
}
else if (isInverseColorScheme(colorScheme) ||
(colorScheme === 'dark' && parentColorScheme === 'light') ||
(colorScheme === 'light' && parentColorScheme === 'dark')) {
return true;
}
else {
return false;
}
}