@re-flex/styles
Version:
Core Style Util Package
134 lines (133 loc) • 5.49 kB
JavaScript
import { convertUnit2Rem, hasKey, isArray, isObject } from "@re-flex/utils";
import { UI_ACTIVE_THEME } from "./Core";
import parseColor from "./parseColor";
const multiples = {
size: ["width", "height"],
};
const transformList = {
bgColor: "backgroundColor",
w: "width",
h: "height",
m: "margin",
mt: "marginTop",
mr: "marginRight",
mb: "marginBottom",
ml: "marginLeft",
marginX: "marginInline",
marginY: "marginBlock",
mx: "marginInline",
my: "marginBlock",
p: "padding",
pt: "paddingTop",
pr: "paddingRight",
pb: "paddingBottom",
pl: "paddingLeft",
paddingX: "paddingInline",
paddingY: "paddingBlock",
px: "paddingInline",
py: "paddingBlock",
};
const ColorList = new Set([
Object.keys(UI_ACTIVE_THEME.palette.background),
Object.keys(UI_ACTIVE_THEME.palette),
].flat());
const setTransformList = new Set(Object.keys(transformList));
const SpacePropList = new Set("paddingBlock|paddingInline|marginBlock|marginInline|m|mx|my|mt|ml|mr|mb|p|px|py|pt|pl|pr|pb|margin|marginTop|marginRight|marginBottom|marginLeft|marginX|marginY|padding|paddingTop|paddingRight|paddingBottom|paddingLeft|paddingX|paddingY|top|right|bottom|left|gridGap|gridColumnGap|gridRowGap|gap|columnGap|rowGap|borderRadius".split("|"));
const ColorPropList = new Set("bgColor|color|backgroundColor|borderColor|borderTopColor|borderBottomColor|borderLeftColor|borderRightColor|outlineColor|fill|stroke".split("|"));
const SizePropList = new Set("fontSize|letterSpacing|width|minWidth|maxWidth|height|minHeight|maxHeight|flexBasis|size".split("|"));
const UnitLessPropList = new Set("inset|fontWeight|animationDuration|animationDelay|transitionDuration|transitionDelay|animationIterationCount|borderImageOutset|borderImageSlice|borderImageWidth|boxFlex|boxFlexGroup|boxOrdinalGroup|columnCount|columns|flex|flexGrow|flexPositive|flexShrink|flexNegative|flexOrder|gridRow|gridRowEnd|gridRowSpan|gridRowStart|gridColumn|gridColumnEnd|gridColumnSpan|gridColumnStart|msGridRow|msGridRowSpan|msGridColumn|msGridColumnSpan|fontWeight|lineHeight|opacity|order|orphans|tabSize|widows|zIndex|zoom|WebkitLineClamp|fillOpacity|floodOpacity|stopOpacity|strokeDasharray|strokeDashoffset|strokeMiterlimit|strokeOpacity|strokeWidth".split("|"));
const COLOR_CACHE = {};
const hasColor = (prop, value) => {
const key = prop + value;
if (hasKey(COLOR_CACHE, key))
return COLOR_CACHE[key];
if (ColorPropList.has(prop)) {
if (value.startsWith("var(")) {
COLOR_CACHE[key] = false;
return false;
}
let isCustomColor = value.includes(".") || ColorList.has(value);
COLOR_CACHE[key] = isCustomColor;
return isCustomColor;
}
COLOR_CACHE[key] = false;
return false;
};
const sxValueTransformerCache = {};
const sxValueTransformer = (prop, value) => {
let result = {};
if (setTransformList.has(prop)) {
prop = transformList[prop];
}
if (hasColor(prop, value)) {
let { primaryColor } = parseColor(value);
value = primaryColor;
}
else if (SpacePropList.has(prop) && typeof value === "number") {
value = convertUnit2Rem(value * UI_ACTIVE_THEME.space);
}
else if (SizePropList.has(prop) && typeof value === "number") {
value = convertUnit2Rem(value);
}
else if (prop === "boxShadow" && typeof value === "number") {
value = UI_ACTIVE_THEME.shadows?.[value] || "none";
}
else if (UnitLessPropList.has(prop) && typeof value === "number") {
value = String(value);
}
if (isArray(multiples[prop])) {
let dirs = multiples[prop];
for (let i = 0; i < dirs.length; i++) {
result[dirs[i]] = value;
}
}
else {
result[prop] = value;
}
return result;
};
const sxParser = (styles) => {
let result = {};
for (const prop in styles) {
let value = styles[prop];
if (!value)
return {};
if (isObject(value)) {
if (Object.keys(value).length === 0)
return {};
if (UI_ACTIVE_THEME.breakpoints.has(prop)) {
result[UI_ACTIVE_THEME.breakpoints.up(prop)] =
sxParser(value);
}
else {
if ([".", "#", "[", "@", "-"].includes(prop[0]) === false &&
Object.keys(value).some((val) => UI_ACTIVE_THEME.breakpoints.has(val))) {
for (const breakPoint in value) {
let val = value;
result[UI_ACTIVE_THEME.breakpoints.up(breakPoint)] = Object.assign({}, result[UI_ACTIVE_THEME.breakpoints.up(breakPoint)], sxValueTransformer(prop, val));
}
}
else {
result[prop] = sxParser(value);
}
}
}
else {
let transformedProperties = sxValueTransformer(prop, value);
for (const key in transformedProperties) {
result[key] = transformedProperties[key];
}
}
}
return result;
};
export const sxPropInitializer = (args) => {
const theme = UI_ACTIVE_THEME;
const sxStyles = typeof args === "function" ? args(theme) : args;
if (!sxStyles || Object.keys(sxStyles).length === 0) {
return {};
}
const sStyles = sxParser(sxStyles);
return sStyles;
};
export default sxPropInitializer;