resolveValueFunction() — tailwindcss Function Reference
Architecture documentation for the resolveValueFunction() function in utilities.ts from the tailwindcss codebase.
Entity Profile
Dependency Diagram
graph TD 0866206a_2fd9_ab63_77ac_471d39e47d4c["resolveValueFunction()"] 5af2f27c_4323_fb62_14cc_5b4f717b4d2f["createCssUtility()"] 5af2f27c_4323_fb62_14cc_5b4f717b4d2f -->|calls| 0866206a_2fd9_ab63_77ac_471d39e47d4c e5eb2faf_45a2_ac47_3404_8bd4e7eb6817["parse()"] 0866206a_2fd9_ab63_77ac_471d39e47d4c -->|calls| e5eb2faf_45a2_ac47_3404_8bd4e7eb6817 ce52b228_a53f_22f4_e753_5d926d778157["resolve()"] 0866206a_2fd9_ab63_77ac_471d39e47d4c -->|calls| ce52b228_a53f_22f4_e753_5d926d778157 fb5e61c5_06c8_ebde_b131_be4b13697508["resolveWith()"] 0866206a_2fd9_ab63_77ac_471d39e47d4c -->|calls| fb5e61c5_06c8_ebde_b131_be4b13697508 eefa9c6c_5f66_c5a0_7a28_80b6d58572cd["inferDataType()"] 0866206a_2fd9_ab63_77ac_471d39e47d4c -->|calls| eefa9c6c_5f66_c5a0_7a28_80b6d58572cd 03b8d706_a876_a776_0056_186ced5d6067["segment()"] 0866206a_2fd9_ab63_77ac_471d39e47d4c -->|calls| 03b8d706_a876_a776_0056_186ced5d6067 4eec17e9_9a96_168a_2273_b6e64e229816["isPositiveInteger()"] 0866206a_2fd9_ab63_77ac_471d39e47d4c -->|calls| 4eec17e9_9a96_168a_2273_b6e64e229816 1dd167b2_b42d_8596_9276_d0e969bf2522["isValidSpacingMultiplier()"] 0866206a_2fd9_ab63_77ac_471d39e47d4c -->|calls| 1dd167b2_b42d_8596_9276_d0e969bf2522 style 0866206a_2fd9_ab63_77ac_471d39e47d4c fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
packages/tailwindcss/src/utilities.ts lines 6303–6445
function resolveValueFunction(
value: NonNullable<
| Extract<Candidate, { kind: 'functional' }>['value']
| Extract<Candidate, { kind: 'functional' }>['modifier']
>,
fn: ValueParser.ValueFunctionNode,
designSystem: DesignSystem,
): { nodes: ValueParser.ValueAstNode[]; ratio?: boolean } | undefined {
for (let arg of fn.nodes) {
// Resolve literal value, e.g.: `--modifier('closest-side')`
if (
value.kind === 'named' &&
arg.kind === 'word' &&
// Should be wreapped in quotes
(arg.value[0] === "'" || arg.value[0] === '"') &&
arg.value[arg.value.length - 1] === arg.value[0] &&
// Values should match
arg.value.slice(1, -1) === value.value
) {
return { nodes: ValueParser.parse(value.value) }
}
// Resolving theme value, e.g.: `--value(--color)`
else if (
value.kind === 'named' &&
arg.kind === 'word' &&
arg.value[0] === '-' &&
arg.value[1] === '-'
) {
let themeKey = arg.value as `--${string}`
// Resolve the theme value, e.g.: `--value(--color)`
if (themeKey.endsWith('-*')) {
// Without `-*` postfix
themeKey = themeKey.slice(0, -2) as `--${string}`
let resolved = designSystem.theme.resolve(value.value, [themeKey])
if (resolved) return { nodes: ValueParser.parse(resolved) }
}
// Split `--text-*--line-height` into `--text` and `--line-height`
else {
let nestedKeys = themeKey.split('-*') as `--${string}`[]
if (nestedKeys.length <= 1) continue
// Resolve theme values with nested keys, e.g.: `--value(--text-*--line-height)`
let themeKeys = [nestedKeys.shift()!]
let resolved = designSystem.theme.resolveWith(value.value, themeKeys, nestedKeys)
if (resolved) {
let [, options = {}] = resolved
// Resolve the value from the `options`
{
let resolved = options[nestedKeys.pop()!]
if (resolved) return { nodes: ValueParser.parse(resolved) }
}
}
}
}
// Bare value, e.g.: `--value(integer)`
else if (value.kind === 'named' && arg.kind === 'word') {
// Limit the bare value types, to prevent new syntax that we
// don't want to support. E.g.: `text-#000` is something we
// don't want to support, but could be built this way.
if (!BARE_VALUE_DATA_TYPES.includes(arg.value)) {
continue
}
let resolved = arg.value === 'ratio' && 'fraction' in value ? value.fraction : value.value
if (!resolved) continue
let type = inferDataType(resolved, [arg.value as any])
if (type === null) continue
// Ratio must be a valid fraction, e.g.: <integer>/<integer>
if (type === 'ratio') {
let [lhs, rhs] = segment(resolved, '/').map(Number)
if (!isPositiveInteger(lhs) || !isPositiveInteger(rhs)) continue
}
// Non-integer numbers should be a valid multiplier,
// e.g.: `1.5`
else if (type === 'number' && !isValidSpacingMultiplier(resolved)) {
continue
}
// Percentages must be an integer, e.g.: `50%`
else if (type === 'percentage' && !isPositiveInteger(resolved.slice(0, -1))) {
continue
}
if (type === 'ratio') {
let [lhs, rhs] = segment(resolved, '/')
return { nodes: ValueParser.parse(`${lhs.trim()} / ${rhs.trim()}`), ratio: true }
}
return { nodes: ValueParser.parse(resolved), ratio: false }
}
// Arbitrary value, e.g.: `--value([integer])`
else if (
value.kind === 'arbitrary' &&
arg.kind === 'word' &&
arg.value[0] === '[' &&
arg.value[arg.value.length - 1] === ']'
) {
let dataType = arg.value.slice(1, -1)
// Allow any data type, e.g.: `--value([*])`
if (dataType === '*') {
return { nodes: ValueParser.parse(value.value) }
}
// The forced arbitrary value hint must match the expected
// data type.
//
// ```css
// @utility tab-* {
// tab-size: --value([integer]);
// }
// ```
//
// Given a candidate like `tab-(color:var(--my-value))`,
// should not match because `color` and `integer` don't
// match.
if ('dataType' in value && value.dataType && value.dataType !== dataType) {
continue
}
// Use the provided data type hint
if ('dataType' in value && value.dataType) {
return { nodes: ValueParser.parse(value.value) }
}
// No data type hint provided, so we have to infer it
let type = inferDataType(value.value, [dataType as any])
if (type !== null) {
return { nodes: ValueParser.parse(value.value) }
}
}
}
}
Domain
Subdomains
Calls
Called By
Source
Frequently Asked Questions
What does resolveValueFunction() do?
resolveValueFunction() is a function in the tailwindcss codebase.
What does resolveValueFunction() call?
resolveValueFunction() calls 7 function(s): inferDataType, isPositiveInteger, isValidSpacingMultiplier, parse, resolve, resolveWith, segment.
What calls resolveValueFunction()?
resolveValueFunction() is called by 1 function(s): createCssUtility.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free