Use SVGR and Material UI together

761 views Asked by At

i'm trying to use SVGR to convert my svg into react components and i need to use <SvgIcon /> of Material UI and pass the converted component as a prop to it. nothing wrong with this yet.

but, SVGR saves these component in a folder called svgCom for example and inside of this folder there is index.js plus converted svg components.

i need to wrapp all these components inside of <SvgIcon> so i don't have to wrap this icon with <SvgIcon/> again for each use case; so far i try to add this component in template.js of SVGR but it throw me an error when try to parse .

is this the best way of doing such thing or there is better way ? if it is what's wrong with my template.js ?

here is my templete.js :

function template(
  { template },
  opts,
  { imports, componentName, props, jsx, exports },
) {
  return template.ast`
    ${imports}
     import { SvgIcon } from "@material-ui/core";
     ///////////////////////////////////// error here
    const ${componentName} = (${props}) => <SvgIcon component={${jsx}} />
    ${exports}
  `
}
module.exports = template

thank you.

1

There are 1 answers

2
SeBass On

We had the same problem and after some research I came to the following solution:

const {
  identifier,
  jsxClosingElement,
  jsxElement,
  jsxIdentifier,
  jsxOpeningElement,
  jsxSpreadAttribute,
} = require('@babel/types')

const iconTemplate = ({ template }, _, { componentName, jsx, exports }) => {
  const wrappedJsx = jsxElement(
    jsxOpeningElement(jsxIdentifier('SvgIcon'), [jsxSpreadAttribute(identifier('props'))]),
    jsxClosingElement(jsxIdentifier('SvgIcon')),
    [jsx],
    false
  )

  return template.ast`
    import React from 'react'
    import SvgIcon from '@material-ui/core/SvgIcon'

    const ${componentName} = (props) => ${wrappedJsx}
    ${exports}
  `
}

module.exports = iconTemplate

If you don't want {...props} on the <svg> tag, you have to disable the expandProps option