@shopify/polaris
Version:
Shopify’s product component library
135 lines (134 loc) • 5.26 kB
JavaScript
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;
}