I'm using babel-plugin-inline-react-svg
to import SVGs and use them as react components. The problem is i need to embed these SVGs inside another SVG. I'd like to convert the root tag svg
to symbol
. When I import the SVG as is, what results is nested SVG tags. Which technically works, but not without many quirks for my target implementation (phantomjs). I'd rather use use xlink:href
, but i'd need to convert the root element generated by the 3rd party lib to have tag name symbol
Here's some fictitious usage
import Flag from 'images/icons/flag.svg'
export default () => {
return (
<svg>
<Flag/>
<text>Foo</text>
</svg>
)
}
What this renders is
<svg>
<svg>
<!-- contents of svg -->
</svg>
<text>Foo</text>
</svg>
What i'd like to be able to do is
import Flag from 'images/icons/flag.svg'
export default () => {
return (
<svg>
<defs>
<Flag as="symbol" id="flag"/>
</defs>
<use xlinkHref="#flag"/>
<text>Foo</text>
</svg>
)
}
It must be a really common use-case to have to change the tagName of the root element of a 3rd party library. If nothing, but just adding aria tags, using semantic element names, so on..
How can I change the tagName of a react component i have no control over?
I ended up using a Higher Order Component to intercept the ReactDOMElement coming from the 3rd party lib. I switched the type
of the element before it renders. Inspired heavily by https://github.com/pwmckenna/react-transform-style/blob/master/src/index.js
const TransformTag = (Component, tagName) => {
const ModifiedComponent = Component
const isFn = (typeof(Component) === 'function')
const render = isFn ? ModifiedComponent : ModifiedComponent.render
const modifiedRender = function() {
const {
props,
...renderedRest
} = render.apply(this, arguments)
renderedRest.type = tagName // this is the magic
return {
props,
...renderedRest
}
}
if (isFn) {
return modifiedRender
} else {
ModifiedComponent.prototype.render = modifiedRender
return ModifiedComponent
}
}
// usage
export default SvgQuote = () => {
return (
<svg>
<defs>
{ TransformTag(Bill, 'symbol') }
</defs>
</svg>
)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.