mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Make dark and rtl/ltr variants insensitive to DOM order (#10766)
* Make `dark` and `rtl`/`ltr` variants insensitive to DOM order * Add explicit test for stacking dark and rtl variants * Update changelog --------- Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
This commit is contained in:
parent
ba56e426af
commit
e40b73a127
@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- [Oxide] Enable relative content paths for the `oxide` engine ([#10621](https://github.com/tailwindlabs/tailwindcss/pull/10621))
|
||||
- Mark `rtl` and `ltr` variants as stable and remove warnings ([#10764](https://github.com/tailwindlabs/tailwindcss/pull/10764))
|
||||
- Use `inset` instead of `top`, `right`, `bottom`, and `left` properties ([#10765](https://github.com/tailwindlabs/tailwindcss/pull/10765))
|
||||
- Make `dark` and `rtl`/`ltr` variants insensitive to DOM order ([#10766](https://github.com/tailwindlabs/tailwindcss/pull/10766))
|
||||
|
||||
## [3.2.7] - 2023-02-16
|
||||
|
||||
|
||||
@ -199,8 +199,8 @@ export let variantPlugins = {
|
||||
},
|
||||
|
||||
directionVariants: ({ addVariant }) => {
|
||||
addVariant('ltr', '[dir="ltr"] &')
|
||||
addVariant('rtl', '[dir="rtl"] &')
|
||||
addVariant('ltr', ':is([dir="ltr"] &)')
|
||||
addVariant('rtl', ':is([dir="rtl"] &)')
|
||||
},
|
||||
|
||||
reducedMotionVariants: ({ addVariant }) => {
|
||||
@ -221,7 +221,7 @@ export let variantPlugins = {
|
||||
}
|
||||
|
||||
if (mode === 'class') {
|
||||
addVariant('dark', `${className} &`)
|
||||
addVariant('dark', `:is(${className} &)`)
|
||||
} else if (mode === 'media') {
|
||||
addVariant('dark', '@media (prefers-color-scheme: dark)')
|
||||
}
|
||||
|
||||
@ -216,14 +216,14 @@ crosscheck(({ stable, oxide }) => {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
.dark .apply-dark-variant {
|
||||
:is(.dark .apply-dark-variant) {
|
||||
text-align: center;
|
||||
}
|
||||
.dark .apply-dark-variant:hover {
|
||||
:is(.dark .apply-dark-variant:hover) {
|
||||
text-align: right;
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.dark .apply-dark-variant {
|
||||
:is(.dark .apply-dark-variant) {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
@ -513,14 +513,14 @@ crosscheck(({ stable, oxide }) => {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
.dark .apply-dark-variant {
|
||||
:is(.dark .apply-dark-variant) {
|
||||
text-align: center;
|
||||
}
|
||||
.dark .apply-dark-variant:hover {
|
||||
:is(.dark .apply-dark-variant:hover) {
|
||||
text-align: right;
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.dark .apply-dark-variant {
|
||||
:is(.dark .apply-dark-variant) {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ crosscheck(() => {
|
||||
.group:hover .group-hover_focus-within_text-left:focus-within {
|
||||
text-align: left;
|
||||
}
|
||||
[dir='rtl'] .rtl_active_text-center:active {
|
||||
:is([dir='rtl'] .rtl_active_text-center:active) {
|
||||
text-align: center;
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
@ -31,7 +31,7 @@ crosscheck(() => {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.dark .dark_focus_text-left:focus {
|
||||
:is(.dark .dark_focus_text-left:focus) {
|
||||
text-align: left;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
|
||||
@ -17,7 +17,7 @@ crosscheck(() => {
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
${defaults}
|
||||
.dark .dark\:font-bold {
|
||||
:is(.dark .dark\:font-bold) {
|
||||
font-weight: 700;
|
||||
}
|
||||
`)
|
||||
@ -40,7 +40,7 @@ crosscheck(() => {
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
${defaults}
|
||||
.test-dark .dark\:font-bold {
|
||||
:is(.test-dark .dark\:font-bold) {
|
||||
font-weight: 700;
|
||||
}
|
||||
`)
|
||||
|
||||
@ -138,7 +138,7 @@ crosscheck(() => {
|
||||
.group:hover .group-hover\:focus-within\:text-left:focus-within {
|
||||
text-align: left !important;
|
||||
}
|
||||
[dir='rtl'] .rtl\:active\:text-center:active {
|
||||
:is([dir='rtl'] .rtl\:active\:text-center:active) {
|
||||
text-align: center !important;
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
@ -146,7 +146,7 @@ crosscheck(() => {
|
||||
text-align: center !important;
|
||||
}
|
||||
}
|
||||
.dark .dark\:focus\:text-left:focus {
|
||||
:is(.dark .dark\:focus\:text-left:focus) {
|
||||
text-align: left !important;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
|
||||
@ -134,7 +134,7 @@ crosscheck(() => {
|
||||
#app .group:hover .group-hover\:focus-within\:text-left:focus-within {
|
||||
text-align: left;
|
||||
}
|
||||
#app [dir='rtl'] .rtl\:active\:text-center:active {
|
||||
#app :is([dir='rtl'] .rtl\:active\:text-center:active) {
|
||||
text-align: center;
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
@ -142,7 +142,7 @@ crosscheck(() => {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
#app .dark .dark\:focus\:text-left:focus {
|
||||
#app :is(.dark .dark\:focus\:text-left:focus) {
|
||||
text-align: left;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
|
||||
@ -303,7 +303,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
}
|
||||
.drop-empty-rules:hover,
|
||||
.group:hover .apply-group,
|
||||
.dark .apply-dark-mode {
|
||||
:is(.dark .apply-dark-mode) {
|
||||
font-weight: 700;
|
||||
}
|
||||
.apply-with-existing:hover {
|
||||
@ -338,7 +338,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
.apply-order-b {
|
||||
margin: 1.5rem 1.25rem 1.25rem;
|
||||
}
|
||||
.dark .group:hover .apply-dark-group-example-a {
|
||||
:is(.dark .group:hover .apply-dark-group-example-a) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
|
||||
}
|
||||
@ -715,7 +715,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
}
|
||||
.dark .dark\:custom-util {
|
||||
:is(.dark .dark\:custom-util) {
|
||||
background: #abcdef;
|
||||
}
|
||||
@media (min-width: 640px) {
|
||||
@ -762,7 +762,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
transition-duration: 0.15s;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active {
|
||||
:is(.dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active) {
|
||||
background: #abcdef !important;
|
||||
}
|
||||
}
|
||||
@ -849,7 +849,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
}
|
||||
.drop-empty-rules:hover,
|
||||
.group:hover .apply-group,
|
||||
.dark .apply-dark-mode {
|
||||
:is(.dark .apply-dark-mode) {
|
||||
font-weight: 700;
|
||||
}
|
||||
.apply-with-existing:hover {
|
||||
@ -883,7 +883,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
.apply-order-b {
|
||||
margin: 1.5rem 1.25rem 1.25rem;
|
||||
}
|
||||
.dark .group:hover .apply-dark-group-example-a {
|
||||
:is(.dark .group:hover .apply-dark-group-example-a) {
|
||||
background-color: #22c55e;
|
||||
}
|
||||
@media (min-width: 640px) {
|
||||
@ -1250,7 +1250,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
}
|
||||
.dark .dark\:custom-util {
|
||||
:is(.dark .dark\:custom-util) {
|
||||
background: #abcdef;
|
||||
}
|
||||
@media (min-width: 640px) {
|
||||
@ -1297,7 +1297,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
transition-duration: 0.15s;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active {
|
||||
:is(.dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active) {
|
||||
background: #abcdef !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
.custom-component {
|
||||
font-weight: 700;
|
||||
}
|
||||
.tw-dark .tw-group:hover .custom-component {
|
||||
:is(.tw-dark .tw-group:hover .custom-component) {
|
||||
font-weight: 400;
|
||||
}
|
||||
.tw--ml-4 {
|
||||
@ -155,7 +155,7 @@ crosscheck(({ stable, oxide }) => {
|
||||
.tw-group:hover .group-hover\:focus-within\:tw-text-left:focus-within {
|
||||
text-align: left;
|
||||
}
|
||||
[dir='rtl'] .rtl\:active\:tw-text-center:active {
|
||||
:is([dir='rtl'] .rtl\:active\:tw-text-center:active) {
|
||||
text-align: center;
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
@ -163,11 +163,11 @@ crosscheck(({ stable, oxide }) => {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.tw-dark .dark\:tw-bg-\[rgb\(255\,0\,0\)\] {
|
||||
:is(.tw-dark .dark\:tw-bg-\[rgb\(255\,0\,0\)\]) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
|
||||
}
|
||||
.tw-dark .dark\:focus\:tw-text-left:focus {
|
||||
:is(.tw-dark .dark\:focus\:tw-text-left:focus) {
|
||||
text-align: left;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
|
||||
@ -283,8 +283,8 @@
|
||||
.peer:disabled ~ .peer-disabled\:shadow-md,
|
||||
.peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:shadow-md,
|
||||
.peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:first\:shadow-md:first-child,
|
||||
[dir="ltr"] .ltr\:shadow-md,
|
||||
[dir="rtl"] .rtl\:shadow-md {
|
||||
:is([dir='ltr'] .ltr\:shadow-md),
|
||||
:is([dir='rtl'] .rtl\:shadow-md) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
@ -318,9 +318,9 @@
|
||||
background-color: #fde047;
|
||||
}
|
||||
}
|
||||
.dark .dark\:shadow-md,
|
||||
.dark .group:disabled:focus:hover .dark\:group-disabled\:group-focus\:group-hover\:shadow-md,
|
||||
.dark .peer:disabled:focus:hover ~ .dark\:peer-disabled\:peer-focus\:peer-hover\:shadow-md {
|
||||
:is(.dark .dark\:shadow-md),
|
||||
:is(.dark .group:disabled:focus:hover .dark\:group-disabled\:group-focus\:group-hover\:shadow-md),
|
||||
:is(.dark .peer:disabled:focus:hover ~ .dark\:peer-disabled\:peer-focus\:peer-hover\:shadow-md) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
@ -361,7 +361,7 @@
|
||||
animation: 1s linear infinite spin;
|
||||
}
|
||||
.lg\:shadow-md,
|
||||
.dark .lg\:dark\:shadow-md {
|
||||
:is(.dark .lg\:dark\:shadow-md) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
|
||||
0 2px 4px -2px var(--tw-shadow-color);
|
||||
@ -371,7 +371,7 @@
|
||||
}
|
||||
@media (min-width: 1280px) {
|
||||
.xl\:shadow-md,
|
||||
.dark .xl\:dark\:disabled\:shadow-md:disabled {
|
||||
:is(.dark .xl\:dark\:disabled\:shadow-md:disabled) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
|
||||
0 2px 4px -2px var(--tw-shadow-color);
|
||||
@ -388,7 +388,7 @@
|
||||
var(--tw-shadow);
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.dark .\32 xl\:dark\:motion-safe\:focus-within\:shadow-md:focus-within {
|
||||
:is(.dark .\32 xl\:dark\:motion-safe\:focus-within\:shadow-md:focus-within) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
|
||||
0 2px 4px -2px var(--tw-shadow-color);
|
||||
@ -407,4 +407,3 @@
|
||||
background-color: #fde047;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -299,8 +299,8 @@
|
||||
.peer:disabled ~ .peer-disabled\:shadow-md,
|
||||
.peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:shadow-md,
|
||||
.peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:first\:shadow-md:first-child,
|
||||
[dir='ltr'] .ltr\:shadow-md,
|
||||
[dir='rtl'] .rtl\:shadow-md {
|
||||
:is([dir='ltr'] .ltr\:shadow-md),
|
||||
:is([dir='rtl'] .rtl\:shadow-md) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
@ -336,9 +336,9 @@
|
||||
background-color: rgb(253 224 71 / var(--tw-bg-opacity));
|
||||
}
|
||||
}
|
||||
.dark .dark\:shadow-md,
|
||||
.dark .group:disabled:focus:hover .dark\:group-disabled\:group-focus\:group-hover\:shadow-md,
|
||||
.dark .peer:disabled:focus:hover ~ .dark\:peer-disabled\:peer-focus\:peer-hover\:shadow-md {
|
||||
:is(.dark .dark\:shadow-md),
|
||||
:is(.dark .group:disabled:focus:hover .dark\:group-disabled\:group-focus\:group-hover\:shadow-md),
|
||||
:is(.dark .peer:disabled:focus:hover ~ .dark\:peer-disabled\:peer-focus\:peer-hover\:shadow-md) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
|
||||
@ -380,7 +380,7 @@
|
||||
animation: 1s linear infinite spin;
|
||||
}
|
||||
.lg\:shadow-md,
|
||||
.dark .lg\:dark\:shadow-md {
|
||||
:is(.dark .lg\:dark\:shadow-md) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
|
||||
0 2px 4px -2px var(--tw-shadow-color);
|
||||
@ -390,7 +390,7 @@
|
||||
}
|
||||
@media (min-width: 1280px) {
|
||||
.xl\:shadow-md,
|
||||
.dark .xl\:dark\:disabled\:shadow-md:disabled {
|
||||
:is(.dark .xl\:dark\:disabled\:shadow-md:disabled) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
|
||||
0 2px 4px -2px var(--tw-shadow-color);
|
||||
@ -407,7 +407,7 @@
|
||||
var(--tw-shadow);
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.dark .\32 xl\:dark\:motion-safe\:focus-within\:shadow-md:focus-within {
|
||||
:is(.dark .\32 xl\:dark\:motion-safe\:focus-within\:shadow-md:focus-within) {
|
||||
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
|
||||
0 2px 4px -2px var(--tw-shadow-color);
|
||||
|
||||
@ -1128,4 +1128,28 @@ crosscheck(({ stable, oxide }) => {
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
test('stacking dark and rtl variants', async () => {
|
||||
let config = {
|
||||
darkMode: 'class',
|
||||
content: [
|
||||
{
|
||||
raw: html` <div class="dark:rtl:italic" /> `,
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
let result = await run(input, config)
|
||||
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
:is(.dark :is([dir='rtl'] .dark\:rtl\:italic)) {
|
||||
font-style: italic;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user