juice-toast 1.1.0 → 1.2.1

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,26 @@
1
+ v1.2.0-rc.2026
2
+ - Adding A11Y
3
+ - Adding More Placement
4
+ - GlassUI Fix (WARNING: Maybe it's Not Working)
5
+ - Adding Animation
6
+
7
+ NEXT 120/2026
8
+ - Adding Swipe to Dismiss
9
+ - Adding Pause on Hover
10
+ - Adding `playSound`
11
+ - Adding GlassUI
12
+
13
+ v1.1.0
14
+ - Adding **Size Preset**
15
+ - Adding Compact
16
+ - Improve Style And Fix Bugs
17
+ - Improve `.d.ts`
18
+ - Adding **Actions Button**
19
+
20
+ v1.0.1
21
+ - Add Forget File `style.css`
22
+
23
+ v1.0.0
24
+ - Published In First Time
25
+
26
+
@@ -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/EoL.md ADDED
@@ -0,0 +1,10 @@
1
+ ## End of Life (EoL) Notice
2
+
3
+ The following versions and distributions have reached End of Life (EoL) and are no longer maintained.
4
+
5
+ | EoL Version | Affected Target | Reason |
6
+ |--------------------|-----------------|--------|
7
+ | 1.2.0-rc.2026 | UMD build | UMD distribution has been removed to simplify maintenance and reduce build complexity |
8
+ | 0.0.0-next.1202026 | Pre-release tag | Versioning structure became inconsistent and difficult to maintain |
9
+ | 1.0.0 | 1.0.0 | Stable release | Deprecated due to outdated internal architecture and styling standards |
10
+ | 1.0.0 | Stable release | Deprecated due to outdated internal architecture and styling standards |
@@ -0,0 +1,7 @@
1
+ # Juice Toast Release Candidate 2026 for v1.2.0
2
+
3
+ ```js
4
+ animation: "slide-in" | "fade-in" | "bounce-in";
5
+ glassUI: true | false | number
6
+ playSound: "soundName.mp3" // You can play `.wav`, `.aiff/.aif`, `.ogg`, `.wma`, `.opus`, etc.
7
+ ```
package/README.md CHANGED
@@ -26,16 +26,16 @@ It supports **ESM and UMD**, **dynamic toast types**, **theme management**, **qu
26
26
 
27
27
  ### ESM
28
28
  ```js
29
- import juiceToast from "https://cdn.kyrt.my.id/libs/js/juice-toast/1.1.0/juice-toast.esm.js";
29
+ import juiceToast from "https://cdn.kyrt.my.id/libs/js/juice-toast/1.1.0/juice-toast.esm.min.js";
30
30
  ```
31
31
 
32
32
  ### UMD (Browser)
33
33
  ```html
34
34
  <link
35
35
  rel="stylesheet"
36
- href="https://cdn.kyrt.my.id/libs/css/fontic/2.0.0/juice-toast/style.css"
36
+ href="https://cdn.kyrt.my.id/libs/css/fontic/2.0.0/juice-toast/style.min.css"
37
37
  />
38
- <script src="https://cdn.kyrt.my.id/libs/js/juice-toast/1.1.0/juice-toast.umd.js"></script>
38
+ <script src="https://cdn.kyrt.my.id/libs/js/juice-toast/1.1.0/juice-toast.umd.min.js"></script>
39
39
 
40
40
  <script>
41
41
  juiceToast.setup({
@@ -189,6 +189,8 @@ interface ToastPayload {
189
189
  width?: string;
190
190
  height?: string;
191
191
 
192
+ animation?: string;
193
+
192
194
  actions?: {
193
195
  label: string;
194
196
  onClick?: (event: MouseEvent) => void;
@@ -1,138 +1,107 @@
1
- /**
2
- * OpenDN Foundation (C) 2026
3
- * Juice Toast v1.1.0 Type Definitions
4
- * @license MIT
5
- */
1
+ /* --------------------------------------------------
2
+ * 2026 (C) OpenDN Foundation
3
+ * Juice Toast v1.2.0-rc.2026 Type Definitions
4
+ * -------------------------------------------------- */
6
5
 
7
- /* ================= BASIC TYPES ================= */
6
+ export type ToastTheme = {
7
+ bg?: string;
8
+ color?: string;
9
+ border?: string;
10
+ };
11
+
12
+ export type ToastSizePreset = "sm" | "md" | "lg";
8
13
 
9
14
  export type ToastPosition =
10
- | "top"
11
- | "center"
12
- | "bottom"
13
15
  | "top-left"
14
16
  | "top-right"
15
17
  | "bottom-left"
16
- | "bottom-right";
17
-
18
- export type ToastSize = "sm" | "md" | "lg";
19
-
20
- export type IconPosition = "left" | "right" | "top";
21
-
22
- export type ToastDuration = number; // 0 = persistent
23
-
24
- /* ================= THEME ================= */
18
+ | "bottom-right"
19
+ | "top-center"
20
+ | "bottom-center";
25
21
 
26
- export interface ToastTheme {
27
- bg?: string;
28
- color?: string;
29
- border?: string;
30
- glow?: string;
31
- }
22
+ export type ToastAnimation =
23
+ | "slide-in"
24
+ | "fade-in"
25
+ | "bounce-in"
26
+ | string;
32
27
 
33
- /* ================= ACTION ================= */
34
-
35
- export interface ToastAction {
28
+ export type ToastAction = {
36
29
  label: string;
37
- onClick?: (event: MouseEvent) => void;
30
+ onClick?: (event: Event) => void;
38
31
  closeOnClick?: boolean;
39
- }
32
+ };
40
33
 
41
- /* ================= PAYLOAD ================= */
42
-
43
- export interface ToastPayload {
44
- /* -------- content -------- */
34
+ export type ToastPayload = {
45
35
  message?: string;
46
36
  title?: string;
47
37
 
48
- /* -------- appearance -------- */
49
- bg?: string;
50
- color?: string;
51
- border?: string;
52
- glow?: string;
38
+ duration?: number; // ms, 0 = persistent
39
+ position?: ToastPosition;
53
40
  theme?: string;
54
-
41
+ bg?: string;
42
+ size?: ToastSizePreset;
55
43
  width?: string;
56
44
  height?: string;
57
- size?: ToastSize;
58
45
  compact?: boolean;
59
-
60
- /* -------- timing & placement -------- */
61
- duration?: ToastDuration;
62
- position?: ToastPosition;
63
- toast?: ToastPosition; // legacy
64
-
65
- /* -------- close -------- */
66
46
  closable?: boolean;
67
- closeable?: boolean; // legacy
47
+ glassUI?: boolean | number;
68
48
 
69
- /* -------- icon (modern) -------- */
70
49
  icon?: string;
71
50
  iconPack?: string;
72
51
  iconSize?: string;
73
- iconPosition?: IconPosition;
52
+ iconPosition?: "left" | "right" | "top";
74
53
  iconLink?: string;
75
54
  iconAnimate?: string;
76
55
 
77
- /* -------- icon (legacy) -------- */
78
- icon_left_top?: string;
79
- icon_config?: string;
80
- icon_onClick_url?: string;
81
- icon_onClick_animate?: string;
56
+ animation?: ToastAnimation;
82
57
 
83
- /* -------- actions -------- */
84
58
  actions?: ToastAction[];
59
+ };
85
60
 
86
- /* -------- escape hatch -------- */
87
- [key: string]: unknown;
88
- }
89
-
90
- /* ================= TYPE CONFIG ================= */
61
+ export type ToastDefaults = {
62
+ duration: number;
63
+ maxVisible: number;
64
+ swipeThreshold: number;
65
+ glassUI: number;
66
+ playSound: string | null;
67
+ };
91
68
 
92
- export interface ToastTypeConfig extends ToastPayload {}
69
+ export interface JuiceToast {
70
+ /* ================= PUBLIC API ================= */
93
71
 
94
- /* ================= CORE API ================= */
72
+ setup(cfg?: Record<string, ToastPayload>): void;
95
73
 
96
- export interface JuiceToastAPI {
97
- /**
98
- * Register toast types in bulk
99
- */
100
- setup<T extends Record<string, ToastTypeConfig>>(config?: T): void;
74
+ addType(name: string, cfg?: ToastPayload): void;
101
75
 
102
- /**
103
- * Add or override a single toast type
104
- */
105
- addType<T extends ToastTypeConfig>(
106
- name: string,
107
- config?: T
108
- ): void;
76
+ defineTheme(name: string, styles?: ToastTheme): void;
109
77
 
110
- /**
111
- * Theme system
112
- */
113
- defineTheme(name: string, styles: ToastTheme): void;
114
78
  setTheme(name: string): void;
115
79
 
116
- /**
117
- * Queue control
118
- */
119
80
  clear(): void;
81
+
120
82
  destroy(): void;
121
83
 
122
- /**
123
- * Dynamic toast methods
124
- * juiceToast.success(...)
125
- * juiceToast.error(...)
126
- * juiceToast.anything(...)
127
- */
128
- [type: string]:
129
- | ((payload?: string | number | ToastPayload) => void)
130
- | unknown;
131
- }
84
+ /* ================= INTERNAL ================= */
132
85
 
133
- /* ================= EXPORT ================= */
86
+ _config: Record<string, ToastPayload>;
87
+ _queue: Array<{ type: string; payload: any }>;
88
+ _showing: boolean;
89
+ _theme: string;
90
+ _defaults: ToastDefaults;
91
+
92
+ _registerTypes(): void;
93
+ _enqueue(type: string, payload: any): void;
94
+ _next(): void;
95
+ _normalizeGlass(value?: boolean | number): number;
96
+ _getRoot(position?: ToastPosition): HTMLElement | null;
97
+ _playSound(src?: string): void;
98
+ _showToast(type: string, payload: ToastPayload | string): void;
99
+
100
+ /* ================= DYNAMIC TOAST METHODS ================= */
101
+ [type: string]: ((payload?: ToastPayload | string) => void) | any;
102
+ }
134
103
 
135
- declare const juiceToast: JuiceToastAPI;
104
+ declare const juiceToast: JuiceToast;
136
105
 
137
106
  export default juiceToast;
138
107
  export { juiceToast };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 2026 (C) OpenDN Foundation
3
- * v1.1.0 Juice Toast
3
+ * v1.2.0-rc.2026 Juice Toast
4
4
  * ESM (ECMAScript Module (import/export))
5
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._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)},_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},_showToast(e,t){if(!isBrowser)return;let i=this._config[e]||{},o="object"==typeof t?t:{message:String(t)},s={...i,...o};s.icon=s.icon??s.icon_left_top,s.iconPack=s.iconPack??s.icon_config,s.iconLink=s.iconLink??s.icon_onClick_url,s.iconAnimate=s.iconAnimate??s.icon_onClick_animate,s.position=s.position??s.toast,s.closable=s.closable??s.closeable,s.iconPosition=s.iconPosition||"left",s.compact=!!s.compact;let n=themes[s.theme||this._theme]||{},a=document.createElement("div");if(a.className="juice-toast",s.size&&sizePreset[s.size]){let c=sizePreset[s.size];c.width&&(a.style.width=c.width),c.padding&&(a.style.padding=c.padding)}s.compact&&a.classList.add("jt-compact"),s.width&&(a.style.width=s.width),s.height&&(a.style.height=s.height),a.style.background=s.bg||n.bg,a.style.color=s.color||n.color,a.style.border=s.border||n.border;let l=null;s.icon&&((l=document.createElement("i")).className=["icon",s.iconPack||"",s.icon].join(" ").trim(),s.iconSize&&(l.style.fontSize=s.iconSize),(s.iconLink||s.iconAnimate)&&(l.classList.add("icon-clickable"),l.onclick=e=>{e.stopPropagation(),s.iconAnimate&&(l.classList.remove(s.iconAnimate),l.offsetWidth,l.classList.add(s.iconAnimate)),s.iconLink&&window.open(s.iconLink,"_blank","noopener")}));let d=document.createElement("div");if(d.className="jt-content",s.title){let h=document.createElement("div");h.className="jt-title",h.textContent=s.title,d.appendChild(h)}let r=document.createElement("div");if(r.className="jt-message",r.textContent=s.message||"",d.appendChild(r),l&&"top"===s.iconPosition?(a.classList.add("jt-icon-top"),a.appendChild(l),a.appendChild(d)):l&&"right"===s.iconPosition?(a.appendChild(d),a.appendChild(l)):(l&&a.appendChild(l),a.appendChild(d)),Array.isArray(s.actions)&&s.actions.length){let p=document.createElement("div");p.className="jt-actions",s.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())},p.appendChild(t)}),d.appendChild(p)}if(s.closable){let m=document.createElement("span");m.className="juice-toast-close",m.innerHTML="\xd7",m.onclick=()=>{a.remove(),this._next()},a.appendChild(m)}let g=this._getRoot(s.position);g.appendChild(a),requestAnimationFrame(()=>a.classList.add("show"));let u=s.duration??2500;0!==u&&setTimeout(()=>{a.classList.remove("show"),setTimeout(()=>{a.remove(),this._next()},300)},u)}};export default juiceToast;export{juiceToast};
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="bottom-right"){if(!isBrowser)return null;let t=document.getElementById(`juice-toast-root-${e}`);if(!t){switch((t=document.createElement("div")).id=`juice-toast-root-${e}`,t.dataset.position=e,t.dataset.theme=this._theme,t.style.position="fixed",t.style.zIndex=9999,e){case"top-left":t.style.top="20px",t.style.left="20px";break;case"top-right":t.style.top="20px",t.style.right="20px";break;case"bottom-left":t.style.bottom="20px",t.style.left="20px";break;case"bottom-right":t.style.bottom="20px",t.style.right="20px";break;case"top-center":t.style.top="20px",t.style.left="50%",t.style.transform="translateX(-50%)";break;case"bottom-center":t.style.bottom="20px",t.style.left="50%",t.style.transform="translateX(-50%)"}document.body.appendChild(t)}return 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 s=new Audio(t);s.volume=.6,s.play().catch(()=>{})}catch{}},_showToast(e,t){if(!isBrowser)return;let s=this._config[e]||{},i="object"==typeof t?t:{message:String(t)},o={...s,...i};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");a.className="juice-toast";let l=o.animation||"slide-in";if(a.style.animation=`${l} 0.4s ease forwards`,a.setAttribute("role","alert"),a.setAttribute("aria-live","polite"),a.tabIndex=0,o.size&&sizePreset[o.size]){let r=sizePreset[o.size];r.width&&(a.style.width=r.width),r.padding&&(a.style.padding=r.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 h=0,p=0;a.addEventListener("touchstart",e=>{h=e.touches[0].clientX}),a.addEventListener("touchmove",e=>{p=e.touches[0].clientX-h,a.style.transform=`translateX(${p}px)`}),a.addEventListener("touchend",()=>{Math.abs(p)>this._defaults.swipeThreshold?(a.style.transform=`translateX(${p>0?1e3:-1e3}px)`,setTimeout(()=>{a.remove(),this._next()},200)):a.style.transform="",h=p=0});let m=document.createElement("div");if(m.className="jt-content",o.title){let u=document.createElement("div");u.className="jt-title",u.textContent=o.title,m.appendChild(u)}let f=document.createElement("div");if(f.className="jt-message",f.textContent=o.message||"",m.appendChild(f),c&&"top"===o.iconPosition?(a.classList.add("jt-icon-top"),a.appendChild(c),a.appendChild(m)):c&&"right"===o.iconPosition?(a.appendChild(m),a.appendChild(c)):(c&&a.appendChild(c),a.appendChild(m)),Array.isArray(o.actions)&&o.actions.length){let g=document.createElement("div");g.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())},g.appendChild(t)}),m.appendChild(g)}if(o.closable){let $=document.createElement("span");$.className="juice-toast-close",$.innerHTML="\xd7",$.onclick=()=>{a.remove(),this._next()},a.appendChild($)}let y=this._getRoot(o.position),b=this._defaults.maxVisible;b&&y.children.length>=b&&y.firstChild.remove(),y.appendChild(a),requestAnimationFrame(()=>a.classList.add("show"));let x=o.duration??2500;if(0===x)return;let w=Date.now(),k=o.duration??this._defaults.duration,v,L=()=>{if(a.__paused)w=Date.now();else{let e=Date.now();k-=e-w,w=e}k<=0?(a.classList.remove("show"),setTimeout(()=>{a.remove(),this._next()},300)):v=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};
package/dist/style.css CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  2026 (C) OpenDN Foundation
3
- v1.1.0
3
+ v1.2.0-rc.2026
4
4
  @license MIT
5
5
  */
6
- #juice-toast-root{position:fixed;left:50%;bottom:20px;transform:translateX(-50%);z-index:9999;pointer-events:none;display:flex;flex-direction:column;align-items:center}#juice-toast-root[data-position=center]{top:50%;bottom:auto;transform:translate(-50%,-50%)}#juice-toast-root[data-position=top]{top:20px;bottom:auto;transform:translateX(-50%)}.juice-toast{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;color:#fff;font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial;font-size:14px;background:#333;opacity:0;transform:translateY(10px);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;transform:translateY(0)}.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}.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}.juice-toast .jt-message{font-weight:400;font-size:13px;line-height:1.2;opacity:.95}.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)}#juice-toast-root>.juice-toast{transform-origin:center}.icon[data-position=top]{align-self:center;margin-bottom:6px}.icon-clickable{opacity:.85}.icon-clickable:hover{opacity:1}@keyframes jt-spin{to{transform:rotate(360deg)}}@keyframes jt-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.2)}}@keyframes jt-shake{0%,100%{transform:translateX(0)}25%,75%{transform:translateX(-2px)}50%{transform:translateX(2px)}}.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}}.jt-compact{padding:8px 10px;gap:8px;font-size:.9em}.jt-icon-top{flex-direction:column;align-items:flex-start}.jt-icon-top .icon{margin-bottom:6px}.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}
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}}@keyframes slide-in{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes fade-in{from{opacity:0}to{opacity:1}}@keyframes bounce-in{0%{transform:scale(.5);opacity:0}60%{transform:scale(1.2);opacity:1}100%{transform:scale(1)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juice-toast",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Lightweight, dependency-free toast notification library",
5
5
  "keywords": [
6
6
  "toast",
@@ -23,26 +23,40 @@
23
23
  },
24
24
  "funding": "https://patreon.com/Khairy47",
25
25
  "engines": {
26
- "node": ">=14"
26
+ "node": ">=15"
27
27
  },
28
- "main": "dist/juice-toast.umd.js",
29
28
  "module": "dist/juice-toast.esm.js",
30
29
  "types": "dist/juice-toast.d.ts",
31
30
  "exports": {
32
31
  ".": {
33
- "require": "./dist/juice-toast.umd.js",
34
32
  "import": "./dist/juice-toast.esm.js",
35
33
  "types": "./dist/juice-toast.d.ts"
36
34
  }
37
35
  },
38
- "files": ["dist"],
36
+ "files": [
37
+ "dist",
38
+ "CHANGELOG.md",
39
+ "CODE_OF_CONDUCT.md",
40
+ "LICENSE",
41
+ "README.md",
42
+ "CONTRIBUTING.md",
43
+ "WARNER_NEXT_VERSION.md",
44
+ "EoL.md",
45
+ "NEW_FUNCTION.md"
46
+ ],
39
47
  "sideEffects": false,
40
48
  "publishConfig": {
41
49
  "access": "public"
42
50
  },
43
- "unpkg": "dist/juice-toast.umd.js",
44
- "jsdelivr": "dist/juice-toast.umd.js",
51
+ "unpkg": "dist/juice-toast.esm.js",
52
+ "jsdelivr": "dist/juice-toast.esm.js",
45
53
  "scripts": {
46
- "dev": "live-server"
54
+ "publish": "npm publish"
55
+ },
56
+ "devDependencies": {
57
+ "jest": "^30.2.0"
58
+ },
59
+ "dependencies": {
60
+ "debug": "^4.4.3"
47
61
  }
48
62
  }
@@ -1,6 +0,0 @@
1
- /**
2
- * 2026 (C) OpenDN Foundation
3
- * v1.1.0 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._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},_showToast(i,o){if(!e)return;let n=this._config[i]||{},s="object"==typeof o?o:{message:String(o)},a={...n,...s};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 c=t[a.theme||this._theme]||{},l=document.createElement("div");if(l.className="juice-toast",a.size&&sizePreset[a.size]){let d=sizePreset[a.size];d.width&&(l.style.width=d.width),d.padding&&(l.style.padding=d.padding)}a.width&&(l.style.width=a.width),a.height&&(l.style.height=a.height),l.style.background=a.bg||c.bg,l.style.color=a.color||c.color,l.style.border=a.border||c.border;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 r=document.createElement("div");if(r.className="jt-content",a.title){let p=document.createElement("div");p.className="jt-title",p.textContent=a.title,r.appendChild(p)}let m=document.createElement("div");if(m.className="jt-message",m.textContent=a.message||"",r.appendChild(m),h&&"top"===a.iconPosition?(l.classList.add("jt-icon-top"),l.appendChild(h),l.appendChild(r)):h&&"right"===a.iconPosition?(l.appendChild(r),l.appendChild(h)):(h&&l.appendChild(h),l.appendChild(r)),Array.isArray(a.actions)&&a.actions.length){let u=document.createElement("div");u.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&&(l.remove(),this._next())},u.appendChild(t)}),r.appendChild(u)}if(a.closable){let f=document.createElement("span");f.className="juice-toast-close",f.innerHTML="\xd7",f.onclick=()=>{l.remove(),this._next()},l.appendChild(f)}let g=this._getRoot(a.position);g.appendChild(l),requestAnimationFrame(()=>l.classList.add("show"));let y=a.duration??2500;0!==y&&setTimeout(()=>{l.classList.remove("show"),setTimeout(()=>{l.remove(),this._next()},300)},y)}}}()});