diff --git a/packages/tailwindcss-language-server/tests/completions/completions.test.js b/packages/tailwindcss-language-server/tests/completions/completions.test.js index feb4999f..ce5c7831 100644 --- a/packages/tailwindcss-language-server/tests/completions/completions.test.js +++ b/packages/tailwindcss-language-server/tests/completions/completions.test.js @@ -740,6 +740,80 @@ defineTest({ }, }) +defineTest({ + name: 'v4: Completions show after a variant arbitrary value, using prefixes', + fs: { + 'app.css': css` + @import 'tailwindcss' prefix(tw); + `, + }, + prepare: async ({ root }) => ({ client: await createClient({ root }) }), + handle: async ({ client }) => { + let document = await client.open({ + lang: 'html', + text: '
', + }) + + //
+ // ^ + let completion = await document.completions({ line: 0, character: 26 }) + + expect(completion?.items.length).toBe(19236) + }, +}) + +defineTest({ + name: 'v4: Variant and utility suggestions show prefix when one has been typed', + fs: { + 'app.css': css` + @import 'tailwindcss' prefix(tw); + `, + }, + prepare: async ({ root }) => ({ client: await createClient({ root }) }), + handle: async ({ client }) => { + let document = await client.open({ + lang: 'html', + text: '
', + }) + + //
+ // ^ + let completion = await document.completions({ line: 0, character: 12 }) + + expect(completion?.items.length).toBe(19237) + + // Verify that variants and utilities are all prefixed + let prefixed = completion.items.filter((item) => !item.label.startsWith('tw:')) + expect(prefixed).toHaveLength(0) + }, +}) + +defineTest({ + name: 'v4: Variant and utility suggestions hide prefix when it has been typed', + fs: { + 'app.css': css` + @import 'tailwindcss' prefix(tw); + `, + }, + prepare: async ({ root }) => ({ client: await createClient({ root }) }), + handle: async ({ client }) => { + let document = await client.open({ + lang: 'html', + text: '
', + }) + + //
+ // ^ + let completion = await document.completions({ line: 0, character: 15 }) + + expect(completion?.items.length).toBe(19236) + + // Verify that no variants and utilities have prefixes + let prefixed = completion.items.filter((item) => item.label.startsWith('tw:')) + expect(prefixed).toHaveLength(0) + }, +}) + defineTest({ name: 'v4: Completions show inside class functions in JS/TS files', fs: { diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index 5c0c5552..843e9a8e 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -261,29 +261,25 @@ export function completionsFromClassList( // TODO: This is a bit of a hack if (prefix.length > 0) { - // No variants seen: suggest the prefix only + // No variants seen: + // - suggest the prefix as a variant + // - Modify the remaining items to include the prefix in the variant name if (existingVariants.length === 0) { - items = items.slice(0, 1) + items = items.map((item, idx) => { + if (idx === 0) return item - return withDefaults( - { - isIncomplete: false, - items, - }, - { - data: { - ...(state.completionItemData ?? {}), - ...(important ? { important } : {}), - variants: existingVariants, - }, - range: replacementRange, - }, - state.editor.capabilities.itemDefaults, - ) + item.label = `${prefix}:${item.label}` + + if (item.textEditText) { + item.textEditText = `${prefix}:${item.textEditText}` + } + + return item + }) } // The first variant is not the prefix: don't suggest anything - if (existingVariants[0] !== prefix) { + if (existingVariants.length > 0 && existingVariants[0] !== prefix) { return null } } @@ -304,6 +300,10 @@ export function completionsFromClassList( documentation = formatColor(color) } + if (prefix.length > 0 && existingVariants.length === 0) { + className = `${prefix}:${className}` + } + items.push({ label: className, kind, diff --git a/packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts b/packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts index c30e729a..823b20f8 100644 --- a/packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts +++ b/packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts @@ -33,6 +33,12 @@ export function getVariantsFromClassName( // NOTE: This should never happen if (!state.designSystem) return false + let prefix = state.designSystem.theme.prefix ?? '' + + if (prefix !== '') { + className = `${prefix}:${className}` + } + // We don't use `compile()` so there's no overhead from PostCSS let compiled = state.designSystem.candidatesToCss([className])