Skip to content

Instantly share code, notes, and snippets.

@artursopelnik
Last active January 28, 2025 12:03
Show Gist options
  • Save artursopelnik/b4d6a6f839fa98c6d8d00d4c6861d286 to your computer and use it in GitHub Desktop.
Save artursopelnik/b4d6a6f839fa98c6d8d00d4c6861d286 to your computer and use it in GitHub Desktop.
Style Dictionary: Custom 'px to rem' Transform (size/pxToRem) to handle all pixel values, not just dimensions and font sizes
import StyleDictionary from 'style-dictionary';
import { Config, PlatformConfig, DesignToken } from "style-dictionary/types";
import { transformTypes } from 'style-dictionary/enums';
function throwSizeError(name: string | undefined, value: string | number, unitType: string): string {
throw `Invalid Number: '${name ? name : ''}: ${value}' is not a valid number, cannot transform to '${unitType}' \n`;
}
function getBasePxFontSize(platform: PlatformConfig): number {
return (platform && platform.basePxFontSize) || 16;
}
/**
* Convert all pixel (px) values to rem, not just dimensions and font sizes, uses `platform.options.basePxFontSize`
* as the base font, or `16` if not provided
* Scales non-zero numbers to rem, and adds ‘rem’ to the end.
*/
StyleDictionary.registerTransform({
type: transformTypes.value,
name: 'size/pxToRem',
transitive: true,
// Checks if the token's value ends with 'px' and skips tokens with attributes.pxToRem set to false.
filter: (token: DesignToken, options: Config) => {
const value = options.usesDtcg ? token.$value : token.value
return (
typeof value === 'string' &&
value.trim().endsWith('px') &&
!token.disablePxToRem
)
},
transform: (token: DesignToken, platform: PlatformConfig, options: Config) => {
const value = options.usesDtcg ? token.$value : token.value;
const parsedVal = parseFloat(value);
const baseFont = getBasePxFontSize(platform);
if (isNaN(parsedVal)) {
throwSizeError(token.name, value, 'rem');
}
return parsedVal === 0 ? '0' : `${parsedVal / baseFont}rem`;
}
});
/*
Example
{
"global / dimension": {
"1": {
"$type": "dimension",
"$value": "2px",
"$description": "Dimension 1",
"disablePxToRem": true
},
"2": {
"$type": "dimension",
"$value": "4px",
"$description": "Dimension 2"
},
"3": {
"$type": "dimension",
"$value": "8px",
"$description": "Dimension 3"
}
}
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment