Home / Function/ compileCandidates() — tailwindcss Function Reference

compileCandidates() — tailwindcss Function Reference

Architecture documentation for the compileCandidates() function in compile.ts from the tailwindcss codebase.

Entity Profile

Dependency Diagram

graph TD
  cbdeac33_581c_3396_0f10_877935a68176["compileCandidates()"]
  5f3acb43_b93f_4293_caaa_25ba26d38178["substituteAtApply()"]
  5f3acb43_b93f_4293_caaa_25ba26d38178 -->|calls| cbdeac33_581c_3396_0f10_877935a68176
  cebe77e1_f0f2_aeee_417e_2192f5790344["buildDesignSystem()"]
  cebe77e1_f0f2_aeee_417e_2192f5790344 -->|calls| cbdeac33_581c_3396_0f10_877935a68176
  6a3a8ab4_d53c_7516_c736_663c060fe979["compileAst()"]
  6a3a8ab4_d53c_7516_c736_663c060fe979 -->|calls| cbdeac33_581c_3396_0f10_877935a68176
  253719f6_2c20_17e4_dfba_451682b655dd["getClassOrder()"]
  253719f6_2c20_17e4_dfba_451682b655dd -->|calls| cbdeac33_581c_3396_0f10_877935a68176
  53cf41fe_5903_d247_3bb3_38414ba7d631["parseCandidate()"]
  cbdeac33_581c_3396_0f10_877935a68176 -->|calls| 53cf41fe_5903_d247_3bb3_38414ba7d631
  13f9b85f_58c4_5390_3b22_04d00b93361b["set()"]
  cbdeac33_581c_3396_0f10_877935a68176 -->|calls| 13f9b85f_58c4_5390_3b22_04d00b93361b
  3ea56425_6e9f_0dc3_e68f_304ee638d53d["compileAstNodes()"]
  cbdeac33_581c_3396_0f10_877935a68176 -->|calls| 3ea56425_6e9f_0dc3_e68f_304ee638d53d
  cd658659_fd0a_fcda_c564_b848d3481771["has()"]
  cbdeac33_581c_3396_0f10_877935a68176 -->|calls| cd658659_fd0a_fcda_c564_b848d3481771
  c9955487_1860_09fc_569b_44f655a0567c["get()"]
  cbdeac33_581c_3396_0f10_877935a68176 -->|calls| c9955487_1860_09fc_569b_44f655a0567c
  a699d8d8_c72a_c935_b653_634724c6403c["compare()"]
  cbdeac33_581c_3396_0f10_877935a68176 -->|calls| a699d8d8_c72a_c935_b653_634724c6403c
  style cbdeac33_581c_3396_0f10_877935a68176 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

packages/tailwindcss/src/compile.ts lines 11–121

export function compileCandidates(
  rawCandidates: Iterable<string>,
  designSystem: DesignSystem,
  {
    onInvalidCandidate,
    respectImportant,
  }: { onInvalidCandidate?: (candidate: string) => void; respectImportant?: boolean } = {},
) {
  let nodeSorting = new Map<
    AstNode,
    { properties: { order: number[]; count: number }; variants: bigint; candidate: string }
  >()
  let astNodes: AstNode[] = []
  let matches = new Map<string, Candidate[]>()

  // Parse candidates and variants
  for (let rawCandidate of rawCandidates) {
    if (designSystem.invalidCandidates.has(rawCandidate)) {
      onInvalidCandidate?.(rawCandidate)
      continue // Bail, invalid candidate
    }

    let candidates = designSystem.parseCandidate(rawCandidate)
    if (candidates.length === 0) {
      onInvalidCandidate?.(rawCandidate)
      continue // Bail, invalid candidate
    }

    matches.set(rawCandidate, candidates)
  }

  let flags = CompileAstFlags.None

  if (respectImportant ?? true) {
    flags |= CompileAstFlags.RespectImportant
  }

  let variantOrderMap = designSystem.getVariantOrder()

  // Create the AST
  for (let [rawCandidate, candidates] of matches) {
    let found = false

    for (let candidate of candidates) {
      let rules = designSystem.compileAstNodes(candidate, flags)
      if (rules.length === 0) continue

      found = true

      for (let { node, propertySort } of rules) {
        // Track the variant order which is a number with each bit representing a
        // variant. This allows us to sort the rules based on the order of
        // variants used.
        let variantOrder = 0n
        for (let variant of candidate.variants) {
          variantOrder |= 1n << BigInt(variantOrderMap.get(variant)!)
        }

        nodeSorting.set(node, {
          properties: propertySort,
          variants: variantOrder,
          candidate: rawCandidate,
        })
        astNodes.push(node)
      }
    }

    if (!found) {
      onInvalidCandidate?.(rawCandidate)
    }
  }

  astNodes.sort((a, z) => {
    // SAFETY: At this point it is safe to use TypeScript's non-null assertion
    // operator because if the ast nodes didn't exist, we introduced a bug
    // above, but there is no need to re-check just to be sure. If this relied
    // on pure user input, then we would need to check for its existence.
    let aSorting = nodeSorting.get(a)!
    let zSorting = nodeSorting.get(z)!

    // Sort by variant order first
    if (aSorting.variants - zSorting.variants !== 0n) {
      return Number(aSorting.variants - zSorting.variants)
    }

    // Find the first property that is different between the two rules
    let offset = 0
    while (
      offset < aSorting.properties.order.length &&
      offset < zSorting.properties.order.length &&
      aSorting.properties.order[offset] === zSorting.properties.order[offset]
    ) {
      offset += 1
    }

    return (
      // Sort by lowest property index first
      (aSorting.properties.order[offset] ?? Infinity) -
        (zSorting.properties.order[offset] ?? Infinity) ||
      // Sort by most properties first, then by least properties
      zSorting.properties.count - aSorting.properties.count ||
      // Sort alphabetically
      compare(aSorting.candidate, zSorting.candidate)
    )
  })

  return {
    astNodes,
    nodeSorting,
  }
}

Subdomains

Frequently Asked Questions

What does compileCandidates() do?
compileCandidates() is a function in the tailwindcss codebase.
What does compileCandidates() call?
compileCandidates() calls 6 function(s): compare, compileAstNodes, get, has, parseCandidate, set.
What calls compileCandidates()?
compileCandidates() is called by 4 function(s): buildDesignSystem, compileAst, getClassOrder, substituteAtApply.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free