Merge branch 'main' into fix/issue-19250

This commit is contained in:
Jordan Pittman 2025-11-04 11:30:48 -05:00 • committed by GitHub
commit ec06099222
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 78 additions and 41 deletions

View file

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Substitute `@variant` inside legacy JS APIs ([#19263](https://github.com/tailwindlabs/tailwindcss/pull/19263))
- Handle utilities with `1` keys in a JS config ([#19254](https://github.com/tailwindlabs/tailwindcss/pull/19254))
### Added

23
Cargo.lock generated
View file

@ -68,19 +68,6 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "crossbeam"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-epoch",
"crossbeam-queue",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.15"
@ -109,15 +96,6 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
@ -595,7 +573,6 @@ dependencies = [
"bexpand",
"bstr",
"classification-macros",
"crossbeam",
"dunce",
"fast-glob",
"globwalk",

View file

@ -9,7 +9,6 @@ globwalk = "0.9.1"
log = "0.4.22"
rayon = "1.10.0"
fxhash = { package = "rustc-hash", version = "2.1.1" }
crossbeam = "0.8.4"
tracing = { version = "0.1.40", features = [] }
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
walkdir = "2.5.0"

View file

@ -23,7 +23,7 @@ import { Theme, ThemeOptions, type ThemeKey } from './theme'
import { Utilities, createUtilities, withAlpha } from './utilities'
import { DefaultMap } from './utils/default-map'
import { extractUsedVariables } from './utils/variables'
import { Variants, createVariants } from './variants'
import { Variants, createVariants, substituteAtVariant } from './variants'
export const enum CompileAstFlags {
None = 0,
@ -77,15 +77,21 @@ export function buildDesignSystem(theme: Theme): DesignSystem {
return new DefaultMap<Candidate>((candidate) => {
let ast = compileAstNodes(candidate, designSystem, flags)
// Arbitrary values (`text-[theme(--color-red-500)]`) and arbitrary
// properties (`[--my-var:theme(--color-red-500)]`) can contain function
// calls so we need evaluate any functions we find there that weren't in
// the source CSS.
try {
// Arbitrary values (`text-[theme(--color-red-500)]`) and arbitrary
// properties (`[--my-var:theme(--color-red-500)]`) can contain function
// calls so we need evaluate any functions we find there that weren't in
// the source CSS.
substituteFunctions(
ast.map(({ node }) => node),
designSystem,
)
// JS plugins might contain an `@variant` inside a generated utility
substituteAtVariant(
ast.map(({ node }) => node),
designSystem,
)
} catch (err) {
// If substitution fails then the candidate likely contains a call to
// `theme()` that is invalid which may be because of incorrect usage,

View file

@ -4665,6 +4665,60 @@ test('addBase', async () => {
`)
})
test('JS APIs support @variant', async () => {
let { build } = await compile(
css`
@plugin "my-plugin";
@layer base, utilities;
@layer utilities {
@tailwind utilities;
}
`,
{
loadModule: async () => ({
path: '',
base: '/root',
module: ({ addBase, addUtilities, matchUtilities }: PluginAPI) => {
addBase({ body: { '@variant dark': { color: 'red' } } })
addUtilities({ '.foo': { '@variant dark': { '--foo': 'foo' } } })
matchUtilities(
{ bar: (value) => ({ '@variant dark': { '--bar': value } }) },
{ values: { one: '1' } },
)
},
}),
},
)
let compiled = build(['underline', 'foo', 'bar-one'])
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
"@layer base {
@media (prefers-color-scheme: dark) {
body {
color: red;
}
}
}
@layer utilities {
.underline {
text-decoration-line: underline;
}
@media (prefers-color-scheme: dark) {
.bar-one {
--bar: 1;
}
.foo {
--foo: foo;
}
}
}"
`)
})
it("should error when `layer(…)` is used, but it's not the first param", async () => {
await expect(async () => {
return await compileCss(

View file

@ -19,7 +19,7 @@
"devDependencies": {
"@types/node": "catalog:",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.1",
"@types/react-dom": "^19.2.2",
"eslint": "^9.37.0",
"eslint-config-next": "^15.5.6",
"typescript": "^5.5.4"

View file

@ -17,7 +17,7 @@
"devDependencies": {
"@types/node": "^20.14.8",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.1",
"@types/react-dom": "^19.2.2",
"autoprefixer": "^10.4.21",
"eslint": "^9.37.0",
"eslint-config-next": "^15.5.6",

View file

@ -17,7 +17,7 @@
},
"devDependencies": {
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.1",
"@types/react-dom": "^19.2.2",
"bun": "^1.3.0",
"vite": "catalog:"
}

18
pnpm-lock.yaml generated
View file

@ -499,8 +499,8 @@ importers:
specifier: ^19.2.2
version: 19.2.2
'@types/react-dom':
specifier: ^19.2.1
version: 19.2.1(@types/react@19.2.2)
specifier: ^19.2.2
version: 19.2.2(@types/react@19.2.2)
eslint:
specifier: ^9.37.0
version: 9.37.0(jiti@2.6.1)
@ -533,8 +533,8 @@ importers:
specifier: ^19.2.2
version: 19.2.2
'@types/react-dom':
specifier: ^19.2.1
version: 19.2.1(@types/react@19.2.2)
specifier: ^19.2.2
version: 19.2.2(@types/react@19.2.2)
autoprefixer:
specifier: ^10.4.21
version: 10.4.21(postcss@8.4.47)
@ -570,8 +570,8 @@ importers:
specifier: ^19.2.2
version: 19.2.2
'@types/react-dom':
specifier: ^19.2.1
version: 19.2.1(@types/react@19.2.2)
specifier: ^19.2.2
version: 19.2.2(@types/react@19.2.2)
bun:
specifier: ^1.3.0
version: 1.3.0
@ -2433,8 +2433,8 @@ packages:
'@types/postcss-import@14.0.3':
resolution: {integrity: sha512-raZhRVTf6Vw5+QbmQ7LOHSDML71A5rj4+EqDzAbrZPfxfoGzFxMHRCq16VlddGIZpHELw0BG4G0YE2ANkdZiIQ==}
'@types/react-dom@19.2.1':
resolution: {integrity: sha512-/EEvYBdT3BflCWvTMO7YkYBHVE9Ci6XdqZciZANQgKpaiDRGOLIlRo91jbTNRQjgPFWVaRxcYc0luVNFitz57A==}
'@types/react-dom@19.2.2':
resolution: {integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==}
peerDependencies:
'@types/react': ^19.2.0
@ -6048,7 +6048,7 @@ snapshots:
dependencies:
postcss: 8.4.41
'@types/react-dom@19.2.1(@types/react@19.2.2)':
'@types/react-dom@19.2.2(@types/react@19.2.2)':
dependencies:
'@types/react': 19.2.2