Sort class lists deterministically for Prettier plugin (#10672)

* Ensure class sorting is deterministic for Prettier

* Update changelog
This commit is contained in:
Jordan Pittman authored and GitHub committed 2023-02-23 13:32:24 -05:00
1 parent 261a8b42cb
commit d2a95a00a8
3 files changed
+39 -4

No files matched your search

+1
View File
@@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Disallow multiple selectors in arbitrary variants ([#10655](https://github.com/tailwindlabs/tailwindcss/pull/10655))
- Sort class lists deterministically for Prettier plugin ([#10672](https://github.com/tailwindlabs/tailwindcss/pull/10672))
### Changed
+9 -2
View File
@@ -931,12 +931,19 @@ function registerPlugins(plugins, context) {
prefix(context, 'peer'),
]
context.getClassOrder = function getClassOrder(classes) {
// Sort classes so they're ordered in a deterministic manner
let sorted = [...classes].sort((a, z) => {
if (a === z) return 0
if (a < z) return -1
return 1
})
// Non-util classes won't be generated, so we default them to null
let sortedClassNames = new Map(classes.map((className) => [className, null]))
let sortedClassNames = new Map(sorted.map((className) => [className, null]))
// Sort all classes in order
// Non-tailwind classes won't be generated and will be left as `null`
let rules = generateRules(new Set(classes), context)
let rules = generateRules(new Set(sorted), context)
rules = context.offsets.sort(rules)
let idx = BigInt(parasiteUtilities.length)
+29 -2
View File
@@ -51,7 +51,7 @@ crosscheck(() => {
['px-3 focus:hover:p-3 hover:p-1 py-3', 'px-3 py-3 hover:p-1 focus:hover:p-3'],
// Utitlies with important
['px-3 !py-4', 'px-3 !py-4'],
['px-3 !py-4', '!py-4 px-3'],
['!py-4 px-3', '!py-4 px-3'],
// Components with variants
@@ -89,7 +89,7 @@ crosscheck(() => {
],
// Utitlies with important
['tw-px-3 !tw-py-4', 'tw-px-3 !tw-py-4'],
['tw-px-3 !tw-py-4', '!tw-py-4 tw-px-3'],
['!tw-py-4 tw-px-3', '!tw-py-4 tw-px-3'],
// Components with variants
@@ -115,4 +115,31 @@ crosscheck(() => {
expect(defaultSort(context.getClassOrder(input.split(' ')))).toEqual(output)
}
)
it('sorts classes deterministically across multiple class lists', () => {
let classes = [
[
'a-class px-3 p-1 b-class py-3 bg-red-500 bg-blue-500',
'a-class b-class bg-blue-500 bg-red-500 p-1 px-3 py-3',
],
[
'px-3 b-class p-1 py-3 bg-blue-500 a-class bg-red-500',
'b-class a-class bg-blue-500 bg-red-500 p-1 px-3 py-3',
],
]
let config = {}
// Same context, different class lists
let context = createContext(resolveConfig(config))
for (const [input, output] of classes) {
expect(defaultSort(context.getClassOrder(input.split(' ')))).toEqual(output)
}
// Different context, different class lists
for (const [input, output] of classes) {
context = createContext(resolveConfig(config))
expect(defaultSort(context.getClassOrder(input.split(' ')))).toEqual(output)
}
})
})