UNPKG

@shopify/polaris

Version:

Shopify’s product component library

61 lines (60 loc) 3.33 kB
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; } }