universe-code 0.0.79 → 0.0.80

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.
@@ -1,69 +1,70 @@
1
1
  class UniverseToaster {
2
- constructor() {
3
- if (UniverseToaster.instance) return UniverseToaster.instance;
4
-
5
- this.container = null;
6
- this.toasts = [];
7
- this.config = {
8
- position: "top-right",
9
- duration: 4000,
10
- maxToasts: 5,
11
- };
12
- this.initialized = false;
13
-
14
- UniverseToaster.instance = this;
15
- }
16
-
17
- /* ---------------- INIT ---------------- */
18
- init() {
19
- if (this.initialized) return;
20
-
21
- this.container = document.createElement("div");
22
- this.container.id = "universe-toaster-container";
23
- this.container.className = `universe-toaster-container ${this.config.position}`;
24
- document.body.appendChild(this.container);
25
-
26
- this.injectStyles();
27
- this.initialized = true;
28
- }
29
-
30
- /* ---------------- CONFIG ---------------- */
31
- configure(options = {}) {
32
- this.config = { ...this.config, ...options };
33
- }
34
-
35
- /* ---------------- STYLES ---------------- */
36
- injectStyles() {
37
- if (document.getElementById("universe-toaster-styles")) return;
38
-
39
- const style = document.createElement("style");
40
- style.id = "universe-toaster-styles";
41
- style.textContent = `
42
- @keyframes progress {
2
+ constructor() {
3
+ if (UniverseToaster.instance) return UniverseToaster.instance;
4
+
5
+ this.container = null;
6
+ this.toasts = [];
7
+ this.config = {
8
+ position: "top-right",
9
+ duration: 4000,
10
+ maxToasts: 5,
11
+ };
12
+ this.initialized = false;
13
+
14
+ UniverseToaster.instance = this;
15
+ }
16
+
17
+ /* ================= INIT ================= */
18
+ init() {
19
+ if (this.initialized) return;
20
+
21
+ this.container = document.createElement("div");
22
+ this.container.id = "universe-toaster-container";
23
+ this.container.className = `universe-toaster-container ${this.config.position}`;
24
+ document.body.appendChild(this.container);
25
+
26
+ this.injectStyles();
27
+ this.initialized = true;
28
+ }
29
+
30
+ /* ================= CONFIG ================= */
31
+ configure(options = {}) {
32
+ this.config = { ...this.config, ...options };
33
+ }
34
+
35
+ /* ================= STYLES ================= */
36
+ injectStyles() {
37
+ if (document.getElementById("universe-toaster-styles")) return;
38
+
39
+ const style = document.createElement("style");
40
+ style.id = "universe-toaster-styles";
41
+ style.textContent = `
42
+ @keyframes universe-progress {
43
43
  from { width: 100%; }
44
44
  to { width: 0%; }
45
45
  }
46
46
 
47
47
  .universe-toaster-container {
48
48
  position: fixed;
49
- top: 20px;
50
- right: 20px;
51
- z-index: 9999;
52
- max-width: 380px;
49
+ top: -5px;
50
+ right: 5px;
51
+ min-width: 300px;
52
+ z-index: 2147483647;
53
+ max-width: 400px;
53
54
  font-family: Arial, sans-serif;
54
55
  }
55
56
 
56
57
  .universe-toast {
57
- background: #fff;
58
- margin: 12px 0;
59
- padding: 16px 18px;
58
+ margin: 15px 0;
59
+ background: white;
60
60
  border-radius: 12px;
61
- box-shadow: 0 10px 35px rgba(0,0,0,0.25);
62
- opacity: 0;
63
- transform: translateX(100%);
64
- transition: all 0.3s ease;
61
+ padding: 2px 20px 10px;
62
+ box-shadow: 0 10px 40px rgba(0,0,0,0.3);
65
63
  position: relative;
66
64
  overflow: hidden;
65
+ opacity: 0;
66
+ transform: translateX(100%);
67
+ transition: all 0.4s cubic-bezier(0.68,-0.55,0.265,1.55);
67
68
  }
68
69
 
69
70
  .universe-toast.show {
@@ -76,19 +77,20 @@ class UniverseToaster {
76
77
  transform: translateX(100%);
77
78
  }
78
79
 
79
- .universe-toast-success { border-left: 5px solid #28a745; }
80
- .universe-toast-error { border-left: 5px solid #dc3545; }
81
- .universe-toast-warning { border-left: 5px solid #ffc107; }
82
- .universe-toast-info { border-left: 5px solid #17a2b8; }
80
+ .universe-toast-success { border-left: 5px solid #28a745; color:#28a745; }
81
+ .universe-toast-error { border-left: 5px solid #dc3545; color:#dc3545; }
82
+ .universe-toast-warning { border-left: 5px solid #ffc107; color:#ffc107; }
83
+ .universe-toast-info { border-left: 5px solid #17a2b8; color:#17a2b8; }
83
84
 
84
85
  .universe-toast-header {
85
86
  display: flex;
86
87
  justify-content: space-between;
87
- margin-bottom: 6px;
88
+ align-items: center;
89
+ margin-bottom: 8px;
88
90
  }
89
91
 
90
92
  .universe-toast-title {
91
- font-weight: 600;
93
+ font-weight: bold;
92
94
  font-size: 14px;
93
95
  display: flex;
94
96
  align-items: center;
@@ -98,9 +100,10 @@ class UniverseToaster {
98
100
  margin-right: 8px;
99
101
  }
100
102
 
101
- .universe-toast-message {
103
+ .universe-toast-description {
102
104
  font-size: 13px;
103
105
  color: #333;
106
+ line-height: 1.4;
104
107
  }
105
108
 
106
109
  .universe-toast-close {
@@ -117,123 +120,100 @@ class UniverseToaster {
117
120
  left: 0;
118
121
  height: 3px;
119
122
  width: 100%;
120
- opacity: 0.4;
123
+ background: currentColor;
121
124
  }
122
-
123
- .universe-toast-success .universe-toast-progress { background: #28a745; }
124
- .universe-toast-error .universe-toast-progress { background: #dc3545; }
125
- .universe-toast-warning .universe-toast-progress { background: #ffc107; }
126
- .universe-toast-info .universe-toast-progress { background: #17a2b8; }
127
125
  `;
128
- document.head.appendChild(style);
129
- }
130
-
131
- /* ---------------- UTIL ---------------- */
132
- getIcon(type) {
133
- return { success: "✓", error: "✗", warning: "⚠", info: "ℹ" }[type] || "ℹ";
126
+ document.head.appendChild(style);
127
+ }
128
+
129
+ /* ================= INTERNAL ================= */
130
+ getIcon(status) {
131
+ return { success: "✓", error: "✗", warning: "⚠", info: "ℹ" }[status];
132
+ }
133
+
134
+ escape(text = "") {
135
+ const div = document.createElement("div");
136
+ div.textContent = text;
137
+ return div.innerHTML;
138
+ }
139
+
140
+ /* ================= CORE SHOW ================= */
141
+ showToast({ status = "info", title = "", description = "", duration }) {
142
+ if (!this.initialized) this.init();
143
+
144
+ if (this.toasts.length >= this.config.maxToasts) {
145
+ this.remove(this.toasts[0].id);
134
146
  }
135
147
 
136
- escape(text = "") {
137
- const div = document.createElement("div");
138
- div.textContent = text;
139
- return div.innerHTML;
140
- }
141
-
142
- /* ---------------- SHOW ---------------- */
143
- show(message, type = "info", options = {}) {
144
- if (!this.initialized) this.init();
145
-
146
- if (this.toasts.length >= this.config.maxToasts) {
147
- this.remove(this.toasts[0].id);
148
- }
148
+ const toastId = `toast-${Date.now()}`;
149
+ const finalDuration =
150
+ typeof duration === "number" ? duration : this.config.duration;
149
151
 
150
- const id = `toast-${Date.now()}`;
151
- const duration =
152
- typeof options.duration === "number"
153
- ? options.duration
154
- : this.config.duration;
152
+ const toast = document.createElement("div");
153
+ toast.className = `universe-toast universe-toast-${status}`;
154
+ toast.dataset.id = toastId;
155
155
 
156
- const toast = document.createElement("div");
157
- toast.className = `universe-toast universe-toast-${type}`;
158
- toast.dataset.id = id;
159
-
160
- toast.innerHTML = `
156
+ toast.innerHTML = `
161
157
  <div class="universe-toast-header">
162
158
  <div class="universe-toast-title">
163
- <span class="universe-toast-icon">${this.getIcon(type)}</span>
164
- ${this.escape(options.title || "")}
159
+ <span class="universe-toast-icon">${this.getIcon(status)}</span>
160
+ ${this.escape(title)}
165
161
  </div>
166
162
  <button class="universe-toast-close">&times;</button>
167
163
  </div>
168
- <div class="universe-toast-message">${this.escape(message)}</div>
169
- <div class="universe-toast-progress"></div>
164
+ <div class="universe-toast-description">${this.escape(description)}</div>
165
+ <div class="universe-toast-progress" style="animation:universe-progress ${finalDuration}ms linear forwards"></div>
170
166
  `;
171
167
 
172
- const progress = toast.querySelector(".universe-toast-progress");
173
- toast.querySelector(".universe-toast-close").onclick = () =>
174
- this.remove(id);
175
-
176
- if (duration > 0) {
177
- progress.style.animation = `progress ${duration}ms linear forwards`;
178
- } else {
179
- progress.style.display = "none";
180
- }
181
-
182
- this.container.appendChild(toast);
183
- this.toasts.push({ id, el: toast });
168
+ toast.querySelector(".universe-toast-close").onclick = () =>
169
+ this.remove(toastId);
184
170
 
185
- setTimeout(() => toast.classList.add("show"), 20);
171
+ this.container.appendChild(toast);
172
+ this.toasts.push({ id: toastId, element: toast });
186
173
 
187
- if (duration > 0) {
188
- setTimeout(() => this.remove(id), duration);
189
- }
190
- }
174
+ setTimeout(() => toast.classList.add("show"), 50);
175
+ setTimeout(() => this.remove(toastId), finalDuration);
176
+ }
191
177
 
192
- /* ---------------- REMOVE ---------------- */
193
- remove(id) {
194
- const toast = this.toasts.find(t => t.id === id);
195
- if (!toast) return;
178
+ /* ================= REMOVE ================= */
179
+ remove(id) {
180
+ const toast = this.toasts.find(t => t.id === id);
181
+ if (!toast) return;
196
182
 
197
- toast.el.classList.add("removing");
183
+ toast.element.classList.add("removing");
198
184
 
199
- setTimeout(() => {
200
- toast.el.remove();
201
- this.toasts = this.toasts.filter(t => t.id !== id);
202
- }, 300);
203
- }
185
+ setTimeout(() => {
186
+ toast.element.remove();
187
+ this.toasts = this.toasts.filter(t => t.id !== id);
188
+ }, 400);
189
+ }
204
190
 
205
- /* ---------------- HELPERS ---------------- */
206
- success(msg, o) { this.show(msg, "success", o); }
207
- error(msg, o) { this.show(msg, "error", o); }
208
- warning(msg, o) { this.show(msg, "warning", o); }
209
- info(msg, o) { this.show(msg, "info", o); }
191
+ /* ================= HELPERS ================= */
192
+ success(options) { this.showToast({ ...options, status: "success" }); }
193
+ error(options) { this.showToast({ ...options, status: "error" }); }
194
+ warning(options) { this.showToast({ ...options, status: "warning" }); }
195
+ info(options) { this.showToast({ ...options, status: "info" }); }
210
196
 
211
- clear() {
212
- this.toasts.forEach(t => t.el.remove());
213
- this.toasts = [];
214
- }
197
+ clear() {
198
+ this.toasts.forEach(t => t.element.remove());
199
+ this.toasts = [];
200
+ }
215
201
  }
216
202
 
217
- /* ================= CALLABLE WRAPPER ================= */
203
+ /* ================= PUBLIC API ================= */
218
204
 
219
- const instance = new UniverseToaster();
205
+ const toasterInstance = new UniverseToaster();
220
206
 
221
- /**
222
- * toaster("success", "Message", { title, duration })
223
- */
224
- function toaster(type, message, options = {}) {
225
- const allowed = ["success", "error", "warning", "info"];
226
- const finalType = allowed.includes(type) ? type : "info";
227
- instance.show(message, finalType, options);
207
+ function toaster(options) {
208
+ toasterInstance.showToast(options);
228
209
  }
229
210
 
230
- /* Attach helpers */
231
- toaster.success = (m, o) => instance.success(m, o);
232
- toaster.error = (m, o) => instance.error(m, o);
233
- toaster.warning = (m, o) => instance.warning(m, o);
234
- toaster.info = (m, o) => instance.info(m, o);
211
+ toaster.success = (options) => toasterInstance.success(options);
212
+ toaster.error = (options) => toasterInstance.error(options);
213
+ toaster.warning = (options) => toasterInstance.warning(options);
214
+ toaster.info = (options) => toasterInstance.info(options);
235
215
 
236
- toaster.configure = (o) => instance.configure(o);
237
- toaster.clear = () => instance.clear();
216
+ toaster.configure = (options) => toasterInstance.configure(options);
217
+ toaster.clear = () => toasterInstance.clear();
238
218
 
239
219
  export { UniverseToaster, toaster };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universe-code",
3
- "version": "0.0.79",
3
+ "version": "0.0.80",
4
4
  "description": "Universal utility functions for all JS frameworks",
5
5
  "license": "ISC",
6
6
  "type": "module",