react-graph-grid 0.0.0

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