@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 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
+ ![React Badge](https://img.shields.io/badge/Library-61DAFB?logo=react&logoColor=000&style=flat)
13
+ ![Vitest Badge](https://img.shields.io/badge/Testing-6E9F18?logo=vitest&logoColor=fff&style=flat)
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"]}
@@ -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
@@ -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"]}
@@ -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
+ }