lumatoast 0.1.0 â 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +307 -45
- package/dist/index.cjs +6 -946
- package/dist/index.js +6 -907
- package/dist/styles.css +1 -819
- package/package.json +31 -19
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/styles.css.map +0 -1
package/LICENSE
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Krishna Kumar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
CHANGED
|
@@ -1,21 +1,42 @@
|
|
|
1
|
-
# LumaToast
|
|
1
|
+
# ð LumaToast
|
|
2
2
|
|
|
3
3
|
A beautiful, lightweight, framework-agnostic toast notification library â inspired by Linear, Vercel, and Apple VisionOS.
|
|
4
4
|
|
|
5
|
-
[](https://lumatoast.vercel.app)
|
|
6
|
+
[](https://www.npmjs.com/package/lumatoast)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
> ðŪ **[Try the Interactive Live Playground â](https://lumatoast.vercel.app)**
|
|
11
|
+
> Test all 9 themes, mobile swipe gestures, animation styles, progress bar positions, and customization options live in your browser!
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
**LumaToast** is an ultra-lightweight, customizable toast notification and snackbar library designed for modern web applications. An elegant, framework-agnostic alternative to `sonner`, `react-hot-toast`, and `react-toastify`.
|
|
9
16
|
|
|
10
17
|
- âĻ **Glassmorphism UI** â VisionOS-inspired frosted glass design
|
|
11
|
-
- ðĻ **9
|
|
12
|
-
- ⥠**Promise API** â
|
|
13
|
-
- ðą **Mobile
|
|
14
|
-
- ð **Dark & Light
|
|
15
|
-
- âĻïļ **
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
18
|
+
- ðĻ **9 Built-in Themes** â Linear, Aurora, Vision, Minimal, Cupertino, Material, Terminal, GitHub, Cyberpunk
|
|
19
|
+
- ⥠**Promise & Async API** â Loading toasts auto-transition to success or error
|
|
20
|
+
- ðą **Mobile Touch Gestures** â Direction-aware swipe to dismiss with spring physics
|
|
21
|
+
- ð **Dark & Light Mode** â Native support for both light and dark backgrounds
|
|
22
|
+
- âĻïļ **Accessible & A11y** â Keyboard focus management, Escape to close, ARIA live regions
|
|
23
|
+
- ðĶ **100% Framework Agnostic** â Zero-wrapper support for React, Vue, Angular, Svelte, Solid, and Vanilla JS
|
|
24
|
+
- ðŠķ **Zero Dependencies** â Pure TypeScript, under 16KB minified, no bloated external runtime
|
|
25
|
+
- ðĒ **Node.js Support** â Node `>= 18.0.0` (LTS 18, 20, 22+)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Why LumaToast vs Other Toast Libraries?
|
|
30
|
+
|
|
31
|
+
| Feature | `lumatoast` | `sonner` | `react-hot-toast` | `react-toastify` |
|
|
32
|
+
|---|:---:|:---:|:---:|:---:|
|
|
33
|
+
| **Framework Agnostic** | â
Any framework | â React only | â React only | â React only |
|
|
34
|
+
| **Built-in Themes** | â
**9 themes** | â 1 default | â 1 default | â CSS themes only |
|
|
35
|
+
| **Progress Bar (Top & Bottom)** | â
Yes | â No | â No | â ïļ Bottom only |
|
|
36
|
+
| **CSS Variables Customization** | â
30+ tokens | â ïļ Limited | â No | â ïļ Limited |
|
|
37
|
+
| **Mobile Swipe to Dismiss** | â
Yes | â
Yes | â No | â ïļ Touch only |
|
|
38
|
+
| **Zero Runtime Dependencies** | â
Yes | â ïļ Multiple | â ïļ Multiple | â ïļ Multiple |
|
|
39
|
+
| **Bundle Size** | **~15 KB** | ~18 KB | ~25 KB | ~35 KB |
|
|
19
40
|
|
|
20
41
|
---
|
|
21
42
|
|
|
@@ -27,27 +48,48 @@ npm install lumatoast
|
|
|
27
48
|
|
|
28
49
|
---
|
|
29
50
|
|
|
30
|
-
##
|
|
51
|
+
## How It Works: Setup in 3 Simple Steps
|
|
31
52
|
|
|
32
|
-
|
|
53
|
+
LumaToast is designed around a clean separation of concerns:
|
|
33
54
|
|
|
34
|
-
```js
|
|
35
|
-
import "lumatoast/styles.css";
|
|
36
55
|
```
|
|
56
|
+
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
|
|
57
|
+
â 1. App Entry Point (run ONCE at startup) â
|
|
58
|
+
â import "lumatoast/styles.css"; â
|
|
59
|
+
â import { initializeRenderer } from "lumatoast"; â
|
|
60
|
+
â initializeRenderer(); â
|
|
61
|
+
âââââââââââââââââââââââââââââŽââââââââââââââââââââââââââââââ
|
|
62
|
+
â (sets up singleton container)
|
|
63
|
+
âž
|
|
64
|
+
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
|
|
65
|
+
â 2. Any Component / Service / Action (ANYWHERE in app) â
|
|
66
|
+
â import { toast } from "lumatoast"; â
|
|
67
|
+
â toast.success("Profile saved!"); â
|
|
68
|
+
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Step 1: Import the CSS (Once at App Root)
|
|
72
|
+
Add this in your root entry file (e.g. `main.tsx`, `main.ts`, `app/layout.tsx`, or global stylesheet):
|
|
37
73
|
|
|
38
|
-
|
|
74
|
+
```ts
|
|
75
|
+
import "lumatoast/styles.css";
|
|
76
|
+
```
|
|
39
77
|
|
|
40
|
-
### 2
|
|
78
|
+
### Step 2: Initialize the Renderer (Once at App Bootstrap)
|
|
79
|
+
Call `initializeRenderer()` once when your application mounts. It sets up the toast container in the DOM and listens for events:
|
|
41
80
|
|
|
42
|
-
```
|
|
43
|
-
import { initializeRenderer
|
|
81
|
+
```ts
|
|
82
|
+
import { initializeRenderer } from "lumatoast";
|
|
44
83
|
|
|
45
84
|
initializeRenderer();
|
|
46
85
|
```
|
|
47
86
|
|
|
48
|
-
### 3
|
|
87
|
+
### Step 3: Trigger Toasts from Anywhere
|
|
88
|
+
Import `toast` in any component, button handler, API callback, or utility file:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { toast } from "lumatoast";
|
|
49
92
|
|
|
50
|
-
```js
|
|
51
93
|
toast.success("Profile updated!");
|
|
52
94
|
toast.error("Something went wrong.");
|
|
53
95
|
toast.warning("Disk space is low.");
|
|
@@ -437,76 +479,296 @@ toast.success("Custom theme!", { theme: "brand" as any });
|
|
|
437
479
|
|
|
438
480
|
## Framework Guides
|
|
439
481
|
|
|
482
|
+
LumaToast is completely framework-agnostic. The pattern is always the same:
|
|
483
|
+
1. **Import `lumatoast/styles.css`** once at the root.
|
|
484
|
+
2. **Call `initializeRenderer()`** once when the app loads.
|
|
485
|
+
3. **Use `toast.*()`** anywhere!
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
### React (Vite / CRA)
|
|
440
490
|
|
|
441
|
-
|
|
491
|
+
In your application entry point (`src/main.tsx` or `src/index.tsx`):
|
|
442
492
|
|
|
443
493
|
```tsx
|
|
444
|
-
// main.tsx
|
|
494
|
+
// src/main.tsx
|
|
495
|
+
import React from "react";
|
|
496
|
+
import ReactDOM from "react-dom/client";
|
|
497
|
+
import App from "./App";
|
|
498
|
+
|
|
499
|
+
// 1. Import styles and initialize once
|
|
445
500
|
import "lumatoast/styles.css";
|
|
446
501
|
import { initializeRenderer } from "lumatoast";
|
|
447
502
|
|
|
448
503
|
initializeRenderer();
|
|
504
|
+
|
|
505
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
506
|
+
<React.StrictMode>
|
|
507
|
+
<App />
|
|
508
|
+
</React.StrictMode>
|
|
509
|
+
);
|
|
449
510
|
```
|
|
450
511
|
|
|
512
|
+
Then trigger toasts anywhere in your components:
|
|
513
|
+
|
|
451
514
|
```tsx
|
|
452
|
-
//
|
|
515
|
+
// src/components/SaveButton.tsx
|
|
453
516
|
import { toast } from "lumatoast";
|
|
454
517
|
|
|
455
|
-
function SaveButton() {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
518
|
+
export function SaveButton() {
|
|
519
|
+
const handleSave = async () => {
|
|
520
|
+
await toast.promise(saveUserData(), {
|
|
521
|
+
loading: { title: "Saving", description: "Saving profile changes..." },
|
|
522
|
+
success: { title: "Saved!", description: "Profile updated successfully." },
|
|
523
|
+
error: { title: "Error", description: "Failed to save profile." },
|
|
524
|
+
});
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
return <button onClick={handleSave}>Save Changes</button>;
|
|
528
|
+
}
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
### Next.js (App Router)
|
|
534
|
+
|
|
535
|
+
Since Next.js App Router renders on the server, create a simple client-side component to initialize the renderer:
|
|
536
|
+
|
|
537
|
+
```tsx
|
|
538
|
+
// app/components/Toaster.tsx
|
|
539
|
+
"use client";
|
|
540
|
+
|
|
541
|
+
import { useEffect } from "react";
|
|
542
|
+
import { initializeRenderer } from "lumatoast";
|
|
543
|
+
import "lumatoast/styles.css";
|
|
544
|
+
|
|
545
|
+
export function Toaster() {
|
|
546
|
+
useEffect(() => {
|
|
547
|
+
initializeRenderer();
|
|
548
|
+
}, []);
|
|
549
|
+
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Mount `<Toaster />` once in your root layout:
|
|
555
|
+
|
|
556
|
+
```tsx
|
|
557
|
+
// app/layout.tsx
|
|
558
|
+
import { Toaster } from "./components/Toaster";
|
|
559
|
+
|
|
560
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
561
|
+
return (
|
|
562
|
+
<html lang="en">
|
|
563
|
+
<body>
|
|
564
|
+
<Toaster />
|
|
565
|
+
{children}
|
|
566
|
+
</body>
|
|
567
|
+
</html>
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
Now call `toast.success()`, `toast.error()`, etc. in any client component:
|
|
573
|
+
|
|
574
|
+
```tsx
|
|
575
|
+
"use client";
|
|
576
|
+
import { toast } from "lumatoast";
|
|
577
|
+
|
|
578
|
+
export default function Page() {
|
|
579
|
+
return <button onClick={() => toast.success("Welcome to Next.js!")}>Notify</button>;
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
### Next.js (Pages Router)
|
|
586
|
+
|
|
587
|
+
In `pages/_app.tsx`:
|
|
588
|
+
|
|
589
|
+
```tsx
|
|
590
|
+
// pages/_app.tsx
|
|
591
|
+
import type { AppProps } from "next/app";
|
|
592
|
+
import { useEffect } from "react";
|
|
593
|
+
import { initializeRenderer } from "lumatoast";
|
|
594
|
+
import "lumatoast/styles.css";
|
|
595
|
+
|
|
596
|
+
export default function MyApp({ Component, pageProps }: AppProps) {
|
|
597
|
+
useEffect(() => {
|
|
598
|
+
initializeRenderer();
|
|
599
|
+
}, []);
|
|
463
600
|
|
|
464
|
-
|
|
601
|
+
return <Component {...pageProps} />;
|
|
465
602
|
}
|
|
466
603
|
```
|
|
467
604
|
|
|
468
|
-
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
### Vue 3 / Vite
|
|
608
|
+
|
|
609
|
+
In `src/main.ts`:
|
|
469
610
|
|
|
470
611
|
```ts
|
|
471
|
-
// main.ts
|
|
612
|
+
// src/main.ts
|
|
613
|
+
import { createApp } from "vue";
|
|
614
|
+
import App from "./App.vue";
|
|
615
|
+
|
|
616
|
+
// 1. Import styles and initialize
|
|
472
617
|
import "lumatoast/styles.css";
|
|
473
618
|
import { initializeRenderer } from "lumatoast";
|
|
474
619
|
|
|
475
620
|
initializeRenderer();
|
|
621
|
+
|
|
476
622
|
createApp(App).mount("#app");
|
|
477
623
|
```
|
|
478
624
|
|
|
625
|
+
In any Vue component (`.vue`):
|
|
626
|
+
|
|
479
627
|
```vue
|
|
480
|
-
<script setup>
|
|
628
|
+
<script setup lang="ts">
|
|
481
629
|
import { toast } from "lumatoast";
|
|
482
|
-
|
|
630
|
+
|
|
631
|
+
function showToast() {
|
|
632
|
+
toast.success("Profile saved successfully!", {
|
|
633
|
+
title: "Success",
|
|
634
|
+
theme: "aurora",
|
|
635
|
+
});
|
|
636
|
+
}
|
|
483
637
|
</script>
|
|
638
|
+
|
|
639
|
+
<template>
|
|
640
|
+
<button @click="showToast">Save</button>
|
|
641
|
+
</template>
|
|
484
642
|
```
|
|
485
643
|
|
|
486
|
-
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
### Nuxt 3
|
|
647
|
+
|
|
648
|
+
Create a client-side plugin `plugins/lumatoast.client.ts`:
|
|
487
649
|
|
|
488
650
|
```ts
|
|
489
|
-
//
|
|
651
|
+
// plugins/lumatoast.client.ts
|
|
490
652
|
import "lumatoast/styles.css";
|
|
491
653
|
import { initializeRenderer } from "lumatoast";
|
|
492
654
|
|
|
655
|
+
export default defineNuxtPlugin(() => {
|
|
656
|
+
initializeRenderer();
|
|
657
|
+
});
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
---
|
|
661
|
+
|
|
662
|
+
### Angular
|
|
663
|
+
|
|
664
|
+
#### 1. Add Styles
|
|
665
|
+
In `angular.json` under `styles`:
|
|
666
|
+
```json
|
|
667
|
+
"styles": [
|
|
668
|
+
"node_modules/lumatoast/dist/styles.css",
|
|
669
|
+
"src/styles.css"
|
|
670
|
+
]
|
|
671
|
+
```
|
|
672
|
+
*(Or add `@import "lumatoast/styles.css";` directly in `src/styles.css`)*.
|
|
673
|
+
|
|
674
|
+
#### 2. Initialize in `main.ts`
|
|
675
|
+
```ts
|
|
676
|
+
// src/main.ts
|
|
677
|
+
import { bootstrapApplication } from "@angular/platform-browser";
|
|
678
|
+
import { AppComponent } from "./app/app.component";
|
|
679
|
+
import { initializeRenderer } from "lumatoast";
|
|
680
|
+
|
|
493
681
|
initializeRenderer();
|
|
494
|
-
|
|
682
|
+
|
|
683
|
+
bootstrapApplication(AppComponent).catch((err) => console.error(err));
|
|
495
684
|
```
|
|
496
685
|
|
|
497
|
-
|
|
686
|
+
#### 3. Use in Any Angular Component or Service
|
|
687
|
+
```ts
|
|
688
|
+
import { Component } from "@angular/core";
|
|
689
|
+
import { toast } from "lumatoast";
|
|
498
690
|
|
|
691
|
+
@Component({
|
|
692
|
+
selector: "app-root",
|
|
693
|
+
standalone: true,
|
|
694
|
+
template: `<button (click)="notify()">Show Toast</button>`,
|
|
695
|
+
})
|
|
696
|
+
export class AppComponent {
|
|
697
|
+
notify() {
|
|
698
|
+
toast.success("Hello from Angular!", { theme: "cupertino" });
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
---
|
|
704
|
+
|
|
705
|
+
### Svelte / SvelteKit
|
|
706
|
+
|
|
707
|
+
In `src/routes/+layout.svelte` (or `src/main.ts`):
|
|
708
|
+
|
|
709
|
+
```svelte
|
|
710
|
+
<!-- src/routes/+layout.svelte -->
|
|
711
|
+
<script>
|
|
712
|
+
import { onMount } from "svelte";
|
|
713
|
+
import "lumatoast/styles.css";
|
|
714
|
+
import { initializeRenderer } from "lumatoast";
|
|
715
|
+
|
|
716
|
+
onMount(() => {
|
|
717
|
+
initializeRenderer();
|
|
718
|
+
});
|
|
719
|
+
</script>
|
|
720
|
+
|
|
721
|
+
<slot />
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
In any Svelte component:
|
|
725
|
+
|
|
726
|
+
```svelte
|
|
727
|
+
<script>
|
|
728
|
+
import { toast } from "lumatoast";
|
|
729
|
+
</script>
|
|
730
|
+
|
|
731
|
+
<button on:click={() => toast.success("Hello from Svelte!")}>Notify</button>
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
---
|
|
735
|
+
|
|
736
|
+
### Vanilla JS / Static HTML
|
|
737
|
+
|
|
738
|
+
With a bundler (Vite / Webpack / Rollup):
|
|
739
|
+
```html
|
|
740
|
+
<script type="module">
|
|
741
|
+
import "lumatoast/styles.css";
|
|
742
|
+
import { initializeRenderer, toast } from "lumatoast";
|
|
743
|
+
|
|
744
|
+
initializeRenderer();
|
|
745
|
+
document.querySelector("#btn").onclick = () => toast.success("Ready!");
|
|
746
|
+
</script>
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
Direct script inclusion from node_modules:
|
|
499
750
|
```html
|
|
500
751
|
<link rel="stylesheet" href="node_modules/lumatoast/dist/styles.css" />
|
|
501
752
|
<script type="module">
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
753
|
+
import { initializeRenderer, toast } from "./node_modules/lumatoast/dist/index.js";
|
|
754
|
+
initializeRenderer();
|
|
755
|
+
toast.success("Vanilla JS works!");
|
|
505
756
|
</script>
|
|
506
757
|
```
|
|
507
758
|
|
|
508
759
|
---
|
|
509
760
|
|
|
761
|
+
## Environment & Compatibility
|
|
762
|
+
|
|
763
|
+
| Environment | Supported Versions | Notes |
|
|
764
|
+
|---|---|---|
|
|
765
|
+
| **Node.js** | `>= 18.0.0` (18, 20, 22, 24+) | Built for modern ESM & CommonJS tooling |
|
|
766
|
+
| **Browsers** | Chrome, Edge, Firefox, Safari, iOS Safari | Supports modern CSS variables and flexbox |
|
|
767
|
+
| **Module Systems** | ESM (`import`) & CommonJS (`require`) | Dual-packaged with TypeScript declarations |
|
|
768
|
+
| **SSR Frameworks** | Next.js, Nuxt, Remix, SvelteKit, Astro | Crash-safe on server; initialize in client lifecycle |
|
|
769
|
+
|
|
770
|
+
---
|
|
771
|
+
|
|
510
772
|
## Keyboard Support
|
|
511
773
|
|
|
512
774
|
| Key | Action |
|