diff --git a/packages/tailwindcss-language-server/src/project-locator.test.ts b/packages/tailwindcss-language-server/src/project-locator.test.ts index 7071b65f..6414a099 100644 --- a/packages/tailwindcss-language-server/src/project-locator.test.ts +++ b/packages/tailwindcss-language-server/src/project-locator.test.ts @@ -1,4 +1,4 @@ -import { expect, test } from 'vitest' +import { expect, test, TestOptions } from 'vitest' import * as path from 'node:path' import { ProjectLocator } from './project-locator' import { URL, fileURLToPath } from 'url' @@ -279,6 +279,48 @@ testLocator({ ], }) +testLocator({ + name: 'Roots are detected when they indirectly use Tailwind features', + fs: { + 'package.json': json` + { + "dependencies": { + "tailwindcss": "4.0.6" + } + } + `, + // TODO: This is marked as the root which is… maybe fine but not sure + // The intention in this example is that src/globals.css is the real root + // but if src/articles.css suddenly gained `@theme` blocks then maybe it'd + // need to be the root instead. + 'src/articles/articles.css': css` + @reference "../globals.css"; + .article-title { + @apply text-primary; + } + `, + 'src/articles/layout.js': js` + import "./articles.css"; + export default function Layout(children) { + return children; + } + `, + 'src/globals.css': scss` + @import "tailwindcss"; + @theme { + --color-primary: #3490dc; + } + `, + }, + expected: [ + { + version: '4.0.6', + config: '/src/articles/articles.css', + content: [], + }, + ], +}) + // --- function testLocator({ @@ -286,16 +328,19 @@ function testLocator({ fs, expected, settings, + options, }: { name: string fs: Storage settings?: Partial expected: any[] + options?: TestOptions }) { defineTest({ name, fs, prepare, + options, async handle({ search }) { let projects = await search(settings) diff --git a/packages/tailwindcss-language-server/src/project-locator.ts b/packages/tailwindcss-language-server/src/project-locator.ts index 64f7329b..460b1423 100644 --- a/packages/tailwindcss-language-server/src/project-locator.ts +++ b/packages/tailwindcss-language-server/src/project-locator.ts @@ -427,11 +427,18 @@ export class ProjectLocator { if (indexPath && themePath) graph.connect(indexPath, themePath) if (indexPath && utilitiesPath) graph.connect(indexPath, utilitiesPath) - for (let root of graph.roots()) { - if (!root.meta) continue + // Sort the graph so potential "roots" appear first + // The entire concept of roots needs to be rethought because it's not always + // clear what the root of a project is. Even when imports are present a file + // may import a file that is the actual "root" of the project. + let roots = Array.from(graph.roots()) + + roots.sort((a, b) => { + return a.meta.root === b.meta.root ? 0 : a.meta.root ? -1 : 1 + }) - // This file is not eligible to act as a root of the CSS graph - if (root.meta.root === false) continue + for (let root of roots) { + if (!root.meta) continue let config: ConfigEntry = configs.remember(root.path, () => ({ source: 'css', diff --git a/packages/vscode-tailwindcss/CHANGELOG.md b/packages/vscode-tailwindcss/CHANGELOG.md index 0dd39795..b5dc30a7 100644 --- a/packages/vscode-tailwindcss/CHANGELOG.md +++ b/packages/vscode-tailwindcss/CHANGELOG.md @@ -2,7 +2,7 @@ ## Prerelease -- Nothing yet! +- Fix detection when project contains stylesheets that import the "main" stylesheet ([#1218](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1218)) ## 0.14.5