react-toast-master 1.0.0 → 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/src/Toast.jsx DELETED
@@ -1,669 +0,0 @@
1
- import { CheckCheck, CircleDashed, Info, PinIcon, X, XCircle } from "lucide-react";
2
- import { createContext, useContext, useEffect, useRef, useState } from "react";
3
-
4
- import "./components/styles/background.css";
5
- import "./components/styles/border.css";
6
- import "./components/styles/button.css";
7
- import "./components/styles/shadows.css";
8
- import "./components/styles/textAlign.css";
9
- import "./components/styles/textColor.css";
10
- import "./components/styles/toastPosition.css";
11
- import "./components/styles/animation.css";
12
- import "./components/styles/breakPoints.css";
13
- import "./components/styles/skew.css";
14
-
15
- import Footer from "./components/footer/Footer";
16
- import InnerFooter from "./components/footer/InnerFooter";
17
- import LoadFooter from "./components/footer/LoadFooter";
18
- import { getAnimation } from "./components/functions/animation";
19
-
20
- const ToastContext = createContext();
21
-
22
- export const useToast = () => useContext(ToastContext);
23
-
24
- export const Toast = ({ children }) => {
25
- const [toastType, setToastType] = useState("");
26
- const [toastMessage, setToastMessage] = useState("");
27
- const [confirmResolve, setConfirmResolve] = useState(null);
28
- const [toastTimeout, setToastTimeout] = useState(null);
29
- const [showCloseButton, setShowCloseButton] = useState(true);
30
- const [showButton, setShowButton] = useState(null);
31
-
32
- const [toastBackground, setToastBackground] = useState("");
33
- const [toastPosition, setToastPosition] = useState("");
34
- const [toastSkew, setToastSkew] = useState("");
35
- const [toastAnimation, setToastAnimation] = useState("");
36
- const [toastShadow, setToastShadow] = useState("");
37
- const [toastRadius, setToastRadius] = useState("");
38
- const [toastAlignment, setToastAlignment] = useState("");
39
- const [showOverlay, setShowOverlay] = useState(false);
40
-
41
- const [footer, setFooter] = useState(null);
42
- const [showLoadFooter, setShowLoadFooter] = useState(false);
43
- const [loadFooter, setLoadFooter] = useState(null);
44
-
45
- const confirmButtonRef = useRef(null);
46
-
47
- const toastBackgroundClasses = {
48
- white: "bg_white",
49
- dark: "bg_dark",
50
- gray: "bg_gray",
51
- success: "bg_success",
52
- error: "bg_error",
53
- warning: "bg_warning",
54
- info: "bg_info",
55
- glass: "bg_glass",
56
- transparent: "bg_transparent",
57
- };
58
-
59
- const toastPositionClasses = {
60
- top: "top",
61
- topFull: "topFull",
62
- topLeft: "topLeft",
63
- topRight: "topRight",
64
-
65
- bottom: "bottom",
66
- bottomFull: "bottomFull",
67
- bottomLeft: "bottomLeft",
68
- bottomRight: "bottomRight",
69
-
70
- center: "middle",
71
- };
72
- const toastRevealAnimation = {
73
- down: "ani_down",
74
- top: "ani_top",
75
- left: "ani_left",
76
- right: "ani_right",
77
- fade: "ani_fade",
78
- zoom: "ani_zoom",
79
- jelly: "ani_jelly",
80
- };
81
-
82
- const toastAwesomeAlignment = {
83
- left: "text_start",
84
- right: "text_end",
85
- center: "text_center",
86
- };
87
- const toastAwesomeSkew = {
88
- right3: "right3",
89
- right6: "right6",
90
- right12: "right12",
91
- left3: "left3",
92
- left6: "left6",
93
- left12: "left12",
94
- };
95
- const toastAwesomeShadow = {
96
- none: "",
97
- gray: "box_shadow",
98
- block: "box_shadow_block",
99
- error: "shadow_error",
100
- white: "shadow_white",
101
- dark: "shadow_dark",
102
- success: "shadow_success",
103
- info: "shadow_info",
104
- warning: "shadow_warning",
105
- around: "shadow_around",
106
- };
107
- const toastAwesomeRadius = {
108
- none: "rounded_none",
109
- sm: "rounded_sm",
110
- md: "rounded_md",
111
- lg: "rounded_lg",
112
- xl: "rounded_xl",
113
- twoXl: "rounded_2xl",
114
- full: "rounded_full",
115
- };
116
-
117
- /**
118
- * Find the position class key from the toastPositionClasses object
119
- * that matches the toastPosition prop value.~
120
- * @param {Object} toastPositionClasses - the object containing all the
121
- * position classes as keys and their corresponding values
122
- * @param {string} toastPosition - the position to be matched
123
- * @returns {string} the key of the matching position class
124
- */
125
- const toastPG = Object.keys(toastPositionClasses).find(
126
- (key) => toastPositionClasses[key] === toastPosition
127
- );
128
-
129
- /**
130
- * Find the background class key from the toastBackgroundClasses object
131
- * that matches the toastBackground prop value.
132
- * @param {Object} toastBackgroundClasses - the object containing all the
133
- * background classes as keys and their corresponding values
134
- * @param {string} toastBackground - the background color to be matched
135
- * @returns {string} the key of the matching background class
136
- */
137
- const toastBG = Object.keys(toastBackgroundClasses).find(
138
- (key) => toastBackgroundClasses[key] === toastBackground
139
- );
140
-
141
- const animation = getAnimation(toastAnimation, toastPG);
142
-
143
- const hideToast = () => {
144
- setToastAnimation(animation);
145
-
146
- const timeoutId = setTimeout(() => {
147
- setToastType("");
148
- setToastMessage("");
149
- clearTimeout(toastTimeout);
150
- setToastAnimation("");
151
- }, 300);
152
-
153
- return () => clearTimeout(timeoutId);
154
- };
155
-
156
- /**
157
- * Displays a toast message.
158
- *
159
- * @param {Object} toast The toast object with the following properties:
160
- * @param {string} type The type of the toast (e.g. success, error, etc.)
161
- * @param {string} message The message to be displayed in the toast
162
- * @param {string} bg The background color of the toast
163
- * @param {string} position The position of the toast
164
- * @param {string} transition The transition animation of the toast
165
- * @param {*} loadFooter The footer will display after 7 seconds
166
- * @param {*} footer The footer of the toast when it's not a "loading" and "confirm" toast
167
- * @param {string} skew The skew of the toast
168
- * @param {boolean} cancelButton Whether or not to display a cancel button
169
- * @param {string} shadow The shadow of the toast
170
- * @param {string} radius The border radius of the toast
171
- * @param {string} align The alignment of the toasts text
172
- * @returns {Promise} A promise that resolves when the toast is confirmed/rejected
173
- */
174
- const toastMaster = (toast) => {
175
- if (toastTimeout) {
176
- clearTimeout(toastTimeout);
177
- }
178
- return new Promise((resolve) => {
179
- setToastAnimation(animation);
180
-
181
- const openToast = () => {
182
- openNewToast(toast, resolve);
183
- };
184
-
185
- if (toastType) {
186
- setTimeout(openToast, 300);
187
- } else {
188
- openToast();
189
- }
190
- });
191
- };
192
-
193
- const openNewToast = (toast, resolve) => {
194
- const {
195
- type = "success",
196
- message = "",
197
- bg = "white",
198
- position = "top",
199
- transition = "zoom",
200
- loadFooter = null,
201
- footer = null,
202
- skew = "",
203
- cancelButton = false,
204
- shadow = "gray",
205
- radius = "lg",
206
- align = "center",
207
- } = toast;
208
-
209
- setToastType(type);
210
- setToastMessage(message);
211
- setLoadFooter(loadFooter);
212
- setFooter(footer);
213
- setShowButton(cancelButton);
214
-
215
- const toastBackground = toastBackgroundClasses[bg] || "";
216
- const toastPosition = toastPositionClasses[position] || "";
217
- const revealAnimation = toastRevealAnimation[transition] || "";
218
- const toastSkew = toastAwesomeSkew[skew] || "";
219
- const toastShadow = toastAwesomeShadow[shadow] || "";
220
- const toastRadius = toastAwesomeRadius[radius] || "";
221
- const toastAlignment = toastAwesomeAlignment[align] || "";
222
-
223
- setToastBackground(toastBackground);
224
- setToastPosition(toastPosition);
225
- setToastAnimation(revealAnimation);
226
- setToastSkew(toastSkew);
227
- setToastShadow(toastShadow);
228
- setToastRadius(toastRadius);
229
- setToastAlignment(toastAlignment);
230
-
231
- if (
232
- type === "success" ||
233
- type === "successWhite" ||
234
- type === "successDark" ||
235
- type === "error" ||
236
- type === "errorWhite" ||
237
- type === "errorDark" ||
238
- type === "warning" ||
239
- type === "warningWhite" ||
240
- type === "warningDark" ||
241
- type === "info" ||
242
- type === "infoWhite" ||
243
- type === "infoDark" ||
244
- type === "basic" ||
245
- type === "basicDark"
246
- ) {
247
- setToastTimeout(setTimeout(() => hideToast(), 4500));
248
- }
249
-
250
- if (type === "confirm" || type === "confirmDark") {
251
- setConfirmResolve(() => resolve);
252
- }
253
-
254
- if (type === "loading" || type === "loadingWhite" || type === "loadingDark") {
255
- setShowLoadFooter(false);
256
- setTimeout(() => setShowLoadFooter(true), 7330);
257
- }
258
- if (type === "loading" || type === "loadingWhite" || type === "loadingDark") {
259
- setToastType("");
260
- setToastMessage("");
261
- setLoadFooter("");
262
- setFooter("");
263
- setShowButton("");
264
-
265
- setTimeout(() => {
266
- setToastType(type);
267
- setToastMessage(message);
268
- setLoadFooter(loadFooter);
269
- setFooter(footer);
270
- setShowButton(cancelButton);
271
- }, 330);
272
-
273
- return;
274
- }
275
- };
276
-
277
- /**
278
- * Handles the show/hide of the close button of the toast.
279
- *
280
- * The close button is hidden when the loading toast initially appears,
281
- * after 7 seconds the close button is shown.
282
- */
283
- useEffect(() => {
284
- if (toastType === "loading" || toastType === "loadingWhite" || toastType === "loadingDark") {
285
- setShowCloseButton(false);
286
- setTimeout(() => setShowCloseButton(true), 7000);
287
- } else {
288
- setShowCloseButton(true);
289
- }
290
- }, [toastType]); // eslint-disable-line react-hooks/exhaustive-deps
291
-
292
- useEffect(() => {
293
- /**
294
- * Handles the key down event and hides the toast if the escape key is pressed.
295
- *
296
- * @param {Object} event - the key down event object
297
- */
298
- const handleKeyDown = (event) => {
299
- if (event.key === "Escape") {
300
- hideToast();
301
- }
302
- };
303
- document.addEventListener("keydown", handleKeyDown);
304
- return () => {
305
- document.removeEventListener("keydown", handleKeyDown);
306
- };
307
- }, []);
308
-
309
- /**
310
- * Handles the confirmation of "confirm" tost type.
311
- *
312
- * @returns {Function} a function to clear the timeout
313
- */
314
- const handleConfirm = () => {
315
- setToastAnimation(animation);
316
-
317
- const timeoutId = setTimeout(() => {
318
- if (confirmResolve) {
319
- confirmResolve(true);
320
- }
321
- setToastAnimation("");
322
- hideToast();
323
- setShowOverlay(false);
324
- }, 330);
325
-
326
- return () => clearTimeout(timeoutId);
327
- };
328
- /**
329
- * Sets focus to the confirm button when toastType is "confirm" or "confirmDark"
330
- */
331
- useEffect(() => {
332
- if (toastType === "confirm" || toastType === "confirmDark") {
333
- confirmButtonRef.current.focus();
334
- }
335
- }, [toastType]);
336
-
337
- /**
338
- * Handles the cancellation of "confirm" and "confirmDark" tost types.
339
- */
340
- const handleCancel = () => {
341
- if (confirmResolve) {
342
- confirmResolve(false);
343
- }
344
- hideToast();
345
- setShowOverlay(false);
346
- };
347
-
348
- const toastClasses = {
349
- success: "text_success",
350
- error: "text_error",
351
- loading: "text_warning",
352
- warning: "text_warning",
353
- warningStay: "text_warning",
354
- info: "text_info",
355
- infoStay: "text_info",
356
- confirm: "text_white",
357
- basic: "text_white",
358
-
359
- successWhite: "text_white",
360
- errorWhite: "text_white",
361
- loadingWhite: "text_white",
362
- warningWhite: "text_white",
363
- warningStayWhite: "text_white",
364
- infoWhite: "text_white",
365
- infoStayWhite: "text_white",
366
-
367
- successDark: "text_dark",
368
- errorDark: "text_dark",
369
- loadingDark: "text_dark",
370
- warningDark: "text_dark",
371
- warningStayDark: "text_dark",
372
- infoDark: "text_dark",
373
- infoStayDark: "text_dark ",
374
- confirmDark: "text_dark ",
375
- basicDark: "text_dark ",
376
- };
377
-
378
- /**
379
- * Create a proxy that will return the appropriate icon component based on
380
- * the prop name passed to it.
381
- * @returns {React.Component} Icon component
382
- */
383
- const iconComponent = new Proxy(
384
- {},
385
- {
386
- /**
387
- * Get the icon component based on the prop name.
388
- * @param {Object} target - The target object
389
- * @param {string} prop - The prop name
390
- * @returns {React.Component} Icon component
391
- */
392
- get(target, prop) {
393
- switch (prop) {
394
- case "success":
395
- case "successWhite":
396
- case "successDark":
397
- return <CheckCheck />;
398
-
399
- case "error":
400
- case "errorWhite":
401
- case "errorDark":
402
- return <XCircle />;
403
-
404
- case "loading":
405
- case "loadingWhite":
406
- case "loadingDark":
407
- return <CircleDashed className="animate_spin" />;
408
-
409
- case "warning":
410
- case "warningWhite":
411
- case "warningDark":
412
- case "warningStay":
413
- case "warningStayWhite":
414
- case "warningStayDark":
415
- return <Info />;
416
-
417
- case "info":
418
- case "infoWhite":
419
- case "infoDark":
420
- case "infoStay":
421
- case "infoStayWhite":
422
- case "infoStayDark":
423
- return <PinIcon className="rotate_deg" />;
424
-
425
- default:
426
- return undefined;
427
- }
428
- },
429
- }
430
- );
431
-
432
- /**
433
- * Set of toast types that are not auto-hidden
434
- *
435
- * These are toast types that do not hide automatically, instead they require
436
- * manual dismissal, hence we clear the timeout when the user hovers over the
437
- * toast and set it again when the user leaves the toast.
438
- */
439
- const nonAutoHideTypesSet = new Set([
440
- "confirm",
441
- "confirmWhite",
442
- "confirmDark",
443
- "infoStay",
444
- "infoStayWhite",
445
- "infoStayDark",
446
- "loading",
447
- "loadingWhite",
448
- "loadingDark",
449
- "warningStay",
450
- "warningStayWhite",
451
- "warningStayDark",
452
- ]);
453
-
454
- /**
455
- * Handle the mouseenter event on the toast
456
- *
457
- * If the toast type is not in the nonAutoHideTypesSet, then we clear the
458
- * toast timeout, so that the toast does not get hidden automatically.
459
- */
460
- const handleMouseEnter = () => {
461
- if (!nonAutoHideTypesSet.has(toastType)) {
462
- clearTimeout(toastTimeout);
463
- }
464
- };
465
-
466
- /**
467
- * Handle the mouseleave event on the toast
468
- *
469
- * If the toast type is not in the nonAutoHideTypesSet, then we set the
470
- * toast timeout again, so that the toast gets hidden after the timeout
471
- * duration.
472
- */
473
- const handleMouseLeave = () => {
474
- if (!nonAutoHideTypesSet.has(toastType)) {
475
- setToastTimeout(setTimeout(hideToast, 1500));
476
- }
477
- };
478
-
479
- /**
480
- * Sets the showOverlay state based on the type of the toast
481
- *
482
- * ShowOverlay is using class "overlay" to show a semi transparent overlay
483
- * and blur on beneath of "confirm" and "confirmDark" toast
484
- *
485
- * If the toast type is either confirm or confirmDark, then set
486
- * showOverlay to true, else set it to false
487
- */
488
- useEffect(() => {
489
- setShowOverlay(toastType === "confirm" || toastType === "confirmDark");
490
- }, [toastType]);
491
-
492
- return (
493
- <ToastContext.Provider value={{ toastMaster, hideToast }}>
494
- <>
495
- {children}
496
- {toastType && (
497
- <>
498
- {(toastType === "confirm" || toastType === "confirmDark") && (
499
- <div className={`overlay ${showOverlay ? "show" : ""}`} />
500
- )}
501
- <div
502
- className={`outer_container ${toastPosition} ${toastAnimation}`}
503
- style={{ zIndex: "9999" }}
504
- >
505
- <div
506
- className={`inner_container ${toastClasses[toastType]} ${toastBackground} ${toastSkew} ${toastShadow} ${toastRadius}`}
507
- onMouseEnter={handleMouseEnter}
508
- onMouseLeave={handleMouseLeave}
509
- >
510
- <div
511
- className={`
512
- ${
513
- toastPG === "bottomFull" || toastPG === "topFull"
514
- ? "toast_width_full"
515
- : toastType === "confirm" || toastType === "confirmDark"
516
- ? "toast_width_confirm"
517
- : "toast_width"
518
- }`}
519
- >
520
- <div className={`toast_message ${toastAlignment}`}>
521
- {toastType !== "confirm" &&
522
- toastType !== "confirmDark" &&
523
- toastType !== "basic" &&
524
- toastType !== "basicDark" && (
525
- <div>
526
- <span className="sr_only">toast icon</span>
527
- <span aria-hidden="true">{iconComponent[toastType]}</span>
528
- </div>
529
- )}
530
- <>{toastMessage}</>
531
-
532
- {/* close button below */}
533
- <div
534
- className={`closeDiv ${
535
- showCloseButton &&
536
- showButton &&
537
- toastType !== "confirm" &&
538
- toastType !== "confirmDark" &&
539
- toastPG !== "bottomFull" &&
540
- toastPG !== "topFull"
541
- ? `div_flex`
542
- : "div_hidden"
543
- }`}
544
- >
545
- <div>
546
- <button
547
- onClick={hideToast}
548
- id="close"
549
- className={`closeButton
550
- ${
551
- toastBG === "white"
552
- ? "bg_whiter"
553
- : toastBG === "glass" || toastBG === "transparent"
554
- ? "bg_glass_close"
555
- : "bg_darker"
556
- }`}
557
- >
558
- {/* This span is just for accessibility purposes so that screen
559
- readers will know what the close button does. */}
560
- <span className="sr_only">close toast</span>
561
- {/* This is the close icon. */}
562
- <X
563
- aria-hidden="true"
564
- size={18}
565
- />
566
- </button>
567
- </div>
568
- </div>
569
- </div>
570
-
571
- {["confirm", "confirmDark"].includes(toastType) && footer && (
572
- <InnerFooter
573
- footer={footer}
574
- toastBG={toastBG}
575
- toastAlignment={toastAlignment}
576
- toastType={toastType}
577
- />
578
- )}
579
-
580
- <>
581
- {(toastType === "confirm" || toastType === "confirmDark") && (
582
- <div
583
- className={`confirm_div
584
- ${
585
- toastAlignment === "text_start"
586
- ? "justify_end"
587
- : toastAlignment === "text_end"
588
- ? "justify_start"
589
- : toastAlignment === "text_center"
590
- ? "justify_center"
591
- : null
592
- }
593
- `}
594
- >
595
- <button
596
- className={`cancel_button ${
597
- toastBG === "white"
598
- ? "cancel_button_dark"
599
- : toastBG === "success" ||
600
- toastBG === "warning" ||
601
- toastBG === "error" ||
602
- toastBG === "info" ||
603
- toastBG === "grWarning" ||
604
- toastBG === "grError" ||
605
- toastBG === "dark"
606
- ? "cancel_button_all"
607
- : "cancel_button_glass"
608
- }`}
609
- onClick={handleCancel}
610
- >
611
- <span className="sr_only">close toast</span>
612
- Cancel
613
- </button>
614
-
615
- <button
616
- ref={confirmButtonRef}
617
- className={`confirm_button
618
- ${toastBG === "dark" ? "confirm_button_dark" : "confirm_button_white"}`}
619
- onClick={handleConfirm}
620
- >
621
- <span className="sr_only">confirm action</span>
622
- Confirm
623
- </button>
624
- </div>
625
- )}
626
- </>
627
- </div>
628
-
629
- <>
630
- {!(
631
- toastType === "confirmDark" ||
632
- toastType === "confirm" ||
633
- toastPG === "bottomFull" ||
634
- toastPG === "topFull"
635
- ) && (
636
- <div>
637
- {footer && (
638
- <Footer
639
- footer={footer}
640
- toastBG={toastBG}
641
- toastAlignment={toastAlignment}
642
- />
643
- )}
644
- </div>
645
- )}
646
-
647
- {!(
648
- toastPG === "bottomFull" ||
649
- toastPG === "topFull" ||
650
- toastType === "confirmDark" ||
651
- toastType === "confirm"
652
- ) &&
653
- showLoadFooter &&
654
- loadFooter && (
655
- <LoadFooter
656
- toastAlignment={toastAlignment}
657
- toastBG={toastBG}
658
- loadFooter={loadFooter}
659
- />
660
- )}
661
- </>
662
- </div>
663
- </div>
664
- </>
665
- )}
666
- </>
667
- </ToastContext.Provider>
668
- );
669
- };
@@ -1,22 +0,0 @@
1
- import "../styles/textColor.css";
2
- import "../styles/breakPoints.css";
3
-
4
- const Footer = ({ footer, toastAlignment, toastBG }) => (
5
- <div className={`_footer toast_width ${toastAlignment} ${toastBGClasses[toastBG]}`}>{footer}</div>
6
- );
7
-
8
- const toastBGClasses = {
9
- dark: "footer_dark",
10
- warning: "footer_dark",
11
- white: "footer_white",
12
- info: "footer_info",
13
- error: "footer_error",
14
- success: "footer_success",
15
- gray: "footer_success",
16
- glass: "footer_success",
17
- transparent: "footer_success",
18
- grWarning: "footer_success",
19
- grError: "footer_success",
20
- };
21
-
22
- export default Footer;
@@ -1,22 +0,0 @@
1
- import "../styles/textColor.css";
2
- import "../styles/breakPoints.css";
3
-
4
- const InnerFooter = ({ footer, toastAlignment, toastBG }) => (
5
- <div className={`innerFooter ${toastAlignment} ${toastBGClasses[toastBG]}`}>{footer}</div>
6
- );
7
-
8
- const toastBGClasses = {
9
- dark: "footer_dark",
10
- warning: "footer_dark",
11
- white: "footer_white",
12
- info: "footer_info",
13
- error: "footer_error",
14
- success: "footer_success",
15
- gray: "footer_success",
16
- glass: "footer_success",
17
- transparent: "footer_success",
18
- grWarning: "footer_success",
19
- grError: "footer_success",
20
- };
21
-
22
- export default InnerFooter;