Skip to content

Commit 6cd1631

Browse files
adamwathanreinink
andauthored
Add dynamic data-* variant (#9559)
* Add data variant * Update CHANGELOG.md Co-authored-by: Jonathan Reinink <[email protected]> Co-authored-by: Adam Wathan <[email protected]>
1 parent 3f9ef7c commit 6cd1631

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030
- Switch to positional argument + object for modifiers ([#9541](https://github.com/tailwindlabs/tailwindcss/pull/9541))
3131
- Add new `min` and `max` variants ([#9558](https://github.com/tailwindlabs/tailwindcss/pull/9558))
3232
- Add aria variants ([#9557](https://github.com/tailwindlabs/tailwindcss/pull/9557))
33+
- Add `data-*` variants ([#9559](https://github.com/tailwindlabs/tailwindcss/pull/9559))
3334
- Upgrade to `postcss-nested` v6.0 ([#9546](https://github.com/tailwindlabs/tailwindcss/pull/9546))
3435

3536
### Fixed

src/corePlugins.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,26 @@ export let variantPlugins = {
401401
)
402402
},
403403

404+
dataVariants: ({ matchVariant, theme }) => {
405+
matchVariant('data', (value) => `&[data-${value}]`, { values: theme('data') ?? {} })
406+
matchVariant(
407+
'group-data',
408+
(value, { modifier }) =>
409+
modifier
410+
? `:merge(.group\\/${modifier})[data-${value}] &`
411+
: `:merge(.group)[data-${value}] &`,
412+
{ values: theme('data') ?? {} }
413+
)
414+
matchVariant(
415+
'peer-data',
416+
(value, { modifier }) =>
417+
modifier
418+
? `:merge(.peer\\/${modifier})[data-${value}] ~ &`
419+
: `:merge(.peer)[data-${value}] ~ &`,
420+
{ values: theme('data') ?? {} }
421+
)
422+
},
423+
404424
orientationVariants: ({ addVariant }) => {
405425
addVariant('portrait', '@media (orientation: portrait)')
406426
addVariant('landscape', '@media (orientation: landscape)')

src/lib/setupContextUtils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ function resolvePlugins(context, root) {
718718
variantPlugins['pseudoElementVariants'],
719719
variantPlugins['pseudoClassVariants'],
720720
variantPlugins['ariaVariants'],
721+
variantPlugins['dataVariants'],
721722
]
722723
let afterVariants = [
723724
variantPlugins['supportsVariants'],

tests/arbitrary-variants.test.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,74 @@ it('should support aria variants', () => {
679679
})
680680
})
681681

682+
fit('should support data variants', () => {
683+
let config = {
684+
theme: {
685+
data: {
686+
checked: 'ui~="checked"',
687+
},
688+
},
689+
content: [
690+
{
691+
raw: html`
692+
<div>
693+
<div class="data-checked:underline"></div>
694+
<div class="data-[position=top]:underline"></div>
695+
<div class="group-data-checked:underline"></div>
696+
<div class="peer-data-checked:underline"></div>
697+
<div class="group-data-checked/foo:underline"></div>
698+
<div class="peer-data-checked/foo:underline"></div>
699+
<div class="group-data-[position=top]:underline"></div>
700+
<div class="peer-data-[position=top]:underline"></div>
701+
<div class="group-data-[position=top]/foo:underline"></div>
702+
<div class="peer-data-[position=top]/foo:underline"></div>
703+
</div>
704+
`,
705+
},
706+
],
707+
corePlugins: { preflight: false },
708+
}
709+
710+
let input = css`
711+
@tailwind utilities;
712+
`
713+
714+
return run(input, config).then((result) => {
715+
expect(result.css).toMatchFormattedCss(css`
716+
.data-checked\:underline[data-ui~='checked'] {
717+
text-decoration-line: underline;
718+
}
719+
.data-\[position\=top\]\:underline[data-position='top'] {
720+
text-decoration-line: underline;
721+
}
722+
.group[data-ui~='checked'] .group-data-checked\:underline {
723+
text-decoration-line: underline;
724+
}
725+
.group\/foo[data-ui~='checked'] .group-data-checked\/foo\:underline {
726+
text-decoration-line: underline;
727+
}
728+
.group[data-position='top'] .group-data-\[position\=top\]\:underline {
729+
text-decoration-line: underline;
730+
}
731+
.group\/foo[data-position='top'] .group-data-\[position\=top\]\/foo\:underline {
732+
text-decoration-line: underline;
733+
}
734+
.peer[data-ui~='checked'] ~ .peer-data-checked\:underline {
735+
text-decoration-line: underline;
736+
}
737+
.peer\/foo[data-ui~='checked'] ~ .peer-data-checked\/foo\:underline {
738+
text-decoration-line: underline;
739+
}
740+
.peer[data-position='top'] ~ .peer-data-\[position\=top\]\:underline {
741+
text-decoration-line: underline;
742+
}
743+
.peer\/foo[data-position='top'] ~ .peer-data-\[position\=top\]\/foo\:underline {
744+
text-decoration-line: underline;
745+
}
746+
`)
747+
})
748+
})
749+
682750
it('should support supports', () => {
683751
let config = {
684752
theme: {

0 commit comments

Comments
 (0)