Skip to content

Commit

Permalink
Only sort pseudo elements after classes when using @apply and varia…
Browse files Browse the repository at this point in the history
…nts (#9765)

* Sort pseudo elements ONLY after classes

* Update changelog
  • Loading branch information
thecrypticace committed Nov 9, 2022
1 parent aac468c commit 6bd9912
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fixed use of `raw` content in the CLI ([#9773](https://github.com/tailwindlabs/tailwindcss/pull/9773))
- Pick up changes from files that are both context and content deps ([#9787](https://github.com/tailwindlabs/tailwindcss/pull/9787))
- Sort pseudo-elements ONLY after classes when using variants and `@apply` ([#9765](https://github.com/tailwindlabs/tailwindcss/pull/9765))

## [3.2.2] - 2022-11-04

Expand Down
4 changes: 2 additions & 2 deletions src/lib/expandApplyAtRules.js
Expand Up @@ -370,9 +370,9 @@ function processApply(root, context, localCache) {
return -1
} else if (a.type === 'class' && b.type === 'tag') {
return 1
} else if (a.type === 'class' && b.type === 'pseudo') {
} else if (a.type === 'class' && b.type === 'pseudo' && b.value.startsWith('::')) {
return -1
} else if (a.type === 'pseudo' && b.type === 'class') {
} else if (a.type === 'pseudo' && a.value.startsWith('::') && b.type === 'class') {
return 1
}

Expand Down
4 changes: 2 additions & 2 deletions src/util/formatVariantSelector.js
Expand Up @@ -69,9 +69,9 @@ function resortSelector(sel) {
return -1
} else if (a.type === 'class' && b.type === 'tag') {
return 1
} else if (a.type === 'class' && b.type === 'pseudo' && b.value !== ':merge') {
} else if (a.type === 'class' && b.type === 'pseudo' && b.value.startsWith('::')) {
return -1
} else if (a.type === 'pseudo' && a.value !== ':merge' && b.type === 'class') {
} else if (a.type === 'pseudo' && a.value.startsWith('::') && b.type === 'class') {
return 1
}

Expand Down
19 changes: 11 additions & 8 deletions tests/apply.test.js
Expand Up @@ -1601,6 +1601,9 @@ it('can apply joined classes when using elements', async () => {
header:nth-of-type(odd) {
@apply foo;
}
header::after {
@apply foo;
}
main {
@apply foo bar;
}
Expand All @@ -1618,7 +1621,13 @@ it('can apply joined classes when using elements', async () => {
.bar.foo {
color: green;
}
header:nth-of-type(odd).bar {
color: red;
}
header.bar:nth-of-type(odd) {
color: green;
}
header.bar::after {
color: red;
color: green;
}
Expand Down Expand Up @@ -1721,21 +1730,15 @@ it('should maintain the correct selector when applying other utilities', () => {

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.foo.bar:hover .baz {
.foo:hover.bar .baz {
--tw-bg-opacity: 1;
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
.foo:hover.bar .baz {
color: red;
}
.foo.bar:hover > .baz {
.foo:hover.bar > .baz {
--tw-bg-opacity: 1;
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
.foo:hover.bar > .baz {
color: red;
}
`)
Expand Down
40 changes: 35 additions & 5 deletions tests/variants.test.js
Expand Up @@ -861,12 +861,12 @@ test('multi-class utilities handle selector-mutating variants correctly', () =>
content: [
{
raw: html`<div
class="hover:foo hover:bar hover:baz group-hover:foo group-hover:bar group-hover:baz peer-checked:foo peer-checked:bar peer-checked:baz"
class="after:foo after:bar after:baz hover:foo hover:bar hover:baz group-hover:foo group-hover:bar group-hover:baz peer-checked:foo peer-checked:bar peer-checked:baz"
></div>`,
},
{
raw: html`<div
class="hover:foo1 hover:bar1 hover:baz1 group-hover:foo1 group-hover:bar1 group-hover:baz1 peer-checked:foo1 peer-checked:bar1 peer-checked:baz1"
class="after:foo1 after:bar1 after:baz1 hover:foo1 hover:bar1 hover:baz1 group-hover:foo1 group-hover:bar1 group-hover:baz1 peer-checked:foo1 peer-checked:bar1 peer-checked:baz1"
></div>`,
},
],
Expand All @@ -885,15 +885,45 @@ test('multi-class utilities handle selector-mutating variants correctly', () =>
}
`

// The second set of ::after cases (w/ descendant selectors)
// are clearly "wrong" BUT you can't have a descendant of a
// pseudo - element so the utilities `after:foo1` and
// `after:bar1` are non-sensical so this is still
// perfectly fine behavior

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.hover\:foo.bar.baz:hover {
.after\:foo.bar.baz::after {
content: var(--tw-content);
color: red;
}
.after\:bar.foo.baz::after {
content: var(--tw-content);
color: red;
}
.after\:baz.foo.bar::after {
content: var(--tw-content);
color: red;
}
.after\:foo1 .bar1 .baz1::after {
content: var(--tw-content);
color: red;
}
.foo1 .after\:bar1 .baz1::after {
content: var(--tw-content);
color: red;
}
.foo1 .bar1 .after\:baz1::after {
content: var(--tw-content);
color: red;
}
.hover\:foo:hover.bar.baz {
color: red;
}
.hover\:bar.foo.baz:hover {
.hover\:bar:hover.foo.baz {
color: red;
}
.hover\:baz.foo.bar:hover {
.hover\:baz:hover.foo.bar {
color: red;
}
.hover\:foo1:hover .bar1 .baz1 {
Expand Down

0 comments on commit 6bd9912

Please sign in to comment.