During the migration process, a lot of changes to the CSS file happen.
Some parts are converted, some parts are deleted and some new CSS is
added.
To make sure we are generating a sensible and good looking CSS file, we
will sort the final CSS and pretty print it.
The order we came up with looks like this:
```css
/* Imports */
@import "tailwindcss";
@import "../other.css";
/* Configuration */
@config "../path/to/tailwindcss.config.js";
@plugin "my-plugin-1";
@plugin "my-plugin-2";
@source "./foo/**/*.ts";
@source "./bar/**/*.ts";
@variant foo {}
@variant bar {}
@theme {}
/* Border compatibility CSS */
@layer base {}
/* Utilities */
@utility foo {}
@utility bar {}
/* Rest of your own CSS if any */
```
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
45 lines
1 KiB
TypeScript
45 lines
1 KiB
TypeScript
export enum WalkAction {
|
|
// Continue walking the tree. Default behavior.
|
|
Continue,
|
|
|
|
// Skip walking into the current node.
|
|
Skip,
|
|
|
|
// Stop walking the tree entirely.
|
|
Stop,
|
|
}
|
|
|
|
interface Walkable<T> {
|
|
each(cb: (node: T, index: number) => void): void
|
|
}
|
|
|
|
// Custom walk implementation where we can skip going into nodes when we don't
|
|
// need to process them.
|
|
export function walk<T>(
|
|
rule: Walkable<T>,
|
|
cb: (rule: T, idx: number, parent: Walkable<T>) => void | WalkAction,
|
|
): undefined | false {
|
|
let result: undefined | false = undefined
|
|
|
|
rule.each?.((node, idx) => {
|
|
let action = cb(node, idx, rule) ?? WalkAction.Continue
|
|
if (action === WalkAction.Stop) {
|
|
result = false
|
|
return result
|
|
}
|
|
if (action !== WalkAction.Skip) {
|
|
result = walk(node as Walkable<T>, cb)
|
|
return result
|
|
}
|
|
})
|
|
|
|
return result
|
|
}
|
|
|
|
// Depth first walk reversal implementation.
|
|
export function walkDepth<T>(rule: Walkable<T>, cb: (rule: T) => void) {
|
|
rule?.each?.((node) => {
|
|
walkDepth(node as Walkable<T>, cb)
|
|
cb(node)
|
|
})
|
|
}
|