react-modal-global
Advanced tools
Comparing version 2023.5.22-experimental-2 to 2023.5.26-experimental
import EventEmitter from 'eventemitter3'; | ||
import { ReactElement, Component } from 'react'; | ||
import { JSXElementConstructor, ExoticComponent, ComponentProps, ReactNode } from 'react'; | ||
import { HasRequiredKeys } from 'type-fest'; | ||
import { IsAny } from 'type-fest/source/is-any'; | ||
interface ModalState { | ||
interface ExternalStore<T> { | ||
subscribe(callback: () => void): () => void; | ||
getSnapshot(): T; | ||
} | ||
interface ModalSnapshot { | ||
active: boolean; | ||
@@ -12,3 +17,5 @@ windows: ModalWindow[]; | ||
*/ | ||
type ModalComponent<P = unknown> = ((props: P) => ReactElement | null) | (() => ReactElement | null) | (new (props: P) => Component<P>) | (new () => Component); | ||
type ModalComponent<P = unknown> = JSXElementConstructor<P> | ExoticComponent<P>; | ||
type ModalComponentProps<T extends ModalComponent> = IsAny<ComponentProps<T>> extends true ? never : ComponentProps<T>; | ||
type ModalNamedComponents = Record<keyof never, ModalComponent<any>>; | ||
interface ModalParams { | ||
@@ -155,6 +162,12 @@ /** | ||
} | ||
declare class ModalController { | ||
interface ModalControllerConfig<Components extends ModalNamedComponents = ModalNamedComponents> { | ||
components: Components; | ||
defaultParams: Partial<ModalParams>; | ||
} | ||
declare class ModalController<Config extends Partial<ModalControllerConfig> = ModalControllerConfig> implements ExternalStore<ModalSnapshot> { | ||
#private; | ||
private config?; | ||
protected windows: Set<ModalWindowAny>; | ||
protected events: EventEmitter<ModalControllerEvents>; | ||
constructor(config?: Config | undefined); | ||
protected set active(value: boolean); | ||
@@ -196,2 +209,3 @@ get active(): boolean; | ||
open<P>(component: ModalComponent<P>, ...[modalParams]: ModalWindowParams<P>): ModalWindow<P>; | ||
openNamed<Name extends keyof Config["components"], P extends ModalComponentProps<NonNullable<Config["components"]>[Name]>>(componentName: Name, ...[modalParams]: ModalWindowParams<P>): ModalWindow<P>; | ||
/** | ||
@@ -203,2 +217,3 @@ * Replaces the last modal window in the queue with a new one. | ||
replace<P>(component: ModalComponent<P>, ...[modalParams]: ModalWindowParams<P>): ModalWindow<P>; | ||
replaceNamed<Name extends keyof Config["components"], P extends ModalComponentProps<NonNullable<Config["components"]>[Name]>>(componentName: Name, ...[modalParams]: ModalWindowParams<P>): ModalWindow<P>; | ||
/** | ||
@@ -220,2 +235,3 @@ * Closes modal by its instance. | ||
closeAll(): void; | ||
private getNamedComponent; | ||
/** | ||
@@ -237,3 +253,5 @@ * Subscribes to `event` with `listener`. | ||
*/ | ||
observe(callback: (state: ModalState) => void): () => void; | ||
subscribe(callback: () => void): () => void; | ||
getSnapshot(): ModalSnapshot; | ||
private refreshSnapshot; | ||
} | ||
@@ -271,6 +289,21 @@ | ||
/** | ||
* Provides access to modal state and listens to updates. | ||
* Shorthand for `useSyncExternalStore`. | ||
*/ | ||
declare function useModalState(controller: ModalController): ModalState; | ||
declare function useModalSnapshot(controller: ModalController): ModalSnapshot; | ||
export { ModalContainer, ModalController, ModalWindow, useModalState, useModalWindow }; | ||
interface ModalPortalProps { | ||
/** | ||
* If not presented, will be used from the context. | ||
*/ | ||
controller: ModalController; | ||
onClose?(): void; | ||
children: ReactNode; | ||
} | ||
/** | ||
* Renders given children as a modal. | ||
* | ||
* Can render | ||
*/ | ||
declare function ModalPortal(props: ModalPortalProps): React.ReactPortal; | ||
export { ModalContainer, ModalController, ModalPortal, ModalWindow, useModalSnapshot, useModalWindow }; |
@@ -1,14 +0,18 @@ | ||
'use strict';Object.defineProperty(exports,"__esModule",{value:!0});var EventEmitter=require("eventemitter3"),jsxRuntime=require("react/jsx-runtime"),react=require("react");function _interopDefaultLegacy(a){return a&&"object"===typeof a&&"default"in a?a:{"default":a}}var EventEmitter__default=_interopDefaultLegacy(EventEmitter); | ||
function __classPrivateFieldGet(a,b,c,e){if("a"===c&&!e)throw new TypeError("Private accessor was defined without a getter");if("function"===typeof b?a!==b||!e:!b.has(a))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===c?e:"a"===c?e.call(a):e?e.value:b.get(a)} | ||
function __classPrivateFieldSet(a,b,c,e,d){if("m"===e)throw new TypeError("Private method is not writable");if("a"===e&&!d)throw new TypeError("Private accessor was defined without a setter");if("function"===typeof b?a!==b||!d:!b.has(a))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===e?d.call(a,c):d?d.value=c:b.set(a,c),c}class Deffered{constructor(){this.promise=new Promise((a,b)=>{this.resolve=a;this.reject=b})}} | ||
function classWithModifiers(a,...b){b=b.filter(Boolean);if(!b.length)return a;b=b.map(c=>a+"--"+c);return a+" "+b.join(" ")}function serialize(a){function b(){let c=new WeakSet;return(e,d)=>{if("object"===typeof d&&null!==d){if(c.has(d))return;c.add(d)}return d}}return null==a?String(a):JSON.stringify(a,function(){let c=b();return(e,d)=>{d=d instanceof Function?d.name===e||0===d.name.length?d.toString():d.name:d;return c(e,d)}}())} | ||
function stopPropagation(a){return({target:b,currentTarget:c})=>{b instanceof Element&&c instanceof Element&&b!==c||(null===a||void 0===a?void 0:a())}}function cyrb53(a,b=0){let c=3735928559^b;b^=1103547991;for(let e=0,d;e<a.length;e++)d=a.charCodeAt(e),c=Math.imul(c^d,2654435761),b=Math.imul(b^d,1597334677);c=Math.imul(c^c>>>16,2246822507);c^=Math.imul(b^b>>>13,3266489909);b=Math.imul(b^b>>>16,2246822507);b^=Math.imul(c^c>>>13,3266489909);return 4294967296*(2097151&b)+(c>>>0)} | ||
'use strict';Object.defineProperty(exports,"__esModule",{value:!0});var EventEmitter=require("eventemitter3"),jsxRuntime=require("react/jsx-runtime"),react=require("react"),reactDom=require("react-dom");function _interopDefaultLegacy(a){return a&&"object"===typeof a&&"default"in a?a:{"default":a}}var EventEmitter__default=_interopDefaultLegacy(EventEmitter); | ||
function __classPrivateFieldGet(a,b,c,d){if("a"===c&&!d)throw new TypeError("Private accessor was defined without a getter");if("function"===typeof b?a!==b||!d:!b.has(a))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===c?d:"a"===c?d.call(a):d?d.value:b.get(a)} | ||
function __classPrivateFieldSet(a,b,c,d,e){if("m"===d)throw new TypeError("Private method is not writable");if("a"===d&&!e)throw new TypeError("Private accessor was defined without a setter");if("function"===typeof b?a!==b||!e:!b.has(a))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===d?e.call(a,c):e?e.value=c:b.set(a,c),c}class Deffered{constructor(){this.promise=new Promise((a,b)=>{this.resolve=a;this.reject=b})}} | ||
function classWithModifiers(a,...b){b=b.filter(Boolean);if(!b.length)return a;b=b.map(c=>a+"--"+c);return a+" "+b.join(" ")}function serialize(a){function b(){let c=new WeakSet;return(d,e)=>{if("object"===typeof e&&null!==e){if(c.has(e))return;c.add(e)}return e}}return null==a?String(a):JSON.stringify(a,function(){let c=b();return(d,e)=>{e=e instanceof Function?e.name===d||0===e.name.length?e.toString():e.name:e;return c(d,e)}}())} | ||
function stopPropagation(a){return({target:b,currentTarget:c})=>{b instanceof Element&&c instanceof Element&&b!==c||(null===a||void 0===a?void 0:a())}}function cyrb53(a,b=0){let c=3735928559^b;b^=1103547991;for(let d=0,e;d<a.length;d++)e=a.charCodeAt(d),c=Math.imul(c^e,2654435761),b=Math.imul(b^e,1597334677);c=Math.imul(c^c>>>16,2246822507);c^=Math.imul(b^b>>>13,3266489909);b=Math.imul(b^b>>>16,2246822507);b^=Math.imul(c^c>>>13,3266489909);return 4294967296*(2097151&b)+(c>>>0)} | ||
let MODAL_SEED=Date.now(),DEFAULT_PARAMS={id:-1,closable:!0,keepMounted:!1,layer:0,label:"Content is unknown. Bad guy didn't set a label.",weak:!1,fork:!1}; | ||
class ModalWindow{constructor(a,b){this.close=()=>{this.closed=!0;this.deffered.resolve();this.events.emit("close")};this.serialized=serialize({component:a,params:b});this.id=cyrb53(this.serialized,MODAL_SEED);this.component=a;this.params=Object.assign(Object.assign({},DEFAULT_PARAMS),b);this.closed=!1;this.events=new EventEmitter__default["default"];this.deffered=new Deffered;this.events.emit("open")}then(a,b){return this.deffered.promise.then(a,b)}on(a,b){this.events.on(a,b);return()=>{this.events.off(a, | ||
b)}}}var _ModalController_active; | ||
class ModalController{constructor(){this.windows=new Set;this.events=new EventEmitter__default["default"];_ModalController_active.set(this,!1)}set active(a){__classPrivateFieldSet(this,_ModalController_active,a,"f")}get active(){return __classPrivateFieldGet(this,_ModalController_active,"f")}hide(){!1!==this.active&&(this.active=!1,this.events.emit("update"))}show(){!0!==this.active&&(this.active=!0,this.events.emit("update"))}open(a,...[b]){let c=new ModalWindow(a,b);c.on("close",()=>this.close(c)); | ||
if(this.active&&(a=[...this.windows].at(-1),(null===a||void 0===a?void 0:a.id)===c.id))return a;0<this.windows.size&&!this.active&&this.windows.clear();this.windows.add(c);this.events.emit("add",c);this.show();return c}replace(a,...[b]){let c=[...this.windows].at(-1);null!=c&&this.windows.delete(c);return this.open(a,b)}close(a){0!==this.windows.size&&this.windows.has(a)&&(1===this.windows.size?this.hide():(this.windows.delete(a),this.events.emit("remove",a)))}closeById(a){[...this.windows].filter(b=> | ||
b.params.id===a).forEach(b=>this.close(b))}closeByComponent(a,b){[...this.windows].filter(c=>c.component!==a||null!=b&&c.params.params!==b?!1:!0).forEach(c=>this.close(c))}closeAll(){this.windows.forEach(a=>this.close(a))}on(a,b){this.events.on(a,b);return()=>{this.events.off(a,b)}}observe(a){let b=()=>{const c={active:this.active,windows:[...this.windows]};a(c)};b();this.events.on("add",b);this.events.on("remove",b);this.events.on("update",b);return()=>{this.events.off("add",b);this.events.off("remove", | ||
b);this.events.off("update",b)}}}_ModalController_active=new WeakMap;let modalContext=react.createContext(null);function useModalWindow(){let a=react.useContext(modalContext);if(!a)throw Error(`ModalError: ${useModalWindow.name} must be used within a modal context.`);return a}let DEFAULT_STATE={active:!1,windows:[]};function useModalState(a){let [b,c]=react.useState(DEFAULT_STATE);react.useEffect(()=>a.observe(c),[a]);return b} | ||
function ModalContainer(a){var b;let {active:c,windows:e}=useModalState(a.controller),d=null!==(b=a.className)&&void 0!==b?b:"modal";a=e.reduceRight((f,g)=>{null==f[g.params.layer]&&(f[g.params.layer]=g);return f},[]);return jsxRuntime.jsx("div",Object.assign({className:classWithModifiers(d,c&&"active"),"aria-modal":!0,"aria-hidden":!c},{children:a.map(f=>jsxRuntime.jsx("div",Object.assign({className:classWithModifiers(d+"__container"),onClick:stopPropagation(function(){f.params.closable&&f.close()})}, | ||
{children:jsxRuntime.jsx(modalContext.Provider,Object.assign({value:f},{children:react.createElement(f.component,Object.assign({},f.params,{key:f.id}))}))}),f.id))}))}exports.ModalContainer=ModalContainer;exports.ModalController=ModalController;exports.ModalWindow=ModalWindow;exports.useModalState=useModalState;exports.useModalWindow=useModalWindow | ||
b)}}}var _ModalController_active,_ModalController_snapshot; | ||
class ModalController{constructor(a){this.config=a;this.windows=new Set;this.events=new EventEmitter__default["default"];_ModalController_active.set(this,!1);_ModalController_snapshot.set(this,{active:this.active,windows:[]});this.subscribe(()=>this.refreshSnapshot())}set active(a){__classPrivateFieldSet(this,_ModalController_active,a,"f")}get active(){return __classPrivateFieldGet(this,_ModalController_active,"f")}hide(){!1!==this.active&&(this.active=!1,this.events.emit("update"))}show(){!0!==this.active&& | ||
(this.active=!0,this.events.emit("update"))}open(a,...[b]){var c;let d=new ModalWindow(a,Object.assign(Object.assign({},null===(c=this.config)||void 0===c?void 0:c.defaultParams),b));d.on("close",()=>this.close(d));if(this.active&&(a=[...this.windows].at(-1),(null===a||void 0===a?void 0:a.id)===d.id))return a;0<this.windows.size&&!this.active&&this.windows.clear();this.windows.add(d);this.events.emit("add",d);this.show();return d}openNamed(a,...[b]){a=this.getNamedComponent(a);return this.open(a, | ||
b)}replace(a,...[b]){let c=[...this.windows].at(-1);null!=c&&this.windows.delete(c);return this.open(a,b)}replaceNamed(a,...[b]){a=this.getNamedComponent(a);return this.replace(a,b)}close(a){0!==this.windows.size&&this.windows.has(a)&&(1===this.windows.size?this.hide():(this.windows.delete(a),this.events.emit("remove",a)))}closeById(a){[...this.windows].filter(b=>b.params.id===a).forEach(b=>this.close(b))}closeByComponent(a,b){[...this.windows].filter(c=>c.component!==a||null!=b&&c.params.params!== | ||
b?!1:!0).forEach(c=>this.close(c))}closeAll(){this.windows.forEach(a=>this.close(a))}getNamedComponent(a){let b={config:this.config,componentName:a};if(null==this.config)throw Error("ModalController `config` is not defined.",{cause:b});if(null==this.config.components)throw Error("ModalController `config.components` is not defined.",{cause:b});return this.config.components[a]}on(a,b){this.events.on(a,b);return()=>{this.events.off(a,b)}}subscribe(a){this.events.on("add",a);this.events.on("remove",a); | ||
this.events.on("update",a);return()=>{this.events.off("add",a);this.events.off("remove",a);this.events.off("update",a)}}getSnapshot(){return __classPrivateFieldGet(this,_ModalController_snapshot,"f")}refreshSnapshot(){__classPrivateFieldSet(this,_ModalController_snapshot,{active:this.active,windows:[...this.windows]},"f")}}_ModalController_active=new WeakMap;_ModalController_snapshot=new WeakMap;let modalContext=react.createContext(null); | ||
function useModalWindow(){let a=react.useContext(modalContext);if(!a)throw Error(`ModalError: ${useModalWindow.name} must be used within a modal context.`);return a}function useModalSnapshot(a){return react.useSyncExternalStore(a.subscribe.bind(a),a.getSnapshot.bind(a))} | ||
function ModalContainer(a){var b;let {active:c,windows:d}=useModalSnapshot(a.controller),e=null!==(b=a.className)&&void 0!==b?b:"modal";a=d.reduceRight((f,g)=>{null==f[g.params.layer]&&(f[g.params.layer]=g);return f},[]);return jsxRuntime.jsx("div",Object.assign({className:classWithModifiers(e,c&&"active"),"aria-modal":!0,"aria-hidden":!c},{children:a.map(f=>jsxRuntime.jsx("div",Object.assign({className:classWithModifiers(e+"__container"),onClick:stopPropagation(function(){f.params.closable&&f.close()})}, | ||
{children:jsxRuntime.jsx(modalContext.Provider,Object.assign({value:f},{children:react.createElement(f.component,Object.assign({},f.params,{key:f.id}))}))}),f.id))}))} | ||
function ModalPortal(a){let b=react.useId();react.useEffect(()=>()=>{a.controller.closeById(b)},[a.controller,b]);return react.useMemo(()=>{function c(f){f=null===f||void 0===f?void 0:f.parentElement;null!=f&&(f.replaceWith(d),d.setAttribute("class",f.className))}let d=document.createElement("div"),e=a.controller.open(function(){return jsxRuntime.jsx("div",{ref:c})},{id:b});if(a.onClose)e.on("close",a.onClose);return reactDom.createPortal(a.children,d,b)},[a.controller,b])} | ||
exports.ModalContainer=ModalContainer;exports.ModalController=ModalController;exports.ModalPortal=ModalPortal;exports.ModalWindow=ModalWindow;exports.useModalSnapshot=useModalSnapshot;exports.useModalWindow=useModalWindow |
{ | ||
"name": "react-modal-global", | ||
"version": "2023.05.22-experimental-2", | ||
"version": "2023.5.26-experimental", | ||
"description": "Highly reusable React Modal that can be run from useEffect.", | ||
@@ -16,3 +16,2 @@ "main": "dist/index.ts", | ||
"eventemitter3": "^5.0.0", | ||
"uuid": "^9.0.0", | ||
"type-fest": "^3.5.5" | ||
@@ -36,3 +35,3 @@ }, | ||
"tslib": "^2.4.0", | ||
"typescript": "^4.9.5" | ||
"typescript": "^4.9.4" | ||
}, | ||
@@ -39,0 +38,0 @@ "scripts": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
35766
3
327
0
- Removeduuid@^9.0.0
- Removeduuid@9.0.1(transitive)