From 61cf624e4bbf8c0867266cc2f67d2f014059df10 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Thu, 13 Jul 2023 10:47:58 -0400 Subject: [PATCH] Move unknown pseudo elements outside of `:is` (#11345) * More pseudo elements outside of `:is` by default * Update changelog --- CHANGELOG.md | 1 + src/util/pseudoElements.js | 23 +++++++++------------ tests/util/apply-important-selector.test.js | 4 ++++ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cc2aed62..900c5e4c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix issue where some pseudo-element variants generated the wrong selector ([#10943](https://github.com/tailwindlabs/tailwindcss/pull/10943), [#10962](https://github.com/tailwindlabs/tailwindcss/pull/10962), [#11111](https://github.com/tailwindlabs/tailwindcss/pull/11111)) - Fix parsing of `theme()` inside `calc()` when there are no spaces around operators ([#11157](https://github.com/tailwindlabs/tailwindcss/pull/11157)) - Ensure `repeating-conic-gradient` is detected as an image ([#11180](https://github.com/tailwindlabs/tailwindcss/pull/11180)) +- Move unknown pseudo-elements outside of `:is` by default ([#11345](https://github.com/tailwindlabs/tailwindcss/pull/11345)) ## [3.3.2] - 2023-04-25 diff --git a/src/util/pseudoElements.js b/src/util/pseudoElements.js index 30466ec2c..5795cdd42 100644 --- a/src/util/pseudoElements.js +++ b/src/util/pseudoElements.js @@ -19,12 +19,13 @@ // **Jumpable** // Any terminal element may "jump" over combinators when moving to the end of the selector // -// This is a backwards-compat quirk of :before and :after variants. +// This is a backwards-compat quirk of pseudo element variants from earlier versions of Tailwind CSS. /** @typedef {'terminal' | 'actionable' | 'jumpable'} PseudoProperty */ /** @type {Record} */ let elementProperties = { + // Pseudo elements from the spec '::after': ['terminal', 'jumpable'], '::backdrop': ['terminal', 'jumpable'], '::before': ['terminal', 'jumpable'], @@ -41,18 +42,14 @@ let elementProperties = { '::spelling-error': ['terminal'], '::target-text': ['terminal'], - // other + // Pseudo elements from the spec with special rules '::file-selector-button': ['terminal', 'actionable'], - '::-webkit-progress-bar': ['terminal', 'actionable'], - // Webkit scroll bar pseudo elements can be combined with user-action pseudo classes - '::-webkit-scrollbar': ['terminal', 'actionable'], - '::-webkit-scrollbar-button': ['terminal', 'actionable'], - '::-webkit-scrollbar-thumb': ['terminal', 'actionable'], - '::-webkit-scrollbar-track': ['terminal', 'actionable'], - '::-webkit-scrollbar-track-piece': ['terminal', 'actionable'], - '::-webkit-scrollbar-corner': ['terminal', 'actionable'], - '::-webkit-resizer': ['terminal', 'actionable'], + // Library-specific pseudo elements used by component libraries + // These are Shadow DOM-like + '::deep': ['actionable'], + '::v-deep': ['actionable'], + '::ng-deep': ['actionable'], // Note: As a rule, double colons (::) should be used instead of a single colon // (:). This distinguishes pseudo-classes from pseudo-elements. However, since @@ -65,8 +62,8 @@ let elementProperties = { // The default value is used when the pseudo-element is not recognized // Because it's not recognized, we don't know if it's terminal or not - // So we assume it can't be moved AND can have user-action pseudo classes attached to it - __default__: ['actionable'], + // So we assume it can be moved AND can have user-action pseudo classes attached to it + __default__: ['terminal', 'actionable'], } /** diff --git a/tests/util/apply-important-selector.test.js b/tests/util/apply-important-selector.test.js index 0ec22792f..3f4ef294c 100644 --- a/tests/util/apply-important-selector.test.js +++ b/tests/util/apply-important-selector.test.js @@ -18,6 +18,10 @@ crosscheck(() => { ${':is(.foo) :is(.bar)'} | ${'#app :is(:is(.foo) :is(.bar))'} ${':is(.foo)::before'} | ${'#app :is(.foo)::before'} ${'.foo:before'} | ${'#app :is(.foo):before'} + ${'.foo::some-uknown-pseudo'} | ${'#app :is(.foo)::some-uknown-pseudo'} + ${'.foo::some-uknown-pseudo:hover'} | ${'#app :is(.foo)::some-uknown-pseudo:hover'} + ${'.foo:focus::some-uknown-pseudo:hover'} | ${'#app :is(.foo:focus)::some-uknown-pseudo:hover'} + ${'.foo:hover::some-uknown-pseudo:focus'} | ${'#app :is(.foo:hover)::some-uknown-pseudo:focus'} `('should generate "$after" from "$before"', ({ before, after }) => { expect(applyImportantSelector(before, '#app')).toEqual(after) })