GithubHelp home page GithubHelp logo

gregberge / svgr Goto Github PK

View Code? Open in Web Editor NEW
10.3K 35.0 407.0 16.31 MB

Transform SVGs into React components 🦁

Home Page: https://react-svgr.com

License: MIT License

JavaScript 14.40% TypeScript 64.91% MDX 20.70%
svg2react svg-to-react svg svgo react react-svg react-svg-creator svg-react webpack-loader webpack

svgr's Introduction

svgr

Transform SVGs into React components 🦁

License Donate npm package npm downloads CI Code Coverage

Try it out online!

Watch the talk at React Europe

SVGR is an universal tool to transform SVG into React components.

SVGR takes a raw SVG and transforms it into a ready-to-use React component.

See the documentation at react-svgr.com for more information about using svgr!

Quicklinks to some of the most-visited pages:

Example

Take a SVG:

<?xml version="1.0" encoding="UTF-8"?>
<svg
  width="48px"
  height="1px"
  viewBox="0 0 48 1"
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
>
  <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
  <title>Rectangle 5</title>
  <desc>Created with Sketch.</desc>
  <defs></defs>
  <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
    <g
      id="19-Separator"
      transform="translate(-129.000000, -156.000000)"
      fill="#063855"
    >
      <g id="Controls/Settings" transform="translate(80.000000, 0.000000)">
        <g id="Content" transform="translate(0.000000, 64.000000)">
          <g id="Group" transform="translate(24.000000, 56.000000)">
            <g id="Group-2">
              <rect id="Rectangle-5" x="25" y="36" width="48" height="1"></rect>
            </g>
          </g>
        </g>
      </g>
    </g>
  </g>
</svg>

Run SVGR

npx @svgr/cli --icon --replace-attr-values "#063855=currentColor" -- icon.svg

Get an optimized React component

import * as React from 'react'

const SvgComponent = (props) => (
  <svg width="1em" height="1em" viewBox="0 0 48 1" {...props}>
    <path d="M0 0h48v1H0z" fill="currentColor" fillRule="evenodd" />
  </svg>
)

export default SvgComponent

Supporting SVGR

SVGR is a MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to the support of these awesome backers. If you'd like to join them, please consider:

Learn more about supporting SVGR.

Contributing

Check out the contributing guidelines

License

Licensed under the MIT License, Copyright © 2017-present Greg Bergé.

See LICENSE for more information.

Acknowledgements

This project has been popularized by Christopher Chedeau and it has been included in create-react-app thanks to Dan Abramov. We would like to thanks Sven Sauleau for his help and its intuition.

svgr's People

Contributors

arcticicestudio avatar await-ovo avatar balsick avatar dependabot[bot] avatar gregberge avatar jalooc avatar joshkel avatar kimak avatar lifeiscontent avatar loicplaire avatar marques-kevin avatar michaeljaltamirano avatar mikaelbr avatar pachuka avatar paescuj avatar peachscript avatar rayrw avatar rhys-vdw avatar rossmoody avatar rschristian avatar ryanfabela avatar samuelmeuli avatar seahindeniz avatar shish avatar sinchang avatar smol-honk avatar sudkumar avatar swissspidy avatar tomchentw avatar trysound avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

svgr's Issues

Webpack usage - ENOENT: No such file .svgo.yml

Using Node V6.11.4 / Yarn 1.3.2

Installed using yarn add svgr

usage as: import Logotype from 'svgr/webpack!images/logo.svg'; or similar

I'm specifying the loader in the import as svgs are already being handled differently elsewhere in the project, but I have a requirement to inline the SVG in places.

the error I receive is as follows:

ERROR in ./node_modules/svgr/webpack.js!./src/assets/images/logo-wizian.svg
[1] Module build failed: Error: ENOENT: no such file or directory, open '/Users/klavelle/projects/brand-wizian/node_modules/svgo/lib/svgo/../../.svgo.yml'

can anyone assist me with this please?

Add titleProp option

As mentioned in #75, it would be nice to be able to specify a title using props. To do it, my proposition is to add a boolean option "titleProp" defaulting to false. When activated, user would be able to specify the title of the SVG using props.

Usage in command line

svgr --title-prop

Usage in Node / Webpack

transform("...", { titleProp: true })

Usage in React, when the option is activated

import SvgrComponent from './SvgrComponent'

<SvgrComponent title="This is a title" />
// The output will be:
// <svg><title>This is a title</title></svg>
// Instead of:
// <svg title="This is a title" />

How to use with rollup

Hi,

I want to make a node package of our logos made in svg.
I want to be able to import them as in the webpack example (react or link)

Is it possible with Rollup.JS ?

Unable to execute sequentially in npm scripts

First off - really nice tool :)

Second - I'm not sure this is a svgr specific issue - or a more general issue regarding transpiled async/await and npm scripts - but...

I'm having trouble executing 2 commands sequentially in an npm script - like so (building a directory of components and making an index file):

  "scripts": {
    "build:icons": "svgr -d ./icons ./images/icons; create-index ./icons",

... when running npm run build:icons the second command starts executing before svgr is done (before it has even created the output dir) - which of course throws an error.

Running the 2 commands directly in bash works beautifully.

(I have also tried using run-s from npm-run-all - makes no difference)

Any ideas?

Error setting tab width for prettier

Hi there,

When attempting to set the tab-width option for prettier using the command line arguments ( --tab-width 4) an error is returned:

● Validation Error:

Option "tabWidth" must be of type:
number
but instead received:
boolean

Example:
{
"tabWidth": 2
}

In addition I've noticed on your online example site, if you attempt to change the tab widths it appears to fail, and the svg side of the site stays grey like it does when loading.

Thank you! 🙏

Contributors–

This is a process I have done manually and just dealt with it up to this point– now I just converted a full directory of icons and am extremely grateful. Excellent work on this tool and documentation! 🙇

remove dimension attributes?

hey there 👋

thanks for the awesome lib! 👏

i'm finding that scaling my SVGs gets a lot more fiddly b/c the components created by SVGR always include height and width attributes on the top-level svg tag.

i found a related PR here but it looks like the use-case and conversation got a bit muddled - to be clear: i just want to be able to completely remove the attributes (not override them).

perhaps there is a way to do this already that i'm missing or maybe there's a good reason not to? any and all suggestions would be much appreciated! 🙏👍

Confusing default value for `--no-view-box` flag

--no-view-box remove viewBox (default: true)

This is confusing since no view box = true would imply that the view box is stripped by default. Actually options.viewBox is true by default and --no-view-box sets it to false.

Template flag hates me

svgr --template src/transforms/svgToTypeScriptComponent.js src/icons/scene-ink.svg

// src/transforms/svgToTypeScriptComponent.js
export default (opts = {}) => (code, state) => `import React from 'react'
const ${state.componentName} = (${opts.expandProps ? 'props' : ''}) => ${code}
export default ${state.componentName}`

Even if I copy the default template, I get an error:

Error when loading template: src/transforms/svgToComponentTemplate.js

Add typescript option

As mentioned in #38, it should be possible to generate a TypeScript file instead of a JavaScript file.
Some details are provided in #38

Usage in CLI

svgr --typescript

Usage in Node / Webpack

transform('...', { typescript: true })

As a result, it will use a TypeScript friendly package and change the extension to ".ts".

Is there a way to pass custom config/plugins to svgo?

Judging from the readme, you can only enable/disable svgo and some of its plugin, but I wanted to use some other svgo plugins.

Does the svgo parameter in node work also as a config object? It's not clear in the readme.

The svgo plugins I wanted to use are removeStyleElement, convertColors: { currentColor: true }, or the inlineStyles plugin.

Include Babel transformation in Webpack loader

Relative to this issue facebook/create-react-app#3907 (comment).

The goal is to apply Babel transformation directly inside the Webpack loader. Babel will transform code into ES5 with createElement, ES modules have to stay.

We must be able to disable the Babel transformation for advanced cases using an option babel: false.

README must reflect the new change and have a not about this.

Add support for .svgrrc

As mentioned in #81 by @lifeiscontent, SVGR should have its own .svgrrc in order to be able to specify desired options.

I like the way Prettier is doing it:

cosmiconfig is the good candidate to do it.

To resume :

  • Load configuration from .svgrrc and other default from cosmiconfig
  • Expose resolveConfig, resolveConfigFile and clearConfigCache

Does this actually work?

The svgr package does install correctly but when I try to action svgr commands I constantly get
"-bash: svgr: command not found".
It doesn't matter how or where I try it, I still get the same error. Even my colleagues are baffled by it. Any help?

Styles are not being applied to all classes with the same name.

If I have an SVG with elements that have the same class, only the first instance of that element with the style class will get rendered properly.

<svg height="100" width="100" viewport="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style>
        .line {
            stroke: #000;
            stroke-width: 5;
        }
    </style>
  </defs>
  <title>lines</title>
  
  <line class="line" x1="25" y1="30" x2="75" y2="30"></line>
  <line class="line" x1="25" y1="50" x2="75" y2="50"></line>
  <line class="line" x1="25" y1="70" x2="75" y2="70"></line>
</svg>

produces...

import React from "react";

const SvgComponent = props => (
  <svg height={100} width={100} {...props}>
    <defs />
    <title>lines</title>
    <path className="line" d="M25 30h50M25 50h50M25 70h50" />
  </svg>
);

export default SvgComponent;

It seems to be missing the other elements.

Copying the default template result in a parsing error (export...)

Hi, thanks for you awesome work! This lib seems amazing.
Just trying it out.
I aim to use it for web & native at the same time.
I tried to adjust the template and I am getting

(function (exports, require, module, __filename, __dirname) { export default (opts = {}) => {
                                                              ^^^^^^

SyntaxError: Unexpected token export

Which make sense since node is not able (yet) to understand export/import natively. I guess we should adjust README to point to a transpiled version or to warn about this?

Issue with loading SVG sprite

I'm trying to load an SVG file as a React component. I found a PR facebook/create-react-app#3718 by @iansu that solves the problem.

However there is an issue with reading the SVG file contents.

Issue
I have the following SVG file (it was generated by [svg-sprite]):(https://www.npmjs.com/package/svg-sprite)

<?xml version="1.0" encoding="UTF-8"?>
<svg width="0" height="0" style="position:absolute">
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="filter">
    <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
    <path d="M0 0h24v24H0z" fill="none" />
  </symbol>
</svg>

which is being imported as:
image
As you see the <svg /> element is empty.

Workaround
I was able to find a workaround to the above. All works fine if I add <defs /> element that includes <style /> element:

<?xml version="1.0" encoding="UTF-8"?>
<svg width="0" height="0" style="position:absolute">
  <defs><style></style></defs>
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="filter">
    <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
    <path d="M0 0h24v24H0z" fill="none" />
  </symbol>
</svg>

which returns a proper <svg /> element and its contents:
image

Expected scenario
The SVG example from Issue section should be loaded correctly (with its contents) without adding some extra tags.

Custom attributes and values for SVGs

Is there a way to pass custom props to SVG and path elements? I need to achieve something like this:

export const AngleDoubleRight = props => {
	const { width, height, styles, ...rest } = props;
	return (
		<svg viewBox="0 0 16 28" width={width} height={height} className={styles}>
			<path
				d="...(too long to paste this)"
				fill={props.fill || '#fff'}
				stroke={props.stroke}
				{...rest}
				className={' '}
			/>
		</svg>
	);
};

So, I need to pass this destructuring assingment, and to assing basic props.values to SVG attributes like height width className, and this {...rest} in path element. I've thought that I can do this by using template file, but after trying to figure out how to do it with it for the last hour or so I'm not sure if that's the way to do it.
Thank you for your work btw, this is a great SVG transformer!

setting componentName through node api

When generating an icon using the CLI, state.componentName is determined based on the file path (state.componentPath). However, when using the node api, there obviously isn't a file path available, and hence no way to set the componentName to anything but SvgComponent. I feel that by and large, the node API should offer at least the same functionality that the CLI does, if not more, and that there should be a way to set the component name.

Am I missing something?

Happy to send a pull request adding this functionality.

is it possible add prefix to file names?

I want to add the "menu" prefix to the name of the "logo.svg" file.
so that the SVGs belonging to a particular component can be simply grouped. like MenuLogo.js

write index.js with outdir option

Hi there, thanks for creating such a nice library,

I was wondering if you could create an option to output an index.js file that requires all icons.

e.g.

one.svg
one.svg

to

icons/one.js
icons/two.js
icons/index.js

and the contents of index.js

would look like this

module.exports = {
  'one': require('icons/one'),
  'two': require('icons/two')
};

this would be a nice feature of this lib so we don't have to maintain a mapping of each icon.

unless you have a better suggestion for managing something like this?

Thanks!

Separate CLI and core package

We might not need prettier/path when using as node package. This can be separated into a different file say cli.js. The main file can only contain code that is necessary. This will help in integrating this to online REPLs.

Getting a Base64 Data URI when importing SVG

Webpack config:

      {
        test: /\.svg$/,
        use: ['svgr/webpack'],
      }

Importing:

import Loader from 'icons/svg/Spinner'
console.log(Loader)

Result:
data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHN0eWxlPSJ3aWR0aDowO2hlaWdodDowO3Bvc2l0aW9uOmFic29sdXRlO292ZXJmbG93OmhpZGRlbjsiPgogIDxkZWZzPgo8c3ltYm9sIHZpZXdCb3g9IjAgMCA4MzYuMzMzMzEyOTg4MjgxMiAxMDI0LjY2Njc0ODA0Njg3NSIgYXJpYS1sYWJlbGxlZGJ5PSJhZHNpLWFudC1hcHBsZS10aXRsZSIgaWQ9InNpLWFudC1hcHBsZSI+PHRpdGxlIGlkPSJhZHNpLWFudC1hcHBsZS10aXRsZSI+aWNvbiBhcHBsZTwvdGl0bGU+PHBhdGggZD0iTTgwOS4zMzMgMzQ5cS0yMS0zMS00OS01Mi41dC01NS41LTMxLTQ2LjUtMTMuNS0zNi00cS0zNS00LTc1IDcuNXQtNzMgMjUtNDggMTMuNXEtMTcgMC03NS0yMi41dC05NC0yMS41cS02NSAxLTEyMS41IDM1LjV0LTkwLjUgOTIuNXEtMzIgNTctNDAgMTI5dDUuNSAxNDEuNSAzOS41IDEzMyA2MCAxMTIuNXEyMCAzMCAzNC41IDQ4dDM2IDQwIDQ0LjUgMzIuNSA0NiA5LjVxMzAtMSA3OC41LTIxLjV0ODkuNS0yMC41cTQwIDAgODggMjAuNXQ4MSAyMC41cTI1LTEgNDctMTF0NDIuNS0zMC41IDMzLjUtMzcuNSAzNC00N3E0My02NCA3MS0xNDYtOC0zLTE3LjUtOHQtMzMtMjIuNS00MC41LTM4LjUtMzEuNS01OC0xNS41LTgwcTAtMzYgMTEuNS02OS41dDI1LTUzLjUgMzQtMzkgMjYuNS0yMy41IDE0LTkuNXptLTE4Ni0zNDlxLTM5IDItODEgMjMuNXQtNzAgNTQuNXEtMjcgMzAtNDEuNSA3M3QtOS41IDg1cTQxIDMgODAuNS0xNy41dDY4LjUtNTQuNXEyOC0zNSA0My03OHQxMC04NnoiLz48L3N5bWJvbD4KICA8L2RlZnM+Cjwvc3ZnPgo=

Is there some config I'm missing or something?

Not outputting files

Running:

"yarn svgr --icon --single-quote ./src/components/icons ./public/assets/images"

Output in console:

import React from "react";

const IcoAdd = props => (
  <svg width={24} height={24} viewBox="0 0 24 24" {...props}>
    <path
      fillRule="evenodd"
      d="M6 10.8h4.8V6h2.4v4.8H18v2.4h-4.8V18h-2.4v-4.8H6z"
    />
  </svg>
);

export default IcoAdd;

import React from "react";

const IcoBack = props => (
  <svg width={24} height={24} viewBox="0 0 24 24" {...props}>
    <path d="M11.488 7l1.423 1.414-3.088 3.088H19v1.996H9.823l3.088 3.088L11.488 18 6 12.5z" />
  </svg>
);

export default IcoBack;

but doesn't make files

Feature Spec: Custom configs

@neoziro I'm opening up this issue as a source for us to track in terms of all the functionality that is required.

Requirements

  • create SVGO config loader e.g. .svgo.yml, .svgo.json
  • create prettier config loader e.g. prettier.config.js, .prettierrc

Questions

  1. how should we load config that is custom to svgr?

Possible implemenations

  1. We could create an svgr.config.js to load h2x and transform features. This way, people could run their own h2x and transforms themselves to extend svgr.

if you have any questions or more requirements please edit this issue and list them.

once we've finished the initial spec of this feature, I can start working on it if you like!

svgr transforms svgs oddly

given this SVG

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60" height="60" viewBox="0 0 60 60">
  <defs>
    <path id="a-to-z-a" d="M20.588,26 L19.1,22.424 L11.9,22.424 L10.412,26 L7.892,26 L15.308,8.96 L15.644,8.96 L23.084,26 L20.588,26 Z M12.812,20.216 L18.188,20.216 L15.5,13.736 L12.812,20.216 Z M47.744,34.2 L47.744,34.488 L40.64,48.792 L47.504,48.792 L47.504,51 L37.256,51 L37.256,50.664 L44.408,36.408 L37.352,36.408 L37.352,34.2 L47.744,34.2 Z M27,18.2532924 C27,18.1134029 27.1139402,18 27.2557783,18 L29.7442217,18 C29.8854841,18 30,18.1070023 30,18.2532924 L30,41.7467076 C30,41.8865971 29.8860598,42 29.7442217,42 L27.2557783,42 C27.1145159,42 27,41.8929977 27,41.7467076 L27,18.2532924 Z"/>
  </defs>
  <g fill="none" fill-rule="evenodd">
    <mask id="a-to-z-b" fill="#fff">
      <use xlink:href="#a-to-z-a"/>
    </mask>
  </g>
</svg>

I'd expect the output to look something like this

import React from "react";

const AToZ = props => (
  <svg width={60} height={60} viewBox="0 0 60 60" {...props}>
      <path
        d="M20.588 26L19.1 22.424h-7.2L10.412 26h-2.52l7.416-17.04h.336L23.084 26h-2.496zm-7.776-5.784h5.376l-2.688-6.48-2.688 6.48zM47.744 34.2v.288L40.64 48.792h6.864V51H37.256v-.336l7.152-14.256h-7.056V34.2h10.392zM27 18.253c0-.14.114-.253.256-.253h2.488a.25.25 0 0 1 .256.253v23.494c0 .14-.114.253-.256.253h-2.488a.25.25 0 0 1-.256-.253V18.253z"
      />
  </svg>
);

export default AToZ;

the result looks like this

import React from "react";

const AToZ = props => (
  <svg width={60} height={60} viewBox="0 0 60 60" {...props}>
    <defs>
      <path
        id="a"
        d="M20.588 26L19.1 22.424h-7.2L10.412 26h-2.52l7.416-17.04h.336L23.084 26h-2.496zm-7.776-5.784h5.376l-2.688-6.48-2.688 6.48zM47.744 34.2v.288L40.64 48.792h6.864V51H37.256v-.336l7.152-14.256h-7.056V34.2h10.392zM27 18.253c0-.14.114-.253.256-.253h2.488a.25.25 0 0 1 .256.253v23.494c0 .14-.114.253-.256.253h-2.488a.25.25 0 0 1-.256-.253V18.253z"
      />
    </defs>
  </svg>
);

export default AToZ;

Error loading large SVG icons

When I import flag-icon-css library, the transformation fails with the following error:

Failed to compile.

./node_modules/flag-icon-css/flags/1x1/do.svg
Module build failed: RangeError: Maximum call stack size exceeded
    at String.replace (<anonymous>)
    at Array.forEach (<anonymous>)
    at Array.forEach (<anonymous>)

This icon is 456 kb, so maybe it has something to do with this?

Does svgr should convert file names to the PascalCase?

Hey,

I saw in the Readme, that file names have to be transformed to the PascalCase. Is it the expected behavior?

I've tried to use svgr and the output file names exactly the same as the svgs. In my case, the filenames are in kebab-case

SyntaxError: Unexpected token, expected } for inline CSS block

I have a logo generated by Adobe Illustrator's SVG export plugin (supplied by our designers). I had transformed it to a React component by hand first, until I found this package. It doesn't seem to handle a style block though; I think the parser tries to interpret it as a react template construction.

Very minimal example, probably not valid SVG but it reproduces the parse error:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1">
    <style type="text/css">
      .st0{fill:#34107D;}
    </style>
</svg>

Error output:

$ svgr test.svg

(node:10071) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): SyntaxError: Unexpected token, expected } (5:14)
  3 | const Test = (props) => <svg id="Layer_1" {...props}>
  4 |   <style>
> 5 |     .st0{fill:#34107d}
    |              ^
  6 |   </style>
  7 | </svg>
  8 |
(node:10071) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Webpack example in readme doesn't seem to work

When I tried to use svgr 0.4.0 in Webpack config I found that the example did not work. This did:

        {
            test: /\.svg$/,
            use: ['babel-loader', {
                loader: 'svgr/lib/webpack',
                options: {
                    icon: true,
                },
            }],
        }
  1. Loaders need to be in reverse order so that babel-loader processes svgr's output.
  2. Specifying svgr/webpack didn't work, but svgr/lib/webpack did.

Add svgAttribute option

Users need to add default attribute to their SVG, like in #82. My proposition is to add a "svgAttribute" option.

Usage in CLI

svgr --svg-attribute "focusable=false"
svgr --svg-attribute "a=b" --svg-attribute "c=d"

At first, all attribute values will be considered as a string

Usage in Node / Webpack

transform("...", { svgAttributes: { focusable: "false" } })
transform("...", { svgAttributes: { a: "b", c: "d" } })

Can generate React components with string style attribute

If SVGO doesn't manage to remove all of the CSS in the style attribute, svgr will generate a React component with a string style prop, which is invalid. For example, when I run 0.4.0 against this Inkscape SVG this is what I get:

import React from "react";

const List = props => (
  <svg
    xmlnsXlink="http://www.w3.org/1999/xlink"
    width={48}
    height={48}
    {...props}
  >
    <g transform="translate(0 -1004.362)">
      <g id="a" color="#000" fill="#a3a3a3" strokeWidth={8}>
        <rect
          style="marker:none"
          width={4}
          height={4}
          x={4}
          y="1010.362"
          rx=".2"
          ry=".2"
          overflow="visible"
        />
        <rect
          ry=".2"
          rx=".2"
          y="1010.362"
          x={12}
          height={4}
          width={32}
          style="marker:none"
          overflow="visible"
        />
      </g>
      <use xlinkHref="#a" />
      <use xlinkHref="#a" transform="translate(0 8)" />
      <use xlinkHref="#a" transform="translate(0 16)" />
      <use xlinkHref="#a" transform="translate(0 24)" />
      <use xlinkHref="#a" transform="translate(0 32)" />
    </g>
  </svg>
);

export default List;

This component fails to render because of the style="marker:none" props.

is there a way to get a ref of an SVG?

As the title says, is it possible currently? Or would this be a feature we can add?

if you're willing to add this feature, I'd sugged calling it svgRef as the prop to hook

loss of semantic information

i didn't tryed to use this open source project.

but one thing bugs me on the project Readme, the first example show that a rect element get transformet to a path, loosing the semantics associated to the rect element, i guess the same is applied to circle, ellipse etc ?

What is the motivation behing this transformation ?

Usage with TypeScript

Hello, all. I believe I'm having a TypeScript issue with SVGR. I've setup the svgr/webpack plugin which is working correctly, but:

When I import an SVG into a .tsx file like so:

import Icon from 'assets/icon.svg';

export default () => (<Icon />);

I get this error from TypeScript:

error TS2307: Cannot find module 'assets/icon.svg'

I was able to fix the issue by adding an index.d.ts file to the root of my "assets" folder with these contents:

declare module '*.svg' {
    const value: React.StatelessComponent<React.SVGAttributes<SVGElement>>;
    export default value;
}

I'm fairly new to TypeScript so I'm not sure the above is the "correct" solution, but it allows me to write <Icon /> and <Icon attr="#fff" /> (where attr is any valid SVG attribute). It might be worth adding something like this to the module itself. Is there any interest in adding TypeScript support to this project?

Thank you so much for this module! ❤️

Usage with url-loader breaks svg imports inside LESS files

Hello there.

Not quite sure if this is a problem with this library, or my setup, however I wanted to keep all the SVG imports as they are, in addition of using import {ReactComponent as Icon} from '...' in React Components.

Here's how my setup looked liked before adding svgr

  {
    test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
    loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
  },

And after

{
    test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
    use: ['babel-loader', 'svgr/webpack', 'url-loader?limit=10000&mimetype=image/svg+xml']
  }

Everything works fine except importing SVG's inside of LESS files (specifically speaking Iconmoon import):
url('@{icomoon-font-path}/myfontsvg?clelyn#myfont') format('svg');
There were no errors, but all icons were appearing as rectangles [].

Please let me know if this is an issue with svgr, or I'm doing something in a wrong way.
Best regards.

P.S I've found a workaround, just want to be sure this isn't my fault :)
The workaround

  {
    test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
    issuer: {
      test: /\.jsx?$/
    },
    use: ['babel-loader', 'svgr/webpack', 'url-loader?limit=10000&mimetype=image/svg+xml']
  },
  {
    test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
    loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
  },

Preserving viewBox

Hi,

First of all, thank you for this amazing library, it is great!

With version 1.0.0, viewBox is dropped. In my case I have some illustrations that I inline, they are not icons but I still need viewBox to scale them.

I would be happy to contribute and help, but in order to understand where you come from: what is the rationale behind removing viewBox for "non-icons"?

is there a way to ignore svgs that have already been converted in a directory?

The use case I have is that the majority of the time I need to amend the created jsx file to peel out <g> tags and the like because where I download them from (InVision i.e. the tool I use at my place of work for designs) can sometimes change the svg's in funny ways which causes problems when rendering.

Given that I never have all the svgs I need at once I don't want to have to run my script for each individual, new svg I bring in to my project but at the moment I am having to due to the current script using the template and overwriting each file that has been created previously.

Internet Explorer 11 (focusable, tabindex)

Sadly we need to support IE 11 on our site, and for some reason IE make tab navigation stop on every svg icon unless you use the non-standard <svg focusable="false"... property. Is there any way I can add this during svgr processing time, so that I can avoid an extra post processing step, or have to write <MyIcon focusable="false"/>?

See: https://stackoverflow.com/q/18646111/112019

Basically I want an option to create components like

import React from "react";

const Bed = props => (
  <svg focusable="false" viewBox="0 0 20 13" width="1em" height="1em" {...props}>
    <path
      fill="#333F52"
      fillRule="evenodd"
      d="M18.821 8.143c.332 0 .608.275.608.607V13H17v-2.429H2.429V13H0V1.464C0 1.132.275.857.607.857h1.214c.332 0 .608.275.608.607v6.679H18.82zM7.893 5.107a2.433 2.433 0 0 1-2.429 2.429 2.433 2.433 0 0 1-2.428-2.429A2.433 2.433 0 0 1 5.464 2.68a2.433 2.433 0 0 1 2.429 2.428zm11.536 2.429H8.5V3.893c0-.332.275-.607.607-.607h6.679a3.644 3.644 0 0 1 3.643 3.643v.607z"
    />
  </svg>
);

export default Bed;

Try to test component with React generated form svgr

Hi,
I have a little problem with Jest tests runner.

My simple component:

import React from 'react';

import {ReactComponent as CloseIcon} from '../images/close.svg';

const CloseBubble = ({minimize}) => (
    <div className='thulium-chat-bubble'>
        <a onClick={event => {
            event.preventDefault();
            minimize()
        }} href=''>
            <CloseIcon/>
        </a>
    </div>
);

export default CloseBubble;

test class:

import CloseBubble from '../CloseBubble';

describe('CloseBubble', () => {
    test('sample', () => {
        expect(1).toBe(1);
    });
});

And after I run this test I got following error:

  ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><style>.cls-1{fill:#231f20;}</style></defs><title>cancel_icon</title><path class="cls-1" d="M52.08,50,70.32,31.84a1.49,1.49,0,0,0-2.11-2.11L50,47.87,31.82,29.63a1.8,1.8,0,0,0-2.22,0,1.82,1.82,0,0,0,0,2.21L47.85,50.09,29.6,68.23a1.47,1.47,0,0,0,0,2.12,1.74,1.74,0,0,0,2.22,0L50.06,52.1,68.31,70.35a1.73,1.73,0,0,0,2.21,0,1.46,1.46,0,0,0,0-2.12Z"/></svg>
                                                                                             ^
    
    SyntaxError: Unexpected token <

       9 |             minimize()
      10 |         }} href=''>
    > 11 |             <CloseIcon/>
      12 |         </a>
      13 |     </div>
      14 | );
      
      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:316:17)
      at Object.<anonymous> (src/components/CloseBubble.js:11:14)

What I've do wrong?

`<style>` discarded

I just used svgr to convert a bunch of SVGs with CSS declarations in a <style> tag in <defs>. eg.

<style>
.foo {
  fill: #fff;
}
</style>

By default these get discarded so my componentized result looks very different – lots of black text on black background and other general nasties…

Running a external pass of svgo first with this config, the <style> tag converts into inline versions and the problems go away:
{ "plugins": [ { "inlineStyles": { "onlyMatchedOnce": false } } ] }

So now I wonder if this should be the default behaviour of svgr and maybe the above should merge into the svgo config this project uses. Or alternatively, I wonder if svgr should preserve <style> tags without changing the SVG structure – perhaps the current discard behaviour is just a bug?

Wrong example in README

In the 'Recipes' section where 'Transform a whole directory' there is an example:

$ svgr -d icons icons

but this doesn't work. First argument should be parent directory. In my case, suppose that I want to parse icons from current directory and put the result to newIcons folder, this command works:

$ svgr ./ -d ./newIcons/

feature request: provide an easy way to add a title to the SVG icon

It would be awesome if we could easily provide some "title" prop to an icon and get it converted to the title element in order to provide some simple tooltip to the icon. Currently it's hard to extend the component to add such title attribute. Even when using a template I've only seen examples to use the 'code' variable, which makes it a bit complicated to add such a title to it based on props.

Thanks for svgr!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.