sonner 2.0.0-beta.2 → 2.0.0-beta.3
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/index.d.mts +7 -12
- package/dist/index.d.ts +7 -12
- package/dist/index.js +53 -30
- package/dist/index.mjs +53 -30
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -2,12 +2,16 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
type ToastTypes = 'normal' | 'action' | 'success' | 'info' | 'warning' | 'error' | 'loading' | 'default';
|
|
4
4
|
type PromiseT<Data = any> = Promise<Data> | (() => Promise<Data>);
|
|
5
|
+
interface PromiseIExtendedResult extends ExternalToast {
|
|
6
|
+
message: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
type PromiseTExtendedResult<Data = any> = PromiseIExtendedResult | ((data: Data) => PromiseIExtendedResult | Promise<PromiseIExtendedResult>);
|
|
5
9
|
type PromiseTResult<Data = any> = string | React.ReactNode | ((data: Data) => React.ReactNode | string | Promise<React.ReactNode | string>);
|
|
6
10
|
type PromiseExternalToast = Omit<ExternalToast, 'description'>;
|
|
7
11
|
type PromiseData<ToastData = any> = PromiseExternalToast & {
|
|
8
12
|
loading?: string | React.ReactNode;
|
|
9
|
-
success?: PromiseTResult<ToastData>;
|
|
10
|
-
error?: PromiseTResult;
|
|
13
|
+
success?: PromiseTResult<ToastData> | PromiseTExtendedResult<ToastData>;
|
|
14
|
+
error?: PromiseTResult | PromiseTExtendedResult;
|
|
11
15
|
description?: PromiseTResult;
|
|
12
16
|
finally?: () => void | Promise<void>;
|
|
13
17
|
};
|
|
@@ -79,6 +83,7 @@ interface ToastOptions {
|
|
|
79
83
|
duration?: number;
|
|
80
84
|
unstyled?: boolean;
|
|
81
85
|
classNames?: ToastClassnames;
|
|
86
|
+
closeButtonAriaLabel?: string;
|
|
82
87
|
}
|
|
83
88
|
type Offset = {
|
|
84
89
|
top?: string | number;
|
|
@@ -104,18 +109,8 @@ interface ToasterProps {
|
|
|
104
109
|
mobileOffset?: Offset;
|
|
105
110
|
dir?: 'rtl' | 'ltr' | 'auto';
|
|
106
111
|
swipeDirections?: SwipeDirection[];
|
|
107
|
-
/**
|
|
108
|
-
* @deprecated Please use the `icons` prop instead:
|
|
109
|
-
* ```jsx
|
|
110
|
-
* <Toaster
|
|
111
|
-
* icons={{ loading: <LoadingIcon /> }}
|
|
112
|
-
* />
|
|
113
|
-
* ```
|
|
114
|
-
*/
|
|
115
|
-
loadingIcon?: React.ReactNode;
|
|
116
112
|
icons?: ToastIcons;
|
|
117
113
|
containerAriaLabel?: string;
|
|
118
|
-
pauseWhenPageIsHidden?: boolean;
|
|
119
114
|
}
|
|
120
115
|
type SwipeDirection = 'top' | 'right' | 'bottom' | 'left';
|
|
121
116
|
interface ToastToDismiss {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,12 +2,16 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
type ToastTypes = 'normal' | 'action' | 'success' | 'info' | 'warning' | 'error' | 'loading' | 'default';
|
|
4
4
|
type PromiseT<Data = any> = Promise<Data> | (() => Promise<Data>);
|
|
5
|
+
interface PromiseIExtendedResult extends ExternalToast {
|
|
6
|
+
message: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
type PromiseTExtendedResult<Data = any> = PromiseIExtendedResult | ((data: Data) => PromiseIExtendedResult | Promise<PromiseIExtendedResult>);
|
|
5
9
|
type PromiseTResult<Data = any> = string | React.ReactNode | ((data: Data) => React.ReactNode | string | Promise<React.ReactNode | string>);
|
|
6
10
|
type PromiseExternalToast = Omit<ExternalToast, 'description'>;
|
|
7
11
|
type PromiseData<ToastData = any> = PromiseExternalToast & {
|
|
8
12
|
loading?: string | React.ReactNode;
|
|
9
|
-
success?: PromiseTResult<ToastData>;
|
|
10
|
-
error?: PromiseTResult;
|
|
13
|
+
success?: PromiseTResult<ToastData> | PromiseTExtendedResult<ToastData>;
|
|
14
|
+
error?: PromiseTResult | PromiseTExtendedResult;
|
|
11
15
|
description?: PromiseTResult;
|
|
12
16
|
finally?: () => void | Promise<void>;
|
|
13
17
|
};
|
|
@@ -79,6 +83,7 @@ interface ToastOptions {
|
|
|
79
83
|
duration?: number;
|
|
80
84
|
unstyled?: boolean;
|
|
81
85
|
classNames?: ToastClassnames;
|
|
86
|
+
closeButtonAriaLabel?: string;
|
|
82
87
|
}
|
|
83
88
|
type Offset = {
|
|
84
89
|
top?: string | number;
|
|
@@ -104,18 +109,8 @@ interface ToasterProps {
|
|
|
104
109
|
mobileOffset?: Offset;
|
|
105
110
|
dir?: 'rtl' | 'ltr' | 'auto';
|
|
106
111
|
swipeDirections?: SwipeDirection[];
|
|
107
|
-
/**
|
|
108
|
-
* @deprecated Please use the `icons` prop instead:
|
|
109
|
-
* ```jsx
|
|
110
|
-
* <Toaster
|
|
111
|
-
* icons={{ loading: <LoadingIcon /> }}
|
|
112
|
-
* />
|
|
113
|
-
* ```
|
|
114
|
-
*/
|
|
115
|
-
loadingIcon?: React.ReactNode;
|
|
116
112
|
icons?: ToastIcons;
|
|
117
113
|
containerAriaLabel?: string;
|
|
118
|
-
pauseWhenPageIsHidden?: boolean;
|
|
119
114
|
}
|
|
120
115
|
type SwipeDirection = 'top' | 'right' | 'bottom' | 'left';
|
|
121
116
|
interface ToastToDismiss {
|
package/dist/index.js
CHANGED
|
@@ -276,23 +276,42 @@ class Observer {
|
|
|
276
276
|
});
|
|
277
277
|
} else if (isHttpResponse(response) && !response.ok) {
|
|
278
278
|
shouldDismiss = false;
|
|
279
|
-
const
|
|
279
|
+
const promiseData = typeof data.error === 'function' ? await data.error(`HTTP error! status: ${response.status}`) : data.error;
|
|
280
280
|
const description = typeof data.description === 'function' ? await data.description(`HTTP error! status: ${response.status}`) : data.description;
|
|
281
|
+
const toastSettings = typeof promiseData === 'object' ? promiseData : {
|
|
282
|
+
message: promiseData
|
|
283
|
+
};
|
|
281
284
|
this.create({
|
|
282
285
|
id,
|
|
283
286
|
type: 'error',
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
description,
|
|
288
|
+
...toastSettings
|
|
289
|
+
});
|
|
290
|
+
} else if (response instanceof Error) {
|
|
291
|
+
shouldDismiss = false;
|
|
292
|
+
const promiseData = typeof data.error === 'function' ? await data.error(response) : data.error;
|
|
293
|
+
const description = typeof data.description === 'function' ? await data.description(response) : data.description;
|
|
294
|
+
const toastSettings = typeof promiseData === 'object' ? promiseData : {
|
|
295
|
+
message: promiseData
|
|
296
|
+
};
|
|
297
|
+
this.create({
|
|
298
|
+
id,
|
|
299
|
+
type: 'error',
|
|
300
|
+
description,
|
|
301
|
+
...toastSettings
|
|
286
302
|
});
|
|
287
303
|
} else if (data.success !== undefined) {
|
|
288
304
|
shouldDismiss = false;
|
|
289
|
-
const
|
|
305
|
+
const promiseData = typeof data.success === 'function' ? await data.success(response) : data.success;
|
|
290
306
|
const description = typeof data.description === 'function' ? await data.description(response) : data.description;
|
|
307
|
+
const toastSettings = typeof promiseData === 'object' ? promiseData : {
|
|
308
|
+
message: promiseData
|
|
309
|
+
};
|
|
291
310
|
this.create({
|
|
292
311
|
id,
|
|
293
312
|
type: 'success',
|
|
294
|
-
|
|
295
|
-
|
|
313
|
+
description,
|
|
314
|
+
...toastSettings
|
|
296
315
|
});
|
|
297
316
|
}
|
|
298
317
|
}).catch(async (error)=>{
|
|
@@ -302,13 +321,16 @@ class Observer {
|
|
|
302
321
|
];
|
|
303
322
|
if (data.error !== undefined) {
|
|
304
323
|
shouldDismiss = false;
|
|
305
|
-
const
|
|
324
|
+
const promiseData = typeof data.error === 'function' ? await data.error(error) : data.error;
|
|
306
325
|
const description = typeof data.description === 'function' ? await data.description(error) : data.description;
|
|
326
|
+
const toastSettings = typeof promiseData === 'object' ? promiseData : {
|
|
327
|
+
message: promiseData
|
|
328
|
+
};
|
|
307
329
|
this.create({
|
|
308
330
|
id,
|
|
309
331
|
type: 'error',
|
|
310
|
-
|
|
311
|
-
|
|
332
|
+
description,
|
|
333
|
+
...toastSettings
|
|
312
334
|
});
|
|
313
335
|
}
|
|
314
336
|
}).finally(()=>{
|
|
@@ -400,7 +422,7 @@ const TOAST_WIDTH = 356;
|
|
|
400
422
|
// Default gap between toasts
|
|
401
423
|
const GAP = 14;
|
|
402
424
|
// Threshold to dismiss a toast
|
|
403
|
-
const SWIPE_THRESHOLD =
|
|
425
|
+
const SWIPE_THRESHOLD = 45;
|
|
404
426
|
// Equal to exit animation duration
|
|
405
427
|
const TIME_BEFORE_UNMOUNT = 200;
|
|
406
428
|
function cn(...classes) {
|
|
@@ -419,7 +441,7 @@ function getDefaultSwipeDirections(position) {
|
|
|
419
441
|
}
|
|
420
442
|
const Toast = (props)=>{
|
|
421
443
|
var _toast_classNames, _toast_classNames1, _toast_classNames2, _toast_classNames3, _toast_classNames4, _toast_classNames5, _toast_classNames6, _toast_classNames7, _toast_classNames8;
|
|
422
|
-
const { invert: ToasterInvert, toast, unstyled, interacting, setHeights, visibleToasts, heights, index, toasts, expanded, removeToast, defaultRichColors, closeButton: closeButtonFromToaster, style, cancelButtonStyle, actionButtonStyle, className = '', descriptionClassName = '', duration: durationFromToaster, position, gap,
|
|
444
|
+
const { invert: ToasterInvert, toast, unstyled, interacting, setHeights, visibleToasts, heights, index, toasts, expanded, removeToast, defaultRichColors, closeButton: closeButtonFromToaster, style, cancelButtonStyle, actionButtonStyle, className = '', descriptionClassName = '', duration: durationFromToaster, position, gap, expandByDefault, classNames, icons, closeButtonAriaLabel = 'Close toast' } = props;
|
|
423
445
|
const [swipeDirection, setSwipeDirection] = React__default.default.useState(null);
|
|
424
446
|
const [swipeOutDirection, setSwipeOutDirection] = React__default.default.useState(null);
|
|
425
447
|
const [mounted, setMounted] = React__default.default.useState(false);
|
|
@@ -578,7 +600,7 @@ const Toast = (props)=>{
|
|
|
578
600
|
deleteToast();
|
|
579
601
|
}, remainingTime.current);
|
|
580
602
|
};
|
|
581
|
-
if (expanded || interacting ||
|
|
603
|
+
if (expanded || interacting || isDocumentHidden) {
|
|
582
604
|
pauseTimer();
|
|
583
605
|
} else {
|
|
584
606
|
startTimer();
|
|
@@ -589,7 +611,6 @@ const Toast = (props)=>{
|
|
|
589
611
|
interacting,
|
|
590
612
|
toast,
|
|
591
613
|
toastType,
|
|
592
|
-
pauseWhenPageIsHidden,
|
|
593
614
|
isDocumentHidden,
|
|
594
615
|
deleteToast
|
|
595
616
|
]);
|
|
@@ -610,13 +631,6 @@ const Toast = (props)=>{
|
|
|
610
631
|
"data-visible": toastType === 'loading'
|
|
611
632
|
}, icons.loading);
|
|
612
633
|
}
|
|
613
|
-
if (loadingIconProp) {
|
|
614
|
-
var _toast_classNames2;
|
|
615
|
-
return /*#__PURE__*/ React__default.default.createElement("div", {
|
|
616
|
-
className: cn(classNames == null ? void 0 : classNames.loader, toast == null ? void 0 : (_toast_classNames2 = toast.classNames) == null ? void 0 : _toast_classNames2.loader, 'sonner-loader'),
|
|
617
|
-
"data-visible": toastType === 'loading'
|
|
618
|
-
}, loadingIconProp);
|
|
619
|
-
}
|
|
620
634
|
return /*#__PURE__*/ React__default.default.createElement(Loader, {
|
|
621
635
|
className: cn(classNames == null ? void 0 : classNames.loader, toast == null ? void 0 : (_toast_classNames = toast.classNames) == null ? void 0 : _toast_classNames.loader),
|
|
622
636
|
visible: toastType === 'loading'
|
|
@@ -720,23 +734,33 @@ const Toast = (props)=>{
|
|
|
720
734
|
x: 0,
|
|
721
735
|
y: 0
|
|
722
736
|
};
|
|
737
|
+
const getDampening = (delta)=>{
|
|
738
|
+
const factor = Math.abs(delta) / 20;
|
|
739
|
+
return 1 / (1.5 + factor);
|
|
740
|
+
};
|
|
723
741
|
// Only apply swipe in the locked direction
|
|
724
742
|
if (swipeDirection === 'y') {
|
|
725
743
|
// Handle vertical swipes
|
|
726
744
|
if (swipeDirections.includes('top') || swipeDirections.includes('bottom')) {
|
|
727
|
-
if (swipeDirections.includes('top') && yDelta < 0) {
|
|
728
|
-
swipeAmount.y = yDelta;
|
|
729
|
-
} else if (swipeDirections.includes('bottom') && yDelta > 0) {
|
|
745
|
+
if (swipeDirections.includes('top') && yDelta < 0 || swipeDirections.includes('bottom') && yDelta > 0) {
|
|
730
746
|
swipeAmount.y = yDelta;
|
|
747
|
+
} else {
|
|
748
|
+
// Smoothly transition to dampened movement
|
|
749
|
+
const dampenedDelta = yDelta * getDampening(yDelta);
|
|
750
|
+
// Ensure we don't jump when transitioning to dampened movement
|
|
751
|
+
swipeAmount.y = Math.abs(dampenedDelta) < Math.abs(yDelta) ? dampenedDelta : yDelta;
|
|
731
752
|
}
|
|
732
753
|
}
|
|
733
754
|
} else if (swipeDirection === 'x') {
|
|
734
755
|
// Handle horizontal swipes
|
|
735
756
|
if (swipeDirections.includes('left') || swipeDirections.includes('right')) {
|
|
736
|
-
if (swipeDirections.includes('left') && xDelta < 0) {
|
|
737
|
-
swipeAmount.x = xDelta;
|
|
738
|
-
} else if (swipeDirections.includes('right') && xDelta > 0) {
|
|
757
|
+
if (swipeDirections.includes('left') && xDelta < 0 || swipeDirections.includes('right') && xDelta > 0) {
|
|
739
758
|
swipeAmount.x = xDelta;
|
|
759
|
+
} else {
|
|
760
|
+
// Smoothly transition to dampened movement
|
|
761
|
+
const dampenedDelta = xDelta * getDampening(xDelta);
|
|
762
|
+
// Ensure we don't jump when transitioning to dampened movement
|
|
763
|
+
swipeAmount.x = Math.abs(dampenedDelta) < Math.abs(xDelta) ? dampenedDelta : xDelta;
|
|
740
764
|
}
|
|
741
765
|
}
|
|
742
766
|
}
|
|
@@ -746,7 +770,7 @@ const Toast = (props)=>{
|
|
|
746
770
|
(_toastRef_current = toastRef.current) == null ? void 0 : _toastRef_current.style.setProperty('--swipe-amount-x', `${swipeAmount.x}px`);
|
|
747
771
|
(_toastRef_current1 = toastRef.current) == null ? void 0 : _toastRef_current1.style.setProperty('--swipe-amount-y', `${swipeAmount.y}px`);
|
|
748
772
|
}
|
|
749
|
-
}, closeButton && !toast.jsx ? /*#__PURE__*/ React__default.default.createElement("button", {
|
|
773
|
+
}, closeButton && !toast.jsx && toastType !== 'loading' ? /*#__PURE__*/ React__default.default.createElement("button", {
|
|
750
774
|
"aria-label": closeButtonAriaLabel,
|
|
751
775
|
"data-disabled": disabled,
|
|
752
776
|
"data-close-button": true,
|
|
@@ -887,7 +911,7 @@ const Toaster = /*#__PURE__*/ React__default.default.forwardRef(function Toaster
|
|
|
887
911
|
const { invert, position = 'bottom-right', hotkey = [
|
|
888
912
|
'altKey',
|
|
889
913
|
'KeyT'
|
|
890
|
-
], expand, closeButton, className, offset, mobileOffset, theme = 'light', richColors, duration, style, visibleToasts = VISIBLE_TOASTS_AMOUNT, toastOptions, dir = getDocumentDirection(), gap = GAP,
|
|
914
|
+
], expand, closeButton, className, offset, mobileOffset, theme = 'light', richColors, duration, style, visibleToasts = VISIBLE_TOASTS_AMOUNT, toastOptions, dir = getDocumentDirection(), gap = GAP, icons, containerAriaLabel = 'Notifications' } = props;
|
|
891
915
|
const [toasts, setToasts] = React__default.default.useState([]);
|
|
892
916
|
const possiblePositions = React__default.default.useMemo(()=>{
|
|
893
917
|
return Array.from(new Set([
|
|
@@ -1122,15 +1146,14 @@ const Toaster = /*#__PURE__*/ React__default.default.forwardRef(function Toaster
|
|
|
1122
1146
|
classNames: toastOptions == null ? void 0 : toastOptions.classNames,
|
|
1123
1147
|
cancelButtonStyle: toastOptions == null ? void 0 : toastOptions.cancelButtonStyle,
|
|
1124
1148
|
actionButtonStyle: toastOptions == null ? void 0 : toastOptions.actionButtonStyle,
|
|
1149
|
+
closeButtonAriaLabel: toastOptions == null ? void 0 : toastOptions.closeButtonAriaLabel,
|
|
1125
1150
|
removeToast: removeToast,
|
|
1126
1151
|
toasts: toasts.filter((t)=>t.position == toast.position),
|
|
1127
1152
|
heights: heights.filter((h)=>h.position == toast.position),
|
|
1128
1153
|
setHeights: setHeights,
|
|
1129
1154
|
expandByDefault: expand,
|
|
1130
1155
|
gap: gap,
|
|
1131
|
-
loadingIcon: loadingIcon,
|
|
1132
1156
|
expanded: expanded,
|
|
1133
|
-
pauseWhenPageIsHidden: pauseWhenPageIsHidden,
|
|
1134
1157
|
swipeDirections: props.swipeDirections
|
|
1135
1158
|
});
|
|
1136
1159
|
}));
|
package/dist/index.mjs
CHANGED
|
@@ -269,23 +269,42 @@ class Observer {
|
|
|
269
269
|
});
|
|
270
270
|
} else if (isHttpResponse(response) && !response.ok) {
|
|
271
271
|
shouldDismiss = false;
|
|
272
|
-
const
|
|
272
|
+
const promiseData = typeof data.error === 'function' ? await data.error(`HTTP error! status: ${response.status}`) : data.error;
|
|
273
273
|
const description = typeof data.description === 'function' ? await data.description(`HTTP error! status: ${response.status}`) : data.description;
|
|
274
|
+
const toastSettings = typeof promiseData === 'object' ? promiseData : {
|
|
275
|
+
message: promiseData
|
|
276
|
+
};
|
|
274
277
|
this.create({
|
|
275
278
|
id,
|
|
276
279
|
type: 'error',
|
|
277
|
-
|
|
278
|
-
|
|
280
|
+
description,
|
|
281
|
+
...toastSettings
|
|
282
|
+
});
|
|
283
|
+
} else if (response instanceof Error) {
|
|
284
|
+
shouldDismiss = false;
|
|
285
|
+
const promiseData = typeof data.error === 'function' ? await data.error(response) : data.error;
|
|
286
|
+
const description = typeof data.description === 'function' ? await data.description(response) : data.description;
|
|
287
|
+
const toastSettings = typeof promiseData === 'object' ? promiseData : {
|
|
288
|
+
message: promiseData
|
|
289
|
+
};
|
|
290
|
+
this.create({
|
|
291
|
+
id,
|
|
292
|
+
type: 'error',
|
|
293
|
+
description,
|
|
294
|
+
...toastSettings
|
|
279
295
|
});
|
|
280
296
|
} else if (data.success !== undefined) {
|
|
281
297
|
shouldDismiss = false;
|
|
282
|
-
const
|
|
298
|
+
const promiseData = typeof data.success === 'function' ? await data.success(response) : data.success;
|
|
283
299
|
const description = typeof data.description === 'function' ? await data.description(response) : data.description;
|
|
300
|
+
const toastSettings = typeof promiseData === 'object' ? promiseData : {
|
|
301
|
+
message: promiseData
|
|
302
|
+
};
|
|
284
303
|
this.create({
|
|
285
304
|
id,
|
|
286
305
|
type: 'success',
|
|
287
|
-
|
|
288
|
-
|
|
306
|
+
description,
|
|
307
|
+
...toastSettings
|
|
289
308
|
});
|
|
290
309
|
}
|
|
291
310
|
}).catch(async (error)=>{
|
|
@@ -295,13 +314,16 @@ class Observer {
|
|
|
295
314
|
];
|
|
296
315
|
if (data.error !== undefined) {
|
|
297
316
|
shouldDismiss = false;
|
|
298
|
-
const
|
|
317
|
+
const promiseData = typeof data.error === 'function' ? await data.error(error) : data.error;
|
|
299
318
|
const description = typeof data.description === 'function' ? await data.description(error) : data.description;
|
|
319
|
+
const toastSettings = typeof promiseData === 'object' ? promiseData : {
|
|
320
|
+
message: promiseData
|
|
321
|
+
};
|
|
300
322
|
this.create({
|
|
301
323
|
id,
|
|
302
324
|
type: 'error',
|
|
303
|
-
|
|
304
|
-
|
|
325
|
+
description,
|
|
326
|
+
...toastSettings
|
|
305
327
|
});
|
|
306
328
|
}
|
|
307
329
|
}).finally(()=>{
|
|
@@ -393,7 +415,7 @@ const TOAST_WIDTH = 356;
|
|
|
393
415
|
// Default gap between toasts
|
|
394
416
|
const GAP = 14;
|
|
395
417
|
// Threshold to dismiss a toast
|
|
396
|
-
const SWIPE_THRESHOLD =
|
|
418
|
+
const SWIPE_THRESHOLD = 45;
|
|
397
419
|
// Equal to exit animation duration
|
|
398
420
|
const TIME_BEFORE_UNMOUNT = 200;
|
|
399
421
|
function cn(...classes) {
|
|
@@ -412,7 +434,7 @@ function getDefaultSwipeDirections(position) {
|
|
|
412
434
|
}
|
|
413
435
|
const Toast = (props)=>{
|
|
414
436
|
var _toast_classNames, _toast_classNames1, _toast_classNames2, _toast_classNames3, _toast_classNames4, _toast_classNames5, _toast_classNames6, _toast_classNames7, _toast_classNames8;
|
|
415
|
-
const { invert: ToasterInvert, toast, unstyled, interacting, setHeights, visibleToasts, heights, index, toasts, expanded, removeToast, defaultRichColors, closeButton: closeButtonFromToaster, style, cancelButtonStyle, actionButtonStyle, className = '', descriptionClassName = '', duration: durationFromToaster, position, gap,
|
|
437
|
+
const { invert: ToasterInvert, toast, unstyled, interacting, setHeights, visibleToasts, heights, index, toasts, expanded, removeToast, defaultRichColors, closeButton: closeButtonFromToaster, style, cancelButtonStyle, actionButtonStyle, className = '', descriptionClassName = '', duration: durationFromToaster, position, gap, expandByDefault, classNames, icons, closeButtonAriaLabel = 'Close toast' } = props;
|
|
416
438
|
const [swipeDirection, setSwipeDirection] = React.useState(null);
|
|
417
439
|
const [swipeOutDirection, setSwipeOutDirection] = React.useState(null);
|
|
418
440
|
const [mounted, setMounted] = React.useState(false);
|
|
@@ -571,7 +593,7 @@ const Toast = (props)=>{
|
|
|
571
593
|
deleteToast();
|
|
572
594
|
}, remainingTime.current);
|
|
573
595
|
};
|
|
574
|
-
if (expanded || interacting ||
|
|
596
|
+
if (expanded || interacting || isDocumentHidden) {
|
|
575
597
|
pauseTimer();
|
|
576
598
|
} else {
|
|
577
599
|
startTimer();
|
|
@@ -582,7 +604,6 @@ const Toast = (props)=>{
|
|
|
582
604
|
interacting,
|
|
583
605
|
toast,
|
|
584
606
|
toastType,
|
|
585
|
-
pauseWhenPageIsHidden,
|
|
586
607
|
isDocumentHidden,
|
|
587
608
|
deleteToast
|
|
588
609
|
]);
|
|
@@ -603,13 +624,6 @@ const Toast = (props)=>{
|
|
|
603
624
|
"data-visible": toastType === 'loading'
|
|
604
625
|
}, icons.loading);
|
|
605
626
|
}
|
|
606
|
-
if (loadingIconProp) {
|
|
607
|
-
var _toast_classNames2;
|
|
608
|
-
return /*#__PURE__*/ React.createElement("div", {
|
|
609
|
-
className: cn(classNames == null ? void 0 : classNames.loader, toast == null ? void 0 : (_toast_classNames2 = toast.classNames) == null ? void 0 : _toast_classNames2.loader, 'sonner-loader'),
|
|
610
|
-
"data-visible": toastType === 'loading'
|
|
611
|
-
}, loadingIconProp);
|
|
612
|
-
}
|
|
613
627
|
return /*#__PURE__*/ React.createElement(Loader, {
|
|
614
628
|
className: cn(classNames == null ? void 0 : classNames.loader, toast == null ? void 0 : (_toast_classNames = toast.classNames) == null ? void 0 : _toast_classNames.loader),
|
|
615
629
|
visible: toastType === 'loading'
|
|
@@ -713,23 +727,33 @@ const Toast = (props)=>{
|
|
|
713
727
|
x: 0,
|
|
714
728
|
y: 0
|
|
715
729
|
};
|
|
730
|
+
const getDampening = (delta)=>{
|
|
731
|
+
const factor = Math.abs(delta) / 20;
|
|
732
|
+
return 1 / (1.5 + factor);
|
|
733
|
+
};
|
|
716
734
|
// Only apply swipe in the locked direction
|
|
717
735
|
if (swipeDirection === 'y') {
|
|
718
736
|
// Handle vertical swipes
|
|
719
737
|
if (swipeDirections.includes('top') || swipeDirections.includes('bottom')) {
|
|
720
|
-
if (swipeDirections.includes('top') && yDelta < 0) {
|
|
721
|
-
swipeAmount.y = yDelta;
|
|
722
|
-
} else if (swipeDirections.includes('bottom') && yDelta > 0) {
|
|
738
|
+
if (swipeDirections.includes('top') && yDelta < 0 || swipeDirections.includes('bottom') && yDelta > 0) {
|
|
723
739
|
swipeAmount.y = yDelta;
|
|
740
|
+
} else {
|
|
741
|
+
// Smoothly transition to dampened movement
|
|
742
|
+
const dampenedDelta = yDelta * getDampening(yDelta);
|
|
743
|
+
// Ensure we don't jump when transitioning to dampened movement
|
|
744
|
+
swipeAmount.y = Math.abs(dampenedDelta) < Math.abs(yDelta) ? dampenedDelta : yDelta;
|
|
724
745
|
}
|
|
725
746
|
}
|
|
726
747
|
} else if (swipeDirection === 'x') {
|
|
727
748
|
// Handle horizontal swipes
|
|
728
749
|
if (swipeDirections.includes('left') || swipeDirections.includes('right')) {
|
|
729
|
-
if (swipeDirections.includes('left') && xDelta < 0) {
|
|
730
|
-
swipeAmount.x = xDelta;
|
|
731
|
-
} else if (swipeDirections.includes('right') && xDelta > 0) {
|
|
750
|
+
if (swipeDirections.includes('left') && xDelta < 0 || swipeDirections.includes('right') && xDelta > 0) {
|
|
732
751
|
swipeAmount.x = xDelta;
|
|
752
|
+
} else {
|
|
753
|
+
// Smoothly transition to dampened movement
|
|
754
|
+
const dampenedDelta = xDelta * getDampening(xDelta);
|
|
755
|
+
// Ensure we don't jump when transitioning to dampened movement
|
|
756
|
+
swipeAmount.x = Math.abs(dampenedDelta) < Math.abs(xDelta) ? dampenedDelta : xDelta;
|
|
733
757
|
}
|
|
734
758
|
}
|
|
735
759
|
}
|
|
@@ -739,7 +763,7 @@ const Toast = (props)=>{
|
|
|
739
763
|
(_toastRef_current = toastRef.current) == null ? void 0 : _toastRef_current.style.setProperty('--swipe-amount-x', `${swipeAmount.x}px`);
|
|
740
764
|
(_toastRef_current1 = toastRef.current) == null ? void 0 : _toastRef_current1.style.setProperty('--swipe-amount-y', `${swipeAmount.y}px`);
|
|
741
765
|
}
|
|
742
|
-
}, closeButton && !toast.jsx ? /*#__PURE__*/ React.createElement("button", {
|
|
766
|
+
}, closeButton && !toast.jsx && toastType !== 'loading' ? /*#__PURE__*/ React.createElement("button", {
|
|
743
767
|
"aria-label": closeButtonAriaLabel,
|
|
744
768
|
"data-disabled": disabled,
|
|
745
769
|
"data-close-button": true,
|
|
@@ -880,7 +904,7 @@ const Toaster = /*#__PURE__*/ React.forwardRef(function Toaster(props, ref) {
|
|
|
880
904
|
const { invert, position = 'bottom-right', hotkey = [
|
|
881
905
|
'altKey',
|
|
882
906
|
'KeyT'
|
|
883
|
-
], expand, closeButton, className, offset, mobileOffset, theme = 'light', richColors, duration, style, visibleToasts = VISIBLE_TOASTS_AMOUNT, toastOptions, dir = getDocumentDirection(), gap = GAP,
|
|
907
|
+
], expand, closeButton, className, offset, mobileOffset, theme = 'light', richColors, duration, style, visibleToasts = VISIBLE_TOASTS_AMOUNT, toastOptions, dir = getDocumentDirection(), gap = GAP, icons, containerAriaLabel = 'Notifications' } = props;
|
|
884
908
|
const [toasts, setToasts] = React.useState([]);
|
|
885
909
|
const possiblePositions = React.useMemo(()=>{
|
|
886
910
|
return Array.from(new Set([
|
|
@@ -1115,15 +1139,14 @@ const Toaster = /*#__PURE__*/ React.forwardRef(function Toaster(props, ref) {
|
|
|
1115
1139
|
classNames: toastOptions == null ? void 0 : toastOptions.classNames,
|
|
1116
1140
|
cancelButtonStyle: toastOptions == null ? void 0 : toastOptions.cancelButtonStyle,
|
|
1117
1141
|
actionButtonStyle: toastOptions == null ? void 0 : toastOptions.actionButtonStyle,
|
|
1142
|
+
closeButtonAriaLabel: toastOptions == null ? void 0 : toastOptions.closeButtonAriaLabel,
|
|
1118
1143
|
removeToast: removeToast,
|
|
1119
1144
|
toasts: toasts.filter((t)=>t.position == toast.position),
|
|
1120
1145
|
heights: heights.filter((h)=>h.position == toast.position),
|
|
1121
1146
|
setHeights: setHeights,
|
|
1122
1147
|
expandByDefault: expand,
|
|
1123
1148
|
gap: gap,
|
|
1124
|
-
loadingIcon: loadingIcon,
|
|
1125
1149
|
expanded: expanded,
|
|
1126
|
-
pauseWhenPageIsHidden: pauseWhenPageIsHidden,
|
|
1127
1150
|
swipeDirections: props.swipeDirections
|
|
1128
1151
|
});
|
|
1129
1152
|
}));
|