@4i/modal-manager 1.0.117 → 1.1.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/package.json +1 -1
- package/readme.md +31 -27
- package/src/components/modal-provider.d.ts +11 -2
- package/src/components/modal-provider.js +36 -22
- package/src/components/modal-provider.tsx +75 -36
- package/src/styles.css +13 -9
- package/src/utils/ModalManager.d.ts +29 -4
- package/src/utils/ModalManager.js +40 -7
- package/src/utils/ModalManager.ts +58 -7
- package/tsconfig.json +1 -1
package/package.json
CHANGED
package/readme.md
CHANGED
@@ -13,37 +13,41 @@ This package simplifies the management of multiple modals, popups, notifications
|
|
13
13
|
npm install @4i/modal-manager
|
14
14
|
```
|
15
15
|
|
16
|
-
##
|
17
|
-
|
18
|
-
#### Instance methods:
|
19
|
-
|
20
|
-
##### .call(action, props)
|
21
|
-
|
22
|
-
Call a modal by its action name and pass props to it.
|
23
|
-
|
24
|
-
##### .close('all')
|
25
|
-
|
26
|
-
Close all modals.
|
27
|
-
|
28
|
-
##### .close(-1)
|
16
|
+
## Example
|
29
17
|
|
30
|
-
|
18
|
+
<a href="https://codesandbox.io/p/github/tonichiga/modal-manager-example/main?layout=%257B%2522sidebarPanel%2522%253A%2522GIT%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clsnqfzod00063p6le9554u03%2522%252C%2522sizes%2522%253A%255B70%252C30%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clsnqfzod00023p6lo9e5ocrg%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clsnqfzod00043p6l5kpjziav%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clsnqfzod00053p6lleknh8sj%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clsnqfzod00023p6lo9e5ocrg%2522%253A%257B%2522id%2522%253A%2522clsnqfzod00023p6lo9e5ocrg%2522%252C%2522tabs%2522%253A%255B%255D%257D%252C%2522clsnqfzod00053p6lleknh8sj%2522%253A%257B%2522id%2522%253A%2522clsnqfzod00053p6lleknh8sj%2522%252C%2522activeTabId%2522%253A%2522clsnqihgr00ht3p6l2nn59nq5%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522TASK_PORT%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522port%2522%253A3000%252C%2522id%2522%253A%2522clsnqihgr00ht3p6l2nn59nq5%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%255D%257D%252C%2522clsnqfzod00043p6l5kpjziav%2522%253A%257B%2522id%2522%253A%2522clsnqfzod00043p6l5kpjziav%2522%252C%2522activeTabId%2522%253A%2522clsnqojb3003j3p6m98yg0rzn%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522id%2522%253A%2522clsnqh362007k3p6lgb90p583%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%252C%257B%2522id%2522%253A%2522clsnqojb3003j3p6m98yg0rzn%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522TERMINAL%2522%252C%2522shellId%2522%253A%2522clsnqojh1001mdjig37kbat9k%2522%257D%255D%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D">Codesandbox</a>
|
31
19
|
|
32
|
-
|
33
|
-
|
34
|
-
Close first modals.
|
35
|
-
|
36
|
-
##### .close() (default)
|
37
|
-
|
38
|
-
Close last modals.
|
39
|
-
|
40
|
-
##### .addEventListener(event, callback)
|
41
|
-
|
42
|
-
Add an event listener to the modal manager.
|
20
|
+
## Usage
|
43
21
|
|
44
|
-
|
22
|
+
#### Instance methods:
|
45
23
|
|
46
|
-
|
24
|
+
| Method | Description |
|
25
|
+
| ------------------------------------ | ----------------------------------------------------- |
|
26
|
+
| call(action, props) | Call a modal by its action name and pass props to it. |
|
27
|
+
| |
|
28
|
+
| close('all') | Close all modals. |
|
29
|
+
| |
|
30
|
+
| close(-1) | Close last modals. |
|
31
|
+
| |
|
32
|
+
| close(0) | Close first modals. |
|
33
|
+
| |
|
34
|
+
| close() | Close last modals. (default) |
|
35
|
+
| |
|
36
|
+
| onOpenModalState(callback) | Is there at least one window open now |
|
37
|
+
| |
|
38
|
+
| addEventListener(event, callback) | Add an event listener to the modal manager. |
|
39
|
+
| |
|
40
|
+
| removeEventListener(event, callback) | Remove an event listener from the modal manager. |
|
41
|
+
| |
|
42
|
+
|
43
|
+
#### ModalProvider props
|
44
|
+
|
45
|
+
| Prop | Type | Description |
|
46
|
+
| ------------------ | -------- | -------------------------------------------------------------------------- |
|
47
|
+
| modalList | Object | An object containing modal actions as keys and modal components as values. |
|
48
|
+
| className | string | |
|
49
|
+
| isOverflow | boolean | Set "overflow: hidden" on body |
|
50
|
+
| onModalStateChange | function | Callback function that is called when modal state changes. |
|
47
51
|
|
48
52
|
#### Define Modal Actions:
|
49
53
|
|
@@ -1,9 +1,18 @@
|
|
1
1
|
import React from "react";
|
2
|
+
import { ModalManager } from "../utils/ModalManager";
|
2
3
|
export type ModalList = {
|
3
4
|
[key: string]: React.ComponentType;
|
4
5
|
};
|
5
6
|
interface ModalProviderProps {
|
6
|
-
modalList:
|
7
|
+
modalList: any;
|
8
|
+
isOverflow?: boolean;
|
9
|
+
className?: string;
|
10
|
+
backdropClassName?: string;
|
11
|
+
modalManager?: ModalManager;
|
12
|
+
onModalStateChange?: (modalState: boolean, data: TData[], names: string[]) => void;
|
7
13
|
}
|
8
|
-
|
14
|
+
type TData = {
|
15
|
+
[key: string]: any;
|
16
|
+
};
|
17
|
+
declare const ModalProvider: ({ modalList, isOverflow, className, backdropClassName, modalManager, onModalStateChange, }: ModalProviderProps) => React.JSX.Element;
|
9
18
|
export default ModalProvider;
|
@@ -1,4 +1,5 @@
|
|
1
1
|
"use strict";
|
2
|
+
"use client";
|
2
3
|
var __assign = (this && this.__assign) || function () {
|
3
4
|
__assign = Object.assign || function(t) {
|
4
5
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
@@ -42,24 +43,38 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
42
43
|
}
|
43
44
|
return to.concat(ar || Array.prototype.slice.call(from));
|
44
45
|
};
|
45
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
46
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
47
|
-
};
|
48
46
|
Object.defineProperty(exports, "__esModule", { value: true });
|
49
47
|
var react_1 = __importStar(require("react"));
|
50
|
-
var ModalManager_1 =
|
51
|
-
var ModalManager_2 = __importDefault(require("../utils/ModalManager"));
|
48
|
+
var ModalManager_1 = __importStar(require("../utils/ModalManager"));
|
52
49
|
var ModalProvider = function (_a) {
|
53
|
-
var modalList = _a.modalList;
|
50
|
+
var modalList = _a.modalList, isOverflow = _a.isOverflow, className = _a.className, backdropClassName = _a.backdropClassName, modalManager = _a.modalManager, onModalStateChange = _a.onModalStateChange;
|
54
51
|
var _b = (0, react_1.useState)([]), data = _b[0], setData = _b[1];
|
55
52
|
var _c = (0, react_1.useState)([]), names = _c[0], setNames = _c[1];
|
56
53
|
var modalRef = (0, react_1.useRef)([]);
|
54
|
+
var m = modalManager !== null && modalManager !== void 0 ? modalManager : ModalManager_1.default;
|
55
|
+
(0, react_1.useEffect)(function () {
|
56
|
+
if (!onModalStateChange)
|
57
|
+
return;
|
58
|
+
var modalState = data.length !== 0;
|
59
|
+
onModalStateChange(modalState, data, names);
|
60
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
61
|
+
}, [data, names]);
|
57
62
|
(0, react_1.useEffect)(function () {
|
58
63
|
var handleOpenModal = function (name, data) {
|
59
64
|
setData(function (prev) { return __spreadArray(__spreadArray([], prev, true), [data], false); });
|
60
65
|
setNames(function (prev) { return __spreadArray(__spreadArray([], prev, true), [name], false); });
|
66
|
+
if (isOverflow) {
|
67
|
+
if (typeof document === "undefined")
|
68
|
+
return;
|
69
|
+
document.body.style.overflow = "hidden";
|
70
|
+
}
|
61
71
|
};
|
62
72
|
var handleClose = function (position) {
|
73
|
+
if (isOverflow) {
|
74
|
+
if (typeof document !== "undefined") {
|
75
|
+
document.body.style.overflow = "";
|
76
|
+
}
|
77
|
+
}
|
63
78
|
if (position === "all") {
|
64
79
|
setData([]);
|
65
80
|
setNames([]);
|
@@ -89,38 +104,37 @@ var ModalProvider = function (_a) {
|
|
89
104
|
return prev.filter(function (_, index) { return index !== prev.length - 1; });
|
90
105
|
});
|
91
106
|
};
|
92
|
-
ModalManager_1.
|
93
|
-
ModalManager_1.
|
107
|
+
m.addEventListener(ModalManager_1.constants.CHANGE, handleOpenModal);
|
108
|
+
m.addEventListener(ModalManager_1.constants.CLOSE, handleClose);
|
94
109
|
return function () {
|
95
|
-
ModalManager_1.
|
96
|
-
ModalManager_1.
|
110
|
+
m.removeEventListener(ModalManager_1.constants.CHANGE, handleOpenModal);
|
111
|
+
m.removeEventListener(ModalManager_1.constants.CLOSE, handleClose);
|
97
112
|
};
|
113
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
98
114
|
}, []);
|
99
115
|
var activeModals = names.map(function (name) {
|
100
116
|
var Component = modalList[name] || (function () { return react_1.default.createElement(react_1.default.Fragment, null); });
|
101
117
|
return Component;
|
102
118
|
});
|
103
|
-
var handleCloseModal = function (index
|
104
|
-
|
105
|
-
if (modalRef.current[index] &&
|
106
|
-
!modalRef.current[index].contains(e.target)) {
|
107
|
-
ModalManager_2.default.close(index);
|
108
|
-
}
|
119
|
+
var handleCloseModal = function (index) {
|
120
|
+
m.close(index);
|
109
121
|
};
|
110
122
|
var refReducer = function (index, value) {
|
111
123
|
modalRef.current[index] = value;
|
112
124
|
};
|
113
|
-
return (data.length !== 0 &&
|
125
|
+
return (react_1.default.createElement(react_1.default.Fragment, null, data.length !== 0 &&
|
114
126
|
data.map(function (item, i) {
|
115
127
|
var Modal = activeModals[i] || (function () { return react_1.default.createElement(react_1.default.Fragment, null); });
|
116
|
-
return (react_1.default.createElement("div", { key: item.modalId,
|
117
|
-
|
118
|
-
|
119
|
-
|
128
|
+
return (react_1.default.createElement("div", { key: item.modalId, className: "modal-manager backdrop_modal_manager ".concat(backdropClassName) },
|
129
|
+
react_1.default.createElement("div", { onClick: function (e) {
|
130
|
+
e.stopPropagation();
|
131
|
+
handleCloseModal(i);
|
132
|
+
}, className: "backdrop" }),
|
133
|
+
react_1.default.createElement("div", { className: "".concat(className, " modal_paper") },
|
120
134
|
react_1.default.createElement("div", { ref: function (ref) {
|
121
135
|
refReducer(i, ref);
|
122
136
|
} },
|
123
137
|
react_1.default.createElement(Modal, __assign({}, item.data))))));
|
124
|
-
}));
|
138
|
+
})));
|
125
139
|
};
|
126
140
|
exports.default = ModalProvider;
|
@@ -1,27 +1,63 @@
|
|
1
|
+
"use client";
|
2
|
+
|
1
3
|
import React, { useEffect, useRef, useState } from "react";
|
2
|
-
import
|
3
|
-
import modal from "../utils/ModalManager";
|
4
|
+
import modal, { constants, ModalManager } from "../utils/ModalManager";
|
4
5
|
|
5
6
|
export type ModalList = { [key: string]: React.ComponentType };
|
6
7
|
|
7
8
|
interface ModalProviderProps {
|
8
|
-
modalList:
|
9
|
+
modalList: any;
|
10
|
+
isOverflow?: boolean;
|
11
|
+
className?: string;
|
12
|
+
backdropClassName?: string;
|
13
|
+
modalManager?: ModalManager;
|
14
|
+
onModalStateChange?: (
|
15
|
+
modalState: boolean,
|
16
|
+
data: TData[],
|
17
|
+
names: string[]
|
18
|
+
) => void;
|
9
19
|
}
|
10
20
|
|
11
21
|
type TData = { [key: string]: any };
|
12
22
|
|
13
|
-
const ModalProvider = ({
|
23
|
+
const ModalProvider = ({
|
24
|
+
modalList,
|
25
|
+
isOverflow,
|
26
|
+
className,
|
27
|
+
backdropClassName,
|
28
|
+
modalManager,
|
29
|
+
onModalStateChange,
|
30
|
+
}: ModalProviderProps) => {
|
14
31
|
const [data, setData] = useState<TData[]>([]);
|
15
32
|
const [names, setNames] = useState<string[]>([]);
|
16
33
|
const modalRef = useRef<any[]>([]);
|
34
|
+
const m = modalManager ?? modal;
|
35
|
+
|
36
|
+
useEffect(() => {
|
37
|
+
if (!onModalStateChange) return;
|
38
|
+
const modalState = data.length !== 0;
|
39
|
+
onModalStateChange(modalState, data, names);
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
41
|
+
}, [data, names]);
|
17
42
|
|
18
43
|
useEffect(() => {
|
19
44
|
const handleOpenModal = (name: string, data: TData) => {
|
20
45
|
setData((prev: TData[]) => [...prev, data]);
|
21
46
|
setNames((prev: string[]) => [...prev, name]);
|
47
|
+
|
48
|
+
if (isOverflow) {
|
49
|
+
if (typeof document === "undefined") return;
|
50
|
+
document.body.style.overflow = "hidden";
|
51
|
+
}
|
22
52
|
};
|
23
53
|
|
24
54
|
const handleClose = (position: number | string) => {
|
55
|
+
if (isOverflow) {
|
56
|
+
if (typeof document !== "undefined") {
|
57
|
+
document.body.style.overflow = "";
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
25
61
|
if (position === "all") {
|
26
62
|
setData([]);
|
27
63
|
setNames([]);
|
@@ -55,12 +91,13 @@ const ModalProvider = ({ modalList }: ModalProviderProps) => {
|
|
55
91
|
);
|
56
92
|
};
|
57
93
|
|
58
|
-
|
59
|
-
|
94
|
+
m.addEventListener(constants.CHANGE, handleOpenModal);
|
95
|
+
m.addEventListener(constants.CLOSE, handleClose);
|
60
96
|
return () => {
|
61
|
-
|
62
|
-
|
97
|
+
m.removeEventListener(constants.CHANGE, handleOpenModal);
|
98
|
+
m.removeEventListener(constants.CLOSE, handleClose);
|
63
99
|
};
|
100
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
64
101
|
}, []);
|
65
102
|
|
66
103
|
const activeModals = names.map((name: string) => {
|
@@ -68,14 +105,8 @@ const ModalProvider = ({ modalList }: ModalProviderProps) => {
|
|
68
105
|
return Component;
|
69
106
|
});
|
70
107
|
|
71
|
-
const handleCloseModal = (index: number
|
72
|
-
|
73
|
-
if (
|
74
|
-
modalRef.current[index] &&
|
75
|
-
!modalRef.current[index].contains(e.target)
|
76
|
-
) {
|
77
|
-
modal.close(index);
|
78
|
-
}
|
108
|
+
const handleCloseModal = (index: number) => {
|
109
|
+
m.close(index);
|
79
110
|
};
|
80
111
|
|
81
112
|
const refReducer = (index: number, value: any) => {
|
@@ -83,29 +114,37 @@ const ModalProvider = ({ modalList }: ModalProviderProps) => {
|
|
83
114
|
};
|
84
115
|
|
85
116
|
return (
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
key={item.modalId}
|
93
|
-
onClick={(e) => {
|
94
|
-
handleCloseModal(i, e);
|
95
|
-
}}
|
96
|
-
>
|
97
|
-
<div className="backdrop_modal_manager">
|
117
|
+
<>
|
118
|
+
{data.length !== 0 &&
|
119
|
+
data.map((item, i) => {
|
120
|
+
const Modal = activeModals[i] || (() => <></>);
|
121
|
+
|
122
|
+
return (
|
98
123
|
<div
|
99
|
-
|
100
|
-
|
101
|
-
}}
|
124
|
+
key={item.modalId}
|
125
|
+
className={`modal-manager backdrop_modal_manager ${backdropClassName}`}
|
102
126
|
>
|
103
|
-
<
|
127
|
+
<div
|
128
|
+
onClick={(e) => {
|
129
|
+
e.stopPropagation();
|
130
|
+
handleCloseModal(i);
|
131
|
+
}}
|
132
|
+
className="backdrop"
|
133
|
+
/>
|
134
|
+
{/* // h-full modal not close */}
|
135
|
+
<div className={`${className} modal_paper`}>
|
136
|
+
<div
|
137
|
+
ref={(ref) => {
|
138
|
+
refReducer(i, ref);
|
139
|
+
}}
|
140
|
+
>
|
141
|
+
<Modal {...item.data} />
|
142
|
+
</div>
|
143
|
+
</div>
|
104
144
|
</div>
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
})
|
145
|
+
);
|
146
|
+
})}
|
147
|
+
</>
|
109
148
|
);
|
110
149
|
};
|
111
150
|
|
package/src/styles.css
CHANGED
@@ -16,8 +16,7 @@
|
|
16
16
|
}
|
17
17
|
}
|
18
18
|
|
19
|
-
.backdrop_modal_manager {
|
20
|
-
position: absolute;
|
19
|
+
.modal-manager.backdrop_modal_manager {
|
21
20
|
display: flex;
|
22
21
|
justify-content: center;
|
23
22
|
align-items: center;
|
@@ -27,18 +26,23 @@
|
|
27
26
|
bottom: 0;
|
28
27
|
width: 100%;
|
29
28
|
height: 100%;
|
30
|
-
background-color: rgba(0, 0, 0, 0.5);
|
31
29
|
position: fixed;
|
32
30
|
z-index: 1000;
|
31
|
+
}
|
32
|
+
|
33
|
+
.modal-manager .backdrop {
|
34
|
+
background-color: rgba(0, 0, 0, 0.5);
|
33
35
|
opacity: 0;
|
36
|
+
position: fixed;
|
37
|
+
top: 0;
|
38
|
+
left: 0;
|
39
|
+
right: 0;
|
40
|
+
bottom: 0;
|
34
41
|
animation: bg_opacity 150ms ease-in-out forwards;
|
35
42
|
}
|
36
43
|
|
37
|
-
.
|
44
|
+
.modal-manager .modal_paper {
|
45
|
+
position: relative;
|
46
|
+
z-index: 1001;
|
38
47
|
animation: bg_opacity_scale 150ms ease-in-out forwards;
|
39
48
|
}
|
40
|
-
|
41
|
-
.main_container_modal_manager {
|
42
|
-
opacity: 0;
|
43
|
-
animation: bg_opacity 250ms forwards;
|
44
|
-
}
|
@@ -1,11 +1,36 @@
|
|
1
1
|
import Manager from "./Manager";
|
2
|
-
declare
|
2
|
+
export declare const constants: {
|
3
|
+
CHANGE: string;
|
4
|
+
CLOSE: string;
|
5
|
+
};
|
6
|
+
interface QueueState {
|
7
|
+
queue: string[];
|
8
|
+
closedModalName?: string | undefined;
|
9
|
+
lastOpenedModal?: string | undefined;
|
10
|
+
}
|
11
|
+
interface ModalState {
|
12
|
+
isHaveOpenModals: boolean;
|
13
|
+
queue: string[];
|
14
|
+
closedModalName?: string | undefined;
|
15
|
+
lastOpenedModal?: string | undefined;
|
16
|
+
}
|
17
|
+
export declare class ModalManager extends Manager {
|
18
|
+
queue: string[];
|
19
|
+
_openModalStateCallback: null | ((props: ModalState) => void);
|
3
20
|
constructor();
|
4
|
-
create(name: string,
|
5
|
-
|
21
|
+
create<T>(name: string, payload: {
|
22
|
+
modalId: number;
|
23
|
+
data?: T;
|
6
24
|
}): void;
|
7
|
-
call(name: string, data?:
|
25
|
+
call<T>(name: string, data?: T): void;
|
8
26
|
close<T>(position?: T): void;
|
27
|
+
getQueueState({ queue, closedModalName, lastOpenedModal }: QueueState): {
|
28
|
+
isHaveOpenModals: boolean;
|
29
|
+
queue: string[];
|
30
|
+
lastOpenedModal: string | undefined;
|
31
|
+
closedModalName: string | undefined;
|
32
|
+
};
|
33
|
+
onOpenModalState(callback: (state: ModalState) => void): void;
|
9
34
|
}
|
10
35
|
declare const modal: ModalManager;
|
11
36
|
export default modal;
|
@@ -18,32 +18,65 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
19
19
|
};
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
21
|
+
exports.ModalManager = exports.constants = void 0;
|
21
22
|
var Manager_1 = __importDefault(require("./Manager"));
|
22
23
|
function uniqueID() {
|
23
24
|
return Math.floor(Math.random() * Date.now());
|
24
25
|
}
|
25
|
-
|
26
|
+
exports.constants = {
|
26
27
|
CHANGE: "change",
|
27
28
|
CLOSE: "close",
|
28
29
|
};
|
29
30
|
var ModalManager = /** @class */ (function (_super) {
|
30
31
|
__extends(ModalManager, _super);
|
31
32
|
function ModalManager() {
|
32
|
-
|
33
|
+
var _this = _super.call(this) || this;
|
34
|
+
_this.queue = [];
|
35
|
+
_this.create = _this.create.bind(_this);
|
36
|
+
_this.call = _this.call.bind(_this);
|
37
|
+
_this.close = _this.close.bind(_this);
|
38
|
+
_this._openModalStateCallback = null;
|
39
|
+
return _this;
|
33
40
|
}
|
34
|
-
ModalManager.prototype.create = function (name,
|
41
|
+
ModalManager.prototype.create = function (name, payload) {
|
35
42
|
this.name = name;
|
36
|
-
this.data =
|
37
|
-
this.emitter.emit(constants.CHANGE, this.name, this.data);
|
43
|
+
this.data = payload;
|
44
|
+
this.emitter.emit(exports.constants.CHANGE, this.name, this.data);
|
38
45
|
};
|
39
46
|
ModalManager.prototype.call = function (name, data) {
|
40
|
-
|
47
|
+
var _a;
|
41
48
|
this.create(name, { modalId: uniqueID(), data: data });
|
49
|
+
var lastOpenedModal = name;
|
50
|
+
this.queue.push(name);
|
51
|
+
(_a = this._openModalStateCallback) === null || _a === void 0 ? void 0 : _a.call(this, this.getQueueState({
|
52
|
+
queue: this.queue,
|
53
|
+
lastOpenedModal: lastOpenedModal,
|
54
|
+
}));
|
42
55
|
};
|
43
56
|
ModalManager.prototype.close = function (position) {
|
44
|
-
|
57
|
+
var _a, _b;
|
58
|
+
this.emitter.emit(exports.constants.CLOSE, position !== null && position !== void 0 ? position : ((_a = this.queue) === null || _a === void 0 ? void 0 : _a.length) - 1);
|
59
|
+
var closedModalName = this.queue[this.queue.length - 1];
|
60
|
+
this.queue.pop();
|
61
|
+
(_b = this._openModalStateCallback) === null || _b === void 0 ? void 0 : _b.call(this, this.getQueueState({
|
62
|
+
queue: this.queue,
|
63
|
+
closedModalName: closedModalName,
|
64
|
+
}));
|
65
|
+
};
|
66
|
+
ModalManager.prototype.getQueueState = function (_a) {
|
67
|
+
var queue = _a.queue, closedModalName = _a.closedModalName, lastOpenedModal = _a.lastOpenedModal;
|
68
|
+
return {
|
69
|
+
isHaveOpenModals: queue.length > 0,
|
70
|
+
queue: queue,
|
71
|
+
lastOpenedModal: lastOpenedModal,
|
72
|
+
closedModalName: closedModalName,
|
73
|
+
};
|
74
|
+
};
|
75
|
+
ModalManager.prototype.onOpenModalState = function (callback) {
|
76
|
+
this._openModalStateCallback = callback;
|
45
77
|
};
|
46
78
|
return ModalManager;
|
47
79
|
}(Manager_1.default));
|
80
|
+
exports.ModalManager = ModalManager;
|
48
81
|
var modal = new ModalManager();
|
49
82
|
exports.default = modal;
|
@@ -4,28 +4,79 @@ function uniqueID() {
|
|
4
4
|
return Math.floor(Math.random() * Date.now());
|
5
5
|
}
|
6
6
|
|
7
|
-
const constants = {
|
7
|
+
export const constants = {
|
8
8
|
CHANGE: "change",
|
9
9
|
CLOSE: "close",
|
10
10
|
};
|
11
11
|
|
12
|
-
|
12
|
+
interface QueueState {
|
13
|
+
queue: string[];
|
14
|
+
closedModalName?: string | undefined;
|
15
|
+
lastOpenedModal?: string | undefined;
|
16
|
+
}
|
17
|
+
|
18
|
+
interface ModalState {
|
19
|
+
isHaveOpenModals: boolean;
|
20
|
+
queue: string[];
|
21
|
+
closedModalName?: string | undefined;
|
22
|
+
lastOpenedModal?: string | undefined;
|
23
|
+
}
|
24
|
+
|
25
|
+
export class ModalManager extends Manager {
|
26
|
+
queue: string[] = [];
|
27
|
+
_openModalStateCallback: null | ((props: ModalState) => void);
|
28
|
+
|
13
29
|
constructor() {
|
14
30
|
super();
|
31
|
+
this.create = this.create.bind(this);
|
32
|
+
this.call = this.call.bind(this);
|
33
|
+
this.close = this.close.bind(this);
|
34
|
+
this._openModalStateCallback = null;
|
15
35
|
}
|
16
36
|
|
17
|
-
create(name: string,
|
37
|
+
create<T>(name: string, payload: { modalId: number; data?: T }) {
|
18
38
|
this.name = name;
|
19
|
-
this.data =
|
39
|
+
this.data = payload;
|
20
40
|
this.emitter.emit(constants.CHANGE, this.name, this.data);
|
21
41
|
}
|
22
42
|
|
23
|
-
call(name: string, data
|
24
|
-
this.create(name, { modalId: uniqueID(), data });
|
43
|
+
call<T>(name: string, data?: T) {
|
44
|
+
this.create<T>(name, { modalId: uniqueID(), data });
|
45
|
+
const lastOpenedModal = name;
|
46
|
+
this.queue.push(name);
|
47
|
+
|
48
|
+
this._openModalStateCallback?.(
|
49
|
+
this.getQueueState({
|
50
|
+
queue: this.queue,
|
51
|
+
lastOpenedModal,
|
52
|
+
})
|
53
|
+
);
|
25
54
|
}
|
26
55
|
|
27
56
|
close<T>(position?: T) {
|
28
|
-
this.emitter.emit(constants.CLOSE, position);
|
57
|
+
this.emitter.emit(constants.CLOSE, position ?? this.queue?.length - 1);
|
58
|
+
const closedModalName = this.queue[this.queue.length - 1];
|
59
|
+
this.queue.pop();
|
60
|
+
|
61
|
+
this._openModalStateCallback?.(
|
62
|
+
this.getQueueState({
|
63
|
+
queue: this.queue,
|
64
|
+
closedModalName,
|
65
|
+
})
|
66
|
+
);
|
67
|
+
}
|
68
|
+
|
69
|
+
getQueueState({ queue, closedModalName, lastOpenedModal }: QueueState) {
|
70
|
+
return {
|
71
|
+
isHaveOpenModals: queue.length > 0,
|
72
|
+
queue,
|
73
|
+
lastOpenedModal: lastOpenedModal,
|
74
|
+
closedModalName,
|
75
|
+
};
|
76
|
+
}
|
77
|
+
|
78
|
+
onOpenModalState(callback: (state: ModalState) => void) {
|
79
|
+
this._openModalStateCallback = callback;
|
29
80
|
}
|
30
81
|
}
|
31
82
|
|
package/tsconfig.json
CHANGED