Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Work around candidate parsing bug
  • Loading branch information
thecrypticace committed Oct 21, 2025
commit ed600f98d85fa44847c48947a0693733702f6408
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export function getVariantsFromClassName(
return { variants: [], offset: 0 }
}

parts = parts.filter(Boolean)

function isValidVariant(part: string) {
if (allVariants.includes(part)) {
return true
Expand Down Expand Up @@ -60,11 +58,36 @@ export function getVariantsFromClassName(
let offset = 0
let variants = new Set<string>()

for (let part of parts) {
for (let [index, part] of parts.entries()) {
// If we see an empty variant it's because:
//
// - The string contains consecutive top-level separators, e.g.
// hover::flex
// - The string *ends* with a `:` which is a signal that the variant is done
// and more should be suggested

// The first case isn't a valid class, partial or otherwise. The second one
// *is* valid because a user is probably in the middle of typing a utility.
//
// In both situations a `break` is sufficient to signal that the remainder
// of the string should be ignored when determining variants.
if (part === '') break
if (!isValidVariant(part)) break

variants.add(part)
offset += part.length + state.separator!.length

offset += part.length

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

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