Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,12 @@ withFixture('v4/basic', (c) => {

expect(resolved).toEqual({
...item,
detail:
'font-size: var(--text-sm); line-height: var(--tw-leading, var(--text-sm--line-height)); letter-spacing: undefined; font-weight: undefined;',
detail: [
'font-size: 0.875rem /* 8.75px */;',
'line-height: ≈ 1.4286;',
'letter-spacing: undefined;',
'font-weight: undefined;',
].join(' '),
documentation: {
kind: 'markdown',
value: [
Expand Down Expand Up @@ -621,7 +625,7 @@ withFixture('v4/basic', (c) => {

expect(resolved).toEqual({
...item,
detail: 'background-color: var(--color-red-500);',
detail: 'background-color: oklch(0.637 0.237 25.331);',
documentation: '#fb2c36',
})
})
Expand Down Expand Up @@ -650,19 +654,19 @@ withFixture('v4/workspaces', (c) => {

expect(resolved[0]).toEqual({
...items[0],
detail: 'background-color: var(--color-beet);',
detail: 'background-color: #8e3b46;',
documentation: '#8e3b46',
})

expect(resolved[1]).toEqual({
...items[1],
detail: 'background-color: var(--color-orangepeel);',
detail: 'background-color: #ff9f00;',
documentation: '#ff9f00',
})

expect(resolved[2]).toEqual({
...items[2],
detail: 'background-color: var(--color-style-main);',
detail: 'background-color: #8e3b46;',
documentation: '#8e3b46',
})
})
Expand Down
8 changes: 7 additions & 1 deletion packages/tailwindcss-language-service/src/util/jit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { State } from './state'
import type { Container, Document, Root, Rule, Node, AtRule } from 'postcss'
import { addPixelEquivalentsToValue } from './pixelEquivalents'
import { addEquivalents } from './equivalents'
import { addThemeValues } from './rewriting'
import { addThemeValues, inlineThemeValues } from './rewriting'

export function bigSign(bigIntValue) {
// @ts-ignore
Expand Down Expand Up @@ -69,12 +69,18 @@ export async function stringifyDecls(state: State, rule: Rule, uri?: string): Pr
let settings = await state.editor.getConfiguration(uri)

let result = []

rule.walkDecls(({ prop, value }) => {
// In v4 we inline theme values into declarations (this is a no-op in v3)
value = inlineThemeValues(value, state).trim()

if (settings.tailwindCSS.showPixelEquivalents) {
value = addPixelEquivalentsToValue(value, settings.tailwindCSS.rootFontSize)
}

result.push(`${prop}: ${value};`)
})

return result.join(' ')
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './replacements'
export * from './var-fallbacks'
export * from './calc'
export * from './add-theme-values'
export * from './inline-theme-values'
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { State, TailwindCssSettings } from '../state'

import { evaluateExpression } from './calc'
import { replaceCssVars, replaceCssCalc } from './replacements'

export function inlineThemeValues(css: string, state: State) {
if (!state.designSystem) return css

css = replaceCssCalc(css, (expr) => {
let inlined = replaceCssVars(expr.value, ({ name, fallback }) => {
if (!name.startsWith('--')) return null

let value = state.designSystem.resolveThemeValue?.(name) ?? null
if (value === null) return fallback

// Inline CSS calc expressions in theme values
value = replaceCssCalc(value, (expr) => evaluateExpression(expr.value))

return value
})

return evaluateExpression(inlined)
})

css = replaceCssVars(css, ({ name, fallback }) => {
if (!name.startsWith('--')) return null

let value = state.designSystem.resolveThemeValue?.(name) ?? null
if (value === null) return fallback

value = replaceCssCalc(value, (expr) => {
let evaluated = evaluateExpression(expr.value)
if (!evaluated) return null
if (evaluated === expr.value) return null

return `≈ ${evaluated}`
})

return value
})

return css
}