diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b50934dd8c7..6156ddff6100 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Nothing yet! +## [3.4.6] - 2024-07-16 + +### Fixed + +- Fix detection of some utilities in Slim/Pug templates ([#14006](https://github.com/tailwindlabs/tailwindcss/pull/14006)) + +### Changed + +- Loosen `:is()` wrapping rules when using an important selector ([#13900](https://github.com/tailwindlabs/tailwindcss/pull/13900)) + ## [3.4.5] - 2024-07-15 ### Fixed @@ -2395,7 +2405,8 @@ No release notes - Everything! -[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.5...HEAD +[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.6...HEAD +[3.4.6]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.5...v3.4.6 [3.4.5]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.4...v3.4.5 [3.4.4]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.3...v3.4.4 [3.4.3]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.2...v3.4.3 diff --git a/package-lock.json b/package-lock.json index d649fab92f7f..a04a12bca3c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "tailwindcss", - "version": "3.4.5", + "version": "3.4.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "tailwindcss", - "version": "3.4.5", + "version": "3.4.6", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", diff --git a/package.json b/package.json index 3c5d64a89a73..484886923f44 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tailwindcss", - "version": "3.4.5", + "version": "3.4.6", "description": "A utility-first CSS framework for rapidly building custom user interfaces.", "license": "MIT", "main": "lib/index.js", diff --git a/src/lib/defaultExtractor.js b/src/lib/defaultExtractor.js index fdcd8dd5d214..8f89596313ce 100644 --- a/src/lib/defaultExtractor.js +++ b/src/lib/defaultExtractor.js @@ -32,7 +32,7 @@ export function defaultExtractor(context) { // If the next segment is a number, discard both, for example seeing // `px-1` and `5` means the real candidate was `px-1.5` which is already // captured. - let next = parseInt(segments[idx + 1]) + let next = Number(segments[idx + 1]) if (isNaN(next)) { results.push(segment) } else { diff --git a/src/util/applyImportantSelector.js b/src/util/applyImportantSelector.js index ff9ec4f4b343..07302f94d5f6 100644 --- a/src/util/applyImportantSelector.js +++ b/src/util/applyImportantSelector.js @@ -5,13 +5,12 @@ export function applyImportantSelector(selector, important) { let sel = parser().astSync(selector) sel.each((sel) => { - // Wrap with :is if it's not already wrapped - let isWrapped = - sel.nodes[0].type === 'pseudo' && - sel.nodes[0].value === ':is' && - sel.nodes.every((node) => node.type !== 'combinator') + // For nesting, we only need to wrap a selector with :is() if it has a top-level combinator, + // e.g. `.dark .text-white`, to be independent of DOM order. Any other selector, including + // combinators inside of pseudos like `:where()`, are ok to nest. + let shouldWrap = sel.nodes.some((node) => node.type === 'combinator') - if (!isWrapped) { + if (shouldWrap) { sel.nodes = [ parser.pseudo({ value: ':is', diff --git a/standalone-cli/package-lock.json b/standalone-cli/package-lock.json index f080054b6088..e894c1fdd356 100644 --- a/standalone-cli/package-lock.json +++ b/standalone-cli/package-lock.json @@ -25,7 +25,7 @@ }, "..": { "name": "tailwindcss", - "version": "3.4.5", + "version": "3.4.6", "dev": true, "license": "MIT", "dependencies": { diff --git a/tests/default-extractor.test.js b/tests/default-extractor.test.js index d99069197d60..0cac75d0c299 100644 --- a/tests/default-extractor.test.js +++ b/tests/default-extractor.test.js @@ -476,6 +476,16 @@ test('classes in slim templates', async () => { expect(extractions).toContain('text-gray-500') }) +test('classes in slim templates starting with number', async () => { + const extractions = defaultExtractor(` + .bg-green-300.2xl:bg-red-300 + '(Look mom, no closing tag!) + `) + + expect(extractions).toContain('bg-green-300') + expect(extractions).toContain('2xl:bg-red-300') +}) + test("classes with fractional numeric values don't also generate the whole number utility", async () => { const extractions = defaultExtractor(`