@primer/primitives
Version:
Typography, spacing, and color primitives for Primer design system
47 lines (46 loc) • 1.76 kB
JavaScript
import { isDimension } from '../filters/index.js';
/**
* @description base font size from options or 16
* @param options
* @returns number
*/
const getBasePxFontSize = (options) => (options && options.basePxFontSize) || 16;
/**
* @description checks if token value has a specific unit
* @param value token value
* @param unit unit string like px or value
* @returns boolean
*/
const hasUnit = (value, unit) => {
if (typeof value === 'number') {
return false;
}
return value.indexOf(unit) > -1;
};
/**
* @description converts dimension tokens value to `rem`, ignores `em` as they are relative to the font size of the parent element
* @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
*/
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);
const floatVal = parseFloat(token[valueProp]);
if (isNaN(floatVal)) {
throw new Error(`Invalid dimension token: '${token.name}: ${token[valueProp]}' is not valid and cannot be transform to 'rem' \n`);
}
if (floatVal === 0) {
return ['0', '0'];
}
if (hasUnit(token[valueProp], 'rem') || hasUnit(token[valueProp], 'em')) {
return [token.value, `${floatVal * baseFont}px`];
}
return [`${floatVal / baseFont}rem`, `${floatVal}px`];
},
};