Skip to content

Clarify how the configFile option works with v4 #1167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions packages/tailwindcss-language-server/src/project-locator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,23 @@ export class ProjectLocator {
configPath: string,
selectors: string[],
): Promise<ProjectConfig | null> {
let config: ConfigEntry = {
type: 'js',
path: configPath,
source: 'js',
entries: [],
content: [],
packageRoot: '',
}
let config: ConfigEntry = configPath.endsWith('.css')
? {
type: 'css',
path: configPath,
source: 'css',
entries: [],
content: [],
packageRoot: '',
}
: {
type: 'js',
path: configPath,
source: 'js',
entries: [],
content: [],
packageRoot: '',
}

let tailwind = await this.detectTailwindVersion(config)

Expand Down
4 changes: 3 additions & 1 deletion packages/tailwindcss-language-server/tests/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,16 @@ export async function init(
text,
lang = 'html',
dir = '',
name = null,
settings = {},
}: {
text: string
lang?: string
dir?: string
name?: string
settings?: Settings
}) {
let uri = resolveUri(dir, `file-${counter++}`)
let uri = resolveUri(dir, name ?? `file-${counter++}`)
docSettings.set(uri, settings)

let openPromise = openingDocuments.remember(uri, () => {
Expand Down
185 changes: 185 additions & 0 deletions packages/tailwindcss-language-server/tests/env/v4.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,188 @@ defineTest({
})
},
})

defineTest({
name: 'v4, using local, with explicit CSS entrypoints',
fs: {
'package.json': json`
{
"dependencies": {
"tailwindcss": "4.0.1"
}
}
`,
'a/app.css': css`
@import 'tailwindcss';
@theme {
--color-primary: #000000;
}
`,
'b/app.css': css`
@import 'tailwindcss';
@theme {
--color-primary: #ffffff;
}
`,
},
prepare: async ({ root }) => ({ c: await init(root) }),
handle: async ({ c }) => {
await c.updateSettings({
tailwindCSS: {
experimental: {
configFile: {
'a/app.css': 'c/a/**',
'b/app.css': 'c/b/**',
},
},
},
})

let documentA = await c.openDocument({
lang: 'html',
text: '<div class="bg-primary">',
name: 'c/a/index.html',
})

let documentB = await c.openDocument({
lang: 'html',
text: '<div class="bg-primary">',
name: 'c/b/index.html',
})

let hoverA = await c.sendRequest(HoverRequest.type, {
textDocument: documentA,

// <div class="bg-primary">
// ^
position: { line: 0, character: 13 },
})

let hoverB = await c.sendRequest(HoverRequest.type, {
textDocument: documentB,

// <div class="bg-primary">
// ^
position: { line: 0, character: 13 },
})

expect(hoverA).toEqual({
contents: {
language: 'css',
value: dedent`
.bg-primary {
background-color: var(--color-primary) /* #000000 */;
}
`,
},
range: {
start: { line: 0, character: 12 },
end: { line: 0, character: 22 },
},
})

expect(hoverB).toEqual({
contents: {
language: 'css',
value: dedent`
.bg-primary {
background-color: var(--color-primary) /* #ffffff */;
}
`,
},
range: {
start: { line: 0, character: 12 },
end: { line: 0, character: 22 },
},
})
},
})

defineTest({
name: 'v4, using fallback, with explicit CSS entrypoints',
fs: {
'a/app.css': css`
@import 'tailwindcss';
@theme {
--color-primary: #000000;
}
`,
'b/app.css': css`
@import 'tailwindcss';
@theme {
--color-primary: #ffffff;
}
`,
},
prepare: async ({ root }) => ({ c: await init(root) }),
handle: async ({ c }) => {
await c.updateSettings({
tailwindCSS: {
experimental: {
configFile: {
'a/app.css': 'c/a/**',
'b/app.css': 'c/b/**',
},
},
},
})

let documentA = await c.openDocument({
lang: 'html',
text: '<div class="bg-primary">',
name: 'c/a/index.html',
})

let documentB = await c.openDocument({
lang: 'html',
text: '<div class="bg-primary">',
name: 'c/b/index.html',
})

let hoverA = await c.sendRequest(HoverRequest.type, {
textDocument: documentA,

// <div class="bg-primary">
// ^
position: { line: 0, character: 13 },
})

let hoverB = await c.sendRequest(HoverRequest.type, {
textDocument: documentB,

// <div class="bg-primary">
// ^
position: { line: 0, character: 13 },
})

expect(hoverA).toEqual({
contents: {
language: 'css',
value: dedent`
.bg-primary {
background-color: var(--color-primary) /* #000000 */;
}
`,
},
range: {
start: { line: 0, character: 12 },
end: { line: 0, character: 22 },
},
})

expect(hoverB).toEqual({
contents: {
language: 'css',
value: dedent`
.bg-primary {
background-color: var(--color-primary) /* #ffffff */;
}
`,
},
range: {
start: { line: 0, character: 12 },
end: { line: 0, character: 22 },
},
})
},
})
1 change: 1 addition & 0 deletions packages/vscode-tailwindcss/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Support style-rule like completions inside `@variant` ([#1165](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1165))
- Make sure `@slot` isn't considered an unknown at-rule ([#1165](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1165))
- Fix equivalent calculation when using prefixes in v4 ([#1166](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1166))
- Fix use of `tailwindCSS.experimental.configFile` option when using the bundled version of v4 ([#1167](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1167))

## 0.14.2

Expand Down
34 changes: 31 additions & 3 deletions packages/vscode-tailwindcss/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,43 @@ Enable the Node.js inspector agent for the language server and listen on the spe

**Default: `null`**

By default the extension will automatically use the first `tailwind.config.{js,cjs,mjs,ts,cts,mts}` file that it can find to provide Tailwind CSS IntelliSense. Use this setting to manually specify the config file(s) yourself instead.
This setting allows you to manually specify the CSS entrypoints (for v4 projects) or the Tailwind configuration file (for v3 projects). By default, the extension attempts to detect your project setup automatically:

If your project contains a single Tailwind config file you can specify a string value:
- **For Tailwind CSS v4**: The extension scans your project for CSS files and determines the "root" CSS file.
- **For Tailwind CSS v3 (and earlier)**: The extension automatically uses the first `tailwind.config.{js,cjs,mjs,ts,cts,mts}` file it finds.

If IntelliSense is unable to detect your project, you can use this setting to define your config files manually.

#### Tailwind CSS v4.x (CSS entrypoints)

For v4 projects, specify the CSS file(s) that serve as your Tailwind entrypoints.

If your project contains a single CSS entrypoint, set this option to a string:

```json
"tailwindCSS.experimental.configFile": "src/styles/app.css"
```

For projects with multiple CSS entrypoints, use an object where each key is a file path and each value is a glob pattern (or array of patterns) representing the files it applies to:

```json
"tailwindCSS.experimental.configFile": {
"packages/a/src/app.css": "packages/a/src/**",
"packages/b/src/app.css": "packages/b/src/**"
}
```

#### Tailwind CSS v3.x and earlier (config files)

For v3 projects and below, specify the Tailwind configuration file(s) instead.

If your project contains a single Tailwind config, set this option to a string:

```json
"tailwindCSS.experimental.configFile": ".config/tailwind.config.js"
```

For projects with multiple config files use an object where each key is a config file path and each value is a glob pattern (or array of glob patterns) representing the set of files that the config file applies to:
For projects with multiple config files, use an object where each key is a config file path and each value is a glob pattern (or array of patterns) representing the files it applies to:

```json
"tailwindCSS.experimental.configFile": {
Expand Down