Skip to content

Commit 722232c

Browse files
garymathewsthecrypticaceRobinMalfait
authored
Allow all classes for @apply (#6580)
* Always include css with apply in context * Use let We use it more consistently * Remove early return To match the style of the surrounding code * Don't return layer directives They do not need to be returned here. If it's needed in the future its easy enough to add it back. * Use let * Update changelog * fix typo And re-format comments Co-authored-by: Jordan Pittman <[email protected]> Co-authored-by: Robin Malfait <[email protected]>
1 parent 51b3c0a commit 722232c

File tree

5 files changed

+57
-13
lines changed

5 files changed

+57
-13
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
- Nothing yet!
10+
### Fixed
11+
12+
- Fix `@apply` in files without `@tailwind` directives ([#6580](https://github.com/tailwindlabs/tailwindcss/pull/6580))
1113

1214
## [3.0.9] - 2022-01-03
1315

src/lib/normalizeTailwindDirectives.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ import log from '../util/log'
33
export default function normalizeTailwindDirectives(root) {
44
let tailwindDirectives = new Set()
55
let layerDirectives = new Set()
6+
let applyDirectives = new Set()
67

78
root.walkAtRules((atRule) => {
9+
if (atRule.name === 'apply') {
10+
applyDirectives.add(atRule)
11+
}
12+
813
if (atRule.name === 'import') {
914
if (atRule.params === '"tailwindcss/base"' || atRule.params === "'tailwindcss/base'") {
1015
atRule.name = 'tailwind'
@@ -74,5 +79,5 @@ export default function normalizeTailwindDirectives(root) {
7479
}
7580
}
7681

77-
return tailwindDirectives
82+
return { tailwindDirectives, applyDirectives }
7883
}

src/lib/setupTrackingContext.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,19 +112,20 @@ function resolveChangedFiles(candidateFiles, fileModifiedMap) {
112112
// source path), or set up a new one (including setting up watchers and registering
113113
// plugins) then return it
114114
export default function setupTrackingContext(configOrPath) {
115-
return ({ tailwindDirectives, registerDependency }) => {
115+
return ({ tailwindDirectives, registerDependency, applyDirectives }) => {
116116
return (root, result) => {
117117
let [tailwindConfig, userConfigPath, tailwindConfigHash, configDependencies] =
118118
getTailwindConfig(configOrPath)
119119

120120
let contextDependencies = new Set(configDependencies)
121121

122-
// If there are no @tailwind rules, we don't consider this CSS file or it's dependencies
123-
// to be dependencies of the context. Can reuse the context even if they change.
124-
// We may want to think about `@layer` being part of this trigger too, but it's tough
125-
// because it's impossible for a layer in one file to end up in the actual @tailwind rule
126-
// in another file since independent sources are effectively isolated.
127-
if (tailwindDirectives.size > 0) {
122+
// If there are no @tailwind or @apply rules, we don't consider this CSS
123+
// file or its dependencies to be dependencies of the context. Can reuse
124+
// the context even if they change. We may want to think about `@layer`
125+
// being part of this trigger too, but it's tough because it's impossible
126+
// for a layer in one file to end up in the actual @tailwind rule in
127+
// another file since independent sources are effectively isolated.
128+
if (tailwindDirectives.size > 0 || applyDirectives.size > 0) {
128129
// Add current css file as a context dependencies.
129130
contextDependencies.add(result.opts.from)
130131

@@ -147,12 +148,12 @@ export default function setupTrackingContext(configOrPath) {
147148

148149
let candidateFiles = getCandidateFiles(context, tailwindConfig)
149150

150-
// If there are no @tailwind rules, we don't consider this CSS file or it's dependencies
151-
// to be dependencies of the context. Can reuse the context even if they change.
151+
// If there are no @tailwind or @apply rules, we don't consider this CSS file or it's
152+
// dependencies to be dependencies of the context. Can reuse the context even if they change.
152153
// We may want to think about `@layer` being part of this trigger too, but it's tough
153154
// because it's impossible for a layer in one file to end up in the actual @tailwind rule
154155
// in another file since independent sources are effectively isolated.
155-
if (tailwindDirectives.size > 0) {
156+
if (tailwindDirectives.size > 0 || applyDirectives.size > 0) {
156157
let fileModifiedMap = getFileModifiedMap(context)
157158

158159
// Add template paths as postcss dependencies.

src/processTailwindFeatures.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ import { issueFlagNotices } from './featureFlags'
1212

1313
export default function processTailwindFeatures(setupContext) {
1414
return function (root, result) {
15-
let tailwindDirectives = normalizeTailwindDirectives(root)
15+
let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root)
1616

1717
let context = setupContext({
1818
tailwindDirectives,
19+
applyDirectives,
1920
registerDependency(dependency) {
2021
result.messages.push({
2122
plugin: 'tailwindcss',

tests/apply.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,3 +775,38 @@ it('should not apply unrelated siblings when applying something from within atru
775775
`)
776776
})
777777
})
778+
779+
it('should be possible to apply user css without tailwind directives', () => {
780+
let config = {
781+
content: [{ raw: html`<div class="foo"></div>` }],
782+
plugins: [],
783+
}
784+
785+
let input = css`
786+
.bop {
787+
color: red;
788+
}
789+
.bar {
790+
background-color: blue;
791+
}
792+
.foo {
793+
@apply absolute bar bop;
794+
}
795+
`
796+
797+
return run(input, config).then((result) => {
798+
return expect(result.css).toMatchFormattedCss(css`
799+
.bop {
800+
color: red;
801+
}
802+
.bar {
803+
background-color: blue;
804+
}
805+
.foo {
806+
position: absolute;
807+
color: red;
808+
background-color: blue;
809+
}
810+
`)
811+
})
812+
})

0 commit comments

Comments
 (0)