diff --git a/packages/tailwindcss/src/intellisense.test.ts b/packages/tailwindcss/src/intellisense.test.ts index 24e418be3fa9..fba60e8824e6 100644 --- a/packages/tailwindcss/src/intellisense.test.ts +++ b/packages/tailwindcss/src/intellisense.test.ts @@ -598,3 +598,25 @@ test('Theme keys with underscores are suggested with underscores', async () => { expect(entries).not.toContainEqual(['p-2_5', { modifiers: [] }]) expect(entries).not.toContainEqual(['p-logo.margin', { modifiers: [] }]) }) + +test('Custom @utility and existing utility with names matching theme keys dont give duplicate results', async () => { + let input = css` + @theme reference { + --leading-sm: 0.25rem; + --text-header: 1.5rem; + } + + @utility text-header { + text-transform: uppercase; + } + ` + + let design = await __unstable__loadDesignSystem(input) + + let classList = design.getClassList() + let classMap = new Map(classList) + let matches = classList.filter(([className]) => className === 'text-header') + + expect(matches).toHaveLength(1) + expect(classMap.get('text-header')?.modifiers).toEqual(['sm']) +}) diff --git a/packages/tailwindcss/src/intellisense.ts b/packages/tailwindcss/src/intellisense.ts index ca9c1a386099..27db3a540bc3 100644 --- a/packages/tailwindcss/src/intellisense.ts +++ b/packages/tailwindcss/src/intellisense.ts @@ -20,16 +20,18 @@ export type ClassEntry = [string, ClassMetadata] const IS_FRACTION = /^\d+\/\d+$/ export function getClassList(design: DesignSystem): ClassEntry[] { - let list: ClassItem[] = [] + let items = new DefaultMap((utility) => ({ + name: utility, + utility, + fraction: false, + modifiers: [], + })) // Static utilities only work as-is for (let utility of design.utilities.keys('static')) { - list.push({ - name: utility, - utility, - fraction: false, - modifiers: [], - }) + let item = items.get(utility) + item.fraction = false + item.modifiers = [] } // Functional utilities have their own list of completions @@ -42,28 +44,25 @@ export function getClassList(design: DesignSystem): ClassEntry[] { let name = value === null ? utility : `${utility}-${value}` - list.push({ - name, - utility, - fraction, - modifiers: group.modifiers, - }) + let item = items.get(name) + item.utility = utility + item.fraction ||= fraction + item.modifiers.push(...group.modifiers) if (group.supportsNegative) { - list.push({ - name: `-${name}`, - utility: `-${utility}`, - fraction, - modifiers: group.modifiers, - }) + let item = items.get(`-${name}`) + item.utility = `-${utility}` + item.fraction ||= fraction + item.modifiers.push(...group.modifiers) } } } } - if (list.length === 0) return [] + if (items.size === 0) return [] // Sort utilities by their class name + let list = Array.from(items.values()) list.sort((a, b) => compare(a.name, b.name)) let entries = sortFractionsLast(list)