UNPKG

react-toast

Version:
393 lines (341 loc) 11.3 kB
import React, { useReducer, useEffect, useCallback } from 'react'; var Success = function Success() { return React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16" }, React.createElement("g", { transform: "translate(.077 .077)" }, React.createElement("g", null, React.createElement("path", { fill: "none", stroke: "#fff", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5", d: "M3.719 7.884L6.235 10.4l3.032-3.032 2.774-2.774" })))); }; var Success$1 = /*#__PURE__*/React.memo(Success); var Close = function Close() { return React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16" }, React.createElement("g", { transform: "translate(.077 .077)" }, React.createElement("g", null, React.createElement("path", { fill: "#fff", d: "M10.915 9.98l2.853-2.846a.666.666 0 00-.942-.942L9.979 9.044 7.133 6.191a.666.666 0 00-.942.942L9.044 9.98 6.19 12.826a.666.666 0 10.942.942l2.846-2.853 2.846 2.853a.666.666 0 10.942-.942z", transform: "translate(-2.017 -2.018)" })))); }; var Close$1 = /*#__PURE__*/React.memo(Close); var Info = function Info() { return React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16" }, React.createElement("g", { transform: "translate(-1533 -39)" }, React.createElement("g", { fill: "#fff", transform: "translate(-.358 -1.639)" }, React.createElement("circle", { cx: "1.134", cy: "1.134", r: "1.134", transform: "rotate(180 771.246 22.823)" }), React.createElement("path", { d: "M1 0a1 1 0 00-1 1v5a1 1 0 002 0V1a1 1 0 00-1-1z", transform: "rotate(180 771.17 26.882)" })))); }; var Info$1 = /*#__PURE__*/React.memo(Info); var Warning = function Warning() { return React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16" }, React.createElement("g", { transform: "rotate(180 774.5 27.5)" }, React.createElement("g", { fill: "#fff", transform: "translate(-.358 -1.639)" }, React.createElement("circle", { cx: "1.134", cy: "1.134", r: "1.134", transform: "rotate(180 771.246 22.823)" }), React.createElement("path", { d: "M1 0a1 1 0 00-1 1v5a1 1 0 002 0V1a1 1 0 00-1-1z", transform: "rotate(180 771.17 26.882)" })))); }; var Warning$1 = /*#__PURE__*/React.memo(Warning); var toastIcon = function toastIcon(_ref) { var type = _ref.type; switch (type) { case 'error': return React.createElement(Close$1, null); case 'info': return React.createElement(Info$1, null); case 'warning': return React.createElement(Warning$1, null); default: return React.createElement(Success$1, null); } }; function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = ":root {\n --toast-default: #8b1dd0;\n --toast-success: #27d0b2;\n --toast-error: #c52965;\n --toast-info: #004eff;\n --toast-warning: #d0761d;\n --toast-black: #221d26;\n --toast-white: #ffffff;\n}\n\n.toast {\n padding: 15px;\n min-width: 300px;\n max-width: 400px;\n color: var(--toast-white);\n display: flex;\n align-items: flex-start;\n line-height: 1.6;\n font-size: 14px;\n border-radius: 15px;\n}\n\n.toast.default {\n background-color: var(--toast-default);\n}\n\n.toast.success {\n background-color: var(--toast-success);\n}\n\n.toast.error {\n background-color: var(--toast-error);\n}\n\n.toast.info {\n background-color: var(--toast-info);\n}\n\n.toast.warning {\n background-color: var(--toast-warning);\n}\n\n.toast .content {\n flex: 1;\n}\n\n.toast .content p {\n padding: 0;\n margin: 0;\n}\n\n.toast .close {\n margin-left: 10px;\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: rgba(255, 255, 255, 0);\n transition: all 100ms ease-in-out;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.toast .close:hover {\n background-color: rgba(255, 255, 255, 0.2);\n}\n\n.toast .icon {\n margin-right: 10px;\n width: 22px;\n height: 22px;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: rgba(255, 255, 255, 0.2);\n border-radius: 8px;\n}\n"; styleInject(css_248z); var Toast = function Toast(_ref) { var id = _ref.id, content = _ref.content, type = _ref.type, _ref$config = _ref.config; _ref$config = _ref$config === void 0 ? {} : _ref$config; var backgroundColor = _ref$config.backgroundColor, color = _ref$config.color, onClose = _ref.onClose; return React.createElement("div", { className: "toast " + type, style: { backgroundColor: backgroundColor } }, React.createElement("div", { className: "icon" }, toastIcon({ type: type })), React.createElement("div", { className: "content" }, React.createElement("p", { style: { color: color } }, content)), React.createElement("div", { className: "close", onClick: function onClick() { return onClose(id); } }, React.createElement(Close$1, null))); }; 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); } var initialState = { toasts: [] }; var toastReducer = function toastReducer(state, action) { switch (action.type) { case 'ADD': return _extends({}, state, { toasts: [].concat(state.toasts, [action.toast]) }); case 'REMOVE': { return _extends({}, state, { toasts: [].concat(state.toasts.filter(function (toast) { return toast.id !== action.id; })) }); } case 'REMOVE_ALL': return _extends({}, state, { toasts: [] }); default: throw new Error(); } }; var useToast = function useToast() { var _useReducer = useReducer(toastReducer, initialState), state = _useReducer[0], dispatch = _useReducer[1]; return _extends({}, state, { dispatch: dispatch }); }; var emitter = /*#__PURE__*/function () { var events = /*#__PURE__*/new Map(); return { /** * Register an event handler for the given event name. * @param {Events} event Type of event to listen for * @param {Handler} callback Handler to call in response to given event */ on: function on(event, callback) { if (!events.has(event)) events.set(event, []); events.get(event).push(callback); }, /** * Invoke all handlers for the given event name. * @param {Events} event The event type to invoke * @param {Any} args Any value passed to each handler */ emit: function emit(event, args) { if (!events.has(event)) return; events.get(event).forEach(function (callback) { return callback(args); }); }, /** Remove all events. */ off: function off() { events.clear(); } }; }(); var toaster = function toaster(_ref) { var content = _ref.content, type = _ref.type, config = _ref.config; return { id: Math.random().toString(36).substr(2, 10), content: content, type: type, config: config }; }; var Events; (function (Events) { Events["SHOW"] = "show"; Events["HIDE"] = "hide"; Events["HIDE_ALL"] = "hideAll"; })(Events || (Events = {})); var toastDispatcher = function toastDispatcher(_ref) { var dispatch = _ref.dispatch, delay = _ref.delay; emitter.on(Events.SHOW, function (toast) { dispatch({ type: 'ADD', toast: toast }); if (delay) setTimeout(function () { dispatch({ type: 'REMOVE', id: toast.id }); }, delay); }); emitter.on(Events.HIDE, function (id) { return dispatch({ type: 'REMOVE', id: id }); }); emitter.on(Events.HIDE_ALL, function () { return dispatch({ type: 'REMOVE_ALL' }); }); }; var css_248z$1 = ".toastContainer {\n overflow: hidden;\n overflow-x: auto;\n display: grid;\n grid-gap: 20px;\n position: fixed;\n user-select: none;\n}\n\n.top-left {\n top: 20px;\n left: 20px;\n}\n\n.top-center {\n top: 20px;\n left: 50%;\n transform: translate(-50%, 0);\n}\n\n.top-right {\n top: 20px;\n right: 20px;\n}\n\n.bottom-left {\n bottom: 20px;\n left: 20px;\n}\n\n.bottom-center {\n bottom: 20px;\n left: 50%;\n transform: translate(-50%, 0);\n}\n\n.bottom-right {\n bottom: 20px;\n right: 20px;\n}\n"; styleInject(css_248z$1); var ToastContainer = function ToastContainer(_ref) { var _ref$position = _ref.position, position = _ref$position === void 0 ? 'bottom-left' : _ref$position, delay = _ref.delay; var _useToast = useToast(), toasts = _useToast.toasts, dispatch = _useToast.dispatch; useEffect(function () { toastDispatcher({ dispatch: dispatch, delay: delay }); return function () { emitter.off(); }; }, [dispatch, delay]); var onClose = useCallback(function (id) { emitter.emit(Events.HIDE, id); }, []); return React.createElement("div", { className: "toastContainer " + position }, toasts.map(function (toast) { return React.createElement(Toast, Object.assign({ key: toast.id }, toast, { onClose: onClose })); })); }; var applyToast = function applyToast(_ref) { var toast = _extends({}, _ref); return emitter.emit(Events.SHOW, toaster(_extends({}, toast))); }; var toast = function toast(content, config) { return applyToast({ content: content, type: 'default', config: config }); }; toast.success = function (content, config) { return applyToast({ content: content, type: 'success', config: config }); }; toast.error = function (content, config) { return applyToast({ content: content, type: 'error', config: config }); }; toast.info = function (content, config) { return applyToast({ content: content, type: 'info', config: config }); }; toast.warn = function (content, config) { return applyToast({ content: content, type: 'warning', config: config }); }; toast.hideAll = function () { return emitter.emit(Events.HIDE_ALL); }; export { ToastContainer, toast }; //# sourceMappingURL=react-toast.esm.js.map