mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Consider earlier variants before sorting functions (#10288)
* Consider earlier variants before sorting functions Co-authored-by: Robin Malfait <malfait.robin@gmail.com> * Update changelog Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This commit is contained in:
parent
b05918ab75
commit
6f45428cc1
@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Fix perf regression when checking for changed content ([#10234](https://github.com/tailwindlabs/tailwindcss/pull/10234))
|
||||
- Fix missing `blocklist` member in the `Config` type ([#10239](https://github.com/tailwindlabs/tailwindcss/pull/10239))
|
||||
- Escape group names in selectors ([#10276](https://github.com/tailwindlabs/tailwindcss/pull/10276))
|
||||
- Consider earlier variants before sorting functions ([#10288](https://github.com/tailwindlabs/tailwindcss/pull/10288))
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import { remapBitfield } from './remap-bitfield.js'
|
||||
* @property {function | undefined} sort The sort function
|
||||
* @property {string|null} value The value we want to compare
|
||||
* @property {string|null} modifier The modifier that was used (if any)
|
||||
* @property {bigint} variant The variant bitmask
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -127,6 +128,8 @@ export class Offsets {
|
||||
* @returns {RuleOffset}
|
||||
*/
|
||||
applyVariantOffset(rule, variant, options) {
|
||||
options.variant = variant.variants
|
||||
|
||||
return {
|
||||
...rule,
|
||||
layer: 'variants',
|
||||
@ -211,6 +214,19 @@ export class Offsets {
|
||||
for (let bOptions of b.options) {
|
||||
if (aOptions.id !== bOptions.id) continue
|
||||
if (!aOptions.sort || !bOptions.sort) continue
|
||||
|
||||
let maxFnVariant = max([aOptions.variant, bOptions.variant]) ?? 0n
|
||||
|
||||
// Create a mask of 0s from bits 1..N where N represents the mask of the Nth bit
|
||||
let mask = ~(maxFnVariant | (maxFnVariant - 1n))
|
||||
let aVariantsAfterFn = a.variants & mask
|
||||
let bVariantsAfterFn = b.variants & mask
|
||||
|
||||
// If the variants the same, we _can_ sort them
|
||||
if (aVariantsAfterFn !== bVariantsAfterFn) {
|
||||
continue
|
||||
}
|
||||
|
||||
let result = aOptions.sort(
|
||||
{
|
||||
value: aOptions.value,
|
||||
|
||||
@ -1158,3 +1158,201 @@ it('Invalid arbitrary variants selectors should produce nothing instead of faili
|
||||
expect(result.css).toMatchFormattedCss(css``)
|
||||
})
|
||||
})
|
||||
|
||||
it('should output responsive variants + stacked variants in the right order', () => {
|
||||
let config = {
|
||||
content: [
|
||||
{
|
||||
raw: html`
|
||||
<div class="xl:p-1"></div>
|
||||
<div class="md:[&_ul]:flex-row"></div>
|
||||
<div class="[&_ul]:flex"></div>
|
||||
<div class="[&_ul]:flex-col"></div>
|
||||
`,
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
@media (min-width: 1280px) {
|
||||
.xl\:p-1 {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
}
|
||||
.\[\&_ul\]\:flex ul {
|
||||
display: flex;
|
||||
}
|
||||
.\[\&_ul\]\:flex-col ul {
|
||||
flex-direction: column;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.md\:\[\&_ul\]\:flex-row ul {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should sort multiple variant fns with normal variants between them', () => {
|
||||
/** @type {string[]} */
|
||||
let lines = []
|
||||
|
||||
for (let a of [1, 2]) {
|
||||
for (let b of [2, 1]) {
|
||||
for (let c of [1, 2]) {
|
||||
for (let d of [2, 1]) {
|
||||
for (let e of [1, 2]) {
|
||||
lines.push(`<div class="fred${a}:qux-[${b}]:baz${c}:bar-[${d}]:foo${e}:p-1"></div>`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fisher-Yates shuffle
|
||||
for (let i = lines.length - 1; i > 0; i--) {
|
||||
let j = Math.floor(Math.random() * i)
|
||||
;[lines[i], lines[j]] = [lines[j], lines[i]]
|
||||
}
|
||||
|
||||
let config = {
|
||||
content: [
|
||||
{
|
||||
raw: lines.join('\n'),
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
plugins: [
|
||||
function ({ addVariant, matchVariant }) {
|
||||
addVariant('foo1', '&[data-foo=1]')
|
||||
addVariant('foo2', '&[data-foo=2]')
|
||||
|
||||
matchVariant('bar', (value) => `&[data-bar=${value}]`, {
|
||||
sort: (a, b) => b.value - a.value,
|
||||
})
|
||||
|
||||
addVariant('baz1', '&[data-baz=1]')
|
||||
addVariant('baz2', '&[data-baz=2]')
|
||||
|
||||
matchVariant('qux', (value) => `&[data-qux=${value}]`, {
|
||||
sort: (a, b) => b.value - a.value,
|
||||
})
|
||||
|
||||
addVariant('fred1', '&[data-fred=1]')
|
||||
addVariant('fred2', '&[data-fred=2]')
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
.fred1\:qux-\[2\]\:baz1\:bar-\[2\]\:foo1\:p-1[data-foo='1'][data-bar='2'][data-baz='1'][data-qux='2'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[2\]\:baz1\:bar-\[2\]\:foo2\:p-1[data-foo='2'][data-bar='2'][data-baz='1'][data-qux='2'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[2\]\:baz1\:bar-\[1\]\:foo1\:p-1[data-foo='1'][data-bar='1'][data-baz='1'][data-qux='2'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[2\]\:baz1\:bar-\[1\]\:foo2\:p-1[data-foo='2'][data-bar='1'][data-baz='1'][data-qux='2'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[2\]\:baz2\:bar-\[2\]\:foo1\:p-1[data-foo='1'][data-bar='2'][data-baz='2'][data-qux='2'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[2\]\:baz2\:bar-\[2\]\:foo2\:p-1[data-foo='2'][data-bar='2'][data-baz='2'][data-qux='2'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[2\]\:baz2\:bar-\[1\]\:foo1\:p-1[data-foo='1'][data-bar='1'][data-baz='2'][data-qux='2'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[2\]\:baz2\:bar-\[1\]\:foo2\:p-1[data-foo='2'][data-bar='1'][data-baz='2'][data-qux='2'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[1\]\:baz1\:bar-\[2\]\:foo1\:p-1[data-foo='1'][data-bar='2'][data-baz='1'][data-qux='1'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[1\]\:baz1\:bar-\[2\]\:foo2\:p-1[data-foo='2'][data-bar='2'][data-baz='1'][data-qux='1'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[1\]\:baz1\:bar-\[1\]\:foo1\:p-1[data-foo='1'][data-bar='1'][data-baz='1'][data-qux='1'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[1\]\:baz1\:bar-\[1\]\:foo2\:p-1[data-foo='2'][data-bar='1'][data-baz='1'][data-qux='1'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[1\]\:baz2\:bar-\[2\]\:foo1\:p-1[data-foo='1'][data-bar='2'][data-baz='2'][data-qux='1'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[1\]\:baz2\:bar-\[2\]\:foo2\:p-1[data-foo='2'][data-bar='2'][data-baz='2'][data-qux='1'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[1\]\:baz2\:bar-\[1\]\:foo1\:p-1[data-foo='1'][data-bar='1'][data-baz='2'][data-qux='1'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred1\:qux-\[1\]\:baz2\:bar-\[1\]\:foo2\:p-1[data-foo='2'][data-bar='1'][data-baz='2'][data-qux='1'][data-fred='1'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[2\]\:baz1\:bar-\[2\]\:foo1\:p-1[data-foo='1'][data-bar='2'][data-baz='1'][data-qux='2'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[2\]\:baz1\:bar-\[2\]\:foo2\:p-1[data-foo='2'][data-bar='2'][data-baz='1'][data-qux='2'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[2\]\:baz1\:bar-\[1\]\:foo1\:p-1[data-foo='1'][data-bar='1'][data-baz='1'][data-qux='2'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[2\]\:baz1\:bar-\[1\]\:foo2\:p-1[data-foo='2'][data-bar='1'][data-baz='1'][data-qux='2'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[2\]\:baz2\:bar-\[2\]\:foo1\:p-1[data-foo='1'][data-bar='2'][data-baz='2'][data-qux='2'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[2\]\:baz2\:bar-\[2\]\:foo2\:p-1[data-foo='2'][data-bar='2'][data-baz='2'][data-qux='2'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[2\]\:baz2\:bar-\[1\]\:foo1\:p-1[data-foo='1'][data-bar='1'][data-baz='2'][data-qux='2'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[2\]\:baz2\:bar-\[1\]\:foo2\:p-1[data-foo='2'][data-bar='1'][data-baz='2'][data-qux='2'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[1\]\:baz1\:bar-\[2\]\:foo1\:p-1[data-foo='1'][data-bar='2'][data-baz='1'][data-qux='1'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[1\]\:baz1\:bar-\[2\]\:foo2\:p-1[data-foo='2'][data-bar='2'][data-baz='1'][data-qux='1'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[1\]\:baz1\:bar-\[1\]\:foo1\:p-1[data-foo='1'][data-bar='1'][data-baz='1'][data-qux='1'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[1\]\:baz1\:bar-\[1\]\:foo2\:p-1[data-foo='2'][data-bar='1'][data-baz='1'][data-qux='1'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[1\]\:baz2\:bar-\[2\]\:foo1\:p-1[data-foo='1'][data-bar='2'][data-baz='2'][data-qux='1'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[1\]\:baz2\:bar-\[2\]\:foo2\:p-1[data-foo='2'][data-bar='2'][data-baz='2'][data-qux='1'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[1\]\:baz2\:bar-\[1\]\:foo1\:p-1[data-foo='1'][data-bar='1'][data-baz='2'][data-qux='1'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fred2\:qux-\[1\]\:baz2\:bar-\[1\]\:foo2\:p-1[data-foo='2'][data-bar='1'][data-baz='2'][data-qux='1'][data-fred='2'] {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user