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,
}
}
Domain
Subdomains
Source
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