Skip to content

Commit a2b3583

Browse files
committed
Refactor
1 parent 0a3d2ab commit a2b3583

File tree

8 files changed

+92
-46
lines changed

8 files changed

+92
-46
lines changed

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

Lines changed: 1 addition & 1 deletion
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 './css-vars'
11+
import { replaceCssVarsWithFallbacks } from './rewriting'
1212

1313
const COLOR_PROPS = [
1414
'accent-color',

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ import type { Comment } from './comments'
66

77
let allowedFunctions = ['rgb', 'rgba', 'hsl', 'hsla', 'lch', 'lab', 'oklch', 'oklab']
88

9+
export function getEquivalentColor(value: string): string {
10+
const color = getColorFromValue(value)
11+
12+
if (!color) return value
13+
if (typeof color === 'string') return value
14+
if (!inGamut('rgb')(color)) return value
15+
16+
return formatColor(color)
17+
}
18+
919
export function equivalentColorValues({ comments }: { comments: Comment[] }): Plugin {
1020
return {
1121
postcssPlugin: 'plugin',
@@ -28,12 +38,11 @@ export function equivalentColorValues({ comments }: { comments: Comment[] }): Pl
2838
return false
2939
}
3040

31-
const color = getColorFromValue(`${node.value}(${values.join(' ')})`)
32-
if (!inGamut('rgb')(color)) {
33-
return false
34-
}
41+
let color = `${node.value}(${values.join(' ')})`
42+
43+
let equivalent = getEquivalentColor(color)
3544

36-
if (!color || typeof color === 'string') {
45+
if (equivalent === color) {
3746
return false
3847
}
3948

@@ -42,7 +51,7 @@ export function equivalentColorValues({ comments }: { comments: Comment[] }): Pl
4251
decl.source.start.offset +
4352
`${decl.prop}${decl.raws.between}`.length +
4453
node.sourceEndIndex,
45-
value: formatColor(color),
54+
value: equivalent,
4655
})
4756

4857
return false
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1+
import { spliceChangesIntoString } from './splice-changes-into-string'
2+
13
export type Comment = { index: number; value: string }
24

35
export function applyComments(str: string, comments: Comment[]): string {
4-
let offset = 0
5-
6-
for (let comment of comments) {
7-
let index = comment.index + offset
8-
let commentStr = ` /* ${comment.value} */`
9-
str = str.slice(0, index) + commentStr + str.slice(index)
10-
offset += commentStr.length
11-
}
12-
13-
return str
6+
return spliceChangesIntoString(
7+
str,
8+
comments.map((c) => ({
9+
start: c.index,
10+
end: c.index,
11+
replacement: ` /* ${c.value} */`,
12+
})),
13+
)
1414
}

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { isTokenNode } from '@csstools/css-parser-algorithms'
55
import type { Comment } from './comments'
66
import { applyComments } from './comments'
77

8-
export function addPixelEquivalentsToValue(value: string, rootFontSize: number): string {
8+
export function addPixelEquivalentsToValue(
9+
value: string,
10+
rootFontSize: number,
11+
inComment = true,
12+
): string {
913
if (!value.includes('rem')) {
1014
return value
1115
}
@@ -20,8 +24,15 @@ export function addPixelEquivalentsToValue(value: string, rootFontSize: number):
2024
return false
2125
}
2226

23-
let commentStr = ` /* ${parseFloat(unit.number) * rootFontSize}px */`
24-
value = value.slice(0, node.sourceEndIndex) + commentStr + value.slice(node.sourceEndIndex)
27+
if (inComment) {
28+
let commentStr = ` /* ${parseFloat(unit.number) * rootFontSize}px */`
29+
value = value.slice(0, node.sourceEndIndex) + commentStr + value.slice(node.sourceEndIndex)
30+
31+
return false
32+
}
33+
34+
let commentStr = `${parseFloat(unit.number) * rootFontSize}px`
35+
value = value.slice(0, node.sourceIndex) + commentStr + value.slice(node.sourceEndIndex)
2536

2637
return false
2738
})

packages/tailwindcss-language-service/src/util/css-vars.test.ts renamed to packages/tailwindcss-language-service/src/util/rewriting/index.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import { expect, test } from 'vitest'
2-
import { replaceCssVarsWithFallbacks } from './css-vars'
3-
import { State } from './state'
4-
import { DesignSystem } from './v4'
2+
import { replaceCssVarsWithFallbacks } from './index'
3+
import { State } from '../state'
4+
import { DesignSystem } from '../v4'
55

66
test('replacing CSS variables with their fallbacks (when they have them)', () => {
7-
let map = new Map<string, string>([
8-
['--known', 'blue'],
9-
])
7+
let map = new Map<string, string>([['--known', 'blue']])
108

119
let state: State = {
1210
enabled: true,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './replacements'
2+
export * from './var-fallbacks'

packages/tailwindcss-language-service/src/util/css-vars.ts renamed to packages/tailwindcss-language-service/src/util/rewriting/replacements.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
import type { State } from './state'
2-
3-
export function replaceCssVarsWithFallbacks(state: State, str: string): string {
4-
return replaceCssVars(str, (name, fallback) => {
5-
// Replace with the value from the design system first. The design system
6-
// take precedences over other sources as that emulates the behavior of a
7-
// browser where the fallback is only used if the variable is defined.
8-
if (state.designSystem && name.startsWith('--')) {
9-
let value = state.designSystem.resolveThemeValue?.(name) ?? null
10-
if (value !== null) return value
11-
}
1+
/**
2+
* A var(…) expression which may have an optional fallback value
3+
*/
4+
export interface CssVariable {
5+
kind: 'css-variable'
6+
range: Range
7+
name: string
8+
fallback: string | null
9+
}
1210

13-
if (fallback) {
14-
return fallback
15-
}
11+
export interface Range {
12+
/** The zero-based offset where this node starts */
13+
start: number
1614

17-
// Don't touch it since there's no suitable replacement
18-
return null
19-
})
15+
/** The zero-based offset where this node ends */
16+
end: number
2017
}
2118

22-
type CssVarReplacer = (name: string, fallback: string | null) => string | null
19+
export type CssVarReplacer = (node: CssVariable) => string | null
2320

24-
function replaceCssVars(str: string, replace: CssVarReplacer): string {
21+
/**
22+
* Replace all var expressions in a string using the replacer function
23+
*/
24+
export function replaceCssVars(str: string, replace: CssVarReplacer): string {
2525
for (let i = 0; i < str.length; ++i) {
2626
if (!str.startsWith('var(', i)) continue
2727

@@ -47,7 +47,12 @@ function replaceCssVars(str: string, replace: CssVarReplacer): string {
4747
fallback = str.slice(fallbackStart, j)
4848
}
4949

50-
let replacement = replace(varName, fallback)
50+
let replacement = replace({
51+
kind: 'css-variable',
52+
name: varName,
53+
fallback,
54+
range: { start: i, end: j },
55+
})
5156

5257
if (replacement !== null) {
5358
str = str.slice(0, i) + replacement + str.slice(j + 1)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { State } from '../state'
2+
import { replaceCssVars } from './replacements'
3+
4+
export function replaceCssVarsWithFallbacks(state: State, str: string): string {
5+
return replaceCssVars(str, ({ name, fallback }) => {
6+
// Replace with the value from the design system first. The design system
7+
// take precedences over other sources as that emulates the behavior of a
8+
// browser where the fallback is only used if the variable is defined.
9+
if (state.designSystem && name.startsWith('--')) {
10+
let value = state.designSystem.resolveThemeValue?.(name) ?? null
11+
if (value !== null) return value
12+
}
13+
14+
if (fallback) {
15+
return fallback
16+
}
17+
18+
// Don't touch it since there's no suitable replacement
19+
return null
20+
})
21+
}

0 commit comments

Comments
 (0)