Skip to content

Commit 4e87ad7

Browse files
committed
fix(convertCssToJss): fix multiple class references out-of-order
fix #12
1 parent 6506380 commit 4e87ad7

File tree

2 files changed

+63
-21
lines changed

2 files changed

+63
-21
lines changed

src/convertCssToJss.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,15 @@ export function splitGlobals(selector: string): [string | null, string | null] {
117117
export function convertSelectors(root: ObjectExpression): void {
118118
const replacements: Map<string, string> = new Map()
119119

120-
const processClasses = root => {
120+
const processClassesSelector = selectorParser(root => {
121121
root.walkClasses(classNode => {
122122
if (!classNode.value) return
123123
const replacement = replacements.get(classNode.value)
124124
if (replacement) {
125125
classNode.replaceWith(selectorParser.tag({ value: replacement }))
126126
}
127127
})
128-
}
128+
})
129129

130130
const processRootSelector = selectorParser(root => {
131131
if (root.length !== 1) return
@@ -139,8 +139,6 @@ export function convertSelectors(root: ObjectExpression): void {
139139
const replacement = camelCase(className)
140140
replacements.set(className, `$${replacement}`)
141141
first.first.replaceWith(selectorParser.tag({ value: replacement }))
142-
} else {
143-
processClasses(root)
144142
}
145143
})
146144

@@ -151,18 +149,12 @@ export function convertSelectors(root: ObjectExpression): void {
151149
node.insertBefore(node.at(0), selectorParser.nesting({}))
152150
}
153151
})
154-
processClasses(root)
155-
})
156-
157-
const processSelectorInMediaOrGlobal = selectorParser(root => {
158-
processClasses(root)
159152
})
160153

161154
const processNode = (
162155
parentKey: string | null,
163156
node: ObjectExpression
164157
): void => {
165-
debugger
166158
const globals: ObjectProperty[] = []
167159
if (!parentKey || !/^@(keyframes|global)/.test(parentKey)) {
168160
node.properties = node.properties.filter(
@@ -179,24 +171,20 @@ export function convertSelectors(root: ObjectExpression): void {
179171
if (newKey !== key) prop.key = objectPropertyKey(newKey)
180172
}
181173
} else {
182-
if (localSelector) {
183-
const replaced =
184-
parentKey.startsWith('@media') || parentKey === '@global'
185-
? processSelectorInMediaOrGlobal.processSync(localSelector)
186-
: processSelector.processSync(localSelector)
174+
if (
175+
localSelector &&
176+
!parentKey.startsWith('@media') &&
177+
parentKey !== '@global'
178+
) {
179+
const replaced = processSelector.processSync(localSelector)
187180
if (replaced !== key) {
188181
prop.key = objectPropertyKey(replaced)
189182
}
190183
}
191184
}
192185
if (globalSelector) {
193186
globals.push(
194-
j.objectProperty(
195-
objectPropertyKey(
196-
processSelectorInMediaOrGlobal.processSync(globalSelector)
197-
),
198-
value
199-
)
187+
j.objectProperty(objectPropertyKey(globalSelector), value)
200188
)
201189
}
202190
return localSelector != null
@@ -219,8 +207,23 @@ export function convertSelectors(root: ObjectExpression): void {
219207
processNode(key, value)
220208
}
221209
}
210+
const processClasses = (node: ObjectExpression): void => {
211+
for (const prop of node.properties) {
212+
if (prop.type !== 'ObjectProperty') continue
213+
const { value } = prop
214+
const key = getRawKey(prop.key)
215+
if (!key || value.type !== 'ObjectExpression') continue
216+
const [localSelector] = splitGlobals(key)
217+
if (localSelector) {
218+
const newKey = processClassesSelector.processSync(localSelector)
219+
if (newKey !== key) prop.key = objectPropertyKey(newKey)
220+
}
222221

222+
processClasses(value)
223+
}
224+
}
223225
processNode(null, root)
226+
processClasses(root)
224227
}
225228

226229
export function convertAnimationNames(
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
export const input = `
2+
const styles = {
3+
/* selectionStart */
4+
.button:hover {
5+
border: 1px solid blue;
6+
box-shadow: 0 0 0 10px blue, 0 0 0 15px green;
7+
}
8+
.button {
9+
border: none;
10+
margin: 5px 10px;
11+
font-size: 12px;
12+
background: white contain no-repeat;
13+
transition: background color font-size;
14+
line-height: 1;
15+
transition-duration: 300ms;
16+
}
17+
/* selectionEnd */
18+
}
19+
`
20+
21+
export const options = {}
22+
23+
export const expected = `
24+
const styles = {
25+
'$button:hover': {
26+
border: '1px solid blue',
27+
boxShadow: '0 0 0 10px blue, 0 0 0 15px green'
28+
},
29+
button: {
30+
border: 'none',
31+
margin: '5px 10px',
32+
fontSize: 12,
33+
background: 'white contain no-repeat',
34+
transition: 'background color font-size',
35+
lineHeight: '1',
36+
transitionDuration: 300
37+
},
38+
}
39+
`

0 commit comments

Comments
 (0)