gregberge / svgr

Transform SVGs into React components 🦁
https://react-svgr.com
MIT License
10.59k stars 422 forks source link

Add option to leave / modify ID attribute (should they exist) #882

Open scottc11 opened 1 year ago

scottc11 commented 1 year ago

🚀 Feature Proposal

Some SVG files contain tags with ID attributes on them, and it appears SVGR is setup to remove this attribute. I imagine the reason for this is because you don't want to populate the DOM with a bunch of IDs, as that could conflict with already existing IDs outside of the SVG.

My proposal is to implement an option where these ID attributes persist, but have the parser append svgr- to the front of the original ID value (ex. my-special-id becomes svgr-my-special-id).

Motivation

I am trying to make interactive SVGs for an HTML product manual. The SVG contains certain objects which I would like to have onClick events and animate when hovered. The SVG I am working with is generated by the graphic design software "Affinity Designer", which inserts IDs into the exported SVGs whenever there is a label associated with a visual element. Using these IDs, I was going to easily be able to track down which parts of the SVGR generated SVG to attack onClick event handlers, either by searching the DOM for particular IDs or manually adding the event into the SVG tags.

Example

The below example is a snippet from the SVG I am working with. One tag has ID="Select", which I would like to target with a javascript onClick event handler.

<g id="Select">
    <g transform="matrix(3.25844,0,0,3.26642,-1621.8,547.257)">
        <text x="1464px" y="259.1px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:5px;fill:rgb(250,250,250);">SELECT</text>
    </g>
</g>

Pitch

Seems like a great addition to the already expansive set of configurable options!

ryparker commented 1 year ago

I could have sworn this was supported before. Really need this.

ryparker commented 1 year ago

Ugh finally figured it out. It doesn't append anything to the ids but it does persist them.

--svgo-config={"plugins":[{"name":"preset-default","params":{"overrides":{"cleanupIds":false}}}]}

Docs would benefit from including examples like this.

scottc11 commented 1 year ago

@ryparker thats amazing you figured that out - you should create a PR and add that info to the docs!

SethFalco commented 1 year ago

append svgr- to the front

The term is "prepend" btw!

You can achieve the desired behavior by overriding the default preset to disable cleanupIds, so it doesn't minify or remove IDs, then use the prefixIds plugin.

original.svg

<svg xmlns="http://www.w3.org/2000/svg">
  <g id="Select">
    <g transform="matrix(3.25844,0,0,3.26642,-1621.8,547.257)">
      <text x="1464px" y="259.1px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:5px;fill:rgb(250,250,250);">SELECT</text>
    </g>
  </g>
</svg>

--svgo-config

{
  plugins: [
    {
      name: "preset-default",
      params: {
        overrides: { 
          cleanupIds: false
        }
      }
    },
    {
      name: "prefixIds",
      params: {
        delim: "-",
        prefix: "svgr"
      }
    }
  ]
}

optimized.svg

<svg xmlns="http://www.w3.org/2000/svg">
  <text id="svgr-Select" x="1464" y="259.1" style="font-family:&quot;ArialMT&quot;,&quot;Arial&quot;,sans-serif;font-size:5px;fill:#fafafa" transform="matrix(3.25844 0 0 3.26642 -1621.8 547.257)">SELECT</text>
</svg>

It's worth noting that SVGs support both CSS and JavaScript, so you may want to consider implementing this behavior directly in the SVG instead, though.