arbitraryUtilities() — tailwindcss Function Reference
Architecture documentation for the arbitraryUtilities() function in canonicalize-candidates.ts from the tailwindcss codebase.
Entity Profile
Dependency Diagram
graph TD 59459a7a_2e6a_375a_d02d_f7a77927b468["arbitraryUtilities()"] f6c14bbb_2e42_58cc_18f1_c89a243da9c0["canonicalize-candidates.ts"] 59459a7a_2e6a_375a_d02d_f7a77927b468 -->|defined in| f6c14bbb_2e42_58cc_18f1_c89a243da9c0 2de86ba2_90a4_8c2d_db18_154bb1a1564f["printCandidate()"] 59459a7a_2e6a_375a_d02d_f7a77927b468 -->|calls| 2de86ba2_90a4_8c2d_db18_154bb1a1564f e065de15_2d14_7687_5e7d_5513c20a5e8c["allVariablesAreUsed()"] 59459a7a_2e6a_375a_d02d_f7a77927b468 -->|calls| e065de15_2d14_7687_5e7d_5513c20a5e8c bafed062_abf8_7e47_4942_385b21bd9b04["parseCandidate()"] 59459a7a_2e6a_375a_d02d_f7a77927b468 -->|calls| bafed062_abf8_7e47_4942_385b21bd9b04 09df19e7_0346_145d_40c4_e93ff14a2ff9["isValidSpacingMultiplier()"] 59459a7a_2e6a_375a_d02d_f7a77927b468 -->|calls| 09df19e7_0346_145d_40c4_e93ff14a2ff9 f44bccaf_a67b_68ab_8fb1_2226f3e5fe00["printModifier()"] 59459a7a_2e6a_375a_d02d_f7a77927b468 -->|calls| f44bccaf_a67b_68ab_8fb1_2226f3e5fe00 2820372c_b982_9e06_fc23_f8f4ac308d00["get()"] 59459a7a_2e6a_375a_d02d_f7a77927b468 -->|calls| 2820372c_b982_9e06_fc23_f8f4ac308d00 style 59459a7a_2e6a_375a_d02d_f7a77927b468 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
packages/tailwindcss/src/canonicalize-candidates.ts lines 967–1143
function arbitraryUtilities(candidate: Candidate, options: InternalCanonicalizeOptions): Candidate {
// We are only interested in arbitrary properties and arbitrary values
if (
// Arbitrary property
candidate.kind !== 'arbitrary' &&
// Arbitrary value
!(candidate.kind === 'functional' && candidate.value?.kind === 'arbitrary')
) {
return candidate
}
let designSystem = options.designSystem
let utilities = designSystem.storage[PRE_COMPUTED_UTILITIES_KEY].get(options.signatureOptions)
let signatures = designSystem.storage[UTILITY_SIGNATURE_KEY].get(options.signatureOptions)
let targetCandidateString = designSystem.printCandidate(candidate)
// Compute the signature for the target candidate
let targetSignature = signatures.get(targetCandidateString)
if (typeof targetSignature !== 'string') return candidate
// Try a few options to find a suitable replacement utility
for (let replacementCandidate of tryReplacements(targetSignature, candidate)) {
let replacementString = designSystem.printCandidate(replacementCandidate)
let replacementSignature = signatures.get(replacementString)
if (replacementSignature !== targetSignature) {
continue
}
// Ensure that if CSS variables were used, that they are still used
if (!allVariablesAreUsed(designSystem, candidate, replacementCandidate)) {
continue
}
return replacementCandidate
}
return candidate
function* tryReplacements(
targetSignature: string,
candidate: Extract<Candidate, { kind: 'functional' | 'arbitrary' }>,
): Generator<Candidate> {
// Find a corresponding utility for the same signature
let replacements = utilities.get(targetSignature)
// Multiple utilities can map to the same signature. Not sure how to migrate
// this one so let's just skip it for now.
//
// TODO: Do we just migrate to the first one?
if (replacements.length > 1) return
// If we didn't find any replacement utilities, let's try to strip the
// modifier and find a replacement then. If we do, we can try to re-add the
// modifier later and verify if we have a valid migration.
//
// This is necessary because `text-red-500/50` will not be pre-computed,
// only `text-red-500` will.
if (replacements.length === 0 && candidate.modifier) {
let candidateWithoutModifier = { ...candidate, modifier: null }
let targetSignatureWithoutModifier = signatures.get(
designSystem.printCandidate(candidateWithoutModifier),
)
if (typeof targetSignatureWithoutModifier === 'string') {
for (let replacementCandidate of tryReplacements(
targetSignatureWithoutModifier,
candidateWithoutModifier,
)) {
yield Object.assign({}, replacementCandidate, { modifier: candidate.modifier })
}
}
}
// If only a single utility maps to the signature, we can use that as the
// replacement.
if (replacements.length === 1) {
for (let replacementCandidate of parseCandidate(designSystem, replacements[0])) {
yield replacementCandidate
}
}
Domain
Subdomains
Calls
Source
Frequently Asked Questions
What does arbitraryUtilities() do?
arbitraryUtilities() is a function in the tailwindcss codebase, defined in packages/tailwindcss/src/canonicalize-candidates.ts.
Where is arbitraryUtilities() defined?
arbitraryUtilities() is defined in packages/tailwindcss/src/canonicalize-candidates.ts at line 967.
What does arbitraryUtilities() call?
arbitraryUtilities() calls 6 function(s): allVariablesAreUsed, get, isValidSpacingMultiplier, parseCandidate, printCandidate, printModifier.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free