Skip to content Skip to sidebar Skip to footer

React Svg Component As Background-image To Div

I am trying to get styled-components to take an SVG that is a react component and set it as a background-image but I get the error: TypeError: Cannot convert a Symbol value to a

Solution 1:

For React SVG background images, I find this works best:

// MyComponent.jsimport mySvg from'./mySvg.svg';

...

functionMyComponent() {
  return (
    <divclassName="someClassName"style={{backgroundImage: `url(${mySvg})` }}
    > 

... etc

The path to the SVG file will change when webpack bundles, so by using the template string you can keep things linked up.

In the CSS class you can do whatever styling you like.

Solution 2:

Unfortunately, what you're trying to achieve is not possible. You'll have to keep your SVG as an actual .svg file (and link to that), or do some CSS trickery to place SVG component behind your foreground-component.

In other words:

<!-- step.svg --><svgversion="1.1"id="Layer_1"x="0px"y="0px"viewBox="0 0 193.3 129.7"><!-- copy paste your svg here --></svg>

And in your component:

import stepSvgUrl from "../../components/UI/SVGs/step.
// ...
<Wrapkey={step._id}bg={stepSvgUrl}>

When you import an SVG file like that, create-react-app applies a Webpack loader that includes the generated URL to the SVG you're importing - which is fine to pass into the background-image css property.

Hope this helps!

Solution 3:

Actually, there is a way to achieve what you want, without the SVG beeing a component:

Here is the updated StepBar component:

importReact, { Component } from"react";
importStepSVG from"../../components/UI/SVGs/test.svg";
import encodeSVG from'../../lib/encodeSVG';

classStepBarextendsComponent {
  render() {
    const { steps } = this.props;

    return (
      <div>
        {steps
          ? steps.map(step => {
              return (
                <Wrapkey={step._id}bg={StepSVG}><P>
                    {" "}
                    <Linkto={"/step/" + step._id}>{step.title} </Link></P></Wrap>
              );
            })
          : null}
      </div>
    );
  }
}

exportdefaultStepBar;

constWrap = styled.div`
  padding: 30px 30px 0 0;
  display: inline-block;
  background-image: ${encodeSVG(bg, '#FF9900')};
`;

Here is encodeSVG lib file:

var symbols = /[\r\n"%#()<>?\[\\\]^`{|}]/g;

functionaddNameSpace(data) {
  if (data.indexOf('http://www.w3.org/2000/svg') < 0) {
    data = data.replace(/<svg/g, "<svg xmlns='http://www.w3.org/2000/svg'");
  }

  return data;
}

functionencodeSVG(data) {
  // Use single quotes instead of double to avoid encoding.if (data.indexOf('"') >= 0) {
    data = data.replace(/"/g, "'");
  }

  data = data.replace(/>\s{1,}</g, '><');
  data = data.replace(/\s{2,}/g, ' ');

  return data.replace(symbols, encodeURIComponent);
}

var encode = function(svg, fill) {
  if (fill) {
    svg = svg.replace(/<svg/g, `<svg fill="${fill}"`);
  }
  var namespaced = addNameSpace(svg);
  var dimensionsRemoved = namespaced
    .replace(/height="\w*" /g, '')
    .replace(/width="\w*" /g, '')
    .replace(/height='\w*' /g, '')
    .replace(/width='\w*' /g, '');
  var encoded = encodeSVG(dimensionsRemoved);

  var header = 'data:image/svg+xml,';
  var dataUrl = header + encoded;  

  return`url("${dataUrl}")`;
};

You import the svg, and use a string loader for svgs with your preferred build system (for example WebPack), pass that svg to encodeSVG, et voila! :)

Solution 4:

I ended up using user11011301's solution in combination with raw-loader to load the SVG content. Not the cleanest solution I'm sure, but I couldn't get it to work with other webpack loaders.

import searchIcon from'../../images/search.svg';

<inputstyle={{backgroundImage: `url(data:image/svg+xml;base64,${btoa(searchIcon)})`}}/>

Solution 5:

url(`data:image/svg+xml;utf8,${svgTxt}`)

;or

url(`data:image/svg+xml;base64,${btoa(svgTxt)}`)

that's it.

Post a Comment for "React Svg Component As Background-image To Div"