UNPKG

@shopify/polaris

Version:

Shopify’s product component library

135 lines (134 loc) 5.26 kB
import { __rest } from "tslib"; import tokens from '@shopify/polaris-tokens'; import { hexToHsluv, hsluvToHex } from 'hsluv'; import { colorToHsla, hslToString, hslToRgb } from '../color-transformers'; import { isLight } from '../color-validation'; import { constructColorName } from '../color-names'; import { createLightColor } from '../color-manipulation'; import { compose } from '../compose'; import { needsVariantList } from './config'; import { roleVariants } from './role-variants'; export function buildCustomProperties(themeConfig, globalTheming, tokens) { const { UNSTABLE_colors = {}, colorScheme } = themeConfig; return globalTheming ? customPropertyTransformer(Object.assign(Object.assign({}, buildColors(UNSTABLE_colors, roleVariants, colorScheme)), tokens)) : buildLegacyColors(themeConfig); } export function buildThemeContext(themeConfig, cssCustomProperties) { const { logo, UNSTABLE_colors, colorScheme } = themeConfig; return { logo, UNSTABLE_cssCustomProperties: toString(cssCustomProperties), UNSTABLE_colors, colorScheme, }; } function toString(obj) { if (obj) { return Object.entries(obj) .map((pair) => pair.join(':')) .join(';'); } else { return undefined; } } function hexToHsluvObj(hex) { const [hue, saturation, lightness] = hexToHsluv(hex); return { hue, saturation, lightness, }; } export function buildColors(colors, roleVariants, colorScheme) { return Object.assign({}, ...Object.entries(colors).map(([role, hex]) => { const base = hexToHsluvObj(hex); const variants = roleVariants[role] || []; return Object.assign({}, variants.reduce((accumulator, _a) => { var { name } = _a, settings = __rest(_a, ["name"]); const { hue = base.hue, saturation = base.saturation, lightness = base.lightness, alpha = 1, } = settings[colorScheme]; const resolve = (value, base) => typeof value === 'number' ? value : value(base); return Object.assign(Object.assign({}, accumulator), { [name]: hslToString(Object.assign(Object.assign({}, colorToHsla(hsluvToHex([ resolve(hue, base.hue), resolve(saturation, base.saturation), resolve(lightness, base.lightness), ]))), { alpha })) }); }, {})); })); } function customPropertyTransformer(properties) { return Object.entries(properties).reduce((transformed, [key, value]) => (Object.assign(Object.assign({}, transformed), { [toCssCustomPropertySyntax(key)]: value })), {}); } export function toCssCustomPropertySyntax(camelCase) { return `--p-${camelCase.replace(/([A-Z0-9])/g, '-$1').toLowerCase()}`; } function buildLegacyColors(theme) { let colorPairs; const colors = theme && theme.colors && theme.colors.topBar ? theme.colors.topBar : { background: '#00848e', backgroundLighter: '#1d9ba4', color: '#f9fafb' }; const colorKey = 'topBar'; const colorKeys = Object.keys(colors); if (colorKeys.length > 1) { colorPairs = colorKeys.map((key) => { return [constructColorName(colorKey, key), colors[key]]; }); } else { colorPairs = parseColors([colorKey, colors]); } return colorPairs.reduce((state, [key, value]) => (Object.assign(Object.assign({}, state), { [key]: value })), {}); } export function needsVariant(name) { return needsVariantList.includes(name); } const lightenToString = compose(hslToString, createLightColor); export function setTextColor(name, variant = 'dark') { if (variant === 'light') { return [name, tokens.colorInk]; } return [name, tokens.colorWhite]; } export function setTheme(color, baseName, key, variant) { const colorPairs = []; switch (variant) { case 'light': colorPairs.push(setTextColor(constructColorName(baseName, null, 'color'), 'light')); colorPairs.push([ constructColorName(baseName, key, 'lighter'), lightenToString(color, 7, -10), ]); break; case 'dark': colorPairs.push(setTextColor(constructColorName(baseName, null, 'color'), 'dark')); colorPairs.push([ constructColorName(baseName, key, 'lighter'), lightenToString(color, 15, 15), ]); break; default: } return colorPairs; } function parseColors([baseName, colors]) { const keys = Object.keys(colors); const colorPairs = []; for (const key of keys) { colorPairs.push([constructColorName(baseName, key), colors[key]]); if (needsVariant(baseName)) { const hslColor = colorToHsla(colors[key]); if (typeof hslColor === 'string') { return colorPairs; } const rgbColor = hslToRgb(hslColor); if (isLight(rgbColor)) { colorPairs.push(...setTheme(hslColor, baseName, key, 'light')); } else { colorPairs.push(...setTheme(hslColor, baseName, key, 'dark')); } } } return colorPairs; }