Skip to content

Commit 9bc3c08

Browse files
authored
customize css prop component injection depending on use case (#228)
generally speaking, the component should be injected just before it's needed, unless it's a styled() HOC and referring to another component in scope, in which case we need to find that component and inject immediately after it
1 parent 733118f commit 9bc3c08

File tree

7 files changed

+277
-148
lines changed

7 files changed

+277
-148
lines changed

src/visitors/transpileCssProp.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,20 @@ export default t => (path, state) => {
4545
)
4646

4747
let styled
48+
let injector
4849

4950
if (TAG_NAME_REGEXP.test(name)) {
5051
styled = t.memberExpression(importName, t.identifier(name))
5152
} else {
5253
styled = t.callExpression(importName, [t.identifier(name)])
54+
55+
if (bindings[name] && !t.isImportDeclaration(bindings[name].path.parent)) {
56+
injector = nodeToInsert =>
57+
(t.isVariableDeclaration(bindings[name].path.parent)
58+
? bindings[name].path.parentPath
59+
: bindings[name].path
60+
).insertAfter(nodeToInsert)
61+
}
5362
}
5463

5564
let css
@@ -179,9 +188,17 @@ export default t => (path, state) => {
179188
}, [])
180189
}
181190

182-
// Add the tagged template expression and then requeue the newly added node
183-
// so Babel runs over it again
184-
const length = program.node.body.push(
191+
if (!injector) {
192+
let parent = elem
193+
194+
while (!t.isProgram(parent.parentPath)) {
195+
parent = parent.parentPath
196+
}
197+
198+
injector = nodeToInsert => parent.insertBefore(nodeToInsert)
199+
}
200+
201+
injector(
185202
t.variableDeclaration('var', [
186203
t.variableDeclarator(
187204
id,
@@ -191,6 +208,4 @@ export default t => (path, state) => {
191208
),
192209
])
193210
)
194-
195-
program.requeue(program.get('body')[length - 1])
196211
}

test/fixtures/transpile-css-prop-add-import/output.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ function _templateObject() {
2727

2828
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
2929

30+
var _StyledDiv = _styledComponents["default"].div(_templateObject());
31+
3032
var _default = function _default() {
3133
return <_StyledDiv>
3234
<_Card.default>
@@ -41,5 +43,3 @@ var _default = function _default() {
4143
};
4244

4345
exports["default"] = _default;
44-
45-
var _StyledDiv = _styledComponents["default"].div(_templateObject());

test/fixtures/transpile-css-prop-add-require/output.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ function _templateObject() {
2323

2424
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
2525

26+
var _StyledDiv = _styledComponents["default"].div(_templateObject());
27+
2628
var _default = function _default() {
2729
return <_StyledDiv />;
2830
};
2931

3032
exports["default"] = _default;
31-
32-
var _StyledDiv = _styledComponents["default"].div(_templateObject());

test/fixtures/transpile-css-prop-all-options-on/code.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import styled from 'styled-components'
2+
import SomeComponent from '../SomeComponentPath'
3+
const { SomeOtherComponent } = require('../SomeOtherComponentPath')
24

35
/**
46
* control
@@ -133,3 +135,22 @@ const ObjectPropMixedInputs = p => {
133135
</p>
134136
)
135137
}
138+
139+
/* styled component defined after function it's used in */
140+
141+
const EarlyUsageComponent = p => <Thing3 css="color: red;" />
142+
143+
const Thing3 = styled.div`
144+
color: blue;
145+
`
146+
147+
const EarlyUsageComponent2 = p => <Thing4 css="color: red;" />
148+
149+
function Thing4(props) {
150+
return <div {...props} />
151+
}
152+
153+
/* insert before usage for non-local scope styled HOC targets */
154+
155+
const ImportedComponentUsage = p => <SomeComponent css="color: red;" />
156+
const RequiredComponentUsage = p => <SomeOtherComponent css="color: red;" />

0 commit comments

Comments
 (0)