juice-toast 0.0.0-next.1202026

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/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ NEXT 120/2026
2
+ - Adding Swipe to Dismiss
3
+ - Adding Pause on Hover
4
+ - Adding `playSound`
5
+ - Adding GlassUI (WARNING: This Function Still In BETA, it not worked or it can make error)
6
+
7
+ v1.1.0
8
+ - Adding **Size Preset**
9
+ - Adding Compact
10
+ - Improve Style And Fix Bugs
11
+ - Improve `.d.ts`
12
+ - Adding **Actions Button**
13
+
14
+ v1.0.1
15
+ - Add Forget File `style.css`
16
+
17
+ v1.0.0
18
+ - Published In First Time
19
+
20
+
@@ -0,0 +1,87 @@
1
+ # Juice Toast Code of Conduct
2
+
3
+ ### Hey there, fellow developer! 👋
4
+
5
+ Welcome to the Juice Toast community! We’re thrilled that you’re here.
6
+ We want to make sure this space is **fun, safe, and welcoming for everyone**.
7
+ Whether you’re submitting your first PR, reporting a bug, or just commenting, we expect all contributors to treat each other with respect and kindness.
8
+
9
+ We believe that great projects are built **together**, and that means fostering a community where **everyone feels comfortable to contribute**, ask questions, and share ideas.
10
+
11
+ ---
12
+
13
+ ### Our Promise to You
14
+
15
+ We, as maintainers and contributors, pledge to:
16
+
17
+ - Keep discussions **friendly, welcoming, and inclusive**
18
+ - Respect all backgrounds, experiences, and skill levels
19
+ - Give and receive **constructive feedback** gracefully
20
+ - Focus on **collaboration over competition**
21
+ - Be understanding and empathetic when conflicts arise
22
+
23
+ ---
24
+
25
+ ### What We Expect From You
26
+
27
+ Here are some ways you can help make Juice Toast a positive community:
28
+
29
+ - Use **clear and polite language** in issues, PRs, and comments
30
+ - Be **patient** with beginners — everyone was new once
31
+ - Give **helpful, actionable feedback** instead of just criticism
32
+ - Celebrate others’ successes and contributions
33
+ - Ask questions respectfully and be open to learning
34
+
35
+ ---
36
+
37
+ ### What We Don’t Accept 🚫
38
+
39
+ - Harassment, threats, or intimidation of any kind
40
+ - Disrespectful or derogatory comments, including those about race, gender, identity, orientation, religion, or skill level
41
+ - Posting private or personal information without permission
42
+ - Trolling, spamming, or intentionally derailing conversations
43
+ - Any behavior that would make others feel unsafe or unwelcome
44
+
45
+ ---
46
+
47
+ ### Handling Issues & Conflicts
48
+
49
+ If you see or experience something that breaks this Code of Conduct:
50
+
51
+ 1. **Stay calm** and don’t respond aggressively.
52
+ 2. **Report it** to the maintainers at **[your-email@example.com]**.
53
+ 3. Maintainers will **review and respond quickly and fairly**, keeping the reporter anonymous if requested.
54
+ 4. Actions can include **warnings, temporary restrictions, or banning**, depending on severity.
55
+
56
+ We’re here to **help resolve conflicts and keep the community safe**.
57
+
58
+ ---
59
+
60
+ ### Scope
61
+
62
+ This Code of Conduct applies:
63
+
64
+ - In all **project spaces**: issues, pull requests, discussions, wiki, and code
65
+ - In all **public spaces** where contributors represent Juice Toast
66
+ - To everyone: maintainers, contributors, and visitors
67
+
68
+ ---
69
+
70
+ ### Our Commitment as Maintainers
71
+
72
+ As maintainers, we promise to:
73
+
74
+ - Model **friendly, inclusive behavior**
75
+ - **Enforce this Code of Conduct fairly** for all community members
76
+ - Listen to feedback and continuously improve our community practices
77
+ - Take action if behavior is harmful or unsafe, even if it’s uncomfortable
78
+
79
+ ---
80
+
81
+ ### Why This Matters
82
+
83
+ Juice Toast isn’t just code — it’s a **community of developers who care**.
84
+ Great ideas come from collaboration, experimentation, and mutual respect.
85
+ By following this Code of Conduct, you’re helping make Juice Toast a **place where developers of all skill levels can grow, learn, and have fun**.
86
+
87
+ Let’s build something amazing together! 🚀
@@ -0,0 +1,65 @@
1
+ # Welcome To Juice Toast Contributing! 🎉
2
+
3
+ Thank you for your contribution to the **Juice Toast** project!
4
+ We hope this project becomes one of the greatest projects on GitHub.
5
+
6
+ ---
7
+
8
+ ## What is Juice Toast?
9
+
10
+ Juice Toast is a **lightweight and flexible JavaScript toast notification library**.
11
+ It’s designed to be **easy to use, fast, and customizable**, making your notifications look awesome in just a few lines of code.
12
+
13
+ ---
14
+
15
+ ## How to Contribute
16
+
17
+ 1. **Fork this repository**
18
+
19
+ ```bash
20
+ # Clone your fork
21
+ git clone https://github.com/KhairyK/juiceToast.git
22
+
23
+ # Move into the project folder
24
+ cd juiceToast
25
+
26
+ # Move into Source code code
27
+ cd src
28
+
29
+ # Synchronize with the original repository
30
+ git remote add upstream https://github.com/KhairyK/juiceToast.git
31
+
32
+ # Check the remotes
33
+ git remote -v
34
+ ```
35
+
36
+ 2. **Create a new branch**
37
+
38
+ ```bash
39
+ git checkout -b feature/your-feature-name
40
+ ```
41
+
42
+ 3. **Make your changes**
43
+ Edit files, add features, or fix bugs.
44
+
45
+ 4. **Commit your changes**
46
+
47
+ ```bash
48
+ git add .
49
+ git commit -m "Add awesome feature"
50
+ ```
51
+
52
+ 5. **Push your branch**
53
+
54
+ ```bash
55
+ git push origin feature/your-feature-name
56
+ ```
57
+
58
+ <small>Note: Wait until the team reviews your code.</small>
59
+
60
+ ---
61
+
62
+ ## Code of Conduct
63
+ Read the [Code Of Conduct](https://github.com/KhairyK/juiceToast/blob/main/CODE_OF_CONDUCT.md)
64
+
65
+ 2026 (C) OpenDN Foundation / Released under MIT LICENSE
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sholehuddin Khairy
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.
package/README.md ADDED
@@ -0,0 +1,247 @@
1
+ # 🍹 JuiceToast
2
+
3
+ **JuiceToast** is a lightweight, flexible, and dependency-free toast notification library for modern web applications.
4
+ Designed with a **clean API**, **extensive customization**, and **strong backward compatibility**, JuiceToast fits both small projects and enterprise-scale systems.
5
+
6
+ It supports **ESM and UMD**, **dynamic toast types**, **theme management**, **queue handling**, and **legacy API compatibility** out of the box.
7
+
8
+ ---
9
+
10
+ ## ✨ Key Features
11
+
12
+ - 🚀 Zero dependencies
13
+ - 📦 Supports **ESM** and **UMD**
14
+ - 🔁 Built-in queue system (one toast displayed at a time)
15
+ - 🎨 Theme system (light, dark, and custom themes)
16
+ - 🧩 Dynamic toast types (`success`, `error`, etc.)
17
+ - ⏳ Auto-dismiss & sticky toasts
18
+ - ❌ Closable toasts
19
+ - ⭐ Icon support (position, animation, link)
20
+ - 📐 Size presets and manual sizing
21
+ - 🧱 Full backward compatibility with legacy APIs
22
+
23
+ ---
24
+
25
+ ## 📦 Installation
26
+
27
+ ### ESM
28
+ ```js
29
+ import juiceToast from "https://cdn.kyrt.my.id/libs/js/juice-toast/1.1.0/juice-toast.esm.min.js";
30
+ ```
31
+
32
+ ### UMD (Browser)
33
+ ```html
34
+ <link
35
+ rel="stylesheet"
36
+ href="https://cdn.kyrt.my.id/libs/css/fontic/2.0.0/juice-toast/style.min.css"
37
+ />
38
+ <script src="https://cdn.kyrt.my.id/libs/js/juice-toast/1.1.0/juice-toast.umd.min.js"></script>
39
+
40
+ <script>
41
+ juiceToast.setup({
42
+ success: {
43
+ bg: "#01AA38"
44
+ }
45
+ });
46
+
47
+ juiceToast.success("Hello world!");
48
+ </script>
49
+ ```
50
+
51
+ ---
52
+
53
+ ## 🚀 Quick Start
54
+
55
+ ```js
56
+ juiceToast.setup({
57
+ success: {
58
+ icon: "check",
59
+ theme: "light",
60
+ duration: 2000
61
+ },
62
+ error: {
63
+ icon: "x",
64
+ bg: "#7f1d1d",
65
+ color: "#fff",
66
+ closable: true
67
+ }
68
+ });
69
+
70
+ juiceToast.success("Operation completed successfully.");
71
+ juiceToast.error({
72
+ title: "Error",
73
+ message: "An unexpected error occurred."
74
+ });
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 🧠 Core Concepts
80
+
81
+ ### Toast Types
82
+
83
+ Toasts are triggered based on **types** registered using `setup()` or `addType()`.
84
+
85
+ ```js
86
+ juiceToast.info("Information message");
87
+ juiceToast.warning({
88
+ message: "Proceed with caution",
89
+ duration: 4000
90
+ });
91
+ ```
92
+
93
+ This approach allows a clear separation between **toast configuration** and **runtime usage**.
94
+
95
+ ---
96
+
97
+ ## ⚙️ API Reference
98
+
99
+ ### `setup(config)`
100
+ Registers all toast types and their default configuration.
101
+
102
+ ```js
103
+ juiceToast.setup({
104
+ success: { bg: "green" },
105
+ error: { bg: "red" }
106
+ });
107
+ ```
108
+
109
+ ---
110
+
111
+ ### `addType(name, config)`
112
+ Adds a new toast type dynamically at runtime.
113
+
114
+ ```js
115
+ juiceToast.addType("warning", {
116
+ bg: "#facc15",
117
+ color: "#111"
118
+ });
119
+ ```
120
+
121
+ ---
122
+
123
+ ### `defineTheme(name, styles)`
124
+ Creates or overrides a theme.
125
+
126
+ ```js
127
+ juiceToast.defineTheme("ocean", {
128
+ bg: "#0ea5e9",
129
+ color: "#ffffff",
130
+ border: "1px solid #0284c7"
131
+ });
132
+ ```
133
+
134
+ ---
135
+
136
+ ### `setTheme(name)`
137
+ Sets the global theme.
138
+
139
+ ```js
140
+ juiceToast.setTheme("dark");
141
+ ```
142
+
143
+ ---
144
+
145
+ ### `clear()`
146
+ Clears all pending toast queues.
147
+
148
+ ```js
149
+ juiceToast.clear();
150
+ ```
151
+
152
+ ---
153
+
154
+ ### `destroy()`
155
+ Removes all queues and the root DOM element.
156
+
157
+ ```js
158
+ juiceToast.destroy();
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 🧾 Toast Payload Interface
164
+
165
+ ```ts
166
+ interface ToastPayload {
167
+ message?: string;
168
+ title?: string;
169
+
170
+ bg?: string;
171
+ color?: string;
172
+ border?: string;
173
+ theme?: string;
174
+
175
+ duration?: number; // milliseconds, 0 = sticky
176
+ position?: "top" | "center" | "bottom";
177
+ toast?: "top" | "center" | "bottom"; // legacy support
178
+
179
+ closable?: boolean;
180
+ closeable?: boolean; // legacy support
181
+
182
+ icon?: string;
183
+ iconPack?: string;
184
+ iconLink?: string;
185
+ iconAnimate?: string;
186
+ iconPosition?: "left" | "right" | "top";
187
+
188
+ size?: "sm" | "md" | "lg";
189
+ width?: string;
190
+ height?: string;
191
+
192
+ actions?: {
193
+ label: string;
194
+ onClick?: (event: MouseEvent) => void;
195
+ closeOnClick?: boolean;
196
+ }[];
197
+
198
+ [key: string]: any;
199
+ }
200
+ ```
201
+
202
+ ---
203
+
204
+ ## 🔄 Backward Compatibility
205
+
206
+ JuiceToast automatically maps legacy options to the modern API.
207
+
208
+ | Legacy Option | Current Option |
209
+ |--------------|----------------|
210
+ | `toast` | `position` |
211
+ | `closeable` | `closable` |
212
+ | `icon_left_top` | `icon` |
213
+ | `icon_config` | `iconPack` |
214
+ | `icon_onClick_url` | `iconLink` |
215
+ | `icon_onClick_animate` | `iconAnimate` |
216
+
217
+ ---
218
+
219
+ ## 🎨 Default Themes
220
+
221
+ ```js
222
+ light: {
223
+ bg: "#ffffff",
224
+ color: "#111",
225
+ border: "1px solid #e5e7eb"
226
+ }
227
+
228
+ dark: {
229
+ bg: "#1f2937",
230
+ color: "#ffffff",
231
+ border: "1px solid rgba(255,255,255,.08)"
232
+ }
233
+ ```
234
+
235
+ ---
236
+
237
+ ## 📌 Notes
238
+
239
+ - Browser-only (DOM required)
240
+ - Root element is automatically created: `#juice-toast-root`
241
+ - Suitable for frameworks, custom runtimes, etc.
242
+
243
+ ---
244
+
245
+ ## 📄 License
246
+
247
+ MIT License © OpenDN Foundation
@@ -0,0 +1,170 @@
1
+ /**
2
+ * OpenDN Foundation (C) 2026
3
+ * Juice Toast — Type Definitions
4
+ * @license MIT
5
+ */
6
+
7
+ /* ================= BASIC TYPES ================= */
8
+
9
+ export type ToastPosition =
10
+ | "top"
11
+ | "center"
12
+ | "bottom"
13
+ | "top-left"
14
+ | "top-right"
15
+ | "top-center"
16
+ | "bottom-left"
17
+ | "bottom-right"
18
+ | "bottom-center";
19
+
20
+ export type ToastSize = "sm" | "md" | "lg";
21
+
22
+ export type IconPosition = "left" | "right" | "top";
23
+
24
+ export type ToastDuration = number; // 0 = persistent
25
+
26
+ /* ================= THEME ================= */
27
+
28
+ export interface ToastTheme {
29
+ bg?: string;
30
+ color?: string;
31
+ border?: string;
32
+ glow?: string;
33
+ }
34
+
35
+ /* ================= ACTION ================= */
36
+
37
+ export interface ToastAction {
38
+ label: string;
39
+ onClick?: (event: MouseEvent) => void;
40
+ closeOnClick?: boolean;
41
+ }
42
+
43
+ /* ================= PAYLOAD ================= */
44
+
45
+ export interface ToastPayload {
46
+ /* -------- content -------- */
47
+ message?: string;
48
+ title?: string;
49
+
50
+ /* -------- appearance -------- */
51
+ bg?: string;
52
+ color?: string;
53
+ border?: string;
54
+ glow?: string;
55
+ theme?: string;
56
+
57
+ width?: string;
58
+ height?: string;
59
+ size?: ToastSize;
60
+ compact?: boolean;
61
+
62
+ /* -------- timing & placement -------- */
63
+ duration?: ToastDuration;
64
+ position?: ToastPosition;
65
+ toast?: ToastPosition; // legacy
66
+
67
+ pauseOnHover?: boolean; // default true
68
+ swipeToDismiss?: boolean; // default true
69
+
70
+ /* -------- close -------- */
71
+ closable?: boolean;
72
+ closeable?: boolean; // legacy
73
+
74
+ /* -------- icon (modern) -------- */
75
+ icon?: string;
76
+ iconPack?: string;
77
+ iconSize?: string;
78
+ iconPosition?: IconPosition;
79
+ iconLink?: string;
80
+ iconAnimate?: string;
81
+
82
+ /* -------- icon (legacy) -------- */
83
+ icon_left_top?: string;
84
+ icon_config?: string;
85
+ icon_onClick_url?: string;
86
+ icon_onClick_animate?: string;
87
+
88
+ playSound ? : string | boolean;
89
+ glassUI ? : boolean;
90
+
91
+ /* -------- actions -------- */
92
+ actions?: ToastAction[];
93
+
94
+ /* -------- advanced -------- */
95
+ render?: (root: HTMLElement) => void;
96
+
97
+ /* -------- escape hatch -------- */
98
+ [key: string]: unknown;
99
+ }
100
+
101
+ /* ================= TYPE CONFIG ================= */
102
+
103
+ export interface ToastTypeConfig extends ToastPayload {}
104
+
105
+ /* ================= GLOBAL CONFIG ================= */
106
+
107
+ export interface JuiceToastDefaults {
108
+ duration?: ToastDuration;
109
+ position?: ToastPosition;
110
+ maxVisible?: number;
111
+ swipeThreshold?: number;
112
+ pauseOnHover?: boolean;
113
+ swipeToDismiss?: boolean;
114
+ closable?: boolean;
115
+ playSound?: string | boolean;
116
+ glassUI?: boolean | number;
117
+ }
118
+
119
+ /* ================= CORE API ================= */
120
+
121
+ export interface JuiceToastAPI {
122
+ /**
123
+ * Register toast types in bulk
124
+ */
125
+ setup<T extends Record<string, ToastTypeConfig>>(
126
+ config?: T & JuiceToastDefaults
127
+ ): void;
128
+
129
+ /**
130
+ * Add or override a single toast type
131
+ */
132
+ addType<T extends ToastTypeConfig>(
133
+ name: string,
134
+ config?: T
135
+ ): void;
136
+
137
+ /**
138
+ * Global defaults
139
+ */
140
+ defaults(config: JuiceToastDefaults): void;
141
+
142
+ /**
143
+ * Theme system
144
+ */
145
+ defineTheme(name: string, styles: ToastTheme): void;
146
+ setTheme(name: string): void;
147
+
148
+ /**
149
+ * Queue control
150
+ */
151
+ clear(): void;
152
+ destroy(): void;
153
+
154
+ /**
155
+ * Dynamic toast methods
156
+ * juiceToast.success(...)
157
+ * juiceToast.error(...)
158
+ * juiceToast.anything(...)
159
+ */
160
+ [type: string]:
161
+ | ((payload?: string | number | ToastPayload) => void)
162
+ | unknown;
163
+ }
164
+
165
+ /* ================= EXPORT ================= */
166
+
167
+ declare const juiceToast: JuiceToastAPI;
168
+
169
+ export default juiceToast;
170
+ export { juiceToast };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 2026 (C) OpenDN Foundation
3
+ * v120/2026 Juice Toast
4
+ * ESM (ECMAScript Module (import/export))
5
+ */
6
+ let isBrowser="undefined"!=typeof window&&"undefined"!=typeof document,themes={light:{bg:"#ffffff",color:"#111",border:"1px solid #e5e7eb"},dark:{bg:"#1f2937",color:"#fff",border:"1px solid rgba(255,255,255,.08)"}},sizePreset={sm:{width:"260px",padding:"10px"},md:{width:"320px",padding:"14px"},lg:{width:"420px",padding:"18px"}},juiceToast={_config:{},_queue:[],_showing:!1,_theme:"dark",setup(e={}){this._config=e,this._defaults={...this._defaults,...e},this._registerTypes()},addType(e,t={}){this._config[e]=t,this._registerTypes()},defineTheme(e,t={}){themes[e]={...themes[e]||{},...t}},setTheme(e){if(this._theme=e,!isBrowser)return;let t=document.getElementById("juice-toast-root");t&&(t.dataset.theme=e)},clear(){this._queue.length=0},destroy(){this.clear(),isBrowser&&document.getElementById("juice-toast-root")?.remove()},_registerTypes(){Object.keys(this._config).forEach(e=>{if("function"==typeof this[e]&&!this[e].__auto)return;let t=t=>this._enqueue(e,t);t.__auto=!0,this[e]=t})},_enqueue(e,t){this._queue.push({type:e,payload:t}),this._showing||this._next()},_next(){if(!this._queue.length){this._showing=!1;return}this._showing=!0;let e=this._queue.shift();this._showToast(e.type,e.payload)},_normalizeGlass(e){if(!0===e)return 60;if(!1===e||null==e)return 0;let t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(100,t)):0},_getRoot(e){if(!isBrowser)return null;let t=document.getElementById("juice-toast-root");return t||((t=document.createElement("div")).id="juice-toast-root",document.body.appendChild(t)),t.dataset.position=e||"bottom",t.dataset.theme=this._theme,t},_defaults:{duration:2500,maxVisible:3,swipeThreshold:60,glassUI:0,playSound:null},_playSound(e){if(!isBrowser)return;let t="string"==typeof e&&e?e:this._defaults.playSound;if(t)try{let i=new Audio(t);i.volume=.6,i.play().catch(()=>{})}catch{}},_showToast(e,t){if(!isBrowser)return;let i=this._config[e]||{},s="object"==typeof t?t:{message:String(t)},o={...i,...s};o.icon=o.icon??o.icon_left_top,o.iconPack=o.iconPack??o.icon_config,o.iconLink=o.iconLink??o.icon_onClick_url,o.iconAnimate=o.iconAnimate??o.icon_onClick_animate,o.position=o.position??o.toast,o.closable=o.closable??o.closeable,o.iconPosition=o.iconPosition||"left",o.compact=!!o.compact;let n=themes[o.theme||this._theme]||{},a=document.createElement("div");if(a.className="juice-toast",o.size&&sizePreset[o.size]){let l=sizePreset[o.size];l.width&&(a.style.width=l.width),l.padding&&(a.style.padding=l.padding)}let d=this._normalizeGlass(o.glassUI??this._defaults.glassUI);d>0&&(a.classList.add("jt-glass"),a.style.setProperty("--jt-glass",d)),d||(a.style.background=o.bg||n.bg),a.style.color=o.color||n.color,a.style.border=o.border||n.border,o.compact&&a.classList.add("jt-compact"),(o.glassUI??this._defaults.glassUI)&&a.classList.add("jt-glass"),o.width&&(a.style.width=o.width),o.height&&(a.style.height=o.height);let c=null;o.icon&&((c=document.createElement("i")).className=["icon",o.iconPack||"",o.icon].join(" ").trim(),o.iconSize&&(c.style.fontSize=o.iconSize),(o.iconLink||o.iconAnimate)&&(c.classList.add("icon-clickable"),c.onclick=e=>{e.stopPropagation(),o.iconAnimate&&(c.classList.remove(o.iconAnimate),c.offsetWidth,c.classList.add(o.iconAnimate)),o.iconLink&&window.open(o.iconLink,"_blank","noopener")}));let r=0,h=0;a.addEventListener("touchstart",e=>{r=e.touches[0].clientX}),a.addEventListener("touchmove",e=>{h=e.touches[0].clientX-r,a.style.transform=`translateX(${h}px)`}),a.addEventListener("touchend",()=>{Math.abs(h)>this._defaults.swipeThreshold?(a.style.transform=`translateX(${h>0?1e3:-1e3}px)`,setTimeout(()=>{a.remove(),this._next()},200)):a.style.transform="",r=h=0});let p=document.createElement("div");if(p.className="jt-content",o.title){let u=document.createElement("div");u.className="jt-title",u.textContent=o.title,p.appendChild(u)}let m=document.createElement("div");if(m.className="jt-message",m.textContent=o.message||"",p.appendChild(m),c&&"top"===o.iconPosition?(a.classList.add("jt-icon-top"),a.appendChild(c),a.appendChild(p)):c&&"right"===o.iconPosition?(a.appendChild(p),a.appendChild(c)):(c&&a.appendChild(c),a.appendChild(p)),Array.isArray(o.actions)&&o.actions.length){let f=document.createElement("div");f.className="jt-actions",o.actions.forEach(e=>{let t=document.createElement("button");t.className="jt-action",t.textContent=e.label,t.onclick=t=>{t.stopPropagation(),e.onClick?.(t),e.closeOnClick&&(a.remove(),this._next())},f.appendChild(t)}),p.appendChild(f)}if(o.closable){let g=document.createElement("span");g.className="juice-toast-close",g.innerHTML="\xd7",g.onclick=()=>{a.remove(),this._next()},a.appendChild(g)}let $=this._getRoot(o.position),y=this._defaults.maxVisible;y&&$.children.length>=y&&$.firstChild.remove(),$.appendChild(a),requestAnimationFrame(()=>a.classList.add("show"));let w=o.duration??2500;if(0===w)return;let b=Date.now(),v=o.duration??this._defaults.duration,x,L=()=>{if(a.__paused)b=Date.now();else{let e=Date.now();v-=e-b,b=e}v<=0?(a.classList.remove("show"),setTimeout(()=>{a.remove(),this._next()},300)):x=requestAnimationFrame(L)};a.addEventListener("mouseenter",()=>a.__paused=!0),a.addEventListener("mouseleave",()=>a.__paused=!1),a.addEventListener("touchstart",()=>a.__paused=!0),a.addEventListener("touchend",()=>a.__paused=!1),requestAnimationFrame(L)}};export default juiceToast;export{juiceToast};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 2026 (C) OpenDN Foundation
3
+ * v120/2026 Juice Toast
4
+ * UMD (Universal Module Definition (<script>))
5
+ */
6
+ !function(e,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof module&&module.exports?module.exports=t():e.juiceToast=t()}(this,function(){return function(){let e="undefined"!=typeof window&&"undefined"!=typeof document,t={light:{bg:"#fff",color:"#111",border:"1px solid #e5e7eb"},dark:{bg:"#1f2937",color:"#fff",border:"1px solid rgba(255,255,255,.08)"}};return{_config:{},_queue:[],_showing:!1,_theme:"dark",setup(e={}){this._config=e,this._defaults={...this._defaults,...e},this._registerTypes()},addType(e,t={}){this._config[e]=t,this._registerTypes()},defineTheme(e,i={}){t[e]={...t[e]||{},...i}},setTheme(t){if(this._theme=t,!e)return;let i=document.getElementById("juice-toast-root");i&&(i.dataset.theme=t)},clear(){this._queue.length=0},destroy(){this.clear(),e&&document.getElementById("juice-toast-root")?.remove()},_registerTypes(){Object.keys(this._config).forEach(e=>{if("function"==typeof this[e]&&!this[e].__auto)return;let t=t=>this._enqueue(e,t);t.__auto=!0,this[e]=t})},_enqueue(e,t){this._queue.push({type:e,payload:t}),this._showing||this._next()},_next(){if(!this._queue.length){this._showing=!1;return}this._showing=!0;let e=this._queue.shift();this._showToast(e.type,e.payload)},_getRoot(t){if(!e)return null;let i=document.getElementById("juice-toast-root");return i||((i=document.createElement("div")).id="juice-toast-root",document.body.appendChild(i)),i.dataset.position=t||"bottom",i.dataset.theme=this._theme,i},_normalizeGlass(e){if(!0===e)return 60;if(!1===e||null==e)return 0;let t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(100,t)):0},_defaults:{duration:2500,maxVisible:3,swipeThreshold:60,glassUI:0,playSound:null},_playSound(t){if(!e)return;let i="string"==typeof t&&t?t:this._defaults.playSound;if(i)try{let s=new Audio(i);s.volume=.6,s.play().catch(()=>{})}catch{}},_showToast(i,s){if(!e)return;let n=this._config[i]||{},o="object"==typeof s?s:{message:String(s)},a={...n,...o};a.icon=a.icon??a.icon_left_top,a.iconPack=a.iconPack??a.icon_config,a.iconLink=a.iconLink??a.icon_onClick_url,a.iconAnimate=a.iconAnimate??a.icon_onClick_animate,a.position=a.position??a.toast,a.closable=a.closable??a.closeable,a.iconPosition=a.iconPosition||"left",a.compact=!!a.compact;let l=t[a.theme||this._theme]||{},c=document.createElement("div");if(c.className="juice-toast",a.size&&sizePreset[a.size]){let d=sizePreset[a.size];d.width&&(c.style.width=d.width),d.padding&&(c.style.padding=d.padding)}let r=this._normalizeGlass(a.glassUI??this._defaults.glassUI);r>0&&(c.classList.add("jt-glass"),c.style.setProperty("--jt-glass",r)),r||(c.style.background=a.bg||l.bg),c.style.color=a.color||l.color,c.style.border=a.border||l.border,(a.glassUI??this._defaults.glassUI)&&c.classList.add("jt-glass"),a.width&&(c.style.width=a.width),a.height&&(c.style.height=a.height);let h=null;a.icon&&((h=document.createElement("i")).className=["icon",a.iconPack||"",a.icon].join(" ").trim(),a.iconSize&&(h.style.fontSize=a.iconSize),(a.iconLink||a.iconAnimate)&&(h.classList.add("icon-clickable"),h.onclick=e=>{e.stopPropagation(),a.iconAnimate&&(h.classList.remove(a.iconAnimate),h.offsetWidth,h.classList.add(a.iconAnimate)),a.iconLink&&window.open(a.iconLink,"_blank","noopener")}));let u=0,p=0;c.addEventListener("touchstart",e=>{u=e.touches[0].clientX}),c.addEventListener("touchmove",e=>{p=e.touches[0].clientX-u,c.style.transform=`translateX(${p}px)`}),c.addEventListener("touchend",()=>{Math.abs(p)>this._defaults.swipeThreshold?(c.style.transform=`translateX(${p>0?1e3:-1e3}px)`,setTimeout(()=>{c.remove(),this._next()},200)):c.style.transform="",u=p=0});let m=document.createElement("div");if(m.className="jt-content",a.title){let f=document.createElement("div");f.className="jt-title",f.textContent=a.title,m.appendChild(f)}let g=document.createElement("div");if(g.className="jt-message",g.textContent=a.message||"",m.appendChild(g),h&&"top"===a.iconPosition?(c.classList.add("jt-icon-top"),c.appendChild(h),c.appendChild(m)):h&&"right"===a.iconPosition?(c.appendChild(m),c.appendChild(h)):(h&&c.appendChild(h),c.appendChild(m)),Array.isArray(a.actions)&&a.actions.length){let $=document.createElement("div");$.className="jt-actions",a.actions.forEach(e=>{let t=document.createElement("button");t.className="jt-action",t.textContent=e.label,t.onclick=t=>{t.stopPropagation(),e.onClick?.(t),e.closeOnClick&&(c.remove(),this._next())},$.appendChild(t)}),m.appendChild($)}if(a.closable){let y=document.createElement("span");y.className="juice-toast-close",y.innerHTML="\xd7",y.onclick=()=>{c.remove(),this._next()},c.appendChild(y)}let b=this._getRoot(a.position),v=this._defaults.maxVisible;v&&b.children.length>=v&&b.firstChild.remove(),b.appendChild(c),requestAnimationFrame(()=>c.classList.add("show"));let k=a.duration??2500;if(0===k)return;let C=Date.now(),E=a.duration??this._defaults.duration,L,w=()=>{if(c.__paused)C=Date.now();else{let e=Date.now();E-=e-C,C=e}E<=0?(c.classList.remove("show"),setTimeout(()=>{c.remove(),this._next()},300)):L=requestAnimationFrame(w)};c.addEventListener("mouseenter",()=>c.__paused=!0),c.addEventListener("mouseleave",()=>c.__paused=!1),c.addEventListener("touchstart",()=>c.__paused=!0),c.addEventListener("touchend",()=>c.__paused=!1),requestAnimationFrame(w)}}}()});
package/dist/style.css ADDED
@@ -0,0 +1,6 @@
1
+ /*
2
+ 2026 (C) OpenDN Foundation
3
+ v120/2026
4
+ @license MIT
5
+ */
6
+ #juice-toast-root{position:fixed;z-index:9999;display:flex;gap:10px;pointer-events:none}#juice-toast-root[data-position=bottom]{bottom:20px;left:50%;transform:translateX(-50%);flex-direction:column;align-items:center}#juice-toast-root[data-position=top]{top:20px;left:50%;transform:translateX(-50%);flex-direction:column;align-items:center}#juice-toast-root[data-position=center]{top:50%;left:50%;transform:translate(-50%,-50%);flex-direction:column;align-items:center}.juice-toast{--jt-x:0px;--jt-y:12px;pointer-events:auto;display:flex;gap:12px;align-items:flex-start;min-width:220px;max-width:420px;padding:12px 16px;margin:6px 0;border-radius:8px;background:#333;color:#fff;font-family:system-ui,-apple-system,"Segoe UI",Roboto,Arial;font-size:14px;opacity:0;transform:translate(var(--jt-x),var(--jt-y));transition:opacity .25s,transform .25s,background .25s,color .25s,box-shadow .25s;position:relative;box-sizing:border-box;overflow:hidden}.juice-toast.show{opacity:1;--jt-y:0px}.juice-toast .icon{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;font-size:16px;line-height:1;flex:0 0 28px}.icon-clickable{opacity:.85;cursor:pointer}.icon-clickable:hover{opacity:1}.juice-toast .jt-content{display:flex;flex-direction:column;gap:4px;flex:1 1 auto}.juice-toast .jt-title{font-weight:700;font-size:13px;line-height:1.1}.juice-toast .jt-message{font-size:13px;line-height:1.3;opacity:.95}.jt-icon-top{flex-direction:column;align-items:flex-start}.jt-icon-top .icon{align-self:center;margin-bottom:6px}.juice-toast-close{position:absolute;top:6px;right:8px;cursor:pointer;font-size:16px;opacity:.75;padding:4px;border-radius:4px}.juice-toast-close:hover{opacity:1;background:rgba(255,255,255,.06)}.jt-actions{display:flex;gap:8px;margin-top:10px}.jt-action{background:0 0;border:1px solid currentColor;padding:4px 10px;border-radius:6px;cursor:pointer;font-size:12px}.jt-compact{padding:8px 10px;gap:8px;font-size:.9em}.jt-glass{--g:calc(var(--jt-glass, 60) / 100);background:rgba(30,30,30,calc(.2 + var(--g)));backdrop-filter:blur(calc(6px + (14px * var(--g)))) saturate(calc(1 + (0.4 * var(--g))));-webkit-backdrop-filter:blur(calc(6px + (14px * var(--g)))) saturate(calc(1 + (0.4 * var(--g))))}[data-theme=light] .jt-glass{background:linear-gradient(rgba(255,255,255,calc(.6 * var(--g))),rgba(255,255,255,calc(.35 * var(--g)))),rgba(255,255,255,calc(.55 - (.25 * var(--g))));color:#111;border:1px solid rgba(0,0,0,calc(.05 + .12 * var(--g)));box-shadow:0 10px 30px rgba(0,0,0,calc(.08 + .18 * var(--g))),inset 0 1px 0 rgba(255,255,255,calc(.4 * var(--g)))}@keyframes jt-spin{to{transform:rotate(360deg)}}@keyframes jt-pulse{50%{transform:scale(1.15)}}@keyframes jt-shake{25%,75%{transform:translateX(-3px)}50%{transform:translateX(3px)}}.spin{animation:.6s linear jt-spin}.pulse{animation:.4s jt-pulse}.shake{animation:.4s jt-shake}@media (prefers-reduced-motion:reduce){.juice-toast,.pulse,.shake,.spin{animation:none!important;transition:none!important}}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "juice-toast",
3
+ "version": "0.0.0-next.1202026",
4
+ "description": "Lightweight, dependency-free toast notification library",
5
+ "keywords": [
6
+ "toast",
7
+ "notification",
8
+ "ui",
9
+ "javascript",
10
+ "frontend",
11
+ "browser",
12
+ "vanilla-js"
13
+ ],
14
+ "license": "MIT",
15
+ "author": "KhairyK",
16
+ "homepage": "https://github.com/KhairyK/juiceToast",
17
+ "bugs": {
18
+ "url": "https://github.com/KhairyK/juiceToast/issues"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/KhairyK/juiceToast.git"
23
+ },
24
+ "funding": "https://patreon.com/Khairy47",
25
+ "engines": {
26
+ "node": ">=15"
27
+ },
28
+ "main": "dist/juice-toast.umd.js",
29
+ "module": "dist/juice-toast.esm.js",
30
+ "types": "dist/juice-toast.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "require": "./dist/juice-toast.umd.js",
34
+ "import": "./dist/juice-toast.esm.js",
35
+ "types": "./dist/juice-toast.d.ts"
36
+ }
37
+ },
38
+ "files": ["dist", "CHANGELOG.md", "CODE_OF_CONDUCT.md", "LICENSE", "README.md", "CONTRIBUTING.md"],
39
+ "sideEffects": false,
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "unpkg": "dist/juice-toast.umd.js",
44
+ "jsdelivr": "dist/juice-toast.umd.js",
45
+ "scripts": {
46
+ "test": "live-server"
47
+ },
48
+ "devDependencies": {
49
+ "live-server": "1.2.2"
50
+ }
51
+ }