Skip to content

Commit 5d22c17

Browse files
committed
Ensure class sorting is deterministic for Prettier
1 parent 261a8b4 commit 5d22c17

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

src/lib/setupContextUtils.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -931,12 +931,19 @@ function registerPlugins(plugins, context) {
931931
prefix(context, 'peer'),
932932
]
933933
context.getClassOrder = function getClassOrder(classes) {
934+
// Sort classes so they're ordered in a deterministic manner
935+
let sorted = [...classes].sort((a, z) => {
936+
if (a === z) return 0
937+
if (a < z) return -1
938+
return 1
939+
})
940+
934941
// Non-util classes won't be generated, so we default them to null
935-
let sortedClassNames = new Map(classes.map((className) => [className, null]))
942+
let sortedClassNames = new Map(sorted.map((className) => [className, null]))
936943

937944
// Sort all classes in order
938945
// Non-tailwind classes won't be generated and will be left as `null`
939-
let rules = generateRules(new Set(classes), context)
946+
let rules = generateRules(new Set(sorted), context)
940947
rules = context.offsets.sort(rules)
941948

942949
let idx = BigInt(parasiteUtilities.length)

tests/getSortOrder.test.js

+29-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ crosscheck(() => {
5151
['px-3 focus:hover:p-3 hover:p-1 py-3', 'px-3 py-3 hover:p-1 focus:hover:p-3'],
5252

5353
// Utitlies with important
54-
['px-3 !py-4', 'px-3 !py-4'],
54+
['px-3 !py-4', '!py-4 px-3'],
5555
['!py-4 px-3', '!py-4 px-3'],
5656

5757
// Components with variants
@@ -89,7 +89,7 @@ crosscheck(() => {
8989
],
9090

9191
// Utitlies with important
92-
['tw-px-3 !tw-py-4', 'tw-px-3 !tw-py-4'],
92+
['tw-px-3 !tw-py-4', '!tw-py-4 tw-px-3'],
9393
['!tw-py-4 tw-px-3', '!tw-py-4 tw-px-3'],
9494

9595
// Components with variants
@@ -115,4 +115,31 @@ crosscheck(() => {
115115
expect(defaultSort(context.getClassOrder(input.split(' ')))).toEqual(output)
116116
}
117117
)
118+
119+
it('sort classes deterministically across multiple class lists', () => {
120+
let classes = [
121+
[
122+
'a-class px-3 p-1 b-class py-3 bg-red-500 bg-blue-500',
123+
'a-class b-class bg-blue-500 bg-red-500 p-1 px-3 py-3',
124+
],
125+
[
126+
'px-3 b-class p-1 py-3 bg-blue-500 a-class bg-red-500',
127+
'b-class a-class bg-blue-500 bg-red-500 p-1 px-3 py-3',
128+
],
129+
]
130+
131+
let config = {}
132+
133+
// Same context, different class lists
134+
let context = createContext(resolveConfig(config))
135+
for (const [input, output] of classes) {
136+
expect(defaultSort(context.getClassOrder(input.split(' ')))).toEqual(output)
137+
}
138+
139+
// Different context, different class lists
140+
for (const [input, output] of classes) {
141+
context = createContext(resolveConfig(config))
142+
expect(defaultSort(context.getClassOrder(input.split(' ')))).toEqual(output)
143+
}
144+
})
118145
})

0 commit comments

Comments
 (0)