Add * variant for targeting direct children (#12551)
* add `*` as child variant * add `*` as allowed variant character * update test to reflect Lightning CSS output * add `childVariant` test * Update changelog --------- Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com> Co-authored-by: Robin Malfait <malfait.robin@gmail.com> Co-authored-by: Gregor Kaczmarczyk <github@aggreggator.de>
This commit is contained in:
parent
c5449a03b4
commit
cb9c64a6d2
7 changed files with 61 additions and 2 deletions
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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.: '<sm'
|
||||
// | '$' | '^' | '_'
|
||||
|
|
@ -473,7 +473,7 @@ impl<'a> 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.:
|
||||
// - <sm:underline
|
||||
|
|
@ -797,6 +797,15 @@ mod test {
|
|||
assert_eq!(candidates, vec!["hover:underline"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_parse_start_variants() {
|
||||
let candidates = run("*:underline", false);
|
||||
assert_eq!(candidates, vec!["*:underline"]);
|
||||
|
||||
let candidates = run("hover:*:underline", false);
|
||||
assert_eq!(candidates, vec!["hover:*:underline"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_can_parse_simple_candidates_with_stacked_variants() {
|
||||
let candidates = run("focus:hover:underline", false);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ import { normalize } from './util/dataTypes'
|
|||
import { INTERNAL_FEATURES } from './lib/setupContextUtils'
|
||||
|
||||
export let variantPlugins = {
|
||||
childVariant: ({ addVariant }) => {
|
||||
addVariant('*', '& > *')
|
||||
},
|
||||
pseudoElementVariants: ({ addVariant }) => {
|
||||
addVariant('first-letter', '&::first-letter')
|
||||
addVariant('first-line', '&::first-line')
|
||||
|
|
|
|||
|
|
@ -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'],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`should test the 'childVariant' plugin 1`] = `
|
||||
"
|
||||
.\\*\\:flex > * {
|
||||
display: flex;
|
||||
}
|
||||
"
|
||||
`;
|
||||
3
tests/plugins/variants/childVariant.test.js
Normal file
3
tests/plugins/variants/childVariant.test.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { quickVariantPluginTest } from '../../util/run'
|
||||
|
||||
quickVariantPluginTest('childVariant').toMatchSnapshot()
|
||||
|
|
@ -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`
|
||||
<div class="*:italic" />
|
||||
<div class="*:hover:italic" />
|
||||
<div class="hover:*:italic" />
|
||||
<div class="data-[slot=label]:*:hover:italic" />
|
||||
<div class="[&_p]:*:hover:italic" />
|
||||
`,
|
||||
},
|
||||
],
|
||||
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;
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue