mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Implement getClassOrder instead of sortClassList (#7459)
* implement `getSortOrder` instead of `sortClassList` * rename `getSortOrder` to `getClassOrder` * update changelog
This commit is contained in:
parent
be5d5c9e66
commit
63537aaa89
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Remove opacity variables from `:visited` pseudo class ([#7458](https://github.com/tailwindlabs/tailwindcss/pull/7458))
|
||||
- Support arbitrary values + calc + theme with quotes ([#7462](https://github.com/tailwindlabs/tailwindcss/pull/7462))
|
||||
- Don't duplicate layer output when scanning content with variants + wildcards ([#7478](https://github.com/tailwindlabs/tailwindcss/pull/7478))
|
||||
- Implement `getClassOrder` instead of `sortClassList` ([#7459](https://github.com/tailwindlabs/tailwindcss/pull/7459))
|
||||
|
||||
## [3.0.22] - 2022-02-11
|
||||
|
||||
|
||||
@ -744,33 +744,25 @@ function registerPlugins(plugins, context) {
|
||||
// sorting could be weird since you still require them in order to make the
|
||||
// host utitlies work properly. (Thanks Biology)
|
||||
let parasiteUtilities = new Set([prefix(context, 'group'), prefix(context, 'peer')])
|
||||
context.sortClassList = function sortClassList(classes) {
|
||||
context.getClassOrder = function getClassOrder(classes) {
|
||||
let sortedClassNames = new Map()
|
||||
for (let [sort, rule] of generateRules(new Set(classes), context)) {
|
||||
if (sortedClassNames.has(rule.raws.tailwind.candidate)) continue
|
||||
sortedClassNames.set(rule.raws.tailwind.candidate, sort)
|
||||
}
|
||||
|
||||
return classes
|
||||
.map((className) => {
|
||||
let order = sortedClassNames.get(className) ?? null
|
||||
return classes.map((className) => {
|
||||
let order = sortedClassNames.get(className) ?? null
|
||||
|
||||
if (order === null && parasiteUtilities.has(className)) {
|
||||
// This will make sure that it is at the very beginning of the
|
||||
// `components` layer which technically means 'before any
|
||||
// components'.
|
||||
order = context.layerOrder.components
|
||||
}
|
||||
if (order === null && parasiteUtilities.has(className)) {
|
||||
// This will make sure that it is at the very beginning of the
|
||||
// `components` layer which technically means 'before any
|
||||
// components'.
|
||||
order = context.layerOrder.components
|
||||
}
|
||||
|
||||
return [className, order]
|
||||
})
|
||||
.sort(([, a], [, z]) => {
|
||||
if (a === z) return 0
|
||||
if (a === null) return -1
|
||||
if (z === null) return 1
|
||||
return bigSign(a - z)
|
||||
})
|
||||
.map(([className]) => className)
|
||||
return [className, order]
|
||||
})
|
||||
}
|
||||
|
||||
// Generate a list of strings for autocompletion purposes, e.g.
|
||||
|
||||
@ -1,5 +1,42 @@
|
||||
import resolveConfig from '../src/public/resolve-config'
|
||||
import { createContext } from '../src/lib/setupContextUtils'
|
||||
import bigSign from '../src/util/bigSign'
|
||||
|
||||
/**
|
||||
* This is a function that the prettier-plugin-tailwindcss would use. It would
|
||||
* do the actual sorting based on the classes and order we return from `getClassOrder`.
|
||||
*
|
||||
* This way the actual sorting logic is done in the plugin which allows you to
|
||||
* put unknown classes at the end for example.
|
||||
*
|
||||
* @param {Array<[string, bigint]>} arrayOfTuples
|
||||
* @returns {string}
|
||||
*/
|
||||
function defaultSort(arrayOfTuples) {
|
||||
return arrayOfTuples
|
||||
.sort(([, a], [, z]) => {
|
||||
if (a === z) return 0
|
||||
if (a === null) return -1
|
||||
if (z === null) return 1
|
||||
return bigSign(a - z)
|
||||
})
|
||||
.map(([className]) => className)
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
it('should return a list of tuples with the sort order', () => {
|
||||
let input = 'font-bold underline hover:font-medium unknown'
|
||||
let config = {}
|
||||
let context = createContext(resolveConfig(config))
|
||||
expect(context.getClassOrder(input.split(' '))).toEqual([
|
||||
['font-bold', expect.any(BigInt)],
|
||||
['underline', expect.any(BigInt)],
|
||||
['hover:font-medium', expect.any(BigInt)],
|
||||
|
||||
// Unknown values receive `null`
|
||||
['unknown', null],
|
||||
])
|
||||
})
|
||||
|
||||
it.each([
|
||||
// Utitlies
|
||||
@ -33,7 +70,7 @@ it.each([
|
||||
])('should sort "%s" based on the order we generate them in to "%s"', (input, output) => {
|
||||
let config = {}
|
||||
let context = createContext(resolveConfig(config))
|
||||
expect(context.sortClassList(input.split(' ')).join(' ')).toEqual(output)
|
||||
expect(defaultSort(context.getClassOrder(input.split(' ')))).toEqual(output)
|
||||
})
|
||||
|
||||
it.each([
|
||||
@ -73,6 +110,6 @@ it.each([
|
||||
(input, output) => {
|
||||
let config = { prefix: 'tw-' }
|
||||
let context = createContext(resolveConfig(config))
|
||||
expect(context.sortClassList(input.split(' ')).join(' ')).toEqual(output)
|
||||
expect(defaultSort(context.getClassOrder(input.split(' ')))).toEqual(output)
|
||||
}
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user