@primer/primitives
Version:
Typography, spacing, and color primitives for Primer design system
49 lines (48 loc) • 2.29 kB
JavaScript
import { toHex } from 'color2k';
import { isShadow } from '../filters/index.js';
import { alpha } from './utilities/alpha.js';
import { checkRequiredTokenProperties } from './utilities/checkRequiredTokenProperties.js';
import { getTokenValue } from './utilities/getTokenValue.js';
import { normalizeColorValue } from './utilities/normalizeColorValue.js';
/**
* @description Converts a W3C dimension object to CSS string
* @param dim - The dimension value in W3C object format
* @returns CSS dimension string (e.g., "16px", "1rem", "0")
*/
const dimensionToCss = (dim) => {
if (dim.value === 0) {
return '0';
}
return `${dim.value}${dim.unit}`;
};
/**
* @description converts w3c shadow tokens in css shadow string
* @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts)
* @matcher matches all tokens of $type `shadow`
* @transformer returns css shadow `string`
*/
export const shadowToCss = {
name: 'shadow/css',
type: 'value',
transitive: true,
filter: isShadow,
transform: (token, config) => {
// extract value
const value = getTokenValue(token);
const valueProp = token.$value ? '$value' : 'value';
// turn value into array
const shadowValues = !Array.isArray(value) ? [value] : value;
return shadowValues
.map((shadow) => {
// if value === string it was probably already transformed
if (typeof shadow === 'string')
return shadow;
checkRequiredTokenProperties(shadow, ['color', 'offsetX', 'offsetY', 'blur', 'spread']);
/*css box shadow: inset? | offset-x | offset-y | blur-radius | spread-radius | color */
const colorString = normalizeColorValue(getTokenValue(Object.assign(Object.assign({}, token), { [valueProp]: shadow }), 'color'));
const colorHex = shadow.alpha !== undefined ? toHex(alpha(colorString, shadow.alpha, token, config)) : toHex(colorString);
return `${shadow.inset === true ? 'inset ' : ''}${dimensionToCss(shadow.offsetX)} ${dimensionToCss(shadow.offsetY)} ${dimensionToCss(shadow.blur)} ${dimensionToCss(shadow.spread)} ${colorHex}`;
})
.join(', ');
},
};