@cookified/toastify 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.cjs ADDED
@@ -0,0 +1,1104 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('motion/react');
5
+ var react$1 = require('react');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/toastify/Toaster.tsx
9
+ function CheckIcon() {
10
+ return /* @__PURE__ */ jsxRuntime.jsx(
11
+ "svg",
12
+ {
13
+ width: "12",
14
+ height: "12",
15
+ viewBox: "0 0 24 24",
16
+ fill: "none",
17
+ stroke: "currentColor",
18
+ strokeWidth: 2.5,
19
+ strokeLinecap: "round",
20
+ strokeLinejoin: "round",
21
+ "aria-hidden": "true",
22
+ children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" })
23
+ }
24
+ );
25
+ }
26
+ function XIcon() {
27
+ return /* @__PURE__ */ jsxRuntime.jsxs(
28
+ "svg",
29
+ {
30
+ width: "12",
31
+ height: "12",
32
+ viewBox: "0 0 24 24",
33
+ fill: "none",
34
+ stroke: "currentColor",
35
+ strokeWidth: 2.5,
36
+ strokeLinecap: "round",
37
+ strokeLinejoin: "round",
38
+ "aria-hidden": "true",
39
+ children: [
40
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
41
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
42
+ ]
43
+ }
44
+ );
45
+ }
46
+ function LoaderIcon() {
47
+ return /* @__PURE__ */ jsxRuntime.jsx(
48
+ "svg",
49
+ {
50
+ width: "12",
51
+ height: "12",
52
+ viewBox: "0 0 24 24",
53
+ fill: "none",
54
+ stroke: "currentColor",
55
+ strokeWidth: 2.5,
56
+ strokeLinecap: "round",
57
+ strokeLinejoin: "round",
58
+ className: "toastify-spin animate-spin",
59
+ "aria-hidden": "true",
60
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
61
+ }
62
+ );
63
+ }
64
+ function DefaultToastIcon({ type }) {
65
+ const badgeClasses = "toastify-badge flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white shadow-xs dark:bg-white dark:text-neutral-950";
66
+ switch (type) {
67
+ case "loading":
68
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: badgeClasses, children: /* @__PURE__ */ jsxRuntime.jsx(LoaderIcon, {}) });
69
+ case "success":
70
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: badgeClasses, children: /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, {}) });
71
+ case "error":
72
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: badgeClasses, children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, {}) });
73
+ case "warning":
74
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: badgeClasses, children: /* @__PURE__ */ jsxRuntime.jsxs(
75
+ "svg",
76
+ {
77
+ width: "12",
78
+ height: "12",
79
+ viewBox: "0 0 24 24",
80
+ fill: "none",
81
+ stroke: "currentColor",
82
+ strokeWidth: 2.5,
83
+ strokeLinecap: "round",
84
+ strokeLinejoin: "round",
85
+ "aria-hidden": "true",
86
+ children: [
87
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
88
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
89
+ ]
90
+ }
91
+ ) });
92
+ case "info":
93
+ case "neutral":
94
+ default:
95
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: badgeClasses, children: /* @__PURE__ */ jsxRuntime.jsxs(
96
+ "svg",
97
+ {
98
+ width: "12",
99
+ height: "12",
100
+ viewBox: "0 0 24 24",
101
+ fill: "none",
102
+ stroke: "currentColor",
103
+ strokeWidth: 2.5,
104
+ strokeLinecap: "round",
105
+ strokeLinejoin: "round",
106
+ "aria-hidden": "true",
107
+ children: [
108
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
109
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
110
+ ]
111
+ }
112
+ ) });
113
+ }
114
+ }
115
+ function Toast({
116
+ toast: toast2,
117
+ onDismiss,
118
+ closeOnClick = false,
119
+ globalIcons,
120
+ globalOptions
121
+ }) {
122
+ if (toast2.customRenderer) {
123
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: toast2.customRenderer(toast2.id) });
124
+ }
125
+ const icon = toast2.icon ?? globalIcons?.[toast2.type] ?? /* @__PURE__ */ jsxRuntime.jsx(DefaultToastIcon, { type: toast2.type });
126
+ return /* @__PURE__ */ jsxRuntime.jsxs(
127
+ "div",
128
+ {
129
+ onClick: () => closeOnClick && onDismiss(),
130
+ className: `toastify-toast flex h-14 w-full select-none items-center justify-between gap-3 rounded-md border border-neutral-200/90 bg-white px-3.5 shadow-md shadow-neutral-950/5 dark:border-neutral-800/90 dark:bg-neutral-900 dark:shadow-neutral-950/40 ${globalOptions?.className ?? ""} ${toast2.className ?? ""}`,
131
+ style: { ...globalOptions?.style, ...toast2.style },
132
+ children: [
133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "toastify-content flex min-w-0 flex-1 items-center gap-3", children: [
134
+ icon,
135
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "toastify-text-group flex min-w-0 flex-col justify-center", children: [
136
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "toastify-title truncate text-[13px] font-medium leading-4 text-neutral-900 dark:text-neutral-100", children: toast2.title }),
137
+ toast2.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "toastify-description mt-0.5 truncate text-[12px] leading-4 text-neutral-500 dark:text-neutral-400", children: toast2.description })
138
+ ] })
139
+ ] }),
140
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "toastify-actions flex shrink-0 items-center gap-2", children: [
141
+ toast2.cancel && /* @__PURE__ */ jsxRuntime.jsx(
142
+ "button",
143
+ {
144
+ type: "button",
145
+ onClick: (event) => {
146
+ event.stopPropagation();
147
+ try {
148
+ toast2.cancel?.onClick(event);
149
+ } catch (err) {
150
+ console.error("Toast cancel handler failed:", err);
151
+ }
152
+ onDismiss();
153
+ },
154
+ className: "toastify-btn-cancel cursor-pointer rounded px-2 py-1 text-xs font-medium text-neutral-600 transition-colors hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-100",
155
+ children: toast2.cancel.label
156
+ }
157
+ ),
158
+ toast2.action && /* @__PURE__ */ jsxRuntime.jsx(
159
+ "button",
160
+ {
161
+ type: "button",
162
+ onClick: (event) => {
163
+ event.stopPropagation();
164
+ try {
165
+ toast2.action?.onClick(event);
166
+ } catch (err) {
167
+ console.error("Toast action handler failed:", err);
168
+ }
169
+ onDismiss();
170
+ },
171
+ className: "toastify-btn-action cursor-pointer rounded px-2.5 py-1 text-xs font-medium bg-neutral-900 text-white transition-all hover:bg-neutral-800 shadow-[inset_0_-2px_4px_rgba(0,0,0,0.5),0_1px_2px_rgba(0,0,0,0.08)] active:shadow-[inset_0_2px_4px_rgba(0,0,0,0.4)] dark:bg-neutral-100 dark:text-neutral-900 dark:hover:bg-neutral-200 dark:shadow-[inset_0_-2px_4px_rgba(0,0,0,0.22),0_1px_2px_rgba(0,0,0,0.15)] dark:active:shadow-[inset_0_2px_4px_rgba(0,0,0,0.25)]",
172
+ children: toast2.action.label
173
+ }
174
+ )
175
+ ] })
176
+ ]
177
+ }
178
+ );
179
+ }
180
+
181
+ // src/toastify/animations/constants.ts
182
+ var defaultSpring = {
183
+ stiffness: 220,
184
+ damping: 26,
185
+ mass: 1
186
+ };
187
+ function FadeAnimation({
188
+ index,
189
+ position,
190
+ isDismissing,
191
+ onDismiss,
192
+ springConfig = defaultSpring,
193
+ children
194
+ }) {
195
+ const isTop = position.startsWith("top");
196
+ const stackStep = 66;
197
+ const targetY = isTop ? index * stackStep : -index * stackStep;
198
+ return /* @__PURE__ */ jsxRuntime.jsx(
199
+ react.motion.article,
200
+ {
201
+ role: "status",
202
+ "aria-live": "polite",
203
+ initial: {
204
+ opacity: 0,
205
+ scale: 0.9,
206
+ y: targetY,
207
+ filter: "blur(4px)"
208
+ },
209
+ animate: {
210
+ opacity: isDismissing ? 0 : 1,
211
+ scale: isDismissing ? 0.9 : 1,
212
+ y: targetY,
213
+ filter: isDismissing ? "blur(4px)" : "blur(0px)",
214
+ zIndex: 50 - index,
215
+ pointerEvents: !isDismissing ? "auto" : "none"
216
+ },
217
+ exit: {
218
+ opacity: 0,
219
+ scale: 0.9,
220
+ filter: "blur(4px)",
221
+ transition: {
222
+ duration: 0.22,
223
+ ease: "easeOut"
224
+ }
225
+ },
226
+ transition: {
227
+ type: "spring",
228
+ ...springConfig
229
+ },
230
+ drag: "x",
231
+ dragConstraints: { left: 0, right: 0 },
232
+ dragElastic: 0.6,
233
+ onDragEnd: (_, info) => {
234
+ if (Math.abs(info.offset.x) > 60 || Math.abs(info.velocity.x) > 500) {
235
+ onDismiss();
236
+ }
237
+ },
238
+ className: "toastify-item absolute h-14 w-full select-none cursor-grab active:cursor-grabbing",
239
+ style: {
240
+ [isTop ? "top" : "bottom"]: 0,
241
+ left: 0,
242
+ right: 0
243
+ },
244
+ children
245
+ }
246
+ );
247
+ }
248
+ function FolderStackAnimation({
249
+ index,
250
+ isHovered,
251
+ position,
252
+ isDismissing,
253
+ onDismiss,
254
+ springConfig = defaultSpring,
255
+ children
256
+ }) {
257
+ const isTop = position.startsWith("top");
258
+ const isCenter = position.endsWith("center");
259
+ const isLeft = position.endsWith("left");
260
+ const collapsed = !isHovered;
261
+ const isVisible = !collapsed || index < 3;
262
+ const stackStep = 66;
263
+ const offset = collapsed ? index * 10 : index * stackStep;
264
+ const targetY = isTop ? offset : -offset;
265
+ const targetScale = collapsed ? Math.max(0.88, 1 - index * 0.05) : 1;
266
+ const targetOpacity = !isVisible ? 0 : collapsed ? index === 0 ? 1 : index === 1 ? 0.94 : 0.84 : 1;
267
+ const exitX = isCenter ? 0 : isLeft ? -36 : 36;
268
+ return /* @__PURE__ */ jsxRuntime.jsx(
269
+ react.motion.article,
270
+ {
271
+ role: "status",
272
+ "aria-live": "polite",
273
+ initial: {
274
+ opacity: 0,
275
+ x: 0,
276
+ y: isTop ? targetY - 14 : targetY + 14,
277
+ scale: 0.94
278
+ },
279
+ animate: {
280
+ opacity: isDismissing ? 0 : targetOpacity,
281
+ x: isDismissing ? exitX : 0,
282
+ y: targetY,
283
+ scale: isDismissing ? 0.94 : targetScale,
284
+ zIndex: 50 - index,
285
+ pointerEvents: !isDismissing && isVisible ? "auto" : "none"
286
+ },
287
+ exit: {
288
+ opacity: 0,
289
+ x: exitX,
290
+ scale: 0.94,
291
+ transition: {
292
+ duration: 0.24,
293
+ ease: [0.16, 1, 0.3, 1]
294
+ }
295
+ },
296
+ transition: {
297
+ type: "spring",
298
+ ...springConfig
299
+ },
300
+ drag: index === 0 || isHovered ? "x" : false,
301
+ dragConstraints: { left: 0, right: 0 },
302
+ dragElastic: 0.6,
303
+ onDragEnd: (_, info) => {
304
+ if (Math.abs(info.offset.x) > 60 || Math.abs(info.velocity.x) > 500) {
305
+ onDismiss();
306
+ }
307
+ },
308
+ className: "toastify-item absolute h-14 w-full select-none cursor-grab active:cursor-grabbing",
309
+ style: {
310
+ [isTop ? "top" : "bottom"]: 0,
311
+ left: 0,
312
+ right: 0,
313
+ transformOrigin: isTop ? "top center" : "bottom center"
314
+ },
315
+ children
316
+ }
317
+ );
318
+ }
319
+ function SlideAnimation({
320
+ index,
321
+ position,
322
+ isDismissing,
323
+ onDismiss,
324
+ springConfig = defaultSpring,
325
+ children
326
+ }) {
327
+ const isTop = position.startsWith("top");
328
+ const isCenter = position.endsWith("center");
329
+ const isLeft = position.endsWith("left");
330
+ const stackStep = 66;
331
+ const targetY = isTop ? index * stackStep : -index * stackStep;
332
+ const entryX = isCenter ? 0 : isLeft ? -120 : 120;
333
+ const exitX = isCenter ? 0 : isLeft ? -140 : 140;
334
+ const initialY = isCenter ? isTop ? targetY - 30 : targetY + 30 : targetY;
335
+ return /* @__PURE__ */ jsxRuntime.jsx(
336
+ react.motion.article,
337
+ {
338
+ role: "status",
339
+ "aria-live": "polite",
340
+ initial: {
341
+ opacity: 0,
342
+ x: entryX,
343
+ y: initialY,
344
+ scale: 0.95
345
+ },
346
+ animate: {
347
+ opacity: isDismissing ? 0 : 1,
348
+ x: isDismissing ? exitX : 0,
349
+ y: targetY,
350
+ scale: 1,
351
+ zIndex: 50 - index,
352
+ pointerEvents: !isDismissing ? "auto" : "none"
353
+ },
354
+ exit: {
355
+ opacity: 0,
356
+ x: exitX,
357
+ scale: 0.95,
358
+ transition: {
359
+ duration: 0.22,
360
+ ease: [0.16, 1, 0.3, 1]
361
+ }
362
+ },
363
+ transition: {
364
+ type: "spring",
365
+ ...springConfig
366
+ },
367
+ drag: "x",
368
+ dragConstraints: { left: 0, right: 0 },
369
+ dragElastic: 0.6,
370
+ onDragEnd: (_, info) => {
371
+ if (Math.abs(info.offset.x) > 60 || Math.abs(info.velocity.x) > 500) {
372
+ onDismiss();
373
+ }
374
+ },
375
+ className: "toastify-item absolute h-14 w-full select-none cursor-grab active:cursor-grabbing",
376
+ style: {
377
+ [isTop ? "top" : "bottom"]: 0,
378
+ left: 0,
379
+ right: 0
380
+ },
381
+ children
382
+ }
383
+ );
384
+ }
385
+ function ToastAnimation({
386
+ animation = "stack",
387
+ ...props
388
+ }) {
389
+ if (typeof animation === "function") {
390
+ const CustomAnimation = animation;
391
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomAnimation, { ...props });
392
+ }
393
+ if (animation === "slide") {
394
+ return /* @__PURE__ */ jsxRuntime.jsx(SlideAnimation, { ...props });
395
+ }
396
+ if (animation === "fade") {
397
+ return /* @__PURE__ */ jsxRuntime.jsx(FadeAnimation, { ...props });
398
+ }
399
+ return /* @__PURE__ */ jsxRuntime.jsx(FolderStackAnimation, { ...props });
400
+ }
401
+
402
+ // src/toastify/store.ts
403
+ var MAX_TOASTS = 30;
404
+ var toasts = [];
405
+ var listeners = /* @__PURE__ */ new Set();
406
+ function generateId() {
407
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
408
+ return crypto.randomUUID();
409
+ }
410
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
411
+ }
412
+ function sanitizeDuration(duration) {
413
+ if (duration === false) return false;
414
+ if (typeof duration === "number") {
415
+ return Number.isFinite(duration) && duration >= 0 ? duration : 3500;
416
+ }
417
+ return void 0;
418
+ }
419
+ function emit() {
420
+ const snapshot = [...toasts];
421
+ listeners.forEach((listener) => {
422
+ try {
423
+ listener(snapshot);
424
+ } catch (err) {
425
+ console.error("Toast listener threw an error:", err);
426
+ }
427
+ });
428
+ }
429
+ function subscribe(listener) {
430
+ listeners.add(listener);
431
+ try {
432
+ listener([...toasts]);
433
+ } catch (err) {
434
+ console.error("Initial toast listener threw an error:", err);
435
+ }
436
+ return () => {
437
+ listeners.delete(listener);
438
+ };
439
+ }
440
+ function remove(id) {
441
+ if (id) {
442
+ toasts = toasts.filter((toast2) => toast2.id !== id);
443
+ } else {
444
+ toasts = [];
445
+ }
446
+ emit();
447
+ }
448
+ function update(id, updates) {
449
+ toasts = toasts.map(
450
+ (toast2) => toast2.id === id ? { ...toast2, ...updates } : toast2
451
+ );
452
+ emit();
453
+ }
454
+ function create(type, title, options = {}) {
455
+ const id = options.id ?? generateId();
456
+ const duration = sanitizeDuration(options.autoClose ?? options.duration);
457
+ const existing = toasts.find((t) => t.id === id);
458
+ if (existing) {
459
+ update(id, {
460
+ type,
461
+ title,
462
+ description: options.description,
463
+ action: options.action,
464
+ cancel: options.cancel,
465
+ icon: options.icon,
466
+ className: options.className,
467
+ style: options.style,
468
+ duration
469
+ });
470
+ return id;
471
+ }
472
+ const toastItem = {
473
+ id,
474
+ type,
475
+ title,
476
+ description: options.description,
477
+ action: options.action,
478
+ cancel: options.cancel,
479
+ icon: options.icon,
480
+ className: options.className,
481
+ style: options.style,
482
+ duration,
483
+ createdAt: Date.now()
484
+ };
485
+ toasts = [toastItem, ...toasts].slice(0, MAX_TOASTS);
486
+ emit();
487
+ return id;
488
+ }
489
+ function promise(promiseOrFn, options) {
490
+ const id = create("loading", options.loading, {
491
+ duration: false
492
+ });
493
+ const p = typeof promiseOrFn === "function" ? promiseOrFn() : promiseOrFn;
494
+ const promiseChain = p.then((data) => {
495
+ let successTitle;
496
+ try {
497
+ successTitle = typeof options.success === "function" ? options.success(data) : options.success;
498
+ } catch {
499
+ successTitle = "Completed successfully";
500
+ }
501
+ let description;
502
+ if (options.description) {
503
+ try {
504
+ description = typeof options.description === "function" ? options.description(data) : options.description;
505
+ } catch {
506
+ description = void 0;
507
+ }
508
+ }
509
+ update(id, {
510
+ type: "success",
511
+ title: successTitle,
512
+ description,
513
+ action: options.action,
514
+ cancel: options.cancel,
515
+ duration: 3500
516
+ });
517
+ return data;
518
+ }).catch((err) => {
519
+ let errorTitle;
520
+ try {
521
+ errorTitle = typeof options.error === "function" ? options.error(err) : options.error;
522
+ } catch {
523
+ errorTitle = "An error occurred";
524
+ }
525
+ update(id, {
526
+ type: "error",
527
+ title: errorTitle,
528
+ action: options.action,
529
+ cancel: options.cancel,
530
+ duration: 4e3
531
+ });
532
+ return Promise.reject(err);
533
+ });
534
+ promiseChain.catch(() => {
535
+ });
536
+ return promiseChain;
537
+ }
538
+ var toastStore = {
539
+ subscribe,
540
+ remove,
541
+ update,
542
+ getToasts: () => [...toasts]
543
+ };
544
+ function toastFn(title, options) {
545
+ return create("neutral", title, options);
546
+ }
547
+ var toast = Object.assign(toastFn, {
548
+ show(title, options) {
549
+ return create("neutral", title, options);
550
+ },
551
+ success(title, options) {
552
+ return create("success", title, options);
553
+ },
554
+ error(title, options) {
555
+ return create("error", title, options);
556
+ },
557
+ warning(title, options) {
558
+ return create("warning", title, options);
559
+ },
560
+ info(title, options) {
561
+ return create("info", title, options);
562
+ },
563
+ loading(title, options) {
564
+ return create("loading", title, { ...options, duration: false });
565
+ },
566
+ custom(renderer, options = {}) {
567
+ const id = options.id ?? generateId();
568
+ const duration = sanitizeDuration(options.autoClose ?? options.duration);
569
+ const toastItem = {
570
+ id,
571
+ type: "custom",
572
+ title: "",
573
+ customRenderer: renderer,
574
+ duration,
575
+ className: options.className,
576
+ style: options.style,
577
+ createdAt: Date.now()
578
+ };
579
+ toasts = [toastItem, ...toasts].slice(0, MAX_TOASTS);
580
+ emit();
581
+ return id;
582
+ },
583
+ promise,
584
+ dismiss(id) {
585
+ remove(id);
586
+ },
587
+ update(id, options) {
588
+ update(id, options);
589
+ }
590
+ });
591
+
592
+ // src/toastify/styles.ts
593
+ var toastifyStyles = `
594
+ /* Toastify Standalone CSS */
595
+ @keyframes toastify-spin {
596
+ from {
597
+ transform: rotate(0deg);
598
+ }
599
+ to {
600
+ transform: rotate(360deg);
601
+ }
602
+ }
603
+
604
+ .toastify-spin {
605
+ animation: toastify-spin 1s linear infinite;
606
+ }
607
+
608
+ .toastify-toaster {
609
+ position: fixed;
610
+ z-index: 9999;
611
+ width: 356px;
612
+ max-width: calc(100vw - 32px);
613
+ box-sizing: border-box;
614
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
615
+ margin: 0;
616
+ padding: 0;
617
+ }
618
+
619
+ .toastify-toaster *,
620
+ .toastify-toaster *::before,
621
+ .toastify-toaster *::after {
622
+ box-sizing: border-box;
623
+ }
624
+
625
+ /* Positions */
626
+ .toastify-pos-top-left {
627
+ top: 24px;
628
+ left: 24px;
629
+ }
630
+ .toastify-pos-top-center {
631
+ top: 24px;
632
+ left: 0;
633
+ right: 0;
634
+ margin-left: auto;
635
+ margin-right: auto;
636
+ }
637
+ .toastify-pos-top-right {
638
+ top: 24px;
639
+ right: 24px;
640
+ }
641
+ .toastify-pos-bottom-left {
642
+ bottom: 24px;
643
+ left: 24px;
644
+ }
645
+ .toastify-pos-bottom-center {
646
+ bottom: 24px;
647
+ left: 0;
648
+ right: 0;
649
+ margin-left: auto;
650
+ margin-right: auto;
651
+ }
652
+ .toastify-pos-bottom-right {
653
+ bottom: 24px;
654
+ right: 24px;
655
+ }
656
+
657
+ .toastify-pointer-auto {
658
+ pointer-events: auto;
659
+ }
660
+ .toastify-pointer-none {
661
+ pointer-events: none;
662
+ }
663
+
664
+ /* Toast List Container */
665
+ .toastify-list {
666
+ position: relative;
667
+ width: 100%;
668
+ height: 100%;
669
+ display: flex;
670
+ }
671
+ .toastify-list-col {
672
+ flex-direction: column;
673
+ }
674
+ .toastify-list-col-reverse {
675
+ flex-direction: column-reverse;
676
+ }
677
+
678
+ /* Individual Toast Item wrapper */
679
+ .toastify-item {
680
+ position: absolute;
681
+ height: 56px;
682
+ width: 100%;
683
+ user-select: none;
684
+ cursor: grab;
685
+ }
686
+ .toastify-item:active {
687
+ cursor: grabbing;
688
+ }
689
+
690
+ /* Toast Card with Tactile Micro-bevels */
691
+ .toastify-toast {
692
+ display: flex;
693
+ height: 56px;
694
+ width: 100%;
695
+ user-select: none;
696
+ align-items: center;
697
+ justify-content: space-between;
698
+ gap: 12px;
699
+ border-radius: 8px;
700
+ padding: 0 14px;
701
+ box-sizing: border-box;
702
+ transition: background-color 0.2s cubic-bezier(0.16, 1, 0.3, 1),
703
+ border-color 0.2s cubic-bezier(0.16, 1, 0.3, 1),
704
+ box-shadow 0.2s cubic-bezier(0.16, 1, 0.3, 1),
705
+ color 0.2s cubic-bezier(0.16, 1, 0.3, 1);
706
+
707
+ /* Light theme default */
708
+ background-color: #ffffff;
709
+ border: 1px solid rgba(229, 231, 235, 0.9);
710
+ color: #111827;
711
+ box-shadow: 0 4px 12px -2px rgba(0, 0, 0, 0.08), 0 2px 6px -1px rgba(0, 0, 0, 0.04);
712
+ }
713
+
714
+ /* Dark theme overrides */
715
+ .toastify-toaster.dark .toastify-toast,
716
+ [data-theme="dark"] .toastify-toast,
717
+ .dark .toastify-toast {
718
+ background-color: #171717;
719
+ border: 1px solid rgba(38, 38, 38, 0.9);
720
+ color: #f5f5f5;
721
+ box-shadow: 0 4px 14px -2px rgba(0, 0, 0, 0.4), 0 2px 6px -1px rgba(0, 0, 0, 0.25);
722
+ }
723
+
724
+ /* System dark theme preference when theme="system" */
725
+ @media (prefers-color-scheme: dark) {
726
+ .toastify-toaster.system .toastify-toast {
727
+ background-color: #171717;
728
+ border: 1px solid rgba(38, 38, 38, 0.9);
729
+ color: #f5f5f5;
730
+ box-shadow: 0 4px 14px -2px rgba(0, 0, 0, 0.4), 0 2px 6px -1px rgba(0, 0, 0, 0.25);
731
+ }
732
+ .toastify-toaster.system .toastify-badge {
733
+ background-color: #ffffff;
734
+ color: #0a0a0a;
735
+ }
736
+ .toastify-toaster.system .toastify-title {
737
+ color: #f5f5f5;
738
+ }
739
+ .toastify-toaster.system .toastify-description {
740
+ color: #a3a3a3;
741
+ }
742
+ .toastify-toaster.system .toastify-btn-cancel {
743
+ color: #a3a3a3;
744
+ }
745
+ .toastify-toaster.system .toastify-btn-cancel:hover {
746
+ background-color: #262626;
747
+ color: #f5f5f5;
748
+ }
749
+ .toastify-toaster.system .toastify-btn-action {
750
+ background-color: #f5f5f5;
751
+ color: #171717;
752
+ box-shadow: inset 0 -2px 4px rgba(0, 0, 0, 0.22), 0 1px 2px rgba(0, 0, 0, 0.15);
753
+ }
754
+ .toastify-toaster.system .toastify-btn-action:hover {
755
+ background-color: #e5e5e5;
756
+ }
757
+ }
758
+
759
+ /* Badge Icon Wrapper */
760
+ .toastify-badge {
761
+ display: flex;
762
+ height: 20px;
763
+ width: 20px;
764
+ flex-shrink: 0;
765
+ align-items: center;
766
+ justify-content: center;
767
+ border-radius: 9999px;
768
+ background-color: #171717;
769
+ color: #ffffff;
770
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
771
+ }
772
+
773
+ .toastify-toaster.dark .toastify-badge,
774
+ [data-theme="dark"] .toastify-badge,
775
+ .dark .toastify-badge {
776
+ background-color: #ffffff;
777
+ color: #0a0a0a;
778
+ }
779
+
780
+ /* Content Area */
781
+ .toastify-content {
782
+ display: flex;
783
+ min-width: 0;
784
+ flex: 1 1 0%;
785
+ align-items: center;
786
+ gap: 12px;
787
+ }
788
+
789
+ .toastify-text-group {
790
+ display: flex;
791
+ min-width: 0;
792
+ flex-direction: column;
793
+ justify-content: center;
794
+ }
795
+
796
+ .toastify-title {
797
+ overflow: hidden;
798
+ text-overflow: ellipsis;
799
+ white-space: nowrap;
800
+ font-size: 13px;
801
+ font-weight: 500;
802
+ line-height: 16px;
803
+ color: #171717;
804
+ }
805
+
806
+ .toastify-toaster.dark .toastify-title,
807
+ [data-theme="dark"] .toastify-title,
808
+ .dark .toastify-title {
809
+ color: #f5f5f5;
810
+ }
811
+
812
+ .toastify-description {
813
+ margin-top: 2px;
814
+ overflow: hidden;
815
+ text-overflow: ellipsis;
816
+ white-space: nowrap;
817
+ font-size: 12px;
818
+ line-height: 16px;
819
+ color: #737373;
820
+ }
821
+
822
+ .toastify-toaster.dark .toastify-description,
823
+ [data-theme="dark"] .toastify-description,
824
+ .dark .toastify-description {
825
+ color: #a3a3a3;
826
+ }
827
+
828
+ /* Action Area */
829
+ .toastify-actions {
830
+ display: flex;
831
+ flex-shrink: 0;
832
+ align-items: center;
833
+ gap: 8px;
834
+ }
835
+
836
+ .toastify-btn-cancel {
837
+ cursor: pointer;
838
+ border: none;
839
+ background: transparent;
840
+ border-radius: 4px;
841
+ padding: 4px 8px;
842
+ font-size: 12px;
843
+ font-weight: 500;
844
+ color: #525252;
845
+ transition: background-color 0.15s, color 0.15s;
846
+ }
847
+
848
+ .toastify-btn-cancel:hover {
849
+ background-color: #f5f5f5;
850
+ color: #171717;
851
+ }
852
+
853
+ .toastify-toaster.dark .toastify-btn-cancel,
854
+ [data-theme="dark"] .toastify-btn-cancel,
855
+ .dark .toastify-btn-cancel {
856
+ color: #a3a3a3;
857
+ }
858
+
859
+ .toastify-toaster.dark .toastify-btn-cancel:hover,
860
+ [data-theme="dark"] .toastify-btn-cancel:hover,
861
+ .dark .toastify-btn-cancel:hover {
862
+ background-color: #262626;
863
+ color: #f5f5f5;
864
+ }
865
+
866
+ .toastify-btn-action {
867
+ cursor: pointer;
868
+ border: none;
869
+ border-radius: 4px;
870
+ padding: 4px 10px;
871
+ font-size: 12px;
872
+ font-weight: 500;
873
+ background-color: #171717;
874
+ color: #ffffff;
875
+ transition: background-color 0.15s, box-shadow 0.15s;
876
+ box-shadow: inset 0 -2px 4px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.08);
877
+ }
878
+
879
+ .toastify-btn-action:hover {
880
+ background-color: #262626;
881
+ }
882
+
883
+ .toastify-btn-action:active {
884
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.4);
885
+ }
886
+
887
+ .toastify-toaster.dark .toastify-btn-action,
888
+ [data-theme="dark"] .toastify-btn-action,
889
+ .dark .toastify-btn-action {
890
+ background-color: #f5f5f5;
891
+ color: #171717;
892
+ box-shadow: inset 0 -2px 4px rgba(0, 0, 0, 0.22), 0 1px 2px rgba(0, 0, 0, 0.15);
893
+ }
894
+
895
+ .toastify-toaster.dark .toastify-btn-action:hover,
896
+ [data-theme="dark"] .toastify-btn-action:hover,
897
+ .dark .toastify-btn-action:hover {
898
+ background-color: #e5e5e5;
899
+ }
900
+
901
+ .toastify-toaster.dark .toastify-btn-action:active,
902
+ [data-theme="dark"] .toastify-btn-action:active,
903
+ .dark .toastify-btn-action:active {
904
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25);
905
+ }
906
+ `;
907
+ var positionClasses = {
908
+ "top-left": "toastify-pos-top-left top-6 left-6",
909
+ "top-center": "toastify-pos-top-center top-6 left-0 right-0 mx-auto",
910
+ "top-right": "toastify-pos-top-right top-6 right-6",
911
+ "bottom-left": "toastify-pos-bottom-left bottom-6 left-6",
912
+ "bottom-center": "toastify-pos-bottom-center bottom-6 left-0 right-0 mx-auto",
913
+ "bottom-right": "toastify-pos-bottom-right bottom-6 right-6"
914
+ };
915
+ function ToasterItem({
916
+ toast: toast2,
917
+ index,
918
+ totalToasts,
919
+ isHovered,
920
+ position,
921
+ duration = 3500,
922
+ autoClose,
923
+ closeOnClick = false,
924
+ animation = "stack",
925
+ springConfig,
926
+ icons,
927
+ toastOptions,
928
+ onDismiss
929
+ }) {
930
+ const itemDuration = toast2.type === "loading" ? false : toast2.duration !== void 0 ? toast2.duration : toastOptions?.duration !== void 0 ? toastOptions.duration : autoClose ?? duration;
931
+ const onDismissRef = react$1.useRef(onDismiss);
932
+ react$1.useEffect(() => {
933
+ onDismissRef.current = onDismiss;
934
+ }, [onDismiss]);
935
+ const [isDismissing, setIsDismissing] = react$1.useState(false);
936
+ const handleDismiss = () => {
937
+ setIsDismissing(true);
938
+ onDismissRef.current();
939
+ };
940
+ const remainingTimeRef = react$1.useRef(itemDuration);
941
+ react$1.useEffect(() => {
942
+ remainingTimeRef.current = itemDuration;
943
+ }, [itemDuration]);
944
+ react$1.useEffect(() => {
945
+ if (itemDuration === false || isHovered) {
946
+ return;
947
+ }
948
+ const startTime = Date.now();
949
+ const currentRemaining = remainingTimeRef.current === false ? itemDuration : remainingTimeRef.current;
950
+ const timer = window.setTimeout(() => {
951
+ handleDismiss();
952
+ }, currentRemaining);
953
+ return () => {
954
+ window.clearTimeout(timer);
955
+ if (remainingTimeRef.current !== false) {
956
+ const elapsed = Date.now() - startTime;
957
+ remainingTimeRef.current = Math.max(0, remainingTimeRef.current - elapsed);
958
+ }
959
+ };
960
+ }, [isHovered, itemDuration]);
961
+ return /* @__PURE__ */ jsxRuntime.jsx(
962
+ ToastAnimation,
963
+ {
964
+ animation,
965
+ toast: toast2,
966
+ index,
967
+ totalToasts,
968
+ isHovered,
969
+ position,
970
+ isDismissing,
971
+ onDismiss: handleDismiss,
972
+ springConfig,
973
+ children: /* @__PURE__ */ jsxRuntime.jsx(
974
+ Toast,
975
+ {
976
+ toast: toast2,
977
+ onDismiss: handleDismiss,
978
+ closeOnClick,
979
+ globalIcons: icons,
980
+ globalOptions: toastOptions
981
+ }
982
+ )
983
+ }
984
+ );
985
+ }
986
+ function Toaster({
987
+ position = "bottom-right",
988
+ duration = 3500,
989
+ autoClose,
990
+ theme = "light",
991
+ className,
992
+ style,
993
+ visibleToasts = 5,
994
+ closeOnClick = false,
995
+ animation = "stack",
996
+ springConfig,
997
+ icons,
998
+ unstyled = false,
999
+ toastOptions
1000
+ }) {
1001
+ const [toasts2, setToasts] = react$1.useState([]);
1002
+ const [isHovered, setIsHovered] = react$1.useState(false);
1003
+ const [hoverExpandedCount, setHoverExpandedCount] = react$1.useState(null);
1004
+ const leaveTimeoutRef = react$1.useRef(null);
1005
+ react$1.useEffect(() => toastStore.subscribe(setToasts), []);
1006
+ const isTop = position.startsWith("top");
1007
+ const hasToasts = toasts2.length > 0;
1008
+ const activeCount = Math.min(toasts2.length, visibleToasts);
1009
+ const effectiveCount = isHovered && hoverExpandedCount !== null ? Math.max(activeCount, hoverExpandedCount) : activeCount;
1010
+ const containerHeight = hasToasts && isHovered && effectiveCount > 0 ? (effectiveCount - 1) * 66 + 56 : 56;
1011
+ const handleMouseEnter = () => {
1012
+ if (leaveTimeoutRef.current) {
1013
+ window.clearTimeout(leaveTimeoutRef.current);
1014
+ leaveTimeoutRef.current = null;
1015
+ }
1016
+ setHoverExpandedCount((prev) => Math.max(prev ?? 0, activeCount));
1017
+ setIsHovered(true);
1018
+ };
1019
+ const handleMouseLeave = () => {
1020
+ leaveTimeoutRef.current = window.setTimeout(() => {
1021
+ setIsHovered(false);
1022
+ setHoverExpandedCount(null);
1023
+ }, 140);
1024
+ };
1025
+ react$1.useEffect(() => {
1026
+ return () => {
1027
+ if (leaveTimeoutRef.current) {
1028
+ window.clearTimeout(leaveTimeoutRef.current);
1029
+ }
1030
+ };
1031
+ }, []);
1032
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1033
+ !unstyled && /* @__PURE__ */ jsxRuntime.jsx(
1034
+ "style",
1035
+ {
1036
+ "data-toastify-styles": "",
1037
+ dangerouslySetInnerHTML: { __html: toastifyStyles }
1038
+ }
1039
+ ),
1040
+ /* @__PURE__ */ jsxRuntime.jsx(
1041
+ react.motion.div,
1042
+ {
1043
+ "data-toastify-toaster": "true",
1044
+ role: "region",
1045
+ "aria-label": "Notifications",
1046
+ "aria-live": "polite",
1047
+ tabIndex: -1,
1048
+ className: `toastify-toaster fixed z-50 w-[356px] max-w-[calc(100vw-32px)] ${hasToasts ? "toastify-pointer-auto pointer-events-auto" : "toastify-pointer-none pointer-events-none"} ${positionClasses[position]} ${theme === "dark" ? "dark" : theme === "system" ? "system" : ""} ${className ?? ""}`,
1049
+ style,
1050
+ animate: {
1051
+ height: containerHeight
1052
+ },
1053
+ transition: {
1054
+ type: "spring",
1055
+ stiffness: 220,
1056
+ damping: 26,
1057
+ mass: 1,
1058
+ ...springConfig
1059
+ },
1060
+ onMouseEnter: handleMouseEnter,
1061
+ onMouseLeave: handleMouseLeave,
1062
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1063
+ "div",
1064
+ {
1065
+ className: `toastify-list relative w-full h-full flex ${isTop ? "toastify-list-col flex-col" : "toastify-list-col-reverse flex-col-reverse"}`,
1066
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: toasts2.slice(0, visibleToasts).map((toastItem, index) => /* @__PURE__ */ jsxRuntime.jsx(
1067
+ ToasterItem,
1068
+ {
1069
+ toast: toastItem,
1070
+ index,
1071
+ totalToasts: toasts2.length,
1072
+ isHovered,
1073
+ position,
1074
+ duration,
1075
+ autoClose,
1076
+ closeOnClick,
1077
+ animation,
1078
+ springConfig,
1079
+ icons,
1080
+ toastOptions,
1081
+ onDismiss: () => toastStore.remove(toastItem.id)
1082
+ },
1083
+ toastItem.id
1084
+ )) })
1085
+ }
1086
+ )
1087
+ }
1088
+ )
1089
+ ] });
1090
+ }
1091
+ var ToastContainer = Toaster;
1092
+
1093
+ exports.DefaultToastIcon = DefaultToastIcon;
1094
+ exports.FadeAnimation = FadeAnimation;
1095
+ exports.FolderStackAnimation = FolderStackAnimation;
1096
+ exports.SlideAnimation = SlideAnimation;
1097
+ exports.Toast = Toast;
1098
+ exports.ToastAnimation = ToastAnimation;
1099
+ exports.ToastContainer = ToastContainer;
1100
+ exports.Toaster = Toaster;
1101
+ exports.defaultSpring = defaultSpring;
1102
+ exports.toast = toast;
1103
+ exports.toastStore = toastStore;
1104
+ exports.toastifyStyles = toastifyStyles;