@@ -16,7 +16,7 @@ export function isSimpleSelectorKey(key: string) {
1616}
1717
1818export function nestedSelectorKey ( key : string , context : TransformContext ) {
19- const parentSelectors = context . parentSelector . split ( "," ) ;
19+ const parentSelectors = splitSelector ( context . parentSelector ) ;
2020 const result = [ ] ;
2121
2222 const parentSelectorsLength = parentSelectors . length ;
@@ -29,6 +29,58 @@ export function nestedSelectorKey(key: string, context: TransformContext) {
2929 return result . join ( ", " ) ;
3030}
3131
32+ function splitSelector ( selector : string ) : string [ ] {
33+ if ( ! selector . includes ( "," ) ) {
34+ return [ selector ] ;
35+ }
36+
37+ const result = [ ] ;
38+ let currentSelector = "" ;
39+ let parenLevel = 0 ;
40+ let bracketLevel = 0 ;
41+
42+ const selectorLength = selector . length ;
43+ for ( let i = 0 ; i < selectorLength ; i ++ ) {
44+ const char = selector [ i ] ;
45+
46+ switch ( char ) {
47+ case "(" :
48+ parenLevel ++ ;
49+ currentSelector += char ;
50+ break ;
51+ case ")" :
52+ parenLevel -- ;
53+ currentSelector += char ;
54+ break ;
55+ case "[" :
56+ bracketLevel ++ ;
57+ currentSelector += char ;
58+ break ;
59+ case "]" :
60+ bracketLevel -- ;
61+ currentSelector += char ;
62+ break ;
63+ case "," :
64+ if ( parenLevel === 0 && bracketLevel === 0 ) {
65+ result . push ( currentSelector ) ;
66+ currentSelector = "" ;
67+ } else {
68+ currentSelector += char ;
69+ }
70+ break ;
71+ default :
72+ currentSelector += char ;
73+ break ;
74+ }
75+ }
76+
77+ if ( currentSelector . trim ( ) !== "" ) {
78+ result . push ( currentSelector ) ;
79+ }
80+
81+ return result ;
82+ }
83+
3284// == Tests ====================================================================
3385// Ignore errors when compiling to CommonJS.
3486// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -88,5 +140,18 @@ if (import.meta.vitest) {
88140 ":root[dir=rtl] nav li > &, :root[dir=rtl] .myClass > &[data-attr-value]"
89141 ) ;
90142 } ) ;
143+
144+ it ( "Complex Nested Selectors" , ( ) => {
145+ const context : TransformContext = {
146+ ...structuredClone ( initTransformContext ) ,
147+ parentSelector : `nav li > &:hover:not(:active, :disabled, [data-list="a, b, c"]), .myClass > &[data-attr-value]:where(:has(> :hover, + :focus), :active)`
148+ } ;
149+ expect ( nestedSelectorKey ( "&::before" , context ) ) . toBe (
150+ `nav li > &:hover:not(:active, :disabled, [data-list="a, b, c"])::before, .myClass > &[data-attr-value]:where(:has(> :hover, + :focus), :active)::before`
151+ ) ;
152+ expect ( nestedSelectorKey ( ":root[dir=rtl] &" , context ) ) . toBe (
153+ `:root[dir=rtl] nav li > &:hover:not(:active, :disabled, [data-list="a, b, c"]), :root[dir=rtl] .myClass > &[data-attr-value]:where(:has(> :hover, + :focus), :active)`
154+ ) ;
155+ } ) ;
91156 } ) ;
92157}
0 commit comments