@fylgja/props-builder
Version:
Effortlessly generate Design Tokens (CSS custom properties) from JavaScript objects.
97 lines (83 loc) • 2.6 kB
JavaScript
// Fylgja (https://fylgja.dev)
// Licensed under MIT Open Source
import {
cssVarRegex,
isValidString,
flattenObj,
unflattenObj,
} from "./utils.js";
import { formatTokens } from "./formats/index.js";
const defaultColorKeys = [
"color",
"white",
"black",
"gray",
"red",
"pink",
"purple",
"violet",
"indigo",
"blue",
"cyan",
"teal",
"green",
"lime",
"yellow",
"orange",
];
/**
* Tokenizes CSS variable strings by converting them into a standardized token format.
*
* @param {string} token - The token string potentially containing CSS variable references.
* @param {string} metaValueKey - The key for the meta value (e.g. "$value" or "value").
* @returns {string} - Tokenized string replacing CSS variable references.
*/
const tokenizeCSSVar = (token, metaValueKey) => {
if (Array.isArray(token)) {
token = token.toString();
}
if (typeof token !== "string") {
return token;
}
return token.replace(cssVarRegex, (match, tokenVal) => {
return `{${tokenVal.replace(/-/g, ".")}.${metaValueKey}}`;
});
};
/**
* Creates a JSON token file from a JavaScript object with CSS props.
*
* @param {Object} props - The object containing CSS properties.
* @param {function(string, string[]): Object} [metaExtend=formatTokens] - Function that extends meta information for a token key.
* @param {Object} options - Configuration options.
* @param {string[]} options.colorKeys - List of keys to be treated as color properties.
* @param {boolean} options.cssVarToToken - Whether to replace CSS variables with tokenized values.
* @returns {string} - JSON formatted string matching the Design Token file format.
*/
const toTokens = (
props,
metaExtend = formatTokens,
{ wrapper = "", colorKeys = defaultColorKeys, cssVarToToken = false } = {},
) => {
const flatProps = flattenObj(props);
const isUsingDefaultFormat = metaExtend === formatTokens;
const metaValueKey = isUsingDefaultFormat ? "$value" : "value";
const shouldUseMinified = isUsingDefaultFormat;
let tokens = Object.entries(flatProps).reduce((acc, [key, token]) => {
const meta = metaExtend(key, colorKeys);
const value = cssVarToToken
? tokenizeCSSVar(token, metaValueKey)
: token;
if (!acc[meta.type]) {
acc = { ...acc, [meta.type]: {} };
}
acc[meta.type][key] = { [metaValueKey]: value, ...meta };
return acc;
}, {});
if (wrapper && isValidString(wrapper)) {
tokens = { [wrapper]: tokens };
}
return shouldUseMinified
? JSON.stringify(tokens, null, 2)
: JSON.stringify(unflattenObj(tokens), null, 2);
};
export { toTokens as default, defaultColorKeys, toTokens };