nuxt-community/svg-module

[Feature] dynamically color svg Ids

Closed this issue · 2 comments

Hi there,
Thanks for this little tool.

I was wondering if it is possible at all to allow for the dynamic coloring of the raw svg ids ?

something that i used to use a ('xmldom).DOMParser to do

i have a render function that does all the magic and this is what it looks like

  • the highlights are dynamically generated by the parent component and passed as props.
  • not sure how would this particular task can be solved using the @nuxt/svg
import Vue from 'vue'
const DOMParser = process.browser
  ? window.DOMParser
  : require('xmldom').DOMParser
const parser = new DOMParser()

Vue.component('svg-inline', {
  name: 'SvgInline',
  props: {
    src: {
      type: String,
      required: true
    },
    highlights: {
      type: Array,
      default: () => []
    }
  },
  render(h) {
    const document = parser.parseFromString(this.src, 'text/xml')
    const svg = document.getElementsByTagName('svg')[0]
    const attrs = {}

    Array.prototype.forEach.call(svg.attributes, attribute => {
      attrs[attribute.nodeName] = attribute.nodeValue
    })
    if (document.getElementById('LAYER_EFO')) {
      let tempArr = [...document.getElementById('LAYER_EFO').children]
      tempArr.forEach(el => el.setAttribute('fill', 'none'))
      let children = tempArr.filter(el => this.highlights.includes(el.id))
      children.forEach(el => {
        el.setAttribute('fill', 'orangered')
      })
    }

    return h('svg', {
      ...this.data,
      attrs,
      domProps: {
        innerHTML: svg.innerHTML
      }
    })
  }
})

with all the latest libs (nuxt, etc ...)

const svg = document.getElementsByTagName('svg')[0]

is null and so the function dies

the nuxt.config.js has the following rules

 const vueLoader = config.module.rules.find(function (module) {
        return module.test.toString() === '/\\.vue$/i'
      })
      // Remove SVG from default rules
      config.module.rules.forEach(rule => {
        if (rule.test.toString() === '/\\.(png|jpe?g|gif|svg|webp)$/i') {
          rule.test = /\.(png|jpe?g|gif|webp)$/i
        }
      })
      // Add svg inline loader configuration
      config.module.rules.push({
        test: /\.svg$/,
        loader: 'svg-inline-loader'
      })
      // Important to apply transforms on svg-inline:src
      vueLoader.options.transformAssetUrls['svg-inline'] = 'src'

so not sure how to adapt the existing rules to add this new one, even as a different param ?

i have solved the issue but perhaps you would be willing to include it as an option with props ?

updateIds(ids) {
      if (document.getElementById('Some Parent Id')) {
        let tempArr = [...document.getElementById('Some Parent Id').children]
        tempArr.forEach(el => el.setAttribute('fill', 'none'))
        let children = tempArr.filter(el => ids.includes(el.id))
        children.forEach(el => {
          el.setAttribute('fill', 'orangered')
        })
      }
    }