goey-toast 0.2.1 → 0.2.2
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/README.md +119 -1
- package/dist/index.cjs +597 -143
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +95 -25
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +53 -3
- package/dist/index.d.ts +53 -3
- package/dist/index.js +598 -145
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2,21 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var sonner = require('sonner');
|
|
5
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
6
5
|
var framerMotion = require('framer-motion');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
|
|
8
8
|
// src/components/GoeyToaster.tsx
|
|
9
9
|
|
|
10
|
+
// src/presets.ts
|
|
11
|
+
var animationPresets = {
|
|
12
|
+
smooth: { bounce: 0.1, spring: true },
|
|
13
|
+
bouncy: { bounce: 0.6, spring: true },
|
|
14
|
+
subtle: { bounce: 0.05, spring: true },
|
|
15
|
+
snappy: { bounce: 0.4, spring: true }
|
|
16
|
+
};
|
|
17
|
+
|
|
10
18
|
// src/context.ts
|
|
11
19
|
var _position = "bottom-right";
|
|
20
|
+
var _dir = "ltr";
|
|
12
21
|
var _spring = true;
|
|
13
22
|
var _bounce = void 0;
|
|
23
|
+
var _theme = "light";
|
|
24
|
+
function setGoeyTheme(theme) {
|
|
25
|
+
_theme = theme;
|
|
26
|
+
}
|
|
27
|
+
function getGoeyTheme() {
|
|
28
|
+
return _theme;
|
|
29
|
+
}
|
|
14
30
|
function setGoeyPosition(position) {
|
|
15
31
|
_position = position;
|
|
16
32
|
}
|
|
17
33
|
function getGoeyPosition() {
|
|
18
34
|
return _position;
|
|
19
35
|
}
|
|
36
|
+
function setGoeyDir(dir) {
|
|
37
|
+
_dir = dir;
|
|
38
|
+
}
|
|
39
|
+
function getGoeyDir() {
|
|
40
|
+
return _dir;
|
|
41
|
+
}
|
|
20
42
|
function setGoeySpring(spring) {
|
|
21
43
|
_spring = spring;
|
|
22
44
|
}
|
|
@@ -36,6 +58,34 @@ function setGoeyVisibleToasts(n) {
|
|
|
36
58
|
function getGoeyVisibleToasts() {
|
|
37
59
|
return _visibleToasts;
|
|
38
60
|
}
|
|
61
|
+
var _swipeToDismiss = true;
|
|
62
|
+
function setGoeySwipeToDismiss(enabled) {
|
|
63
|
+
_swipeToDismiss = enabled;
|
|
64
|
+
}
|
|
65
|
+
function getGoeySwipeToDismiss() {
|
|
66
|
+
return _swipeToDismiss;
|
|
67
|
+
}
|
|
68
|
+
var _maxQueue = Infinity;
|
|
69
|
+
function setGoeyMaxQueue(n) {
|
|
70
|
+
_maxQueue = n;
|
|
71
|
+
}
|
|
72
|
+
function getGoeyMaxQueue() {
|
|
73
|
+
return _maxQueue;
|
|
74
|
+
}
|
|
75
|
+
var _queueOverflow = "drop-oldest";
|
|
76
|
+
function setGoeyQueueOverflow(strategy) {
|
|
77
|
+
_queueOverflow = strategy;
|
|
78
|
+
}
|
|
79
|
+
function getGoeyQueueOverflow() {
|
|
80
|
+
return _queueOverflow;
|
|
81
|
+
}
|
|
82
|
+
var _showProgress = false;
|
|
83
|
+
function setGoeyShowProgress(show) {
|
|
84
|
+
_showProgress = show;
|
|
85
|
+
}
|
|
86
|
+
function getGoeyShowProgress() {
|
|
87
|
+
return _showProgress;
|
|
88
|
+
}
|
|
39
89
|
var _containerHovered = false;
|
|
40
90
|
var _hoverSubs = /* @__PURE__ */ new Set();
|
|
41
91
|
function setContainerHovered(hovered) {
|
|
@@ -52,101 +102,15 @@ function subscribeContainerHovered(cb) {
|
|
|
52
102
|
_hoverSubs.delete(cb);
|
|
53
103
|
};
|
|
54
104
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
richColors,
|
|
65
|
-
visibleToasts,
|
|
66
|
-
dir,
|
|
67
|
-
spring = true,
|
|
68
|
-
bounce
|
|
69
|
-
}) {
|
|
70
|
-
react.useEffect(() => {
|
|
71
|
-
setGoeyPosition(position);
|
|
72
|
-
}, [position]);
|
|
73
|
-
react.useEffect(() => {
|
|
74
|
-
setGoeySpring(spring);
|
|
75
|
-
}, [spring]);
|
|
76
|
-
react.useEffect(() => {
|
|
77
|
-
setGoeyBounce(bounce);
|
|
78
|
-
}, [bounce]);
|
|
79
|
-
react.useEffect(() => {
|
|
80
|
-
setGoeyVisibleToasts(visibleToasts ?? 3);
|
|
81
|
-
}, [visibleToasts]);
|
|
82
|
-
react.useEffect(() => {
|
|
83
|
-
let expandObs = null;
|
|
84
|
-
let currentOl = null;
|
|
85
|
-
const syncFromExpanded = (ol) => {
|
|
86
|
-
const anyExpanded = ol.querySelector('[data-sonner-toast][data-expanded="true"]') !== null;
|
|
87
|
-
setContainerHovered(anyExpanded);
|
|
88
|
-
};
|
|
89
|
-
const attach = (ol) => {
|
|
90
|
-
if (ol === currentOl) return;
|
|
91
|
-
expandObs?.disconnect();
|
|
92
|
-
currentOl = ol;
|
|
93
|
-
expandObs = new MutationObserver(() => syncFromExpanded(ol));
|
|
94
|
-
expandObs.observe(ol, { attributes: true, attributeFilter: ["data-expanded"], subtree: true });
|
|
95
|
-
syncFromExpanded(ol);
|
|
96
|
-
};
|
|
97
|
-
const el = document.querySelector("[data-sonner-toaster]");
|
|
98
|
-
if (el) attach(el);
|
|
99
|
-
const bodyObs = new MutationObserver(() => {
|
|
100
|
-
const found = document.querySelector("[data-sonner-toaster]");
|
|
101
|
-
if (found) {
|
|
102
|
-
attach(found);
|
|
103
|
-
} else if (currentOl) {
|
|
104
|
-
expandObs?.disconnect();
|
|
105
|
-
currentOl = null;
|
|
106
|
-
setContainerHovered(false);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
bodyObs.observe(document.body, { childList: true, subtree: true });
|
|
110
|
-
return () => {
|
|
111
|
-
bodyObs.disconnect();
|
|
112
|
-
expandObs?.disconnect();
|
|
113
|
-
setContainerHovered(false);
|
|
114
|
-
};
|
|
115
|
-
}, []);
|
|
116
|
-
react.useEffect(() => {
|
|
117
|
-
if (process.env.NODE_ENV !== "development") return;
|
|
118
|
-
const el = document.createElement("div");
|
|
119
|
-
el.setAttribute("data-goey-toast-css", "");
|
|
120
|
-
el.style.position = "absolute";
|
|
121
|
-
el.style.width = "0";
|
|
122
|
-
el.style.height = "0";
|
|
123
|
-
el.style.overflow = "hidden";
|
|
124
|
-
el.style.pointerEvents = "none";
|
|
125
|
-
document.body.appendChild(el);
|
|
126
|
-
const value = getComputedStyle(el).getPropertyValue("--goey-toast");
|
|
127
|
-
document.body.removeChild(el);
|
|
128
|
-
if (!value) {
|
|
129
|
-
console.warn(
|
|
130
|
-
'[goey-toast] Styles not found. Make sure to import the CSS:\n\n import "goey-toast/styles.css";\n'
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
}, []);
|
|
134
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
135
|
-
sonner.Toaster,
|
|
136
|
-
{
|
|
137
|
-
position,
|
|
138
|
-
duration,
|
|
139
|
-
gap,
|
|
140
|
-
offset,
|
|
141
|
-
theme,
|
|
142
|
-
toastOptions: { unstyled: true, ...toastOptions },
|
|
143
|
-
expand,
|
|
144
|
-
closeButton,
|
|
145
|
-
richColors,
|
|
146
|
-
visibleToasts: 99,
|
|
147
|
-
dir
|
|
148
|
-
}
|
|
149
|
-
);
|
|
105
|
+
var _announceSubs = /* @__PURE__ */ new Set();
|
|
106
|
+
function announce(message, politeness = "polite") {
|
|
107
|
+
_announceSubs.forEach((cb) => cb({ message, politeness }));
|
|
108
|
+
}
|
|
109
|
+
function subscribeAnnouncements(cb) {
|
|
110
|
+
_announceSubs.add(cb);
|
|
111
|
+
return () => {
|
|
112
|
+
_announceSubs.delete(cb);
|
|
113
|
+
};
|
|
150
114
|
}
|
|
151
115
|
var DefaultIcon = ({ size = 20, className }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
152
116
|
"svg",
|
|
@@ -309,8 +273,18 @@ var styles = {
|
|
|
309
273
|
actionSuccess: "goey-actionSuccess",
|
|
310
274
|
actionError: "goey-actionError",
|
|
311
275
|
actionWarning: "goey-actionWarning",
|
|
312
|
-
actionInfo: "goey-actionInfo"
|
|
276
|
+
actionInfo: "goey-actionInfo",
|
|
277
|
+
progressWrapper: "goey-progressWrapper",
|
|
278
|
+
progressBar: "goey-progressBar",
|
|
279
|
+
progressDefault: "goey-progressDefault",
|
|
280
|
+
progressSuccess: "goey-progressSuccess",
|
|
281
|
+
progressError: "goey-progressError",
|
|
282
|
+
progressWarning: "goey-progressWarning",
|
|
283
|
+
progressInfo: "goey-progressInfo",
|
|
284
|
+
progressPaused: "goey-progressPaused",
|
|
285
|
+
timestamp: "goey-timestamp"
|
|
313
286
|
};
|
|
287
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
|
|
314
288
|
var phaseIconMap = {
|
|
315
289
|
default: DefaultIcon,
|
|
316
290
|
success: SuccessIcon,
|
|
@@ -334,6 +308,14 @@ var actionColorMap = {
|
|
|
334
308
|
warning: styles.actionWarning,
|
|
335
309
|
info: styles.actionInfo
|
|
336
310
|
};
|
|
311
|
+
var progressColorMap = {
|
|
312
|
+
loading: styles.progressInfo,
|
|
313
|
+
default: styles.progressDefault,
|
|
314
|
+
success: styles.progressSuccess,
|
|
315
|
+
error: styles.progressError,
|
|
316
|
+
warning: styles.progressWarning,
|
|
317
|
+
info: styles.progressInfo
|
|
318
|
+
};
|
|
337
319
|
var PH = 34;
|
|
338
320
|
var DEFAULT_DISPLAY_DURATION = 4e3;
|
|
339
321
|
var DEFAULT_EXPAND_DUR = 0.6;
|
|
@@ -425,7 +407,19 @@ function syncSonnerHeights(wrapperEl, includeOffsets = false) {
|
|
|
425
407
|
for (const t of toasts) t.style.removeProperty("transition");
|
|
426
408
|
}
|
|
427
409
|
}
|
|
428
|
-
function
|
|
410
|
+
function memoizePath(fn) {
|
|
411
|
+
let lastArgs = null;
|
|
412
|
+
let lastResult = "";
|
|
413
|
+
return (pw, bw, th, t) => {
|
|
414
|
+
if (lastArgs && lastArgs[0] === pw && lastArgs[1] === bw && lastArgs[2] === th && lastArgs[3] === t) {
|
|
415
|
+
return lastResult;
|
|
416
|
+
}
|
|
417
|
+
lastResult = fn(pw, bw, th, t);
|
|
418
|
+
lastArgs = [pw, bw, th, t];
|
|
419
|
+
return lastResult;
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function morphPathRaw(pw, bw, th, t) {
|
|
429
423
|
const pr = PH / 2;
|
|
430
424
|
const pillW = Math.min(pw, bw);
|
|
431
425
|
const bodyH = PH + (th - PH) * t;
|
|
@@ -462,7 +456,7 @@ function morphPath(pw, bw, th, t) {
|
|
|
462
456
|
`Z`
|
|
463
457
|
].join(" ");
|
|
464
458
|
}
|
|
465
|
-
function
|
|
459
|
+
function morphPathCenterRaw(pw, bw, th, t) {
|
|
466
460
|
const pr = PH / 2;
|
|
467
461
|
const pillW = Math.min(pw, bw);
|
|
468
462
|
const pillOffset = (bw - pillW) / 2;
|
|
@@ -525,6 +519,8 @@ function morphPathCenter(pw, bw, th, t) {
|
|
|
525
519
|
`Z`
|
|
526
520
|
].join(" ");
|
|
527
521
|
}
|
|
522
|
+
var morphPath = memoizePath(morphPathRaw);
|
|
523
|
+
var morphPathCenter = memoizePath(morphPathCenterRaw);
|
|
528
524
|
var SMOOTH_EASE = [0.4, 0, 0.2, 1];
|
|
529
525
|
var GoeyToast = ({
|
|
530
526
|
title,
|
|
@@ -533,22 +529,31 @@ var GoeyToast = ({
|
|
|
533
529
|
icon,
|
|
534
530
|
phase,
|
|
535
531
|
classNames,
|
|
536
|
-
fillColor
|
|
532
|
+
fillColor: fillColorProp,
|
|
537
533
|
borderColor,
|
|
538
534
|
borderWidth,
|
|
539
535
|
timing,
|
|
536
|
+
preset,
|
|
540
537
|
spring: springProp,
|
|
541
538
|
bounce: bounceProp,
|
|
539
|
+
showProgress: showProgressProp,
|
|
542
540
|
toastId
|
|
543
541
|
}) => {
|
|
542
|
+
const theme = getGoeyTheme();
|
|
543
|
+
const fillColor = fillColorProp ?? (theme === "dark" ? "#1a1a1a" : "#ffffff");
|
|
544
544
|
const position = getGoeyPosition();
|
|
545
|
-
const
|
|
545
|
+
const dir = getGoeyDir();
|
|
546
|
+
const posIsRight = position?.includes("right") ?? false;
|
|
546
547
|
const isCenter = position?.includes("center") ?? false;
|
|
548
|
+
const isRight = dir === "rtl" ? isCenter ? false : !posIsRight : posIsRight;
|
|
547
549
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
548
|
-
const
|
|
549
|
-
const
|
|
550
|
+
const presetConfig = preset ? animationPresets[preset] : void 0;
|
|
551
|
+
const useSpring = springProp ?? presetConfig?.spring ?? getGoeySpring();
|
|
552
|
+
const bounceVal = bounceProp ?? presetConfig?.bounce ?? getGoeyBounce() ?? 0.4;
|
|
553
|
+
const showProgress = showProgressProp ?? getGoeyShowProgress();
|
|
550
554
|
const [actionSuccess, setActionSuccess] = react.useState(null);
|
|
551
555
|
const [dismissing, setDismissing] = react.useState(false);
|
|
556
|
+
const [progressKey, setProgressKey] = react.useState(0);
|
|
552
557
|
const [hovered, setHovered] = react.useState(false);
|
|
553
558
|
const hoveredRef = react.useRef(false);
|
|
554
559
|
const containerHoveredRef = react.useRef(getContainerHovered());
|
|
@@ -592,8 +597,10 @@ var GoeyToast = ({
|
|
|
592
597
|
if (p <= 0 || b <= 0 || h <= 0) return;
|
|
593
598
|
const t = Math.max(0, Math.min(1, morphTRef.current));
|
|
594
599
|
const pos = getGoeyPosition();
|
|
595
|
-
const
|
|
600
|
+
const d = getGoeyDir();
|
|
596
601
|
const centerPos = pos?.includes("center") ?? false;
|
|
602
|
+
const posRight = pos?.includes("right") ?? false;
|
|
603
|
+
const rightSide = d === "rtl" ? centerPos ? false : !posRight : posRight;
|
|
597
604
|
if (centerPos) {
|
|
598
605
|
const centerBw = Math.max(dimsRef.current.bw, expandedDimsRef.current.bw, p);
|
|
599
606
|
pathRef.current?.setAttribute("d", morphPathCenter(p, centerBw, h, t));
|
|
@@ -680,7 +687,7 @@ var GoeyToast = ({
|
|
|
680
687
|
dimsRef.current = { pw: pw2, bw: bw2, th: th2 };
|
|
681
688
|
setDims({ pw: pw2, bw: bw2, th: th2 });
|
|
682
689
|
}, []);
|
|
683
|
-
|
|
690
|
+
useIsomorphicLayoutEffect(() => {
|
|
684
691
|
measure();
|
|
685
692
|
const t = setTimeout(measure, 100);
|
|
686
693
|
return () => clearTimeout(t);
|
|
@@ -707,8 +714,8 @@ var GoeyToast = ({
|
|
|
707
714
|
const el = wrapperRef.current;
|
|
708
715
|
const springConfig = phase2 === "collapse" ? squishSpring(collapseDur, DEFAULT_COLLAPSE_DUR, bounceVal) : squishSpring(expandDur, DEFAULT_EXPAND_DUR, bounceVal);
|
|
709
716
|
const bScale = bounceVal / 0.4;
|
|
710
|
-
const compressY = (phase2 === "collapse" ? 0.
|
|
711
|
-
const expandX = (phase2 === "collapse" ? 0.
|
|
717
|
+
const compressY = (phase2 === "collapse" ? 0.035 : 0.12) * bScale;
|
|
718
|
+
const expandX = (phase2 === "collapse" ? 0.018 : 0.06) * bScale;
|
|
712
719
|
blobSquishCtrl.current = framerMotion.animate(0, 1, {
|
|
713
720
|
...springConfig,
|
|
714
721
|
onUpdate: (v) => {
|
|
@@ -726,7 +733,7 @@ var GoeyToast = ({
|
|
|
726
733
|
}
|
|
727
734
|
});
|
|
728
735
|
}, [prefersReducedMotion, expandDur, collapseDur, useSpring, bounceVal]);
|
|
729
|
-
|
|
736
|
+
useIsomorphicLayoutEffect(() => {
|
|
730
737
|
if (!hasDims || collapsingRef.current) return;
|
|
731
738
|
const prev = { ...aDims.current };
|
|
732
739
|
const target = { pw, bw, th };
|
|
@@ -778,7 +785,7 @@ var GoeyToast = ({
|
|
|
778
785
|
}
|
|
779
786
|
}, [hasDims, squishDelayMs, triggerLandingSquish]);
|
|
780
787
|
const prevShowBody = react.useRef(false);
|
|
781
|
-
|
|
788
|
+
useIsomorphicLayoutEffect(() => {
|
|
782
789
|
if (!prevShowBody.current && showBody && !hoveredRef.current) {
|
|
783
790
|
const t = setTimeout(() => triggerLandingSquish("expand"), 80);
|
|
784
791
|
return () => clearTimeout(t);
|
|
@@ -870,12 +877,14 @@ var GoeyToast = ({
|
|
|
870
877
|
}, [isExpanded, flush, prefersReducedMotion, useSpring, triggerLandingSquish]);
|
|
871
878
|
const remainingRef = react.useRef(null);
|
|
872
879
|
const timerStartRef = react.useRef(0);
|
|
880
|
+
const progressDelayRef = react.useRef(0);
|
|
873
881
|
react.useEffect(() => {
|
|
874
882
|
if (!showBody || actionSuccess || dismissing) return;
|
|
875
883
|
const expandDelayMs = prefersReducedMotion ? 0 : 330;
|
|
876
884
|
const collapseMs = prefersReducedMotion ? 10 : 0.9 * 1e3;
|
|
877
885
|
const displayMs = timing?.displayDuration ?? DEFAULT_DISPLAY_DURATION;
|
|
878
886
|
const fullDelay = displayMs - expandDelayMs - collapseMs;
|
|
887
|
+
progressDelayRef.current = Math.max(fullDelay, 0);
|
|
879
888
|
if (fullDelay <= 0) return;
|
|
880
889
|
if (hoveredRef.current || containerHoveredRef.current) return;
|
|
881
890
|
const delay = remainingRef.current ?? fullDelay;
|
|
@@ -913,6 +922,7 @@ var GoeyToast = ({
|
|
|
913
922
|
reExpandingRef.current = true;
|
|
914
923
|
setDismissing(false);
|
|
915
924
|
setShowBody(true);
|
|
925
|
+
if (showProgress) setProgressKey((k) => k + 1);
|
|
916
926
|
const currentT = morphTRef.current;
|
|
917
927
|
const startDims = { ...aDims.current };
|
|
918
928
|
const morphExpandTransition = useSpring ? { type: "spring", duration: 0.9, bounce: bounceVal } : { duration: 0.6, ease: SMOOTH_EASE };
|
|
@@ -1079,13 +1089,56 @@ var GoeyToast = ({
|
|
|
1079
1089
|
} catch {
|
|
1080
1090
|
}
|
|
1081
1091
|
}, [effectiveAction]);
|
|
1092
|
+
const SWIPE_THRESHOLD = 100;
|
|
1093
|
+
const swipeStartRef = react.useRef(null);
|
|
1094
|
+
const [swipeOffsetX, setSwipeOffsetX] = react.useState(0);
|
|
1095
|
+
const isSwipingRef = react.useRef(false);
|
|
1096
|
+
const handleTouchStart = react.useCallback((e) => {
|
|
1097
|
+
if (!getGoeySwipeToDismiss()) return;
|
|
1098
|
+
const touch = e.touches[0];
|
|
1099
|
+
swipeStartRef.current = { x: touch.clientX, y: touch.clientY };
|
|
1100
|
+
isSwipingRef.current = false;
|
|
1101
|
+
}, []);
|
|
1102
|
+
const handleTouchMove = react.useCallback((e) => {
|
|
1103
|
+
if (!swipeStartRef.current || !getGoeySwipeToDismiss()) return;
|
|
1104
|
+
const touch = e.touches[0];
|
|
1105
|
+
const dx = touch.clientX - swipeStartRef.current.x;
|
|
1106
|
+
const dy = touch.clientY - swipeStartRef.current.y;
|
|
1107
|
+
if (!isSwipingRef.current && Math.abs(dy) > Math.abs(dx) && Math.abs(dy) > 10) {
|
|
1108
|
+
swipeStartRef.current = null;
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
if (!isSwipingRef.current && Math.abs(dx) > 10) {
|
|
1112
|
+
isSwipingRef.current = true;
|
|
1113
|
+
}
|
|
1114
|
+
if (isSwipingRef.current) {
|
|
1115
|
+
setSwipeOffsetX(dx);
|
|
1116
|
+
}
|
|
1117
|
+
}, []);
|
|
1118
|
+
const handleTouchEnd = react.useCallback(() => {
|
|
1119
|
+
if (!getGoeySwipeToDismiss()) {
|
|
1120
|
+
swipeStartRef.current = null;
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
if (isSwipingRef.current && Math.abs(swipeOffsetX) >= SWIPE_THRESHOLD && toastId) {
|
|
1124
|
+
sonner.toast.dismiss(toastId);
|
|
1125
|
+
}
|
|
1126
|
+
swipeStartRef.current = null;
|
|
1127
|
+
isSwipingRef.current = false;
|
|
1128
|
+
setSwipeOffsetX(0);
|
|
1129
|
+
}, [swipeOffsetX, toastId]);
|
|
1130
|
+
const swipeOpacity = swipeOffsetX !== 0 ? Math.max(0, 1 - Math.abs(swipeOffsetX) / (SWIPE_THRESHOLD * 1.5)) : 1;
|
|
1131
|
+
const swipeTranslate = swipeOffsetX !== 0 ? `translateX(${swipeOffsetX}px)` : "";
|
|
1082
1132
|
const renderIcon = () => {
|
|
1083
1133
|
if (!actionSuccess && icon) return icon;
|
|
1084
1134
|
if (isLoading) return /* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, { size: 18, className: styles.spinnerSpin });
|
|
1085
1135
|
const IconComponent = phaseIconMap[effectivePhase];
|
|
1086
1136
|
return /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { size: 18 });
|
|
1087
1137
|
};
|
|
1088
|
-
const iconTransition =
|
|
1138
|
+
const iconTransition = react.useMemo(
|
|
1139
|
+
() => prefersReducedMotion ? { duration: 0.01 } : { duration: 0.2 },
|
|
1140
|
+
[prefersReducedMotion]
|
|
1141
|
+
);
|
|
1089
1142
|
const iconEl = /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${styles.iconWrapper}${classNames?.icon ? ` ${classNames.icon}` : ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1090
1143
|
framerMotion.motion.div,
|
|
1091
1144
|
{
|
|
@@ -1098,17 +1151,43 @@ var GoeyToast = ({
|
|
|
1098
1151
|
isLoading ? "spinner" : effectivePhase
|
|
1099
1152
|
) }) });
|
|
1100
1153
|
const titleEl = /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${styles.title}${classNames?.title ? ` ${classNames.title}` : ""}`, children: effectiveTitle });
|
|
1154
|
+
const createdAtRef = react.useRef(/* @__PURE__ */ new Date());
|
|
1155
|
+
const timestampStr = react.useMemo(
|
|
1156
|
+
() => createdAtRef.current.toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit", second: "2-digit" }),
|
|
1157
|
+
[]
|
|
1158
|
+
);
|
|
1101
1159
|
const iconAndTitle = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1102
1160
|
iconEl,
|
|
1103
1161
|
titleEl
|
|
1104
1162
|
] });
|
|
1105
|
-
|
|
1163
|
+
const basePositionStyle = react.useMemo(
|
|
1164
|
+
() => isCenter ? { margin: "0 auto" } : isRight ? { marginLeft: "auto", transform: "scaleX(-1)" } : {},
|
|
1165
|
+
[isCenter, isRight]
|
|
1166
|
+
);
|
|
1167
|
+
const wrapperStyle = react.useMemo(() => {
|
|
1168
|
+
if (swipeTranslate) {
|
|
1169
|
+
return {
|
|
1170
|
+
...basePositionStyle,
|
|
1171
|
+
transform: (basePositionStyle.transform ? basePositionStyle.transform + " " : "") + swipeTranslate,
|
|
1172
|
+
opacity: swipeOpacity,
|
|
1173
|
+
transition: "none"
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
return Object.keys(basePositionStyle).length > 0 ? basePositionStyle : void 0;
|
|
1177
|
+
}, [basePositionStyle, swipeTranslate, swipeOpacity]);
|
|
1178
|
+
const contentStyle = react.useMemo(
|
|
1179
|
+
() => isCenter ? { textAlign: "center" } : isRight ? { transform: "scaleX(-1)", textAlign: "right" } : { textAlign: "left" },
|
|
1180
|
+
[isCenter, isRight]
|
|
1181
|
+
);
|
|
1182
|
+
const handleMouseEnter = react.useCallback(() => {
|
|
1106
1183
|
hoveredRef.current = true;
|
|
1107
1184
|
setHovered(true);
|
|
1108
|
-
},
|
|
1185
|
+
}, []);
|
|
1186
|
+
const handleMouseLeave = react.useCallback(() => {
|
|
1109
1187
|
hoveredRef.current = false;
|
|
1110
1188
|
setHovered(false);
|
|
1111
|
-
},
|
|
1189
|
+
}, []);
|
|
1190
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: wrapperRef, className: `${styles.wrapper}${classNames?.wrapper ? ` ${classNames.wrapper}` : ""}`, style: wrapperStyle, role: effectivePhase === "error" || effectivePhase === "warning" ? "alert" : "status", "aria-live": effectivePhase === "error" || effectivePhase === "warning" ? "assertive" : "polite", "aria-atomic": "true", onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, "data-center": isCenter || void 0, "data-theme": theme, children: [
|
|
1112
1191
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1113
1192
|
"svg",
|
|
1114
1193
|
{
|
|
@@ -1130,10 +1209,13 @@ var GoeyToast = ({
|
|
|
1130
1209
|
{
|
|
1131
1210
|
ref: contentRef,
|
|
1132
1211
|
className: `${styles.content} ${showBody ? styles.contentExpanded : styles.contentCompact}${classNames?.content ? ` ${classNames.content}` : ""}`,
|
|
1133
|
-
style:
|
|
1212
|
+
style: contentStyle,
|
|
1134
1213
|
children: [
|
|
1135
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1136
|
-
|
|
1214
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: headerRef, className: `${styles.header} ${titleColorMap[effectivePhase]}${classNames?.header ? ` ${classNames.header}` : ""}`, children: [
|
|
1215
|
+
iconAndTitle,
|
|
1216
|
+
!hasDescription && !hasAction && !actionSuccess && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.timestamp, children: timestampStr })
|
|
1217
|
+
] }),
|
|
1218
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showBody && hasDescription && !dismissing && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1137
1219
|
framerMotion.motion.div,
|
|
1138
1220
|
{
|
|
1139
1221
|
className: `${styles.description}${classNames?.description ? ` ${classNames.description}` : ""}`,
|
|
@@ -1142,10 +1224,26 @@ var GoeyToast = ({
|
|
|
1142
1224
|
animate: { opacity: 1 },
|
|
1143
1225
|
exit: { opacity: 0 },
|
|
1144
1226
|
transition: prefersReducedMotion ? { duration: 0.01 } : { duration: 0.35, ease: [0.4, 0, 0.2, 1] },
|
|
1145
|
-
children:
|
|
1227
|
+
children: [
|
|
1228
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.timestamp, style: { float: "right", marginLeft: 10, marginTop: 3, paddingLeft: 0 }, children: timestampStr }),
|
|
1229
|
+
effectiveDescription
|
|
1230
|
+
]
|
|
1146
1231
|
},
|
|
1147
1232
|
"description"
|
|
1148
1233
|
) }),
|
|
1234
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showBody && !hasDescription && hasAction && !dismissing && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1235
|
+
framerMotion.motion.div,
|
|
1236
|
+
{
|
|
1237
|
+
className: styles.timestamp,
|
|
1238
|
+
style: { textAlign: "right", marginTop: 8, paddingLeft: 0 },
|
|
1239
|
+
initial: prefersReducedMotion ? false : { opacity: 0 },
|
|
1240
|
+
animate: { opacity: 1 },
|
|
1241
|
+
exit: { opacity: 0 },
|
|
1242
|
+
transition: prefersReducedMotion ? { duration: 0.01 } : { duration: 0.35, ease: [0.4, 0, 0.2, 1] },
|
|
1243
|
+
children: timestampStr
|
|
1244
|
+
},
|
|
1245
|
+
"timestamp-body"
|
|
1246
|
+
) }),
|
|
1149
1247
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showBody && hasAction && effectiveAction && !dismissing && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1150
1248
|
framerMotion.motion.div,
|
|
1151
1249
|
{
|
|
@@ -1166,7 +1264,22 @@ var GoeyToast = ({
|
|
|
1166
1264
|
)
|
|
1167
1265
|
},
|
|
1168
1266
|
"action"
|
|
1169
|
-
) })
|
|
1267
|
+
) }),
|
|
1268
|
+
showProgress && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1269
|
+
"div",
|
|
1270
|
+
{
|
|
1271
|
+
className: `${styles.progressWrapper}${hovered || containerHovered ? ` ${styles.progressPaused}` : ""}`,
|
|
1272
|
+
style: { opacity: showBody && !actionSuccess ? 1 : 0 },
|
|
1273
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1274
|
+
"div",
|
|
1275
|
+
{
|
|
1276
|
+
className: `${styles.progressBar} ${progressColorMap[effectivePhase]}`,
|
|
1277
|
+
style: { "--goey-progress-duration": `${progressDelayRef.current || (timing?.displayDuration ?? DEFAULT_DISPLAY_DURATION)}ms` }
|
|
1278
|
+
}
|
|
1279
|
+
)
|
|
1280
|
+
},
|
|
1281
|
+
progressKey
|
|
1282
|
+
)
|
|
1170
1283
|
]
|
|
1171
1284
|
}
|
|
1172
1285
|
)
|
|
@@ -1193,37 +1306,129 @@ var ToastErrorBoundary = class extends react.Component {
|
|
|
1193
1306
|
}
|
|
1194
1307
|
};
|
|
1195
1308
|
var DEFAULT_EXPANDED_DURATION = 4e3;
|
|
1196
|
-
|
|
1309
|
+
function getAnnouncePoliteness(type) {
|
|
1310
|
+
return type === "error" || type === "warning" ? "assertive" : "polite";
|
|
1311
|
+
}
|
|
1312
|
+
function buildAnnouncementMessage(title, description) {
|
|
1313
|
+
if (!description || typeof description !== "string") return title;
|
|
1314
|
+
return `${title}: ${description}`;
|
|
1315
|
+
}
|
|
1316
|
+
var _activeIds = /* @__PURE__ */ new Map();
|
|
1197
1317
|
var _queue = [];
|
|
1318
|
+
var _toastCallbacks = /* @__PURE__ */ new Map();
|
|
1319
|
+
var _autoCloseFlags = /* @__PURE__ */ new Set();
|
|
1320
|
+
var _manualDismissFlags = /* @__PURE__ */ new Set();
|
|
1321
|
+
function _getMostRecentActiveId() {
|
|
1322
|
+
let last;
|
|
1323
|
+
for (const id of _activeIds.keys()) last = id;
|
|
1324
|
+
return last;
|
|
1325
|
+
}
|
|
1198
1326
|
function _processQueue() {
|
|
1199
1327
|
const max = getGoeyVisibleToasts();
|
|
1200
1328
|
while (_queue.length > 0 && _activeIds.size < max) {
|
|
1201
1329
|
const next = _queue.shift();
|
|
1202
|
-
_activeIds.
|
|
1330
|
+
_activeIds.set(next.id, next.type);
|
|
1203
1331
|
next.create();
|
|
1204
1332
|
}
|
|
1205
1333
|
}
|
|
1334
|
+
function _enqueue(entry) {
|
|
1335
|
+
const maxQueue = getGoeyMaxQueue();
|
|
1336
|
+
const overflow = getGoeyQueueOverflow();
|
|
1337
|
+
if (_queue.length >= maxQueue) {
|
|
1338
|
+
if (overflow === "drop-newest") return false;
|
|
1339
|
+
_queue.shift();
|
|
1340
|
+
}
|
|
1341
|
+
_queue.push(entry);
|
|
1342
|
+
return true;
|
|
1343
|
+
}
|
|
1206
1344
|
function _onToastDismissed(id) {
|
|
1207
1345
|
if (!_activeIds.delete(id)) return;
|
|
1346
|
+
_toastUpdateListeners.delete(id);
|
|
1347
|
+
const cbs = _toastCallbacks.get(id);
|
|
1348
|
+
if (cbs) {
|
|
1349
|
+
const isAutoClose = _autoCloseFlags.has(id) || !_manualDismissFlags.has(id);
|
|
1350
|
+
if (isAutoClose && cbs.onAutoClose) {
|
|
1351
|
+
try {
|
|
1352
|
+
cbs.onAutoClose(id);
|
|
1353
|
+
} catch {
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
if (cbs.onDismiss) {
|
|
1357
|
+
try {
|
|
1358
|
+
cbs.onDismiss(id);
|
|
1359
|
+
} catch {
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
_toastCallbacks.delete(id);
|
|
1363
|
+
}
|
|
1364
|
+
_autoCloseFlags.delete(id);
|
|
1365
|
+
_manualDismissFlags.delete(id);
|
|
1208
1366
|
_processQueue();
|
|
1209
1367
|
}
|
|
1368
|
+
var _toastUpdateListeners = /* @__PURE__ */ new Map();
|
|
1369
|
+
function updateGoeyToast(id, options) {
|
|
1370
|
+
const listener = _toastUpdateListeners.get(id);
|
|
1371
|
+
if (listener) {
|
|
1372
|
+
listener(options);
|
|
1373
|
+
if (options.type !== void 0 && _activeIds.has(id)) {
|
|
1374
|
+
_activeIds.set(id, options.type);
|
|
1375
|
+
}
|
|
1376
|
+
if (options.title !== void 0) {
|
|
1377
|
+
announce(
|
|
1378
|
+
buildAnnouncementMessage(options.title, options.description),
|
|
1379
|
+
options.type ? getAnnouncePoliteness(options.type) : "polite"
|
|
1380
|
+
);
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1210
1384
|
function GoeyToastWrapper({
|
|
1211
1385
|
initialPhase,
|
|
1212
|
-
title,
|
|
1213
|
-
type,
|
|
1214
|
-
description,
|
|
1215
|
-
action,
|
|
1386
|
+
title: initialTitle,
|
|
1387
|
+
type: initialType,
|
|
1388
|
+
description: initialDescription,
|
|
1389
|
+
action: initialAction,
|
|
1216
1390
|
icon,
|
|
1217
1391
|
classNames,
|
|
1218
1392
|
fillColor,
|
|
1219
1393
|
borderColor,
|
|
1220
1394
|
borderWidth,
|
|
1221
1395
|
timing,
|
|
1396
|
+
preset,
|
|
1222
1397
|
spring,
|
|
1223
1398
|
bounce,
|
|
1399
|
+
showProgress,
|
|
1224
1400
|
toastId,
|
|
1225
|
-
activeId
|
|
1401
|
+
activeId,
|
|
1402
|
+
onDismiss,
|
|
1403
|
+
onAutoClose
|
|
1226
1404
|
}) {
|
|
1405
|
+
react.useEffect(() => {
|
|
1406
|
+
if (onDismiss || onAutoClose) {
|
|
1407
|
+
_toastCallbacks.set(activeId, { onDismiss, onAutoClose });
|
|
1408
|
+
}
|
|
1409
|
+
}, [activeId, onDismiss, onAutoClose]);
|
|
1410
|
+
const [title, setTitle] = react.useState(initialTitle);
|
|
1411
|
+
const [type, setType] = react.useState(initialType);
|
|
1412
|
+
const [phase, setPhase] = react.useState(initialPhase);
|
|
1413
|
+
const [description, setDescription] = react.useState(initialDescription);
|
|
1414
|
+
const [action, setAction] = react.useState(initialAction);
|
|
1415
|
+
const [currentIcon, setCurrentIcon] = react.useState(icon);
|
|
1416
|
+
react.useEffect(() => {
|
|
1417
|
+
const handleUpdate = (opts) => {
|
|
1418
|
+
if (opts.title !== void 0) setTitle(opts.title);
|
|
1419
|
+
if (opts.description !== void 0) setDescription(opts.description);
|
|
1420
|
+
if (opts.type !== void 0) {
|
|
1421
|
+
setType(opts.type);
|
|
1422
|
+
setPhase(opts.type);
|
|
1423
|
+
}
|
|
1424
|
+
if (opts.action !== void 0) setAction(opts.action);
|
|
1425
|
+
if ("icon" in opts) setCurrentIcon(opts.icon ?? void 0);
|
|
1426
|
+
};
|
|
1427
|
+
_toastUpdateListeners.set(activeId, handleUpdate);
|
|
1428
|
+
return () => {
|
|
1429
|
+
_toastUpdateListeners.delete(activeId);
|
|
1430
|
+
};
|
|
1431
|
+
}, [activeId]);
|
|
1227
1432
|
const mountedRef = react.useRef(true);
|
|
1228
1433
|
react.useEffect(() => {
|
|
1229
1434
|
mountedRef.current = true;
|
|
@@ -1241,15 +1446,17 @@ function GoeyToastWrapper({
|
|
|
1241
1446
|
description,
|
|
1242
1447
|
type,
|
|
1243
1448
|
action,
|
|
1244
|
-
icon,
|
|
1245
|
-
phase
|
|
1449
|
+
icon: currentIcon,
|
|
1450
|
+
phase,
|
|
1246
1451
|
classNames,
|
|
1247
1452
|
fillColor,
|
|
1248
1453
|
borderColor,
|
|
1249
1454
|
borderWidth,
|
|
1250
1455
|
timing,
|
|
1456
|
+
preset,
|
|
1251
1457
|
spring,
|
|
1252
1458
|
bounce,
|
|
1459
|
+
showProgress,
|
|
1253
1460
|
toastId
|
|
1254
1461
|
}
|
|
1255
1462
|
) });
|
|
@@ -1263,6 +1470,11 @@ function PromiseToastWrapper({
|
|
|
1263
1470
|
const [title, setTitle] = react.useState(data.loading);
|
|
1264
1471
|
const [description, setDescription] = react.useState(data.description?.loading);
|
|
1265
1472
|
const [action, setAction] = react.useState(void 0);
|
|
1473
|
+
react.useEffect(() => {
|
|
1474
|
+
if (data.onDismiss || data.onAutoClose) {
|
|
1475
|
+
_toastCallbacks.set(toastId, { onDismiss: data.onDismiss, onAutoClose: data.onAutoClose });
|
|
1476
|
+
}
|
|
1477
|
+
}, [toastId, data.onDismiss, data.onAutoClose]);
|
|
1266
1478
|
const mountedRef = react.useRef(true);
|
|
1267
1479
|
react.useEffect(() => {
|
|
1268
1480
|
mountedRef.current = true;
|
|
@@ -1284,22 +1496,22 @@ function PromiseToastWrapper({
|
|
|
1284
1496
|
};
|
|
1285
1497
|
promise.then((result) => {
|
|
1286
1498
|
const desc = typeof data.description?.success === "function" ? data.description.success(result) : data.description?.success;
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
);
|
|
1499
|
+
const resolvedTitle = typeof data.success === "function" ? data.success(result) : data.success;
|
|
1500
|
+
setTitle(resolvedTitle);
|
|
1290
1501
|
setDescription(desc);
|
|
1291
1502
|
setAction(data.action?.success);
|
|
1292
1503
|
setPhase("success");
|
|
1293
1504
|
resetDuration(Boolean(desc || data.action?.success));
|
|
1505
|
+
announce(buildAnnouncementMessage(resolvedTitle, desc), "polite");
|
|
1294
1506
|
}).catch((err) => {
|
|
1295
1507
|
const desc = typeof data.description?.error === "function" ? data.description.error(err) : data.description?.error;
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
);
|
|
1508
|
+
const resolvedTitle = typeof data.error === "function" ? data.error(err) : data.error;
|
|
1509
|
+
setTitle(resolvedTitle);
|
|
1299
1510
|
setDescription(desc);
|
|
1300
1511
|
setAction(data.action?.error);
|
|
1301
1512
|
setPhase("error");
|
|
1302
1513
|
resetDuration(Boolean(desc || data.action?.error));
|
|
1514
|
+
announce(buildAnnouncementMessage(resolvedTitle, desc), "assertive");
|
|
1303
1515
|
});
|
|
1304
1516
|
}, []);
|
|
1305
1517
|
return /* @__PURE__ */ jsxRuntime.jsx(ToastErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1315,6 +1527,7 @@ function PromiseToastWrapper({
|
|
|
1315
1527
|
borderColor: data.borderColor,
|
|
1316
1528
|
borderWidth: data.borderWidth,
|
|
1317
1529
|
timing: data.timing,
|
|
1530
|
+
preset: data.preset,
|
|
1318
1531
|
spring: data.spring,
|
|
1319
1532
|
bounce: data.bounce
|
|
1320
1533
|
}
|
|
@@ -1341,10 +1554,14 @@ function createGoeyToast(title, type, options) {
|
|
|
1341
1554
|
borderColor: options?.borderColor,
|
|
1342
1555
|
borderWidth: options?.borderWidth,
|
|
1343
1556
|
timing: options?.timing,
|
|
1557
|
+
preset: options?.preset,
|
|
1344
1558
|
spring: options?.spring,
|
|
1345
1559
|
bounce: options?.bounce,
|
|
1560
|
+
showProgress: options?.showProgress,
|
|
1346
1561
|
toastId: hasExpandedContent ? toastId : void 0,
|
|
1347
|
-
activeId: toastId
|
|
1562
|
+
activeId: toastId,
|
|
1563
|
+
onDismiss: options?.onDismiss,
|
|
1564
|
+
onAutoClose: options?.onAutoClose
|
|
1348
1565
|
}
|
|
1349
1566
|
),
|
|
1350
1567
|
{
|
|
@@ -1353,23 +1570,48 @@ function createGoeyToast(title, type, options) {
|
|
|
1353
1570
|
}
|
|
1354
1571
|
);
|
|
1355
1572
|
};
|
|
1573
|
+
if (options?.onDismiss || options?.onAutoClose) {
|
|
1574
|
+
_toastCallbacks.set(toastId, { onDismiss: options.onDismiss, onAutoClose: options.onAutoClose });
|
|
1575
|
+
}
|
|
1576
|
+
announce(
|
|
1577
|
+
buildAnnouncementMessage(title, options?.description),
|
|
1578
|
+
getAnnouncePoliteness(type)
|
|
1579
|
+
);
|
|
1356
1580
|
if (_activeIds.size < getGoeyVisibleToasts()) {
|
|
1357
|
-
_activeIds.
|
|
1581
|
+
_activeIds.set(toastId, type);
|
|
1358
1582
|
create();
|
|
1359
1583
|
} else {
|
|
1360
|
-
|
|
1584
|
+
_enqueue({ id: toastId, type, create });
|
|
1361
1585
|
}
|
|
1362
1586
|
return toastId;
|
|
1363
1587
|
}
|
|
1364
|
-
function dismissGoeyToast(
|
|
1365
|
-
if (
|
|
1366
|
-
const
|
|
1588
|
+
function dismissGoeyToast(idOrFilter) {
|
|
1589
|
+
if (idOrFilter != null && typeof idOrFilter === "object") {
|
|
1590
|
+
const filterTypes = Array.isArray(idOrFilter.type) ? idOrFilter.type : [idOrFilter.type];
|
|
1591
|
+
const typesSet = new Set(filterTypes);
|
|
1592
|
+
for (let i = _queue.length - 1; i >= 0; i--) {
|
|
1593
|
+
if (typesSet.has(_queue[i].type)) {
|
|
1594
|
+
_queue.splice(i, 1);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
for (const [id, toastType] of _activeIds) {
|
|
1598
|
+
if (typesSet.has(toastType)) {
|
|
1599
|
+
_manualDismissFlags.add(id);
|
|
1600
|
+
sonner.toast.dismiss(id);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
} else if (idOrFilter != null) {
|
|
1604
|
+
const idx = _queue.findIndex((q) => q.id === idOrFilter);
|
|
1367
1605
|
if (idx !== -1) {
|
|
1368
1606
|
_queue.splice(idx, 1);
|
|
1369
1607
|
return;
|
|
1370
1608
|
}
|
|
1371
|
-
|
|
1609
|
+
_manualDismissFlags.add(idOrFilter);
|
|
1610
|
+
sonner.toast.dismiss(idOrFilter);
|
|
1372
1611
|
} else {
|
|
1612
|
+
for (const id of _activeIds.keys()) {
|
|
1613
|
+
_manualDismissFlags.add(id);
|
|
1614
|
+
}
|
|
1373
1615
|
_queue.length = 0;
|
|
1374
1616
|
_activeIds.clear();
|
|
1375
1617
|
sonner.toast.dismiss();
|
|
@@ -1384,6 +1626,10 @@ var goeyToast = Object.assign(
|
|
|
1384
1626
|
info: (title, options) => createGoeyToast(title, "info", options),
|
|
1385
1627
|
promise: (promise, data) => {
|
|
1386
1628
|
const id = Math.random().toString(36).slice(2);
|
|
1629
|
+
announce(buildAnnouncementMessage(data.loading, data.description?.loading), "polite");
|
|
1630
|
+
if (data.onDismiss || data.onAutoClose) {
|
|
1631
|
+
_toastCallbacks.set(id, { onDismiss: data.onDismiss, onAutoClose: data.onAutoClose });
|
|
1632
|
+
}
|
|
1387
1633
|
const create = () => {
|
|
1388
1634
|
sonner.toast.custom(() => /* @__PURE__ */ jsxRuntime.jsx(PromiseToastWrapper, { promise, data, toastId: id }), {
|
|
1389
1635
|
id,
|
|
@@ -1391,18 +1637,226 @@ var goeyToast = Object.assign(
|
|
|
1391
1637
|
});
|
|
1392
1638
|
};
|
|
1393
1639
|
if (_activeIds.size < getGoeyVisibleToasts()) {
|
|
1394
|
-
_activeIds.
|
|
1640
|
+
_activeIds.set(id, "info");
|
|
1395
1641
|
create();
|
|
1396
1642
|
} else {
|
|
1397
|
-
|
|
1643
|
+
_enqueue({ id, type: "info", create });
|
|
1398
1644
|
}
|
|
1399
1645
|
return id;
|
|
1400
1646
|
},
|
|
1401
|
-
dismiss: dismissGoeyToast
|
|
1647
|
+
dismiss: dismissGoeyToast,
|
|
1648
|
+
update: updateGoeyToast
|
|
1402
1649
|
}
|
|
1403
1650
|
);
|
|
1651
|
+
function AriaLiveAnnouncer() {
|
|
1652
|
+
const [politeMessage, setPoliteMessage] = react.useState("");
|
|
1653
|
+
const [assertiveMessage, setAssertiveMessage] = react.useState("");
|
|
1654
|
+
const handleAnnouncement = react.useCallback(({ message, politeness }) => {
|
|
1655
|
+
if (politeness === "assertive") {
|
|
1656
|
+
setAssertiveMessage("");
|
|
1657
|
+
requestAnimationFrame(() => setAssertiveMessage(message));
|
|
1658
|
+
} else {
|
|
1659
|
+
setPoliteMessage("");
|
|
1660
|
+
requestAnimationFrame(() => setPoliteMessage(message));
|
|
1661
|
+
}
|
|
1662
|
+
}, []);
|
|
1663
|
+
react.useEffect(() => {
|
|
1664
|
+
return subscribeAnnouncements(handleAnnouncement);
|
|
1665
|
+
}, [handleAnnouncement]);
|
|
1666
|
+
react.useEffect(() => {
|
|
1667
|
+
if (!politeMessage) return;
|
|
1668
|
+
const t = setTimeout(() => setPoliteMessage(""), 7e3);
|
|
1669
|
+
return () => clearTimeout(t);
|
|
1670
|
+
}, [politeMessage]);
|
|
1671
|
+
react.useEffect(() => {
|
|
1672
|
+
if (!assertiveMessage) return;
|
|
1673
|
+
const t = setTimeout(() => setAssertiveMessage(""), 7e3);
|
|
1674
|
+
return () => clearTimeout(t);
|
|
1675
|
+
}, [assertiveMessage]);
|
|
1676
|
+
const visuallyHidden = {
|
|
1677
|
+
position: "absolute",
|
|
1678
|
+
width: "1px",
|
|
1679
|
+
height: "1px",
|
|
1680
|
+
padding: 0,
|
|
1681
|
+
margin: "-1px",
|
|
1682
|
+
overflow: "hidden",
|
|
1683
|
+
clip: "rect(0, 0, 0, 0)",
|
|
1684
|
+
whiteSpace: "nowrap",
|
|
1685
|
+
border: 0
|
|
1686
|
+
};
|
|
1687
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1688
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1689
|
+
"div",
|
|
1690
|
+
{
|
|
1691
|
+
role: "status",
|
|
1692
|
+
"aria-live": "polite",
|
|
1693
|
+
"aria-atomic": "true",
|
|
1694
|
+
style: visuallyHidden,
|
|
1695
|
+
children: politeMessage
|
|
1696
|
+
}
|
|
1697
|
+
),
|
|
1698
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1699
|
+
"div",
|
|
1700
|
+
{
|
|
1701
|
+
role: "alert",
|
|
1702
|
+
"aria-live": "assertive",
|
|
1703
|
+
"aria-atomic": "true",
|
|
1704
|
+
style: visuallyHidden,
|
|
1705
|
+
children: assertiveMessage
|
|
1706
|
+
}
|
|
1707
|
+
)
|
|
1708
|
+
] });
|
|
1709
|
+
}
|
|
1710
|
+
function GoeyToaster({
|
|
1711
|
+
position = "bottom-right",
|
|
1712
|
+
duration,
|
|
1713
|
+
gap = 14,
|
|
1714
|
+
offset = "24px",
|
|
1715
|
+
theme = "light",
|
|
1716
|
+
toastOptions,
|
|
1717
|
+
expand,
|
|
1718
|
+
closeButton,
|
|
1719
|
+
richColors,
|
|
1720
|
+
visibleToasts,
|
|
1721
|
+
dir,
|
|
1722
|
+
preset,
|
|
1723
|
+
spring,
|
|
1724
|
+
bounce,
|
|
1725
|
+
swipeToDismiss = true,
|
|
1726
|
+
closeOnEscape = true,
|
|
1727
|
+
maxQueue = Infinity,
|
|
1728
|
+
queueOverflow = "drop-oldest",
|
|
1729
|
+
showProgress = false
|
|
1730
|
+
}) {
|
|
1731
|
+
const presetConfig = preset ? animationPresets[preset] : void 0;
|
|
1732
|
+
const resolvedSpring = spring ?? presetConfig?.spring ?? true;
|
|
1733
|
+
const resolvedBounce = bounce ?? presetConfig?.bounce;
|
|
1734
|
+
react.useEffect(() => {
|
|
1735
|
+
setGoeyPosition(position);
|
|
1736
|
+
}, [position]);
|
|
1737
|
+
react.useEffect(() => {
|
|
1738
|
+
setGoeyDir(dir ?? "ltr");
|
|
1739
|
+
}, [dir]);
|
|
1740
|
+
react.useEffect(() => {
|
|
1741
|
+
setGoeyTheme(theme);
|
|
1742
|
+
}, [theme]);
|
|
1743
|
+
react.useEffect(() => {
|
|
1744
|
+
setGoeySpring(resolvedSpring);
|
|
1745
|
+
}, [resolvedSpring]);
|
|
1746
|
+
react.useEffect(() => {
|
|
1747
|
+
setGoeyBounce(resolvedBounce);
|
|
1748
|
+
}, [resolvedBounce]);
|
|
1749
|
+
react.useEffect(() => {
|
|
1750
|
+
setGoeySwipeToDismiss(swipeToDismiss);
|
|
1751
|
+
}, [swipeToDismiss]);
|
|
1752
|
+
react.useEffect(() => {
|
|
1753
|
+
}, [closeOnEscape]);
|
|
1754
|
+
react.useEffect(() => {
|
|
1755
|
+
if (!closeOnEscape) return;
|
|
1756
|
+
const handleKeyDown = (e) => {
|
|
1757
|
+
if (e.key === "Escape") {
|
|
1758
|
+
const recentId = _getMostRecentActiveId();
|
|
1759
|
+
if (recentId != null) {
|
|
1760
|
+
goeyToast.dismiss(recentId);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1765
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1766
|
+
}, [closeOnEscape]);
|
|
1767
|
+
react.useEffect(() => {
|
|
1768
|
+
setGoeyVisibleToasts(visibleToasts ?? 3);
|
|
1769
|
+
}, [visibleToasts]);
|
|
1770
|
+
react.useEffect(() => {
|
|
1771
|
+
setGoeyMaxQueue(maxQueue);
|
|
1772
|
+
}, [maxQueue]);
|
|
1773
|
+
react.useEffect(() => {
|
|
1774
|
+
setGoeyQueueOverflow(queueOverflow);
|
|
1775
|
+
}, [queueOverflow]);
|
|
1776
|
+
react.useEffect(() => {
|
|
1777
|
+
setGoeyShowProgress(showProgress);
|
|
1778
|
+
}, [showProgress]);
|
|
1779
|
+
react.useEffect(() => {
|
|
1780
|
+
let expandObs = null;
|
|
1781
|
+
let currentOl = null;
|
|
1782
|
+
const syncFromExpanded = (ol) => {
|
|
1783
|
+
const anyExpanded = ol.querySelector('[data-sonner-toast][data-expanded="true"]') !== null;
|
|
1784
|
+
setContainerHovered(anyExpanded);
|
|
1785
|
+
};
|
|
1786
|
+
const attach = (ol) => {
|
|
1787
|
+
if (ol === currentOl) return;
|
|
1788
|
+
expandObs?.disconnect();
|
|
1789
|
+
currentOl = ol;
|
|
1790
|
+
expandObs = new MutationObserver(() => syncFromExpanded(ol));
|
|
1791
|
+
expandObs.observe(ol, { attributes: true, attributeFilter: ["data-expanded"], subtree: true });
|
|
1792
|
+
syncFromExpanded(ol);
|
|
1793
|
+
};
|
|
1794
|
+
const el = document.querySelector("[data-sonner-toaster]");
|
|
1795
|
+
if (el) attach(el);
|
|
1796
|
+
let bodyRafId = 0;
|
|
1797
|
+
const bodyObs = new MutationObserver(() => {
|
|
1798
|
+
if (bodyRafId) return;
|
|
1799
|
+
bodyRafId = requestAnimationFrame(() => {
|
|
1800
|
+
bodyRafId = 0;
|
|
1801
|
+
const found = document.querySelector("[data-sonner-toaster]");
|
|
1802
|
+
if (found) {
|
|
1803
|
+
attach(found);
|
|
1804
|
+
} else if (currentOl) {
|
|
1805
|
+
expandObs?.disconnect();
|
|
1806
|
+
currentOl = null;
|
|
1807
|
+
setContainerHovered(false);
|
|
1808
|
+
}
|
|
1809
|
+
});
|
|
1810
|
+
});
|
|
1811
|
+
bodyObs.observe(document.body, { childList: true, subtree: true });
|
|
1812
|
+
return () => {
|
|
1813
|
+
if (bodyRafId) cancelAnimationFrame(bodyRafId);
|
|
1814
|
+
bodyObs.disconnect();
|
|
1815
|
+
expandObs?.disconnect();
|
|
1816
|
+
setContainerHovered(false);
|
|
1817
|
+
};
|
|
1818
|
+
}, []);
|
|
1819
|
+
react.useEffect(() => {
|
|
1820
|
+
if (process.env.NODE_ENV !== "development") return;
|
|
1821
|
+
const el = document.createElement("div");
|
|
1822
|
+
el.setAttribute("data-goey-toast-css", "");
|
|
1823
|
+
el.style.position = "absolute";
|
|
1824
|
+
el.style.width = "0";
|
|
1825
|
+
el.style.height = "0";
|
|
1826
|
+
el.style.overflow = "hidden";
|
|
1827
|
+
el.style.pointerEvents = "none";
|
|
1828
|
+
document.body.appendChild(el);
|
|
1829
|
+
const value = getComputedStyle(el).getPropertyValue("--goey-toast");
|
|
1830
|
+
document.body.removeChild(el);
|
|
1831
|
+
if (!value) {
|
|
1832
|
+
console.warn(
|
|
1833
|
+
'[goey-toast] Styles not found. Make sure to import the CSS:\n\n import "goey-toast/styles.css";\n'
|
|
1834
|
+
);
|
|
1835
|
+
}
|
|
1836
|
+
}, []);
|
|
1837
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1838
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1839
|
+
sonner.Toaster,
|
|
1840
|
+
{
|
|
1841
|
+
position,
|
|
1842
|
+
duration,
|
|
1843
|
+
gap,
|
|
1844
|
+
offset,
|
|
1845
|
+
theme,
|
|
1846
|
+
toastOptions: { unstyled: true, ...toastOptions },
|
|
1847
|
+
expand,
|
|
1848
|
+
closeButton,
|
|
1849
|
+
richColors,
|
|
1850
|
+
visibleToasts: 99,
|
|
1851
|
+
dir
|
|
1852
|
+
}
|
|
1853
|
+
),
|
|
1854
|
+
/* @__PURE__ */ jsxRuntime.jsx(AriaLiveAnnouncer, {})
|
|
1855
|
+
] });
|
|
1856
|
+
}
|
|
1404
1857
|
|
|
1405
1858
|
exports.GoeyToaster = GoeyToaster;
|
|
1859
|
+
exports.animationPresets = animationPresets;
|
|
1406
1860
|
exports.goeyToast = goeyToast;
|
|
1407
1861
|
//# sourceMappingURL=index.cjs.map
|
|
1408
1862
|
//# sourceMappingURL=index.cjs.map
|