@terrazzo/token-tools
Version:
Various utilities for token types
99 lines • 4.06 kB
JavaScript
import { kebabCase } from '../string.js';
import { transformDimension } from './dimension.js';
import { transformFontFamily } from './font-family.js';
import { transformFontWeight } from './font-weight.js';
import { defaultAliasTransform } from './lib.js';
import { transformNumber } from './number.js';
import { transformString } from './string.js';
/** Convert typography value to multiple CSS values */
export function transformTypography(token, options) {
const { tokensSet, transformAlias = defaultAliasTransform } = options;
const output = {};
for (const [property, subvalue] of Object.entries(token.$value)) {
let transformedValue;
const aliasedID = token.aliasChain?.[0] ?? token.partialAliasOf?.[property];
if (aliasedID) {
const resolvedToken = tokensSet[aliasedID];
transformedValue = transformAlias(
// Pass a complete sub-token, not a bare `{ id }` stub, so recursive consumers can resolve it.
resolvedToken.$type === 'typography'
? {
id: `${aliasedID}-${property}`,
$type: typographySubValueType(property, subvalue),
$value: subvalue,
mode: { '.': { $value: subvalue } },
}
: resolvedToken);
}
else {
switch (property) {
case 'fontFamily': {
transformedValue = transformFontFamily({ $value: subvalue }, options);
break;
}
case 'fontSize':
case 'letterSpacing': {
transformedValue = transformDimension({ $value: subvalue }, options);
break;
}
case 'fontWeight': {
transformedValue = transformFontWeight({ $value: subvalue }, options);
break;
}
case 'lineHeight': {
if (typeof subvalue === 'number') {
transformedValue = transformNumber({ $value: subvalue }, options);
}
else {
transformedValue = transformDimension({ $value: subvalue }, options);
}
break;
}
default: {
// For other typography properties, dimensions are the only other likely token type
if (subvalue && typeof subvalue === 'object' && 'value' in subvalue) {
transformedValue = transformDimension({ $value: subvalue }, options);
}
else if (typeof subvalue === 'number') {
// number is technically allowed for things like `paragraph-spacing: 0`
transformedValue = transformNumber({ $value: subvalue }, options);
}
else {
transformedValue = transformString({ $value: subvalue }, options);
}
break;
}
}
}
output[kebabCase(property)] = transformedValue;
}
return output;
}
/** The `$type` a typography sub-property's value transforms as. */
function typographySubValueType(property, subvalue) {
switch (property) {
case 'fontFamily': {
return 'fontFamily';
}
case 'fontWeight': {
return 'fontWeight';
}
case 'fontSize':
case 'letterSpacing': {
return 'dimension';
}
case 'lineHeight': {
return typeof subvalue === 'number' ? 'number' : 'dimension';
}
default: {
if (subvalue && typeof subvalue === 'object' && 'value' in subvalue) {
return 'dimension';
}
if (typeof subvalue === 'number') {
return 'number';
}
return 'string';
}
}
}
//# sourceMappingURL=typography.js.map