@lerx/promise-modal 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/dist/app/ModalManager.d.ts +0 -1
  2. package/dist/app/constant.d.ts +0 -1
  3. package/dist/bootstrap/BootstrapProvider/BootstrapProvider.d.ts +0 -1
  4. package/dist/bootstrap/BootstrapProvider/helpers/bootstrap.d.ts +0 -1
  5. package/dist/bootstrap/BootstrapProvider/hooks/useInitialize.d.ts +0 -1
  6. package/dist/bootstrap/BootstrapProvider/index.d.ts +0 -1
  7. package/dist/bootstrap/BootstrapProvider/type.d.ts +0 -1
  8. package/dist/bootstrap/BootstrapProvider/useBootstrap.d.ts +0 -1
  9. package/dist/bootstrap/index.d.ts +0 -1
  10. package/dist/components/Anchor/Anchor.d.ts +0 -1
  11. package/dist/components/Anchor/classNames.emotion.d.ts +0 -1
  12. package/dist/components/Anchor/index.d.ts +0 -1
  13. package/dist/components/Background/Background.d.ts +0 -1
  14. package/dist/components/Background/classNames.emotion.d.ts +0 -1
  15. package/dist/components/Background/index.d.ts +0 -1
  16. package/dist/components/FallbackComponents/FallbackContent.d.ts +0 -1
  17. package/dist/components/FallbackComponents/FallbackFooter.d.ts +0 -1
  18. package/dist/components/FallbackComponents/FallbackForegroundFrame.d.ts +0 -1
  19. package/dist/components/FallbackComponents/FallbackSubtitle.d.ts +0 -1
  20. package/dist/components/FallbackComponents/FallbackTitle.d.ts +0 -1
  21. package/dist/components/FallbackComponents/classNames.emotion.d.ts +0 -1
  22. package/dist/components/FallbackComponents/index.d.ts +0 -1
  23. package/dist/components/Foreground/Foreground.d.ts +0 -1
  24. package/dist/components/Foreground/classNames.emotion.d.ts +0 -1
  25. package/dist/components/Foreground/components/AlertInner.d.ts +0 -1
  26. package/dist/components/Foreground/components/ConfirmInner.d.ts +0 -1
  27. package/dist/components/Foreground/components/PromptInner.d.ts +0 -1
  28. package/dist/components/Foreground/components/index.d.ts +0 -1
  29. package/dist/components/Foreground/index.d.ts +0 -1
  30. package/dist/components/Presenter/Presenter.d.ts +0 -1
  31. package/dist/components/Presenter/classNames.emotion.d.ts +0 -1
  32. package/dist/components/Presenter/index.d.ts +0 -1
  33. package/dist/core/handle/alert.d.ts +0 -1
  34. package/dist/core/handle/confirm.d.ts +0 -1
  35. package/dist/core/handle/index.d.ts +0 -1
  36. package/dist/core/handle/prompt.d.ts +0 -1
  37. package/dist/core/index.d.ts +0 -1
  38. package/dist/core/node/ModalNode/AbstractNode.d.ts +0 -1
  39. package/dist/core/node/ModalNode/AlertNode.d.ts +0 -1
  40. package/dist/core/node/ModalNode/ConfirmNode.d.ts +0 -1
  41. package/dist/core/node/ModalNode/PromptNode.d.ts +0 -1
  42. package/dist/core/node/ModalNode/index.d.ts +0 -1
  43. package/dist/core/node/index.d.ts +0 -1
  44. package/dist/core/node/nodeFactory.d.ts +0 -1
  45. package/dist/core/node/type.d.ts +0 -1
  46. package/dist/hooks/useActiveModalCount.d.ts +0 -1
  47. package/dist/hooks/useDefaultPathname.d.ts +0 -1
  48. package/dist/hooks/useDestroyAfter.d.ts +0 -1
  49. package/dist/hooks/useModalAnimation.d.ts +0 -1
  50. package/dist/hooks/useSubscribeModal.d.ts +0 -1
  51. package/dist/index.cjs +966 -2
  52. package/dist/index.d.ts +0 -1
  53. package/dist/index.mjs +953 -2
  54. package/dist/providers/ConfigurationContext/ConfigurationContext.d.ts +0 -1
  55. package/dist/providers/ConfigurationContext/ConfigurationContextProvider.d.ts +4 -1
  56. package/dist/providers/ConfigurationContext/index.d.ts +0 -1
  57. package/dist/providers/ConfigurationContext/useConfigurationContext.d.ts +0 -1
  58. package/dist/providers/ModalManagerContext/ModalManagerContext.d.ts +0 -1
  59. package/dist/providers/ModalManagerContext/ModalManagerContextProvider.d.ts +0 -1
  60. package/dist/providers/ModalManagerContext/index.d.ts +0 -1
  61. package/dist/providers/ModalManagerContext/useModalManagerContext.d.ts +0 -1
  62. package/dist/providers/UserDefinedContext/UserDefinedContext.d.ts +0 -1
  63. package/dist/providers/UserDefinedContext/UserDefinedContextProvider.d.ts +2 -2
  64. package/dist/providers/UserDefinedContext/index.d.ts +0 -1
  65. package/dist/providers/UserDefinedContext/useUserDefinedContext.d.ts +0 -1
  66. package/dist/providers/index.d.ts +0 -1
  67. package/dist/types/alert.d.ts +0 -1
  68. package/dist/types/background.d.ts +0 -1
  69. package/dist/types/base.d.ts +0 -1
  70. package/dist/types/confirm.d.ts +0 -1
  71. package/dist/types/index.d.ts +0 -1
  72. package/dist/types/modal.d.ts +0 -1
  73. package/dist/types/prompt.d.ts +0 -1
  74. package/package.json +34 -27
  75. package/dist/app/ModalManager.d.ts.map +0 -1
  76. package/dist/app/constant.d.ts.map +0 -1
  77. package/dist/bootstrap/BootstrapProvider/BootstrapProvider.d.ts.map +0 -1
  78. package/dist/bootstrap/BootstrapProvider/helpers/bootstrap.d.ts.map +0 -1
  79. package/dist/bootstrap/BootstrapProvider/hooks/useInitialize.d.ts.map +0 -1
  80. package/dist/bootstrap/BootstrapProvider/index.d.ts.map +0 -1
  81. package/dist/bootstrap/BootstrapProvider/type.d.ts.map +0 -1
  82. package/dist/bootstrap/BootstrapProvider/useBootstrap.d.ts.map +0 -1
  83. package/dist/bootstrap/index.d.ts.map +0 -1
  84. package/dist/components/Anchor/Anchor.d.ts.map +0 -1
  85. package/dist/components/Anchor/classNames.emotion.d.ts.map +0 -1
  86. package/dist/components/Anchor/index.d.ts.map +0 -1
  87. package/dist/components/Background/Background.d.ts.map +0 -1
  88. package/dist/components/Background/classNames.emotion.d.ts.map +0 -1
  89. package/dist/components/Background/index.d.ts.map +0 -1
  90. package/dist/components/FallbackComponents/FallbackContent.d.ts.map +0 -1
  91. package/dist/components/FallbackComponents/FallbackFooter.d.ts.map +0 -1
  92. package/dist/components/FallbackComponents/FallbackForegroundFrame.d.ts.map +0 -1
  93. package/dist/components/FallbackComponents/FallbackSubtitle.d.ts.map +0 -1
  94. package/dist/components/FallbackComponents/FallbackTitle.d.ts.map +0 -1
  95. package/dist/components/FallbackComponents/classNames.emotion.d.ts.map +0 -1
  96. package/dist/components/FallbackComponents/index.d.ts.map +0 -1
  97. package/dist/components/Foreground/Foreground.d.ts.map +0 -1
  98. package/dist/components/Foreground/classNames.emotion.d.ts.map +0 -1
  99. package/dist/components/Foreground/components/AlertInner.d.ts.map +0 -1
  100. package/dist/components/Foreground/components/ConfirmInner.d.ts.map +0 -1
  101. package/dist/components/Foreground/components/PromptInner.d.ts.map +0 -1
  102. package/dist/components/Foreground/components/index.d.ts.map +0 -1
  103. package/dist/components/Foreground/index.d.ts.map +0 -1
  104. package/dist/components/Presenter/Presenter.d.ts.map +0 -1
  105. package/dist/components/Presenter/classNames.emotion.d.ts.map +0 -1
  106. package/dist/components/Presenter/index.d.ts.map +0 -1
  107. package/dist/core/handle/alert.d.ts.map +0 -1
  108. package/dist/core/handle/confirm.d.ts.map +0 -1
  109. package/dist/core/handle/index.d.ts.map +0 -1
  110. package/dist/core/handle/prompt.d.ts.map +0 -1
  111. package/dist/core/index.d.ts.map +0 -1
  112. package/dist/core/node/ModalNode/AbstractNode.d.ts.map +0 -1
  113. package/dist/core/node/ModalNode/AlertNode.d.ts.map +0 -1
  114. package/dist/core/node/ModalNode/ConfirmNode.d.ts.map +0 -1
  115. package/dist/core/node/ModalNode/PromptNode.d.ts.map +0 -1
  116. package/dist/core/node/ModalNode/index.d.ts.map +0 -1
  117. package/dist/core/node/index.d.ts.map +0 -1
  118. package/dist/core/node/nodeFactory.d.ts.map +0 -1
  119. package/dist/core/node/type.d.ts.map +0 -1
  120. package/dist/hooks/useActiveModalCount.d.ts.map +0 -1
  121. package/dist/hooks/useDefaultPathname.d.ts.map +0 -1
  122. package/dist/hooks/useDestroyAfter.d.ts.map +0 -1
  123. package/dist/hooks/useModalAnimation.d.ts.map +0 -1
  124. package/dist/hooks/useSubscribeModal.d.ts.map +0 -1
  125. package/dist/index.cjs.map +0 -1
  126. package/dist/index.d.ts.map +0 -1
  127. package/dist/index.mjs.map +0 -1
  128. package/dist/providers/ConfigurationContext/ConfigurationContext.d.ts.map +0 -1
  129. package/dist/providers/ConfigurationContext/ConfigurationContextProvider.d.ts.map +0 -1
  130. package/dist/providers/ConfigurationContext/index.d.ts.map +0 -1
  131. package/dist/providers/ConfigurationContext/useConfigurationContext.d.ts.map +0 -1
  132. package/dist/providers/ModalManagerContext/ModalManagerContext.d.ts.map +0 -1
  133. package/dist/providers/ModalManagerContext/ModalManagerContextProvider.d.ts.map +0 -1
  134. package/dist/providers/ModalManagerContext/index.d.ts.map +0 -1
  135. package/dist/providers/ModalManagerContext/useModalManagerContext.d.ts.map +0 -1
  136. package/dist/providers/UserDefinedContext/UserDefinedContext.d.ts.map +0 -1
  137. package/dist/providers/UserDefinedContext/UserDefinedContextProvider.d.ts.map +0 -1
  138. package/dist/providers/UserDefinedContext/index.d.ts.map +0 -1
  139. package/dist/providers/UserDefinedContext/useUserDefinedContext.d.ts.map +0 -1
  140. package/dist/providers/index.d.ts.map +0 -1
  141. package/dist/types/alert.d.ts.map +0 -1
  142. package/dist/types/background.d.ts.map +0 -1
  143. package/dist/types/base.d.ts.map +0 -1
  144. package/dist/types/confirm.d.ts.map +0 -1
  145. package/dist/types/index.d.ts.map +0 -1
  146. package/dist/types/modal.d.ts.map +0 -1
  147. package/dist/types/prompt.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,2 +1,953 @@
1
- function _EMOTION_STRINGIFIED_CSS_ERROR__$4(){return"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."}function _EMOTION_STRINGIFIED_CSS_ERROR__$3(){return"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."}function _EMOTION_STRINGIFIED_CSS_ERROR__$2(){return"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."}import{jsx as e,jsxs as n}from"react/jsx-runtime";import{createContext as o,memo as t,useRef as r,useState,useMemo as i,useLayoutEffect as a,useCallback as l,useContext as s,forwardRef as c,Fragment as d,useEffect,useImperativeHandle as u}from"react";import{convertMsFromDuration as m}from"@winglet/common-utils/convert";import{useReference as p,useOnMountLayout as C,useHandle as h,useVersion as g,useOnMount as f}from"@winglet/react-utils/hook";import{getRandomString as b,counterFactory as v}from"@winglet/common-utils/lib";import{css as y,cx as k}from"@emotion/css";import{createPortal as O}from"react-dom";import{map as _}from"@winglet/common-utils/array";import{withErrorBoundary as x}from"@winglet/react-utils/hoc";import{isString as I,isFunction as M}from"@winglet/common-utils/filter";import{renderComponent as N}from"@winglet/react-utils/render";import{printError as D}from"@winglet/common-utils/console";class ModalManager{static#e=0;static activate(){return ModalManager.#e?0:ModalManager.#e=1}static#n=null;static anchor(e){if(ModalManager.#n){const e=document.getElementById(ModalManager.#n.id);if(e)return e}const{tag:n="div",prefix:o="promise-modal",root:t=document.body}=e||{},r=document.createElement(n);return r.setAttribute("id",`${o}-${b(36)}`),t.appendChild(r),ModalManager.#n=r,r}static#o=[];static get prerender(){return ModalManager.#o}static#t=e=>ModalManager.#o.push(e);static set openHandler(e){ModalManager.#t=e,ModalManager.#o=[]}static get unanchored(){return!ModalManager.#n}static reset(){ModalManager.#e=0,ModalManager.#n=null,ModalManager.#o=[],ModalManager.#t=e=>ModalManager.#o.push(e)}static open(e){ModalManager.#t(e)}}const alert=({subtype:e,title:n,subtitle:o,content:t,background:r,footer:i,dimmed:a,manualDestroy:l,closeOnBackdropClick:s,ForegroundComponent:c,BackgroundComponent:d})=>new Promise(((u,m)=>{try{ModalManager.open({type:"alert",subtype:e,resolve:()=>u(),title:n,subtitle:o,content:t,background:r,footer:i,dimmed:a,manualDestroy:l,closeOnBackdropClick:s,ForegroundComponent:c,BackgroundComponent:d})}catch(e){m(e)}})),confirm=({subtype:e,title:n,subtitle:o,content:t,background:r,footer:i,dimmed:a,manualDestroy:l,closeOnBackdropClick:s,ForegroundComponent:c,BackgroundComponent:d})=>new Promise(((u,m)=>{try{ModalManager.open({type:"confirm",subtype:e,resolve:e=>u(e??0),title:n,subtitle:o,content:t,background:r,footer:i,dimmed:a,manualDestroy:l,closeOnBackdropClick:s,ForegroundComponent:c,BackgroundComponent:d})}catch(e){m(e)}})),prompt=({defaultValue:e,title:n,subtitle:o,content:t,Input:r,disabled:i,returnOnCancel:a,background:l,footer:s,dimmed:c,manualDestroy:d,closeOnBackdropClick:u,ForegroundComponent:m,BackgroundComponent:p})=>new Promise(((C,h)=>{try{ModalManager.open({type:"prompt",resolve:e=>C(e),title:n,subtitle:o,content:t,Input:r,defaultValue:e,disabled:i,returnOnCancel:a,background:l,footer:s,dimmed:c,manualDestroy:d,closeOnBackdropClick:u,ForegroundComponent:m,BackgroundComponent:p})}catch(e){h(e)}}));class AbstractNode{id;initiator;title;subtitle;background;manualDestroy;closeOnBackdropClick;dimmed;ForegroundComponent;BackgroundComponent;#r;get alive(){return this.#r}#i;get visible(){return this.#i}#a;#l=new Set;constructor({id:e,initiator:n,title:o,subtitle:t,background:r,dimmed:i=1,manualDestroy:a=0,closeOnBackdropClick:l=1,resolve:s,ForegroundComponent:c,BackgroundComponent:d}){this.id=e,this.initiator=n,this.title=o,this.subtitle=t,this.background=r,this.dimmed=i,this.manualDestroy=a,this.closeOnBackdropClick=l,this.ForegroundComponent=c,this.BackgroundComponent=d,this.#r=1,this.#i=1,this.#a=s}subscribe(e){return this.#l.add(e),()=>{this.#l.delete(e)}}publish(){for(const e of this.#l)e()}resolve(e){this.#a(e)}onDestroy(){const e=1==this.#r;this.#r=0,this.manualDestroy&&e&&this.publish()}onShow(){const e=0==this.#i;this.#i=1,e&&this.publish()}onHide(){const e=1==this.#i;this.#i=0,e&&this.publish()}}class AlertNode extends AbstractNode{type;subtype;content;footer;constructor({id:e,initiator:n,type:o,subtype:t,title:r,subtitle:i,content:a,footer:l,background:s,dimmed:c,manualDestroy:d,closeOnBackdropClick:u,resolve:m,ForegroundComponent:p,BackgroundComponent:C}){super({id:e,initiator:n,title:r,subtitle:i,background:s,dimmed:c,manualDestroy:d,closeOnBackdropClick:u,resolve:m,ForegroundComponent:p,BackgroundComponent:C}),this.type=o,this.subtype=t,this.content=a,this.footer=l}onClose(){this.resolve(null)}onConfirm(){this.resolve(null)}}class ConfirmNode extends AbstractNode{type;subtype;content;footer;constructor({id:e,initiator:n,type:o,subtype:t,title:r,subtitle:i,content:a,footer:l,background:s,dimmed:c,manualDestroy:d,closeOnBackdropClick:u,resolve:m,ForegroundComponent:p,BackgroundComponent:C}){super({id:e,initiator:n,title:r,subtitle:i,background:s,dimmed:c,manualDestroy:d,closeOnBackdropClick:u,resolve:m,ForegroundComponent:p,BackgroundComponent:C}),this.type=o,this.subtype=t,this.content=a,this.footer=l}onClose(){this.resolve(0)}onConfirm(){this.resolve(1)}}class PromptNode extends AbstractNode{type;content;defaultValue;Input;disabled;returnOnCancel;footer;#s;constructor({id:e,initiator:n,type:o,title:t,subtitle:r,content:i,defaultValue:a,Input:l,disabled:s,returnOnCancel:c,footer:d,background:u,dimmed:m,manualDestroy:p,closeOnBackdropClick:C,resolve:h,ForegroundComponent:g,BackgroundComponent:f}){super({id:e,initiator:n,title:t,subtitle:r,background:u,dimmed:m,manualDestroy:p,closeOnBackdropClick:C,resolve:h,ForegroundComponent:g,BackgroundComponent:f}),this.type=o,this.content=i,this.Input=l,this.defaultValue=a,this.#s=a,this.disabled=s,this.returnOnCancel=c,this.footer=d}onChange(e){this.#s=e}onConfirm(){this.resolve(this.#s??null)}onClose(){this.returnOnCancel?this.resolve(this.#s??null):this.resolve(null)}}const nodeFactory=e=>{switch(e.type){case"alert":return new AlertNode(e);case"confirm":return new ConfirmNode(e);case"prompt":return new PromptNode(e)}throw new Error(`Unknown modal: ${e.type}`,{modal:e})},S=o({}),E=t((({usePathname:n,children:o})=>{const t=r(new Map),[s,c]=useState([]),d=p(s),{pathname:u}=n(),h=r(u),g=r(0),f=useConfigurationOptions(),b=i((()=>m(f.duration)),[f]);C((()=>{const{manualDestroy:e,closeOnBackdropClick:n}=f;for(const o of ModalManager.prerender){const r=nodeFactory({...o,id:g.current++,initiator:h.current,manualDestroy:void 0!==o.manualDestroy?o.manualDestroy:e,closeOnBackdropClick:void 0!==o.closeOnBackdropClick?o.closeOnBackdropClick:n});t.current.set(r.id,r),c((e=>[...e,r.id]))}return ModalManager.openHandler=o=>{const r=nodeFactory({...o,id:g.current++,initiator:h.current,manualDestroy:void 0!==o.manualDestroy?o.manualDestroy:e,closeOnBackdropClick:void 0!==o.closeOnBackdropClick?o.closeOnBackdropClick:n});t.current.set(r.id,r),c((e=>{const n=[];for(let o=0;o<e.length;o++){const r=e[o];t.current.get(r)?.alive?n.push(r):t.current.delete(r)}return[...n,r.id]}))},()=>{ModalManager.reset()}})),a((()=>{for(const e of d.current){const n=t.current.get(e);n?.alive&&(n.initiator===u?n.onShow():n.onHide())}h.current=u}),[u]);const v=l((e=>t.current.get(e)),[]),y=l((e=>{const n=t.current.get(e);n&&(n.onDestroy(),k.current?.())}),[]),k=r(void 0),O=l((e=>{const n=t.current.get(e);n&&(n.onHide(),k.current?.(),n.manualDestroy||setTimeout((()=>{n.onDestroy()}),b))}),[b]),_=l(((e,n)=>{const o=t.current.get(e);o&&"prompt"===o.type&&o.onChange(n)}),[]),x=l((e=>{const n=t.current.get(e);n&&(n.onConfirm(),O(e))}),[O]),I=l((e=>{const n=t.current.get(e);n&&(n.onClose(),O(e))}),[O]),M=l((e=>({modal:v(e),onConfirm:()=>x(e),onClose:()=>I(e),onChange:n=>_(e,n),onDestroy:()=>y(e)})),[v,x,I,_,y]),N=i((()=>({modalIds:s,getModalNode:v,onChange:_,onConfirm:x,onClose:I,onDestroy:y,getModal:M,setUpdater:e=>{k.current=e}})),[s,M,v,_,x,I,y]);return e(S.Provider,{value:N,children:o})})),useModalManagerContext=()=>s(S),useModal=e=>{const{getModal:n}=useModalManagerContext();return i((()=>n(e)),[e,n])},B=y("production"===process.env.NODE_ENV?{name:"131j9g2",styles:"margin:unset"}:{name:"1w3kbco-fallback",styles:"margin:unset;label:fallback;",toString:_EMOTION_STRINGIFIED_CSS_ERROR__$4}),F=y("production"===process.env.NODE_ENV?{name:"1kuk3a3",styles:"display:flex;flex-direction:column;justify-content:center;align-items:center;background-color:white;padding:20px 80px;gap:10px;border:1px solid black"}:{name:"16dbbea-frame",styles:"display:flex;flex-direction:column;justify-content:center;align-items:center;background-color:white;padding:20px 80px;gap:10px;border:1px solid black;label:frame;",toString:_EMOTION_STRINGIFIED_CSS_ERROR__$4}),FallbackTitle=({children:n})=>e("h2",{className:B,children:n}),FallbackSubtitle=({children:n})=>e("h3",{className:B,children:n}),FallbackContent=({children:n})=>e("div",{className:B,children:n}),FallbackFooter=({confirmLabel:o,hideConfirm:t=0,cancelLabel:r,hideCancel:i=0,disabled:a,onConfirm:l,onCancel:s})=>n("div",{children:[!t&&e("button",{onClick:l,disabled:a,children:o||"Confirm"}),!i&&"function"==typeof s&&e("button",{onClick:s,children:r||"Cancel"})]}),defaultValidate=e=>e?.visible,useActiveModalCount=(e=defaultValidate,n=0)=>{const{modalIds:o,getModalNode:t}=useModalManagerContext();return i((()=>{let n=0;for(const r of o)e(t(r))&&n++;return n}),[t,o,n])},R=c((({id:n,onChangeOrder:o,children:t},r)=>{const a=useActiveModalCount(),[l,s]=i((()=>{const e=a>1;return[e?Math.floor(n/5)%3*100:0,e?n%5*35:0]}),[a,n]);return e("div",{ref:r,className:F,onClick:o,style:{marginBottom:`calc(25vh + ${l}px)`,marginLeft:`${l}px`,transform:`translate(${s}px, ${s}px)`},children:t})})),T=o({}),w=t((({ForegroundComponent:n,BackgroundComponent:o,TitleComponent:r,SubtitleComponent:a,ContentComponent:l,FooterComponent:s,options:c,children:d})=>{const u=i((()=>({BackgroundComponent:o,ForegroundComponent:n||R,TitleComponent:r||FallbackTitle,SubtitleComponent:a||FallbackSubtitle,ContentComponent:t(l||FallbackContent),FooterComponent:t(s||FallbackFooter),options:{duration:"300ms",backdrop:"rgba(0, 0, 0, 0.5)",closeOnBackdropClick:1,manualDestroy:0,...c}})),[n,o,l,s,a,r,c]);return e(T.Provider,{value:u,children:d})})),useConfigurationContext=()=>s(T),useConfigurationOptions=()=>s(T).options,useConfigurationDuration=()=>{const e=useConfigurationOptions();return{duration:e.duration,milliseconds:m(e.duration)}},useConfigurationBackdrop=()=>useConfigurationOptions().backdrop,P=o({}),UserDefinedContextProvider=({context:n,children:o})=>{const t=i((()=>({context:n||{}})),[n]);return e(P.Provider,{value:t,children:o})},useUserDefinedContext=()=>s(P),usePathname=()=>{const[e,n]=useState(window.location.pathname);return a((()=>{let o;const checkPathname=()=>{o&&cancelAnimationFrame(o),e!==window.location.pathname?n(window.location.pathname):o=requestAnimationFrame(checkPathname)};return o=requestAnimationFrame(checkPathname),()=>{o&&cancelAnimationFrame(o)}}),[e]),{pathname:e}},$=y("production"===process.env.NODE_ENV?{name:"u7uu4v",styles:"display:none;position:fixed;inset:0;z-index:-999;pointer-events:none;>*{pointer-events:none;}"}:{name:"coymdj-background",styles:"display:none;position:fixed;inset:0;z-index:-999;pointer-events:none;>*{pointer-events:none;};label:background;",toString:_EMOTION_STRINGIFIED_CSS_ERROR__$3}),j=y("production"===process.env.NODE_ENV?{name:"n07k1x",styles:"pointer-events:all"}:{name:"1hektcs-active",styles:"pointer-events:all;label:active;",toString:_EMOTION_STRINGIFIED_CSS_ERROR__$3}),V=y("production"===process.env.NODE_ENV?{name:"1wnowod",styles:"display:flex;align-items:center;justify-content:center"}:{name:"xppew7-visible",styles:"display:flex;align-items:center;justify-content:center;label:visible;",toString:_EMOTION_STRINGIFIED_CSS_ERROR__$3}),BackgroundFrame=({modalId:n,onChangeOrder:o})=>{const{BackgroundComponent:t}=useConfigurationContext(),{context:r}=useUserDefinedContext(),{modal:a,onClose:s,onChange:c,onConfirm:d,onDestroy:u}=useModal(n),m=l((e=>{a&&a.closeOnBackdropClick&&a.visible&&s(),e.stopPropagation()}),[a,s]),p=i((()=>a?.BackgroundComponent||t),[t,a]);return a?e("div",{className:k($,{[V]:a.manualDestroy?a.alive:a.visible,[j]:a.closeOnBackdropClick&&a.visible}),onClick:m,children:p&&e(p,{id:a.id,type:a.type,alive:a.alive,visible:a.visible,initiator:a.initiator,manualDestroy:a.manualDestroy,closeOnBackdropClick:a.closeOnBackdropClick,background:a.background,onChange:c,onConfirm:d,onClose:s,onDestroy:u,onChangeOrder:o,context:r})}):null},z=y("production"===process.env.NODE_ENV?{name:"12g0hx0",styles:"pointer-events:none;display:none;position:fixed;inset:0;z-index:1"}:{name:"1hcczik-foreground",styles:"pointer-events:none;display:none;position:fixed;inset:0;z-index:1;label:foreground;",toString:_EMOTION_STRINGIFIED_CSS_ERROR__$2}),A=y("production"===process.env.NODE_ENV?{name:"1g95xyq",styles:">*{pointer-events:all;}"}:{name:"123csva-active",styles:">*{pointer-events:all;};label:active;",toString:_EMOTION_STRINGIFIED_CSS_ERROR__$2}),L=y("production"===process.env.NODE_ENV?{name:"1fmljv2",styles:"display:flex!important;justify-content:center;align-items:center"}:{name:"1p4unab-visible",styles:"display:flex!important;justify-content:center;align-items:center;label:visible;",toString:_EMOTION_STRINGIFIED_CSS_ERROR__$2}),G=t((({modal:o,handlers:t})=>{const{title:r,subtitle:a,content:l,footer:s}=i((()=>o),[o]),{context:c}=useUserDefinedContext(),{onConfirm:u}=i((()=>t),[t]),m=h(u),{TitleComponent:p,SubtitleComponent:C,ContentComponent:g,FooterComponent:f}=useConfigurationContext();return n(d,{children:[r&&(I(r)?e(p,{context:c,children:r}):r),a&&(I(a)?e(C,{context:c,children:a}):a),l&&(I(l)?e(g,{context:c,children:l}):N(l,{onConfirm:m})),0!=s&&("function"==typeof s?s({onConfirm:m,context:c}):e(f,{onConfirm:m,confirmLabel:s?.confirm,hideConfirm:s?.hideConfirm,context:c}))]})})),H=t((({modal:o,handlers:t})=>{const{title:r,subtitle:a,content:l,footer:s}=i((()=>o),[o]),{context:c}=useUserDefinedContext(),{onConfirm:u,onClose:m}=i((()=>t),[t]),p=h(u),C=h(m),{TitleComponent:g,SubtitleComponent:f,ContentComponent:b,FooterComponent:v}=useConfigurationContext();return n(d,{children:[r&&(I(r)?e(g,{context:c,children:r}):r),a&&(I(a)?e(f,{context:c,children:a}):a),l&&(I(l)?e(b,{context:c,children:l}):N(l,{onConfirm:p,onCancel:C,context:c})),0!=s&&("function"==typeof s?s({onConfirm:p,onCancel:C,context:c}):e(v,{onConfirm:p,onCancel:C,confirmLabel:s?.confirm,cancelLabel:s?.cancel,hideConfirm:s?.hideConfirm,hideCancel:s?.hideCancel,context:c}))]})})),q=t((({modal:o,handlers:r})=>{const{Input:a,defaultValue:s,disabled:c,title:u,subtitle:m,content:p,footer:C}=i((()=>({...o,Input:t(x(o.Input))})),[o]),{context:g}=useUserDefinedContext(),[f,b]=useState(s),{onChange:v,onClose:y,onConfirm:k}=i((()=>r),[r]),O=h(y),_=h((e=>{const n=M(e)?e(f):e;b(n),v(n)})),D=l((()=>{requestAnimationFrame(k)}),[k]),S=i((()=>f?!!c?.(f):0),[c,f]),{TitleComponent:E,SubtitleComponent:B,ContentComponent:F,FooterComponent:R}=useConfigurationContext();return n(d,{children:[u&&(I(u)?e(E,{context:g,children:u}):u),m&&(I(m)?e(B,{context:g,children:m}):m),p&&(I(p)?e(F,{context:g,children:p}):N(p,{onConfirm:D,onCancel:O,context:g})),a&&e(a,{defaultValue:s,value:f,onChange:_,onConfirm:D,onCancel:O,context:g}),0!=C&&("function"==typeof C?C({value:f,disabled:S,onChange:_,onConfirm:D,onCancel:O,context:g}):e(R,{disabled:S,onConfirm:D,onCancel:O,confirmLabel:C?.confirm,cancelLabel:C?.cancel,hideConfirm:C?.hideConfirm,hideCancel:C?.hideCancel,context:g}))]})})),ForegroundFrame=({modalId:o,onChangeOrder:t})=>{const{ForegroundComponent:r}=useConfigurationContext(),{context:a}=useUserDefinedContext(),{modal:l,onChange:s,onConfirm:c,onClose:d,onDestroy:u}=useModal(o),m=i((()=>l?.ForegroundComponent||r),[r,l]);return l?e("div",{className:k(z,{[L]:l.manualDestroy?l.alive:l.visible,[A]:l.visible}),children:n(m,{id:l.id,type:l.type,alive:l.alive,visible:l.visible,initiator:l.initiator,manualDestroy:l.manualDestroy,closeOnBackdropClick:l.closeOnBackdropClick,background:l.background,onChange:s,onConfirm:c,onClose:d,onDestroy:u,onChangeOrder:t,context:a,children:["alert"===l.type&&e(G,{modal:l,handlers:{onConfirm:c}}),"confirm"===l.type&&e(H,{modal:l,handlers:{onConfirm:c,onClose:d}}),"prompt"===l.type&&e(q,{modal:l,handlers:{onChange:s,onConfirm:c,onClose:d}})]})}):null},useSubscribeModal=e=>{const[n,o]=g();return useEffect((()=>{if(e)return e.subscribe(o)}),[e,o]),n},Y=y("production"===process.env.NODE_ENV?{name:"13dmkf4",styles:"position:fixed;inset:0;pointer-events:none;overflow:hidden"}:{name:"yjeu12-presenter",styles:"position:fixed;inset:0;pointer-events:none;overflow:hidden;label:presenter;",toString:function _EMOTION_STRINGIFIED_CSS_ERROR__$1(){return"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."}}),{increment:U}=v(1),J=t((({modalId:o})=>{const t=r(null),{modal:i}=useModal(o);useSubscribeModal(i);const a=h((()=>{t.current&&(t.current.style.zIndex=`${U()}`)}));return n("div",{ref:t,className:Y,children:[e(BackgroundFrame,{modalId:o,onChangeOrder:a}),e(ForegroundFrame,{modalId:o,onChangeOrder:a})]})})),K=y("production"===process.env.NODE_ENV?{name:"2hpasy",styles:"display:flex;align-items:center;justify-content:center;position:fixed;inset:0;pointer-events:none;z-index:1000;transition:background-color ease-in-out"}:{name:"lhj8co-anchor",styles:"display:flex;align-items:center;justify-content:center;position:fixed;inset:0;pointer-events:none;z-index:1000;transition:background-color ease-in-out;label:anchor;",toString:function _EMOTION_STRINGIFIED_CSS_ERROR__(){return"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."}}),validateDimmable=e=>e?.visible&&e.dimmed,Q=t(x((()=>{const[n,o]=g(),{modalIds:t,setUpdater:r}=useModalManagerContext();useEffect((()=>{r(o)}),[r,o]);const i=useConfigurationOptions(),a=useActiveModalCount(validateDimmable,n);return e("div",{className:K,style:{transitionDuration:i.duration,backgroundColor:a?i.backdrop:"transparent"},children:_(t,(n=>e(J,{modalId:n},n)))})}))),bootstrap=({ForegroundComponent:n,BackgroundComponent:o,TitleComponent:t,SubtitleComponent:r,ContentComponent:i,FooterComponent:a,usePathname:l,options:s,context:c,anchor:d})=>O(e(UserDefinedContextProvider,{context:c,children:e(w,{ForegroundComponent:n,BackgroundComponent:o,TitleComponent:t,SubtitleComponent:r,ContentComponent:i,FooterComponent:a,options:s,children:e(E,{usePathname:l,children:e(Q,{})})})}),d),useInitialize=()=>{const e=r(ModalManager.activate()),n=r(null),[,o]=g(),t=l((t=>{e.current?(n.current=ModalManager.anchor({root:t}),o()):D("ModalProvider is already initialized",["ModalProvider can only be initialized once.","Nesting ModalProvider will be ignored..."],{info:"Something is wrong with the ModalProvider initialization..."})}),[o]);return{anchorRef:n,handleInitialize:t}},W=c((({usePathname:e,ForegroundComponent:o,BackgroundComponent:t,TitleComponent:r,SubtitleComponent:a,ContentComponent:l,FooterComponent:s,options:c,context:m,children:p},C)=>{const h=i((()=>e||usePathname),[e]),{anchorRef:g,handleInitialize:b}=useInitialize();return u(C,(()=>({initialize:b})),[b]),f((()=>(null===C&&b(),()=>{g.current&&g.current.remove()}))),n(d,{children:[p,g.current&&bootstrap({ForegroundComponent:o,BackgroundComponent:t,TitleComponent:r,SubtitleComponent:a,ContentComponent:l,FooterComponent:s,usePathname:h,options:c,context:m,anchor:g.current})]})})),useBootstrap=({usePathname:e,ForegroundComponent:n,BackgroundComponent:o,TitleComponent:t,SubtitleComponent:r,ContentComponent:a,FooterComponent:s,options:c,context:d,mode:u="auto"}={})=>{const m=i((()=>e||usePathname),[e]),{anchorRef:p,handleInitialize:C}=useInitialize();f((()=>("auto"===u&&C(),()=>{p.current&&p.current.remove()})));const h=l((e=>{"manual"===u&&C(e)}),[u,C]);return{portal:p.current&&bootstrap({usePathname:m,ForegroundComponent:n,BackgroundComponent:o,TitleComponent:t,SubtitleComponent:r,ContentComponent:a,FooterComponent:s,options:c,context:d,anchor:p.current}),initialize:h}},useDestroyAfter=(e,n)=>{const{modal:o,onDestroy:t}=useModal(e),i=useSubscribeModal(o),a=r({modal:o,onDestroy:t,milliseconds:I(n)?m(n):n});useEffect((()=>{const{modal:e,onDestroy:n,milliseconds:o}=a.current;if(!e||e.visible||!e.alive)return;const t=setTimeout((()=>{n()}),o);return()=>{t&&clearTimeout(t)}}),[i])},useModalAnimation=(e,n)=>{const o=r(n);o.current=n,a((()=>{if(!o.current)return;let n;return n=e?requestAnimationFrame((()=>o.current.onVisible?.())):requestAnimationFrame((()=>o.current.onHidden?.())),()=>{n&&cancelAnimationFrame(n)}}),[e])};export{W as ModalProvider,alert,confirm,prompt,useActiveModalCount,useDestroyAfter,useBootstrap as useInitializeModal,useModalAnimation,useConfigurationBackdrop as useModalBackdrop,useConfigurationDuration as useModalDuration,useConfigurationOptions as useModalOptions,useSubscribeModal};
2
- //# sourceMappingURL=index.mjs.map
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { createContext, useContext, useMemo, forwardRef, memo, useRef, useState, useLayoutEffect, useCallback, Fragment, useEffect, useImperativeHandle } from 'react';
3
+ import { convertMsFromDuration } from '@winglet/common-utils/convert';
4
+ import { useReference, useOnMountLayout, useHandle, useVersion, useOnMount } from '@winglet/react-utils/hook';
5
+ import { getRandomString, counterFactory } from '@winglet/common-utils/lib';
6
+ import { css, cx } from '@emotion/css';
7
+ import { createPortal } from 'react-dom';
8
+ import { map } from '@winglet/common-utils/array';
9
+ import { withErrorBoundary } from '@winglet/react-utils/hoc';
10
+ import { isString, isFunction } from '@winglet/common-utils/filter';
11
+ import { renderComponent } from '@winglet/react-utils/render';
12
+ import { printError } from '@winglet/common-utils/console';
13
+
14
+ class ModalManager {
15
+ static #active = false;
16
+ static activate() {
17
+ if (ModalManager.#active)
18
+ return false;
19
+ return (ModalManager.#active = true);
20
+ }
21
+ static #anchor = null;
22
+ static anchor(options) {
23
+ if (ModalManager.#anchor) {
24
+ const anchor = document.getElementById(ModalManager.#anchor.id);
25
+ if (anchor)
26
+ return anchor;
27
+ }
28
+ const { tag = 'div', prefix = 'promise-modal', root = document.body, } = options || {};
29
+ const node = document.createElement(tag);
30
+ node.setAttribute('id', `${prefix}-${getRandomString(36)}`);
31
+ root.appendChild(node);
32
+ ModalManager.#anchor = node;
33
+ return node;
34
+ }
35
+ static #prerenderList = [];
36
+ static get prerender() {
37
+ return ModalManager.#prerenderList;
38
+ }
39
+ static #openHandler = (modal) => ModalManager.#prerenderList.push(modal);
40
+ static set openHandler(handler) {
41
+ ModalManager.#openHandler = handler;
42
+ ModalManager.#prerenderList = [];
43
+ }
44
+ static get unanchored() {
45
+ return !ModalManager.#anchor;
46
+ }
47
+ static reset() {
48
+ ModalManager.#active = false;
49
+ ModalManager.#anchor = null;
50
+ ModalManager.#prerenderList = [];
51
+ ModalManager.#openHandler = (modal) => ModalManager.#prerenderList.push(modal);
52
+ }
53
+ static open(modal) {
54
+ ModalManager.#openHandler(modal);
55
+ }
56
+ }
57
+
58
+ const alert = ({ subtype, title, subtitle, content, background, footer, dimmed, manualDestroy, closeOnBackdropClick, ForegroundComponent, BackgroundComponent, }) => {
59
+ return new Promise((resolve, reject) => {
60
+ try {
61
+ ModalManager.open({
62
+ type: 'alert',
63
+ subtype,
64
+ resolve: () => resolve(),
65
+ title,
66
+ subtitle,
67
+ content,
68
+ background,
69
+ footer,
70
+ dimmed,
71
+ manualDestroy,
72
+ closeOnBackdropClick,
73
+ ForegroundComponent,
74
+ BackgroundComponent,
75
+ });
76
+ }
77
+ catch (error) {
78
+ reject(error);
79
+ }
80
+ });
81
+ };
82
+
83
+ const confirm = ({ subtype, title, subtitle, content, background, footer, dimmed, manualDestroy, closeOnBackdropClick, ForegroundComponent, BackgroundComponent, }) => {
84
+ return new Promise((resolve, reject) => {
85
+ try {
86
+ ModalManager.open({
87
+ type: 'confirm',
88
+ subtype,
89
+ resolve: (result) => resolve(result ?? false),
90
+ title,
91
+ subtitle,
92
+ content,
93
+ background,
94
+ footer,
95
+ dimmed,
96
+ manualDestroy,
97
+ closeOnBackdropClick,
98
+ ForegroundComponent,
99
+ BackgroundComponent,
100
+ });
101
+ }
102
+ catch (error) {
103
+ reject(error);
104
+ }
105
+ });
106
+ };
107
+
108
+ const prompt = ({ defaultValue, title, subtitle, content, Input, disabled, returnOnCancel, background, footer, dimmed, manualDestroy, closeOnBackdropClick, ForegroundComponent, BackgroundComponent, }) => {
109
+ return new Promise((resolve, reject) => {
110
+ try {
111
+ ModalManager.open({
112
+ type: 'prompt',
113
+ resolve: (result) => resolve(result),
114
+ title,
115
+ subtitle,
116
+ content,
117
+ Input,
118
+ defaultValue,
119
+ disabled,
120
+ returnOnCancel,
121
+ background,
122
+ footer,
123
+ dimmed,
124
+ manualDestroy,
125
+ closeOnBackdropClick,
126
+ ForegroundComponent,
127
+ BackgroundComponent,
128
+ });
129
+ }
130
+ catch (error) {
131
+ reject(error);
132
+ }
133
+ });
134
+ };
135
+
136
+ class AbstractNode {
137
+ id;
138
+ initiator;
139
+ title;
140
+ subtitle;
141
+ background;
142
+ manualDestroy;
143
+ closeOnBackdropClick;
144
+ dimmed;
145
+ ForegroundComponent;
146
+ BackgroundComponent;
147
+ #alive;
148
+ get alive() {
149
+ return this.#alive;
150
+ }
151
+ #visible;
152
+ get visible() {
153
+ return this.#visible;
154
+ }
155
+ #resolve;
156
+ #listeners = new Set();
157
+ constructor({ id, initiator, title, subtitle, background, dimmed = true, manualDestroy = false, closeOnBackdropClick = true, resolve, ForegroundComponent, BackgroundComponent, }) {
158
+ this.id = id;
159
+ this.initiator = initiator;
160
+ this.title = title;
161
+ this.subtitle = subtitle;
162
+ this.background = background;
163
+ this.dimmed = dimmed;
164
+ this.manualDestroy = manualDestroy;
165
+ this.closeOnBackdropClick = closeOnBackdropClick;
166
+ this.ForegroundComponent = ForegroundComponent;
167
+ this.BackgroundComponent = BackgroundComponent;
168
+ this.#alive = true;
169
+ this.#visible = true;
170
+ this.#resolve = resolve;
171
+ }
172
+ subscribe(listener) {
173
+ this.#listeners.add(listener);
174
+ return () => {
175
+ this.#listeners.delete(listener);
176
+ };
177
+ }
178
+ publish() {
179
+ for (const listener of this.#listeners)
180
+ listener();
181
+ }
182
+ resolve(result) {
183
+ this.#resolve(result);
184
+ }
185
+ onDestroy() {
186
+ const needPublish = this.#alive === true;
187
+ this.#alive = false;
188
+ if (this.manualDestroy && needPublish)
189
+ this.publish();
190
+ }
191
+ onShow() {
192
+ const needPublish = this.#visible === false;
193
+ this.#visible = true;
194
+ if (needPublish)
195
+ this.publish();
196
+ }
197
+ onHide() {
198
+ const needPublish = this.#visible === true;
199
+ this.#visible = false;
200
+ if (needPublish)
201
+ this.publish();
202
+ }
203
+ }
204
+
205
+ class AlertNode extends AbstractNode {
206
+ type;
207
+ subtype;
208
+ content;
209
+ footer;
210
+ constructor({ id, initiator, type, subtype, title, subtitle, content, footer, background, dimmed, manualDestroy, closeOnBackdropClick, resolve, ForegroundComponent, BackgroundComponent, }) {
211
+ super({
212
+ id,
213
+ initiator,
214
+ title,
215
+ subtitle,
216
+ background,
217
+ dimmed,
218
+ manualDestroy,
219
+ closeOnBackdropClick,
220
+ resolve,
221
+ ForegroundComponent,
222
+ BackgroundComponent,
223
+ });
224
+ this.type = type;
225
+ this.subtype = subtype;
226
+ this.content = content;
227
+ this.footer = footer;
228
+ }
229
+ onClose() {
230
+ this.resolve(null);
231
+ }
232
+ onConfirm() {
233
+ this.resolve(null);
234
+ }
235
+ }
236
+
237
+ class ConfirmNode extends AbstractNode {
238
+ type;
239
+ subtype;
240
+ content;
241
+ footer;
242
+ constructor({ id, initiator, type, subtype, title, subtitle, content, footer, background, dimmed, manualDestroy, closeOnBackdropClick, resolve, ForegroundComponent, BackgroundComponent, }) {
243
+ super({
244
+ id,
245
+ initiator,
246
+ title,
247
+ subtitle,
248
+ background,
249
+ dimmed,
250
+ manualDestroy,
251
+ closeOnBackdropClick,
252
+ resolve,
253
+ ForegroundComponent,
254
+ BackgroundComponent,
255
+ });
256
+ this.type = type;
257
+ this.subtype = subtype;
258
+ this.content = content;
259
+ this.footer = footer;
260
+ }
261
+ onClose() {
262
+ this.resolve(false);
263
+ }
264
+ onConfirm() {
265
+ this.resolve(true);
266
+ }
267
+ }
268
+
269
+ class PromptNode extends AbstractNode {
270
+ type;
271
+ content;
272
+ defaultValue;
273
+ Input;
274
+ disabled;
275
+ returnOnCancel;
276
+ footer;
277
+ #value;
278
+ constructor({ id, initiator, type, title, subtitle, content, defaultValue, Input, disabled, returnOnCancel, footer, background, dimmed, manualDestroy, closeOnBackdropClick, resolve, ForegroundComponent, BackgroundComponent, }) {
279
+ super({
280
+ id,
281
+ initiator,
282
+ title,
283
+ subtitle,
284
+ background,
285
+ dimmed,
286
+ manualDestroy,
287
+ closeOnBackdropClick,
288
+ resolve,
289
+ ForegroundComponent,
290
+ BackgroundComponent,
291
+ });
292
+ this.type = type;
293
+ this.content = content;
294
+ this.Input = Input;
295
+ this.defaultValue = defaultValue;
296
+ this.#value = defaultValue;
297
+ this.disabled = disabled;
298
+ this.returnOnCancel = returnOnCancel;
299
+ this.footer = footer;
300
+ }
301
+ onChange(value) {
302
+ this.#value = value;
303
+ }
304
+ onConfirm() {
305
+ this.resolve(this.#value ?? null);
306
+ }
307
+ onClose() {
308
+ if (this.returnOnCancel)
309
+ this.resolve(this.#value ?? null);
310
+ else
311
+ this.resolve(null);
312
+ }
313
+ }
314
+
315
+ const nodeFactory = (modal) => {
316
+ switch (modal.type) {
317
+ case 'alert':
318
+ return new AlertNode(modal);
319
+ case 'confirm':
320
+ return new ConfirmNode(modal);
321
+ case 'prompt':
322
+ return new PromptNode(modal);
323
+ }
324
+ throw new Error(`Unknown modal: ${modal.type}`, { modal });
325
+ };
326
+
327
+ const DEFAULT_ANIMATION_DURATION = '300ms';
328
+ const DEFAULT_BACKDROP_COLOR = 'rgba(0, 0, 0, 0.5)';
329
+
330
+ const fallback = css `
331
+ margin: unset;
332
+ `;
333
+ const frame = css `
334
+ display: flex;
335
+ flex-direction: column;
336
+ justify-content: center;
337
+ align-items: center;
338
+ background-color: white;
339
+ padding: 20px 80px;
340
+ gap: 10px;
341
+ border: 1px solid black;
342
+ `;
343
+
344
+ const FallbackTitle = ({ children }) => {
345
+ return jsx("h2", { className: fallback, children: children });
346
+ };
347
+
348
+ const FallbackSubtitle = ({ children }) => {
349
+ return jsx("h3", { className: fallback, children: children });
350
+ };
351
+
352
+ const FallbackContent = ({ children }) => {
353
+ return jsx("div", { className: fallback, children: children });
354
+ };
355
+
356
+ const FallbackFooter = ({ confirmLabel, hideConfirm = false, cancelLabel, hideCancel = false, disabled, onConfirm, onCancel, }) => {
357
+ return (jsxs("div", { children: [!hideConfirm && (jsx("button", { onClick: onConfirm, disabled: disabled, children: confirmLabel || 'Confirm' })), !hideCancel && typeof onCancel === 'function' && (jsx("button", { onClick: onCancel, children: cancelLabel || 'Cancel' }))] }));
358
+ };
359
+
360
+ const ModalManagerContext = createContext({});
361
+
362
+ const useModalManagerContext = () => useContext(ModalManagerContext);
363
+ const useModal = (id) => {
364
+ const { getModal } = useModalManagerContext();
365
+ return useMemo(() => getModal(id), [id, getModal]);
366
+ };
367
+
368
+ const defaultValidate = (modal) => modal?.visible;
369
+ const useActiveModalCount = (validate = defaultValidate, refreshKey = 0) => {
370
+ const { modalIds, getModalNode } = useModalManagerContext();
371
+ return useMemo(() => {
372
+ let count = 0;
373
+ for (const id of modalIds) {
374
+ if (validate(getModalNode(id)))
375
+ count++;
376
+ }
377
+ return count;
378
+ }, [getModalNode, modalIds, refreshKey]);
379
+ };
380
+
381
+ const MAX_MODAL_COUNT = 5;
382
+ const MAX_MODAL_LEVEL = 3;
383
+ const FallbackForegroundFrame = forwardRef(({ id, onChangeOrder, children }, ref) => {
384
+ const activeCount = useActiveModalCount();
385
+ const [level, offset] = useMemo(() => {
386
+ const stacked = activeCount > 1;
387
+ const level = stacked
388
+ ? (Math.floor(id / MAX_MODAL_COUNT) % MAX_MODAL_LEVEL) * 100
389
+ : 0;
390
+ const offset = stacked ? (id % MAX_MODAL_COUNT) * 35 : 0;
391
+ return [level, offset];
392
+ }, [activeCount, id]);
393
+ return (jsx("div", { ref: ref, className: frame, onClick: onChangeOrder, style: {
394
+ marginBottom: `calc(25vh + ${level}px)`,
395
+ marginLeft: `${level}px`,
396
+ transform: `translate(${offset}px, ${offset}px)`,
397
+ }, children: children }));
398
+ });
399
+
400
+ const ConfigurationContext = createContext({});
401
+
402
+ const ConfigurationContextProvider = memo(({ ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, options, children, }) => {
403
+ const value = useMemo(() => ({
404
+ BackgroundComponent,
405
+ ForegroundComponent: ForegroundComponent || FallbackForegroundFrame,
406
+ TitleComponent: TitleComponent || FallbackTitle,
407
+ SubtitleComponent: SubtitleComponent || FallbackSubtitle,
408
+ ContentComponent: memo(ContentComponent || FallbackContent),
409
+ FooterComponent: memo(FooterComponent || FallbackFooter),
410
+ options: {
411
+ duration: DEFAULT_ANIMATION_DURATION,
412
+ backdrop: DEFAULT_BACKDROP_COLOR,
413
+ closeOnBackdropClick: true,
414
+ manualDestroy: false,
415
+ ...options,
416
+ },
417
+ }), [
418
+ ForegroundComponent,
419
+ BackgroundComponent,
420
+ ContentComponent,
421
+ FooterComponent,
422
+ SubtitleComponent,
423
+ TitleComponent,
424
+ options,
425
+ ]);
426
+ return (jsx(ConfigurationContext.Provider, { value: value, children: children }));
427
+ });
428
+
429
+ const useConfigurationContext = () => useContext(ConfigurationContext);
430
+ const useConfigurationOptions = () => {
431
+ const context = useContext(ConfigurationContext);
432
+ return context.options;
433
+ };
434
+ const useConfigurationDuration = () => {
435
+ const context = useConfigurationOptions();
436
+ return {
437
+ duration: context.duration,
438
+ milliseconds: convertMsFromDuration(context.duration),
439
+ };
440
+ };
441
+ const useConfigurationBackdrop = () => {
442
+ const context = useConfigurationOptions();
443
+ return context.backdrop;
444
+ };
445
+
446
+ const ModalManagerContextProvider = memo(({ usePathname, children, }) => {
447
+ const modalDictionary = useRef(new Map());
448
+ const [modalIds, setModalIds] = useState([]);
449
+ const modalIdsRef = useReference(modalIds);
450
+ const { pathname } = usePathname();
451
+ const initiator = useRef(pathname);
452
+ const modalIdSequence = useRef(0);
453
+ const options = useConfigurationOptions();
454
+ const duration = useMemo(() => convertMsFromDuration(options.duration), [options]);
455
+ useOnMountLayout(() => {
456
+ const { manualDestroy, closeOnBackdropClick } = options;
457
+ for (const data of ModalManager.prerender) {
458
+ const modal = nodeFactory({
459
+ ...data,
460
+ id: modalIdSequence.current++,
461
+ initiator: initiator.current,
462
+ manualDestroy: data.manualDestroy !== undefined
463
+ ? data.manualDestroy
464
+ : manualDestroy,
465
+ closeOnBackdropClick: data.closeOnBackdropClick !== undefined
466
+ ? data.closeOnBackdropClick
467
+ : closeOnBackdropClick,
468
+ });
469
+ modalDictionary.current.set(modal.id, modal);
470
+ setModalIds((ids) => [...ids, modal.id]);
471
+ }
472
+ ModalManager.openHandler = (data) => {
473
+ const modal = nodeFactory({
474
+ ...data,
475
+ id: modalIdSequence.current++,
476
+ initiator: initiator.current,
477
+ manualDestroy: data.manualDestroy !== undefined
478
+ ? data.manualDestroy
479
+ : manualDestroy,
480
+ closeOnBackdropClick: data.closeOnBackdropClick !== undefined
481
+ ? data.closeOnBackdropClick
482
+ : closeOnBackdropClick,
483
+ });
484
+ modalDictionary.current.set(modal.id, modal);
485
+ setModalIds((ids) => {
486
+ const aliveIds = [];
487
+ for (let index = 0; index < ids.length; index++) {
488
+ const id = ids[index];
489
+ const destroyed = !modalDictionary.current.get(id)?.alive;
490
+ if (destroyed)
491
+ modalDictionary.current.delete(id);
492
+ else
493
+ aliveIds.push(id);
494
+ }
495
+ return [...aliveIds, modal.id];
496
+ });
497
+ };
498
+ return () => {
499
+ ModalManager.reset();
500
+ };
501
+ });
502
+ useLayoutEffect(() => {
503
+ for (const id of modalIdsRef.current) {
504
+ const modal = modalDictionary.current.get(id);
505
+ if (!modal?.alive)
506
+ continue;
507
+ if (modal.initiator === pathname)
508
+ modal.onShow();
509
+ else
510
+ modal.onHide();
511
+ }
512
+ initiator.current = pathname;
513
+ }, [pathname]);
514
+ const getModalNode = useCallback((modalId) => {
515
+ return modalDictionary.current.get(modalId);
516
+ }, []);
517
+ const onDestroy = useCallback((modalId) => {
518
+ const modal = modalDictionary.current.get(modalId);
519
+ if (!modal)
520
+ return;
521
+ modal.onDestroy();
522
+ updaterRef.current?.();
523
+ }, []);
524
+ const updaterRef = useRef(undefined);
525
+ const hideModal = useCallback((modalId) => {
526
+ const modal = modalDictionary.current.get(modalId);
527
+ if (!modal)
528
+ return;
529
+ modal.onHide();
530
+ updaterRef.current?.();
531
+ if (!modal.manualDestroy)
532
+ setTimeout(() => {
533
+ modal.onDestroy();
534
+ }, duration);
535
+ }, [duration]);
536
+ const onChange = useCallback((modalId, value) => {
537
+ const modal = modalDictionary.current.get(modalId);
538
+ if (!modal)
539
+ return;
540
+ if (modal.type === 'prompt')
541
+ modal.onChange(value);
542
+ }, []);
543
+ const onConfirm = useCallback((modalId) => {
544
+ const modal = modalDictionary.current.get(modalId);
545
+ if (!modal)
546
+ return;
547
+ modal.onConfirm();
548
+ hideModal(modalId);
549
+ }, [hideModal]);
550
+ const onClose = useCallback((modalId) => {
551
+ const modal = modalDictionary.current.get(modalId);
552
+ if (!modal)
553
+ return;
554
+ modal.onClose();
555
+ hideModal(modalId);
556
+ }, [hideModal]);
557
+ const getModal = useCallback((modalId) => ({
558
+ modal: getModalNode(modalId),
559
+ onConfirm: () => onConfirm(modalId),
560
+ onClose: () => onClose(modalId),
561
+ onChange: (value) => onChange(modalId, value),
562
+ onDestroy: () => onDestroy(modalId),
563
+ }), [getModalNode, onConfirm, onClose, onChange, onDestroy]);
564
+ const value = useMemo(() => {
565
+ return {
566
+ modalIds,
567
+ getModalNode,
568
+ onChange,
569
+ onConfirm,
570
+ onClose,
571
+ onDestroy,
572
+ getModal,
573
+ setUpdater: (updater) => {
574
+ updaterRef.current = updater;
575
+ },
576
+ };
577
+ }, [
578
+ modalIds,
579
+ getModal,
580
+ getModalNode,
581
+ onChange,
582
+ onConfirm,
583
+ onClose,
584
+ onDestroy,
585
+ ]);
586
+ return (jsx(ModalManagerContext.Provider, { value: value, children: children }));
587
+ });
588
+
589
+ const UserDefinedContext = createContext({});
590
+
591
+ const UserDefinedContextProvider = ({ context, children, }) => {
592
+ const contextValue = useMemo(() => ({ context: context || {} }), [context]);
593
+ return (jsx(UserDefinedContext.Provider, { value: contextValue, children: children }));
594
+ };
595
+
596
+ const useUserDefinedContext = () => {
597
+ return useContext(UserDefinedContext);
598
+ };
599
+
600
+ const usePathname = () => {
601
+ const [pathname, setPathname] = useState(window.location.pathname);
602
+ useLayoutEffect(() => {
603
+ let requestId;
604
+ const checkPathname = () => {
605
+ if (requestId)
606
+ cancelAnimationFrame(requestId);
607
+ if (pathname !== window.location.pathname) {
608
+ setPathname(window.location.pathname);
609
+ }
610
+ else {
611
+ requestId = requestAnimationFrame(checkPathname);
612
+ }
613
+ };
614
+ requestId = requestAnimationFrame(checkPathname);
615
+ return () => {
616
+ if (requestId)
617
+ cancelAnimationFrame(requestId);
618
+ };
619
+ }, [pathname]);
620
+ return { pathname };
621
+ };
622
+
623
+ const background = css `
624
+ display: none;
625
+ position: fixed;
626
+ inset: 0;
627
+ z-index: -999;
628
+ pointer-events: none;
629
+ > * {
630
+ pointer-events: none;
631
+ }
632
+ `;
633
+ const active$1 = css `
634
+ pointer-events: all;
635
+ `;
636
+ const visible$1 = css `
637
+ display: flex;
638
+ align-items: center;
639
+ justify-content: center;
640
+ `;
641
+
642
+ const BackgroundFrame = ({ modalId, onChangeOrder, }) => {
643
+ const { BackgroundComponent } = useConfigurationContext();
644
+ const { context: userDefinedContext } = useUserDefinedContext();
645
+ const { modal, onClose, onChange, onConfirm, onDestroy } = useModal(modalId);
646
+ const handleClose = useCallback((event) => {
647
+ if (modal && modal.closeOnBackdropClick && modal.visible)
648
+ onClose();
649
+ event.stopPropagation();
650
+ }, [modal, onClose]);
651
+ const Background = useMemo(() => modal?.BackgroundComponent || BackgroundComponent, [BackgroundComponent, modal]);
652
+ if (!modal)
653
+ return null;
654
+ return (jsx("div", { className: cx(background, {
655
+ [visible$1]: modal.manualDestroy ? modal.alive : modal.visible,
656
+ [active$1]: modal.closeOnBackdropClick && modal.visible,
657
+ }), onClick: handleClose, children: Background && (jsx(Background, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext })) }));
658
+ };
659
+
660
+ const foreground = css `
661
+ pointer-events: none;
662
+ display: none;
663
+ position: fixed;
664
+ inset: 0;
665
+ z-index: 1;
666
+ `;
667
+ const active = css `
668
+ > * {
669
+ pointer-events: all;
670
+ }
671
+ `;
672
+ const visible = css `
673
+ display: flex !important;
674
+ justify-content: center;
675
+ align-items: center;
676
+ `;
677
+
678
+ const AlertInner = memo(({ modal, handlers }) => {
679
+ const { title, subtitle, content, footer } = useMemo(() => modal, [modal]);
680
+ const { context: userDefinedContext } = useUserDefinedContext();
681
+ const { onConfirm } = useMemo(() => handlers, [handlers]);
682
+ const handleConfirm = useHandle(onConfirm);
683
+ const { TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, } = useConfigurationContext();
684
+ return (jsxs(Fragment, { children: [title &&
685
+ (isString(title) ? (jsx(TitleComponent, { context: userDefinedContext, children: title })) : (title)), subtitle &&
686
+ (isString(subtitle) ? (jsx(SubtitleComponent, { context: userDefinedContext, children: subtitle })) : (subtitle)), content &&
687
+ (isString(content) ? (jsx(ContentComponent, { context: userDefinedContext, children: content })) : (renderComponent(content, {
688
+ onConfirm: handleConfirm,
689
+ }))), footer !== false &&
690
+ (typeof footer === 'function' ? (footer({
691
+ onConfirm: handleConfirm,
692
+ context: userDefinedContext,
693
+ })) : (jsx(FooterComponent, { onConfirm: handleConfirm, confirmLabel: footer?.confirm, hideConfirm: footer?.hideConfirm, context: userDefinedContext })))] }));
694
+ });
695
+
696
+ const ConfirmInner = memo(({ modal, handlers }) => {
697
+ const { title, subtitle, content, footer } = useMemo(() => modal, [modal]);
698
+ const { context: userDefinedContext } = useUserDefinedContext();
699
+ const { onConfirm, onClose } = useMemo(() => handlers, [handlers]);
700
+ const handleConfirm = useHandle(onConfirm);
701
+ const handleClose = useHandle(onClose);
702
+ const { TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, } = useConfigurationContext();
703
+ return (jsxs(Fragment, { children: [title &&
704
+ (isString(title) ? (jsx(TitleComponent, { context: userDefinedContext, children: title })) : (title)), subtitle &&
705
+ (isString(subtitle) ? (jsx(SubtitleComponent, { context: userDefinedContext, children: subtitle })) : (subtitle)), content &&
706
+ (isString(content) ? (jsx(ContentComponent, { context: userDefinedContext, children: content })) : (renderComponent(content, {
707
+ onConfirm: handleConfirm,
708
+ onCancel: handleClose,
709
+ context: userDefinedContext,
710
+ }))), footer !== false &&
711
+ (typeof footer === 'function' ? (footer({
712
+ onConfirm: handleConfirm,
713
+ onCancel: handleClose,
714
+ context: userDefinedContext,
715
+ })) : (jsx(FooterComponent, { onConfirm: handleConfirm, onCancel: handleClose, confirmLabel: footer?.confirm, cancelLabel: footer?.cancel, hideConfirm: footer?.hideConfirm, hideCancel: footer?.hideCancel, context: userDefinedContext })))] }));
716
+ });
717
+
718
+ const PromptInner = memo(({ modal, handlers }) => {
719
+ const { Input, defaultValue, disabled: checkDisabled, title, subtitle, content, footer, } = useMemo(() => ({
720
+ ...modal,
721
+ Input: memo(withErrorBoundary(modal.Input)),
722
+ }), [modal]);
723
+ const { context: userDefinedContext } = useUserDefinedContext();
724
+ const [value, setValue] = useState(defaultValue);
725
+ const { onChange, onClose, onConfirm } = useMemo(() => handlers, [handlers]);
726
+ const handleClose = useHandle(onClose);
727
+ const handleChange = useHandle((inputValue) => {
728
+ const input = isFunction(inputValue) ? inputValue(value) : inputValue;
729
+ setValue(input);
730
+ onChange(input);
731
+ });
732
+ const handleConfirm = useCallback(() => {
733
+ requestAnimationFrame(onConfirm);
734
+ }, [onConfirm]);
735
+ const disabled = useMemo(() => (value ? !!checkDisabled?.(value) : false), [checkDisabled, value]);
736
+ const { TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, } = useConfigurationContext();
737
+ return (jsxs(Fragment, { children: [title &&
738
+ (isString(title) ? (jsx(TitleComponent, { context: userDefinedContext, children: title })) : (title)), subtitle &&
739
+ (isString(subtitle) ? (jsx(SubtitleComponent, { context: userDefinedContext, children: subtitle })) : (subtitle)), content &&
740
+ (isString(content) ? (jsx(ContentComponent, { context: userDefinedContext, children: content })) : (renderComponent(content, {
741
+ onConfirm: handleConfirm,
742
+ onCancel: handleClose,
743
+ context: userDefinedContext,
744
+ }))), Input && (jsx(Input, { defaultValue: defaultValue, value: value, onChange: handleChange, onConfirm: handleConfirm, onCancel: handleClose, context: userDefinedContext })), footer !== false &&
745
+ (typeof footer === 'function' ? (footer({
746
+ value,
747
+ disabled,
748
+ onChange: handleChange,
749
+ onConfirm: handleConfirm,
750
+ onCancel: handleClose,
751
+ context: userDefinedContext,
752
+ })) : (jsx(FooterComponent, { disabled: disabled, onConfirm: handleConfirm, onCancel: handleClose, confirmLabel: footer?.confirm, cancelLabel: footer?.cancel, hideConfirm: footer?.hideConfirm, hideCancel: footer?.hideCancel, context: userDefinedContext })))] }));
753
+ });
754
+
755
+ const ForegroundFrame = ({ modalId, onChangeOrder, }) => {
756
+ const { ForegroundComponent } = useConfigurationContext();
757
+ const { context: userDefinedContext } = useUserDefinedContext();
758
+ const { modal, onChange, onConfirm, onClose, onDestroy } = useModal(modalId);
759
+ const Foreground = useMemo(() => modal?.ForegroundComponent || ForegroundComponent, [ForegroundComponent, modal]);
760
+ if (!modal)
761
+ return null;
762
+ return (jsx("div", { className: cx(foreground, {
763
+ [visible]: modal.manualDestroy ? modal.alive : modal.visible,
764
+ [active]: modal.visible,
765
+ }), children: jsxs(Foreground, { id: modal.id, type: modal.type, alive: modal.alive, visible: modal.visible, initiator: modal.initiator, manualDestroy: modal.manualDestroy, closeOnBackdropClick: modal.closeOnBackdropClick, background: modal.background, onChange: onChange, onConfirm: onConfirm, onClose: onClose, onDestroy: onDestroy, onChangeOrder: onChangeOrder, context: userDefinedContext, children: [modal.type === 'alert' && (jsx(AlertInner, { modal: modal, handlers: { onConfirm } })), modal.type === 'confirm' && (jsx(ConfirmInner, { modal: modal, handlers: { onConfirm, onClose } })), modal.type === 'prompt' && (jsx(PromptInner, { modal: modal, handlers: { onChange, onConfirm, onClose } }))] }) }));
766
+ };
767
+
768
+ const useSubscribeModal = (modal) => {
769
+ const [version, update] = useVersion();
770
+ useEffect(() => {
771
+ if (!modal)
772
+ return;
773
+ const unsubscribe = modal.subscribe(update);
774
+ return unsubscribe;
775
+ }, [modal, update]);
776
+ return version;
777
+ };
778
+
779
+ const presenter = css `
780
+ position: fixed;
781
+ inset: 0;
782
+ pointer-events: none;
783
+ overflow: hidden;
784
+ `;
785
+
786
+ const { increment } = counterFactory(1);
787
+ const Presenter = memo(({ modalId }) => {
788
+ const ref = useRef(null);
789
+ const { modal } = useModal(modalId);
790
+ useSubscribeModal(modal);
791
+ const handleChangeOrder = useHandle(() => {
792
+ if (ref.current) {
793
+ ref.current.style.zIndex = `${increment()}`;
794
+ }
795
+ });
796
+ return (jsxs("div", { ref: ref, className: presenter, children: [jsx(BackgroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder }), jsx(ForegroundFrame, { modalId: modalId, onChangeOrder: handleChangeOrder })] }));
797
+ });
798
+
799
+ const anchor = css `
800
+ display: flex;
801
+ align-items: center;
802
+ justify-content: center;
803
+ position: fixed;
804
+ inset: 0;
805
+ pointer-events: none;
806
+ z-index: 1000;
807
+ transition: background-color ease-in-out;
808
+ `;
809
+
810
+ const AnchorInner = () => {
811
+ const [version, update] = useVersion();
812
+ const { modalIds, setUpdater } = useModalManagerContext();
813
+ useEffect(() => {
814
+ setUpdater(update);
815
+ }, [setUpdater, update]);
816
+ const options = useConfigurationOptions();
817
+ const dimmed = useActiveModalCount(validateDimmable, version);
818
+ return (jsx("div", { className: anchor, style: {
819
+ transitionDuration: options.duration,
820
+ backgroundColor: dimmed ? options.backdrop : 'transparent',
821
+ }, children: map(modalIds, (id) => (jsx(Presenter, { modalId: id }, id))) }));
822
+ };
823
+ const validateDimmable = (modal) => modal?.visible && modal.dimmed;
824
+ const Anchor = memo(withErrorBoundary(AnchorInner));
825
+
826
+ const bootstrap = ({ ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, usePathname, options, context, anchor, }) => createPortal(jsx(UserDefinedContextProvider, { context: context, children: jsx(ConfigurationContextProvider, { ForegroundComponent: ForegroundComponent, BackgroundComponent: BackgroundComponent, TitleComponent: TitleComponent, SubtitleComponent: SubtitleComponent, ContentComponent: ContentComponent, FooterComponent: FooterComponent, options: options, children: jsx(ModalManagerContextProvider, { usePathname: usePathname, children: jsx(Anchor, {}) }) }) }), anchor);
827
+
828
+ const useInitialize = () => {
829
+ const permitted = useRef(ModalManager.activate());
830
+ const anchorRef = useRef(null);
831
+ const [, update] = useVersion();
832
+ const handleInitialize = useCallback((root) => {
833
+ if (permitted.current) {
834
+ anchorRef.current = ModalManager.anchor({ root });
835
+ update();
836
+ }
837
+ else
838
+ printError('ModalProvider is already initialized', [
839
+ 'ModalProvider can only be initialized once.',
840
+ 'Nesting ModalProvider will be ignored...',
841
+ ], {
842
+ info: 'Something is wrong with the ModalProvider initialization...',
843
+ });
844
+ }, [update]);
845
+ return {
846
+ anchorRef,
847
+ handleInitialize,
848
+ };
849
+ };
850
+
851
+ const BootstrapProvider = forwardRef(({ usePathname: useExternalPathname, ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, options, context, children, }, handleRef) => {
852
+ const usePathname$1 = useMemo(() => useExternalPathname || usePathname, [useExternalPathname]);
853
+ const { anchorRef, handleInitialize } = useInitialize();
854
+ useImperativeHandle(handleRef, () => ({
855
+ initialize: handleInitialize,
856
+ }), [handleInitialize]);
857
+ useOnMount(() => {
858
+ if (handleRef === null)
859
+ handleInitialize();
860
+ return () => {
861
+ if (anchorRef.current)
862
+ anchorRef.current.remove();
863
+ };
864
+ });
865
+ return (jsxs(Fragment, { children: [children, anchorRef.current &&
866
+ bootstrap({
867
+ ForegroundComponent,
868
+ BackgroundComponent,
869
+ TitleComponent,
870
+ SubtitleComponent,
871
+ ContentComponent,
872
+ FooterComponent,
873
+ usePathname: usePathname$1,
874
+ options,
875
+ context,
876
+ anchor: anchorRef.current,
877
+ })] }));
878
+ });
879
+
880
+ const useBootstrap = ({ usePathname: useExternalPathname, ForegroundComponent, BackgroundComponent, TitleComponent, SubtitleComponent, ContentComponent, FooterComponent, options, context, mode = 'auto', } = {}) => {
881
+ const usePathname$1 = useMemo(() => useExternalPathname || usePathname, [useExternalPathname]);
882
+ const { anchorRef, handleInitialize } = useInitialize();
883
+ useOnMount(() => {
884
+ if (mode === 'auto')
885
+ handleInitialize();
886
+ return () => {
887
+ if (anchorRef.current)
888
+ anchorRef.current.remove();
889
+ };
890
+ });
891
+ const initialize = useCallback((element) => {
892
+ if (mode === 'manual')
893
+ handleInitialize(element);
894
+ }, [mode, handleInitialize]);
895
+ const portal = anchorRef.current &&
896
+ bootstrap({
897
+ usePathname: usePathname$1,
898
+ ForegroundComponent,
899
+ BackgroundComponent,
900
+ TitleComponent,
901
+ SubtitleComponent,
902
+ ContentComponent,
903
+ FooterComponent,
904
+ options,
905
+ context,
906
+ anchor: anchorRef.current,
907
+ });
908
+ return { portal, initialize };
909
+ };
910
+
911
+ const useDestroyAfter = (modalId, duration) => {
912
+ const { modal, onDestroy } = useModal(modalId);
913
+ const tick = useSubscribeModal(modal);
914
+ const reference = useRef({
915
+ modal,
916
+ onDestroy,
917
+ milliseconds: isString(duration)
918
+ ? convertMsFromDuration(duration)
919
+ : duration,
920
+ });
921
+ useEffect(() => {
922
+ const { modal, onDestroy, milliseconds } = reference.current;
923
+ if (!modal || modal.visible || !modal.alive)
924
+ return;
925
+ const timer = setTimeout(() => {
926
+ onDestroy();
927
+ }, milliseconds);
928
+ return () => {
929
+ if (timer)
930
+ clearTimeout(timer);
931
+ };
932
+ }, [tick]);
933
+ };
934
+
935
+ const useModalAnimation = (visible, handler) => {
936
+ const handlerRef = useRef(handler);
937
+ handlerRef.current = handler;
938
+ useLayoutEffect(() => {
939
+ if (!handlerRef.current)
940
+ return;
941
+ let frame;
942
+ if (visible)
943
+ frame = requestAnimationFrame(() => handlerRef.current.onVisible?.());
944
+ else
945
+ frame = requestAnimationFrame(() => handlerRef.current.onHidden?.());
946
+ return () => {
947
+ if (frame)
948
+ cancelAnimationFrame(frame);
949
+ };
950
+ }, [visible]);
951
+ };
952
+
953
+ export { BootstrapProvider as ModalProvider, alert, confirm, prompt, useActiveModalCount, useDestroyAfter, useBootstrap as useInitializeModal, useModalAnimation, useConfigurationBackdrop as useModalBackdrop, useConfigurationDuration as useModalDuration, useConfigurationOptions as useModalOptions, useSubscribeModal };