@primer/primitives
Version:
Typography, spacing, and color primitives for Primer design system
46 lines (45 loc) • 2 kB
JavaScript
import { isDimension } from '../filters/index.js';
import { parseDimension } from './utilities/parseDimension.js';
/**
* @description base font size from options or 16
* @param options
* @returns number
*/
const getBasePxFontSize = (options) => (options && options.basePxFontSize) || 16;
/**
* @description converts dimension tokens value to an array with both `rem` and `px` values
* @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
* @matcher matches all tokens of $type `dimension`
* @transformer returns an array with the `rem` and `pixel` string
* @note Expects W3C DTCG format { value: number, unit: "px" | "rem" | "em" }
*/
export const dimensionToRemPxArray = {
name: 'dimension/remPxArray',
type: 'value',
transitive: true,
filter: isDimension,
transform: (token, config, options) => {
const valueProp = options.usesDtcg ? '$value' : 'value';
const baseFont = getBasePxFontSize(config);
try {
const { value, unit } = parseDimension(token[valueProp]);
if (value === 0) {
return ['0', '0'];
}
// em values pass through unchanged (relative to parent, cannot convert)
if (unit === 'em') {
return [`${value}em`, `${value}em`];
}
// rem values pass through, convert to px for second value
if (unit === 'rem') {
return [`${value}rem`, `${value * baseFont}px`];
}
// px values convert to rem for first value
return [`${value / baseFont}rem`, `${value}px`];
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Invalid dimension token: '${token.name}: ${JSON.stringify(token[valueProp])}' is not valid and cannot be transformed to 'rem' - ${errorMessage}\n`);
}
},
};