Skip to content

Commit 87ef383

Browse files
committed
wip
wip wip wip wip wip wip wip wip wip
1 parent ef7f203 commit 87ef383

File tree

17 files changed

+1095
-609
lines changed

17 files changed

+1095
-609
lines changed

packages/tailwindcss-language-service/src/util/color.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as jit from './jit'
88
import * as culori from 'culori'
99
import namedColors from 'color-name'
1010
import postcss from 'postcss'
11-
import { replaceCssVarsWithFallbacks } from './rewriting'
11+
import { createProcessor } from './rewriting'
1212

1313
const COLOR_PROPS = [
1414
'accent-color',
@@ -64,9 +64,16 @@ function getColorsInString(state: State, str: string): (culori.Color | KeywordCo
6464
return getKeywordColor(color) ?? tryParseColor(color)
6565
}
6666

67-
str = replaceCssVarsWithFallbacks(state, str)
68-
str = removeColorMixWherePossible(str)
69-
str = resolveLightDark(str)
67+
// @ts-ignore
68+
state.processColors ??= createProcessor({
69+
style: 'full-evaluation',
70+
fontSize: null,
71+
variables: new Map(),
72+
state,
73+
})
74+
75+
// @ts-ignore
76+
str = state.processColors(str)
7077

7178
let possibleColors = str.matchAll(colorRegex)
7279

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* A Map that can generate default values for keys that don't exist.
3+
* Generated default values are added to the map to avoid recomputation.
4+
*/
5+
export class DefaultMap<T = string, V = any> extends Map<T, V> {
6+
constructor(private factory: (key: T, self: DefaultMap<T, V>) => V) {
7+
super()
8+
}
9+
10+
get(key: T): V {
11+
let value = super.get(key)
12+
13+
if (value === undefined) {
14+
value = this.factory(key, this)
15+
this.set(key, value)
16+
}
17+
18+
return value
19+
}
20+
}

packages/tailwindcss-language-service/src/util/jit.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import type { State } from './state'
22
import type { Container, Document, Root, Rule, Node, AtRule } from 'postcss'
3-
import { addPixelEquivalentsToValue } from './pixelEquivalents'
4-
import { addEquivalents } from './equivalents'
5-
import { addThemeValues, inlineThemeValues } from './rewriting'
3+
import { createProcessor } from './rewriting'
64

75
export function bigSign(bigIntValue: number | bigint): number {
86
// @ts-ignore
@@ -45,8 +43,14 @@ export async function stringifyRoot(state: State, root: Root, uri?: string): Pro
4543

4644
let css = clone.toString()
4745

48-
css = addThemeValues(css, state, settings.tailwindCSS)
49-
css = addEquivalents(css, settings.tailwindCSS)
46+
let process = createProcessor({
47+
style: 'user-presentable',
48+
fontSize: settings.tailwindCSS.showPixelEquivalents ? settings.tailwindCSS.rootFontSize : null,
49+
variables: new Map(),
50+
state,
51+
})
52+
53+
css = process(css)
5054

5155
let identSize = state.v4 ? 2 : 4
5256
let identPattern = state.v4 ? /^(?: )+/gm : /^(?: )+/gm
@@ -68,15 +72,17 @@ export function stringifyRules(state: State, rules: Rule[], tabSize: number = 2)
6872
export async function stringifyDecls(state: State, rule: Rule, uri?: string): Promise<string> {
6973
let settings = await state.editor.getConfiguration(uri)
7074

75+
let process = createProcessor({
76+
style: 'full-evaluation',
77+
fontSize: settings.tailwindCSS.showPixelEquivalents ? settings.tailwindCSS.rootFontSize : null,
78+
variables: new Map(),
79+
state,
80+
})
81+
7182
let result = []
7283

7384
rule.walkDecls(({ prop, value }) => {
74-
// In v4 we inline theme values into declarations (this is a no-op in v3)
75-
value = inlineThemeValues(value, state).trim()
76-
77-
if (settings.tailwindCSS.showPixelEquivalents) {
78-
value = addPixelEquivalentsToValue(value, settings.tailwindCSS.rootFontSize)
79-
}
85+
value = process(value).trim()
8086

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

packages/tailwindcss-language-service/src/util/rewriting/add-theme-values.ts

Lines changed: 0 additions & 120 deletions
This file was deleted.

packages/tailwindcss-language-service/src/util/rewriting/calc.ts

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { expect, test } from 'vitest'
2+
import { colorFromString, colorMixFromString, equivalentColorFromString } from './color'
3+
4+
test('colorFromString', () => {
5+
expect(colorFromString('red')).toEqual({ mode: 'rgb', r: 1, g: 0, b: 0 })
6+
expect(colorFromString('rgb(255 0 0)')).toEqual({ mode: 'rgb', r: 1, g: 0, b: 0 })
7+
expect(colorFromString('hsl(0 100% 50%)')).toEqual({ mode: 'hsl', h: 0, s: 1, l: 0.5 })
8+
expect(colorFromString('#f00')).toEqual({ mode: 'rgb', r: 1, g: 0, b: 0 })
9+
expect(colorFromString('#f003')).toEqual({ mode: 'rgb', r: 1, g: 0, b: 0, alpha: 0.2 })
10+
expect(colorFromString('#ff0000')).toEqual({ mode: 'rgb', r: 1, g: 0, b: 0 })
11+
expect(colorFromString('#ff000033')).toEqual({ mode: 'rgb', r: 1, g: 0, b: 0, alpha: 0.2 })
12+
13+
expect(colorFromString('color(srgb 1 0 0 )')).toEqual({ mode: 'rgb', r: 1, g: 0, b: 0 })
14+
expect(colorFromString('color(srgb-linear 1 0 0 )')).toEqual({ mode: 'lrgb', r: 1, g: 0, b: 0 })
15+
expect(colorFromString('color(display-p3 1 0 0 )')).toEqual({ mode: 'p3', r: 1, g: 0, b: 0 })
16+
expect(colorFromString('color(a98-rgb 1 0 0 )')).toEqual({ mode: 'a98', r: 1, g: 0, b: 0 })
17+
expect(colorFromString('color(prophoto-rgb 1 0 0 )')).toEqual({
18+
mode: 'prophoto',
19+
r: 1,
20+
g: 0,
21+
b: 0,
22+
})
23+
expect(colorFromString('color(rec2020 1 0 0 )')).toEqual({ mode: 'rec2020', r: 1, g: 0, b: 0 })
24+
25+
expect(colorFromString('color(xyz 1 0 0 )')).toEqual({ mode: 'xyz65', x: 1, y: 0, z: 0 })
26+
expect(colorFromString('color(xyz-d65 1 0 0 )')).toEqual({ mode: 'xyz65', x: 1, y: 0, z: 0 })
27+
expect(colorFromString('color(xyz-d50 1 0 0 )')).toEqual({ mode: 'xyz50', x: 1, y: 0, z: 0 })
28+
29+
expect(colorFromString('#ff000033cccc')).toEqual(null)
30+
31+
// none keywords work too
32+
expect(colorFromString('rgb(255 none 0)')).toEqual({ mode: 'rgb', r: 1, b: 0 })
33+
})
34+
35+
test('can compute color mix', () => {
36+
expect(colorMixFromString('color-mix(in srgb, #f00 50%, transparent)')).toEqual({
37+
mode: 'rgb',
38+
r: 1,
39+
g: 0,
40+
b: 0,
41+
alpha: 0.5,
42+
})
43+
44+
expect(colorMixFromString('color-mix(in srgb, #ff33ff, #33ff3380)')).toEqual({
45+
mode: 'rgb',
46+
r: expect.closeTo(0.733),
47+
g: expect.closeTo(0.467),
48+
b: expect.closeTo(0.733),
49+
alpha: 0.751,
50+
})
51+
})
52+
53+
test('equivalentColorFromString', () => {
54+
expect(equivalentColorFromString('oklch(0.9876 0.0249 101.95)')).toEqual('#fefce9')
55+
})

0 commit comments

Comments
 (0)