@tsirosgeorge/toastnotification 5.4.0 → 5.6.0

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/Readme.md CHANGED
@@ -103,6 +103,55 @@ toast('Are you sure?', {
103
103
  });
104
104
  ```
105
105
 
106
+ ### 🔄 Wrapping an async action
107
+
108
+ ```javascript
109
+ const order = await toast.promise(saveOrder(cart), {
110
+ loading: 'Saving your order…',
111
+ success: (order) => `Order #${order.id} saved.`,
112
+ error: (err) => `Could not save: ${err.message}`,
113
+ });
114
+ ```
115
+
116
+ One loading toast becomes the success or error message. It resolves with the promise's
117
+ value and re-throws its rejection, so the caller still handles the failure.
118
+
119
+ ### ↩️ Action button
120
+
121
+ ```javascript
122
+ toast.success('Item removed from your cart.', {
123
+ duration: 8000,
124
+ showProgress: true,
125
+ action: { text: 'Undo', onClick: () => restoreItem() },
126
+ });
127
+ ```
128
+
129
+ ### ⚙️ Site-wide defaults
130
+
131
+ ```javascript
132
+ toast.defaults = { position: 'bottom-right', showProgress: true, duration: 4000 };
133
+ ```
134
+
135
+ Applied to every toast unless the individual call overrides them.
136
+
137
+ ### ⌨️ Keyboard and screen readers
138
+
139
+ Confirm dialogs take focus when they open, keep Tab inside themselves while they are
140
+ open, and hand focus back to whatever opened them when they close. Escape cancels, and
141
+ Enter submits a single-line input. Without this the element that opened the dialog kept
142
+ focus behind the backdrop, so Enter or Space re-triggered it and stacked a second dialog.
143
+
144
+ Toast containers are announced as `aria-live="polite"`; `error` and `warning` toasts get
145
+ `role="alert"`. Everything respects `prefers-reduced-motion`.
146
+
147
+ ### ✋ Closing toasts yourself
148
+
149
+ ```javascript
150
+ const t = toast('Working…', { duration: 0 });
151
+ t.close(); // dismiss this one
152
+ toast.dismissAll(); // dismiss everything; open dialogs settle as a cancel
153
+ ```
154
+
106
155
  ### ⏳ Loading → Update
107
156
  ```javascript
108
157
  const t = toast.loading('Uploading…', { type: 'info' });
@@ -114,12 +163,17 @@ t.update('Done!', { type: 'success', duration: 2000 });
114
163
 
115
164
  | Option | Type | Default | Description |
116
165
  |--------------|------------|---------------|-----------------------------------------------------------------------------------------------|
117
- | `position` | `string` | `'top-right'` | Container position. Values: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`, `'top-center'`, `'bottom-center'`. |
166
+ | `position` | `string` | `'top-right'` | Container position. Values: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`, `'top-center'`, `'bottom-center'`, `'center'`. `'center'` places it dead centre of the viewport and defaults to the `zoom-in` animation; it works for plain toasts and for confirm dialogs. |
118
167
  | `animation` | `string` | `'slide-right'` | Show animation. Examples: `'slide-right'`, `'slide-left'`, `'slide-top'`, `'slide-bottom'`, `'zoom-in'`. Hide uses reverse automatically. |
119
168
  | `type` | `string` | `'info'` | Type of toast, controlling icon and styling. Possible values: `'info'`, `'success'`, `'error'`, `'warning'`. |
120
169
  | `duration` | `number` | `3000` | Duration in milliseconds before the toast automatically dismisses. |
121
170
  | `icon` | `string` or `null` | `null` | Optional custom icon displayed as text (e.g., emoji) before the toast message. If not set, a default GIF icon is used based on the `type`. |
122
171
  | `showLoader` | `boolean` | `false` | Whether to show a loader/progress bar animation on the toast during its visible duration. |
172
+ | `pauseOnHover` | `boolean` | `true` | Freeze the countdown while the pointer or keyboard focus is on the toast. |
173
+ | `showProgress` | `boolean` | `false` | Thin bar counting the remaining time down. Needs `duration > 0`; pauses with `pauseOnHover`. |
174
+ | `action` | `object` or `null` | `null` | `{ text, onClick }` renders a button inside the toast, e.g. Undo. Clicking it runs `onClick` and closes the toast. |
175
+ | `allowHtml` | `boolean` | `true` | `message` is written as HTML. Pass `false` to render it as plain text — do that for anything user-supplied, or you have an XSS hole. |
176
+ | `closeOnEscape` | `boolean` | `true` | Confirm dialogs only. Escape cancels the dialog. |
123
177
  | `onClick` | `function` or `null` | `null` | Callback function executed when the toast is clicked. |
124
178
  | `onShow` | `function` or `null` | `null` | Callback function executed when the toast appears (after it's added to the DOM and shown). |
125
179
  | `onDismiss` | `function` or `null` | `null` | Callback function executed when the toast is dismissed and removed from the DOM. |
@@ -52,6 +52,14 @@
52
52
  align-items: center;
53
53
  }
54
54
 
55
+ /* Dead centre of the viewport, for alerts that should not sit in a corner. */
56
+ .ts-toast-container.center {
57
+ top: 50%;
58
+ left: 50%;
59
+ transform: translate(-50%, -50%);
60
+ align-items: center;
61
+ }
62
+
55
63
  /* General Toast styles */
56
64
  .ts-toast-container .ts-toast {
57
65
  display: flex;
@@ -334,6 +342,7 @@
334
342
  .ts-toast-overlay.bottom-left { align-items: flex-end; justify-content: flex-start; padding: 1rem; }
335
343
  .ts-toast-overlay.bottom-center { align-items: flex-end; justify-content: center; padding: 1rem; }
336
344
  .ts-toast-overlay.bottom-right { align-items: flex-end; justify-content: flex-end; padding: 1rem; }
345
+ .ts-toast-overlay.center { align-items: center; justify-content: center; padding: 1rem; }
337
346
 
338
347
  /* Tiny utility: flex icon container */
339
348
  /* Scoped utility to avoid conflicts */
@@ -342,4 +351,50 @@
342
351
  /* Prevent scroll behind confirm overlay */
343
352
  body.ts-toast-no-scroll {
344
353
  overflow: hidden;
345
- }
354
+ }
355
+
356
+ /* Progress bar counting down the remaining time */
357
+ @keyframes ts-toast-progress {
358
+ from { transform: scaleX(1); }
359
+ to { transform: scaleX(0); }
360
+ }
361
+
362
+ .ts-toast-container .ts-toast-progress {
363
+ position: absolute;
364
+ left: 0;
365
+ right: 0;
366
+ bottom: 0;
367
+ height: 3px;
368
+ transform-origin: left center;
369
+ border-radius: 0 0 8px 8px;
370
+ background: var(--toast-progress-color, currentColor);
371
+ opacity: 0.35;
372
+ pointer-events: none;
373
+ }
374
+
375
+ .ts-toast-container .ts-toast-success .ts-toast-progress { background: var(--toast-success-color, #17a35c); }
376
+ .ts-toast-container .ts-toast-error .ts-toast-progress { background: var(--toast-error-color, #ef4444); }
377
+ .ts-toast-container .ts-toast-warning .ts-toast-progress { background: var(--toast-warning-color, #f0a020); }
378
+ .ts-toast-container .ts-toast-info .ts-toast-progress { background: var(--toast-info-color, #3b82f6); }
379
+
380
+ /* Action button inside a toast (e.g. Undo) */
381
+ .ts-toast-container .ts-toast-action {
382
+ /* Toasts lay out row-reverse, so the lowest order sits at the right-hand end:
383
+ icon, message, then the action button. */
384
+ order: -1;
385
+ flex: none;
386
+ appearance: none;
387
+ border: 0;
388
+ background: transparent;
389
+ color: var(--toast-action-color, #3b82f6);
390
+ font: inherit;
391
+ font-weight: 600;
392
+ padding: 4px 8px;
393
+ margin-left: 4px;
394
+ border-radius: 6px;
395
+ cursor: pointer;
396
+ }
397
+
398
+ .ts-toast-container .ts-toast-action:hover {
399
+ background: var(--toast-action-hover, rgba(59, 130, 246, 0.12));
400
+ }
@@ -1 +1 @@
1
- .ts-toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:10px;pointer-events:none;width:fit-content;max-width:calc(100% - 2rem)}.ts-toast-container>:not(:last-child){margin-bottom:0!important}.ts-toast-container.top-right{top:1rem;right:1rem;align-items:flex-end}.ts-toast-container.top-left{top:1rem;left:1rem;align-items:flex-start}.ts-toast-container.top-center{top:1rem;left:50%;transform:translateX(-50%);align-items:center}.ts-toast-container.bottom-right{bottom:1rem;right:1rem;align-items:flex-end}.ts-toast-container.bottom-left{bottom:1rem;left:1rem;align-items:flex-start}.ts-toast-container.bottom-center{bottom:1rem;left:50%;transform:translateX(-50%);align-items:center}.ts-toast-container .ts-toast{display:flex;align-items:center;gap:.75rem;background-color:var(--toast-bg,#fff);color:var(--toast-color,#000);padding:.75rem 1rem;border-radius:8px;border:1px solid var(--toast-border,#e5e7eb);box-shadow:var(--toast-shadow,0 10px 15px -3px rgba(0,0,0,.1));font-family:sans-serif;font-size:.95rem;pointer-events:all;position:relative;opacity:0;transform:translateY(20px);transition:opacity .5s ease,transform .5s ease;width:auto!important}.ts-toast.ts-toast-confirm{display:flex;align-items:center;justify-content:center;background-color:var(--toast-bg,#fff);color:var(--toast-color,#000);border:1px solid var(--toast-border,#e5e7eb);border-radius:12px;padding:16px 20px;box-shadow:var(--toast-shadow,0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1));transition:opacity .5s ease,transform .5s ease}.ts-toast.ts-toast-confirm .ts-toast-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;text-align:center}.ts-toast.ts-toast-confirm .ts-toast-body{text-align:center}.ts-toast-actions{display:flex;gap:10px;justify-content:center;margin-top:12px}.ts-toast-input{width:100%;padding:8px 12px;border:1px solid var(--toast-border,#e5e7eb);border-radius:8px;font-family:inherit;font-size:.95rem;margin-top:12px;background:var(--toast-bg,#fff);color:var(--toast-color,#000);outline:0;transition:border-color .2s ease}.ts-toast-input:focus{border-color:#3b82f6}.ts-toast-container .ts-toast.ts-toast-show{opacity:1;transform:translateY(0)}@keyframes ts-toast-slide-left{from{transform:translateX(-100%)}to{transform:translateX(0)}}@keyframes ts-toast-slide-right{from{transform:translateX(100%)}to{transform:translateX(0)}}@keyframes ts-toast-slide-top{from{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes ts-toast-slide-bottom{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes ts-toast-zoom-in{from{transform:scale(0)}to{transform:scale(1)}}@keyframes ts-toast-zoom-out{from{transform:scale(1)}to{transform:scale(0)}}@keyframes ts-toast-flip{from{transform:rotateY(90deg)}to{transform:rotateY(0)}}.ts-toast-container .ts-toast-icon{font-size:1.2rem}.ts-toast-container .ts-toast-success .ts-toast-icon{color:var(--toast-success-color,#66ee78)}.ts-toast-container .ts-toast-error .ts-toast-icon{color:var(--toast-error-color,#ef4444)}.ts-toast-container .ts-toast-loader{width:20px;height:20px;border:3px solid #f3f3f3;border-top:3px solid var(--toast-loader-color,#66ee78);border-radius:50%;animation:ts-toast-spin 1s linear infinite}@keyframes ts-toast-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.ts-toast-container .ts-toast-loader.done{animation:none;opacity:0;transition:opacity .5s ease}.ts-toast-container .ts-toast-icon{font-size:1.2rem;opacity:0;transition:opacity .5s ease}.ts-toast-container .ts-toast.ts-toast-show .ts-toast-icon{opacity:1}@keyframes progress-bar{0%{width:0%}100%{width:100%}}@keyframes ts-toast-slide-top-reverse{from{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes ts-toast-slide-bottom-reverse{from{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes ts-toast-slide-left-reverse{from{transform:translateX(0)}to{transform:translateX(-100%)}}@keyframes ts-toast-slide-right-reverse{from{transform:translateX(0)}to{transform:translateX(100%)}}.ts-toast.ts-toast-slide-out{opacity:0}.ts-toast-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:2147483646}.ts-toast-overlay.top-left{align-items:flex-start;justify-content:flex-start;padding:1rem}.ts-toast-overlay.top-center{align-items:flex-start;justify-content:center;padding:1rem}.ts-toast-overlay.top-right{align-items:flex-start;justify-content:flex-end;padding:1rem}.ts-toast-overlay.bottom-left{align-items:flex-end;justify-content:flex-start;padding:1rem}.ts-toast-overlay.bottom-center{align-items:flex-end;justify-content:center;padding:1rem}.ts-toast-overlay.bottom-right{align-items:flex-end;justify-content:flex-end;padding:1rem}.ts-toast-d-flex{display:inline-flex;align-items:center}body.ts-toast-no-scroll{overflow:hidden}
1
+ .ts-toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:10px;pointer-events:none;width:fit-content;max-width:calc(100% - 2rem)}.ts-toast-container>:not(:last-child){margin-bottom:0!important}.ts-toast-container.top-right{top:1rem;right:1rem;align-items:flex-end}.ts-toast-container.top-left{top:1rem;left:1rem;align-items:flex-start}.ts-toast-container.top-center{top:1rem;left:50%;transform:translateX(-50%);align-items:center}.ts-toast-container.bottom-right{bottom:1rem;right:1rem;align-items:flex-end}.ts-toast-container.bottom-left{bottom:1rem;left:1rem;align-items:flex-start}.ts-toast-container.bottom-center{bottom:1rem;left:50%;transform:translateX(-50%);align-items:center}.ts-toast-container.center{top:50%;left:50%;transform:translate(-50%,-50%);align-items:center}.ts-toast-container .ts-toast{display:flex;align-items:center;gap:.75rem;background-color:var(--toast-bg,#fff);color:var(--toast-color,#000);padding:.75rem 1rem;border-radius:8px;border:1px solid var(--toast-border,#e5e7eb);box-shadow:var(--toast-shadow,0 10px 15px -3px rgba(0,0,0,.1));font-family:sans-serif;font-size:.95rem;pointer-events:all;position:relative;opacity:0;transform:translateY(20px);transition:opacity .5s ease,transform .5s ease;width:auto!important}.ts-toast.ts-toast-confirm{display:flex;align-items:center;justify-content:center;background-color:var(--toast-bg,#fff);color:var(--toast-color,#000);border:1px solid var(--toast-border,#e5e7eb);border-radius:12px;padding:16px 20px;box-shadow:var(--toast-shadow,0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1));transition:opacity .5s ease,transform .5s ease}.ts-toast.ts-toast-confirm .ts-toast-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;text-align:center}.ts-toast.ts-toast-confirm .ts-toast-body{text-align:center}.ts-toast-actions{display:flex;gap:10px;justify-content:center;margin-top:12px}.ts-toast-input{width:100%;padding:8px 12px;border:1px solid var(--toast-border,#e5e7eb);border-radius:8px;font-family:inherit;font-size:.95rem;margin-top:12px;background:var(--toast-bg,#fff);color:var(--toast-color,#000);outline:0;transition:border-color .2s ease}.ts-toast-input:focus{border-color:#3b82f6}.ts-toast-container .ts-toast.ts-toast-show{opacity:1;transform:translateY(0)}@keyframes ts-toast-slide-left{from{transform:translateX(-100%)}to{transform:translateX(0)}}@keyframes ts-toast-slide-right{from{transform:translateX(100%)}to{transform:translateX(0)}}@keyframes ts-toast-slide-top{from{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes ts-toast-slide-bottom{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes ts-toast-zoom-in{from{transform:scale(0)}to{transform:scale(1)}}@keyframes ts-toast-zoom-out{from{transform:scale(1)}to{transform:scale(0)}}@keyframes ts-toast-flip{from{transform:rotateY(90deg)}to{transform:rotateY(0)}}.ts-toast-container .ts-toast-icon{font-size:1.2rem}.ts-toast-container .ts-toast-success .ts-toast-icon{color:var(--toast-success-color,#66ee78)}.ts-toast-container .ts-toast-error .ts-toast-icon{color:var(--toast-error-color,#ef4444)}.ts-toast-container .ts-toast-loader{width:20px;height:20px;border:3px solid #f3f3f3;border-top:3px solid var(--toast-loader-color,#66ee78);border-radius:50%;animation:ts-toast-spin 1s linear infinite}@keyframes ts-toast-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.ts-toast-container .ts-toast-loader.done{animation:none;opacity:0;transition:opacity .5s ease}.ts-toast-container .ts-toast-icon{font-size:1.2rem;opacity:0;transition:opacity .5s ease}.ts-toast-container .ts-toast.ts-toast-show .ts-toast-icon{opacity:1}@keyframes progress-bar{0%{width:0%}100%{width:100%}}@keyframes ts-toast-slide-top-reverse{from{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes ts-toast-slide-bottom-reverse{from{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes ts-toast-slide-left-reverse{from{transform:translateX(0)}to{transform:translateX(-100%)}}@keyframes ts-toast-slide-right-reverse{from{transform:translateX(0)}to{transform:translateX(100%)}}.ts-toast.ts-toast-slide-out{opacity:0}.ts-toast-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:2147483646}.ts-toast-overlay.top-left{align-items:flex-start;justify-content:flex-start;padding:1rem}.ts-toast-overlay.top-center{align-items:flex-start;justify-content:center;padding:1rem}.ts-toast-overlay.top-right{align-items:flex-start;justify-content:flex-end;padding:1rem}.ts-toast-overlay.bottom-left{align-items:flex-end;justify-content:flex-start;padding:1rem}.ts-toast-overlay.bottom-center{align-items:flex-end;justify-content:center;padding:1rem}.ts-toast-overlay.bottom-right{align-items:flex-end;justify-content:flex-end;padding:1rem}.ts-toast-overlay.center{align-items:center;justify-content:center;padding:1rem}.ts-toast-d-flex{display:inline-flex;align-items:center}body.ts-toast-no-scroll{overflow:hidden}@keyframes ts-toast-progress{from{transform:scaleX(1)}to{transform:scaleX(0)}}.ts-toast-container .ts-toast-progress{position:absolute;left:0;right:0;bottom:0;height:3px;transform-origin:left center;border-radius:0 0 8px 8px;background:var(--toast-progress-color,currentColor);opacity:.35;pointer-events:none}.ts-toast-container .ts-toast-success .ts-toast-progress{background:var(--toast-success-color,#17a35c)}.ts-toast-container .ts-toast-error .ts-toast-progress{background:var(--toast-error-color,#ef4444)}.ts-toast-container .ts-toast-warning .ts-toast-progress{background:var(--toast-warning-color,#f0a020)}.ts-toast-container .ts-toast-info .ts-toast-progress{background:var(--toast-info-color,#3b82f6)}.ts-toast-container .ts-toast-action{order:-1;flex:none;appearance:none;border:0;background:0 0;color:var(--toast-action-color,#3b82f6);font:inherit;font-weight:600;padding:4px 8px;margin-left:4px;border-radius:6px;cursor:pointer}.ts-toast-container .ts-toast-action:hover{background:var(--toast-action-hover,rgba(59,130,246,.12))}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsirosgeorge/toastnotification",
3
- "version": "5.4.0",
3
+ "version": "5.6.0",
4
4
  "description": "a toast notification plugin",
5
5
  "main": "toast.min.js",
6
6
  "module": "toast.module.js",
@@ -21,8 +21,9 @@
21
21
  "build:css": "cleancss -o assets/css/toast.min.css assets/css/toast.css",
22
22
  "build:js": "terser toast.js --compress --mangle --output toast.min.js",
23
23
  "build": "npm run sync:version && npm run build:module && npm run build:css && npm run build:js",
24
+ "version": "node scripts/stamp-changelog.mjs && npm run build && git add -A",
24
25
  "prepublishOnly": "npm run build",
25
- "release": "npm version ${V:-patch} && npm publish --access public && git push origin main --follow-tags"
26
+ "release": "npm version ${V:-patch} && git push origin main --follow-tags"
26
27
  },
27
28
  "files": [
28
29
  "toast.js",
package/toast.d.ts CHANGED
@@ -2,7 +2,9 @@ export type ToastType = 'info' | 'success' | 'warning' | 'error';
2
2
 
3
3
  export type ToastPosition =
4
4
  | 'top-left' | 'top-right' | 'top-center'
5
- | 'bottom-left' | 'bottom-right' | 'bottom-center';
5
+ | 'bottom-left' | 'bottom-right' | 'bottom-center'
6
+ /** Dead centre of the viewport. Defaults to the zoom-in animation. */
7
+ | 'center';
6
8
 
7
9
  export type ToastAnimation =
8
10
  | 'slide-top' | 'slide-bottom' | 'slide-left' | 'slide-right'
@@ -16,6 +18,8 @@ export type ConfirmResult = boolean | string | null;
16
18
  export interface ToastElement extends HTMLDivElement {
17
19
  /** Present in confirm mode: resolves when the user confirms, cancels or dismisses. */
18
20
  result?: Promise<ConfirmResult>;
21
+ /** Dismiss this toast now. On a confirm dialog this settles as a cancel. */
22
+ close(): void;
19
23
  }
20
24
 
21
25
  export interface ToastOptions {
@@ -27,6 +31,17 @@ export interface ToastOptions {
27
31
  /** Emoji or text used instead of the bundled animated icon. */
28
32
  icon?: string | null;
29
33
  showLoader?: boolean;
34
+ /** Freeze the countdown while the pointer or keyboard focus is on the toast. */
35
+ pauseOnHover?: boolean;
36
+ /** Thin bar counting the remaining time down. Needs `duration > 0`. */
37
+ showProgress?: boolean;
38
+ /** Renders a button inside the toast, e.g. Undo. */
39
+ action?: ToastAction | null;
40
+ /**
41
+ * `message` is written as HTML by default, for backwards compatibility.
42
+ * Pass `false` to render it as plain text — do that for anything user-supplied.
43
+ */
44
+ allowHtml?: boolean;
30
45
  /** `'confirm'` (alias `'swal'`) renders a modal dialog instead of a toast. */
31
46
  mode?: 'alert' | 'confirm' | 'swal';
32
47
  dismissOnClick?: boolean;
@@ -48,6 +63,8 @@ export interface ConfirmOptions extends ToastOptions {
48
63
  cancelButtonColor?: string | null;
49
64
  useOverlay?: boolean;
50
65
  closeOnOverlayClick?: boolean;
66
+ /** Escape cancels the dialog. Defaults to true. */
67
+ closeOnEscape?: boolean;
51
68
  showClose?: boolean;
52
69
  /** Receives the input's value when `input` is set, otherwise `true`. */
53
70
  onConfirm?: (value: string | true, el: ToastElement) => void;
@@ -55,6 +72,21 @@ export interface ConfirmOptions extends ToastOptions {
55
72
  onResult?: (result: ConfirmResult, el: ToastElement) => void;
56
73
  }
57
74
 
75
+ export interface ToastAction {
76
+ /** Button label. */
77
+ text: string;
78
+ /** Runs on click; the toast closes afterwards. */
79
+ onClick?: (el: ToastElement) => void;
80
+ }
81
+
82
+ export interface PromiseMessages<T = unknown> {
83
+ loading?: string;
84
+ /** A function receives the resolved value. */
85
+ success?: string | ((value: T) => string);
86
+ /** A function receives the rejection reason. */
87
+ error?: string | ((err: unknown) => string);
88
+ }
89
+
58
90
  export interface LoadingHandle {
59
91
  update(message: string, options?: ToastOptions): void;
60
92
  close(): void;
@@ -74,6 +106,16 @@ export interface Toast {
74
106
  * and `null` on cancel/dismiss — so an empty submission is not read as a cancel.
75
107
  */
76
108
  confirm(message: string, options?: ConfirmOptions): Promise<ConfirmResult>;
109
+ /** Dismiss every toast on screen; open confirm dialogs settle as a cancel. */
110
+ dismissAll(): void;
111
+ /**
112
+ * Shows a loading toast that becomes the success or error message when
113
+ * `promise` settles. Resolves with the promise's value, and re-throws its
114
+ * rejection so the caller still handles the failure.
115
+ */
116
+ promise<T>(promise: Promise<T>, messages?: PromiseMessages<T>, options?: ToastOptions): Promise<T>;
117
+ /** Options applied to every toast unless the call overrides them. */
118
+ defaults: ToastOptions;
77
119
  }
78
120
 
79
121
  declare const toast: Toast;