@t007/toast 0.0.22 → 0.0.24

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/dist/index.js CHANGED
@@ -1,55 +1,60 @@
1
- // src/index.js
2
- import { isStr, isNum, isObj, isFunc, clamp, uid, bindAllMethods, createEl, loadResource } from "@t007/utils";
1
+ // src/js/index.js
2
+ import { isStr, isNum, isObj, isFunc, clamp, uid, bindAllMethods, isInteractive, createEl, loadResource, isDef } from "@t007/utils";
3
3
  var T007_Toast = class {
4
+ #constructed = false;
5
+ // to minimize updates
4
6
  #autoCloseInterval;
5
7
  #progressInterval;
6
8
  #timeVisible = 0;
7
9
  #isPaused = false;
8
10
  #shouldUnPause;
9
11
  queue = [];
10
- destroyed = true;
12
+ inactive = true;
11
13
  #visiblityChange = () => this.#shouldUnPause = document.visibilityState === "visible";
12
14
  constructor(options) {
13
15
  bindAllMethods(this);
14
- this.opts = { ...options };
15
- this.id = this.opts.id ??= uid(this.opts.idPrefix ?? "t007_toast_");
16
- t007.toasts.set(this.id, this);
17
- !isNum(this.opts.delay) ? this.init() : this.queue.push(setTimeout(this.init, this.opts.delay));
16
+ this.opts = options;
17
+ t007.toasts.set(this.opts.id ??= uid(this.opts.groupId ??= "t007_toast_"), this);
18
+ !isNum(this.opts.delay) ? this.activate() : this.queue.push(setTimeout(this.activate, this.opts.delay));
18
19
  this.update(this.opts);
19
20
  }
20
- init() {
21
- this.toastElement = createEl("div", { className: "t007-toast", id: this.id, ariaAtomic: "true" }, { idPrefix: this.opts.idPrefix });
21
+ activate() {
22
+ this.toastElement = createEl("div", { className: `t007-toast${this.scoped ? " t007-toast-scoped" : ""}`, id: this.opts.id, ariaAtomic: "true" }, { groupId: this.opts.groupId });
22
23
  requestAnimationFrame(() => this.toastElement.classList.add("t007-toast-show"));
23
- this.destroyed = false;
24
+ this.inactive = false;
24
25
  }
25
- update(options) {
26
- if (!options || !isObj(options)) return this.opts.id;
26
+ update(options, constructed = this.#constructed) {
27
+ if (!options || !isObj(options) || constructed && this.inactive) return this.opts.id;
27
28
  try {
28
29
  this.opts = { ...this.opts, ...options };
29
- const run = () => Object.keys(options).forEach((key) => this[key] = options[key]);
30
+ const run = () => (Object.keys(options).forEach((key) => this[key] = options[key]), this.#constructed = true, !constructed && (this.position = this.opts.position));
30
31
  !isNum(this.opts.delay) ? run() : this.queue.push(setTimeout(run, this.opts.delay));
31
32
  this.opts.delay = null;
32
33
  } catch (err) {
33
- console.error("toast update failed:", err);
34
+ console.error("t007 toast update failed:", err);
34
35
  }
35
36
  return this.opts.id;
36
37
  }
37
38
  play = () => setTimeout(() => this.#isPaused = false);
38
39
  pause = () => this.#isPaused = true;
40
+ get rootElement() {
41
+ return this.opts.rootElement ?? document.body;
42
+ }
39
43
  set rootElement(value) {
40
- const container = value?.querySelector(`.t007-toast-container[data-position="${this.opts.position}"]`);
41
- container?.style.setProperty("--t007-toast-container-position", value === document.body ? "fixed" : "absolute");
42
- container && !value.contains(container) && value.append(container);
44
+ if (this.#constructed) this.position = this.opts.position;
45
+ }
46
+ get scoped() {
47
+ return this.rootElement !== document.body;
43
48
  }
44
49
  set type(value) {
45
50
  this.toastElement.classList.remove("info", "success", "error", "warning");
46
51
  value && this.toastElement.classList.add(value);
47
52
  this.toastElement.role = value === "error" || value === "warning" ? "alert" : "status";
48
53
  this.toastElement.ariaLive = value === "error" || value === "warning" ? "assertive" : "polite";
49
- if (value) this.icon = this.opts.icon;
54
+ if (value && this.#constructed) this.icon = this.opts.icon;
50
55
  }
51
56
  set bodyHTML(value) {
52
- this.toastElement.querySelectorAll(".t007-toast > *:not(.t007-toast-cancel-button)").forEach((el) => el.remove());
57
+ for (const el of this.toastElement.querySelectorAll(":scope > *:not(.t007-toast-cancel-button)")) el.remove();
53
58
  this.toastElement.insertAdjacentHTML("afterbegin", `${value ? isFunc(value) ? value() : value : ""}`);
54
59
  }
55
60
  set render(value) {
@@ -75,12 +80,7 @@ var T007_Toast = class {
75
80
  const image = () => this.toastElement.querySelector(".t007-toast-image");
76
81
  if (value) {
77
82
  this._setUpBodyHTML();
78
- this.toastElement.querySelector(".t007-toast-image-wrapper").prepend(
79
- image() || createEl("img", {
80
- className: "t007-toast-image",
81
- alt: "toast-image"
82
- })
83
- );
83
+ this.toastElement.querySelector(".t007-toast-image-wrapper").prepend(image() || createEl("img", { className: "t007-toast-image", alt: "toast-image" }));
84
84
  const img = image();
85
85
  img.src = value;
86
86
  img.onload = img.onerror = () => img.dataset.loaded = img.complete && img.naturalWidth > 0;
@@ -94,7 +94,7 @@ var T007_Toast = class {
94
94
  const icon = () => this.toastElement.querySelector(".t007-toast-icon:not(.t007-toast-loader)");
95
95
  if (value) {
96
96
  this._setUpBodyHTML();
97
- this.toastElement.querySelector(".t007-toast-image-wrapper").appendChild(icon() || createEl("span", { className: "t007-toast-icon" }));
97
+ this.toastElement.querySelector(".t007-toast-image-wrapper").append(icon() || createEl("span", { className: "t007-toast-icon" }));
98
98
  const icn = icon();
99
99
  icn.innerHTML = icn.dataset.icon = this.icon;
100
100
  } else icon()?.remove();
@@ -103,49 +103,25 @@ var T007_Toast = class {
103
103
  const loader = () => this.toastElement.querySelector(".t007-toast-loader");
104
104
  if (value) {
105
105
  this._setUpBodyHTML();
106
- this.toastElement.querySelectorAll(".t007-toast-icon:not(.t007-toast-loader)").forEach((i) => i.remove());
107
- this.toastElement.querySelector(".t007-toast-image-wrapper").appendChild(
108
- loader() || createEl("span", {
109
- className: "t007-toast-icon t007-toast-loader"
110
- })
111
- );
106
+ for (const i of this.toastElement.querySelectorAll(".t007-toast-icon:not(.t007-toast-loader)")) i.remove();
107
+ this.toastElement.querySelector(".t007-toast-image-wrapper").append(loader() || createEl("span", { className: "t007-toast-icon t007-toast-loader" }));
112
108
  loader().innerHTML = isStr(value) ? value : t007.TOAST_ICONS.loading;
113
109
  } else {
114
110
  loader()?.remove();
115
- this.icon = this.opts.icon;
111
+ if (this.#constructed) this.icon = this.opts.icon;
116
112
  }
117
113
  }
118
114
  set closeButton(value) {
119
115
  const btn = this.toastElement.querySelector(".t007-toast-cancel-button");
120
- if (value)
121
- this.toastElement.appendChild(
122
- btn || createEl("button", {
123
- title: "Close",
124
- ariaLabel: "Close notification",
125
- className: "t007-toast-cancel-button",
126
- innerHTML: "×",
127
- onclick: this._remove
128
- })
129
- );
116
+ if (value) this.toastElement.append(btn || createEl("button", { title: "Close", ariaLabel: "Close notification", className: "t007-toast-cancel-button", innerHTML: "×", onclick: this.remove }));
130
117
  else btn?.remove();
131
118
  }
132
119
  get animation() {
120
+ const p = this.opts.position;
133
121
  if (this.opts.animation === true || this.opts.animation === "slide")
134
- switch (this.opts.position) {
135
- case "top-right":
136
- case "center-right":
137
- case "bottom-right":
138
- return "slide-left";
139
- case "top-center":
140
- case "center-center":
141
- case "bottom-center":
142
- return this.opts.position === "top-center" ? "slide-down" : "slide-up";
143
- case "top-left":
144
- case "center-left":
145
- case "bottom-left":
146
- default:
147
- return "slide-right";
148
- }
122
+ if (p === "top-right" || p === "center-right" || p === "bottom-right") return "slide-left";
123
+ else if (p === "top-center" || p === "center-center" || p === "bottom-center") return p === "top-center" ? "slide-down" : "slide-up";
124
+ else return "slide-right";
149
125
  return this.opts.animation;
150
126
  }
151
127
  set animation(value) {
@@ -157,6 +133,7 @@ var T007_Toast = class {
157
133
  set autoClose(value) {
158
134
  cancelAnimationFrame(this.#autoCloseInterval);
159
135
  this.#timeVisible = 0;
136
+ this.nprogress = void 0;
160
137
  let lastTime;
161
138
  const loop = (time) => {
162
139
  if (this.#shouldUnPause) {
@@ -170,7 +147,7 @@ var T007_Toast = class {
170
147
  if (!this.#isPaused) {
171
148
  this.#timeVisible += time - lastTime;
172
149
  this.onTimeUpdate?.(this.#timeVisible);
173
- if (isNum(this.autoClose) && this.#timeVisible >= this.autoClose) return this._remove("smooth", true);
150
+ if (isNum(this.autoClose) && this.#timeVisible >= this.autoClose) return this.remove("smooth", true);
174
151
  }
175
152
  lastTime = time;
176
153
  this.#autoCloseInterval = requestAnimationFrame(loop);
@@ -178,20 +155,21 @@ var T007_Toast = class {
178
155
  if (value) this.#autoCloseInterval = requestAnimationFrame(loop);
179
156
  }
180
157
  set position(value) {
181
- const currentContainer = this.toastElement.parentElement;
182
- const container = this.opts.rootElement?.querySelector(`.t007-toast-container[data-position="${value}"]`) || this._createContainer(value);
158
+ if (!this.#constructed) return;
159
+ const currContainer = this.toastElement.parentElement, container = this.rootElement.querySelector(`:scope > .t007-toast-container[data-position="${value}"]`) || this._createContainer(value);
183
160
  container[this.opts.newestOnTop ? "prepend" : "append"](this.toastElement);
184
- if (!(currentContainer == null || currentContainer.hasChildNodes())) currentContainer.remove();
161
+ this.toastElement.classList.toggle("t007-toast-scoped", this.scoped);
162
+ if (!(currContainer == null || currContainer.hasChildNodes())) currContainer.remove();
185
163
  }
186
164
  set closeOnClick(value) {
187
- this.toastElement.onclick = value ? () => this._remove() : null;
165
+ this.toastElement.onclick = value ? () => this.remove() : null;
188
166
  }
189
167
  set hideProgressBar(value) {
190
168
  this.toastElement.classList.toggle("progress", !value);
191
- this.nprogress = 0;
169
+ this.nprogress = void 0;
192
170
  cancelAnimationFrame(this.#progressInterval);
193
171
  const loop = () => {
194
- if (isNum(this.autoClose) && !this.#isPaused) this.nprogress = 1 - this.#timeVisible / this.autoClose;
172
+ if (isNum(this.autoClose) && !this.#isPaused) this.nprogress = void 0;
195
173
  this.#progressInterval = requestAnimationFrame(loop);
196
174
  };
197
175
  if (!value) this.#progressInterval = requestAnimationFrame(loop);
@@ -199,7 +177,7 @@ var T007_Toast = class {
199
177
  get nprogress() {
200
178
  return Number(this.toastElement.style.getProperty("--progress"));
201
179
  }
202
- set nprogress(value) {
180
+ set nprogress(value = 1 - this.#timeVisible / this.autoClose) {
203
181
  this.toastElement.style.setProperty("--progress", value);
204
182
  }
205
183
  set pauseOnHover(value) {
@@ -214,7 +192,9 @@ var T007_Toast = class {
214
192
  this.toastElement.dataset.tag = value;
215
193
  }
216
194
  set renotify(value) {
217
- value && this.opts.tag && t007.toasts.entries().forEach(([id, toast2]) => id !== this.id && (toast2.opts.tag ?? 1) === (this.opts.tag ?? 0) && toast2._remove("instant"));
195
+ if (value && this.opts.tag) {
196
+ for (const toast2 of t007.toasts.values()) if (toast2.opts.tag === this.opts.tag && toast2.opts.id !== this.opts.id) toast2.remove("instant");
197
+ }
218
198
  }
219
199
  get vibrate() {
220
200
  return this.opts.vibrate === true ? t007.TOAST_VIBRATIONS[this.opts.type] || t007.TOAST_VIBRATIONS.info : this.opts.vibrate;
@@ -222,12 +202,10 @@ var T007_Toast = class {
222
202
  set vibrate(value) {
223
203
  value && navigator?.vibrate?.(this.vibrate);
224
204
  }
225
- set maxToasts(value) {
205
+ set limit(value) {
226
206
  const toastsInContainer = [...this.toastElement?.parentElement?.children || []];
227
207
  if (!toastsInContainer.length) return;
228
- for (let i = 0; i < toastsInContainer.length - value; i++) {
229
- [...t007.toasts.values()].find((t) => t.toastElement === (this.opts.newestOnTop ? toastsInContainer[toastsInContainer.length - 1 - i] : toastsInContainer[i]))?._remove("instant");
230
- }
208
+ for (let i = 0; i < toastsInContainer.length - value; i++) [...t007.toasts.values()].find((t) => t.toastElement === (this.opts.newestOnTop ? toastsInContainer[toastsInContainer.length - 1 - i] : toastsInContainer[i]))?.remove("instant");
231
209
  }
232
210
  set newestOnTop(value) {
233
211
  this.toastElement?.parentElement?.[value ? "prepend" : "append"](this.toastElement);
@@ -240,7 +218,7 @@ var T007_Toast = class {
240
218
  _handleToastPointerStart(e) {
241
219
  if (isStr(this._ptrType) && e.pointerType !== this._ptrType) return;
242
220
  if (e.touches?.length > 1) return;
243
- !e.target?.matches('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])') && this.toastElement.setPointerCapture(e.pointerId);
221
+ !isInteractive(e.target) && this.toastElement.setPointerCapture(e.pointerId);
244
222
  this.#isPaused = true;
245
223
  this._ptrTicker = this._ptrDirSet = this._ptrDir = false;
246
224
  this._ptrStartX = e.clientX ?? e.targetTouches[0]?.clientX;
@@ -268,34 +246,28 @@ var T007_Toast = class {
268
246
  _handleToastPointerUp(e) {
269
247
  if (isStr(this._ptrType) && e.pointerType !== this._ptrType) return;
270
248
  cancelAnimationFrame(this._ptrRAF);
271
- if (Math.abs(this._ptrDeltaX) > this.toastElement.offsetWidth * (this.opts.dragToClosePercent.x ?? this.opts.dragToClosePercent / 100) || Math.abs(this._ptrDeltaY) > this.toastElement.offsetHeight * (this.opts.dragToClosePercent.y ?? this.opts.dragToClosePercent / 100)) return this._remove("instant");
249
+ if (Math.abs(this._ptrDeltaX) > this.toastElement.offsetWidth * ((this.opts.dragToClosePercent.x ?? this.opts.dragToClosePercent) / 100) || Math.abs(this._ptrDeltaY) > this.toastElement.offsetHeight * ((this.opts.dragToClosePercent.y ?? this.opts.dragToClosePercent) / 100)) return this.remove("instant");
272
250
  this.#isPaused = this._ptrTicker = this._ptrDirSet = this._ptrDir = false;
273
251
  this.toastElement.removeEventListener("pointermove", this._handleToastPointerMove, { passive: false });
274
- this.toastElement.style.removeProperty("transition");
275
- this.toastElement.style.removeProperty("transform");
276
- this.toastElement.style.removeProperty("opacity");
252
+ for (const prop of ["transition", "transform", "opacity"]) this.toastElement.style.removeProperty(prop);
277
253
  }
278
- _remove(manner = "smooth", timeElapsed = false) {
279
- if (!this.opts.isLoading) t007.toasts.delete(this.id);
280
- this.queue.forEach(clearTimeout);
254
+ remove(manner = "smooth", timeElapsed = false) {
255
+ if (!this.opts.isLoading) t007.toasts.delete(this.opts.id);
256
+ for (const tid of this.queue) clearTimeout(tid);
281
257
  document.removeEventListener("visibilitychange", this.#visiblityChange);
282
- cancelAnimationFrame(this.#autoCloseInterval);
283
- cancelAnimationFrame(this.#progressInterval);
284
- if (this.destroyed || manner === "instant" || !this.animation) this._cleanUpToast();
258
+ cancelAnimationFrame(this.#autoCloseInterval), cancelAnimationFrame(this.#progressInterval);
259
+ if (this.inactive || manner === "instant" || !this.animation) this._cleanUpToast();
285
260
  else this.toastElement.onanimationend = this._cleanUpToast;
286
261
  this.toastElement.classList.remove("t007-toast-show");
287
262
  this.onClose?.(timeElapsed);
288
263
  }
289
264
  _createContainer(position) {
290
- const container = document.createElement("div");
291
- container.classList.add("t007-toast-container");
292
- container.style.setProperty("--t007-toast-container-position", this.opts.rootElement === document.body ? "fixed" : "absolute");
293
- container.dataset.position = position;
294
- this.opts.rootElement?.append(container);
295
- return container;
265
+ const container = createEl("div", { className: "t007-toast-container" }, { position });
266
+ container.style.setProperty("--t007-toast-container-position", !this.scoped ? "fixed" : "absolute");
267
+ return this.rootElement.appendChild(container);
296
268
  }
297
269
  _setUpBodyHTML() {
298
- this.toastElement.querySelectorAll(".t007-toast > *:not(.t007-toast-image-wrapper, .t007-toast-body, .t007-toast-actions-wrapper, .t007-toast-cancel-button)").forEach((el) => el.remove());
270
+ this.#constructed && this.toastElement.querySelectorAll(":scope > *:not(.t007-toast-image-wrapper, .t007-toast-body, .t007-toast-actions-wrapper, .t007-toast-cancel-button)").forEach((el) => el.remove());
299
271
  const imageWrapper = () => this.toastElement.querySelector(".t007-toast-image-wrapper");
300
272
  if (!imageWrapper()) this.toastElement.prepend(createEl("div", { className: "t007-toast-image-wrapper" }));
301
273
  if (!this.toastElement.querySelector(".t007-toast-body")) imageWrapper().insertAdjacentElement("afterend", createEl("div", { className: "t007-toast-body" }));
@@ -304,46 +276,42 @@ var T007_Toast = class {
304
276
  const container = this.toastElement.parentElement;
305
277
  this.toastElement.remove();
306
278
  if (!container?.hasChildNodes()) container?.remove();
307
- this.destroyed = true;
279
+ this.inactive = true;
308
280
  }
309
281
  };
310
282
  var toasting = {
311
- update(base, id, options) {
283
+ isActive(_, id) {
312
284
  const toast2 = t007.toasts.get(id);
313
- toast2?.queue.forEach(clearTimeout);
314
- return !!toast2 && (toast2.destroyed ? base(options.render, { ...toast2.opts, id, ...options }) : toast2.update(options));
285
+ return !!toast2 && !toast2.inactive;
286
+ },
287
+ update(base, id, options, _toast) {
288
+ const toast2 = _toast ?? t007.toasts.get(id);
289
+ if (toast2?.queue) for (const tid of toast2.queue) clearTimeout(tid);
290
+ return toast2 && (toast2.inactive ? base(options.render, { ...toast2.opts, id, ...options }) : toast2.update(options));
315
291
  },
316
- message: (base, defaults, action) => base[action] = (renderOrId, options = {}) => {
292
+ message: (base, getDefaults, action, renderOrId, options = {}) => {
317
293
  options = { ...options, type: action === "warn" ? "warning" : action };
318
- if (!t007.toasts.get(renderOrId)) return base(renderOrId, options);
319
- const { autoClose, closeButton, closeOnClick, dragToClose } = defaults();
320
- return base.update(renderOrId, {
321
- ...t007.toasts.get(renderOrId)?.opts.isLoading ? { autoClose, closeButton, closeOnClick, dragToClose } : {},
322
- ...options,
323
- isLoading: false
324
- });
294
+ const id = options.id ?? renderOrId, toast2 = t007.toasts.get(id);
295
+ if (!toast2) return base(renderOrId, options);
296
+ const { autoClose, closeButton, closeOnClick, dragToClose } = getDefaults();
297
+ return base.update(id, { ...toast2.opts.isLoading ? { closeButton, closeOnClick, dragToClose } : null, ...options.id ? { render: renderOrId } : null, autoClose, ...options, isLoading: false }, toast2);
298
+ },
299
+ loading: (base, renderOrId, options = {}) => {
300
+ const id = options.id ?? renderOrId, toast2 = t007.toasts.get(id);
301
+ return (toast2 ? base.update : base)(id, { closeButton: false, closeOnClick: false, dragToClose: false, ...options.id ? { render: renderOrId } : null, autoClose: false, ...options, isLoading: options.isLoading || true, type: "" }, toast2 || void 0);
325
302
  },
326
- loading: (base, renderOrId, options = {}) => (t007.toasts.get(renderOrId) ? base.update : base)(renderOrId, {
327
- autoClose: false,
328
- closeButton: false,
329
- closeOnClick: false,
330
- dragToClose: false,
331
- ...options,
332
- isLoading: options.isLoading || true,
333
- type: ""
334
- }),
335
303
  promise(base, promise = new Promise((res, rej) => setTimeout(Math.round(Math.random()) ? res : rej, 3e3)), { pending, success, error } = {}) {
336
304
  if (!promise || !isFunc(promise.then)) return console.error("toast.promise() requires a valid promise");
337
305
  const NFC = (input, type) => isStr(input) ? { render: input, type } : isObj(input) ? { ...input, type } : { type };
338
- const pendingConfig = NFC(pending);
339
- const pendingToastId = base.loading(pendingConfig.render || "Promise pending...", { ...pendingConfig });
306
+ const pendingCfg = NFC(pending);
307
+ const pendingId = base.loading(pendingCfg.render || "Promise pending...", { ...pendingCfg });
340
308
  promise.then(
341
309
  (response) => {
342
310
  const successConfig = NFC(success || "Promise resolved", "success");
343
311
  const { render, bodyHTML } = successConfig;
344
312
  if (isFunc(render)) successConfig.render = (response2) => render(response2);
345
313
  if (isFunc(bodyHTML)) successConfig.bodyHTML = (response2) => bodyHTML(response2);
346
- base.success(pendingToastId, successConfig);
314
+ base.success(pendingId, successConfig);
347
315
  return response;
348
316
  },
349
317
  (err) => {
@@ -351,41 +319,36 @@ var toasting = {
351
319
  const { render, bodyHTML } = errorConfig;
352
320
  if (isFunc(render)) errorConfig.render = (err2) => render(err2);
353
321
  if (isFunc(bodyHTML)) errorConfig.bodyHTML = (err2) => bodyHTML(err2);
354
- base.error(pendingToastId, errorConfig);
322
+ base.error(pendingId, errorConfig);
355
323
  return Promise.reject(err);
356
324
  }
357
325
  );
358
326
  return promise;
359
327
  },
360
328
  dismiss(base, id, manner, timeElapsed) {
361
- return !arguments.length ? base.dismissAll() : t007.toasts.get(id)?._remove(manner, timeElapsed);
329
+ return !isDef(id) ? base.dismissAll() : t007.toasts.get(id)?.remove(manner, timeElapsed);
362
330
  },
363
- dismissAll(base, idPrefix) {
364
- t007.toasts.values().forEach((toast2) => (!arguments.length ? true : toast2.id.startsWith(idPrefix)) && toast2._remove());
331
+ dismissAll(base, groupId) {
332
+ for (const toast2 of t007.toasts.values()) (!isDef(groupId) ? true : toast2.opts.groupId === groupId) && toast2.remove();
365
333
  },
366
- doForAll(base, action, options, idPrefix) {
367
- t007.toasts.keys().forEach((id) => (!arguments.length ? true : id.startsWith(idPrefix)) && base[action]?.(id, options));
334
+ doForAll(base, action, options, groupId) {
335
+ for (const toast2 of t007.toasts.values()) (!isDef(groupId) ? true : toast2.opts.groupId === groupId) && base[action]?.(toast2.opts.id, options);
368
336
  },
369
- getAll(base, idPrefix) {
370
- return t007.toasts.values().filter((toast2) => !arguments.length ? true : toast2.id.startsWith(idPrefix));
337
+ getAll(base, groupId) {
338
+ return t007.toasts.values().filter((toast2) => !isDef(groupId) ? true : toast2.opts.groupId === groupId);
371
339
  }
372
340
  };
373
- var toaster = (defOptions = {}, idPrefix = "t007_toast_") => {
374
- const defaults = () => ({ ...t007.TOAST_DEFAULT_OPTIONS, ...defOptions }), base = (render, options = {}) => new T007_Toast({
375
- ...defaults(),
376
- ...options,
377
- id: render?.startsWith?.(idPrefix) ? render : options.id,
378
- render: render?.startsWith?.(idPrefix) ? options.render : render,
379
- idPrefix
380
- }).id;
381
- base.update = (id, options) => toasting.update(base, id, options);
382
- ["info", "success", "warn", "error"].forEach((action) => toasting.message(base, defaults, action));
383
- base.loading = (render, options) => toasting.loading(base, render, options);
384
- base.promise = (promise, options) => toasting.promise(base, promise, options);
341
+ var toaster = (defOptions = {}, groupId = "t007_toast_") => {
342
+ const getDefaults = () => ({ ...t007.TOAST_DEFAULT_OPTIONS, ...defOptions }), base = (render, options = {}, mayBeId = render?.startsWith?.(groupId)) => new T007_Toast({ ...getDefaults(), ...options, id: mayBeId ? render : options.id, render: mayBeId ? options.render : render, groupId }).opts.id;
343
+ base.isActive = (id) => toasting.isActive(base, id);
344
+ base.update = (id, options, _toast) => toasting.update(base, id, options, _toast);
345
+ for (const action of ["info", "success", "warn", "error"]) base[action] = (renderOrId, options) => toasting.message(base, getDefaults, action, renderOrId, options);
346
+ base.loading = (renderOrId, options) => toasting.loading(base, renderOrId, options);
347
+ base.promise = (promise, config) => toasting.promise(base, promise, config);
385
348
  base.dismiss = (id, manner, timeElapsed) => toasting.dismiss(base, id, manner, timeElapsed);
386
- base.dismissAll = (idPrefix2) => toasting.dismissAll(base, idPrefix2);
387
- base.doForAll = (action, options, idPrefix2) => toasting.doForAll(base, action, options, idPrefix2);
388
- base.getAll = (idPrefix2) => toasting.getAll(base, idPrefix2);
349
+ base.dismissAll = (groupId2) => toasting.dismissAll(base, groupId2);
350
+ base.doForAll = (action, options, groupId2) => toasting.doForAll(base, action, options, groupId2);
351
+ base.getAll = (groupId2) => toasting.getAll(base, groupId2);
389
352
  return base;
390
353
  };
391
354
  var toast = toaster();
@@ -395,11 +358,7 @@ if ("undefined" !== typeof window) {
395
358
  t007.toasting = toasting;
396
359
  t007.toaster = toaster;
397
360
  t007.toasts = /* @__PURE__ */ new Map();
398
- t007.TOAST_DEFAULT_OPTIONS ??= {};
399
- t007.TOAST_DURATIONS ??= {};
400
- t007.TOAST_VIBRATIONS ??= {};
401
- t007.TOAST_ICONS ??= {};
402
- t007.TOAST_DEFAULT_OPTIONS.rootElement ??= document.body;
361
+ t007.TOAST_DEFAULT_OPTIONS ??= {}, t007.TOAST_DURATIONS ??= {}, t007.TOAST_VIBRATIONS ??= {}, t007.TOAST_ICONS ??= {};
403
362
  t007.TOAST_DEFAULT_OPTIONS.render ??= "";
404
363
  t007.TOAST_DEFAULT_OPTIONS.type ??= "";
405
364
  t007.TOAST_DEFAULT_OPTIONS.icon ??= true;
@@ -419,22 +378,16 @@ if ("undefined" !== typeof window) {
419
378
  t007.TOAST_DEFAULT_OPTIONS.vibrate ??= false;
420
379
  t007.TOAST_DEFAULT_OPTIONS.animation ??= true;
421
380
  t007.TOAST_DEFAULT_OPTIONS.newestOnTop ??= false;
422
- t007.TOAST_DEFAULT_OPTIONS.maxToasts ??= 1e3;
423
- t007.TOAST_DURATIONS.success ??= 2500;
424
- t007.TOAST_DURATIONS.error ??= 4500;
425
- t007.TOAST_DURATIONS.warning ??= 3500;
426
- t007.TOAST_DURATIONS.info ??= 4e3;
427
- t007.TOAST_VIBRATIONS.success ??= [100, 50, 100];
428
- t007.TOAST_VIBRATIONS.warning ??= [300, 100, 300];
429
- t007.TOAST_VIBRATIONS.error ??= [500, 200, 500];
430
- t007.TOAST_VIBRATIONS.info ??= [200];
381
+ t007.TOAST_DEFAULT_OPTIONS.limit ??= 100;
382
+ t007.TOAST_DURATIONS.success ??= 2500, t007.TOAST_DURATIONS.error ??= 4500, t007.TOAST_DURATIONS.warning ??= 3500, t007.TOAST_DURATIONS.info ??= 4e3;
383
+ t007.TOAST_VIBRATIONS.success ??= [100, 50, 100], t007.TOAST_VIBRATIONS.warning ??= [300, 100, 300], t007.TOAST_VIBRATIONS.error ??= [500, 200, 500], t007.TOAST_VIBRATIONS.info ??= [200];
431
384
  t007.TOAST_ICONS.success ??= `<svg class="no-css-fill" width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="#27ae60"/><path fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M7 12l3 3l6-6"/></svg>`;
432
385
  t007.TOAST_ICONS.error ??= `<svg class="no-css-fill" width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="#e74c3c"/><path fill="#fff" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M8 8l8 8M16 8l-8 8"/></svg>`;
433
386
  t007.TOAST_ICONS.warning ??= `<svg class="no-css-fill" width="24" height="24" viewBox="0 0 24 24"><path fill="#f1c40f" stroke="#f39c12" stroke-width="2" stroke-linejoin="round" d="M12 3L2.5 20.5A2 2 0 0 0 4.5 23h15a2 2 0 0 0 2-2.5L12 3z"/><circle cx="12" cy="17" r="1.5" fill="#fff"/><path fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M12 8v6"/></svg>`;
434
387
  t007.TOAST_ICONS.info ??= `<svg class="no-css-fill" width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="#3498db"/><path fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M12 10v6"/><circle cx="12" cy="7" r="1.5" fill="#fff"/></svg>`;
435
388
  t007.TOAST_ICONS.loading ??= `<svg class="no-css-fill" width="24" height="24" viewBox="0 0 16 16" fill="none" style="scale:0.75;"><g fill-rule="evenodd" clip-rule="evenodd"><path fill="whitesmoke" d="M8 1.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8"/><path fill="gray" d="M7.25.75A.75.75 0 0 1 8 0a8 8 0 0 1 8 8 .75.75 0 0 1-1.5 0A6.5 6.5 0 0 0 8 1.5a.75.75 0 0 1-.75-.75"/></g><animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="360" dur="600ms" repeatCount="indefinite"/></svg>`;
436
389
  loadResource(T007_TOAST_CSS_SRC);
437
- window.Toast ??= t007.toast;
390
+ window.toast ??= t007.toast;
438
391
  console.log("%cT007 Toasts attached to window!", "color: darkturquoise");
439
392
  }
440
393
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t007/toast",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "description": "A lightweight, pure JS toast system.",
5
5
  "author": "Oketade Oluwatobiloba <tobioketade007@gmail.com>",
6
6
  "license": "MIT",
@@ -46,6 +46,7 @@
46
46
  "ecosystem",
47
47
  "ui",
48
48
  "vanilla-js",
49
+ "react",
49
50
  "toast",
50
51
  "snackbar",
51
52
  "notification",
@@ -53,6 +54,6 @@
53
54
  "promise"
54
55
  ],
55
56
  "dependencies": {
56
- "@t007/utils": "^0.0.24"
57
+ "@t007/utils": "^0.0.26"
57
58
  }
58
59
  }