UNPKG

react-toastify

Version:
1,319 lines (1,154 loc) 37.2 kB
import { isValidElement, createElement, useRef, useEffect, useReducer, cloneElement, useState, Children } from 'react'; import { Transition } from 'react-transition-group'; import cx from 'clsx'; import PropTypes from 'prop-types'; import { render } from 'react-dom'; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function isNum(v) { return typeof v === 'number' && !isNaN(v); } function isBool(v) { return typeof v === 'boolean'; } function isStr(v) { return typeof v === 'string'; } function isFn(v) { return typeof v === 'function'; } function parseClassName(v) { return isStr(v) || isFn(v) ? v : null; } function objectValues(obj) { return Object.keys(obj).map(function (key) { return obj[key]; }); } function hasToastId(toastId) { return toastId === 0 || toastId; } function getAutoCloseDelay(toastAutoClose, containerAutoClose) { return toastAutoClose === false || isNum(toastAutoClose) && toastAutoClose > 0 ? toastAutoClose : containerAutoClose; } var canUseDom = !!(typeof window !== 'undefined' && window.document && window.document.createElement); function canBeRendered(content) { return isValidElement(content) || isStr(content) || isFn(content) || isNum(content); } var POSITION = { TOP_LEFT: 'top-left', TOP_RIGHT: 'top-right', TOP_CENTER: 'top-center', BOTTOM_LEFT: 'bottom-left', BOTTOM_RIGHT: 'bottom-right', BOTTOM_CENTER: 'bottom-center' }; var TYPE = { INFO: 'info', SUCCESS: 'success', WARNING: 'warning', ERROR: 'error', DEFAULT: 'default', DARK: 'dark' }; /** * Used to collapse toast after exit animation */ function collapseToast(node, done, duration /* COLLAPSE_DURATION */ ) { if (duration === void 0) { duration = 300; } var height = node.scrollHeight; var style = node.style; requestAnimationFrame(function () { style.minHeight = 'initial'; style.height = height + 'px'; style.transition = "all " + duration + "ms"; requestAnimationFrame(function () { style.height = '0'; style.padding = '0'; style.margin = '0'; setTimeout(function () { return done(); }, duration); }); }); } function cssTransition(_ref) { var enter = _ref.enter, exit = _ref.exit, _ref$duration = _ref.duration, duration = _ref$duration === void 0 ? 750 : _ref$duration, _ref$appendPosition = _ref.appendPosition, appendPosition = _ref$appendPosition === void 0 ? false : _ref$appendPosition, _ref$collapse = _ref.collapse, collapse = _ref$collapse === void 0 ? true : _ref$collapse, _ref$collapseDuration = _ref.collapseDuration, collapseDuration = _ref$collapseDuration === void 0 ? 300 : _ref$collapseDuration; var enterDuration, exitDuration; if (Array.isArray(duration) && duration.length === 2) { enterDuration = duration[0]; exitDuration = duration[1]; } else { enterDuration = exitDuration = duration; } return function ToastTransition(_ref2) { var children = _ref2.children, position = _ref2.position, preventExitTransition = _ref2.preventExitTransition, done = _ref2.done, props = _objectWithoutPropertiesLoose(_ref2, ["children", "position", "preventExitTransition", "done"]); var enterClassName = appendPosition ? enter + "--" + position : enter; var exitClassName = appendPosition ? exit + "--" + position : exit; var onEnter = function onEnter() { var node = props.nodeRef.current; if (node) { node.classList.add(enterClassName); node.style.animationFillMode = 'forwards'; node.style.animationDuration = enterDuration + "ms"; } }; var onEntered = function onEntered() { var node = props.nodeRef.current; if (node) { node.classList.remove(enterClassName); node.style.cssText = ''; } }; var onExited = function onExited() { var node = props.nodeRef.current; if (node) { node.removeEventListener('animationend', onExited); collapse ? collapseToast(node, done, collapseDuration) : done(); } }; var onExit = function onExit() { var node = props.nodeRef.current; if (node) { node.classList.add(exitClassName); node.style.animationFillMode = 'forwards'; node.style.animationDuration = exitDuration + "ms"; node.addEventListener('animationend', onExited); } }; return createElement(Transition, Object.assign({}, props, { timeout: preventExitTransition ? collapse ? collapseDuration : 50 /* DEBOUNCE_DURATION */ : { enter: enterDuration, exit: collapse ? exitDuration + collapseDuration : exitDuration + 50 /* DEBOUNCE_DURATION */ }, onEnter: onEnter, onEntered: onEntered, onExit: preventExitTransition ? onExited : onExit, unmountOnExit: true }), children); }; } var eventManager = { list: /*#__PURE__*/new Map(), emitQueue: /*#__PURE__*/new Map(), on: function on(event, callback) { this.list.has(event) || this.list.set(event, []); this.list.get(event).push(callback); return this; }, off: function off(event, callback) { if (callback) { var cb = this.list.get(event).filter(function (cb) { return cb !== callback; }); this.list.set(event, cb); return this; } this.list["delete"](event); return this; }, cancelEmit: function cancelEmit(event) { var timers = this.emitQueue.get(event); if (timers) { timers.forEach(function (timer) { return clearTimeout(timer); }); this.emitQueue["delete"](event); } return this; }, /** * Enqueue the event at the end of the call stack * Doing so let the user call toast as follow: * toast('1') * toast('2') * toast('3') * Without setTimemout the code above will not work */ emit: function emit(event) { var _this = this; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } this.list.has(event) && this.list.get(event).forEach(function (callback) { var timer = setTimeout(function () { // @ts-ignore callback.apply(void 0, args); }, 0); _this.emitQueue.has(event) || _this.emitQueue.set(event, []); _this.emitQueue.get(event).push(timer); }); } }; /** * `useKeeper` is a helper around `useRef`. * * You don't need to access the `.current`property to get the value * If refresh is set to true. The ref will be updated every render */ function useKeeper(arg, refresh) { if (refresh === void 0) { refresh = false; } var ref = useRef(arg); useEffect(function () { if (refresh) ref.current = arg; }); return ref.current; } function reducer(state, action) { switch (action.type) { case 'ADD': return [].concat(state, [action.toastId]).filter(function (id) { return id !== action.staleId; }); case 'REMOVE': return hasToastId(action.toastId) ? state.filter(function (id) { return id !== action.toastId; }) : []; } } function useToastContainer(props) { var _useReducer = useReducer(function (x) { return x + 1; }, 0), forceUpdate = _useReducer[1]; var _useReducer2 = useReducer(reducer, []), toast = _useReducer2[0], dispatch = _useReducer2[1]; var containerRef = useRef(null); var toastCount = useKeeper(0); var queue = useKeeper([]); var collection = useKeeper({}); var instance = useKeeper({ toastKey: 1, displayedToast: 0, props: props, containerId: null, isToastActive: isToastActive, getToast: function getToast(id) { return collection[id] || null; } }); useEffect(function () { instance.containerId = props.containerId; eventManager.cancelEmit(3 /* WillUnmount */ ).on(0 /* Show */ , buildToast).on(1 /* Clear */ , function (toastId) { return containerRef.current && removeToast(toastId); }).on(5 /* ClearWaitingQueue */ , clearWaitingQueue).emit(2 /* DidMount */ , instance); return function () { return eventManager.emit(3 /* WillUnmount */ , instance); }; }, []); useEffect(function () { instance.isToastActive = isToastActive; instance.displayedToast = toast.length; eventManager.emit(4 /* Change */ , toast.length, props.containerId); }, [toast]); useEffect(function () { instance.props = props; }); function isToastActive(id) { return toast.indexOf(id) !== -1; } function clearWaitingQueue(_ref) { var containerId = _ref.containerId; var _instance$props = instance.props, limit = _instance$props.limit, enableMultiContainer = _instance$props.enableMultiContainer; if (limit && (!containerId || instance.containerId === containerId && enableMultiContainer)) { toastCount -= queue.length; queue = []; } } function removeToast(toastId) { var queueLen = queue.length; toastCount = hasToastId(toastId) ? toastCount - 1 : toastCount - instance.displayedToast; if (toastCount < 0) toastCount = 0; if (queueLen > 0) { var freeSlot = hasToastId(toastId) ? 1 : instance.props.limit; if (queueLen === 1 || freeSlot === 1) { instance.displayedToast++; dequeueToast(); } else { var toDequeue = freeSlot > queueLen ? queueLen : freeSlot; instance.displayedToast = toDequeue; for (var i = 0; i < toDequeue; i++) { dequeueToast(); } } } dispatch({ type: 'REMOVE', toastId: toastId }); } function dequeueToast() { var _queue$shift = queue.shift(), toastContent = _queue$shift.toastContent, toastProps = _queue$shift.toastProps, staleId = _queue$shift.staleId; // ensure that exit transition has been completed, hence the timeout setTimeout(function () { appendToast(toastContent, toastProps, staleId); }, 500); } /** * check if a container is attached to the dom * check for multi-container, build only if associated * check for duplicate toastId if no update */ function isNotValid(_ref2) { var containerId = _ref2.containerId, toastId = _ref2.toastId, updateId = _ref2.updateId; return !containerRef.current || instance.props.enableMultiContainer && containerId !== instance.props.containerId || instance.isToastActive(toastId) && updateId == null ? true : false; } // this function and all the function called inside needs to rely on ref(`useKeeper`) function buildToast(content, _ref3) { var delay = _ref3.delay, staleId = _ref3.staleId, options = _objectWithoutPropertiesLoose(_ref3, ["delay", "staleId"]); if (!canBeRendered(content) || isNotValid(options)) return; var toastId = options.toastId, updateId = options.updateId; var props = instance.props, isToastActive = instance.isToastActive; var closeToast = function closeToast() { return removeToast(toastId); }; var isNotAnUpdate = !isToastActive(toastId); if (isNotAnUpdate) toastCount++; var toastProps = { toastId: toastId, updateId: updateId, key: options.key || instance.toastKey++, type: options.type, closeToast: closeToast, closeButton: options.closeButton, rtl: props.rtl, position: options.position || props.position, transition: options.transition || props.transition, className: parseClassName(options.className || props.toastClassName), bodyClassName: parseClassName(options.bodyClassName || props.bodyClassName), style: options.style || props.toastStyle, bodyStyle: options.bodyStyle || props.bodyStyle, onClick: options.onClick || props.onClick, pauseOnHover: isBool(options.pauseOnHover) ? options.pauseOnHover : props.pauseOnHover, pauseOnFocusLoss: isBool(options.pauseOnFocusLoss) ? options.pauseOnFocusLoss : props.pauseOnFocusLoss, draggable: isBool(options.draggable) ? options.draggable : props.draggable, draggablePercent: isNum(options.draggablePercent) ? options.draggablePercent : props.draggablePercent, closeOnClick: isBool(options.closeOnClick) ? options.closeOnClick : props.closeOnClick, progressClassName: parseClassName(options.progressClassName || props.progressClassName), progressStyle: options.progressStyle || props.progressStyle, autoClose: getAutoCloseDelay(options.autoClose, props.autoClose), hideProgressBar: isBool(options.hideProgressBar) ? options.hideProgressBar : props.hideProgressBar, progress: options.progress, role: isStr(options.role) ? options.role : props.role, deleteToast: function deleteToast() { removeFromCollection(toastId); } }; if (isFn(options.onOpen)) toastProps.onOpen = options.onOpen; if (isFn(options.onClose)) toastProps.onClose = options.onClose; var closeButton = props.closeButton; if (options.closeButton === false || canBeRendered(options.closeButton)) { closeButton = options.closeButton; } else if (options.closeButton === true) { closeButton = canBeRendered(props.closeButton) ? props.closeButton : true; } toastProps.closeButton = closeButton; var toastContent = content; if (isValidElement(content) && !isStr(content.type)) { toastContent = cloneElement(content, { closeToast: closeToast }); } else if (isFn(content)) { toastContent = content({ closeToast: closeToast }); } // not handling limit + delay by design. Waiting for user feedback first if (props.limit && props.limit > 0 && toastCount > props.limit && isNotAnUpdate) { queue.push({ toastContent: toastContent, toastProps: toastProps, staleId: staleId }); } else if (isNum(delay) && delay > 0) { setTimeout(function () { appendToast(toastContent, toastProps, staleId); }, delay); } else { appendToast(toastContent, toastProps, staleId); } } function appendToast(content, toastProps, staleId) { var toastId = toastProps.toastId; collection[toastId] = { content: content, props: toastProps }; dispatch({ type: 'ADD', toastId: toastId, staleId: staleId }); } function removeFromCollection(toastId) { delete collection[toastId]; forceUpdate(); } function getToastToRender(cb) { var toastToRender = {}; var toastList = props.newestOnTop ? Object.keys(collection).reverse() : Object.keys(collection); for (var i = 0; i < toastList.length; i++) { var _toast = collection[toastList[i]]; var position = _toast.props.position; toastToRender[position] || (toastToRender[position] = []); toastToRender[position].push(_toast); } return Object.keys(toastToRender).map(function (p) { return cb(p, toastToRender[p]); }); } return { getToastToRender: getToastToRender, collection: collection, containerRef: containerRef, isToastActive: isToastActive }; } function getX(e) { return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientX : e.clientX; } function getY(e) { return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientY : e.clientY; } function useToast(props) { var _useState = useState(true), isRunning = _useState[0], setIsRunning = _useState[1]; var _useState2 = useState(false), preventExitTransition = _useState2[0], setPreventExitTransition = _useState2[1]; var toastRef = useRef(null); var drag = useKeeper({ start: 0, x: 0, y: 0, deltaX: 0, removalDistance: 0, canCloseOnClick: true, canDrag: false, boundingRect: null }); var syncProps = useKeeper(props, true); var autoClose = props.autoClose, pauseOnHover = props.pauseOnHover, closeToast = props.closeToast, onClick = props.onClick, closeOnClick = props.closeOnClick; useEffect(function () { if (isFn(props.onOpen)) props.onOpen(isValidElement(props.children) && props.children.props); return function () { if (isFn(syncProps.onClose)) syncProps.onClose(isValidElement(syncProps.children) && syncProps.children.props); }; }, []); useEffect(function () { props.draggable && bindDragEvents(); return function () { props.draggable && unbindDragEvents(); }; }, [props.draggable]); useEffect(function () { props.pauseOnFocusLoss && bindFocusEvents(); return function () { props.pauseOnFocusLoss && unbindFocusEvents(); }; }, [props.pauseOnFocusLoss]); function onDragStart(e) { var toast = toastRef.current; drag.canCloseOnClick = true; drag.canDrag = true; drag.boundingRect = toast.getBoundingClientRect(); toast.style.transition = ''; drag.start = drag.x = getX(e.nativeEvent); drag.removalDistance = toast.offsetWidth * (props.draggablePercent / 100); } function onDragTransitionEnd() { if (drag.boundingRect) { var _drag$boundingRect = drag.boundingRect, top = _drag$boundingRect.top, bottom = _drag$boundingRect.bottom, left = _drag$boundingRect.left, right = _drag$boundingRect.right; if (props.pauseOnHover && drag.x >= left && drag.x <= right && drag.y >= top && drag.y <= bottom) { pauseToast(); } else { playToast(); } } } function playToast() { setIsRunning(true); } function pauseToast() { setIsRunning(false); } function bindFocusEvents() { window.addEventListener('focus', playToast); window.addEventListener('blur', pauseToast); } function unbindFocusEvents() { window.removeEventListener('focus', playToast); window.removeEventListener('blur', pauseToast); } function bindDragEvents() { document.addEventListener('mousemove', onDragMove); document.addEventListener('mouseup', onDragEnd); document.addEventListener('touchmove', onDragMove); document.addEventListener('touchend', onDragEnd); } function unbindDragEvents() { document.removeEventListener('mousemove', onDragMove); document.removeEventListener('mouseup', onDragEnd); document.removeEventListener('touchmove', onDragMove); document.removeEventListener('touchend', onDragEnd); } function onDragMove(e) { var toast = toastRef.current; if (drag.canDrag) { if (isRunning) pauseToast(); drag.x = getX(e); drag.deltaX = drag.x - drag.start; drag.y = getY(e); // prevent false positif during a toast click if (drag.start !== drag.x) drag.canCloseOnClick = false; toast.style.transform = "translateX(" + drag.deltaX + "px)"; toast.style.opacity = "" + (1 - Math.abs(drag.deltaX / drag.removalDistance)); } } function onDragEnd() { var toast = toastRef.current; if (drag.canDrag) { drag.canDrag = false; if (Math.abs(drag.deltaX) > drag.removalDistance) { setPreventExitTransition(true); props.closeToast(); return; } toast.style.transition = 'transform 0.2s, opacity 0.2s'; toast.style.transform = 'translateX(0)'; toast.style.opacity = '1'; } } var eventHandlers = { onMouseDown: onDragStart, onTouchStart: onDragStart, onMouseUp: onDragTransitionEnd, onTouchEnd: onDragTransitionEnd }; if (autoClose && pauseOnHover) { eventHandlers.onMouseEnter = pauseToast; eventHandlers.onMouseLeave = playToast; } // prevent toast from closing when user drags the toast if (closeOnClick) { eventHandlers.onClick = function (e) { onClick && onClick(e); drag.canCloseOnClick && closeToast(); }; } return { playToast: playToast, pauseToast: pauseToast, isRunning: isRunning, preventExitTransition: preventExitTransition, toastRef: toastRef, eventHandlers: eventHandlers }; } function CloseButton(_ref) { var closeToast = _ref.closeToast, type = _ref.type, _ref$ariaLabel = _ref.ariaLabel, ariaLabel = _ref$ariaLabel === void 0 ? 'close' : _ref$ariaLabel; return createElement("button", { className: "Toastify" /* CSS_NAMESPACE */ + "__close-button " + "Toastify" /* CSS_NAMESPACE */ + "__close-button--" + type, type: "button", onClick: function onClick(e) { e.stopPropagation(); closeToast(e); }, "aria-label": ariaLabel }, createElement("svg", { "aria-hidden": "true", viewBox: "0 0 14 16" }, createElement("path", { fillRule: "evenodd", 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" }))); } function ProgressBar(_ref) { var _ref2, _animationEvent; var delay = _ref.delay, isRunning = _ref.isRunning, closeToast = _ref.closeToast, type = _ref.type, hide = _ref.hide, className = _ref.className, userStyle = _ref.style, controlledProgress = _ref.controlledProgress, progress = _ref.progress, rtl = _ref.rtl, isIn = _ref.isIn; var style = _extends({}, userStyle, { animationDuration: delay + "ms", animationPlayState: isRunning ? 'running' : 'paused', opacity: hide ? 0 : 1 }); if (controlledProgress) style.transform = "scaleX(" + progress + ")"; var defaultClassArr = ["Toastify" /* CSS_NAMESPACE */ + "__progress-bar", controlledProgress ? "Toastify" /* CSS_NAMESPACE */ + "__progress-bar--controlled" : "Toastify" /* CSS_NAMESPACE */ + "__progress-bar--animated", "Toastify" /* CSS_NAMESPACE */ + "__progress-bar--" + type, (_ref2 = {}, _ref2["Toastify" /* CSS_NAMESPACE */ + "__progress-bar--rtl"] = rtl, _ref2)]; var classNames = isFn(className) ? className({ rtl: rtl, type: type, defaultClassName: cx.apply(void 0, defaultClassArr) }) : cx.apply(void 0, [].concat(defaultClassArr, [className])); // 🧐 controlledProgress is derived from progress // so if controlledProgress is set // it means that this is also the case for progress var animationEvent = (_animationEvent = {}, _animationEvent[controlledProgress && progress >= 1 ? 'onTransitionEnd' : 'onAnimationEnd'] = controlledProgress && progress < 1 ? null : function () { isIn && closeToast(); }, _animationEvent); return createElement("div", Object.assign({ className: classNames, style: style }, animationEvent)); } ProgressBar.defaultProps = { type: TYPE.DEFAULT, hide: false }; var Toast = function Toast(props) { var _ref; var _useToast = useToast(props), isRunning = _useToast.isRunning, preventExitTransition = _useToast.preventExitTransition, toastRef = _useToast.toastRef, eventHandlers = _useToast.eventHandlers; var closeButton = props.closeButton, children = props.children, autoClose = props.autoClose, onClick = props.onClick, type = props.type, hideProgressBar = props.hideProgressBar, closeToast = props.closeToast, Transition = props.transition, position = props.position, className = props.className, style = props.style, bodyClassName = props.bodyClassName, bodyStyle = props.bodyStyle, progressClassName = props.progressClassName, progressStyle = props.progressStyle, updateId = props.updateId, role = props.role, progress = props.progress, rtl = props.rtl, toastId = props.toastId, deleteToast = props.deleteToast; var defaultClassArr = ["Toastify" /* CSS_NAMESPACE */ + "__toast", "Toastify" /* CSS_NAMESPACE */ + "__toast--" + type, (_ref = {}, _ref["Toastify" /* CSS_NAMESPACE */ + "__toast--rtl"] = rtl, _ref)]; var cssClasses = isFn(className) ? className({ rtl: rtl, position: position, type: type, defaultClassName: cx.apply(void 0, defaultClassArr) }) : cx.apply(void 0, [].concat(defaultClassArr, [className])); var controlledProgress = !!progress; function renderCloseButton(closeButton) { if (!closeButton) return; var props = { closeToast: closeToast, type: type }; if (isFn(closeButton)) return closeButton(props); if (isValidElement(closeButton)) return cloneElement(closeButton, props); } return createElement(Transition, { "in": props["in"], appear: true, done: deleteToast, position: position, preventExitTransition: preventExitTransition, nodeRef: toastRef }, createElement("div", Object.assign({ id: toastId, onClick: onClick, className: cssClasses || undefined }, eventHandlers, { style: style, ref: toastRef }), createElement("div", Object.assign({}, props["in"] && { role: role }, { className: isFn(bodyClassName) ? bodyClassName({ type: type }) : cx("Toastify" /* CSS_NAMESPACE */ + "__toast-body", bodyClassName), style: bodyStyle }), children), renderCloseButton(closeButton), (autoClose || controlledProgress) && createElement(ProgressBar, Object.assign({}, updateId && !controlledProgress ? { key: "pb-" + updateId } : {}, { rtl: rtl, delay: autoClose, isRunning: isRunning, isIn: props["in"], closeToast: closeToast, hide: hideProgressBar, type: type, style: progressStyle, className: progressClassName, controlledProgress: controlledProgress, progress: progress })))); }; var Bounce = /*#__PURE__*/cssTransition({ enter: "Toastify" /* CSS_NAMESPACE */ + "__bounce-enter", exit: "Toastify" /* CSS_NAMESPACE */ + "__bounce-exit", appendPosition: true }); var Slide = /*#__PURE__*/cssTransition({ enter: "Toastify" /* CSS_NAMESPACE */ + "__slide-enter", exit: "Toastify" /* CSS_NAMESPACE */ + "__slide-exit", duration: [450, 750], appendPosition: true }); var Zoom = /*#__PURE__*/cssTransition({ enter: "Toastify" /* CSS_NAMESPACE */ + "__zoom-enter", exit: "Toastify" /* CSS_NAMESPACE */ + "__zoom-exit" }); var Flip = /*#__PURE__*/cssTransition({ enter: "Toastify" /* CSS_NAMESPACE */ + "__flip-enter", exit: "Toastify" /* CSS_NAMESPACE */ + "__flip-exit" }); var ToastPositioner = function ToastPositioner(_ref) { var children = _ref.children, className = _ref.className, style = _ref.style, rest = _objectWithoutPropertiesLoose(_ref, ["children", "className", "style"]); // Monkey patch react-transition-group // As exit transition is broken with strict mode delete rest["in"]; return createElement("div", { className: className, style: style }, Children.map(children, function (child) { return cloneElement(child, rest); })); }; var ToastContainer = function ToastContainer(props) { var _useToastContainer = useToastContainer(props), getToastToRender = _useToastContainer.getToastToRender, containerRef = _useToastContainer.containerRef, isToastActive = _useToastContainer.isToastActive; var className = props.className, style = props.style, rtl = props.rtl, containerId = props.containerId; return createElement("div", { ref: containerRef, className: "Toastify" /* CSS_NAMESPACE */ , id: containerId }, getToastToRender(function (position, toastList) { var _cx, _cx2; var swag = { className: isFn(className) ? className({ position: position, rtl: rtl, defaultClassName: cx("Toastify" /* CSS_NAMESPACE */ + "__toast-container", "Toastify" /* CSS_NAMESPACE */ + "__toast-container--" + position, (_cx = {}, _cx["Toastify" /* CSS_NAMESPACE */ + "__toast-container--rtl"] = rtl, _cx)) }) : cx("Toastify" /* CSS_NAMESPACE */ + "__toast-container", "Toastify" /* CSS_NAMESPACE */ + "__toast-container--" + position, (_cx2 = {}, _cx2["Toastify" /* CSS_NAMESPACE */ + "__toast-container--rtl"] = rtl, _cx2), parseClassName(className)), style: toastList.length === 0 ? _extends({}, style, { pointerEvents: 'none' }) : _extends({}, style) }; return createElement(ToastPositioner, Object.assign({}, swag, { key: "container-" + position }), toastList.map(function (_ref) { var content = _ref.content, toastProps = _ref.props; return createElement(Toast, Object.assign({}, toastProps, { "in": isToastActive(toastProps.toastId), key: "toast-" + toastProps.key, closeButton: toastProps.closeButton === true ? CloseButton : toastProps.closeButton }), content); })); })); }; if (process.env.NODE_ENV !== 'production') { // @ts-ignore ToastContainer.propTypes = { // @ts-ignore position: /*#__PURE__*/PropTypes.oneOf( /*#__PURE__*/objectValues(POSITION)), // @ts-ignore autoClose: /*#__PURE__*/PropTypes.oneOfType([PropTypes.bool, PropTypes.number]), // @ts-ignore closeButton: /*#__PURE__*/PropTypes.oneOfType([PropTypes.node, PropTypes.bool, PropTypes.func]), hideProgressBar: PropTypes.bool, pauseOnHover: PropTypes.bool, closeOnClick: PropTypes.bool, newestOnTop: PropTypes.bool, className: PropTypes.any, style: PropTypes.object, toastClassName: /*#__PURE__*/PropTypes.oneOfType([PropTypes.func, PropTypes.string]), bodyClassName: /*#__PURE__*/PropTypes.oneOfType([PropTypes.func, PropTypes.string]), progressClassName: /*#__PURE__*/PropTypes.oneOfType([PropTypes.func, PropTypes.string]), progressStyle: PropTypes.object, transition: PropTypes.func, rtl: PropTypes.bool, draggable: PropTypes.bool, draggablePercent: PropTypes.number, pauseOnFocusLoss: PropTypes.bool, enableMultiContainer: PropTypes.bool, containerId: /*#__PURE__*/PropTypes.oneOfType([PropTypes.string, PropTypes.number]), role: PropTypes.string, onClick: PropTypes.func }; } ToastContainer.defaultProps = { position: POSITION.TOP_RIGHT, transition: Bounce, rtl: false, autoClose: 5000, hideProgressBar: false, closeButton: CloseButton, pauseOnHover: true, pauseOnFocusLoss: true, closeOnClick: true, newestOnTop: false, draggable: true, draggablePercent: 80, role: 'alert' }; var containers = /*#__PURE__*/new Map(); var latestInstance; var containerDomNode; var containerConfig; var queue = []; var lazy = false; /** * Check whether any container is currently mounted in the DOM */ function isAnyContainerMounted() { return containers.size > 0; } /** * Get the container by id. Returns the last container declared when no id is given. */ function getContainer(containerId) { if (!isAnyContainerMounted()) return null; return containers.get(!containerId ? latestInstance : containerId); } /** * Get the toast by id, given it's in the DOM, otherwise returns null */ function getToast(toastId, _ref) { var containerId = _ref.containerId; var container = getContainer(containerId); if (!container) return null; return container.getToast(toastId); } /** * Generate a random toastId */ function generateToastId() { return (Math.random().toString(36) + Date.now().toString(36)).substr(2, 10); } /** * Generate a toastId or use the one provided */ function getToastId(options) { if (options && (isStr(options.toastId) || isNum(options.toastId))) { return options.toastId; } return generateToastId(); } /** * If the container is not mounted, the toast is enqueued and * the container lazy mounted */ function dispatchToast(content, options) { if (isAnyContainerMounted()) { eventManager.emit(0 /* Show */ , content, options); } else { queue.push({ content: content, options: options }); if (lazy && canUseDom) { lazy = false; containerDomNode = document.createElement('div'); document.body.appendChild(containerDomNode); render(createElement(ToastContainer, Object.assign({}, containerConfig)), containerDomNode); } } return options.toastId; } /** * Merge provided options with the defaults settings and generate the toastId */ function mergeOptions(type, options) { return _extends({}, options, { type: options && options.type || type, toastId: getToastId(options) }); } var toast = function toast(content, options) { return dispatchToast(content, mergeOptions(TYPE.DEFAULT, options)); }; toast.success = function (content, options) { return dispatchToast(content, mergeOptions(TYPE.SUCCESS, options)); }; toast.info = function (content, options) { return dispatchToast(content, mergeOptions(TYPE.INFO, options)); }; toast.error = function (content, options) { return dispatchToast(content, mergeOptions(TYPE.ERROR, options)); }; toast.warning = function (content, options) { return dispatchToast(content, mergeOptions(TYPE.WARNING, options)); }; toast.dark = function (content, options) { return dispatchToast(content, mergeOptions(TYPE.DARK, options)); }; /** * Maybe I should remove warning in favor of warn, I don't know */ toast.warn = toast.warning; /** * Remove toast programmaticaly */ toast.dismiss = function (id) { return isAnyContainerMounted() && eventManager.emit(1 /* Clear */ , id); }; /** * Clear waiting queue when limit is used */ toast.clearWaitingQueue = function (params) { if (params === void 0) { params = {}; } return isAnyContainerMounted() && eventManager.emit(5 /* ClearWaitingQueue */ , params); }; /** * return true if one container is displaying the toast */ toast.isActive = function (id) { var isToastActive = false; containers.forEach(function (container) { if (container.isToastActive && container.isToastActive(id)) { isToastActive = true; } }); return isToastActive; }; toast.update = function (toastId, options) { if (options === void 0) { options = {}; } // if you call toast and toast.update directly nothing will be displayed // this is why I defered the update setTimeout(function () { var toast = getToast(toastId, options); if (toast) { var oldOptions = toast.props, oldContent = toast.content; var nextOptions = _extends({}, oldOptions, options, { toastId: options.toastId || toastId, updateId: generateToastId() }); if (nextOptions.toastId !== toastId) nextOptions.staleId = toastId; var content = typeof nextOptions.render !== 'undefined' ? nextOptions.render : oldContent; delete nextOptions.render; dispatchToast(content, nextOptions); } }, 0); }; /** * Used for controlled progress bar. */ toast.done = function (id) { toast.update(id, { progress: 1 }); }; /** * Track changes. The callback get the number of toast displayed * */ toast.onChange = function (callback) { if (isFn(callback)) { eventManager.on(4 /* Change */ , callback); } return function () { isFn(callback) && eventManager.off(4 /* Change */ , callback); }; }; /** * Configure the ToastContainer when lazy mounted */ toast.configure = function (config) { if (config === void 0) { config = {}; } lazy = true; containerConfig = config; }; toast.POSITION = POSITION; toast.TYPE = TYPE; /** * Wait until the ToastContainer is mounted to dispatch the toast * and attach isActive method */ eventManager.on(2 /* DidMount */ , function (containerInstance) { latestInstance = containerInstance.containerId || containerInstance; containers.set(latestInstance, containerInstance); queue.forEach(function (item) { eventManager.emit(0 /* Show */ , item.content, item.options); }); queue = []; }).on(3 /* WillUnmount */ , function (containerInstance) { containers["delete"](containerInstance.containerId || containerInstance); if (containers.size === 0) { eventManager.off(0 /* Show */ ).off(1 /* Clear */ ).off(5 /* ClearWaitingQueue */ ); } if (canUseDom && containerDomNode) { document.body.removeChild(containerDomNode); } }); export { Bounce, Flip, Slide, ToastContainer, Zoom, collapseToast, cssTransition, toast, useToast, useToastContainer }; //# sourceMappingURL=react-toastify.esm.js.map