Svgr: [Feature proposal] Hability to use variables within svg when used as ReactComponent

Created on 29 May 2018  ·  14Comments  ·  Source: gregberge/svgr

Description

A new API that would allow us to pass variables in order to render a valid svg:

Why?

The hability of react to mount/unmount and rerender components depending on their props is efficient, but it still require a lot more tunning if you wish to render svg and you are a maintainer of svg libraries.

We are missing a feature to do the same with svg that is scalable for large project.

It would be basically the same as doing the mapping within a react component, except you don't have to write the react component and you only convert your svg using a JSX template.

Downside

  • A): Most of developers would simply just compute the svg using a custom react component and that would work.
  • B): There are no fallback within .svg for non-existing variables so the svg would become templated as it would be in react JSX. This could be introduced as an extension .svgr for svg react

Upside

  • C): It is done directly within .svg/.svgr, no need to write additional code.
  • D): Not only developer but graphic designer can work with it, all we need is to produce a sandbox UI tool for testing the rendering, and a CLI tool to convert .svgr to .svg
  • E): You will not have to maintain duplicate code for every of your svg. But you can still maintain any additional logic that calculates variables within casual react.

Regarding (B):

  • meta-data could be introduced within the svg using comments such as: <!-- { width: 100, primaryColor: '#F00' } --> in order to render default instead if the missing props. (I have added this example in proposal 2). Missing props without comments declared would be automatically required by default.
  • A custom extension .svgr could also be used to detect such import.
  • This could also benefit for (D) to automatically generate the editing tool. We can add complexity to the meta-data for such purpose. import { metadata } from './logo'

Proposal

Proposal 1

Using props that are not reserved by svgr libs:

import { ReactComponent } from './logo.svg'

export default = () => (
  <ReactComponent 
    title="Hello World" 
    width={50} 
    colorPrimary="#f07" 
    config={config} 
  />
);

Original svg

<svg>
  <path color={colorPrimary} />
  <path color={colorPrimary} width={`${width}`%} />
  <path color={config.darkColor} />
</svg>

Rendered svg

<svg>
  <title>Hello World</title>
  <path color="#f07" />
  <path color="#f07" with="50%" />
  <path color="#111" />
</svg>

Proposal 2

Using predifined props svgProps and comment default values.

import { ReactComponent, metadata } from './logo.svg'

const svgProps = {
  width: metadata.width * 2,
  config,
};

export default = () => <ReactComponent title="Hello World" svgProps={svgProps} />

Original svg

<svg>
   <!-- { width: 50, colorPrimary: '#0f9' } -->
  <path color={props.colorPrimary} />
  <path color={props.colorPrimary} width={`${props.width}`%} />
  <path color={props.config.darkColor} />
</svg>

Rendered svg

<svg>
  <title>Hello World</title>
  <path color="#0f9" />
  <path color="#0f9" with="100%" />
  <path color="#111" />
</svg>

Links / references

feature request 🙏

Most helpful comment

Thanks a lot for sharing this @lifeiscontent , maybe this can help neoziro to make a move.

@neoziro , do you know approx when v2 will be released =)?

All 14 comments

+1

Ohhh 😮! I saw, you want to enrich the SVG in order to generate the JSX! Great idea!

The two proposals looks great to me. The first one is more elegant. The second one is interesting for default properties.

But there is still one problem for me. Your SVG is no longer a SVG. I think we could find a format to annotate a SVG without breaking it.

@neoziro thank you for the interest. We could save a lot more test and code with it.

We can mix up the two proposal in order to get a final spec for the new API, I thought you would do it because you know the angles.

What kind of format are you thinking to save the svg format?

Using comments is a good idea, I have to think about it 🧐

this is interesting, one of the reasons I built https://github.com/lifeiscontent/react-svg-injector was so I could do this kind of behavior

Thanks a lot for sharing this @lifeiscontent , maybe this can help neoziro to make a move.

@neoziro , do you know approx when v2 will be released =)?

Hey! Lot of work in june, probably in july!

SVGR is focused on transforming SVG created using tools, this is a little out of scope for now. Your proposition is not the common use case. I close it for now, but why not in future.

@neoziro I am so sad to read that. How do you recommend to programme the interaction with svg in react if you need to replace value within the svg?

@kopax Did you tried to use currentColor or css variables? They are not universal, but should work for styling.

currentColor doesn't allow much. CSS does not play well with JS programming (games) and advanced web programming. Resolving the ticket would turn the tool from great to excellent.
@neoziro is arguing it is out of scope but the scope remains small and delimited. I have no clue about svgr code. Is that big cost ?

It's about introducing custom syntax, not valid svg. It can be a big cost.

If you need to have more control on svg I recommend to keep it in js. svgr is about simple conversion static svg.

Ok I understand. svgr is a really good tool thanks a lot for doing it!

Hello again, I am trying to fill a color from react props in react-native.

I have tried currentColor, fill, but nothing work. Do you guys have an svg example I can use to rely on it? Thanks in advance!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

smashercosmo picture smashercosmo  ·  3Comments

1saf picture 1saf  ·  3Comments

SilencerWeb picture SilencerWeb  ·  4Comments

rj-coding picture rj-coding  ·  5Comments

gwmaster picture gwmaster  ·  4Comments