Skip to content

Commit

Permalink
Only detect nesting when using @apply (#13325)
Browse files Browse the repository at this point in the history
* drop nesting detection for `@tailwind`

* drop separate nesting detection entirely

* detect nesting only when using `@apply` with a class that uses nesting

* drop unnecessary `important` config

* add test to verify applying nested user CSS errors

* add error reason to tests

* update `@apply` error message
  • Loading branch information
RobinMalfait authored Mar 23, 2024
1 parent 3ba51d1 commit bda8421
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 178 deletions.
47 changes: 0 additions & 47 deletions src/lib/detectNesting.js

This file was deleted.

17 changes: 17 additions & 0 deletions src/lib/expandApplyAtRules.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,23 @@ function processApply(root, context, localCache) {

let rules = applyClassCache.get(applyCandidate)

// Verify that we can apply the class
for (let [, rule] of rules) {
if (rule.type === 'atrule') {
continue
}

rule.walkRules(() => {
throw apply.error(
[
`The \`${applyCandidate}\` class cannot be used with \`@apply\` because \`@apply\` does not currently support nested CSS.`,
'Rewrite the selector without nesting or configure the `tailwindcss/nesting` plugin:',
'https://tailwindcss.com/docs/using-with-preprocessors#nesting',
].join('\n')
)
})
}

candidates.push([applyCandidate, important, rules])
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/processTailwindFeatures.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@ import resolveDefaultsAtRules from './lib/resolveDefaultsAtRules'
import collapseAdjacentRules from './lib/collapseAdjacentRules'
import collapseDuplicateDeclarations from './lib/collapseDuplicateDeclarations'
import partitionApplyAtRules from './lib/partitionApplyAtRules'
import detectNesting from './lib/detectNesting'
import { createContext } from './lib/setupContextUtils'
import { issueFlagNotices } from './featureFlags'

export default function processTailwindFeatures(setupContext) {
return async function (root, result) {
let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root)

detectNesting()(root, result)

// Partition apply rules that are found in the css
// itself.
partitionApplyAtRules()(root, result)
Expand Down
69 changes: 69 additions & 0 deletions tests/apply.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2143,3 +2143,72 @@ test('should not break replacing important selector when the same as the parent
}
`)
})

test('applying classes with nested CSS should result in an error', async () => {
let config = {
content: [
{
raw: html`<div class="foo"></div>`,
},
],
}

let input = css`
@tailwind components;
@layer components {
.bar .baz {
color: red;
&:hover {
color: red;
}
}
.foo {
@apply flex baz;
}
}
`

expect.assertions(1)

return run(input, config).catch((err) => {
expect(err.reason).toMatchInlineSnapshot(`
"The \`baz\` class cannot be used with \`@apply\` because \`@apply\` does not currently support nested CSS.
Rewrite the selector without nesting or configure the \`tailwindcss/nesting\` plugin:
https://tailwindcss.com/docs/using-with-preprocessors#nesting"
`)
})
})

test('applying user defined classes with nested CSS should result in an error', async () => {
let config = {
content: [
{
raw: html`<div class="example"></div>`,
},
],
}

let input = css`
.foo {
.bar {
color: red;
}
}
.example {
@apply bar;
}
`

expect.assertions(1)

return run(input, config).catch((err) => {
expect(err.reason).toMatchInlineSnapshot(`
"The \`bar\` class cannot be used with \`@apply\` because \`@apply\` does not currently support nested CSS.
Rewrite the selector without nesting or configure the \`tailwindcss/nesting\` plugin:
https://tailwindcss.com/docs/using-with-preprocessors#nesting"
`)
})
})
128 changes: 0 additions & 128 deletions tests/detect-nesting.test.js

This file was deleted.

0 comments on commit bda8421

Please sign in to comment.