Skip to content

Commit

Permalink
Avoid over-extracting utilities from candidates with decimal values (#…
Browse files Browse the repository at this point in the history
…13959)

* Avoid over-extracting utilities from candidates with decimal values

Prevent candidates like `px-1.5` from generating both the `px-1.5` class and the `px-1` class.

* Update CHANGELOG.md

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
  • Loading branch information
adamwathan and adamwathan authored Jul 5, 2024
1 parent 588a822 commit 074736c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Disable automatic `var()` injection for anchor properties ([#13826](https://github.com/tailwindlabs/tailwindcss/pull/13826))
- Use no value instead of `blur(0px)` for `backdrop-blur-none` and `blur-none` utilities ([#13830](https://github.com/tailwindlabs/tailwindcss/pull/13830))
- Add `.mts` and `.cts` config file detection ([#13940](https://github.com/tailwindlabs/tailwindcss/pull/13940))
- Don't generate utilities like `px-1` unnecessarily when using utilities like `px-1.5` ([#13959](https://github.com/tailwindlabs/tailwindcss/pull/13959))

## [3.4.4] - 2024-06-05

Expand Down
28 changes: 25 additions & 3 deletions src/lib/defaultExtractor.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as regex from './regex'
import { splitAtTopLevelOnly } from '../util/splitAtTopLevelOnly'

export function defaultExtractor(context) {
let patterns = Array.from(buildRegExps(context))
Expand All @@ -16,6 +17,30 @@ export function defaultExtractor(context) {
}
}

// Extract any subclasses from languages like Slim and Pug, eg:
// div.flex.px-5.underline
for (let result of results.slice()) {
let segments = splitAtTopLevelOnly(result, '.')

for (let idx = 0; idx < segments.length; idx++) {
let segment = segments[idx]
if (idx >= segments.length - 1) {
results.push(segment)
continue
}

// 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])
if (isNaN(next)) {
results.push(segment)
} else {
idx++
}
}
}

return results
}
}
Expand Down Expand Up @@ -127,9 +152,6 @@ function* buildRegExps(context) {
utility,
])
}

// 5. Inner matches
yield /[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g
}

// We want to capture any "special" characters
Expand Down
13 changes: 13 additions & 0 deletions tests/default-extractor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,19 @@ test('classes in slim templates', async () => {
expect(extractions).toContain('text-gray-500')
})

test("classes with fractional numeric values don't also generate the whole number utility", async () => {
const extractions = defaultExtractor(`
<div class="px-1.5 py-2.75">Hello world!</div>
`)

expect(extractions).toContain('px-1.5')
expect(extractions).toContain('py-2.75')
expect(extractions).not.toContain('px-1')
expect(extractions).not.toContain('5')
expect(extractions).not.toContain('py-2')
expect(extractions).not.toContain('75')
})

test('multi-word + arbitrary values + quotes', async () => {
const extractions = defaultExtractor(`
grid-cols-['repeat(2)']
Expand Down

0 comments on commit 074736c

Please sign in to comment.