Skip to content

Commit 7377102

Browse files
committed
Update important selector handling for :is and :has
1 parent 8589ab8 commit 7377102

File tree

2 files changed

+30
-11
lines changed

2 files changed

+30
-11
lines changed

src/util/applyImportantSelector.js

+23-11
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,31 @@
11
import { splitAtTopLevelOnly } from './splitAtTopLevelOnly'
2+
import parser from 'postcss-selector-parser'
3+
import { collectPseudoElements, sortSelector } from './formatVariantSelector.js'
24

35
export function applyImportantSelector(selector, important) {
4-
let matches = /^(.*?)(:before|:after|::[\w-]+)(\)*)$/g.exec(selector)
5-
if (!matches) return `${important} ${wrapWithIs(selector)}`
6+
let sel = parser().astSync(selector)
67

7-
let [, before, pseudo, brackets] = matches
8-
return `${important} ${wrapWithIs(before + brackets)}${pseudo}`
9-
}
8+
sel.each((sel) => {
9+
// Wrap with :is if it's not already wrapped
10+
let isWrapped =
11+
sel.nodes[0].type === 'pseudo' &&
12+
sel.nodes[0].value === ':is' &&
13+
sel.nodes.every((node) => node.type !== 'combinator')
1014

11-
function wrapWithIs(selector) {
12-
let parts = splitAtTopLevelOnly(selector, ' ')
15+
if (!isWrapped) {
16+
sel.nodes = [
17+
parser.pseudo({
18+
value: ':is',
19+
nodes: [sel.clone()],
20+
}),
21+
]
22+
}
1323

14-
if (parts.length === 1 && parts[0].startsWith(':is(') && parts[0].endsWith(')')) {
15-
return selector
16-
}
24+
let [pseudoElements] = collectPseudoElements(sel)
25+
if (pseudoElements.length > 0) {
26+
sel.nodes.push(...pseudoElements.sort(sortSelector))
27+
}
28+
})
1729

18-
return `:is(${selector})`
30+
return `${important} ${sel.toString()}`
1931
}

tests/important-selector.test.js

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ crosscheck(({ stable, oxide }) => {
2121
<div class="group-hover:focus-within:text-left"></div>
2222
<div class="rtl:active:text-center"></div>
2323
<div class="dark:before:underline"></div>
24+
<div class="hover:[&::file-selector-button]:rtl:dark:bg-black/100"></div>
2425
`,
2526
},
2627
],
@@ -155,6 +156,12 @@ crosscheck(({ stable, oxide }) => {
155156
text-align: right;
156157
}
157158
}
159+
#app
160+
:is(
161+
[dir='rtl'] :is(.dark .hover\:\[\&\:\:file-selector-button\]\:rtl\:dark\:bg-black\/100)
162+
)::file-selector-button:hover {
163+
background-color: #000;
164+
}
158165
`)
159166
})
160167
})

0 commit comments

Comments
 (0)