@react-stately/toast
Advanced tools
Comparing version 3.0.0-nightly-993de98ad-241210 to 3.0.0-nightly-9b3385ac6-250228
export interface ToastStateProps { | ||
/** The maximum number of toasts to display at a time. */ | ||
maxVisibleToasts?: number; | ||
/** | ||
* Whether toasts have an exit animation. If true, toasts are not | ||
* removed immediately but transition into an "exiting" state instead. | ||
* Once the animation is complete, call the `remove` function. | ||
*/ | ||
hasExitAnimation?: boolean; | ||
/** Function to wrap updates in (i.e. document.startViewTransition()). */ | ||
wrapUpdate?: (fn: () => void) => void; | ||
} | ||
@@ -16,4 +12,2 @@ export interface ToastOptions { | ||
timeout?: number; | ||
/** The priority of the toast relative to other toasts. Larger numbers indicate higher priority. */ | ||
priority?: number; | ||
} | ||
@@ -27,4 +21,2 @@ export interface QueuedToast<T> extends ToastOptions { | ||
timer?: Timer; | ||
/** The current animation state for the toast. */ | ||
animation?: 'entering' | 'queued' | 'exiting' | null; | ||
} | ||
@@ -35,8 +27,5 @@ export interface ToastState<T> { | ||
/** | ||
* Closes a toast. If `hasExitAnimation` is true, the toast | ||
* transitions to an "exiting" state instead of being removed immediately. | ||
* Closes a toast. | ||
*/ | ||
close(key: string): void; | ||
/** Removes a toast from the visible toasts after an exiting animation. */ | ||
remove(key: string): void; | ||
/** Pauses the timers for all visible toasts. */ | ||
@@ -59,3 +48,3 @@ pauseAll(): void; | ||
/** | ||
* A ToastQueue is a priority queue of toasts. | ||
* A ToastQueue manages the order of toasts. | ||
*/ | ||
@@ -71,8 +60,5 @@ export class ToastQueue<T> { | ||
/** | ||
* Closes a toast. If `hasExitAnimation` is true, the toast | ||
* transitions to an "exiting" state instead of being removed immediately. | ||
* Closes a toast. | ||
*/ | ||
close(key: string): void; | ||
/** Removes a toast from the visible toasts after an exiting animation. */ | ||
remove(key: string): void; | ||
/** Pauses the timers for all visible toasts. */ | ||
@@ -79,0 +65,0 @@ pauseAll(): void; |
@@ -25,9 +25,7 @@ var $pwpJQ$react = require("react"); | ||
function $c995945a643dde76$export$c7b26b20d3ced9c5(props = {}) { | ||
let { maxVisibleToasts: maxVisibleToasts = 1, hasExitAnimation: hasExitAnimation = false } = props; | ||
let { maxVisibleToasts: maxVisibleToasts = 1 } = props; | ||
let queue = (0, $pwpJQ$react.useMemo)(()=>new $c995945a643dde76$export$f1f8569633bbbec4({ | ||
maxVisibleToasts: maxVisibleToasts, | ||
hasExitAnimation: hasExitAnimation | ||
maxVisibleToasts: maxVisibleToasts | ||
}), [ | ||
maxVisibleToasts, | ||
hasExitAnimation | ||
maxVisibleToasts | ||
]); | ||
@@ -48,3 +46,2 @@ return $c995945a643dde76$export$84726ef35ca2129a(queue); | ||
close: (key)=>queue.close(key), | ||
remove: (key)=>queue.remove(key), | ||
pauseAll: ()=>queue.pauseAll(), | ||
@@ -55,2 +52,6 @@ resumeAll: ()=>queue.resumeAll() | ||
class $c995945a643dde76$export$f1f8569633bbbec4 { | ||
runWithWrapUpdate(fn) { | ||
if (this.wrapUpdate) this.wrapUpdate(fn); | ||
else fn(); | ||
} | ||
/** Subscribes to updates to the visible toasts. */ subscribe(fn) { | ||
@@ -61,3 +62,3 @@ this.subscriptions.add(fn); | ||
/** Adds a new toast to the queue. */ add(content, options = {}) { | ||
let toastKey = Math.random().toString(36); | ||
let toastKey = '_' + Math.random().toString(36).slice(2); | ||
let toast = { | ||
@@ -69,21 +70,8 @@ ...options, | ||
}; | ||
let low = 0; | ||
let high = this.queue.length; | ||
while(low < high){ | ||
let mid = Math.floor((low + high) / 2); | ||
if ((toast.priority || 0) > (this.queue[mid].priority || 0)) high = mid; | ||
else low = mid + 1; | ||
} | ||
this.queue.splice(low, 0, toast); | ||
toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued'; | ||
let i = this.maxVisibleToasts; | ||
while(i < this.queue.length)this.queue[i++].animation = 'queued'; | ||
this.updateVisibleToasts({ | ||
action: 'add' | ||
}); | ||
this.queue.unshift(toast); | ||
this.updateVisibleToasts(); | ||
return toastKey; | ||
} | ||
/** | ||
* Closes a toast. If `hasExitAnimation` is true, the toast | ||
* transitions to an "exiting" state instead of being removed immediately. | ||
* Closes a toast. | ||
*/ close(key) { | ||
@@ -96,36 +84,8 @@ let index = this.queue.findIndex((t)=>t.key === key); | ||
} | ||
this.updateVisibleToasts({ | ||
action: 'close', | ||
key: key | ||
}); | ||
this.updateVisibleToasts(); | ||
} | ||
/** Removes a toast from the visible toasts after an exiting animation. */ remove(key) { | ||
this.updateVisibleToasts({ | ||
action: 'remove', | ||
key: key | ||
}); | ||
updateVisibleToasts() { | ||
this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts); | ||
for (let fn of this.subscriptions)this.runWithWrapUpdate(fn); | ||
} | ||
updateVisibleToasts(options) { | ||
let { action: action, key: key } = options; | ||
let toasts = this.queue.slice(0, this.maxVisibleToasts); | ||
if (action === 'add' && this.hasExitAnimation) { | ||
let prevToasts = this.visibleToasts.filter((t)=>!toasts.some((t2)=>t.key === t2.key)).map((t)=>({ | ||
...t, | ||
animation: 'exiting' | ||
})); | ||
this.visibleToasts = prevToasts.concat(toasts).sort((a, b)=>{ | ||
var _b_priority, _a_priority; | ||
return ((_b_priority = b.priority) !== null && _b_priority !== void 0 ? _b_priority : 0) - ((_a_priority = a.priority) !== null && _a_priority !== void 0 ? _a_priority : 0); | ||
}); | ||
} else if (action === 'close' && this.hasExitAnimation) // Cause a rerender to happen for exit animation | ||
this.visibleToasts = this.visibleToasts.map((t)=>{ | ||
if (t.key !== key) return t; | ||
else return { | ||
...t, | ||
animation: 'exiting' | ||
}; | ||
}); | ||
else this.visibleToasts = toasts; | ||
for (let fn of this.subscriptions)fn(); | ||
} | ||
/** Pauses the timers for all visible toasts. */ pauseAll() { | ||
@@ -142,5 +102,4 @@ for (let toast of this.visibleToasts)if (toast.timer) toast.timer.pause(); | ||
var _options_maxVisibleToasts; | ||
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts : 1; | ||
var _options_hasExitAnimation; | ||
this.hasExitAnimation = (_options_hasExitAnimation = options === null || options === void 0 ? void 0 : options.hasExitAnimation) !== null && _options_hasExitAnimation !== void 0 ? _options_hasExitAnimation : false; | ||
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts : Infinity; | ||
this.wrapUpdate = options === null || options === void 0 ? void 0 : options.wrapUpdate; | ||
} | ||
@@ -147,0 +106,0 @@ } |
@@ -17,9 +17,7 @@ import {useMemo as $cNx9A$useMemo, useCallback as $cNx9A$useCallback} from "react"; | ||
function $77b352cf12efcf73$export$c7b26b20d3ced9c5(props = {}) { | ||
let { maxVisibleToasts: maxVisibleToasts = 1, hasExitAnimation: hasExitAnimation = false } = props; | ||
let { maxVisibleToasts: maxVisibleToasts = 1 } = props; | ||
let queue = (0, $cNx9A$useMemo)(()=>new $77b352cf12efcf73$export$f1f8569633bbbec4({ | ||
maxVisibleToasts: maxVisibleToasts, | ||
hasExitAnimation: hasExitAnimation | ||
maxVisibleToasts: maxVisibleToasts | ||
}), [ | ||
maxVisibleToasts, | ||
hasExitAnimation | ||
maxVisibleToasts | ||
]); | ||
@@ -40,3 +38,2 @@ return $77b352cf12efcf73$export$84726ef35ca2129a(queue); | ||
close: (key)=>queue.close(key), | ||
remove: (key)=>queue.remove(key), | ||
pauseAll: ()=>queue.pauseAll(), | ||
@@ -47,2 +44,6 @@ resumeAll: ()=>queue.resumeAll() | ||
class $77b352cf12efcf73$export$f1f8569633bbbec4 { | ||
runWithWrapUpdate(fn) { | ||
if (this.wrapUpdate) this.wrapUpdate(fn); | ||
else fn(); | ||
} | ||
/** Subscribes to updates to the visible toasts. */ subscribe(fn) { | ||
@@ -53,3 +54,3 @@ this.subscriptions.add(fn); | ||
/** Adds a new toast to the queue. */ add(content, options = {}) { | ||
let toastKey = Math.random().toString(36); | ||
let toastKey = '_' + Math.random().toString(36).slice(2); | ||
let toast = { | ||
@@ -61,21 +62,8 @@ ...options, | ||
}; | ||
let low = 0; | ||
let high = this.queue.length; | ||
while(low < high){ | ||
let mid = Math.floor((low + high) / 2); | ||
if ((toast.priority || 0) > (this.queue[mid].priority || 0)) high = mid; | ||
else low = mid + 1; | ||
} | ||
this.queue.splice(low, 0, toast); | ||
toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued'; | ||
let i = this.maxVisibleToasts; | ||
while(i < this.queue.length)this.queue[i++].animation = 'queued'; | ||
this.updateVisibleToasts({ | ||
action: 'add' | ||
}); | ||
this.queue.unshift(toast); | ||
this.updateVisibleToasts(); | ||
return toastKey; | ||
} | ||
/** | ||
* Closes a toast. If `hasExitAnimation` is true, the toast | ||
* transitions to an "exiting" state instead of being removed immediately. | ||
* Closes a toast. | ||
*/ close(key) { | ||
@@ -88,36 +76,8 @@ let index = this.queue.findIndex((t)=>t.key === key); | ||
} | ||
this.updateVisibleToasts({ | ||
action: 'close', | ||
key: key | ||
}); | ||
this.updateVisibleToasts(); | ||
} | ||
/** Removes a toast from the visible toasts after an exiting animation. */ remove(key) { | ||
this.updateVisibleToasts({ | ||
action: 'remove', | ||
key: key | ||
}); | ||
updateVisibleToasts() { | ||
this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts); | ||
for (let fn of this.subscriptions)this.runWithWrapUpdate(fn); | ||
} | ||
updateVisibleToasts(options) { | ||
let { action: action, key: key } = options; | ||
let toasts = this.queue.slice(0, this.maxVisibleToasts); | ||
if (action === 'add' && this.hasExitAnimation) { | ||
let prevToasts = this.visibleToasts.filter((t)=>!toasts.some((t2)=>t.key === t2.key)).map((t)=>({ | ||
...t, | ||
animation: 'exiting' | ||
})); | ||
this.visibleToasts = prevToasts.concat(toasts).sort((a, b)=>{ | ||
var _b_priority, _a_priority; | ||
return ((_b_priority = b.priority) !== null && _b_priority !== void 0 ? _b_priority : 0) - ((_a_priority = a.priority) !== null && _a_priority !== void 0 ? _a_priority : 0); | ||
}); | ||
} else if (action === 'close' && this.hasExitAnimation) // Cause a rerender to happen for exit animation | ||
this.visibleToasts = this.visibleToasts.map((t)=>{ | ||
if (t.key !== key) return t; | ||
else return { | ||
...t, | ||
animation: 'exiting' | ||
}; | ||
}); | ||
else this.visibleToasts = toasts; | ||
for (let fn of this.subscriptions)fn(); | ||
} | ||
/** Pauses the timers for all visible toasts. */ pauseAll() { | ||
@@ -134,5 +94,4 @@ for (let toast of this.visibleToasts)if (toast.timer) toast.timer.pause(); | ||
var _options_maxVisibleToasts; | ||
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts : 1; | ||
var _options_hasExitAnimation; | ||
this.hasExitAnimation = (_options_hasExitAnimation = options === null || options === void 0 ? void 0 : options.hasExitAnimation) !== null && _options_hasExitAnimation !== void 0 ? _options_hasExitAnimation : false; | ||
this.maxVisibleToasts = (_options_maxVisibleToasts = options === null || options === void 0 ? void 0 : options.maxVisibleToasts) !== null && _options_maxVisibleToasts !== void 0 ? _options_maxVisibleToasts : Infinity; | ||
this.wrapUpdate = options === null || options === void 0 ? void 0 : options.wrapUpdate; | ||
} | ||
@@ -139,0 +98,0 @@ } |
{ | ||
"name": "@react-stately/toast", | ||
"version": "3.0.0-nightly-993de98ad-241210", | ||
"version": "3.0.0-nightly-9b3385ac6-250228", | ||
"description": "Spectrum UI components in React", | ||
@@ -26,3 +26,3 @@ "license": "Apache-2.0", | ||
"@swc/helpers": "^0.5.0", | ||
"use-sync-external-store": "^1.2.0" | ||
"use-sync-external-store": "^1.4.0" | ||
}, | ||
@@ -37,4 +37,3 @@ "devDependencies": { | ||
"access": "public" | ||
}, | ||
"stableVersion": "3.0.0-beta.7" | ||
} | ||
} |
@@ -20,8 +20,4 @@ /* | ||
maxVisibleToasts?: number, | ||
/** | ||
* Whether toasts have an exit animation. If true, toasts are not | ||
* removed immediately but transition into an "exiting" state instead. | ||
* Once the animation is complete, call the `remove` function. | ||
*/ | ||
hasExitAnimation?: boolean | ||
/** Function to wrap updates in (i.e. document.startViewTransition()). */ | ||
wrapUpdate?: (fn: () => void) => void | ||
} | ||
@@ -33,5 +29,3 @@ | ||
/** A timeout to automatically close the toast after, in milliseconds. */ | ||
timeout?: number, | ||
/** The priority of the toast relative to other toasts. Larger numbers indicate higher priority. */ | ||
priority?: number | ||
timeout?: number | ||
} | ||
@@ -45,5 +39,3 @@ | ||
/** A timer for the toast, if a timeout was set. */ | ||
timer?: Timer, | ||
/** The current animation state for the toast. */ | ||
animation?: 'entering' | 'queued' | 'exiting' | null | ||
timer?: Timer | ||
} | ||
@@ -55,8 +47,5 @@ | ||
/** | ||
* Closes a toast. If `hasExitAnimation` is true, the toast | ||
* transitions to an "exiting" state instead of being removed immediately. | ||
* Closes a toast. | ||
*/ | ||
close(key: string): void, | ||
/** Removes a toast from the visible toasts after an exiting animation. */ | ||
remove(key: string): void, | ||
/** Pauses the timers for all visible toasts. */ | ||
@@ -75,4 +64,4 @@ pauseAll(): void, | ||
export function useToastState<T>(props: ToastStateProps = {}): ToastState<T> { | ||
let {maxVisibleToasts = 1, hasExitAnimation = false} = props; | ||
let queue = useMemo(() => new ToastQueue<T>({maxVisibleToasts, hasExitAnimation}), [maxVisibleToasts, hasExitAnimation]); | ||
let {maxVisibleToasts = 1} = props; | ||
let queue = useMemo(() => new ToastQueue<T>({maxVisibleToasts}), [maxVisibleToasts]); | ||
return useToastQueue(queue); | ||
@@ -93,3 +82,2 @@ } | ||
close: key => queue.close(key), | ||
remove: key => queue.remove(key), | ||
pauseAll: () => queue.pauseAll(), | ||
@@ -101,3 +89,3 @@ resumeAll: () => queue.resumeAll() | ||
/** | ||
* A ToastQueue is a priority queue of toasts. | ||
* A ToastQueue manages the order of toasts. | ||
*/ | ||
@@ -108,3 +96,3 @@ export class ToastQueue<T> { | ||
private maxVisibleToasts: number; | ||
private hasExitAnimation: boolean; | ||
private wrapUpdate?: (fn: () => void) => void; | ||
/** The currently visible toasts. */ | ||
@@ -114,6 +102,14 @@ visibleToasts: QueuedToast<T>[] = []; | ||
constructor(options?: ToastStateProps) { | ||
this.maxVisibleToasts = options?.maxVisibleToasts ?? 1; | ||
this.hasExitAnimation = options?.hasExitAnimation ?? false; | ||
this.maxVisibleToasts = options?.maxVisibleToasts ?? Infinity; | ||
this.wrapUpdate = options?.wrapUpdate; | ||
} | ||
private runWithWrapUpdate(fn: () => void): void { | ||
if (this.wrapUpdate) { | ||
this.wrapUpdate(fn); | ||
} else { | ||
fn(); | ||
} | ||
} | ||
/** Subscribes to updates to the visible toasts. */ | ||
@@ -127,3 +123,3 @@ subscribe(fn: () => void) { | ||
add(content: T, options: ToastOptions = {}) { | ||
let toastKey = Math.random().toString(36); | ||
let toastKey = '_' + Math.random().toString(36).slice(2); | ||
let toast: QueuedToast<T> = { | ||
@@ -136,22 +132,5 @@ ...options, | ||
let low = 0; | ||
let high = this.queue.length; | ||
while (low < high) { | ||
let mid = Math.floor((low + high) / 2); | ||
if ((toast.priority || 0) > (this.queue[mid].priority || 0)) { | ||
high = mid; | ||
} else { | ||
low = mid + 1; | ||
} | ||
} | ||
this.queue.unshift(toast); | ||
this.queue.splice(low, 0, toast); | ||
toast.animation = low < this.maxVisibleToasts ? 'entering' : 'queued'; | ||
let i = this.maxVisibleToasts; | ||
while (i < this.queue.length) { | ||
this.queue[i++].animation = 'queued'; | ||
} | ||
this.updateVisibleToasts({action: 'add'}); | ||
this.updateVisibleToasts(); | ||
return toastKey; | ||
@@ -161,4 +140,3 @@ } | ||
/** | ||
* Closes a toast. If `hasExitAnimation` is true, the toast | ||
* transitions to an "exiting" state instead of being removed immediately. | ||
* Closes a toast. | ||
*/ | ||
@@ -172,34 +150,10 @@ close(key: string) { | ||
this.updateVisibleToasts({action: 'close', key}); | ||
this.updateVisibleToasts(); | ||
} | ||
/** Removes a toast from the visible toasts after an exiting animation. */ | ||
remove(key: string) { | ||
this.updateVisibleToasts({action: 'remove', key}); | ||
} | ||
private updateVisibleToasts() { | ||
this.visibleToasts = this.queue.slice(0, this.maxVisibleToasts); | ||
private updateVisibleToasts(options: {action: 'add' | 'close' | 'remove', key?: string}) { | ||
let {action, key} = options; | ||
let toasts = this.queue.slice(0, this.maxVisibleToasts); | ||
if (action === 'add' && this.hasExitAnimation) { | ||
let prevToasts: QueuedToast<T>[] = this.visibleToasts | ||
.filter(t => !toasts.some(t2 => t.key === t2.key)) | ||
.map(t => ({...t, animation: 'exiting'})); | ||
this.visibleToasts = prevToasts.concat(toasts).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0)); | ||
} else if (action === 'close' && this.hasExitAnimation) { | ||
// Cause a rerender to happen for exit animation | ||
this.visibleToasts = this.visibleToasts.map(t => { | ||
if (t.key !== key) { | ||
return t; | ||
} else { | ||
return {...t, animation: 'exiting'}; | ||
} | ||
}); | ||
} else { | ||
this.visibleToasts = toasts; | ||
} | ||
for (let fn of this.subscriptions) { | ||
fn(); | ||
this.runWithWrapUpdate(fn); | ||
} | ||
@@ -206,0 +160,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
49989
664