Skip to content

Commit 5dcb301

Browse files
Overwrite core utilities to ensure we have a consistent order
1 parent 669fd15 commit 5dcb301

3 files changed

Lines changed: 95 additions & 19 deletions

File tree

packages/tailwindcss/src/compat/config.test.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ describe('default font family compatibility', () => {
979979
})
980980
})
981981

982-
test('creates variants for `data`, `supports`, and `aria` theme options', async () => {
982+
test('creates variants for `data`, `supports`, and `aria` theme options at the same level as the core utility ', async () => {
983983
let input = css`
984984
@tailwind utilities;
985985
@config "./config.js";
@@ -1008,23 +1008,51 @@ test('creates variants for `data`, `supports`, and `aria` theme options', async
10081008
'aria-polite:underline',
10091009
'supports-child-combinator:underline',
10101010
'data-checked:underline',
1011+
1012+
// Ensure core utility still works
1013+
'aria-hidden:flex',
1014+
'supports-grid:flex',
1015+
'data-foo:flex',
1016+
1017+
// print variants should be at the end, like it is in the core utility
1018+
'print:flex',
10111019
]),
10121020
).toMatchInlineSnapshot(`
10131021
".aria-polite\\:underline {
10141022
&[aria-live="polite"] {
10151023
text-decoration-line: underline;
10161024
}
10171025
}
1018-
.supports-child-combinator\\:underline {
1019-
@supports (h2 > p) {
1020-
text-decoration-line: underline;
1026+
.aria-hidden\\:flex {
1027+
&[aria-hidden="true"] {
1028+
display: flex;
10211029
}
10221030
}
10231031
.data-checked\\:underline {
10241032
&[data-ui~="checked"] {
10251033
text-decoration-line: underline;
10261034
}
10271035
}
1036+
.data-foo\\:flex {
1037+
&[data-foo] {
1038+
display: flex;
1039+
}
1040+
}
1041+
.supports-child-combinator\\:underline {
1042+
@supports (h2 > p) {
1043+
text-decoration-line: underline;
1044+
}
1045+
}
1046+
.supports-grid\\:flex {
1047+
@supports (grid: var(--tw)) {
1048+
display: flex;
1049+
}
1050+
}
1051+
.print\\:flex {
1052+
@media print {
1053+
display: flex;
1054+
}
1055+
}
10281056
"
10291057
`)
10301058
})
Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,79 @@
1-
import type { PluginAPI } from '../plugin-api'
1+
import { rule } from '../ast'
2+
import type { DesignSystem } from '../design-system'
3+
import type { ResolvedConfig } from './config/types'
24
import DefaultTheme from './default-theme'
35

4-
export function themeVariantsPlugin({ addVariant, config }: PluginAPI) {
5-
let ariaVariants = config('theme.aria', {})
6-
let supportsVariants = config('theme.supports', {})
7-
let dataVariants = config('theme.data', {})
6+
export function registerThemeVariantOverrides(config: ResolvedConfig, designSystem: DesignSystem) {
7+
let ariaVariants = config.theme.aria || {}
8+
let supportsVariants = config.theme.supports || {}
9+
let dataVariants = config.theme.data || {}
810

911
for (let [name, rule] of Object.entries(DefaultTheme.aria)) {
1012
// `theme.aria` contains values from the default theme. We don't
1113
// want to create variants for these values as these are already
1214
// handled by the core utility.
13-
if (Object.hasOwn(DefaultTheme.aria, name) && ariaVariants[name] === rule) {
14-
continue
15+
if (ariaVariants[name] === rule) {
16+
delete ariaVariants[name]
1517
}
18+
}
1619

20+
for (let [name, rule] of Object.entries(DefaultTheme.aria)) {
1721
if (ariaVariants[name] === rule) {
1822
delete ariaVariants[name]
1923
}
2024
}
2125

22-
for (let [name, rule] of Object.entries(ariaVariants)) {
23-
addVariant(`aria-${name}`, `&[aria-${rule}]`)
26+
if (Object.keys(ariaVariants).length > 0) {
27+
let coreAria = designSystem.variants.get('aria')
28+
let coreApplyFn = coreAria?.applyFn
29+
let coreCompounds = coreAria?.compounds
30+
designSystem.variants.functional(
31+
'aria',
32+
(ruleNode, variant) => {
33+
let value = variant.value
34+
if (value && value.kind === 'named' && value.value in ariaVariants) {
35+
ruleNode.nodes = [rule(`&[aria-${ariaVariants[value.value]}]`, ruleNode.nodes)]
36+
return
37+
}
38+
return coreApplyFn?.(ruleNode, variant)
39+
},
40+
{ compounds: coreCompounds },
41+
)
2442
}
2543

26-
for (let [name, rule] of Object.entries(supportsVariants)) {
27-
addVariant(`supports-${name}`, `@supports (${rule})`)
44+
if (Object.keys(supportsVariants).length > 0) {
45+
let coreSupports = designSystem.variants.get('supports')
46+
let coreApplyFn = coreSupports?.applyFn
47+
let coreCompounds = coreSupports?.compounds
48+
designSystem.variants.functional(
49+
'supports',
50+
(ruleNode, variant) => {
51+
let value = variant.value
52+
if (value && value.kind === 'named' && value.value in supportsVariants) {
53+
ruleNode.nodes = [rule(`@supports (${supportsVariants[value.value]})`, ruleNode.nodes)]
54+
return
55+
}
56+
return coreApplyFn?.(ruleNode, variant)
57+
},
58+
{ compounds: coreCompounds },
59+
)
2860
}
2961

30-
for (let [name, rule] of Object.entries(dataVariants)) {
31-
addVariant(`data-${name}`, `&[data-${rule}]`)
62+
if (Object.keys(dataVariants).length > 0) {
63+
let coreData = designSystem.variants.get('data')
64+
let coreApplyFn = coreData?.applyFn
65+
let coreCompounds = coreData?.compounds
66+
designSystem.variants.functional(
67+
'data',
68+
(ruleNode, variant) => {
69+
let value = variant.value
70+
if (value && value.kind === 'named' && value.value in dataVariants) {
71+
ruleNode.nodes = [rule(`&[data-${dataVariants[value.value]}]`, ruleNode.nodes)]
72+
return
73+
}
74+
return coreApplyFn?.(ruleNode, variant)
75+
},
76+
{ compounds: coreCompounds },
77+
)
3278
}
3379
}

packages/tailwindcss/src/plugin-api.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { resolveConfig } from './compat/config/resolve-config'
77
import type { ResolvedConfig, UserConfig } from './compat/config/types'
88
import { darkModePlugin } from './compat/dark-mode'
99
import { createThemeFn } from './compat/plugin-functions'
10-
import { themeVariantsPlugin } from './compat/theme-variants'
10+
import { registerThemeVariantOverrides } from './compat/theme-variants'
1111
import { substituteFunctions } from './css-functions'
1212
import * as CSS from './css-parser'
1313
import type { DesignSystem } from './design-system'
@@ -522,7 +522,7 @@ export async function applyCompatibilityHooks({
522522
let resolvedConfig = resolveConfig(designSystem, [
523523
{ config: createCompatConfig(designSystem.theme) },
524524
...userConfig,
525-
{ config: { plugins: [darkModePlugin, themeVariantsPlugin] } },
525+
{ config: { plugins: [darkModePlugin] } },
526526
])
527527

528528
let pluginApi = buildPluginApi(designSystem, ast, resolvedConfig)
@@ -536,6 +536,8 @@ export async function applyCompatibilityHooks({
536536
// core utilities already read from.
537537
applyConfigToTheme(designSystem, userConfig)
538538

539+
registerThemeVariantOverrides(resolvedConfig, designSystem)
540+
539541
// Replace `resolveThemeValue` with a version that is backwards compatible
540542
// with dot-notation but also aware of any JS theme configurations registered
541543
// by plugins or JS config files. This is significantly slower than just

0 commit comments

Comments
 (0)