@4i/modal-manager 1.1.21 → 1.1.30
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 +42 -42
- package/readme.md +285 -285
- package/src/components/modal-provider.d.ts +9 -6
- package/src/components/modal-provider.js +91 -90
- package/src/components/modal-provider.tsx +177 -171
- package/src/index.ts +5 -5
- package/src/styles.css +53 -77
- package/src/utils/Manager.ts +27 -27
- package/src/utils/ModalManager.d.ts +6 -2
- package/src/utils/ModalManager.js +44 -12
- package/src/utils/ModalManager.ts +131 -94
- package/tsconfig.json +17 -17
package/src/styles.css
CHANGED
@@ -1,77 +1,53 @@
|
|
1
|
-
@keyframes bg_opacity_scale {
|
2
|
-
from {
|
3
|
-
transform: scale(0.8);
|
4
|
-
}
|
5
|
-
to {
|
6
|
-
transform: scale(1);
|
7
|
-
}
|
8
|
-
}
|
9
|
-
|
10
|
-
@keyframes bg_opacity {
|
11
|
-
from {
|
12
|
-
opacity: 0;
|
13
|
-
}
|
14
|
-
to {
|
15
|
-
opacity: 1;
|
16
|
-
}
|
17
|
-
}
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
background-color: rgba(0, 0, 0, 0.5);
|
55
|
-
opacity: 0;
|
56
|
-
position: fixed;
|
57
|
-
top: 0;
|
58
|
-
left: 0;
|
59
|
-
right: 0;
|
60
|
-
bottom: 0;
|
61
|
-
animation: bg_opacity 150ms ease-in-out forwards;
|
62
|
-
}
|
63
|
-
|
64
|
-
.modal-manager .modal_paper {
|
65
|
-
position: relative;
|
66
|
-
z-index: 1001;
|
67
|
-
animation: bg_opacity_scale 150ms ease-in-out forwards;
|
68
|
-
width: 100%;
|
69
|
-
}
|
70
|
-
|
71
|
-
.modal-manager.closing .backdrop {
|
72
|
-
animation: bg_opacity_out 150ms ease-in-out forwards;
|
73
|
-
}
|
74
|
-
|
75
|
-
.modal-manager.closing .modal_paper {
|
76
|
-
animation: bg_scale_out 150ms ease-in-out forwards;
|
77
|
-
}
|
1
|
+
@keyframes bg_opacity_scale {
|
2
|
+
from {
|
3
|
+
transform: scale(0.8) translateY(-50%) translateX(-50%);
|
4
|
+
}
|
5
|
+
to {
|
6
|
+
transform: scale(1) translateY(-50%) translateX(-50%);
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
@keyframes bg_opacity {
|
11
|
+
from {
|
12
|
+
opacity: 0;
|
13
|
+
}
|
14
|
+
to {
|
15
|
+
opacity: 1;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
/* */
|
20
|
+
|
21
|
+
.modal_container {
|
22
|
+
position: relative;
|
23
|
+
z-index: 10000;
|
24
|
+
}
|
25
|
+
|
26
|
+
.modal_backdrop {
|
27
|
+
position: fixed;
|
28
|
+
top: 0;
|
29
|
+
left: 0;
|
30
|
+
right: 0;
|
31
|
+
bottom: 0;
|
32
|
+
background-color: rgba(0, 0, 0, 0.5);
|
33
|
+
animation: bg_opacity 0.3s ease forwards;
|
34
|
+
}
|
35
|
+
|
36
|
+
.modal_paper {
|
37
|
+
position: fixed;
|
38
|
+
z-index: 1000;
|
39
|
+
width: max-content;
|
40
|
+
overflow: hidden;
|
41
|
+
display: flex;
|
42
|
+
flex-direction: column;
|
43
|
+
align-items: center;
|
44
|
+
justify-content: center;
|
45
|
+
top: 50%;
|
46
|
+
left: 50%;
|
47
|
+
transform-origin: left;
|
48
|
+
animation: bg_opacity_scale 0.3s ease forwards;
|
49
|
+
}
|
50
|
+
|
51
|
+
.modal_closing {
|
52
|
+
animation: bg_opacity 150ms ease reverse forwards;
|
53
|
+
}
|
package/src/utils/Manager.ts
CHANGED
@@ -1,27 +1,27 @@
|
|
1
|
-
import { EventEmitter } from "events";
|
2
|
-
|
3
|
-
type TData = {
|
4
|
-
[key: string]: any;
|
5
|
-
};
|
6
|
-
|
7
|
-
class Manager {
|
8
|
-
emitter: EventEmitter;
|
9
|
-
name: string | null;
|
10
|
-
data: { [key: string]: any };
|
11
|
-
|
12
|
-
constructor() {
|
13
|
-
this.name = "";
|
14
|
-
this.data = {};
|
15
|
-
this.emitter = new EventEmitter();
|
16
|
-
}
|
17
|
-
|
18
|
-
addEventListener(event: string, listener: (...args: any[]) => void) {
|
19
|
-
this.emitter.addListener(event, listener);
|
20
|
-
}
|
21
|
-
|
22
|
-
removeEventListener(event: string, listener: (...args: any[]) => void) {
|
23
|
-
this.emitter.removeListener(event, listener);
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
|
-
export default Manager;
|
1
|
+
import { EventEmitter } from "events";
|
2
|
+
|
3
|
+
type TData = {
|
4
|
+
[key: string]: any;
|
5
|
+
};
|
6
|
+
|
7
|
+
class Manager {
|
8
|
+
emitter: EventEmitter;
|
9
|
+
name: string | null;
|
10
|
+
data: { [key: string]: any };
|
11
|
+
|
12
|
+
constructor() {
|
13
|
+
this.name = "";
|
14
|
+
this.data = {};
|
15
|
+
this.emitter = new EventEmitter();
|
16
|
+
}
|
17
|
+
|
18
|
+
addEventListener(event: string, listener: (...args: any[]) => void) {
|
19
|
+
this.emitter.addListener(event, listener);
|
20
|
+
}
|
21
|
+
|
22
|
+
removeEventListener(event: string, listener: (...args: any[]) => void) {
|
23
|
+
this.emitter.removeListener(event, listener);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
export default Manager;
|
@@ -21,13 +21,14 @@ export interface Options {
|
|
21
21
|
}
|
22
22
|
export declare class ModalManager extends Manager {
|
23
23
|
queue: string[];
|
24
|
+
modalData: Map<string, any>;
|
24
25
|
_openModalStateCallback: null | ((props: ModalState) => void);
|
25
26
|
constructor();
|
26
27
|
create<T>(name: string, payload: {
|
27
28
|
modalId: number;
|
28
29
|
data?: T;
|
29
|
-
}, options?: Options):
|
30
|
-
call<T>(name: string, data?: T, options?: Options):
|
30
|
+
}, options?: Options): string;
|
31
|
+
call<T>(name: string, data?: T, options?: Options): string;
|
31
32
|
close<T>(position?: T): void;
|
32
33
|
getQueueState({ queue, closedModalName, lastOpenedModal }: QueueState): {
|
33
34
|
isHaveOpenModals: boolean;
|
@@ -36,6 +37,9 @@ export declare class ModalManager extends Manager {
|
|
36
37
|
closedModalName: string | undefined;
|
37
38
|
};
|
38
39
|
onOpenModalState(callback: (state: ModalState) => void): void;
|
40
|
+
getModalCount(): number;
|
41
|
+
closeAll(): void;
|
39
42
|
}
|
40
43
|
declare const modal: ModalManager;
|
44
|
+
export { modal };
|
41
45
|
export default modal;
|
@@ -18,7 +18,7 @@ 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
|
+
exports.modal = exports.ModalManager = exports.constants = void 0;
|
22
22
|
var Manager_1 = __importDefault(require("./Manager"));
|
23
23
|
function uniqueID() {
|
24
24
|
return Math.floor(Math.random() * Date.now());
|
@@ -32,26 +32,37 @@ var ModalManager = /** @class */ (function (_super) {
|
|
32
32
|
function ModalManager() {
|
33
33
|
var _this = _super.call(this) || this;
|
34
34
|
_this.queue = [];
|
35
|
+
_this.modalData = new Map(); // Сохраняем данные для каждого модального окна
|
35
36
|
_this.create = _this.create.bind(_this);
|
36
37
|
_this.call = _this.call.bind(_this);
|
37
|
-
_this.close = _this.close.bind(_this);
|
38
38
|
_this._openModalStateCallback = null;
|
39
39
|
return _this;
|
40
40
|
}
|
41
41
|
ModalManager.prototype.create = function (name, payload, options) {
|
42
|
-
|
43
|
-
|
44
|
-
this.
|
42
|
+
var _this = this;
|
43
|
+
var modalId = String(payload.modalId);
|
44
|
+
this.modalData.set(modalId, { name: name, payload: payload, options: options });
|
45
|
+
// Используем setTimeout для обеспечения асинхронного выполнения
|
46
|
+
setTimeout(function () {
|
47
|
+
_this.emitter.emit(exports.constants.CHANGE, name, payload, options);
|
48
|
+
}, 0);
|
49
|
+
return modalId;
|
45
50
|
};
|
46
51
|
ModalManager.prototype.call = function (name, data, options) {
|
47
|
-
var
|
48
|
-
|
52
|
+
var _this = this;
|
53
|
+
var modalId = uniqueID();
|
54
|
+
var id = this.create(name, { modalId: modalId, data: data }, options);
|
49
55
|
var lastOpenedModal = name;
|
50
|
-
this.queue.push(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
56
|
+
this.queue.push(id);
|
57
|
+
// Используем setTimeout чтобы дать React возможность обновить DOM
|
58
|
+
setTimeout(function () {
|
59
|
+
var _a;
|
60
|
+
(_a = _this._openModalStateCallback) === null || _a === void 0 ? void 0 : _a.call(_this, _this.getQueueState({
|
61
|
+
queue: _this.queue,
|
62
|
+
lastOpenedModal: lastOpenedModal,
|
63
|
+
}));
|
64
|
+
}, 0);
|
65
|
+
return id;
|
55
66
|
};
|
56
67
|
ModalManager.prototype.close = function (position) {
|
57
68
|
var _a, _b;
|
@@ -75,8 +86,29 @@ var ModalManager = /** @class */ (function (_super) {
|
|
75
86
|
ModalManager.prototype.onOpenModalState = function (callback) {
|
76
87
|
this._openModalStateCallback = callback;
|
77
88
|
};
|
89
|
+
// Получить количество открытых модальных окон
|
90
|
+
ModalManager.prototype.getModalCount = function () {
|
91
|
+
return this.queue.length;
|
92
|
+
};
|
93
|
+
// Метод для закрытия всех модальных окон
|
94
|
+
ModalManager.prototype.closeAll = function () {
|
95
|
+
var _this = this;
|
96
|
+
if (this.queue.length === 0)
|
97
|
+
return;
|
98
|
+
setTimeout(function () {
|
99
|
+
var _a;
|
100
|
+
_this.emitter.emit(exports.constants.CLOSE, "all");
|
101
|
+
_this.queue = [];
|
102
|
+
_this.modalData.clear();
|
103
|
+
(_a = _this._openModalStateCallback) === null || _a === void 0 ? void 0 : _a.call(_this, _this.getQueueState({
|
104
|
+
queue: _this.queue,
|
105
|
+
closedModalName: undefined,
|
106
|
+
}));
|
107
|
+
}, 0);
|
108
|
+
};
|
78
109
|
return ModalManager;
|
79
110
|
}(Manager_1.default));
|
80
111
|
exports.ModalManager = ModalManager;
|
81
112
|
var modal = new ModalManager();
|
113
|
+
exports.modal = modal;
|
82
114
|
exports.default = modal;
|
@@ -1,94 +1,131 @@
|
|
1
|
-
import Manager from "./Manager";
|
2
|
-
|
3
|
-
function uniqueID() {
|
4
|
-
return Math.floor(Math.random() * Date.now());
|
5
|
-
}
|
6
|
-
|
7
|
-
export const constants = {
|
8
|
-
CHANGE: "change",
|
9
|
-
CLOSE: "close",
|
10
|
-
};
|
11
|
-
|
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 interface Options {
|
26
|
-
hideBackdrop?: boolean;
|
27
|
-
extraClass?: string;
|
28
|
-
openMinimized?: boolean;
|
29
|
-
}
|
30
|
-
|
31
|
-
export class ModalManager extends Manager {
|
32
|
-
queue: string[] = [];
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
this.
|
39
|
-
this.
|
40
|
-
this._openModalStateCallback = null;
|
41
|
-
}
|
42
|
-
|
43
|
-
create<T>(
|
44
|
-
name: string,
|
45
|
-
payload: { modalId: number; data?: T },
|
46
|
-
options?: Options
|
47
|
-
) {
|
48
|
-
|
49
|
-
this.
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
}
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
1
|
+
import Manager from "./Manager";
|
2
|
+
|
3
|
+
function uniqueID() {
|
4
|
+
return Math.floor(Math.random() * Date.now());
|
5
|
+
}
|
6
|
+
|
7
|
+
export const constants = {
|
8
|
+
CHANGE: "change",
|
9
|
+
CLOSE: "close",
|
10
|
+
};
|
11
|
+
|
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 interface Options {
|
26
|
+
hideBackdrop?: boolean;
|
27
|
+
extraClass?: string;
|
28
|
+
openMinimized?: boolean;
|
29
|
+
}
|
30
|
+
|
31
|
+
export class ModalManager extends Manager {
|
32
|
+
queue: string[] = [];
|
33
|
+
modalData: Map<string, any> = new Map(); // Сохраняем данные для каждого модального окна
|
34
|
+
_openModalStateCallback: null | ((props: ModalState) => void);
|
35
|
+
|
36
|
+
constructor() {
|
37
|
+
super();
|
38
|
+
this.create = this.create.bind(this);
|
39
|
+
this.call = this.call.bind(this);
|
40
|
+
this._openModalStateCallback = null;
|
41
|
+
}
|
42
|
+
|
43
|
+
create<T>(
|
44
|
+
name: string,
|
45
|
+
payload: { modalId: number; data?: T },
|
46
|
+
options?: Options
|
47
|
+
) {
|
48
|
+
const modalId = String(payload.modalId);
|
49
|
+
this.modalData.set(modalId, { name, payload, options });
|
50
|
+
|
51
|
+
// Используем setTimeout для обеспечения асинхронного выполнения
|
52
|
+
setTimeout(() => {
|
53
|
+
this.emitter.emit(constants.CHANGE, name, payload, options);
|
54
|
+
}, 0);
|
55
|
+
|
56
|
+
return modalId;
|
57
|
+
}
|
58
|
+
|
59
|
+
call<T>(name: string, data?: T, options?: Options) {
|
60
|
+
const modalId = uniqueID();
|
61
|
+
const id = this.create<T>(name, { modalId, data }, options);
|
62
|
+
|
63
|
+
const lastOpenedModal = name;
|
64
|
+
this.queue.push(id);
|
65
|
+
|
66
|
+
// Используем setTimeout чтобы дать React возможность обновить DOM
|
67
|
+
setTimeout(() => {
|
68
|
+
this._openModalStateCallback?.(
|
69
|
+
this.getQueueState({
|
70
|
+
queue: this.queue,
|
71
|
+
lastOpenedModal,
|
72
|
+
})
|
73
|
+
);
|
74
|
+
}, 0);
|
75
|
+
|
76
|
+
return id;
|
77
|
+
}
|
78
|
+
|
79
|
+
close<T>(position?: T) {
|
80
|
+
this.emitter.emit(constants.CLOSE, position ?? this.queue?.length - 1);
|
81
|
+
const closedModalName = this.queue[this.queue.length - 1];
|
82
|
+
this.queue.pop();
|
83
|
+
|
84
|
+
this._openModalStateCallback?.(
|
85
|
+
this.getQueueState({
|
86
|
+
queue: this.queue,
|
87
|
+
closedModalName,
|
88
|
+
})
|
89
|
+
);
|
90
|
+
}
|
91
|
+
|
92
|
+
getQueueState({ queue, closedModalName, lastOpenedModal }: QueueState) {
|
93
|
+
return {
|
94
|
+
isHaveOpenModals: queue.length > 0,
|
95
|
+
queue,
|
96
|
+
lastOpenedModal: lastOpenedModal,
|
97
|
+
closedModalName,
|
98
|
+
};
|
99
|
+
}
|
100
|
+
|
101
|
+
onOpenModalState(callback: (state: ModalState) => void) {
|
102
|
+
this._openModalStateCallback = callback;
|
103
|
+
}
|
104
|
+
|
105
|
+
// Получить количество открытых модальных окон
|
106
|
+
getModalCount() {
|
107
|
+
return this.queue.length;
|
108
|
+
}
|
109
|
+
|
110
|
+
// Метод для закрытия всех модальных окон
|
111
|
+
closeAll() {
|
112
|
+
if (this.queue.length === 0) return;
|
113
|
+
|
114
|
+
setTimeout(() => {
|
115
|
+
this.emitter.emit(constants.CLOSE, "all");
|
116
|
+
this.queue = [];
|
117
|
+
this.modalData.clear();
|
118
|
+
|
119
|
+
this._openModalStateCallback?.(
|
120
|
+
this.getQueueState({
|
121
|
+
queue: this.queue,
|
122
|
+
closedModalName: undefined,
|
123
|
+
})
|
124
|
+
);
|
125
|
+
}, 0);
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
const modal = new ModalManager();
|
130
|
+
export { modal };
|
131
|
+
export default modal;
|
package/tsconfig.json
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
{
|
2
|
-
"compilerOptions": {
|
3
|
-
"target": "es5",
|
4
|
-
"module": "commonjs",
|
5
|
-
"esModuleInterop": true,
|
6
|
-
"jsx": "react",
|
7
|
-
"strict": true,
|
8
|
-
"skipLibCheck": true,
|
9
|
-
"forceConsistentCasingInFileNames": true,
|
10
|
-
"moduleResolution": "node",
|
11
|
-
"declaration": true,
|
12
|
-
"outDir": "./src",
|
13
|
-
"allowJs": true
|
14
|
-
},
|
15
|
-
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
16
|
-
"exclude": ["node_modules"]
|
17
|
-
}
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "es5",
|
4
|
+
"module": "commonjs",
|
5
|
+
"esModuleInterop": true,
|
6
|
+
"jsx": "react",
|
7
|
+
"strict": true,
|
8
|
+
"skipLibCheck": true,
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
10
|
+
"moduleResolution": "node",
|
11
|
+
"declaration": true,
|
12
|
+
"outDir": "./src",
|
13
|
+
"allowJs": true
|
14
|
+
},
|
15
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
16
|
+
"exclude": ["node_modules"]
|
17
|
+
}
|