Skip to content

Commit

Permalink
implement getSortOrder instead of sortClassList
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinMalfait committed Feb 14, 2022
1 parent 0c5af6f commit 2352979
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 21 deletions.
30 changes: 11 additions & 19 deletions src/lib/setupContextUtils.js
Expand Up @@ -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.getSortOrder = function getSortOrder(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.
Expand Down
41 changes: 39 additions & 2 deletions tests/sortClassList.test.js → tests/getSortOrder.test.js
@@ -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 `getSortOrder`.
*
* 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.getSortOrder(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
Expand Down Expand Up @@ -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.getSortOrder(input.split(' ')))).toEqual(output)
})

it.each([
Expand Down Expand Up @@ -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.getSortOrder(input.split(' ')))).toEqual(output)
}
)

0 comments on commit 2352979

Please sign in to comment.