@react-stately/toast 3.0.0-nightly.5042 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types.d.ts +5 -19
- package/dist/types.d.ts.map +1 -1
- package/dist/useToastState.main.js +19 -56
- package/dist/useToastState.main.js.map +1 -1
- package/dist/useToastState.mjs +19 -56
- package/dist/useToastState.module.js +19 -56
- package/dist/useToastState.module.js.map +1 -1
- package/package.json +4 -4
- package/src/useToastState.ts +30 -76
package/dist/types.d.ts
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
export interface ToastStateProps {
|
|
2
2
|
/** The maximum number of toasts to display at a time. */
|
|
3
3
|
maxVisibleToasts?: number;
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
* removed immediately but transition into an "exiting" state instead.
|
|
7
|
-
* Once the animation is complete, call the `remove` function.
|
|
8
|
-
*/
|
|
9
|
-
hasExitAnimation?: boolean;
|
|
4
|
+
/** Function to wrap updates in (i.e. document.startViewTransition()). */
|
|
5
|
+
wrapUpdate?: (fn: () => void) => void;
|
|
10
6
|
}
|
|
11
7
|
export interface ToastOptions {
|
|
12
8
|
/** Handler that is called when the toast is closed, either by the user or after a timeout. */
|
|
13
9
|
onClose?: () => void;
|
|
14
10
|
/** A timeout to automatically close the toast after, in milliseconds. */
|
|
15
11
|
timeout?: number;
|
|
16
|
-
/** The priority of the toast relative to other toasts. Larger numbers indicate higher priority. */
|
|
17
|
-
priority?: number;
|
|
18
12
|
}
|
|
19
13
|
export interface QueuedToast<T> extends ToastOptions {
|
|
20
14
|
/** The content of the toast. */
|
|
@@ -23,19 +17,14 @@ export interface QueuedToast<T> extends ToastOptions {
|
|
|
23
17
|
key: string;
|
|
24
18
|
/** A timer for the toast, if a timeout was set. */
|
|
25
19
|
timer?: Timer;
|
|
26
|
-
/** The current animation state for the toast. */
|
|
27
|
-
animation?: 'entering' | 'queued' | 'exiting';
|
|
28
20
|
}
|
|
29
21
|
export interface ToastState<T> {
|
|
30
22
|
/** Adds a new toast to the queue. */
|
|
31
23
|
add(content: T, options?: ToastOptions): string;
|
|
32
24
|
/**
|
|
33
|
-
* Closes a toast.
|
|
34
|
-
* transitions to an "exiting" state instead of being removed immediately.
|
|
25
|
+
* Closes a toast.
|
|
35
26
|
*/
|
|
36
27
|
close(key: string): void;
|
|
37
|
-
/** Removes a toast from the visible toasts after an exiting animation. */
|
|
38
|
-
remove(key: string): void;
|
|
39
28
|
/** Pauses the timers for all visible toasts. */
|
|
40
29
|
pauseAll(): void;
|
|
41
30
|
/** Resumes the timers for all visible toasts. */
|
|
@@ -53,7 +42,7 @@ export function useToastState<T>(props?: ToastStateProps): ToastState<T>;
|
|
|
53
42
|
*/
|
|
54
43
|
export function useToastQueue<T>(queue: ToastQueue<T>): ToastState<T>;
|
|
55
44
|
/**
|
|
56
|
-
* A ToastQueue
|
|
45
|
+
* A ToastQueue manages the order of toasts.
|
|
57
46
|
*/
|
|
58
47
|
export class ToastQueue<T> {
|
|
59
48
|
/** The currently visible toasts. */
|
|
@@ -64,12 +53,9 @@ export class ToastQueue<T> {
|
|
|
64
53
|
/** Adds a new toast to the queue. */
|
|
65
54
|
add(content: T, options?: ToastOptions): string;
|
|
66
55
|
/**
|
|
67
|
-
* Closes a toast.
|
|
68
|
-
* transitions to an "exiting" state instead of being removed immediately.
|
|
56
|
+
* Closes a toast.
|
|
69
57
|
*/
|
|
70
58
|
close(key: string): void;
|
|
71
|
-
/** Removes a toast from the visible toasts after an exiting animation. */
|
|
72
|
-
remove(key: string): void;
|
|
73
59
|
/** Pauses the timers for all visible toasts. */
|
|
74
60
|
pauseAll(): void;
|
|
75
61
|
/** Resumes the timers for all visible toasts. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAgBA;IACE,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B
|
|
1
|
+
{"mappings":"AAgBA;IACE,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAA;CACtC;AAED;IACE,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,6BAA6B,CAAC,CAAE,SAAQ,YAAY;IAClD,gCAAgC;IAChC,OAAO,EAAE,CAAC,CAAC;IACX,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,4BAA4B,CAAC;IAC3B,qCAAqC;IACrC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAChD;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gDAAgD;IAChD,QAAQ,IAAI,IAAI,CAAC;IACjB,iDAAiD;IACjD,SAAS,IAAI,IAAI,CAAC;IAClB,0BAA0B;IAC1B,aAAa,EAAE,YAAY,CAAC,CAAC,EAAE,CAAA;CAChC;AAED;;;GAGG;AACH,8BAA8B,CAAC,EAAE,KAAK,GAAE,eAAoB,GAAG,WAAW,CAAC,CAAC,CAI3E;AAED;;GAEG;AACH,8BAA8B,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAYpE;AAED;;GAEG;AACH,wBAAwB,CAAC;IAKvB,oCAAoC;IACpC,aAAa,EAAE,YAAY,CAAC,CAAC,EAAE,CAAM;gBAEzB,OAAO,CAAC,EAAE,eAAe;IAarC,mDAAmD;IACnD,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI;IAKxB,qCAAqC;IACrC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,GAAE,YAAiB;IAe1C;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM;IAkBjB,gDAAgD;IAChD,QAAQ;IAQR,iDAAiD;IACjD,SAAS;CAOV;AAED;gBAMc,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM;IAK/C,KAAK,CAAC,KAAK,EAAE,MAAM;IAKnB,KAAK;IAUL,MAAM;CAYP","sources":["packages/@react-stately/toast/src/packages/@react-stately/toast/src/useToastState.ts","packages/@react-stately/toast/src/packages/@react-stately/toast/src/index.ts","packages/@react-stately/toast/src/index.ts"],"sourcesContent":[null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nexport {useToastState, ToastQueue, useToastQueue} from './useToastState';\n\nexport type {ToastState, QueuedToast, ToastStateProps, ToastOptions} from './useToastState';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
|
|
@@ -22,13 +22,11 @@ $parcel$export(module.exports, "useToastQueue", () => $c995945a643dde76$export$8
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
function $c995945a643dde76$export$c7b26b20d3ced9c5(props = {}) {
|
|
25
|
-
let { maxVisibleToasts: maxVisibleToasts = 1
|
|
25
|
+
let { maxVisibleToasts: maxVisibleToasts = 1 } = props;
|
|
26
26
|
let queue = (0, $pwpJQ$react.useMemo)(()=>new $c995945a643dde76$export$f1f8569633bbbec4({
|
|
27
|
-
maxVisibleToasts: maxVisibleToasts
|
|
28
|
-
hasExitAnimation: hasExitAnimation
|
|
27
|
+
maxVisibleToasts: maxVisibleToasts
|
|
29
28
|
}), [
|
|
30
|
-
maxVisibleToasts
|
|
31
|
-
hasExitAnimation
|
|
29
|
+
maxVisibleToasts
|
|
32
30
|
]);
|
|
33
31
|
return $c995945a643dde76$export$84726ef35ca2129a(queue);
|
|
34
32
|
}
|
|
@@ -44,43 +42,33 @@ function $c995945a643dde76$export$84726ef35ca2129a(queue) {
|
|
|
44
42
|
visibleToasts: visibleToasts,
|
|
45
43
|
add: (content, options)=>queue.add(content, options),
|
|
46
44
|
close: (key)=>queue.close(key),
|
|
47
|
-
remove: (key)=>queue.remove(key),
|
|
48
45
|
pauseAll: ()=>queue.pauseAll(),
|
|
49
46
|
resumeAll: ()=>queue.resumeAll()
|
|
50
47
|
};
|
|
51
48
|
}
|
|
52
49
|
class $c995945a643dde76$export$f1f8569633bbbec4 {
|
|
50
|
+
runWithWrapUpdate(fn) {
|
|
51
|
+
if (this.wrapUpdate) this.wrapUpdate(fn);
|
|
52
|
+
else fn();
|
|
53
|
+
}
|
|
53
54
|
/** Subscribes to updates to the visible toasts. */ subscribe(fn) {
|
|
54
55
|
this.subscriptions.add(fn);
|
|
55
56
|
return ()=>this.subscriptions.delete(fn);
|
|
56
57
|
}
|
|
57
58
|
/** Adds a new toast to the queue. */ add(content, options = {}) {
|
|
58
|
-
let toastKey = Math.random().toString(36);
|
|
59
|
+
let toastKey = '_' + Math.random().toString(36).slice(2);
|
|
59
60
|
let toast = {
|
|
60
61
|
...options,
|
|
61
62
|
content: content,
|
|
62
63
|
key: toastKey,
|
|
63
|
-
timer: options.timeout ? new $c995945a643dde76$var$Timer(()=>this.close(toastKey), options.timeout) :
|
|
64
|
+
timer: options.timeout ? new $c995945a643dde76$var$Timer(()=>this.close(toastKey), options.timeout) : undefined
|
|
64
65
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
while(low < high){
|
|
68
|
-
let mid = Math.floor((low + high) / 2);
|
|
69
|
-
if ((toast.priority || 0) > (this.queue[mid].priority || 0)) high = mid;
|
|
70
|
-
else low = mid + 1;
|
|
71
|
-
}
|
|
72
|
-
this.queue.splice(low, 0, toast);
|
|
73
|
-
toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued';
|
|
74
|
-
let i = this.maxVisibleToasts;
|
|
75
|
-
while(i < this.queue.length)this.queue[i++].animation = 'queued';
|
|
76
|
-
this.updateVisibleToasts({
|
|
77
|
-
action: 'add'
|
|
78
|
-
});
|
|
66
|
+
this.queue.unshift(toast);
|
|
67
|
+
this.updateVisibleToasts();
|
|
79
68
|
return toastKey;
|
|
80
69
|
}
|
|
81
70
|
/**
|
|
82
|
-
* Closes a toast.
|
|
83
|
-
* transitions to an "exiting" state instead of being removed immediately.
|
|
71
|
+
* Closes a toast.
|
|
84
72
|
*/ close(key) {
|
|
85
73
|
let index = this.queue.findIndex((t)=>t.key === key);
|
|
86
74
|
if (index >= 0) {
|
|
@@ -88,36 +76,11 @@ class $c995945a643dde76$export$f1f8569633bbbec4 {
|
|
|
88
76
|
(_this_queue_index_onClose = (_this_queue_index = this.queue[index]).onClose) === null || _this_queue_index_onClose === void 0 ? void 0 : _this_queue_index_onClose.call(_this_queue_index);
|
|
89
77
|
this.queue.splice(index, 1);
|
|
90
78
|
}
|
|
91
|
-
this.updateVisibleToasts(
|
|
92
|
-
action: 'close',
|
|
93
|
-
key: key
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/** Removes a toast from the visible toasts after an exiting animation. */ remove(key) {
|
|
97
|
-
this.updateVisibleToasts({
|
|
98
|
-
action: 'remove',
|
|
99
|
-
key: key
|
|
100
|
-
});
|
|
79
|
+
this.updateVisibleToasts();
|
|
101
80
|
}
|
|
102
|
-
updateVisibleToasts(
|
|
103
|
-
|
|
104
|
-
let
|
|
105
|
-
if (action === 'add' && this.hasExitAnimation) {
|
|
106
|
-
let prevToasts = this.visibleToasts.filter((t)=>!toasts.some((t2)=>t.key === t2.key)).map((t)=>({
|
|
107
|
-
...t,
|
|
108
|
-
animation: 'exiting'
|
|
109
|
-
}));
|
|
110
|
-
this.visibleToasts = prevToasts.concat(toasts).sort((a, b)=>b.priority - a.priority);
|
|
111
|
-
} else if (action === 'close' && this.hasExitAnimation) // Cause a rerender to happen for exit animation
|
|
112
|
-
this.visibleToasts = this.visibleToasts.map((t)=>{
|
|
113
|
-
if (t.key !== key) return t;
|
|
114
|
-
else return {
|
|
115
|
-
...t,
|
|
116
|
-
animation: 'exiting'
|
|
117
|
-
};
|
|
118
|
-
});
|
|
119
|
-
else this.visibleToasts = toasts;
|
|
120
|
-
for (let fn of this.subscriptions)fn();
|
|
81
|
+
updateVisibleToasts() {
|
|
82
|
+
this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts);
|
|
83
|
+
for (let fn of this.subscriptions)this.runWithWrapUpdate(fn);
|
|
121
84
|
}
|
|
122
85
|
/** Pauses the timers for all visible toasts. */ pauseAll() {
|
|
123
86
|
for (let toast of this.visibleToasts)if (toast.timer) toast.timer.pause();
|
|
@@ -130,9 +93,8 @@ class $c995945a643dde76$export$f1f8569633bbbec4 {
|
|
|
130
93
|
this.subscriptions = new Set();
|
|
131
94
|
/** The currently visible toasts. */ this.visibleToasts = [];
|
|
132
95
|
var _options_maxVisibleToasts;
|
|
133
|
-
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts :
|
|
134
|
-
|
|
135
|
-
this.hasExitAnimation = (_options_hasExitAnimation = options === null || options === void 0 ? void 0 : options.hasExitAnimation) !== null && _options_hasExitAnimation !== void 0 ? _options_hasExitAnimation : false;
|
|
96
|
+
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts : Infinity;
|
|
97
|
+
this.wrapUpdate = options === null || options === void 0 ? void 0 : options.wrapUpdate;
|
|
136
98
|
}
|
|
137
99
|
}
|
|
138
100
|
class $c995945a643dde76$var$Timer {
|
|
@@ -156,6 +118,7 @@ class $c995945a643dde76$var$Timer {
|
|
|
156
118
|
}, this.remaining);
|
|
157
119
|
}
|
|
158
120
|
constructor(callback, delay){
|
|
121
|
+
this.startTime = null;
|
|
159
122
|
this.remaining = delay;
|
|
160
123
|
this.callback = callback;
|
|
161
124
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["packages/@react-stately/toast/src/useToastState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {useCallback, useMemo} from 'react';\n// Shim to support React 17 and below.\nimport {useSyncExternalStore} from 'use-sync-external-store/shim/index.js';\n\nexport interface ToastStateProps {\n /** The maximum number of toasts to display at a time. */\n maxVisibleToasts?: number,\n /**\n * Whether toasts have an exit animation. If true, toasts are not\n * removed immediately but transition into an \"exiting\" state instead.\n * Once the animation is complete, call the `remove` function.\n */\n hasExitAnimation?: boolean\n}\n\nexport interface ToastOptions {\n /** Handler that is called when the toast is closed, either by the user or after a timeout. */\n onClose?: () => void,\n /** A timeout to automatically close the toast after, in milliseconds. */\n timeout?: number,\n /** The priority of the toast relative to other toasts. Larger numbers indicate higher priority. */\n priority?: number\n}\n\nexport interface QueuedToast<T> extends ToastOptions {\n /** The content of the toast. */\n content: T,\n /** A unique key for the toast. */\n key: string,\n /** A timer for the toast, if a timeout was set. */\n timer?: Timer,\n /** The current animation state for the toast. */\n animation?: 'entering' | 'queued' | 'exiting'\n}\n\nexport interface ToastState<T> {\n /** Adds a new toast to the queue. */\n add(content: T, options?: ToastOptions): string,\n /**\n * Closes a toast. If `hasExitAnimation` is true, the toast\n * transitions to an \"exiting\" state instead of being removed immediately.\n */\n close(key: string): void,\n /** Removes a toast from the visible toasts after an exiting animation. */\n remove(key: string): void,\n /** Pauses the timers for all visible toasts. */\n pauseAll(): void,\n /** Resumes the timers for all visible toasts. */\n resumeAll(): void,\n /** The visible toasts. */\n visibleToasts: QueuedToast<T>[]\n}\n\n/**\n * Provides state management for a toast queue. Toasts display brief, temporary notifications\n * of actions, errors, or other events in an application.\n */\nexport function useToastState<T>(props: ToastStateProps = {}): ToastState<T> {\n let {maxVisibleToasts = 1, hasExitAnimation = false} = props;\n let queue = useMemo(() => new ToastQueue<T>({maxVisibleToasts, hasExitAnimation}), [maxVisibleToasts, hasExitAnimation]);\n return useToastQueue(queue);\n}\n\n/**\n * Subscribes to a provided toast queue and provides methods to update it.\n */\nexport function useToastQueue<T>(queue: ToastQueue<T>): ToastState<T> {\n let subscribe = useCallback(fn => queue.subscribe(fn), [queue]);\n let getSnapshot = useCallback(() => queue.visibleToasts, [queue]);\n let visibleToasts = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return {\n visibleToasts,\n add: (content, options) => queue.add(content, options),\n close: key => queue.close(key),\n remove: key => queue.remove(key),\n pauseAll: () => queue.pauseAll(),\n resumeAll: () => queue.resumeAll()\n };\n}\n\n/**\n * A ToastQueue is a priority queue of toasts.\n */\nexport class ToastQueue<T> {\n private queue: QueuedToast<T>[] = [];\n private subscriptions: Set<() => void> = new Set();\n private maxVisibleToasts: number;\n private hasExitAnimation: boolean;\n /** The currently visible toasts. */\n visibleToasts: QueuedToast<T>[] = [];\n\n constructor(options?: ToastStateProps) {\n this.maxVisibleToasts = options?.maxVisibleToasts ?? 1;\n this.hasExitAnimation = options?.hasExitAnimation ?? false;\n }\n\n /** Subscribes to updates to the visible toasts. */\n subscribe(fn: () => void) {\n this.subscriptions.add(fn);\n return () => this.subscriptions.delete(fn);\n }\n\n /** Adds a new toast to the queue. */\n add(content: T, options: ToastOptions = {}) {\n let toastKey = Math.random().toString(36);\n let toast: QueuedToast<T> = {\n ...options,\n content,\n key: toastKey,\n timer: options.timeout ? new Timer(() => this.close(toastKey), options.timeout) : null\n };\n\n let low = 0;\n let high = this.queue.length;\n while (low < high) {\n let mid = Math.floor((low + high) / 2);\n if ((toast.priority || 0) > (this.queue[mid].priority || 0)) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n this.queue.splice(low, 0, toast);\n\n toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued';\n let i = this.maxVisibleToasts;\n while (i < this.queue.length) {\n this.queue[i++].animation = 'queued';\n }\n\n this.updateVisibleToasts({action: 'add'});\n return toastKey;\n }\n\n /**\n * Closes a toast. If `hasExitAnimation` is true, the toast\n * transitions to an \"exiting\" state instead of being removed immediately.\n */\n close(key: string) {\n let index = this.queue.findIndex(t => t.key === key);\n if (index >= 0) {\n this.queue[index].onClose?.();\n this.queue.splice(index, 1);\n }\n\n this.updateVisibleToasts({action: 'close', key});\n }\n\n /** Removes a toast from the visible toasts after an exiting animation. */\n remove(key: string) {\n this.updateVisibleToasts({action: 'remove', key});\n }\n\n private updateVisibleToasts(options: {action: 'add' | 'close' | 'remove', key?: string}) {\n let {action, key} = options;\n let toasts = this.queue.slice(0, this.maxVisibleToasts);\n\n if (action === 'add' && this.hasExitAnimation) {\n let prevToasts: QueuedToast<T>[] = this.visibleToasts\n .filter(t => !toasts.some(t2 => t.key === t2.key))\n .map(t => ({...t, animation: 'exiting'}));\n this.visibleToasts = prevToasts.concat(toasts).sort((a, b) => b.priority - a.priority);\n } else if (action === 'close' && this.hasExitAnimation) {\n // Cause a rerender to happen for exit animation\n this.visibleToasts = this.visibleToasts.map(t => {\n if (t.key !== key) {\n return t;\n } else {\n return {...t, animation: 'exiting'};\n }\n });\n } else {\n this.visibleToasts = toasts;\n }\n\n for (let fn of this.subscriptions) {\n fn();\n }\n }\n\n /** Pauses the timers for all visible toasts. */\n pauseAll() {\n for (let toast of this.visibleToasts) {\n if (toast.timer) {\n toast.timer.pause();\n }\n }\n }\n\n /** Resumes the timers for all visible toasts. */\n resumeAll() {\n for (let toast of this.visibleToasts) {\n if (toast.timer) {\n toast.timer.resume();\n }\n }\n }\n}\n\nclass Timer {\n private timerId;\n private startTime: number;\n private remaining: number;\n private callback: () => void;\n\n constructor(callback: () => void, delay: number) {\n this.remaining = delay;\n this.callback = callback;\n }\n\n reset(delay: number) {\n this.remaining = delay;\n this.resume();\n }\n\n pause() {\n if (this.timerId == null) {\n return;\n }\n\n clearTimeout(this.timerId);\n this.timerId = null;\n this.remaining -= Date.now() - this.startTime;\n }\n\n resume() {\n if (this.remaining <= 0) {\n return;\n }\n\n this.startTime = Date.now();\n this.timerId = setTimeout(() => {\n this.timerId = null;\n this.remaining = 0;\n this.callback();\n }, this.remaining);\n }\n}\n"],"names":[],"version":3,"file":"useToastState.main.js.map"}
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-stately/toast/src/useToastState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {useCallback, useMemo} from 'react';\n// Shim to support React 17 and below.\nimport {useSyncExternalStore} from 'use-sync-external-store/shim/index.js';\n\nexport interface ToastStateProps {\n /** The maximum number of toasts to display at a time. */\n maxVisibleToasts?: number,\n /** Function to wrap updates in (i.e. document.startViewTransition()). */\n wrapUpdate?: (fn: () => void) => void\n}\n\nexport interface ToastOptions {\n /** Handler that is called when the toast is closed, either by the user or after a timeout. */\n onClose?: () => void,\n /** A timeout to automatically close the toast after, in milliseconds. */\n timeout?: number\n}\n\nexport interface QueuedToast<T> extends ToastOptions {\n /** The content of the toast. */\n content: T,\n /** A unique key for the toast. */\n key: string,\n /** A timer for the toast, if a timeout was set. */\n timer?: Timer\n}\n\nexport interface ToastState<T> {\n /** Adds a new toast to the queue. */\n add(content: T, options?: ToastOptions): string,\n /**\n * Closes a toast.\n */\n close(key: string): void,\n /** Pauses the timers for all visible toasts. */\n pauseAll(): void,\n /** Resumes the timers for all visible toasts. */\n resumeAll(): void,\n /** The visible toasts. */\n visibleToasts: QueuedToast<T>[]\n}\n\n/**\n * Provides state management for a toast queue. Toasts display brief, temporary notifications\n * of actions, errors, or other events in an application.\n */\nexport function useToastState<T>(props: ToastStateProps = {}): ToastState<T> {\n let {maxVisibleToasts = 1} = props;\n let queue = useMemo(() => new ToastQueue<T>({maxVisibleToasts}), [maxVisibleToasts]);\n return useToastQueue(queue);\n}\n\n/**\n * Subscribes to a provided toast queue and provides methods to update it.\n */\nexport function useToastQueue<T>(queue: ToastQueue<T>): ToastState<T> {\n let subscribe = useCallback(fn => queue.subscribe(fn), [queue]);\n let getSnapshot = useCallback(() => queue.visibleToasts, [queue]);\n let visibleToasts = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return {\n visibleToasts,\n add: (content, options) => queue.add(content, options),\n close: key => queue.close(key),\n pauseAll: () => queue.pauseAll(),\n resumeAll: () => queue.resumeAll()\n };\n}\n\n/**\n * A ToastQueue manages the order of toasts.\n */\nexport class ToastQueue<T> {\n private queue: QueuedToast<T>[] = [];\n private subscriptions: Set<() => void> = new Set();\n private maxVisibleToasts: number;\n private wrapUpdate?: (fn: () => void) => void;\n /** The currently visible toasts. */\n visibleToasts: QueuedToast<T>[] = [];\n\n constructor(options?: ToastStateProps) {\n this.maxVisibleToasts = options?.maxVisibleToasts ?? Infinity;\n this.wrapUpdate = options?.wrapUpdate;\n }\n\n private runWithWrapUpdate(fn: () => void): void {\n if (this.wrapUpdate) {\n this.wrapUpdate(fn);\n } else {\n fn();\n }\n }\n\n /** Subscribes to updates to the visible toasts. */\n subscribe(fn: () => void) {\n this.subscriptions.add(fn);\n return () => this.subscriptions.delete(fn);\n }\n\n /** Adds a new toast to the queue. */\n add(content: T, options: ToastOptions = {}) {\n let toastKey = '_' + Math.random().toString(36).slice(2);\n let toast: QueuedToast<T> = {\n ...options,\n content,\n key: toastKey,\n timer: options.timeout ? new Timer(() => this.close(toastKey), options.timeout) : undefined\n };\n\n this.queue.unshift(toast);\n\n this.updateVisibleToasts();\n return toastKey;\n }\n\n /**\n * Closes a toast.\n */\n close(key: string) {\n let index = this.queue.findIndex(t => t.key === key);\n if (index >= 0) {\n this.queue[index].onClose?.();\n this.queue.splice(index, 1);\n }\n\n this.updateVisibleToasts();\n }\n\n private updateVisibleToasts() {\n this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts);\n\n for (let fn of this.subscriptions) {\n this.runWithWrapUpdate(fn);\n }\n }\n\n /** Pauses the timers for all visible toasts. */\n pauseAll() {\n for (let toast of this.visibleToasts) {\n if (toast.timer) {\n toast.timer.pause();\n }\n }\n }\n\n /** Resumes the timers for all visible toasts. */\n resumeAll() {\n for (let toast of this.visibleToasts) {\n if (toast.timer) {\n toast.timer.resume();\n }\n }\n }\n}\n\nclass Timer {\n private timerId;\n private startTime: number | null = null;\n private remaining: number;\n private callback: () => void;\n\n constructor(callback: () => void, delay: number) {\n this.remaining = delay;\n this.callback = callback;\n }\n\n reset(delay: number) {\n this.remaining = delay;\n this.resume();\n }\n\n pause() {\n if (this.timerId == null) {\n return;\n }\n\n clearTimeout(this.timerId);\n this.timerId = null;\n this.remaining -= Date.now() - this.startTime!;\n }\n\n resume() {\n if (this.remaining <= 0) {\n return;\n }\n\n this.startTime = Date.now();\n this.timerId = setTimeout(() => {\n this.timerId = null;\n this.remaining = 0;\n this.callback();\n }, this.remaining);\n }\n}\n"],"names":[],"version":3,"file":"useToastState.main.js.map"}
|
package/dist/useToastState.mjs
CHANGED
|
@@ -14,13 +14,11 @@ import {useSyncExternalStore as $cNx9A$useSyncExternalStore} from "use-sync-exte
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
function $77b352cf12efcf73$export$c7b26b20d3ced9c5(props = {}) {
|
|
17
|
-
let { maxVisibleToasts: maxVisibleToasts = 1
|
|
17
|
+
let { maxVisibleToasts: maxVisibleToasts = 1 } = props;
|
|
18
18
|
let queue = (0, $cNx9A$useMemo)(()=>new $77b352cf12efcf73$export$f1f8569633bbbec4({
|
|
19
|
-
maxVisibleToasts: maxVisibleToasts
|
|
20
|
-
hasExitAnimation: hasExitAnimation
|
|
19
|
+
maxVisibleToasts: maxVisibleToasts
|
|
21
20
|
}), [
|
|
22
|
-
maxVisibleToasts
|
|
23
|
-
hasExitAnimation
|
|
21
|
+
maxVisibleToasts
|
|
24
22
|
]);
|
|
25
23
|
return $77b352cf12efcf73$export$84726ef35ca2129a(queue);
|
|
26
24
|
}
|
|
@@ -36,43 +34,33 @@ function $77b352cf12efcf73$export$84726ef35ca2129a(queue) {
|
|
|
36
34
|
visibleToasts: visibleToasts,
|
|
37
35
|
add: (content, options)=>queue.add(content, options),
|
|
38
36
|
close: (key)=>queue.close(key),
|
|
39
|
-
remove: (key)=>queue.remove(key),
|
|
40
37
|
pauseAll: ()=>queue.pauseAll(),
|
|
41
38
|
resumeAll: ()=>queue.resumeAll()
|
|
42
39
|
};
|
|
43
40
|
}
|
|
44
41
|
class $77b352cf12efcf73$export$f1f8569633bbbec4 {
|
|
42
|
+
runWithWrapUpdate(fn) {
|
|
43
|
+
if (this.wrapUpdate) this.wrapUpdate(fn);
|
|
44
|
+
else fn();
|
|
45
|
+
}
|
|
45
46
|
/** Subscribes to updates to the visible toasts. */ subscribe(fn) {
|
|
46
47
|
this.subscriptions.add(fn);
|
|
47
48
|
return ()=>this.subscriptions.delete(fn);
|
|
48
49
|
}
|
|
49
50
|
/** Adds a new toast to the queue. */ add(content, options = {}) {
|
|
50
|
-
let toastKey = Math.random().toString(36);
|
|
51
|
+
let toastKey = '_' + Math.random().toString(36).slice(2);
|
|
51
52
|
let toast = {
|
|
52
53
|
...options,
|
|
53
54
|
content: content,
|
|
54
55
|
key: toastKey,
|
|
55
|
-
timer: options.timeout ? new $77b352cf12efcf73$var$Timer(()=>this.close(toastKey), options.timeout) :
|
|
56
|
+
timer: options.timeout ? new $77b352cf12efcf73$var$Timer(()=>this.close(toastKey), options.timeout) : undefined
|
|
56
57
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
while(low < high){
|
|
60
|
-
let mid = Math.floor((low + high) / 2);
|
|
61
|
-
if ((toast.priority || 0) > (this.queue[mid].priority || 0)) high = mid;
|
|
62
|
-
else low = mid + 1;
|
|
63
|
-
}
|
|
64
|
-
this.queue.splice(low, 0, toast);
|
|
65
|
-
toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued';
|
|
66
|
-
let i = this.maxVisibleToasts;
|
|
67
|
-
while(i < this.queue.length)this.queue[i++].animation = 'queued';
|
|
68
|
-
this.updateVisibleToasts({
|
|
69
|
-
action: 'add'
|
|
70
|
-
});
|
|
58
|
+
this.queue.unshift(toast);
|
|
59
|
+
this.updateVisibleToasts();
|
|
71
60
|
return toastKey;
|
|
72
61
|
}
|
|
73
62
|
/**
|
|
74
|
-
* Closes a toast.
|
|
75
|
-
* transitions to an "exiting" state instead of being removed immediately.
|
|
63
|
+
* Closes a toast.
|
|
76
64
|
*/ close(key) {
|
|
77
65
|
let index = this.queue.findIndex((t)=>t.key === key);
|
|
78
66
|
if (index >= 0) {
|
|
@@ -80,36 +68,11 @@ class $77b352cf12efcf73$export$f1f8569633bbbec4 {
|
|
|
80
68
|
(_this_queue_index_onClose = (_this_queue_index = this.queue[index]).onClose) === null || _this_queue_index_onClose === void 0 ? void 0 : _this_queue_index_onClose.call(_this_queue_index);
|
|
81
69
|
this.queue.splice(index, 1);
|
|
82
70
|
}
|
|
83
|
-
this.updateVisibleToasts(
|
|
84
|
-
action: 'close',
|
|
85
|
-
key: key
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
/** Removes a toast from the visible toasts after an exiting animation. */ remove(key) {
|
|
89
|
-
this.updateVisibleToasts({
|
|
90
|
-
action: 'remove',
|
|
91
|
-
key: key
|
|
92
|
-
});
|
|
71
|
+
this.updateVisibleToasts();
|
|
93
72
|
}
|
|
94
|
-
updateVisibleToasts(
|
|
95
|
-
|
|
96
|
-
let
|
|
97
|
-
if (action === 'add' && this.hasExitAnimation) {
|
|
98
|
-
let prevToasts = this.visibleToasts.filter((t)=>!toasts.some((t2)=>t.key === t2.key)).map((t)=>({
|
|
99
|
-
...t,
|
|
100
|
-
animation: 'exiting'
|
|
101
|
-
}));
|
|
102
|
-
this.visibleToasts = prevToasts.concat(toasts).sort((a, b)=>b.priority - a.priority);
|
|
103
|
-
} else if (action === 'close' && this.hasExitAnimation) // Cause a rerender to happen for exit animation
|
|
104
|
-
this.visibleToasts = this.visibleToasts.map((t)=>{
|
|
105
|
-
if (t.key !== key) return t;
|
|
106
|
-
else return {
|
|
107
|
-
...t,
|
|
108
|
-
animation: 'exiting'
|
|
109
|
-
};
|
|
110
|
-
});
|
|
111
|
-
else this.visibleToasts = toasts;
|
|
112
|
-
for (let fn of this.subscriptions)fn();
|
|
73
|
+
updateVisibleToasts() {
|
|
74
|
+
this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts);
|
|
75
|
+
for (let fn of this.subscriptions)this.runWithWrapUpdate(fn);
|
|
113
76
|
}
|
|
114
77
|
/** Pauses the timers for all visible toasts. */ pauseAll() {
|
|
115
78
|
for (let toast of this.visibleToasts)if (toast.timer) toast.timer.pause();
|
|
@@ -122,9 +85,8 @@ class $77b352cf12efcf73$export$f1f8569633bbbec4 {
|
|
|
122
85
|
this.subscriptions = new Set();
|
|
123
86
|
/** The currently visible toasts. */ this.visibleToasts = [];
|
|
124
87
|
var _options_maxVisibleToasts;
|
|
125
|
-
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts :
|
|
126
|
-
|
|
127
|
-
this.hasExitAnimation = (_options_hasExitAnimation = options === null || options === void 0 ? void 0 : options.hasExitAnimation) !== null && _options_hasExitAnimation !== void 0 ? _options_hasExitAnimation : false;
|
|
88
|
+
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts : Infinity;
|
|
89
|
+
this.wrapUpdate = options === null || options === void 0 ? void 0 : options.wrapUpdate;
|
|
128
90
|
}
|
|
129
91
|
}
|
|
130
92
|
class $77b352cf12efcf73$var$Timer {
|
|
@@ -148,6 +110,7 @@ class $77b352cf12efcf73$var$Timer {
|
|
|
148
110
|
}, this.remaining);
|
|
149
111
|
}
|
|
150
112
|
constructor(callback, delay){
|
|
113
|
+
this.startTime = null;
|
|
151
114
|
this.remaining = delay;
|
|
152
115
|
this.callback = callback;
|
|
153
116
|
}
|
|
@@ -14,13 +14,11 @@ import {useSyncExternalStore as $cNx9A$useSyncExternalStore} from "use-sync-exte
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
function $77b352cf12efcf73$export$c7b26b20d3ced9c5(props = {}) {
|
|
17
|
-
let { maxVisibleToasts: maxVisibleToasts = 1
|
|
17
|
+
let { maxVisibleToasts: maxVisibleToasts = 1 } = props;
|
|
18
18
|
let queue = (0, $cNx9A$useMemo)(()=>new $77b352cf12efcf73$export$f1f8569633bbbec4({
|
|
19
|
-
maxVisibleToasts: maxVisibleToasts
|
|
20
|
-
hasExitAnimation: hasExitAnimation
|
|
19
|
+
maxVisibleToasts: maxVisibleToasts
|
|
21
20
|
}), [
|
|
22
|
-
maxVisibleToasts
|
|
23
|
-
hasExitAnimation
|
|
21
|
+
maxVisibleToasts
|
|
24
22
|
]);
|
|
25
23
|
return $77b352cf12efcf73$export$84726ef35ca2129a(queue);
|
|
26
24
|
}
|
|
@@ -36,43 +34,33 @@ function $77b352cf12efcf73$export$84726ef35ca2129a(queue) {
|
|
|
36
34
|
visibleToasts: visibleToasts,
|
|
37
35
|
add: (content, options)=>queue.add(content, options),
|
|
38
36
|
close: (key)=>queue.close(key),
|
|
39
|
-
remove: (key)=>queue.remove(key),
|
|
40
37
|
pauseAll: ()=>queue.pauseAll(),
|
|
41
38
|
resumeAll: ()=>queue.resumeAll()
|
|
42
39
|
};
|
|
43
40
|
}
|
|
44
41
|
class $77b352cf12efcf73$export$f1f8569633bbbec4 {
|
|
42
|
+
runWithWrapUpdate(fn) {
|
|
43
|
+
if (this.wrapUpdate) this.wrapUpdate(fn);
|
|
44
|
+
else fn();
|
|
45
|
+
}
|
|
45
46
|
/** Subscribes to updates to the visible toasts. */ subscribe(fn) {
|
|
46
47
|
this.subscriptions.add(fn);
|
|
47
48
|
return ()=>this.subscriptions.delete(fn);
|
|
48
49
|
}
|
|
49
50
|
/** Adds a new toast to the queue. */ add(content, options = {}) {
|
|
50
|
-
let toastKey = Math.random().toString(36);
|
|
51
|
+
let toastKey = '_' + Math.random().toString(36).slice(2);
|
|
51
52
|
let toast = {
|
|
52
53
|
...options,
|
|
53
54
|
content: content,
|
|
54
55
|
key: toastKey,
|
|
55
|
-
timer: options.timeout ? new $77b352cf12efcf73$var$Timer(()=>this.close(toastKey), options.timeout) :
|
|
56
|
+
timer: options.timeout ? new $77b352cf12efcf73$var$Timer(()=>this.close(toastKey), options.timeout) : undefined
|
|
56
57
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
while(low < high){
|
|
60
|
-
let mid = Math.floor((low + high) / 2);
|
|
61
|
-
if ((toast.priority || 0) > (this.queue[mid].priority || 0)) high = mid;
|
|
62
|
-
else low = mid + 1;
|
|
63
|
-
}
|
|
64
|
-
this.queue.splice(low, 0, toast);
|
|
65
|
-
toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued';
|
|
66
|
-
let i = this.maxVisibleToasts;
|
|
67
|
-
while(i < this.queue.length)this.queue[i++].animation = 'queued';
|
|
68
|
-
this.updateVisibleToasts({
|
|
69
|
-
action: 'add'
|
|
70
|
-
});
|
|
58
|
+
this.queue.unshift(toast);
|
|
59
|
+
this.updateVisibleToasts();
|
|
71
60
|
return toastKey;
|
|
72
61
|
}
|
|
73
62
|
/**
|
|
74
|
-
* Closes a toast.
|
|
75
|
-
* transitions to an "exiting" state instead of being removed immediately.
|
|
63
|
+
* Closes a toast.
|
|
76
64
|
*/ close(key) {
|
|
77
65
|
let index = this.queue.findIndex((t)=>t.key === key);
|
|
78
66
|
if (index >= 0) {
|
|
@@ -80,36 +68,11 @@ class $77b352cf12efcf73$export$f1f8569633bbbec4 {
|
|
|
80
68
|
(_this_queue_index_onClose = (_this_queue_index = this.queue[index]).onClose) === null || _this_queue_index_onClose === void 0 ? void 0 : _this_queue_index_onClose.call(_this_queue_index);
|
|
81
69
|
this.queue.splice(index, 1);
|
|
82
70
|
}
|
|
83
|
-
this.updateVisibleToasts(
|
|
84
|
-
action: 'close',
|
|
85
|
-
key: key
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
/** Removes a toast from the visible toasts after an exiting animation. */ remove(key) {
|
|
89
|
-
this.updateVisibleToasts({
|
|
90
|
-
action: 'remove',
|
|
91
|
-
key: key
|
|
92
|
-
});
|
|
71
|
+
this.updateVisibleToasts();
|
|
93
72
|
}
|
|
94
|
-
updateVisibleToasts(
|
|
95
|
-
|
|
96
|
-
let
|
|
97
|
-
if (action === 'add' && this.hasExitAnimation) {
|
|
98
|
-
let prevToasts = this.visibleToasts.filter((t)=>!toasts.some((t2)=>t.key === t2.key)).map((t)=>({
|
|
99
|
-
...t,
|
|
100
|
-
animation: 'exiting'
|
|
101
|
-
}));
|
|
102
|
-
this.visibleToasts = prevToasts.concat(toasts).sort((a, b)=>b.priority - a.priority);
|
|
103
|
-
} else if (action === 'close' && this.hasExitAnimation) // Cause a rerender to happen for exit animation
|
|
104
|
-
this.visibleToasts = this.visibleToasts.map((t)=>{
|
|
105
|
-
if (t.key !== key) return t;
|
|
106
|
-
else return {
|
|
107
|
-
...t,
|
|
108
|
-
animation: 'exiting'
|
|
109
|
-
};
|
|
110
|
-
});
|
|
111
|
-
else this.visibleToasts = toasts;
|
|
112
|
-
for (let fn of this.subscriptions)fn();
|
|
73
|
+
updateVisibleToasts() {
|
|
74
|
+
this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts);
|
|
75
|
+
for (let fn of this.subscriptions)this.runWithWrapUpdate(fn);
|
|
113
76
|
}
|
|
114
77
|
/** Pauses the timers for all visible toasts. */ pauseAll() {
|
|
115
78
|
for (let toast of this.visibleToasts)if (toast.timer) toast.timer.pause();
|
|
@@ -122,9 +85,8 @@ class $77b352cf12efcf73$export$f1f8569633bbbec4 {
|
|
|
122
85
|
this.subscriptions = new Set();
|
|
123
86
|
/** The currently visible toasts. */ this.visibleToasts = [];
|
|
124
87
|
var _options_maxVisibleToasts;
|
|
125
|
-
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts :
|
|
126
|
-
|
|
127
|
-
this.hasExitAnimation = (_options_hasExitAnimation = options === null || options === void 0 ? void 0 : options.hasExitAnimation) !== null && _options_hasExitAnimation !== void 0 ? _options_hasExitAnimation : false;
|
|
88
|
+
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts : Infinity;
|
|
89
|
+
this.wrapUpdate = options === null || options === void 0 ? void 0 : options.wrapUpdate;
|
|
128
90
|
}
|
|
129
91
|
}
|
|
130
92
|
class $77b352cf12efcf73$var$Timer {
|
|
@@ -148,6 +110,7 @@ class $77b352cf12efcf73$var$Timer {
|
|
|
148
110
|
}, this.remaining);
|
|
149
111
|
}
|
|
150
112
|
constructor(callback, delay){
|
|
113
|
+
this.startTime = null;
|
|
151
114
|
this.remaining = delay;
|
|
152
115
|
this.callback = callback;
|
|
153
116
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["packages/@react-stately/toast/src/useToastState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {useCallback, useMemo} from 'react';\n// Shim to support React 17 and below.\nimport {useSyncExternalStore} from 'use-sync-external-store/shim/index.js';\n\nexport interface ToastStateProps {\n /** The maximum number of toasts to display at a time. */\n maxVisibleToasts?: number,\n /**\n * Whether toasts have an exit animation. If true, toasts are not\n * removed immediately but transition into an \"exiting\" state instead.\n * Once the animation is complete, call the `remove` function.\n */\n hasExitAnimation?: boolean\n}\n\nexport interface ToastOptions {\n /** Handler that is called when the toast is closed, either by the user or after a timeout. */\n onClose?: () => void,\n /** A timeout to automatically close the toast after, in milliseconds. */\n timeout?: number,\n /** The priority of the toast relative to other toasts. Larger numbers indicate higher priority. */\n priority?: number\n}\n\nexport interface QueuedToast<T> extends ToastOptions {\n /** The content of the toast. */\n content: T,\n /** A unique key for the toast. */\n key: string,\n /** A timer for the toast, if a timeout was set. */\n timer?: Timer,\n /** The current animation state for the toast. */\n animation?: 'entering' | 'queued' | 'exiting'\n}\n\nexport interface ToastState<T> {\n /** Adds a new toast to the queue. */\n add(content: T, options?: ToastOptions): string,\n /**\n * Closes a toast. If `hasExitAnimation` is true, the toast\n * transitions to an \"exiting\" state instead of being removed immediately.\n */\n close(key: string): void,\n /** Removes a toast from the visible toasts after an exiting animation. */\n remove(key: string): void,\n /** Pauses the timers for all visible toasts. */\n pauseAll(): void,\n /** Resumes the timers for all visible toasts. */\n resumeAll(): void,\n /** The visible toasts. */\n visibleToasts: QueuedToast<T>[]\n}\n\n/**\n * Provides state management for a toast queue. Toasts display brief, temporary notifications\n * of actions, errors, or other events in an application.\n */\nexport function useToastState<T>(props: ToastStateProps = {}): ToastState<T> {\n let {maxVisibleToasts = 1, hasExitAnimation = false} = props;\n let queue = useMemo(() => new ToastQueue<T>({maxVisibleToasts, hasExitAnimation}), [maxVisibleToasts, hasExitAnimation]);\n return useToastQueue(queue);\n}\n\n/**\n * Subscribes to a provided toast queue and provides methods to update it.\n */\nexport function useToastQueue<T>(queue: ToastQueue<T>): ToastState<T> {\n let subscribe = useCallback(fn => queue.subscribe(fn), [queue]);\n let getSnapshot = useCallback(() => queue.visibleToasts, [queue]);\n let visibleToasts = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return {\n visibleToasts,\n add: (content, options) => queue.add(content, options),\n close: key => queue.close(key),\n remove: key => queue.remove(key),\n pauseAll: () => queue.pauseAll(),\n resumeAll: () => queue.resumeAll()\n };\n}\n\n/**\n * A ToastQueue is a priority queue of toasts.\n */\nexport class ToastQueue<T> {\n private queue: QueuedToast<T>[] = [];\n private subscriptions: Set<() => void> = new Set();\n private maxVisibleToasts: number;\n private hasExitAnimation: boolean;\n /** The currently visible toasts. */\n visibleToasts: QueuedToast<T>[] = [];\n\n constructor(options?: ToastStateProps) {\n this.maxVisibleToasts = options?.maxVisibleToasts ?? 1;\n this.hasExitAnimation = options?.hasExitAnimation ?? false;\n }\n\n /** Subscribes to updates to the visible toasts. */\n subscribe(fn: () => void) {\n this.subscriptions.add(fn);\n return () => this.subscriptions.delete(fn);\n }\n\n /** Adds a new toast to the queue. */\n add(content: T, options: ToastOptions = {}) {\n let toastKey = Math.random().toString(36);\n let toast: QueuedToast<T> = {\n ...options,\n content,\n key: toastKey,\n timer: options.timeout ? new Timer(() => this.close(toastKey), options.timeout) : null\n };\n\n let low = 0;\n let high = this.queue.length;\n while (low < high) {\n let mid = Math.floor((low + high) / 2);\n if ((toast.priority || 0) > (this.queue[mid].priority || 0)) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n this.queue.splice(low, 0, toast);\n\n toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued';\n let i = this.maxVisibleToasts;\n while (i < this.queue.length) {\n this.queue[i++].animation = 'queued';\n }\n\n this.updateVisibleToasts({action: 'add'});\n return toastKey;\n }\n\n /**\n * Closes a toast. If `hasExitAnimation` is true, the toast\n * transitions to an \"exiting\" state instead of being removed immediately.\n */\n close(key: string) {\n let index = this.queue.findIndex(t => t.key === key);\n if (index >= 0) {\n this.queue[index].onClose?.();\n this.queue.splice(index, 1);\n }\n\n this.updateVisibleToasts({action: 'close', key});\n }\n\n /** Removes a toast from the visible toasts after an exiting animation. */\n remove(key: string) {\n this.updateVisibleToasts({action: 'remove', key});\n }\n\n private updateVisibleToasts(options: {action: 'add' | 'close' | 'remove', key?: string}) {\n let {action, key} = options;\n let toasts = this.queue.slice(0, this.maxVisibleToasts);\n\n if (action === 'add' && this.hasExitAnimation) {\n let prevToasts: QueuedToast<T>[] = this.visibleToasts\n .filter(t => !toasts.some(t2 => t.key === t2.key))\n .map(t => ({...t, animation: 'exiting'}));\n this.visibleToasts = prevToasts.concat(toasts).sort((a, b) => b.priority - a.priority);\n } else if (action === 'close' && this.hasExitAnimation) {\n // Cause a rerender to happen for exit animation\n this.visibleToasts = this.visibleToasts.map(t => {\n if (t.key !== key) {\n return t;\n } else {\n return {...t, animation: 'exiting'};\n }\n });\n } else {\n this.visibleToasts = toasts;\n }\n\n for (let fn of this.subscriptions) {\n fn();\n }\n }\n\n /** Pauses the timers for all visible toasts. */\n pauseAll() {\n for (let toast of this.visibleToasts) {\n if (toast.timer) {\n toast.timer.pause();\n }\n }\n }\n\n /** Resumes the timers for all visible toasts. */\n resumeAll() {\n for (let toast of this.visibleToasts) {\n if (toast.timer) {\n toast.timer.resume();\n }\n }\n }\n}\n\nclass Timer {\n private timerId;\n private startTime: number;\n private remaining: number;\n private callback: () => void;\n\n constructor(callback: () => void, delay: number) {\n this.remaining = delay;\n this.callback = callback;\n }\n\n reset(delay: number) {\n this.remaining = delay;\n this.resume();\n }\n\n pause() {\n if (this.timerId == null) {\n return;\n }\n\n clearTimeout(this.timerId);\n this.timerId = null;\n this.remaining -= Date.now() - this.startTime;\n }\n\n resume() {\n if (this.remaining <= 0) {\n return;\n }\n\n this.startTime = Date.now();\n this.timerId = setTimeout(() => {\n this.timerId = null;\n this.remaining = 0;\n this.callback();\n }, this.remaining);\n }\n}\n"],"names":[],"version":3,"file":"useToastState.module.js.map"}
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-stately/toast/src/useToastState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {useCallback, useMemo} from 'react';\n// Shim to support React 17 and below.\nimport {useSyncExternalStore} from 'use-sync-external-store/shim/index.js';\n\nexport interface ToastStateProps {\n /** The maximum number of toasts to display at a time. */\n maxVisibleToasts?: number,\n /** Function to wrap updates in (i.e. document.startViewTransition()). */\n wrapUpdate?: (fn: () => void) => void\n}\n\nexport interface ToastOptions {\n /** Handler that is called when the toast is closed, either by the user or after a timeout. */\n onClose?: () => void,\n /** A timeout to automatically close the toast after, in milliseconds. */\n timeout?: number\n}\n\nexport interface QueuedToast<T> extends ToastOptions {\n /** The content of the toast. */\n content: T,\n /** A unique key for the toast. */\n key: string,\n /** A timer for the toast, if a timeout was set. */\n timer?: Timer\n}\n\nexport interface ToastState<T> {\n /** Adds a new toast to the queue. */\n add(content: T, options?: ToastOptions): string,\n /**\n * Closes a toast.\n */\n close(key: string): void,\n /** Pauses the timers for all visible toasts. */\n pauseAll(): void,\n /** Resumes the timers for all visible toasts. */\n resumeAll(): void,\n /** The visible toasts. */\n visibleToasts: QueuedToast<T>[]\n}\n\n/**\n * Provides state management for a toast queue. Toasts display brief, temporary notifications\n * of actions, errors, or other events in an application.\n */\nexport function useToastState<T>(props: ToastStateProps = {}): ToastState<T> {\n let {maxVisibleToasts = 1} = props;\n let queue = useMemo(() => new ToastQueue<T>({maxVisibleToasts}), [maxVisibleToasts]);\n return useToastQueue(queue);\n}\n\n/**\n * Subscribes to a provided toast queue and provides methods to update it.\n */\nexport function useToastQueue<T>(queue: ToastQueue<T>): ToastState<T> {\n let subscribe = useCallback(fn => queue.subscribe(fn), [queue]);\n let getSnapshot = useCallback(() => queue.visibleToasts, [queue]);\n let visibleToasts = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return {\n visibleToasts,\n add: (content, options) => queue.add(content, options),\n close: key => queue.close(key),\n pauseAll: () => queue.pauseAll(),\n resumeAll: () => queue.resumeAll()\n };\n}\n\n/**\n * A ToastQueue manages the order of toasts.\n */\nexport class ToastQueue<T> {\n private queue: QueuedToast<T>[] = [];\n private subscriptions: Set<() => void> = new Set();\n private maxVisibleToasts: number;\n private wrapUpdate?: (fn: () => void) => void;\n /** The currently visible toasts. */\n visibleToasts: QueuedToast<T>[] = [];\n\n constructor(options?: ToastStateProps) {\n this.maxVisibleToasts = options?.maxVisibleToasts ?? Infinity;\n this.wrapUpdate = options?.wrapUpdate;\n }\n\n private runWithWrapUpdate(fn: () => void): void {\n if (this.wrapUpdate) {\n this.wrapUpdate(fn);\n } else {\n fn();\n }\n }\n\n /** Subscribes to updates to the visible toasts. */\n subscribe(fn: () => void) {\n this.subscriptions.add(fn);\n return () => this.subscriptions.delete(fn);\n }\n\n /** Adds a new toast to the queue. */\n add(content: T, options: ToastOptions = {}) {\n let toastKey = '_' + Math.random().toString(36).slice(2);\n let toast: QueuedToast<T> = {\n ...options,\n content,\n key: toastKey,\n timer: options.timeout ? new Timer(() => this.close(toastKey), options.timeout) : undefined\n };\n\n this.queue.unshift(toast);\n\n this.updateVisibleToasts();\n return toastKey;\n }\n\n /**\n * Closes a toast.\n */\n close(key: string) {\n let index = this.queue.findIndex(t => t.key === key);\n if (index >= 0) {\n this.queue[index].onClose?.();\n this.queue.splice(index, 1);\n }\n\n this.updateVisibleToasts();\n }\n\n private updateVisibleToasts() {\n this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts);\n\n for (let fn of this.subscriptions) {\n this.runWithWrapUpdate(fn);\n }\n }\n\n /** Pauses the timers for all visible toasts. */\n pauseAll() {\n for (let toast of this.visibleToasts) {\n if (toast.timer) {\n toast.timer.pause();\n }\n }\n }\n\n /** Resumes the timers for all visible toasts. */\n resumeAll() {\n for (let toast of this.visibleToasts) {\n if (toast.timer) {\n toast.timer.resume();\n }\n }\n }\n}\n\nclass Timer {\n private timerId;\n private startTime: number | null = null;\n private remaining: number;\n private callback: () => void;\n\n constructor(callback: () => void, delay: number) {\n this.remaining = delay;\n this.callback = callback;\n }\n\n reset(delay: number) {\n this.remaining = delay;\n this.resume();\n }\n\n pause() {\n if (this.timerId == null) {\n return;\n }\n\n clearTimeout(this.timerId);\n this.timerId = null;\n this.remaining -= Date.now() - this.startTime!;\n }\n\n resume() {\n if (this.remaining <= 0) {\n return;\n }\n\n this.startTime = Date.now();\n this.timerId = setTimeout(() => {\n this.timerId = null;\n this.remaining = 0;\n this.callback();\n }, this.remaining);\n }\n}\n"],"names":[],"version":3,"file":"useToastState.module.js.map"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-stately/toast",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Spectrum UI components in React",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -23,16 +23,16 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@swc/helpers": "^0.5.0",
|
|
26
|
-
"use-sync-external-store": "^1.
|
|
26
|
+
"use-sync-external-store": "^1.4.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/use-sync-external-store": "^0.0.3"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
|
|
32
|
+
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
|
33
33
|
},
|
|
34
34
|
"publishConfig": {
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "4d3c72c94eea2d72eb3a0e7d56000c6ef7e39726"
|
|
38
38
|
}
|
package/src/useToastState.ts
CHANGED
|
@@ -17,21 +17,15 @@ import {useSyncExternalStore} from 'use-sync-external-store/shim/index.js';
|
|
|
17
17
|
export interface ToastStateProps {
|
|
18
18
|
/** The maximum number of toasts to display at a time. */
|
|
19
19
|
maxVisibleToasts?: number,
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
* removed immediately but transition into an "exiting" state instead.
|
|
23
|
-
* Once the animation is complete, call the `remove` function.
|
|
24
|
-
*/
|
|
25
|
-
hasExitAnimation?: boolean
|
|
20
|
+
/** Function to wrap updates in (i.e. document.startViewTransition()). */
|
|
21
|
+
wrapUpdate?: (fn: () => void) => void
|
|
26
22
|
}
|
|
27
23
|
|
|
28
24
|
export interface ToastOptions {
|
|
29
25
|
/** Handler that is called when the toast is closed, either by the user or after a timeout. */
|
|
30
26
|
onClose?: () => void,
|
|
31
27
|
/** A timeout to automatically close the toast after, in milliseconds. */
|
|
32
|
-
timeout?: number
|
|
33
|
-
/** The priority of the toast relative to other toasts. Larger numbers indicate higher priority. */
|
|
34
|
-
priority?: number
|
|
28
|
+
timeout?: number
|
|
35
29
|
}
|
|
36
30
|
|
|
37
31
|
export interface QueuedToast<T> extends ToastOptions {
|
|
@@ -40,21 +34,16 @@ export interface QueuedToast<T> extends ToastOptions {
|
|
|
40
34
|
/** A unique key for the toast. */
|
|
41
35
|
key: string,
|
|
42
36
|
/** A timer for the toast, if a timeout was set. */
|
|
43
|
-
timer?: Timer
|
|
44
|
-
/** The current animation state for the toast. */
|
|
45
|
-
animation?: 'entering' | 'queued' | 'exiting'
|
|
37
|
+
timer?: Timer
|
|
46
38
|
}
|
|
47
39
|
|
|
48
40
|
export interface ToastState<T> {
|
|
49
41
|
/** Adds a new toast to the queue. */
|
|
50
42
|
add(content: T, options?: ToastOptions): string,
|
|
51
43
|
/**
|
|
52
|
-
* Closes a toast.
|
|
53
|
-
* transitions to an "exiting" state instead of being removed immediately.
|
|
44
|
+
* Closes a toast.
|
|
54
45
|
*/
|
|
55
46
|
close(key: string): void,
|
|
56
|
-
/** Removes a toast from the visible toasts after an exiting animation. */
|
|
57
|
-
remove(key: string): void,
|
|
58
47
|
/** Pauses the timers for all visible toasts. */
|
|
59
48
|
pauseAll(): void,
|
|
60
49
|
/** Resumes the timers for all visible toasts. */
|
|
@@ -68,8 +57,8 @@ export interface ToastState<T> {
|
|
|
68
57
|
* of actions, errors, or other events in an application.
|
|
69
58
|
*/
|
|
70
59
|
export function useToastState<T>(props: ToastStateProps = {}): ToastState<T> {
|
|
71
|
-
let {maxVisibleToasts = 1
|
|
72
|
-
let queue = useMemo(() => new ToastQueue<T>({maxVisibleToasts
|
|
60
|
+
let {maxVisibleToasts = 1} = props;
|
|
61
|
+
let queue = useMemo(() => new ToastQueue<T>({maxVisibleToasts}), [maxVisibleToasts]);
|
|
73
62
|
return useToastQueue(queue);
|
|
74
63
|
}
|
|
75
64
|
|
|
@@ -85,26 +74,33 @@ export function useToastQueue<T>(queue: ToastQueue<T>): ToastState<T> {
|
|
|
85
74
|
visibleToasts,
|
|
86
75
|
add: (content, options) => queue.add(content, options),
|
|
87
76
|
close: key => queue.close(key),
|
|
88
|
-
remove: key => queue.remove(key),
|
|
89
77
|
pauseAll: () => queue.pauseAll(),
|
|
90
78
|
resumeAll: () => queue.resumeAll()
|
|
91
79
|
};
|
|
92
80
|
}
|
|
93
81
|
|
|
94
82
|
/**
|
|
95
|
-
* A ToastQueue
|
|
83
|
+
* A ToastQueue manages the order of toasts.
|
|
96
84
|
*/
|
|
97
85
|
export class ToastQueue<T> {
|
|
98
86
|
private queue: QueuedToast<T>[] = [];
|
|
99
87
|
private subscriptions: Set<() => void> = new Set();
|
|
100
88
|
private maxVisibleToasts: number;
|
|
101
|
-
private
|
|
89
|
+
private wrapUpdate?: (fn: () => void) => void;
|
|
102
90
|
/** The currently visible toasts. */
|
|
103
91
|
visibleToasts: QueuedToast<T>[] = [];
|
|
104
92
|
|
|
105
93
|
constructor(options?: ToastStateProps) {
|
|
106
|
-
this.maxVisibleToasts = options?.maxVisibleToasts ??
|
|
107
|
-
this.
|
|
94
|
+
this.maxVisibleToasts = options?.maxVisibleToasts ?? Infinity;
|
|
95
|
+
this.wrapUpdate = options?.wrapUpdate;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private runWithWrapUpdate(fn: () => void): void {
|
|
99
|
+
if (this.wrapUpdate) {
|
|
100
|
+
this.wrapUpdate(fn);
|
|
101
|
+
} else {
|
|
102
|
+
fn();
|
|
103
|
+
}
|
|
108
104
|
}
|
|
109
105
|
|
|
110
106
|
/** Subscribes to updates to the visible toasts. */
|
|
@@ -115,40 +111,22 @@ export class ToastQueue<T> {
|
|
|
115
111
|
|
|
116
112
|
/** Adds a new toast to the queue. */
|
|
117
113
|
add(content: T, options: ToastOptions = {}) {
|
|
118
|
-
let toastKey = Math.random().toString(36);
|
|
114
|
+
let toastKey = '_' + Math.random().toString(36).slice(2);
|
|
119
115
|
let toast: QueuedToast<T> = {
|
|
120
116
|
...options,
|
|
121
117
|
content,
|
|
122
118
|
key: toastKey,
|
|
123
|
-
timer: options.timeout ? new Timer(() => this.close(toastKey), options.timeout) :
|
|
119
|
+
timer: options.timeout ? new Timer(() => this.close(toastKey), options.timeout) : undefined
|
|
124
120
|
};
|
|
125
121
|
|
|
126
|
-
|
|
127
|
-
let high = this.queue.length;
|
|
128
|
-
while (low < high) {
|
|
129
|
-
let mid = Math.floor((low + high) / 2);
|
|
130
|
-
if ((toast.priority || 0) > (this.queue[mid].priority || 0)) {
|
|
131
|
-
high = mid;
|
|
132
|
-
} else {
|
|
133
|
-
low = mid + 1;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
122
|
+
this.queue.unshift(toast);
|
|
136
123
|
|
|
137
|
-
this.
|
|
138
|
-
|
|
139
|
-
toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued';
|
|
140
|
-
let i = this.maxVisibleToasts;
|
|
141
|
-
while (i < this.queue.length) {
|
|
142
|
-
this.queue[i++].animation = 'queued';
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
this.updateVisibleToasts({action: 'add'});
|
|
124
|
+
this.updateVisibleToasts();
|
|
146
125
|
return toastKey;
|
|
147
126
|
}
|
|
148
127
|
|
|
149
128
|
/**
|
|
150
|
-
* Closes a toast.
|
|
151
|
-
* transitions to an "exiting" state instead of being removed immediately.
|
|
129
|
+
* Closes a toast.
|
|
152
130
|
*/
|
|
153
131
|
close(key: string) {
|
|
154
132
|
let index = this.queue.findIndex(t => t.key === key);
|
|
@@ -157,38 +135,14 @@ export class ToastQueue<T> {
|
|
|
157
135
|
this.queue.splice(index, 1);
|
|
158
136
|
}
|
|
159
137
|
|
|
160
|
-
this.updateVisibleToasts(
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** Removes a toast from the visible toasts after an exiting animation. */
|
|
164
|
-
remove(key: string) {
|
|
165
|
-
this.updateVisibleToasts({action: 'remove', key});
|
|
138
|
+
this.updateVisibleToasts();
|
|
166
139
|
}
|
|
167
140
|
|
|
168
|
-
private updateVisibleToasts(
|
|
169
|
-
|
|
170
|
-
let toasts = this.queue.slice(0, this.maxVisibleToasts);
|
|
171
|
-
|
|
172
|
-
if (action === 'add' && this.hasExitAnimation) {
|
|
173
|
-
let prevToasts: QueuedToast<T>[] = this.visibleToasts
|
|
174
|
-
.filter(t => !toasts.some(t2 => t.key === t2.key))
|
|
175
|
-
.map(t => ({...t, animation: 'exiting'}));
|
|
176
|
-
this.visibleToasts = prevToasts.concat(toasts).sort((a, b) => b.priority - a.priority);
|
|
177
|
-
} else if (action === 'close' && this.hasExitAnimation) {
|
|
178
|
-
// Cause a rerender to happen for exit animation
|
|
179
|
-
this.visibleToasts = this.visibleToasts.map(t => {
|
|
180
|
-
if (t.key !== key) {
|
|
181
|
-
return t;
|
|
182
|
-
} else {
|
|
183
|
-
return {...t, animation: 'exiting'};
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
} else {
|
|
187
|
-
this.visibleToasts = toasts;
|
|
188
|
-
}
|
|
141
|
+
private updateVisibleToasts() {
|
|
142
|
+
this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts);
|
|
189
143
|
|
|
190
144
|
for (let fn of this.subscriptions) {
|
|
191
|
-
fn
|
|
145
|
+
this.runWithWrapUpdate(fn);
|
|
192
146
|
}
|
|
193
147
|
}
|
|
194
148
|
|
|
@@ -213,7 +167,7 @@ export class ToastQueue<T> {
|
|
|
213
167
|
|
|
214
168
|
class Timer {
|
|
215
169
|
private timerId;
|
|
216
|
-
private startTime: number;
|
|
170
|
+
private startTime: number | null = null;
|
|
217
171
|
private remaining: number;
|
|
218
172
|
private callback: () => void;
|
|
219
173
|
|
|
@@ -234,7 +188,7 @@ class Timer {
|
|
|
234
188
|
|
|
235
189
|
clearTimeout(this.timerId);
|
|
236
190
|
this.timerId = null;
|
|
237
|
-
this.remaining -= Date.now() - this.startTime
|
|
191
|
+
this.remaining -= Date.now() - this.startTime!;
|
|
238
192
|
}
|
|
239
193
|
|
|
240
194
|
resume() {
|