diff --git a/CHANGELOG.md b/CHANGELOG.md index 80f4b6cc7e2e..2fb250f7f4e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `forced-colors` variant ([#11694](https://github.com/tailwindlabs/tailwindcss/pull/11694)) - Add `appearance-auto` utility ([#12404](https://github.com/tailwindlabs/tailwindcss/pull/12404)) - Add logical property values for `float` and `clear` utilities ([#12480](https://github.com/tailwindlabs/tailwindcss/pull/12480)) +- Add `*` variant for targeting direct children ([#12551](https://github.com/tailwindlabs/tailwindcss/pull/12551)) - [Oxide] New Rust template parsing engine ([#10252](https://github.com/tailwindlabs/tailwindcss/pull/10252)) - [Oxide] Support `@import "tailwindcss"` using top-level `index.css` file ([#11205](https://github.com/tailwindlabs/tailwindcss/pull/11205), ([#11260](https://github.com/tailwindlabs/tailwindcss/pull/11260))) - [Oxide] Use `lightningcss` for nesting and vendor prefixes in PostCSS plugin ([#10399](https://github.com/tailwindlabs/tailwindcss/pull/10399)) diff --git a/oxide/crates/core/src/parser.rs b/oxide/crates/core/src/parser.rs index 2ac3a97cdab4..845f3385e449 100644 --- a/oxide/crates/core/src/parser.rs +++ b/oxide/crates/core/src/parser.rs @@ -412,7 +412,7 @@ impl<'a> Extractor<'a> { } // Allowed first characters. - b'@' | b'!' | b'-' | b'<' | b'>' | b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' => { + b'@' | b'!' | b'-' | b'<' | b'>' | b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'*' => { // TODO: A bunch of characters that we currently support but maybe we only want it behind // a flag. E.g.: ' Extractor<'a> { b'%' => return ParseAction::Skip, // < and > can only be part of a variant and only be the first or last character - b'<' | b'>' => { + b'<' | b'>' | b'*' => { // Can only be the first or last character // E.g.: // - { + addVariant('*', '& > *') + }, pseudoElementVariants: ({ addVariant }) => { addVariant('first-letter', '&::first-letter') addVariant('first-line', '&::first-line') diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index 050e3cfe49f0..10bd0dc9664d 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -746,6 +746,7 @@ function resolvePlugins(context, root) { // TODO: This is a workaround for backwards compatibility, since custom variants // were historically sorted before screen/stackable variants. let beforeVariants = [ + variantPlugins['childVariant'], variantPlugins['pseudoElementVariants'], variantPlugins['pseudoClassVariants'], variantPlugins['hasVariants'], diff --git a/tests/plugins/variants/__snapshots__/childVariant.test.js.snap b/tests/plugins/variants/__snapshots__/childVariant.test.js.snap new file mode 100644 index 000000000000..c05c5962e964 --- /dev/null +++ b/tests/plugins/variants/__snapshots__/childVariant.test.js.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should test the 'childVariant' plugin 1`] = ` +" +.\\*\\:flex > * { + display: flex; +} +" +`; diff --git a/tests/plugins/variants/childVariant.test.js b/tests/plugins/variants/childVariant.test.js new file mode 100644 index 000000000000..702a11686855 --- /dev/null +++ b/tests/plugins/variants/childVariant.test.js @@ -0,0 +1,3 @@ +import { quickVariantPluginTest } from '../../util/run' + +quickVariantPluginTest('childVariant').toMatchSnapshot() diff --git a/tests/variants.test.js b/tests/variants.test.js index 51980d8a09dd..8a0509828a25 100644 --- a/tests/variants.test.js +++ b/tests/variants.test.js @@ -1167,3 +1167,36 @@ test('stacking dark and rtl variants with pseudo elements', async () => { } `) }) + +test('* is matched by the parser as the children variant', async () => { + let config = { + content: [ + { + raw: html` +
+
+
+
+
+ `, + }, + ], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + let result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .\*\:italic > *, + .\*\:hover\:italic:hover > *, + .hover\:\*\:italic > :hover, + .data-\[slot\=label\]\:\*\:hover\:italic:hover > [data-slot='label'], + .\[\&_p\]\:\*\:hover\:italic:hover > * p { + font-style: italic; + } + `) +})