diff --git a/index.js b/index.js
index 20107ac6..18962cf8 100644
--- a/index.js
+++ b/index.js
@@ -1,4 +1,4 @@
-import React, {Component} from "react";
+import React, {Component, useState, useEffect} from "react";
import {View} from 'react-native';
import PropTypes from 'prop-types'
import xmldom from 'xmldom';
@@ -78,170 +78,98 @@ function fixYPosition (y, node) {
return fixYPosition(y, node.parentNode)
}
-class SvgUri extends Component{
+const SvgUri = (props) => {
- constructor(props){
- super(props);
+ const [fill, setFill] = useState(props.fill)
+ const [source, setSource] = useState(props.source)
+ const [svgXmlData, setSvgXmlData] = useState(props.svgXmlData)
+ const [isComponentMounted, setIsComponentMounted] = useState(false)
- this.state = {fill: props.fill, svgXmlData: props.svgXmlData};
-
- this.createSVGElement = this.createSVGElement.bind(this);
- this.obtainComponentAtts = this.obtainComponentAtts.bind(this);
- this.inspectNode = this.inspectNode.bind(this);
- this.fetchSVGData = this.fetchSVGData.bind(this);
-
- this.isComponentMounted = false;
-
- // Gets the image data from an URL or a static file
- if (props.source) {
- const source = resolveAssetSource(props.source) || {};
- this.fetchSVGData(source.uri);
- }
- }
-
- componentWillMount() {
- this.isComponentMounted = true;
- }
-
- componentWillReceiveProps (nextProps){
- if (nextProps.source) {
- const source = resolveAssetSource(nextProps.source) || {};
- const oldSource = resolveAssetSource(this.props.source) || {};
- if(source.uri !== oldSource.uri){
- this.fetchSVGData(source.uri);
- }
- }
-
- if (nextProps.svgXmlData !== this.props.svgXmlData) {
- this.setState({ svgXmlData: nextProps.svgXmlData });
- }
-
- if (nextProps.fill !== this.props.fill) {
- this.setState({ fill: nextProps.fill });
- }
- }
-
- componentWillUnmount() {
- this.isComponentMounted = false
- }
-
- async fetchSVGData(uri) {
- let responseXML = null, error = null;
- try {
- const response = await fetch(uri);
- responseXML = await response.text();
- } catch(e) {
- error = e;
- console.error("ERROR SVG", e);
- } finally {
- if (this.isComponentMounted) {
- this.setState({ svgXmlData: responseXML }, () => {
- const { onLoad } = this.props;
- if (onLoad && !error) {
- onLoad();
- }
- });
- }
- }
-
- return responseXML;
- }
-
- // Remove empty strings from children array
- trimElementChilden(children) {
- for (child of children) {
- if (typeof child === 'string') {
- if (child.trim().length === 0)
- children.splice(children.indexOf(child), 1);
- }
- }
- }
-
- createSVGElement(node, childs){
- this.trimElementChilden(childs);
+ const createSVGElement = (node, childs) => {
+ const children = trimElementChilden(childs);
let componentAtts = {};
const i = ind++;
switch (node.nodeName) {
- case 'svg':
- componentAtts = this.obtainComponentAtts(node, SVG_ATTS);
- if (this.props.width) {
- componentAtts.width = this.props.width;
- }
- if (this.props.height) {
- componentAtts.height = this.props.height;
- }
+ case 'svg':
+ componentAtts = obtainComponentAtts(node, SVG_ATTS);
+ if (props.width) {
+ componentAtts.width = props.width;
+ }
+ if (props.height) {
+ componentAtts.height = props.height;
+ }
- return ;
- case 'g':
- componentAtts = this.obtainComponentAtts(node, G_ATTS);
- return {childs};
- case 'path':
- componentAtts = this.obtainComponentAtts(node, PATH_ATTS);
- return {childs};
- case 'circle':
- componentAtts = this.obtainComponentAtts(node, CIRCLE_ATTS);
- return {childs};
- case 'rect':
- componentAtts = this.obtainComponentAtts(node, RECT_ATTS);
- return {childs};
- case 'line':
- componentAtts = this.obtainComponentAtts(node, LINE_ATTS);
- return {childs};
- case 'defs':
- return {childs};
- case 'linearGradient':
- componentAtts = this.obtainComponentAtts(node, LINEARG_ATTS);
- return {childs};
- case 'radialGradient':
- componentAtts = this.obtainComponentAtts(node, RADIALG_ATTS);
- return {childs};
- case 'stop':
- componentAtts = this.obtainComponentAtts(node, STOP_ATTS);
- return {childs};
- case 'ellipse':
- componentAtts = this.obtainComponentAtts(node, ELLIPSE_ATTS);
- return {childs};
- case 'polygon':
- componentAtts = this.obtainComponentAtts(node, POLYGON_ATTS);
- return {childs};
- case 'polyline':
- componentAtts = this.obtainComponentAtts(node, POLYLINE_ATTS);
- return {childs};
- case 'text':
- componentAtts = this.obtainComponentAtts(node, TEXT_ATTS);
- return {childs};
- case 'tspan':
- componentAtts = this.obtainComponentAtts(node, TEXT_ATTS);
- if (componentAtts.y) {
- componentAtts.y = fixYPosition(componentAtts.y, node)
- }
- return {childs};
- default:
- return null;
+ return ;
+ case 'g':
+ componentAtts = obtainComponentAtts(node, G_ATTS);
+ return {childs};
+ case 'path':
+ componentAtts = obtainComponentAtts(node, PATH_ATTS);
+ return {childs};
+ case 'circle':
+ componentAtts = obtainComponentAtts(node, CIRCLE_ATTS);
+ return {childs};
+ case 'rect':
+ componentAtts = obtainComponentAtts(node, RECT_ATTS);
+ return {childs};
+ case 'line':
+ componentAtts = obtainComponentAtts(node, LINE_ATTS);
+ return {childs};
+ case 'defs':
+ return {childs};
+ case 'linearGradient':
+ componentAtts = obtainComponentAtts(node, LINEARG_ATTS);
+ return {childs};
+ case 'radialGradient':
+ componentAtts = obtainComponentAtts(node, RADIALG_ATTS);
+ return {childs};
+ case 'stop':
+ componentAtts = obtainComponentAtts(node, STOP_ATTS);
+ return {childs};
+ case 'ellipse':
+ componentAtts = obtainComponentAtts(node, ELLIPSE_ATTS);
+ return {childs};
+ case 'polygon':
+ componentAtts = obtainComponentAtts(node, POLYGON_ATTS);
+ return {childs};
+ case 'polyline':
+ componentAtts = obtainComponentAtts(node, POLYLINE_ATTS);
+ return {childs};
+ case 'text':
+ componentAtts = obtainComponentAtts(node, TEXT_ATTS);
+ return {childs};
+ case 'tspan':
+ componentAtts = obtainComponentAtts(node, TEXT_ATTS);
+ if (componentAtts.y) {
+ componentAtts.y = fixYPosition(componentAtts.y, node)
+ }
+ return {childs};
+ default:
+ return null;
}
}
- obtainComponentAtts({attributes}, enabledAttributes) {
+ const obtainComponentAtts = ({attributes}, enabledAttributes) => {
const styleAtts = {};
- if (this.state.fill && this.props.fillAll) {
- styleAtts.fill = this.state.fill;
+ if (fill && props.fillAll) {
+ styleAtts.fill = fill;
}
Array.from(attributes).forEach(({nodeName, nodeValue}) => {
Object.assign(styleAtts, utils.transformStyle({
nodeName,
nodeValue,
- fillProp: this.state.fill
+ fillProp: fill
}));
});
- const componentAtts = Array.from(attributes)
+ const componentAtts = Array.from(attributes)
.map(utils.camelCaseNodeName)
.map(utils.removePixelsFromNodeValue)
.filter(utils.getEnabledAttributes(enabledAttributes.concat(COMMON_ATTS)))
.reduce((acc, {nodeName, nodeValue}) => {
- acc[nodeName] = (this.state.fill && nodeName === 'fill' && nodeValue !== 'none') ? this.state.fill : nodeValue
+ acc[nodeName] = (fill && nodeName === 'fill' && nodeValue !== 'none') ? fill : nodeValue
return acc
}, {});
Object.assign(componentAtts, styleAtts);
@@ -249,7 +177,7 @@ class SvgUri extends Component{
return componentAtts;
}
- inspectNode(node){
+ const inspectNode = (node) => {
// Only process accepted elements
if (!ACCEPTED_SVG_ELEMENTS.includes(node.nodeName)) {
return ();
@@ -261,47 +189,86 @@ class SvgUri extends Component{
// if have children process them.
// Recursive function.
if (node.childNodes && node.childNodes.length > 0){
- for (let i = 0; i < node.childNodes.length; i++){
- const isTextValue = node.childNodes[i].nodeValue
- if (isTextValue) {
- arrayElements.push(node.childNodes[i].nodeValue)
- } else {
- const nodo = this.inspectNode(node.childNodes[i]);
- if (nodo != null) {
- arrayElements.push(nodo);
- }
+ for (let i = 0; i < node.childNodes.length; i++){
+ const isTextValue = node.childNodes[i].nodeValue
+ if (isTextValue) {
+ arrayElements.push(node.childNodes[i].nodeValue)
+ } else {
+ const nodo = inspectNode(node.childNodes[i]);
+ if (nodo != null) {
+ arrayElements.push(nodo);
}
}
+ }
+ }
+
+ return createSVGElement(node, arrayElements);
+ }
+
+ const fetchSVGData = async(uri) => {
+ let responseXML = null, error = null;
+ try {
+ const response = await fetch(uri);
+ responseXML = await response.text();
+ } catch(e) {
+ error = e;
+ console.error("ERROR SVG", e);
+ } finally {
+ setSvgXmlData(responseXML)
}
+ }
- return this.createSVGElement(node, arrayElements);
+ const trimElementChilden = (children) => {
+ for (child of children) {
+ if (typeof child === 'string') {
+ if (child.trim().length === 0)
+ children.splice(children.indexOf(child), 1);
+ }
+ }
+ return children
}
- render () {
+ useEffect(() => {
+ if (props.source) {
+ const src = resolveAssetSource(props.source) || {};
+ if(src.uri){
+ fetchSVGData(src.uri)
+ }
+ }
+
+ if (props.fill) {
+ setFill(props.fill)
+ }
+
+ }, [props.source])
+
+ const renderSvgElement = () => {
try {
- if (this.state.svgXmlData == null) {
+ if (svgXmlData == null) {
return null;
}
- const inputSVG = this.state.svgXmlData.substring(
- this.state.svgXmlData.indexOf("