All files / packages/fds-uif/generator-base/src/analyzer classNames.ts

100% Statements 9/9
100% Branches 0/0
100% Functions 0/0
100% Lines 9/9

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                                        39x     39x   6x       39x         3x                   9x                 39x         7x               39x    
/**
 * Class Name Rules
 *
 * Builds conditional class name rules from UIF modifiers, states, and variants.
 */
 
import type { ResolvedUIF, ResolvedModifier } from '@fds-uif/schema';
import { getVariants } from '@fds-uif/core/browser';
 
import type { ClassNameRule } from '../types/index.js';
import { sanitizeIdentifier } from '../types/index.js';
 
/**
 * Build class name rules from UIF definition
 */
export function buildClassNameRules(
  uif: ResolvedUIF,
  modifiers: ResolvedModifier[],
  stateClasses: Array<{ state: string; class: string }>,
): ClassNameRule[] {
  const baseClasses: string[] = [];
 
  // Extract base class from structure.attributes.static.class
  const staticClass = uif.structure.attributes?.static?.class;
  if (typeof staticClass === 'string') {
    baseClasses.push(...staticClass.split(' ').filter(Boolean));
  }
 
  // Build conditional rules
  const conditional: Array<{ classes: string[]; condition: string }> = [];
 
  // stateClasses should be conditional on the state, not always applied
  // Sanitize state names to be valid JS identifiers
  for (const sc of stateClasses) {
    conditional.push({
      classes: [sc.class],
      condition: sanitizeIdentifier(sc.state),
    });
  }
 
  // Modifiers → conditional classes
  // Sanitize modifier names to be valid JS identifiers
  for (const modifier of modifiers) {
    if (modifier.attribute === 'class') {
      conditional.push({
        classes: [modifier.value],
        condition: sanitizeIdentifier(modifier.name),
      });
    }
  }
 
  // Variants → conditional classes (switch-style, value-based)
  // Sanitize variant names to be valid JS identifiers
  const variants = getVariants(uif);
  for (const variant of variants) {
    for (const option of variant.options) {
      if (option.class) {
        // Generate condition: variantName === 'optionValue'
        conditional.push({
          classes: [option.class],
          condition: `${sanitizeIdentifier(variant.name)} === '${option.value}'`,
        });
      }
    }
  }
 
  return [{ base: baseClasses, conditional }];
}