Update changelog details and naming around the new not-* variant (#14785)

I've tweaked the changelog with suggestions from @adamwathan to improve
clarity around what the actual changes are.

I also renamed `compoundWith` back to `compound` — I felt that it made
sense at the time but keeping the old name definitely feels better the
more I think about it.
This commit is contained in:
Jordan Pittman 2024-10-24 14:50:20 -04:00 committed by GitHub
parent 430836f651
commit 3fe53dd8f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 23 deletions

View File

@ -9,8 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added `not-*` versions of all builtin media query and supports variants ([#14743](https://github.com/tailwindlabs/tailwindcss/pull/14743))
- Improved support for custom variants with `group-*`, `peer-*`, `has-*`, and `not-*` ([#14743](https://github.com/tailwindlabs/tailwindcss/pull/14743))
- Support `not-*` with all built-in media query and `supports-*` variants ([#14743](https://github.com/tailwindlabs/tailwindcss/pull/14743))
- Support `not-*` with custom variants containing at-rules ([#14743](https://github.com/tailwindlabs/tailwindcss/pull/14743))
- Support `group-*`, `peer-*`, and `has-*` with custom variants containing multiple, non-nested style rules ([#14743](https://github.com/tailwindlabs/tailwindcss/pull/14743))
### Fixed
@ -18,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Don't migrate important modifiers inside conditional statements in Vue and Alpine (e.g. `<div v-if="!border" />`) ([#14774](https://github.com/tailwindlabs/tailwindcss/pull/14774))
- Ensure third-party plugins with `exports` in their `package.json` are resolved correctly ([#14775](https://github.com/tailwindlabs/tailwindcss/pull/14775))
- Ensure underscores in the `url()` function are never unescaped ([#14776](https://github.com/tailwindlabs/tailwindcss/pull/14776))
- Fixed display of complex variants in Intellisense ([#14743](https://github.com/tailwindlabs/tailwindcss/pull/14743))
- Ensure complex variants are displayed correctly in IntelliSense completions ([#14743](https://github.com/tailwindlabs/tailwindcss/pull/14743))
- _Upgrade (experimental)_: Ensure `@import` statements for relative CSS files are actually migrated to use relative path syntax ([#14769](https://github.com/tailwindlabs/tailwindcss/pull/14769))
- _Upgrade (experimental)_: Only generate Preflight compatibility styles when Preflight is used ([#14773](https://github.com/tailwindlabs/tailwindcss/pull/14773))
- _Upgrade (experimental)_: Don't escape underscores when printing theme values migrated to CSS variables in arbitrary values (e.g. `m-[var(--spacing-1_5)]` instead of `m-[var(--spacing-1\_5)]`) ([#14778](https://github.com/tailwindlabs/tailwindcss/pull/14778))

View File

@ -209,7 +209,7 @@ it('should parse compound variants with an arbitrary value as an arbitrary varia
utilities.static('flex', () => [])
let variants = new Variants()
variants.compoundWith('group', Compounds.StyleRules, () => {})
variants.compound('group', Compounds.StyleRules, () => {})
expect(run('group-[&_p]/parent-name:flex', { utilities, variants })).toMatchInlineSnapshot(`
[
@ -244,7 +244,7 @@ it('should parse a simple utility with a parameterized variant and a modifier',
utilities.static('flex', () => [])
let variants = new Variants()
variants.compoundWith('group', Compounds.StyleRules, () => {})
variants.compound('group', Compounds.StyleRules, () => {})
variants.functional('aria', () => {})
expect(run('group-aria-[disabled]/parent-name:flex', { utilities, variants }))
@ -286,7 +286,7 @@ it('should parse compound group with itself group-group-*', () => {
let variants = new Variants()
variants.static('hover', () => {})
variants.compoundWith('group', Compounds.StyleRules, () => {})
variants.compound('group', Compounds.StyleRules, () => {})
expect(run('group-group-group-hover/parent-name:flex', { utilities, variants }))
.toMatchInlineSnapshot(`
@ -1255,7 +1255,7 @@ it('should not parse compound group with a non-compoundable variant', () => {
utilities.static('flex', () => [])
let variants = new Variants()
variants.compoundWith('group', Compounds.StyleRules, () => {})
variants.compound('group', Compounds.StyleRules, () => {})
expect(run('group-*:flex', { utilities, variants })).toMatchInlineSnapshot(`[]`)
})

View File

@ -1706,6 +1706,10 @@ test('not', async () => {
`,
[
'not-[:checked]:flex',
'not-[@media_print]:flex',
'not-[@media(orientation:portrait)]:flex',
'not-[@media_(orientation:landscape)]:flex',
'not-[@media_not_(orientation:portrait)]:flex',
'not-hocus:flex',
'not-device-hocus:flex',
@ -2052,6 +2056,30 @@ test('not', async () => {
display: flex;
}
@media not (orientation: landscape) {
.not-\\[\\@media_\\(orientation\\:landscape\\)\\]\\:flex {
display: flex;
}
}
@media (orientation: portrait) {
.not-\\[\\@media_not_\\(orientation\\:portrait\\)\\]\\:flex {
display: flex;
}
}
@media not print {
.not-\\[\\@media_print\\]\\:flex {
display: flex;
}
}
@media not (orientation: portrait) {
.not-\\[\\@media\\(orientation\\:portrait\\)\\]\\:flex {
display: flex;
}
}
.group-not-checked\\:flex:is(:where(.group):not(:checked) *) {
display: flex;
}
@ -2122,6 +2150,10 @@ test('not', async () => {
'not-[+img]:flex',
'not-[~img]:flex',
'not-[:checked]/foo:flex',
'not-[@media_screen,print]:flex',
'not-[@media_not_screen,print]:flex',
'not-[@media_not_screen,not_print]:flex',
'not-nested-at-rules:flex',
'not-nested-style-rules:flex',
'not-multiple-media-conditions:flex',
@ -2147,14 +2179,6 @@ test('not', async () => {
// This is not a conditional at rule
'not-starting:flex',
// TODO:
// 'not-group-[...]:flex',
// 'not-group-*:flex',
// 'not-peer-[...]:flex',
// 'not-peer-*:flex',
// 'not-max-*:flex',
// 'not-min-*:flex',
],
),
).toEqual('')

View File

@ -101,7 +101,7 @@ export class Variants {
})
}
compoundWith(
compound(
name: string,
compoundsWith: Compounds,
applyFn: VariantFn<'compound'>,
@ -354,12 +354,16 @@ export function createVariants(theme: Theme): Variants {
})
}
let conditionalRules = ['@media', '@supports', '@container']
function negateSelector(selector: string) {
if (selector[0] === '@') {
let name = selector.slice(1, selector.indexOf(' '))
let params = selector.slice(selector.indexOf(' ') + 1)
for (let ruleName of conditionalRules) {
if (!selector.startsWith(ruleName)) continue
let name = ruleName.slice(1)
let params = selector.slice(ruleName.length).trim()
if (name === 'media' || name === 'supports' || name === 'container') {
let conditions = segment(params, ',')
// We don't support things like `@media screen, print` because
@ -392,7 +396,7 @@ export function createVariants(theme: Theme): Variants {
return `&:not(${selectors.join(', ')})`
}
variants.compoundWith('not', Compounds.StyleRules | Compounds.AtRules, (ruleNode, variant) => {
variants.compound('not', Compounds.StyleRules | Compounds.AtRules, (ruleNode, variant) => {
if (variant.variant.kind === 'arbitrary' && variant.variant.relative) return null
if (variant.modifier) return null
@ -467,7 +471,7 @@ export function createVariants(theme: Theme): Variants {
})
})
variants.compoundWith('group', Compounds.StyleRules, (ruleNode, variant) => {
variants.compound('group', Compounds.StyleRules, (ruleNode, variant) => {
if (variant.variant.kind === 'arbitrary' && variant.variant.relative) return null
// Name the group by appending the modifier to `group` class itself if
@ -523,7 +527,7 @@ export function createVariants(theme: Theme): Variants {
})
})
variants.compoundWith('peer', Compounds.StyleRules, (ruleNode, variant) => {
variants.compound('peer', Compounds.StyleRules, (ruleNode, variant) => {
if (variant.variant.kind === 'arbitrary' && variant.variant.relative) return null
// Name the peer by appending the modifier to `peer` class itself if
@ -670,7 +674,7 @@ export function createVariants(theme: Theme): Variants {
staticVariant('inert', ['&:is([inert], [inert] *)'])
variants.compoundWith('has', Compounds.StyleRules, (ruleNode, variant) => {
variants.compound('has', Compounds.StyleRules, (ruleNode, variant) => {
if (variant.modifier) return null
let didApply = false