UNPKG

41.1 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var React = require('react');
8var React__default = _interopDefault(React);
9var cx = _interopDefault(require('clsx'));
10var reactDom = require('react-dom');
11
12function _extends() {
13 _extends = Object.assign || function (target) {
14 for (var i = 1; i < arguments.length; i++) {
15 var source = arguments[i];
16
17 for (var key in source) {
18 if (Object.prototype.hasOwnProperty.call(source, key)) {
19 target[key] = source[key];
20 }
21 }
22 }
23
24 return target;
25 };
26
27 return _extends.apply(this, arguments);
28}
29
30function _objectWithoutPropertiesLoose(source, excluded) {
31 if (source == null) return {};
32 var target = {};
33 var sourceKeys = Object.keys(source);
34 var key, i;
35
36 for (i = 0; i < sourceKeys.length; i++) {
37 key = sourceKeys[i];
38 if (excluded.indexOf(key) >= 0) continue;
39 target[key] = source[key];
40 }
41
42 return target;
43}
44
45function isNum(v) {
46 return typeof v === 'number' && !isNaN(v);
47}
48function isBool(v) {
49 return typeof v === 'boolean';
50}
51function isStr(v) {
52 return typeof v === 'string';
53}
54function isFn(v) {
55 return typeof v === 'function';
56}
57function parseClassName(v) {
58 return isStr(v) || isFn(v) ? v : null;
59}
60function isToastIdValid(toastId) {
61 return toastId === 0 || toastId;
62}
63function getAutoCloseDelay(toastAutoClose, containerAutoClose) {
64 return toastAutoClose === false || isNum(toastAutoClose) && toastAutoClose > 0 ? toastAutoClose : containerAutoClose;
65}
66var canUseDom = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
67function canBeRendered(content) {
68 return React.isValidElement(content) || isStr(content) || isFn(content) || isNum(content);
69}
70
71var POSITION = {
72 TOP_LEFT: 'top-left',
73 TOP_RIGHT: 'top-right',
74 TOP_CENTER: 'top-center',
75 BOTTOM_LEFT: 'bottom-left',
76 BOTTOM_RIGHT: 'bottom-right',
77 BOTTOM_CENTER: 'bottom-center'
78};
79var TYPE = {
80 INFO: 'info',
81 SUCCESS: 'success',
82 WARNING: 'warning',
83 ERROR: 'error',
84 DEFAULT: 'default'
85};
86
87/**
88 * Used to collapse toast after exit animation
89 */
90function collapseToast(node, done, duration
91/* COLLAPSE_DURATION */
92) {
93 if (duration === void 0) {
94 duration = 300;
95 }
96
97 var scrollHeight = node.scrollHeight,
98 style = node.style;
99 requestAnimationFrame(function () {
100 style.minHeight = 'initial';
101 style.height = scrollHeight + 'px';
102 style.transition = "all " + duration + "ms";
103 requestAnimationFrame(function () {
104 style.height = '0';
105 style.padding = '0';
106 style.margin = '0';
107 setTimeout(done, duration);
108 });
109 });
110}
111
112/**
113 * Css animation that just work.
114 * You could use animate.css for instance
115 *
116 *
117 * ```
118 * cssTransition({
119 * enter: "animate__animated animate__bounceIn",
120 * exit: "animate__animated animate__bounceOut"
121 * })
122 * ```
123 *
124 */
125
126function cssTransition(_ref) {
127 var enter = _ref.enter,
128 exit = _ref.exit,
129 _ref$appendPosition = _ref.appendPosition,
130 appendPosition = _ref$appendPosition === void 0 ? false : _ref$appendPosition,
131 _ref$collapse = _ref.collapse,
132 collapse = _ref$collapse === void 0 ? true : _ref$collapse,
133 _ref$collapseDuration = _ref.collapseDuration,
134 collapseDuration = _ref$collapseDuration === void 0 ? 300 : _ref$collapseDuration;
135 return function ToastTransition(_ref2) {
136 var children = _ref2.children,
137 position = _ref2.position,
138 preventExitTransition = _ref2.preventExitTransition,
139 done = _ref2.done,
140 nodeRef = _ref2.nodeRef,
141 isIn = _ref2.isIn;
142 var enterClassName = appendPosition ? enter + "--" + position : enter;
143 var exitClassName = appendPosition ? exit + "--" + position : exit;
144 var baseClassName = React.useRef();
145 var animationStep = React.useRef(0
146 /* Enter */
147 );
148 React.useLayoutEffect(function () {
149 onEnter();
150 }, []);
151 React.useEffect(function () {
152 if (!isIn) preventExitTransition ? onExited() : onExit();
153 }, [isIn]);
154
155 function onEnter() {
156 var node = nodeRef.current;
157 baseClassName.current = node.className;
158 node.className += " " + enterClassName;
159 node.addEventListener('animationend', onEntered);
160 }
161
162 function onEntered(e) {
163 if (e.target !== nodeRef.current) return;
164 var node = nodeRef.current;
165 node.removeEventListener('animationend', onEntered);
166
167 if (animationStep.current === 0
168 /* Enter */
169 ) {
170 node.className = baseClassName.current;
171 }
172 }
173
174 function onExit() {
175 animationStep.current = 1
176 /* Exit */
177 ;
178 var node = nodeRef.current;
179 node.className += " " + exitClassName;
180 node.addEventListener('animationend', onExited);
181 }
182
183 function onExited() {
184 var node = nodeRef.current;
185 node.removeEventListener('animationend', onExited);
186 collapse ? collapseToast(node, done, collapseDuration) : done();
187 }
188
189 return React__default.createElement(React__default.Fragment, null, children);
190 };
191}
192
193var eventManager = {
194 list: /*#__PURE__*/new Map(),
195 emitQueue: /*#__PURE__*/new Map(),
196 on: function on(event, callback) {
197 this.list.has(event) || this.list.set(event, []);
198 this.list.get(event).push(callback);
199 return this;
200 },
201 off: function off(event, callback) {
202 if (callback) {
203 var cb = this.list.get(event).filter(function (cb) {
204 return cb !== callback;
205 });
206 this.list.set(event, cb);
207 return this;
208 }
209
210 this.list["delete"](event);
211 return this;
212 },
213 cancelEmit: function cancelEmit(event) {
214 var timers = this.emitQueue.get(event);
215
216 if (timers) {
217 timers.forEach(clearTimeout);
218 this.emitQueue["delete"](event);
219 }
220
221 return this;
222 },
223
224 /**
225 * Enqueue the event at the end of the call stack
226 * Doing so let the user call toast as follow:
227 * toast('1')
228 * toast('2')
229 * toast('3')
230 * Without setTimemout the code above will not work
231 */
232 emit: function emit(event) {
233 var _this = this;
234
235 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
236 args[_key - 1] = arguments[_key];
237 }
238
239 this.list.has(event) && this.list.get(event).forEach(function (callback) {
240 var timer = setTimeout(function () {
241 // @ts-ignore
242 callback.apply(void 0, args);
243 }, 0);
244 _this.emitQueue.has(event) || _this.emitQueue.set(event, []);
245
246 _this.emitQueue.get(event).push(timer);
247 });
248 }
249};
250
251/**
252 * `useKeeper` is a helper around `useRef`.
253 *
254 * You don't need to access the `.current`property to get the value
255 * If refresh is set to true. The ref will be updated every render
256 */
257
258function useKeeper(arg, refresh) {
259 if (refresh === void 0) {
260 refresh = false;
261 }
262
263 var ref = React.useRef(arg);
264 React.useEffect(function () {
265 if (refresh) ref.current = arg;
266 });
267 return ref.current;
268}
269
270function reducer(state, action) {
271 switch (action.type) {
272 case 0
273 /* ADD */
274 :
275 return [].concat(state, [action.toastId]).filter(function (id) {
276 return id !== action.staleId;
277 });
278
279 case 1
280 /* REMOVE */
281 :
282 return isToastIdValid(action.toastId) ? state.filter(function (id) {
283 return id !== action.toastId;
284 }) : [];
285 }
286}
287
288var _excluded = ["delay", "staleId"];
289function useToastContainer(props) {
290 var _useReducer = React.useReducer(function (x) {
291 return x + 1;
292 }, 0),
293 forceUpdate = _useReducer[1];
294
295 var _useReducer2 = React.useReducer(reducer, []),
296 toast = _useReducer2[0],
297 dispatch = _useReducer2[1];
298
299 var containerRef = React.useRef(null);
300 var toastCount = useKeeper(0);
301 var queue = useKeeper([]);
302 var collection = useKeeper({});
303 var instance = useKeeper({
304 toastKey: 1,
305 displayedToast: 0,
306 props: props,
307 containerId: null,
308 isToastActive: isToastActive,
309 getToast: function getToast(id) {
310 return collection[id] || null;
311 }
312 });
313 React.useEffect(function () {
314 instance.containerId = props.containerId;
315 eventManager.cancelEmit(3
316 /* WillUnmount */
317 ).on(0
318 /* Show */
319 , buildToast).on(1
320 /* Clear */
321 , function (toastId) {
322 return containerRef.current && removeToast(toastId);
323 }).on(5
324 /* ClearWaitingQueue */
325 , clearWaitingQueue).emit(2
326 /* DidMount */
327 , instance);
328 return function () {
329 return eventManager.emit(3
330 /* WillUnmount */
331 , instance);
332 };
333 }, []);
334 React.useEffect(function () {
335 instance.isToastActive = isToastActive;
336 instance.displayedToast = toast.length;
337 eventManager.emit(4
338 /* Change */
339 , toast.length, props.containerId);
340 }, [toast]);
341 React.useEffect(function () {
342 instance.props = props;
343 });
344
345 function isToastActive(id) {
346 return toast.indexOf(id) !== -1;
347 }
348
349 function clearWaitingQueue(_ref) {
350 var containerId = _ref.containerId;
351 var limit = instance.props.limit;
352
353 if (limit && (!containerId || instance.containerId === containerId)) {
354 toastCount -= queue.length;
355 queue = [];
356 }
357 }
358
359 function removeToast(toastId) {
360 dispatch({
361 type: 1
362 /* REMOVE */
363 ,
364 toastId: toastId
365 });
366 }
367
368 function dequeueToast() {
369 var _queue$shift = queue.shift(),
370 toastContent = _queue$shift.toastContent,
371 toastProps = _queue$shift.toastProps,
372 staleId = _queue$shift.staleId;
373
374 appendToast(toastContent, toastProps, staleId);
375 }
376 /**
377 * check if a container is attached to the dom
378 * check for multi-container, build only if associated
379 * check for duplicate toastId if no update
380 */
381
382
383 function isNotValid(_ref2) {
384 var containerId = _ref2.containerId,
385 toastId = _ref2.toastId,
386 updateId = _ref2.updateId;
387 return !containerRef.current || instance.props.enableMultiContainer && containerId !== instance.props.containerId || collection[toastId] && updateId == null ? true : false;
388 } // this function and all the function called inside needs to rely on ref(`useKeeper`)
389
390
391 function buildToast(content, _ref3) {
392 var _options$icon;
393
394 var delay = _ref3.delay,
395 staleId = _ref3.staleId,
396 options = _objectWithoutPropertiesLoose(_ref3, _excluded);
397
398 if (!canBeRendered(content) || isNotValid(options)) return;
399 var toastId = options.toastId,
400 updateId = options.updateId,
401 data = options.data;
402 var props = instance.props;
403
404 var closeToast = function closeToast() {
405 return removeToast(toastId);
406 };
407
408 var isNotAnUpdate = options.updateId == null;
409 if (isNotAnUpdate) toastCount++;
410 var toastProps = {
411 toastId: toastId,
412 updateId: updateId,
413 isLoading: options.isLoading,
414 theme: options.theme || props.theme,
415 icon: (_options$icon = options.icon) != null ? _options$icon : props.icon,
416 isIn: false,
417 key: options.key || instance.toastKey++,
418 type: options.type,
419 closeToast: closeToast,
420 closeButton: options.closeButton,
421 rtl: props.rtl,
422 position: options.position || props.position,
423 transition: options.transition || props.transition,
424 className: parseClassName(options.className || props.toastClassName),
425 bodyClassName: parseClassName(options.bodyClassName || props.bodyClassName),
426 style: options.style || props.toastStyle,
427 bodyStyle: options.bodyStyle || props.bodyStyle,
428 onClick: options.onClick || props.onClick,
429 pauseOnHover: isBool(options.pauseOnHover) ? options.pauseOnHover : props.pauseOnHover,
430 pauseOnFocusLoss: isBool(options.pauseOnFocusLoss) ? options.pauseOnFocusLoss : props.pauseOnFocusLoss,
431 draggable: isBool(options.draggable) ? options.draggable : props.draggable,
432 draggablePercent: isNum(options.draggablePercent) ? options.draggablePercent : props.draggablePercent,
433 draggableDirection: options.draggableDirection || props.draggableDirection,
434 closeOnClick: isBool(options.closeOnClick) ? options.closeOnClick : props.closeOnClick,
435 progressClassName: parseClassName(options.progressClassName || props.progressClassName),
436 progressStyle: options.progressStyle || props.progressStyle,
437 autoClose: options.isLoading ? false : getAutoCloseDelay(options.autoClose, props.autoClose),
438 hideProgressBar: isBool(options.hideProgressBar) ? options.hideProgressBar : props.hideProgressBar,
439 progress: options.progress,
440 role: isStr(options.role) ? options.role : props.role,
441 deleteToast: function deleteToast() {
442 removeFromCollection(toastId);
443 }
444 };
445 if (isFn(options.onOpen)) toastProps.onOpen = options.onOpen;
446 if (isFn(options.onClose)) toastProps.onClose = options.onClose; // tweak for vertical dragging
447
448 if (toastProps.draggableDirection === "y"
449 /* Y */
450 && toastProps.draggablePercent === 80
451 /* DRAGGABLE_PERCENT */
452 ) {
453 toastProps.draggablePercent *= 1.5;
454 }
455
456 var closeButton = props.closeButton;
457
458 if (options.closeButton === false || canBeRendered(options.closeButton)) {
459 closeButton = options.closeButton;
460 } else if (options.closeButton === true) {
461 closeButton = canBeRendered(props.closeButton) ? props.closeButton : true;
462 }
463
464 toastProps.closeButton = closeButton;
465 var toastContent = content;
466
467 if (React.isValidElement(content) && !isStr(content.type)) {
468 toastContent = React.cloneElement(content, {
469 closeToast: closeToast,
470 toastProps: toastProps,
471 data: data
472 });
473 } else if (isFn(content)) {
474 toastContent = content({
475 closeToast: closeToast,
476 toastProps: toastProps,
477 data: data
478 });
479 } // not handling limit + delay by design. Waiting for user feedback first
480
481
482 if (props.limit && props.limit > 0 && toastCount > props.limit && isNotAnUpdate) {
483 queue.push({
484 toastContent: toastContent,
485 toastProps: toastProps,
486 staleId: staleId
487 });
488 } else if (isNum(delay) && delay > 0) {
489 setTimeout(function () {
490 appendToast(toastContent, toastProps, staleId);
491 }, delay);
492 } else {
493 appendToast(toastContent, toastProps, staleId);
494 }
495 }
496
497 function appendToast(content, toastProps, staleId) {
498 var toastId = toastProps.toastId;
499 if (staleId) delete collection[staleId];
500 collection[toastId] = {
501 content: content,
502 props: toastProps
503 };
504 dispatch({
505 type: 0
506 /* ADD */
507 ,
508 toastId: toastId,
509 staleId: staleId
510 });
511 }
512
513 function removeFromCollection(toastId) {
514 delete collection[toastId];
515 var queueLen = queue.length;
516 toastCount = isToastIdValid(toastId) ? toastCount - 1 : toastCount - instance.displayedToast;
517 if (toastCount < 0) toastCount = 0;
518
519 if (queueLen > 0) {
520 var freeSlot = isToastIdValid(toastId) ? 1 : instance.props.limit;
521
522 if (queueLen === 1 || freeSlot === 1) {
523 instance.displayedToast++;
524 dequeueToast();
525 } else {
526 var toDequeue = freeSlot > queueLen ? queueLen : freeSlot;
527 instance.displayedToast = toDequeue;
528
529 for (var i = 0; i < toDequeue; i++) {
530 dequeueToast();
531 }
532 }
533 } else {
534 forceUpdate();
535 }
536 }
537
538 function getToastToRender(cb) {
539 var toastToRender = {};
540 var toastList = props.newestOnTop ? Object.keys(collection).reverse() : Object.keys(collection);
541
542 for (var i = 0; i < toastList.length; i++) {
543 var _toast = collection[toastList[i]];
544 var position = _toast.props.position;
545 toastToRender[position] || (toastToRender[position] = []);
546 toastToRender[position].push(_toast);
547 }
548
549 return Object.keys(toastToRender).map(function (p) {
550 return cb(p, toastToRender[p]);
551 });
552 }
553
554 return {
555 getToastToRender: getToastToRender,
556 collection: collection,
557 containerRef: containerRef,
558 isToastActive: isToastActive
559 };
560}
561
562function getX(e) {
563 return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientX : e.clientX;
564}
565
566function getY(e) {
567 return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientY : e.clientY;
568}
569
570function useToast(props) {
571 var _useState = React.useState(true),
572 isRunning = _useState[0],
573 setIsRunning = _useState[1];
574
575 var _useState2 = React.useState(false),
576 preventExitTransition = _useState2[0],
577 setPreventExitTransition = _useState2[1];
578
579 var toastRef = React.useRef(null);
580 var drag = useKeeper({
581 start: 0,
582 x: 0,
583 y: 0,
584 delta: 0,
585 removalDistance: 0,
586 canCloseOnClick: true,
587 canDrag: false,
588 boundingRect: null
589 });
590 var syncProps = useKeeper(props, true);
591 var autoClose = props.autoClose,
592 pauseOnHover = props.pauseOnHover,
593 closeToast = props.closeToast,
594 onClick = props.onClick,
595 closeOnClick = props.closeOnClick;
596 React.useEffect(function () {
597 if (isFn(props.onOpen)) props.onOpen(React.isValidElement(props.children) && props.children.props);
598 return function () {
599 if (isFn(syncProps.onClose)) syncProps.onClose(React.isValidElement(syncProps.children) && syncProps.children.props);
600 };
601 }, []);
602 React.useEffect(function () {
603 props.draggable && bindDragEvents();
604 return function () {
605 props.draggable && unbindDragEvents();
606 };
607 }, [props.draggable]);
608 React.useEffect(function () {
609 props.pauseOnFocusLoss && bindFocusEvents();
610 return function () {
611 props.pauseOnFocusLoss && unbindFocusEvents();
612 };
613 }, [props.pauseOnFocusLoss]);
614
615 function onDragStart(e) {
616 if (props.draggable) {
617 var toast = toastRef.current;
618 drag.canCloseOnClick = true;
619 drag.canDrag = true;
620 drag.boundingRect = toast.getBoundingClientRect();
621 toast.style.transition = '';
622 drag.x = getX(e.nativeEvent);
623 drag.y = getY(e.nativeEvent);
624
625 if (props.draggableDirection === "x"
626 /* X */
627 ) {
628 drag.start = drag.x;
629 drag.removalDistance = toast.offsetWidth * (props.draggablePercent / 100);
630 } else {
631 drag.start = drag.y;
632 drag.removalDistance = toast.offsetHeight * (props.draggablePercent / 100);
633 }
634 }
635 }
636
637 function onDragTransitionEnd() {
638 if (drag.boundingRect) {
639 var _drag$boundingRect = drag.boundingRect,
640 top = _drag$boundingRect.top,
641 bottom = _drag$boundingRect.bottom,
642 left = _drag$boundingRect.left,
643 right = _drag$boundingRect.right;
644
645 if (props.pauseOnHover && drag.x >= left && drag.x <= right && drag.y >= top && drag.y <= bottom) {
646 pauseToast();
647 } else {
648 playToast();
649 }
650 }
651 }
652
653 function playToast() {
654 setIsRunning(true);
655 }
656
657 function pauseToast() {
658 setIsRunning(false);
659 }
660
661 function bindFocusEvents() {
662 if (!document.hasFocus()) pauseToast();
663 window.addEventListener('focus', playToast);
664 window.addEventListener('blur', pauseToast);
665 }
666
667 function unbindFocusEvents() {
668 window.removeEventListener('focus', playToast);
669 window.removeEventListener('blur', pauseToast);
670 }
671
672 function bindDragEvents() {
673 document.addEventListener('mousemove', onDragMove);
674 document.addEventListener('mouseup', onDragEnd);
675 document.addEventListener('touchmove', onDragMove);
676 document.addEventListener('touchend', onDragEnd);
677 }
678
679 function unbindDragEvents() {
680 document.removeEventListener('mousemove', onDragMove);
681 document.removeEventListener('mouseup', onDragEnd);
682 document.removeEventListener('touchmove', onDragMove);
683 document.removeEventListener('touchend', onDragEnd);
684 }
685
686 function onDragMove(e) {
687 if (drag.canDrag) {
688 e.preventDefault();
689 var toast = toastRef.current;
690 if (isRunning) pauseToast();
691 drag.x = getX(e);
692 drag.y = getY(e);
693
694 if (props.draggableDirection === "x"
695 /* X */
696 ) {
697 drag.delta = drag.x - drag.start;
698 } else {
699 drag.delta = drag.y - drag.start;
700 } // prevent false positif during a toast click
701
702
703 if (drag.start !== drag.x) drag.canCloseOnClick = false;
704 toast.style.transform = "translate" + props.draggableDirection + "(" + drag.delta + "px)";
705 toast.style.opacity = "" + (1 - Math.abs(drag.delta / drag.removalDistance));
706 }
707 }
708
709 function onDragEnd() {
710 var toast = toastRef.current;
711
712 if (drag.canDrag) {
713 drag.canDrag = false;
714
715 if (Math.abs(drag.delta) > drag.removalDistance) {
716 setPreventExitTransition(true);
717 props.closeToast();
718 return;
719 }
720
721 toast.style.transition = 'transform 0.2s, opacity 0.2s';
722 toast.style.transform = "translate" + props.draggableDirection + "(0)";
723 toast.style.opacity = '1';
724 }
725 }
726
727 var eventHandlers = {
728 onMouseDown: onDragStart,
729 onTouchStart: onDragStart,
730 onMouseUp: onDragTransitionEnd,
731 onTouchEnd: onDragTransitionEnd
732 };
733
734 if (autoClose && pauseOnHover) {
735 eventHandlers.onMouseEnter = pauseToast;
736 eventHandlers.onMouseLeave = playToast;
737 } // prevent toast from closing when user drags the toast
738
739
740 if (closeOnClick) {
741 eventHandlers.onClick = function (e) {
742 onClick && onClick(e);
743 drag.canCloseOnClick && closeToast();
744 };
745 }
746
747 return {
748 playToast: playToast,
749 pauseToast: pauseToast,
750 isRunning: isRunning,
751 preventExitTransition: preventExitTransition,
752 toastRef: toastRef,
753 eventHandlers: eventHandlers
754 };
755}
756
757function CloseButton(_ref) {
758 var closeToast = _ref.closeToast,
759 theme = _ref.theme,
760 _ref$ariaLabel = _ref.ariaLabel,
761 ariaLabel = _ref$ariaLabel === void 0 ? 'close' : _ref$ariaLabel;
762 return React.createElement("button", {
763 className: "Toastify"
764 /* CSS_NAMESPACE */
765 + "__close-button " + "Toastify"
766 /* CSS_NAMESPACE */
767 + "__close-button--" + theme,
768 type: "button",
769 onClick: function onClick(e) {
770 e.stopPropagation();
771 closeToast(e);
772 },
773 "aria-label": ariaLabel
774 }, React.createElement("svg", {
775 "aria-hidden": "true",
776 viewBox: "0 0 14 16"
777 }, React.createElement("path", {
778 fillRule: "evenodd",
779 d: "M7.71 8.23l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75L1 11.98l3.75-3.75L1 4.48 2.48 3l3.75 3.75L9.98 3l1.48 1.48-3.75 3.75z"
780 })));
781}
782
783function ProgressBar(_ref) {
784 var _cx, _animationEvent;
785
786 var delay = _ref.delay,
787 isRunning = _ref.isRunning,
788 closeToast = _ref.closeToast,
789 type = _ref.type,
790 hide = _ref.hide,
791 className = _ref.className,
792 userStyle = _ref.style,
793 controlledProgress = _ref.controlledProgress,
794 progress = _ref.progress,
795 rtl = _ref.rtl,
796 isIn = _ref.isIn,
797 theme = _ref.theme;
798
799 var style = _extends({}, userStyle, {
800 animationDuration: delay + "ms",
801 animationPlayState: isRunning ? 'running' : 'paused',
802 opacity: hide ? 0 : 1
803 });
804
805 if (controlledProgress) style.transform = "scaleX(" + progress + ")";
806 var defaultClassName = cx("Toastify"
807 /* CSS_NAMESPACE */
808 + "__progress-bar", controlledProgress ? "Toastify"
809 /* CSS_NAMESPACE */
810 + "__progress-bar--controlled" : "Toastify"
811 /* CSS_NAMESPACE */
812 + "__progress-bar--animated", "Toastify"
813 /* CSS_NAMESPACE */
814 + "__progress-bar-theme--" + theme, "Toastify"
815 /* CSS_NAMESPACE */
816 + "__progress-bar--" + type, (_cx = {}, _cx["Toastify"
817 /* CSS_NAMESPACE */
818 + "__progress-bar--rtl"] = rtl, _cx));
819 var classNames = isFn(className) ? className({
820 rtl: rtl,
821 type: type,
822 defaultClassName: defaultClassName
823 }) : cx(defaultClassName, className); // 🧐 controlledProgress is derived from progress
824 // so if controlledProgress is set
825 // it means that this is also the case for progress
826
827 var animationEvent = (_animationEvent = {}, _animationEvent[controlledProgress && progress >= 1 ? 'onTransitionEnd' : 'onAnimationEnd'] = controlledProgress && progress < 1 ? null : function () {
828 isIn && closeToast();
829 }, _animationEvent); // TODO: add aria-valuenow, aria-valuemax, aria-valuemin
830
831 return React.createElement("div", Object.assign({
832 role: "progressbar",
833 "aria-hidden": hide ? 'true' : 'false',
834 "aria-label": "notification timer",
835 className: classNames,
836 style: style
837 }, animationEvent));
838}
839ProgressBar.defaultProps = {
840 type: TYPE.DEFAULT,
841 hide: false
842};
843
844var _excluded$1 = ["theme", "type"];
845
846var Svg = function Svg(_ref) {
847 var theme = _ref.theme,
848 type = _ref.type,
849 rest = _objectWithoutPropertiesLoose(_ref, _excluded$1);
850
851 return React__default.createElement("svg", Object.assign({
852 viewBox: "0 0 24 24",
853 width: "100%",
854 height: "100%",
855 fill: theme === 'colored' ? 'currentColor' : "var(--toastify-icon-color-" + type + ")"
856 }, rest));
857};
858
859function Warning(props) {
860 return React__default.createElement(Svg, Object.assign({}, props), React__default.createElement("path", {
861 d: "M23.32 17.191L15.438 2.184C14.728.833 13.416 0 11.996 0c-1.42 0-2.733.833-3.443 2.184L.533 17.448a4.744 4.744 0 000 4.368C1.243 23.167 2.555 24 3.975 24h16.05C22.22 24 24 22.044 24 19.632c0-.904-.251-1.746-.68-2.44zm-9.622 1.46c0 1.033-.724 1.823-1.698 1.823s-1.698-.79-1.698-1.822v-.043c0-1.028.724-1.822 1.698-1.822s1.698.79 1.698 1.822v.043zm.039-12.285l-.84 8.06c-.057.581-.408.943-.897.943-.49 0-.84-.367-.896-.942l-.84-8.065c-.057-.624.25-1.095.779-1.095h1.91c.528.005.84.476.784 1.1z"
862 }));
863}
864
865function Info(props) {
866 return React__default.createElement(Svg, Object.assign({}, props), React__default.createElement("path", {
867 d: "M12 0a12 12 0 1012 12A12.013 12.013 0 0012 0zm.25 5a1.5 1.5 0 11-1.5 1.5 1.5 1.5 0 011.5-1.5zm2.25 13.5h-4a1 1 0 010-2h.75a.25.25 0 00.25-.25v-4.5a.25.25 0 00-.25-.25h-.75a1 1 0 010-2h1a2 2 0 012 2v4.75a.25.25 0 00.25.25h.75a1 1 0 110 2z"
868 }));
869}
870
871function Success(props) {
872 return React__default.createElement(Svg, Object.assign({}, props), React__default.createElement("path", {
873 d: "M12 0a12 12 0 1012 12A12.014 12.014 0 0012 0zm6.927 8.2l-6.845 9.289a1.011 1.011 0 01-1.43.188l-4.888-3.908a1 1 0 111.25-1.562l4.076 3.261 6.227-8.451a1 1 0 111.61 1.183z"
874 }));
875}
876
877function Error(props) {
878 return React__default.createElement(Svg, Object.assign({}, props), React__default.createElement("path", {
879 d: "M11.983 0a12.206 12.206 0 00-8.51 3.653A11.8 11.8 0 000 12.207 11.779 11.779 0 0011.8 24h.214A12.111 12.111 0 0024 11.791 11.766 11.766 0 0011.983 0zM10.5 16.542a1.476 1.476 0 011.449-1.53h.027a1.527 1.527 0 011.523 1.47 1.475 1.475 0 01-1.449 1.53h-.027a1.529 1.529 0 01-1.523-1.47zM11 12.5v-6a1 1 0 012 0v6a1 1 0 11-2 0z"
880 }));
881}
882
883function Spinner() {
884 return React__default.createElement("div", {
885 className: "Toastify"
886 /* CSS_NAMESPACE */
887 + "__spinner"
888 });
889}
890
891var Icons = {
892 info: Info,
893 warning: Warning,
894 success: Success,
895 error: Error,
896 spinner: Spinner
897};
898
899var Toast = function Toast(props) {
900 var _cx, _cx2;
901
902 var _useToast = useToast(props),
903 isRunning = _useToast.isRunning,
904 preventExitTransition = _useToast.preventExitTransition,
905 toastRef = _useToast.toastRef,
906 eventHandlers = _useToast.eventHandlers;
907
908 var closeButton = props.closeButton,
909 children = props.children,
910 autoClose = props.autoClose,
911 onClick = props.onClick,
912 type = props.type,
913 hideProgressBar = props.hideProgressBar,
914 closeToast = props.closeToast,
915 Transition = props.transition,
916 position = props.position,
917 className = props.className,
918 style = props.style,
919 bodyClassName = props.bodyClassName,
920 bodyStyle = props.bodyStyle,
921 progressClassName = props.progressClassName,
922 progressStyle = props.progressStyle,
923 updateId = props.updateId,
924 role = props.role,
925 progress = props.progress,
926 rtl = props.rtl,
927 toastId = props.toastId,
928 deleteToast = props.deleteToast,
929 isIn = props.isIn,
930 isLoading = props.isLoading,
931 icon = props.icon,
932 theme = props.theme;
933 var defaultClassName = cx("Toastify"
934 /* CSS_NAMESPACE */
935 + "__toast", "Toastify"
936 /* CSS_NAMESPACE */
937 + "__toast-theme--" + theme, "Toastify"
938 /* CSS_NAMESPACE */
939 + "__toast--" + type, (_cx = {}, _cx["Toastify"
940 /* CSS_NAMESPACE */
941 + "__toast--rtl"] = rtl, _cx));
942 var cssClasses = isFn(className) ? className({
943 rtl: rtl,
944 position: position,
945 type: type,
946 defaultClassName: defaultClassName
947 }) : cx(defaultClassName, className);
948 var isProgressControlled = !!progress;
949 var maybeIcon = Icons[type];
950 var iconProps = {
951 theme: theme,
952 type: type
953 };
954 var Icon = maybeIcon && maybeIcon(iconProps);
955
956 if (icon === false) {
957 Icon = void 0;
958 } else if (isFn(icon)) {
959 Icon = icon(iconProps);
960 } else if (React.isValidElement(icon)) {
961 Icon = React.cloneElement(icon, iconProps);
962 } else if (isStr(icon)) {
963 Icon = icon;
964 } else if (isLoading) {
965 Icon = Icons.spinner();
966 }
967
968 function renderCloseButton(closeButton) {
969 if (!closeButton) return;
970 var props = {
971 closeToast: closeToast,
972 type: type,
973 theme: theme
974 };
975 if (isFn(closeButton)) return closeButton(props);
976 if (React.isValidElement(closeButton)) return React.cloneElement(closeButton, props);
977 }
978
979 return React.createElement(Transition, {
980 isIn: isIn,
981 done: deleteToast,
982 position: position,
983 preventExitTransition: preventExitTransition,
984 nodeRef: toastRef
985 }, React.createElement("div", Object.assign({
986 id: toastId,
987 onClick: onClick,
988 className: cssClasses
989 }, eventHandlers, {
990 style: style,
991 ref: toastRef
992 }), React.createElement("div", Object.assign({}, isIn && {
993 role: role
994 }, {
995 className: isFn(bodyClassName) ? bodyClassName({
996 type: type
997 }) : cx("Toastify"
998 /* CSS_NAMESPACE */
999 + "__toast-body", bodyClassName),
1000 style: bodyStyle
1001 }), Icon && React.createElement("div", {
1002 className: cx("Toastify"
1003 /* CSS_NAMESPACE */
1004 + "__toast-icon", (_cx2 = {}, _cx2["Toastify"
1005 /* CSS_NAMESPACE */
1006 + "--animate-icon " + "Toastify"
1007 /* CSS_NAMESPACE */
1008 + "__zoom-enter"] = !isLoading, _cx2))
1009 }, Icon), React.createElement("div", null, children)), renderCloseButton(closeButton), (autoClose || isProgressControlled) && React.createElement(ProgressBar, Object.assign({}, updateId && !isProgressControlled ? {
1010 key: "pb-" + updateId
1011 } : {}, {
1012 rtl: rtl,
1013 theme: theme,
1014 delay: autoClose,
1015 isRunning: isRunning,
1016 isIn: isIn,
1017 closeToast: closeToast,
1018 hide: hideProgressBar,
1019 type: type,
1020 style: progressStyle,
1021 className: progressClassName,
1022 controlledProgress: isProgressControlled,
1023 progress: progress
1024 }))));
1025};
1026
1027var Bounce = /*#__PURE__*/cssTransition({
1028 enter: "Toastify"
1029 /* CSS_NAMESPACE */
1030 + "--animate " + "Toastify"
1031 /* CSS_NAMESPACE */
1032 + "__bounce-enter",
1033 exit: "Toastify"
1034 /* CSS_NAMESPACE */
1035 + "--animate " + "Toastify"
1036 /* CSS_NAMESPACE */
1037 + "__bounce-exit",
1038 appendPosition: true
1039});
1040var Slide = /*#__PURE__*/cssTransition({
1041 enter: "Toastify"
1042 /* CSS_NAMESPACE */
1043 + "--animate " + "Toastify"
1044 /* CSS_NAMESPACE */
1045 + "__slide-enter",
1046 exit: "Toastify"
1047 /* CSS_NAMESPACE */
1048 + "--animate " + "Toastify"
1049 /* CSS_NAMESPACE */
1050 + "__slide-exit",
1051 appendPosition: true
1052});
1053var Zoom = /*#__PURE__*/cssTransition({
1054 enter: "Toastify"
1055 /* CSS_NAMESPACE */
1056 + "--animate " + "Toastify"
1057 /* CSS_NAMESPACE */
1058 + "__zoom-enter",
1059 exit: "Toastify"
1060 /* CSS_NAMESPACE */
1061 + "--animate " + "Toastify"
1062 /* CSS_NAMESPACE */
1063 + "__zoom-exit"
1064});
1065var Flip = /*#__PURE__*/cssTransition({
1066 enter: "Toastify"
1067 /* CSS_NAMESPACE */
1068 + "--animate " + "Toastify"
1069 /* CSS_NAMESPACE */
1070 + "__flip-enter",
1071 exit: "Toastify"
1072 /* CSS_NAMESPACE */
1073 + "--animate " + "Toastify"
1074 /* CSS_NAMESPACE */
1075 + "__flip-exit"
1076});
1077
1078var ToastContainer = function ToastContainer(props) {
1079 var _useToastContainer = useToastContainer(props),
1080 getToastToRender = _useToastContainer.getToastToRender,
1081 containerRef = _useToastContainer.containerRef,
1082 isToastActive = _useToastContainer.isToastActive;
1083
1084 var className = props.className,
1085 style = props.style,
1086 rtl = props.rtl,
1087 containerId = props.containerId;
1088
1089 function getClassName(position) {
1090 var _cx;
1091
1092 var defaultClassName = cx("Toastify"
1093 /* CSS_NAMESPACE */
1094 + "__toast-container", "Toastify"
1095 /* CSS_NAMESPACE */
1096 + "__toast-container--" + position, (_cx = {}, _cx["Toastify"
1097 /* CSS_NAMESPACE */
1098 + "__toast-container--rtl"] = rtl, _cx));
1099 return isFn(className) ? className({
1100 position: position,
1101 rtl: rtl,
1102 defaultClassName: defaultClassName
1103 }) : cx(defaultClassName, parseClassName(className));
1104 }
1105
1106 return React.createElement("div", {
1107 ref: containerRef,
1108 className: "Toastify"
1109 /* CSS_NAMESPACE */
1110 ,
1111 id: containerId
1112 }, getToastToRender(function (position, toastList) {
1113 var containerStyle = toastList.length === 0 ? _extends({}, style, {
1114 pointerEvents: 'none'
1115 }) : _extends({}, style);
1116 return React.createElement("div", {
1117 className: getClassName(position),
1118 style: containerStyle,
1119 key: "container-" + position
1120 }, toastList.map(function (_ref) {
1121 var content = _ref.content,
1122 toastProps = _ref.props;
1123 return React.createElement(Toast, Object.assign({}, toastProps, {
1124 isIn: isToastActive(toastProps.toastId),
1125 key: "toast-" + toastProps.key,
1126 closeButton: toastProps.closeButton === true ? CloseButton : toastProps.closeButton
1127 }), content);
1128 }));
1129 }));
1130};
1131ToastContainer.defaultProps = {
1132 position: POSITION.TOP_RIGHT,
1133 transition: Bounce,
1134 rtl: false,
1135 autoClose: 5000,
1136 hideProgressBar: false,
1137 closeButton: CloseButton,
1138 pauseOnHover: true,
1139 pauseOnFocusLoss: true,
1140 closeOnClick: true,
1141 newestOnTop: false,
1142 draggable: true,
1143 draggablePercent: 80
1144 /* DRAGGABLE_PERCENT */
1145 ,
1146 draggableDirection: "x"
1147 /* X */
1148 ,
1149 role: 'alert',
1150 theme: 'light'
1151};
1152
1153var containers = /*#__PURE__*/new Map();
1154var latestInstance;
1155var containerDomNode;
1156var containerConfig;
1157var queue = [];
1158var lazy = false;
1159/**
1160 * Check whether any container is currently mounted in the DOM
1161 */
1162
1163function isAnyContainerMounted() {
1164 return containers.size > 0;
1165}
1166/**
1167 * Get the toast by id, given it's in the DOM, otherwise returns null
1168 */
1169
1170
1171function getToast(toastId, _ref) {
1172 var containerId = _ref.containerId;
1173 var container = containers.get(containerId || latestInstance);
1174 if (!container) return null;
1175 return container.getToast(toastId);
1176}
1177/**
1178 * Generate a random toastId
1179 */
1180
1181
1182function generateToastId() {
1183 return Math.random().toString(36).substr(2, 9);
1184}
1185/**
1186 * Generate a toastId or use the one provided
1187 */
1188
1189
1190function getToastId(options) {
1191 if (options && (isStr(options.toastId) || isNum(options.toastId))) {
1192 return options.toastId;
1193 }
1194
1195 return generateToastId();
1196}
1197/**
1198 * If the container is not mounted, the toast is enqueued and
1199 * the container lazy mounted
1200 */
1201
1202
1203function dispatchToast(content, options) {
1204 if (isAnyContainerMounted()) {
1205 eventManager.emit(0
1206 /* Show */
1207 , content, options);
1208 } else {
1209 queue.push({
1210 content: content,
1211 options: options
1212 });
1213
1214 if (lazy && canUseDom) {
1215 lazy = false;
1216 containerDomNode = document.createElement('div');
1217 document.body.appendChild(containerDomNode);
1218 reactDom.render(React.createElement(ToastContainer, Object.assign({}, containerConfig)), containerDomNode);
1219 }
1220 }
1221
1222 return options.toastId;
1223}
1224/**
1225 * Merge provided options with the defaults settings and generate the toastId
1226 */
1227
1228
1229function mergeOptions(type, options) {
1230 return _extends({}, options, {
1231 type: options && options.type || type,
1232 toastId: getToastId(options)
1233 });
1234}
1235
1236var createToastByType = function createToastByType(type) {
1237 return function (content, options) {
1238 return dispatchToast(content, mergeOptions(type, options));
1239 };
1240};
1241
1242var toast = function toast(content, options) {
1243 return dispatchToast(content, mergeOptions(TYPE.DEFAULT, options));
1244};
1245
1246toast.loading = function (content, options) {
1247 return dispatchToast(content, mergeOptions(TYPE.DEFAULT, _extends({
1248 isLoading: true,
1249 autoClose: false,
1250 closeOnClick: false,
1251 closeButton: false,
1252 draggable: false
1253 }, options)));
1254};
1255
1256function handlePromise(promise, _ref2, options) {
1257 var pending = _ref2.pending,
1258 error = _ref2.error,
1259 success = _ref2.success;
1260 var id = isStr(pending) ? toast.loading(pending, options) : toast.loading(pending.render, _extends({}, options, pending));
1261 var resetParams = {
1262 isLoading: null,
1263 autoClose: null,
1264 closeOnClick: null,
1265 closeButton: null,
1266 draggable: null
1267 };
1268
1269 var resolver = function resolver(type, input, result) {
1270 var params = isStr(input) ? {
1271 render: input
1272 } : input;
1273 toast.update(id, _extends({
1274 type: type
1275 }, resetParams, options, params, {
1276 data: result
1277 }));
1278 return result;
1279 };
1280
1281 var p = isFn(promise) ? promise() : promise;
1282 p.then(function (result) {
1283 return resolver('success', success, result);
1284 })["catch"](function (err) {
1285 return resolver('error', error, err);
1286 });
1287 return p;
1288}
1289
1290toast.promise = handlePromise;
1291toast.success = /*#__PURE__*/createToastByType(TYPE.SUCCESS);
1292toast.info = /*#__PURE__*/createToastByType(TYPE.INFO);
1293toast.error = /*#__PURE__*/createToastByType(TYPE.ERROR);
1294toast.warning = /*#__PURE__*/createToastByType(TYPE.WARNING);
1295toast.warn = toast.warning;
1296
1297toast.dark = function (content, options) {
1298 return dispatchToast(content, mergeOptions(TYPE.DEFAULT, _extends({
1299 theme: 'dark'
1300 }, options)));
1301};
1302/**
1303 * Remove toast programmaticaly
1304 */
1305
1306
1307toast.dismiss = function (id) {
1308 return eventManager.emit(1
1309 /* Clear */
1310 , id);
1311};
1312/**
1313 * Clear waiting queue when limit is used
1314 */
1315
1316
1317toast.clearWaitingQueue = function (params) {
1318 if (params === void 0) {
1319 params = {};
1320 }
1321
1322 return eventManager.emit(5
1323 /* ClearWaitingQueue */
1324 , params);
1325};
1326/**
1327 * return true if one container is displaying the toast
1328 */
1329
1330
1331toast.isActive = function (id) {
1332 var isToastActive = false;
1333 containers.forEach(function (container) {
1334 if (container.isToastActive && container.isToastActive(id)) {
1335 isToastActive = true;
1336 }
1337 });
1338 return isToastActive;
1339};
1340
1341toast.update = function (toastId, options) {
1342 if (options === void 0) {
1343 options = {};
1344 }
1345
1346 // if you call toast and toast.update directly nothing will be displayed
1347 // this is why I defered the update
1348 setTimeout(function () {
1349 var toast = getToast(toastId, options);
1350
1351 if (toast) {
1352 var oldOptions = toast.props,
1353 oldContent = toast.content;
1354
1355 var nextOptions = _extends({}, oldOptions, options, {
1356 toastId: options.toastId || toastId,
1357 updateId: generateToastId()
1358 });
1359
1360 if (nextOptions.toastId !== toastId) nextOptions.staleId = toastId;
1361 var content = nextOptions.render || oldContent;
1362 delete nextOptions.render;
1363 dispatchToast(content, nextOptions);
1364 }
1365 }, 0);
1366};
1367/**
1368 * Used for controlled progress bar.
1369 */
1370
1371
1372toast.done = function (id) {
1373 toast.update(id, {
1374 progress: 1
1375 });
1376};
1377/**
1378 * Track changes. The callback get the number of toast displayed
1379 *
1380 */
1381
1382
1383toast.onChange = function (callback) {
1384 if (isFn(callback)) {
1385 eventManager.on(4
1386 /* Change */
1387 , callback);
1388 }
1389
1390 return function () {
1391 isFn(callback) && eventManager.off(4
1392 /* Change */
1393 , callback);
1394 };
1395};
1396/**
1397 * Configure the ToastContainer when lazy mounted
1398 */
1399
1400
1401toast.configure = function (config) {
1402 if (config === void 0) {
1403 config = {};
1404 }
1405
1406 lazy = true;
1407 containerConfig = config;
1408};
1409
1410toast.POSITION = POSITION;
1411toast.TYPE = TYPE;
1412/**
1413 * Wait until the ToastContainer is mounted to dispatch the toast
1414 * and attach isActive method
1415 */
1416
1417eventManager.on(2
1418/* DidMount */
1419, function (containerInstance) {
1420 latestInstance = containerInstance.containerId || containerInstance;
1421 containers.set(latestInstance, containerInstance);
1422 queue.forEach(function (item) {
1423 eventManager.emit(0
1424 /* Show */
1425 , item.content, item.options);
1426 });
1427 queue = [];
1428}).on(3
1429/* WillUnmount */
1430, function (containerInstance) {
1431 containers["delete"](containerInstance.containerId || containerInstance);
1432
1433 if (containers.size === 0) {
1434 eventManager.off(0
1435 /* Show */
1436 ).off(1
1437 /* Clear */
1438 ).off(5
1439 /* ClearWaitingQueue */
1440 );
1441 }
1442
1443 if (canUseDom && containerDomNode) {
1444 document.body.removeChild(containerDomNode);
1445 }
1446});
1447
1448exports.Bounce = Bounce;
1449exports.Flip = Flip;
1450exports.Icons = Icons;
1451exports.Slide = Slide;
1452exports.ToastContainer = ToastContainer;
1453exports.Zoom = Zoom;
1454exports.collapseToast = collapseToast;
1455exports.cssTransition = cssTransition;
1456exports.toast = toast;
1457exports.useToast = useToast;
1458exports.useToastContainer = useToastContainer;
1459//# sourceMappingURL=react-toastify.cjs.development.js.map