From 6cd1631be7d45929d9903af8672c4c38620b41fc Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Sat, 15 Oct 2022 08:41:13 -0400 Subject: [PATCH] Add dynamic `data-*` variant (#9559) * Add data variant * Update CHANGELOG.md Co-authored-by: Jonathan Reinink Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com> --- CHANGELOG.md | 1 + src/corePlugins.js | 20 ++++++++++ src/lib/setupContextUtils.js | 1 + tests/arbitrary-variants.test.js | 68 ++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5df4952d530..2c4c34a35db2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Switch to positional argument + object for modifiers ([#9541](https://github.com/tailwindlabs/tailwindcss/pull/9541)) - Add new `min` and `max` variants ([#9558](https://github.com/tailwindlabs/tailwindcss/pull/9558)) - Add aria variants ([#9557](https://github.com/tailwindlabs/tailwindcss/pull/9557)) +- Add `data-*` variants ([#9559](https://github.com/tailwindlabs/tailwindcss/pull/9559)) - Upgrade to `postcss-nested` v6.0 ([#9546](https://github.com/tailwindlabs/tailwindcss/pull/9546)) ### Fixed diff --git a/src/corePlugins.js b/src/corePlugins.js index fe9573d38d70..119d2e6451a4 100644 --- a/src/corePlugins.js +++ b/src/corePlugins.js @@ -401,6 +401,26 @@ export let variantPlugins = { ) }, + dataVariants: ({ matchVariant, theme }) => { + matchVariant('data', (value) => `&[data-${value}]`, { values: theme('data') ?? {} }) + matchVariant( + 'group-data', + (value, { modifier }) => + modifier + ? `:merge(.group\\/${modifier})[data-${value}] &` + : `:merge(.group)[data-${value}] &`, + { values: theme('data') ?? {} } + ) + matchVariant( + 'peer-data', + (value, { modifier }) => + modifier + ? `:merge(.peer\\/${modifier})[data-${value}] ~ &` + : `:merge(.peer)[data-${value}] ~ &`, + { values: theme('data') ?? {} } + ) + }, + orientationVariants: ({ addVariant }) => { addVariant('portrait', '@media (orientation: portrait)') addVariant('landscape', '@media (orientation: landscape)') diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index 18650509085e..55e8e0748985 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -718,6 +718,7 @@ function resolvePlugins(context, root) { variantPlugins['pseudoElementVariants'], variantPlugins['pseudoClassVariants'], variantPlugins['ariaVariants'], + variantPlugins['dataVariants'], ] let afterVariants = [ variantPlugins['supportsVariants'], diff --git a/tests/arbitrary-variants.test.js b/tests/arbitrary-variants.test.js index 91b57f5b1eaa..eae8d2918968 100644 --- a/tests/arbitrary-variants.test.js +++ b/tests/arbitrary-variants.test.js @@ -679,6 +679,74 @@ it('should support aria variants', () => { }) }) +fit('should support data variants', () => { + let config = { + theme: { + data: { + checked: 'ui~="checked"', + }, + }, + content: [ + { + raw: html` +
+
+
+
+
+
+
+
+
+
+
+
+ `, + }, + ], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + return run(input, config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .data-checked\:underline[data-ui~='checked'] { + text-decoration-line: underline; + } + .data-\[position\=top\]\:underline[data-position='top'] { + text-decoration-line: underline; + } + .group[data-ui~='checked'] .group-data-checked\:underline { + text-decoration-line: underline; + } + .group\/foo[data-ui~='checked'] .group-data-checked\/foo\:underline { + text-decoration-line: underline; + } + .group[data-position='top'] .group-data-\[position\=top\]\:underline { + text-decoration-line: underline; + } + .group\/foo[data-position='top'] .group-data-\[position\=top\]\/foo\:underline { + text-decoration-line: underline; + } + .peer[data-ui~='checked'] ~ .peer-data-checked\:underline { + text-decoration-line: underline; + } + .peer\/foo[data-ui~='checked'] ~ .peer-data-checked\/foo\:underline { + text-decoration-line: underline; + } + .peer[data-position='top'] ~ .peer-data-\[position\=top\]\:underline { + text-decoration-line: underline; + } + .peer\/foo[data-position='top'] ~ .peer-data-\[position\=top\]\/foo\:underline { + text-decoration-line: underline; + } + `) + }) +}) + it('should support supports', () => { let config = { theme: {