@t007/toast 0.0.38 → 0.0.39

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.css CHANGED
@@ -280,6 +280,14 @@
280
280
  animation-duration: var(--t007-toast-animation-duration);
281
281
  touch-action: none;
282
282
  }
283
+ .t007-toast.t007-toast-compact {
284
+ min-width: unset;
285
+ width: fit-content;
286
+ max-width: var(--t007-toast-width);
287
+ height: fit-content;
288
+ min-height: unset;
289
+ max-height: var(--t007-toast-height);
290
+ }
283
291
  .t007-toast:not(:has(.t007-toast-image, .t007-toast-icon:not(:empty))):has(.t007-toast-body) {
284
292
  padding-left: max(var(--t007-toast-padding), var(--t007-toast-smart-padding-left));
285
293
  }
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ type ToastType = undefined | "info" | "success" | "error" | "warning";
3
3
  /** Screen anchor for toast placement. */
4
4
  type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right" | "center-left" | "center-center" | "center-right";
5
5
  /** Motion preset used when a toast enters or leaves the screen. */
6
- type ToastAnimation = "fade" | "zoom" | "slide" | "slide-left" | "slide-right" | "slide-up" | "slide-down" | boolean;
6
+ type ToastAnimation = "fade" | "zoom" | "slide" | "slide-left" | "slide-right" | "slide-up" | "slide-down" | false;
7
7
  /** Allowed pointer types for drag-to-dismiss gestures. */
8
8
  type ToastDragOption = boolean | "mouse" | "touch" | "pen";
9
9
  /** Allowed drag directions for dismiss gestures. `|` combines axes where it can be `a` or `b` and can change anytime while `||` does not change after a pick is determined. */
@@ -68,11 +68,13 @@ interface ToastOptions {
68
68
  /** Action buttons rendered under the message body. */
69
69
  actions?: Record<string, (e: MouseEvent, toast: ToastInstance) => void> | false;
70
70
  /** Callback fired when the toast closes. */
71
- onClose?: (timeElapsed?: boolean | false) => void;
71
+ onClose?: (timeElapsed?: boolean | false, userInitiated?: boolean) => void;
72
72
  /** Callback fired as the toast auto-close timer advances. */
73
73
  onTimeUpdate?: (timeVisible: number) => void;
74
74
  /** Abort signal to control the toast's lifecycle and timeout aborts. */
75
75
  signal?: AbortSignal;
76
+ /** When true, the toast will be displayed in a more compact form. */
77
+ compact?: boolean;
76
78
  // [key: string]: any; // To allow arbitrary overrides internally if needed
77
79
  }
78
80
 
@@ -128,6 +130,8 @@ interface ToastPromiseConfig<T = any> {
128
130
 
129
131
  /** Public toast API exposed to consumers. */
130
132
  interface Toast {
133
+ /** Default options merged into every toast, update as needed. */
134
+ defaults: ToastOptions;
131
135
  /** Create a default toast.
132
136
  * @param render Body text for the toast.
133
137
  * @param options Toast configuration.
@@ -187,6 +191,11 @@ interface Toast {
187
191
  * @param timeElapsed Whether the auto-close timer already elapsed.
188
192
  */
189
193
  dismiss(id?: string, manner?: "smooth" | "instant", timeElapsed?: boolean): void;
194
+ /** Check if any toasts that share a group id are currently active.
195
+ * @param groupId Optional group id filter.
196
+ * @returns True if any toasts are active, false otherwise.
197
+ */
198
+ anyActive(groupId?: string): boolean;
190
199
  /** Dismiss every toast that matches an optional group id or the whole stack.
191
200
  * @param groupId Optional group id filter.
192
201
  */
@@ -222,11 +231,11 @@ interface Toasting {
222
231
  /** Internal helper methods used by the toast factory. */
223
232
  declare const toasting: Toasting;
224
233
  /** Create a toast factory with custom defaults and a group id.
225
- * @param defOptions Default options merged into every toast.
234
+ * @param defaults Default options merged into every toast.
226
235
  * @param groupId Prefix applied to generated ids.
227
236
  * @returns Toast factory.
228
237
  */
229
- declare function toaster(defOptions?: ToastOptions, groupId?: string): Toast;
238
+ declare function toaster(defaults?: ToastOptions, groupId?: string): Toast;
230
239
  /** Default toast factory instance attached by the bundle. */
231
240
  declare const toast: Toast;
232
241
 
@@ -13,7 +13,7 @@
13
13
  return sig.addEventListener("abort", kill, { once: true }), id;
14
14
  }
15
15
 
16
- // ../../../sia-reactor/dist/chunk-PJTPFVEG.js
16
+ // ../../../sia-reactor/dist/chunk-4SGW3Y6X.js
17
17
  function onAllMethods(owner, callback, skipOwn = true, nested = false) {
18
18
  let proto = owner;
19
19
  while (proto && proto !== Object.prototype) {
@@ -53,7 +53,7 @@
53
53
  return el;
54
54
  }
55
55
 
56
- // ../../../sia-reactor/dist/chunk-LZJYX2LE.js
56
+ // ../../../sia-reactor/dist/chunk-GH5QAGIC.js
57
57
  var RTR_BATCH = "undefined" !== typeof window ? ("undefined" !== typeof queueMicrotask ? queueMicrotask : setTimeout).bind(window) : "undefined" !== typeof process && process.nextTick ? process.nextTick : setTimeout;
58
58
  var RTR_LOG = console.log.bind(console, "[S.I.A Reactor]");
59
59
  var NIL = Object.freeze({});
@@ -88,7 +88,7 @@
88
88
  return "object" === typeof obj && obj !== null && (arraycheck ? !Array.isArray(obj) : true);
89
89
  }
90
90
 
91
- // ../utils/dist/chunk-ZFW6HNGO.js
91
+ // ../utils/dist/chunk-RCSOMCIC.js
92
92
  var INTERACTIVE_SELECTOR = ":is(button,[href],input:not([type='hidden']),select,textarea,details>summary,[contenteditable],iframe,audio[controls],video[controls],[tabindex]):not([disabled],[tabindex='-1'],[data-focus-guard],[inert],[inert] *)";
93
93
  var VIRTUAL_RESOURCE = /* @__PURE__ */ Symbol.for("T007_VIRTUAL_RESOURCE");
94
94
  function loadResource(req, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, win = window) {
@@ -104,7 +104,7 @@
104
104
  el?.remove?.();
105
105
  if (remaining > 1) {
106
106
  setTimeout(tryLoad, 1e3, remaining - 1);
107
- console.warn(`Retrying ${type} load for "${src}" (${attempts - remaining + 1})...`);
107
+ console.warn(`Retrying ${type} load for "${src}" (${attempts - remaining + 1}/${attempts})...`);
108
108
  } else {
109
109
  delete win.t007._resourceCache[src];
110
110
  reject(new Error(`${capitalize(type)} load failed for "${src}"`));
@@ -172,7 +172,6 @@
172
172
  #constructed = false;
173
173
  // to minimize updates
174
174
  #autoCloseInterval;
175
- #progressInterval;
176
175
  #timeVisible = 0;
177
176
  #isPaused = false;
178
177
  #shouldUnPause;
@@ -282,7 +281,7 @@
282
281
  }
283
282
  set closeButton(value) {
284
283
  const btn = this.toastElement.querySelector(".t007-toast-cancel-button");
285
- if (value) this.toastElement.append(btn || createEl("button", { title: "Close", ariaLabel: "Close notification", className: "t007-toast-cancel-button", innerHTML: "&times;", onclick: this.remove }));
284
+ if (value) this.toastElement.append(btn || createEl("button", { title: "Close", ariaLabel: "Close notification", className: "t007-toast-cancel-button", innerHTML: "&times;", onclick: () => this.remove(void 0, false, true) }));
286
285
  else btn?.remove();
287
286
  }
288
287
  get animation() {
@@ -302,6 +301,7 @@
302
301
  set autoClose(value) {
303
302
  cancelAnimationFrame(this.#autoCloseInterval);
304
303
  this.#timeVisible = 0;
304
+ this.toastElement.classList.toggle("progress", !this.opts.hideProgressBar && isNum(this.autoClose));
305
305
  this.nprogress = void 0;
306
306
  let lastTime;
307
307
  const loop = (time) => {
@@ -316,6 +316,7 @@
316
316
  if (!this.#isPaused) {
317
317
  this.#timeVisible += time - lastTime;
318
318
  this.onTimeUpdate?.(this.#timeVisible);
319
+ if (!this.opts.hideProgressBar) this.nprogress = void 0;
319
320
  if (isNum(this.autoClose) && this.#timeVisible >= this.autoClose) return this.remove("smooth", true);
320
321
  }
321
322
  lastTime = time;
@@ -327,21 +328,15 @@
327
328
  if (!this.#constructed) return;
328
329
  const currContainer = this.toastElement.parentElement, container = this.rootElement.querySelector(`:scope > .t007-toast-container[data-position="${value}"]`) || this._createContainer(value);
329
330
  !container.contains(this.toastElement) && container[this.opts.newestOnTop ? "prepend" : "append"](this.toastElement);
330
- this.toastElement.classList.toggle("t007-toast-scoped", this.scoped);
331
+ this.toastElement.classList.toggle("t007-toast-scoped", this.scoped), this.animation = true;
331
332
  if (!(currContainer == null || currContainer.hasChildNodes())) currContainer.remove();
332
333
  }
333
334
  set closeOnClick(value) {
334
- this.toastElement.onclick = value ? () => this.remove() : null;
335
+ this.toastElement.onclick = value ? () => this.remove(void 0, false, true) : null;
335
336
  }
336
337
  set hideProgressBar(value) {
337
- this.toastElement.classList.toggle("progress", !value);
338
- this.nprogress = void 0;
339
- cancelAnimationFrame(this.#progressInterval);
340
- const loop = () => {
341
- if (isNum(this.autoClose) && !this.#isPaused) this.nprogress = void 0;
342
- this.#progressInterval = requestAnimationFrame(loop);
343
- };
344
- if (!value) this.#progressInterval = requestAnimationFrame(loop);
338
+ this.toastElement.classList.toggle("progress", !value && isNum(this.autoClose));
339
+ if (!value && isNum(this.autoClose)) this.nprogress = void 0;
345
340
  }
346
341
  get nprogress() {
347
342
  return Number(this.toastElement.style.getProperty("--progress"));
@@ -372,9 +367,10 @@
372
367
  value && navigator?.vibrate?.(this.vibrate);
373
368
  }
374
369
  set limit(value) {
375
- const toastsInContainer = [...this.toastElement?.parentElement?.children || []];
376
- if (!toastsInContainer.length) return;
377
- 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]))?.abort();
370
+ if (!value) return;
371
+ const els = [...this.toastElement?.parentElement?.children || []];
372
+ if (!els.length) return;
373
+ for (let i = 0; i < els.length - value; i++) [...t007.toasts.values()].find((t) => t.toastElement === (this.opts.newestOnTop ? els[els.length - 1 - i] : els[i]))?.abort();
378
374
  }
379
375
  set newestOnTop(value) {
380
376
  this.toastElement?.parentElement?.[value ? "prepend" : "append"](this.toastElement);
@@ -384,6 +380,9 @@
384
380
  this.toastElement.onpointerdown = value ? this._handleToastPointerStart : null;
385
381
  this.toastElement.onpointerup = value ? this._handleToastPointerUp : null;
386
382
  }
383
+ set compact(value) {
384
+ this.toastElement.classList.toggle("t007-toast-compact", !!value);
385
+ }
387
386
  _handleToastPointerStart(e) {
388
387
  if (isStr(this._ptrType) && e.pointerType !== this._ptrType) return;
389
388
  if (e.touches?.length > 1) return;
@@ -417,22 +416,22 @@
417
416
  _handleToastPointerUp(e) {
418
417
  if (isStr(this._ptrType) && e.pointerType !== this._ptrType) return;
419
418
  cancelAnimationFrame(this._ptrRAF);
420
- 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.abort();
419
+ 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", false, true);
421
420
  this.#isPaused = this._ptrTicker = this._ptrDirSet = this._ptrDir = false;
422
421
  this.toastElement.removeEventListener("pointermove", this._handleToastPointerMove, { passive: false });
423
422
  for (const prop of ["transition", "transform", "opacity"]) this.toastElement.style.removeProperty(prop);
424
423
  }
425
- remove(manner = "smooth", timeElapsed = false) {
424
+ remove(manner = "smooth", timeElapsed = false, userInitiated = false) {
426
425
  if (!this.opts.isLoading) t007.toasts.delete(this.opts.id);
427
426
  for (const tid of this.queue) clearTimeout(tid);
428
427
  document.removeEventListener("visibilitychange", this.#visiblityChange);
429
- cancelAnimationFrame(this.#autoCloseInterval), cancelAnimationFrame(this.#progressInterval);
428
+ cancelAnimationFrame(this.#autoCloseInterval);
430
429
  if (this.inactive || manner === "instant" || !this.animation) this._cleanUpToast();
431
430
  else if (this.toastElement) this.toastElement.onanimationend = this._cleanUpToast;
432
431
  this.toastElement?.classList.remove("t007-toast-show");
433
- this.onClose?.(timeElapsed);
432
+ this.onClose?.(timeElapsed, userInitiated);
434
433
  }
435
- abort = () => this.remove("instant", false);
434
+ abort = () => this.remove("instant");
436
435
  _createContainer(position) {
437
436
  const container = createEl("div", { className: "t007-toast-container" }, { position });
438
437
  container.style.setProperty("--t007-toast-container-position", !this.scoped ? "fixed" : "absolute");
@@ -479,19 +478,19 @@
479
478
  const pendingId = base.loading(pendingCfg.render || "Promise pending...", { ...pendingCfg });
480
479
  promise.then(
481
480
  (response) => {
482
- const successConfig = NFC(success || "Promise resolved", "success");
483
- const { render, bodyHTML } = successConfig;
484
- if (isFunc(render)) successConfig.render = (txt = response) => render(txt);
485
- if (isFunc(bodyHTML)) successConfig.bodyHTML = (txt = response) => bodyHTML(txt);
486
- base.success(pendingId, successConfig);
481
+ const config = NFC(success || "Promise resolved", "success");
482
+ const { render, bodyHTML } = config;
483
+ if (isFunc(render)) config.render = (txt = response) => render(txt);
484
+ if (isFunc(bodyHTML)) config.bodyHTML = (txt = response) => bodyHTML(txt);
485
+ base.success(pendingId, config);
487
486
  return response;
488
487
  },
489
488
  (err) => {
490
- const errorConfig = NFC(error || "Promise rejected", "error");
491
- const { render, bodyHTML } = errorConfig;
492
- if (isFunc(render)) errorConfig.render = (txt = err) => render(txt);
493
- if (isFunc(bodyHTML)) errorConfig.bodyHTML = (txt = err) => bodyHTML(txt);
494
- base.error(pendingId, errorConfig);
489
+ const config = NFC(error || "Promise rejected", "error");
490
+ const { render, bodyHTML } = config;
491
+ if (isFunc(render)) config.render = (txt = err) => render(txt);
492
+ if (isFunc(bodyHTML)) config.bodyHTML = (txt = err) => bodyHTML(txt);
493
+ base.error(pendingId, config);
495
494
  return Promise.reject(err);
496
495
  }
497
496
  );
@@ -500,6 +499,9 @@
500
499
  dismiss(base, id, manner, timeElapsed) {
501
500
  return !isDef(id) ? base.dismissAll() : t007.toasts.get(id)?.remove(manner, timeElapsed);
502
501
  },
502
+ anyActive(base, groupId) {
503
+ return [...t007.toasts.values()].some((toast2) => (!isDef(groupId) ? true : toast2.opts.groupId === groupId) && base.isActive(toast2.opts.id, toast2));
504
+ },
503
505
  dismissAll(base, groupId) {
504
506
  for (const toast2 of t007.toasts.values()) (!isDef(groupId) ? true : toast2.opts.groupId === groupId) && toast2.remove();
505
507
  },
@@ -510,14 +512,16 @@
510
512
  return t007.toasts.values().filter((toast2) => !isDef(groupId) ? true : toast2.opts.groupId === groupId);
511
513
  }
512
514
  };
513
- var toaster = (defOptions = {}, groupId = "t007_toast_") => {
514
- const getDefaults = () => ({ ...t007.TOAST_DEFAULT_OPTIONS, ...defOptions }), base = (renderOrId, options = {}, mayBeId = renderOrId?.startsWith?.(groupId), render = mayBeId ? options.render : renderOrId, id = mayBeId ? renderOrId : options.id, toast2 = t007.toasts.get(id)) => toast2 ? toasting.update(base, id, { ...options, render }, toast2) : new T007_Toast({ ...getDefaults(), ...options, id, render, groupId }).opts.id;
515
+ var toaster = (defaults = {}, groupId = "t007_toast_") => {
516
+ const getDefaults = () => ({ ...t007.TOAST_DEFAULT_OPTIONS, ...base.defaults, groupId }), base = (renderOrId, options = {}, mayBeId = renderOrId?.startsWith?.(groupId), render = mayBeId ? options.render : renderOrId, id = mayBeId ? renderOrId : options.id, toast2 = t007.toasts.get(id)) => toast2 ? toasting.update(base, id, { ...options, render }, toast2) : new T007_Toast({ ...getDefaults(), ...options, id, render }).opts.id;
517
+ base.defaults = defaults;
515
518
  base.isActive = (id) => toasting.isActive(base, id);
516
519
  base.update = (id, options, _toast) => toasting.update(base, id, options, _toast);
517
520
  for (const action of ["info", "success", "warn", "error"]) base[action] = (renderOrId, options) => toasting.message(base, getDefaults, action, renderOrId, options);
518
521
  base.loading = (renderOrId, options) => toasting.loading(base, renderOrId, options);
519
522
  base.promise = (promise, config) => toasting.promise(base, promise, config);
520
523
  base.dismiss = (id, manner, timeElapsed) => toasting.dismiss(base, id, manner, timeElapsed);
524
+ base.anyActive = (groupId2) => toasting.anyActive(base, groupId2);
521
525
  base.dismissAll = (groupId2) => toasting.dismissAll(base, groupId2);
522
526
  base.doForAll = (action, options, groupId2) => toasting.doForAll(base, action, options, groupId2);
523
527
  base.getAll = (groupId2) => toasting.getAll(base, groupId2);
@@ -526,7 +530,7 @@
526
530
  var toast = toaster();
527
531
  var index_default = toast;
528
532
  var TOAST_UI_POSITIONS = [{ value: "top-left", display: "Top Left" }, { value: "top-center", display: "Top Center" }, { value: "top-right", display: "Top Right" }, { value: "center-left", display: "Center Left" }, { value: "center-center", display: "Center Center" }, { value: "center-right", display: "Center Right" }, { value: "bottom-left", display: "Bottom Left" }, { value: "bottom-center", display: "Bottom Center" }, { value: "bottom-right", display: "Bottom Right" }];
529
- var TOAST_UI_ANIMATIONS = [{ value: "fade", display: "Fade" }, { value: "zoom", display: "Zoom" }, { value: "slide", display: "Slide" }, { value: "slide-left", display: "Slide Left" }, { value: "slide-right", display: "Slide Right" }, { value: "slide-up", display: "Slide Up" }, { value: "slide-down", display: "Slide Down" }];
533
+ var TOAST_UI_ANIMATIONS = [{ value: "fade", display: "Fade" }, { value: "zoom", display: "Zoom" }, { value: "slide", display: "Slide" }, { value: "slide-left", display: "Slide Left" }, { value: "slide-right", display: "Slide Right" }, { value: "slide-up", display: "Slide Up" }, { value: "slide-down", display: "Slide Down" }, { value: false, display: "None" }];
530
534
  var TOAST_UI_TYPES = [{ value: void 0, display: "None" }, { value: "info", display: "Info" }, { value: "success", display: "Success" }, { value: "warning", display: "Warning" }, { value: "error", display: "Error" }];
531
535
  var TOAST_UI_DRAG_OPTIONS = [{ value: true, display: "On" }, { value: "mouse", display: "Mouse" }, { value: "touch", display: "Touch" }, { value: "pen", display: "Pen" }, { value: false, display: "Off" }];
532
536
  var TOAST_UI_DRAG_DIRECTIONS = [{ value: "x", display: "Horizontal" }, { value: "y", display: "Vertical" }, { value: "xy", display: "Horizontal and Vertical" }, { value: "x|y", display: "Horizontal or Vertical" }, { value: "x||y", display: "Horizontal or Vertical (Locked)" }, { value: "x+", display: "Right" }, { value: "x-", display: "Left" }, { value: "y+", display: "Down" }, { value: "y-", display: "Up" }, { value: "xy+", display: "Right and Down" }, { value: "xy-", display: "Left and Up" }, { value: "x|y+", display: "Right or Down" }, { value: "x|y-", display: "Left or Up" }, { value: "x||y+", display: "Right or Down (Locked)" }, { value: "x||y-", display: "Left or Up (Locked)" }];
@@ -554,6 +558,7 @@
554
558
  t007.TOAST_DEFAULT_OPTIONS.animation ??= true;
555
559
  t007.TOAST_DEFAULT_OPTIONS.newestOnTop ??= false;
556
560
  t007.TOAST_DEFAULT_OPTIONS.limit ??= 100;
561
+ t007.TOAST_DEFAULT_OPTIONS.compact ??= false;
557
562
  t007.TOAST_DURATIONS.success ??= 2500, t007.TOAST_DURATIONS.error ??= 4500, t007.TOAST_DURATIONS.warning ??= 3500, t007.TOAST_DURATIONS.info ??= 4e3;
558
563
  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];
559
564
  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>`;
package/dist/index.js CHANGED
@@ -4,7 +4,6 @@ var T007_Toast = class {
4
4
  #constructed = false;
5
5
  // to minimize updates
6
6
  #autoCloseInterval;
7
- #progressInterval;
8
7
  #timeVisible = 0;
9
8
  #isPaused = false;
10
9
  #shouldUnPause;
@@ -114,7 +113,7 @@ var T007_Toast = class {
114
113
  }
115
114
  set closeButton(value) {
116
115
  const btn = this.toastElement.querySelector(".t007-toast-cancel-button");
117
- if (value) this.toastElement.append(btn || createEl("button", { title: "Close", ariaLabel: "Close notification", className: "t007-toast-cancel-button", innerHTML: "&times;", onclick: this.remove }));
116
+ if (value) this.toastElement.append(btn || createEl("button", { title: "Close", ariaLabel: "Close notification", className: "t007-toast-cancel-button", innerHTML: "&times;", onclick: () => this.remove(void 0, false, true) }));
118
117
  else btn?.remove();
119
118
  }
120
119
  get animation() {
@@ -134,6 +133,7 @@ var T007_Toast = class {
134
133
  set autoClose(value) {
135
134
  cancelAnimationFrame(this.#autoCloseInterval);
136
135
  this.#timeVisible = 0;
136
+ this.toastElement.classList.toggle("progress", !this.opts.hideProgressBar && isNum(this.autoClose));
137
137
  this.nprogress = void 0;
138
138
  let lastTime;
139
139
  const loop = (time) => {
@@ -148,6 +148,7 @@ var T007_Toast = class {
148
148
  if (!this.#isPaused) {
149
149
  this.#timeVisible += time - lastTime;
150
150
  this.onTimeUpdate?.(this.#timeVisible);
151
+ if (!this.opts.hideProgressBar) this.nprogress = void 0;
151
152
  if (isNum(this.autoClose) && this.#timeVisible >= this.autoClose) return this.remove("smooth", true);
152
153
  }
153
154
  lastTime = time;
@@ -159,21 +160,15 @@ var T007_Toast = class {
159
160
  if (!this.#constructed) return;
160
161
  const currContainer = this.toastElement.parentElement, container = this.rootElement.querySelector(`:scope > .t007-toast-container[data-position="${value}"]`) || this._createContainer(value);
161
162
  !container.contains(this.toastElement) && container[this.opts.newestOnTop ? "prepend" : "append"](this.toastElement);
162
- this.toastElement.classList.toggle("t007-toast-scoped", this.scoped);
163
+ this.toastElement.classList.toggle("t007-toast-scoped", this.scoped), this.animation = true;
163
164
  if (!(currContainer == null || currContainer.hasChildNodes())) currContainer.remove();
164
165
  }
165
166
  set closeOnClick(value) {
166
- this.toastElement.onclick = value ? () => this.remove() : null;
167
+ this.toastElement.onclick = value ? () => this.remove(void 0, false, true) : null;
167
168
  }
168
169
  set hideProgressBar(value) {
169
- this.toastElement.classList.toggle("progress", !value);
170
- this.nprogress = void 0;
171
- cancelAnimationFrame(this.#progressInterval);
172
- const loop = () => {
173
- if (isNum(this.autoClose) && !this.#isPaused) this.nprogress = void 0;
174
- this.#progressInterval = requestAnimationFrame(loop);
175
- };
176
- if (!value) this.#progressInterval = requestAnimationFrame(loop);
170
+ this.toastElement.classList.toggle("progress", !value && isNum(this.autoClose));
171
+ if (!value && isNum(this.autoClose)) this.nprogress = void 0;
177
172
  }
178
173
  get nprogress() {
179
174
  return Number(this.toastElement.style.getProperty("--progress"));
@@ -204,9 +199,10 @@ var T007_Toast = class {
204
199
  value && navigator?.vibrate?.(this.vibrate);
205
200
  }
206
201
  set limit(value) {
207
- const toastsInContainer = [...this.toastElement?.parentElement?.children || []];
208
- if (!toastsInContainer.length) return;
209
- 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]))?.abort();
202
+ if (!value) return;
203
+ const els = [...this.toastElement?.parentElement?.children || []];
204
+ if (!els.length) return;
205
+ for (let i = 0; i < els.length - value; i++) [...t007.toasts.values()].find((t) => t.toastElement === (this.opts.newestOnTop ? els[els.length - 1 - i] : els[i]))?.abort();
210
206
  }
211
207
  set newestOnTop(value) {
212
208
  this.toastElement?.parentElement?.[value ? "prepend" : "append"](this.toastElement);
@@ -216,6 +212,9 @@ var T007_Toast = class {
216
212
  this.toastElement.onpointerdown = value ? this._handleToastPointerStart : null;
217
213
  this.toastElement.onpointerup = value ? this._handleToastPointerUp : null;
218
214
  }
215
+ set compact(value) {
216
+ this.toastElement.classList.toggle("t007-toast-compact", !!value);
217
+ }
219
218
  _handleToastPointerStart(e) {
220
219
  if (isStr(this._ptrType) && e.pointerType !== this._ptrType) return;
221
220
  if (e.touches?.length > 1) return;
@@ -249,22 +248,22 @@ var T007_Toast = class {
249
248
  _handleToastPointerUp(e) {
250
249
  if (isStr(this._ptrType) && e.pointerType !== this._ptrType) return;
251
250
  cancelAnimationFrame(this._ptrRAF);
252
- 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.abort();
251
+ 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", false, true);
253
252
  this.#isPaused = this._ptrTicker = this._ptrDirSet = this._ptrDir = false;
254
253
  this.toastElement.removeEventListener("pointermove", this._handleToastPointerMove, { passive: false });
255
254
  for (const prop of ["transition", "transform", "opacity"]) this.toastElement.style.removeProperty(prop);
256
255
  }
257
- remove(manner = "smooth", timeElapsed = false) {
256
+ remove(manner = "smooth", timeElapsed = false, userInitiated = false) {
258
257
  if (!this.opts.isLoading) t007.toasts.delete(this.opts.id);
259
258
  for (const tid of this.queue) clearTimeout(tid);
260
259
  document.removeEventListener("visibilitychange", this.#visiblityChange);
261
- cancelAnimationFrame(this.#autoCloseInterval), cancelAnimationFrame(this.#progressInterval);
260
+ cancelAnimationFrame(this.#autoCloseInterval);
262
261
  if (this.inactive || manner === "instant" || !this.animation) this._cleanUpToast();
263
262
  else if (this.toastElement) this.toastElement.onanimationend = this._cleanUpToast;
264
263
  this.toastElement?.classList.remove("t007-toast-show");
265
- this.onClose?.(timeElapsed);
264
+ this.onClose?.(timeElapsed, userInitiated);
266
265
  }
267
- abort = () => this.remove("instant", false);
266
+ abort = () => this.remove("instant");
268
267
  _createContainer(position) {
269
268
  const container = createEl("div", { className: "t007-toast-container" }, { position });
270
269
  container.style.setProperty("--t007-toast-container-position", !this.scoped ? "fixed" : "absolute");
@@ -311,19 +310,19 @@ var toasting = {
311
310
  const pendingId = base.loading(pendingCfg.render || "Promise pending...", { ...pendingCfg });
312
311
  promise.then(
313
312
  (response) => {
314
- const successConfig = NFC(success || "Promise resolved", "success");
315
- const { render, bodyHTML } = successConfig;
316
- if (isFunc(render)) successConfig.render = (txt = response) => render(txt);
317
- if (isFunc(bodyHTML)) successConfig.bodyHTML = (txt = response) => bodyHTML(txt);
318
- base.success(pendingId, successConfig);
313
+ const config = NFC(success || "Promise resolved", "success");
314
+ const { render, bodyHTML } = config;
315
+ if (isFunc(render)) config.render = (txt = response) => render(txt);
316
+ if (isFunc(bodyHTML)) config.bodyHTML = (txt = response) => bodyHTML(txt);
317
+ base.success(pendingId, config);
319
318
  return response;
320
319
  },
321
320
  (err) => {
322
- const errorConfig = NFC(error || "Promise rejected", "error");
323
- const { render, bodyHTML } = errorConfig;
324
- if (isFunc(render)) errorConfig.render = (txt = err) => render(txt);
325
- if (isFunc(bodyHTML)) errorConfig.bodyHTML = (txt = err) => bodyHTML(txt);
326
- base.error(pendingId, errorConfig);
321
+ const config = NFC(error || "Promise rejected", "error");
322
+ const { render, bodyHTML } = config;
323
+ if (isFunc(render)) config.render = (txt = err) => render(txt);
324
+ if (isFunc(bodyHTML)) config.bodyHTML = (txt = err) => bodyHTML(txt);
325
+ base.error(pendingId, config);
327
326
  return Promise.reject(err);
328
327
  }
329
328
  );
@@ -332,6 +331,9 @@ var toasting = {
332
331
  dismiss(base, id, manner, timeElapsed) {
333
332
  return !isDef(id) ? base.dismissAll() : t007.toasts.get(id)?.remove(manner, timeElapsed);
334
333
  },
334
+ anyActive(base, groupId) {
335
+ return [...t007.toasts.values()].some((toast2) => (!isDef(groupId) ? true : toast2.opts.groupId === groupId) && base.isActive(toast2.opts.id, toast2));
336
+ },
335
337
  dismissAll(base, groupId) {
336
338
  for (const toast2 of t007.toasts.values()) (!isDef(groupId) ? true : toast2.opts.groupId === groupId) && toast2.remove();
337
339
  },
@@ -342,14 +344,16 @@ var toasting = {
342
344
  return t007.toasts.values().filter((toast2) => !isDef(groupId) ? true : toast2.opts.groupId === groupId);
343
345
  }
344
346
  };
345
- var toaster = (defOptions = {}, groupId = "t007_toast_") => {
346
- const getDefaults = () => ({ ...t007.TOAST_DEFAULT_OPTIONS, ...defOptions }), base = (renderOrId, options = {}, mayBeId = renderOrId?.startsWith?.(groupId), render = mayBeId ? options.render : renderOrId, id = mayBeId ? renderOrId : options.id, toast2 = t007.toasts.get(id)) => toast2 ? toasting.update(base, id, { ...options, render }, toast2) : new T007_Toast({ ...getDefaults(), ...options, id, render, groupId }).opts.id;
347
+ var toaster = (defaults = {}, groupId = "t007_toast_") => {
348
+ const getDefaults = () => ({ ...t007.TOAST_DEFAULT_OPTIONS, ...base.defaults, groupId }), base = (renderOrId, options = {}, mayBeId = renderOrId?.startsWith?.(groupId), render = mayBeId ? options.render : renderOrId, id = mayBeId ? renderOrId : options.id, toast2 = t007.toasts.get(id)) => toast2 ? toasting.update(base, id, { ...options, render }, toast2) : new T007_Toast({ ...getDefaults(), ...options, id, render }).opts.id;
349
+ base.defaults = defaults;
347
350
  base.isActive = (id) => toasting.isActive(base, id);
348
351
  base.update = (id, options, _toast) => toasting.update(base, id, options, _toast);
349
352
  for (const action of ["info", "success", "warn", "error"]) base[action] = (renderOrId, options) => toasting.message(base, getDefaults, action, renderOrId, options);
350
353
  base.loading = (renderOrId, options) => toasting.loading(base, renderOrId, options);
351
354
  base.promise = (promise, config) => toasting.promise(base, promise, config);
352
355
  base.dismiss = (id, manner, timeElapsed) => toasting.dismiss(base, id, manner, timeElapsed);
356
+ base.anyActive = (groupId2) => toasting.anyActive(base, groupId2);
353
357
  base.dismissAll = (groupId2) => toasting.dismissAll(base, groupId2);
354
358
  base.doForAll = (action, options, groupId2) => toasting.doForAll(base, action, options, groupId2);
355
359
  base.getAll = (groupId2) => toasting.getAll(base, groupId2);
@@ -358,7 +362,7 @@ var toaster = (defOptions = {}, groupId = "t007_toast_") => {
358
362
  var toast = toaster();
359
363
  var index_default = toast;
360
364
  var TOAST_UI_POSITIONS = [{ value: "top-left", display: "Top Left" }, { value: "top-center", display: "Top Center" }, { value: "top-right", display: "Top Right" }, { value: "center-left", display: "Center Left" }, { value: "center-center", display: "Center Center" }, { value: "center-right", display: "Center Right" }, { value: "bottom-left", display: "Bottom Left" }, { value: "bottom-center", display: "Bottom Center" }, { value: "bottom-right", display: "Bottom Right" }];
361
- var TOAST_UI_ANIMATIONS = [{ value: "fade", display: "Fade" }, { value: "zoom", display: "Zoom" }, { value: "slide", display: "Slide" }, { value: "slide-left", display: "Slide Left" }, { value: "slide-right", display: "Slide Right" }, { value: "slide-up", display: "Slide Up" }, { value: "slide-down", display: "Slide Down" }];
365
+ var TOAST_UI_ANIMATIONS = [{ value: "fade", display: "Fade" }, { value: "zoom", display: "Zoom" }, { value: "slide", display: "Slide" }, { value: "slide-left", display: "Slide Left" }, { value: "slide-right", display: "Slide Right" }, { value: "slide-up", display: "Slide Up" }, { value: "slide-down", display: "Slide Down" }, { value: false, display: "None" }];
362
366
  var TOAST_UI_TYPES = [{ value: void 0, display: "None" }, { value: "info", display: "Info" }, { value: "success", display: "Success" }, { value: "warning", display: "Warning" }, { value: "error", display: "Error" }];
363
367
  var TOAST_UI_DRAG_OPTIONS = [{ value: true, display: "On" }, { value: "mouse", display: "Mouse" }, { value: "touch", display: "Touch" }, { value: "pen", display: "Pen" }, { value: false, display: "Off" }];
364
368
  var TOAST_UI_DRAG_DIRECTIONS = [{ value: "x", display: "Horizontal" }, { value: "y", display: "Vertical" }, { value: "xy", display: "Horizontal and Vertical" }, { value: "x|y", display: "Horizontal or Vertical" }, { value: "x||y", display: "Horizontal or Vertical (Locked)" }, { value: "x+", display: "Right" }, { value: "x-", display: "Left" }, { value: "y+", display: "Down" }, { value: "y-", display: "Up" }, { value: "xy+", display: "Right and Down" }, { value: "xy-", display: "Left and Up" }, { value: "x|y+", display: "Right or Down" }, { value: "x|y-", display: "Left or Up" }, { value: "x||y+", display: "Right or Down (Locked)" }, { value: "x||y-", display: "Left or Up (Locked)" }];
@@ -386,6 +390,7 @@ if ("undefined" !== typeof window) {
386
390
  t007.TOAST_DEFAULT_OPTIONS.animation ??= true;
387
391
  t007.TOAST_DEFAULT_OPTIONS.newestOnTop ??= false;
388
392
  t007.TOAST_DEFAULT_OPTIONS.limit ??= 100;
393
+ t007.TOAST_DEFAULT_OPTIONS.compact ??= false;
389
394
  t007.TOAST_DURATIONS.success ??= 2500, t007.TOAST_DURATIONS.error ??= 4500, t007.TOAST_DURATIONS.warning ??= 3500, t007.TOAST_DURATIONS.info ??= 4e3;
390
395
  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];
391
396
  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>`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t007/toast",
3
- "version": "0.0.38",
3
+ "version": "0.0.39",
4
4
  "description": "A lightweight, pure JS toast system.",
5
5
  "author": "Oketade Oluwatobiloba <tobioketade007@gmail.com>",
6
6
  "license": "MIT",
@@ -55,7 +55,7 @@
55
55
  "promise"
56
56
  ],
57
57
  "dependencies": {
58
- "@t007/utils": "^0.0.39"
58
+ "@t007/utils": "^0.0.40"
59
59
  },
60
60
  "devDependencies": {
61
61
  "esbuild-sass-plugin": "^3.7.0"