From 07ad87e8da8bbefb824609857ec7f1fbf3fbf628 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Tue, 3 Jan 2023 16:22:15 +0000 Subject: [PATCH] Support class modifiers (#686) --- .../tailwindcss-language-server/src/server.ts | 3 ++ .../src/completionProvider.ts | 38 +++++++++++++------ .../src/util/state.ts | 2 +- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/packages/tailwindcss-language-server/src/server.ts b/packages/tailwindcss-language-server/src/server.ts index 980b5d9..3437298 100644 --- a/packages/tailwindcss-language-server/src/server.ts +++ b/packages/tailwindcss-language-server/src/server.ts @@ -991,6 +991,9 @@ async function createProjectService( .getClassList() .filter((className) => className !== '*') .map((className) => { + if (Array.isArray(className)) { + return [className[0], { color: getColor(state, className[0]), ...className[1] }] + } return [className, { color: getColor(state, className) }] }) } diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index 2ee4871..d8bee18 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -64,25 +64,43 @@ export function completionsFromClassList( } if (state.jit) { + let { variants: existingVariants, offset } = getVariantsFromClassName(state, partialClassName) + if ( context && (context.triggerKind === 1 || (context.triggerKind === 2 && context.triggerCharacter === '/')) && partialClassName.includes('/') ) { - // opacity modifiers + // modifiers + let modifiers: string[] let beforeSlash = partialClassName.split('/').slice(0, -1).join('/') - let testClass = beforeSlash + '/[0]' - let { rules } = jit.generateRules(state, [testClass]) - if (rules.length > 0) { - let opacities = dlv(state.config, 'theme.opacity', {}) - if (!isObject(opacities)) { - opacities = {} + let classListContainsModifiers = state.classList.some( + (cls) => Array.isArray(cls) && cls[1].modifiers + ) + + if (classListContainsModifiers) { + let baseClassName = beforeSlash.slice(offset) + modifiers = state.classList.find( + (cls) => Array.isArray(cls) && cls[0] === baseClassName + )?.[1].modifiers + } else { + let testClass = beforeSlash + '/[0]' + let { rules } = jit.generateRules(state, [testClass]) + if (rules.length > 0) { + let opacities = dlv(state.config, 'theme.opacity', {}) + if (!isObject(opacities)) { + opacities = {} + } + modifiers = Object.keys(opacities) } + } + + if (modifiers) { return { isIncomplete: false, - items: Object.keys(opacities).map((opacity, index) => { - let className = `${beforeSlash}/${opacity}` + items: modifiers.map((modifier, index) => { + let className = `${beforeSlash}/${modifier}` let kind: CompletionItemKind = 21 let documentation: string = null @@ -110,8 +128,6 @@ export function completionsFromClassList( } } - let { variants: existingVariants, offset } = getVariantsFromClassName(state, partialClassName) - replacementRange.start.character += offset let important = partialClassName.substr(offset).startsWith('!') diff --git a/packages/tailwindcss-language-service/src/util/state.ts b/packages/tailwindcss-language-service/src/util/state.ts index 5d5c832..3787bdc 100644 --- a/packages/tailwindcss-language-service/src/util/state.ts +++ b/packages/tailwindcss-language-service/src/util/state.ts @@ -116,7 +116,7 @@ export interface State { editor?: EditorState jit?: boolean jitContext?: any - classList?: Array<[string, { color: culori.Color | KeywordColor | null }]> + classList?: Array<[string, { color: culori.Color | KeywordColor | null; modifiers?: string[] }]> pluginVersions?: string // postcssPlugins?: { before: any[]; after: any[] } }