Add new ** variant (#14903)

This PR adds a new `**` variant to target any level of children.

This is very similar to the `*` variant, the big difference is that:

- `*` applies to direct children only
- `**` applies to any level of children

Thought of this because of all the recent work we did around globs. So a
good analogy for this is glob syntax where you have the exact same
difference. `*.html` vs `**/*.html`.
This commit is contained in:
Robin Malfait 2024-11-07 16:48:49 +01:00 • committed by GitHub
parent a4f8a36413
commit 3821f692c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 21 additions and 1 deletions

View file

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support derived spacing scales based on a single `--spacing` theme value ([#14857](https://github.com/tailwindlabs/tailwindcss/pull/14857))
- Add `svh`, `dvh`, `svw`, `dvw`, and `auto` values to all width/height/size utilities ([#14857](https://github.com/tailwindlabs/tailwindcss/pull/14857))
- Add new `**` variant ([#14903](https://github.com/tailwindlabs/tailwindcss/pull/14903))
- _Upgrade (experimental)_: Migrate `grid-cols-[subgrid]` and `grid-rows-[subgrid]` to `grid-cols-subgrid` and `grid-rows-subgrid` ([#14840](https://github.com/tailwindlabs/tailwindcss/pull/14840))
- _Upgrade (experimental)_: Support migrating projects with multiple config files ([#14863](https://github.com/tailwindlabs/tailwindcss/pull/14863))
- _Upgrade (experimental)_: Rename `shadow` to `shadow-sm`, `shadow-sm` to `shadow-xs`, and `shadow-xs` to `shadow-2xs` ([#14875](https://github.com/tailwindlabs/tailwindcss/pull/14875))

View file

@ -44,7 +44,7 @@ describe.each([
`,
'project-a/index.html': html`
<div
class="underline 2xl:font-bold hocus:underline inverted:flex"
class="underline 2xl:font-bold hocus:underline inverted:flex *:flex **:flex"
></div>
`,
'project-a/plugin.js': js`
@ -89,6 +89,8 @@ describe.each([
candidate`content-['project-b/src/index.js']`,
candidate`inverted:flex`,
candidate`hocus:underline`,
candidate`*:flex`,
candidate`**:flex`,
])
},
)

View file

@ -6950,6 +6950,13 @@ exports[`getVariants 1`] = `
"selectors": [Function],
"values": [],
},
{
"hasDash": true,
"isArbitrary": false,
"name": "**",
"selectors": [Function],
"values": [],
},
{
"hasDash": true,
"isArbitrary": true,

View file

@ -24,6 +24,15 @@ test('*', async () => {
expect(await run(['*/foo:flex'])).toEqual('')
})
test('**', async () => {
expect(await run(['**:flex'])).toMatchInlineSnapshot(`
":where(.\\*\\*\\:flex *) {
display: flex;
}"
`)
expect(await run(['**/foo:flex'])).toEqual('')
})
test('first-letter', async () => {
expect(await run(['first-letter:flex'])).toMatchInlineSnapshot(`
".first-letter\\:flex:first-letter {

View file

@ -364,6 +364,7 @@ export function createVariants(theme: Theme): Variants {
variants.static('force', () => {}, { compounds: Compounds.Never })
staticVariant('*', [':where(& > *)'], { compounds: Compounds.Never })
staticVariant('**', [':where(& *)'], { compounds: Compounds.Never })
function negateConditions(ruleName: string, conditions: string[]) {
return conditions.map((condition) => {