import cssToObj from "./css-to-obj" ; import { hyphenToCamel , namespaceToCamel } from "./camelize" ; import BabelCore from "@babel/core" ; export default function ( babel ) { const t = babel . types ; const restElement = t . restElement ? t . restElement : t . restProperty ; const createClass = ( className ) => t . logicalExpression ( "||" , t . memberExpression ( t . identifier ( "styles" ) , t . stringLiteral ( className ) , true ) , t . stringLiteral ( className ) ) ; const attrVisitor = { JSXAttribute ( path ) { const name = path . get ( "name" ) ; const value = path . get ( "value" ) ; if ( name . isJSXNamespacedName ( ) ) { name . replaceWith ( t . jSXIdentifier ( namespaceToCamel ( path . node . name . namespace . name , path . node . name . name . name ) ) ) ; } else if ( name . isJSXIdentifier ( ) ) { if ( name . node . name === "class" ) { name . replaceWith ( t . jSXIdentifier ( "className" ) ) ; let classes = value . node . value . split ( /\s/ ) ; if ( classes . length > 0 ) { let expr = createClass ( classes [ 0 ] ) ; for ( let i = 1 ; i < classes . length ; i ++ ) { expr = t . binaryExpression ( "+" , t . binaryExpression ( "+" , expr , t . stringLiteral ( " " ) ) , createClass ( classes [ i ] ) ) ; } value . replaceWith ( t . jSXExpressionContainer ( expr ) ) ; } } if ( name . node . name === "style" ) { let csso = cssToObj ( value . node . value ) ; let properties = Object . keys ( csso ) . map ( prop => t . objectProperty ( t . identifier ( hyphenToCamel ( prop ) ) , t . stringLiteral ( csso [ prop ] ) ) ) ; value . replaceWith ( t . jSXExpressionContainer ( t . objectExpression ( properties ) ) ) ; } if ( ! /^(data-|aria-)/ . test ( name . node . name ) ) { name . replaceWith ( t . jSXIdentifier ( hyphenToCamel ( path . node . name . name ) ) ) ; } } } } ; const getExport = function ( svg ) { return t . exportDefaultDeclaration ( t . arrowFunctionExpression ( [ t . objectPattern ( [ t . objectProperty ( t . identifier ( "styles" ) , t . assignmentPattern ( t . identifier ( "styles" ) , t . objectExpression ( [ ] ) ) , false , true ) , restElement ( t . identifier ( "props" ) ) ] ) ] , svg ) ) ; } ; const svgVisitor = { JSXOpeningElement ( path ) { if ( path . node . name . name . toLowerCase ( ) === "svg" ) { path . node . attributes . push ( t . jSXSpreadAttribute ( t . identifier ( "props" ) ) ) ; } } } ; const svgExpressionVisitor = { ExpressionStatement ( path ) { if ( ! path . get ( "expression" ) . isJSXElement ( ) ) return ; if ( path . get ( "expression.openingElement.name" ) . node . name !== "svg" ) return ; path . replaceWith ( getExport ( path . get ( "expression" ) . node ) ) ; } } ; const programVisitor = { Program ( path ) { path . node . body . unshift ( t . importDeclaration ( [ t . importDefaultSpecifier ( t . identifier ( "React" ) ) ] , t . stringLiteral ( "react" ) ) ) ; } } ; return { visitor : Object . assign ( { } , programVisitor , svgExpressionVisitor , svgVisitor , attrVisitor ) } ; }