react-modal-global
Advanced tools
Comparing version 1.2.0-rc5 to 1.2.0
import EventEmitter from 'eventemitter3'; | ||
import { ReactElement, ReactNode, ComponentLifecycle } from 'react'; | ||
import { HasRequiredKeys, SetOptional } from 'type-fest'; | ||
import { ReactElement, ReactNode } from 'react'; | ||
import { HasRequiredKeys } from 'type-fest'; | ||
/** | ||
* A modal component can be either a function component or a class component. | ||
*/ | ||
type ModalComponent<P = unknown> = ((props: P) => ReactElement | null) | (() => ReactElement | null); | ||
@@ -152,8 +155,9 @@ interface ModalParams { | ||
/** | ||
* Subscribes on event. | ||
* Used for container component to get the current state. | ||
* | ||
* @returns `unsubscribe` method | ||
* Observes the state and calls the callback on any changes. | ||
* | ||
* @returns `unsubscribe` method to stop observing. | ||
*/ | ||
observe(callback: (state: ModalState) => void): () => void; | ||
on<T extends keyof Events>(event: T, callback: (state: ModalState) => void): () => void; | ||
} | ||
@@ -180,3 +184,5 @@ declare const Modal: ModalController; | ||
} | ||
/** | ||
* Modal container component. Renders modal windows. | ||
*/ | ||
declare function ModalContainer(props: ModalContainerProps): JSX.Element; | ||
@@ -189,45 +195,8 @@ | ||
* It has 3 overloads: | ||
* 1. `useModalContext<ModalComponent>()` - infers the props from the class component type. | ||
* 2. `useModalContext<typeof ModalComponent>()` - infers the props from the function component type. | ||
* 3. `useModalContext<unknown>()` - infers any type besides the above. | ||
* 1. `useModalContext<typeof ModalClassComponent>()` - infers the props from the class component type. | ||
* 2. `useModalContext<typeof ModalFunctionComponent>()` - infers the props from the function component type. | ||
* 3. `useModalContext<{ c: 3 }>()` - you can enter props by yourself too. | ||
*/ | ||
declare function useModalContext<T>(): ModalWindow<T extends ComponentLifecycle<infer P, unknown> | ((props: infer P) => ReactNode) ? P : T>; | ||
declare function useModalContext<T>(): any; | ||
interface ModalViewProps { | ||
controller?: ModalController; | ||
onClosed?(): void; | ||
children: ReactNode; | ||
} | ||
/** | ||
* Renders given children as a modal. | ||
* | ||
* Can render | ||
*/ | ||
declare function ModalView(props: ModalViewProps): null; | ||
interface ModalOpenProps<ComponentProps> extends Partial<ModalParams> { | ||
component: ModalComponent<ComponentProps>; | ||
componentProps: ComponentProps; | ||
onClosed?(): void; | ||
controller?: ModalController; | ||
} | ||
/** | ||
* Opens a modal with given component and props. | ||
* | ||
* Similar to `ModalView`, but it opens a modal instead of rendering it as a child. | ||
* It can be closed by component and given id. | ||
*/ | ||
declare function ModalOpen<ComponentProps>(props: keyof ComponentProps extends never ? SetOptional<ModalOpenProps<ComponentProps>, "componentProps"> : ModalOpenProps<ComponentProps>): null; | ||
interface ModalGroupProps { | ||
/** | ||
* Called when a modal from this group is closed. | ||
*/ | ||
onClosed?(): void; | ||
/** | ||
* Called when all modals from this group are closed. | ||
*/ | ||
onAllClosed?(): void; | ||
children: ReactElement<ModalViewProps | ModalOpenProps<unknown>>[]; | ||
} | ||
declare function ModalGroup(props: ModalGroupProps): JSX.Element; | ||
export { Modal, ModalContainer, ModalController, ModalGroup, ModalOpen, ModalView, useModalContext }; | ||
export { Modal, ModalContainer, ModalController, useModalContext }; |
@@ -1,2 +0,2 @@ | ||
'use strict';Object.defineProperty(exports,"__esModule",{value:!0});var EventEmitter=require("eventemitter3"),jsxRuntime=require("react/jsx-runtime"),react=require("react"),_=require("lodash"),reactUse=require("react-use");function _interopDefaultLegacy(a){return a&&"object"===typeof a&&"default"in a?a:{"default":a}}var EventEmitter__default=_interopDefaultLegacy(EventEmitter),___default=_interopDefaultLegacy(_); | ||
'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,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)} | ||
@@ -6,12 +6,8 @@ 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} | ||
function stopPropagation(a){return({target:b,currentTarget:c})=>{b instanceof Element&&c instanceof Element&&b!==c||(null===a||void 0===a?void 0:a())}}var _ModalController_isOpen;let DEFAULT_PARAMS={id:0,closable:!0,weak:!1,fork:!1}; | ||
class ModalController{constructor(){_ModalController_isOpen.set(this,!1);this.windows=new Set;this.events=new EventEmitter__default["default"]}set isOpen(a){__classPrivateFieldSet(this,_ModalController_isOpen,a,"f")}get isOpen(){return __classPrivateFieldGet(this,_ModalController_isOpen,"f")}open(a,...[b]){let c=()=>{},d=new Promise(g=>c=g);b=Object.assign(Object.assign({},DEFAULT_PARAMS),b);let e={component:a,params:b,close:()=>{this.remove(e);c()},closed:!1,focused:!0};this.add(e);return Object.assign(Object.assign({}, | ||
e),{then(g,k){return d.then(g,k)}})}replace(a,...[b]){let c=[...this.windows].at(-1);null!=c&&this.windows.delete(c);return this.open(a,b)}add(a){!1===this.isOpen&&0<this.windows.size&&this.windows.clear();this.isOpen=!0;this.windows.add(a);this.events.emit("add",a)}remove(a){if(this.windows.has(a)){if(1===this.windows.size&&(this.isOpen=!1,!a.params.weak)){this.events.emit("update");return}this.windows.delete(a);this.events.emit("remove",a)}}findByComponent(a,b){return[...this.windows].filter(c=> | ||
c.component!==a?!1:null!=b?serialize(b)===serialize(c.params):!0)}findById(a){return[...this.windows].filter(b=>b.params.id===a)}closeByComponent(a,b){this.findByComponent(a,b).forEach(c=>c.close())}closeById(a){this.findById(a).forEach(b=>b.close())}closeAll(){this.isOpen=!1;this.events.emit("update")}observe(a){let b=()=>{const c={isOpen:this.isOpen,windows:[...this.windows]};a(c)};this.events.on("add",b);this.events.on("remove",b);this.events.on("update",b);this.events.emit("update");return()=> | ||
{this.events.off("add",b);this.events.off("remove",b);this.events.off("update",b)}}on(a,b){let c=()=>{const d={isOpen:this.isOpen,windows:[...this.windows]};b(d)};this.events.on(a,c);return()=>{this.events.off(a,c)}}}_ModalController_isOpen=new WeakMap;let Modal=new ModalController,modalContext=react.createContext(null),DEFAULT_STATE={isOpen:!1,windows:[]}; | ||
function ModalContainer(a){var b,c;let [d,e]=react.useState(DEFAULT_STATE);react.useEffect(()=>(a.controller||Modal).observe(e),[a.controller]);let g=a.className||"modal",k=a.template||react.Fragment,f=d.windows.at(-1),l=(null===(b=null===f||void 0===f?void 0:f.params)||void 0===b?0:b.closable)?stopPropagation(f.close):void 0;b=f?Object.assign(Object.assign({},f),{closed:!d.isOpen,focused:!0}):null;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",Object.assign({className:classWithModifiers(g, | ||
d.isOpen&&"active"),"aria-modal":!0,"aria-hidden":!d.isOpen},{children:jsxRuntime.jsx("div",Object.assign({className:g+"__container",onClick:l},{children:jsxRuntime.jsx(k,{children:jsxRuntime.jsx(modalContext.Provider,Object.assign({value:b},{children:(null===f||void 0===f?void 0:f.component)&&react.createElement(f.component,Object.assign({},f.params,{key:null===(c=null===f||void 0===f?void 0:f.params)||void 0===c?void 0:c.id}))}))})}))})),[...d.windows].reverse().filter(h=>h.params.fork).map(h=> | ||
jsxRuntime.jsx("div",Object.assign({className:classWithModifiers(g,"active"),"aria-modal":!0},{children:jsxRuntime.jsx("div",Object.assign({className:g+"__container",onClick:h.params.closable?stopPropagation(h.close):void 0},{children:jsxRuntime.jsx(modalContext.Provider,Object.assign({value:h},{children:jsxRuntime.jsx(h.component,Object.assign({},h.params))}))}))}),h.params.id))]})} | ||
function useModalContext(){let a=react.useContext(modalContext);if(!a)throw Error("ModalError: useModalContext must be used within a modalContext");return a}function ModalView(a){let b=react.useId();react.useEffect(()=>{let c=(a.controller||Modal).open(function(){return jsxRuntime.jsx(jsxRuntime.Fragment,{children:a.children})},{id:b});c.then(a.onClosed);return()=>{setTimeout(()=>c.close())}},[a.children,a.controller]);reactUse.useUnmount(()=>{(a.controller||Modal).closeById(b)});return null} | ||
function ModalOpen(a){react.useEffect(()=>{let b=a.controller||Modal,c=Object.assign(Object.assign({},a.componentProps),___default["default"].omit(a,"component","componentProps","controller")),d=b.open(a.component,c);d.then(a.onClosed);return()=>{setTimeout(()=>d.close())}},[a.component,serialize(a.componentProps),a.controller]);return null} | ||
function ModalGroup(a){let b=react.useRef(new ModalController);react.useEffect(()=>{if(null!=b.current)return b.current.on("remove",d=>{var e,g;null===(e=a.onClosed)||void 0===e?void 0:e.call(a);d.isOpen||(null===(g=a.onAllClosed)||void 0===g?void 0:g.call(a))})},[a.children]);let c=a.children.map(d=>{const e=b.current;return react.cloneElement(d,Object.assign(Object.assign({},d.props),{controller:e}))});return jsxRuntime.jsx(jsxRuntime.Fragment,{children:c})}exports.Modal=Modal; | ||
exports.ModalContainer=ModalContainer;exports.ModalController=ModalController;exports.ModalGroup=ModalGroup;exports.ModalOpen=ModalOpen;exports.ModalView=ModalView;exports.useModalContext=useModalContext | ||
class ModalController{constructor(){_ModalController_isOpen.set(this,!1);this.windows=new Set;this.events=new EventEmitter__default["default"]}set isOpen(a){__classPrivateFieldSet(this,_ModalController_isOpen,a,"f")}get isOpen(){return __classPrivateFieldGet(this,_ModalController_isOpen,"f")}open(a,...[b]){let c=()=>{},d=new Promise(f=>c=f);b=Object.assign(Object.assign({},DEFAULT_PARAMS),b);let e={component:a,params:b,close:()=>{this.remove(e);c()},closed:!1,focused:!0};this.add(e);return Object.assign(Object.assign({}, | ||
e),{then(f,h){return d.then(f,h)}})}replace(a,...[b]){let c=[...this.windows].at(-1);null!=c&&this.windows.delete(c);return this.open(a,b)}add(a){!1===this.isOpen&&0<this.windows.size&&this.windows.clear();this.isOpen=!0;this.windows.add(a);this.events.emit("add",a)}remove(a){if(this.windows.has(a)){if(1===this.windows.size&&(this.isOpen=!1,!a.params.weak)){this.events.emit("update");return}this.windows.delete(a);this.events.emit("remove",a)}}findByComponent(a,b){return[...this.windows].filter(c=> | ||
c.component!==a?!1:null!=b?serialize(b)===serialize(c.params):!0)}findById(a){return[...this.windows].filter(b=>b.params.id===a)}closeByComponent(a,b){this.findByComponent(a,b).forEach(c=>c.close())}closeById(a){this.findById(a).forEach(b=>b.close())}closeAll(){this.isOpen=!1;this.events.emit("update")}observe(a){let b=()=>{const c={isOpen:this.isOpen,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_isOpen=new WeakMap;let Modal=new ModalController,modalContext=react.createContext(null);function useModalContext(){let a=react.useContext(modalContext);if(!a)throw Error("ModalError: useModalContext must be used within a modalContext");return a}let DEFAULT_STATE={isOpen:!1,windows:[]};function useModalState(a=Modal){let [b,c]=react.useState(DEFAULT_STATE);react.useEffect(()=>a.observe(c),[a]);return b} | ||
function ModalContainer(a){var b,c;let d=useModalState(a.controller),e=a.className||"modal";a=a.template||react.Fragment;let f=d.windows.at(-1),h=(null===(b=null===f||void 0===f?void 0:f.params)||void 0===b?0:b.closable)?stopPropagation(f.close):void 0;b=f?Object.assign(Object.assign({},f),{closed:!d.isOpen,focused:!0}):null;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",Object.assign({className:classWithModifiers(e,d.isOpen&&"active"),"aria-modal":!0,"aria-hidden":!d.isOpen}, | ||
{children:jsxRuntime.jsx("div",Object.assign({className:e+"__container",onClick:h},{children:jsxRuntime.jsx(modalContext.Provider,Object.assign({value:b},{children:jsxRuntime.jsx(a,{children:(null===f||void 0===f?void 0:f.component)&&react.createElement(f.component,Object.assign({},f.params,{key:null===(c=null===f||void 0===f?void 0:f.params)||void 0===c?void 0:c.id}))})}))}))})),[...d.windows].reverse().filter(g=>g.params.fork).map(g=>jsxRuntime.jsx("div",Object.assign({className:classWithModifiers(e, | ||
"active"),"aria-modal":!0},{children:jsxRuntime.jsx("div",Object.assign({className:e+"__container",onClick:g.params.closable?stopPropagation(g.close):void 0},{children:jsxRuntime.jsx(modalContext.Provider,Object.assign({value:g},{children:jsxRuntime.jsx(g.component,Object.assign({},g.params))}))}))}),g.params.id))]})}exports.Modal=Modal;exports.ModalContainer=ModalContainer;exports.ModalController=ModalController;exports.useModalContext=useModalContext |
{ | ||
"name": "react-modal-global", | ||
"version": "1.2.0-rc5", | ||
"version": "1.2.0", | ||
"description": "Highly reusable React Modal that can be run from useEffect.", | ||
@@ -15,5 +15,3 @@ "main": "dist/index.ts", | ||
"dependencies": { | ||
"eventemitter3": "^5.0.0", | ||
"lodash": "^4.17.21", | ||
"react-use": "^17.4.0" | ||
"eventemitter3": "^5.0.0" | ||
}, | ||
@@ -26,3 +24,2 @@ "devDependencies": { | ||
"@types/jest": "^29.4.0", | ||
"@types/lodash": "^4.14.191", | ||
"@types/react": "^18.0.15", | ||
@@ -43,8 +40,6 @@ "eslint": "^8.6.0", | ||
"build": "rollup --config", | ||
"watch": "ncc build src/index.ts -w", | ||
"compile": "npm run build && npm run start && npm run post-fix", | ||
"help": "ncc", | ||
"reinstall": "rimraf node_moduless && npm ci --silent", | ||
"test": "react-scripts test", | ||
"test:coverage": "react-scripts test --coverage *", | ||
"post-fix": "eslint out --fix" | ||
"test:coverage": "npm test -- --coverage *", | ||
"prepublish": "rimraf build && npm run build" | ||
}, | ||
@@ -51,0 +46,0 @@ "repository": { |
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
2
17
0
25483
218
- Removedlodash@^4.17.21
- Removedreact-use@^17.4.0
- Removed@babel/runtime@7.26.0(transitive)
- Removed@jridgewell/sourcemap-codec@1.5.0(transitive)
- Removed@types/js-cookie@2.2.7(transitive)
- Removed@xobotyi/scrollbar-width@1.9.5(transitive)
- Removedcopy-to-clipboard@3.3.3(transitive)
- Removedcss-in-js-utils@3.1.0(transitive)
- Removedcss-tree@1.1.3(transitive)
- Removedcsstype@3.1.3(transitive)
- Removederror-stack-parser@2.1.4(transitive)
- Removedfast-deep-equal@3.1.3(transitive)
- Removedfast-shallow-equal@1.0.0(transitive)
- Removedfastest-stable-stringify@2.0.2(transitive)
- Removedhyphenate-style-name@1.1.0(transitive)
- Removedinline-style-prefixer@7.0.1(transitive)
- Removedjs-cookie@2.2.1(transitive)
- Removedlodash@4.17.21(transitive)
- Removedmdn-data@2.0.14(transitive)
- Removednano-css@5.6.2(transitive)
- Removedreact-dom@18.3.1(transitive)
- Removedreact-universal-interface@0.6.2(transitive)
- Removedreact-use@17.5.1(transitive)
- Removedregenerator-runtime@0.14.1(transitive)
- Removedresize-observer-polyfill@1.5.1(transitive)
- Removedrtl-css-js@1.16.1(transitive)
- Removedscheduler@0.23.2(transitive)
- Removedscreenfull@5.2.0(transitive)
- Removedset-harmonic-interval@1.0.1(transitive)
- Removedsource-map@0.5.60.6.1(transitive)
- Removedstack-generator@2.0.10(transitive)
- Removedstackframe@1.3.4(transitive)
- Removedstacktrace-gps@3.1.2(transitive)
- Removedstacktrace-js@2.0.2(transitive)
- Removedstylis@4.3.4(transitive)
- Removedthrottle-debounce@3.0.1(transitive)
- Removedtoggle-selection@1.0.6(transitive)
- Removedts-easing@0.2.0(transitive)
- Removedtslib@2.8.1(transitive)