react-graph-grid 0.1.8 → 0.1.11

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/src/Modal.jsx ADDED
@@ -0,0 +1,511 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { BaseComponent, log } from './Base';
3
+ import { Overlay, OverlayClass } from './Overlay';
4
+ import { renderToStaticMarkup } from 'react-dom/server';
5
+ // ==================================================================================================================================================================
6
+ export function Modal(props) {
7
+ let wnd = null;
8
+
9
+ const [wndState, setState] = useState({ wnd: wnd, ind: 0 });
10
+
11
+ const oldWnd = wndState.wnd;
12
+
13
+ wnd = oldWnd && oldWnd.uid === props.uid ? oldWnd : new ModalClass(props);
14
+
15
+ if (props.init) {
16
+ props.init(wnd);
17
+ }
18
+
19
+ wnd.refreshState = function () {
20
+ setState({ wnd: wnd, ind: wnd.stateind++ });
21
+ }
22
+
23
+ useEffect(() => {
24
+ wnd.setupEvents();
25
+
26
+ return () => {
27
+ //log(' 0.11 Clear ModalEvents');
28
+
29
+ wnd.clearEvents();
30
+ }
31
+ }, [wnd])
32
+
33
+ return (wnd.render());
34
+ }
35
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
36
+ export class ModalClass extends BaseComponent {
37
+ constructor(props) {
38
+ super(props);
39
+
40
+ const wnd = this;
41
+ wnd.uid = props.uid;
42
+
43
+ wnd.opt = {};
44
+
45
+ wnd.id = ModalClass._seq++;
46
+
47
+ wnd.opt.keyAdd = props.keyAdd;
48
+
49
+ wnd.opt.zInd = props.zInd || ++OverlayClass._zInd;
50
+
51
+ wnd.opt.pos = props.pos || { x: 0, y: 0, w: '100%', h: '100%' };
52
+
53
+ wnd.opt.isModal = props.isModal != null ? props.isModal : true;
54
+
55
+ wnd.opt.closeWhenClick = props.closeWhenClick;
56
+ wnd.opt.closeWhenEscape = props.closeWhenEscape;
57
+ wnd.opt.closeWhenMiss = props.closeWhenMiss && wnd.opt.isModal;
58
+ //wnd.opt.closeWhenMiss = (props.closeWhenMiss || props.closeWhenMouseLeave == false) && wnd.opt.isModal;
59
+ wnd.opt.closeWhenMouseLeave = props.closeWhenMouseLeave;
60
+
61
+ wnd.opt.onMouseEnter = props.onMouseEnter;
62
+ wnd.opt.onMouseLeave = props.onMouseLeave;
63
+
64
+ wnd.opt.resizable = props.resizable != null ? props.resizable : true;
65
+ wnd.opt.draggable = props.draggable != null ? props.draggable : true;
66
+
67
+ wnd.opt.hiddenOverlay = props.hiddenOverlay;
68
+
69
+ wnd.opt.noHeader = props.noHeader;
70
+ wnd.opt.noFooter = props.noFooter;
71
+ wnd.opt.noPadding = props.noPadding;
72
+ wnd.opt.noBodyOverflow = props.noBodyOverflow;
73
+
74
+ wnd.opt.margin = props.margin;
75
+ wnd.opt.padding = props.padding;
76
+
77
+ wnd.opt.windowClass = props.windowClass;
78
+ wnd.opt.bodyClass = props.bodyClass || BaseComponent.theme.modalBodyClass || 'modal-window-body';
79
+ wnd.opt.headerClass = props.headerClass || BaseComponent.theme.modalHeaderClass || 'modal-window-header';
80
+ wnd.opt.footerClass = props.footerClass || BaseComponent.theme.modalFooterClass || 'modal-window-footer';
81
+ wnd.opt.footerButtonClass = props.footerButtonClass || BaseComponent.theme.modalFooterButtonClass || 'modal-window-footer-button'
82
+ wnd.opt.titleClass = props.titleClass || BaseComponent.theme.modalTitleClass || 'modal-window-header-title';
83
+ wnd.opt.title = props.title;
84
+
85
+ wnd.opt.pos.x = !isNaN(wnd.opt.pos.x) ? wnd.opt.pos.x + 'px' : wnd.opt.pos.x;
86
+ wnd.opt.pos.y = !isNaN(wnd.opt.pos.y) ? wnd.opt.pos.y + 'px' : wnd.opt.pos.y;
87
+ wnd.opt.pos.w = !isNaN(wnd.opt.pos.w) ? wnd.opt.pos.w + 'px' : wnd.opt.pos.w;
88
+ wnd.opt.pos.h = !isNaN(wnd.opt.pos.h) ? wnd.opt.pos.h + 'px' : wnd.opt.pos.h;
89
+ wnd.opt.pos.minW = !isNaN(wnd.opt.pos.minW) ? wnd.opt.pos.minW + 'px' : wnd.opt.pos.minW;
90
+ wnd.opt.pos.minH = !isNaN(wnd.opt.pos.minH) ? wnd.opt.pos.minH + 'px' : wnd.opt.pos.minH;
91
+ wnd.opt.pos.maxW = !isNaN(wnd.opt.pos.maxW) ? wnd.opt.pos.maxW + 'px' : wnd.opt.pos.maxW;
92
+ wnd.opt.pos.maxH = !isNaN(wnd.opt.pos.maxH) ? wnd.opt.pos.maxH + 'px' : wnd.opt.pos.maxH;
93
+
94
+ wnd.onClose = props.onClose;
95
+
96
+ wnd.opt.dimensionsByContent = props.dimensionsByContent;
97
+
98
+ wnd.renderContent = props.renderContent || function () { return null };
99
+
100
+ wnd.buttons = [];
101
+ if (props.footerButtons) {
102
+ wnd.buttonsDict = {};
103
+ let seq = 0;
104
+ for (let btn of props.footerButtons) {
105
+ btn._ind = seq++;
106
+ wnd.buttonsDict[btn._ind] = btn;
107
+ wnd.buttons.push(btn);
108
+ }
109
+ }
110
+
111
+ wnd.visible = props.visible != null ? props.visible : true;
112
+
113
+ wnd.stateind = 0;
114
+ }
115
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
116
+ static _isFake = false;
117
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
118
+ static _seq = 0;
119
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
120
+ render() {
121
+ const wnd = this;
122
+ if (!wnd.visible) {
123
+ return <></>;
124
+ }
125
+
126
+ if (wnd.opt.dimensionsByContent) {
127
+ const rect = wnd.getDimensionsByContent(wnd.opt.margin, wnd.opt.padding);
128
+ wnd.opt.pos.w = rect.w || wnd.opt.pos.w;
129
+ wnd.opt.pos.h = rect.h || wnd.opt.pos.h;
130
+ if (wnd.opt.pos.maxX != null && parseInt(wnd.opt.pos.x) > wnd.opt.pos.maxX) {
131
+ wnd.opt.pos.x = (wnd.opt.pos.maxX - Math.max(wnd.opt.pos.w, parseInt(wnd.opt.pos.minW) || 0)) + 'px';
132
+ }
133
+ }
134
+
135
+ if (wnd.opt.isModal || wnd.opt.closeWhenMiss) {
136
+ return (
137
+ <>
138
+ <Overlay
139
+ renderChild={(zInd) => { return wnd.renderSelf(zInd++) }} closeWhenClick={wnd.opt.closeWhenMiss}
140
+ init={(ovl) => ovl.visible = wnd.visible}
141
+ onClose={() => wnd.close()}
142
+ isHidden={wnd.opt.hiddenOverlay}
143
+ >
144
+ </Overlay>
145
+ </>
146
+ )
147
+ }
148
+
149
+ return wnd.renderSelf();
150
+ }
151
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
152
+ renderSelf(zInd) {
153
+ const wnd = this;
154
+ return (
155
+ <>
156
+ <div
157
+ id={`window_${wnd.id}_`}
158
+ key={`window_${wnd.id}_${wnd.opt.keyAdd != null ? wnd.opt.keyAdd : ''}_`}
159
+ style={
160
+ {
161
+ width: wnd.opt.pos.w,
162
+ height: wnd.opt.pos.h,
163
+ top: wnd.opt.pos.y,
164
+ left: wnd.opt.pos.x,
165
+ minWidth: wnd.opt.pos.minW || '',
166
+ minHeight: wnd.opt.pos.minH || '',
167
+ maxWidth: wnd.opt.pos.maxW || '',
168
+ maxHeight: wnd.opt.pos.maxH || '',
169
+ zIndex: zInd || wnd.opt.zInd,
170
+ display: "flex",
171
+ flexDirection: "column",
172
+ justifyContent: "space-between",
173
+ position: "fixed",
174
+ overflow: 'hidden',
175
+ backgroundColor: 'white',
176
+ border: '1px solid',
177
+ }
178
+ }
179
+ className={`modal-window-wnd ${wnd.opt.windowClass || ''}`}
180
+ onMouseLeave={(e) => wnd.onMouseLeave(e)}
181
+ onMouseEnter={(e) => wnd.onMouseEnter(e)}
182
+ >
183
+ {wnd.opt.noHeader ? <></> : wnd.renderHeader()}
184
+ <div
185
+ key={`window_${wnd.id}_body_`}
186
+ wnd-body={1}
187
+ className={wnd.opt.bodyClass}
188
+ style={{ padding: wnd.opt.noPadding ? '0' : '', overflow: wnd.opt.noBodyOverflow ? 'hidden' : 'auto', height: '100%' }}
189
+ >
190
+ {wnd.renderContent(wnd)}
191
+ </div>
192
+ {wnd.opt.noFooter ? <></> : wnd.renderFooter()}
193
+ {!wnd.opt.resizable ? <></> : wnd.renderResizables()}
194
+ </div>
195
+ </>
196
+ );
197
+ }
198
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
199
+ renderHeader() {
200
+ const wnd = this;
201
+ return (
202
+ <div
203
+ key={`window_${wnd.id}_header_`}
204
+ wnd-header={1}
205
+ className={wnd.opt.headerClass}
206
+ style={{ display: 'flex', flexWrap: 'nowrap', justifyContent: 'space-between' }}
207
+ onMouseDown={(e) => wnd.mouseDownDrag(e)}
208
+ >
209
+ <h4 className={wnd.opt.titleClass} style={{ margin: '0.5em 0 0.5em 1.5em' }}>
210
+ {wnd.opt.title || ''}
211
+ </h4>
212
+ <button wnd-btn={`close_${wnd.id}_`} type="button" className="close" style={{ color: "black", lineHeight: '1', fontWeight: '21px', border: 'none' }} onClick={() => wnd.close()}>×</button>
213
+ </div>
214
+ )
215
+ }
216
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
217
+ renderFooter() {
218
+ const wnd = this;
219
+ return (
220
+ <div
221
+ key={`window_${wnd.id}_footer_`}
222
+ wnd-footer={1}
223
+ className={wnd.opt.footerClass}
224
+ onMouseDown={(e) => wnd.mouseDownDrag(e)}
225
+ style={
226
+ {
227
+ display: "flex",
228
+ flexWrap: "nowrap",
229
+ justifyContent: "space-between",
230
+ alignItems: "center"
231
+ }
232
+ } >
233
+ {wnd.buttons.map((btn, ind) => {
234
+ return (
235
+ <button
236
+ key={`window_${wnd.id}_${btn._ind}_${ind}_button_`}
237
+ wnd-btn={`button_${wnd.id}_${btn._ind}_`}
238
+ className={wnd.opt.footerButtonClass}
239
+ title={btn.title}
240
+ onClick={btn.onClick ? (e) => btn.onClick(e) : null}
241
+ disabled={btn.getDisabled ? btn.getDisabled() : false}
242
+ >
243
+ <i className={btn.imageClass}></i>
244
+ {btn.title}
245
+ </button>
246
+ )
247
+ })}
248
+ </div>
249
+ )
250
+ }
251
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
252
+ renderResizables() {
253
+ const wnd = this;
254
+
255
+ return (
256
+ <>
257
+ <div wnd-rsz-y={wnd.id}
258
+ key={`wnd-rsz-y_${wnd.id}_`}
259
+ style={
260
+ {
261
+ position: "absolute",
262
+ left: "-1px",
263
+ bottom: "-6px",
264
+ cursor: "s-resize",
265
+ height: "12px",
266
+ width: "calc(100% - 10px)",
267
+ zIndex: wnd.opt.zInd + 5
268
+ }
269
+ }
270
+ onMouseDown={(e) => wnd.mouseDownResize(e)}
271
+ >
272
+ </div>
273
+ <div wnd-rsz-x={wnd.id}
274
+ key={`wnd-rsz-x_${wnd.id}_`}
275
+ style={
276
+ {
277
+ position: "absolute",
278
+ right: "-6px",
279
+ top: "-1px",
280
+ cursor: "e-resize",
281
+ height: "calc(100% - 10px)",
282
+ width: "12px",
283
+ zIndex: wnd.opt.zInd + 5
284
+ }
285
+ }
286
+ onMouseDown={(e) => wnd.mouseDownResize(e)}
287
+ >
288
+ </div>
289
+ <div wnd-rsz-xy={wnd.id}
290
+ key={`wnd-rsz-xy_${wnd.id}_`}
291
+ style={
292
+ {
293
+ position: "absolute",
294
+ right: "-5px",
295
+ bottom: "-5px",
296
+ cursor: "se-resize",
297
+ height: "16px",
298
+ width: "16px",
299
+ zIndex: wnd.opt.zInd + 5
300
+ }
301
+ }
302
+ onMouseDown={(e) => wnd.mouseDownResize(e)}
303
+ >
304
+ </div>
305
+ </>
306
+ )
307
+ }
308
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
309
+ close() {
310
+ const wnd = this;
311
+
312
+ if (wnd.onClose) {
313
+ const ev = { self: wnd };
314
+ wnd.onClose(ev);
315
+ if (ev.cancel) return;
316
+ }
317
+
318
+ wnd.visible = false;
319
+ wnd.refreshState();
320
+ }
321
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
322
+ show(e) {
323
+ const wnd = this;
324
+ wnd.visible = true;
325
+
326
+ if (e) {
327
+ wnd.opt.pos.x = e.clientX;
328
+ wnd.opt.pos.y = e.clientY;
329
+ }
330
+
331
+ wnd.refreshState();
332
+ }
333
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
334
+ getDimensionsByContent(margin, padding) {
335
+ const wnd = this;
336
+ const renderFake = function () {
337
+ return (
338
+ <div>
339
+ {wnd.opt.noHeader ? <></> : wnd.renderHeader()}
340
+ <div
341
+ key={`window_${wnd.id}_body_`}
342
+ wnd-body={1}
343
+ className={wnd.opt.bodyClass}
344
+ style={{ padding: wnd.opt.noPadding ? '0' : '' }}
345
+ >
346
+ {wnd.renderContent(wnd, 'fake')}
347
+ </div>
348
+ {wnd.opt.noFooter ? <></> : wnd.renderFooter()}
349
+ {!wnd.opt.resizable ? <></> : wnd.renderResizables()}
350
+ </div>
351
+ )
352
+ }
353
+
354
+ const res = { w: 0, h: 0 };
355
+
356
+ ModalClass._isFake = true;
357
+
358
+ const fakeDiv = document.createElement('div');
359
+ fakeDiv.style.opacity = 0;
360
+ fakeDiv.style.position = 'fixed';
361
+ fakeDiv.style.height = 'auto';
362
+ fakeDiv.style.margin = margin || '';
363
+ fakeDiv.style.padding = padding || '';
364
+ fakeDiv.innerHTML = renderToStaticMarkup(renderFake());
365
+ document.body.append(fakeDiv);
366
+ const rect = getComputedStyle(fakeDiv);
367
+ res.w = parseInt(rect.width) + 2;
368
+ res.h = parseInt(rect.height) + 2;
369
+ fakeDiv.remove();
370
+
371
+ ModalClass._isFake = false;
372
+
373
+ return res;
374
+ }
375
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
376
+ setupEvents() {
377
+ const wnd = this;
378
+
379
+ function onKeyDown(e) {
380
+ const key = e && e.key ? e.key.toLowerCase() : '';
381
+
382
+ if ((key === 'esc' || key === 'escape') && wnd.opt.closeWhenEscape === true) {
383
+ wnd.close();
384
+ }
385
+ }
386
+
387
+ document.addEventListener('keydown', onKeyDown);
388
+
389
+ wnd.clearEvents = function () {
390
+ document.removeEventListener('keydown', onKeyDown);
391
+ }
392
+ }
393
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
394
+ onMouseLeave() {
395
+ const wnd = this;
396
+
397
+ if (wnd.opt.onMouseLeave) {
398
+ wnd.opt.onMouseLeave(wnd);
399
+ }
400
+
401
+ if (wnd.opt.closeWhenMouseLeave) {
402
+ wnd.close();
403
+ }
404
+ }
405
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
406
+ onMouseEnter(e) {
407
+ const wnd = this;
408
+ if (wnd.opt.onMouseEnter) {
409
+ wnd.opt.onMouseEnter(e);
410
+ }
411
+ }
412
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
413
+ mouseDownDrag(e) {
414
+ const wnd = this;
415
+ if (!wnd.visible || !wnd.opt.draggable) return;
416
+
417
+ if (e.target.tagName !== 'DIV') return;
418
+
419
+ const pos = wnd.opt.pos;
420
+
421
+ const elem = document.getElementById(`window_${wnd.id}_`);
422
+ if (!elem) {
423
+ log(`Elem window_${wnd.id}_ not found!`);
424
+ return;
425
+ }
426
+
427
+ const rect = elem.getBoundingClientRect();
428
+ const shiftX = e.pageX - rect.left;
429
+ const shiftY = e.pageY - rect.top;
430
+
431
+ moveAt(e.pageX, e.pageY);
432
+
433
+ // переносит окно на координаты (pageX, pageY), дополнительно учитывая изначальный сдвиг относительно указателя мыши
434
+ function moveAt(pageX, pageY) {
435
+ pos.x = pageX - shiftX;
436
+ pos.y = pageY - shiftY;
437
+
438
+ elem.style.left = pos.x + 'px';
439
+ elem.style.top = pos.y + 'px';
440
+ }
441
+
442
+ function onMouseMove(e) {
443
+ moveAt(e.pageX, e.pageY);
444
+ }
445
+
446
+ // передвигаем окно при событии mousemove
447
+ document.addEventListener('mousemove', onMouseMove);
448
+ document.addEventListener('mouseup', onMouseUp);
449
+ // отпустить окно, удалить ненужные обработчики
450
+ function onMouseUp() {
451
+ document.removeEventListener('mousemove', onMouseMove);
452
+ document.removeEventListener('mouseup', onMouseUp);
453
+ elem.ondragstart = null;
454
+ };
455
+
456
+ elem.ondragstart = function () {
457
+ return false;
458
+ };
459
+ };
460
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
461
+ mouseDownResize(e) {
462
+ const wnd = this;
463
+ if (!wnd.visible || !wnd.opt.resizable) return;
464
+
465
+ const pos = wnd.opt.pos;
466
+
467
+ const elem = document.getElementById(`window_${wnd.id}_`);
468
+
469
+ const cs = getComputedStyle(elem);
470
+ const [initW, initH] = [parseInt(cs.width), parseInt(cs.height)];
471
+
472
+ const shiftX = e.target.hasAttribute('wnd-rsz-x') || e.target.hasAttribute('wnd-rsz-xy') ? e.pageX : -1;
473
+ const shiftY = e.target.hasAttribute('wnd-rsz-y') || e.target.hasAttribute('wnd-rsz-xy') ? e.pageY : -1;
474
+
475
+ resize(e.pageX, e.pageY);
476
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
477
+ function resize(pageX, pageY) {
478
+ if (shiftX > 0) {
479
+ const w = initW + pageX - shiftX;
480
+
481
+ pos.w = (!pos.maxW || w <= pos.maxW) && (!pos.minW || w >= pos.minW) ? w : pos.w;
482
+ elem.style.width = pos.w + 'px';
483
+ }
484
+ if (shiftY > 0) {
485
+ const h = initH + pageY - shiftY;
486
+
487
+ pos.h = (!pos.maxH || h <= pos.maxH) && (!pos.minH || h >= pos.minH) ? h : pos.h;
488
+ elem.style.height = pos.h + 'px';
489
+ }
490
+ }
491
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
492
+ function onMouseMove(e) {
493
+ resize(e.pageX, e.pageY);
494
+ }
495
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
496
+ document.addEventListener('mousemove', onMouseMove);
497
+ document.addEventListener('mouseup', onMouseUp);
498
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
499
+ elem.ondragstart = function () {
500
+ return false;
501
+ };
502
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
503
+ function onMouseUp() {
504
+ document.removeEventListener('mousemove', onMouseMove);
505
+ document.removeEventListener('mouseup', onMouseUp);
506
+ elem.ondragstart = null;
507
+ };
508
+ };
509
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
510
+ }
511
+ // ==================================================================================================================================================================
@@ -0,0 +1,140 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { BaseComponent } from './Base';
3
+ // ==================================================================================================================================================================
4
+ export function Overlay(props) {
5
+ let ovl = null;
6
+
7
+ const [ovlState, setState] = useState({ ovl: ovl, ind: 0 });
8
+
9
+ if (ovlState.ovl) {
10
+ ovl = ovlState.ovl;
11
+ if (ovlState.ovl.closing) {
12
+ ovl.closing = false;
13
+ }
14
+ }
15
+ else {
16
+ ovl = new OverlayClass(props);
17
+ }
18
+
19
+ ovl.onClose = props.onClose;
20
+
21
+ if (props.init) {
22
+ props.init(ovl);
23
+ }
24
+
25
+ ovl.refreshState = function () {
26
+ setState({ ovl: ovl, ind: ovl.stateind++ });
27
+ }
28
+
29
+ useEffect(() => {
30
+ ovl.setupEvents();
31
+
32
+ return () => {
33
+ ovl.clearEvents();
34
+ }
35
+ }, [ovl])
36
+
37
+ return (ovl.render());
38
+ }
39
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
40
+ export class OverlayClass extends BaseComponent {
41
+ constructor(props) {
42
+ super(props);
43
+
44
+ const ovl = this;
45
+ ovl.opt = {};
46
+
47
+ ovl.id = OverlayClass._seq++;
48
+ ovl.uid = props.uid;
49
+
50
+ ovl.opt.zInd = props.zInd || ++OverlayClass._zInd;
51
+
52
+ ovl.opt.pos = props.pos || { x: 0, y: 0, w: '100%', h: '100%' };
53
+
54
+ ovl.opt.isHidden = props.isHidden;
55
+ ovl.opt.closeWhenClick = props.closeWhenClick;
56
+ ovl.opt.closeWhenEscape = props.closeWhenEscape;
57
+
58
+ ovl.opt.pos.x = !isNaN(ovl.opt.pos.x) ? ovl.opt.pos.x + 'px' : ovl.opt.pos.x;
59
+ ovl.opt.pos.y = !isNaN(ovl.opt.pos.y) ? ovl.opt.pos.y + 'px' : ovl.opt.pos.y;
60
+ ovl.opt.pos.w = !isNaN(ovl.opt.pos.w) ? ovl.opt.pos.w + 'px' : ovl.opt.pos.w;
61
+ ovl.opt.pos.h = !isNaN(ovl.opt.pos.h) ? ovl.opt.pos.h + 'px' : ovl.opt.pos.h;
62
+
63
+ ovl.renderChild = props.renderChild || function () { return null };
64
+
65
+ ovl.visible = props.visible != null ? props.visible : true;
66
+
67
+ ovl.stateind = 0;
68
+ }
69
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
70
+ static _seq = 0;
71
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
72
+ static _zInd = 999;
73
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
74
+ render() {
75
+ const ovl = this;
76
+ if (!ovl.visible) return <></>;
77
+
78
+ return (
79
+ <>
80
+ <div
81
+ key={`overlay_${ovl.id}_`}
82
+ onClick={(e) => ovl.onClick(e)}
83
+ style={
84
+ {
85
+ width: ovl.opt.pos.w,
86
+ height: ovl.opt.pos.h,
87
+ top: ovl.opt.pos.y,
88
+ left: ovl.opt.pos.x,
89
+ opacity: ovl.opt.opacity ? ovl.opt.opacity : ovl.opt.isHidden ? 0 : 0.2,
90
+ zIndex: ovl.opt.zInd,
91
+ backgroundColor: !ovl.opt.isHidden ? 'black' : '',
92
+ display: 'flex',
93
+ position: 'fixed',
94
+ }
95
+ }
96
+ className="overlay-default"
97
+ >
98
+ </div>
99
+ {ovl.renderChild(ovl.opt.zInd + 1)}
100
+ </>
101
+ );
102
+ }
103
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
104
+ close() {
105
+ const ovl = this;
106
+ ovl.visible = false;
107
+ if (ovl.onClose) {
108
+ ovl.onClose();
109
+ }
110
+ ovl.closing = true;
111
+
112
+ ovl.refreshState();
113
+ }
114
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
115
+ onClick() {
116
+ const ovl = this;
117
+
118
+ if (ovl.opt && ovl.opt.closeWhenClick) {
119
+ ovl.close();
120
+ }
121
+ }
122
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
123
+ setupEvents = function () {
124
+ const ovl = this;
125
+ function onKeyDown(e) {
126
+ const key = e && e.key ? e.key.toLowerCase() : '';
127
+
128
+ if ((key === 'esc' || key === 'escape') && ovl.opt && ovl.opt.closeWhenEscape) {
129
+ ovl.close();
130
+ }
131
+ }
132
+
133
+ document.addEventListener('keydown', onKeyDown);
134
+
135
+ ovl.clearEvents = function () {
136
+ document.removeEventListener('keydown', onKeyDown);
137
+ }
138
+ }
139
+ // -------------------------------------------------------------------------------------------------------------------------------------------------------------
140
+ }