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 +20 -0
- package/CODE_OF_CONDUCT.md +87 -0
- package/CONTRIBUTING.md +65 -0
- package/LICENSE +21 -0
- package/README.md +247 -0
- package/dist/juice-toast.d.ts +170 -0
- package/dist/juice-toast.esm.js +6 -0
- package/dist/juice-toast.umd.js +6 -0
- package/dist/style.css +6 -0
- package/package.json +51 -0
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! 🚀
|
package/CONTRIBUTING.md
ADDED
|
@@ -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
|
+
}
|