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:
Jordan Pittman 2023-01-10 09:57:11 -05:00 committed by GitHub
parent b05918ab75
commit 6f45428cc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 215 additions and 0 deletions

View File

@ -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

View File

@ -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,

View File

@ -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;
}
`)
})
})