react-toastify-v2 11.0.5
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/LICENSE +21 -0
- package/README.md +115 -0
- package/addons/use-notification-center/index.d.mts +395 -0
- package/addons/use-notification-center/index.d.ts +395 -0
- package/addons/use-notification-center/index.js +3 -0
- package/addons/use-notification-center/index.js.map +1 -0
- package/addons/use-notification-center/index.mjs +3 -0
- package/addons/use-notification-center/index.mjs.map +1 -0
- package/dist/ReactToastify.css +800 -0
- package/dist/index.d.mts +431 -0
- package/dist/index.d.ts +431 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4 -0
- package/dist/index.mjs.map +1 -0
- package/dist/unstyled.d.mts +431 -0
- package/dist/unstyled.d.ts +431 -0
- package/dist/unstyled.js +3 -0
- package/dist/unstyled.js.map +1 -0
- package/dist/unstyled.mjs +3 -0
- package/dist/unstyled.mjs.map +1 -0
- package/package.json +108 -0
@@ -0,0 +1,395 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
interface CloseButtonProps {
|
4
|
+
closeToast: CloseToastFunc;
|
5
|
+
type: TypeOptions;
|
6
|
+
ariaLabel?: string;
|
7
|
+
theme: Theme;
|
8
|
+
}
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Used when providing custom icon
|
12
|
+
*/
|
13
|
+
interface IconProps {
|
14
|
+
theme: Theme;
|
15
|
+
type: TypeOptions;
|
16
|
+
isLoading?: boolean;
|
17
|
+
}
|
18
|
+
|
19
|
+
type TypeOptions = 'info' | 'success' | 'warning' | 'error' | 'default';
|
20
|
+
type Theme = 'light' | 'dark' | 'colored' | (string & {});
|
21
|
+
type ToastPosition = 'top-right' | 'top-center' | 'top-left' | 'bottom-right' | 'bottom-center' | 'bottom-left';
|
22
|
+
type CloseToastFunc = ((reason?: boolean | string) => void) & ((e: React.MouseEvent) => void);
|
23
|
+
interface ToastContentProps<Data = unknown> {
|
24
|
+
closeToast: CloseToastFunc;
|
25
|
+
toastProps: ToastProps;
|
26
|
+
isPaused: boolean;
|
27
|
+
data: Data;
|
28
|
+
}
|
29
|
+
type ToastContent<T = unknown> = React.ReactNode | ((props: ToastContentProps<T>) => React.ReactNode);
|
30
|
+
type ToastIcon = false | ((props: IconProps) => React.ReactNode) | React.ReactElement<IconProps>;
|
31
|
+
type Id = number | string;
|
32
|
+
type ToastTransition = React.FC<ToastTransitionProps> | React.ComponentClass<ToastTransitionProps>;
|
33
|
+
/**
|
34
|
+
* ClassName for the elements - can take a function to build a classname or a raw string that is cx'ed to defaults
|
35
|
+
*/
|
36
|
+
type ToastClassName = ((context?: {
|
37
|
+
type?: TypeOptions;
|
38
|
+
defaultClassName?: string;
|
39
|
+
position?: ToastPosition;
|
40
|
+
rtl?: boolean;
|
41
|
+
}) => string) | string;
|
42
|
+
type DraggableDirection = 'x' | 'y';
|
43
|
+
interface CommonOptions {
|
44
|
+
/**
|
45
|
+
* Pause the timer when the mouse hover the toast.
|
46
|
+
* `Default: true`
|
47
|
+
*/
|
48
|
+
pauseOnHover?: boolean;
|
49
|
+
/**
|
50
|
+
* Pause the toast when the window loses focus.
|
51
|
+
* `Default: true`
|
52
|
+
*/
|
53
|
+
pauseOnFocusLoss?: boolean;
|
54
|
+
/**
|
55
|
+
* Remove the toast when clicked.
|
56
|
+
* `Default: false`
|
57
|
+
*/
|
58
|
+
closeOnClick?: boolean;
|
59
|
+
/**
|
60
|
+
* Set the delay in ms to close the toast automatically.
|
61
|
+
* Use `false` to prevent the toast from closing.
|
62
|
+
* `Default: 5000`
|
63
|
+
*/
|
64
|
+
autoClose?: number | false;
|
65
|
+
/**
|
66
|
+
* Set the default position to use.
|
67
|
+
* `One of: 'top-right', 'top-center', 'top-left', 'bottom-right', 'bottom-center', 'bottom-left'`
|
68
|
+
* `Default: 'top-right'`
|
69
|
+
*/
|
70
|
+
position?: ToastPosition;
|
71
|
+
/**
|
72
|
+
* Pass a custom close button.
|
73
|
+
* To remove the close button pass `false`
|
74
|
+
*/
|
75
|
+
closeButton?: boolean | ((props: CloseButtonProps) => React.ReactNode) | React.ReactElement<CloseButtonProps>;
|
76
|
+
/**
|
77
|
+
* An optional css class to set for the progress bar.
|
78
|
+
*/
|
79
|
+
progressClassName?: ToastClassName;
|
80
|
+
/**
|
81
|
+
* Hide or show the progress bar.
|
82
|
+
* `Default: false`
|
83
|
+
*/
|
84
|
+
hideProgressBar?: boolean;
|
85
|
+
/**
|
86
|
+
* Pass a custom transition see https://fkhadra.github.io/react-toastify-v2/custom-animation/
|
87
|
+
*/
|
88
|
+
transition?: ToastTransition;
|
89
|
+
/**
|
90
|
+
* Allow toast to be draggable
|
91
|
+
* `Default: 'touch'`
|
92
|
+
*/
|
93
|
+
draggable?: boolean | 'mouse' | 'touch';
|
94
|
+
/**
|
95
|
+
* The percentage of the toast's width it takes for a drag to dismiss a toast
|
96
|
+
* `Default: 80`
|
97
|
+
*/
|
98
|
+
draggablePercent?: number;
|
99
|
+
/**
|
100
|
+
* Specify in which direction should you swipe to dismiss the toast
|
101
|
+
* `Default: "x"`
|
102
|
+
*/
|
103
|
+
draggableDirection?: DraggableDirection;
|
104
|
+
/**
|
105
|
+
* Define the ARIA role for the toast
|
106
|
+
* `Default: alert`
|
107
|
+
* https://www.w3.org/WAI/PF/aria/roles
|
108
|
+
*/
|
109
|
+
role?: string;
|
110
|
+
/**
|
111
|
+
* Set id to handle multiple container
|
112
|
+
*/
|
113
|
+
containerId?: Id;
|
114
|
+
/**
|
115
|
+
* Fired when clicking inside toaster
|
116
|
+
*/
|
117
|
+
onClick?: (event: React.MouseEvent) => void;
|
118
|
+
/**
|
119
|
+
* Support right to left display.
|
120
|
+
* `Default: false`
|
121
|
+
*/
|
122
|
+
rtl?: boolean;
|
123
|
+
/**
|
124
|
+
* Used to display a custom icon. Set it to `false` to prevent
|
125
|
+
* the icons from being displayed
|
126
|
+
*/
|
127
|
+
icon?: ToastIcon;
|
128
|
+
/**
|
129
|
+
* Theme to use.
|
130
|
+
* `One of: 'light', 'dark', 'colored'`
|
131
|
+
* `Default: 'light'`
|
132
|
+
*/
|
133
|
+
theme?: Theme;
|
134
|
+
/**
|
135
|
+
* When set to `true` the built-in progress bar won't be rendered at all. Autoclose delay won't have any effect as well
|
136
|
+
* This is only used when you want to replace the progress bar with your own.
|
137
|
+
*
|
138
|
+
* See https://stackblitz.com/edit/react-toastify-v2-custom-progress-bar?file=src%2FApp.tsx for an example.
|
139
|
+
*/
|
140
|
+
customProgressBar?: boolean;
|
141
|
+
}
|
142
|
+
interface ToastOptions<Data = unknown> extends CommonOptions {
|
143
|
+
/**
|
144
|
+
* An optional css class to set.
|
145
|
+
*/
|
146
|
+
className?: ToastClassName;
|
147
|
+
/**
|
148
|
+
* Called when toast is mounted.
|
149
|
+
*/
|
150
|
+
onOpen?: () => void;
|
151
|
+
/**
|
152
|
+
* Called when toast is unmounted.
|
153
|
+
* The callback first argument is the closure reason.
|
154
|
+
* It is "true" when the notification is closed by a user action like clicking on the close button.
|
155
|
+
*/
|
156
|
+
onClose?: (reason?: boolean | string) => void;
|
157
|
+
/**
|
158
|
+
* An optional inline style to apply.
|
159
|
+
*/
|
160
|
+
style?: React.CSSProperties;
|
161
|
+
/**
|
162
|
+
* Set the toast type.
|
163
|
+
* `One of: 'info', 'success', 'warning', 'error', 'default'`
|
164
|
+
*/
|
165
|
+
type?: TypeOptions;
|
166
|
+
/**
|
167
|
+
* Set a custom `toastId`
|
168
|
+
*/
|
169
|
+
toastId?: Id;
|
170
|
+
/**
|
171
|
+
* Used during update
|
172
|
+
*/
|
173
|
+
updateId?: Id;
|
174
|
+
/**
|
175
|
+
* Set the percentage for the controlled progress bar. `Value must be between 0 and 1.`
|
176
|
+
*/
|
177
|
+
progress?: number;
|
178
|
+
/**
|
179
|
+
* Let you provide any data, useful when you are using your own component
|
180
|
+
*/
|
181
|
+
data?: Data;
|
182
|
+
/**
|
183
|
+
* Let you specify the aria-label
|
184
|
+
*/
|
185
|
+
ariaLabel?: string;
|
186
|
+
/**
|
187
|
+
* Add a delay in ms before the toast appear.
|
188
|
+
*/
|
189
|
+
delay?: number;
|
190
|
+
isLoading?: boolean;
|
191
|
+
}
|
192
|
+
interface ToastTransitionProps {
|
193
|
+
isIn: boolean;
|
194
|
+
done: () => void;
|
195
|
+
position: ToastPosition | string;
|
196
|
+
preventExitTransition: boolean;
|
197
|
+
nodeRef: React.RefObject<HTMLElement>;
|
198
|
+
children?: React.ReactNode;
|
199
|
+
playToast(): void;
|
200
|
+
}
|
201
|
+
/**
|
202
|
+
* @INTERNAL
|
203
|
+
*/
|
204
|
+
interface ToastProps extends ToastOptions {
|
205
|
+
isIn: boolean;
|
206
|
+
staleId?: Id;
|
207
|
+
toastId: Id;
|
208
|
+
key: Id;
|
209
|
+
transition: ToastTransition;
|
210
|
+
closeToast: CloseToastFunc;
|
211
|
+
position: ToastPosition;
|
212
|
+
children?: ToastContent;
|
213
|
+
draggablePercent: number;
|
214
|
+
draggableDirection?: DraggableDirection;
|
215
|
+
progressClassName?: ToastClassName;
|
216
|
+
className?: ToastClassName;
|
217
|
+
deleteToast: () => void;
|
218
|
+
theme: Theme;
|
219
|
+
type: TypeOptions;
|
220
|
+
collapseAll: () => void;
|
221
|
+
stacked?: boolean;
|
222
|
+
}
|
223
|
+
type ToastItemStatus = 'added' | 'removed' | 'updated';
|
224
|
+
interface ToastItem<Data = {}> {
|
225
|
+
content: ToastContent<Data>;
|
226
|
+
id: Id;
|
227
|
+
theme?: Theme;
|
228
|
+
type?: TypeOptions;
|
229
|
+
isLoading?: boolean;
|
230
|
+
containerId?: Id;
|
231
|
+
data: Data;
|
232
|
+
icon?: ToastIcon;
|
233
|
+
status: ToastItemStatus;
|
234
|
+
reason?: boolean | string;
|
235
|
+
}
|
236
|
+
|
237
|
+
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
238
|
+
interface NotificationCenterItem<Data = {}> extends Optional<ToastItem<Data>, 'content' | 'data' | 'status'> {
|
239
|
+
read: boolean;
|
240
|
+
createdAt: number;
|
241
|
+
}
|
242
|
+
type SortFn<Data> = (l: NotificationCenterItem<Data>, r: NotificationCenterItem<Data>) => number;
|
243
|
+
type FilterFn<Data = {}> = (item: NotificationCenterItem<Data>) => boolean;
|
244
|
+
interface UseNotificationCenterParams<Data = {}> {
|
245
|
+
/**
|
246
|
+
* initial data to rehydrate the notification center
|
247
|
+
*/
|
248
|
+
data?: NotificationCenterItem<Data>[];
|
249
|
+
/**
|
250
|
+
* By default, the notifications are sorted from the newest to the oldest using
|
251
|
+
* the `createdAt` field. Use this to provide your own sort function
|
252
|
+
*
|
253
|
+
* Usage:
|
254
|
+
* ```
|
255
|
+
* // old notifications first
|
256
|
+
* useNotificationCenter({
|
257
|
+
* sort: ((l, r) => l.createdAt - r.createdAt)
|
258
|
+
* })
|
259
|
+
* ```
|
260
|
+
*/
|
261
|
+
sort?: SortFn<Data>;
|
262
|
+
/**
|
263
|
+
* Keep the toast that meets the condition specified in the callback function.
|
264
|
+
*
|
265
|
+
* Usage:
|
266
|
+
* ```
|
267
|
+
* // keep only the toasts when hidden is set to false
|
268
|
+
* useNotificationCenter({
|
269
|
+
* filter: item => item.data.hidden === false
|
270
|
+
* })
|
271
|
+
* ```
|
272
|
+
*/
|
273
|
+
filter?: FilterFn<Data>;
|
274
|
+
}
|
275
|
+
interface UseNotificationCenter<Data> {
|
276
|
+
/**
|
277
|
+
* Contains all the notifications
|
278
|
+
*/
|
279
|
+
notifications: NotificationCenterItem<Data>[];
|
280
|
+
/**
|
281
|
+
* Clear all notifications
|
282
|
+
*/
|
283
|
+
clear(): void;
|
284
|
+
/**
|
285
|
+
* Mark all notification as read
|
286
|
+
*/
|
287
|
+
markAllAsRead(): void;
|
288
|
+
/**
|
289
|
+
* Mark all notification as read or not.
|
290
|
+
*
|
291
|
+
* Usage:
|
292
|
+
* ```
|
293
|
+
* markAllAsRead(false) // mark all notification as not read
|
294
|
+
*
|
295
|
+
* markAllAsRead(true) // same as calling markAllAsRead()
|
296
|
+
* ```
|
297
|
+
*/
|
298
|
+
markAllAsRead(read?: boolean): void;
|
299
|
+
/**
|
300
|
+
* Mark one or more notifications as read.
|
301
|
+
*
|
302
|
+
* Usage:
|
303
|
+
* ```
|
304
|
+
* markAsRead("anId")
|
305
|
+
* markAsRead(["a","list", "of", "id"])
|
306
|
+
* ```
|
307
|
+
*/
|
308
|
+
markAsRead(id: Id | Id[]): void;
|
309
|
+
/**
|
310
|
+
* Mark one or more notifications as read.The second parameter let you mark the notification as read or not.
|
311
|
+
*
|
312
|
+
* Usage:
|
313
|
+
* ```
|
314
|
+
* markAsRead("anId", false)
|
315
|
+
* markAsRead(["a","list", "of", "id"], false)
|
316
|
+
*
|
317
|
+
* markAsRead("anId", true) // same as markAsRead("anId")
|
318
|
+
* ```
|
319
|
+
*/
|
320
|
+
markAsRead(id: Id | Id[], read?: boolean): void;
|
321
|
+
/**
|
322
|
+
* Remove one or more notifications
|
323
|
+
*
|
324
|
+
* Usage:
|
325
|
+
* ```
|
326
|
+
* remove("anId")
|
327
|
+
* remove(["a","list", "of", "id"])
|
328
|
+
* ```
|
329
|
+
*/
|
330
|
+
remove(id: Id | Id[]): void;
|
331
|
+
/**
|
332
|
+
* Push a notification to the notification center.
|
333
|
+
* Returns null when an item with the given id already exists
|
334
|
+
*
|
335
|
+
* Usage:
|
336
|
+
* ```
|
337
|
+
* const id = add({id: "id", content: "test", data: { foo: "hello" } })
|
338
|
+
*
|
339
|
+
* // Return the id of the notification, generate one if none provided
|
340
|
+
* const id = add({ data: {title: "a title", text: "some text"} })
|
341
|
+
* ```
|
342
|
+
*/
|
343
|
+
add(item: Partial<NotificationCenterItem<Data>>): Id | null;
|
344
|
+
/**
|
345
|
+
* Update the notification that match the id
|
346
|
+
* Returns null when no matching notification found
|
347
|
+
*
|
348
|
+
* Usage:
|
349
|
+
* ```
|
350
|
+
* const id = update("anId", {content: "test", data: { foo: "hello" } })
|
351
|
+
*
|
352
|
+
* // It's also possible to update the id
|
353
|
+
* const id = update("anId"m { id:"anotherOne", data: {title: "a title", text: "some text"} })
|
354
|
+
* ```
|
355
|
+
*/
|
356
|
+
update(id: Id, item: Partial<NotificationCenterItem<Data>>): Id | null;
|
357
|
+
/**
|
358
|
+
* Retrieve one or more notifications
|
359
|
+
*
|
360
|
+
* Usage:
|
361
|
+
* ```
|
362
|
+
* find("anId")
|
363
|
+
* find(["a","list", "of", "id"])
|
364
|
+
* ```
|
365
|
+
*/
|
366
|
+
find(id: Id): NotificationCenterItem<Data> | undefined;
|
367
|
+
/**
|
368
|
+
* Retrieve one or more notifications
|
369
|
+
*
|
370
|
+
* Usage:
|
371
|
+
* ```
|
372
|
+
* find("anId")
|
373
|
+
* find(["a","list", "of", "id"])
|
374
|
+
* ```
|
375
|
+
*/
|
376
|
+
find(id: Id[]): NotificationCenterItem<Data>[] | undefined;
|
377
|
+
/**
|
378
|
+
* Retrieve the count for unread notifications
|
379
|
+
*/
|
380
|
+
unreadCount: number;
|
381
|
+
/**
|
382
|
+
* Sort notifications using the newly provided function
|
383
|
+
*
|
384
|
+
* Usage:
|
385
|
+
* ```
|
386
|
+
* // old notifications first
|
387
|
+
* sort((l, r) => l.createdAt - r.createdAt)
|
388
|
+
* ```
|
389
|
+
*/
|
390
|
+
sort(sort: SortFn<Data>): void;
|
391
|
+
}
|
392
|
+
declare function useNotificationCenter<Data = {}>(params?: UseNotificationCenterParams<Data>): UseNotificationCenter<Data>;
|
393
|
+
declare function decorate<Data>(item: NotificationCenterItem<Data> | Partial<NotificationCenterItem<Data>>): NotificationCenterItem<Data>;
|
394
|
+
|
395
|
+
export { type FilterFn, type NotificationCenterItem, type SortFn, type UseNotificationCenter, type UseNotificationCenterParams, decorate, useNotificationCenter };
|
@@ -0,0 +1,3 @@
|
|
1
|
+
"use client";
|
2
|
+
var H=Object.create;var D=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var Y=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var Z=(t,e)=>{for(var a in e)D(t,a,{get:e[a],enumerable:!0})},L=(t,e,a,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of X(e))!J.call(t,s)&&s!==a&&D(t,s,{get:()=>e[s],enumerable:!(c=z(e,s))||c.enumerable});return t};var tt=(t,e,a)=>(a=t!=null?H(Y(t)):{},L(e||!t||!t.__esModule?D(a,"default",{value:t,enumerable:!0}):a,t)),et=t=>L(D({},"__esModule",{value:!0}),t);var dt={};Z(dt,{decorate:()=>w,useNotificationCenter:()=>st});module.exports=et(dt);var T=require("react");var U=require("react"),g=t=>typeof t=="number"&&!isNaN(t),f=t=>typeof t=="string",O=t=>typeof t=="function",F=t=>f(t)||g(t);var y=t=>(0,U.isValidElement)(t)||f(t)||O(t)||g(t);var P=tt(require("react"));var _=require("react");var at=1,R=()=>`${at++}`;var u=new Map,S=[],Q=new Set;var V=()=>u.size>0;var W=(t,{containerId:e})=>{var a;return(a=u.get(e||1))==null?void 0:a.toasts.get(t)};function $(t,e){var c;if(e)return!!((c=u.get(e))!=null&&c.isToastActive(t));let a=!1;return u.forEach(s=>{s.isToastActive(t)&&(a=!0)}),a}function q(t){if(!V()){S=S.filter(e=>t!=null&&e.options.toastId!==t);return}if(t==null||F(t))u.forEach(e=>{e.removeToast(t)});else if(t&&("containerId"in t||"id"in t)){let e=u.get(t.containerId);e?e.removeToast(t.id):u.forEach(a=>{a.removeToast(t.id)})}}var M=(t={})=>{u.forEach(e=>{e.props.limit&&(!t.containerId||e.id===t.containerId)&&e.clearQueue()})};function j(t,e){y(t)&&(V()||S.push({content:t,options:e}),u.forEach(a=>{a.buildToast(t,e)}))}function k(t,e){u.forEach(a=>{(e==null||!(e!=null&&e.containerId)||(e==null?void 0:e.containerId)===a.id)&&a.toggle(t,e==null?void 0:e.id)})}function G(t){return Q.add(t),()=>{Q.delete(t)}}function nt(t){return t&&(f(t.toastId)||g(t.toastId))?t.toastId:R()}function C(t,e){return j(t,e),e.toastId}function E(t,e){return{...e,type:e&&e.type||t,toastId:nt(e)}}function A(t){return(e,a)=>C(e,E(t,a))}function r(t,e){return C(t,E("default",e))}r.loading=(t,e)=>C(t,E("default",{isLoading:!0,autoClose:!1,closeOnClick:!1,closeButton:!1,draggable:!1,...e}));function ot(t,{pending:e,error:a,success:c},s){let l;e&&(l=f(e)?r.loading(e,s):r.loading(e.render,{...s,...e}));let N={isLoading:null,autoClose:null,closeOnClick:null,closeButton:null,draggable:null},x=(m,p,h)=>{if(p==null){r.dismiss(l);return}let b={type:m,...N,...s,data:h},n=f(p)?{render:p}:p;return l?r.update(l,{...b,...n}):r(n.render,{...b,...n}),h},v=O(t)?t():t;return v.then(m=>x("success",c,m)).catch(m=>x("error",a,m)),v}r.promise=ot;r.success=A("success");r.info=A("info");r.error=A("error");r.warning=A("warning");r.warn=r.warning;r.dark=(t,e)=>C(t,E("default",{theme:"dark",...e}));function rt(t){q(t)}r.dismiss=rt;r.clearWaitingQueue=M;r.isActive=$;r.update=(t,e={})=>{let a=W(t,e);if(a){let{props:c,content:s}=a,l={delay:100,...c,...e,toastId:e.toastId||t,updateId:R()};l.toastId!==t&&(l.staleId=t);let N=l.render||s;delete l.render,C(N,l)}};r.done=t=>{r.update(t,{progress:1})};r.onChange=G;r.play=t=>k(!0,t);r.pause=t=>k(!1,t);function st(t={}){let e=(0,T.useRef)(t.sort||it),a=(0,T.useRef)(t.filter||null),[c,s]=(0,T.useState)(()=>t.data?a.current?t.data.filter(a.current).sort(e.current):[...t.data].sort(e.current):[]);return(0,T.useEffect)(()=>r.onChange(n=>{if(n.status==="added"||n.status==="updated"){let o=w(n);if(a.current&&!a.current(o))return;s(i=>{let d=[],I=i.findIndex(K=>K.id===o.id);return I!==-1?(d=i.slice(),Object.assign(d[I],o,{createdAt:Date.now()})):i.length===0?d=[o]:d=[o,...i],d.sort(e.current)})}}),[]),{notifications:c,clear:()=>{s([])},markAllAsRead:(n=!0)=>{s(o=>o.map(i=>(i.read=n,i)))},markAsRead:(n,o=!0)=>{let i=d=>(d.id===n&&(d.read=o),d);Array.isArray(n)&&(i=d=>(n.includes(d.id)&&(d.read=o),d)),s(d=>d.map(i))},add:n=>{if(c.find(i=>i.id===n.id))return null;let o=w(n);return s(i=>[...i,o].sort(e.current)),o.id},update:(n,o)=>{let i=c.findIndex(d=>d.id===n);return i!==-1?(s(d=>{let I=[...d];return Object.assign(I[i],o,{createdAt:o.createdAt||Date.now()}),I.sort(e.current)}),o.id):null},remove:n=>{s(o=>o.filter(Array.isArray(n)?i=>!n.includes(i.id):i=>i.id!==n))},find:n=>Array.isArray(n)?c.filter(o=>n.includes(o.id)):c.find(o=>o.id===n),sort:n=>{e.current=n,s(o=>o.slice().sort(n))},get unreadCount(){return c.reduce((n,o)=>o.read?n:n+1,0)}}}function w(t){return t.id==null&&(t.id=Date.now().toString(36).substring(2,9)),t.createdAt||(t.createdAt=Date.now()),t.read==null&&(t.read=!1),t}function it(t,e){return e.createdAt-t.createdAt}0&&(module.exports={decorate,useNotificationCenter});
|
3
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/addons/use-notification-center/index.ts","../../src/addons/use-notification-center/useNotificationCenter.ts","../../src/utils/propValidator.ts","../../src/utils/cssTransition.tsx","../../src/utils/mapper.ts","../../src/core/genToastId.ts","../../src/core/store.ts","../../src/core/toast.ts"],"sourcesContent":["export * from './useNotificationCenter';\n","import { useState, useEffect, useRef } from 'react';\nimport { Id, ToastItem } from '../../types';\nimport { toast } from '../../core';\n// import { toast, ToastItem, Id } from 'react-toastify-v2';\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;\n\nexport interface NotificationCenterItem<Data = {}> extends Optional<ToastItem<Data>, 'content' | 'data' | 'status'> {\n read: boolean;\n createdAt: number;\n}\n\nexport type SortFn<Data> = (l: NotificationCenterItem<Data>, r: NotificationCenterItem<Data>) => number;\n\nexport type FilterFn<Data = {}> = (item: NotificationCenterItem<Data>) => boolean;\n\nexport interface UseNotificationCenterParams<Data = {}> {\n /**\n * initial data to rehydrate the notification center\n */\n data?: NotificationCenterItem<Data>[];\n\n /**\n * By default, the notifications are sorted from the newest to the oldest using\n * the `createdAt` field. Use this to provide your own sort function\n *\n * Usage:\n * ```\n * // old notifications first\n * useNotificationCenter({\n * sort: ((l, r) => l.createdAt - r.createdAt)\n * })\n * ```\n */\n sort?: SortFn<Data>;\n\n /**\n * Keep the toast that meets the condition specified in the callback function.\n *\n * Usage:\n * ```\n * // keep only the toasts when hidden is set to false\n * useNotificationCenter({\n * filter: item => item.data.hidden === false\n * })\n * ```\n */\n filter?: FilterFn<Data>;\n}\n\nexport interface UseNotificationCenter<Data> {\n /**\n * Contains all the notifications\n */\n notifications: NotificationCenterItem<Data>[];\n\n /**\n * Clear all notifications\n */\n clear(): void;\n\n /**\n * Mark all notification as read\n */\n markAllAsRead(): void;\n\n /**\n * Mark all notification as read or not.\n *\n * Usage:\n * ```\n * markAllAsRead(false) // mark all notification as not read\n *\n * markAllAsRead(true) // same as calling markAllAsRead()\n * ```\n */\n markAllAsRead(read?: boolean): void;\n\n /**\n * Mark one or more notifications as read.\n *\n * Usage:\n * ```\n * markAsRead(\"anId\")\n * markAsRead([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n markAsRead(id: Id | Id[]): void;\n\n /**\n * Mark one or more notifications as read.The second parameter let you mark the notification as read or not.\n *\n * Usage:\n * ```\n * markAsRead(\"anId\", false)\n * markAsRead([\"a\",\"list\", \"of\", \"id\"], false)\n *\n * markAsRead(\"anId\", true) // same as markAsRead(\"anId\")\n * ```\n */\n markAsRead(id: Id | Id[], read?: boolean): void;\n\n /**\n * Remove one or more notifications\n *\n * Usage:\n * ```\n * remove(\"anId\")\n * remove([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n remove(id: Id | Id[]): void;\n\n /**\n * Push a notification to the notification center.\n * Returns null when an item with the given id already exists\n *\n * Usage:\n * ```\n * const id = add({id: \"id\", content: \"test\", data: { foo: \"hello\" } })\n *\n * // Return the id of the notification, generate one if none provided\n * const id = add({ data: {title: \"a title\", text: \"some text\"} })\n * ```\n */\n add(item: Partial<NotificationCenterItem<Data>>): Id | null;\n\n /**\n * Update the notification that match the id\n * Returns null when no matching notification found\n *\n * Usage:\n * ```\n * const id = update(\"anId\", {content: \"test\", data: { foo: \"hello\" } })\n *\n * // It's also possible to update the id\n * const id = update(\"anId\"m { id:\"anotherOne\", data: {title: \"a title\", text: \"some text\"} })\n * ```\n */\n update(id: Id, item: Partial<NotificationCenterItem<Data>>): Id | null;\n\n /**\n * Retrieve one or more notifications\n *\n * Usage:\n * ```\n * find(\"anId\")\n * find([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n find(id: Id): NotificationCenterItem<Data> | undefined;\n\n /**\n * Retrieve one or more notifications\n *\n * Usage:\n * ```\n * find(\"anId\")\n * find([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n find(id: Id[]): NotificationCenterItem<Data>[] | undefined;\n\n /**\n * Retrieve the count for unread notifications\n */\n unreadCount: number;\n\n /**\n * Sort notifications using the newly provided function\n *\n * Usage:\n * ```\n * // old notifications first\n * sort((l, r) => l.createdAt - r.createdAt)\n * ```\n */\n sort(sort: SortFn<Data>): void;\n}\n\nexport function useNotificationCenter<Data = {}>(\n params: UseNotificationCenterParams<Data> = {}\n): UseNotificationCenter<Data> {\n const sortFn = useRef(params.sort || defaultSort);\n const filterFn = useRef(params.filter || null);\n const [notifications, setNotifications] = useState<NotificationCenterItem<Data>[]>(() => {\n if (params.data) {\n return filterFn.current\n ? params.data.filter(filterFn.current).sort(sortFn.current)\n : [...params.data].sort(sortFn.current);\n }\n return [];\n });\n\n useEffect(() => {\n return toast.onChange(item => {\n if (item.status === 'added' || item.status === 'updated') {\n const newItem = decorate(item as NotificationCenterItem<Data>);\n if (filterFn.current && !filterFn.current(newItem)) return;\n\n setNotifications(prev => {\n let nextState: NotificationCenterItem<Data>[] = [];\n const updateIdx = prev.findIndex(v => v.id === newItem.id);\n\n if (updateIdx !== -1) {\n nextState = prev.slice();\n Object.assign(nextState[updateIdx], newItem, {\n createdAt: Date.now()\n });\n } else if (prev.length === 0) {\n nextState = [newItem];\n } else {\n nextState = [newItem, ...prev];\n }\n return nextState.sort(sortFn.current);\n });\n }\n });\n }, []);\n\n const remove = (id: Id | Id[]) => {\n setNotifications(prev => prev.filter(Array.isArray(id) ? v => !id.includes(v.id) : v => v.id !== id));\n };\n\n const clear = () => {\n setNotifications([]);\n };\n\n const markAllAsRead = (read = true) => {\n setNotifications(prev =>\n prev.map(v => {\n v.read = read;\n return v;\n })\n );\n };\n\n const markAsRead = (id: Id | Id[], read = true) => {\n let map = (v: NotificationCenterItem<Data>) => {\n if (v.id === id) v.read = read;\n return v;\n };\n\n if (Array.isArray(id)) {\n map = v => {\n if (id.includes(v.id)) v.read = read;\n return v;\n };\n }\n\n setNotifications(prev => prev.map(map));\n };\n\n const find = (id: Id | Id[]) => {\n return Array.isArray(id) ? notifications.filter(v => id.includes(v.id)) : notifications.find(v => v.id === id);\n };\n\n const add = (item: Partial<NotificationCenterItem<Data>>) => {\n if (notifications.find(v => v.id === item.id)) return null;\n\n const newItem = decorate(item);\n\n setNotifications(prev => [...prev, newItem].sort(sortFn.current));\n\n return newItem.id;\n };\n\n const update = (id: Id, item: Partial<NotificationCenterItem<Data>>) => {\n const index = notifications.findIndex(v => v.id === id);\n\n if (index !== -1) {\n setNotifications(prev => {\n const nextState = [...prev];\n Object.assign(nextState[index], item, {\n createdAt: item.createdAt || Date.now()\n });\n\n return nextState.sort(sortFn.current);\n });\n\n return item.id as Id;\n }\n\n return null;\n };\n\n const sort = (compareFn: SortFn<Data>) => {\n sortFn.current = compareFn;\n setNotifications(prev => prev.slice().sort(compareFn));\n };\n\n return {\n notifications,\n clear,\n markAllAsRead,\n markAsRead,\n add,\n update,\n remove,\n // @ts-ignore fixme: overloading issue\n find,\n sort,\n get unreadCount() {\n return notifications.reduce((prev, cur) => (!cur.read ? prev + 1 : prev), 0);\n }\n };\n}\n\nexport function decorate<Data>(item: NotificationCenterItem<Data> | Partial<NotificationCenterItem<Data>>) {\n if (item.id == null) item.id = Date.now().toString(36).substring(2, 9);\n if (!item.createdAt) item.createdAt = Date.now();\n if (item.read == null) item.read = false;\n return item as NotificationCenterItem<Data>;\n}\n\n// newest to oldest\nfunction defaultSort<Data>(l: NotificationCenterItem<Data>, r: NotificationCenterItem<Data>) {\n return r.createdAt - l.createdAt;\n}\n","import { isValidElement } from 'react';\nimport { Id } from '../types';\n\nexport const isNum = (v: any): v is Number => typeof v === 'number' && !isNaN(v);\n\nexport const isStr = (v: any): v is String => typeof v === 'string';\n\nexport const isFn = (v: any): v is Function => typeof v === 'function';\n\nexport const isId = (v: unknown): v is Id => isStr(v) || isNum(v);\n\nexport const parseClassName = (v: any) => (isStr(v) || isFn(v) ? v : null);\n\nexport const getAutoCloseDelay = (toastAutoClose?: false | number, containerAutoClose?: false | number) =>\n toastAutoClose === false || (isNum(toastAutoClose) && toastAutoClose > 0) ? toastAutoClose : containerAutoClose;\n\nexport const canBeRendered = <T>(content: T): boolean =>\n isValidElement(content) || isStr(content) || isFn(content) || isNum(content);\n","import React, { useEffect, useLayoutEffect, useRef } from 'react';\nimport { collapseToast } from './collapseToast';\nimport { Default } from './constant';\n\nimport { ToastTransitionProps } from '../types';\n\nexport interface CSSTransitionProps {\n /**\n * Css class to apply when toast enter\n */\n enter: string;\n\n /**\n * Css class to apply when toast leave\n */\n exit: string;\n\n /**\n * Append current toast position to the classname.\n * If multiple classes are provided, only the last one will get the position\n * For instance `myclass--top-center`...\n * `Default: false`\n */\n appendPosition?: boolean;\n\n /**\n * Collapse toast smoothly when exit animation end\n * `Default: true`\n */\n collapse?: boolean;\n\n /**\n * Collapse transition duration\n * `Default: 300`\n */\n collapseDuration?: number;\n}\n\nconst enum AnimationStep {\n Enter,\n Exit\n}\n\n/**\n * Css animation that just work.\n * You could use animate.css for instance\n *\n *\n * ```\n * cssTransition({\n * enter: \"animate__animated animate__bounceIn\",\n * exit: \"animate__animated animate__bounceOut\"\n * })\n * ```\n *\n */\nexport function cssTransition({\n enter,\n exit,\n appendPosition = false,\n collapse = true,\n collapseDuration = Default.COLLAPSE_DURATION\n}: CSSTransitionProps) {\n return function ToastTransition({\n children,\n position,\n preventExitTransition,\n done,\n nodeRef,\n isIn,\n playToast\n }: ToastTransitionProps) {\n const enterClassName = appendPosition ? `${enter}--${position}` : enter;\n const exitClassName = appendPosition ? `${exit}--${position}` : exit;\n const animationStep = useRef(AnimationStep.Enter);\n\n useLayoutEffect(() => {\n const node = nodeRef.current!;\n const classToToken = enterClassName.split(' ');\n\n const onEntered = (e: AnimationEvent) => {\n if (e.target !== nodeRef.current) return;\n\n playToast();\n node.removeEventListener('animationend', onEntered);\n node.removeEventListener('animationcancel', onEntered);\n if (animationStep.current === AnimationStep.Enter && e.type !== 'animationcancel') {\n node.classList.remove(...classToToken);\n }\n };\n\n const onEnter = () => {\n node.classList.add(...classToToken);\n node.addEventListener('animationend', onEntered);\n node.addEventListener('animationcancel', onEntered);\n };\n\n onEnter();\n }, []);\n\n useEffect(() => {\n const node = nodeRef.current!;\n\n const onExited = () => {\n node.removeEventListener('animationend', onExited);\n collapse ? collapseToast(node, done, collapseDuration) : done();\n };\n\n const onExit = () => {\n animationStep.current = AnimationStep.Exit;\n node.className += ` ${exitClassName}`;\n node.addEventListener('animationend', onExited);\n };\n\n if (!isIn) preventExitTransition ? onExited() : onExit();\n }, [isIn]);\n\n return <>{children}</>;\n };\n}\n","import { Toast, ToastContentProps, ToastItem, ToastItemStatus, ToastProps } from '../types';\nimport { cloneElement, isValidElement, ReactElement } from 'react';\nimport { isFn, isStr } from './propValidator';\n\nexport function toToastItem(toast: Toast, status: ToastItemStatus): ToastItem {\n return {\n content: renderContent(toast.content, toast.props),\n containerId: toast.props.containerId,\n id: toast.props.toastId,\n theme: toast.props.theme,\n type: toast.props.type,\n data: toast.props.data || {},\n isLoading: toast.props.isLoading,\n icon: toast.props.icon,\n reason: toast.removalReason,\n status\n };\n}\n\nexport function renderContent(content: unknown, props: ToastProps, isPaused: boolean = false) {\n if (isValidElement(content) && !isStr(content.type)) {\n return cloneElement<ToastContentProps>(content as ReactElement<any>, {\n closeToast: props.closeToast,\n toastProps: props,\n data: props.data,\n isPaused\n });\n } else if (isFn(content)) {\n return content({\n closeToast: props.closeToast,\n toastProps: props,\n data: props.data,\n isPaused\n });\n }\n\n return content;\n}\n","let TOAST_ID = 1;\n\nexport const genToastId = () => `${TOAST_ID++}`;\n","import {\n ClearWaitingQueueParams,\n Id,\n NotValidatedToastProps,\n OnChangeCallback,\n ToastContainerProps,\n ToastContent,\n ToastItem,\n ToastOptions\n} from '../types';\nimport { Default, canBeRendered, isId } from '../utils';\nimport { ContainerObserver, createContainerObserver } from './containerObserver';\n\ninterface EnqueuedToast {\n content: ToastContent<any>;\n options: NotValidatedToastProps;\n}\n\ninterface RemoveParams {\n id?: Id;\n containerId: Id;\n}\n\nconst containers = new Map<Id, ContainerObserver>();\nlet renderQueue: EnqueuedToast[] = [];\nconst listeners = new Set<OnChangeCallback>();\n\nconst dispatchChanges = (data: ToastItem) => listeners.forEach(cb => cb(data));\n\nconst hasContainers = () => containers.size > 0;\n\nfunction flushRenderQueue() {\n renderQueue.forEach(v => pushToast(v.content, v.options));\n renderQueue = [];\n}\n\nexport const getToast = (id: Id, { containerId }: ToastOptions) =>\n containers.get(containerId || Default.CONTAINER_ID)?.toasts.get(id);\n\nexport function isToastActive(id: Id, containerId?: Id) {\n if (containerId) return !!containers.get(containerId)?.isToastActive(id);\n\n let isActive = false;\n containers.forEach(c => {\n if (c.isToastActive(id)) isActive = true;\n });\n\n return isActive;\n}\n\nexport function removeToast(params?: Id | RemoveParams) {\n if (!hasContainers()) {\n renderQueue = renderQueue.filter(v => params != null && v.options.toastId !== params);\n return;\n }\n\n if (params == null || isId(params)) {\n containers.forEach(c => {\n c.removeToast(params as Id);\n });\n } else if (params && ('containerId' in params || 'id' in params)) {\n const container = containers.get(params.containerId);\n container\n ? container.removeToast(params.id)\n : containers.forEach(c => {\n c.removeToast(params.id);\n });\n }\n}\n\nexport const clearWaitingQueue = (p: ClearWaitingQueueParams = {}) => {\n containers.forEach(c => {\n if (c.props.limit && (!p.containerId || c.id === p.containerId)) {\n c.clearQueue();\n }\n });\n};\n\nexport function pushToast<TData>(content: ToastContent<TData>, options: NotValidatedToastProps) {\n if (!canBeRendered(content)) return;\n if (!hasContainers()) renderQueue.push({ content, options });\n\n containers.forEach(c => {\n c.buildToast(content, options);\n });\n}\n\ninterface ToggleToastParams {\n id?: Id;\n containerId?: Id;\n}\n\ntype RegisterToggleOpts = {\n id: Id;\n containerId?: Id;\n fn: (v: boolean) => void;\n};\n\nexport function registerToggle(opts: RegisterToggleOpts) {\n containers.get(opts.containerId || Default.CONTAINER_ID)?.setToggle(opts.id, opts.fn);\n}\n\nexport function toggleToast(v: boolean, opt?: ToggleToastParams) {\n containers.forEach(c => {\n if (opt == null || !opt?.containerId) {\n c.toggle(v, opt?.id);\n } else if (opt?.containerId === c.id) {\n c.toggle(v, opt?.id);\n }\n });\n}\n\nexport function registerContainer(props: ToastContainerProps) {\n const id = props.containerId || Default.CONTAINER_ID;\n return {\n subscribe(notify: () => void) {\n const container = createContainerObserver(id, props, dispatchChanges);\n\n containers.set(id, container);\n const unobserve = container.observe(notify);\n flushRenderQueue();\n\n return () => {\n unobserve();\n containers.delete(id);\n };\n },\n setProps(p: ToastContainerProps) {\n containers.get(id)?.setProps(p);\n },\n getSnapshot() {\n return containers.get(id)?.getSnapshot();\n }\n };\n}\n\nexport function onChange(cb: OnChangeCallback) {\n listeners.add(cb);\n\n return () => {\n listeners.delete(cb);\n };\n}\n","import {\n ClearWaitingQueueFunc,\n Id,\n IdOpts,\n NotValidatedToastProps,\n OnChangeCallback,\n ToastContent,\n ToastOptions,\n ToastProps,\n TypeOptions,\n UpdateOptions\n} from '../types';\nimport { isFn, isNum, isStr, Type } from '../utils';\nimport { genToastId } from './genToastId';\nimport { clearWaitingQueue, getToast, isToastActive, onChange, pushToast, removeToast, toggleToast } from './store';\n\n/**\n * Generate a toastId or use the one provided\n */\nfunction getToastId<TData>(options?: ToastOptions<TData>) {\n return options && (isStr(options.toastId) || isNum(options.toastId)) ? options.toastId : genToastId();\n}\n\n/**\n * If the container is not mounted, the toast is enqueued\n */\nfunction dispatchToast<TData>(content: ToastContent<TData>, options: NotValidatedToastProps): Id {\n pushToast(content, options);\n return options.toastId;\n}\n\n/**\n * Merge provided options with the defaults settings and generate the toastId\n */\nfunction mergeOptions<TData>(type: string, options?: ToastOptions<TData>) {\n return {\n ...options,\n type: (options && options.type) || type,\n toastId: getToastId(options)\n } as NotValidatedToastProps;\n}\n\nfunction createToastByType(type: string) {\n return <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) =>\n dispatchToast(content, mergeOptions(type, options));\n}\n\nfunction toast<TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) {\n return dispatchToast(content, mergeOptions(Type.DEFAULT, options));\n}\n\ntoast.loading = <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) =>\n dispatchToast(\n content,\n mergeOptions(Type.DEFAULT, {\n isLoading: true,\n autoClose: false,\n closeOnClick: false,\n closeButton: false,\n draggable: false,\n ...options\n })\n );\n\nexport interface ToastPromiseParams<TData = unknown, TError = unknown, TPending = unknown> {\n pending?: string | UpdateOptions<TPending>;\n success?: string | UpdateOptions<TData>;\n error?: string | UpdateOptions<TError>;\n}\n\nfunction handlePromise<TData = unknown, TError = unknown, TPending = unknown>(\n promise: Promise<TData> | (() => Promise<TData>),\n { pending, error, success }: ToastPromiseParams<TData, TError, TPending>,\n options?: ToastOptions<TData>\n) {\n let id: Id;\n\n if (pending) {\n id = isStr(pending)\n ? toast.loading(pending, options)\n : toast.loading(pending.render, {\n ...options,\n ...(pending as ToastOptions)\n } as ToastOptions<TPending>);\n }\n\n const resetParams = {\n isLoading: null,\n autoClose: null,\n closeOnClick: null,\n closeButton: null,\n draggable: null\n };\n\n const resolver = <T>(type: TypeOptions, input: string | UpdateOptions<T> | undefined, result: T) => {\n // Remove the toast if the input has not been provided. This prevents the toast from hanging\n // in the pending state if a success/error toast has not been provided.\n if (input == null) {\n toast.dismiss(id);\n return;\n }\n\n const baseParams = {\n type,\n ...resetParams,\n ...options,\n data: result\n };\n const params = isStr(input) ? { render: input } : input;\n\n // if the id is set we know that it's an update\n if (id) {\n toast.update(id, {\n ...baseParams,\n ...params\n } as UpdateOptions);\n } else {\n // using toast.promise without loading\n toast(params!.render, {\n ...baseParams,\n ...params\n } as ToastOptions<T>);\n }\n\n return result;\n };\n\n const p = isFn(promise) ? promise() : promise;\n\n //call the resolvers only when needed\n p.then(result => resolver('success', success, result)).catch(err => resolver('error', error, err));\n\n return p;\n}\n\n/**\n * Supply a promise or a function that return a promise and the notification will be updated if it resolves or fails.\n * When the promise is pending a spinner is displayed by default.\n * `toast.promise` returns the provided promise so you can chain it.\n *\n * Simple example:\n *\n * ```\n * toast.promise(MyPromise,\n * {\n * pending: 'Promise is pending',\n * success: 'Promise resolved 👌',\n * error: 'Promise rejected 🤯'\n * }\n * )\n *\n * ```\n *\n * Advanced usage:\n * ```\n * toast.promise<{name: string}, {message: string}, undefined>(\n * resolveWithSomeData,\n * {\n * pending: {\n * render: () => \"I'm loading\",\n * icon: false,\n * },\n * success: {\n * render: ({data}) => `Hello ${data.name}`,\n * icon: \"🟢\",\n * },\n * error: {\n * render({data}){\n * // When the promise reject, data will contains the error\n * return <MyErrorComponent message={data.message} />\n * }\n * }\n * }\n * )\n * ```\n */\ntoast.promise = handlePromise;\ntoast.success = createToastByType(Type.SUCCESS);\ntoast.info = createToastByType(Type.INFO);\ntoast.error = createToastByType(Type.ERROR);\ntoast.warning = createToastByType(Type.WARNING);\ntoast.warn = toast.warning;\ntoast.dark = (content: ToastContent, options?: ToastOptions) =>\n dispatchToast(\n content,\n mergeOptions(Type.DEFAULT, {\n theme: 'dark',\n ...options\n })\n );\n\ninterface RemoveParams {\n id?: Id;\n containerId: Id;\n}\n\nfunction dismiss(params: RemoveParams): void;\nfunction dismiss(params?: Id): void;\nfunction dismiss(params?: Id | RemoveParams) {\n removeToast(params);\n}\n\n/**\n * Remove toast programmatically\n *\n * - Remove all toasts:\n * ```\n * toast.dismiss()\n * ```\n *\n * - Remove all toasts that belongs to a given container\n * ```\n * toast.dismiss({ container: \"123\" })\n * ```\n *\n * - Remove toast that has a given id regardless the container\n * ```\n * toast.dismiss({ id: \"123\" })\n * ```\n *\n * - Remove toast that has a given id for a specific container\n * ```\n * toast.dismiss({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.dismiss = dismiss;\n\n/**\n * Clear waiting queue when limit is used\n */\ntoast.clearWaitingQueue = clearWaitingQueue as ClearWaitingQueueFunc;\n\n/**\n * Check if a toast is active\n *\n * - Check regardless the container\n * ```\n * toast.isActive(\"123\")\n * ```\n *\n * - Check in a specific container\n * ```\n * toast.isActive(\"123\", \"containerId\")\n * ```\n */\ntoast.isActive = isToastActive;\n\n/**\n * Update a toast, see https://fkhadra.github.io/react-toastify-v2/update-toast/ for more\n *\n * Example:\n * ```\n * // With a string\n * toast.update(toastId, {\n * render: \"New content\",\n * type: \"info\",\n * });\n *\n * // Or with a component\n * toast.update(toastId, {\n * render: MyComponent\n * });\n *\n * // Or a function\n * toast.update(toastId, {\n * render: () => <div>New content</div>\n * });\n *\n * // Apply a transition\n * toast.update(toastId, {\n * render: \"New Content\",\n * type: toast.TYPE.INFO,\n * transition: Rotate\n * })\n * ```\n */\ntoast.update = <TData = unknown>(toastId: Id, options: UpdateOptions<TData> = {}) => {\n const toast = getToast(toastId, options as ToastOptions);\n\n if (toast) {\n const { props: oldOptions, content: oldContent } = toast;\n\n const nextOptions = {\n delay: 100,\n ...oldOptions,\n ...options,\n toastId: options.toastId || toastId,\n updateId: genToastId()\n } as ToastProps & UpdateOptions;\n\n if (nextOptions.toastId !== toastId) nextOptions.staleId = toastId;\n\n const content = nextOptions.render || oldContent;\n delete nextOptions.render;\n\n dispatchToast(content, nextOptions);\n }\n};\n\n/**\n * Used for controlled progress bar. It will automatically close the notification.\n *\n * If you don't want your notification to be clsoed when the timer is done you should use `toast.update` instead as follow instead:\n *\n * ```\n * toast.update(id, {\n * progress: null, // remove controlled progress bar\n * render: \"ok\",\n * type: \"success\",\n * autoClose: 5000 // set autoClose to the desired value\n * });\n * ```\n */\ntoast.done = (id: Id) => {\n toast.update(id, {\n progress: 1\n });\n};\n\n/**\n * Subscribe to change when a toast is added, removed and updated\n *\n * Usage:\n * ```\n * const unsubscribe = toast.onChange((payload) => {\n * switch (payload.status) {\n * case \"added\":\n * // new toast added\n * break;\n * case \"updated\":\n * // toast updated\n * break;\n * case \"removed\":\n * // toast has been removed\n * break;\n * }\n * })\n * ```\n */\ntoast.onChange = onChange as (cb: OnChangeCallback) => () => void;\n\n/**\n * Play a toast(s) timer progammatically\n *\n * Usage:\n *\n * - Play all toasts\n * ```\n * toast.play()\n * ```\n *\n * - Play all toasts for a given container\n * ```\n * toast.play({ containerId: \"123\" })\n * ```\n *\n * - Play toast that has a given id regardless the container\n * ```\n * toast.play({ id: \"123\" })\n * ```\n *\n * - Play toast that has a given id for a specific container\n * ```\n * toast.play({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.play = (opts?: IdOpts) => toggleToast(true, opts);\n\n/**\n * Pause a toast(s) timer progammatically\n *\n * Usage:\n *\n * - Pause all toasts\n * ```\n * toast.pause()\n * ```\n *\n * - Pause all toasts for a given container\n * ```\n * toast.pause({ containerId: \"123\" })\n * ```\n *\n * - Pause toast that has a given id regardless the container\n * ```\n * toast.pause({ id: \"123\" })\n * ```\n *\n * - Pause toast that has a given id for a specific container\n * ```\n * toast.pause({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.pause = (opts?: IdOpts) => toggleToast(false, opts);\n\nexport { toast };\n"],"mappings":"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","names":["use_notification_center_exports","__export","decorate","useNotificationCenter","__toCommonJS","import_react","import_react","isNum","v","isStr","isFn","isId","canBeRendered","content","isStr","isFn","isNum","import_react","import_react","TOAST_ID","genToastId","containers","renderQueue","listeners","hasContainers","containers","getToast","id","containerId","_a","containers","isToastActive","isActive","c","removeToast","params","hasContainers","renderQueue","v","isId","container","clearWaitingQueue","p","pushToast","content","options","canBeRendered","toggleToast","v","opt","containers","c","onChange","cb","listeners","getToastId","options","isStr","isNum","genToastId","dispatchToast","content","pushToast","mergeOptions","type","createToastByType","toast","handlePromise","promise","pending","error","success","id","resetParams","resolver","input","result","baseParams","params","p","isFn","err","dismiss","removeToast","clearWaitingQueue","isToastActive","toastId","getToast","oldOptions","oldContent","nextOptions","onChange","opts","toggleToast","useNotificationCenter","params","sortFn","defaultSort","filterFn","notifications","setNotifications","toast","item","newItem","decorate","prev","nextState","updateIdx","v","read","id","map","index","compareFn","cur","l","r"]}
|
@@ -0,0 +1,3 @@
|
|
1
|
+
"use client";
|
2
|
+
import{useState as H,useEffect as z,useRef as V}from"react";import{isValidElement as q}from"react";var I=t=>typeof t=="number"&&!isNaN(t),f=t=>typeof t=="string",N=t=>typeof t=="function",R=t=>f(t)||I(t);var v=t=>q(t)||f(t)||N(t)||I(t);import ot,{useEffect as rt,useLayoutEffect as st,useRef as it}from"react";import{cloneElement as ft,isValidElement as Tt}from"react";var M=1,h=()=>`${M++}`;var u=new Map,b=[],k=new Set;var w=()=>u.size>0;var L=(t,{containerId:e})=>{var o;return(o=u.get(e||1))==null?void 0:o.toasts.get(t)};function U(t,e){var c;if(e)return!!((c=u.get(e))!=null&&c.isToastActive(t));let o=!1;return u.forEach(d=>{d.isToastActive(t)&&(o=!0)}),o}function F(t){if(!w()){b=b.filter(e=>t!=null&&e.options.toastId!==t);return}if(t==null||R(t))u.forEach(e=>{e.removeToast(t)});else if(t&&("containerId"in t||"id"in t)){let e=u.get(t.containerId);e?e.removeToast(t.id):u.forEach(o=>{o.removeToast(t.id)})}}var B=(t={})=>{u.forEach(e=>{e.props.limit&&(!t.containerId||e.id===t.containerId)&&e.clearQueue()})};function _(t,e){v(t)&&(w()||b.push({content:t,options:e}),u.forEach(o=>{o.buildToast(t,e)}))}function y(t,e){u.forEach(o=>{(e==null||!(e!=null&&e.containerId)||(e==null?void 0:e.containerId)===o.id)&&o.toggle(t,e==null?void 0:e.id)})}function Q(t){return k.add(t),()=>{k.delete(t)}}function j(t){return t&&(f(t.toastId)||I(t.toastId))?t.toastId:h()}function g(t,e){return _(t,e),e.toastId}function D(t,e){return{...e,type:e&&e.type||t,toastId:j(e)}}function O(t){return(e,o)=>g(e,D(t,o))}function r(t,e){return g(t,D("default",e))}r.loading=(t,e)=>g(t,D("default",{isLoading:!0,autoClose:!1,closeOnClick:!1,closeButton:!1,draggable:!1,...e}));function G(t,{pending:e,error:o,success:c},d){let l;e&&(l=f(e)?r.loading(e,d):r.loading(e.render,{...d,...e}));let C={isLoading:null,autoClose:null,closeOnClick:null,closeButton:null,draggable:null},P=(T,m,A)=>{if(m==null){r.dismiss(l);return}let x={type:T,...C,...d,data:A},a=f(m)?{render:m}:m;return l?r.update(l,{...x,...a}):r(a.render,{...x,...a}),A},E=N(t)?t():t;return E.then(T=>P("success",c,T)).catch(T=>P("error",o,T)),E}r.promise=G;r.success=O("success");r.info=O("info");r.error=O("error");r.warning=O("warning");r.warn=r.warning;r.dark=(t,e)=>g(t,D("default",{theme:"dark",...e}));function K(t){F(t)}r.dismiss=K;r.clearWaitingQueue=B;r.isActive=U;r.update=(t,e={})=>{let o=L(t,e);if(o){let{props:c,content:d}=o,l={delay:100,...c,...e,toastId:e.toastId||t,updateId:h()};l.toastId!==t&&(l.staleId=t);let C=l.render||d;delete l.render,g(C,l)}};r.done=t=>{r.update(t,{progress:1})};r.onChange=Q;r.play=t=>y(!0,t);r.pause=t=>y(!1,t);function qt(t={}){let e=V(t.sort||X),o=V(t.filter||null),[c,d]=H(()=>t.data?o.current?t.data.filter(o.current).sort(e.current):[...t.data].sort(e.current):[]);return z(()=>r.onChange(a=>{if(a.status==="added"||a.status==="updated"){let n=W(a);if(o.current&&!o.current(n))return;d(s=>{let i=[],p=s.findIndex($=>$.id===n.id);return p!==-1?(i=s.slice(),Object.assign(i[p],n,{createdAt:Date.now()})):s.length===0?i=[n]:i=[n,...s],i.sort(e.current)})}}),[]),{notifications:c,clear:()=>{d([])},markAllAsRead:(a=!0)=>{d(n=>n.map(s=>(s.read=a,s)))},markAsRead:(a,n=!0)=>{let s=i=>(i.id===a&&(i.read=n),i);Array.isArray(a)&&(s=i=>(a.includes(i.id)&&(i.read=n),i)),d(i=>i.map(s))},add:a=>{if(c.find(s=>s.id===a.id))return null;let n=W(a);return d(s=>[...s,n].sort(e.current)),n.id},update:(a,n)=>{let s=c.findIndex(i=>i.id===a);return s!==-1?(d(i=>{let p=[...i];return Object.assign(p[s],n,{createdAt:n.createdAt||Date.now()}),p.sort(e.current)}),n.id):null},remove:a=>{d(n=>n.filter(Array.isArray(a)?s=>!a.includes(s.id):s=>s.id!==a))},find:a=>Array.isArray(a)?c.filter(n=>a.includes(n.id)):c.find(n=>n.id===a),sort:a=>{e.current=a,d(n=>n.slice().sort(a))},get unreadCount(){return c.reduce((a,n)=>n.read?a:a+1,0)}}}function W(t){return t.id==null&&(t.id=Date.now().toString(36).substring(2,9)),t.createdAt||(t.createdAt=Date.now()),t.read==null&&(t.read=!1),t}function X(t,e){return e.createdAt-t.createdAt}export{W as decorate,qt as useNotificationCenter};
|
3
|
+
//# sourceMappingURL=index.mjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/addons/use-notification-center/useNotificationCenter.ts","../../src/utils/propValidator.ts","../../src/utils/cssTransition.tsx","../../src/utils/mapper.ts","../../src/core/genToastId.ts","../../src/core/store.ts","../../src/core/toast.ts"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport { Id, ToastItem } from '../../types';\nimport { toast } from '../../core';\n// import { toast, ToastItem, Id } from 'react-toastify-v2';\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;\n\nexport interface NotificationCenterItem<Data = {}> extends Optional<ToastItem<Data>, 'content' | 'data' | 'status'> {\n read: boolean;\n createdAt: number;\n}\n\nexport type SortFn<Data> = (l: NotificationCenterItem<Data>, r: NotificationCenterItem<Data>) => number;\n\nexport type FilterFn<Data = {}> = (item: NotificationCenterItem<Data>) => boolean;\n\nexport interface UseNotificationCenterParams<Data = {}> {\n /**\n * initial data to rehydrate the notification center\n */\n data?: NotificationCenterItem<Data>[];\n\n /**\n * By default, the notifications are sorted from the newest to the oldest using\n * the `createdAt` field. Use this to provide your own sort function\n *\n * Usage:\n * ```\n * // old notifications first\n * useNotificationCenter({\n * sort: ((l, r) => l.createdAt - r.createdAt)\n * })\n * ```\n */\n sort?: SortFn<Data>;\n\n /**\n * Keep the toast that meets the condition specified in the callback function.\n *\n * Usage:\n * ```\n * // keep only the toasts when hidden is set to false\n * useNotificationCenter({\n * filter: item => item.data.hidden === false\n * })\n * ```\n */\n filter?: FilterFn<Data>;\n}\n\nexport interface UseNotificationCenter<Data> {\n /**\n * Contains all the notifications\n */\n notifications: NotificationCenterItem<Data>[];\n\n /**\n * Clear all notifications\n */\n clear(): void;\n\n /**\n * Mark all notification as read\n */\n markAllAsRead(): void;\n\n /**\n * Mark all notification as read or not.\n *\n * Usage:\n * ```\n * markAllAsRead(false) // mark all notification as not read\n *\n * markAllAsRead(true) // same as calling markAllAsRead()\n * ```\n */\n markAllAsRead(read?: boolean): void;\n\n /**\n * Mark one or more notifications as read.\n *\n * Usage:\n * ```\n * markAsRead(\"anId\")\n * markAsRead([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n markAsRead(id: Id | Id[]): void;\n\n /**\n * Mark one or more notifications as read.The second parameter let you mark the notification as read or not.\n *\n * Usage:\n * ```\n * markAsRead(\"anId\", false)\n * markAsRead([\"a\",\"list\", \"of\", \"id\"], false)\n *\n * markAsRead(\"anId\", true) // same as markAsRead(\"anId\")\n * ```\n */\n markAsRead(id: Id | Id[], read?: boolean): void;\n\n /**\n * Remove one or more notifications\n *\n * Usage:\n * ```\n * remove(\"anId\")\n * remove([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n remove(id: Id | Id[]): void;\n\n /**\n * Push a notification to the notification center.\n * Returns null when an item with the given id already exists\n *\n * Usage:\n * ```\n * const id = add({id: \"id\", content: \"test\", data: { foo: \"hello\" } })\n *\n * // Return the id of the notification, generate one if none provided\n * const id = add({ data: {title: \"a title\", text: \"some text\"} })\n * ```\n */\n add(item: Partial<NotificationCenterItem<Data>>): Id | null;\n\n /**\n * Update the notification that match the id\n * Returns null when no matching notification found\n *\n * Usage:\n * ```\n * const id = update(\"anId\", {content: \"test\", data: { foo: \"hello\" } })\n *\n * // It's also possible to update the id\n * const id = update(\"anId\"m { id:\"anotherOne\", data: {title: \"a title\", text: \"some text\"} })\n * ```\n */\n update(id: Id, item: Partial<NotificationCenterItem<Data>>): Id | null;\n\n /**\n * Retrieve one or more notifications\n *\n * Usage:\n * ```\n * find(\"anId\")\n * find([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n find(id: Id): NotificationCenterItem<Data> | undefined;\n\n /**\n * Retrieve one or more notifications\n *\n * Usage:\n * ```\n * find(\"anId\")\n * find([\"a\",\"list\", \"of\", \"id\"])\n * ```\n */\n find(id: Id[]): NotificationCenterItem<Data>[] | undefined;\n\n /**\n * Retrieve the count for unread notifications\n */\n unreadCount: number;\n\n /**\n * Sort notifications using the newly provided function\n *\n * Usage:\n * ```\n * // old notifications first\n * sort((l, r) => l.createdAt - r.createdAt)\n * ```\n */\n sort(sort: SortFn<Data>): void;\n}\n\nexport function useNotificationCenter<Data = {}>(\n params: UseNotificationCenterParams<Data> = {}\n): UseNotificationCenter<Data> {\n const sortFn = useRef(params.sort || defaultSort);\n const filterFn = useRef(params.filter || null);\n const [notifications, setNotifications] = useState<NotificationCenterItem<Data>[]>(() => {\n if (params.data) {\n return filterFn.current\n ? params.data.filter(filterFn.current).sort(sortFn.current)\n : [...params.data].sort(sortFn.current);\n }\n return [];\n });\n\n useEffect(() => {\n return toast.onChange(item => {\n if (item.status === 'added' || item.status === 'updated') {\n const newItem = decorate(item as NotificationCenterItem<Data>);\n if (filterFn.current && !filterFn.current(newItem)) return;\n\n setNotifications(prev => {\n let nextState: NotificationCenterItem<Data>[] = [];\n const updateIdx = prev.findIndex(v => v.id === newItem.id);\n\n if (updateIdx !== -1) {\n nextState = prev.slice();\n Object.assign(nextState[updateIdx], newItem, {\n createdAt: Date.now()\n });\n } else if (prev.length === 0) {\n nextState = [newItem];\n } else {\n nextState = [newItem, ...prev];\n }\n return nextState.sort(sortFn.current);\n });\n }\n });\n }, []);\n\n const remove = (id: Id | Id[]) => {\n setNotifications(prev => prev.filter(Array.isArray(id) ? v => !id.includes(v.id) : v => v.id !== id));\n };\n\n const clear = () => {\n setNotifications([]);\n };\n\n const markAllAsRead = (read = true) => {\n setNotifications(prev =>\n prev.map(v => {\n v.read = read;\n return v;\n })\n );\n };\n\n const markAsRead = (id: Id | Id[], read = true) => {\n let map = (v: NotificationCenterItem<Data>) => {\n if (v.id === id) v.read = read;\n return v;\n };\n\n if (Array.isArray(id)) {\n map = v => {\n if (id.includes(v.id)) v.read = read;\n return v;\n };\n }\n\n setNotifications(prev => prev.map(map));\n };\n\n const find = (id: Id | Id[]) => {\n return Array.isArray(id) ? notifications.filter(v => id.includes(v.id)) : notifications.find(v => v.id === id);\n };\n\n const add = (item: Partial<NotificationCenterItem<Data>>) => {\n if (notifications.find(v => v.id === item.id)) return null;\n\n const newItem = decorate(item);\n\n setNotifications(prev => [...prev, newItem].sort(sortFn.current));\n\n return newItem.id;\n };\n\n const update = (id: Id, item: Partial<NotificationCenterItem<Data>>) => {\n const index = notifications.findIndex(v => v.id === id);\n\n if (index !== -1) {\n setNotifications(prev => {\n const nextState = [...prev];\n Object.assign(nextState[index], item, {\n createdAt: item.createdAt || Date.now()\n });\n\n return nextState.sort(sortFn.current);\n });\n\n return item.id as Id;\n }\n\n return null;\n };\n\n const sort = (compareFn: SortFn<Data>) => {\n sortFn.current = compareFn;\n setNotifications(prev => prev.slice().sort(compareFn));\n };\n\n return {\n notifications,\n clear,\n markAllAsRead,\n markAsRead,\n add,\n update,\n remove,\n // @ts-ignore fixme: overloading issue\n find,\n sort,\n get unreadCount() {\n return notifications.reduce((prev, cur) => (!cur.read ? prev + 1 : prev), 0);\n }\n };\n}\n\nexport function decorate<Data>(item: NotificationCenterItem<Data> | Partial<NotificationCenterItem<Data>>) {\n if (item.id == null) item.id = Date.now().toString(36).substring(2, 9);\n if (!item.createdAt) item.createdAt = Date.now();\n if (item.read == null) item.read = false;\n return item as NotificationCenterItem<Data>;\n}\n\n// newest to oldest\nfunction defaultSort<Data>(l: NotificationCenterItem<Data>, r: NotificationCenterItem<Data>) {\n return r.createdAt - l.createdAt;\n}\n","import { isValidElement } from 'react';\nimport { Id } from '../types';\n\nexport const isNum = (v: any): v is Number => typeof v === 'number' && !isNaN(v);\n\nexport const isStr = (v: any): v is String => typeof v === 'string';\n\nexport const isFn = (v: any): v is Function => typeof v === 'function';\n\nexport const isId = (v: unknown): v is Id => isStr(v) || isNum(v);\n\nexport const parseClassName = (v: any) => (isStr(v) || isFn(v) ? v : null);\n\nexport const getAutoCloseDelay = (toastAutoClose?: false | number, containerAutoClose?: false | number) =>\n toastAutoClose === false || (isNum(toastAutoClose) && toastAutoClose > 0) ? toastAutoClose : containerAutoClose;\n\nexport const canBeRendered = <T>(content: T): boolean =>\n isValidElement(content) || isStr(content) || isFn(content) || isNum(content);\n","import React, { useEffect, useLayoutEffect, useRef } from 'react';\nimport { collapseToast } from './collapseToast';\nimport { Default } from './constant';\n\nimport { ToastTransitionProps } from '../types';\n\nexport interface CSSTransitionProps {\n /**\n * Css class to apply when toast enter\n */\n enter: string;\n\n /**\n * Css class to apply when toast leave\n */\n exit: string;\n\n /**\n * Append current toast position to the classname.\n * If multiple classes are provided, only the last one will get the position\n * For instance `myclass--top-center`...\n * `Default: false`\n */\n appendPosition?: boolean;\n\n /**\n * Collapse toast smoothly when exit animation end\n * `Default: true`\n */\n collapse?: boolean;\n\n /**\n * Collapse transition duration\n * `Default: 300`\n */\n collapseDuration?: number;\n}\n\nconst enum AnimationStep {\n Enter,\n Exit\n}\n\n/**\n * Css animation that just work.\n * You could use animate.css for instance\n *\n *\n * ```\n * cssTransition({\n * enter: \"animate__animated animate__bounceIn\",\n * exit: \"animate__animated animate__bounceOut\"\n * })\n * ```\n *\n */\nexport function cssTransition({\n enter,\n exit,\n appendPosition = false,\n collapse = true,\n collapseDuration = Default.COLLAPSE_DURATION\n}: CSSTransitionProps) {\n return function ToastTransition({\n children,\n position,\n preventExitTransition,\n done,\n nodeRef,\n isIn,\n playToast\n }: ToastTransitionProps) {\n const enterClassName = appendPosition ? `${enter}--${position}` : enter;\n const exitClassName = appendPosition ? `${exit}--${position}` : exit;\n const animationStep = useRef(AnimationStep.Enter);\n\n useLayoutEffect(() => {\n const node = nodeRef.current!;\n const classToToken = enterClassName.split(' ');\n\n const onEntered = (e: AnimationEvent) => {\n if (e.target !== nodeRef.current) return;\n\n playToast();\n node.removeEventListener('animationend', onEntered);\n node.removeEventListener('animationcancel', onEntered);\n if (animationStep.current === AnimationStep.Enter && e.type !== 'animationcancel') {\n node.classList.remove(...classToToken);\n }\n };\n\n const onEnter = () => {\n node.classList.add(...classToToken);\n node.addEventListener('animationend', onEntered);\n node.addEventListener('animationcancel', onEntered);\n };\n\n onEnter();\n }, []);\n\n useEffect(() => {\n const node = nodeRef.current!;\n\n const onExited = () => {\n node.removeEventListener('animationend', onExited);\n collapse ? collapseToast(node, done, collapseDuration) : done();\n };\n\n const onExit = () => {\n animationStep.current = AnimationStep.Exit;\n node.className += ` ${exitClassName}`;\n node.addEventListener('animationend', onExited);\n };\n\n if (!isIn) preventExitTransition ? onExited() : onExit();\n }, [isIn]);\n\n return <>{children}</>;\n };\n}\n","import { Toast, ToastContentProps, ToastItem, ToastItemStatus, ToastProps } from '../types';\nimport { cloneElement, isValidElement, ReactElement } from 'react';\nimport { isFn, isStr } from './propValidator';\n\nexport function toToastItem(toast: Toast, status: ToastItemStatus): ToastItem {\n return {\n content: renderContent(toast.content, toast.props),\n containerId: toast.props.containerId,\n id: toast.props.toastId,\n theme: toast.props.theme,\n type: toast.props.type,\n data: toast.props.data || {},\n isLoading: toast.props.isLoading,\n icon: toast.props.icon,\n reason: toast.removalReason,\n status\n };\n}\n\nexport function renderContent(content: unknown, props: ToastProps, isPaused: boolean = false) {\n if (isValidElement(content) && !isStr(content.type)) {\n return cloneElement<ToastContentProps>(content as ReactElement<any>, {\n closeToast: props.closeToast,\n toastProps: props,\n data: props.data,\n isPaused\n });\n } else if (isFn(content)) {\n return content({\n closeToast: props.closeToast,\n toastProps: props,\n data: props.data,\n isPaused\n });\n }\n\n return content;\n}\n","let TOAST_ID = 1;\n\nexport const genToastId = () => `${TOAST_ID++}`;\n","import {\n ClearWaitingQueueParams,\n Id,\n NotValidatedToastProps,\n OnChangeCallback,\n ToastContainerProps,\n ToastContent,\n ToastItem,\n ToastOptions\n} from '../types';\nimport { Default, canBeRendered, isId } from '../utils';\nimport { ContainerObserver, createContainerObserver } from './containerObserver';\n\ninterface EnqueuedToast {\n content: ToastContent<any>;\n options: NotValidatedToastProps;\n}\n\ninterface RemoveParams {\n id?: Id;\n containerId: Id;\n}\n\nconst containers = new Map<Id, ContainerObserver>();\nlet renderQueue: EnqueuedToast[] = [];\nconst listeners = new Set<OnChangeCallback>();\n\nconst dispatchChanges = (data: ToastItem) => listeners.forEach(cb => cb(data));\n\nconst hasContainers = () => containers.size > 0;\n\nfunction flushRenderQueue() {\n renderQueue.forEach(v => pushToast(v.content, v.options));\n renderQueue = [];\n}\n\nexport const getToast = (id: Id, { containerId }: ToastOptions) =>\n containers.get(containerId || Default.CONTAINER_ID)?.toasts.get(id);\n\nexport function isToastActive(id: Id, containerId?: Id) {\n if (containerId) return !!containers.get(containerId)?.isToastActive(id);\n\n let isActive = false;\n containers.forEach(c => {\n if (c.isToastActive(id)) isActive = true;\n });\n\n return isActive;\n}\n\nexport function removeToast(params?: Id | RemoveParams) {\n if (!hasContainers()) {\n renderQueue = renderQueue.filter(v => params != null && v.options.toastId !== params);\n return;\n }\n\n if (params == null || isId(params)) {\n containers.forEach(c => {\n c.removeToast(params as Id);\n });\n } else if (params && ('containerId' in params || 'id' in params)) {\n const container = containers.get(params.containerId);\n container\n ? container.removeToast(params.id)\n : containers.forEach(c => {\n c.removeToast(params.id);\n });\n }\n}\n\nexport const clearWaitingQueue = (p: ClearWaitingQueueParams = {}) => {\n containers.forEach(c => {\n if (c.props.limit && (!p.containerId || c.id === p.containerId)) {\n c.clearQueue();\n }\n });\n};\n\nexport function pushToast<TData>(content: ToastContent<TData>, options: NotValidatedToastProps) {\n if (!canBeRendered(content)) return;\n if (!hasContainers()) renderQueue.push({ content, options });\n\n containers.forEach(c => {\n c.buildToast(content, options);\n });\n}\n\ninterface ToggleToastParams {\n id?: Id;\n containerId?: Id;\n}\n\ntype RegisterToggleOpts = {\n id: Id;\n containerId?: Id;\n fn: (v: boolean) => void;\n};\n\nexport function registerToggle(opts: RegisterToggleOpts) {\n containers.get(opts.containerId || Default.CONTAINER_ID)?.setToggle(opts.id, opts.fn);\n}\n\nexport function toggleToast(v: boolean, opt?: ToggleToastParams) {\n containers.forEach(c => {\n if (opt == null || !opt?.containerId) {\n c.toggle(v, opt?.id);\n } else if (opt?.containerId === c.id) {\n c.toggle(v, opt?.id);\n }\n });\n}\n\nexport function registerContainer(props: ToastContainerProps) {\n const id = props.containerId || Default.CONTAINER_ID;\n return {\n subscribe(notify: () => void) {\n const container = createContainerObserver(id, props, dispatchChanges);\n\n containers.set(id, container);\n const unobserve = container.observe(notify);\n flushRenderQueue();\n\n return () => {\n unobserve();\n containers.delete(id);\n };\n },\n setProps(p: ToastContainerProps) {\n containers.get(id)?.setProps(p);\n },\n getSnapshot() {\n return containers.get(id)?.getSnapshot();\n }\n };\n}\n\nexport function onChange(cb: OnChangeCallback) {\n listeners.add(cb);\n\n return () => {\n listeners.delete(cb);\n };\n}\n","import {\n ClearWaitingQueueFunc,\n Id,\n IdOpts,\n NotValidatedToastProps,\n OnChangeCallback,\n ToastContent,\n ToastOptions,\n ToastProps,\n TypeOptions,\n UpdateOptions\n} from '../types';\nimport { isFn, isNum, isStr, Type } from '../utils';\nimport { genToastId } from './genToastId';\nimport { clearWaitingQueue, getToast, isToastActive, onChange, pushToast, removeToast, toggleToast } from './store';\n\n/**\n * Generate a toastId or use the one provided\n */\nfunction getToastId<TData>(options?: ToastOptions<TData>) {\n return options && (isStr(options.toastId) || isNum(options.toastId)) ? options.toastId : genToastId();\n}\n\n/**\n * If the container is not mounted, the toast is enqueued\n */\nfunction dispatchToast<TData>(content: ToastContent<TData>, options: NotValidatedToastProps): Id {\n pushToast(content, options);\n return options.toastId;\n}\n\n/**\n * Merge provided options with the defaults settings and generate the toastId\n */\nfunction mergeOptions<TData>(type: string, options?: ToastOptions<TData>) {\n return {\n ...options,\n type: (options && options.type) || type,\n toastId: getToastId(options)\n } as NotValidatedToastProps;\n}\n\nfunction createToastByType(type: string) {\n return <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) =>\n dispatchToast(content, mergeOptions(type, options));\n}\n\nfunction toast<TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) {\n return dispatchToast(content, mergeOptions(Type.DEFAULT, options));\n}\n\ntoast.loading = <TData = unknown>(content: ToastContent<TData>, options?: ToastOptions<TData>) =>\n dispatchToast(\n content,\n mergeOptions(Type.DEFAULT, {\n isLoading: true,\n autoClose: false,\n closeOnClick: false,\n closeButton: false,\n draggable: false,\n ...options\n })\n );\n\nexport interface ToastPromiseParams<TData = unknown, TError = unknown, TPending = unknown> {\n pending?: string | UpdateOptions<TPending>;\n success?: string | UpdateOptions<TData>;\n error?: string | UpdateOptions<TError>;\n}\n\nfunction handlePromise<TData = unknown, TError = unknown, TPending = unknown>(\n promise: Promise<TData> | (() => Promise<TData>),\n { pending, error, success }: ToastPromiseParams<TData, TError, TPending>,\n options?: ToastOptions<TData>\n) {\n let id: Id;\n\n if (pending) {\n id = isStr(pending)\n ? toast.loading(pending, options)\n : toast.loading(pending.render, {\n ...options,\n ...(pending as ToastOptions)\n } as ToastOptions<TPending>);\n }\n\n const resetParams = {\n isLoading: null,\n autoClose: null,\n closeOnClick: null,\n closeButton: null,\n draggable: null\n };\n\n const resolver = <T>(type: TypeOptions, input: string | UpdateOptions<T> | undefined, result: T) => {\n // Remove the toast if the input has not been provided. This prevents the toast from hanging\n // in the pending state if a success/error toast has not been provided.\n if (input == null) {\n toast.dismiss(id);\n return;\n }\n\n const baseParams = {\n type,\n ...resetParams,\n ...options,\n data: result\n };\n const params = isStr(input) ? { render: input } : input;\n\n // if the id is set we know that it's an update\n if (id) {\n toast.update(id, {\n ...baseParams,\n ...params\n } as UpdateOptions);\n } else {\n // using toast.promise without loading\n toast(params!.render, {\n ...baseParams,\n ...params\n } as ToastOptions<T>);\n }\n\n return result;\n };\n\n const p = isFn(promise) ? promise() : promise;\n\n //call the resolvers only when needed\n p.then(result => resolver('success', success, result)).catch(err => resolver('error', error, err));\n\n return p;\n}\n\n/**\n * Supply a promise or a function that return a promise and the notification will be updated if it resolves or fails.\n * When the promise is pending a spinner is displayed by default.\n * `toast.promise` returns the provided promise so you can chain it.\n *\n * Simple example:\n *\n * ```\n * toast.promise(MyPromise,\n * {\n * pending: 'Promise is pending',\n * success: 'Promise resolved 👌',\n * error: 'Promise rejected 🤯'\n * }\n * )\n *\n * ```\n *\n * Advanced usage:\n * ```\n * toast.promise<{name: string}, {message: string}, undefined>(\n * resolveWithSomeData,\n * {\n * pending: {\n * render: () => \"I'm loading\",\n * icon: false,\n * },\n * success: {\n * render: ({data}) => `Hello ${data.name}`,\n * icon: \"🟢\",\n * },\n * error: {\n * render({data}){\n * // When the promise reject, data will contains the error\n * return <MyErrorComponent message={data.message} />\n * }\n * }\n * }\n * )\n * ```\n */\ntoast.promise = handlePromise;\ntoast.success = createToastByType(Type.SUCCESS);\ntoast.info = createToastByType(Type.INFO);\ntoast.error = createToastByType(Type.ERROR);\ntoast.warning = createToastByType(Type.WARNING);\ntoast.warn = toast.warning;\ntoast.dark = (content: ToastContent, options?: ToastOptions) =>\n dispatchToast(\n content,\n mergeOptions(Type.DEFAULT, {\n theme: 'dark',\n ...options\n })\n );\n\ninterface RemoveParams {\n id?: Id;\n containerId: Id;\n}\n\nfunction dismiss(params: RemoveParams): void;\nfunction dismiss(params?: Id): void;\nfunction dismiss(params?: Id | RemoveParams) {\n removeToast(params);\n}\n\n/**\n * Remove toast programmatically\n *\n * - Remove all toasts:\n * ```\n * toast.dismiss()\n * ```\n *\n * - Remove all toasts that belongs to a given container\n * ```\n * toast.dismiss({ container: \"123\" })\n * ```\n *\n * - Remove toast that has a given id regardless the container\n * ```\n * toast.dismiss({ id: \"123\" })\n * ```\n *\n * - Remove toast that has a given id for a specific container\n * ```\n * toast.dismiss({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.dismiss = dismiss;\n\n/**\n * Clear waiting queue when limit is used\n */\ntoast.clearWaitingQueue = clearWaitingQueue as ClearWaitingQueueFunc;\n\n/**\n * Check if a toast is active\n *\n * - Check regardless the container\n * ```\n * toast.isActive(\"123\")\n * ```\n *\n * - Check in a specific container\n * ```\n * toast.isActive(\"123\", \"containerId\")\n * ```\n */\ntoast.isActive = isToastActive;\n\n/**\n * Update a toast, see https://fkhadra.github.io/react-toastify-v2/update-toast/ for more\n *\n * Example:\n * ```\n * // With a string\n * toast.update(toastId, {\n * render: \"New content\",\n * type: \"info\",\n * });\n *\n * // Or with a component\n * toast.update(toastId, {\n * render: MyComponent\n * });\n *\n * // Or a function\n * toast.update(toastId, {\n * render: () => <div>New content</div>\n * });\n *\n * // Apply a transition\n * toast.update(toastId, {\n * render: \"New Content\",\n * type: toast.TYPE.INFO,\n * transition: Rotate\n * })\n * ```\n */\ntoast.update = <TData = unknown>(toastId: Id, options: UpdateOptions<TData> = {}) => {\n const toast = getToast(toastId, options as ToastOptions);\n\n if (toast) {\n const { props: oldOptions, content: oldContent } = toast;\n\n const nextOptions = {\n delay: 100,\n ...oldOptions,\n ...options,\n toastId: options.toastId || toastId,\n updateId: genToastId()\n } as ToastProps & UpdateOptions;\n\n if (nextOptions.toastId !== toastId) nextOptions.staleId = toastId;\n\n const content = nextOptions.render || oldContent;\n delete nextOptions.render;\n\n dispatchToast(content, nextOptions);\n }\n};\n\n/**\n * Used for controlled progress bar. It will automatically close the notification.\n *\n * If you don't want your notification to be clsoed when the timer is done you should use `toast.update` instead as follow instead:\n *\n * ```\n * toast.update(id, {\n * progress: null, // remove controlled progress bar\n * render: \"ok\",\n * type: \"success\",\n * autoClose: 5000 // set autoClose to the desired value\n * });\n * ```\n */\ntoast.done = (id: Id) => {\n toast.update(id, {\n progress: 1\n });\n};\n\n/**\n * Subscribe to change when a toast is added, removed and updated\n *\n * Usage:\n * ```\n * const unsubscribe = toast.onChange((payload) => {\n * switch (payload.status) {\n * case \"added\":\n * // new toast added\n * break;\n * case \"updated\":\n * // toast updated\n * break;\n * case \"removed\":\n * // toast has been removed\n * break;\n * }\n * })\n * ```\n */\ntoast.onChange = onChange as (cb: OnChangeCallback) => () => void;\n\n/**\n * Play a toast(s) timer progammatically\n *\n * Usage:\n *\n * - Play all toasts\n * ```\n * toast.play()\n * ```\n *\n * - Play all toasts for a given container\n * ```\n * toast.play({ containerId: \"123\" })\n * ```\n *\n * - Play toast that has a given id regardless the container\n * ```\n * toast.play({ id: \"123\" })\n * ```\n *\n * - Play toast that has a given id for a specific container\n * ```\n * toast.play({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.play = (opts?: IdOpts) => toggleToast(true, opts);\n\n/**\n * Pause a toast(s) timer progammatically\n *\n * Usage:\n *\n * - Pause all toasts\n * ```\n * toast.pause()\n * ```\n *\n * - Pause all toasts for a given container\n * ```\n * toast.pause({ containerId: \"123\" })\n * ```\n *\n * - Pause toast that has a given id regardless the container\n * ```\n * toast.pause({ id: \"123\" })\n * ```\n *\n * - Pause toast that has a given id for a specific container\n * ```\n * toast.pause({ id: \"123\", containerId: \"12\" })\n * ```\n */\ntoast.pause = (opts?: IdOpts) => toggleToast(false, opts);\n\nexport { toast };\n"],"mappings":"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","names":["useState","useEffect","useRef","isValidElement","isNum","v","isStr","isFn","isId","canBeRendered","content","isValidElement","isStr","isFn","isNum","React","useEffect","useLayoutEffect","useRef","cloneElement","isValidElement","TOAST_ID","genToastId","containers","renderQueue","listeners","hasContainers","containers","getToast","id","containerId","_a","containers","isToastActive","isActive","c","removeToast","params","hasContainers","renderQueue","v","isId","container","clearWaitingQueue","p","pushToast","content","options","canBeRendered","toggleToast","v","opt","containers","c","onChange","cb","listeners","getToastId","options","isStr","isNum","genToastId","dispatchToast","content","pushToast","mergeOptions","type","createToastByType","toast","handlePromise","promise","pending","error","success","id","resetParams","resolver","input","result","baseParams","params","p","isFn","err","dismiss","removeToast","clearWaitingQueue","isToastActive","toastId","getToast","oldOptions","oldContent","nextOptions","onChange","opts","toggleToast","useNotificationCenter","params","sortFn","useRef","defaultSort","filterFn","notifications","setNotifications","useState","useEffect","toast","item","newItem","decorate","prev","nextState","updateIdx","v","read","id","map","index","compareFn","cur","l","r"]}
|