├── .babelrc
├── .editorconfig
├── .eslintrc
├── .gitignore
├── .travis.yml
├── README.md
├── dist
├── index.es.js
├── index.es.js.map
├── index.js
└── index.js.map
├── example
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── ship.sh
├── src
│ ├── App.js
│ ├── index.css
│ └── index.js
├── yarn-error.log
└── yarn.lock
├── imgs
└── intro.png
├── package.json
├── rollup.config.js
├── src
├── .eslintrc
├── Favicons
│ ├── Donut.js
│ ├── Exception.js
│ ├── Pie.js
│ └── Success.js
├── index.js
├── styles.css
├── test.js
└── utils
│ ├── NoSSR.js
│ └── index.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "modules": false
5 | }],
6 | "stage-0",
7 | "react"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": [
4 | "standard",
5 | "standard-react"
6 | ],
7 | "env": {
8 | "es6": true
9 | },
10 | "plugins": [
11 | "react"
12 | ],
13 | "parserOptions": {
14 | "sourceType": "module"
15 | },
16 | "rules": {
17 | // don't force es6 functions to include space before paren
18 | "space-before-function-paren": 0,
19 |
20 | // allow specifying true explicitly for boolean props
21 | "react/jsx-boolean-value": 0
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | build/
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 9
4 | - 8
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-loadcon
2 |
3 | > React component to manipulate the favicon, as a loading or progress indicator, for now. The idea of "Favicon as DOM" is under construction.
4 |
5 | [](https://www.npmjs.com/package/react-loadcon) [](https://standardjs.com)
6 |
7 | 
8 |
9 | ## Why bother?
10 |
11 | When it comes to a huge file loading or download in a tab, a tiny progress indicator on favicon could be an interesting but also considerate UX experience. The idea comes from a long time ago and has been realized by so many open-source developers, and it comes back to me when try to solve this [good first issue](https://github.com/mozilla/send/issues/803) for the Mozilla Send.
12 |
13 | So here is React-LoadCon for React community, now this tiny project can only use canvas to draw dynamic images and replace the tag, which is extremely tedious, but it plans to be a more general tool to offer `Favicon as DOM`. [dom-to-img](https://github.com/tsayen/dom-to-image) could be introduced to simplify the covert process.
14 |
15 | [Live Demo Here](https://foreseaz.github.io/react-loadcon/)
16 |
17 | And if you find the idea interesting, [](https://spectrum.chat/favicon)
18 |
19 |
20 | ## 🚀 Installation
21 |
22 | ```bash
23 | npm install --save react-loadcon
24 | ```
25 | or
26 | ```bash
27 | yarn add react-loadcon
28 | ```
29 |
30 | ## 🖲 Usage
31 |
32 | Put `` anywhere, even in your SSR components (LoadCon would only trigger after `componentDidMount`).
33 |
34 | ```JavaScript
35 |
36 | ```
37 |
38 | Full example with async function, and show `Success` or `Exception` afterwards.
39 |
40 | ```JavaScript
41 | import React, { Component } from 'react'
42 | import LoadCon from 'react-loadcon'
43 |
44 | export default class ExampleComponent extends Component {
45 | state = {
46 | percentage: 0, // isRequired
47 | status: 'normal', // oneOf(['normal', 'active', 'exception', 'success'])
48 | type: 'pie', // oneOf(['pie', 'donut'])
49 | }
50 |
51 | componentDidMount () {
52 | this.apiCall()
53 | }
54 |
55 | apiCall = () => {
56 | this.setState({ status: 'active' })
57 | fetch(url)
58 | .then(res => return res.json())
59 | .then(data => {
60 | // normal loading
61 | this.setState({ status: 'normal' })
62 |
63 | // loading with success
64 | this.setState({ status: 'success' })
65 | setTimeout(() => {
66 | this.setState({ status: 'normal' })
67 | }, 1500)
68 | })
69 | .catch(e => {
70 | this.setState({ status: 'exception' })
71 | setTimeout(() => {
72 | this.setState({ status: 'normal' })
73 | }, 1500)
74 | })
75 | }
76 |
77 | render () {
78 | return (
79 |
84 | )
85 | }
86 | }
87 | ```
88 |
89 | ## 🧬 Props
90 |
91 | OPTION | TYPE | DEFAULT | DESCRIPTION
92 | ------ | ---- | ------- | -----------
93 | percentage | `number` | `0` | the percentage of loading progress for LoadCon
94 | type | `oneOf(['pie', 'donut'])` | `pie` | the theme of LoadCon, now has `PieCon` and `DonutCon`, and more themes will be added soon
95 | status | `oneOf(['normal', 'active', 'exception', 'success'])` | `normal` | load status of LoadCon, `normal` reset to default favicon, `active` set LoadCon according to the type prop, `exception` set ErrorCon and `success` set SuccessCon.
96 | color | `string` |  `#25c639` | color of loading indicator in hash format.
97 | background | `string` |  `#eee` | color of background in hash format.
98 | shadow | `string` |  `#fff` | color of 2 pixals border in hash format
99 | donutWidth | `number` | `8` | width of DonutCon indicator.
100 |
101 |
102 | ## 📝 License
103 |
104 | MIT © [foreseaz](https://github.com/foreseaz)
105 |
--------------------------------------------------------------------------------
/dist/index.es.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | var isArray = Array.isArray;
5 | var keyList = Object.keys;
6 | var hasProp = Object.prototype.hasOwnProperty;
7 | var hasElementType = typeof Element !== 'undefined';
8 |
9 | function equal(a, b) {
10 | // fast-deep-equal index.js 2.0.1
11 | if (a === b) return true;
12 |
13 | if (a && b && typeof a == 'object' && typeof b == 'object') {
14 | var arrA = isArray(a)
15 | , arrB = isArray(b)
16 | , i
17 | , length
18 | , key;
19 |
20 | if (arrA && arrB) {
21 | length = a.length;
22 | if (length != b.length) return false;
23 | for (i = length; i-- !== 0;)
24 | if (!equal(a[i], b[i])) return false;
25 | return true;
26 | }
27 |
28 | if (arrA != arrB) return false;
29 |
30 | var dateA = a instanceof Date
31 | , dateB = b instanceof Date;
32 | if (dateA != dateB) return false;
33 | if (dateA && dateB) return a.getTime() == b.getTime();
34 |
35 | var regexpA = a instanceof RegExp
36 | , regexpB = b instanceof RegExp;
37 | if (regexpA != regexpB) return false;
38 | if (regexpA && regexpB) return a.toString() == b.toString();
39 |
40 | var keys = keyList(a);
41 | length = keys.length;
42 |
43 | if (length !== keyList(b).length)
44 | return false;
45 |
46 | for (i = length; i-- !== 0;)
47 | if (!hasProp.call(b, keys[i])) return false;
48 | // end fast-deep-equal
49 |
50 | // start react-fast-compare
51 | // custom handling for DOM elements
52 | if (hasElementType && a instanceof Element && b instanceof Element)
53 | return a === b;
54 |
55 | // custom handling for React
56 | for (i = length; i-- !== 0;) {
57 | key = keys[i];
58 | if (key === '_owner' && a.$$typeof) {
59 | // React-specific: avoid traversing React elements' _owner.
60 | // _owner contains circular references
61 | // and is not needed when comparing the actual elements (and not their owners)
62 | // .$$typeof and ._store on just reasonable markers of a react element
63 | continue;
64 | } else {
65 | // all other properties should be traversed as usual
66 | if (!equal(a[key], b[key])) return false;
67 | }
68 | }
69 | // end react-fast-compare
70 |
71 | // fast-deep-equal index.js 2.0.1
72 | return true;
73 | }
74 |
75 | return a !== a && b !== b;
76 | }
77 | // end fast-deep-equal
78 |
79 | var reactFastCompare = function exportedEqual(a, b) {
80 | try {
81 | return equal(a, b);
82 | } catch (error) {
83 | if ((error.message && error.message.match(/stack|recursion/i)) || (error.number === -2146828260)) {
84 | // warn on circular references, don't crash
85 | // browsers give this different errors name and messages:
86 | // chrome/safari: "RangeError", "Maximum call stack size exceeded"
87 | // firefox: "InternalError", too much recursion"
88 | // edge: "Error", "Out of stack space"
89 | console.warn('Warning: react-fast-compare does not handle circular references.', error.name, error.message);
90 | return false;
91 | }
92 | // some other error. we should definitely know about these
93 | throw error;
94 | }
95 | };
96 |
97 | var classCallCheck = function (instance, Constructor) {
98 | if (!(instance instanceof Constructor)) {
99 | throw new TypeError("Cannot call a class as a function");
100 | }
101 | };
102 |
103 | var createClass = function () {
104 | function defineProperties(target, props) {
105 | for (var i = 0; i < props.length; i++) {
106 | var descriptor = props[i];
107 | descriptor.enumerable = descriptor.enumerable || false;
108 | descriptor.configurable = true;
109 | if ("value" in descriptor) descriptor.writable = true;
110 | Object.defineProperty(target, descriptor.key, descriptor);
111 | }
112 | }
113 |
114 | return function (Constructor, protoProps, staticProps) {
115 | if (protoProps) defineProperties(Constructor.prototype, protoProps);
116 | if (staticProps) defineProperties(Constructor, staticProps);
117 | return Constructor;
118 | };
119 | }();
120 |
121 | var inherits = function (subClass, superClass) {
122 | if (typeof superClass !== "function" && superClass !== null) {
123 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
124 | }
125 |
126 | subClass.prototype = Object.create(superClass && superClass.prototype, {
127 | constructor: {
128 | value: subClass,
129 | enumerable: false,
130 | writable: true,
131 | configurable: true
132 | }
133 | });
134 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
135 | };
136 |
137 | var possibleConstructorReturn = function (self, call) {
138 | if (!self) {
139 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
140 | }
141 |
142 | return call && (typeof call === "object" || typeof call === "function") ? call : self;
143 | };
144 |
145 | var DefaultOnSSR = function DefaultOnSSR() {
146 | return React.createElement('span', null);
147 | };
148 |
149 | var NoSSR = function (_Component) {
150 | inherits(NoSSR, _Component);
151 |
152 | function NoSSR() {
153 | var _ref;
154 |
155 | var _temp, _this, _ret;
156 |
157 | classCallCheck(this, NoSSR);
158 |
159 | for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
160 | args[_key] = arguments[_key];
161 | }
162 |
163 | return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = NoSSR.__proto__ || Object.getPrototypeOf(NoSSR)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
164 | canRender: false
165 | }, _temp), possibleConstructorReturn(_this, _ret);
166 | }
167 |
168 | createClass(NoSSR, [{
169 | key: 'componentDidMount',
170 | value: function componentDidMount() {
171 | this.setState({ canRender: true });
172 | }
173 | }, {
174 | key: 'render',
175 | value: function render() {
176 | var _props = this.props,
177 | children = _props.children,
178 | _props$onSSR = _props.onSSR,
179 | onSSR = _props$onSSR === undefined ? React.createElement(DefaultOnSSR, null) : _props$onSSR;
180 |
181 |
182 | return React.createElement(
183 | React.Fragment,
184 | null,
185 | this.state.canRender ? children : onSSR
186 | );
187 | }
188 | }]);
189 | return NoSSR;
190 | }(Component);
191 |
192 | var getIsRetina = function getIsRetina() {
193 | return window.devicePixelRatio > 1;
194 | };
195 |
196 | var getFaviconURL = function getFaviconURL() {
197 | var links = document.getElementsByTagName('link');
198 | var tag = null;
199 |
200 | for (var i = 0, l = links.length; i < l; i++) {
201 | if (links[i].getAttribute('rel') === 'icon' || links[i].getAttribute('rel') === 'shortcut icon') {
202 | tag = links[i];
203 | }
204 | }
205 |
206 | return tag ? tag.getAttribute('href') : '/favicon.ico';
207 | };
208 |
209 | var removeFaviconTag = function removeFaviconTag() {
210 | var links = Array.prototype.slice.call(document.getElementsByTagName('link'), 0);
211 | var head = document.getElementsByTagName('head')[0];
212 |
213 | for (var i = 0, l = links.length; i < l; i++) {
214 | if (links[i].getAttribute('rel') === 'icon' || links[i].getAttribute('rel') === 'shortcut icon') {
215 | head.removeChild(links[i]);
216 | }
217 | }
218 | };
219 |
220 | var setFaviconTag = function setFaviconTag(url) {
221 | removeFaviconTag();
222 |
223 | var link = document.createElement('link');
224 | link.type = 'image/x-icon';
225 | link.rel = 'icon';
226 | link.href = url;
227 |
228 | document.getElementsByTagName('head')[0].appendChild(link);
229 | };
230 |
231 | var getCanvas = function getCanvas() {
232 | var canvas = document.createElement("canvas");
233 | if (getIsRetina()) {
234 | canvas.width = 32;
235 | canvas.height = 32;
236 | } else {
237 | canvas.width = 16;
238 | canvas.height = 16;
239 | }
240 |
241 | return canvas;
242 | };
243 |
244 | var Pie = function (_React$Component) {
245 | inherits(Pie, _React$Component);
246 |
247 | function Pie() {
248 | classCallCheck(this, Pie);
249 | return possibleConstructorReturn(this, (Pie.__proto__ || Object.getPrototypeOf(Pie)).apply(this, arguments));
250 | }
251 |
252 | createClass(Pie, [{
253 | key: 'componentDidMount',
254 | value: function componentDidMount() {
255 | this.drawFavicon();
256 | }
257 | }, {
258 | key: 'componentDidUpdate',
259 | value: function componentDidUpdate(prevProps) {
260 | var isPropsChanged = !reactFastCompare(this.props, prevProps);
261 | if (isPropsChanged) {
262 | this.drawFavicon();
263 | }
264 | }
265 | }, {
266 | key: 'drawFavicon',
267 | value: function drawFavicon() {
268 | var _props = this.props,
269 | percentage = _props.percentage,
270 | color = _props.color,
271 | background = _props.background,
272 | shadow = _props.shadow;
273 |
274 | var canvas = getCanvas();
275 | var ctx = canvas.getContext('2d');
276 |
277 | if (ctx) {
278 | ctx.clearRect(0, 0, canvas.width, canvas.height);
279 |
280 | // Draw shadow
281 | ctx.beginPath();
282 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
283 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false);
284 | ctx.fillStyle = shadow;
285 | ctx.fill();
286 |
287 | // Draw background
288 | ctx.beginPath();
289 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
290 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false);
291 | ctx.fillStyle = background;
292 | ctx.fill();
293 |
294 | // Draw pie
295 | if (percentage > 0) {
296 | ctx.beginPath();
297 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
298 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, -0.5 * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false);
299 | ctx.lineTo(canvas.width / 2, canvas.height / 2);
300 | ctx.fillStyle = color;
301 | ctx.fill();
302 | }
303 | }
304 |
305 | setFaviconTag(canvas.toDataURL());
306 | }
307 | }, {
308 | key: 'render',
309 | value: function render() {
310 | return null;
311 | }
312 | }]);
313 | return Pie;
314 | }(React.Component);
315 |
316 | Pie.propTypes = {
317 | percentage: PropTypes.number,
318 | color: PropTypes.string,
319 | background: PropTypes.string,
320 | shadow: PropTypes.string
321 | };
322 |
323 | var Donut = function (_React$Component) {
324 | inherits(Donut, _React$Component);
325 |
326 | function Donut() {
327 | classCallCheck(this, Donut);
328 | return possibleConstructorReturn(this, (Donut.__proto__ || Object.getPrototypeOf(Donut)).apply(this, arguments));
329 | }
330 |
331 | createClass(Donut, [{
332 | key: 'componentDidMount',
333 | value: function componentDidMount() {
334 | this.drawFavicon();
335 | }
336 | }, {
337 | key: 'componentDidUpdate',
338 | value: function componentDidUpdate(prevProps) {
339 | var isPropsChanged = !reactFastCompare(this.props, prevProps);
340 | if (isPropsChanged) {
341 | this.drawFavicon();
342 | }
343 | }
344 | }, {
345 | key: 'drawFavicon',
346 | value: function drawFavicon() {
347 | var _props = this.props,
348 | donutWidth = _props.donutWidth,
349 | percentage = _props.percentage,
350 | color = _props.color,
351 | background = _props.background,
352 | shadow = _props.shadow;
353 |
354 | var canvas = getCanvas();
355 | var ctx = canvas.getContext('2d');
356 |
357 | if (ctx) {
358 | ctx.clearRect(0, 0, canvas.width, canvas.height);
359 |
360 | // Draw shadow
361 | ctx.beginPath();
362 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
363 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false);
364 | ctx.fillStyle = shadow;
365 | ctx.fill();
366 |
367 | // Draw background
368 | ctx.beginPath();
369 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
370 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false);
371 | ctx.fillStyle = background;
372 | ctx.fill();
373 |
374 | // Draw donut
375 | if (percentage > 0) {
376 | ctx.beginPath();
377 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
378 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, -0.5 * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false);
379 | ctx.lineTo(canvas.width / 2, canvas.height / 2);
380 | ctx.fillStyle = color;
381 | ctx.fill();
382 |
383 | ctx.beginPath();
384 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
385 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - donutWidth, -0.5 * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false);
386 | ctx.lineTo(canvas.width / 2, canvas.height / 2);
387 | ctx.fillStyle = background;
388 | ctx.fill();
389 | }
390 | }
391 |
392 | setFaviconTag(canvas.toDataURL());
393 | }
394 | }, {
395 | key: 'render',
396 | value: function render() {
397 | return null;
398 | }
399 | }]);
400 | return Donut;
401 | }(React.Component);
402 |
403 | Donut.propTypes = {
404 | donutWidth: PropTypes.number,
405 | percentage: PropTypes.number,
406 | color: PropTypes.string,
407 | background: PropTypes.string,
408 | shadow: PropTypes.string
409 | };
410 |
411 | var Exception = function (_React$Component) {
412 | inherits(Exception, _React$Component);
413 |
414 | function Exception() {
415 | classCallCheck(this, Exception);
416 | return possibleConstructorReturn(this, (Exception.__proto__ || Object.getPrototypeOf(Exception)).apply(this, arguments));
417 | }
418 |
419 | createClass(Exception, [{
420 | key: 'componentDidMount',
421 | value: function componentDidMount() {
422 | this.drawFavicon();
423 | }
424 | }, {
425 | key: 'drawFavicon',
426 | value: function drawFavicon() {
427 | var color = this.props.color;
428 |
429 | var canvas = getCanvas();
430 | var ctx = canvas.getContext('2d');
431 |
432 | ctx.clearRect(0, 0, canvas.width, canvas.height);
433 |
434 | // Draw background
435 | ctx.beginPath();
436 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
437 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false);
438 | ctx.fillStyle = color;
439 | ctx.fill();
440 |
441 | // Draw cross
442 | ctx.beginPath();
443 | ctx.moveTo(canvas.width / 3, canvas.height / 3);
444 | ctx.lineTo(2 * canvas.width / 3, 2 * canvas.height / 3);
445 | ctx.lineWidth = 3;
446 | ctx.strokeStyle = '#fff';
447 | ctx.stroke();
448 |
449 | ctx.beginPath();
450 | ctx.moveTo(canvas.width / 3, 2 * canvas.height / 3);
451 | ctx.lineTo(2 * canvas.width / 3, canvas.height / 3);
452 | ctx.lineWidth = 3;
453 | ctx.strokeStyle = '#fff';
454 | ctx.stroke();
455 |
456 | setFaviconTag(canvas.toDataURL());
457 | }
458 | }, {
459 | key: 'render',
460 | value: function render() {
461 | return null;
462 | }
463 | }]);
464 | return Exception;
465 | }(React.Component);
466 |
467 | Exception.propTypes = {
468 | color: PropTypes.string
469 | };
470 |
471 | Exception.defaultProps = {
472 | color: '#ff564e'
473 | };
474 |
475 | var Success = function (_React$Component) {
476 | inherits(Success, _React$Component);
477 |
478 | function Success() {
479 | classCallCheck(this, Success);
480 | return possibleConstructorReturn(this, (Success.__proto__ || Object.getPrototypeOf(Success)).apply(this, arguments));
481 | }
482 |
483 | createClass(Success, [{
484 | key: 'componentDidMount',
485 | value: function componentDidMount() {
486 | this.drawFavicon();
487 | }
488 | }, {
489 | key: 'drawFavicon',
490 | value: function drawFavicon() {
491 | var color = this.props.color;
492 |
493 | var canvas = getCanvas();
494 | var ctx = canvas.getContext('2d');
495 |
496 | if (ctx) {
497 | ctx.clearRect(0, 0, canvas.width, canvas.height);
498 |
499 | // Draw background
500 | ctx.beginPath();
501 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
502 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false);
503 | ctx.fillStyle = color;
504 | ctx.fill();
505 |
506 | // Draw tick
507 | ctx.beginPath();
508 | ctx.moveTo(canvas.width * 0.22, canvas.height * 0.5);
509 | ctx.lineTo(canvas.width * 0.45, canvas.height * 0.7);
510 | ctx.lineTo(canvas.width * 0.73, canvas.height * 0.3);
511 | ctx.lineWidth = 3;
512 | ctx.strokeStyle = '#fff';
513 | ctx.stroke();
514 | }
515 |
516 | setFaviconTag(canvas.toDataURL());
517 | }
518 | }, {
519 | key: 'render',
520 | value: function render() {
521 | return null;
522 | }
523 | }]);
524 | return Success;
525 | }(React.Component);
526 |
527 | Success.propTypes = {
528 | color: PropTypes.string
529 | };
530 |
531 | Success.defaultProps = {
532 | color: '#25c639'
533 | };
534 |
535 | var LoadCon = function (_React$Component) {
536 | inherits(LoadCon, _React$Component);
537 |
538 | function LoadCon() {
539 | var _ref;
540 |
541 | var _temp, _this, _ret;
542 |
543 | classCallCheck(this, LoadCon);
544 |
545 | for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
546 | args[_key] = arguments[_key];
547 | }
548 |
549 | return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = LoadCon.__proto__ || Object.getPrototypeOf(LoadCon)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
550 | originalFaviconURL: null
551 | }, _this._renderFavicon = function () {
552 | switch (_this.props.type) {
553 | default:
554 | case 'pie':
555 | return React.createElement(Pie, _this.props);
556 | case 'donut':
557 | return React.createElement(Donut, _this.props);
558 | }
559 | }, _this._resetFavicon = function () {
560 | var originalFaviconURL = _this.state.originalFaviconURL;
561 |
562 | setFaviconTag(originalFaviconURL);
563 | }, _temp), possibleConstructorReturn(_this, _ret);
564 | }
565 |
566 | createClass(LoadCon, [{
567 | key: 'componentDidMount',
568 | value: function componentDidMount() {
569 | this.setState({
570 | originalFaviconURL: getFaviconURL()
571 | });
572 | }
573 | }, {
574 | key: 'componentDidUpdate',
575 | value: function componentDidUpdate(prevProps) {
576 | var isPropsChanged = !reactFastCompare(this.props, prevProps);
577 | if (isPropsChanged) {
578 | if (this.props.status === 'normal') {
579 | this._resetFavicon();
580 | }
581 | }
582 | }
583 | }, {
584 | key: 'render',
585 | value: function render() {
586 | var status = this.props.status;
587 |
588 | return React.createElement(
589 | NoSSR,
590 | null,
591 | status === 'active' && this._renderFavicon(),
592 | status === 'exception' && React.createElement(Exception, null),
593 | status === 'success' && React.createElement(Success, null)
594 | );
595 | }
596 | }]);
597 | return LoadCon;
598 | }(React.Component);
599 |
600 | LoadCon.propTypes = {
601 | percentage: PropTypes.number.isRequired,
602 | type: PropTypes.oneOf(['pie', 'donut']),
603 | status: PropTypes.oneOf(['normal', 'active', 'exception', 'success']),
604 | color: PropTypes.string,
605 | background: PropTypes.string,
606 | shadow: PropTypes.string,
607 | donutWidth: PropTypes.number
608 | };
609 |
610 | LoadCon.defaultProps = {
611 | percentage: 0,
612 | type: 'pie',
613 | status: 'normal',
614 | color: '#25c639',
615 | background: '#eee',
616 | shadow: '#fff',
617 | donutWidth: 8
618 | };
619 |
620 | export default LoadCon;
621 | //# sourceMappingURL=index.es.js.map
622 |
--------------------------------------------------------------------------------
/dist/index.es.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.es.js","sources":["../node_modules/react-fast-compare/index.js","../src/utils/NoSSR.js","../src/utils/index.js","../src/Favicons/Pie.js","../src/Favicons/Donut.js","../src/Favicons/Exception.js","../src/Favicons/Success.js","../src/index.js"],"sourcesContent":["'use strict';\n\nvar isArray = Array.isArray;\nvar keyList = Object.keys;\nvar hasProp = Object.prototype.hasOwnProperty;\nvar hasElementType = typeof Element !== 'undefined';\n\nfunction equal(a, b) {\n // fast-deep-equal index.js 2.0.1\n if (a === b) return true;\n\n if (a && b && typeof a == 'object' && typeof b == 'object') {\n var arrA = isArray(a)\n , arrB = isArray(b)\n , i\n , length\n , key;\n\n if (arrA && arrB) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (!equal(a[i], b[i])) return false;\n return true;\n }\n\n if (arrA != arrB) return false;\n\n var dateA = a instanceof Date\n , dateB = b instanceof Date;\n if (dateA != dateB) return false;\n if (dateA && dateB) return a.getTime() == b.getTime();\n\n var regexpA = a instanceof RegExp\n , regexpB = b instanceof RegExp;\n if (regexpA != regexpB) return false;\n if (regexpA && regexpB) return a.toString() == b.toString();\n\n var keys = keyList(a);\n length = keys.length;\n\n if (length !== keyList(b).length)\n return false;\n\n for (i = length; i-- !== 0;)\n if (!hasProp.call(b, keys[i])) return false;\n // end fast-deep-equal\n\n // start react-fast-compare\n // custom handling for DOM elements\n if (hasElementType && a instanceof Element && b instanceof Element)\n return a === b;\n\n // custom handling for React\n for (i = length; i-- !== 0;) {\n key = keys[i];\n if (key === '_owner' && a.$$typeof) {\n // React-specific: avoid traversing React elements' _owner.\n // _owner contains circular references\n // and is not needed when comparing the actual elements (and not their owners)\n // .$$typeof and ._store on just reasonable markers of a react element\n continue;\n } else {\n // all other properties should be traversed as usual\n if (!equal(a[key], b[key])) return false;\n }\n }\n // end react-fast-compare\n\n // fast-deep-equal index.js 2.0.1\n return true;\n }\n\n return a !== a && b !== b;\n}\n// end fast-deep-equal\n\nmodule.exports = function exportedEqual(a, b) {\n try {\n return equal(a, b);\n } catch (error) {\n if ((error.message && error.message.match(/stack|recursion/i)) || (error.number === -2146828260)) {\n // warn on circular references, don't crash\n // browsers give this different errors name and messages:\n // chrome/safari: \"RangeError\", \"Maximum call stack size exceeded\"\n // firefox: \"InternalError\", too much recursion\"\n // edge: \"Error\", \"Out of stack space\"\n console.warn('Warning: react-fast-compare does not handle circular references.', error.name, error.message);\n return false;\n }\n // some other error. we should definitely know about these\n throw error;\n }\n};\n","import React, { Component } from 'react'\n\nconst DefaultOnSSR = () => ()\n\nclass NoSSR extends Component {\n state = {\n canRender: false\n }\n\n componentDidMount() {\n this.setState({ canRender: true })\n }\n\n render() {\n const { children, onSSR = } = this.props\n\n return (\n \n {this.state.canRender ? children : onSSR}\n \n )\n }\n}\n\nexport default NoSSR\n","const isUA = (browser) => {\n const agent = navigator.userAgent.toLowerCase()\n return agent.indexOf(browser) !== 1\n}\n\nexport const getIsRetina = () => {\n return window.devicePixelRatio > 1\n}\n\nexport const getBrowser = () => {\n if (isUA('msie')) {\n return 'ie'\n } else if (isUA('chrome')) {\n return 'chrome'\n } else if (isUA('chrome') || isUA('safari')) {\n return 'webkit'\n } else if (isUA('safari') && !isUA('chrome')) {\n return 'safari'\n } else if (isUA('mozilla') && !isUA('chrome') && !isUA('safari')) {\n return 'mozilla'\n }\n}\n\nexport const getFaviconURL = () => {\n const links = document.getElementsByTagName('link')\n let tag = null\n\n for (let i = 0, l = links.length; i < l; i++) {\n if (links[i].getAttribute('rel') === 'icon'\n || links[i].getAttribute('rel') === 'shortcut icon') {\n tag = links[i]\n }\n }\n\n return tag ? tag.getAttribute('href') : '/favicon.ico'\n}\n\nexport const removeFaviconTag = () => {\n const links = Array.prototype.slice.call(document.getElementsByTagName('link'), 0)\n const head = document.getElementsByTagName('head')[0]\n\n for (let i = 0, l = links.length; i < l; i++) {\n if (links[i].getAttribute('rel') === 'icon'\n || links[i].getAttribute('rel') === 'shortcut icon') {\n head.removeChild(links[i])\n }\n }\n}\n\nexport const setFaviconTag = (url) => {\n removeFaviconTag()\n\n const link = document.createElement('link')\n link.type = 'image/x-icon'\n link.rel = 'icon'\n link.href = url\n\n document.getElementsByTagName('head')[0].appendChild(link)\n}\n\nexport const getCanvas = function () {\n const canvas = document.createElement(\"canvas\")\n if (getIsRetina()) {\n canvas.width = 32\n canvas.height = 32\n } else {\n canvas.width = 16\n canvas.height = 16\n }\n\n return canvas\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport isEqual from 'react-fast-compare'\n\nimport { getCanvas, setFaviconTag } from '../utils'\n\nclass Pie extends React.Component {\n componentDidMount () {\n this.drawFavicon()\n }\n\n componentDidUpdate (prevProps) {\n const isPropsChanged = !isEqual(this.props, prevProps)\n if (isPropsChanged) {\n this.drawFavicon()\n }\n }\n\n drawFavicon () {\n const { percentage, color, background, shadow } = this.props\n const canvas = getCanvas()\n const ctx = canvas.getContext('2d')\n\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n // Draw shadow\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false)\n ctx.fillStyle = shadow\n ctx.fill()\n\n // Draw background\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)\n ctx.fillStyle = background\n ctx.fill()\n\n // Draw pie\n if (percentage > 0) {\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)\n ctx.lineTo(canvas.width / 2, canvas.height / 2)\n ctx.fillStyle = color\n ctx.fill()\n }\n }\n\n setFaviconTag(canvas.toDataURL())\n }\n\n render () {\n return (null)\n }\n}\n\nPie.propTypes = {\n percentage: PropTypes.number,\n color: PropTypes.string,\n background: PropTypes.string,\n shadow: PropTypes.string,\n}\n\nexport default Pie\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport isEqual from 'react-fast-compare'\n\nimport { getCanvas, setFaviconTag } from '../utils'\n\nclass Donut extends React.Component {\n componentDidMount () {\n this.drawFavicon()\n }\n\n componentDidUpdate (prevProps) {\n const isPropsChanged = !isEqual(this.props, prevProps)\n if (isPropsChanged) {\n this.drawFavicon()\n }\n }\n\n drawFavicon () {\n const { donutWidth, percentage, color, background, shadow } = this.props\n const canvas = getCanvas()\n const ctx = canvas.getContext('2d')\n\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n // Draw shadow\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false)\n ctx.fillStyle = shadow\n ctx.fill()\n\n // Draw background\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)\n ctx.fillStyle = background\n ctx.fill()\n\n // Draw donut\n if (percentage > 0) {\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)\n ctx.lineTo(canvas.width / 2, canvas.height / 2)\n ctx.fillStyle = color\n ctx.fill()\n\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - donutWidth, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)\n ctx.lineTo(canvas.width / 2, canvas.height / 2)\n ctx.fillStyle = background\n ctx.fill()\n }\n }\n\n setFaviconTag(canvas.toDataURL())\n }\n\n render () {\n return (null)\n }\n}\n\nDonut.propTypes = {\n donutWidth: PropTypes.number,\n percentage: PropTypes.number,\n color: PropTypes.string,\n background: PropTypes.string,\n shadow: PropTypes.string,\n}\n\nexport default Donut\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\nimport { getCanvas, setFaviconTag } from '../utils'\n\nclass Exception extends React.Component {\n componentDidMount () {\n this.drawFavicon()\n }\n\n drawFavicon () {\n const { color } = this.props\n const canvas = getCanvas()\n const ctx = canvas.getContext('2d')\n\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n // Draw background\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)\n ctx.fillStyle = color\n ctx.fill()\n\n // Draw cross\n ctx.beginPath()\n ctx.moveTo(canvas.width / 3, canvas.height / 3)\n ctx.lineTo(2 * canvas.width / 3, 2 * canvas.height / 3)\n ctx.lineWidth = 3\n ctx.strokeStyle = '#fff'\n ctx.stroke()\n\n ctx.beginPath()\n ctx.moveTo(canvas.width / 3, 2 * canvas.height / 3)\n ctx.lineTo(2 * canvas.width / 3, canvas.height / 3)\n ctx.lineWidth = 3\n ctx.strokeStyle = '#fff'\n ctx.stroke()\n\n setFaviconTag(canvas.toDataURL())\n }\n\n render () {\n return (null)\n }\n}\n\nException.propTypes = {\n color: PropTypes.string,\n}\n\nException.defaultProps = {\n color: '#ff564e'\n}\n\nexport default Exception\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\nimport { getCanvas, setFaviconTag } from '../utils'\n\nclass Success extends React.Component {\n componentDidMount () {\n this.drawFavicon()\n }\n\n drawFavicon () {\n const { color } = this.props\n const canvas = getCanvas()\n const ctx = canvas.getContext('2d')\n\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n // Draw background\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)\n ctx.fillStyle = color\n ctx.fill()\n\n // Draw tick\n ctx.beginPath()\n ctx.moveTo(canvas.width * 0.22, canvas.height * 0.5)\n ctx.lineTo(canvas.width * 0.45, canvas.height * 0.7)\n ctx.lineTo(canvas.width * 0.73, canvas.height * 0.3)\n ctx.lineWidth = 3\n ctx.strokeStyle = '#fff'\n ctx.stroke()\n }\n\n setFaviconTag(canvas.toDataURL())\n }\n\n render () {\n return (null)\n }\n}\n\nSuccess.propTypes = {\n color: PropTypes.string,\n}\n\nSuccess.defaultProps = {\n color: '#25c639'\n}\n\nexport default Success\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport isEqual from 'react-fast-compare'\n\nimport NoSSR from './utils/NoSSR'\nimport { getFaviconURL, setFaviconTag } from './utils'\n\nimport PieCon from './Favicons/Pie'\nimport DonutCon from './Favicons/Donut'\nimport ExceptionCon from './Favicons/Exception'\nimport SuccessCon from './Favicons/Success'\n\nclass LoadCon extends React.Component {\n state = {\n originalFaviconURL: null\n }\n\n componentDidMount () {\n this.setState({\n originalFaviconURL: getFaviconURL()\n })\n }\n\n componentDidUpdate (prevProps) {\n const isPropsChanged = !isEqual(this.props, prevProps)\n if (isPropsChanged) {\n if (this.props.status === 'normal') {\n this._resetFavicon()\n }\n }\n }\n\n _renderFavicon = () => {\n switch (this.props.type) {\n default:\n case 'pie':\n return \n case 'donut':\n return \n }\n }\n\n _resetFavicon = () => {\n const { originalFaviconURL } = this.state\n setFaviconTag(originalFaviconURL)\n }\n\n render() {\n const { status } = this.props\n return (\n \n {status === 'active' && this._renderFavicon()}\n {status === 'exception' && }\n {status === 'success' && }\n \n )\n }\n}\n\nLoadCon.propTypes = {\n percentage: PropTypes.number.isRequired,\n type: PropTypes.oneOf(['pie', 'donut']),\n status: PropTypes.oneOf(['normal', 'active', 'exception', 'success']),\n color: PropTypes.string,\n background: PropTypes.string,\n shadow: PropTypes.string,\n donutWidth: PropTypes.number,\n}\n\nLoadCon.defaultProps = {\n percentage: 0,\n type: 'pie',\n status: 'normal',\n color: '#25c639',\n background: '#eee',\n shadow: '#fff',\n donutWidth: 8,\n}\n\nexport default LoadCon\n"],"names":["DefaultOnSSR","NoSSR","state","setState","canRender","props","children","onSSR","Component","getIsRetina","window","devicePixelRatio","getFaviconURL","links","document","getElementsByTagName","tag","i","l","length","getAttribute","removeFaviconTag","Array","prototype","slice","call","head","removeChild","setFaviconTag","url","link","createElement","type","rel","href","appendChild","getCanvas","canvas","width","height","Pie","drawFavicon","prevProps","isPropsChanged","isEqual","percentage","color","background","shadow","ctx","getContext","clearRect","beginPath","moveTo","arc","Math","min","PI","fillStyle","fill","lineTo","toDataURL","React","propTypes","PropTypes","number","string","Donut","donutWidth","Exception","lineWidth","strokeStyle","stroke","defaultProps","Success","LoadCon","_renderFavicon","PieCon","DonutCon","_resetFavicon","originalFaviconURL","status","ExceptionCon","SuccessCon","isRequired","oneOf"],"mappings":"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"}
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4 |
5 | var React = require('react');
6 | var React__default = _interopDefault(React);
7 | var PropTypes = _interopDefault(require('prop-types'));
8 |
9 | var isArray = Array.isArray;
10 | var keyList = Object.keys;
11 | var hasProp = Object.prototype.hasOwnProperty;
12 | var hasElementType = typeof Element !== 'undefined';
13 |
14 | function equal(a, b) {
15 | // fast-deep-equal index.js 2.0.1
16 | if (a === b) return true;
17 |
18 | if (a && b && typeof a == 'object' && typeof b == 'object') {
19 | var arrA = isArray(a)
20 | , arrB = isArray(b)
21 | , i
22 | , length
23 | , key;
24 |
25 | if (arrA && arrB) {
26 | length = a.length;
27 | if (length != b.length) return false;
28 | for (i = length; i-- !== 0;)
29 | if (!equal(a[i], b[i])) return false;
30 | return true;
31 | }
32 |
33 | if (arrA != arrB) return false;
34 |
35 | var dateA = a instanceof Date
36 | , dateB = b instanceof Date;
37 | if (dateA != dateB) return false;
38 | if (dateA && dateB) return a.getTime() == b.getTime();
39 |
40 | var regexpA = a instanceof RegExp
41 | , regexpB = b instanceof RegExp;
42 | if (regexpA != regexpB) return false;
43 | if (regexpA && regexpB) return a.toString() == b.toString();
44 |
45 | var keys = keyList(a);
46 | length = keys.length;
47 |
48 | if (length !== keyList(b).length)
49 | return false;
50 |
51 | for (i = length; i-- !== 0;)
52 | if (!hasProp.call(b, keys[i])) return false;
53 | // end fast-deep-equal
54 |
55 | // start react-fast-compare
56 | // custom handling for DOM elements
57 | if (hasElementType && a instanceof Element && b instanceof Element)
58 | return a === b;
59 |
60 | // custom handling for React
61 | for (i = length; i-- !== 0;) {
62 | key = keys[i];
63 | if (key === '_owner' && a.$$typeof) {
64 | // React-specific: avoid traversing React elements' _owner.
65 | // _owner contains circular references
66 | // and is not needed when comparing the actual elements (and not their owners)
67 | // .$$typeof and ._store on just reasonable markers of a react element
68 | continue;
69 | } else {
70 | // all other properties should be traversed as usual
71 | if (!equal(a[key], b[key])) return false;
72 | }
73 | }
74 | // end react-fast-compare
75 |
76 | // fast-deep-equal index.js 2.0.1
77 | return true;
78 | }
79 |
80 | return a !== a && b !== b;
81 | }
82 | // end fast-deep-equal
83 |
84 | var reactFastCompare = function exportedEqual(a, b) {
85 | try {
86 | return equal(a, b);
87 | } catch (error) {
88 | if ((error.message && error.message.match(/stack|recursion/i)) || (error.number === -2146828260)) {
89 | // warn on circular references, don't crash
90 | // browsers give this different errors name and messages:
91 | // chrome/safari: "RangeError", "Maximum call stack size exceeded"
92 | // firefox: "InternalError", too much recursion"
93 | // edge: "Error", "Out of stack space"
94 | console.warn('Warning: react-fast-compare does not handle circular references.', error.name, error.message);
95 | return false;
96 | }
97 | // some other error. we should definitely know about these
98 | throw error;
99 | }
100 | };
101 |
102 | var classCallCheck = function (instance, Constructor) {
103 | if (!(instance instanceof Constructor)) {
104 | throw new TypeError("Cannot call a class as a function");
105 | }
106 | };
107 |
108 | var createClass = function () {
109 | function defineProperties(target, props) {
110 | for (var i = 0; i < props.length; i++) {
111 | var descriptor = props[i];
112 | descriptor.enumerable = descriptor.enumerable || false;
113 | descriptor.configurable = true;
114 | if ("value" in descriptor) descriptor.writable = true;
115 | Object.defineProperty(target, descriptor.key, descriptor);
116 | }
117 | }
118 |
119 | return function (Constructor, protoProps, staticProps) {
120 | if (protoProps) defineProperties(Constructor.prototype, protoProps);
121 | if (staticProps) defineProperties(Constructor, staticProps);
122 | return Constructor;
123 | };
124 | }();
125 |
126 | var inherits = function (subClass, superClass) {
127 | if (typeof superClass !== "function" && superClass !== null) {
128 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
129 | }
130 |
131 | subClass.prototype = Object.create(superClass && superClass.prototype, {
132 | constructor: {
133 | value: subClass,
134 | enumerable: false,
135 | writable: true,
136 | configurable: true
137 | }
138 | });
139 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
140 | };
141 |
142 | var possibleConstructorReturn = function (self, call) {
143 | if (!self) {
144 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
145 | }
146 |
147 | return call && (typeof call === "object" || typeof call === "function") ? call : self;
148 | };
149 |
150 | var DefaultOnSSR = function DefaultOnSSR() {
151 | return React__default.createElement('span', null);
152 | };
153 |
154 | var NoSSR = function (_Component) {
155 | inherits(NoSSR, _Component);
156 |
157 | function NoSSR() {
158 | var _ref;
159 |
160 | var _temp, _this, _ret;
161 |
162 | classCallCheck(this, NoSSR);
163 |
164 | for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
165 | args[_key] = arguments[_key];
166 | }
167 |
168 | return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = NoSSR.__proto__ || Object.getPrototypeOf(NoSSR)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
169 | canRender: false
170 | }, _temp), possibleConstructorReturn(_this, _ret);
171 | }
172 |
173 | createClass(NoSSR, [{
174 | key: 'componentDidMount',
175 | value: function componentDidMount() {
176 | this.setState({ canRender: true });
177 | }
178 | }, {
179 | key: 'render',
180 | value: function render() {
181 | var _props = this.props,
182 | children = _props.children,
183 | _props$onSSR = _props.onSSR,
184 | onSSR = _props$onSSR === undefined ? React__default.createElement(DefaultOnSSR, null) : _props$onSSR;
185 |
186 |
187 | return React__default.createElement(
188 | React__default.Fragment,
189 | null,
190 | this.state.canRender ? children : onSSR
191 | );
192 | }
193 | }]);
194 | return NoSSR;
195 | }(React.Component);
196 |
197 | var getIsRetina = function getIsRetina() {
198 | return window.devicePixelRatio > 1;
199 | };
200 |
201 | var getFaviconURL = function getFaviconURL() {
202 | var links = document.getElementsByTagName('link');
203 | var tag = null;
204 |
205 | for (var i = 0, l = links.length; i < l; i++) {
206 | if (links[i].getAttribute('rel') === 'icon' || links[i].getAttribute('rel') === 'shortcut icon') {
207 | tag = links[i];
208 | }
209 | }
210 |
211 | return tag ? tag.getAttribute('href') : '/favicon.ico';
212 | };
213 |
214 | var removeFaviconTag = function removeFaviconTag() {
215 | var links = Array.prototype.slice.call(document.getElementsByTagName('link'), 0);
216 | var head = document.getElementsByTagName('head')[0];
217 |
218 | for (var i = 0, l = links.length; i < l; i++) {
219 | if (links[i].getAttribute('rel') === 'icon' || links[i].getAttribute('rel') === 'shortcut icon') {
220 | head.removeChild(links[i]);
221 | }
222 | }
223 | };
224 |
225 | var setFaviconTag = function setFaviconTag(url) {
226 | removeFaviconTag();
227 |
228 | var link = document.createElement('link');
229 | link.type = 'image/x-icon';
230 | link.rel = 'icon';
231 | link.href = url;
232 |
233 | document.getElementsByTagName('head')[0].appendChild(link);
234 | };
235 |
236 | var getCanvas = function getCanvas() {
237 | var canvas = document.createElement("canvas");
238 | if (getIsRetina()) {
239 | canvas.width = 32;
240 | canvas.height = 32;
241 | } else {
242 | canvas.width = 16;
243 | canvas.height = 16;
244 | }
245 |
246 | return canvas;
247 | };
248 |
249 | var Pie = function (_React$Component) {
250 | inherits(Pie, _React$Component);
251 |
252 | function Pie() {
253 | classCallCheck(this, Pie);
254 | return possibleConstructorReturn(this, (Pie.__proto__ || Object.getPrototypeOf(Pie)).apply(this, arguments));
255 | }
256 |
257 | createClass(Pie, [{
258 | key: 'componentDidMount',
259 | value: function componentDidMount() {
260 | this.drawFavicon();
261 | }
262 | }, {
263 | key: 'componentDidUpdate',
264 | value: function componentDidUpdate(prevProps) {
265 | var isPropsChanged = !reactFastCompare(this.props, prevProps);
266 | if (isPropsChanged) {
267 | this.drawFavicon();
268 | }
269 | }
270 | }, {
271 | key: 'drawFavicon',
272 | value: function drawFavicon() {
273 | var _props = this.props,
274 | percentage = _props.percentage,
275 | color = _props.color,
276 | background = _props.background,
277 | shadow = _props.shadow;
278 |
279 | var canvas = getCanvas();
280 | var ctx = canvas.getContext('2d');
281 |
282 | if (ctx) {
283 | ctx.clearRect(0, 0, canvas.width, canvas.height);
284 |
285 | // Draw shadow
286 | ctx.beginPath();
287 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
288 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false);
289 | ctx.fillStyle = shadow;
290 | ctx.fill();
291 |
292 | // Draw background
293 | ctx.beginPath();
294 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
295 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false);
296 | ctx.fillStyle = background;
297 | ctx.fill();
298 |
299 | // Draw pie
300 | if (percentage > 0) {
301 | ctx.beginPath();
302 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
303 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, -0.5 * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false);
304 | ctx.lineTo(canvas.width / 2, canvas.height / 2);
305 | ctx.fillStyle = color;
306 | ctx.fill();
307 | }
308 | }
309 |
310 | setFaviconTag(canvas.toDataURL());
311 | }
312 | }, {
313 | key: 'render',
314 | value: function render() {
315 | return null;
316 | }
317 | }]);
318 | return Pie;
319 | }(React__default.Component);
320 |
321 | Pie.propTypes = {
322 | percentage: PropTypes.number,
323 | color: PropTypes.string,
324 | background: PropTypes.string,
325 | shadow: PropTypes.string
326 | };
327 |
328 | var Donut = function (_React$Component) {
329 | inherits(Donut, _React$Component);
330 |
331 | function Donut() {
332 | classCallCheck(this, Donut);
333 | return possibleConstructorReturn(this, (Donut.__proto__ || Object.getPrototypeOf(Donut)).apply(this, arguments));
334 | }
335 |
336 | createClass(Donut, [{
337 | key: 'componentDidMount',
338 | value: function componentDidMount() {
339 | this.drawFavicon();
340 | }
341 | }, {
342 | key: 'componentDidUpdate',
343 | value: function componentDidUpdate(prevProps) {
344 | var isPropsChanged = !reactFastCompare(this.props, prevProps);
345 | if (isPropsChanged) {
346 | this.drawFavicon();
347 | }
348 | }
349 | }, {
350 | key: 'drawFavicon',
351 | value: function drawFavicon() {
352 | var _props = this.props,
353 | donutWidth = _props.donutWidth,
354 | percentage = _props.percentage,
355 | color = _props.color,
356 | background = _props.background,
357 | shadow = _props.shadow;
358 |
359 | var canvas = getCanvas();
360 | var ctx = canvas.getContext('2d');
361 |
362 | if (ctx) {
363 | ctx.clearRect(0, 0, canvas.width, canvas.height);
364 |
365 | // Draw shadow
366 | ctx.beginPath();
367 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
368 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false);
369 | ctx.fillStyle = shadow;
370 | ctx.fill();
371 |
372 | // Draw background
373 | ctx.beginPath();
374 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
375 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false);
376 | ctx.fillStyle = background;
377 | ctx.fill();
378 |
379 | // Draw donut
380 | if (percentage > 0) {
381 | ctx.beginPath();
382 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
383 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, -0.5 * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false);
384 | ctx.lineTo(canvas.width / 2, canvas.height / 2);
385 | ctx.fillStyle = color;
386 | ctx.fill();
387 |
388 | ctx.beginPath();
389 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
390 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - donutWidth, -0.5 * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false);
391 | ctx.lineTo(canvas.width / 2, canvas.height / 2);
392 | ctx.fillStyle = background;
393 | ctx.fill();
394 | }
395 | }
396 |
397 | setFaviconTag(canvas.toDataURL());
398 | }
399 | }, {
400 | key: 'render',
401 | value: function render() {
402 | return null;
403 | }
404 | }]);
405 | return Donut;
406 | }(React__default.Component);
407 |
408 | Donut.propTypes = {
409 | donutWidth: PropTypes.number,
410 | percentage: PropTypes.number,
411 | color: PropTypes.string,
412 | background: PropTypes.string,
413 | shadow: PropTypes.string
414 | };
415 |
416 | var Exception = function (_React$Component) {
417 | inherits(Exception, _React$Component);
418 |
419 | function Exception() {
420 | classCallCheck(this, Exception);
421 | return possibleConstructorReturn(this, (Exception.__proto__ || Object.getPrototypeOf(Exception)).apply(this, arguments));
422 | }
423 |
424 | createClass(Exception, [{
425 | key: 'componentDidMount',
426 | value: function componentDidMount() {
427 | this.drawFavicon();
428 | }
429 | }, {
430 | key: 'drawFavicon',
431 | value: function drawFavicon() {
432 | var color = this.props.color;
433 |
434 | var canvas = getCanvas();
435 | var ctx = canvas.getContext('2d');
436 |
437 | ctx.clearRect(0, 0, canvas.width, canvas.height);
438 |
439 | // Draw background
440 | ctx.beginPath();
441 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
442 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false);
443 | ctx.fillStyle = color;
444 | ctx.fill();
445 |
446 | // Draw cross
447 | ctx.beginPath();
448 | ctx.moveTo(canvas.width / 3, canvas.height / 3);
449 | ctx.lineTo(2 * canvas.width / 3, 2 * canvas.height / 3);
450 | ctx.lineWidth = 3;
451 | ctx.strokeStyle = '#fff';
452 | ctx.stroke();
453 |
454 | ctx.beginPath();
455 | ctx.moveTo(canvas.width / 3, 2 * canvas.height / 3);
456 | ctx.lineTo(2 * canvas.width / 3, canvas.height / 3);
457 | ctx.lineWidth = 3;
458 | ctx.strokeStyle = '#fff';
459 | ctx.stroke();
460 |
461 | setFaviconTag(canvas.toDataURL());
462 | }
463 | }, {
464 | key: 'render',
465 | value: function render() {
466 | return null;
467 | }
468 | }]);
469 | return Exception;
470 | }(React__default.Component);
471 |
472 | Exception.propTypes = {
473 | color: PropTypes.string
474 | };
475 |
476 | Exception.defaultProps = {
477 | color: '#ff564e'
478 | };
479 |
480 | var Success = function (_React$Component) {
481 | inherits(Success, _React$Component);
482 |
483 | function Success() {
484 | classCallCheck(this, Success);
485 | return possibleConstructorReturn(this, (Success.__proto__ || Object.getPrototypeOf(Success)).apply(this, arguments));
486 | }
487 |
488 | createClass(Success, [{
489 | key: 'componentDidMount',
490 | value: function componentDidMount() {
491 | this.drawFavicon();
492 | }
493 | }, {
494 | key: 'drawFavicon',
495 | value: function drawFavicon() {
496 | var color = this.props.color;
497 |
498 | var canvas = getCanvas();
499 | var ctx = canvas.getContext('2d');
500 |
501 | if (ctx) {
502 | ctx.clearRect(0, 0, canvas.width, canvas.height);
503 |
504 | // Draw background
505 | ctx.beginPath();
506 | ctx.moveTo(canvas.width / 2, canvas.height / 2);
507 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false);
508 | ctx.fillStyle = color;
509 | ctx.fill();
510 |
511 | // Draw tick
512 | ctx.beginPath();
513 | ctx.moveTo(canvas.width * 0.22, canvas.height * 0.5);
514 | ctx.lineTo(canvas.width * 0.45, canvas.height * 0.7);
515 | ctx.lineTo(canvas.width * 0.73, canvas.height * 0.3);
516 | ctx.lineWidth = 3;
517 | ctx.strokeStyle = '#fff';
518 | ctx.stroke();
519 | }
520 |
521 | setFaviconTag(canvas.toDataURL());
522 | }
523 | }, {
524 | key: 'render',
525 | value: function render() {
526 | return null;
527 | }
528 | }]);
529 | return Success;
530 | }(React__default.Component);
531 |
532 | Success.propTypes = {
533 | color: PropTypes.string
534 | };
535 |
536 | Success.defaultProps = {
537 | color: '#25c639'
538 | };
539 |
540 | var LoadCon = function (_React$Component) {
541 | inherits(LoadCon, _React$Component);
542 |
543 | function LoadCon() {
544 | var _ref;
545 |
546 | var _temp, _this, _ret;
547 |
548 | classCallCheck(this, LoadCon);
549 |
550 | for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
551 | args[_key] = arguments[_key];
552 | }
553 |
554 | return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = LoadCon.__proto__ || Object.getPrototypeOf(LoadCon)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
555 | originalFaviconURL: null
556 | }, _this._renderFavicon = function () {
557 | switch (_this.props.type) {
558 | default:
559 | case 'pie':
560 | return React__default.createElement(Pie, _this.props);
561 | case 'donut':
562 | return React__default.createElement(Donut, _this.props);
563 | }
564 | }, _this._resetFavicon = function () {
565 | var originalFaviconURL = _this.state.originalFaviconURL;
566 |
567 | setFaviconTag(originalFaviconURL);
568 | }, _temp), possibleConstructorReturn(_this, _ret);
569 | }
570 |
571 | createClass(LoadCon, [{
572 | key: 'componentDidMount',
573 | value: function componentDidMount() {
574 | this.setState({
575 | originalFaviconURL: getFaviconURL()
576 | });
577 | }
578 | }, {
579 | key: 'componentDidUpdate',
580 | value: function componentDidUpdate(prevProps) {
581 | var isPropsChanged = !reactFastCompare(this.props, prevProps);
582 | if (isPropsChanged) {
583 | if (this.props.status === 'normal') {
584 | this._resetFavicon();
585 | }
586 | }
587 | }
588 | }, {
589 | key: 'render',
590 | value: function render() {
591 | var status = this.props.status;
592 |
593 | return React__default.createElement(
594 | NoSSR,
595 | null,
596 | status === 'active' && this._renderFavicon(),
597 | status === 'exception' && React__default.createElement(Exception, null),
598 | status === 'success' && React__default.createElement(Success, null)
599 | );
600 | }
601 | }]);
602 | return LoadCon;
603 | }(React__default.Component);
604 |
605 | LoadCon.propTypes = {
606 | percentage: PropTypes.number.isRequired,
607 | type: PropTypes.oneOf(['pie', 'donut']),
608 | status: PropTypes.oneOf(['normal', 'active', 'exception', 'success']),
609 | color: PropTypes.string,
610 | background: PropTypes.string,
611 | shadow: PropTypes.string,
612 | donutWidth: PropTypes.number
613 | };
614 |
615 | LoadCon.defaultProps = {
616 | percentage: 0,
617 | type: 'pie',
618 | status: 'normal',
619 | color: '#25c639',
620 | background: '#eee',
621 | shadow: '#fff',
622 | donutWidth: 8
623 | };
624 |
625 | module.exports = LoadCon;
626 | //# sourceMappingURL=index.js.map
627 |
--------------------------------------------------------------------------------
/dist/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.js","sources":["../node_modules/react-fast-compare/index.js","../src/utils/NoSSR.js","../src/utils/index.js","../src/Favicons/Pie.js","../src/Favicons/Donut.js","../src/Favicons/Exception.js","../src/Favicons/Success.js","../src/index.js"],"sourcesContent":["'use strict';\n\nvar isArray = Array.isArray;\nvar keyList = Object.keys;\nvar hasProp = Object.prototype.hasOwnProperty;\nvar hasElementType = typeof Element !== 'undefined';\n\nfunction equal(a, b) {\n // fast-deep-equal index.js 2.0.1\n if (a === b) return true;\n\n if (a && b && typeof a == 'object' && typeof b == 'object') {\n var arrA = isArray(a)\n , arrB = isArray(b)\n , i\n , length\n , key;\n\n if (arrA && arrB) {\n length = a.length;\n if (length != b.length) return false;\n for (i = length; i-- !== 0;)\n if (!equal(a[i], b[i])) return false;\n return true;\n }\n\n if (arrA != arrB) return false;\n\n var dateA = a instanceof Date\n , dateB = b instanceof Date;\n if (dateA != dateB) return false;\n if (dateA && dateB) return a.getTime() == b.getTime();\n\n var regexpA = a instanceof RegExp\n , regexpB = b instanceof RegExp;\n if (regexpA != regexpB) return false;\n if (regexpA && regexpB) return a.toString() == b.toString();\n\n var keys = keyList(a);\n length = keys.length;\n\n if (length !== keyList(b).length)\n return false;\n\n for (i = length; i-- !== 0;)\n if (!hasProp.call(b, keys[i])) return false;\n // end fast-deep-equal\n\n // start react-fast-compare\n // custom handling for DOM elements\n if (hasElementType && a instanceof Element && b instanceof Element)\n return a === b;\n\n // custom handling for React\n for (i = length; i-- !== 0;) {\n key = keys[i];\n if (key === '_owner' && a.$$typeof) {\n // React-specific: avoid traversing React elements' _owner.\n // _owner contains circular references\n // and is not needed when comparing the actual elements (and not their owners)\n // .$$typeof and ._store on just reasonable markers of a react element\n continue;\n } else {\n // all other properties should be traversed as usual\n if (!equal(a[key], b[key])) return false;\n }\n }\n // end react-fast-compare\n\n // fast-deep-equal index.js 2.0.1\n return true;\n }\n\n return a !== a && b !== b;\n}\n// end fast-deep-equal\n\nmodule.exports = function exportedEqual(a, b) {\n try {\n return equal(a, b);\n } catch (error) {\n if ((error.message && error.message.match(/stack|recursion/i)) || (error.number === -2146828260)) {\n // warn on circular references, don't crash\n // browsers give this different errors name and messages:\n // chrome/safari: \"RangeError\", \"Maximum call stack size exceeded\"\n // firefox: \"InternalError\", too much recursion\"\n // edge: \"Error\", \"Out of stack space\"\n console.warn('Warning: react-fast-compare does not handle circular references.', error.name, error.message);\n return false;\n }\n // some other error. we should definitely know about these\n throw error;\n }\n};\n","import React, { Component } from 'react'\n\nconst DefaultOnSSR = () => ()\n\nclass NoSSR extends Component {\n state = {\n canRender: false\n }\n\n componentDidMount() {\n this.setState({ canRender: true })\n }\n\n render() {\n const { children, onSSR = } = this.props\n\n return (\n \n {this.state.canRender ? children : onSSR}\n \n )\n }\n}\n\nexport default NoSSR\n","const isUA = (browser) => {\n const agent = navigator.userAgent.toLowerCase()\n return agent.indexOf(browser) !== 1\n}\n\nexport const getIsRetina = () => {\n return window.devicePixelRatio > 1\n}\n\nexport const getBrowser = () => {\n if (isUA('msie')) {\n return 'ie'\n } else if (isUA('chrome')) {\n return 'chrome'\n } else if (isUA('chrome') || isUA('safari')) {\n return 'webkit'\n } else if (isUA('safari') && !isUA('chrome')) {\n return 'safari'\n } else if (isUA('mozilla') && !isUA('chrome') && !isUA('safari')) {\n return 'mozilla'\n }\n}\n\nexport const getFaviconURL = () => {\n const links = document.getElementsByTagName('link')\n let tag = null\n\n for (let i = 0, l = links.length; i < l; i++) {\n if (links[i].getAttribute('rel') === 'icon'\n || links[i].getAttribute('rel') === 'shortcut icon') {\n tag = links[i]\n }\n }\n\n return tag ? tag.getAttribute('href') : '/favicon.ico'\n}\n\nexport const removeFaviconTag = () => {\n const links = Array.prototype.slice.call(document.getElementsByTagName('link'), 0)\n const head = document.getElementsByTagName('head')[0]\n\n for (let i = 0, l = links.length; i < l; i++) {\n if (links[i].getAttribute('rel') === 'icon'\n || links[i].getAttribute('rel') === 'shortcut icon') {\n head.removeChild(links[i])\n }\n }\n}\n\nexport const setFaviconTag = (url) => {\n removeFaviconTag()\n\n const link = document.createElement('link')\n link.type = 'image/x-icon'\n link.rel = 'icon'\n link.href = url\n\n document.getElementsByTagName('head')[0].appendChild(link)\n}\n\nexport const getCanvas = function () {\n const canvas = document.createElement(\"canvas\")\n if (getIsRetina()) {\n canvas.width = 32\n canvas.height = 32\n } else {\n canvas.width = 16\n canvas.height = 16\n }\n\n return canvas\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport isEqual from 'react-fast-compare'\n\nimport { getCanvas, setFaviconTag } from '../utils'\n\nclass Pie extends React.Component {\n componentDidMount () {\n this.drawFavicon()\n }\n\n componentDidUpdate (prevProps) {\n const isPropsChanged = !isEqual(this.props, prevProps)\n if (isPropsChanged) {\n this.drawFavicon()\n }\n }\n\n drawFavicon () {\n const { percentage, color, background, shadow } = this.props\n const canvas = getCanvas()\n const ctx = canvas.getContext('2d')\n\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n // Draw shadow\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false)\n ctx.fillStyle = shadow\n ctx.fill()\n\n // Draw background\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)\n ctx.fillStyle = background\n ctx.fill()\n\n // Draw pie\n if (percentage > 0) {\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)\n ctx.lineTo(canvas.width / 2, canvas.height / 2)\n ctx.fillStyle = color\n ctx.fill()\n }\n }\n\n setFaviconTag(canvas.toDataURL())\n }\n\n render () {\n return (null)\n }\n}\n\nPie.propTypes = {\n percentage: PropTypes.number,\n color: PropTypes.string,\n background: PropTypes.string,\n shadow: PropTypes.string,\n}\n\nexport default Pie\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport isEqual from 'react-fast-compare'\n\nimport { getCanvas, setFaviconTag } from '../utils'\n\nclass Donut extends React.Component {\n componentDidMount () {\n this.drawFavicon()\n }\n\n componentDidUpdate (prevProps) {\n const isPropsChanged = !isEqual(this.props, prevProps)\n if (isPropsChanged) {\n this.drawFavicon()\n }\n }\n\n drawFavicon () {\n const { donutWidth, percentage, color, background, shadow } = this.props\n const canvas = getCanvas()\n const ctx = canvas.getContext('2d')\n\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n // Draw shadow\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false)\n ctx.fillStyle = shadow\n ctx.fill()\n\n // Draw background\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)\n ctx.fillStyle = background\n ctx.fill()\n\n // Draw donut\n if (percentage > 0) {\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)\n ctx.lineTo(canvas.width / 2, canvas.height / 2)\n ctx.fillStyle = color\n ctx.fill()\n\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - donutWidth, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)\n ctx.lineTo(canvas.width / 2, canvas.height / 2)\n ctx.fillStyle = background\n ctx.fill()\n }\n }\n\n setFaviconTag(canvas.toDataURL())\n }\n\n render () {\n return (null)\n }\n}\n\nDonut.propTypes = {\n donutWidth: PropTypes.number,\n percentage: PropTypes.number,\n color: PropTypes.string,\n background: PropTypes.string,\n shadow: PropTypes.string,\n}\n\nexport default Donut\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\nimport { getCanvas, setFaviconTag } from '../utils'\n\nclass Exception extends React.Component {\n componentDidMount () {\n this.drawFavicon()\n }\n\n drawFavicon () {\n const { color } = this.props\n const canvas = getCanvas()\n const ctx = canvas.getContext('2d')\n\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n // Draw background\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)\n ctx.fillStyle = color\n ctx.fill()\n\n // Draw cross\n ctx.beginPath()\n ctx.moveTo(canvas.width / 3, canvas.height / 3)\n ctx.lineTo(2 * canvas.width / 3, 2 * canvas.height / 3)\n ctx.lineWidth = 3\n ctx.strokeStyle = '#fff'\n ctx.stroke()\n\n ctx.beginPath()\n ctx.moveTo(canvas.width / 3, 2 * canvas.height / 3)\n ctx.lineTo(2 * canvas.width / 3, canvas.height / 3)\n ctx.lineWidth = 3\n ctx.strokeStyle = '#fff'\n ctx.stroke()\n\n setFaviconTag(canvas.toDataURL())\n }\n\n render () {\n return (null)\n }\n}\n\nException.propTypes = {\n color: PropTypes.string,\n}\n\nException.defaultProps = {\n color: '#ff564e'\n}\n\nexport default Exception\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\nimport { getCanvas, setFaviconTag } from '../utils'\n\nclass Success extends React.Component {\n componentDidMount () {\n this.drawFavicon()\n }\n\n drawFavicon () {\n const { color } = this.props\n const canvas = getCanvas()\n const ctx = canvas.getContext('2d')\n\n if (ctx) {\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n // Draw background\n ctx.beginPath()\n ctx.moveTo(canvas.width / 2, canvas.height / 2)\n ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)\n ctx.fillStyle = color\n ctx.fill()\n\n // Draw tick\n ctx.beginPath()\n ctx.moveTo(canvas.width * 0.22, canvas.height * 0.5)\n ctx.lineTo(canvas.width * 0.45, canvas.height * 0.7)\n ctx.lineTo(canvas.width * 0.73, canvas.height * 0.3)\n ctx.lineWidth = 3\n ctx.strokeStyle = '#fff'\n ctx.stroke()\n }\n\n setFaviconTag(canvas.toDataURL())\n }\n\n render () {\n return (null)\n }\n}\n\nSuccess.propTypes = {\n color: PropTypes.string,\n}\n\nSuccess.defaultProps = {\n color: '#25c639'\n}\n\nexport default Success\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport isEqual from 'react-fast-compare'\n\nimport NoSSR from './utils/NoSSR'\nimport { getFaviconURL, setFaviconTag } from './utils'\n\nimport PieCon from './Favicons/Pie'\nimport DonutCon from './Favicons/Donut'\nimport ExceptionCon from './Favicons/Exception'\nimport SuccessCon from './Favicons/Success'\n\nclass LoadCon extends React.Component {\n state = {\n originalFaviconURL: null\n }\n\n componentDidMount () {\n this.setState({\n originalFaviconURL: getFaviconURL()\n })\n }\n\n componentDidUpdate (prevProps) {\n const isPropsChanged = !isEqual(this.props, prevProps)\n if (isPropsChanged) {\n if (this.props.status === 'normal') {\n this._resetFavicon()\n }\n }\n }\n\n _renderFavicon = () => {\n switch (this.props.type) {\n default:\n case 'pie':\n return \n case 'donut':\n return \n }\n }\n\n _resetFavicon = () => {\n const { originalFaviconURL } = this.state\n setFaviconTag(originalFaviconURL)\n }\n\n render() {\n const { status } = this.props\n return (\n \n {status === 'active' && this._renderFavicon()}\n {status === 'exception' && }\n {status === 'success' && }\n \n )\n }\n}\n\nLoadCon.propTypes = {\n percentage: PropTypes.number.isRequired,\n type: PropTypes.oneOf(['pie', 'donut']),\n status: PropTypes.oneOf(['normal', 'active', 'exception', 'success']),\n color: PropTypes.string,\n background: PropTypes.string,\n shadow: PropTypes.string,\n donutWidth: PropTypes.number,\n}\n\nLoadCon.defaultProps = {\n percentage: 0,\n type: 'pie',\n status: 'normal',\n color: '#25c639',\n background: '#eee',\n shadow: '#fff',\n donutWidth: 8,\n}\n\nexport default LoadCon\n"],"names":["DefaultOnSSR","React","NoSSR","state","setState","canRender","props","children","onSSR","Component","getIsRetina","window","devicePixelRatio","getFaviconURL","links","document","getElementsByTagName","tag","i","l","length","getAttribute","removeFaviconTag","Array","prototype","slice","call","head","removeChild","setFaviconTag","url","link","createElement","type","rel","href","appendChild","getCanvas","canvas","width","height","Pie","drawFavicon","prevProps","isPropsChanged","isEqual","percentage","color","background","shadow","ctx","getContext","clearRect","beginPath","moveTo","arc","Math","min","PI","fillStyle","fill","lineTo","toDataURL","propTypes","PropTypes","number","string","Donut","donutWidth","Exception","lineWidth","strokeStyle","stroke","defaultProps","Success","LoadCon","_renderFavicon","PieCon","DonutCon","_resetFavicon","originalFaviconURL","status","ExceptionCon","SuccessCon","isRequired","oneOf"],"mappings":"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"}
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-loadcon-example",
3 | "homepage": "https://foreseaz.github.io/react-loadcon",
4 | "version": "0.0.0",
5 | "license": "MIT",
6 | "private": true,
7 | "dependencies": {
8 | "prop-types": "^15.6.2",
9 | "react": "^16.4.1",
10 | "react-dom": "^16.4.1",
11 | "react-loadcon": "^0.1.0",
12 | "react-markdown": "^4.0.6",
13 | "react-scripts": "^1.1.4",
14 | "react-syntax-highlighter": "^10.2.1"
15 | },
16 | "scripts": {
17 | "start": "react-scripts start",
18 | "build": "react-scripts build",
19 | "test": "react-scripts test --env=jsdom",
20 | "eject": "react-scripts eject"
21 | },
22 | "devDependencies": {}
23 | }
24 |
--------------------------------------------------------------------------------
/example/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foreseaz/react-loadcon/770ccb24c25d63714a4279f932c3ed1ca3ae0624/example/public/favicon.ico
--------------------------------------------------------------------------------
/example/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | React LoadCon
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/example/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "react-loadcon",
3 | "name": "react-loadcon",
4 | "start_url": "./index.html",
5 | "display": "standalone",
6 | "theme_color": "#000000",
7 | "background_color": "#ffffff"
8 | }
9 |
--------------------------------------------------------------------------------
/example/ship.sh:
--------------------------------------------------------------------------------
1 |
2 | #!/usr/bin/env sh
3 |
4 | # abort on errors
5 | set -e
6 |
7 | # build
8 | yarn build
9 |
10 | # navigate into the build output directory
11 | cd build
12 |
13 | # if you are deploying to a custom domain
14 | # echo 'domain.io' > CNAME
15 |
16 | git init
17 | git add -A
18 | git commit -m 'ship: deployment gh-page'
19 |
20 | # if you are deploying to https://.github.io
21 | # git push -f git@github.com:/.github.io.git master
22 |
23 | # if you are deploying to https://.github.io/
24 | git push -f https://github.com/foreseaz/react-loadcon.git master:gh-pages
25 |
26 |
27 | cd -
28 |
--------------------------------------------------------------------------------
/example/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | import ReactMarkdown from 'react-markdown'
4 | import SyntaxHighlighter from 'react-syntax-highlighter'
5 | import { atomOneDark } from 'react-syntax-highlighter/dist/esm/styles/hljs'
6 |
7 | import LoadCon from 'react-loadcon'
8 |
9 | export default class App extends Component {
10 | state = {
11 | status: 'normal',
12 | type: 'pie',
13 | percentage: 0
14 | }
15 |
16 | handleTypeChange = (e) => {
17 | this.setState({ type: e.target.value })
18 | e.preventDefault()
19 | }
20 |
21 | asyncLoading = (hasError = false) => {
22 | this.setState({ status: 'active', percentage: 0 })
23 |
24 | const promise = new Promise((resolve, reject) => {
25 | let inter = setInterval(() => {
26 | const { percentage } = this.state
27 |
28 | let p = percentage + Math.random() * 1000 % 10
29 | p = p >= 100 ? 100 : p
30 | if (hasError && p > 70) {
31 | clearInterval(inter)
32 | reject()
33 | }
34 | if (p === 100) {
35 | clearInterval(inter)
36 | this.setState({ status: 'normal' })
37 | resolve()
38 | }
39 |
40 | this.setState({ percentage: p })
41 | }, 200)
42 | })
43 |
44 | return promise
45 | }
46 |
47 | raiseException = () => {
48 | this.asyncLoading(true).catch(e => {
49 | this.setState({ status: 'exception' })
50 | setTimeout(() => {
51 | this.setState({ status: 'normal' })
52 | }, 1500)
53 | })
54 | }
55 |
56 | raiseSuccess = () => {
57 | this.asyncLoading().then(() => {
58 | this.setState({ status: 'success' })
59 | setTimeout(() => {
60 | this.setState({ status: 'normal' })
61 | }, 1500)
62 | })
63 | }
64 |
65 | updateStatus = (status) => {
66 | this.setState({ status })
67 | }
68 |
69 | normalDoc = () => `\
70 | import React, { Component } from 'react'
71 | import LoadCon from 'react-loadcon'
72 |
73 | export default class ExampleComponent extends Component {
74 | state = {
75 | percentage: 0, // isRequired
76 | status: 'normal', // oneOf(['normal', 'active', 'exception', 'success'])
77 | type: 'pie', // oneOf(['pie', 'donut'])
78 | }
79 |
80 | componentDidMount () {
81 | this.apiCall()
82 | }
83 |
84 | apiCall = () => {
85 | this.setState({ status: 'active' })
86 | fetch(url)
87 | .then(res => return res.json())
88 | .then(data => {
89 | // normal loading
90 | this.setState({ status: 'normal' })
91 |
92 | // loading with success
93 | this.setState({ status: 'success' })
94 | setTimeout(() => {
95 | this.setState({ status: 'normal' })
96 | }, 1500)
97 | })
98 | .catch(e => {
99 | this.setState({ status: 'exception' })
100 | setTimeout(() => {
101 | this.setState({ status: 'normal' })
102 | }, 1500)
103 | })
104 | }
105 |
106 | render () {
107 | return (
108 |
113 | )
114 | }
115 | }\
116 | `
117 |
118 | propsExplain = () => `\
119 | ## Props
120 |
121 | - \`percentage: PropTypes.number.isRequired\`, the percentage of loading progress for LoadCon.
122 | - \`type: PropTypes.oneOf(['pie', 'donut'])\`, the theme of LoadCon, now has \`PieCon\` and \`DonutCon\`, and more themes will be added soon.
123 | - \`status: PropTypes.oneOf(['normal', 'active', 'exception', 'success'])\`, load status of LoadCon, \`normal\` reset to default favicon, \`active\` set LoadCon according to the type prop, \`exception\` set ErrorCon and \`success\` set SuccessCon.
124 | - \`color: PropTypes.string\`, color of loading indicator in hash format, default is \`#25c639\`.
125 | - \`background: PropTypes.string\`, color of background in hash format, default is \`#eeeeee\`.
126 | - \`shadow: PropTypes.string\`, color of 2 pixals border in hash format, default is \`#ffffff\`.
127 | - \`donutWidth: PropTypes.number\`, width of DonutCon indicator in number, default is \`8px\`.
128 | `
129 |
130 | render () {
131 | return (
132 |
133 |
138 |
151 |
152 |
153 |
154 |
155 |
159 |
160 |
161 |
162 |
167 |
173 |
179 |
180 |
181 |
186 | {this.normalDoc()}
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | Foreseaz | 2019
197 |
198 |
199 | )
200 | }
201 | }
202 |
--------------------------------------------------------------------------------
/example/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: 'Montserrat', sans-serif;
5 | background: #fff7e5;
6 | }
7 | ::selection {
8 | background-color: #79FFE1;
9 | color: #000;
10 | }
11 | .container {
12 | width: 960px;
13 | padding: 50px 100px;
14 | margin: 0 auto;
15 | }
16 | .nav {
17 | padding: 30px 0;
18 | display: flex;
19 | justify-content: space-between;
20 | }
21 | .nav .title {
22 | /* color: #bf2f4c; */
23 | font-weight: 600;
24 | font-size: 40px;
25 | }
26 | .select-wrapper {
27 | padding: 0;
28 | margin-left: 10px;
29 | transform: translateY(10px);
30 | display: inline-block;
31 | border: 1px solid #bf2f4c;
32 | border-radius: 5px;
33 | width: 80px;
34 | overflow: hidden;
35 | background-color: #fff;
36 | box-shadow: rgba(0, 0, 0, 0.12) 0px 5px 10px;
37 | }
38 | .select-wrapper select {
39 | font-family: 'Montserrat', sans-serif;
40 | font-weight: 600;
41 | font-size: 14px;
42 | color: #bf2f4c;
43 | padding: 5px;
44 | width: 100%;
45 | border: none;
46 | box-shadow: none;
47 | background-color: #fff;
48 | background-image: none;
49 | -webkit-appearance: none;
50 | -moz-appearance: none;
51 | appearance: none;
52 | }
53 | .select-wrapper select:focus {
54 | outline: none;
55 | }
56 |
57 | .btns {
58 | padding: 50px 0 20px;
59 | }
60 | button {
61 | align-items: center;
62 | color: #fff;
63 | height: 40px;
64 | width: 175px;
65 | font-size: 12px;
66 | justify-content: center;
67 | text-transform: uppercase;
68 | cursor: pointer;
69 | text-align: center;
70 | user-select: none;
71 | font-weight: 100;
72 | position: relative;
73 | white-space: nowrap;
74 | line-height: 0;
75 | box-shadow: rgba(0, 0, 0, 0.12) 0px 5px 10px;
76 | background: rgb(0, 122, 255);
77 | padding: 0px 25px;
78 | outline: none;
79 | border-width: 1px;
80 | border-style: solid;
81 | border-color: rgb(0, 122, 255);
82 | border-image: initial;
83 | overflow: hidden;
84 | transition: all 0.15s ease 0s;
85 | border-radius: 5px;
86 | }
87 | button.success {
88 | background: #25c639;
89 | border-color: #25c639;
90 | }
91 | button.error {
92 | background: #ff564e;
93 | border-color: #ff564e;
94 | }
95 | button:hover {
96 | box-shadow: rgba(0, 0, 0, 0.16) 0px 7px 20px;
97 | transform: translateY(-1px);
98 | }
99 | button + button {
100 | margin-left: 15px;
101 | }
102 | .star {
103 | margin-top: 100px;
104 | }
105 | .author {
106 | margin-top: 30px;
107 | color: #aaa;
108 | font-size: 12px;
109 | }
110 | .markdown {
111 | font-family: sans-serif;
112 | }
113 | .markdown li {
114 | line-height: 1.4em;
115 | }
116 | .markdown code {
117 | background: white;
118 | border: 1px solid #ccc;
119 | padding: 1px 5px;
120 | border-radius: 5px;
121 | }
122 |
--------------------------------------------------------------------------------
/example/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 |
4 | import './index.css'
5 | import App from './App'
6 |
7 | ReactDOM.render(, document.getElementById('root'))
8 |
--------------------------------------------------------------------------------
/example/yarn-error.log:
--------------------------------------------------------------------------------
1 | Arguments:
2 | /usr/local/bin/node /Users/Foresea/.yarn/bin/yarn.js
3 |
4 | PATH:
5 | /Users/Foresea/.npm-packages/bin:/Users/Foresea/.rbenv/shims:/Users/Foresea/google-cloud-sdk/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/texbin:/Users/Foresea/bin:/Users/Foresea/.yarn/bin:/Users/Foresea/go/bin:/usr/local/go/bin
6 |
7 | Yarn version:
8 | 0.24.6
9 |
10 | Node version:
11 | 11.6.0
12 |
13 | Platform:
14 | darwin x64
15 |
16 | npm manifest:
17 | {
18 | "name": "react-loadcon-example",
19 | "homepage": "https://foreseaz.github.io/react-loadcon",
20 | "version": "0.0.0",
21 | "license": "MIT",
22 | "private": true,
23 | "dependencies": {
24 | "prop-types": "^15.6.2",
25 | "react": "^16.4.1",
26 | "react-dom": "^16.4.1",
27 | "react-scripts": "^1.1.4",
28 | "react-loadcon": "link:../dist/index.es.js"
29 | },
30 | "scripts": {
31 | "start": "react-scripts start",
32 | "build": "react-scripts build",
33 | "test": "react-scripts test --env=jsdom",
34 | "eject": "react-scripts eject"
35 | }
36 | }
37 |
38 | yarn manifest:
39 | No manifest
40 |
41 | Lockfile:
42 | No lockfile
43 |
44 | Trace:
45 | Error: https://registry.yarnpkg.com/react-loadcon: Not found
46 | at Request.params.callback [as _callback] (/Users/Foresea/.yarn/lib/yarn-cli.js:56255:18)
47 | at Request.self.callback (/Users/Foresea/.yarn/lib/yarn-cli.js:107854:22)
48 | at Request.emit (events.js:188:13)
49 | at Request. (/Users/Foresea/.yarn/lib/yarn-cli.js:108837:10)
50 | at Request.emit (events.js:188:13)
51 | at IncomingMessage. (/Users/Foresea/.yarn/lib/yarn-cli.js:108757:12)
52 | at Object.onceWrapper (events.js:276:13)
53 | at IncomingMessage.emit (events.js:193:15)
54 | at endReadableNT (_stream_readable.js:1129:12)
55 | at process.internalTickCallback (internal/process/next_tick.js:72:19)
56 |
--------------------------------------------------------------------------------
/imgs/intro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/foreseaz/react-loadcon/770ccb24c25d63714a4279f932c3ed1ca3ae0624/imgs/intro.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-loadcon",
3 | "version": "0.1.1",
4 | "description": "React component for manipulating the favicon, for loading or progress.",
5 | "author": "foreseaz",
6 | "license": "MIT",
7 | "repository": "foreseaz/react-loadcon",
8 | "main": "dist/index.js",
9 | "module": "dist/index.es.js",
10 | "jsnext:main": "dist/index.es.js",
11 | "engines": {
12 | "node": ">=8",
13 | "npm": ">=5"
14 | },
15 | "scripts": {
16 | "test": "cross-env CI=1 react-scripts test --env=jsdom",
17 | "test:watch": "react-scripts test --env=jsdom",
18 | "build": "rollup -c",
19 | "start": "rollup -c -w",
20 | "prepare": "yarn run build",
21 | "predeploy": "cd example && yarn install && yarn run build",
22 | "deploy": "gh-pages -d example/build"
23 | },
24 | "peerDependencies": {
25 | "prop-types": "^15.5.4",
26 | "react": "^15.0.0 || ^16.0.0",
27 | "react-dom": "^15.0.0 || ^16.0.0"
28 | },
29 | "devDependencies": {
30 | "@svgr/rollup": "^2.4.1",
31 | "babel-core": "^6.26.3",
32 | "babel-eslint": "^8.2.5",
33 | "babel-plugin-external-helpers": "^6.22.0",
34 | "babel-preset-env": "^1.7.0",
35 | "babel-preset-react": "^6.24.1",
36 | "babel-preset-stage-0": "^6.24.1",
37 | "cross-env": "^5.1.4",
38 | "eslint": "^5.0.1",
39 | "eslint-config-standard": "^11.0.0",
40 | "eslint-config-standard-react": "^6.0.0",
41 | "eslint-plugin-import": "^2.13.0",
42 | "eslint-plugin-node": "^7.0.1",
43 | "eslint-plugin-promise": "^4.0.0",
44 | "eslint-plugin-react": "^7.10.0",
45 | "eslint-plugin-standard": "^3.1.0",
46 | "gh-pages": "^1.2.0",
47 | "react": "^16.4.1",
48 | "react-dom": "^16.4.1",
49 | "react-scripts": "^1.1.4",
50 | "rollup": "^0.64.1",
51 | "rollup-plugin-babel": "^3.0.7",
52 | "rollup-plugin-commonjs": "^9.1.3",
53 | "rollup-plugin-node-resolve": "^3.3.0",
54 | "rollup-plugin-peer-deps-external": "^2.2.0",
55 | "rollup-plugin-postcss": "^1.6.2",
56 | "rollup-plugin-url": "^1.4.0"
57 | },
58 | "files": [
59 | "dist"
60 | ],
61 | "dependencies": {
62 | "react-fast-compare": "^2.0.4"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 | import commonjs from 'rollup-plugin-commonjs'
3 | import external from 'rollup-plugin-peer-deps-external'
4 | import postcss from 'rollup-plugin-postcss'
5 | import resolve from 'rollup-plugin-node-resolve'
6 | import url from 'rollup-plugin-url'
7 | import svgr from '@svgr/rollup'
8 |
9 | import pkg from './package.json'
10 |
11 | export default {
12 | input: 'src/index.js',
13 | output: [
14 | {
15 | file: pkg.main,
16 | format: 'cjs',
17 | sourcemap: true
18 | },
19 | {
20 | file: pkg.module,
21 | format: 'es',
22 | sourcemap: true
23 | }
24 | ],
25 | plugins: [
26 | external(),
27 | postcss({
28 | modules: true
29 | }),
30 | url(),
31 | svgr(),
32 | babel({
33 | exclude: 'node_modules/**',
34 | plugins: [ 'external-helpers' ]
35 | }),
36 | resolve(),
37 | commonjs()
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/src/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jest": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/Favicons/Donut.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import isEqual from 'react-fast-compare'
4 |
5 | import { getCanvas, setFaviconTag } from '../utils'
6 |
7 | class Donut extends React.Component {
8 | componentDidMount () {
9 | this.drawFavicon()
10 | }
11 |
12 | componentDidUpdate (prevProps) {
13 | const isPropsChanged = !isEqual(this.props, prevProps)
14 | if (isPropsChanged) {
15 | this.drawFavicon()
16 | }
17 | }
18 |
19 | drawFavicon () {
20 | const { donutWidth, percentage, color, background, shadow } = this.props
21 | const canvas = getCanvas()
22 | const ctx = canvas.getContext('2d')
23 |
24 | if (ctx) {
25 | ctx.clearRect(0, 0, canvas.width, canvas.height)
26 |
27 | // Draw shadow
28 | ctx.beginPath()
29 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
30 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false)
31 | ctx.fillStyle = shadow
32 | ctx.fill()
33 |
34 | // Draw background
35 | ctx.beginPath()
36 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
37 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)
38 | ctx.fillStyle = background
39 | ctx.fill()
40 |
41 | // Draw donut
42 | if (percentage > 0) {
43 | ctx.beginPath()
44 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
45 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)
46 | ctx.lineTo(canvas.width / 2, canvas.height / 2)
47 | ctx.fillStyle = color
48 | ctx.fill()
49 |
50 | ctx.beginPath()
51 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
52 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - donutWidth, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)
53 | ctx.lineTo(canvas.width / 2, canvas.height / 2)
54 | ctx.fillStyle = background
55 | ctx.fill()
56 | }
57 | }
58 |
59 | setFaviconTag(canvas.toDataURL())
60 | }
61 |
62 | render () {
63 | return (null)
64 | }
65 | }
66 |
67 | Donut.propTypes = {
68 | donutWidth: PropTypes.number,
69 | percentage: PropTypes.number,
70 | color: PropTypes.string,
71 | background: PropTypes.string,
72 | shadow: PropTypes.string,
73 | }
74 |
75 | export default Donut
76 |
--------------------------------------------------------------------------------
/src/Favicons/Exception.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 |
4 | import { getCanvas, setFaviconTag } from '../utils'
5 |
6 | class Exception extends React.Component {
7 | componentDidMount () {
8 | this.drawFavicon()
9 | }
10 |
11 | drawFavicon () {
12 | const { color } = this.props
13 | const canvas = getCanvas()
14 | const ctx = canvas.getContext('2d')
15 |
16 | ctx.clearRect(0, 0, canvas.width, canvas.height)
17 |
18 | // Draw background
19 | ctx.beginPath()
20 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
21 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)
22 | ctx.fillStyle = color
23 | ctx.fill()
24 |
25 | // Draw cross
26 | ctx.beginPath()
27 | ctx.moveTo(canvas.width / 3, canvas.height / 3)
28 | ctx.lineTo(2 * canvas.width / 3, 2 * canvas.height / 3)
29 | ctx.lineWidth = 3
30 | ctx.strokeStyle = '#fff'
31 | ctx.stroke()
32 |
33 | ctx.beginPath()
34 | ctx.moveTo(canvas.width / 3, 2 * canvas.height / 3)
35 | ctx.lineTo(2 * canvas.width / 3, canvas.height / 3)
36 | ctx.lineWidth = 3
37 | ctx.strokeStyle = '#fff'
38 | ctx.stroke()
39 |
40 | setFaviconTag(canvas.toDataURL())
41 | }
42 |
43 | render () {
44 | return (null)
45 | }
46 | }
47 |
48 | Exception.propTypes = {
49 | color: PropTypes.string,
50 | }
51 |
52 | Exception.defaultProps = {
53 | color: '#ff564e'
54 | }
55 |
56 | export default Exception
57 |
--------------------------------------------------------------------------------
/src/Favicons/Pie.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import isEqual from 'react-fast-compare'
4 |
5 | import { getCanvas, setFaviconTag } from '../utils'
6 |
7 | class Pie extends React.Component {
8 | componentDidMount () {
9 | this.drawFavicon()
10 | }
11 |
12 | componentDidUpdate (prevProps) {
13 | const isPropsChanged = !isEqual(this.props, prevProps)
14 | if (isPropsChanged) {
15 | this.drawFavicon()
16 | }
17 | }
18 |
19 | drawFavicon () {
20 | const { percentage, color, background, shadow } = this.props
21 | const canvas = getCanvas()
22 | const ctx = canvas.getContext('2d')
23 |
24 | if (ctx) {
25 | ctx.clearRect(0, 0, canvas.width, canvas.height)
26 |
27 | // Draw shadow
28 | ctx.beginPath()
29 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
30 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2), 0, Math.PI * 2, false)
31 | ctx.fillStyle = shadow
32 | ctx.fill()
33 |
34 | // Draw background
35 | ctx.beginPath()
36 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
37 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)
38 | ctx.fillStyle = background
39 | ctx.fill()
40 |
41 | // Draw pie
42 | if (percentage > 0) {
43 | ctx.beginPath()
44 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
45 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, (-0.5) * Math.PI, (-0.5 + 2 * percentage / 100) * Math.PI, false)
46 | ctx.lineTo(canvas.width / 2, canvas.height / 2)
47 | ctx.fillStyle = color
48 | ctx.fill()
49 | }
50 | }
51 |
52 | setFaviconTag(canvas.toDataURL())
53 | }
54 |
55 | render () {
56 | return (null)
57 | }
58 | }
59 |
60 | Pie.propTypes = {
61 | percentage: PropTypes.number,
62 | color: PropTypes.string,
63 | background: PropTypes.string,
64 | shadow: PropTypes.string,
65 | }
66 |
67 | export default Pie
68 |
--------------------------------------------------------------------------------
/src/Favicons/Success.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 |
4 | import { getCanvas, setFaviconTag } from '../utils'
5 |
6 | class Success extends React.Component {
7 | componentDidMount () {
8 | this.drawFavicon()
9 | }
10 |
11 | drawFavicon () {
12 | const { color } = this.props
13 | const canvas = getCanvas()
14 | const ctx = canvas.getContext('2d')
15 |
16 | if (ctx) {
17 | ctx.clearRect(0, 0, canvas.width, canvas.height)
18 |
19 | // Draw background
20 | ctx.beginPath()
21 | ctx.moveTo(canvas.width / 2, canvas.height / 2)
22 | ctx.arc(canvas.width / 2, canvas.height / 2, Math.min(canvas.width / 2, canvas.height / 2) - 2, 0, Math.PI * 2, false)
23 | ctx.fillStyle = color
24 | ctx.fill()
25 |
26 | // Draw tick
27 | ctx.beginPath()
28 | ctx.moveTo(canvas.width * 0.22, canvas.height * 0.5)
29 | ctx.lineTo(canvas.width * 0.45, canvas.height * 0.7)
30 | ctx.lineTo(canvas.width * 0.73, canvas.height * 0.3)
31 | ctx.lineWidth = 3
32 | ctx.strokeStyle = '#fff'
33 | ctx.stroke()
34 | }
35 |
36 | setFaviconTag(canvas.toDataURL())
37 | }
38 |
39 | render () {
40 | return (null)
41 | }
42 | }
43 |
44 | Success.propTypes = {
45 | color: PropTypes.string,
46 | }
47 |
48 | Success.defaultProps = {
49 | color: '#25c639'
50 | }
51 |
52 | export default Success
53 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import isEqual from 'react-fast-compare'
4 |
5 | import NoSSR from './utils/NoSSR'
6 | import { getFaviconURL, setFaviconTag } from './utils'
7 |
8 | import PieCon from './Favicons/Pie'
9 | import DonutCon from './Favicons/Donut'
10 | import ExceptionCon from './Favicons/Exception'
11 | import SuccessCon from './Favicons/Success'
12 |
13 | class LoadCon extends React.Component {
14 | state = {
15 | originalFaviconURL: null
16 | }
17 |
18 | componentDidMount () {
19 | this.setState({
20 | originalFaviconURL: getFaviconURL()
21 | })
22 | }
23 |
24 | componentDidUpdate (prevProps) {
25 | const isPropsChanged = !isEqual(this.props, prevProps)
26 | if (isPropsChanged) {
27 | if (this.props.status === 'normal') {
28 | this._resetFavicon()
29 | }
30 | }
31 | }
32 |
33 | _renderFavicon = () => {
34 | switch (this.props.type) {
35 | default:
36 | case 'pie':
37 | return
38 | case 'donut':
39 | return
40 | }
41 | }
42 |
43 | _resetFavicon = () => {
44 | const { originalFaviconURL } = this.state
45 | setFaviconTag(originalFaviconURL)
46 | }
47 |
48 | render() {
49 | const { status } = this.props
50 | return (
51 |
52 | {status === 'active' && this._renderFavicon()}
53 | {status === 'exception' && }
54 | {status === 'success' && }
55 |
56 | )
57 | }
58 | }
59 |
60 | LoadCon.propTypes = {
61 | percentage: PropTypes.number.isRequired,
62 | type: PropTypes.oneOf(['pie', 'donut']),
63 | status: PropTypes.oneOf(['normal', 'active', 'exception', 'success']),
64 | color: PropTypes.string,
65 | background: PropTypes.string,
66 | shadow: PropTypes.string,
67 | donutWidth: PropTypes.number,
68 | }
69 |
70 | LoadCon.defaultProps = {
71 | percentage: 0,
72 | type: 'pie',
73 | status: 'normal',
74 | color: '#25c639',
75 | background: '#eee',
76 | shadow: '#fff',
77 | donutWidth: 8,
78 | }
79 |
80 | export default LoadCon
81 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | /* add css styles here (optional) */
2 |
3 | .test {
4 | display: inline-block;
5 | margin: 2em auto;
6 | border: 2px solid #000;
7 | font-size: 2em;
8 | }
9 |
--------------------------------------------------------------------------------
/src/test.js:
--------------------------------------------------------------------------------
1 | import ExampleComponent from './'
2 |
3 | describe('ExampleComponent', () => {
4 | it('is truthy', () => {
5 | expect(ExampleComponent).toBeTruthy()
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/src/utils/NoSSR.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | const DefaultOnSSR = () => ()
4 |
5 | class NoSSR extends Component {
6 | state = {
7 | canRender: false
8 | }
9 |
10 | componentDidMount() {
11 | this.setState({ canRender: true })
12 | }
13 |
14 | render() {
15 | const { children, onSSR = } = this.props
16 |
17 | return (
18 |
19 | {this.state.canRender ? children : onSSR}
20 |
21 | )
22 | }
23 | }
24 |
25 | export default NoSSR
26 |
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | const isUA = (browser) => {
2 | const agent = navigator.userAgent.toLowerCase()
3 | return agent.indexOf(browser) !== 1
4 | }
5 |
6 | export const getIsRetina = () => {
7 | return window.devicePixelRatio > 1
8 | }
9 |
10 | export const getBrowser = () => {
11 | if (isUA('msie')) {
12 | return 'ie'
13 | } else if (isUA('chrome')) {
14 | return 'chrome'
15 | } else if (isUA('chrome') || isUA('safari')) {
16 | return 'webkit'
17 | } else if (isUA('safari') && !isUA('chrome')) {
18 | return 'safari'
19 | } else if (isUA('mozilla') && !isUA('chrome') && !isUA('safari')) {
20 | return 'mozilla'
21 | }
22 | }
23 |
24 | export const getFaviconURL = () => {
25 | const links = document.getElementsByTagName('link')
26 | let tag = null
27 |
28 | for (let i = 0, l = links.length; i < l; i++) {
29 | if (links[i].getAttribute('rel') === 'icon'
30 | || links[i].getAttribute('rel') === 'shortcut icon') {
31 | tag = links[i]
32 | }
33 | }
34 |
35 | return tag ? tag.getAttribute('href') : '/favicon.ico'
36 | }
37 |
38 | export const removeFaviconTag = () => {
39 | const links = Array.prototype.slice.call(document.getElementsByTagName('link'), 0)
40 | const head = document.getElementsByTagName('head')[0]
41 |
42 | for (let i = 0, l = links.length; i < l; i++) {
43 | if (links[i].getAttribute('rel') === 'icon'
44 | || links[i].getAttribute('rel') === 'shortcut icon') {
45 | head.removeChild(links[i])
46 | }
47 | }
48 | }
49 |
50 | export const setFaviconTag = (url) => {
51 | removeFaviconTag()
52 |
53 | const link = document.createElement('link')
54 | link.type = 'image/x-icon'
55 | link.rel = 'icon'
56 | link.href = url
57 |
58 | document.getElementsByTagName('head')[0].appendChild(link)
59 | }
60 |
61 | export const getCanvas = function () {
62 | const canvas = document.createElement("canvas")
63 | if (getIsRetina()) {
64 | canvas.width = 32
65 | canvas.height = 32
66 | } else {
67 | canvas.width = 16
68 | canvas.height = 16
69 | }
70 |
71 | return canvas
72 | }
73 |
--------------------------------------------------------------------------------