Skip to content

Commit d27a004

Browse files
committed
Suggest more appropriate at-rules based on context
- v4 doesn’t have `@screen` - `@apply` doesn’t make sense to suggest top-level - `@tailwind` doesn’t make sense to suggest in v4 — we want people to use the imports instead - Things like `@config`, `@plugin`, `@source` etc… all must be top-level
1 parent ade6991 commit d27a004

File tree

2 files changed

+52
-37
lines changed

2 files changed

+52
-37
lines changed

packages/tailwindcss-language-server/tests/completions/completions.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ withFixture('v4/basic', (c) => {
485485
})
486486

487487
// Make sure `@slot` is NOT suggested by default
488-
expect(result.items.length).toBe(11)
488+
expect(result.items.length).toBe(7)
489489
expect(result.items).not.toEqual(
490490
expect.arrayContaining([
491491
expect.objectContaining({ kind: 14, label: '@slot', sortText: '-0000000' }),
@@ -499,7 +499,7 @@ withFixture('v4/basic', (c) => {
499499
})
500500

501501
// Make sure `@slot` is suggested
502-
expect(result.items.length).toBe(12)
502+
expect(result.items.length).toBe(4)
503503
expect(result.items).toEqual(
504504
expect.arrayContaining([
505505
expect.objectContaining({ kind: 14, label: '@slot', sortText: '-0000000' }),

packages/tailwindcss-language-service/src/completionProvider.ts

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,10 +1353,16 @@ function provideLayerDirectiveCompletions(
13531353

13541354
if (match === null) return null
13551355

1356+
let layerNames = ['base', 'components', 'utilities']
1357+
1358+
if (state.v4) {
1359+
layerNames = ['theme', 'base', 'components', 'utilities']
1360+
}
1361+
13561362
return withDefaults(
13571363
{
13581364
isIncomplete: false,
1359-
items: ['base', 'components', 'utilities'].map((layer, index, layers) => ({
1365+
items: layerNames.map((layer, index, layers) => ({
13601366
label: layer,
13611367
kind: 21,
13621368
sortText: naturalExpand(index, layers.length),
@@ -1487,40 +1493,49 @@ function provideCssDirectiveCompletions(
14871493

14881494
let items: CompletionItem[] = []
14891495

1490-
items.push({
1491-
label: '@tailwind',
1492-
documentation: {
1493-
kind: 'markdown' as typeof MarkupKind.Markdown,
1494-
value: `Use the \`@tailwind\` directive to insert Tailwind’s \`base\`, \`components\`, \`utilities\` and \`${
1495-
state.jit && semver.gte(state.version, '2.1.99') ? 'variants' : 'screens'
1496-
}\` styles into your CSS.\n\n[Tailwind CSS Documentation](${docsUrl(
1497-
state.version,
1498-
'functions-and-directives/#tailwind',
1499-
)})`,
1500-
},
1501-
})
1496+
if (state.v4) {
1497+
// We don't suggest @tailwind anymore in v4 because we prefer that people
1498+
// use the imports instead
1499+
} else {
1500+
items.push({
1501+
label: '@tailwind',
1502+
documentation: {
1503+
kind: 'markdown' as typeof MarkupKind.Markdown,
1504+
value: `Use the \`@tailwind\` directive to insert Tailwind’s \`base\`, \`components\`, \`utilities\` and \`${
1505+
state.jit && semver.gte(state.version, '2.1.99') ? 'variants' : 'screens'
1506+
}\` styles into your CSS.\n\n[Tailwind CSS Documentation](${docsUrl(
1507+
state.version,
1508+
'functions-and-directives/#tailwind',
1509+
)})`,
1510+
},
1511+
})
1512+
}
15021513

1503-
items.push({
1504-
label: '@screen',
1505-
documentation: {
1506-
kind: 'markdown' as typeof MarkupKind.Markdown,
1507-
value: `The \`@screen\` directive allows you to create media queries that reference your breakpoints by name instead of duplicating their values in your own CSS.\n\n[Tailwind CSS Documentation](${docsUrl(
1508-
state.version,
1509-
'functions-and-directives/#screen',
1510-
)})`,
1511-
},
1512-
})
1514+
if (!state.v4) {
1515+
items.push({
1516+
label: '@screen',
1517+
documentation: {
1518+
kind: 'markdown' as typeof MarkupKind.Markdown,
1519+
value: `The \`@screen\` directive allows you to create media queries that reference your breakpoints by name instead of duplicating their values in your own CSS.\n\n[Tailwind CSS Documentation](${docsUrl(
1520+
state.version,
1521+
'functions-and-directives/#screen',
1522+
)})`,
1523+
},
1524+
})
1525+
}
15131526

1514-
items.push({
1515-
label: '@apply',
1516-
documentation: {
1517-
kind: 'markdown' as typeof MarkupKind.Markdown,
1518-
value: `Use \`@apply\` to inline any existing utility classes into your own custom CSS.\n\n[Tailwind CSS Documentation](${docsUrl(
1519-
state.version,
1520-
'functions-and-directives/#apply',
1521-
)})`,
1522-
},
1523-
})
1527+
if (isNested) {
1528+
items.push({
1529+
label: '@apply',
1530+
documentation: {
1531+
kind: 'markdown' as typeof MarkupKind.Markdown,
1532+
value: `Use \`@apply\` to inline any existing utility classes into your own custom CSS.\n\n[Tailwind CSS Documentation](${docsUrl(
1533+
state.version,
1534+
'functions-and-directives/#apply',
1535+
)})`,
1536+
},
1537+
})
1538+
}
15241539

15251540
if (semver.gte(state.version, '1.8.0')) {
15261541
items.push({
@@ -1560,7 +1575,7 @@ function provideCssDirectiveCompletions(
15601575
})
15611576
}
15621577

1563-
if (semver.gte(state.version, '3.2.0')) {
1578+
if (semver.gte(state.version, '3.2.0') && !isNested) {
15641579
items.push({
15651580
label: '@config',
15661581
documentation: {
@@ -1573,7 +1588,7 @@ function provideCssDirectiveCompletions(
15731588
})
15741589
}
15751590

1576-
if (state.v4) {
1591+
if (state.v4 && !isNested) {
15771592
items.push({
15781593
label: '@theme',
15791594
documentation: {

0 commit comments

Comments
 (0)