diff --git a/index.d.ts b/index.d.ts index 37b1cc1..1863a07 100644 --- a/index.d.ts +++ b/index.d.ts @@ -52,7 +52,17 @@ export interface Tailwindcss { * [myHtmlCode] * ) */ - generateStylesFromContent: (css: string, content: (Content | string)[]) => Promise; + generateStylesFromContent: (css: string, content: (Content | string)[]) => Promise + + /** + * Get the class order for the provided list of classes + * + * @param classList The list of classes to get the order for. + * @returns The ordered list of classes. + * @example + * tailwindcss.getClassOrder(['left-3', 'inset-x-2', bg-red-500', 'bg-blue-500']) + */ + getClassOrder: (classList: string[]) => string[] } /** @@ -89,7 +99,7 @@ export interface Content { /** * Client side api to generate css via tailwind jit in the browser - * + * * @deprecated with 0.2.0 */ declare function jitBrowserTailwindcss(tailwindMainCss: string, jitContent: string, userTailwindConfig?: TailwindConfig): Promise; diff --git a/src/index.ts b/src/index.ts index c40c8f7..be26a12 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,24 @@ import postcss from 'postcss'; import processTailwindFeatures from 'tailwindcss/src/processTailwindFeatures.js'; +// @ts-ignore +import { createContext } from 'tailwindcss/src/lib/setupContextUtils.js' import resolveConfig from 'tailwindcss/src/public/resolve-config.js'; +export function bigSign(bigIntValue: bigint) { + return Number(bigIntValue > 0n) - Number(bigIntValue < 0n) +} + +function defaultSort(arrayOfTuples: [string, bigint | null][]) { + 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) +} + export const createTailwindcss: typeof import('..').createTailwindcss = ( { tailwindConfig } = {}, ) => { @@ -18,9 +35,14 @@ export const createTailwindcss: typeof import('..').createTailwindcss = ( const processor = postcss([tailwindcssPlugin]); const result = await processor.process(css, { from: undefined }); return result.css; - } + }, + + getClassOrder: (classList: string[]) => { + const context = createContext(resolveConfig(tailwindConfig ?? {})) + return defaultSort(context.getClassOrder(classList)) + }, } -}; +} export const createTailwindcssPlugin: typeof import('..').createTailwindcssPlugin = ({ tailwindConfig, content: contentCollection }) => { const config = resolveConfig(tailwindConfig ?? {}); @@ -39,3 +61,4 @@ export const jitBrowserTailwindcss: typeof import('..').default = (tailwindMainC } export default jitBrowserTailwindcss; + diff --git a/tests/unit-tests/src/getClassOrder.test.js b/tests/unit-tests/src/getClassOrder.test.js new file mode 100644 index 0000000..84ae2cb --- /dev/null +++ b/tests/unit-tests/src/getClassOrder.test.js @@ -0,0 +1,36 @@ +import { createTailwindcss } from '../../../dist/module.esm' + +test('getClassOrder', async () => { + const tailwind = createTailwindcss({ + tailwindConfig: { + corePlugins: { preflight: false }, + }, + }) + + const cases = [ + { + input: 'px-3 b-class p-1 py-3 bg-blue-500 a-class bg-red-500', + output: 'b-class a-class bg-blue-500 bg-red-500 p-1 px-3 py-3', + }, + { + input: 'a-class px-3 p-1 b-class py-3 bg-red-500 bg-blue-500', + output: 'a-class b-class bg-blue-500 bg-red-500 p-1 px-3 py-3', + }, + { + input: 'left-5 left-1', + output: 'left-1 left-5', + }, + { + input: 'left-3 inset-x-10', + output: 'inset-x-10 left-3', + }, + { + input: 'left-3 inset-x-2 bg-red-500 bg-blue-500', + output: 'inset-x-2 left-3 bg-blue-500 bg-red-500', + }, + ] + + for (const { input, output } of cases) { + expect(tailwind.getClassOrder(input.split(' '))).toEqual(output.split(' ')) + } +}) diff --git a/types.d.ts b/types.d.ts index 0ceef62..88cf469 100644 --- a/types.d.ts +++ b/types.d.ts @@ -55,6 +55,7 @@ declare module 'tailwindcss/src/lib/setupContextUtils.js' { export interface JitContext { changedContent: ChangedContent[]; getClassList: () => string[]; + getClassOrder: (classList: string[]) => Array<[string, bigint | null]>; tailwindConfig: TailwindConfig; variantMap: Map; } @@ -89,3 +90,4 @@ declare module 'tailwindcss/src/public/resolve-config.js' { export default function resolveConfig(tailwindConfig: TailwindConfig): TailwindConfig; } +