Skip to content

Commit 759c1a3

Browse files
Unify implementations of compile and __unstable__loadDesignSystem (#14150)
Right now there's some minor duplication and a ton of missing stuff in `__unstable__loadDesignSystem` — this PR makes sure the functionality is unified between it and `compile()`
1 parent f06472e commit 759c1a3

File tree

2 files changed

+55
-62
lines changed

2 files changed

+55
-62
lines changed

packages/tailwindcss/src/index.ts

Lines changed: 45 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,9 @@ function parseThemeOptions(selector: string) {
3535
return { isReference, isInline }
3636
}
3737

38-
export async function compile(
39-
css: string,
40-
{ loadPlugin = throwOnPlugin }: CompileOptions = {},
41-
): Promise<{
42-
globs: string[]
43-
build(candidates: string[]): string
44-
}> {
38+
async function parseCss(css: string, { loadPlugin = throwOnPlugin }: CompileOptions = {}) {
4539
let ast = CSS.parse(css)
4640

47-
if (process.env.NODE_ENV !== 'test') {
48-
ast.unshift(comment(`! tailwindcss v${version} | MIT License | https://tailwindcss.com `))
49-
}
50-
51-
// Track all invalid candidates
52-
let invalidCandidates = new Set<string>()
53-
function onInvalidCandidate(candidate: string) {
54-
invalidCandidates.add(candidate)
55-
}
56-
5741
// Find all `@theme` declarations
5842
let theme = new Theme()
5943
let pluginLoaders: Promise<Plugin>[] = []
@@ -301,21 +285,6 @@ export async function compile(
301285

302286
await Promise.all(pluginLoaders.map((loader) => loader.then((plugin) => plugin(pluginApi))))
303287

304-
let tailwindUtilitiesNode: Rule | null = null
305-
306-
// Find `@tailwind utilities` so that we can later replace it with the actual
307-
// generated utility class CSS.
308-
walk(ast, (node) => {
309-
if (node.kind === 'rule' && node.selector === '@tailwind utilities') {
310-
tailwindUtilitiesNode = node
311-
312-
// Stop walking after finding `@tailwind utilities` to avoid walking all
313-
// of the generated CSS. This means `@tailwind utilities` can only appear
314-
// once per file but that's the intended usage at this point in time.
315-
return WalkAction.Stop
316-
}
317-
})
318-
319288
// Replace `@apply` rules with the actual utility classes.
320289
if (css.includes('@apply')) {
321290
substituteAtApply(ast, designSystem)
@@ -335,6 +304,47 @@ export async function compile(
335304
return WalkAction.Skip
336305
})
337306

307+
return {
308+
designSystem,
309+
ast,
310+
globs,
311+
}
312+
}
313+
314+
export async function compile(
315+
css: string,
316+
opts: CompileOptions = {},
317+
): Promise<{
318+
globs: string[]
319+
build(candidates: string[]): string
320+
}> {
321+
let { designSystem, ast, globs } = await parseCss(css, opts)
322+
323+
let tailwindUtilitiesNode: Rule | null = null
324+
325+
// Find `@tailwind utilities` so that we can later replace it with the actual
326+
// generated utility class CSS.
327+
walk(ast, (node) => {
328+
if (node.kind === 'rule' && node.selector === '@tailwind utilities') {
329+
tailwindUtilitiesNode = node
330+
331+
// Stop walking after finding `@tailwind utilities` to avoid walking all
332+
// of the generated CSS. This means `@tailwind utilities` can only appear
333+
// once per file but that's the intended usage at this point in time.
334+
return WalkAction.Stop
335+
}
336+
})
337+
338+
if (process.env.NODE_ENV !== 'test') {
339+
ast.unshift(comment(`! tailwindcss v${version} | MIT License | https://tailwindcss.com `))
340+
}
341+
342+
// Track all invalid candidates
343+
let invalidCandidates = new Set<string>()
344+
function onInvalidCandidate(candidate: string) {
345+
invalidCandidates.add(candidate)
346+
}
347+
338348
// Track all valid candidates, these are the incoming `rawCandidate` that
339349
// resulted in a generated AST Node. All the other `rawCandidates` are invalid
340350
// and should be ignored.
@@ -385,24 +395,7 @@ export async function compile(
385395
}
386396
}
387397

388-
export function __unstable__loadDesignSystem(css: string) {
389-
// Find all `@theme` declarations
390-
let theme = new Theme()
391-
let ast = CSS.parse(css)
392-
393-
walk(ast, (node) => {
394-
if (node.kind !== 'rule') return
395-
if (node.selector !== '@theme' && !node.selector.startsWith('@theme ')) return
396-
let { isReference, isInline } = parseThemeOptions(node.selector)
397-
398-
// Record all custom properties in the `@theme` declaration
399-
walk([node], (node) => {
400-
if (node.kind !== 'declaration') return
401-
if (!node.property.startsWith('--')) return
402-
403-
theme.add(node.property, node.value, { isReference, isInline })
404-
})
405-
})
406-
407-
return buildDesignSystem(theme)
398+
export async function __unstable__loadDesignSystem(css: string, opts: CompileOptions = {}) {
399+
let result = await parseCss(css, opts)
400+
return result.designSystem
408401
}

packages/tailwindcss/src/sort.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ const table = [
3535
// ['dark a underline', 'a dark underline'],
3636
] as const
3737

38-
test.each(table)('sorts classes: "%s" -> "%s"', (input, expected) => {
39-
expect(sortClasses(input, loadDesign())).toEqual(expected)
38+
test.each(table)('sorts classes: "%s" -> "%s"', async (input, expected) => {
39+
expect(sortClasses(input, await loadDesign())).toEqual(expected)
4040
})
4141

42-
test.skip('group, peer, and dark have their own order', () => {
42+
test.skip('group, peer, and dark have their own order', async () => {
4343
let input = shuffle(['group', 'peer', 'dark']).join(' ')
44-
expect(sortClasses(input, loadDesign())).toEqual('dark group peer')
44+
expect(sortClasses(input, await loadDesign())).toEqual('dark group peer')
4545
})
4646

47-
test('can sort classes deterministically across multiple class lists', () => {
47+
test('can sort classes deterministically across multiple class lists', async () => {
4848
let classes = [
4949
[
5050
'a-class px-3 p-1 b-class py-3 bg-red-500 bg-blue-500',
@@ -57,32 +57,32 @@ test('can sort classes deterministically across multiple class lists', () => {
5757
]
5858

5959
// Shared design
60-
let design = loadDesign()
60+
let design = await loadDesign()
6161
for (const [input, output] of classes) {
6262
expect(sortClasses(input, design)).toEqual(output)
6363
}
6464

6565
// Fresh design
6666
for (const [input, output] of classes) {
67-
expect(sortClasses(input, loadDesign())).toEqual(output)
67+
expect(sortClasses(input, await loadDesign())).toEqual(output)
6868
}
6969
})
7070

71-
test('sorts arbitrary values across one or more class lists consistently', () => {
71+
test('sorts arbitrary values across one or more class lists consistently', async () => {
7272
let classes = [
7373
['[--fg:#fff]', '[--fg:#fff]'],
7474
['[--bg:#111] [--bg_hover:#000] [--fg:#fff]', '[--bg:#111] [--bg_hover:#000] [--fg:#fff]'],
7575
]
7676

7777
// Shared design
78-
let design = loadDesign()
78+
let design = await loadDesign()
7979
for (const [input, output] of classes) {
8080
expect(sortClasses(input, design)).toEqual(output)
8181
}
8282

8383
// Fresh design
8484
for (const [input, output] of classes) {
85-
expect(sortClasses(input, loadDesign())).toEqual(output)
85+
expect(sortClasses(input, await loadDesign())).toEqual(output)
8686
}
8787
})
8888

0 commit comments

Comments
 (0)