Skip to content

Commit 23e6d43

Browse files
Allow variants to be overridden (#14008)
* Allow variants to be overridden * Update changelog * Update changelog * Update tests
1 parent 5ebd589 commit 23e6d43

File tree

3 files changed

+87
-17
lines changed

3 files changed

+87
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717

1818
### Added
1919

20-
- Add support for basic `addVariant` plugins with new `@plugin` directive ([#13982](https://github.com/tailwindlabs/tailwindcss/pull/13982))
21-
- Add `@variant` at-rule for defining custom variants in CSS ([#13992](https://github.com/tailwindlabs/tailwindcss/pull/13992))
20+
- Add support for basic `addVariant` plugins with new `@plugin` directive ([#13982](https://github.com/tailwindlabs/tailwindcss/pull/13982), [#14008](https://github.com/tailwindlabs/tailwindcss/pull/14008))
21+
- Add `@variant` at-rule for defining custom variants in CSS ([#13992](https://github.com/tailwindlabs/tailwindcss/pull/13992), [#14008](https://github.com/tailwindlabs/tailwindcss/pull/14008))
2222

2323
## [4.0.0-alpha.17] - 2024-07-04
2424

packages/tailwindcss/src/index.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,47 @@ describe('plugins', () => {
13011301
}"
13021302
`)
13031303
})
1304+
1305+
test('built-in variants can be overridden while keeping their order', () => {
1306+
let compiled = compile(
1307+
css`
1308+
@plugin "my-plugin";
1309+
@layer utilities {
1310+
@tailwind utilities;
1311+
}
1312+
`,
1313+
1314+
{
1315+
loadPlugin: () => {
1316+
return ({ addVariant }) => {
1317+
addVariant('dark', '&:is([data-theme=dark] *)')
1318+
}
1319+
},
1320+
},
1321+
).build(
1322+
// Make sure the order does not change by including the variants
1323+
// immediately before and after `dark`
1324+
['rtl:flex', 'dark:flex', 'starting:flex'],
1325+
)
1326+
1327+
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
1328+
"@layer utilities {
1329+
.rtl\\:flex:where([dir="rtl"], [dir="rtl"] *) {
1330+
display: flex;
1331+
}
1332+
1333+
.dark\\:flex:is([data-theme="dark"] *) {
1334+
display: flex;
1335+
}
1336+
1337+
@starting-style {
1338+
.starting\\:flex {
1339+
display: flex;
1340+
}
1341+
}
1342+
}"
1343+
`)
1344+
})
13041345
})
13051346

13061347
describe('@variant', () => {
@@ -1737,4 +1778,37 @@ describe('@variant', () => {
17371778
`)
17381779
})
17391780
})
1781+
1782+
test('built-in variants can be overridden while keeping their order', () => {
1783+
expect(
1784+
compileCss(
1785+
css`
1786+
@variant dark (&:is([data-theme='dark'] *));
1787+
@layer utilities {
1788+
@tailwind utilities;
1789+
}
1790+
`,
1791+
1792+
// Make sure the order does not change by including the variants
1793+
// immediately before and after `dark`
1794+
['rtl:flex', 'dark:flex', 'starting:flex'],
1795+
),
1796+
).toMatchInlineSnapshot(`
1797+
"@layer utilities {
1798+
.rtl\\:flex:where([dir="rtl"], [dir="rtl"] *) {
1799+
display: flex;
1800+
}
1801+
1802+
.dark\\:flex:is([data-theme="dark"] *) {
1803+
display: flex;
1804+
}
1805+
1806+
@starting-style {
1807+
.starting\\:flex {
1808+
display: flex;
1809+
}
1810+
}
1811+
}"
1812+
`)
1813+
})
17401814
})

packages/tailwindcss/src/variants.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,22 +158,18 @@ export class Variants {
158158
name: string,
159159
{ kind, applyFn, compounds }: { kind: T; applyFn: VariantFn<T>; compounds: boolean },
160160
) {
161-
// In test mode, throw an error if we accidentally override another variant
162-
// by mistake when implementing a new variant that shares the same root
163-
// without realizing the definitions need to be merged.
164-
if (process.env.NODE_ENV === 'test') {
165-
if (this.variants.has(name)) {
166-
throw new Error(`Duplicate variant prefix [${name}]`)
167-
}
161+
let existing = this.variants.get(name)
162+
if (existing) {
163+
Object.assign(existing, { kind, applyFn, compounds })
164+
} else {
165+
this.lastOrder = this.nextOrder()
166+
this.variants.set(name, {
167+
kind,
168+
applyFn,
169+
order: this.lastOrder,
170+
compounds,
171+
})
168172
}
169-
170-
this.lastOrder = this.nextOrder()
171-
this.variants.set(name, {
172-
kind,
173-
applyFn,
174-
order: this.lastOrder,
175-
compounds,
176-
})
177173
}
178174

179175
private nextOrder() {

0 commit comments

Comments
 (0)