Skip to content

Commit 0533619

Browse files
committed
Escape variant modifiers when used in selectors and at-rules
1 parent dc6a3ce commit 0533619

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

packages/tailwindcss/src/variants.test.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,11 +586,13 @@ test('group-*', async () => {
586586

587587
'group-hover:group-focus:flex',
588588
'group-focus:group-hover:flex',
589+
590+
'group-hover/foo+bar:flex',
589591
],
590592
),
591593
).toMatchInlineSnapshot(`
592594
"@media (hover: hover) {
593-
.group-hover\\:flex:is(:where(.group):hover *) {
595+
.group-hover\\:flex:is(:where(.group):hover *), .group-hover\\/foo\\+bar\\:flex:is(:where(.group\\/foo\\+bar):hover *) {
594596
display: flex;
595597
}
596598
}
@@ -677,11 +679,13 @@ test('peer-*', async () => {
677679
'peer-hocus:flex',
678680
'peer-hover:peer-focus:flex',
679681
'peer-focus:peer-hover:flex',
682+
683+
'peer-hover/foo+bar:flex',
680684
],
681685
),
682686
).toMatchInlineSnapshot(`
683687
"@media (hover: hover) {
684-
.peer-hover\\:flex:is(:where(.peer):hover ~ *) {
688+
.peer-hover\\:flex:is(:where(.peer):hover ~ *), .peer-hover\\/foo\\+bar\\:flex:is(:where(.peer\\/foo\\+bar):hover ~ *) {
685689
display: flex;
686690
}
687691
}
@@ -2081,20 +2085,23 @@ test('container queries', async () => {
20812085
[
20822086
'@lg:flex',
20832087
'@lg/name:flex',
2088+
'@lg/foo+bar:flex',
20842089
'@[123px]:flex',
20852090
'@[456px]/name:flex',
20862091
'@foo-bar:flex',
20872092
'@foo-bar/name:flex',
20882093

20892094
'@min-lg:flex',
20902095
'@min-lg/name:flex',
2096+
'@min-lg/foo+bar:flex',
20912097
'@min-[123px]:flex',
20922098
'@min-[456px]/name:flex',
20932099
'@min-foo-bar:flex',
20942100
'@min-foo-bar/name:flex',
20952101

20962102
'@max-lg:flex',
20972103
'@max-lg/name:flex',
2104+
'@max-lg/foo+bar:flex',
20982105
'@max-[123px]:flex',
20992106
'@max-[456px]/name:flex',
21002107
'@max-foo-bar:flex',
@@ -2114,6 +2121,12 @@ test('container queries', async () => {
21142121
}
21152122
}
21162123
2124+
@container foo\\+bar not (min-width: 1024px) {
2125+
.\\@max-lg\\/foo\\+bar\\:flex {
2126+
display: flex;
2127+
}
2128+
}
2129+
21172130
@container name not (min-width: 1024px) {
21182131
.\\@max-lg\\/name\\:flex {
21192132
display: flex;
@@ -2150,6 +2163,12 @@ test('container queries', async () => {
21502163
}
21512164
}
21522165
2166+
@container foo\\+bar (min-width: 1024px) {
2167+
.\\@lg\\/foo\\+bar\\:flex {
2168+
display: flex;
2169+
}
2170+
}
2171+
21532172
@container name (min-width: 1024px) {
21542173
.\\@lg\\/name\\:flex {
21552174
display: flex;
@@ -2162,6 +2181,12 @@ test('container queries', async () => {
21622181
}
21632182
}
21642183
2184+
@container foo\\+bar (min-width: 1024px) {
2185+
.\\@min-lg\\/foo\\+bar\\:flex {
2186+
display: flex;
2187+
}
2188+
}
2189+
21652190
@container name (min-width: 1024px) {
21662191
.\\@min-lg\\/name\\:flex {
21672192
display: flex;

packages/tailwindcss/src/variants.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { DesignSystem } from './design-system'
1717
import type { Theme } from './theme'
1818
import { compareBreakpoints } from './utils/compare-breakpoints'
1919
import { DefaultMap } from './utils/default-map'
20+
import { escape } from './utils/escape'
2021
import { isPositiveInteger } from './utils/infer-data-type'
2122
import { segment } from './utils/segment'
2223
import { walk, WalkAction } from './walk'
@@ -522,7 +523,7 @@ export function createVariants(theme: Theme): Variants {
522523
// Name the group by appending the modifier to `group` class itself if
523524
// present.
524525
let variantSelector = variant.modifier
525-
? `:where(.${theme.prefix ? `${theme.prefix}\\:` : ''}group\\/${variant.modifier.value})`
526+
? `:where(.${theme.prefix ? `${theme.prefix}\\:` : ''}group\\/${escape(variant.modifier.value)})`
526527
: `:where(.${theme.prefix ? `${theme.prefix}\\:` : ''}group)`
527528

528529
let didApply = false
@@ -574,7 +575,7 @@ export function createVariants(theme: Theme): Variants {
574575
// Name the peer by appending the modifier to `peer` class itself if
575576
// present.
576577
let variantSelector = variant.modifier
577-
? `:where(.${theme.prefix ? `${theme.prefix}\\:` : ''}peer\\/${variant.modifier.value})`
578+
? `:where(.${theme.prefix ? `${theme.prefix}\\:` : ''}peer\\/${escape(variant.modifier.value)})`
578579
: `:where(.${theme.prefix ? `${theme.prefix}\\:` : ''}peer)`
579580

580581
let didApply = false
@@ -1063,7 +1064,7 @@ export function createVariants(theme: Theme): Variants {
10631064
atRule(
10641065
'@container',
10651066
variant.modifier
1066-
? `${variant.modifier.value} (width < ${value})`
1067+
? `${escape(variant.modifier.value)} (width < ${value})`
10671068
: `(width < ${value})`,
10681069
ruleNode.nodes,
10691070
),
@@ -1092,7 +1093,7 @@ export function createVariants(theme: Theme): Variants {
10921093
atRule(
10931094
'@container',
10941095
variant.modifier
1095-
? `${variant.modifier.value} (width >= ${value})`
1096+
? `${escape(variant.modifier.value)} (width >= ${value})`
10961097
: `(width >= ${value})`,
10971098
ruleNode.nodes,
10981099
),
@@ -1110,7 +1111,7 @@ export function createVariants(theme: Theme): Variants {
11101111
atRule(
11111112
'@container',
11121113
variant.modifier
1113-
? `${variant.modifier.value} (width >= ${value})`
1114+
? `${escape(variant.modifier.value)} (width >= ${value})`
11141115
: `(width >= ${value})`,
11151116
ruleNode.nodes,
11161117
),

0 commit comments

Comments
 (0)