Svgr: How to use SVGR with emotion

Created on 21 Nov 2018  ·  9Comments  ·  Source: gregberge/svgr

I'd like to know how to integrate SVGR with emotion components so I can style them.

ideally, I'd like to have a single Icon component that switches its icon by passing a name prop

and that way no matter what icon I use, the Icon component will be able to generically be styled.

any ideas on how to achieve this?

question ❓

Most helpful comment

A simple example that should work:

function template(
  { template },
  opts,
  { imports, componentName, props, jsx, exports },
) {
  return template.ast`
    import styled from 'react-emotion';
    ${imports}

    const SvgComponent = (${props}) => ${jsx}
    const ${componentName} = styled(SvgComponent)`
      color: red;
    `

    ${exports}
  `
}

module.exports = template

All 9 comments

@lifeiscontent You may do whatever you want. Keep in mind this is an example for v3. I didn't migrated to v4 yet.

const template = (code, options, state) => `
// @flow
// Generated from ${state.filePath}

import * as React from "react";
import { css, cx } from 'emotion';

type Props = {
  size?: string | number,
  fill?: string,
  className?: string,
  css?: any,
};

const style = /*#__PURE__*/ css({
  display: "block",
  flex: "0 0 auto",
});

export const ${state.componentName} = ({
  size,
  fill,
  className,
  css: cssProp,
  ...props
}: Props) => {
  return (
    ${code}
  );
};
`;

module.exports = {
  template,
  icon: true,
  expandProps: 'start',
  svgProps: {
    preserveAspectRatio: `xMidYMid meet`,
    fontSize: `{size == null ? null : size}`,
    fill: `{fill == null ? "currentColor" : fill}`,
    className: '{cx(style, className, css(cssProp))}',
  },
};

@lifeiscontent yes you can do it using a custom template. It is documented (see https://github.com/smooth-code/svgr#use-a-specific-template).

@neoziro the new template API is confusing and I don’t know how to use it.

A simple example that should work:

function template(
  { template },
  opts,
  { imports, componentName, props, jsx, exports },
) {
  return template.ast`
    import styled from 'react-emotion';
    ${imports}

    const SvgComponent = (${props}) => ${jsx}
    const ${componentName} = styled(SvgComponent)`
      color: red;
    `

    ${exports}
  `
}

module.exports = template

I’ll try it later today

@neoziro, thanks for your example. In my case (styled-components wrap, same syntax), I need to escape the second pair of backticks that surround CSS styles.

@sbadulin yes of course, I forgot to escape it.

Can you share your example @sbadulin ? I would also like to use it with styled-components

@designdevy, sure, here is mine, it uses typescript and themes:
https://gist.github.com/sbadulin/7871e19235cc30f38313d07463dab0f2

Was this page helpful?
0 / 5 - 0 ratings