outsystems-design-tokens
Version:
Store the Design Tokens used on the Ionic Framework and Widgets Library
152 lines (128 loc) • 5.24 kB
JavaScript
const glob = require("glob");
const fs = require('fs');
const path = require("path");
let _varTypePrefix;
// Set the prefix for the variable type
function setVariableTypePrefix(prefix) {
_varTypePrefix = prefix;
}
// Generates a valid rgba() color
function getRgbaValue(propValue) {
// Check if its rgba color
const isRgba = hexToRgba(propValue);
// If it is, then compose rgba() color, otherwise use the normal color
if (isRgba !== null) {
return (propValue = `rgba(${isRgba.r}, ${isRgba.g}, ${isRgba.b},${isRgba.a})`);
} else {
return propValue;
}
}
// Translates an hex color value to rgb
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
}
: null;
}
// Translates an hex color value to rgba
function hexToRgba(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
a: Math.round((parseInt(result[4], 16) * 100) / 255) / 100,
}
: null;
}
// Utility function to remove consecutive repeated words
function removeConsecutiveRepeatedWords(str) {
return str.replace(/(\b\w+\b)(-\1)+/g, '$1');
}
// Generates a valid default value, based if its color or any other token
function generateDeafultValue(prop, propName) {
const rgb = hexToRgb(prop.$value);
let rgbDeclaration = '';
if (rgb) {
// If the token is color, also add a rgb variable using the same color
rgbDeclaration = `\n${_varTypePrefix}${propName}-rgb: ${rgb.r}, ${rgb.g}, ${rgb.b};`;
prop.value = getRgbaValue(prop.$value);
}
return `${_varTypePrefix}${propName}: ${prop.$value};${rgbDeclaration}`;
}
// Generates a valid box-shadow value from a shadow Design Token structure
function generateShadowValue(prop, propName) {
const cssShadow = prop.$value.map(shadow => {
// Assuming shadow is an object with properties like offsetX, offsetY, blurRadius, spreadRadius, color
const color = getRgbaValue(shadow.color);
return `${shadow.x}px ${shadow.y}px ${shadow.blur}px ${shadow.spread}px ${color}`;
}).join(', ');
return `${_varTypePrefix}${propName}: ${cssShadow};`;
}
// Generates a valid font-size value from a font-size Design Token structure, while transforming the pixels to rem
function generateFontSizeValue(prop, propName) {
const pixelValue = parseInt(prop.$value);
const remValue = pixelValue / 16;
return `${_varTypePrefix}${propName}: ${remValue}rem;`;
}
// Generates a valid font-family value from a font-family Design Token structure
function generateFontFamilyValue(prop, propName) {
// Remove the last word from the token, as it contains the name of the font, which we don't want to be included on the generated variables
const _propName = propName.split('-').slice(0, -1).join('-');
return `${_varTypePrefix}${_propName}: "${prop.$value}", sans-serif;`;
}
function findFilesByExtension(startPath, extension, fileList = []) {
const files = fs.readdirSync(startPath, { withFileTypes: true });
for (const file of files) {
const filePath = path.join(startPath, file.name);
if (file.isDirectory()) {
findFilesByExtension(filePath, extension, fileList); // Recurse into subdirectories
} else if (file.isFile() && path.extname(file.name) === `.${extension}`) {
fileList.push(filePath); // Add file if it matches the extension
}
}
return fileList;
}
// Set the source and target paths
function setSourceAndTargetPaths(sourcePath, targetPath) {
let _finalSourcePath = sourcePath;
let _finalTargetPath = targetPath;
// Construct source paths based on the determined base path
if (sourcePath === undefined || sourcePath === "undefined") {
// Use path.resolve to ensure the path is correctly resolved from the current working directory
if (targetPath !== undefined && targetPath !== "undefined") {
_finalSourcePath = findFilesByExtension(path.resolve("node_modules/outsystems-design-tokens/tokens"), "json", []);
} else {
_finalSourcePath = [];
_finalTargetPath = path.resolve("dist/");
_finalSourcePath = findFilesByExtension(path.resolve("tokens"), "json", []);
}
} else {
// Get an array of paths from the src environment variable
const paths = process.env.src.split(",");
// Check if each path is absolute, if not, resolve it relative to the current working directory
_finalSourcePath = paths.flatMap((pathString) => {
const resolvedPath = path.isAbsolute(pathString.trim())
? pathString.trim()
: path.resolve(pathString.trim());
return glob.sync(resolvedPath);
});
}
return { sourcePath: _finalSourcePath, targetPath: _finalTargetPath };
}
module.exports = {
getRgbaValue,
hexToRgb,
generateDeafultValue,
generateShadowValue,
generateFontSizeValue,
generateFontFamilyValue,
removeConsecutiveRepeatedWords,
setSourceAndTargetPaths,
setVariableTypePrefix
};