Skip to content

Commit ec06099

Browse files
Merge branch 'main' into fix/issue-19250
2 parents 027097d + dc6a3ce commit ec06099

File tree

9 files changed

+78
-41
lines changed

9 files changed

+78
-41
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
- Substitute `@variant` inside legacy JS APIs ([#19263](https://github.com/tailwindlabs/tailwindcss/pull/19263))
1213
- Handle utilities with `1` keys in a JS config ([#19254](https://github.com/tailwindlabs/tailwindcss/pull/19254))
1314

1415
### Added

Cargo.lock

Lines changed: 0 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/oxide/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ globwalk = "0.9.1"
99
log = "0.4.22"
1010
rayon = "1.10.0"
1111
fxhash = { package = "rustc-hash", version = "2.1.1" }
12-
crossbeam = "0.8.4"
1312
tracing = { version = "0.1.40", features = [] }
1413
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
1514
walkdir = "2.5.0"

packages/tailwindcss/src/design-system.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { Theme, ThemeOptions, type ThemeKey } from './theme'
2323
import { Utilities, createUtilities, withAlpha } from './utilities'
2424
import { DefaultMap } from './utils/default-map'
2525
import { extractUsedVariables } from './utils/variables'
26-
import { Variants, createVariants } from './variants'
26+
import { Variants, createVariants, substituteAtVariant } from './variants'
2727

2828
export const enum CompileAstFlags {
2929
None = 0,
@@ -77,15 +77,21 @@ export function buildDesignSystem(theme: Theme): DesignSystem {
7777
return new DefaultMap<Candidate>((candidate) => {
7878
let ast = compileAstNodes(candidate, designSystem, flags)
7979

80-
// Arbitrary values (`text-[theme(--color-red-500)]`) and arbitrary
81-
// properties (`[--my-var:theme(--color-red-500)]`) can contain function
82-
// calls so we need evaluate any functions we find there that weren't in
83-
// the source CSS.
8480
try {
81+
// Arbitrary values (`text-[theme(--color-red-500)]`) and arbitrary
82+
// properties (`[--my-var:theme(--color-red-500)]`) can contain function
83+
// calls so we need evaluate any functions we find there that weren't in
84+
// the source CSS.
8585
substituteFunctions(
8686
ast.map(({ node }) => node),
8787
designSystem,
8888
)
89+
90+
// JS plugins might contain an `@variant` inside a generated utility
91+
substituteAtVariant(
92+
ast.map(({ node }) => node),
93+
designSystem,
94+
)
8995
} catch (err) {
9096
// If substitution fails then the candidate likely contains a call to
9197
// `theme()` that is invalid which may be because of incorrect usage,

packages/tailwindcss/src/index.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4665,6 +4665,60 @@ test('addBase', async () => {
46654665
`)
46664666
})
46674667

4668+
test('JS APIs support @variant', async () => {
4669+
let { build } = await compile(
4670+
css`
4671+
@plugin "my-plugin";
4672+
@layer base, utilities;
4673+
@layer utilities {
4674+
@tailwind utilities;
4675+
}
4676+
`,
4677+
{
4678+
loadModule: async () => ({
4679+
path: '',
4680+
base: '/root',
4681+
module: ({ addBase, addUtilities, matchUtilities }: PluginAPI) => {
4682+
addBase({ body: { '@variant dark': { color: 'red' } } })
4683+
addUtilities({ '.foo': { '@variant dark': { '--foo': 'foo' } } })
4684+
matchUtilities(
4685+
{ bar: (value) => ({ '@variant dark': { '--bar': value } }) },
4686+
{ values: { one: '1' } },
4687+
)
4688+
},
4689+
}),
4690+
},
4691+
)
4692+
4693+
let compiled = build(['underline', 'foo', 'bar-one'])
4694+
4695+
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
4696+
"@layer base {
4697+
@media (prefers-color-scheme: dark) {
4698+
body {
4699+
color: red;
4700+
}
4701+
}
4702+
}
4703+
4704+
@layer utilities {
4705+
.underline {
4706+
text-decoration-line: underline;
4707+
}
4708+
4709+
@media (prefers-color-scheme: dark) {
4710+
.bar-one {
4711+
--bar: 1;
4712+
}
4713+
4714+
.foo {
4715+
--foo: foo;
4716+
}
4717+
}
4718+
}"
4719+
`)
4720+
})
4721+
46684722
it("should error when `layer(…)` is used, but it's not the first param", async () => {
46694723
await expect(async () => {
46704724
return await compileCss(

playgrounds/nextjs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"devDependencies": {
2020
"@types/node": "catalog:",
2121
"@types/react": "^19.2.2",
22-
"@types/react-dom": "^19.2.1",
22+
"@types/react-dom": "^19.2.2",
2323
"eslint": "^9.37.0",
2424
"eslint-config-next": "^15.5.6",
2525
"typescript": "^5.5.4"

playgrounds/v3/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"devDependencies": {
1818
"@types/node": "^20.14.8",
1919
"@types/react": "^19.2.2",
20-
"@types/react-dom": "^19.2.1",
20+
"@types/react-dom": "^19.2.2",
2121
"autoprefixer": "^10.4.21",
2222
"eslint": "^9.37.0",
2323
"eslint-config-next": "^15.5.6",

playgrounds/vite/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
},
1818
"devDependencies": {
1919
"@types/react": "^19.2.2",
20-
"@types/react-dom": "^19.2.1",
20+
"@types/react-dom": "^19.2.2",
2121
"bun": "^1.3.0",
2222
"vite": "catalog:"
2323
}

pnpm-lock.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)