Skip to content

Commit 3aa6b6f

Browse files
committed
wip
1 parent e33bb3e commit 3aa6b6f

File tree

6 files changed

+65
-46
lines changed

6 files changed

+65
-46
lines changed

packages/tailwindcss-language-server/src/util/v4/design-system.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,39 @@ export async function loadDesignSystem(
4848
return tailwindcss.optimizeCss(css)
4949
},
5050

51-
compile(classes: string[]): postcss.Root {
52-
let css = design.candidatesToCss(classes).join('\n')
51+
compile(classes: string[]): postcss.Root[] {
52+
let css = design.candidatesToCss(classes) as (string | null)[]
5353

5454
// Downlevel syntax
5555
// TODO: Either don't downlevel nesting or make `recordClassDetails` more robust
56-
// try {
57-
// css = tailwindcss.optimizeCss(css)
58-
// } catch {}
56+
// css = css.map((str) => {
57+
// if (!str) return null
58+
// try {
59+
// return tailwindcss.optimizeCss(str)
60+
// } catch {}
61+
// return str
62+
// })
5963

6064
// Reformat with Prettier
61-
try {
62-
css = format(css, {
63-
parser: 'css',
64-
singleQuote: true,
65-
trailingComma: 'all',
66-
filepath: 'input.css',
67-
}).trim()
68-
} catch {}
69-
70-
return postcss.parse(css)
65+
let opts = {
66+
parser: 'css',
67+
singleQuote: true,
68+
trailingComma: 'all',
69+
filepath: 'input.css',
70+
}
71+
72+
css = css.map((str) => {
73+
if (!str) return null
74+
try {
75+
return format(str, opts).trim()
76+
} catch {}
77+
return str
78+
})
79+
80+
return css.map((str) => {
81+
if (str === null) return postcss.root()
82+
return postcss.parse(str)
83+
})
7184
},
7285

7386
toCss(nodes: postcss.Root | postcss.Node[]): string {

packages/tailwindcss-language-service/src/completionProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1715,7 +1715,7 @@ export async function resolveCompletionItem(
17151715
if (state.v4) {
17161716
if (item.kind === 9) return item
17171717
if (item.detail && item.documentation) return item
1718-
let root = state.designSystem.compile([[...variants, className].join(state.separator)])
1718+
let root = state.designSystem.compile([[...variants, className].join(state.separator)])[0]
17191719
let rules = root.nodes.filter((node) => node.type === 'rule')
17201720
if (rules.length === 0) return item
17211721

packages/tailwindcss-language-service/src/diagnostics/getCssConflictDiagnostics.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,14 @@ export function visit(
248248
}
249249
}
250250

251-
252251
function recordClassDetails(state: State, classes: DocumentClassName[]): ClassDetails {
253252
const groups: Record<string, RuleEntry[]> = {}
254253

254+
let roots = state.designSystem.compile(classes.map((c) => c.className))
255+
255256
// Get all the properties for each class
256-
for (let className of classes) {
257-
let root = state.designSystem.compile([className.className])
257+
for (let [idx, root] of roots.entries()) {
258+
let { className } = classes[idx]
258259

259260
visit([root], (node, path) => {
260261
if (node.type !== 'rule' && node.type !== 'atrule') return
@@ -269,8 +270,8 @@ function recordClassDetails(state: State, classes: DocumentClassName[]): ClassDe
269270
if (properties.length === 0) return
270271

271272
// We have to slice off the first `context` item because it's the class name and that's always different
272-
groups[className.className] ??= []
273-
groups[className.className].push({
273+
groups[className] ??= []
274+
groups[className].push({
274275
properties,
275276
context: path
276277
.map((node) => {

packages/tailwindcss-language-service/src/hoverProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { State } from './util/state'
2-
import type { Hover, Position } from 'vscode-languageserver'
2+
import type { Hover, Position } from 'vscode-languageserver'
33
import { stringifyCss, stringifyConfigValue } from './util/stringify'
44
import dlv from 'dlv'
55
import { isCssContext } from './util/css'
@@ -63,7 +63,7 @@ async function provideClassNameHover(
6363
if (className === null) return null
6464

6565
if (state.v4) {
66-
let root = state.designSystem.compile([className.className])
66+
let root = state.designSystem.compile([className.className])[0]
6767

6868
if (root.nodes.length === 0) {
6969
return null

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

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -131,33 +131,38 @@ function getColorFromDecls(
131131
return null
132132
}
133133

134-
export function getColor(state: State, className: string): culori.Color | KeywordColor | null {
135-
if (state.v4) {
136-
let css = state.designSystem.compile([className])
137-
let decls: Record<string, string[]> = {}
134+
function getColorFromRoot(state: State, css: postcss.Root): culori.Color | KeywordColor | null {
135+
let decls: Record<string, string[]> = {}
138136

139-
let rule = postcss.rule({
140-
selector: '.x',
141-
nodes: [],
142-
})
137+
let rule = postcss.rule({
138+
selector: '.x',
139+
nodes: [],
140+
})
143141

144-
css.walkDecls((decl) => {
145-
rule.append(decl.clone())
146-
})
142+
css.walkDecls((decl) => {
143+
rule.append(decl.clone())
144+
})
147145

148-
// Optimize the CSS if possible
149-
try {
150-
let str = state.designSystem.toCss(css)
151-
str = state.designSystem.optimizeCss(str)
152-
css = postcss.parse(str)
153-
} catch {}
146+
// Optimize the CSS if possible
147+
try {
148+
let str = state.designSystem.toCss(css)
149+
str = state.designSystem.optimizeCss(str)
150+
css = postcss.parse(str)
151+
} catch {}
154152

155-
css.walkDecls((decl) => {
156-
decls[decl.prop] ??= []
157-
decls[decl.prop].push(decl.value)
158-
})
153+
css.walkDecls((decl) => {
154+
decls[decl.prop] ??= []
155+
decls[decl.prop].push(decl.value)
156+
})
159157

160-
return getColorFromDecls(decls)
158+
return getColorFromDecls(decls)
159+
}
160+
161+
export function getColor(state: State, className: string): culori.Color | KeywordColor | null {
162+
if (state.v4) {
163+
let css = state.designSystem.compile([className])[0]
164+
165+
return getColorFromRoot(state, css)
161166
}
162167

163168
if (state.jit) {

packages/tailwindcss-language-service/src/util/v4/design-system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export interface DesignSystem {
3030
}
3131

3232
export interface DesignSystem {
33-
compile(classes: string[]): postcss.Root
33+
compile(classes: string[]): postcss.Root[]
3434
toCss(nodes: postcss.Root | postcss.Node[]): string
3535
optimizeCss(css: string): string
3636
}

0 commit comments

Comments
 (0)