UNPKG

muinotify

Version:

muinotify has an imperative API that makes it easy to display snackbars, without having to handle their open/close state. It also enables you to stack them on top of one another (although this is discouraged by the Material Design guidelines).

9 lines (7 loc) 3.76 kB
import t,{createContext as e,memo as i,useState as r,useCallback as o,useRef as n,useEffect as s,useContext as a}from"react";import{createPortal as m}from"react-dom";import c from"@emotion/styled";import p from"@mui/material/Stack";import u from"@mui/material/Alert";import{Slide as l}from"@mui/material";function d(){return d=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var r in i)Object.prototype.hasOwnProperty.call(i,r)&&(t[r]=i[r])}return t},d.apply(this,arguments)}const f=e();f.Consumer,f.Provider;var h=i((e=>{const{message:i,options:a={},id:m,isEntered:c,notifyItemProps:p}=e,{defaultSeverity:l,TransitionComponent:f,TransitionProps:h,AlertProps:v,generalTimeOut:y,remove:P,customAlert:E}=p,{timeOut:g=y,isPersist:S}=a,[T,x]=r(!0),A=function(){const t=n(!1);return s((()=>(t.current=!0,()=>{t.current=!1})),[]),o((()=>t.current),[])}();let N=n(null);s((()=>(clearTimeout(N.current),N.current=setTimeout((()=>{A&&!S&&x(!1)}),g),()=>clearTimeout(N.current))),[g,S,A]),s((()=>{c||x(!1)}),[c,m]);return t.createElement(f,d({in:T,mountOnEnter:!0,unmountOnExit:!0,onExited:()=>{!T&&P&&P(m)}},h),E?t.createElement("div",{className:"Custom-Alert"},E(e)):t.createElement(u,d({id:m,severity:a&&a.variant||l},v),i))}));const v=c.div` position: fixed; z-index: 100000; height: auto; max-width: 50%; ${({position:t})=>t.split("-").map((t=>`${t}: 10px`))} `,y=({notifyList:e,remove:i,...r})=>{const{position:o,defaultSeverity:n,generalTimeOut:s,TransitionComponent:a,TransitionProps:m,AlertProps:c,StackProps:u,customAlert:l}=r,f={defaultSeverity:n,TransitionComponent:a,TransitionProps:m,AlertProps:c,generalTimeOut:s,remove:i,customAlert:l};return t.createElement(v,{position:o},t.createElement(p,d({spacing:2},u),e.map((e=>t.createElement(h,d({key:e.id,notifyItemProps:f},e))))))};class P extends t.PureComponent{constructor(t){super(t);const{wrapperElement:e,wrapperName:i}=this.props,r=document.createElement(e||"div");r.className=i||"rezvani-notify-wrapper",document.body.appendChild(r),this.renderPortal=r,this.actionQueue=[],this.isStateBlocked=!1,this.state={notifyList:[]}}getList=()=>[...this.state.notifyList];commitState=(t,e)=>{this.isStateBlocked=e,this.setState({notifyList:t},(()=>{e||this.proccessQueue()}))};proccessQueue=()=>{const t=this.actionQueue.shift();t&&t()};notifier=(t,e)=>{const{maxNotif:i,preventDuplicate:r}=this.props,o=Math.random().toString(16).slice(2),n={message:t,options:e,isEntered:!0,id:o},s=this.getList();if(!(s.findIndex((e=>e.message===t))>=0&&r)){if(!this.isStateBlocked)return s.length>=i?(s[0].isEntered=!1,s.push(n),this.commitState(s,!0)):(s.push(n),this.commitState(s,!1)),o;this.actionQueue.push((()=>this.notifier(t,e)))}};removeNofityById=t=>{const e=[...this.state.notifyList].filter((e=>e.id!==t));this.commitState(e,!1)};removeNotifierAnimationById=t=>{const e=this.getList(),i=e.findIndex((e=>e.id===t));i>=0&&(e[i].isEntered=!1),this.commitState(e,!1)};render(){const{notifyList:e}=this.state,{children:i,...r}=this.props;return t.createElement(f.Provider,{value:{notifier:this.notifier,removeNotifier:this.removeNotifierAnimationById}},i,m(t.createElement(y,d({notifyList:e,remove:this.removeNofityById},r)),this.renderPortal))}}P.defaultProps={customAlert:null,preventDuplicate:!1,position:"bottom-left",wrapperElement:"div",wrapperName:"rezvani-notify-wrapper",maxNotif:3,defaultSeverity:"info",generalTimeOut:3e3,TransitionComponent:l,TransitionProps:{},AlertProps:{},StackProps:{spacing:1,direction:"column-reverse"}};const E=()=>a(f),g=e=>{class i extends t.PureComponent{render(){return t.createElement(f.Consumer,null,(i=>t.createElement(e,d({},this.props,i))))}}return i};export{P as MuiNotifyProvider,E as useNotifier,g as withNotifier};