react-modal-port 0.1.5 → 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.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=require("react/jsx-runtime"),t=require("react");function n(){return n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},n.apply(this,arguments)}var r=t.createContext({stack:[],launchModal:function(){},updateStack:function(){},updateState:function(){}});function o(){return t.useContext(r)}exports.ModalContextProvider=function(o){var a=o.children,c=t.useState([]),u=c[0],l=c[1],s={stack:u,launchModal:function(e,t,n){var r=Object.keys(t).reduce(function(e,n){var r=t[n];return e[n]=function(){try{return Promise.resolve(r.apply(void 0,[].slice.call(arguments))).then(function(e){return l(function(e){return e.slice(0,-1)}),e})}catch(e){return Promise.reject(e)}},e},{});l([].concat(u,[{render:e,resolvers:r,onBackdropClickUse:n,state:{}}]))},updateStack:l,updateState:function(e){var t=[].concat(u);t[u.length-1].state=n({},e),l(t)}};return e.jsx(r.Provider,{value:s,children:a})},exports.ModalPort=function(n){var r=n.onModalLaunch,a=n.onModalClose,c=n.render,u=o().stack,l=t.useMemo(function(){return u.length>0?u[u.length-1]:null},[u]),s=t.useCallback(function(e){e.currentTarget===e.target&&(null==l?void 0:l.onBackdropClickUse)&&l.resolvers[l.onBackdropClickUse](e)},[l]);return t.useEffect(function(){l?r&&r():a&&a()},[l,r,a]),l&&e.jsx(c,{onBackdropClick:s,children:l.render(l.resolvers)})||null},exports.useModal=function(){return o().launchModal},exports.useModalContext=o,exports.useModalState=function(){var e=o(),t=e.stack,n=e.updateState;if(0===t.length)throw new Error("Trying to access modal state while no modal is open");return[t[t.length-1].state,n]};
1
+ var e=require("react/jsx-runtime"),t=require("react");function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},r.apply(this,arguments)}var n=t.createContext({stack:[],launchModal:function(){},updateStack:function(){},updateState:function(){}});function o(){return t.useContext(n)}exports.ModalContextProvider=function(o){var a=o.children,c=t.useState([]),u=c[0],s=c[1],l={stack:u,launchModal:function(e,t,r){void 0===r&&(r={});var n=Object.keys(t).reduce(function(e,r){var n=t[r];return e[r]=function(){try{return Promise.resolve(n.apply(void 0,[].slice.call(arguments))).then(function(e){return s(function(e){return e.slice(0,-1)}),e})}catch(e){return Promise.reject(e)}},e},{});s([].concat(u,[{render:e,resolvers:n,props:r,state:{}}]))},updateStack:s,updateState:function(e){var t=[].concat(u);t[u.length-1].state=r({},e),s(t)}};return e.jsx(n.Provider,{value:l,children:a})},exports.ModalPort=function(n){var a=n.onModalLaunch,c=n.onModalClose,u=n.render,s=o().stack,l=t.useMemo(function(){return s.length>0?s[s.length-1]:null},[s]),i=t.useCallback(function(e){e.currentTarget===e.target&&(null==l?void 0:l.resolvers.onBackdropClickUse)&&l.resolvers.onBackdropClickUse(e)},[l]);return t.useEffect(function(){l?a&&a():c&&c()},[l,a,c]),l&&e.jsx(u,{onBackdropClick:i,children:l.render(r({},l.resolvers,l.props))})||null},exports.useModal=function(){return o().launchModal},exports.useModalContext=o,exports.useModalState=function(){var e=o(),t=e.stack,r=e.updateState;if(0===t.length)throw new Error("Trying to access modal state while no modal is open");return[t[t.length-1].state,r]};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/context.tsx","../src/modal-port.tsx"],"sourcesContent":["import { \n createContext, \n useContext, \n useState, \n type SyntheticEvent \n} from 'react';\nimport { \n type ModalStackItem,\n type ModalContextProperties,\n type LaunchModal,\n type LaunchModalResolvers,\n type ModalState,\n type UpdateModalState,\n} from '../types';\n\nexport const ModalContext = createContext<ModalContextProperties>({\n stack: [],\n launchModal: () => {},\n updateStack: () => {},\n updateState: () => {},\n});\n\nexport const ModalContextProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {\n\n const [ stack, updateStack ] = useState<ModalStackItem[]>([]);\n\n const launchModal: LaunchModal = (render, resolvers, onBackdropClickUse) => {\n // Wrap resolvers to update the stack\n const wrappedResovers = Object.keys(resolvers).reduce((acc, key) => {\n const resolver = resolvers[key];\n acc[key] = async (...args: any[]) => {\n const result = await resolver(...args);\n // update stack with an array conating all the items in the stack except the last one\n updateStack(currStack => currStack.slice(0, -1));\n return result;\n };\n return acc;\n }, {} as LaunchModalResolvers);\n updateStack([\n ...stack,\n {\n render,\n resolvers: wrappedResovers,\n onBackdropClickUse,\n state: {},\n },\n ]);\n };\n\n const updateState = (newState: ModalState) => {\n const updatedStack = [\n ...stack,\n ];\n updatedStack[stack.length - 1].state = { ...newState };\n updateStack(updatedStack);\n };\n\n const contextProperties: ModalContextProperties = {\n stack,\n launchModal,\n updateStack,\n updateState,\n };\n\n return <ModalContext.Provider value={contextProperties}>{children}</ModalContext.Provider>;\n\n};\n\n/**\n * Get properties from the modal context\n * @returns {ModalContextProperties} Object with the modal context properties\n */\nexport function useModalContext(): ModalContextProperties {\n return useContext(ModalContext);\n}\n\n/**\n * Short-hand for `useModalContext().launchModal`\n * @returns {LaunchModal} The launchModal function\n */\nexport function useModal(): LaunchModal {\n const { launchModal } = useModalContext();\n return launchModal;\n}\n\n/**\n * Get access to the current modal state and a function to update it\n * @returns {[ ModalState, UpdateModalState ]} A tuple with the current modal state and a function to update it\n */\nexport function useModalState(): [ ModalState, UpdateModalState ] {\n const { stack, updateState } = useModalContext();\n if (stack.length === 0) \n throw new Error('Trying to access modal state while no modal is open');\n const state = stack[stack.length - 1].state;\n return [ state, updateState ];\n}\n","import { \n type ModalPortProps, \n type ModalStackItem \n} from \"../types\";\nimport { useModalContext } from \"./context\";\nimport { \n type SyntheticEvent, \n useCallback, \n useEffect, \n useMemo\n} from \"react\";\n\nconst ModalPort: React.FC<ModalPortProps> = ({\n onModalLaunch,\n onModalClose,\n render: Backdrop\n}) => {\n\n const { stack } = useModalContext();\n const currentModal: ModalStackItem | null = useMemo(\n () => stack.length > 0 ? stack[stack.length - 1] : null,\n [ stack ]\n );\n const onBackdropClick = useCallback((ev: SyntheticEvent) => {\n if (ev.currentTarget !== ev.target) return;\n currentModal?.onBackdropClickUse &&\n currentModal.resolvers[currentModal.onBackdropClickUse](ev);\n }, [ currentModal ]);\n\n useEffect(() => {\n if (currentModal) {\n onModalLaunch && onModalLaunch();\n } else {\n onModalClose && onModalClose();\n }\n }, [ currentModal, onModalLaunch, onModalClose ]);\n\n return currentModal && (\n <Backdrop onBackdropClick={onBackdropClick}>\n {currentModal.render(currentModal.resolvers)}\n </Backdrop>\n ) || null;\n};\n\nexport default ModalPort;\n"],"names":["ModalContext","createContext","stack","launchModal","updateStack","updateState","useModalContext","useContext","_ref","children","_useState","useState","contextProperties","render","resolvers","onBackdropClickUse","wrappedResovers","Object","keys","reduce","acc","key","resolver","Promise","resolve","apply","slice","call","arguments","then","result","currStack","e","reject","concat","state","newState","updatedStack","length","_extends","_jsx","Provider","value","onModalLaunch","onModalClose","Backdrop","currentModal","useMemo","onBackdropClick","useCallback","ev","currentTarget","target","useEffect","_useModalContext2","Error"],"mappings":"8RAeaA,EAAeC,EAAaA,cAAyB,CAChEC,MAAO,GACPC,YAAa,WAAQ,EACrBC,YAAa,WAAK,EAClBC,YAAa,wBAqDCC,IACd,OAAOC,EAAUA,WAACP,EACpB,8BApDoC,SAAHQ,GAA6D,IAAvDC,EAAQD,EAARC,SAErCC,EAA+BC,EAAQA,SAAmB,IAAlDT,EAAKQ,EAAA,GAAEN,EAAWM,EAAA,GAiCpBE,EAA4C,CAChDV,MAAAA,EACAC,YAjC+B,SAACU,EAAQC,EAAWC,GAEnD,IAAMC,EAAkBC,OAAOC,KAAKJ,GAAWK,OAAO,SAACC,EAAKC,GAC1D,IAAMC,EAAWR,EAAUO,GAO3B,OANAD,EAAIC,GAAI,WAAA,WAA4BE,QAAAC,QACbF,EAAQG,WAAA,EAAA,GAAAC,MAAAC,KADKC,aACIC,KAAA,SAAhCC,GAGN,OADA1B,EAAY,SAAA2B,GAAS,OAAIA,EAAUL,MAAM,GAAI,EAAE,GACxCI,CAAO,EAChB,CAAC,MAAAE,UAAAT,QAAAU,OAAAD,EAAA,CAAA,EACMZ,CACT,EAAG,CAAA,GACHhB,EAAW,GAAA8B,OACNhC,EACH,CAAA,CACEW,OAAAA,EACAC,UAAWE,EACXD,mBAAAA,EACAoB,MAAO,MAGb,EAaE/B,YAAAA,EACAC,YAZkB,SAAC+B,GACnB,IAAMC,EAAY,GAAAH,OACbhC,GAELmC,EAAanC,EAAMoC,OAAS,GAAGH,MAAKI,EAAQH,CAAAA,EAAAA,GAC5ChC,EAAYiC,EACd,GASA,OAAOG,EAAAA,IAACxC,EAAayC,SAAQ,CAACC,MAAO9B,EAAiBH,SAAGA,GAE3D,oBCtD4C,SAA7BD,GAIV,IAHHmC,EAAanC,EAAbmC,cACAC,EAAYpC,EAAZoC,aACQC,EAAQrC,EAAhBK,OAGQX,EAAUI,IAAVJ,MACF4C,EAAsCC,EAAOA,QACjD,WAAA,OAAM7C,EAAMoC,OAAS,EAAIpC,EAAMA,EAAMoC,OAAS,GAAK,IAAI,EACvD,CAAEpC,IAEE8C,EAAkBC,EAAWA,YAAC,SAACC,GAC/BA,EAAGC,gBAAkBD,EAAGE,SAChB,MAAZN,OAAY,EAAZA,EAAc/B,qBACd+B,EAAahC,UAAUgC,EAAa/B,oBAAoBmC,EAC1D,EAAG,CAAEJ,IAUL,OARAO,EAAAA,UAAU,WACJP,EACFH,GAAiBA,IAEjBC,GAAgBA,GAEpB,EAAG,CAAEE,EAAcH,EAAeC,IAE3BE,GACLN,EAAAA,IAACK,EAAS,CAAAG,gBAAiBA,EACxBvC,SAAAqC,EAAajC,OAAOiC,EAAahC,cAEjC,IACP,8BDwCE,OADwBR,IAAhBH,WAEV,kDAMgB,WACd,IAAAmD,EAA+BhD,IAAvBJ,EAAKoD,EAALpD,MAAOG,EAAWiD,EAAXjD,YACf,GAAqB,IAAjBH,EAAMoC,OACR,MAAU,IAAAiB,MAAM,uDAElB,MAAO,CADOrD,EAAMA,EAAMoC,OAAS,GAAGH,MACtB9B,EAClB"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/context.tsx","../src/modal-port.tsx"],"sourcesContent":["import { \n createContext, \n useContext, \n useState, \n type SyntheticEvent \n} from 'react';\nimport { \n type ModalStackItem,\n type ModalContextProperties,\n type LaunchModal,\n type LaunchModalResolvers,\n type ModalState,\n type UpdateModalState,\n} from '../types';\n\nexport const ModalContext = createContext<ModalContextProperties>({\n stack: [],\n launchModal: () => {},\n updateStack: () => {},\n updateState: () => {},\n});\n\nexport const ModalContextProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {\n\n const [ stack, updateStack ] = useState<ModalStackItem[]>([]);\n\n const launchModal: LaunchModal = (render, resolvers, props = {}) => {\n // Wrap resolvers to update the stack\n const wrappedResovers = Object.keys(resolvers).reduce((acc, key) => {\n const resolver = resolvers[key];\n acc[key] = async (...args: any[]) => {\n const result = await resolver(...args);\n // update stack with an array conating all the items in the stack except the last one\n updateStack(currStack => currStack.slice(0, -1));\n return result;\n };\n return acc;\n }, {} as LaunchModalResolvers);\n updateStack([\n ...stack,\n {\n render,\n resolvers: wrappedResovers,\n props,\n state: {},\n },\n ]);\n };\n\n const updateState = (newState: ModalState) => {\n const updatedStack = [\n ...stack,\n ];\n updatedStack[stack.length - 1].state = { ...newState };\n updateStack(updatedStack);\n };\n\n const contextProperties: ModalContextProperties = {\n stack,\n launchModal,\n updateStack,\n updateState,\n };\n\n return <ModalContext.Provider value={contextProperties}>{children}</ModalContext.Provider>;\n\n};\n\n/**\n * Get properties from the modal context\n * @returns {ModalContextProperties} Object with the modal context properties\n */\nexport function useModalContext(): ModalContextProperties {\n return useContext(ModalContext);\n}\n\n/**\n * Short-hand for `useModalContext().launchModal`\n * @returns {LaunchModal} The launchModal function\n */\nexport function useModal(): LaunchModal {\n const { launchModal } = useModalContext();\n return launchModal;\n}\n\n/**\n * Get access to the current modal state and a function to update it\n * @returns {[ ModalState, UpdateModalState ]} A tuple with the current modal state and a function to update it\n */\nexport function useModalState(): [ ModalState, UpdateModalState ] {\n const { stack, updateState } = useModalContext();\n if (stack.length === 0) \n throw new Error('Trying to access modal state while no modal is open');\n const state = stack[stack.length - 1].state;\n return [ state, updateState ];\n}\n","import { \n type ModalPortProps, \n type ModalStackItem \n} from \"../types\";\nimport { useModalContext } from \"./context\";\nimport { \n type SyntheticEvent, \n useCallback, \n useEffect, \n useMemo\n} from \"react\";\n\nconst ModalPort: React.FC<ModalPortProps> = ({\n onModalLaunch,\n onModalClose,\n render: Backdrop\n}) => {\n\n const { stack } = useModalContext();\n const currentModal: ModalStackItem | null = useMemo(\n () => stack.length > 0 ? stack[stack.length - 1] : null,\n [ stack ]\n );\n const onBackdropClick = useCallback((ev: SyntheticEvent) => {\n if (ev.currentTarget !== ev.target) return;\n currentModal?.resolvers.onBackdropClickUse &&\n currentModal.resolvers.onBackdropClickUse(ev);\n }, [ currentModal ]);\n\n useEffect(() => {\n if (currentModal) {\n onModalLaunch && onModalLaunch();\n } else {\n onModalClose && onModalClose();\n }\n }, [ currentModal, onModalLaunch, onModalClose ]);\n\n return currentModal && (\n <Backdrop onBackdropClick={onBackdropClick}>\n {currentModal.render({\n ...currentModal.resolvers,\n ...currentModal.props,\n })}\n </Backdrop>\n ) || null;\n};\n\nexport default ModalPort;\n"],"names":["ModalContext","createContext","stack","launchModal","updateStack","updateState","useModalContext","useContext","_ref","children","_useState","useState","contextProperties","render","resolvers","props","wrappedResovers","Object","keys","reduce","acc","key","resolver","Promise","resolve","apply","slice","call","arguments","then","result","currStack","e","reject","concat","state","newState","updatedStack","length","_extends","_jsx","Provider","value","onModalLaunch","onModalClose","Backdrop","currentModal","useMemo","onBackdropClick","useCallback","ev","currentTarget","target","onBackdropClickUse","useEffect","_useModalContext2","Error"],"mappings":"8RAeaA,EAAeC,EAAaA,cAAyB,CAChEC,MAAO,GACPC,YAAa,WAAQ,EACrBC,YAAa,WAAQ,EACrBC,YAAa,WAAK,aAqDJC,IACd,OAAOC,EAAAA,WAAWP,EACpB,8BApDoC,SAAHQ,GAAM,IAAAC,EAAQD,EAARC,SAErCC,EAA+BC,EAAAA,SAA2B,IAAlDT,EAAKQ,EAAEN,GAAAA,EAAWM,EAE1B,GA+BME,EAA4C,CAChDV,MAAAA,EACAC,YAjC+B,SAACU,EAAQC,EAAWC,QAAAA,IAAAA,IAAAA,EAAQ,CAAA,GAE3D,IAAMC,EAAkBC,OAAOC,KAAKJ,GAAWK,OAAO,SAACC,EAAKC,GAC1D,IAAMC,EAAWR,EAAUO,GAO3B,OANAD,EAAIC,kBAAgCE,OAAAA,QAAAC,QACbF,EAAQG,WAAA,EAAA,GAAAC,MAAAC,KADKC,aACIC,KAAhCC,SAAAA,GAGN,OADA1B,EAAY,SAAA2B,UAAaA,EAAUL,MAAM,GAAI,EAAE,GACxCI,CAAO,EAChB,CAAC,MAAAE,GAAA,OAAAT,QAAAU,OAAAD,EACD,CAAA,EAAOZ,CACT,EAAG,IACHhB,KAAW8B,OACNhC,EACH,CAAA,CACEW,OAAAA,EACAC,UAAWE,EACXD,MAAAA,EACAoB,MAAO,CAAA,KAGb,EAaE/B,YAAAA,EACAC,YAZkB,SAAC+B,GACnB,IAAMC,EAAY,GAAAH,OACbhC,GAELmC,EAAanC,EAAMoC,OAAS,GAAGH,MAAKI,KAAQH,GAC5ChC,EAAYiC,EACd,GASA,OAAOG,MAACxC,EAAayC,SAAQ,CAACC,MAAO9B,EAAiBH,SAAGA,GAE3D,oBCtD4C,SAA7BD,GACb,IAAAmC,EAAanC,EAAbmC,cACAC,EAAYpC,EAAZoC,aACQC,EAAQrC,EAAhBK,OAGQX,EAAUI,IAAVJ,MACF4C,EAAsCC,EAAOA,QACjD,kBAAM7C,EAAMoC,OAAS,EAAIpC,EAAMA,EAAMoC,OAAS,GAAK,IAAI,EACvD,CAAEpC,IAEE8C,EAAkBC,cAAY,SAACC,GAC/BA,EAAGC,gBAAkBD,EAAGE,SAChB,MAAZN,OAAY,EAAZA,EAAchC,UAAUuC,qBACxBP,EAAahC,UAAUuC,mBAAmBH,EAC5C,EAAG,CAAEJ,IAUL,OARAQ,EAASA,UAAC,WACJR,EACFH,GAAiBA,IAEjBC,GAAgBA,GAEpB,EAAG,CAAEE,EAAcH,EAAeC,IAE3BE,GACLN,MAACK,EAAQ,CAACG,gBAAiBA,EAAevC,SACvCqC,EAAajC,OAAM0B,EACfO,CAAAA,EAAAA,EAAahC,UACbgC,EAAa/B,WAGjB,IACP,mBDmCgB,WAEd,OADwBT,IAAhBH,WAEV,kDAMgB,WACd,IAAAoD,EAA+BjD,IAAvBJ,EAAKqD,EAALrD,MAAOG,EAAWkD,EAAXlD,YACf,GAAqB,IAAjBH,EAAMoC,OACR,MAAU,IAAAkB,MAAM,uDAElB,MAAO,CADOtD,EAAMA,EAAMoC,OAAS,GAAGH,MACtB9B,EAClB"}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{jsx as n}from"react/jsx-runtime";import{createContext as t,useState as r,useContext as e,useMemo as o,useCallback as c,useEffect as a}from"react";function u(){return u=Object.assign?Object.assign.bind():function(n){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(n[e]=r[e])}return n},u.apply(this,arguments)}var i=t({stack:[],launchModal:function(){},updateStack:function(){},updateState:function(){}}),l=function(t){var e=t.children,o=r([]),c=o[0],a=o[1],l={stack:c,launchModal:function(n,t,r){var e=Object.keys(t).reduce(function(n,r){var e=t[r];return n[r]=function(){try{return Promise.resolve(e.apply(void 0,[].slice.call(arguments))).then(function(n){return a(function(n){return n.slice(0,-1)}),n})}catch(n){return Promise.reject(n)}},n},{});a([].concat(c,[{render:n,resolvers:e,onBackdropClickUse:r,state:{}}]))},updateStack:a,updateState:function(n){var t=[].concat(c);t[c.length-1].state=u({},n),a(t)}};return n(i.Provider,{value:l,children:e})};function s(){return e(i)}function d(){return s().launchModal}function f(){var n=s(),t=n.stack,r=n.updateState;if(0===t.length)throw new Error("Trying to access modal state while no modal is open");return[t[t.length-1].state,r]}var p=function(t){var r=t.onModalLaunch,e=t.onModalClose,u=t.render,i=s().stack,l=o(function(){return i.length>0?i[i.length-1]:null},[i]),d=c(function(n){n.currentTarget===n.target&&(null==l?void 0:l.onBackdropClickUse)&&l.resolvers[l.onBackdropClickUse](n)},[l]);return a(function(){l?r&&r():e&&e()},[l,r,e]),l&&n(u,{onBackdropClick:d,children:l.render(l.resolvers)})||null};export{l as ModalContextProvider,p as ModalPort,d as useModal,s as useModalContext,f as useModalState};
1
+ import{jsx as n}from"react/jsx-runtime";import{createContext as r,useState as t,useContext as e,useMemo as o,useCallback as a,useEffect as c}from"react";function u(){return u=Object.assign?Object.assign.bind():function(n){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&(n[e]=t[e])}return n},u.apply(this,arguments)}var i=r({stack:[],launchModal:function(){},updateStack:function(){},updateState:function(){}}),l=function(r){var e=r.children,o=t([]),a=o[0],c=o[1],l={stack:a,launchModal:function(n,r,t){void 0===t&&(t={});var e=Object.keys(r).reduce(function(n,t){var e=r[t];return n[t]=function(){try{return Promise.resolve(e.apply(void 0,[].slice.call(arguments))).then(function(n){return c(function(n){return n.slice(0,-1)}),n})}catch(n){return Promise.reject(n)}},n},{});c([].concat(a,[{render:n,resolvers:e,props:t,state:{}}]))},updateStack:c,updateState:function(n){var r=[].concat(a);r[a.length-1].state=u({},n),c(r)}};return n(i.Provider,{value:l,children:e})};function s(){return e(i)}function d(){return s().launchModal}function f(){var n=s(),r=n.stack,t=n.updateState;if(0===r.length)throw new Error("Trying to access modal state while no modal is open");return[r[r.length-1].state,t]}var p=function(r){var t=r.onModalLaunch,e=r.onModalClose,i=r.render,l=s().stack,d=o(function(){return l.length>0?l[l.length-1]:null},[l]),f=a(function(n){n.currentTarget===n.target&&(null==d?void 0:d.resolvers.onBackdropClickUse)&&d.resolvers.onBackdropClickUse(n)},[d]);return c(function(){d?t&&t():e&&e()},[d,t,e]),d&&n(i,{onBackdropClick:f,children:d.render(u({},d.resolvers,d.props))})||null};export{l as ModalContextProvider,p as ModalPort,d as useModal,s as useModalContext,f as useModalState};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/context.tsx","../src/modal-port.tsx"],"sourcesContent":["import { \n createContext, \n useContext, \n useState, \n type SyntheticEvent \n} from 'react';\nimport { \n type ModalStackItem,\n type ModalContextProperties,\n type LaunchModal,\n type LaunchModalResolvers,\n type ModalState,\n type UpdateModalState,\n} from '../types';\n\nexport const ModalContext = createContext<ModalContextProperties>({\n stack: [],\n launchModal: () => {},\n updateStack: () => {},\n updateState: () => {},\n});\n\nexport const ModalContextProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {\n\n const [ stack, updateStack ] = useState<ModalStackItem[]>([]);\n\n const launchModal: LaunchModal = (render, resolvers, onBackdropClickUse) => {\n // Wrap resolvers to update the stack\n const wrappedResovers = Object.keys(resolvers).reduce((acc, key) => {\n const resolver = resolvers[key];\n acc[key] = async (...args: any[]) => {\n const result = await resolver(...args);\n // update stack with an array conating all the items in the stack except the last one\n updateStack(currStack => currStack.slice(0, -1));\n return result;\n };\n return acc;\n }, {} as LaunchModalResolvers);\n updateStack([\n ...stack,\n {\n render,\n resolvers: wrappedResovers,\n onBackdropClickUse,\n state: {},\n },\n ]);\n };\n\n const updateState = (newState: ModalState) => {\n const updatedStack = [\n ...stack,\n ];\n updatedStack[stack.length - 1].state = { ...newState };\n updateStack(updatedStack);\n };\n\n const contextProperties: ModalContextProperties = {\n stack,\n launchModal,\n updateStack,\n updateState,\n };\n\n return <ModalContext.Provider value={contextProperties}>{children}</ModalContext.Provider>;\n\n};\n\n/**\n * Get properties from the modal context\n * @returns {ModalContextProperties} Object with the modal context properties\n */\nexport function useModalContext(): ModalContextProperties {\n return useContext(ModalContext);\n}\n\n/**\n * Short-hand for `useModalContext().launchModal`\n * @returns {LaunchModal} The launchModal function\n */\nexport function useModal(): LaunchModal {\n const { launchModal } = useModalContext();\n return launchModal;\n}\n\n/**\n * Get access to the current modal state and a function to update it\n * @returns {[ ModalState, UpdateModalState ]} A tuple with the current modal state and a function to update it\n */\nexport function useModalState(): [ ModalState, UpdateModalState ] {\n const { stack, updateState } = useModalContext();\n if (stack.length === 0) \n throw new Error('Trying to access modal state while no modal is open');\n const state = stack[stack.length - 1].state;\n return [ state, updateState ];\n}\n","import { \n type ModalPortProps, \n type ModalStackItem \n} from \"../types\";\nimport { useModalContext } from \"./context\";\nimport { \n type SyntheticEvent, \n useCallback, \n useEffect, \n useMemo\n} from \"react\";\n\nconst ModalPort: React.FC<ModalPortProps> = ({\n onModalLaunch,\n onModalClose,\n render: Backdrop\n}) => {\n\n const { stack } = useModalContext();\n const currentModal: ModalStackItem | null = useMemo(\n () => stack.length > 0 ? stack[stack.length - 1] : null,\n [ stack ]\n );\n const onBackdropClick = useCallback((ev: SyntheticEvent) => {\n if (ev.currentTarget !== ev.target) return;\n currentModal?.onBackdropClickUse &&\n currentModal.resolvers[currentModal.onBackdropClickUse](ev);\n }, [ currentModal ]);\n\n useEffect(() => {\n if (currentModal) {\n onModalLaunch && onModalLaunch();\n } else {\n onModalClose && onModalClose();\n }\n }, [ currentModal, onModalLaunch, onModalClose ]);\n\n return currentModal && (\n <Backdrop onBackdropClick={onBackdropClick}>\n {currentModal.render(currentModal.resolvers)}\n </Backdrop>\n ) || null;\n};\n\nexport default ModalPort;\n"],"names":["ModalContext","createContext","stack","launchModal","updateStack","updateState","ModalContextProvider","_ref","children","_useState","useState","contextProperties","render","resolvers","onBackdropClickUse","wrappedResovers","Object","keys","reduce","acc","key","resolver","Promise","resolve","apply","slice","call","arguments","then","result","currStack","e","reject","concat","state","newState","updatedStack","length","_extends","_jsx","Provider","value","useModalContext","useContext","useModal","useModalState","_useModalContext2","Error","ModalPort","onModalLaunch","onModalClose","Backdrop","currentModal","useMemo","onBackdropClick","useCallback","ev","currentTarget","target","useEffect"],"mappings":"iYAeaA,EAAeC,EAAsC,CAChEC,MAAO,GACPC,YAAa,WAAQ,EACrBC,YAAa,WAAK,EAClBC,YAAa,eAGFC,EAAuB,SAAHC,GAA6D,IAAvDC,EAAQD,EAARC,SAErCC,EAA+BC,EAA2B,IAAlDR,EAAKO,EAAA,GAAEL,EAAWK,EAAA,GAiCpBE,EAA4C,CAChDT,MAAAA,EACAC,YAjC+B,SAACS,EAAQC,EAAWC,GAEnD,IAAMC,EAAkBC,OAAOC,KAAKJ,GAAWK,OAAO,SAACC,EAAKC,GAC1D,IAAMC,EAAWR,EAAUO,GAO3B,OANAD,EAAIC,GAAI,WAAA,WAA4BE,QAAAC,QACbF,EAAQG,WAAA,EAAA,GAAAC,MAAAC,KADKC,aACIC,KAAA,SAAhCC,GAGN,OADAzB,EAAY,SAAA0B,GAAS,OAAIA,EAAUL,MAAM,GAAI,EAAE,GACxCI,CAAO,EAChB,CAAC,MAAAE,UAAAT,QAAAU,OAAAD,EAAA,CAAA,EACMZ,CACT,EAAG,CAAA,GACHf,EAAW,GAAA6B,OACN/B,EACH,CAAA,CACEU,OAAAA,EACAC,UAAWE,EACXD,mBAAAA,EACAoB,MAAO,MAGb,EAaE9B,YAAAA,EACAC,YAZkB,SAAC8B,GACnB,IAAMC,EAAY,GAAAH,OACb/B,GAELkC,EAAalC,EAAMmC,OAAS,GAAGH,MAAKI,EAAQH,CAAAA,EAAAA,GAC5C/B,EAAYgC,EACd,GASA,OAAOG,EAACvC,EAAawC,SAAQ,CAACC,MAAO9B,EAAiBH,SAAGA,GAE3D,WAMgBkC,IACd,OAAOC,EAAW3C,EACpB,UAMgB4C,IAEd,OADwBF,IAAhBvC,WAEV,CAMgB,SAAA0C,IACd,IAAAC,EAA+BJ,IAAvBxC,EAAK4C,EAAL5C,MAAOG,EAAWyC,EAAXzC,YACf,GAAqB,IAAjBH,EAAMmC,OACR,MAAU,IAAAU,MAAM,uDAElB,MAAO,CADO7C,EAAMA,EAAMmC,OAAS,GAAGH,MACtB7B,EAClB,CCnFM,IAAA2C,EAAsC,SAA7BzC,GAIV,IAHH0C,EAAa1C,EAAb0C,cACAC,EAAY3C,EAAZ2C,aACQC,EAAQ5C,EAAhBK,OAGQV,EAAUwC,IAAVxC,MACFkD,EAAsCC,EAC1C,WAAA,OAAMnD,EAAMmC,OAAS,EAAInC,EAAMA,EAAMmC,OAAS,GAAK,IAAI,EACvD,CAAEnC,IAEEoD,EAAkBC,EAAY,SAACC,GAC/BA,EAAGC,gBAAkBD,EAAGE,SAChB,MAAZN,OAAY,EAAZA,EAActC,qBACdsC,EAAavC,UAAUuC,EAAatC,oBAAoB0C,EAC1D,EAAG,CAAEJ,IAUL,OARAO,EAAU,WACJP,EACFH,GAAiBA,IAEjBC,GAAgBA,GAEpB,EAAG,CAAEE,EAAcH,EAAeC,IAE3BE,GACLb,EAACY,EAAS,CAAAG,gBAAiBA,EACxB9C,SAAA4C,EAAaxC,OAAOwC,EAAavC,cAEjC,IACP"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/context.tsx","../src/modal-port.tsx"],"sourcesContent":["import { \n createContext, \n useContext, \n useState, \n type SyntheticEvent \n} from 'react';\nimport { \n type ModalStackItem,\n type ModalContextProperties,\n type LaunchModal,\n type LaunchModalResolvers,\n type ModalState,\n type UpdateModalState,\n} from '../types';\n\nexport const ModalContext = createContext<ModalContextProperties>({\n stack: [],\n launchModal: () => {},\n updateStack: () => {},\n updateState: () => {},\n});\n\nexport const ModalContextProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {\n\n const [ stack, updateStack ] = useState<ModalStackItem[]>([]);\n\n const launchModal: LaunchModal = (render, resolvers, props = {}) => {\n // Wrap resolvers to update the stack\n const wrappedResovers = Object.keys(resolvers).reduce((acc, key) => {\n const resolver = resolvers[key];\n acc[key] = async (...args: any[]) => {\n const result = await resolver(...args);\n // update stack with an array conating all the items in the stack except the last one\n updateStack(currStack => currStack.slice(0, -1));\n return result;\n };\n return acc;\n }, {} as LaunchModalResolvers);\n updateStack([\n ...stack,\n {\n render,\n resolvers: wrappedResovers,\n props,\n state: {},\n },\n ]);\n };\n\n const updateState = (newState: ModalState) => {\n const updatedStack = [\n ...stack,\n ];\n updatedStack[stack.length - 1].state = { ...newState };\n updateStack(updatedStack);\n };\n\n const contextProperties: ModalContextProperties = {\n stack,\n launchModal,\n updateStack,\n updateState,\n };\n\n return <ModalContext.Provider value={contextProperties}>{children}</ModalContext.Provider>;\n\n};\n\n/**\n * Get properties from the modal context\n * @returns {ModalContextProperties} Object with the modal context properties\n */\nexport function useModalContext(): ModalContextProperties {\n return useContext(ModalContext);\n}\n\n/**\n * Short-hand for `useModalContext().launchModal`\n * @returns {LaunchModal} The launchModal function\n */\nexport function useModal(): LaunchModal {\n const { launchModal } = useModalContext();\n return launchModal;\n}\n\n/**\n * Get access to the current modal state and a function to update it\n * @returns {[ ModalState, UpdateModalState ]} A tuple with the current modal state and a function to update it\n */\nexport function useModalState(): [ ModalState, UpdateModalState ] {\n const { stack, updateState } = useModalContext();\n if (stack.length === 0) \n throw new Error('Trying to access modal state while no modal is open');\n const state = stack[stack.length - 1].state;\n return [ state, updateState ];\n}\n","import { \n type ModalPortProps, \n type ModalStackItem \n} from \"../types\";\nimport { useModalContext } from \"./context\";\nimport { \n type SyntheticEvent, \n useCallback, \n useEffect, \n useMemo\n} from \"react\";\n\nconst ModalPort: React.FC<ModalPortProps> = ({\n onModalLaunch,\n onModalClose,\n render: Backdrop\n}) => {\n\n const { stack } = useModalContext();\n const currentModal: ModalStackItem | null = useMemo(\n () => stack.length > 0 ? stack[stack.length - 1] : null,\n [ stack ]\n );\n const onBackdropClick = useCallback((ev: SyntheticEvent) => {\n if (ev.currentTarget !== ev.target) return;\n currentModal?.resolvers.onBackdropClickUse &&\n currentModal.resolvers.onBackdropClickUse(ev);\n }, [ currentModal ]);\n\n useEffect(() => {\n if (currentModal) {\n onModalLaunch && onModalLaunch();\n } else {\n onModalClose && onModalClose();\n }\n }, [ currentModal, onModalLaunch, onModalClose ]);\n\n return currentModal && (\n <Backdrop onBackdropClick={onBackdropClick}>\n {currentModal.render({\n ...currentModal.resolvers,\n ...currentModal.props,\n })}\n </Backdrop>\n ) || null;\n};\n\nexport default ModalPort;\n"],"names":["ModalContext","createContext","stack","launchModal","updateStack","updateState","ModalContextProvider","_ref","children","_useState","useState","contextProperties","render","resolvers","props","wrappedResovers","Object","keys","reduce","acc","key","resolver","Promise","resolve","apply","slice","call","arguments","then","result","currStack","e","reject","concat","state","newState","updatedStack","length","_extends","_jsx","Provider","value","useModalContext","useContext","useModal","useModalState","_useModalContext2","Error","ModalPort","onModalLaunch","onModalClose","Backdrop","currentModal","useMemo","onBackdropClick","useCallback","ev","currentTarget","target","onBackdropClickUse","useEffect"],"mappings":"iYAeaA,EAAeC,EAAsC,CAChEC,MAAO,GACPC,YAAa,WAAQ,EACrBC,YAAa,WAAQ,EACrBC,YAAa,WAAK,IAGPC,EAAuB,SAAHC,GAAM,IAAAC,EAAQD,EAARC,SAErCC,EAA+BC,EAA2B,IAAlDR,EAAKO,EAAEL,GAAAA,EAAWK,EAE1B,GA+BME,EAA4C,CAChDT,MAAAA,EACAC,YAjC+B,SAACS,EAAQC,EAAWC,QAAAA,IAAAA,IAAAA,EAAQ,CAAA,GAE3D,IAAMC,EAAkBC,OAAOC,KAAKJ,GAAWK,OAAO,SAACC,EAAKC,GAC1D,IAAMC,EAAWR,EAAUO,GAO3B,OANAD,EAAIC,kBAAgCE,OAAAA,QAAAC,QACbF,EAAQG,WAAA,EAAA,GAAAC,MAAAC,KADKC,aACIC,KAAhCC,SAAAA,GAGN,OADAzB,EAAY,SAAA0B,UAAaA,EAAUL,MAAM,GAAI,EAAE,GACxCI,CAAO,EAChB,CAAC,MAAAE,GAAA,OAAAT,QAAAU,OAAAD,EACD,CAAA,EAAOZ,CACT,EAAG,IACHf,KAAW6B,OACN/B,EACH,CAAA,CACEU,OAAAA,EACAC,UAAWE,EACXD,MAAAA,EACAoB,MAAO,CAAA,KAGb,EAaE9B,YAAAA,EACAC,YAZkB,SAAC8B,GACnB,IAAMC,EAAY,GAAAH,OACb/B,GAELkC,EAAalC,EAAMmC,OAAS,GAAGH,MAAKI,KAAQH,GAC5C/B,EAAYgC,EACd,GASA,OAAOG,EAACvC,EAAawC,SAAQ,CAACC,MAAO9B,EAAiBH,SAAGA,GAE3D,WAMgBkC,IACd,OAAOC,EAAW3C,EACpB,CAMgB,SAAA4C,IAEd,OADwBF,IAAhBvC,WAEV,CAMgB,SAAA0C,IACd,IAAAC,EAA+BJ,IAAvBxC,EAAK4C,EAAL5C,MAAOG,EAAWyC,EAAXzC,YACf,GAAqB,IAAjBH,EAAMmC,OACR,MAAU,IAAAU,MAAM,uDAElB,MAAO,CADO7C,EAAMA,EAAMmC,OAAS,GAAGH,MACtB7B,EAClB,CCnFM,IAAA2C,EAAsC,SAA7BzC,GACb,IAAA0C,EAAa1C,EAAb0C,cACAC,EAAY3C,EAAZ2C,aACQC,EAAQ5C,EAAhBK,OAGQV,EAAUwC,IAAVxC,MACFkD,EAAsCC,EAC1C,kBAAMnD,EAAMmC,OAAS,EAAInC,EAAMA,EAAMmC,OAAS,GAAK,IAAI,EACvD,CAAEnC,IAEEoD,EAAkBC,EAAY,SAACC,GAC/BA,EAAGC,gBAAkBD,EAAGE,SAChB,MAAZN,OAAY,EAAZA,EAAcvC,UAAU8C,qBACxBP,EAAavC,UAAU8C,mBAAmBH,EAC5C,EAAG,CAAEJ,IAUL,OARAQ,EAAU,WACJR,EACFH,GAAiBA,IAEjBC,GAAgBA,GAEpB,EAAG,CAAEE,EAAcH,EAAeC,IAE3BE,GACLb,EAACY,EAAQ,CAACG,gBAAiBA,EAAe9C,SACvC4C,EAAaxC,OAAM0B,EACfc,CAAAA,EAAAA,EAAavC,UACbuC,EAAatC,WAGjB,IACP"}
@@ -1,2 +1,2 @@
1
- import{jsx as t}from"react/jsx-runtime";import{createContext as e,useState as n,useContext as r,useMemo as o,useCallback as a,useEffect as c}from"react";function s(){return s=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},s.apply(this,arguments)}const l=e({stack:[],launchModal:()=>{},updateStack:()=>{},updateState:()=>{}}),u=({children:e})=>{const[r,o]=n([]);return t(l.Provider,{value:{stack:r,launchModal:(t,e,n)=>{const a=Object.keys(e).reduce((t,n)=>{const r=e[n];return t[n]=async(...t)=>{const e=await r(...t);return o(t=>t.slice(0,-1)),e},t},{});o([...r,{render:t,resolvers:a,onBackdropClickUse:n,state:{}}])},updateStack:o,updateState:t=>{const e=[...r];e[r.length-1].state=s({},t),o(e)}},children:e})};function i(){return r(l)}function d(){const{launchModal:t}=i();return t}function p(){const{stack:t,updateState:e}=i();if(0===t.length)throw new Error("Trying to access modal state while no modal is open");return[t[t.length-1].state,e]}const h=({onModalLaunch:e,onModalClose:n,render:r})=>{const{stack:s}=i(),l=o(()=>s.length>0?s[s.length-1]:null,[s]),u=a(t=>{t.currentTarget===t.target&&(null==l?void 0:l.onBackdropClickUse)&&l.resolvers[l.onBackdropClickUse](t)},[l]);return c(()=>{l?e&&e():n&&n()},[l,e,n]),l&&t(r,{onBackdropClick:u,children:l.render(l.resolvers)})||null};export{u as ModalContextProvider,h as ModalPort,d as useModal,i as useModalContext,p as useModalState};
1
+ import{jsx as t}from"react/jsx-runtime";import{createContext as e,useState as r,useContext as n,useMemo as o,useCallback as a,useEffect as c}from"react";function s(){return s=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t},s.apply(this,arguments)}const l=e({stack:[],launchModal:()=>{},updateStack:()=>{},updateState:()=>{}}),u=({children:e})=>{const[n,o]=r([]);return t(l.Provider,{value:{stack:n,launchModal:(t,e,r={})=>{const a=Object.keys(e).reduce((t,r)=>{const n=e[r];return t[r]=async(...t)=>{const e=await n(...t);return o(t=>t.slice(0,-1)),e},t},{});o([...n,{render:t,resolvers:a,props:r,state:{}}])},updateStack:o,updateState:t=>{const e=[...n];e[n.length-1].state=s({},t),o(e)}},children:e})};function i(){return n(l)}function d(){const{launchModal:t}=i();return t}function p(){const{stack:t,updateState:e}=i();if(0===t.length)throw new Error("Trying to access modal state while no modal is open");return[t[t.length-1].state,e]}const h=({onModalLaunch:e,onModalClose:r,render:n})=>{const{stack:l}=i(),u=o(()=>l.length>0?l[l.length-1]:null,[l]),d=a(t=>{t.currentTarget===t.target&&(null==u?void 0:u.resolvers.onBackdropClickUse)&&u.resolvers.onBackdropClickUse(t)},[u]);return c(()=>{u?e&&e():r&&r()},[u,e,r]),u&&t(n,{onBackdropClick:d,children:u.render(s({},u.resolvers,u.props))})||null};export{u as ModalContextProvider,h as ModalPort,d as useModal,i as useModalContext,p as useModalState};
2
2
  //# sourceMappingURL=index.modern.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.modern.mjs","sources":["../src/context.tsx","../src/modal-port.tsx"],"sourcesContent":["import { \n createContext, \n useContext, \n useState, \n type SyntheticEvent \n} from 'react';\nimport { \n type ModalStackItem,\n type ModalContextProperties,\n type LaunchModal,\n type LaunchModalResolvers,\n type ModalState,\n type UpdateModalState,\n} from '../types';\n\nexport const ModalContext = createContext<ModalContextProperties>({\n stack: [],\n launchModal: () => {},\n updateStack: () => {},\n updateState: () => {},\n});\n\nexport const ModalContextProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {\n\n const [ stack, updateStack ] = useState<ModalStackItem[]>([]);\n\n const launchModal: LaunchModal = (render, resolvers, onBackdropClickUse) => {\n // Wrap resolvers to update the stack\n const wrappedResovers = Object.keys(resolvers).reduce((acc, key) => {\n const resolver = resolvers[key];\n acc[key] = async (...args: any[]) => {\n const result = await resolver(...args);\n // update stack with an array conating all the items in the stack except the last one\n updateStack(currStack => currStack.slice(0, -1));\n return result;\n };\n return acc;\n }, {} as LaunchModalResolvers);\n updateStack([\n ...stack,\n {\n render,\n resolvers: wrappedResovers,\n onBackdropClickUse,\n state: {},\n },\n ]);\n };\n\n const updateState = (newState: ModalState) => {\n const updatedStack = [\n ...stack,\n ];\n updatedStack[stack.length - 1].state = { ...newState };\n updateStack(updatedStack);\n };\n\n const contextProperties: ModalContextProperties = {\n stack,\n launchModal,\n updateStack,\n updateState,\n };\n\n return <ModalContext.Provider value={contextProperties}>{children}</ModalContext.Provider>;\n\n};\n\n/**\n * Get properties from the modal context\n * @returns {ModalContextProperties} Object with the modal context properties\n */\nexport function useModalContext(): ModalContextProperties {\n return useContext(ModalContext);\n}\n\n/**\n * Short-hand for `useModalContext().launchModal`\n * @returns {LaunchModal} The launchModal function\n */\nexport function useModal(): LaunchModal {\n const { launchModal } = useModalContext();\n return launchModal;\n}\n\n/**\n * Get access to the current modal state and a function to update it\n * @returns {[ ModalState, UpdateModalState ]} A tuple with the current modal state and a function to update it\n */\nexport function useModalState(): [ ModalState, UpdateModalState ] {\n const { stack, updateState } = useModalContext();\n if (stack.length === 0) \n throw new Error('Trying to access modal state while no modal is open');\n const state = stack[stack.length - 1].state;\n return [ state, updateState ];\n}\n","import { \n type ModalPortProps, \n type ModalStackItem \n} from \"../types\";\nimport { useModalContext } from \"./context\";\nimport { \n type SyntheticEvent, \n useCallback, \n useEffect, \n useMemo\n} from \"react\";\n\nconst ModalPort: React.FC<ModalPortProps> = ({\n onModalLaunch,\n onModalClose,\n render: Backdrop\n}) => {\n\n const { stack } = useModalContext();\n const currentModal: ModalStackItem | null = useMemo(\n () => stack.length > 0 ? stack[stack.length - 1] : null,\n [ stack ]\n );\n const onBackdropClick = useCallback((ev: SyntheticEvent) => {\n if (ev.currentTarget !== ev.target) return;\n currentModal?.onBackdropClickUse &&\n currentModal.resolvers[currentModal.onBackdropClickUse](ev);\n }, [ currentModal ]);\n\n useEffect(() => {\n if (currentModal) {\n onModalLaunch && onModalLaunch();\n } else {\n onModalClose && onModalClose();\n }\n }, [ currentModal, onModalLaunch, onModalClose ]);\n\n return currentModal && (\n <Backdrop onBackdropClick={onBackdropClick}>\n {currentModal.render(currentModal.resolvers)}\n </Backdrop>\n ) || null;\n};\n\nexport default ModalPort;\n"],"names":["ModalContext","createContext","stack","launchModal","updateStack","updateState","ModalContextProvider","children","useState","_jsx","Provider","value","render","resolvers","onBackdropClickUse","wrappedResovers","Object","keys","reduce","acc","key","resolver","async","args","result","currStack","slice","state","newState","updatedStack","length","_extends","useModalContext","useContext","useModal","useModalState","Error","ModalPort","onModalLaunch","onModalClose","Backdrop","currentModal","useMemo","onBackdropClick","useCallback","ev","currentTarget","target","useEffect"],"mappings":"mYAeaA,EAAeC,EAAsC,CAChEC,MAAO,GACPC,YAAaA,OACbC,YAAaA,OACbC,YAAaA,SAGFC,EAAuBA,EAAGC,eAErC,MAAQL,EAAOE,GAAgBI,EAA2B,IAwC1D,OAAOC,EAACT,EAAaU,SAAQ,CAACC,MAPoB,CAChDT,QACAC,YAjC+BA,CAACS,EAAQC,EAAWC,KAEnD,MAAMC,EAAkBC,OAAOC,KAAKJ,GAAWK,OAAO,CAACC,EAAKC,KAC1D,MAAMC,EAAWR,EAAUO,GAO3B,OANAD,EAAIC,GAAOE,SAAUC,KACnB,MAAMC,QAAeH,KAAYE,GAGjC,OADAnB,EAAYqB,GAAaA,EAAUC,MAAM,GAAI,IACtCF,GAEFL,GACN,CAAA,GACHf,EAAY,IACPF,EACH,CACEU,SACAC,UAAWE,EACXD,qBACAa,MAAO,CACR,IACF,EAcDvB,cACAC,YAZmBuB,IACnB,MAAMC,EAAe,IAChB3B,GAEL2B,EAAa3B,EAAM4B,OAAS,GAAGH,MAAKI,EAAA,CAAA,EAAQH,GAC5CxB,EAAYyB,EACd,GASsDtB,SAAGA,GAAQ,EAQnD,SAAAyB,IACd,OAAOC,EAAWjC,EACpB,CAMgB,SAAAkC,IACd,MAAM/B,YAAEA,GAAgB6B,IACxB,OAAO7B,CACT,UAMgBgC,IACd,MAAMjC,MAAEA,EAAKG,YAAEA,GAAgB2B,IAC/B,GAAqB,IAAjB9B,EAAM4B,OACR,MAAM,IAAIM,MAAM,uDAElB,MAAO,CADOlC,EAAMA,EAAM4B,OAAS,GAAGH,MACtBtB,EAClB,CCnFM,MAAAgC,EAAsCA,EAC1CC,gBACAC,eACA3B,OAAQ4B,MAGR,MAAMtC,MAAEA,GAAU8B,IACZS,EAAsCC,EAC1C,IAAMxC,EAAM4B,OAAS,EAAI5B,EAAMA,EAAM4B,OAAS,GAAK,KACnD,CAAE5B,IAEEyC,EAAkBC,EAAaC,IAC/BA,EAAGC,gBAAkBD,EAAGE,eAC5BN,SAAAA,EAAc3B,qBACd2B,EAAa5B,UAAU4B,EAAa3B,oBAAoB+B,EAAE,EACzD,CAAEJ,IAUL,OARAO,EAAU,KACJP,EACFH,GAAiBA,IAEjBC,GAAgBA,GAClB,EACC,CAAEE,EAAcH,EAAeC,IAE3BE,GACLhC,EAAC+B,EAAS,CAAAG,gBAAiBA,EACxBpC,SAAAkC,EAAa7B,OAAO6B,EAAa5B,cAEjC"}
1
+ {"version":3,"file":"index.modern.mjs","sources":["../src/context.tsx","../src/modal-port.tsx"],"sourcesContent":["import { \n createContext, \n useContext, \n useState, \n type SyntheticEvent \n} from 'react';\nimport { \n type ModalStackItem,\n type ModalContextProperties,\n type LaunchModal,\n type LaunchModalResolvers,\n type ModalState,\n type UpdateModalState,\n} from '../types';\n\nexport const ModalContext = createContext<ModalContextProperties>({\n stack: [],\n launchModal: () => {},\n updateStack: () => {},\n updateState: () => {},\n});\n\nexport const ModalContextProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {\n\n const [ stack, updateStack ] = useState<ModalStackItem[]>([]);\n\n const launchModal: LaunchModal = (render, resolvers, props = {}) => {\n // Wrap resolvers to update the stack\n const wrappedResovers = Object.keys(resolvers).reduce((acc, key) => {\n const resolver = resolvers[key];\n acc[key] = async (...args: any[]) => {\n const result = await resolver(...args);\n // update stack with an array conating all the items in the stack except the last one\n updateStack(currStack => currStack.slice(0, -1));\n return result;\n };\n return acc;\n }, {} as LaunchModalResolvers);\n updateStack([\n ...stack,\n {\n render,\n resolvers: wrappedResovers,\n props,\n state: {},\n },\n ]);\n };\n\n const updateState = (newState: ModalState) => {\n const updatedStack = [\n ...stack,\n ];\n updatedStack[stack.length - 1].state = { ...newState };\n updateStack(updatedStack);\n };\n\n const contextProperties: ModalContextProperties = {\n stack,\n launchModal,\n updateStack,\n updateState,\n };\n\n return <ModalContext.Provider value={contextProperties}>{children}</ModalContext.Provider>;\n\n};\n\n/**\n * Get properties from the modal context\n * @returns {ModalContextProperties} Object with the modal context properties\n */\nexport function useModalContext(): ModalContextProperties {\n return useContext(ModalContext);\n}\n\n/**\n * Short-hand for `useModalContext().launchModal`\n * @returns {LaunchModal} The launchModal function\n */\nexport function useModal(): LaunchModal {\n const { launchModal } = useModalContext();\n return launchModal;\n}\n\n/**\n * Get access to the current modal state and a function to update it\n * @returns {[ ModalState, UpdateModalState ]} A tuple with the current modal state and a function to update it\n */\nexport function useModalState(): [ ModalState, UpdateModalState ] {\n const { stack, updateState } = useModalContext();\n if (stack.length === 0) \n throw new Error('Trying to access modal state while no modal is open');\n const state = stack[stack.length - 1].state;\n return [ state, updateState ];\n}\n","import { \n type ModalPortProps, \n type ModalStackItem \n} from \"../types\";\nimport { useModalContext } from \"./context\";\nimport { \n type SyntheticEvent, \n useCallback, \n useEffect, \n useMemo\n} from \"react\";\n\nconst ModalPort: React.FC<ModalPortProps> = ({\n onModalLaunch,\n onModalClose,\n render: Backdrop\n}) => {\n\n const { stack } = useModalContext();\n const currentModal: ModalStackItem | null = useMemo(\n () => stack.length > 0 ? stack[stack.length - 1] : null,\n [ stack ]\n );\n const onBackdropClick = useCallback((ev: SyntheticEvent) => {\n if (ev.currentTarget !== ev.target) return;\n currentModal?.resolvers.onBackdropClickUse &&\n currentModal.resolvers.onBackdropClickUse(ev);\n }, [ currentModal ]);\n\n useEffect(() => {\n if (currentModal) {\n onModalLaunch && onModalLaunch();\n } else {\n onModalClose && onModalClose();\n }\n }, [ currentModal, onModalLaunch, onModalClose ]);\n\n return currentModal && (\n <Backdrop onBackdropClick={onBackdropClick}>\n {currentModal.render({\n ...currentModal.resolvers,\n ...currentModal.props,\n })}\n </Backdrop>\n ) || null;\n};\n\nexport default ModalPort;\n"],"names":["ModalContext","createContext","stack","launchModal","updateStack","updateState","ModalContextProvider","children","useState","_jsx","Provider","value","render","resolvers","props","wrappedResovers","Object","keys","reduce","acc","key","resolver","async","args","result","currStack","slice","state","newState","updatedStack","length","_extends","useModalContext","useContext","useModal","useModalState","Error","ModalPort","onModalLaunch","onModalClose","Backdrop","currentModal","useMemo","onBackdropClick","useCallback","ev","currentTarget","target","onBackdropClickUse","useEffect"],"mappings":"mYAeaA,EAAeC,EAAsC,CAChEC,MAAO,GACPC,YAAaA,OACbC,YAAaA,OACbC,YAAaA,SAGFC,EAAuBA,EAAGC,eAErC,MAAQL,EAAOE,GAAgBI,EAA2B,IAwC1D,OAAOC,EAACT,EAAaU,SAAQ,CAACC,MAPoB,CAChDT,QACAC,YAjC+BA,CAACS,EAAQC,EAAWC,EAAQ,CAAA,KAE3D,MAAMC,EAAkBC,OAAOC,KAAKJ,GAAWK,OAAO,CAACC,EAAKC,KAC1D,MAAMC,EAAWR,EAAUO,GAO3B,OANAD,EAAIC,GAAOE,SAAUC,KACnB,MAAMC,QAAeH,KAAYE,GAGjC,OADAnB,EAAYqB,GAAaA,EAAUC,MAAM,GAAI,IACtCF,GAEFL,GACN,CAA0B,GAC7Bf,EAAY,IACPF,EACH,CACEU,SACAC,UAAWE,EACXD,QACAa,MAAO,CAAA,IAGb,EAaEvB,cACAC,YAZmBuB,IACnB,MAAMC,EAAe,IAChB3B,GAEL2B,EAAa3B,EAAM4B,OAAS,GAAGH,MAAKI,EAAA,GAAQH,GAC5CxB,EAAYyB,EAAY,GAU4BtB,SAAGA,GAAQ,WAQnDyB,IACd,OAAOC,EAAWjC,EACpB,UAMgBkC,IACd,MAAM/B,YAAEA,GAAgB6B,IACxB,OAAO7B,CACT,UAMgBgC,IACd,MAAMjC,MAAEA,EAAKG,YAAEA,GAAgB2B,IAC/B,GAAqB,IAAjB9B,EAAM4B,OACR,UAAUM,MAAM,uDAElB,MAAO,CADOlC,EAAMA,EAAM4B,OAAS,GAAGH,MACtBtB,EAClB,CCnFM,MAAAgC,EAAsCA,EAC1CC,gBACAC,eACA3B,OAAQ4B,MAGR,MAAMtC,MAAEA,GAAU8B,IACZS,EAAsCC,EAC1C,IAAMxC,EAAM4B,OAAS,EAAI5B,EAAMA,EAAM4B,OAAS,GAAK,KACnD,CAAE5B,IAEEyC,EAAkBC,EAAaC,IAC/BA,EAAGC,gBAAkBD,EAAGE,SAChB,MAAZN,OAAY,EAAZA,EAAc5B,UAAUmC,qBACxBP,EAAa5B,UAAUmC,mBAAmBH,EAC5C,EAAG,CAAEJ,IAUL,OARAQ,EAAU,KACJR,EACFH,GAAiBA,IAEjBC,GAAgBA,GAClB,EACC,CAAEE,EAAcH,EAAeC,IAE3BE,GACLhC,EAAC+B,EAAQ,CAACG,gBAAiBA,EAAepC,SACvCkC,EAAa7B,OAAMmB,EAAA,CAAA,EACfU,EAAa5B,UACb4B,EAAa3B,WAGjB"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react/jsx-runtime"),require("react")):"function"==typeof define&&define.amd?define(["exports","react/jsx-runtime","react"],t):t((e||self).reactModalPort={},e.jsx,e.react)}(this,function(e,t,n){function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}var o=n.createContext({stack:[],launchModal:function(){},updateStack:function(){},updateState:function(){}});function a(){return n.useContext(o)}e.ModalContextProvider=function(e){var a=e.children,c=n.useState([]),u=c[0],i=c[1],l={stack:u,launchModal:function(e,t,n){var r=Object.keys(t).reduce(function(e,n){var r=t[n];return e[n]=function(){try{return Promise.resolve(r.apply(void 0,[].slice.call(arguments))).then(function(e){return i(function(e){return e.slice(0,-1)}),e})}catch(e){return Promise.reject(e)}},e},{});i([].concat(u,[{render:e,resolvers:r,onBackdropClickUse:n,state:{}}]))},updateStack:i,updateState:function(e){var t=[].concat(u);t[u.length-1].state=r({},e),i(t)}};return t.jsx(o.Provider,{value:l,children:a})},e.ModalPort=function(e){var r=e.onModalLaunch,o=e.onModalClose,c=e.render,u=a().stack,i=n.useMemo(function(){return u.length>0?u[u.length-1]:null},[u]),l=n.useCallback(function(e){e.currentTarget===e.target&&(null==i?void 0:i.onBackdropClickUse)&&i.resolvers[i.onBackdropClickUse](e)},[i]);return n.useEffect(function(){i?r&&r():o&&o()},[i,r,o]),i&&t.jsx(c,{onBackdropClick:l,children:i.render(i.resolvers)})||null},e.useModal=function(){return a().launchModal},e.useModalContext=a,e.useModalState=function(){var e=a(),t=e.stack,n=e.updateState;if(0===t.length)throw new Error("Trying to access modal state while no modal is open");return[t[t.length-1].state,n]}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react/jsx-runtime"),require("react")):"function"==typeof define&&define.amd?define(["exports","react/jsx-runtime","react"],t):t((e||self).reactModalPort={},e.jsx,e.react)}(this,function(e,t,n){function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}var o=n.createContext({stack:[],launchModal:function(){},updateStack:function(){},updateState:function(){}});function a(){return n.useContext(o)}e.ModalContextProvider=function(e){var a=e.children,c=n.useState([]),u=c[0],i=c[1],l={stack:u,launchModal:function(e,t,n){void 0===n&&(n={});var r=Object.keys(t).reduce(function(e,n){var r=t[n];return e[n]=function(){try{return Promise.resolve(r.apply(void 0,[].slice.call(arguments))).then(function(e){return i(function(e){return e.slice(0,-1)}),e})}catch(e){return Promise.reject(e)}},e},{});i([].concat(u,[{render:e,resolvers:r,props:n,state:{}}]))},updateStack:i,updateState:function(e){var t=[].concat(u);t[u.length-1].state=r({},e),i(t)}};return t.jsx(o.Provider,{value:l,children:a})},e.ModalPort=function(e){var o=e.onModalLaunch,c=e.onModalClose,u=e.render,i=a().stack,l=n.useMemo(function(){return i.length>0?i[i.length-1]:null},[i]),s=n.useCallback(function(e){e.currentTarget===e.target&&(null==l?void 0:l.resolvers.onBackdropClickUse)&&l.resolvers.onBackdropClickUse(e)},[l]);return n.useEffect(function(){l?o&&o():c&&c()},[l,o,c]),l&&t.jsx(u,{onBackdropClick:s,children:l.render(r({},l.resolvers,l.props))})||null},e.useModal=function(){return a().launchModal},e.useModalContext=a,e.useModalState=function(){var e=a(),t=e.stack,n=e.updateState;if(0===t.length)throw new Error("Trying to access modal state while no modal is open");return[t[t.length-1].state,n]}});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/context.tsx","../src/modal-port.tsx"],"sourcesContent":["import { \n createContext, \n useContext, \n useState, \n type SyntheticEvent \n} from 'react';\nimport { \n type ModalStackItem,\n type ModalContextProperties,\n type LaunchModal,\n type LaunchModalResolvers,\n type ModalState,\n type UpdateModalState,\n} from '../types';\n\nexport const ModalContext = createContext<ModalContextProperties>({\n stack: [],\n launchModal: () => {},\n updateStack: () => {},\n updateState: () => {},\n});\n\nexport const ModalContextProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {\n\n const [ stack, updateStack ] = useState<ModalStackItem[]>([]);\n\n const launchModal: LaunchModal = (render, resolvers, onBackdropClickUse) => {\n // Wrap resolvers to update the stack\n const wrappedResovers = Object.keys(resolvers).reduce((acc, key) => {\n const resolver = resolvers[key];\n acc[key] = async (...args: any[]) => {\n const result = await resolver(...args);\n // update stack with an array conating all the items in the stack except the last one\n updateStack(currStack => currStack.slice(0, -1));\n return result;\n };\n return acc;\n }, {} as LaunchModalResolvers);\n updateStack([\n ...stack,\n {\n render,\n resolvers: wrappedResovers,\n onBackdropClickUse,\n state: {},\n },\n ]);\n };\n\n const updateState = (newState: ModalState) => {\n const updatedStack = [\n ...stack,\n ];\n updatedStack[stack.length - 1].state = { ...newState };\n updateStack(updatedStack);\n };\n\n const contextProperties: ModalContextProperties = {\n stack,\n launchModal,\n updateStack,\n updateState,\n };\n\n return <ModalContext.Provider value={contextProperties}>{children}</ModalContext.Provider>;\n\n};\n\n/**\n * Get properties from the modal context\n * @returns {ModalContextProperties} Object with the modal context properties\n */\nexport function useModalContext(): ModalContextProperties {\n return useContext(ModalContext);\n}\n\n/**\n * Short-hand for `useModalContext().launchModal`\n * @returns {LaunchModal} The launchModal function\n */\nexport function useModal(): LaunchModal {\n const { launchModal } = useModalContext();\n return launchModal;\n}\n\n/**\n * Get access to the current modal state and a function to update it\n * @returns {[ ModalState, UpdateModalState ]} A tuple with the current modal state and a function to update it\n */\nexport function useModalState(): [ ModalState, UpdateModalState ] {\n const { stack, updateState } = useModalContext();\n if (stack.length === 0) \n throw new Error('Trying to access modal state while no modal is open');\n const state = stack[stack.length - 1].state;\n return [ state, updateState ];\n}\n","import { \n type ModalPortProps, \n type ModalStackItem \n} from \"../types\";\nimport { useModalContext } from \"./context\";\nimport { \n type SyntheticEvent, \n useCallback, \n useEffect, \n useMemo\n} from \"react\";\n\nconst ModalPort: React.FC<ModalPortProps> = ({\n onModalLaunch,\n onModalClose,\n render: Backdrop\n}) => {\n\n const { stack } = useModalContext();\n const currentModal: ModalStackItem | null = useMemo(\n () => stack.length > 0 ? stack[stack.length - 1] : null,\n [ stack ]\n );\n const onBackdropClick = useCallback((ev: SyntheticEvent) => {\n if (ev.currentTarget !== ev.target) return;\n currentModal?.onBackdropClickUse &&\n currentModal.resolvers[currentModal.onBackdropClickUse](ev);\n }, [ currentModal ]);\n\n useEffect(() => {\n if (currentModal) {\n onModalLaunch && onModalLaunch();\n } else {\n onModalClose && onModalClose();\n }\n }, [ currentModal, onModalLaunch, onModalClose ]);\n\n return currentModal && (\n <Backdrop onBackdropClick={onBackdropClick}>\n {currentModal.render(currentModal.resolvers)}\n </Backdrop>\n ) || null;\n};\n\nexport default ModalPort;\n"],"names":["ModalContext","createContext","stack","launchModal","updateStack","updateState","useModalContext","useContext","_ref","children","_useState","useState","contextProperties","render","resolvers","onBackdropClickUse","wrappedResovers","Object","keys","reduce","acc","key","resolver","Promise","resolve","apply","slice","call","arguments","then","result","currStack","e","reject","concat","state","newState","updatedStack","length","_extends","_jsx","Provider","value","onModalLaunch","onModalClose","Backdrop","currentModal","useMemo","onBackdropClick","useCallback","ev","currentTarget","target","useEffect","_useModalContext2","Error"],"mappings":"4iBAeaA,EAAeC,EAAaA,cAAyB,CAChEC,MAAO,GACPC,YAAa,WAAQ,EACrBC,YAAa,WAAK,EAClBC,YAAa,wBAqDCC,IACd,OAAOC,EAAUA,WAACP,EACpB,wBApDoC,SAAHQ,GAA6D,IAAvDC,EAAQD,EAARC,SAErCC,EAA+BC,EAAQA,SAAmB,IAAlDT,EAAKQ,EAAA,GAAEN,EAAWM,EAAA,GAiCpBE,EAA4C,CAChDV,MAAAA,EACAC,YAjC+B,SAACU,EAAQC,EAAWC,GAEnD,IAAMC,EAAkBC,OAAOC,KAAKJ,GAAWK,OAAO,SAACC,EAAKC,GAC1D,IAAMC,EAAWR,EAAUO,GAO3B,OANAD,EAAIC,GAAI,WAAA,WAA4BE,QAAAC,QACbF,EAAQG,WAAA,EAAA,GAAAC,MAAAC,KADKC,aACIC,KAAA,SAAhCC,GAGN,OADA1B,EAAY,SAAA2B,GAAS,OAAIA,EAAUL,MAAM,GAAI,EAAE,GACxCI,CAAO,EAChB,CAAC,MAAAE,UAAAT,QAAAU,OAAAD,EAAA,CAAA,EACMZ,CACT,EAAG,CAAA,GACHhB,EAAW,GAAA8B,OACNhC,EACH,CAAA,CACEW,OAAAA,EACAC,UAAWE,EACXD,mBAAAA,EACAoB,MAAO,MAGb,EAaE/B,YAAAA,EACAC,YAZkB,SAAC+B,GACnB,IAAMC,EAAY,GAAAH,OACbhC,GAELmC,EAAanC,EAAMoC,OAAS,GAAGH,MAAKI,EAAQH,CAAAA,EAAAA,GAC5ChC,EAAYiC,EACd,GASA,OAAOG,EAAAA,IAACxC,EAAayC,SAAQ,CAACC,MAAO9B,EAAiBH,SAAGA,GAE3D,cCtD4C,SAA7BD,GAIV,IAHHmC,EAAanC,EAAbmC,cACAC,EAAYpC,EAAZoC,aACQC,EAAQrC,EAAhBK,OAGQX,EAAUI,IAAVJ,MACF4C,EAAsCC,EAAOA,QACjD,WAAA,OAAM7C,EAAMoC,OAAS,EAAIpC,EAAMA,EAAMoC,OAAS,GAAK,IAAI,EACvD,CAAEpC,IAEE8C,EAAkBC,EAAWA,YAAC,SAACC,GAC/BA,EAAGC,gBAAkBD,EAAGE,SAChB,MAAZN,OAAY,EAAZA,EAAc/B,qBACd+B,EAAahC,UAAUgC,EAAa/B,oBAAoBmC,EAC1D,EAAG,CAAEJ,IAUL,OARAO,EAAAA,UAAU,WACJP,EACFH,GAAiBA,IAEjBC,GAAgBA,GAEpB,EAAG,CAAEE,EAAcH,EAAeC,IAE3BE,GACLN,EAAAA,IAACK,EAAS,CAAAG,gBAAiBA,EACxBvC,SAAAqC,EAAajC,OAAOiC,EAAahC,cAEjC,IACP,wBDwCE,OADwBR,IAAhBH,WAEV,sCAMgB,WACd,IAAAmD,EAA+BhD,IAAvBJ,EAAKoD,EAALpD,MAAOG,EAAWiD,EAAXjD,YACf,GAAqB,IAAjBH,EAAMoC,OACR,MAAU,IAAAiB,MAAM,uDAElB,MAAO,CADOrD,EAAMA,EAAMoC,OAAS,GAAGH,MACtB9B,EAClB"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/context.tsx","../src/modal-port.tsx"],"sourcesContent":["import { \n createContext, \n useContext, \n useState, \n type SyntheticEvent \n} from 'react';\nimport { \n type ModalStackItem,\n type ModalContextProperties,\n type LaunchModal,\n type LaunchModalResolvers,\n type ModalState,\n type UpdateModalState,\n} from '../types';\n\nexport const ModalContext = createContext<ModalContextProperties>({\n stack: [],\n launchModal: () => {},\n updateStack: () => {},\n updateState: () => {},\n});\n\nexport const ModalContextProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {\n\n const [ stack, updateStack ] = useState<ModalStackItem[]>([]);\n\n const launchModal: LaunchModal = (render, resolvers, props = {}) => {\n // Wrap resolvers to update the stack\n const wrappedResovers = Object.keys(resolvers).reduce((acc, key) => {\n const resolver = resolvers[key];\n acc[key] = async (...args: any[]) => {\n const result = await resolver(...args);\n // update stack with an array conating all the items in the stack except the last one\n updateStack(currStack => currStack.slice(0, -1));\n return result;\n };\n return acc;\n }, {} as LaunchModalResolvers);\n updateStack([\n ...stack,\n {\n render,\n resolvers: wrappedResovers,\n props,\n state: {},\n },\n ]);\n };\n\n const updateState = (newState: ModalState) => {\n const updatedStack = [\n ...stack,\n ];\n updatedStack[stack.length - 1].state = { ...newState };\n updateStack(updatedStack);\n };\n\n const contextProperties: ModalContextProperties = {\n stack,\n launchModal,\n updateStack,\n updateState,\n };\n\n return <ModalContext.Provider value={contextProperties}>{children}</ModalContext.Provider>;\n\n};\n\n/**\n * Get properties from the modal context\n * @returns {ModalContextProperties} Object with the modal context properties\n */\nexport function useModalContext(): ModalContextProperties {\n return useContext(ModalContext);\n}\n\n/**\n * Short-hand for `useModalContext().launchModal`\n * @returns {LaunchModal} The launchModal function\n */\nexport function useModal(): LaunchModal {\n const { launchModal } = useModalContext();\n return launchModal;\n}\n\n/**\n * Get access to the current modal state and a function to update it\n * @returns {[ ModalState, UpdateModalState ]} A tuple with the current modal state and a function to update it\n */\nexport function useModalState(): [ ModalState, UpdateModalState ] {\n const { stack, updateState } = useModalContext();\n if (stack.length === 0) \n throw new Error('Trying to access modal state while no modal is open');\n const state = stack[stack.length - 1].state;\n return [ state, updateState ];\n}\n","import { \n type ModalPortProps, \n type ModalStackItem \n} from \"../types\";\nimport { useModalContext } from \"./context\";\nimport { \n type SyntheticEvent, \n useCallback, \n useEffect, \n useMemo\n} from \"react\";\n\nconst ModalPort: React.FC<ModalPortProps> = ({\n onModalLaunch,\n onModalClose,\n render: Backdrop\n}) => {\n\n const { stack } = useModalContext();\n const currentModal: ModalStackItem | null = useMemo(\n () => stack.length > 0 ? stack[stack.length - 1] : null,\n [ stack ]\n );\n const onBackdropClick = useCallback((ev: SyntheticEvent) => {\n if (ev.currentTarget !== ev.target) return;\n currentModal?.resolvers.onBackdropClickUse &&\n currentModal.resolvers.onBackdropClickUse(ev);\n }, [ currentModal ]);\n\n useEffect(() => {\n if (currentModal) {\n onModalLaunch && onModalLaunch();\n } else {\n onModalClose && onModalClose();\n }\n }, [ currentModal, onModalLaunch, onModalClose ]);\n\n return currentModal && (\n <Backdrop onBackdropClick={onBackdropClick}>\n {currentModal.render({\n ...currentModal.resolvers,\n ...currentModal.props,\n })}\n </Backdrop>\n ) || null;\n};\n\nexport default ModalPort;\n"],"names":["ModalContext","createContext","stack","launchModal","updateStack","updateState","useModalContext","useContext","_ref","children","_useState","useState","contextProperties","render","resolvers","props","wrappedResovers","Object","keys","reduce","acc","key","resolver","Promise","resolve","apply","slice","call","arguments","then","result","currStack","e","reject","concat","state","newState","updatedStack","length","_extends","_jsx","Provider","value","onModalLaunch","onModalClose","Backdrop","currentModal","useMemo","onBackdropClick","useCallback","ev","currentTarget","target","onBackdropClickUse","useEffect","_useModalContext2","Error"],"mappings":"4iBAeaA,EAAeC,EAAaA,cAAyB,CAChEC,MAAO,GACPC,YAAa,WAAQ,EACrBC,YAAa,WAAQ,EACrBC,YAAa,WAAK,aAqDJC,IACd,OAAOC,EAAAA,WAAWP,EACpB,wBApDoC,SAAHQ,GAAM,IAAAC,EAAQD,EAARC,SAErCC,EAA+BC,EAAAA,SAA2B,IAAlDT,EAAKQ,EAAEN,GAAAA,EAAWM,EAE1B,GA+BME,EAA4C,CAChDV,MAAAA,EACAC,YAjC+B,SAACU,EAAQC,EAAWC,QAAAA,IAAAA,IAAAA,EAAQ,CAAA,GAE3D,IAAMC,EAAkBC,OAAOC,KAAKJ,GAAWK,OAAO,SAACC,EAAKC,GAC1D,IAAMC,EAAWR,EAAUO,GAO3B,OANAD,EAAIC,kBAAgCE,OAAAA,QAAAC,QACbF,EAAQG,WAAA,EAAA,GAAAC,MAAAC,KADKC,aACIC,KAAhCC,SAAAA,GAGN,OADA1B,EAAY,SAAA2B,UAAaA,EAAUL,MAAM,GAAI,EAAE,GACxCI,CAAO,EAChB,CAAC,MAAAE,GAAA,OAAAT,QAAAU,OAAAD,EACD,CAAA,EAAOZ,CACT,EAAG,IACHhB,KAAW8B,OACNhC,EACH,CAAA,CACEW,OAAAA,EACAC,UAAWE,EACXD,MAAAA,EACAoB,MAAO,CAAA,KAGb,EAaE/B,YAAAA,EACAC,YAZkB,SAAC+B,GACnB,IAAMC,EAAY,GAAAH,OACbhC,GAELmC,EAAanC,EAAMoC,OAAS,GAAGH,MAAKI,KAAQH,GAC5ChC,EAAYiC,EACd,GASA,OAAOG,MAACxC,EAAayC,SAAQ,CAACC,MAAO9B,EAAiBH,SAAGA,GAE3D,cCtD4C,SAA7BD,GACb,IAAAmC,EAAanC,EAAbmC,cACAC,EAAYpC,EAAZoC,aACQC,EAAQrC,EAAhBK,OAGQX,EAAUI,IAAVJ,MACF4C,EAAsCC,EAAOA,QACjD,kBAAM7C,EAAMoC,OAAS,EAAIpC,EAAMA,EAAMoC,OAAS,GAAK,IAAI,EACvD,CAAEpC,IAEE8C,EAAkBC,cAAY,SAACC,GAC/BA,EAAGC,gBAAkBD,EAAGE,SAChB,MAAZN,OAAY,EAAZA,EAAchC,UAAUuC,qBACxBP,EAAahC,UAAUuC,mBAAmBH,EAC5C,EAAG,CAAEJ,IAUL,OARAQ,EAASA,UAAC,WACJR,EACFH,GAAiBA,IAEjBC,GAAgBA,GAEpB,EAAG,CAAEE,EAAcH,EAAeC,IAE3BE,GACLN,MAACK,EAAQ,CAACG,gBAAiBA,EAAevC,SACvCqC,EAAajC,OAAM0B,EACfO,CAAAA,EAAAA,EAAahC,UACbgC,EAAa/B,WAGjB,IACP,aDmCgB,WAEd,OADwBT,IAAhBH,WAEV,sCAMgB,WACd,IAAAoD,EAA+BjD,IAAvBJ,EAAKqD,EAALrD,MAAOG,EAAWkD,EAAXlD,YACf,GAAqB,IAAjBH,EAAMoC,OACR,MAAU,IAAAkB,MAAM,uDAElB,MAAO,CADOtD,EAAMA,EAAMoC,OAAS,GAAGH,MACtB9B,EAClB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-modal-port",
3
- "version": "0.1.5",
3
+ "version": "0.2.1",
4
4
  "description": "Launch modals from any React component.",
5
5
  "type": "module",
6
6
  "source": "src/index.ts",
package/readme.md CHANGED
@@ -84,10 +84,14 @@ const Page: React.FC = () => {
84
84
  {
85
85
  decideYay: () => setDecision(true),
86
86
  decideNay: () => setDecision(false),
87
- leaveMeAlone: () => {},
87
+ // Provide an `onBackdropClick` resolver to have it passed to
88
+ // the Backdrop component
89
+ onBackdropClick: () => {},
88
90
  },
89
- // Optional name of the `onBackdropClick` resolver
90
- "leaveMeAlone"
91
+ // Optionally, add further props to be passed to the modal component
92
+ {
93
+ timeLeft: Math.random() * 86400
94
+ }
91
95
  );
92
96
  }
93
97
 
@@ -113,7 +117,7 @@ The `launchModal` function expects the following arguments:
113
117
  |----------|------|-------------|
114
118
  | render | `React.FC` | A function that renders the modal and returns a `ReactNode`. |
115
119
  | resolvers | `{ [key: string]: (...args: any[]) => Promise<void>\|void }` | An object of resolver functions that will be passed as props to `render`. |
116
- | onBackdropClickUse | `string` | Optional: The key of the resolver function in the `resolvers` object that should be passed to the backdrop component’s `onBackdropClick` prop. |
120
+ | props | `{ [key: string]: any }` | Optional: Further props you’d like to pass to the modal component in `render`. |
117
121
 
118
122
  Modals can be created and designed to fully fit your needs. The only requirement is to define the functions to resolve them, for example, when clicking a button. The modal component for the example above could look like this:
119
123
 
@@ -170,8 +174,6 @@ So you could adapt the `onClick` handler in our earlier example as follows:
170
174
  letMeThinkAboutIt: (p: Promise) => p,
171
175
  leaveMeAlone: () => {},
172
176
  },
173
- // Optional name of the `onBackdropClick` resolver
174
- "leaveMeAlone"
175
177
  );
176
178
  }
177
179
 
@@ -262,9 +264,17 @@ export const AskForNameModal: React.FC<AskForNameModalProps> = ({
262
264
  };
263
265
 
264
266
  const onButtonClick = () => {
265
- launchModal(ConfirmModal, {
266
- confirm: () => provideName(modalState.name),
267
- });
267
+ launchModal(
268
+ ConfirmModal,
269
+ {
270
+ // Chain first modal’s resolution to the second one’s
271
+ confirm: () => provideName(modalState.name),
272
+ },
273
+ // Pass the name on to the ConfirmModal for rendering
274
+ {
275
+ name: modalState.name,
276
+ }
277
+ );
268
278
  };
269
279
 
270
280
  return (
package/types/index.d.ts CHANGED
@@ -9,17 +9,21 @@ export type LaunchModalResolvers = {
9
9
  [key: string]: ModalResolver;
10
10
  };
11
11
 
12
+ export type LaunchModalProps = {
13
+ [key: string]: any;
14
+ };
15
+
12
16
  export type ModalStackItem = {
13
17
  render: React.FunctionComponent<LaunchModalResolvers>;
14
18
  resolvers: LaunchModalResolvers;
15
- onBackdropClickUse?: string;
19
+ props: LaunchModalProps;
16
20
  state: ModalState;
17
21
  };
18
22
 
19
23
  export type LaunchModal = (
20
- render: React.FunctionComponent<LaunchModalResolvers>,
24
+ render: React.FunctionComponent<LaunchModalResolvers & LaunchModalProps>,
21
25
  resolvers: LaunchModalResolvers,
22
- onBackdropClickUse?: string,
26
+ props?: LaunchModalProps,
23
27
  ) => void;
24
28
 
25
29
  export type ModalState = { [key: string]: any };