@nicojones/toast 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +618 -0
- package/dist/main.cjs +4 -0
- package/dist/main.cjs.map +1 -0
- package/dist/main.d.cts +87 -0
- package/dist/main.d.ts +87 -0
- package/dist/main.js +4 -0
- package/dist/main.js.map +1 -0
- package/dist/styles.css +1 -0
- package/package.json +74 -0
package/README.md
ADDED
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<p />
|
|
3
|
+
<p>
|
|
4
|
+
<b>
|
|
5
|
+
An simple notification library for React. Fully customizable and lightweight.
|
|
6
|
+
</b>
|
|
7
|
+
</p>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div align="center">
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
## ๐ Features
|
|
18
|
+
|
|
19
|
+
- [x] ๐ชด Ultra-lightweight core.
|
|
20
|
+
- [x] ๐ฆพ Fully accessible (ARIA-friendly).
|
|
21
|
+
- [x] ๐ Built-in light, dark, & system themes.
|
|
22
|
+
- [x] ๐ถ๏ธ Pause dismissal on hover.
|
|
23
|
+
- [x] ๐ Customizable toast position.
|
|
24
|
+
- [x] ๐ช Respects user reduced-motion settings.
|
|
25
|
+
- [x] ๐ฆ 100% TypeScript.
|
|
26
|
+
- [x] ๐งฉ Can run inside Shadow Root (manually import styles).
|
|
27
|
+
- [x] ๐๏ธ Fully customizableโdisable all styles if desired.
|
|
28
|
+
- [x] ๐ Replace/update content of already open toasts by ID.
|
|
29
|
+
- [x] ๐ฆ Close toasts programmatically.
|
|
30
|
+
|
|
31
|
+
## ๐ Getting Started
|
|
32
|
+
|
|
33
|
+
> [!IMPORTANT]
|
|
34
|
+
> This library requires **React v18** or higher.
|
|
35
|
+
|
|
36
|
+
1. Install the library:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Using npm:
|
|
40
|
+
npm install @nicojones/toast
|
|
41
|
+
|
|
42
|
+
# Using pnpm:
|
|
43
|
+
pnpm add @nicojones/toast
|
|
44
|
+
|
|
45
|
+
# Using yarn:
|
|
46
|
+
yarn install @nicojones/toast
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
2. Add the toast provider:
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
// ๐ root.tsx
|
|
53
|
+
|
|
54
|
+
import { Toaster } from "@nicojones/toast";
|
|
55
|
+
|
|
56
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
57
|
+
<React.StrictMode>
|
|
58
|
+
<App />
|
|
59
|
+
<Toaster />
|
|
60
|
+
</React.StrictMode>,
|
|
61
|
+
);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
3. Usage:
|
|
65
|
+
|
|
66
|
+
```jsx
|
|
67
|
+
// ๐ index.tsx
|
|
68
|
+
|
|
69
|
+
import { toast } from "@nicojones/toast";
|
|
70
|
+
|
|
71
|
+
export default function Index() {
|
|
72
|
+
return (
|
|
73
|
+
<>
|
|
74
|
+
<button
|
|
75
|
+
onClick={() =>
|
|
76
|
+
toast.success({
|
|
77
|
+
text: "Success!",
|
|
78
|
+
description: "Your action was completed successfully",
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
>
|
|
82
|
+
Show Toast
|
|
83
|
+
</button>
|
|
84
|
+
</>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## ๐ Documentation
|
|
90
|
+
|
|
91
|
+
### Toast Variants
|
|
92
|
+
|
|
93
|
+
Show a toast with a specific variant:
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { toast } from "@nicojones/toast";
|
|
97
|
+
|
|
98
|
+
// Default toast
|
|
99
|
+
toast.default({
|
|
100
|
+
text: "Hello โจ",
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Success toast
|
|
104
|
+
toast.success({
|
|
105
|
+
text: "Success!",
|
|
106
|
+
description: "Operation completed successfully",
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Error toast
|
|
110
|
+
toast.error({
|
|
111
|
+
text: "Error!",
|
|
112
|
+
description: "Something went wrong",
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Warning toast
|
|
116
|
+
toast.warning({
|
|
117
|
+
text: "Warning!",
|
|
118
|
+
description: "Please check your input",
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Info toast
|
|
122
|
+
toast.info({
|
|
123
|
+
text: "Info",
|
|
124
|
+
description: "Here's some information",
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Action Buttons
|
|
129
|
+
|
|
130
|
+
Show a button and execute a custom function when clicked. The default text for the button is `Action`:
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
toast.default({
|
|
134
|
+
text: "A toast with action button",
|
|
135
|
+
action: {
|
|
136
|
+
content: "Action", // Button label
|
|
137
|
+
onClick: () => {
|
|
138
|
+
// Do something
|
|
139
|
+
console.log("Action clicked!");
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Replacing Toasts by ID
|
|
146
|
+
|
|
147
|
+
You can replace an existing toast by providing the same `id`. This is useful for updating progress or preventing duplicate toasts:
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
// First toast with ID
|
|
151
|
+
toast.info({
|
|
152
|
+
id: "update-toast",
|
|
153
|
+
text: "Processing...",
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Later, replace it with the same ID
|
|
157
|
+
toast.success({
|
|
158
|
+
id: "update-toast",
|
|
159
|
+
text: "Completed!",
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Toast Loading
|
|
164
|
+
|
|
165
|
+
Show a toast with loading state that automatically updates after a promise resolves or fails:
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
toast.loading({
|
|
169
|
+
// Initial message:
|
|
170
|
+
text: "Loading",
|
|
171
|
+
options: {
|
|
172
|
+
promise: yourFunction(),
|
|
173
|
+
success: "Ready",
|
|
174
|
+
error: "Error",
|
|
175
|
+
// Close toast automatically (the duration depends by delayDuration property):
|
|
176
|
+
autoDismiss: true,
|
|
177
|
+
// Optional:
|
|
178
|
+
onSuccess: (data) => {
|
|
179
|
+
console.log("Success", data);
|
|
180
|
+
},
|
|
181
|
+
// Optional:
|
|
182
|
+
onError: (error, id) => {
|
|
183
|
+
console.log("Error", error);
|
|
184
|
+
// Replace the toast and use the error.message
|
|
185
|
+
toast.error({text: error.message, id });
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Example with async function:
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
const fetchData = async () => {
|
|
195
|
+
const response = await fetch("/api/data");
|
|
196
|
+
return response.json();
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
toast.loading({
|
|
200
|
+
text: "Fetching data",
|
|
201
|
+
options: {
|
|
202
|
+
promise: fetchData(),
|
|
203
|
+
success: "Data loaded",
|
|
204
|
+
error: "Failed to load data",
|
|
205
|
+
autoDismiss: true,
|
|
206
|
+
onSuccess: (data) => {
|
|
207
|
+
console.log("Received:", data);
|
|
208
|
+
// Replace the toast and use received data
|
|
209
|
+
toast.success({ text: data.message, id })
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Closing Toasts
|
|
216
|
+
|
|
217
|
+
Close a toast programmatically using `toast.close()`:
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import { toast } from "@nicojones/toast";
|
|
221
|
+
|
|
222
|
+
// Show a toast and store its ID
|
|
223
|
+
const toastData = toast.info({
|
|
224
|
+
text: "This will be closed",
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Close it later
|
|
228
|
+
toast.close(toastData.id);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Or close by the ID you provided:
|
|
232
|
+
|
|
233
|
+
```tsx
|
|
234
|
+
toast.info({
|
|
235
|
+
id: "my-toast",
|
|
236
|
+
text: "This toast has an ID",
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Close it using the ID
|
|
240
|
+
toast.close("my-toast");
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Custom Icon
|
|
244
|
+
|
|
245
|
+
You can use a custom icon for a toast using the `icon` property and passing
|
|
246
|
+
any valid `JSX.Element`.
|
|
247
|
+
|
|
248
|
+
```tsx
|
|
249
|
+
toast.default({
|
|
250
|
+
text: "Party popper!",
|
|
251
|
+
icon: <FontAwesomeIcon width={18} height={18} icon={faPoo} />,
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Custom Attributes
|
|
256
|
+
|
|
257
|
+
You can pass custom HTML attributes to the toast:
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
toast.default({
|
|
261
|
+
text: "Custom toast",
|
|
262
|
+
attrs: {
|
|
263
|
+
"aria-customized": "yes",
|
|
264
|
+
"data-testid": "my-test-id",
|
|
265
|
+
style: {
|
|
266
|
+
color: "pink",
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## ๐ Toaster Component
|
|
273
|
+
|
|
274
|
+
The `<Toaster />` component is used to show toasts in your application. It accepts several props for customization.
|
|
275
|
+
|
|
276
|
+
### Position
|
|
277
|
+
|
|
278
|
+
By default, the position is `bottom-right`. You can customize the position:
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
import { Toaster } from "@nicojones/toast";
|
|
282
|
+
|
|
283
|
+
<Toaster position="top-left" />
|
|
284
|
+
<Toaster position="top-right" />
|
|
285
|
+
<Toaster position="top-center" />
|
|
286
|
+
<Toaster position="bottom-left" />
|
|
287
|
+
<Toaster position="bottom-right" /> {/* default */}
|
|
288
|
+
<Toaster position="bottom-center" />
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Theme
|
|
292
|
+
|
|
293
|
+
You can set the theme of the toasts using the `theme` prop:
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
<Toaster theme="light" />
|
|
297
|
+
<Toaster theme="dark" />
|
|
298
|
+
<Toaster theme="system" /> {/* default */}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Max Toasts
|
|
302
|
+
|
|
303
|
+
By default, the maximum number of toasts is set to `4`. You can change this value:
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
<Toaster maxToasts={8} />
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Toast Options
|
|
310
|
+
|
|
311
|
+
You can customize all toasts globally using the `toastOptions` prop:
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
<Toaster
|
|
315
|
+
toastOptions={{
|
|
316
|
+
font: "font-sans",
|
|
317
|
+
defaultActionContent: "Close me",
|
|
318
|
+
defaultCloseContent: "Close",
|
|
319
|
+
animationOnClose: "slide", // or "swipe"
|
|
320
|
+
}}
|
|
321
|
+
/>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
#### Custom Icons
|
|
325
|
+
|
|
326
|
+
Replace the default icons for all toasts:
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
import { Info, CircleX, CircleAlert, CircleCheck, Loader } from "lucide-react";
|
|
330
|
+
|
|
331
|
+
<Toaster
|
|
332
|
+
toastOptions={{
|
|
333
|
+
icons: {
|
|
334
|
+
info: <Info className="dark:text-blue-500" />,
|
|
335
|
+
error: <CircleX className="text-red-500" />,
|
|
336
|
+
warning: <CircleAlert className="text-yellow-500" />,
|
|
337
|
+
success: <CircleCheck className="text-green-500" />,
|
|
338
|
+
loading: <Loader className="animate-spin text-gray-500" />,
|
|
339
|
+
},
|
|
340
|
+
}}
|
|
341
|
+
/>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### Custom Styles
|
|
345
|
+
|
|
346
|
+
Extend the default styles using the `classNames` property:
|
|
347
|
+
|
|
348
|
+
```tsx
|
|
349
|
+
<Toaster
|
|
350
|
+
toastOptions={{
|
|
351
|
+
classNames: {
|
|
352
|
+
toast: "bg-zinc-100 dark:bg-zinc-900",
|
|
353
|
+
container: "rounded-lg",
|
|
354
|
+
icon: "text-blue-500",
|
|
355
|
+
content: "text-sm",
|
|
356
|
+
actions: {
|
|
357
|
+
container: "flex gap-2",
|
|
358
|
+
closeBtn: "text-gray-500",
|
|
359
|
+
actionBtn: "text-blue-600",
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
}}
|
|
363
|
+
/>
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### Headless Mode
|
|
367
|
+
|
|
368
|
+
Disable all default styles using `headless` property. It works together with `classNames`:
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
<Toaster
|
|
372
|
+
toastOptions={{
|
|
373
|
+
headless: true,
|
|
374
|
+
classNames: {
|
|
375
|
+
toast: "bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4",
|
|
376
|
+
// ... other custom styles
|
|
377
|
+
},
|
|
378
|
+
}}
|
|
379
|
+
/>
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## ๐ง Framework Guides
|
|
383
|
+
|
|
384
|
+
### Next.js
|
|
385
|
+
|
|
386
|
+
1. Add the `Toaster` to your `layout.tsx`:
|
|
387
|
+
|
|
388
|
+
```tsx
|
|
389
|
+
// ๐ app/layout.tsx
|
|
390
|
+
|
|
391
|
+
import { Toaster } from "@nicojones/toast";
|
|
392
|
+
|
|
393
|
+
export default function RootLayout({
|
|
394
|
+
children,
|
|
395
|
+
}: {
|
|
396
|
+
children: React.ReactNode;
|
|
397
|
+
}) {
|
|
398
|
+
return (
|
|
399
|
+
<html lang="en">
|
|
400
|
+
<body>
|
|
401
|
+
{children}
|
|
402
|
+
<Toaster />
|
|
403
|
+
</body>
|
|
404
|
+
</html>
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
2. Use the `toast` function in client components:
|
|
410
|
+
|
|
411
|
+
```tsx
|
|
412
|
+
"use client";
|
|
413
|
+
|
|
414
|
+
import { toast } from "@nicojones/toast";
|
|
415
|
+
|
|
416
|
+
export default function MyComponent() {
|
|
417
|
+
return (
|
|
418
|
+
<button
|
|
419
|
+
onClick={() =>
|
|
420
|
+
toast.success({
|
|
421
|
+
text: "Ready ๐",
|
|
422
|
+
})
|
|
423
|
+
}
|
|
424
|
+
>
|
|
425
|
+
Click me!
|
|
426
|
+
</button>
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
3. (Optional) Add the styles if needed:
|
|
432
|
+
|
|
433
|
+
```tsx
|
|
434
|
+
// ๐ app/layout.tsx
|
|
435
|
+
|
|
436
|
+
import "@nicojones/toast/dist/styles.css";
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Astro
|
|
440
|
+
|
|
441
|
+
1. Add the `Toaster` to your layout with `client:load`:
|
|
442
|
+
|
|
443
|
+
```tsx
|
|
444
|
+
// ๐ layouts/Layout.astro
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
import { Toaster } from "@nicojones/toast";
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
<!doctype html>
|
|
451
|
+
<html lang="en">
|
|
452
|
+
<body>
|
|
453
|
+
<slot />
|
|
454
|
+
<Toaster client:load />
|
|
455
|
+
</body>
|
|
456
|
+
</html>
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
2. Create a component to trigger toasts:
|
|
460
|
+
|
|
461
|
+
```tsx
|
|
462
|
+
// ๐ components/showToast.tsx
|
|
463
|
+
|
|
464
|
+
import { toast } from "@nicojones/toast";
|
|
465
|
+
|
|
466
|
+
const ShowToast = () => {
|
|
467
|
+
const handleClick = () => {
|
|
468
|
+
toast.default({
|
|
469
|
+
text: "Hello from Astro!",
|
|
470
|
+
});
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
return (
|
|
474
|
+
<button type="button" onClick={handleClick}>
|
|
475
|
+
Show Toast
|
|
476
|
+
</button>
|
|
477
|
+
);
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
export default ShowToast;
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
3. Use the component in your pages:
|
|
484
|
+
|
|
485
|
+
```tsx
|
|
486
|
+
// ๐ pages/index.astro
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
import Layout from "../layouts/Layout.astro";
|
|
490
|
+
import ShowToast from "../components/showToast";
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
<Layout title="Welcome">
|
|
494
|
+
<main>
|
|
495
|
+
<ShowToast client:load />
|
|
496
|
+
</main>
|
|
497
|
+
</Layout>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## ๐ API Reference
|
|
501
|
+
|
|
502
|
+
### `toast.{variant}()`
|
|
503
|
+
|
|
504
|
+
The `toast` function accepts the following options:
|
|
505
|
+
|
|
506
|
+
| Property | Description | Type | Required |
|
|
507
|
+
| --------------- | --------------------------------------------- | ----------------------------------------------------------------------------- | -------- |
|
|
508
|
+
| `text` | Notification title | `string` | โ
|
|
|
509
|
+
| `description` | Toast's description | `string` | - |
|
|
510
|
+
| `icon` | Icon to display in the toast | `ReactNode` | - |
|
|
511
|
+
| `delayDuration` | Duration before the toast disappears | `number` (default: `4000`) | - |
|
|
512
|
+
| `variant` | Variant of the toast | `Variant`: `info`, `success`, `warning`, `error` or `loading` | - |
|
|
513
|
+
| `theme` | Theme of the toast | `Theme` (default: `system`): `light`, `dark` or `system` | - |
|
|
514
|
+
| `action` | Show an _Action_ button and execute a function | `{ content?: string \| ReactNode, onClick: () => void \| Promise<void> }` | - |
|
|
515
|
+
| `id` | Set a unique `id` to replace an existing toast or ensure there are no duplicates | `string` or `number` | - |
|
|
516
|
+
| `attrs` | Custom HTML attributes | `HTMLProps<HTMLDivElement>` | - |
|
|
517
|
+
|
|
518
|
+
### `toast.loading()`
|
|
519
|
+
|
|
520
|
+
The `toast.loading` function accepts the same options as above, plus:
|
|
521
|
+
|
|
522
|
+
| Property | Description | Type | Required |
|
|
523
|
+
| --------------- | --------------------------------------------- | ----------------------------------------------------------------------------- | -------- |
|
|
524
|
+
| `options` | Loading-specific options | `LoadingType` | - |
|
|
525
|
+
|
|
526
|
+
#### `LoadingType`
|
|
527
|
+
|
|
528
|
+
| Property | Description | Type | Required |
|
|
529
|
+
| ------------- | --------------------------------------------- | --------------------------------------- | -------- |
|
|
530
|
+
| `promise` | Promise or function that returns a promise | `Promise<T>` or `() => Promise<T>` | โ
|
|
|
531
|
+
| `success` | Success message | `string` | โ
|
|
|
532
|
+
| `error` | Error message | `string` | โ
|
|
|
533
|
+
| `autoDismiss` | Close toast automatically after promise | `boolean` | โ
|
|
|
534
|
+
| `onSuccess` | Callback when promise resolves | `(data: T) => void` | - |
|
|
535
|
+
| `onError` | Callback when promise rejects | `(error: Error, id?: ToastId) => void` | - |
|
|
536
|
+
|
|
537
|
+
### `toast.close()`
|
|
538
|
+
|
|
539
|
+
Close a toast by its ID:
|
|
540
|
+
|
|
541
|
+
```tsx
|
|
542
|
+
toast.close(id: ToastId): void
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### `<Toaster />`
|
|
546
|
+
|
|
547
|
+
The `<Toaster />` component accepts the following options:
|
|
548
|
+
|
|
549
|
+
| Property | Description | Type | Required |
|
|
550
|
+
| -------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------- |
|
|
551
|
+
| `theme` | Theme of all toasts | `Theme` (default: `system`): `'light'`, `'dark'`, or `'system'` | - |
|
|
552
|
+
| `maxToasts` | Maximum number of toasts to display | `number` (default: `4`) | - |
|
|
553
|
+
| `toastIcons` | Replace the default icons with custom icons | `Record<Variant, ReactNode>` | - |
|
|
554
|
+
| `position` | Position of the toaster on the screen | `Position` (default: `bottom-right`): `'top-left'`, `'top-right'`, `'top-center'`, `'bottom-left'`, `'bottom-right'` or `'bottom-center'` | - |
|
|
555
|
+
| `toastOptions` | Options to customize all toasts | `ToastOptions` | - |
|
|
556
|
+
|
|
557
|
+
### `ToastOptions`
|
|
558
|
+
|
|
559
|
+
| Property | Description | Type | Required |
|
|
560
|
+
| ---------------------- | --------------------------------------------------------------- | ---------------------------- | -------- |
|
|
561
|
+
| `font` | Font for all toasts | `string` | - |
|
|
562
|
+
| `icons` | Icons for all toasts | `Record<Variant, ReactNode>` | - |
|
|
563
|
+
| `defaultActionContent` | Default content for the action button | `string` or `ReactNode` | - |
|
|
564
|
+
| `defaultCloseContent` | Default content for the close button | `string` or `ReactNode` | - |
|
|
565
|
+
| `headless` | Disable all default styles. It works together with `classNames` | `boolean` | - |
|
|
566
|
+
| `animationOnClose` | Animation when closing toast | `'slide'` or `'swipe'` | - |
|
|
567
|
+
| `classNames` | Custom styles for all toasts | `ToastClassnames` | - |
|
|
568
|
+
|
|
569
|
+
### `ToastClassnames`
|
|
570
|
+
|
|
571
|
+
| Property | Description | Type | Required |
|
|
572
|
+
| ----------- | ------------------------------------- | -------- | -------- |
|
|
573
|
+
| `toast` | Global toast style | `string` | - |
|
|
574
|
+
| `container` | Toast container styles | `string` | - |
|
|
575
|
+
| `icon` | Styles for the main icon of the toast | `string` | - |
|
|
576
|
+
| `content` | Styles for title and description | `string` | - |
|
|
577
|
+
| `actions` | Styles for the buttons | `ToastActionsCustomClassnames` | - |
|
|
578
|
+
|
|
579
|
+
### `ToastActionsCustomClassnames`
|
|
580
|
+
|
|
581
|
+
| Property | Description | Type | Required |
|
|
582
|
+
| ----------- | ------------------------ | -------- | -------- |
|
|
583
|
+
| `container` | Action buttons container | `string` | - |
|
|
584
|
+
| `closeBtn` | Close button styles | `string` | - |
|
|
585
|
+
| `actionBtn` | Action button styles | `string` | - |
|
|
586
|
+
|
|
587
|
+
## ๐ค Contributing
|
|
588
|
+
|
|
589
|
+
- **Library**: React 19 with tsup + Lightning CSS + Vitest for testing.
|
|
590
|
+
|
|
591
|
+
1. Fork the repository.
|
|
592
|
+
|
|
593
|
+
2. Install dependencies:
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
# Install pnpm globally if you don't have it:
|
|
597
|
+
npm install -g pnpm
|
|
598
|
+
|
|
599
|
+
# and install dependencies:
|
|
600
|
+
pnpm install
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
3. Commands:
|
|
604
|
+
|
|
605
|
+
```bash
|
|
606
|
+
# Run packages:
|
|
607
|
+
pnpm dev
|
|
608
|
+
|
|
609
|
+
# Build the docs & library:
|
|
610
|
+
pnpm build
|
|
611
|
+
|
|
612
|
+
# Test the library:
|
|
613
|
+
pnpm test
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
## ๐ License
|
|
617
|
+
|
|
618
|
+
MIT License - 2026.
|
package/dist/main.cjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
"use strict";var k=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var X=Object.prototype.hasOwnProperty;var q=(t,o)=>{for(var e in o)k(t,e,{get:o[e],enumerable:!0})},J=(t,o,e,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of Q(o))!X.call(t,n)&&n!==e&&k(t,n,{get:()=>o[n],enumerable:!(a=H(o,n))||a.enumerable});return t};var K=t=>J(k({},"__esModule",{value:!0}),t);var at={};q(at,{Toaster:()=>U,toast:()=>$});module.exports=K(at);function I(t,{insertAt:o}={}){if(!t||typeof document>"u")return;let e=document.head||document.getElementsByTagName("head")[0],a=document.createElement("style");a.type="text/css",o==="top"&&e.firstChild?e.insertBefore(a,e.firstChild):e.appendChild(a),a.styleSheet?a.styleSheet.cssText=t:a.appendChild(document.createTextNode(t))}I(`:root{--pheralb-toast-animation-enter: .4s;--pheralb-toast-animation-exit: .4s}:where(.t_global){--box-shadow: rgba(0, 0, 0, .1);--background-color: #ffffff;--hover-bg-color: #f5f5f5;--border-color: #e5e5e5;--text-color: #171717;--description-color: #262626;--focus-color: #a3a3a3}.t_light-theme{--box-shadow: rgba(0, 0, 0, .1);--background-color: #ffffff;--hover-bg-color: #f5f5f5;--border-color: #e5e5e5;--text-color: #171717;--description-color: #262626;--focus-color: #a3a3a3}.t_dark-theme{--box-shadow: rgba(0, 0, 0, .1);--background-color: #171717;--hover-bg-color: #27272a;--border-color: #262626;--text-color: #fafafa;--description-color: #e5e5e5;--focus-color: #404040}@media (prefers-color-scheme: dark){:where(.t_global){--box-shadow: rgba(0, 0, 0, .1);--background-color: #171717;--hover-bg-color: #27272a;--border-color: #262626;--text-color: #fafafa;--description-color: #e5e5e5;--focus-color: #404040}}.t_toasts{display:flex;flex-direction:column;gap:10px;padding:14px;position:fixed;z-index:999;overflow:hidden;transition:max-height .5s ease-in-out;width:100%}.t_default_font{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.t_top-left{top:0;left:0}.t_top-right{top:0;right:0}.t_top-center{top:0;left:50%;transform:translate(-50%)}.t_bottom-left{bottom:0;left:0}.t_bottom-right{bottom:0;right:0}.t_bottom-center{bottom:0;left:50%;transform:translate(-50%)}@media (min-width: 768px){.t_toasts{max-width:355px}}.t_global{display:flex;justify-content:space-between;padding:0;margin:0;list-style:none;outline:none;background-color:var(--background-color);width:auto;box-shadow:0 1px 3px 0 var(--box-shadow),0 1px 2px -1px var(--box-shadow);border:1px solid var(--border-color);border-radius:.375rem;font-size:.875rem;line-height:1.25rem;overflow:hidden}.t_global button{border:none;outline:none}.t_global button:focus{outline:1px solid var(--focus-color);outline-offset:0px;background-color:var(--hover-color)}.t_container{display:flex;flex-direction:row;align-items:center;width:100%;max-width:20rem;height:100wh;gap:.6rem;padding:12px;word-wrap:break-word;overflow-wrap:break-word}.t_icon{fill:var(--text-color);margin-top:.1rem;flex-shrink:0}.t_content{display:flex;flex-direction:column;justify-content:center;max-width:100%}.t_content p{font-weight:600;color:var(--text-color);margin:0}.t_content p:nth-of-type(2){font-weight:400;font-size:.75rem;color:var(--description-color)}.t_actions{display:flex;flex-direction:column;border-left:1px solid var(--border-color);height:100wh}.t_actions>button{flex:1 1 0%;width:100%;padding:6px 20px;font-size:13px;background-color:transparent;cursor:pointer;border:none}.t_actions>button:nth-child(1){color:var(--text-color);font-weight:500}.t_actions>button:nth-child(2){color:var(--text-color);border-top:1px solid var(--border-color)}.t_actions>button:hover{background-color:var(--hover-color)}.t_loading{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.t_slide-enter-top{animation:slide-top var(--pheralb-toast-animation-enter) ease}@keyframes slide-top{0%{opacity:0;transform:translateY(-100%)}to{opacity:1;transform:translateY(0)}}.t_slide-enter-bottom{animation:slide-bottom var(--pheralb-toast-animation-enter) ease}@keyframes slide-bottom{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}.t-slide-exit-top,.t-slide-exit-bottom{will-change:transform,opacity}.t-slide-exit-top{animation:slide-top-exit var(--pheralb-toast-animation-exit) ease}@keyframes slide-top-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t-slide-exit-bottom{animation:slide-bottom-exit var(--pheralb-toast-animation-exit) ease}@keyframes slide-bottom-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(100%)}}.t_swipe-exit-center{animation:swipe-center-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-center-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t_swipe-exit-left{animation:swipe-left-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-left-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-100%)}}.t_swipe-exit-right{animation:swipe-right-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-right-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(100%)}}
|
|
3
|
+
`);var y=require("react");var g=require("react");var m=require("react/jsx-runtime"),A=t=>(0,m.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:(0,m.jsx)("path",{d:"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm45.66 85.66l-56 56a8 8 0 01-11.32 0l-24-24a8 8 0 0111.32-11.32L112 148.69l50.34-50.35a8 8 0 0111.32 11.32z"})}),z=t=>(0,m.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:(0,m.jsx)("path",{d:"M236.8 188.09L149.35 36.22a24.76 24.76 0 00-42.7 0L19.2 188.09a23.51 23.51 0 000 23.72A24.35 24.35 0 0040.55 224h174.9a24.35 24.35 0 0021.33-12.19 23.51 23.51 0 00.02-23.72zM120 104a8 8 0 0116 0v40a8 8 0 01-16 0zm8 88a12 12 0 1112-12 12 12 0 01-12 12z"})}),E=t=>(0,m.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:(0,m.jsx)("path",{d:"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm-8 56a8 8 0 0116 0v56a8 8 0 01-16 0zm8 104a12 12 0 1112-12 12 12 0 01-12 12z"})}),R=t=>(0,m.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:(0,m.jsx)("path",{d:"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm-4 48a12 12 0 11-12 12 12 12 0 0112-12zm12 112a16 16 0 01-16-16v-40a8 8 0 010-16 16 16 0 0116 16v40a8 8 0 010 16z"})}),S=t=>(0,m.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:(0,m.jsx)("path",{d:"M136 32v32a8 8 0 01-16 0V32a8 8 0 0116 0zm37.25 58.75a8 8 0 005.66-2.35l22.63-22.62a8 8 0 00-11.32-11.32L167.6 77.09a8 8 0 005.65 13.66zM224 120h-32a8 8 0 000 16h32a8 8 0 000-16zm-45.09 47.6a8 8 0 00-11.31 11.31l22.62 22.63a8 8 0 0011.32-11.32zM128 184a8 8 0 00-8 8v32a8 8 0 0016 0v-32a8 8 0 00-8-8zm-50.91-16.4l-22.63 22.62a8 8 0 0011.32 11.32l22.62-22.63a8 8 0 00-11.31-11.31zM72 128a8 8 0 00-8-8H32a8 8 0 000 16h32a8 8 0 008-8zm-6.22-73.54a8 8 0 00-11.32 11.32L77.09 88.4A8 8 0 0088.4 77.09z"})});var r=require("react"),L=(t,o)=>{let e=(0,r.useRef)(0),a=(0,r.useRef)(t),n=(0,r.useRef)(0),f=(0,r.useRef)(o),l=(0,r.useRef)(!0),h=(0,r.useCallback)(()=>{e.current&&window.clearTimeout(e.current)},[]),T=(0,r.useCallback)(()=>{!l.current||!n.current||(h(),f.current-=Date.now()-n.current,l.current=!1)},[h]),x=(0,r.useCallback)(()=>{l.current||(n.current=Date.now(),e.current=window.setTimeout(a.current,f.current),l.current=!0)},[]),u=(0,r.useCallback)(()=>{h(),f.current=o,n.current=Date.now(),e.current=window.setTimeout(a.current,o),l.current=!0},[h,o]);return(0,r.useEffect)(()=>{a.current=t},[t]),(0,r.useEffect)(()=>(u(),h),[o,u,h]),{pause:T,resume:x,reset:u,isActive:l.current}};var d=(...t)=>t.filter(Boolean).join(" "),B=()=>Math.floor(Math.random()*1e6),W=(()=>{let t;return()=>(t===void 0&&(typeof window<"u"&&window.matchMedia!==void 0?t=window.matchMedia("(prefers-reduced-motion: reduce)").matches:t=!1),t)})(),F=()=>typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"t_dark-theme":"t_light-theme";var C={success:"#22c55e",error:"#ef4444",warning:"#eab308",info:"#3b82f6",loading:"currentColor"},Z={"top-left":"t_slide-enter-top","top-right":"t_slide-enter-top","top-center":"t_slide-enter-top","bottom-left":"t_slide-enter-bottom","bottom-right":"t_slide-enter-bottom","bottom-center":"t_slide-enter-bottom"},tt={"top-left":"t-slide-exit-top","top-right":"t-slide-exit-top","top-center":"t-slide-exit-top","bottom-left":"t-slide-exit-bottom","bottom-right":"t-slide-exit-bottom","bottom-center":"t-slide-exit-bottom"},ot={"top-left":"t_swipe-exit-left","top-right":"t_swipe-exit-right","top-center":"t_swipe-exit-center","bottom-left":"t_swipe-exit-left","bottom-right":"t_swipe-exit-right","bottom-center":"t_swipe-exit-center"},Y=(t,o,e)=>t?o==="swipe"?ot[e]:tt[e]:Z[e];var i=require("react/jsx-runtime"),et=t=>{let[o,e]=(0,g.useState)(t.variant||"info"),[a,n]=(0,g.useState)(C[o]),[f,l]=(0,g.useState)(t.text),[h,T]=(0,g.useState)(!1),x=t.delayDuration||4e3,{pause:u,resume:c}=L(()=>{b()},x),s=d("t_icon",t.variant==="loading"&&o==="loading"?"t_loading":""),p={success:(0,i.jsx)(A,{width:18,height:18,style:{fill:a},className:s}),error:(0,i.jsx)(E,{width:18,height:18,style:{fill:a},className:s}),warning:(0,i.jsx)(z,{width:18,height:18,style:{fill:a},className:s}),info:(0,i.jsx)(R,{width:18,height:18,style:{fill:a},className:s}),loading:(0,i.jsx)(S,{width:18,height:18,style:{fill:a},className:s})},_=t.toastOptions?.icons?t.toastOptions?.icons[o]:p[o],b=(0,g.useCallback)(()=>{T(!0),W()?t.onClose&&t.onClose():setTimeout(()=>{t.onClose&&t.onClose()},300)},[t]),P=()=>{c()},v=()=>{u()};return(0,g.useEffect)(()=>{t.variant==="loading"&&t.options&&(u(),(typeof t.options.promise=="function"?t.options.promise():Promise.resolve(t.options.promise)).then(N=>{c(),e("success"),t.options.autoDismiss&&setTimeout(()=>{b()},x),l(t.options.success),n(C.success),t.options?.onSuccess&&t.options.onSuccess(N)}).catch(N=>{e("error"),l(t.options.error),n(C.error),t.options.autoDismiss&&setTimeout(()=>{b()},x),t.options?.onError&&t.options.onError(N,t.id)}))},[x,b,u,t.options,t.variant,c]),(0,i.jsxs)("div",{...t.attrs,role:"alert","aria-labelledby":`toast-title-${t.id}`,"aria-describedby":`toast-description-${t.id}`,title:t.text,className:d(W()?"":Y(h,t.toastOptions?.animationOnClose||"slide",t.toastPosition),!t.toastOptions?.headless&&t.theme==="system"?F():"",!t.toastOptions?.headless&&t.theme==="dark"?"t_dark-theme":"",!t.toastOptions?.headless&&t.theme==="light"?"t_light-theme":"",t.toastOptions?.headless?"":"t_global",t.toastOptions?.classNames?.toast,t.attrs?.className),style:{zIndex:t.active?1e3:999,...t.attrs?.style},onMouseEnter:v,onMouseLeave:P,onFocus:v,onBlur:P,children:[(0,i.jsxs)("div",{className:d(t.toastOptions?.headless?"":"t_container",t.toastOptions?.classNames?.container),children:[t.variant&&!t.icon?(0,i.jsx)("div",{className:d(t.toastOptions?.headless?"":"t_icon",t.toastOptions?.classNames?.icon),children:_}):t.icon&&(0,i.jsx)("div",{className:d(t.toastOptions?.headless?"":"t_icon",t.toastOptions?.classNames?.icon),children:t.icon}),(0,i.jsxs)("div",{className:d(t.toastOptions?.headless?"":"t_content",t.toastOptions?.classNames?.content),children:[(0,i.jsx)("p",{id:`toast-title-${t.id}`,children:f}),t.description&&(0,i.jsx)("p",{id:`toast-description-${t.id}`,children:t.description})]})]}),(0,i.jsxs)("div",{className:d(t.toastOptions?.headless?"":"t_actions",t.toastOptions?.classNames?.actions?.container),children:[t.action&&(0,i.jsx)("button",{onClick:t.action.onClick,title:typeof t.action.content=="string"?t.action.content:"Action Button",className:d(t.toastOptions?.classNames?.actions?.actionBtn),children:t.action.content??t.toastOptions?.defaultActionContent??"Action"}),(0,i.jsx)("button",{onClick:b,title:"Close toast",className:d(t.toastOptions?.classNames?.actions?.closeBtn),children:t.toastOptions?.defaultCloseContent??"Close"})]})]})},D=et;var V=require("react/jsx-runtime"),M,O,U=({maxToasts:t=4,position:o="bottom-right",theme:e="system",toastOptions:a,...n})=>{let[f,l]=(0,y.useState)([]),[h,T]=(0,y.useState)(!1);(0,y.useEffect)(()=>{T(!0)},[]);let x=c=>{let s={id:B(),...c};l(p=>{let _=o==="top-left"||o==="top-right"||o==="top-center",b=!1,P=p.map(v=>v.id===s.id?(b=!0,{...v,...s}):v);return b?[...P]:p.length>=t?_?[s,...p.slice(0,-1)]:[...p.slice(1),s]:_?[s,...p]:[...p,s]})},u=c=>{l(s=>s.filter(p=>p.id!==c))};return M=x,O=u,h&&f.length>0&&(0,V.jsx)("section",{...n,"aria-label":"Toast Notifications",role:"alert","aria-live":"polite",className:d("t_toasts",o==="top-left"?"t_top-left":"",o==="top-right"?"t_top-right":"",o==="top-center"?"t_top-center":"",o==="bottom-left"?"t_bottom-left":"",o==="bottom-right"?"t_bottom-right":"",o==="bottom-center"?"t_bottom-center":"",a?.font?a?.font:"t_default_font"),children:f.map(c=>(0,V.jsx)(D,{theme:e,toastPosition:o,onClose:()=>u(c.id),toastOptions:a,active:f.indexOf(c)===f.length-1,...c},c.id))})},w=t=>{M?M(t):console.error("\u{1F514} <Toaster /> component is not mounted. Check toast.pheralb.dev/toaster for more information.")},j=t=>{O?O(t):console.error("\u{1F514} <Toaster /> component is not mounted. Check toast.pheralb.dev/toaster for more information.")};var $={default:t=>(w({...t}),t),success:t=>(w({...t,variant:"success"}),t),error:t=>(w({...t,variant:"error"}),t),warning:t=>(w({...t,variant:"warning"}),t),info:t=>(w({...t,variant:"info"}),t),loading:t=>(w({...t,variant:"loading"}),t),close:t=>j(t)};0&&(module.exports={Toaster,toast});
|
|
4
|
+
//# sourceMappingURL=main.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/main.tsx","#style-inject:#style-inject","../src/styles/globals.css","../src/components/toaster.tsx","../src/components/toast.tsx","../src/icons/index.tsx","../src/hooks/useTimeout.tsx","../src/utils/index.ts","../src/components/default-options.ts","../src/components/toast-functions.ts"],"sourcesContent":["/* eslint-disable react-refresh/only-export-components */\nimport \"./styles/globals.css\";\n\nexport { toast } from \"./components/toast-functions\";\nexport { Toaster } from \"./components/toaster\";\nexport type {\n Position as ToastPosition,\n ToastProps as ToastProperties,\n Variant as ToastVariant,\n Theme as ToastTheme,\n ToastOptions,\n ToasterProperties,\n ToastPropsWithLoading,\n ToastPropsWithVariant,\n ToastAnimations,\n} from \"./types/toast.types\";\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\":root{--pheralb-toast-animation-enter: .4s;--pheralb-toast-animation-exit: .4s}:where(.t_global){--box-shadow: rgba(0, 0, 0, .1);--background-color: #ffffff;--hover-bg-color: #f5f5f5;--border-color: #e5e5e5;--text-color: #171717;--description-color: #262626;--focus-color: #a3a3a3}.t_light-theme{--box-shadow: rgba(0, 0, 0, .1);--background-color: #ffffff;--hover-bg-color: #f5f5f5;--border-color: #e5e5e5;--text-color: #171717;--description-color: #262626;--focus-color: #a3a3a3}.t_dark-theme{--box-shadow: rgba(0, 0, 0, .1);--background-color: #171717;--hover-bg-color: #27272a;--border-color: #262626;--text-color: #fafafa;--description-color: #e5e5e5;--focus-color: #404040}@media (prefers-color-scheme: dark){:where(.t_global){--box-shadow: rgba(0, 0, 0, .1);--background-color: #171717;--hover-bg-color: #27272a;--border-color: #262626;--text-color: #fafafa;--description-color: #e5e5e5;--focus-color: #404040}}.t_toasts{display:flex;flex-direction:column;gap:10px;padding:14px;position:fixed;z-index:999;overflow:hidden;transition:max-height .5s ease-in-out;width:100%}.t_default_font{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.t_top-left{top:0;left:0}.t_top-right{top:0;right:0}.t_top-center{top:0;left:50%;transform:translate(-50%)}.t_bottom-left{bottom:0;left:0}.t_bottom-right{bottom:0;right:0}.t_bottom-center{bottom:0;left:50%;transform:translate(-50%)}@media (min-width: 768px){.t_toasts{max-width:355px}}.t_global{display:flex;justify-content:space-between;padding:0;margin:0;list-style:none;outline:none;background-color:var(--background-color);width:auto;box-shadow:0 1px 3px 0 var(--box-shadow),0 1px 2px -1px var(--box-shadow);border:1px solid var(--border-color);border-radius:.375rem;font-size:.875rem;line-height:1.25rem;overflow:hidden}.t_global button{border:none;outline:none}.t_global button:focus{outline:1px solid var(--focus-color);outline-offset:0px;background-color:var(--hover-color)}.t_container{display:flex;flex-direction:row;align-items:center;width:100%;max-width:20rem;height:100wh;gap:.6rem;padding:12px;word-wrap:break-word;overflow-wrap:break-word}.t_icon{fill:var(--text-color);margin-top:.1rem;flex-shrink:0}.t_content{display:flex;flex-direction:column;justify-content:center;max-width:100%}.t_content p{font-weight:600;color:var(--text-color);margin:0}.t_content p:nth-of-type(2){font-weight:400;font-size:.75rem;color:var(--description-color)}.t_actions{display:flex;flex-direction:column;border-left:1px solid var(--border-color);height:100wh}.t_actions>button{flex:1 1 0%;width:100%;padding:6px 20px;font-size:13px;background-color:transparent;cursor:pointer;border:none}.t_actions>button:nth-child(1){color:var(--text-color);font-weight:500}.t_actions>button:nth-child(2){color:var(--text-color);border-top:1px solid var(--border-color)}.t_actions>button:hover{background-color:var(--hover-color)}.t_loading{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.t_slide-enter-top{animation:slide-top var(--pheralb-toast-animation-enter) ease}@keyframes slide-top{0%{opacity:0;transform:translateY(-100%)}to{opacity:1;transform:translateY(0)}}.t_slide-enter-bottom{animation:slide-bottom var(--pheralb-toast-animation-enter) ease}@keyframes slide-bottom{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}.t-slide-exit-top,.t-slide-exit-bottom{will-change:transform,opacity}.t-slide-exit-top{animation:slide-top-exit var(--pheralb-toast-animation-exit) ease}@keyframes slide-top-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t-slide-exit-bottom{animation:slide-bottom-exit var(--pheralb-toast-animation-exit) ease}@keyframes slide-bottom-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(100%)}}.t_swipe-exit-center{animation:swipe-center-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-center-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t_swipe-exit-left{animation:swipe-left-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-left-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-100%)}}.t_swipe-exit-right{animation:swipe-right-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-right-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(100%)}}\\n\")","import { useEffect, useState } from \"react\";\n\nimport type {\n ToastId,\n ToastPropsWithVariant,\n ToasterProperties,\n} from \"../types/toast.types\";\n\nimport ToastComponent from \"./toast\";\nimport { cn, generateRandomId } from \"../utils\";\n\n// Ensure openToastGlobal is initialized correctly\nlet openToastGlobal: (data: ToastPropsWithVariant) => void;\n// Ensure closeToastGlobal is initialized correctly\nlet closeToastGlobal: (id: ToastId) => void;\n\nexport const Toaster = ({\n maxToasts = 4,\n position = \"bottom-right\",\n theme = \"system\",\n toastOptions,\n ...htmlProps\n}: ToasterProperties) => {\n const [toasts, setToasts] = useState<ToastPropsWithVariant[]>([]);\n const [isMounted, setIsMounted] = useState<boolean>(false);\n\n useEffect(() => {\n setIsMounted(true);\n }, []);\n\n // Define the openToast function\n const openToast = (data: ToastPropsWithVariant) => {\n const newToast = {\n id: generateRandomId(),\n ...data,\n };\n setToasts((prevToasts) => {\n const isTopPosition =\n position === \"top-left\" ||\n position === \"top-right\" ||\n position === \"top-center\";\n\n // If the `id` exists, update the notification\n let isToastUpdate = false;\n const updatedToasts = prevToasts.map(pt => {\n if (pt.id === newToast.id) {\n isToastUpdate = true;\n return {...pt, ...newToast}\n }\n return pt\n })\n\n if (isToastUpdate) {\n // `newToast` is embedded, array preserves length\n return [...updatedToasts]\n }\n\n if (prevToasts.length >= maxToasts) {\n return isTopPosition\n ? [newToast, ...prevToasts.slice(0, -1)]\n : [...prevToasts.slice(1), newToast];\n }\n\n return isTopPosition\n ? [newToast, ...prevToasts]\n : [...prevToasts, newToast];\n });\n };\n\n // Define the closeToast function\n const closeToast = (id: ToastId) => {\n setToasts((prevToasts) => prevToasts.filter((toast) => toast.id !== id));\n };\n\n // Assign openToast to the global variable\n openToastGlobal = openToast;\n // Assign closeToast to the global variable\n closeToastGlobal = closeToast;\n\n // Render the component\n return (\n isMounted &&\n toasts.length > 0 && (\n <section\n {...htmlProps}\n aria-label=\"Toast Notifications\"\n role=\"alert\"\n aria-live=\"polite\"\n className={cn(\n \"t_toasts\",\n position === \"top-left\" ? \"t_top-left\" : \"\",\n position === \"top-right\" ? \"t_top-right\" : \"\",\n position === \"top-center\" ? \"t_top-center\" : \"\",\n position === \"bottom-left\" ? \"t_bottom-left\" : \"\",\n position === \"bottom-right\" ? \"t_bottom-right\" : \"\",\n position === \"bottom-center\" ? \"t_bottom-center\" : \"\",\n toastOptions?.font ? toastOptions?.font : \"t_default_font\",\n )}\n >\n {toasts.map((toast) => (\n <ToastComponent\n key={toast.id}\n theme={theme}\n toastPosition={position}\n onClose={() => closeToast(toast.id!)}\n toastOptions={toastOptions}\n active={toasts.indexOf(toast) === toasts.length - 1}\n {...toast}\n />\n ))}\n </section>\n )\n );\n};\n\n// Export the openToast function:\n// eslint-disable-next-line react-refresh/only-export-components\nexport const openToast = (data: ToastPropsWithVariant): void => {\n if (openToastGlobal) {\n openToastGlobal(data);\n } else {\n console.error(\n \"๐ <Toaster /> component is not mounted. Check toast.pheralb.dev/toaster for more information.\",\n );\n }\n};\n\n// Export the closeToast function:\n// eslint-disable-next-line react-refresh/only-export-components\nexport const closeToast = (id: ToastId): void => {\n if (closeToastGlobal) {\n closeToastGlobal(id);\n } else {\n console.error(\n \"๐ <Toaster /> component is not mounted. Check toast.pheralb.dev/toaster for more information.\",\n );\n }\n};\n","import type {\n Position,\n ToastIcons,\n ToastOptions,\n ToastPropsWithLoading,\n Variant,\n} from \"../types/toast.types\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport { Error, Info, Loading, Success, Warning } from \"../icons\";\nimport { useTimeout } from \"../hooks/useTimeout\";\nimport { cn, getSystemTheme, prefersReducedMotion } from \"../utils\";\n\nimport { iconsColors, getAnimationClass } from \"./default-options\";\n\ninterface ToastComponentProps extends ToastPropsWithLoading {\n toastPosition: Position;\n toastOptions?: ToastOptions;\n active?: boolean;\n onClose: () => void;\n}\n\nconst Toast = (props: ToastComponentProps) => {\n const [status, setStatus] = useState<Variant>(props.variant || \"info\");\n const [iconColor, setIconColor] = useState<string>(iconsColors[status]);\n const [toastText, setToastText] = useState<string>(props.text);\n const [isExiting, setIsExiting] = useState<boolean>(false);\n\n const delayDuration = props.delayDuration || 4000;\n\n const { pause, resume } = useTimeout(() => {\n handleCloseToast();\n }, delayDuration);\n\n const iconClass = cn(\n \"t_icon\",\n props.variant === \"loading\" && status === \"loading\" ? \"t_loading\" : \"\",\n );\n\n const icons: ToastIcons = {\n success: (\n <Success\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n error: (\n <Error\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n warning: (\n <Warning\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n info: (\n <Info\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n loading: (\n <Loading\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n };\n\n const IconComponent = props.toastOptions?.icons\n ? props.toastOptions?.icons[status]\n : icons[status];\n\n const handleCloseToast = useCallback(() => {\n setIsExiting(true);\n const animationDisabled = prefersReducedMotion();\n if (!animationDisabled) {\n setTimeout(() => {\n if (props.onClose) {\n props.onClose();\n }\n }, 300);\n } else if (props.onClose) {\n props.onClose();\n }\n }, [props]);\n\n const handleMouseLeave = () => {\n resume();\n };\n\n const handleMouseEnter = () => {\n pause();\n };\n\n useEffect(() => {\n if (props.variant === \"loading\" && props.options) {\n pause();\n\n const executePromise =\n typeof props.options.promise === \"function\"\n ? props.options.promise()\n : Promise.resolve(props.options.promise);\n\n executePromise\n .then((data) => {\n resume();\n setStatus(\"success\");\n if (props.options!.autoDismiss) {\n setTimeout(() => {\n handleCloseToast();\n }, delayDuration);\n }\n setToastText(props.options!.success);\n setIconColor(iconsColors.success);\n if (props.options?.onSuccess) {\n props.options.onSuccess(data);\n }\n })\n .catch((error) => {\n setStatus(\"error\");\n setToastText(props.options!.error);\n setIconColor(iconsColors.error);\n if (props.options!.autoDismiss) {\n setTimeout(() => {\n handleCloseToast();\n }, delayDuration);\n }\n if (props.options?.onError) {\n props.options.onError(error, props.id);\n }\n });\n }\n }, [\n delayDuration,\n handleCloseToast,\n pause,\n props.options,\n props.variant,\n resume,\n ]);\n\n return (\n <div\n {...props.attrs}\n role=\"alert\"\n aria-labelledby={`toast-title-${props.id}`}\n aria-describedby={`toast-description-${props.id}`}\n title={props.text}\n className={cn(\n !prefersReducedMotion()\n ? getAnimationClass(\n isExiting,\n props.toastOptions?.animationOnClose || \"slide\",\n props.toastPosition,\n )\n : \"\",\n !props.toastOptions?.headless && props.theme === \"system\"\n ? getSystemTheme()\n : \"\",\n !props.toastOptions?.headless && props.theme === \"dark\"\n ? \"t_dark-theme\"\n : \"\",\n !props.toastOptions?.headless && props.theme === \"light\"\n ? \"t_light-theme\"\n : \"\",\n !props.toastOptions?.headless ? \"t_global\" : \"\",\n props.toastOptions?.classNames?.toast,\n props.attrs?.className,\n )}\n style={{\n zIndex: props.active ? 1000 : 999,\n ...props.attrs?.style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleMouseEnter}\n onBlur={handleMouseLeave}\n >\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_container\" : \"\",\n props.toastOptions?.classNames?.container,\n )}\n >\n {props.variant && !props.icon ? (\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_icon\" : \"\",\n props.toastOptions?.classNames?.icon,\n )}\n >\n {IconComponent}\n </div>\n ) : (\n props.icon && (\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_icon\" : \"\",\n props.toastOptions?.classNames?.icon,\n )}\n >\n {props.icon}\n </div>\n )\n )}\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_content\" : \"\",\n props.toastOptions?.classNames?.content,\n )}\n >\n <p id={`toast-title-${props.id}`}>{toastText}</p>\n {props.description && (\n <p id={`toast-description-${props.id}`}>{props.description}</p>\n )}\n </div>\n </div>\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_actions\" : \"\",\n props.toastOptions?.classNames?.actions?.container,\n )}\n >\n {props.action && (\n <button\n onClick={props.action.onClick}\n title={\n typeof props.action.content === \"string\"\n ? props.action.content\n : \"Action Button\"\n }\n className={cn(props.toastOptions?.classNames?.actions?.actionBtn)}\n >\n {props.action.content ??\n props.toastOptions?.defaultActionContent ??\n \"Action\"}\n </button>\n )}\n <button\n onClick={handleCloseToast}\n title=\"Close toast\"\n className={cn(props.toastOptions?.classNames?.actions?.closeBtn)}\n >\n {props.toastOptions?.defaultCloseContent ?? \"Close\"}\n </button>\n </div>\n </div>\n );\n};\n\nexport default Toast;\n","import type { ComponentProps, FC } from \"react\";\n\nexport const Success: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm45.66 85.66l-56 56a8 8 0 01-11.32 0l-24-24a8 8 0 0111.32-11.32L112 148.69l50.34-50.35a8 8 0 0111.32 11.32z\"></path>\n </svg>\n);\n\nexport const Warning: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M236.8 188.09L149.35 36.22a24.76 24.76 0 00-42.7 0L19.2 188.09a23.51 23.51 0 000 23.72A24.35 24.35 0 0040.55 224h174.9a24.35 24.35 0 0021.33-12.19 23.51 23.51 0 00.02-23.72zM120 104a8 8 0 0116 0v40a8 8 0 01-16 0zm8 88a12 12 0 1112-12 12 12 0 01-12 12z\"></path>\n </svg>\n);\n\nexport const Error: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm-8 56a8 8 0 0116 0v56a8 8 0 01-16 0zm8 104a12 12 0 1112-12 12 12 0 01-12 12z\"></path>\n </svg>\n);\n\nexport const Info: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm-4 48a12 12 0 11-12 12 12 12 0 0112-12zm12 112a16 16 0 01-16-16v-40a8 8 0 010-16 16 16 0 0116 16v40a8 8 0 010 16z\"></path>\n </svg>\n);\n\nexport const Loading: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M136 32v32a8 8 0 01-16 0V32a8 8 0 0116 0zm37.25 58.75a8 8 0 005.66-2.35l22.63-22.62a8 8 0 00-11.32-11.32L167.6 77.09a8 8 0 005.65 13.66zM224 120h-32a8 8 0 000 16h32a8 8 0 000-16zm-45.09 47.6a8 8 0 00-11.31 11.31l22.62 22.63a8 8 0 0011.32-11.32zM128 184a8 8 0 00-8 8v32a8 8 0 0016 0v-32a8 8 0 00-8-8zm-50.91-16.4l-22.63 22.62a8 8 0 0011.32 11.32l22.62-22.63a8 8 0 00-11.31-11.31zM72 128a8 8 0 00-8-8H32a8 8 0 000 16h32a8 8 0 008-8zm-6.22-73.54a8 8 0 00-11.32 11.32L77.09 88.4A8 8 0 0088.4 77.09z\"></path>\n </svg>\n);\n","import { useCallback, useEffect, useRef } from \"react\";\n\ninterface UseTimeoutReturn {\n pause: () => void;\n resume: () => void;\n reset: () => void;\n isActive: boolean;\n}\n\nexport const useTimeout = (\n callback: () => void,\n delay: number,\n): UseTimeoutReturn => {\n const timeoutRef = useRef<number>(0);\n const callbackRef = useRef(callback);\n const startTimeRef = useRef<number>(0);\n const remainingRef = useRef(delay);\n const isActiveRef = useRef(true);\n\n const cleanup = useCallback(() => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n }, []);\n\n const pause = useCallback(() => {\n if (!isActiveRef.current || !startTimeRef.current) return;\n\n cleanup();\n remainingRef.current -= Date.now() - startTimeRef.current;\n isActiveRef.current = false;\n }, [cleanup]);\n\n const resume = useCallback(() => {\n if (isActiveRef.current) return;\n\n startTimeRef.current = Date.now();\n timeoutRef.current = window.setTimeout(\n callbackRef.current,\n remainingRef.current,\n );\n isActiveRef.current = true;\n }, []);\n\n const reset = useCallback(() => {\n cleanup();\n remainingRef.current = delay;\n startTimeRef.current = Date.now();\n timeoutRef.current = window.setTimeout(callbackRef.current, delay);\n isActiveRef.current = true;\n }, [cleanup, delay]);\n\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n useEffect(() => {\n reset();\n return cleanup;\n }, [delay, reset, cleanup]);\n\n return {\n pause,\n resume,\n reset,\n isActive: isActiveRef.current,\n };\n};\n","export const cn = (...classes: (string | undefined)[]) => {\n return classes.filter(Boolean).join(\" \");\n};\n\nexport const generateRandomId = () => Math.floor(Math.random() * 1000000);\n\nexport const prefersReducedMotion = (() => {\n let shouldReduceMotion: boolean | undefined = undefined;\n return () => {\n if (shouldReduceMotion === undefined) {\n if (typeof window !== \"undefined\" && window.matchMedia !== undefined) {\n const mediaQuery = window.matchMedia(\n \"(prefers-reduced-motion: reduce)\",\n );\n shouldReduceMotion = mediaQuery.matches;\n } else {\n shouldReduceMotion = false;\n }\n }\n return shouldReduceMotion;\n };\n})();\n\n// Get system theme:\nexport const getSystemTheme = () => {\n if (typeof window !== \"undefined\") {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"t_dark-theme\"\n : \"t_light-theme\";\n }\n return \"t_light-theme\";\n};\n","import type { Position, ToastAnimations, Variant } from \"../types/toast.types\";\n\n/* Default icon colors */\n\nexport const iconsColors: Record<Variant, string> = {\n success: \"#22c55e\",\n error: \"#ef4444\",\n warning: \"#eab308\",\n info: \"#3b82f6\",\n loading: \"currentColor\",\n};\n\n/* Default animations */\n\nconst ANIMATION_ENTER_MAP: Record<Position, string> = {\n \"top-left\": \"t_slide-enter-top\",\n \"top-right\": \"t_slide-enter-top\",\n \"top-center\": \"t_slide-enter-top\",\n \"bottom-left\": \"t_slide-enter-bottom\",\n \"bottom-right\": \"t_slide-enter-bottom\",\n \"bottom-center\": \"t_slide-enter-bottom\",\n};\n\nconst ANIMATION_EXIT_MAP: Record<Position, string> = {\n \"top-left\": \"t-slide-exit-top\",\n \"top-right\": \"t-slide-exit-top\",\n \"top-center\": \"t-slide-exit-top\",\n \"bottom-left\": \"t-slide-exit-bottom\",\n \"bottom-right\": \"t-slide-exit-bottom\",\n \"bottom-center\": \"t-slide-exit-bottom\",\n};\n\n/* Swipe exit animations */\n\nconst ANIMATION_SWIPE_EXIT_MAP: Record<Position, string> = {\n \"top-left\": \"t_swipe-exit-left\",\n \"top-right\": \"t_swipe-exit-right\",\n \"top-center\": \"t_swipe-exit-center\",\n \"bottom-left\": \"t_swipe-exit-left\",\n \"bottom-right\": \"t_swipe-exit-right\",\n \"bottom-center\": \"t_swipe-exit-center\",\n};\n\nexport const getAnimationClass = (\n isExiting: boolean,\n animationType: ToastAnimations,\n position: Position,\n) => {\n if (!isExiting) {\n return ANIMATION_ENTER_MAP[position];\n }\n\n if (animationType === \"swipe\") {\n return ANIMATION_SWIPE_EXIT_MAP[position];\n }\n\n return ANIMATION_EXIT_MAP[position];\n};\n","import type {\n ToastId,\n ToastPropsWithLoading,\n ToastPropsWithVariant\n} from '../types/toast.types';\nimport { openToast, closeToast } from './toaster';\n\ninterface ToastFunctions {\n default: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n success: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n error: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n warning: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n info: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n loading: (data: ToastPropsWithLoading) => ToastPropsWithLoading;\n close: (id: ToastId) => void;\n}\n\nexport const toast: ToastFunctions = {\n default: (data: ToastPropsWithVariant) => {\n openToast({ ...data });\n return data;\n },\n success: (data: ToastPropsWithVariant) => {\n openToast({ ...data, variant: 'success' });\n return data;\n },\n error: (data: ToastPropsWithVariant) => {\n openToast({ ...data, variant: 'error' });\n return data;\n },\n warning: (data: ToastPropsWithVariant) => {\n openToast({ ...data, variant: 'warning' });\n return data;\n },\n info: (data: ToastPropsWithVariant) => {\n openToast({ ...data, variant: 'info' });\n return data;\n },\n loading: (data: ToastPropsWithLoading) => {\n openToast({ ...data, variant: 'loading' });\n return data;\n },\n close: (id: ToastId) => closeToast(id)\n};\n"],"mappings":"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","names":["main_exports","__export","Toaster","toast","__toCommonJS","styleInject","css","insertAt","head","style","styleInject","import_react","import_react","import_jsx_runtime","Success","props","Warning","Error","Info","Loading","import_react","useTimeout","callback","delay","timeoutRef","callbackRef","startTimeRef","remainingRef","isActiveRef","cleanup","pause","resume","reset","cn","classes","generateRandomId","prefersReducedMotion","shouldReduceMotion","getSystemTheme","iconsColors","ANIMATION_ENTER_MAP","ANIMATION_EXIT_MAP","ANIMATION_SWIPE_EXIT_MAP","getAnimationClass","isExiting","animationType","position","import_jsx_runtime","Toast","props","status","setStatus","iconColor","setIconColor","iconsColors","toastText","setToastText","isExiting","setIsExiting","delayDuration","pause","resume","useTimeout","handleCloseToast","iconClass","cn","icons","Success","Error","Warning","Info","Loading","IconComponent","prefersReducedMotion","handleMouseLeave","handleMouseEnter","data","error","getAnimationClass","getSystemTheme","toast_default","import_jsx_runtime","openToastGlobal","closeToastGlobal","Toaster","maxToasts","position","theme","toastOptions","htmlProps","toasts","setToasts","isMounted","setIsMounted","openToast","data","newToast","generateRandomId","prevToasts","isTopPosition","isToastUpdate","updatedToasts","pt","closeToast","id","toast","cn","toast_default","toast","data","openToast","id","closeToast"]}
|
package/dist/main.d.cts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ReactNode, HTMLProps } from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
type Variant = "success" | "error" | "warning" | "info" | "loading";
|
|
5
|
+
type Position = "top-left" | "top-right" | "top-center" | "bottom-left" | "bottom-right" | "bottom-center";
|
|
6
|
+
type Theme = "light" | "dark" | "system";
|
|
7
|
+
interface Action {
|
|
8
|
+
content?: string | ReactNode;
|
|
9
|
+
onClick: () => void | (() => Promise<void>);
|
|
10
|
+
}
|
|
11
|
+
type ToastIcons = Record<Variant, ReactNode>;
|
|
12
|
+
type ToastId = number | string;
|
|
13
|
+
type ToastProps = {
|
|
14
|
+
/**
|
|
15
|
+
* Optionally set an ID.
|
|
16
|
+
* If the ID exists, it will replace the existing notification
|
|
17
|
+
*/
|
|
18
|
+
id?: ToastId;
|
|
19
|
+
text: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
icon?: ReactNode;
|
|
22
|
+
delayDuration?: number;
|
|
23
|
+
theme?: Theme;
|
|
24
|
+
action?: Action;
|
|
25
|
+
/**
|
|
26
|
+
* Set any HTML Attributes to the notification
|
|
27
|
+
*/
|
|
28
|
+
attrs?: HTMLProps<HTMLDivElement>;
|
|
29
|
+
};
|
|
30
|
+
interface LoadingType<T = unknown> {
|
|
31
|
+
promise: (() => Promise<T>) | Promise<T>;
|
|
32
|
+
success: string;
|
|
33
|
+
error: string;
|
|
34
|
+
autoDismiss: boolean;
|
|
35
|
+
onSuccess?: (data: T) => void;
|
|
36
|
+
onError?: (error: Error, id?: ToastId) => void;
|
|
37
|
+
}
|
|
38
|
+
interface ToastActionsCustomClassnames {
|
|
39
|
+
container: string;
|
|
40
|
+
closeBtn: string;
|
|
41
|
+
actionBtn: string;
|
|
42
|
+
}
|
|
43
|
+
interface ToastClassnames {
|
|
44
|
+
toast?: string;
|
|
45
|
+
container?: string;
|
|
46
|
+
icon?: string;
|
|
47
|
+
content?: string;
|
|
48
|
+
actions?: ToastActionsCustomClassnames;
|
|
49
|
+
}
|
|
50
|
+
type ToastAnimations = "slide" | "swipe";
|
|
51
|
+
type ToastOptions = {
|
|
52
|
+
animationOnClose?: ToastAnimations;
|
|
53
|
+
font?: string;
|
|
54
|
+
icons?: ToastIcons;
|
|
55
|
+
headless?: boolean;
|
|
56
|
+
classNames?: ToastClassnames;
|
|
57
|
+
defaultActionContent?: string | ReactNode;
|
|
58
|
+
defaultCloseContent?: string | ReactNode;
|
|
59
|
+
};
|
|
60
|
+
type ToasterHTMLElementProperties = Omit<HTMLProps<HTMLElement>, 'aria-role' | 'aria-label' | 'role' | 'className'>;
|
|
61
|
+
type ToasterProperties = ToasterHTMLElementProperties & {
|
|
62
|
+
theme?: Theme;
|
|
63
|
+
maxToasts?: number;
|
|
64
|
+
position?: Position;
|
|
65
|
+
toastOptions?: ToastOptions;
|
|
66
|
+
};
|
|
67
|
+
interface ToastPropsWithVariant extends ToastProps {
|
|
68
|
+
variant?: Variant;
|
|
69
|
+
}
|
|
70
|
+
interface ToastPropsWithLoading extends ToastPropsWithVariant {
|
|
71
|
+
options?: LoadingType;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface ToastFunctions {
|
|
75
|
+
default: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
76
|
+
success: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
77
|
+
error: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
78
|
+
warning: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
79
|
+
info: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
80
|
+
loading: (data: ToastPropsWithLoading) => ToastPropsWithLoading;
|
|
81
|
+
close: (id: ToastId) => void;
|
|
82
|
+
}
|
|
83
|
+
declare const toast: ToastFunctions;
|
|
84
|
+
|
|
85
|
+
declare const Toaster: ({ maxToasts, position, theme, toastOptions, ...htmlProps }: ToasterProperties) => false | react_jsx_runtime.JSX.Element;
|
|
86
|
+
|
|
87
|
+
export { type ToastAnimations, type ToastOptions, type Position as ToastPosition, type ToastProps as ToastProperties, type ToastPropsWithLoading, type ToastPropsWithVariant, type Theme as ToastTheme, type Variant as ToastVariant, Toaster, type ToasterProperties, toast };
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ReactNode, HTMLProps } from 'react';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
type Variant = "success" | "error" | "warning" | "info" | "loading";
|
|
5
|
+
type Position = "top-left" | "top-right" | "top-center" | "bottom-left" | "bottom-right" | "bottom-center";
|
|
6
|
+
type Theme = "light" | "dark" | "system";
|
|
7
|
+
interface Action {
|
|
8
|
+
content?: string | ReactNode;
|
|
9
|
+
onClick: () => void | (() => Promise<void>);
|
|
10
|
+
}
|
|
11
|
+
type ToastIcons = Record<Variant, ReactNode>;
|
|
12
|
+
type ToastId = number | string;
|
|
13
|
+
type ToastProps = {
|
|
14
|
+
/**
|
|
15
|
+
* Optionally set an ID.
|
|
16
|
+
* If the ID exists, it will replace the existing notification
|
|
17
|
+
*/
|
|
18
|
+
id?: ToastId;
|
|
19
|
+
text: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
icon?: ReactNode;
|
|
22
|
+
delayDuration?: number;
|
|
23
|
+
theme?: Theme;
|
|
24
|
+
action?: Action;
|
|
25
|
+
/**
|
|
26
|
+
* Set any HTML Attributes to the notification
|
|
27
|
+
*/
|
|
28
|
+
attrs?: HTMLProps<HTMLDivElement>;
|
|
29
|
+
};
|
|
30
|
+
interface LoadingType<T = unknown> {
|
|
31
|
+
promise: (() => Promise<T>) | Promise<T>;
|
|
32
|
+
success: string;
|
|
33
|
+
error: string;
|
|
34
|
+
autoDismiss: boolean;
|
|
35
|
+
onSuccess?: (data: T) => void;
|
|
36
|
+
onError?: (error: Error, id?: ToastId) => void;
|
|
37
|
+
}
|
|
38
|
+
interface ToastActionsCustomClassnames {
|
|
39
|
+
container: string;
|
|
40
|
+
closeBtn: string;
|
|
41
|
+
actionBtn: string;
|
|
42
|
+
}
|
|
43
|
+
interface ToastClassnames {
|
|
44
|
+
toast?: string;
|
|
45
|
+
container?: string;
|
|
46
|
+
icon?: string;
|
|
47
|
+
content?: string;
|
|
48
|
+
actions?: ToastActionsCustomClassnames;
|
|
49
|
+
}
|
|
50
|
+
type ToastAnimations = "slide" | "swipe";
|
|
51
|
+
type ToastOptions = {
|
|
52
|
+
animationOnClose?: ToastAnimations;
|
|
53
|
+
font?: string;
|
|
54
|
+
icons?: ToastIcons;
|
|
55
|
+
headless?: boolean;
|
|
56
|
+
classNames?: ToastClassnames;
|
|
57
|
+
defaultActionContent?: string | ReactNode;
|
|
58
|
+
defaultCloseContent?: string | ReactNode;
|
|
59
|
+
};
|
|
60
|
+
type ToasterHTMLElementProperties = Omit<HTMLProps<HTMLElement>, 'aria-role' | 'aria-label' | 'role' | 'className'>;
|
|
61
|
+
type ToasterProperties = ToasterHTMLElementProperties & {
|
|
62
|
+
theme?: Theme;
|
|
63
|
+
maxToasts?: number;
|
|
64
|
+
position?: Position;
|
|
65
|
+
toastOptions?: ToastOptions;
|
|
66
|
+
};
|
|
67
|
+
interface ToastPropsWithVariant extends ToastProps {
|
|
68
|
+
variant?: Variant;
|
|
69
|
+
}
|
|
70
|
+
interface ToastPropsWithLoading extends ToastPropsWithVariant {
|
|
71
|
+
options?: LoadingType;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface ToastFunctions {
|
|
75
|
+
default: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
76
|
+
success: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
77
|
+
error: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
78
|
+
warning: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
79
|
+
info: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
|
|
80
|
+
loading: (data: ToastPropsWithLoading) => ToastPropsWithLoading;
|
|
81
|
+
close: (id: ToastId) => void;
|
|
82
|
+
}
|
|
83
|
+
declare const toast: ToastFunctions;
|
|
84
|
+
|
|
85
|
+
declare const Toaster: ({ maxToasts, position, theme, toastOptions, ...htmlProps }: ToasterProperties) => false | react_jsx_runtime.JSX.Element;
|
|
86
|
+
|
|
87
|
+
export { type ToastAnimations, type ToastOptions, type Position as ToastPosition, type ToastProps as ToastProperties, type ToastPropsWithLoading, type ToastPropsWithVariant, type Theme as ToastTheme, type Variant as ToastVariant, Toaster, type ToasterProperties, toast };
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
function I(t,{insertAt:o}={}){if(!t||typeof document>"u")return;let a=document.head||document.getElementsByTagName("head")[0],e=document.createElement("style");e.type="text/css",o==="top"&&a.firstChild?a.insertBefore(e,a.firstChild):a.appendChild(e),e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t))}I(`:root{--pheralb-toast-animation-enter: .4s;--pheralb-toast-animation-exit: .4s}:where(.t_global){--box-shadow: rgba(0, 0, 0, .1);--background-color: #ffffff;--hover-bg-color: #f5f5f5;--border-color: #e5e5e5;--text-color: #171717;--description-color: #262626;--focus-color: #a3a3a3}.t_light-theme{--box-shadow: rgba(0, 0, 0, .1);--background-color: #ffffff;--hover-bg-color: #f5f5f5;--border-color: #e5e5e5;--text-color: #171717;--description-color: #262626;--focus-color: #a3a3a3}.t_dark-theme{--box-shadow: rgba(0, 0, 0, .1);--background-color: #171717;--hover-bg-color: #27272a;--border-color: #262626;--text-color: #fafafa;--description-color: #e5e5e5;--focus-color: #404040}@media (prefers-color-scheme: dark){:where(.t_global){--box-shadow: rgba(0, 0, 0, .1);--background-color: #171717;--hover-bg-color: #27272a;--border-color: #262626;--text-color: #fafafa;--description-color: #e5e5e5;--focus-color: #404040}}.t_toasts{display:flex;flex-direction:column;gap:10px;padding:14px;position:fixed;z-index:999;overflow:hidden;transition:max-height .5s ease-in-out;width:100%}.t_default_font{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.t_top-left{top:0;left:0}.t_top-right{top:0;right:0}.t_top-center{top:0;left:50%;transform:translate(-50%)}.t_bottom-left{bottom:0;left:0}.t_bottom-right{bottom:0;right:0}.t_bottom-center{bottom:0;left:50%;transform:translate(-50%)}@media (min-width: 768px){.t_toasts{max-width:355px}}.t_global{display:flex;justify-content:space-between;padding:0;margin:0;list-style:none;outline:none;background-color:var(--background-color);width:auto;box-shadow:0 1px 3px 0 var(--box-shadow),0 1px 2px -1px var(--box-shadow);border:1px solid var(--border-color);border-radius:.375rem;font-size:.875rem;line-height:1.25rem;overflow:hidden}.t_global button{border:none;outline:none}.t_global button:focus{outline:1px solid var(--focus-color);outline-offset:0px;background-color:var(--hover-color)}.t_container{display:flex;flex-direction:row;align-items:center;width:100%;max-width:20rem;height:100wh;gap:.6rem;padding:12px;word-wrap:break-word;overflow-wrap:break-word}.t_icon{fill:var(--text-color);margin-top:.1rem;flex-shrink:0}.t_content{display:flex;flex-direction:column;justify-content:center;max-width:100%}.t_content p{font-weight:600;color:var(--text-color);margin:0}.t_content p:nth-of-type(2){font-weight:400;font-size:.75rem;color:var(--description-color)}.t_actions{display:flex;flex-direction:column;border-left:1px solid var(--border-color);height:100wh}.t_actions>button{flex:1 1 0%;width:100%;padding:6px 20px;font-size:13px;background-color:transparent;cursor:pointer;border:none}.t_actions>button:nth-child(1){color:var(--text-color);font-weight:500}.t_actions>button:nth-child(2){color:var(--text-color);border-top:1px solid var(--border-color)}.t_actions>button:hover{background-color:var(--hover-color)}.t_loading{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.t_slide-enter-top{animation:slide-top var(--pheralb-toast-animation-enter) ease}@keyframes slide-top{0%{opacity:0;transform:translateY(-100%)}to{opacity:1;transform:translateY(0)}}.t_slide-enter-bottom{animation:slide-bottom var(--pheralb-toast-animation-enter) ease}@keyframes slide-bottom{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}.t-slide-exit-top,.t-slide-exit-bottom{will-change:transform,opacity}.t-slide-exit-top{animation:slide-top-exit var(--pheralb-toast-animation-exit) ease}@keyframes slide-top-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t-slide-exit-bottom{animation:slide-bottom-exit var(--pheralb-toast-animation-exit) ease}@keyframes slide-bottom-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(100%)}}.t_swipe-exit-center{animation:swipe-center-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-center-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t_swipe-exit-left{animation:swipe-left-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-left-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-100%)}}.t_swipe-exit-right{animation:swipe-right-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-right-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(100%)}}
|
|
3
|
+
`);import{useEffect as Z,useState as U}from"react";import{useCallback as q,useEffect as J,useState as C}from"react";import{jsx as h}from"react/jsx-runtime";var V=t=>h("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:h("path",{d:"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm45.66 85.66l-56 56a8 8 0 01-11.32 0l-24-24a8 8 0 0111.32-11.32L112 148.69l50.34-50.35a8 8 0 0111.32 11.32z"})}),A=t=>h("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:h("path",{d:"M236.8 188.09L149.35 36.22a24.76 24.76 0 00-42.7 0L19.2 188.09a23.51 23.51 0 000 23.72A24.35 24.35 0 0040.55 224h174.9a24.35 24.35 0 0021.33-12.19 23.51 23.51 0 00.02-23.72zM120 104a8 8 0 0116 0v40a8 8 0 01-16 0zm8 88a12 12 0 1112-12 12 12 0 01-12 12z"})}),z=t=>h("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:h("path",{d:"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm-8 56a8 8 0 0116 0v56a8 8 0 01-16 0zm8 104a12 12 0 1112-12 12 12 0 01-12 12z"})}),E=t=>h("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:h("path",{d:"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm-4 48a12 12 0 11-12 12 12 12 0 0112-12zm12 112a16 16 0 01-16-16v-40a8 8 0 010-16 16 16 0 0116 16v40a8 8 0 010 16z"})}),R=t=>h("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 256 256",...t,children:h("path",{d:"M136 32v32a8 8 0 01-16 0V32a8 8 0 0116 0zm37.25 58.75a8 8 0 005.66-2.35l22.63-22.62a8 8 0 00-11.32-11.32L167.6 77.09a8 8 0 005.65 13.66zM224 120h-32a8 8 0 000 16h32a8 8 0 000-16zm-45.09 47.6a8 8 0 00-11.31 11.31l22.62 22.63a8 8 0 0011.32-11.32zM128 184a8 8 0 00-8 8v32a8 8 0 0016 0v-32a8 8 0 00-8-8zm-50.91-16.4l-22.63 22.62a8 8 0 0011.32 11.32l22.62-22.63a8 8 0 00-11.31-11.31zM72 128a8 8 0 00-8-8H32a8 8 0 000 16h32a8 8 0 008-8zm-6.22-73.54a8 8 0 00-11.32 11.32L77.09 88.4A8 8 0 0088.4 77.09z"})});import{useCallback as _,useEffect as S,useRef as v}from"react";var L=(t,o)=>{let a=v(0),e=v(t),u=v(0),c=v(o),n=v(!0),d=_(()=>{a.current&&window.clearTimeout(a.current)},[]),w=_(()=>{!n.current||!u.current||(d(),c.current-=Date.now()-u.current,n.current=!1)},[d]),p=_(()=>{n.current||(u.current=Date.now(),a.current=window.setTimeout(e.current,c.current),n.current=!0)},[]),m=_(()=>{d(),c.current=o,u.current=Date.now(),a.current=window.setTimeout(e.current,o),n.current=!0},[d,o]);return S(()=>{e.current=t},[t]),S(()=>(m(),d),[o,m,d]),{pause:w,resume:p,reset:m,isActive:n.current}};var r=(...t)=>t.filter(Boolean).join(" "),B=()=>Math.floor(Math.random()*1e6),W=(()=>{let t;return()=>(t===void 0&&(typeof window<"u"&&window.matchMedia!==void 0?t=window.matchMedia("(prefers-reduced-motion: reduce)").matches:t=!1),t)})(),F=()=>typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"t_dark-theme":"t_light-theme";var P={success:"#22c55e",error:"#ef4444",warning:"#eab308",info:"#3b82f6",loading:"currentColor"},H={"top-left":"t_slide-enter-top","top-right":"t_slide-enter-top","top-center":"t_slide-enter-top","bottom-left":"t_slide-enter-bottom","bottom-right":"t_slide-enter-bottom","bottom-center":"t_slide-enter-bottom"},Q={"top-left":"t-slide-exit-top","top-right":"t-slide-exit-top","top-center":"t-slide-exit-top","bottom-left":"t-slide-exit-bottom","bottom-right":"t-slide-exit-bottom","bottom-center":"t-slide-exit-bottom"},X={"top-left":"t_swipe-exit-left","top-right":"t_swipe-exit-right","top-center":"t_swipe-exit-center","bottom-left":"t_swipe-exit-left","bottom-right":"t_swipe-exit-right","bottom-center":"t_swipe-exit-center"},Y=(t,o,a)=>t?o==="swipe"?X[a]:Q[a]:H[a];import{jsx as l,jsxs as N}from"react/jsx-runtime";var K=t=>{let[o,a]=C(t.variant||"info"),[e,u]=C(P[o]),[c,n]=C(t.text),[d,w]=C(!1),p=t.delayDuration||4e3,{pause:m,resume:s}=L(()=>{g()},p),i=r("t_icon",t.variant==="loading"&&o==="loading"?"t_loading":""),f={success:l(V,{width:18,height:18,style:{fill:e},className:i}),error:l(z,{width:18,height:18,style:{fill:e},className:i}),warning:l(A,{width:18,height:18,style:{fill:e},className:i}),info:l(E,{width:18,height:18,style:{fill:e},className:i}),loading:l(R,{width:18,height:18,style:{fill:e},className:i})},T=t.toastOptions?.icons?t.toastOptions?.icons[o]:f[o],g=q(()=>{w(!0),W()?t.onClose&&t.onClose():setTimeout(()=>{t.onClose&&t.onClose()},300)},[t]),y=()=>{s()},b=()=>{m()};return J(()=>{t.variant==="loading"&&t.options&&(m(),(typeof t.options.promise=="function"?t.options.promise():Promise.resolve(t.options.promise)).then(k=>{s(),a("success"),t.options.autoDismiss&&setTimeout(()=>{g()},p),n(t.options.success),u(P.success),t.options?.onSuccess&&t.options.onSuccess(k)}).catch(k=>{a("error"),n(t.options.error),u(P.error),t.options.autoDismiss&&setTimeout(()=>{g()},p),t.options?.onError&&t.options.onError(k,t.id)}))},[p,g,m,t.options,t.variant,s]),N("div",{...t.attrs,role:"alert","aria-labelledby":`toast-title-${t.id}`,"aria-describedby":`toast-description-${t.id}`,title:t.text,className:r(W()?"":Y(d,t.toastOptions?.animationOnClose||"slide",t.toastPosition),!t.toastOptions?.headless&&t.theme==="system"?F():"",!t.toastOptions?.headless&&t.theme==="dark"?"t_dark-theme":"",!t.toastOptions?.headless&&t.theme==="light"?"t_light-theme":"",t.toastOptions?.headless?"":"t_global",t.toastOptions?.classNames?.toast,t.attrs?.className),style:{zIndex:t.active?1e3:999,...t.attrs?.style},onMouseEnter:b,onMouseLeave:y,onFocus:b,onBlur:y,children:[N("div",{className:r(t.toastOptions?.headless?"":"t_container",t.toastOptions?.classNames?.container),children:[t.variant&&!t.icon?l("div",{className:r(t.toastOptions?.headless?"":"t_icon",t.toastOptions?.classNames?.icon),children:T}):t.icon&&l("div",{className:r(t.toastOptions?.headless?"":"t_icon",t.toastOptions?.classNames?.icon),children:t.icon}),N("div",{className:r(t.toastOptions?.headless?"":"t_content",t.toastOptions?.classNames?.content),children:[l("p",{id:`toast-title-${t.id}`,children:c}),t.description&&l("p",{id:`toast-description-${t.id}`,children:t.description})]})]}),N("div",{className:r(t.toastOptions?.headless?"":"t_actions",t.toastOptions?.classNames?.actions?.container),children:[t.action&&l("button",{onClick:t.action.onClick,title:typeof t.action.content=="string"?t.action.content:"Action Button",className:r(t.toastOptions?.classNames?.actions?.actionBtn),children:t.action.content??t.toastOptions?.defaultActionContent??"Action"}),l("button",{onClick:g,title:"Close toast",className:r(t.toastOptions?.classNames?.actions?.closeBtn),children:t.toastOptions?.defaultCloseContent??"Close"})]})]})},D=K;import{jsx as j}from"react/jsx-runtime";var M,O,tt=({maxToasts:t=4,position:o="bottom-right",theme:a="system",toastOptions:e,...u})=>{let[c,n]=U([]),[d,w]=U(!1);Z(()=>{w(!0)},[]);let p=s=>{let i={id:B(),...s};n(f=>{let T=o==="top-left"||o==="top-right"||o==="top-center",g=!1,y=f.map(b=>b.id===i.id?(g=!0,{...b,...i}):b);return g?[...y]:f.length>=t?T?[i,...f.slice(0,-1)]:[...f.slice(1),i]:T?[i,...f]:[...f,i]})},m=s=>{n(i=>i.filter(f=>f.id!==s))};return M=p,O=m,d&&c.length>0&&j("section",{...u,"aria-label":"Toast Notifications",role:"alert","aria-live":"polite",className:r("t_toasts",o==="top-left"?"t_top-left":"",o==="top-right"?"t_top-right":"",o==="top-center"?"t_top-center":"",o==="bottom-left"?"t_bottom-left":"",o==="bottom-right"?"t_bottom-right":"",o==="bottom-center"?"t_bottom-center":"",e?.font?e?.font:"t_default_font"),children:c.map(s=>j(D,{theme:a,toastPosition:o,onClose:()=>m(s.id),toastOptions:e,active:c.indexOf(s)===c.length-1,...s},s.id))})},x=t=>{M?M(t):console.error("\u{1F514} <Toaster /> component is not mounted. Check toast.pheralb.dev/toaster for more information.")},$=t=>{O?O(t):console.error("\u{1F514} <Toaster /> component is not mounted. Check toast.pheralb.dev/toaster for more information.")};var ot={default:t=>(x({...t}),t),success:t=>(x({...t,variant:"success"}),t),error:t=>(x({...t,variant:"error"}),t),warning:t=>(x({...t,variant:"warning"}),t),info:t=>(x({...t,variant:"info"}),t),loading:t=>(x({...t,variant:"loading"}),t),close:t=>$(t)};export{tt as Toaster,ot as toast};
|
|
4
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["#style-inject:#style-inject","../src/styles/globals.css","../src/components/toaster.tsx","../src/components/toast.tsx","../src/icons/index.tsx","../src/hooks/useTimeout.tsx","../src/utils/index.ts","../src/components/default-options.ts","../src/components/toast-functions.ts"],"sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\":root{--pheralb-toast-animation-enter: .4s;--pheralb-toast-animation-exit: .4s}:where(.t_global){--box-shadow: rgba(0, 0, 0, .1);--background-color: #ffffff;--hover-bg-color: #f5f5f5;--border-color: #e5e5e5;--text-color: #171717;--description-color: #262626;--focus-color: #a3a3a3}.t_light-theme{--box-shadow: rgba(0, 0, 0, .1);--background-color: #ffffff;--hover-bg-color: #f5f5f5;--border-color: #e5e5e5;--text-color: #171717;--description-color: #262626;--focus-color: #a3a3a3}.t_dark-theme{--box-shadow: rgba(0, 0, 0, .1);--background-color: #171717;--hover-bg-color: #27272a;--border-color: #262626;--text-color: #fafafa;--description-color: #e5e5e5;--focus-color: #404040}@media (prefers-color-scheme: dark){:where(.t_global){--box-shadow: rgba(0, 0, 0, .1);--background-color: #171717;--hover-bg-color: #27272a;--border-color: #262626;--text-color: #fafafa;--description-color: #e5e5e5;--focus-color: #404040}}.t_toasts{display:flex;flex-direction:column;gap:10px;padding:14px;position:fixed;z-index:999;overflow:hidden;transition:max-height .5s ease-in-out;width:100%}.t_default_font{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.t_top-left{top:0;left:0}.t_top-right{top:0;right:0}.t_top-center{top:0;left:50%;transform:translate(-50%)}.t_bottom-left{bottom:0;left:0}.t_bottom-right{bottom:0;right:0}.t_bottom-center{bottom:0;left:50%;transform:translate(-50%)}@media (min-width: 768px){.t_toasts{max-width:355px}}.t_global{display:flex;justify-content:space-between;padding:0;margin:0;list-style:none;outline:none;background-color:var(--background-color);width:auto;box-shadow:0 1px 3px 0 var(--box-shadow),0 1px 2px -1px var(--box-shadow);border:1px solid var(--border-color);border-radius:.375rem;font-size:.875rem;line-height:1.25rem;overflow:hidden}.t_global button{border:none;outline:none}.t_global button:focus{outline:1px solid var(--focus-color);outline-offset:0px;background-color:var(--hover-color)}.t_container{display:flex;flex-direction:row;align-items:center;width:100%;max-width:20rem;height:100wh;gap:.6rem;padding:12px;word-wrap:break-word;overflow-wrap:break-word}.t_icon{fill:var(--text-color);margin-top:.1rem;flex-shrink:0}.t_content{display:flex;flex-direction:column;justify-content:center;max-width:100%}.t_content p{font-weight:600;color:var(--text-color);margin:0}.t_content p:nth-of-type(2){font-weight:400;font-size:.75rem;color:var(--description-color)}.t_actions{display:flex;flex-direction:column;border-left:1px solid var(--border-color);height:100wh}.t_actions>button{flex:1 1 0%;width:100%;padding:6px 20px;font-size:13px;background-color:transparent;cursor:pointer;border:none}.t_actions>button:nth-child(1){color:var(--text-color);font-weight:500}.t_actions>button:nth-child(2){color:var(--text-color);border-top:1px solid var(--border-color)}.t_actions>button:hover{background-color:var(--hover-color)}.t_loading{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.t_slide-enter-top{animation:slide-top var(--pheralb-toast-animation-enter) ease}@keyframes slide-top{0%{opacity:0;transform:translateY(-100%)}to{opacity:1;transform:translateY(0)}}.t_slide-enter-bottom{animation:slide-bottom var(--pheralb-toast-animation-enter) ease}@keyframes slide-bottom{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}.t-slide-exit-top,.t-slide-exit-bottom{will-change:transform,opacity}.t-slide-exit-top{animation:slide-top-exit var(--pheralb-toast-animation-exit) ease}@keyframes slide-top-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t-slide-exit-bottom{animation:slide-bottom-exit var(--pheralb-toast-animation-exit) ease}@keyframes slide-bottom-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(100%)}}.t_swipe-exit-center{animation:swipe-center-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-center-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t_swipe-exit-left{animation:swipe-left-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-left-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-100%)}}.t_swipe-exit-right{animation:swipe-right-exit var(--pheralb-toast-animation-exit) ease}@keyframes swipe-right-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(100%)}}\\n\")","import { useEffect, useState } from \"react\";\n\nimport type {\n ToastId,\n ToastPropsWithVariant,\n ToasterProperties,\n} from \"../types/toast.types\";\n\nimport ToastComponent from \"./toast\";\nimport { cn, generateRandomId } from \"../utils\";\n\n// Ensure openToastGlobal is initialized correctly\nlet openToastGlobal: (data: ToastPropsWithVariant) => void;\n// Ensure closeToastGlobal is initialized correctly\nlet closeToastGlobal: (id: ToastId) => void;\n\nexport const Toaster = ({\n maxToasts = 4,\n position = \"bottom-right\",\n theme = \"system\",\n toastOptions,\n ...htmlProps\n}: ToasterProperties) => {\n const [toasts, setToasts] = useState<ToastPropsWithVariant[]>([]);\n const [isMounted, setIsMounted] = useState<boolean>(false);\n\n useEffect(() => {\n setIsMounted(true);\n }, []);\n\n // Define the openToast function\n const openToast = (data: ToastPropsWithVariant) => {\n const newToast = {\n id: generateRandomId(),\n ...data,\n };\n setToasts((prevToasts) => {\n const isTopPosition =\n position === \"top-left\" ||\n position === \"top-right\" ||\n position === \"top-center\";\n\n // If the `id` exists, update the notification\n let isToastUpdate = false;\n const updatedToasts = prevToasts.map(pt => {\n if (pt.id === newToast.id) {\n isToastUpdate = true;\n return {...pt, ...newToast}\n }\n return pt\n })\n\n if (isToastUpdate) {\n // `newToast` is embedded, array preserves length\n return [...updatedToasts]\n }\n\n if (prevToasts.length >= maxToasts) {\n return isTopPosition\n ? [newToast, ...prevToasts.slice(0, -1)]\n : [...prevToasts.slice(1), newToast];\n }\n\n return isTopPosition\n ? [newToast, ...prevToasts]\n : [...prevToasts, newToast];\n });\n };\n\n // Define the closeToast function\n const closeToast = (id: ToastId) => {\n setToasts((prevToasts) => prevToasts.filter((toast) => toast.id !== id));\n };\n\n // Assign openToast to the global variable\n openToastGlobal = openToast;\n // Assign closeToast to the global variable\n closeToastGlobal = closeToast;\n\n // Render the component\n return (\n isMounted &&\n toasts.length > 0 && (\n <section\n {...htmlProps}\n aria-label=\"Toast Notifications\"\n role=\"alert\"\n aria-live=\"polite\"\n className={cn(\n \"t_toasts\",\n position === \"top-left\" ? \"t_top-left\" : \"\",\n position === \"top-right\" ? \"t_top-right\" : \"\",\n position === \"top-center\" ? \"t_top-center\" : \"\",\n position === \"bottom-left\" ? \"t_bottom-left\" : \"\",\n position === \"bottom-right\" ? \"t_bottom-right\" : \"\",\n position === \"bottom-center\" ? \"t_bottom-center\" : \"\",\n toastOptions?.font ? toastOptions?.font : \"t_default_font\",\n )}\n >\n {toasts.map((toast) => (\n <ToastComponent\n key={toast.id}\n theme={theme}\n toastPosition={position}\n onClose={() => closeToast(toast.id!)}\n toastOptions={toastOptions}\n active={toasts.indexOf(toast) === toasts.length - 1}\n {...toast}\n />\n ))}\n </section>\n )\n );\n};\n\n// Export the openToast function:\n// eslint-disable-next-line react-refresh/only-export-components\nexport const openToast = (data: ToastPropsWithVariant): void => {\n if (openToastGlobal) {\n openToastGlobal(data);\n } else {\n console.error(\n \"๐ <Toaster /> component is not mounted. Check toast.pheralb.dev/toaster for more information.\",\n );\n }\n};\n\n// Export the closeToast function:\n// eslint-disable-next-line react-refresh/only-export-components\nexport const closeToast = (id: ToastId): void => {\n if (closeToastGlobal) {\n closeToastGlobal(id);\n } else {\n console.error(\n \"๐ <Toaster /> component is not mounted. Check toast.pheralb.dev/toaster for more information.\",\n );\n }\n};\n","import type {\n Position,\n ToastIcons,\n ToastOptions,\n ToastPropsWithLoading,\n Variant,\n} from \"../types/toast.types\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport { Error, Info, Loading, Success, Warning } from \"../icons\";\nimport { useTimeout } from \"../hooks/useTimeout\";\nimport { cn, getSystemTheme, prefersReducedMotion } from \"../utils\";\n\nimport { iconsColors, getAnimationClass } from \"./default-options\";\n\ninterface ToastComponentProps extends ToastPropsWithLoading {\n toastPosition: Position;\n toastOptions?: ToastOptions;\n active?: boolean;\n onClose: () => void;\n}\n\nconst Toast = (props: ToastComponentProps) => {\n const [status, setStatus] = useState<Variant>(props.variant || \"info\");\n const [iconColor, setIconColor] = useState<string>(iconsColors[status]);\n const [toastText, setToastText] = useState<string>(props.text);\n const [isExiting, setIsExiting] = useState<boolean>(false);\n\n const delayDuration = props.delayDuration || 4000;\n\n const { pause, resume } = useTimeout(() => {\n handleCloseToast();\n }, delayDuration);\n\n const iconClass = cn(\n \"t_icon\",\n props.variant === \"loading\" && status === \"loading\" ? \"t_loading\" : \"\",\n );\n\n const icons: ToastIcons = {\n success: (\n <Success\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n error: (\n <Error\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n warning: (\n <Warning\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n info: (\n <Info\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n loading: (\n <Loading\n width={18}\n height={18}\n style={{ fill: iconColor }}\n className={iconClass}\n />\n ),\n };\n\n const IconComponent = props.toastOptions?.icons\n ? props.toastOptions?.icons[status]\n : icons[status];\n\n const handleCloseToast = useCallback(() => {\n setIsExiting(true);\n const animationDisabled = prefersReducedMotion();\n if (!animationDisabled) {\n setTimeout(() => {\n if (props.onClose) {\n props.onClose();\n }\n }, 300);\n } else if (props.onClose) {\n props.onClose();\n }\n }, [props]);\n\n const handleMouseLeave = () => {\n resume();\n };\n\n const handleMouseEnter = () => {\n pause();\n };\n\n useEffect(() => {\n if (props.variant === \"loading\" && props.options) {\n pause();\n\n const executePromise =\n typeof props.options.promise === \"function\"\n ? props.options.promise()\n : Promise.resolve(props.options.promise);\n\n executePromise\n .then((data) => {\n resume();\n setStatus(\"success\");\n if (props.options!.autoDismiss) {\n setTimeout(() => {\n handleCloseToast();\n }, delayDuration);\n }\n setToastText(props.options!.success);\n setIconColor(iconsColors.success);\n if (props.options?.onSuccess) {\n props.options.onSuccess(data);\n }\n })\n .catch((error) => {\n setStatus(\"error\");\n setToastText(props.options!.error);\n setIconColor(iconsColors.error);\n if (props.options!.autoDismiss) {\n setTimeout(() => {\n handleCloseToast();\n }, delayDuration);\n }\n if (props.options?.onError) {\n props.options.onError(error, props.id);\n }\n });\n }\n }, [\n delayDuration,\n handleCloseToast,\n pause,\n props.options,\n props.variant,\n resume,\n ]);\n\n return (\n <div\n {...props.attrs}\n role=\"alert\"\n aria-labelledby={`toast-title-${props.id}`}\n aria-describedby={`toast-description-${props.id}`}\n title={props.text}\n className={cn(\n !prefersReducedMotion()\n ? getAnimationClass(\n isExiting,\n props.toastOptions?.animationOnClose || \"slide\",\n props.toastPosition,\n )\n : \"\",\n !props.toastOptions?.headless && props.theme === \"system\"\n ? getSystemTheme()\n : \"\",\n !props.toastOptions?.headless && props.theme === \"dark\"\n ? \"t_dark-theme\"\n : \"\",\n !props.toastOptions?.headless && props.theme === \"light\"\n ? \"t_light-theme\"\n : \"\",\n !props.toastOptions?.headless ? \"t_global\" : \"\",\n props.toastOptions?.classNames?.toast,\n props.attrs?.className,\n )}\n style={{\n zIndex: props.active ? 1000 : 999,\n ...props.attrs?.style,\n }}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleMouseEnter}\n onBlur={handleMouseLeave}\n >\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_container\" : \"\",\n props.toastOptions?.classNames?.container,\n )}\n >\n {props.variant && !props.icon ? (\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_icon\" : \"\",\n props.toastOptions?.classNames?.icon,\n )}\n >\n {IconComponent}\n </div>\n ) : (\n props.icon && (\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_icon\" : \"\",\n props.toastOptions?.classNames?.icon,\n )}\n >\n {props.icon}\n </div>\n )\n )}\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_content\" : \"\",\n props.toastOptions?.classNames?.content,\n )}\n >\n <p id={`toast-title-${props.id}`}>{toastText}</p>\n {props.description && (\n <p id={`toast-description-${props.id}`}>{props.description}</p>\n )}\n </div>\n </div>\n <div\n className={cn(\n !props.toastOptions?.headless ? \"t_actions\" : \"\",\n props.toastOptions?.classNames?.actions?.container,\n )}\n >\n {props.action && (\n <button\n onClick={props.action.onClick}\n title={\n typeof props.action.content === \"string\"\n ? props.action.content\n : \"Action Button\"\n }\n className={cn(props.toastOptions?.classNames?.actions?.actionBtn)}\n >\n {props.action.content ??\n props.toastOptions?.defaultActionContent ??\n \"Action\"}\n </button>\n )}\n <button\n onClick={handleCloseToast}\n title=\"Close toast\"\n className={cn(props.toastOptions?.classNames?.actions?.closeBtn)}\n >\n {props.toastOptions?.defaultCloseContent ?? \"Close\"}\n </button>\n </div>\n </div>\n );\n};\n\nexport default Toast;\n","import type { ComponentProps, FC } from \"react\";\n\nexport const Success: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm45.66 85.66l-56 56a8 8 0 01-11.32 0l-24-24a8 8 0 0111.32-11.32L112 148.69l50.34-50.35a8 8 0 0111.32 11.32z\"></path>\n </svg>\n);\n\nexport const Warning: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M236.8 188.09L149.35 36.22a24.76 24.76 0 00-42.7 0L19.2 188.09a23.51 23.51 0 000 23.72A24.35 24.35 0 0040.55 224h174.9a24.35 24.35 0 0021.33-12.19 23.51 23.51 0 00.02-23.72zM120 104a8 8 0 0116 0v40a8 8 0 01-16 0zm8 88a12 12 0 1112-12 12 12 0 01-12 12z\"></path>\n </svg>\n);\n\nexport const Error: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm-8 56a8 8 0 0116 0v56a8 8 0 01-16 0zm8 104a12 12 0 1112-12 12 12 0 01-12 12z\"></path>\n </svg>\n);\n\nexport const Info: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M128 24a104 104 0 10104 104A104.11 104.11 0 00128 24zm-4 48a12 12 0 11-12 12 12 12 0 0112-12zm12 112a16 16 0 01-16-16v-40a8 8 0 010-16 16 16 0 0116 16v40a8 8 0 010 16z\"></path>\n </svg>\n);\n\nexport const Loading: FC<ComponentProps<\"svg\">> = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\" {...props}>\n <path d=\"M136 32v32a8 8 0 01-16 0V32a8 8 0 0116 0zm37.25 58.75a8 8 0 005.66-2.35l22.63-22.62a8 8 0 00-11.32-11.32L167.6 77.09a8 8 0 005.65 13.66zM224 120h-32a8 8 0 000 16h32a8 8 0 000-16zm-45.09 47.6a8 8 0 00-11.31 11.31l22.62 22.63a8 8 0 0011.32-11.32zM128 184a8 8 0 00-8 8v32a8 8 0 0016 0v-32a8 8 0 00-8-8zm-50.91-16.4l-22.63 22.62a8 8 0 0011.32 11.32l22.62-22.63a8 8 0 00-11.31-11.31zM72 128a8 8 0 00-8-8H32a8 8 0 000 16h32a8 8 0 008-8zm-6.22-73.54a8 8 0 00-11.32 11.32L77.09 88.4A8 8 0 0088.4 77.09z\"></path>\n </svg>\n);\n","import { useCallback, useEffect, useRef } from \"react\";\n\ninterface UseTimeoutReturn {\n pause: () => void;\n resume: () => void;\n reset: () => void;\n isActive: boolean;\n}\n\nexport const useTimeout = (\n callback: () => void,\n delay: number,\n): UseTimeoutReturn => {\n const timeoutRef = useRef<number>(0);\n const callbackRef = useRef(callback);\n const startTimeRef = useRef<number>(0);\n const remainingRef = useRef(delay);\n const isActiveRef = useRef(true);\n\n const cleanup = useCallback(() => {\n if (timeoutRef.current) {\n window.clearTimeout(timeoutRef.current);\n }\n }, []);\n\n const pause = useCallback(() => {\n if (!isActiveRef.current || !startTimeRef.current) return;\n\n cleanup();\n remainingRef.current -= Date.now() - startTimeRef.current;\n isActiveRef.current = false;\n }, [cleanup]);\n\n const resume = useCallback(() => {\n if (isActiveRef.current) return;\n\n startTimeRef.current = Date.now();\n timeoutRef.current = window.setTimeout(\n callbackRef.current,\n remainingRef.current,\n );\n isActiveRef.current = true;\n }, []);\n\n const reset = useCallback(() => {\n cleanup();\n remainingRef.current = delay;\n startTimeRef.current = Date.now();\n timeoutRef.current = window.setTimeout(callbackRef.current, delay);\n isActiveRef.current = true;\n }, [cleanup, delay]);\n\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n useEffect(() => {\n reset();\n return cleanup;\n }, [delay, reset, cleanup]);\n\n return {\n pause,\n resume,\n reset,\n isActive: isActiveRef.current,\n };\n};\n","export const cn = (...classes: (string | undefined)[]) => {\n return classes.filter(Boolean).join(\" \");\n};\n\nexport const generateRandomId = () => Math.floor(Math.random() * 1000000);\n\nexport const prefersReducedMotion = (() => {\n let shouldReduceMotion: boolean | undefined = undefined;\n return () => {\n if (shouldReduceMotion === undefined) {\n if (typeof window !== \"undefined\" && window.matchMedia !== undefined) {\n const mediaQuery = window.matchMedia(\n \"(prefers-reduced-motion: reduce)\",\n );\n shouldReduceMotion = mediaQuery.matches;\n } else {\n shouldReduceMotion = false;\n }\n }\n return shouldReduceMotion;\n };\n})();\n\n// Get system theme:\nexport const getSystemTheme = () => {\n if (typeof window !== \"undefined\") {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"t_dark-theme\"\n : \"t_light-theme\";\n }\n return \"t_light-theme\";\n};\n","import type { Position, ToastAnimations, Variant } from \"../types/toast.types\";\n\n/* Default icon colors */\n\nexport const iconsColors: Record<Variant, string> = {\n success: \"#22c55e\",\n error: \"#ef4444\",\n warning: \"#eab308\",\n info: \"#3b82f6\",\n loading: \"currentColor\",\n};\n\n/* Default animations */\n\nconst ANIMATION_ENTER_MAP: Record<Position, string> = {\n \"top-left\": \"t_slide-enter-top\",\n \"top-right\": \"t_slide-enter-top\",\n \"top-center\": \"t_slide-enter-top\",\n \"bottom-left\": \"t_slide-enter-bottom\",\n \"bottom-right\": \"t_slide-enter-bottom\",\n \"bottom-center\": \"t_slide-enter-bottom\",\n};\n\nconst ANIMATION_EXIT_MAP: Record<Position, string> = {\n \"top-left\": \"t-slide-exit-top\",\n \"top-right\": \"t-slide-exit-top\",\n \"top-center\": \"t-slide-exit-top\",\n \"bottom-left\": \"t-slide-exit-bottom\",\n \"bottom-right\": \"t-slide-exit-bottom\",\n \"bottom-center\": \"t-slide-exit-bottom\",\n};\n\n/* Swipe exit animations */\n\nconst ANIMATION_SWIPE_EXIT_MAP: Record<Position, string> = {\n \"top-left\": \"t_swipe-exit-left\",\n \"top-right\": \"t_swipe-exit-right\",\n \"top-center\": \"t_swipe-exit-center\",\n \"bottom-left\": \"t_swipe-exit-left\",\n \"bottom-right\": \"t_swipe-exit-right\",\n \"bottom-center\": \"t_swipe-exit-center\",\n};\n\nexport const getAnimationClass = (\n isExiting: boolean,\n animationType: ToastAnimations,\n position: Position,\n) => {\n if (!isExiting) {\n return ANIMATION_ENTER_MAP[position];\n }\n\n if (animationType === \"swipe\") {\n return ANIMATION_SWIPE_EXIT_MAP[position];\n }\n\n return ANIMATION_EXIT_MAP[position];\n};\n","import type {\n ToastId,\n ToastPropsWithLoading,\n ToastPropsWithVariant\n} from '../types/toast.types';\nimport { openToast, closeToast } from './toaster';\n\ninterface ToastFunctions {\n default: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n success: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n error: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n warning: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n info: (data: ToastPropsWithVariant) => ToastPropsWithVariant;\n loading: (data: ToastPropsWithLoading) => ToastPropsWithLoading;\n close: (id: ToastId) => void;\n}\n\nexport const toast: ToastFunctions = {\n default: (data: ToastPropsWithVariant) => {\n openToast({ ...data });\n return data;\n },\n success: (data: ToastPropsWithVariant) => {\n openToast({ ...data, variant: 'success' });\n return data;\n },\n error: (data: ToastPropsWithVariant) => {\n openToast({ ...data, variant: 'error' });\n return data;\n },\n warning: (data: ToastPropsWithVariant) => {\n openToast({ ...data, variant: 'warning' });\n return data;\n },\n info: (data: ToastPropsWithVariant) => {\n openToast({ ...data, variant: 'info' });\n return data;\n },\n loading: (data: ToastPropsWithLoading) => {\n openToast({ ...data, variant: 'loading' });\n return data;\n },\n close: (id: ToastId) => closeToast(id)\n};\n"],"mappings":"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","names":["styleInject","css","insertAt","head","style","styleInject","useEffect","useState","useCallback","useEffect","useState","jsx","Success","props","Warning","Error","Info","Loading","useCallback","useEffect","useRef","useTimeout","callback","delay","timeoutRef","callbackRef","startTimeRef","remainingRef","isActiveRef","cleanup","pause","resume","reset","cn","classes","generateRandomId","prefersReducedMotion","shouldReduceMotion","getSystemTheme","iconsColors","ANIMATION_ENTER_MAP","ANIMATION_EXIT_MAP","ANIMATION_SWIPE_EXIT_MAP","getAnimationClass","isExiting","animationType","position","jsx","jsxs","Toast","props","status","setStatus","useState","iconColor","setIconColor","iconsColors","toastText","setToastText","isExiting","setIsExiting","delayDuration","pause","resume","useTimeout","handleCloseToast","iconClass","cn","icons","Success","Error","Warning","Info","Loading","IconComponent","useCallback","prefersReducedMotion","handleMouseLeave","handleMouseEnter","useEffect","data","error","getAnimationClass","getSystemTheme","toast_default","jsx","openToastGlobal","closeToastGlobal","Toaster","maxToasts","position","theme","toastOptions","htmlProps","toasts","setToasts","useState","isMounted","setIsMounted","useEffect","openToast","data","newToast","generateRandomId","prevToasts","isTopPosition","isToastUpdate","updatedToasts","pt","closeToast","id","toast","cn","toast_default","toast","data","openToast","id","closeToast"]}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--pheralb-toast-animation-enter:.4s;--pheralb-toast-animation-exit:.4s}:where(.t_global),.t_light-theme{--box-shadow:#0000001a;--background-color:#fff;--hover-bg-color:#f5f5f5;--border-color:#e5e5e5;--text-color:#171717;--description-color:#262626;--focus-color:#a3a3a3}.t_dark-theme{--box-shadow:#0000001a;--background-color:#171717;--hover-bg-color:#27272a;--border-color:#262626;--text-color:#fafafa;--description-color:#e5e5e5;--focus-color:#404040}@media (prefers-color-scheme:dark){:where(.t_global){--box-shadow:#0000001a;--background-color:#171717;--hover-bg-color:#27272a;--border-color:#262626;--text-color:#fafafa;--description-color:#e5e5e5;--focus-color:#404040}}.t_toasts{z-index:999;flex-direction:column;gap:10px;width:100%;padding:14px;transition:max-height .5s ease-in-out;display:flex;position:fixed;overflow:hidden}.t_default_font{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.t_top-left{top:0;left:0}.t_top-right{top:0;right:0}.t_top-center{top:0;left:50%;transform:translate(-50%)}.t_bottom-left{bottom:0;left:0}.t_bottom-right{bottom:0;right:0}.t_bottom-center{bottom:0;left:50%;transform:translate(-50%)}@media (width>=768px){.t_toasts{max-width:355px}}.t_global{background-color:var(--background-color);width:auto;box-shadow:0 1px 3px 0 var(--box-shadow),0 1px 2px -1px var(--box-shadow);border:1px solid var(--border-color);border-radius:.375rem;outline:none;justify-content:space-between;margin:0;padding:0;font-size:.875rem;line-height:1.25rem;list-style:none;display:flex;overflow:hidden}.t_global button{border:none;outline:none}.t_global button:focus{outline:1px solid var(--focus-color);outline-offset:0px;background-color:var(--hover-color)}.t_container{width:100%;max-width:20rem;height:100wh;word-wrap:break-word;overflow-wrap:break-word;flex-direction:row;align-items:center;gap:.6rem;padding:12px;display:flex}.t_icon{fill:var(--text-color);flex-shrink:0;margin-top:.1rem}.t_content{flex-direction:column;justify-content:center;max-width:100%;display:flex}.t_content p{color:var(--text-color);margin:0;font-weight:600}.t_content p:nth-of-type(2){color:var(--description-color);font-size:.75rem;font-weight:400}.t_actions{border-left:1px solid var(--border-color);height:100wh;flex-direction:column;display:flex}.t_actions>button{cursor:pointer;background-color:#0000;border:none;flex:1;width:100%;padding:6px 20px;font-size:13px}.t_actions>button:first-child{color:var(--text-color);font-weight:500}.t_actions>button:nth-child(2){color:var(--text-color);border-top:1px solid var(--border-color)}.t_actions>button:hover{background-color:var(--hover-color)}.t_loading{animation:1s linear infinite spin}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.t_slide-enter-top{animation:slide-top var(--pheralb-toast-animation-enter)ease}@keyframes slide-top{0%{opacity:0;transform:translateY(-100%)}to{opacity:1;transform:translateY(0)}}.t_slide-enter-bottom{animation:slide-bottom var(--pheralb-toast-animation-enter)ease}@keyframes slide-bottom{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}.t-slide-exit-top,.t-slide-exit-bottom{will-change:transform,opacity}.t-slide-exit-top{animation:slide-top-exit var(--pheralb-toast-animation-exit)ease}@keyframes slide-top-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t-slide-exit-bottom{animation:slide-bottom-exit var(--pheralb-toast-animation-exit)ease}@keyframes slide-bottom-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(100%)}}.t_swipe-exit-center{animation:swipe-center-exit var(--pheralb-toast-animation-exit)ease}@keyframes swipe-center-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}.t_swipe-exit-left{animation:swipe-left-exit var(--pheralb-toast-animation-exit)ease}@keyframes swipe-left-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-100%)}}.t_swipe-exit-right{animation:swipe-right-exit var(--pheralb-toast-animation-exit)ease}@keyframes swipe-right-exit{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(100%)}}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nicojones/toast",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"author": "@nicojones",
|
|
5
|
+
"description": "A simple notification library for React. Fully customizable and lightweight.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/nicojones/toast.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/nicojones/toast/issues"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"react",
|
|
15
|
+
"react-component",
|
|
16
|
+
"toast",
|
|
17
|
+
"notification",
|
|
18
|
+
"no-dependencies",
|
|
19
|
+
"lightweight",
|
|
20
|
+
"customizable"
|
|
21
|
+
],
|
|
22
|
+
"private": false,
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/main.js",
|
|
26
|
+
"types": "./dist/main.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"require": "./dist/main.cjs",
|
|
30
|
+
"import": "./dist/main.js",
|
|
31
|
+
"types": "./dist/main.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./dist/styles.css": "./dist/styles.css"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "pnpm build:library && pnpm build:styles",
|
|
40
|
+
"build:library": "tsc && tsup",
|
|
41
|
+
"build:styles": "lightningcss --minify --bundle ./src/styles/globals.css -o ./dist/styles.css",
|
|
42
|
+
"dev": "tsup --watch",
|
|
43
|
+
"test": "vitest run --config ./vitest.config.ts",
|
|
44
|
+
"test:watch": "vitest --watch",
|
|
45
|
+
"lint": "eslint ./src",
|
|
46
|
+
"prepublishOnly": "pnpm build"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@testing-library/jest-dom": "6.6.3",
|
|
50
|
+
"@testing-library/react": "16.2.0",
|
|
51
|
+
"@types/node": "20.17.16",
|
|
52
|
+
"@types/react": "19.2.7",
|
|
53
|
+
"@types/react-dom": "19.0.3",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "8.22.0",
|
|
55
|
+
"@typescript-eslint/parser": "8.22.0",
|
|
56
|
+
"eslint": "9.19.0",
|
|
57
|
+
"eslint-plugin-react-hooks": "5.1.0",
|
|
58
|
+
"eslint-plugin-react-refresh": "0.4.18",
|
|
59
|
+
"eslint-plugin-jsx-a11y": "6.10.2",
|
|
60
|
+
"globals": "15.14.0",
|
|
61
|
+
"jsdom": "26.0.0",
|
|
62
|
+
"lightningcss-cli": "1.29.1",
|
|
63
|
+
"react": "19.2.1",
|
|
64
|
+
"react-dom": "19.2.1",
|
|
65
|
+
"tsup": "8.3.6",
|
|
66
|
+
"typescript": "5.7.3",
|
|
67
|
+
"typescript-eslint": "8.22.0",
|
|
68
|
+
"vitest": "3.0.4"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"react": ">=18.0.0",
|
|
72
|
+
"react-dom": ">=18.0.0"
|
|
73
|
+
}
|
|
74
|
+
}
|