From f52f9de21c0bc39c15f41c12286aacec2944e148 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 3 Dec 2024 22:17:24 -0500 Subject: [PATCH 1/4] Cleanup --- .../src/util/v4/design-system.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/tailwindcss-language-service/src/util/v4/design-system.ts b/packages/tailwindcss-language-service/src/util/v4/design-system.ts index ee9396a8..e0c89765 100644 --- a/packages/tailwindcss-language-service/src/util/v4/design-system.ts +++ b/packages/tailwindcss-language-service/src/util/v4/design-system.ts @@ -32,12 +32,12 @@ export interface DesignSystem { getClassOrder(classes: string[]): [string, bigint | null][] getClassList(): ClassEntry[] getVariants(): VariantEntry[] + + // Optional because it did not exist in earlier v4 alpha versions + resolveThemeValue?(path: string): string | undefined } export interface DesignSystem { compile(classes: string[]): postcss.Root[] toCss(nodes: postcss.Root | postcss.Node[]): string - - // Optional because it did not exist in earlier v4 alpha versions - resolveThemeValue?(path: string): string | undefined } From 148bb6ab76b0f70adde253ac4e3aa870f984b5b4 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 3 Dec 2024 22:18:06 -0500 Subject: [PATCH 2/4] Refactor --- .../src/completionProvider.ts | 74 +++++++++---------- .../src/util/v4/design-system.ts | 5 ++ 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index 157c4610..afd6a82a 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -789,6 +789,8 @@ function provideThemeVariableCompletions( position: Position, _context?: CompletionContext, ): CompletionList { + if (!state.v4) return null + // Make sure we're in a CSS "context' if (!isCssContext(state, document, position)) return null let text = getTextWithoutComments(document, 'css', { @@ -804,52 +806,46 @@ function provideThemeVariableCompletions( if (themeBlock === -1) return null if (braceLevel(text.slice(themeBlock)) !== 1) return null - function themeVar(label: string) { - return { - label, - kind: CompletionItemKind.Variable, - // insertTextFormat: InsertTextFormat.Snippet, - // textEditText: `${label}-[\${1}]`, - } - } + let entries: ThemeEntry[] = [ + // Polyfill data for older versions of the design system + { kind: 'variable', name: '--default-transition-duration' }, + { kind: 'variable', name: '--default-transition-timing-function' }, + { kind: 'variable', name: '--default-font-family' }, + { kind: 'variable', name: '--default-font-feature-settings' }, + { kind: 'variable', name: '--default-font-variation-settings' }, + { kind: 'variable', name: '--default-mono-font-family' }, + { kind: 'variable', name: '--default-mono-font-feature-settings' }, + { kind: 'variable', name: '--default-mono-font-variation-settings' }, + { kind: 'namespace', name: '--breakpoint' }, + { kind: 'namespace', name: '--color' }, + { kind: 'namespace', name: '--animate' }, + { kind: 'namespace', name: '--blur' }, + { kind: 'namespace', name: '--radius' }, + { kind: 'namespace', name: '--shadow' }, + { kind: 'namespace', name: '--inset-shadow' }, + { kind: 'namespace', name: '--drop-shadow' }, + { kind: 'namespace', name: '--spacing' }, + { kind: 'namespace', name: '--width' }, + { kind: 'namespace', name: '--font-family' }, + { kind: 'namespace', name: '--font-size' }, + { kind: 'namespace', name: '--letter-spacing' }, + { kind: 'namespace', name: '--line-height' }, + { kind: 'namespace', name: '--transition-timing-function' }, + ] - function themeNamespace(label: string) { - return { - label: `${label}-`, + let items: CompletionItem[] = [] + + for (let entry of entries) { + items.push({ + label: entry.kind === 'namespace' ? entry.name : `${entry.name}-`, kind: CompletionItemKind.Variable, - // insertTextFormat: InsertTextFormat.Snippet, - // textEditText: `${label}-[\${1}]`, - } + }) } return withDefaults( { isIncomplete: false, - items: [ - themeVar('--default-transition-duration'), - themeVar('--default-transition-timing-function'), - themeVar('--default-font-family'), - themeVar('--default-font-feature-settings'), - themeVar('--default-font-variation-settings'), - themeVar('--default-mono-font-family'), - themeVar('--default-mono-font-feature-settings'), - themeVar('--default-mono-font-variation-settings'), - themeNamespace('--breakpoint'), - themeNamespace('--color'), - themeNamespace('--animate'), - themeNamespace('--blur'), - themeNamespace('--radius'), - themeNamespace('--shadow'), - themeNamespace('--inset-shadow'), - themeNamespace('--drop-shadow'), - themeNamespace('--spacing'), - themeNamespace('--width'), - themeNamespace('--font-family'), - themeNamespace('--font-size'), - themeNamespace('--letter-spacing'), - themeNamespace('--line-height'), - themeNamespace('--transition-timing-function'), - ], + items, }, { data: { diff --git a/packages/tailwindcss-language-service/src/util/v4/design-system.ts b/packages/tailwindcss-language-service/src/util/v4/design-system.ts index e0c89765..0cb08c0a 100644 --- a/packages/tailwindcss-language-service/src/util/v4/design-system.ts +++ b/packages/tailwindcss-language-service/src/util/v4/design-system.ts @@ -24,6 +24,11 @@ export interface VariantEntry { export type VariantFn = (rule: Rule, variant: NamedVariant) => null | void +export interface ThemeEntry { + kind: 'namespace' | 'variable' + name: string +} + export interface DesignSystem { theme: Theme variants: Map From 5203c457b117abc5a59a2a7fa60e990619543a83 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 3 Dec 2024 22:18:54 -0500 Subject: [PATCH 3/4] Add support for `getThemeEntries` API --- .../tailwindcss-language-service/src/completionProvider.ts | 5 +++++ .../src/util/v4/design-system.ts | 3 +++ 2 files changed, 8 insertions(+) diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index afd6a82a..37ecd892 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -40,6 +40,7 @@ import { customClassesIn } from './util/classes' import { IS_SCRIPT_SOURCE, IS_TEMPLATE_SOURCE } from './metadata/extensions' import * as postcss from 'postcss' import { findFileDirective } from './completions/file-paths' +import type { ThemeEntry } from './util/v4' let isUtil = (className) => Array.isArray(className.__info) @@ -833,6 +834,10 @@ function provideThemeVariableCompletions( { kind: 'namespace', name: '--transition-timing-function' }, ] + if (state.designSystem.getThemeEntries) { + entries = state.designSystem.getThemeEntries() + } + let items: CompletionItem[] = [] for (let entry of entries) { diff --git a/packages/tailwindcss-language-service/src/util/v4/design-system.ts b/packages/tailwindcss-language-service/src/util/v4/design-system.ts index 0cb08c0a..3a43b011 100644 --- a/packages/tailwindcss-language-service/src/util/v4/design-system.ts +++ b/packages/tailwindcss-language-service/src/util/v4/design-system.ts @@ -40,6 +40,9 @@ export interface DesignSystem { // Optional because it did not exist in earlier v4 alpha versions resolveThemeValue?(path: string): string | undefined + + // Earlier v4 versions did not have this method + getThemeEntries?(): ThemeEntry[] } export interface DesignSystem { From 1dde6785ad920ba61096287e9a87ec69ca9b3af5 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 4 Dec 2024 06:15:31 -0500 Subject: [PATCH 4/4] Fix --- packages/tailwindcss-language-service/src/completionProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts index 37ecd892..df49ab9d 100644 --- a/packages/tailwindcss-language-service/src/completionProvider.ts +++ b/packages/tailwindcss-language-service/src/completionProvider.ts @@ -842,7 +842,7 @@ function provideThemeVariableCompletions( for (let entry of entries) { items.push({ - label: entry.kind === 'namespace' ? entry.name : `${entry.name}-`, + label: entry.kind === 'namespace' ? `${entry.name}-` : entry.name, kind: CompletionItemKind.Variable, }) }