Skip to content

Commit ed600f9

Browse files
committed
Work around candidate parsing bug
1 parent 861e636 commit ed600f9

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ export function getVariantsFromClassName(
2020
return { variants: [], offset: 0 }
2121
}
2222

23-
parts = parts.filter(Boolean)
24-
2523
function isValidVariant(part: string) {
2624
if (allVariants.includes(part)) {
2725
return true
@@ -60,11 +58,36 @@ export function getVariantsFromClassName(
6058
let offset = 0
6159
let variants = new Set<string>()
6260

63-
for (let part of parts) {
61+
for (let [index, part] of parts.entries()) {
62+
// If we see an empty variant it's because:
63+
//
64+
// - The string contains consecutive top-level separators, e.g.
65+
// hover::flex
66+
// - The string *ends* with a `:` which is a signal that the variant is done
67+
// and more should be suggested
68+
69+
// The first case isn't a valid class, partial or otherwise. The second one
70+
// *is* valid because a user is probably in the middle of typing a utility.
71+
//
72+
// In both situations a `break` is sufficient to signal that the remainder
73+
// of the string should be ignored when determining variants.
74+
if (part === '') break
6475
if (!isValidVariant(part)) break
6576

6677
variants.add(part)
67-
offset += part.length + state.separator!.length
78+
79+
offset += part.length
80+
81+
// All variants must be succeeded by the separator (`:`) when used in a
82+
// utility. However, Tailwind CSS <= v4.1.15 has a bug where we consider
83+
// `bg-[` valid because we try to compile `bg-[:[color:red]` which in turn
84+
// parses as a valid class when it obviously is not.
85+
//
86+
// To combat this we've done two things:
87+
// - Add the offset to all variants *except* the last one
88+
// - Allow an empty string in the last position to account for situations
89+
// where a utility name is currently being typed (e.g. `hover:`)
90+
offset += index < parts.length - 1 ? state.separator!.length : 0
6891
}
6992

7093
return { variants: Array.from(variants), offset }

0 commit comments

Comments
 (0)