UNPKG

6.74 kBJavaScriptView Raw
1import _extends from '@babel/runtime/helpers/extends';
2import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/objectWithoutPropertiesLoose';
3import _inheritsLoose from '@babel/runtime/helpers/inheritsLoose';
4import { SVGInjector } from '@tanem/svg-injector';
5import * as PropTypes from 'prop-types';
6import * as React from 'react';
7
8// Hat-tip: https://github.com/developit/preact-compat/blob/master/src/index.js#L402.
9var shallowDiffers = function shallowDiffers(a, b) {
10 for (var i in a) {
11 if (!(i in b)) {
12 return true;
13 }
14 }
15
16 for (var _i in b) {
17 if (a[_i] !== b[_i]) {
18 return true;
19 }
20 }
21
22 return false;
23};
24
25var _excluded = ["afterInjection", "beforeInjection", "evalScripts", "fallback", "loading", "renumerateIRIElements", "src", "useRequestCache", "wrapper"];
26var svgNamespace = 'http://www.w3.org/2000/svg';
27var xlinkNamespace = 'http://www.w3.org/1999/xlink';
28var ReactSVG = /*#__PURE__*/function (_React$Component) {
29 _inheritsLoose(ReactSVG, _React$Component);
30
31 function ReactSVG() {
32 var _this;
33
34 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
35 args[_key] = arguments[_key];
36 }
37
38 _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
39 _this.initialState = {
40 hasError: false,
41 isLoading: true
42 };
43 _this.state = _this.initialState;
44 _this._isMounted = false;
45 _this.reactWrapper = void 0;
46 _this.nonReactWrapper = void 0;
47
48 _this.refCallback = function (reactWrapper) {
49 _this.reactWrapper = reactWrapper;
50 };
51
52 return _this;
53 }
54
55 var _proto = ReactSVG.prototype;
56
57 _proto.renderSVG = function renderSVG() {
58 var _this2 = this;
59
60 /* istanbul ignore else */
61 if (this.reactWrapper instanceof Node) {
62 var _this$props = this.props,
63 beforeInjection = _this$props.beforeInjection,
64 evalScripts = _this$props.evalScripts,
65 renumerateIRIElements = _this$props.renumerateIRIElements,
66 src = _this$props.src,
67 useRequestCache = _this$props.useRequestCache;
68 /* eslint-disable @typescript-eslint/no-non-null-assertion */
69
70 var afterInjection = this.props.afterInjection;
71 var wrapper = this.props.wrapper;
72 /* eslint-enable @typescript-eslint/no-non-null-assertion */
73
74 var nonReactWrapper;
75 var nonReactTarget;
76
77 if (wrapper === 'svg') {
78 nonReactWrapper = document.createElementNS(svgNamespace, wrapper);
79 nonReactWrapper.setAttribute('xmlns', svgNamespace);
80 nonReactWrapper.setAttribute('xmlns:xlink', xlinkNamespace);
81 nonReactTarget = document.createElementNS(svgNamespace, wrapper);
82 } else {
83 nonReactWrapper = document.createElement(wrapper);
84 nonReactTarget = document.createElement(wrapper);
85 }
86
87 nonReactWrapper.appendChild(nonReactTarget);
88 nonReactTarget.dataset.src = src;
89 this.nonReactWrapper = this.reactWrapper.appendChild(nonReactWrapper);
90
91 var afterEach = function afterEach(error, svg) {
92 if (error) {
93 _this2.removeSVG();
94
95 if (!_this2._isMounted) {
96 afterInjection(error);
97 return;
98 }
99 } // TODO (Tane): It'd be better to cleanly unsubscribe from SVGInjector
100 // callbacks instead of tracking a property like this.
101
102
103 if (_this2._isMounted) {
104 _this2.setState(function () {
105 return {
106 hasError: !!error,
107 isLoading: false
108 };
109 }, function () {
110 afterInjection(error, svg);
111 });
112 }
113 };
114
115 SVGInjector(nonReactTarget, {
116 afterEach: afterEach,
117 beforeEach: beforeInjection,
118 cacheRequests: useRequestCache,
119 evalScripts: evalScripts,
120 renumerateIRIElements: renumerateIRIElements
121 });
122 }
123 };
124
125 _proto.removeSVG = function removeSVG() {
126 var _this$nonReactWrapper;
127
128 if ((_this$nonReactWrapper = this.nonReactWrapper) != null && _this$nonReactWrapper.parentNode) {
129 this.nonReactWrapper.parentNode.removeChild(this.nonReactWrapper);
130 this.nonReactWrapper = null;
131 }
132 };
133
134 _proto.componentDidMount = function componentDidMount() {
135 this._isMounted = true;
136 this.renderSVG();
137 };
138
139 _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
140 var _this3 = this;
141
142 if (shallowDiffers(prevProps, this.props)) {
143 this.setState(function () {
144 return _this3.initialState;
145 }, function () {
146 _this3.removeSVG();
147
148 _this3.renderSVG();
149 });
150 }
151 };
152
153 _proto.componentWillUnmount = function componentWillUnmount() {
154 this._isMounted = false;
155 this.removeSVG();
156 };
157
158 _proto.render = function render() {
159 /* eslint-disable @typescript-eslint/no-unused-vars */
160 var _this$props2 = this.props;
161 _this$props2.afterInjection;
162 _this$props2.beforeInjection;
163 _this$props2.evalScripts;
164 var Fallback = _this$props2.fallback,
165 Loading = _this$props2.loading;
166 _this$props2.renumerateIRIElements;
167 _this$props2.src;
168 _this$props2.useRequestCache;
169 var wrapper = _this$props2.wrapper,
170 rest = _objectWithoutPropertiesLoose(_this$props2, _excluded);
171 /* eslint-enable @typescript-eslint/no-unused-vars */
172 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
173
174
175 var Wrapper = wrapper;
176 return /*#__PURE__*/React.createElement(Wrapper, _extends({}, rest, {
177 ref: this.refCallback
178 }, wrapper === 'svg' ? {
179 xmlns: svgNamespace,
180 xmlnsXlink: xlinkNamespace
181 } : {}), this.state.isLoading && Loading && /*#__PURE__*/React.createElement(Loading, null), this.state.hasError && Fallback && /*#__PURE__*/React.createElement(Fallback, null));
182 };
183
184 return ReactSVG;
185}(React.Component);
186ReactSVG.defaultProps = {
187 afterInjection: function afterInjection() {
188 return undefined;
189 },
190 beforeInjection: function beforeInjection() {
191 return undefined;
192 },
193 evalScripts: 'never',
194 fallback: null,
195 loading: null,
196 renumerateIRIElements: true,
197 useRequestCache: true,
198 wrapper: 'div'
199};
200ReactSVG.propTypes = {
201 afterInjection: PropTypes.func,
202 beforeInjection: PropTypes.func,
203 evalScripts: PropTypes.oneOf(['always', 'once', 'never']),
204 fallback: PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.string]),
205 loading: PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.string]),
206 renumerateIRIElements: PropTypes.bool,
207 src: PropTypes.string.isRequired,
208 useRequestCache: PropTypes.bool,
209 wrapper: PropTypes.oneOf(['div', 'span', 'svg'])
210} ;
211
212export { ReactSVG };
213//# sourceMappingURL=react-svg.esm.js.map