@primer/primitives
Version:
Typography, spacing, and color primitives for Primer design system
121 lines (120 loc) • 5.41 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { format } from 'prettier';
import { transformNamePathToFigma } from '../transformers/namePathToFigma.js';
import { hexToRgbaFloat } from '../transformers/utilities/hexToRgbaFloat.js';
import { isRgbaFloat } from '../transformers/utilities/isRgbaFloat.js';
import { getReferences, sortByReference } from 'style-dictionary/utils';
const isReference = (string) => /^\{([^\\]*)\}$/g.test(string);
const getReference = (dictionary, refString, platform) => {
var _a;
if (isReference(refString)) {
// retrieve reference token
const refToken = getReferences(refString, dictionary.tokens, { unfilteredTokens: dictionary.unfilteredTokens })[0];
// return full reference
return [(_a = refToken.attributes) === null || _a === void 0 ? void 0 : _a.collection, transformNamePathToFigma(refToken, platform)].filter(Boolean).join('/');
}
};
const getFigmaType = (type) => {
const validTypes = {
color: 'COLOR',
dimension: 'FLOAT',
fontWeight: 'FLOAT',
number: 'FLOAT',
fontFamily: 'STRING',
};
if (type in validTypes)
return validTypes[type];
throw new Error(`Invalid type: ${type}`);
};
const shadowToVariables = (name, values, token) => {
// floatValue
const floatValue = (property) => ({
name: `${name}/${property}`,
value: parseInt(values[property].replace('px', '')),
type: 'FLOAT',
scopes: ['EFFECT_FLOAT'],
mode,
collection,
group,
});
const { attributes } = token;
const { mode, collection, group } = attributes || {};
return [
floatValue('offsetX'),
floatValue('offsetY'),
floatValue('blur'),
floatValue('spread'),
{
name: `${name}/color`,
value: isRgbaFloat(values.color)
? Object.assign(Object.assign({}, values.color), (values.alpha ? { a: values.alpha } : {})) : hexToRgbaFloat(values.color, values.alpha),
type: 'COLOR',
scopes: ['EFFECT_COLOR'],
mode,
collection,
group,
},
];
};
/**
* @description Converts `StyleDictionary.dictionary.tokens` to javascript esm (javascript export statement)
* @param arguments [FormatterArguments](https://github.com/amzn/style-dictionary/blob/main/types/Format.d.ts)
* @returns formatted `string`
*/
export const jsonFigma = (_a) => __awaiter(void 0, [_a], void 0, function* ({ dictionary, file: _file, platform }) {
// array to store tokens in
const tokens = [];
const sortedTokens = [...dictionary.allTokens].sort(sortByReference(dictionary.tokens, { unfilteredTokens: dictionary.unfilteredTokens }));
// loop through tokens sorted by reference
for (const token of sortedTokens) {
// deconstruct token
const { attributes, $value: value, $type, $description: description, original, alpha } = token;
const { mode, collection, scopes, group, codeSyntax } = attributes || {};
// early escape if no type is present
if (!$type)
return;
// shadows need to be specifically dealt with
if ($type === 'shadow') {
const shadowValues = !Array.isArray(value) ? [value] : value;
// if only one set of shadow values is present
if (shadowValues.length === 1) {
tokens.push(...shadowToVariables(token.name, shadowValues[0], Object.assign(Object.assign({}, token), (platform.mode ? { mode: platform.mode } : {}))));
}
else {
// if multiple shadow sets values are present we need loop through them and add the index to the name
for (const [index, stepValue] of shadowValues.entries()) {
tokens.push(...shadowToVariables(`${token.name}/${index + 1}`, stepValue, Object.assign(Object.assign({}, token), (platform.mode ? { mode: platform.mode } : {}))));
}
}
// other tokens just get added to tokens array
}
else {
tokens.push({
name: token.name,
value,
type: getFigmaType($type),
alpha,
description,
refId: [collection, token.name].filter(Boolean).join('/'),
reference: getReference(dictionary, original.$value, platform),
collection,
mode,
group,
scopes,
codeSyntax,
});
}
}
// add file header and convert output
const output = JSON.stringify(tokens, null, 2);
// return prettified
return format(output, { parser: 'json', printWidth: 500 });
});