All files / packages/design-tokens/src/style-dictionary/transforms/css dynamic-vars.js

100% Statements 20/20
100% Branches 18/18
100% Functions 6/6
100% Lines 20/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73            2x   3549x           1524x       2025x 1205x           820x 820x   820x                 2x 821x     821x         799x 799x         22x 32x 32x                 2x 3x       3538x 813x      
/**
 * CSS filter to detect tokens with dynamic values
 *
 * @param {Object} token
 * @returns boolean
 */
export const dynamicVarFilter = (token) => {
  // Only process tokens with references (not literal values)
  if (
    !token.original ||
    typeof token.original.$value !== 'string' ||
    !token.original.$value.includes('{') ||
    !token.original.$value.includes('}')
  ) {
    return false;
  }
 
  // Don't process any alias references - let Style Dictionary handle the resolution
  if (token.original.$value.includes('{alias.')) {
    return false;
  }
 
  // Convert tokens to var() syntax if:
  // 1. Shared (s) or component (c) scope tokens (standard behavior)
  // 2. OR tokens explicitly marked as dynamic (e.g., spacing-var tokens, focus shadows)
  const scope = token.path && token.path[1];
  const isExplicitlyDynamic = token.original?.dynamic === true;
 
  return scope === 's' || scope === 'c' || isExplicitlyDynamic;
};
 
/**
 * CSS Transformer that takes a dynamic value and converts to
 * CSS variable references
 *
 * @param {Object} token
 */
export const dynamicVarTransformer = (token) => {
  const originalValue = token.original.$value;
 
  // Handle simple single token reference (e.g., "{slds.g.spacing.1}")
  if (
    originalValue.startsWith('{') &&
    originalValue.endsWith('}') &&
    originalValue.indexOf('}') === originalValue.lastIndexOf('}')
  ) {
    const tokenName = originalValue.replace('{', '').replace('}', '').replace(/\./g, '-');
    return `var(--${tokenName})`;
  }
 
  // Handle complex values with embedded token references
  // (e.g., "0px 0px 0px 2px {slds.g.color.brand.base.40} inset")
  return originalValue.replace(/\{([^}]+)\}/g, (match, tokenPath) => {
    const tokenName = tokenPath.replace(/\./g, '-');
    return `var(--${tokenName})`;
  });
};
 
/**
 * Style Dictionary registration for the dynamic CSS transformer
 *
 * @param {StyleDictionary} StyleDictionary
 */
export const cssVarTransformer = (StyleDictionary) => {
  StyleDictionary.registerTransform({
    name: 'value/css-vars',
    type: 'value',
    transitive: true,
    filter: (token) => dynamicVarFilter(token),
    transform: (token) => dynamicVarTransformer(token),
  });
};