11// Most of this code was taken from @satya 164's babel-plugin-css-prop
22// @see https://github.com/satya164/babel-plugin-css-prop
3+ import { addDefault } from '@babel/helper-module-imports'
34import { useCssProp } from '../utils/options'
45
56const getName = ( node , t ) => {
@@ -18,27 +19,26 @@ export default t => (path, state) => {
1819 if ( ! useCssProp ( state ) ) return
1920 if ( path . node . name . name !== 'css' ) return
2021
21- // Insert require('styled-components') if it doesn't exist yet
22- const { bindings } = path . findParent ( p => p . type === 'Program' ) . scope
23- if ( ! state . required ) {
24- if ( ! bindings . styled ) {
25- state . items . push (
26- t . importDeclaration (
27- [ t . importDefaultSpecifier ( t . identifier ( 'styled' ) ) ] ,
28- t . stringLiteral ( 'styled-components' )
29- )
30- )
31- }
32- state . required = true
22+ const program = state . file . path
23+ // state.customImportName is passed through from styled-components/macro if it's used
24+ // since the macro also inserts the import
25+ let importName = state . customImportName
26+ // Insert import if it doesn't exist yet
27+ const { bindings } = program . scope
28+ if ( ! importName || ! bindings [ importName . name ] ) {
29+ importName = addDefault ( path , 'styled-components' , {
30+ nameHint : importName ? importName . name : 'styled' ,
31+ } )
3332 }
33+ if ( ! state . customImportName ) state . customImportName = importName
3434
3535 const elem = path . parentPath
3636 const name = getName ( elem . node . name , t )
3737 const id = path . scope . generateUidIdentifier (
3838 'Styled' + name . replace ( / ^ ( [ a - z ] ) / , ( match , p1 ) => p1 . toUpperCase ( ) )
3939 )
4040
41- const styled = t . callExpression ( t . identifier ( 'styled' ) , [
41+ const styled = t . callExpression ( importName , [
4242 / ^ [ a - z ] / . test ( name ) ? t . stringLiteral ( name ) : t . identifier ( name ) ,
4343 ] )
4444
@@ -105,9 +105,13 @@ export default t => (path, state) => {
105105 return acc
106106 } , [ ] )
107107
108- state . items . push (
108+ // Add the tagged template expression and then requeue the newly added node
109+ // so Babel runs over it again
110+ const length = program . node . body . push (
109111 t . variableDeclaration ( 'var' , [
110112 t . variableDeclarator ( id , t . taggedTemplateExpression ( styled , css ) ) ,
111113 ] )
112114 )
115+
116+ program . requeue ( program . get ( 'body' ) [ length - 1 ] )
113117}
0 commit comments