Skip to content

Commit

Permalink
Update important selector handling for :is and :has
Browse files Browse the repository at this point in the history
  • Loading branch information
thecrypticace committed Mar 29, 2023
1 parent 87aef2f commit 933606a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
34 changes: 23 additions & 11 deletions src/util/applyImportantSelector.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import { splitAtTopLevelOnly } from './splitAtTopLevelOnly'
import parser from 'postcss-selector-parser'
import { collectPseudoElements, sortSelector } from './formatVariantSelector.js'

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

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

function wrapWithIs(selector) {
let parts = splitAtTopLevelOnly(selector, ' ')
if (!isWrapped) {
sel.nodes = [
parser.pseudo({
value: ':is',
nodes: [sel.clone()],
}),
]
}

if (parts.length === 1 && parts[0].startsWith(':is(') && parts[0].endsWith(')')) {
return selector
}
let [pseudoElements] = collectPseudoElements(sel)
if (pseudoElements.length > 0) {
sel.nodes.push(...pseudoElements.sort(sortSelector))
}
})

return `:is(${selector})`
return `${important} ${sel.toString()}`
}
7 changes: 7 additions & 0 deletions tests/important-selector.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ crosscheck(({ stable, oxide }) => {
<div class="group-hover:focus-within:text-left"></div>
<div class="rtl:active:text-center"></div>
<div class="dark:before:underline"></div>
<div class="hover:[&::file-selector-button]:rtl:dark:bg-black/100"></div>
`,
},
],
Expand Down Expand Up @@ -155,6 +156,12 @@ crosscheck(({ stable, oxide }) => {
text-align: right;
}
}
#app
:is(
[dir='rtl'] :is(.dark .hover\:\[\&\:\:file-selector-button\]\:rtl\:dark\:bg-black\/100)
)::file-selector-button:hover {
background-color: #000;
}
`)
})
})
Expand Down

0 comments on commit 933606a

Please sign in to comment.