@enigmax/primitives 0.21.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/chunk-3BQVOOAM.js +388 -0
  2. package/dist/{chunk-QQFNAKMY.js → chunk-45UHLZYT.js} +1 -1
  3. package/dist/chunk-4VUHQFAT.js +130 -0
  4. package/dist/{chunk-D5A2ZMAG.js → chunk-4ZPMP47J.js} +6 -1
  5. package/dist/chunk-DSBYVA7V.js +713 -0
  6. package/dist/{chunk-FWVWX67R.js → chunk-FGBIZDV2.js} +3 -3
  7. package/dist/{chunk-R4ZAEE7V.js → chunk-KEVZ5XQV.js} +1 -1
  8. package/dist/chunk-N6PDHMAX.js +213 -0
  9. package/dist/chunk-NONGREXC.js +248 -0
  10. package/dist/chunk-VKL3DEIQ.js +804 -0
  11. package/dist/chunk-WPTBURIC.js +1627 -0
  12. package/dist/chunk-WSQC3PCC.js +466 -0
  13. package/dist/context-menu-D3FtTn7v.d.ts +174 -0
  14. package/dist/{index-dTdAbOWl.d.ts → index-DQNnohoo.d.ts} +1 -1
  15. package/dist/index.d.ts +5 -1
  16. package/dist/index.js +8 -4
  17. package/dist/keys-D2zJs1uB.d.ts +100 -0
  18. package/dist/next/index.d.ts +12 -5
  19. package/dist/next/index.js +21 -14
  20. package/dist/react/button.d.ts +2 -2
  21. package/dist/react/context-menu.d.ts +202 -0
  22. package/dist/react/context-menu.js +6 -0
  23. package/dist/react/index.d.ts +11 -4
  24. package/dist/react/index.js +20 -13
  25. package/dist/react/input.d.ts +2 -2
  26. package/dist/react/input.js +1 -1
  27. package/dist/react/palette.d.ts +1 -1
  28. package/dist/react/palette.js +3 -3
  29. package/dist/react/search.d.ts +1 -1
  30. package/dist/react/search.js +2 -2
  31. package/dist/react/select.d.ts +217 -0
  32. package/dist/react/select.js +7 -0
  33. package/dist/react/selection.d.ts +104 -0
  34. package/dist/react/selection.js +4 -0
  35. package/dist/react/slot.d.ts +2 -2
  36. package/dist/react/toast.d.ts +165 -32
  37. package/dist/react/toast.js +1 -1
  38. package/dist/react-router/index.d.ts +12 -5
  39. package/dist/react-router/index.js +21 -14
  40. package/dist/search/index.d.ts +2 -2
  41. package/dist/search/index.js +1 -1
  42. package/dist/{search-DXxY8SEH.d.ts → search-DYgqRp37.d.ts} +20 -3
  43. package/dist/{search-UQEXAPQB.js → search-PBZORZ7P.js} +1 -1
  44. package/dist/select-ClSy-J1f.d.ts +100 -0
  45. package/dist/selection-B_pmzHpy.d.ts +150 -0
  46. package/package.json +21 -2
  47. package/recipes/context-menu/styles.css +177 -0
  48. package/recipes/input/styles.css +9 -0
  49. package/recipes/palette/styles.css +3 -0
  50. package/recipes/search/tailwind.tsx +3 -2
  51. package/recipes/select/styles.css +230 -0
  52. package/recipes/toast/styles.css +688 -192
  53. package/registry.json +434 -29
  54. package/src/core/context-menu.ts +694 -0
  55. package/src/core/keys.ts +264 -0
  56. package/src/core/search.ts +25 -1
  57. package/src/core/select.ts +404 -0
  58. package/src/core/selection.ts +648 -0
  59. package/src/index.ts +60 -1
  60. package/src/react/context-menu/context.ts +57 -0
  61. package/src/react/context-menu/index.tsx +94 -0
  62. package/src/react/context-menu/root.tsx +846 -0
  63. package/src/react/context-menu/styles.ts +186 -0
  64. package/src/react/index.ts +70 -2
  65. package/src/react/palette/root.tsx +2 -2
  66. package/src/react/select/context.ts +56 -0
  67. package/src/react/select/index.tsx +96 -0
  68. package/src/react/select/root.tsx +839 -0
  69. package/src/react/select/styles.ts +238 -0
  70. package/src/react/selection/index.tsx +115 -0
  71. package/src/react/selection/use-selection.ts +260 -0
  72. package/src/react/toast/NOTICE +20 -0
  73. package/src/react/toast/assets.tsx +85 -0
  74. package/src/react/toast/cn.ts +10 -0
  75. package/src/react/toast/hooks.ts +13 -0
  76. package/src/react/toast/index.tsx +736 -0
  77. package/src/react/toast/state.ts +207 -0
  78. package/src/react/toast/styles.ts +738 -0
  79. package/src/react/toast/types.ts +193 -0
  80. package/src/react/toaster.tsx +76 -341
  81. package/dist/chunk-JCCL7XKC.js +0 -465
  82. package/src/react/toast-styles.ts +0 -247
  83. /package/dist/{chunk-U3V4EHOB.js → chunk-3HDEZ2E7.js} +0 -0
@@ -0,0 +1,1627 @@
1
+ import { defaultQueue } from './chunk-QYMUIW5I.js';
2
+ import React3, { forwardRef, isValidElement, useLayoutEffect, useRef, useEffect } from 'react';
3
+ import ReactDOM from 'react-dom';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+
6
+ // src/react/toast/styles.ts
7
+ var TOAST_STYLES = `:where(html[dir="ltr"]),
8
+ :where([data-toastcmp-toaster][dir="ltr"]) {
9
+ --toast-icon-margin-start: -3px;
10
+ --toast-icon-margin-end: 4px;
11
+ --toast-svg-margin-start: -1px;
12
+ --toast-svg-margin-end: 0px;
13
+ --toast-button-margin-start: auto;
14
+ --toast-button-margin-end: 0;
15
+ --toast-close-button-start: 0;
16
+ --toast-close-button-end: unset;
17
+ --toast-close-button-transform: translate(-35%, -35%);
18
+ }
19
+
20
+ :where(html[dir="rtl"]),
21
+ :where([data-toastcmp-toaster][dir="rtl"]) {
22
+ --toast-icon-margin-start: 4px;
23
+ --toast-icon-margin-end: -3px;
24
+ --toast-svg-margin-start: 0px;
25
+ --toast-svg-margin-end: -1px;
26
+ --toast-button-margin-start: 0;
27
+ --toast-button-margin-end: auto;
28
+ --toast-close-button-start: unset;
29
+ --toast-close-button-end: 0;
30
+ --toast-close-button-transform: translate(35%, -35%);
31
+ }
32
+
33
+ :where([data-toastcmp-toaster]) {
34
+ position: fixed;
35
+ width: var(--width);
36
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial,
37
+ Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
38
+ --gray1: hsl(0, 0%, 99%);
39
+ --gray2: hsl(0, 0%, 97.3%);
40
+ --gray3: hsl(0, 0%, 95.1%);
41
+ --gray4: hsl(0, 0%, 93%);
42
+ --gray5: hsl(0, 0%, 90.9%);
43
+ --gray6: hsl(0, 0%, 88.7%);
44
+ --gray7: hsl(0, 0%, 85.8%);
45
+ --gray8: hsl(0, 0%, 78%);
46
+ --gray9: hsl(0, 0%, 56.1%);
47
+ --gray10: hsl(0, 0%, 52.3%);
48
+ --gray11: hsl(0, 0%, 43.5%);
49
+ --gray12: hsl(0, 0%, 9%);
50
+ --border-radius: 8px;
51
+ box-sizing: border-box;
52
+ padding: 0;
53
+ margin: 0;
54
+ list-style: none;
55
+ outline: none;
56
+ z-index: 999999999;
57
+ transition: transform 400ms ease;
58
+ }
59
+
60
+ :where([data-toastcmp-toaster][data-lifted="true"]) {
61
+ transform: translateY(-10px);
62
+ }
63
+
64
+ @media (hover: none) and (pointer: coarse) {
65
+ :where([data-toastcmp-toaster][data-lifted="true"]) {
66
+ transform: none;
67
+ }
68
+ }
69
+
70
+ :where([data-toastcmp-toaster][data-x-position="right"]) {
71
+ right: var(--offset-right);
72
+ }
73
+
74
+ :where([data-toastcmp-toaster][data-x-position="left"]) {
75
+ left: var(--offset-left);
76
+ }
77
+
78
+ :where([data-toastcmp-toaster][data-x-position="center"]) {
79
+ left: 50%;
80
+ transform: translateX(-50%);
81
+ }
82
+
83
+ :where([data-toastcmp-toaster][data-y-position="top"]) {
84
+ top: var(--offset-top);
85
+ }
86
+
87
+ :where([data-toastcmp-toaster][data-y-position="bottom"]) {
88
+ bottom: var(--offset-bottom);
89
+ }
90
+
91
+ :where([data-toastcmp-toast]) {
92
+ --y: translateY(100%);
93
+ --lift-amount: calc(var(--lift) * var(--gap));
94
+ z-index: var(--z-index);
95
+ position: absolute;
96
+ opacity: 0;
97
+ transform: var(--y);
98
+ filter: blur(0);
99
+ /* https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not */
100
+ touch-action: none;
101
+ transition: transform 400ms, opacity 400ms, height 400ms, box-shadow 200ms;
102
+ box-sizing: border-box;
103
+ outline: none;
104
+ overflow-wrap: anywhere;
105
+ }
106
+
107
+ :where([data-toastcmp-toast][data-styled="true"]) {
108
+ padding: 16px;
109
+ background: var(--normal-bg);
110
+ border: 1px solid var(--normal-border);
111
+ color: var(--normal-text);
112
+ border-radius: var(--border-radius);
113
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
114
+ width: var(--width);
115
+ font-size: 13px;
116
+ display: flex;
117
+ align-items: center;
118
+ gap: 6px;
119
+ }
120
+
121
+ :where([data-toastcmp-toast]:focus-visible) {
122
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1), 0 0 0 2px rgba(0, 0, 0, 0.2);
123
+ }
124
+
125
+ :where([data-toastcmp-toast][data-y-position="top"]) {
126
+ top: 0;
127
+ --y: translateY(-100%);
128
+ --lift: 1;
129
+ --lift-amount: calc(1 * var(--gap));
130
+ }
131
+
132
+ :where([data-toastcmp-toast][data-y-position="bottom"]) {
133
+ bottom: 0;
134
+ --y: translateY(100%);
135
+ --lift: -1;
136
+ --lift-amount: calc(var(--lift) * var(--gap));
137
+ }
138
+
139
+ :where([data-toastcmp-toast]) :where([data-description]) {
140
+ font-weight: 400;
141
+ line-height: 1.4;
142
+ color: inherit;
143
+ }
144
+
145
+ :where([data-toastcmp-toast]) :where([data-title]) {
146
+ font-weight: 500;
147
+ line-height: 1.5;
148
+ color: inherit;
149
+ }
150
+
151
+ :where([data-toastcmp-toast]) :where([data-icon]) {
152
+ display: flex;
153
+ height: 16px;
154
+ width: 16px;
155
+ position: relative;
156
+ justify-content: flex-start;
157
+ align-items: center;
158
+ flex-shrink: 0;
159
+ margin-left: var(--toast-icon-margin-start);
160
+ margin-right: var(--toast-icon-margin-end);
161
+ }
162
+
163
+ :where([data-toastcmp-toast][data-promise="true"]) :where([data-icon])>svg {
164
+ opacity: 0;
165
+ transform: scale(0.8);
166
+ transform-origin: center;
167
+ animation: toastcmp-fade-in 300ms ease forwards;
168
+ }
169
+
170
+ :where([data-toastcmp-toast]) :where([data-icon])>* {
171
+ flex-shrink: 0;
172
+ }
173
+
174
+ :where([data-toastcmp-toast]) :where([data-icon]) svg {
175
+ margin-left: var(--toast-svg-margin-start);
176
+ margin-right: var(--toast-svg-margin-end);
177
+ }
178
+
179
+ :where([data-toastcmp-toast]) :where([data-content]) {
180
+ display: flex;
181
+ flex-direction: column;
182
+ gap: 2px;
183
+ }
184
+
185
+ [data-toastcmp-toast][data-styled="true"] [data-button] {
186
+ border-radius: 4px;
187
+ padding-left: 8px;
188
+ padding-right: 8px;
189
+ height: 24px;
190
+ font-size: 12px;
191
+ color: var(--normal-bg);
192
+ background: var(--normal-text);
193
+ margin-left: var(--toast-button-margin-start);
194
+ margin-right: var(--toast-button-margin-end);
195
+ border: none;
196
+ cursor: pointer;
197
+ outline: none;
198
+ display: flex;
199
+ align-items: center;
200
+ flex-shrink: 0;
201
+ transition: opacity 400ms, box-shadow 200ms;
202
+ }
203
+
204
+ :where([data-toastcmp-toast]) :where([data-button]):focus-visible {
205
+ box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.4);
206
+ }
207
+
208
+ :where([data-toastcmp-toast]) :where([data-button]):first-of-type {
209
+ margin-left: var(--toast-button-margin-start);
210
+ margin-right: var(--toast-button-margin-end);
211
+ }
212
+
213
+ :where([data-toastcmp-toast]) :where([data-cancel]) {
214
+ color: var(--normal-text);
215
+ background: rgba(0, 0, 0, 0.08);
216
+ }
217
+
218
+ :where([data-toastcmp-toast][data-theme="dark"]) :where([data-cancel]) {
219
+ background: rgba(255, 255, 255, 0.3);
220
+ }
221
+
222
+ :where([data-toastcmp-toast]) :where([data-close-button]) {
223
+ position: absolute;
224
+ left: var(--toast-close-button-start);
225
+ right: var(--toast-close-button-end);
226
+ top: 0;
227
+ height: 20px;
228
+ width: 20px;
229
+ display: flex;
230
+ justify-content: center;
231
+ align-items: center;
232
+ padding: 0;
233
+ color: var(--gray12);
234
+ border: 1px solid var(--gray4);
235
+ transform: var(--toast-close-button-transform);
236
+ border-radius: 50%;
237
+ cursor: pointer;
238
+ z-index: 1;
239
+ transition: opacity 100ms, background 200ms, border-color 200ms;
240
+ }
241
+
242
+ [data-toastcmp-toast] [data-close-button] {
243
+ background: var(--gray1);
244
+ }
245
+
246
+ :where([data-toastcmp-toast]) :where([data-close-button]):focus-visible {
247
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1), 0 0 0 2px rgba(0, 0, 0, 0.2);
248
+ }
249
+
250
+ :where([data-toastcmp-toast]) :where([data-disabled="true"]) {
251
+ cursor: not-allowed;
252
+ }
253
+
254
+ :where([data-toastcmp-toast]):hover :where([data-close-button]):hover {
255
+ background: var(--gray2);
256
+ border-color: var(--gray5);
257
+ }
258
+
259
+ /* Leave a ghost div to avoid setting hover to false when swiping out */
260
+ :where([data-toastcmp-toast][data-swiping="true"])::before {
261
+ content: "";
262
+ position: absolute;
263
+ left: -50%;
264
+ right: -50%;
265
+ height: 100%;
266
+ z-index: -1;
267
+ }
268
+
269
+ :where([data-toastcmp-toast][data-y-position="top"][data-swiping="true"])::before {
270
+ /* y 50% needed to distribute height additional height evenly */
271
+ bottom: 50%;
272
+ transform: scaleY(3) translateY(50%);
273
+ }
274
+
275
+ :where([data-toastcmp-toast][data-y-position="bottom"][data-swiping="true"])::before {
276
+ /* y -50% needed to distribute height additional height evenly */
277
+ top: 50%;
278
+ transform: scaleY(3) translateY(-50%);
279
+ }
280
+
281
+ /* Leave a ghost div to avoid setting hover to false when transitioning out */
282
+ :where([data-toastcmp-toast][data-swiping="false"][data-removed="true"])::before {
283
+ content: "";
284
+ position: absolute;
285
+ inset: 0;
286
+ transform: scaleY(2);
287
+ }
288
+
289
+ /* Needed to avoid setting hover to false when inbetween toasts */
290
+ :where([data-toastcmp-toast])::after {
291
+ content: "";
292
+ position: absolute;
293
+ left: 0;
294
+ height: calc(var(--gap) + 1px);
295
+ bottom: 100%;
296
+ width: 100%;
297
+ }
298
+
299
+ :where([data-toastcmp-toast][data-mounted="true"]) {
300
+ --y: translateY(0);
301
+ opacity: 1;
302
+ }
303
+
304
+ :where([data-toastcmp-toast][data-expanded="false"][data-front="false"]) {
305
+ --scale: var(--toasts-before) * 0.05 + 1;
306
+ --y: translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)));
307
+ height: var(--front-toast-height);
308
+ }
309
+
310
+ :where([data-toastcmp-toast])>* {
311
+ transition: opacity 400ms;
312
+ }
313
+
314
+ :where([data-toastcmp-toast][data-expanded="false"][data-front="false"][data-styled="true"])>* {
315
+ opacity: 0;
316
+ }
317
+
318
+ :where([data-toastcmp-toast][data-visible="false"]) {
319
+ opacity: 0;
320
+ pointer-events: none;
321
+ }
322
+
323
+ :where([data-toastcmp-toast][data-mounted="true"][data-expanded="true"]) {
324
+ --y: translateY(calc(var(--lift) * var(--offset)));
325
+ height: var(--initial-height);
326
+ }
327
+
328
+ :where([data-toastcmp-toast][data-removed="true"][data-front="true"][data-swipe-out="false"]) {
329
+ --y: translateY(calc(var(--lift) * -100%));
330
+ opacity: 0;
331
+ }
332
+
333
+ :where([data-toastcmp-toast][data-removed="true"][data-front="false"][data-swipe-out="false"][data-expanded="true"]) {
334
+ --y: translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%));
335
+ opacity: 0;
336
+ }
337
+
338
+ :where([data-toastcmp-toast][data-removed="true"][data-front="false"][data-swipe-out="false"][data-expanded="false"]) {
339
+ --y: translateY(40%);
340
+ opacity: 0;
341
+ transition: transform 500ms, opacity 200ms;
342
+ }
343
+
344
+ /* Bump up the height to make sure hover state doesn"t get set to false */
345
+ :where([data-toastcmp-toast][data-removed="true"][data-front="false"])::before {
346
+ height: calc(var(--initial-height) + 20%);
347
+ }
348
+
349
+ [data-toastcmp-toast][data-swiping="true"] {
350
+ transform: var(--y) translateY(var(--swipe-amount-y, 0px)) translateX(var(--swipe-amount-x, 0px));
351
+ transition: none;
352
+ }
353
+
354
+ [data-toastcmp-toast][data-swiped="true"] {
355
+ user-select: none;
356
+ }
357
+
358
+ [data-toastcmp-toast][data-swipe-out="true"][data-y-position="bottom"],
359
+ [data-toastcmp-toast][data-swipe-out="true"][data-y-position="top"] {
360
+ animation-duration: 200ms;
361
+ animation-timing-function: ease-out;
362
+ animation-fill-mode: forwards;
363
+ }
364
+
365
+ [data-toastcmp-toast][data-swipe-out="true"][data-swipe-direction="left"] {
366
+ animation-name: swipe-out-left;
367
+ }
368
+
369
+ [data-toastcmp-toast][data-swipe-out="true"][data-swipe-direction="right"] {
370
+ animation-name: swipe-out-right;
371
+ }
372
+
373
+ [data-toastcmp-toast][data-swipe-out="true"][data-swipe-direction="up"] {
374
+ animation-name: swipe-out-up;
375
+ }
376
+
377
+ [data-toastcmp-toast][data-swipe-out="true"][data-swipe-direction="down"] {
378
+ animation-name: swipe-out-down;
379
+ }
380
+
381
+ @keyframes swipe-out-left {
382
+ from {
383
+ transform: var(--y) translateX(var(--swipe-amount-x));
384
+ opacity: 1;
385
+ }
386
+
387
+ to {
388
+ transform: var(--y) translateX(calc(var(--swipe-amount-x) - 100%));
389
+ opacity: 0;
390
+ }
391
+ }
392
+
393
+ @keyframes swipe-out-right {
394
+ from {
395
+ transform: var(--y) translateX(var(--swipe-amount-x));
396
+ opacity: 1;
397
+ }
398
+
399
+ to {
400
+ transform: var(--y) translateX(calc(var(--swipe-amount-x) + 100%));
401
+ opacity: 0;
402
+ }
403
+ }
404
+
405
+ @keyframes swipe-out-up {
406
+ from {
407
+ transform: var(--y) translateY(var(--swipe-amount-y));
408
+ opacity: 1;
409
+ }
410
+
411
+ to {
412
+ transform: var(--y) translateY(calc(var(--swipe-amount-y) - 100%));
413
+ opacity: 0;
414
+ }
415
+ }
416
+
417
+ @keyframes swipe-out-down {
418
+ from {
419
+ transform: var(--y) translateY(var(--swipe-amount-y));
420
+ opacity: 1;
421
+ }
422
+
423
+ to {
424
+ transform: var(--y) translateY(calc(var(--swipe-amount-y) + 100%));
425
+ opacity: 0;
426
+ }
427
+ }
428
+
429
+ @media (max-width: 600px) {
430
+ [data-toastcmp-toaster] {
431
+ position: fixed;
432
+ right: var(--mobile-offset-right);
433
+ left: var(--mobile-offset-left);
434
+ width: 100%;
435
+ }
436
+
437
+ [data-toastcmp-toaster][dir="rtl"] {
438
+ left: calc(var(--mobile-offset-left) * -1);
439
+ }
440
+
441
+ [data-toastcmp-toaster] [data-toastcmp-toast] {
442
+ left: 0;
443
+ right: 0;
444
+ width: calc(100% - var(--mobile-offset-left) * 2);
445
+ }
446
+
447
+ [data-toastcmp-toaster][data-x-position="left"] {
448
+ left: var(--mobile-offset-left);
449
+ }
450
+
451
+ [data-toastcmp-toaster][data-y-position="bottom"] {
452
+ bottom: var(--mobile-offset-bottom);
453
+ }
454
+
455
+ [data-toastcmp-toaster][data-y-position="top"] {
456
+ top: var(--mobile-offset-top);
457
+ }
458
+
459
+ [data-toastcmp-toaster][data-x-position="center"] {
460
+ left: var(--mobile-offset-left);
461
+ right: var(--mobile-offset-right);
462
+ transform: none;
463
+ }
464
+ }
465
+
466
+ [data-toastcmp-toaster][data-theme="light"] {
467
+ --normal-bg: #fff;
468
+ --normal-border: var(--gray4);
469
+ --normal-text: var(--gray12);
470
+
471
+ --success-bg: hsl(143, 85%, 96%);
472
+ --success-border: hsl(145, 92%, 91%);
473
+ --success-text: hsl(140, 100%, 27%);
474
+
475
+ --info-bg: hsl(208, 100%, 97%);
476
+ --info-border: hsl(221, 91%, 91%);
477
+ --info-text: hsl(210, 92%, 45%);
478
+
479
+ --warning-bg: hsl(49, 100%, 97%);
480
+ --warning-border: hsl(49, 91%, 91%);
481
+ --warning-text: hsl(31, 92%, 45%);
482
+
483
+ --error-bg: hsl(359, 100%, 97%);
484
+ --error-border: hsl(359, 100%, 94%);
485
+ --error-text: hsl(360, 100%, 45%);
486
+ }
487
+
488
+ [data-toastcmp-toaster][data-theme="light"] [data-toastcmp-toast][data-invert="true"] {
489
+ --normal-bg: #000;
490
+ --normal-border: hsl(0, 0%, 20%);
491
+ --normal-text: var(--gray1);
492
+ }
493
+
494
+ [data-toastcmp-toaster][data-theme="dark"] [data-toastcmp-toast][data-invert="true"] {
495
+ --normal-bg: #fff;
496
+ --normal-border: var(--gray3);
497
+ --normal-text: var(--gray12);
498
+ }
499
+
500
+ [data-toastcmp-toaster][data-theme="dark"] {
501
+ --normal-bg: #000;
502
+ --normal-bg-hover: hsl(0, 0%, 12%);
503
+ --normal-border: hsl(0, 0%, 20%);
504
+ --normal-border-hover: hsl(0, 0%, 25%);
505
+ --normal-text: var(--gray1);
506
+
507
+ --success-bg: hsl(150, 100%, 6%);
508
+ --success-border: hsl(147, 100%, 12%);
509
+ --success-text: hsl(150, 86%, 65%);
510
+
511
+ --info-bg: hsl(215, 100%, 6%);
512
+ --info-border: hsl(223, 100%, 12%);
513
+ --info-text: hsl(216, 87%, 65%);
514
+
515
+ --warning-bg: hsl(64, 100%, 6%);
516
+ --warning-border: hsl(60, 100%, 12%);
517
+ --warning-text: hsl(46, 87%, 65%);
518
+
519
+ --error-bg: hsl(358, 76%, 10%);
520
+ --error-border: hsl(357, 89%, 16%);
521
+ --error-text: hsl(358, 100%, 81%);
522
+ }
523
+
524
+ [data-toastcmp-toaster][data-theme="dark"] [data-toastcmp-toast] [data-close-button] {
525
+ background: var(--normal-bg);
526
+ border-color: var(--normal-border);
527
+ color: var(--normal-text);
528
+ }
529
+
530
+ [data-toastcmp-toaster][data-theme="dark"] [data-toastcmp-toast] [data-close-button]:hover {
531
+ background: var(--normal-bg-hover);
532
+ border-color: var(--normal-border-hover);
533
+ }
534
+
535
+ [data-rich-colors="true"][data-toastcmp-toast][data-type="success"] {
536
+ background: var(--success-bg);
537
+ border-color: var(--success-border);
538
+ color: var(--success-text);
539
+ }
540
+
541
+ [data-rich-colors="true"][data-toastcmp-toast][data-type="success"] [data-close-button] {
542
+ background: var(--success-bg);
543
+ border-color: var(--success-border);
544
+ color: var(--success-text);
545
+ }
546
+
547
+ [data-rich-colors="true"][data-toastcmp-toast][data-type="info"] {
548
+ background: var(--info-bg);
549
+ border-color: var(--info-border);
550
+ color: var(--info-text);
551
+ }
552
+
553
+ [data-rich-colors="true"][data-toastcmp-toast][data-type="info"] [data-close-button] {
554
+ background: var(--info-bg);
555
+ border-color: var(--info-border);
556
+ color: var(--info-text);
557
+ }
558
+
559
+ [data-rich-colors="true"][data-toastcmp-toast][data-type="warning"] {
560
+ background: var(--warning-bg);
561
+ border-color: var(--warning-border);
562
+ color: var(--warning-text);
563
+ }
564
+
565
+ [data-rich-colors="true"][data-toastcmp-toast][data-type="warning"] [data-close-button] {
566
+ background: var(--warning-bg);
567
+ border-color: var(--warning-border);
568
+ color: var(--warning-text);
569
+ }
570
+
571
+ [data-rich-colors="true"][data-toastcmp-toast][data-type="error"] {
572
+ background: var(--error-bg);
573
+ border-color: var(--error-border);
574
+ color: var(--error-text);
575
+ }
576
+
577
+ [data-rich-colors="true"][data-toastcmp-toast][data-type="error"] [data-close-button] {
578
+ background: var(--error-bg);
579
+ border-color: var(--error-border);
580
+ color: var(--error-text);
581
+ }
582
+
583
+ .toastcmp-loading-wrapper {
584
+ --size: 16px;
585
+ height: var(--size);
586
+ width: var(--size);
587
+ position: absolute;
588
+ inset: 0;
589
+ z-index: 10;
590
+ }
591
+
592
+ .toastcmp-loading-wrapper[data-visible="false"] {
593
+ transform-origin: center;
594
+ animation: toastcmp-fade-out 0.2s ease forwards;
595
+ }
596
+
597
+ .toastcmp-spinner {
598
+ position: relative;
599
+ top: 50%;
600
+ left: 50%;
601
+ height: var(--size);
602
+ width: var(--size);
603
+ }
604
+
605
+ .toastcmp-loading-bar {
606
+ animation: toastcmp-spin 1.2s linear infinite;
607
+ background: var(--gray11);
608
+ border-radius: 6px;
609
+ height: 8%;
610
+ left: -10%;
611
+ position: absolute;
612
+ top: -3.9%;
613
+ width: 24%;
614
+ }
615
+
616
+ .toastcmp-loading-bar:nth-child(1) {
617
+ animation-delay: -1.2s;
618
+ transform: rotate(0.0001deg) translate(146%);
619
+ }
620
+
621
+ .toastcmp-loading-bar:nth-child(2) {
622
+ animation-delay: -1.1s;
623
+ transform: rotate(30deg) translate(146%);
624
+ }
625
+
626
+ .toastcmp-loading-bar:nth-child(3) {
627
+ animation-delay: -1s;
628
+ transform: rotate(60deg) translate(146%);
629
+ }
630
+
631
+ .toastcmp-loading-bar:nth-child(4) {
632
+ animation-delay: -0.9s;
633
+ transform: rotate(90deg) translate(146%);
634
+ }
635
+
636
+ .toastcmp-loading-bar:nth-child(5) {
637
+ animation-delay: -0.8s;
638
+ transform: rotate(120deg) translate(146%);
639
+ }
640
+
641
+ .toastcmp-loading-bar:nth-child(6) {
642
+ animation-delay: -0.7s;
643
+ transform: rotate(150deg) translate(146%);
644
+ }
645
+
646
+ .toastcmp-loading-bar:nth-child(7) {
647
+ animation-delay: -0.6s;
648
+ transform: rotate(180deg) translate(146%);
649
+ }
650
+
651
+ .toastcmp-loading-bar:nth-child(8) {
652
+ animation-delay: -0.5s;
653
+ transform: rotate(210deg) translate(146%);
654
+ }
655
+
656
+ .toastcmp-loading-bar:nth-child(9) {
657
+ animation-delay: -0.4s;
658
+ transform: rotate(240deg) translate(146%);
659
+ }
660
+
661
+ .toastcmp-loading-bar:nth-child(10) {
662
+ animation-delay: -0.3s;
663
+ transform: rotate(270deg) translate(146%);
664
+ }
665
+
666
+ .toastcmp-loading-bar:nth-child(11) {
667
+ animation-delay: -0.2s;
668
+ transform: rotate(300deg) translate(146%);
669
+ }
670
+
671
+ .toastcmp-loading-bar:nth-child(12) {
672
+ animation-delay: -0.1s;
673
+ transform: rotate(330deg) translate(146%);
674
+ }
675
+
676
+ @keyframes toastcmp-fade-in {
677
+ 0% {
678
+ opacity: 0;
679
+ transform: scale(0.8);
680
+ }
681
+
682
+ 100% {
683
+ opacity: 1;
684
+ transform: scale(1);
685
+ }
686
+ }
687
+
688
+ @keyframes toastcmp-fade-out {
689
+ 0% {
690
+ opacity: 1;
691
+ transform: scale(1);
692
+ }
693
+
694
+ 100% {
695
+ opacity: 0;
696
+ transform: scale(0.8);
697
+ }
698
+ }
699
+
700
+ @keyframes toastcmp-spin {
701
+ 0% {
702
+ opacity: 1;
703
+ }
704
+
705
+ 100% {
706
+ opacity: 0.15;
707
+ }
708
+ }
709
+
710
+ @media (prefers-reduced-motion) {
711
+
712
+ [data-toastcmp-toast],
713
+ [data-toastcmp-toast]>*,
714
+ .toastcmp-loading-bar {
715
+ transition: none !important;
716
+ animation: none !important;
717
+ }
718
+ }
719
+
720
+ .toastcmp-loader {
721
+ position: absolute;
722
+ top: 50%;
723
+ left: 50%;
724
+ transform: translate(-50%, -50%);
725
+ transform-origin: center;
726
+ transition: opacity 200ms, transform 200ms;
727
+ }
728
+
729
+ .toastcmp-loader[data-visible="false"] {
730
+ opacity: 0;
731
+ transform: scale(0.8) translate(-50%, -50%);
732
+ }`;
733
+ var toastsCounter = 1;
734
+ var Observer = class {
735
+ subscribers;
736
+ toasts;
737
+ constructor() {
738
+ this.subscribers = [];
739
+ this.toasts = [];
740
+ }
741
+ // We use arrow functions to maintain the correct `this` reference.
742
+ subscribe = (subscriber) => {
743
+ this.subscribers.push(subscriber);
744
+ return () => {
745
+ const index = this.subscribers.indexOf(subscriber);
746
+ this.subscribers.splice(index, 1);
747
+ };
748
+ };
749
+ publish = (data) => {
750
+ this.subscribers.forEach((subscriber) => subscriber(data));
751
+ };
752
+ addToast = (data) => {
753
+ this.publish(data);
754
+ this.toasts = [...this.toasts, data];
755
+ };
756
+ create = (data) => {
757
+ const { message, ...rest } = data;
758
+ const id = typeof data?.id === "number" || typeof data?.id === "string" && data.id?.length > 0 ? data.id : toastsCounter++;
759
+ const alreadyExists = this.toasts.find((toast2) => toast2.id === id);
760
+ const dismissible = data.dismissible === void 0 ? true : data.dismissible;
761
+ if (alreadyExists) {
762
+ this.toasts = this.toasts.map((toast2) => {
763
+ if (toast2.id === id) {
764
+ this.publish({ ...toast2, ...data, id, title: message });
765
+ return {
766
+ ...toast2,
767
+ ...data,
768
+ id,
769
+ dismissible,
770
+ title: message
771
+ };
772
+ }
773
+ return toast2;
774
+ });
775
+ } else this.addToast({ title: message, ...rest, dismissible, id });
776
+ return id;
777
+ };
778
+ dismiss = (id) => {
779
+ if (!id) this.toasts.forEach((toast2) => this.subscribers.forEach((subscriber) => subscriber({ id: toast2.id, dismiss: true })));
780
+ this.subscribers.forEach((subscriber) => subscriber({ id, dismiss: true }));
781
+ return id;
782
+ };
783
+ message = (message, data) => {
784
+ return this.create({ ...data, message });
785
+ };
786
+ error = (message, data) => {
787
+ return this.create({ ...data, message, type: "error" });
788
+ };
789
+ success = (message, data) => {
790
+ return this.create({ ...data, type: "success", message });
791
+ };
792
+ info = (message, data) => {
793
+ return this.create({ ...data, type: "info", message });
794
+ };
795
+ warning = (message, data) => {
796
+ return this.create({ ...data, type: "warning", message });
797
+ };
798
+ loading = (message, data) => {
799
+ return this.create({ ...data, type: "loading", message });
800
+ };
801
+ promise = (promise, data) => {
802
+ if (!data) return;
803
+ let id = void 0;
804
+ if (data.loading !== void 0) {
805
+ id = this.create({
806
+ ...data,
807
+ promise,
808
+ type: "loading",
809
+ message: data.loading,
810
+ description: typeof data.description !== "function" ? data.description : void 0
811
+ });
812
+ }
813
+ const p = promise instanceof Promise ? promise : promise();
814
+ let shouldDismiss = id !== void 0;
815
+ let result;
816
+ const originalPromise = p.then(async (response) => {
817
+ result = ["resolve", response];
818
+ const isReactElementResponse = React3.isValidElement(response);
819
+ if (isReactElementResponse) {
820
+ shouldDismiss = false;
821
+ this.create({ id, type: "default", message: response });
822
+ } else if (isHttpResponse(response) && !response.ok) {
823
+ shouldDismiss = false;
824
+ const message = typeof data.error === "function" ? await data.error(`HTTP error! status: ${response.status}`) : data.error;
825
+ const description = typeof data.description === "function" ? await data.description(`HTTP error! status: ${response.status}`) : data.description;
826
+ this.create({ id, type: "error", message, description });
827
+ } else if (data.success !== void 0) {
828
+ shouldDismiss = false;
829
+ const message = typeof data.success === "function" ? await data.success(response) : data.success;
830
+ const description = typeof data.description === "function" ? await data.description(response) : data.description;
831
+ this.create({ id, type: "success", message, description });
832
+ }
833
+ }).catch(async (error) => {
834
+ result = ["reject", error];
835
+ if (data.error !== void 0) {
836
+ shouldDismiss = false;
837
+ const message = typeof data.error === "function" ? await data.error(error) : data.error;
838
+ const description = typeof data.description === "function" ? await data.description(error) : data.description;
839
+ this.create({ id, type: "error", message, description });
840
+ }
841
+ }).finally(() => {
842
+ if (shouldDismiss) {
843
+ this.dismiss(id);
844
+ id = void 0;
845
+ }
846
+ data.finally?.();
847
+ });
848
+ const unwrap = () => new Promise((resolve, reject) => originalPromise.then(() => result[0] === "reject" ? reject(result[1]) : resolve(result[1])).catch(reject));
849
+ if (typeof id !== "string" && typeof id !== "number") return { unwrap };
850
+ else return Object.assign(id, { unwrap });
851
+ };
852
+ custom = (jsx4, data) => {
853
+ const id = data?.id || toastsCounter++;
854
+ this.create({ jsx: jsx4(id), id, ...data });
855
+ return id;
856
+ };
857
+ };
858
+ var ToastState = new Observer();
859
+ var toastFunction = (message, data) => {
860
+ const id = data?.id || toastsCounter++;
861
+ ToastState.addToast({
862
+ title: message,
863
+ ...data,
864
+ id
865
+ });
866
+ return id;
867
+ };
868
+ var isHttpResponse = (data) => {
869
+ return data && typeof data === "object" && "ok" in data && typeof data.ok === "boolean" && "status" in data && typeof data.status === "number";
870
+ };
871
+ var basicToast = toastFunction;
872
+ var getHistory = () => ToastState.toasts;
873
+ var toast = Object.assign(
874
+ basicToast,
875
+ {
876
+ success: ToastState.success,
877
+ info: ToastState.info,
878
+ warning: ToastState.warning,
879
+ error: ToastState.error,
880
+ custom: ToastState.custom,
881
+ message: ToastState.message,
882
+ promise: ToastState.promise,
883
+ dismiss: ToastState.dismiss,
884
+ loading: ToastState.loading
885
+ },
886
+ { getHistory }
887
+ );
888
+
889
+ // src/react/toast/cn.ts
890
+ function cn(...classes) {
891
+ return classes.filter(Boolean).join(" ");
892
+ }
893
+ var useIsDocumentHidden = () => {
894
+ const [isDocumentHidden, setIsDocumentHidden] = React3.useState(document.hidden);
895
+ React3.useEffect(() => {
896
+ const callback = () => setIsDocumentHidden(document.hidden);
897
+ document.addEventListener("visibilitychange", callback);
898
+ return () => window.removeEventListener("visibilitychange", callback);
899
+ }, []);
900
+ return isDocumentHidden;
901
+ };
902
+ var getAsset = (type) => {
903
+ switch (type) {
904
+ case "success":
905
+ return SuccessIcon;
906
+ case "info":
907
+ return InfoIcon;
908
+ case "warning":
909
+ return WarningIcon;
910
+ case "error":
911
+ return ErrorIcon;
912
+ default:
913
+ return null;
914
+ }
915
+ };
916
+ var bars = Array(12).fill(0);
917
+ var Loader = ({ visible, className }) => {
918
+ return /* @__PURE__ */ jsx("div", { className: ["toastcmp-loading-wrapper", className].filter(Boolean).join(" "), "data-visible": visible, children: /* @__PURE__ */ jsx("div", { className: "toastcmp-spinner", children: bars.map((_, i) => /* @__PURE__ */ jsx("div", { className: "toastcmp-loading-bar" }, `spinner-bar-${i}`)) }) });
919
+ };
920
+ var SuccessIcon = /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", height: "20", width: "20", children: /* @__PURE__ */ jsx(
921
+ "path",
922
+ {
923
+ fillRule: "evenodd",
924
+ d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z",
925
+ clipRule: "evenodd"
926
+ }
927
+ ) });
928
+ var WarningIcon = /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", height: "20", width: "20", children: /* @__PURE__ */ jsx(
929
+ "path",
930
+ {
931
+ fillRule: "evenodd",
932
+ d: "M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z",
933
+ clipRule: "evenodd"
934
+ }
935
+ ) });
936
+ var InfoIcon = /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", height: "20", width: "20", children: /* @__PURE__ */ jsx(
937
+ "path",
938
+ {
939
+ fillRule: "evenodd",
940
+ d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z",
941
+ clipRule: "evenodd"
942
+ }
943
+ ) });
944
+ var ErrorIcon = /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", height: "20", width: "20", children: /* @__PURE__ */ jsx(
945
+ "path",
946
+ {
947
+ fillRule: "evenodd",
948
+ d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z",
949
+ clipRule: "evenodd"
950
+ }
951
+ ) });
952
+ var CloseIcon = /* @__PURE__ */ jsxs(
953
+ "svg",
954
+ {
955
+ xmlns: "http://www.w3.org/2000/svg",
956
+ width: "12",
957
+ height: "12",
958
+ viewBox: "0 0 24 24",
959
+ fill: "none",
960
+ stroke: "currentColor",
961
+ strokeWidth: "1.5",
962
+ strokeLinecap: "round",
963
+ strokeLinejoin: "round",
964
+ children: [
965
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
966
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
967
+ ]
968
+ }
969
+ );
970
+
971
+ // src/react/toast/types.ts
972
+ function isAction(action) {
973
+ return action.label !== void 0;
974
+ }
975
+ var VISIBLE_TOASTS_AMOUNT = 3;
976
+ var VIEWPORT_OFFSET = "32px";
977
+ var MOBILE_VIEWPORT_OFFSET = "16px";
978
+ var TOAST_LIFETIME = 4e3;
979
+ var TOAST_WIDTH = 356;
980
+ var GAP = 14;
981
+ var SWIPE_THRESHOLD = 20;
982
+ var TIME_BEFORE_UNMOUNT = 200;
983
+ function getDefaultSwipeDirections(position) {
984
+ const [y, x] = position.split("-");
985
+ const directions = [];
986
+ if (y) directions.push(y);
987
+ if (x) directions.push(x);
988
+ return directions;
989
+ }
990
+ var Toast = (props) => {
991
+ const {
992
+ invert: ToasterInvert,
993
+ toast: toast2,
994
+ unstyled,
995
+ interacting,
996
+ setHeights,
997
+ visibleToasts,
998
+ heights,
999
+ index,
1000
+ toasts,
1001
+ expanded,
1002
+ removeToast,
1003
+ defaultRichColors,
1004
+ closeButton: closeButtonFromToaster,
1005
+ style,
1006
+ cancelButtonStyle,
1007
+ actionButtonStyle,
1008
+ className = "",
1009
+ descriptionClassName = "",
1010
+ duration: durationFromToaster,
1011
+ position,
1012
+ gap,
1013
+ loadingIcon: loadingIconProp,
1014
+ expandByDefault,
1015
+ classNames,
1016
+ icons,
1017
+ closeButtonAriaLabel = "Close toast",
1018
+ pauseWhenPageIsHidden
1019
+ } = props;
1020
+ const [swipeDirection, setSwipeDirection] = React3.useState(null);
1021
+ const [swipeOutDirection, setSwipeOutDirection] = React3.useState(null);
1022
+ const [mounted, setMounted] = React3.useState(false);
1023
+ const [removed, setRemoved] = React3.useState(false);
1024
+ const [swiping, setSwiping] = React3.useState(false);
1025
+ const [swipeOut, setSwipeOut] = React3.useState(false);
1026
+ const [isSwiped, setIsSwiped] = React3.useState(false);
1027
+ const [offsetBeforeRemove, setOffsetBeforeRemove] = React3.useState(0);
1028
+ const [initialHeight, setInitialHeight] = React3.useState(0);
1029
+ const remainingTime = React3.useRef(toast2.duration || durationFromToaster || TOAST_LIFETIME);
1030
+ const dragStartTime = React3.useRef(null);
1031
+ const toastRef = React3.useRef(null);
1032
+ const isFront = index === 0;
1033
+ const isVisible = index + 1 <= visibleToasts;
1034
+ const toastType = toast2.type;
1035
+ const dismissible = toast2.dismissible !== false;
1036
+ const toastClassname = toast2.className || "";
1037
+ const toastDescriptionClassname = toast2.descriptionClassName || "";
1038
+ const heightIndex = React3.useMemo(() => heights.findIndex((height) => height.toastId === toast2.id) || 0, [heights, toast2.id]);
1039
+ const closeButton = React3.useMemo(() => toast2.closeButton ?? closeButtonFromToaster, [toast2.closeButton, closeButtonFromToaster]);
1040
+ const duration = React3.useMemo(() => toast2.duration || durationFromToaster || TOAST_LIFETIME, [toast2.duration, durationFromToaster]);
1041
+ const closeTimerStartTimeRef = React3.useRef(0);
1042
+ const offset = React3.useRef(0);
1043
+ const lastCloseTimerStartTimeRef = React3.useRef(0);
1044
+ const pointerStartRef = React3.useRef(null);
1045
+ const [y, x] = position.split("-");
1046
+ const toastsHeightBefore = React3.useMemo(() => {
1047
+ return heights.reduce((prev, curr, reducerIndex) => {
1048
+ if (reducerIndex >= heightIndex) return prev;
1049
+ return prev + curr.height;
1050
+ }, 0);
1051
+ }, [heights, heightIndex]);
1052
+ const isDocumentHidden = useIsDocumentHidden();
1053
+ const invert = toast2.invert || ToasterInvert;
1054
+ const disabled = toastType === "loading";
1055
+ offset.current = React3.useMemo(() => heightIndex * (gap ?? 0) + toastsHeightBefore, [heightIndex, gap, toastsHeightBefore]);
1056
+ React3.useEffect(() => {
1057
+ remainingTime.current = duration;
1058
+ }, [duration]);
1059
+ React3.useEffect(() => setMounted(true), []);
1060
+ React3.useEffect(() => {
1061
+ const toastNode = toastRef.current;
1062
+ if (toastNode) {
1063
+ const height = toastNode.getBoundingClientRect().height;
1064
+ setInitialHeight(height);
1065
+ setHeights((h) => [{ toastId: toast2.id, height, position: toast2.position }, ...h]);
1066
+ return () => setHeights((h) => h.filter((height2) => height2.toastId !== toast2.id));
1067
+ }
1068
+ }, [setHeights, toast2.id]);
1069
+ React3.useLayoutEffect(() => {
1070
+ if (!mounted) return;
1071
+ const toastNode = toastRef.current;
1072
+ const originalHeight = toastNode?.style.height || "";
1073
+ if (toastNode) toastNode.style.height = "auto";
1074
+ const newHeight = toastNode?.getBoundingClientRect().height;
1075
+ if (toastNode) toastNode.style.height = originalHeight;
1076
+ setInitialHeight(newHeight);
1077
+ setHeights((heights2) => {
1078
+ const alreadyExists = heights2.find((height) => height.toastId === toast2.id);
1079
+ if (!alreadyExists) return [{ toastId: toast2.id, height: newHeight, position: toast2.position }, ...heights2];
1080
+ else return heights2.map((height) => height.toastId === toast2.id ? { ...height, height: newHeight } : height);
1081
+ });
1082
+ }, [mounted, toast2.title, toast2.description, setHeights, toast2.id]);
1083
+ const deleteToast = React3.useCallback(() => {
1084
+ setRemoved(true);
1085
+ setOffsetBeforeRemove(offset.current);
1086
+ setHeights((h) => h.filter((height) => height.toastId !== toast2.id));
1087
+ setTimeout(() => removeToast(toast2), TIME_BEFORE_UNMOUNT);
1088
+ }, [toast2, removeToast, setHeights, offset]);
1089
+ React3.useEffect(() => {
1090
+ if (toast2.promise && toastType === "loading" || toast2.duration === Infinity || toast2.type === "loading") return;
1091
+ let timeoutId;
1092
+ const pauseTimer = () => {
1093
+ if (lastCloseTimerStartTimeRef.current < closeTimerStartTimeRef.current) remainingTime.current = remainingTime.current - (/* @__PURE__ */ new Date()).getTime() - closeTimerStartTimeRef.current;
1094
+ lastCloseTimerStartTimeRef.current = (/* @__PURE__ */ new Date()).getTime();
1095
+ };
1096
+ const startTimer = () => {
1097
+ if (remainingTime.current === Infinity) return;
1098
+ closeTimerStartTimeRef.current = (/* @__PURE__ */ new Date()).getTime();
1099
+ timeoutId = setTimeout(() => {
1100
+ toast2.onAutoClose?.(toast2);
1101
+ deleteToast();
1102
+ }, remainingTime.current);
1103
+ };
1104
+ if (expanded || interacting || pauseWhenPageIsHidden && isDocumentHidden) pauseTimer();
1105
+ else startTimer();
1106
+ return () => clearTimeout(timeoutId);
1107
+ }, [expanded, interacting, toast2, toastType, pauseWhenPageIsHidden, isDocumentHidden, deleteToast]);
1108
+ React3.useEffect(() => {
1109
+ if (toast2.delete) deleteToast();
1110
+ }, [deleteToast, toast2.delete]);
1111
+ function getLoadingIcon() {
1112
+ if (icons?.loading) {
1113
+ return /* @__PURE__ */ jsx(
1114
+ "div",
1115
+ {
1116
+ className: cn(classNames?.loader, toast2?.classNames?.loader, "toastcmp-loader"),
1117
+ "data-visible": toastType === "loading",
1118
+ children: icons.loading
1119
+ }
1120
+ );
1121
+ }
1122
+ if (loadingIconProp) {
1123
+ return /* @__PURE__ */ jsx(
1124
+ "div",
1125
+ {
1126
+ className: cn(classNames?.loader, toast2?.classNames?.loader, "toastcmp-loader"),
1127
+ "data-visible": toastType === "loading",
1128
+ children: loadingIconProp
1129
+ }
1130
+ );
1131
+ }
1132
+ return /* @__PURE__ */ jsx(Loader, { className: cn(classNames?.loader, toast2?.classNames?.loader), visible: toastType === "loading" });
1133
+ }
1134
+ return /* @__PURE__ */ jsxs(
1135
+ "li",
1136
+ {
1137
+ tabIndex: 0,
1138
+ ref: toastRef,
1139
+ className: cn(
1140
+ className,
1141
+ toastClassname,
1142
+ classNames?.toast,
1143
+ toast2?.classNames?.toast,
1144
+ classNames?.default,
1145
+ //@ts-ignore
1146
+ classNames?.[toastType],
1147
+ //@ts-ignore
1148
+ toast2?.classNames?.[toastType]
1149
+ ),
1150
+ "data-toastcmp-toast": true,
1151
+ "data-rich-colors": toast2.richColors ?? defaultRichColors ?? true,
1152
+ "data-styled": !Boolean(toast2.jsx || toast2.unstyled || unstyled),
1153
+ "data-mounted": mounted,
1154
+ "data-promise": Boolean(toast2.promise),
1155
+ "data-swiped": isSwiped,
1156
+ "data-removed": removed,
1157
+ "data-visible": isVisible,
1158
+ "data-y-position": y,
1159
+ "data-x-position": x,
1160
+ "data-index": index,
1161
+ "data-front": isFront,
1162
+ "data-swiping": swiping,
1163
+ "data-dismissible": dismissible,
1164
+ "data-type": toastType,
1165
+ "data-invert": invert,
1166
+ "data-swipe-out": swipeOut,
1167
+ "data-swipe-direction": swipeOutDirection,
1168
+ "data-expanded": Boolean(expanded || expandByDefault && mounted),
1169
+ style: {
1170
+ "--index": index,
1171
+ "--toasts-before": index,
1172
+ "--z-index": toasts.length - index,
1173
+ "--offset": `${removed ? offsetBeforeRemove : offset.current}px`,
1174
+ "--initial-height": expandByDefault ? "auto" : `${initialHeight}px`,
1175
+ ...style,
1176
+ ...toast2.style
1177
+ },
1178
+ onPointerDown: (event) => {
1179
+ if (disabled || !dismissible) return;
1180
+ dragStartTime.current = /* @__PURE__ */ new Date();
1181
+ setOffsetBeforeRemove(offset.current);
1182
+ event.target.setPointerCapture(event.pointerId);
1183
+ if (event.target.tagName === "BUTTON") return;
1184
+ setSwiping(true);
1185
+ pointerStartRef.current = { x: event.clientX, y: event.clientY };
1186
+ },
1187
+ onPointerUp: () => {
1188
+ if (swipeOut || !dismissible) return;
1189
+ pointerStartRef.current = null;
1190
+ const swipeAmountX = Number(toastRef.current?.style.getPropertyValue("--swipe-amount-x").replace("px", "") || 0);
1191
+ const swipeAmountY = Number(toastRef.current?.style.getPropertyValue("--swipe-amount-y").replace("px", "") || 0);
1192
+ const timeTaken = (/* @__PURE__ */ new Date()).getTime() - (dragStartTime.current?.getTime() || 0);
1193
+ const swipeAmount = swipeDirection === "x" ? swipeAmountX : swipeAmountY;
1194
+ const velocity = Math.abs(swipeAmount) / timeTaken;
1195
+ if (Math.abs(swipeAmount) >= SWIPE_THRESHOLD || velocity > 0.11) {
1196
+ setOffsetBeforeRemove(offset.current);
1197
+ toast2.onDismiss?.(toast2);
1198
+ if (swipeDirection === "x") setSwipeOutDirection(swipeAmountX > 0 ? "right" : "left");
1199
+ else setSwipeOutDirection(swipeAmountY > 0 ? "down" : "up");
1200
+ deleteToast();
1201
+ setSwipeOut(true);
1202
+ setIsSwiped(false);
1203
+ return;
1204
+ }
1205
+ setSwiping(false);
1206
+ setSwipeDirection(null);
1207
+ },
1208
+ onPointerMove: (event) => {
1209
+ if (!pointerStartRef.current || !dismissible) return;
1210
+ const selection = window.getSelection();
1211
+ const isHighlighted = selection ? selection.toString().length > 0 : false;
1212
+ if (isHighlighted) return;
1213
+ const yDelta = event.clientY - pointerStartRef.current.y;
1214
+ const xDelta = event.clientX - pointerStartRef.current.x;
1215
+ const swipeDirections = props.swipeDirections ?? getDefaultSwipeDirections(position);
1216
+ if (!swipeDirection && (Math.abs(xDelta) > 1 || Math.abs(yDelta) > 1)) setSwipeDirection(Math.abs(xDelta) > Math.abs(yDelta) ? "x" : "y");
1217
+ let swipeAmount = { x: 0, y: 0 };
1218
+ if (swipeDirection === "y") {
1219
+ if (swipeDirections.includes("top") || swipeDirections.includes("bottom")) {
1220
+ if (swipeDirections.includes("top") && yDelta < 0) swipeAmount.y = yDelta;
1221
+ else if (swipeDirections.includes("bottom") && yDelta > 0) swipeAmount.y = yDelta;
1222
+ }
1223
+ } else if (swipeDirection === "x") {
1224
+ if (swipeDirections.includes("left") || swipeDirections.includes("right")) {
1225
+ if (swipeDirections.includes("left") && xDelta < 0) swipeAmount.x = xDelta;
1226
+ else if (swipeDirections.includes("right") && xDelta > 0) swipeAmount.x = xDelta;
1227
+ }
1228
+ }
1229
+ if (Math.abs(swipeAmount.x) > 0 || Math.abs(swipeAmount.y) > 0) setIsSwiped(true);
1230
+ toastRef.current?.style.setProperty("--swipe-amount-x", `${swipeAmount.x}px`);
1231
+ toastRef.current?.style.setProperty("--swipe-amount-y", `${swipeAmount.y}px`);
1232
+ },
1233
+ children: [
1234
+ closeButton && !toast2.jsx ? /* @__PURE__ */ jsx(
1235
+ "button",
1236
+ {
1237
+ "aria-label": closeButtonAriaLabel,
1238
+ "data-disabled": disabled,
1239
+ "data-close-button": true,
1240
+ onClick: disabled || !dismissible ? () => {
1241
+ } : () => {
1242
+ deleteToast();
1243
+ toast2.onDismiss?.(toast2);
1244
+ },
1245
+ className: cn(classNames?.closeButton, toast2?.classNames?.closeButton),
1246
+ children: icons?.close ?? CloseIcon
1247
+ }
1248
+ ) : null,
1249
+ toast2.jsx || isValidElement(toast2.title) ? toast2.jsx ? toast2.jsx : typeof toast2.title === "function" ? toast2.title() : toast2.title : /* @__PURE__ */ jsxs(Fragment, { children: [
1250
+ toastType || toast2.icon || toast2.promise ? /* @__PURE__ */ jsxs("div", { "data-icon": "", className: cn(classNames?.icon, toast2?.classNames?.icon), children: [
1251
+ toast2.promise || toast2.type === "loading" && !toast2.icon ? toast2.icon || getLoadingIcon() : null,
1252
+ toast2.type !== "loading" ? toast2.icon || icons?.[toastType] || getAsset(toastType ?? "default") : null
1253
+ ] }) : null,
1254
+ /* @__PURE__ */ jsxs("div", { "data-content": "", className: cn(classNames?.content, toast2?.classNames?.content), children: [
1255
+ /* @__PURE__ */ jsx("div", { "data-title": "", className: cn(classNames?.title, toast2?.classNames?.title), children: typeof toast2.title === "function" ? toast2.title() : toast2.title }),
1256
+ toast2.description ? /* @__PURE__ */ jsx(
1257
+ "div",
1258
+ {
1259
+ "data-description": "",
1260
+ className: cn(
1261
+ descriptionClassName,
1262
+ toastDescriptionClassname,
1263
+ classNames?.description,
1264
+ toast2?.classNames?.description
1265
+ ),
1266
+ children: typeof toast2.description === "function" ? toast2.description() : toast2.description
1267
+ }
1268
+ ) : null
1269
+ ] }),
1270
+ isValidElement(toast2.cancel) ? toast2.cancel : toast2.cancel && isAction(toast2.cancel) ? /* @__PURE__ */ jsx(
1271
+ "button",
1272
+ {
1273
+ "data-button": true,
1274
+ "data-cancel": true,
1275
+ style: toast2.cancelButtonStyle || cancelButtonStyle,
1276
+ onClick: (event) => {
1277
+ if (!isAction(toast2.cancel)) return;
1278
+ if (!dismissible) return;
1279
+ toast2.cancel.onClick?.(event);
1280
+ deleteToast();
1281
+ },
1282
+ className: cn(classNames?.cancelButton, toast2?.classNames?.cancelButton),
1283
+ children: toast2.cancel.label
1284
+ }
1285
+ ) : null,
1286
+ isValidElement(toast2.action) ? toast2.action : toast2.action && isAction(toast2.action) ? /* @__PURE__ */ jsx(
1287
+ "button",
1288
+ {
1289
+ "data-button": true,
1290
+ "data-action": true,
1291
+ style: toast2.actionButtonStyle || actionButtonStyle,
1292
+ onClick: (event) => {
1293
+ if (!isAction(toast2.action)) return;
1294
+ toast2.action.onClick?.(event);
1295
+ if (event.defaultPrevented) return;
1296
+ deleteToast();
1297
+ },
1298
+ className: cn(classNames?.actionButton, toast2?.classNames?.actionButton),
1299
+ children: toast2.action.label
1300
+ }
1301
+ ) : null
1302
+ ] })
1303
+ ]
1304
+ }
1305
+ );
1306
+ };
1307
+ function getDocumentDirection() {
1308
+ if (typeof window === "undefined") return "ltr";
1309
+ if (typeof document === "undefined") return "ltr";
1310
+ const dirAttribute = document.documentElement.getAttribute("dir");
1311
+ if (dirAttribute === "auto" || !dirAttribute) return window.getComputedStyle(document.documentElement).direction;
1312
+ return dirAttribute;
1313
+ }
1314
+ function assignOffset(defaultOffset, mobileOffset) {
1315
+ const styles = {};
1316
+ [defaultOffset, mobileOffset].forEach((offset, index) => {
1317
+ const isMobile = index === 1;
1318
+ const prefix = isMobile ? "--mobile-offset" : "--offset";
1319
+ const defaultValue = isMobile ? MOBILE_VIEWPORT_OFFSET : VIEWPORT_OFFSET;
1320
+ function assignAll(offset2) {
1321
+ ["top", "right", "bottom", "left"].forEach((key) => {
1322
+ styles[`${prefix}-${key}`] = typeof offset2 === "number" ? `${offset2}px` : offset2;
1323
+ });
1324
+ }
1325
+ if (typeof offset === "number" || typeof offset === "string") assignAll(offset);
1326
+ else if (typeof offset === "object") {
1327
+ ["top", "right", "bottom", "left"].forEach((key) => {
1328
+ if (offset[key] === void 0) styles[`${prefix}-${key}`] = defaultValue;
1329
+ else styles[`${prefix}-${key}`] = typeof offset[key] === "number" ? `${offset[key]}px` : offset[key];
1330
+ });
1331
+ } else assignAll(defaultValue);
1332
+ });
1333
+ return styles;
1334
+ }
1335
+ function useSonner() {
1336
+ const [activeToasts, setActiveToasts] = React3.useState([]);
1337
+ React3.useEffect(() => {
1338
+ return ToastState.subscribe((toast2) => {
1339
+ setActiveToasts((currentToasts) => {
1340
+ if ("dismiss" in toast2 && toast2.dismiss) return currentToasts.filter((t) => t.id !== toast2.id);
1341
+ const existingToastIndex = currentToasts.findIndex((t) => t.id === toast2.id);
1342
+ if (existingToastIndex !== -1) {
1343
+ const updatedToasts = [...currentToasts];
1344
+ updatedToasts[existingToastIndex] = { ...updatedToasts[existingToastIndex], ...toast2 };
1345
+ return updatedToasts;
1346
+ } else return [toast2, ...currentToasts];
1347
+ });
1348
+ });
1349
+ }, []);
1350
+ return {
1351
+ toasts: activeToasts
1352
+ };
1353
+ }
1354
+ var Toaster = forwardRef(function Toaster2(props, ref) {
1355
+ const {
1356
+ invert,
1357
+ position = "bottom-right",
1358
+ hotkey = ["altKey", "KeyT"],
1359
+ expand,
1360
+ closeButton,
1361
+ className,
1362
+ offset,
1363
+ mobileOffset,
1364
+ theme = "dark",
1365
+ richColors,
1366
+ duration = 4e3,
1367
+ style,
1368
+ visibleToasts = VISIBLE_TOASTS_AMOUNT,
1369
+ toastOptions,
1370
+ dir = getDocumentDirection(),
1371
+ gap = GAP,
1372
+ loadingIcon,
1373
+ icons,
1374
+ containerAriaLabel = "Notifications",
1375
+ pauseWhenPageIsHidden
1376
+ } = props;
1377
+ const [toasts, setToasts] = React3.useState([]);
1378
+ const possiblePositions = React3.useMemo(() => Array.from(/* @__PURE__ */ new Set([position, ...toasts.filter((toast2) => toast2.position !== void 0).map((toast2) => toast2.position)])), [toasts, position]);
1379
+ const [heights, setHeights] = React3.useState([]);
1380
+ const [expanded, setExpanded] = React3.useState(false);
1381
+ const [interacting, setInteracting] = React3.useState(false);
1382
+ const [actualTheme, setActualTheme] = React3.useState(theme !== "system" ? theme : typeof window !== "undefined" ? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : "light");
1383
+ const listRef = React3.useRef(null);
1384
+ const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
1385
+ const lastFocusedElementRef = React3.useRef(null);
1386
+ const isFocusWithinRef = React3.useRef(false);
1387
+ const removeToast = React3.useCallback((toastToRemove) => {
1388
+ setToasts((toasts2) => {
1389
+ if (!toasts2.find((toast2) => toast2.id === toastToRemove.id)?.delete) ToastState.dismiss(toastToRemove.id);
1390
+ return toasts2.filter(({ id }) => id !== toastToRemove.id);
1391
+ });
1392
+ }, []);
1393
+ React3.useEffect(() => {
1394
+ return ToastState.subscribe((toast2) => {
1395
+ if (toast2.dismiss) return setToasts((toasts2) => toasts2.map((t) => t.id === toast2.id ? { ...t, delete: true } : t));
1396
+ setTimeout(() => {
1397
+ ReactDOM.flushSync(() => {
1398
+ setToasts((toasts2) => {
1399
+ const indexOfExistingToast = toasts2.findIndex((t) => t.id === toast2.id);
1400
+ if (indexOfExistingToast !== -1) {
1401
+ return [
1402
+ ...toasts2.slice(0, indexOfExistingToast),
1403
+ { ...toasts2[indexOfExistingToast], ...toast2 },
1404
+ ...toasts2.slice(indexOfExistingToast + 1)
1405
+ ];
1406
+ }
1407
+ return [toast2, ...toasts2];
1408
+ });
1409
+ });
1410
+ });
1411
+ });
1412
+ }, []);
1413
+ React3.useEffect(() => {
1414
+ if (theme !== "system") return setActualTheme(theme);
1415
+ if (theme === "system") {
1416
+ if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
1417
+ setActualTheme("dark");
1418
+ } else {
1419
+ setActualTheme("light");
1420
+ }
1421
+ }
1422
+ if (typeof window === "undefined") return;
1423
+ const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1424
+ try {
1425
+ darkMediaQuery.addEventListener("change", ({ matches }) => {
1426
+ if (matches) setActualTheme("dark");
1427
+ else setActualTheme("light");
1428
+ });
1429
+ } catch (error) {
1430
+ darkMediaQuery.addListener(({ matches }) => {
1431
+ try {
1432
+ if (matches) setActualTheme("dark");
1433
+ else setActualTheme("light");
1434
+ } catch (e) {
1435
+ console.error(e);
1436
+ }
1437
+ });
1438
+ }
1439
+ }, [theme]);
1440
+ React3.useEffect(() => {
1441
+ if (toasts.length <= 1) setExpanded(false);
1442
+ }, [toasts]);
1443
+ React3.useEffect(() => {
1444
+ const handleKeyDown = (event) => {
1445
+ const isHotkeyPressed = hotkey.every((key) => event[key] || event.code === key);
1446
+ if (isHotkeyPressed) {
1447
+ setExpanded(true);
1448
+ listRef.current?.focus();
1449
+ }
1450
+ if (event.code === "Escape" && (document.activeElement === listRef.current || listRef.current?.contains(document.activeElement))) setExpanded(false);
1451
+ };
1452
+ document.addEventListener("keydown", handleKeyDown);
1453
+ return () => document.removeEventListener("keydown", handleKeyDown);
1454
+ }, [hotkey]);
1455
+ React3.useEffect(() => {
1456
+ if (listRef.current) {
1457
+ return () => {
1458
+ if (lastFocusedElementRef.current) {
1459
+ lastFocusedElementRef.current.focus({ preventScroll: true });
1460
+ lastFocusedElementRef.current = null;
1461
+ isFocusWithinRef.current = false;
1462
+ }
1463
+ };
1464
+ }
1465
+ }, [listRef.current]);
1466
+ return (
1467
+ // Remove item from normal navigation flow, only available via hotkey.
1468
+ /* @__PURE__ */ jsx(
1469
+ "section",
1470
+ {
1471
+ ref,
1472
+ "aria-label": `${containerAriaLabel} ${hotkeyLabel}`,
1473
+ tabIndex: -1,
1474
+ "aria-live": "polite",
1475
+ "aria-relevant": "additions text",
1476
+ "aria-atomic": "false",
1477
+ suppressHydrationWarning: true,
1478
+ children: possiblePositions.map((position2, index) => {
1479
+ const [y, x] = (position2 ?? "").split("-");
1480
+ if (!toasts.length) return null;
1481
+ return /* @__PURE__ */ jsx(
1482
+ "ol",
1483
+ {
1484
+ dir: dir === "auto" ? getDocumentDirection() : dir,
1485
+ tabIndex: -1,
1486
+ ref: listRef,
1487
+ className,
1488
+ "data-toastcmp-toaster": true,
1489
+ "data-theme": actualTheme,
1490
+ "data-y-position": y,
1491
+ "data-lifted": expanded && toasts.length > 1 && !expand,
1492
+ "data-x-position": x,
1493
+ style: {
1494
+ "--front-toast-height": `${heights[0]?.height || 0}px`,
1495
+ "--width": `${TOAST_WIDTH}px`,
1496
+ "--gap": `${gap}px`,
1497
+ ...style,
1498
+ ...assignOffset(offset, mobileOffset)
1499
+ },
1500
+ onBlur: (event) => {
1501
+ if (isFocusWithinRef.current && !event.currentTarget.contains(event.relatedTarget)) {
1502
+ isFocusWithinRef.current = false;
1503
+ if (lastFocusedElementRef.current) {
1504
+ lastFocusedElementRef.current.focus({ preventScroll: true });
1505
+ lastFocusedElementRef.current = null;
1506
+ }
1507
+ }
1508
+ },
1509
+ onFocus: (event) => {
1510
+ const isNotDismissible = event.target instanceof HTMLElement && event.target.dataset.dismissible === "false";
1511
+ if (isNotDismissible) return;
1512
+ if (!isFocusWithinRef.current) {
1513
+ isFocusWithinRef.current = true;
1514
+ lastFocusedElementRef.current = event.relatedTarget;
1515
+ }
1516
+ },
1517
+ onMouseEnter: () => setExpanded(true),
1518
+ onMouseMove: () => setExpanded(true),
1519
+ onMouseLeave: () => {
1520
+ if (!interacting) setExpanded(false);
1521
+ },
1522
+ onPointerDown: (event) => {
1523
+ const isNotDismissible = event.target instanceof HTMLElement && event.target.dataset.dismissible === "false";
1524
+ if (isNotDismissible) return;
1525
+ setInteracting(true);
1526
+ },
1527
+ onPointerUp: () => setInteracting(false),
1528
+ children: toasts.filter((toast2) => !toast2.position && index === 0 || toast2.position === position2).map((toast2, index2) => /* @__PURE__ */ jsx(
1529
+ Toast,
1530
+ {
1531
+ icons,
1532
+ index: index2,
1533
+ toast: toast2,
1534
+ defaultRichColors: richColors,
1535
+ duration: toastOptions?.duration ?? duration,
1536
+ className: toastOptions?.className,
1537
+ descriptionClassName: toastOptions?.descriptionClassName,
1538
+ invert,
1539
+ visibleToasts,
1540
+ closeButton: toastOptions?.closeButton ?? closeButton,
1541
+ interacting,
1542
+ position: position2,
1543
+ style: toastOptions?.style,
1544
+ unstyled: toastOptions?.unstyled,
1545
+ classNames: toastOptions?.classNames,
1546
+ cancelButtonStyle: toastOptions?.cancelButtonStyle,
1547
+ actionButtonStyle: toastOptions?.actionButtonStyle,
1548
+ removeToast,
1549
+ toasts: toasts.filter((t) => t.position == toast2.position),
1550
+ heights: heights.filter((h) => h.position == toast2.position),
1551
+ setHeights,
1552
+ expandByDefault: expand,
1553
+ gap,
1554
+ loadingIcon,
1555
+ expanded,
1556
+ pauseWhenPageIsHidden,
1557
+ swipeDirections: props.swipeDirections
1558
+ },
1559
+ toast2.id
1560
+ ))
1561
+ },
1562
+ position2
1563
+ );
1564
+ })
1565
+ }
1566
+ )
1567
+ );
1568
+ });
1569
+ var injected = false;
1570
+ function injectStyles() {
1571
+ if (injected || typeof document === "undefined") return;
1572
+ injected = true;
1573
+ if (document.querySelector("[data-enigma-toast-styles]")) return;
1574
+ const element = document.createElement("style");
1575
+ element.setAttribute("data-enigma-toast-styles", "");
1576
+ element.textContent = TOAST_STYLES;
1577
+ document.head.prepend(element);
1578
+ }
1579
+ function Toaster3({ styles = true, queue = defaultQueue, ...props }) {
1580
+ useLayoutEffect(() => {
1581
+ if (styles) injectStyles();
1582
+ }, [styles]);
1583
+ const forwarded = useRef(/* @__PURE__ */ new Map());
1584
+ useEffect(() => {
1585
+ if (!queue) return;
1586
+ const sync = (items) => {
1587
+ const live = new Set(items.map((item) => item.id));
1588
+ for (const item of items) {
1589
+ if (forwarded.current.has(item.id)) continue;
1590
+ forwarded.current.set(item.id, raise(item));
1591
+ }
1592
+ for (const [id, toastId] of forwarded.current) {
1593
+ if (live.has(id)) continue;
1594
+ toast.dismiss(toastId);
1595
+ forwarded.current.delete(id);
1596
+ }
1597
+ };
1598
+ sync(queue.items);
1599
+ return queue.subscribe(sync);
1600
+ }, [queue]);
1601
+ return /* @__PURE__ */ jsx(Toaster, { ...props });
1602
+ }
1603
+ function raise(item) {
1604
+ const options = {
1605
+ description: item.body,
1606
+ // The queue already counts down and removes the item; leaving the toast's own timer
1607
+ // running as well would race it, and the shorter of the two would win at random.
1608
+ duration: Infinity,
1609
+ action: item.action ? { label: item.action.label, onClick: () => item.action?.onSelect() } : void 0
1610
+ };
1611
+ switch (item.tone) {
1612
+ case "success":
1613
+ return toast.success(item.title, options);
1614
+ case "error":
1615
+ return toast.error(item.title, options);
1616
+ case "warning":
1617
+ return toast.warning(item.title, options);
1618
+ case "info":
1619
+ return toast.info(item.title, options);
1620
+ case "loading":
1621
+ return toast.loading(item.title, options);
1622
+ default:
1623
+ return toast(item.title, options);
1624
+ }
1625
+ }
1626
+
1627
+ export { Toaster3 as Toaster, toast, useSonner };