Skip to content

Commit 0762081

Browse files
committed
fix: merge with existing className non-string literal value (fixes #20)
1 parent 6096c7e commit 0762081

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

src/replaceJsxExpressionContainer.js

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
// @flow
22

33
import BabelTypes, {
4+
binaryExpression,
5+
Identifier,
6+
isJSXExpressionContainer,
7+
isStringLiteral,
8+
jSXAttribute,
49
JSXAttribute,
5-
Identifier
10+
jSXExpressionContainer,
11+
jSXIdentifier,
12+
stringLiteral
613
} from 'babel-types';
714

815
export default (
@@ -17,12 +24,13 @@ export default (
1724
.find((attribute) => {
1825
return typeof attribute.name !== 'undefined' && attribute.name.name === 'className';
1926
});
20-
const classNameAttributeValue = classNameAttribute ? classNameAttribute.value.value : '';
2127

2228
if (classNameAttribute) {
2329
path.node.openingElement.attributes.splice(path.node.openingElement.attributes.indexOf(classNameAttribute), 1);
2430
}
2531

32+
path.node.openingElement.attributes.splice(path.node.openingElement.attributes.indexOf(styleNameAttribute), 1);
33+
2634
const styleNameExpression = t.callExpression(
2735
importedHelperIndentifier,
2836
[
@@ -31,13 +39,42 @@ export default (
3139
]
3240
);
3341

34-
styleNameAttribute.value = t.jSXExpressionContainer(
35-
classNameAttribute ?
36-
t.binaryExpression(
37-
'+',
38-
t.stringLiteral(classNameAttributeValue + ' '),
42+
if (classNameAttribute) {
43+
if (isStringLiteral(classNameAttribute.value)) {
44+
path.node.openingElement.attributes.push(jSXAttribute(
45+
jSXIdentifier('className'),
46+
jSXExpressionContainer(
47+
binaryExpression(
48+
'+',
49+
t.stringLiteral(classNameAttribute.value.value + ' '),
50+
styleNameExpression
51+
)
52+
)
53+
));
54+
} else if (isJSXExpressionContainer(classNameAttribute.value)) {
55+
path.node.openingElement.attributes.push(jSXAttribute(
56+
jSXIdentifier('className'),
57+
jSXExpressionContainer(
58+
binaryExpression(
59+
'+',
60+
classNameAttribute.value.expression,
61+
binaryExpression(
62+
'+',
63+
stringLiteral(' '),
64+
styleNameExpression
65+
)
66+
)
67+
)
68+
));
69+
} else {
70+
throw new Error('Unexpected attribute value.');
71+
}
72+
} else {
73+
path.node.openingElement.attributes.push(jSXAttribute(
74+
jSXIdentifier('className'),
75+
jSXExpressionContainer(
3976
styleNameExpression
40-
) : styleNameExpression
41-
);
42-
styleNameAttribute.name.name = 'className';
77+
)
78+
));
79+
}
4380
};

src/resolveStringLiteral.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
// @flow
22

33
import {
4-
JSXAttribute
4+
binaryExpression,
5+
isJSXExpressionContainer,
6+
isStringLiteral,
7+
JSXAttribute,
8+
stringLiteral
59
} from 'babel-types';
610
import getClassName from './getClassName';
711
import type {
@@ -20,7 +24,17 @@ export default (path: Object, styleModuleImportMap: StyleModuleImportMapType, st
2024
const resolvedStyleName = getClassName(styleNameAttribute.value.value, styleModuleImportMap);
2125

2226
if (classNameAttribute) {
23-
classNameAttribute.value.value += ' ' + resolvedStyleName;
27+
if (isStringLiteral(classNameAttribute.value)) {
28+
classNameAttribute.value.value += ' ' + resolvedStyleName;
29+
} else if (isJSXExpressionContainer(classNameAttribute.value)) {
30+
classNameAttribute.value.expression = binaryExpression(
31+
'+',
32+
classNameAttribute.value.expression,
33+
stringLiteral(' ' + resolvedStyleName)
34+
);
35+
} else {
36+
throw new Error('Unexpected attribute value.');
37+
}
2438

2539
path.node.openingElement.attributes.splice(path.node.openingElement.attributes.indexOf(styleNameAttribute), 1);
2640
} else {
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
import './bar.css';
22

33
<div className='apple banana' styleName="a"></div>;
4+
5+
<div className={this.props.className} styleName="a"></div>;
6+
7+
<div className={Math.random() > 0.5 ? 'apple' : 'banana'} styleName="a"></div>;
8+
9+
<div className={this.props.className} styleName={foo}></div>;
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
import _getClassName from 'babel-plugin-react-css-modules/dist/browser/getClassName';
12
import './bar.css';
23

4+
const _styleModuleImportMap = {
5+
'random-test': {
6+
'a': 'bar__a'
7+
}
8+
};
39
<div className="apple banana bar__a"></div>;
10+
11+
<div className={this.props.className + ' bar__a'}></div>;
12+
13+
<div className={(Math.random() > 0.5 ? 'apple' : 'banana') + ' bar__a'}></div>;
14+
15+
<div className={this.props.className + (' ' + _getClassName(foo, _styleModuleImportMap))}></div>;

0 commit comments

Comments
 (0)