UNPKG

@afzalimdad9/react-alert

Version:
132 lines 5.46 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import React, { Fragment, useState, useRef, useEffect, useCallback, } from 'react'; import PropTypes from 'prop-types'; import { TransitionGroup } from 'react-transition-group'; import { createPortal } from 'react-dom'; import DefaultContext from './Context'; import Wrapper from './Wrapper'; import Transition from './Transition'; import { positions, transitions, types } from './options'; import { groupBy } from './helpers'; const Provider = (_a) => { var { children, offset, position, timeout, type, transition, containerStyle, template: AlertComponent, context: Context } = _a, props = __rest(_a, ["children", "offset", "position", "timeout", "type", "transition", "containerStyle", "template", "context"]); const root = useRef(null); const alertContext = useRef(null); const timersId = useRef([]); const [alerts, setAlerts] = useState([]); useEffect(() => { root.current = document.createElement('div'); root.current.id = '__react-alert__'; document.body.appendChild(root.current); const timersIdRef = timersId.current; return () => { timersIdRef.forEach(clearTimeout); if (root.current) document.body.removeChild(root.current); }; }, []); const remove = useCallback((alert) => { setAlerts((currentAlerts) => { const lengthBeforeRemove = currentAlerts.length; const filteredAlerts = currentAlerts.filter((a) => a.id !== alert.id); if (lengthBeforeRemove > filteredAlerts.length && alert.options.onClose) { alert.options.onClose(); } return filteredAlerts; }); }, []); const removeAll = useCallback(() => { alertContext.current.alerts.forEach(remove); }, [remove]); const show = useCallback((message = '', options = {}) => { const id = Math.random().toString(36).substr(2, 9); const alertOptions = Object.assign({ position: options.position || position, timeout, type }, options); const alert = { id, message, options: alertOptions, close: () => remove(alert), }; if (alert.options.timeout) { const timerId = setTimeout(() => { remove(alert); timersId.current.splice(timersId.current.indexOf(timerId), 1); }, alert.options.timeout); timersId.current.push(timerId); } setAlerts((state) => state.concat(alert)); if (alert.options.onOpen) alert.options.onOpen(); return alert; }, [position, remove, timeout, type]); const success = useCallback((message = '', options = {}) => { options.type = types.SUCCESS; return show(message, options); }, [show]); const error = useCallback((message = '', options = {}) => { options.type = types.ERROR; return show(message, options); }, [show]); const info = useCallback((message = '', options = {}) => { options.type = types.INFO; return show(message, options); }, [show]); alertContext.current = { alerts, show, remove, removeAll, success, error, info, }; const alertsByPosition = groupBy(alerts, (alert) => alert.options.position); return (React.createElement(Context.Provider, { value: alertContext.current }, children, root.current && createPortal(React.createElement(Fragment, null, Object.values(positions).map((position) => { return (React.createElement(TransitionGroup, Object.assign({ appear: true, key: position, options: { position, containerStyle }, component: Wrapper }, props), alertsByPosition[position] ? (alertsByPosition[position].map((alert) => (React.createElement(Transition, { type: transition, key: alert.id }, React.createElement(AlertComponent, Object.assign({ style: { margin: offset, pointerEvents: 'all' } }, alert)))))) : (React.createElement(React.Fragment, null)))); })), root.current))); }; Provider.propTypes = { offset: PropTypes.string, position: PropTypes.oneOf(Object.values(positions)), timeout: PropTypes.number, type: PropTypes.oneOf(Object.values(types)), transition: PropTypes.oneOf(Object.values(transitions)), containerStyle: PropTypes.object, template: PropTypes.oneOfType([ PropTypes.element, PropTypes.func, PropTypes.elementType, ]).isRequired, context: PropTypes.shape({ Provider: PropTypes.object, Consumer: PropTypes.object, }), }; Provider.defaultProps = { offset: '10px', position: positions.TOP_CENTER, timeout: 0, type: types.INFO, transition: transitions.FADE, containerStyle: { zIndex: 100, }, context: DefaultContext, }; export default Provider; //# sourceMappingURL=Provider.js.map