Allow variants to be overridden (#14008)

* Allow variants to be overridden

* Update changelog

* Update changelog

* Update tests
This commit is contained in:
Jordan Pittman 2024-07-16 16:55:13 -04:00 committed by GitHub
parent 5ebd5896d7
commit 23e6d433a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 87 additions and 17 deletions

View File

@ -17,8 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add support for basic `addVariant` plugins with new `@plugin` directive ([#13982](https://github.com/tailwindlabs/tailwindcss/pull/13982))
- Add `@variant` at-rule for defining custom variants in CSS ([#13992](https://github.com/tailwindlabs/tailwindcss/pull/13992))
- 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))
- 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))
## [4.0.0-alpha.17] - 2024-07-04

View File

@ -1301,6 +1301,47 @@ describe('plugins', () => {
}"
`)
})
test('built-in variants can be overridden while keeping their order', () => {
let compiled = compile(
css`
@plugin "my-plugin";
@layer utilities {
@tailwind utilities;
}
`,
{
loadPlugin: () => {
return ({ addVariant }) => {
addVariant('dark', '&:is([data-theme=dark] *)')
}
},
},
).build(
// Make sure the order does not change by including the variants
// immediately before and after `dark`
['rtl:flex', 'dark:flex', 'starting:flex'],
)
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
"@layer utilities {
.rtl\\:flex:where([dir="rtl"], [dir="rtl"] *) {
display: flex;
}
.dark\\:flex:is([data-theme="dark"] *) {
display: flex;
}
@starting-style {
.starting\\:flex {
display: flex;
}
}
}"
`)
})
})
describe('@variant', () => {
@ -1737,4 +1778,37 @@ describe('@variant', () => {
`)
})
})
test('built-in variants can be overridden while keeping their order', () => {
expect(
compileCss(
css`
@variant dark (&:is([data-theme='dark'] *));
@layer utilities {
@tailwind utilities;
}
`,
// Make sure the order does not change by including the variants
// immediately before and after `dark`
['rtl:flex', 'dark:flex', 'starting:flex'],
),
).toMatchInlineSnapshot(`
"@layer utilities {
.rtl\\:flex:where([dir="rtl"], [dir="rtl"] *) {
display: flex;
}
.dark\\:flex:is([data-theme="dark"] *) {
display: flex;
}
@starting-style {
.starting\\:flex {
display: flex;
}
}
}"
`)
})
})

View File

@ -158,22 +158,18 @@ export class Variants {
name: string,
{ kind, applyFn, compounds }: { kind: T; applyFn: VariantFn<T>; compounds: boolean },
) {
// In test mode, throw an error if we accidentally override another variant
// by mistake when implementing a new variant that shares the same root
// without realizing the definitions need to be merged.
if (process.env.NODE_ENV === 'test') {
if (this.variants.has(name)) {
throw new Error(`Duplicate variant prefix [${name}]`)
}
let existing = this.variants.get(name)
if (existing) {
Object.assign(existing, { kind, applyFn, compounds })
} else {
this.lastOrder = this.nextOrder()
this.variants.set(name, {
kind,
applyFn,
order: this.lastOrder,
compounds,
})
}
this.lastOrder = this.nextOrder()
this.variants.set(name, {
kind,
applyFn,
order: this.lastOrder,
compounds,
})
}
private nextOrder() {