dce-reactkit 3.7.9 → 3.7.10-beta.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/dist/cjs/index.js +161 -16
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/AppWrapper.d.ts +21 -0
- package/dist/cjs/types/components/Modal/ModalForWrapper.d.ts +9 -0
- package/dist/cjs/types/components/{Modal.d.ts → Modal/ModalProps.d.ts} +9 -9
- package/dist/cjs/types/components/Modal/index.d.ts +8 -0
- package/dist/esm/index.js +161 -16
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/AppWrapper.d.ts +21 -0
- package/dist/esm/types/components/Modal/ModalForWrapper.d.ts +9 -0
- package/dist/esm/types/components/{Modal.d.ts → Modal/ModalProps.d.ts} +9 -9
- package/dist/esm/types/components/Modal/index.d.ts +8 -0
- package/dist/index.d.ts +116 -110
- package/package.json +1 -1
- package/src/components/AppWrapper.tsx +129 -5
- package/src/components/IntelliTable.tsx +1 -1
- package/src/components/{Modal.tsx → Modal/ModalForWrapper.tsx} +22 -83
- package/src/components/Modal/ModalProps.ts +72 -0
- package/src/components/Modal/index.tsx +105 -0
|
@@ -19,11 +19,12 @@ import ModalButtonType from '../types/ModalButtonType';
|
|
|
19
19
|
import ModalType from '../types/ModalType';
|
|
20
20
|
import Variant from '../types/Variant';
|
|
21
21
|
import LogBuiltInMetadata from '../types/LogBuiltInMetadata';
|
|
22
|
+
import ModalProps from './Modal/ModalProps';
|
|
22
23
|
|
|
23
24
|
// Import shared components
|
|
24
25
|
// TODO: fix dependency cycle
|
|
25
26
|
// eslint-disable-next-line import/no-cycle
|
|
26
|
-
import
|
|
27
|
+
import ModalForWrapper from './Modal/ModalForWrapper';
|
|
27
28
|
|
|
28
29
|
// Import custom errors
|
|
29
30
|
import ErrorWithCode from '../errors/ErrorWithCode';
|
|
@@ -358,6 +359,99 @@ export const showSessionExpiredMessage = async () => {
|
|
|
358
359
|
}
|
|
359
360
|
};
|
|
360
361
|
|
|
362
|
+
/*----------------------------------------*/
|
|
363
|
+
/* --------------- Modals --------------- */
|
|
364
|
+
/*----------------------------------------*/
|
|
365
|
+
|
|
366
|
+
// Modal tuple with id and props
|
|
367
|
+
type ModalTuple = {
|
|
368
|
+
// Unique id
|
|
369
|
+
id: number,
|
|
370
|
+
// Modal props
|
|
371
|
+
props: ModalProps,
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
// Stored copies of setters
|
|
375
|
+
let setModals: (modals: ModalTuple[]) => void;
|
|
376
|
+
|
|
377
|
+
// Stored copies of modals
|
|
378
|
+
let modals: ModalTuple[] = [];
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Add a modal to the screen
|
|
382
|
+
* @author Gabe Abrams
|
|
383
|
+
* @param id the uniqueId of the modal
|
|
384
|
+
* @param props the props for the modal
|
|
385
|
+
*/
|
|
386
|
+
export const addModal = async (
|
|
387
|
+
id: number,
|
|
388
|
+
props: ModalProps,
|
|
389
|
+
) => {
|
|
390
|
+
// Wait for helper to exist
|
|
391
|
+
await waitForHelper(() => {
|
|
392
|
+
return !!setModals;
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
// Add modal
|
|
396
|
+
modals.push({
|
|
397
|
+
id,
|
|
398
|
+
props,
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// Update modals
|
|
402
|
+
setModals(modals);
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Update a modal on the screen by id (if it exists) with new props
|
|
407
|
+
* @author Gabe Abrams
|
|
408
|
+
* @param id the uniqueId of the modal
|
|
409
|
+
* @param props the new props for the modal
|
|
410
|
+
*/
|
|
411
|
+
export const updateModal = async (
|
|
412
|
+
id: number,
|
|
413
|
+
props: ModalProps,
|
|
414
|
+
) => {
|
|
415
|
+
// Wait for helper to exist
|
|
416
|
+
await waitForHelper(() => {
|
|
417
|
+
return !!setModals;
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// Update modal
|
|
421
|
+
modals = modals.map((modal) => {
|
|
422
|
+
if (modal.id === id) {
|
|
423
|
+
return {
|
|
424
|
+
id,
|
|
425
|
+
props,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
return modal;
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
// Update modals
|
|
432
|
+
setModals(modals);
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Remove a modal from the screen by id (if it exists)
|
|
437
|
+
* @author Gabe Abrams
|
|
438
|
+
* @param id the uniqueId of the modal
|
|
439
|
+
*/
|
|
440
|
+
export const removeModal = async (id: number) => {
|
|
441
|
+
// Wait for helper to exist
|
|
442
|
+
await waitForHelper(() => {
|
|
443
|
+
return !!setModals;
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// Remove modal
|
|
447
|
+
modals = modals.filter((modal) => {
|
|
448
|
+
return modal.id !== id;
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Update modals
|
|
452
|
+
setModals(modals);
|
|
453
|
+
};
|
|
454
|
+
|
|
361
455
|
/*------------------------------------------------------------------------*/
|
|
362
456
|
/* -------------------------------- Style ------------------------------- */
|
|
363
457
|
/*------------------------------------------------------------------------*/
|
|
@@ -464,6 +558,13 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
464
558
|
] = useState<boolean>(false);
|
|
465
559
|
setSessionHasExpired = setSessionHasExpiredInner;
|
|
466
560
|
|
|
561
|
+
// Modals
|
|
562
|
+
const [
|
|
563
|
+
modalsFromState,
|
|
564
|
+
setModalsInner,
|
|
565
|
+
] = useState<ModalTuple[]>([]);
|
|
566
|
+
setModals = setModalsInner;
|
|
567
|
+
|
|
467
568
|
/*------------------------------------------------------------------------*/
|
|
468
569
|
/* ------------------------------- Render ------------------------------- */
|
|
469
570
|
/*------------------------------------------------------------------------*/
|
|
@@ -479,7 +580,7 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
479
580
|
|
|
480
581
|
if (alertInfo) {
|
|
481
582
|
modal = (
|
|
482
|
-
<
|
|
583
|
+
<ModalForWrapper
|
|
483
584
|
key={`alert-${alertInfo.title}-${alertInfo.text}`}
|
|
484
585
|
title={alertInfo.title}
|
|
485
586
|
type={ModalType.Okay}
|
|
@@ -493,7 +594,7 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
493
594
|
onTopOfOtherModals
|
|
494
595
|
>
|
|
495
596
|
{alertInfo.text}
|
|
496
|
-
</
|
|
597
|
+
</ModalForWrapper>
|
|
497
598
|
);
|
|
498
599
|
}
|
|
499
600
|
|
|
@@ -501,7 +602,7 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
501
602
|
|
|
502
603
|
if (confirmInfo) {
|
|
503
604
|
modal = (
|
|
504
|
-
<
|
|
605
|
+
<ModalForWrapper
|
|
505
606
|
key={`confirm-${confirmInfo.title}-${confirmInfo.text}`}
|
|
506
607
|
title={confirmInfo.title}
|
|
507
608
|
type={ModalType.OkayCancel}
|
|
@@ -518,10 +619,26 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
518
619
|
dontAllowBackdropExit
|
|
519
620
|
>
|
|
520
621
|
{confirmInfo.text}
|
|
521
|
-
</
|
|
622
|
+
</ModalForWrapper>
|
|
522
623
|
);
|
|
523
624
|
}
|
|
524
625
|
|
|
626
|
+
/* ---------- Custom Modals --------- */
|
|
627
|
+
|
|
628
|
+
// List of modals added outside reactkit via the Modal component
|
|
629
|
+
const customModals: React.ReactNode[] = [];
|
|
630
|
+
|
|
631
|
+
// Add custom modals
|
|
632
|
+
modalsFromState.forEach((modalTuple) => {
|
|
633
|
+
customModals.push(
|
|
634
|
+
<ModalForWrapper
|
|
635
|
+
key={String(modalTuple.props.key ?? modalTuple.id)}
|
|
636
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
637
|
+
{...modalTuple.props}
|
|
638
|
+
/>,
|
|
639
|
+
);
|
|
640
|
+
});
|
|
641
|
+
|
|
525
642
|
/*----------------------------------------*/
|
|
526
643
|
/* ---------------- Views --------------- */
|
|
527
644
|
/*----------------------------------------*/
|
|
@@ -641,10 +758,12 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
641
758
|
background-color: white;
|
|
642
759
|
color: black;
|
|
643
760
|
border: 0.1rem solid black;
|
|
761
|
+
pointer-events: none;
|
|
644
762
|
}
|
|
645
763
|
div[data-popper-placement="top"] .tooltip-arrow::before {
|
|
646
764
|
border-top-color: white !important;
|
|
647
765
|
transform: translate(0, -0.05rem);
|
|
766
|
+
pointer-events: none;
|
|
648
767
|
}
|
|
649
768
|
`
|
|
650
769
|
: `
|
|
@@ -652,10 +771,12 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
652
771
|
background-color: black;
|
|
653
772
|
color: black;
|
|
654
773
|
border: 0.1rem solid white;
|
|
774
|
+
pointer-events: none;
|
|
655
775
|
}
|
|
656
776
|
div[data-popper-placement="top"] .tooltip-arrow::before {
|
|
657
777
|
border-top-color: black !important;
|
|
658
778
|
transform: translate(0, -0.05rem);
|
|
779
|
+
pointer-events: none;
|
|
659
780
|
}
|
|
660
781
|
`
|
|
661
782
|
);
|
|
@@ -679,6 +800,9 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
679
800
|
{/* Modal */}
|
|
680
801
|
{modal}
|
|
681
802
|
|
|
803
|
+
{/* Custom Modals */}
|
|
804
|
+
{customModals}
|
|
805
|
+
|
|
682
806
|
{/* Body */}
|
|
683
807
|
{body}
|
|
684
808
|
</>
|
|
@@ -26,7 +26,7 @@ import roundToNumDecimals from '../helpers/roundToNumDecimals';
|
|
|
26
26
|
import genCSV from '../helpers/genCSV';
|
|
27
27
|
|
|
28
28
|
// Import shared components
|
|
29
|
-
import Modal from './Modal';
|
|
29
|
+
import Modal from './Modal/ModalForWrapper';
|
|
30
30
|
import ModalType from '../types/ModalType';
|
|
31
31
|
import CheckboxButton from './CheckboxButton';
|
|
32
32
|
import CSVDownloadButton from './CSVDownloadButton';
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
/* eslint-disable react/destructuring-assignment */
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* The displayable modal component (this is the modal that's added to the
|
|
8
|
+
* wrapper, not the one that the programmer renders)
|
|
8
9
|
* @author Gabe Abrams
|
|
9
10
|
*/
|
|
10
11
|
|
|
@@ -12,18 +13,19 @@
|
|
|
12
13
|
import React, { useState, useEffect, useRef } from 'react';
|
|
13
14
|
|
|
14
15
|
// Import other components
|
|
15
|
-
import waitMs from '
|
|
16
|
+
import waitMs from '../../helpers/waitMs';
|
|
16
17
|
|
|
17
18
|
// Import types
|
|
18
|
-
import Variant from '
|
|
19
|
-
import ModalButtonType from '
|
|
20
|
-
import ModalSize from '
|
|
21
|
-
import ModalType from '
|
|
19
|
+
import Variant from '../../types/Variant';
|
|
20
|
+
import ModalButtonType from '../../types/ModalButtonType';
|
|
21
|
+
import ModalSize from '../../types/ModalSize';
|
|
22
|
+
import ModalType from '../../types/ModalType';
|
|
23
|
+
import ModalProps from './ModalProps';
|
|
22
24
|
|
|
23
25
|
// Import shared helpers
|
|
24
26
|
// TODO: fix dependency cycle
|
|
25
27
|
// eslint-disable-next-line import/no-cycle
|
|
26
|
-
import { isDarkModeOn } from '
|
|
28
|
+
import { isDarkModeOn } from '../../client/initClient';
|
|
27
29
|
|
|
28
30
|
/*------------------------------------------------------------------------*/
|
|
29
31
|
/* ------------------------------ Constants ----------------------------- */
|
|
@@ -142,7 +144,7 @@ const getModalButtonTypeToLabelAndVariant = () => {
|
|
|
142
144
|
/*------------------------------------------------------------------------*/
|
|
143
145
|
|
|
144
146
|
const style = `
|
|
145
|
-
.
|
|
147
|
+
.ModalForWrapper-backdrop {
|
|
146
148
|
position: fixed;
|
|
147
149
|
top: 0;
|
|
148
150
|
left: 0;
|
|
@@ -150,7 +152,7 @@ const style = `
|
|
|
150
152
|
height: 200vh;
|
|
151
153
|
background-color: rgba(0, 0, 0, 0.7);
|
|
152
154
|
}
|
|
153
|
-
.
|
|
155
|
+
.ModalForWrapper-fading-in {
|
|
154
156
|
animation-name: Modal-fading-in;
|
|
155
157
|
animation-duration: ${Math.floor(MS_TO_ANIMATE * 2)}ms;
|
|
156
158
|
animation-iteration-count: 1;
|
|
@@ -165,7 +167,7 @@ const style = `
|
|
|
165
167
|
opacity: 1;
|
|
166
168
|
}
|
|
167
169
|
}
|
|
168
|
-
.
|
|
170
|
+
.ModalForWrapper-animating-in {
|
|
169
171
|
animation-name: Modal-animating-in;
|
|
170
172
|
animation-duration: ${MS_TO_ANIMATE}ms;
|
|
171
173
|
animation-iteration-count: 1;
|
|
@@ -182,14 +184,14 @@ const style = `
|
|
|
182
184
|
opacity: 1;
|
|
183
185
|
}
|
|
184
186
|
}
|
|
185
|
-
.
|
|
186
|
-
animation-name:
|
|
187
|
+
.ModalForWrapper-animating-pop {
|
|
188
|
+
animation-name: ModalForWrapper-animating-pop;
|
|
187
189
|
animation-duration: ${MS_TO_ANIMATE}ms;
|
|
188
190
|
animation-iteration-count: 1;
|
|
189
191
|
animation-fill-mode: both;
|
|
190
192
|
animation-timing-function: ease-in-out;
|
|
191
193
|
}
|
|
192
|
-
@keyframes
|
|
194
|
+
@keyframes ModalForWrapper-animating-pop {
|
|
193
195
|
0% {
|
|
194
196
|
transform: scale(1);
|
|
195
197
|
opacity: 1;
|
|
@@ -205,74 +207,11 @@ const style = `
|
|
|
205
207
|
}
|
|
206
208
|
`;
|
|
207
209
|
|
|
208
|
-
/*------------------------------------------------------------------------*/
|
|
209
|
-
/* -------------------------------- Types ------------------------------- */
|
|
210
|
-
/*------------------------------------------------------------------------*/
|
|
211
|
-
|
|
212
|
-
type Props = {
|
|
213
|
-
// Type of the modal
|
|
214
|
-
type?: ModalType,
|
|
215
|
-
// Size of the modal
|
|
216
|
-
size?: ModalSize,
|
|
217
|
-
// Title of the modal (if excluded, no header)
|
|
218
|
-
title?: React.ReactNode,
|
|
219
|
-
// The body of the modal
|
|
220
|
-
children?: React.ReactNode,
|
|
221
|
-
// Handler to call when modal is closed (if excluded, not closable)
|
|
222
|
-
onClose?: (type: ModalButtonType) => void,
|
|
223
|
-
// If true, don't allow the user to click the backdrop to exit
|
|
224
|
-
dontAllowBackdropExit?: boolean,
|
|
225
|
-
// If true, don't show the "X" close button
|
|
226
|
-
dontShowXButton?: boolean,
|
|
227
|
-
// Custom label for "okay" button
|
|
228
|
-
okayLabel?: string,
|
|
229
|
-
// Custom variant for "okay" button
|
|
230
|
-
okayVariant?: Variant,
|
|
231
|
-
// Custom label for "cancel" button
|
|
232
|
-
cancelLabel?: string,
|
|
233
|
-
// Custom variant for "cancel" button
|
|
234
|
-
cancelVariant?: Variant,
|
|
235
|
-
// Custom label for "yes" button
|
|
236
|
-
yesLabel?: string,
|
|
237
|
-
// Custom variant for "yes" button
|
|
238
|
-
yesVariant?: Variant,
|
|
239
|
-
// Custom label for "no" button
|
|
240
|
-
noLabel?: string,
|
|
241
|
-
// Custom variant for "no" button
|
|
242
|
-
noVariant?: Variant,
|
|
243
|
-
// Custom label for "abandon" button
|
|
244
|
-
abandonLabel?: string,
|
|
245
|
-
// Custom variant for "abandon" button
|
|
246
|
-
abandonVariant?: Variant,
|
|
247
|
-
// Custom label for "goBack" button
|
|
248
|
-
goBackLabel?: string,
|
|
249
|
-
// Custom variant for "goBack" button
|
|
250
|
-
goBackVariant?: Variant,
|
|
251
|
-
// Custom label for "continue" button
|
|
252
|
-
continueLabel?: string,
|
|
253
|
-
// Custom variant for "continue" button
|
|
254
|
-
continueVariant?: Variant,
|
|
255
|
-
// Custom label for "imSure" button
|
|
256
|
-
imSureLabel?: string,
|
|
257
|
-
// Custom variant for "imSure" button
|
|
258
|
-
imSureVariant?: Variant,
|
|
259
|
-
// Custom label for "delete" button
|
|
260
|
-
deleteLabel?: string,
|
|
261
|
-
// Custom variant for "delete" button
|
|
262
|
-
deleteVariant?: Variant,
|
|
263
|
-
// Custom label for "confirm" button
|
|
264
|
-
confirmLabel?: string,
|
|
265
|
-
// Custom variant for "confirm" button
|
|
266
|
-
confirmVariant?: Variant,
|
|
267
|
-
// True if modal should be on top of other modals
|
|
268
|
-
onTopOfOtherModals?: boolean,
|
|
269
|
-
};
|
|
270
|
-
|
|
271
210
|
/*------------------------------------------------------------------------*/
|
|
272
211
|
/* ------------------------------ Component ----------------------------- */
|
|
273
212
|
/*------------------------------------------------------------------------*/
|
|
274
213
|
|
|
275
|
-
const Modal: React.FC<
|
|
214
|
+
const Modal: React.FC<ModalProps> = (props) => {
|
|
276
215
|
/*------------------------------------------------------------------------*/
|
|
277
216
|
/* -------------------------------- Setup ------------------------------- */
|
|
278
217
|
/*------------------------------------------------------------------------*/
|
|
@@ -383,7 +322,7 @@ const Modal: React.FC<Props> = (props) => {
|
|
|
383
322
|
<button
|
|
384
323
|
key={modalButtonType}
|
|
385
324
|
type="button"
|
|
386
|
-
className={`
|
|
325
|
+
className={`ModalForWrapper-${modalButtonType}-button btn btn-${variant} ${last ? '' : 'me-1'}`}
|
|
387
326
|
onClick={() => {
|
|
388
327
|
handleClose(modalButtonType);
|
|
389
328
|
}}
|
|
@@ -408,10 +347,10 @@ const Modal: React.FC<Props> = (props) => {
|
|
|
408
347
|
let animationClass = '';
|
|
409
348
|
let backdropAnimationClass = '';
|
|
410
349
|
if (animatingIn) {
|
|
411
|
-
animationClass = '
|
|
412
|
-
backdropAnimationClass = '
|
|
350
|
+
animationClass = 'ModalForWrapper-animating-in';
|
|
351
|
+
backdropAnimationClass = 'ModalForWrapper-fading-in';
|
|
413
352
|
} else if (animatingPop) {
|
|
414
|
-
animationClass = '
|
|
353
|
+
animationClass = 'ModalForWrapper-animating-pop';
|
|
415
354
|
}
|
|
416
355
|
|
|
417
356
|
// Render the modal
|
|
@@ -433,7 +372,7 @@ const Modal: React.FC<Props> = (props) => {
|
|
|
433
372
|
>
|
|
434
373
|
<style>{style}</style>
|
|
435
374
|
<div
|
|
436
|
-
className={`
|
|
375
|
+
className={`ModalForWrapper-backdrop ${backdropAnimationClass}`}
|
|
437
376
|
style={{
|
|
438
377
|
zIndex: 5000000003,
|
|
439
378
|
}}
|
|
@@ -502,7 +441,7 @@ const Modal: React.FC<Props> = (props) => {
|
|
|
502
441
|
{(onClose && !dontShowXButton) && (
|
|
503
442
|
<button
|
|
504
443
|
type="button"
|
|
505
|
-
className="
|
|
444
|
+
className="ModalForWrapper-x-button btn-close"
|
|
506
445
|
aria-label="Close"
|
|
507
446
|
style={{
|
|
508
447
|
backgroundColor: (
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Import types
|
|
2
|
+
import Variant from '../../types/Variant';
|
|
3
|
+
import ModalButtonType from '../../types/ModalButtonType';
|
|
4
|
+
import ModalSize from '../../types/ModalSize';
|
|
5
|
+
import ModalType from '../../types/ModalType';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Props for the Modal component
|
|
9
|
+
* @author Gabe Abrams
|
|
10
|
+
*/
|
|
11
|
+
type ModalProps = {
|
|
12
|
+
// Key of the modal
|
|
13
|
+
key?: string,
|
|
14
|
+
// Type of the modal
|
|
15
|
+
type?: ModalType,
|
|
16
|
+
// Size of the modal
|
|
17
|
+
size?: ModalSize,
|
|
18
|
+
// Title of the modal (if excluded, no header)
|
|
19
|
+
title?: React.ReactNode,
|
|
20
|
+
// The body of the modal
|
|
21
|
+
children?: React.ReactNode,
|
|
22
|
+
// Handler to call when modal is closed (if excluded, not closable)
|
|
23
|
+
onClose?: (type: ModalButtonType) => void,
|
|
24
|
+
// If true, don't allow the user to click the backdrop to exit
|
|
25
|
+
dontAllowBackdropExit?: boolean,
|
|
26
|
+
// If true, don't show the "X" close button
|
|
27
|
+
dontShowXButton?: boolean,
|
|
28
|
+
// Custom label for "okay" button
|
|
29
|
+
okayLabel?: string,
|
|
30
|
+
// Custom variant for "okay" button
|
|
31
|
+
okayVariant?: Variant,
|
|
32
|
+
// Custom label for "cancel" button
|
|
33
|
+
cancelLabel?: string,
|
|
34
|
+
// Custom variant for "cancel" button
|
|
35
|
+
cancelVariant?: Variant,
|
|
36
|
+
// Custom label for "yes" button
|
|
37
|
+
yesLabel?: string,
|
|
38
|
+
// Custom variant for "yes" button
|
|
39
|
+
yesVariant?: Variant,
|
|
40
|
+
// Custom label for "no" button
|
|
41
|
+
noLabel?: string,
|
|
42
|
+
// Custom variant for "no" button
|
|
43
|
+
noVariant?: Variant,
|
|
44
|
+
// Custom label for "abandon" button
|
|
45
|
+
abandonLabel?: string,
|
|
46
|
+
// Custom variant for "abandon" button
|
|
47
|
+
abandonVariant?: Variant,
|
|
48
|
+
// Custom label for "goBack" button
|
|
49
|
+
goBackLabel?: string,
|
|
50
|
+
// Custom variant for "goBack" button
|
|
51
|
+
goBackVariant?: Variant,
|
|
52
|
+
// Custom label for "continue" button
|
|
53
|
+
continueLabel?: string,
|
|
54
|
+
// Custom variant for "continue" button
|
|
55
|
+
continueVariant?: Variant,
|
|
56
|
+
// Custom label for "imSure" button
|
|
57
|
+
imSureLabel?: string,
|
|
58
|
+
// Custom variant for "imSure" button
|
|
59
|
+
imSureVariant?: Variant,
|
|
60
|
+
// Custom label for "delete" button
|
|
61
|
+
deleteLabel?: string,
|
|
62
|
+
// Custom variant for "delete" button
|
|
63
|
+
deleteVariant?: Variant,
|
|
64
|
+
// Custom label for "confirm" button
|
|
65
|
+
confirmLabel?: string,
|
|
66
|
+
// Custom variant for "confirm" button
|
|
67
|
+
confirmVariant?: Variant,
|
|
68
|
+
// True if modal should be on top of other modals
|
|
69
|
+
onTopOfOtherModals?: boolean,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default ModalProps;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* General use modal component
|
|
3
|
+
* @author Gabe Abrams
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Import React
|
|
7
|
+
import React, { useEffect, useRef } from 'react';
|
|
8
|
+
|
|
9
|
+
// Import shared types
|
|
10
|
+
import ModalProps from './ModalProps';
|
|
11
|
+
|
|
12
|
+
// Import helpers from AppWrapper
|
|
13
|
+
import { addModal, removeModal, updateModal } from '../AppWrapper';
|
|
14
|
+
|
|
15
|
+
/*------------------------------------------------------------------------*/
|
|
16
|
+
/* --------------------------- Static Helpers --------------------------- */
|
|
17
|
+
/*------------------------------------------------------------------------*/
|
|
18
|
+
|
|
19
|
+
// Next unique id
|
|
20
|
+
let nextUniqueId = 0;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get a new unique id for this modal
|
|
24
|
+
* @author Gabe Abrams
|
|
25
|
+
* @returns new unique id
|
|
26
|
+
*/
|
|
27
|
+
const getNextUniqueId = (): number => {
|
|
28
|
+
// eslint-disable-next-line no-plusplus
|
|
29
|
+
return nextUniqueId++;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/*------------------------------------------------------------------------*/
|
|
33
|
+
/* ------------------------------ Component ----------------------------- */
|
|
34
|
+
/*------------------------------------------------------------------------*/
|
|
35
|
+
|
|
36
|
+
const Modal: React.FC<ModalProps> = (props) => {
|
|
37
|
+
/*------------------------------------------------------------------------*/
|
|
38
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
39
|
+
/*------------------------------------------------------------------------*/
|
|
40
|
+
|
|
41
|
+
/* -------------- Refs -------------- */
|
|
42
|
+
|
|
43
|
+
// Initialize refs
|
|
44
|
+
const id = useRef<number>(getNextUniqueId());
|
|
45
|
+
|
|
46
|
+
/*------------------------------------------------------------------------*/
|
|
47
|
+
/* ------------------------- Lifecycle Functions ------------------------ */
|
|
48
|
+
/*------------------------------------------------------------------------*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Mount: add to app wrapper
|
|
52
|
+
* @author Gabe Abrams
|
|
53
|
+
*/
|
|
54
|
+
useEffect(
|
|
55
|
+
() => {
|
|
56
|
+
addModal(id.current, props);
|
|
57
|
+
},
|
|
58
|
+
[],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Update: update modal props in app wrapper when props change
|
|
63
|
+
* @author Gabe Abrams
|
|
64
|
+
*/
|
|
65
|
+
useEffect(
|
|
66
|
+
() => {
|
|
67
|
+
// Update modal props
|
|
68
|
+
updateModal(id.current, props);
|
|
69
|
+
},
|
|
70
|
+
[props],
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Unmount: remove from app wrapper when unmounting
|
|
75
|
+
* @author Gabe Abrams
|
|
76
|
+
*/
|
|
77
|
+
useEffect(
|
|
78
|
+
() => {
|
|
79
|
+
return () => {
|
|
80
|
+
// Remove modal
|
|
81
|
+
removeModal(id.current);
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
[],
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
/*------------------------------------------------------------------------*/
|
|
88
|
+
/* ------------------------------- Render ------------------------------- */
|
|
89
|
+
/*------------------------------------------------------------------------*/
|
|
90
|
+
|
|
91
|
+
/*----------------------------------------*/
|
|
92
|
+
/* --------------- Main UI -------------- */
|
|
93
|
+
/*----------------------------------------*/
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div className="Modal-shell d-none" />
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/*------------------------------------------------------------------------*/
|
|
101
|
+
/* ------------------------------- Wrap Up ------------------------------ */
|
|
102
|
+
/*------------------------------------------------------------------------*/
|
|
103
|
+
|
|
104
|
+
// Export component
|
|
105
|
+
export default Modal;
|