vanilla-jui 1.4.7 → 1.5.1

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.
Files changed (52) hide show
  1. package/README.md +10 -4
  2. package/dist/index.d.ts +418 -970
  3. package/dist/index.js +1 -1
  4. package/dist/index.umd.js +1 -1
  5. package/dist/style.css +1 -1
  6. package/package.json +3 -3
  7. package/src/components/accordion.ts +466 -346
  8. package/src/components/flow.ts +779 -1133
  9. package/src/components/form.ts +666 -509
  10. package/src/components/menu.ts +198 -328
  11. package/src/components/modal.ts +510 -747
  12. package/src/components/offcanvas.ts +273 -367
  13. package/src/components/pagination.ts +201 -375
  14. package/src/components/swiper.ts +689 -1107
  15. package/src/components/tabs.ts +467 -778
  16. package/src/components/toc.ts +191 -244
  17. package/src/core/component.ts +332 -0
  18. package/src/core/motion.ts +298 -0
  19. package/src/core/presence.ts +233 -0
  20. package/src/core/scheduler.ts +91 -0
  21. package/src/core/view.ts +31 -0
  22. package/src/css/accordion.css +94 -3
  23. package/src/css/content.css +18 -24
  24. package/src/css/drop.css +4 -1
  25. package/src/css/form.css +8 -0
  26. package/src/css/menu.css +10 -5
  27. package/src/css/modal.css +2 -1
  28. package/src/css/offcanvas.css +5 -17
  29. package/src/css/swiper.css +2 -1
  30. package/src/css/tabs.css +8 -17
  31. package/src/css/themes/default/accordion.css +0 -48
  32. package/src/css/themes/default/swiper.css +1 -1
  33. package/src/css/themes/default/tabs.css +4 -6
  34. package/src/css/toast.css +1 -17
  35. package/src/css/tooltip.css +2 -1
  36. package/src/index.ts +8 -2
  37. package/src/locales/index.ts +3 -0
  38. package/src/primitives/drop.ts +253 -262
  39. package/src/primitives/loading.ts +22 -4
  40. package/src/primitives/parabola.ts +123 -164
  41. package/src/primitives/sticky.ts +297 -0
  42. package/src/primitives/theme.ts +164 -222
  43. package/src/primitives/toast.ts +309 -284
  44. package/src/primitives/tooltip.ts +65 -66
  45. package/src/utilities/browser.ts +38 -0
  46. package/src/utilities/dom.ts +0 -54
  47. package/src/utilities/refs.ts +61 -0
  48. package/src/utilities/state.ts +73 -0
  49. package/src/utilities/timer.ts +11 -31
  50. package/src/validation/validator.ts +289 -389
  51. package/src/components/sticky.ts +0 -297
  52. package/src/core/Component.ts +0 -377
@@ -1,4 +1,4 @@
1
- import { jsx } from 'vanilla-signal';
1
+ import { insert, jsx } from 'vanilla-signal';
2
2
  import { t } from 'vanilla-signal-i18n';
3
3
 
4
4
  import locales from '../locales/index.ts';
@@ -37,6 +37,7 @@ export interface ToastOptions {
37
37
  }
38
38
 
39
39
  export interface ToastActionProps extends ToastOptions {
40
+ type?: ToastType;
40
41
  text?: {
41
42
  close?: string;
42
43
  action?: string;
@@ -45,10 +46,6 @@ export interface ToastActionProps extends ToastOptions {
45
46
  onClose?: () => void | Promise<void>;
46
47
  }
47
48
 
48
- interface ResolvedToastOptions {
49
- className: ToastClassNames;
50
- }
51
-
52
49
  const DEFAULT_CLASS_NAMES: ToastClassNames = {
53
50
  container: 'j-toast-container',
54
51
  toast: 'j-toast',
@@ -71,309 +68,337 @@ const TOAST_TYPE_RULE = {
71
68
  type: 'string',
72
69
  enum: ['info', 'success', 'warning', 'error', 'primary'],
73
70
  };
71
+ const TOAST_DURATION_RULE = { type: 'number', min: 0 };
72
+ const LITE_DURATION_RULE = { type: 'number', greaterThan: 0 };
74
73
 
75
- const TOAST_DURATION_RULE = {
76
- type: 'number',
77
- min: 0,
78
- };
79
-
80
- const LITE_DURATION_RULE = {
81
- type: 'number',
82
- greaterThan: 0,
83
- };
74
+ const timers = new Set<string>();
75
+ const disposers = new Map<HTMLElement, () => void>();
76
+ const animations = new Map<HTMLElement, Animation>();
77
+ const operations = new Map<HTMLElement, number>();
78
+ let classNames = DEFAULT_CLASS_NAMES;
84
79
 
85
- function mergeClassNames(className?: ToastClassNameConfig): ToastClassNames {
86
- return { ...DEFAULT_CLASS_NAMES, ...className };
80
+ function mergeClassNames(value?: ToastClassNameConfig): ToastClassNames {
81
+ return { ...DEFAULT_CLASS_NAMES, ...value };
87
82
  }
88
83
 
89
- /**
90
- * Toast 消息提示工具。
91
- *
92
- * 以静态方法方式使用,支持多类型堆叠消息和单实例轻提示。
93
- */
94
- export class Toast {
95
- static timers = new Set<string>();
96
- static disposers = new Map<HTMLElement, () => void>();
97
- private static classNames = new WeakMap<HTMLElement, ToastClassNames>();
98
- private static options: ResolvedToastOptions = {
99
- className: DEFAULT_CLASS_NAMES,
100
- };
101
-
102
- static configure(options: ToastOptions = {}): ToastOptions {
103
- Toast.options = {
104
- className: mergeClassNames(options.className),
105
- };
106
- return Toast.options;
107
- }
108
-
109
- private static resolveClassNames(options?: ToastOptions): ToastClassNames {
110
- return mergeClassNames({
111
- ...Toast.options.className,
112
- ...options?.className,
113
- });
114
- }
115
-
116
- static show(
117
- message = '',
118
- duration = 3000,
119
- type: ToastType = 'info',
120
- options: ToastOptions = {}
121
- ): HTMLElement {
122
- validateParam('message', message, 'string', 'Toast.show');
123
- validateParam('duration', duration, TOAST_DURATION_RULE, 'Toast.show');
124
- validateParam('type', type, TOAST_TYPE_RULE, 'Toast.show');
84
+ function resolveClassNames(options?: ToastOptions): ToastClassNames {
85
+ return mergeClassNames({ ...classNames, ...options?.className });
86
+ }
125
87
 
126
- const className = Toast.resolveClassNames(options);
127
- const toastContainer = Toast.getOrCreateContainer(className);
128
- const id = randomId();
129
- const toast = jsx('div', {
130
- className: joinClasses(className.toast, className[type]),
131
- 'data-toast': id,
132
- role: 'alert',
133
- 'aria-atomic': 'true',
134
- children: [
135
- jsx('span', {
136
- className: className.icon,
137
- 'data-toast-icon': id,
138
- children: icon(type === 'primary' ? 'info' : type),
139
- }),
140
- jsx('span', {
141
- className: className.message,
142
- 'data-toast-message': id,
143
- children: message,
144
- }),
145
- ],
88
+ function getOrCreateContainer(names: ToastClassNames): HTMLElement {
89
+ let container = q<HTMLElement>('[data-toast-container]');
90
+ if (!container) {
91
+ container = jsx('div', {
92
+ className: names.container,
93
+ 'data-toast-container': '',
146
94
  }) as HTMLElement;
147
-
148
- Toast.classNames.set(toast, className);
149
- toastContainer.appendChild(toast);
150
-
151
- const v = type === 'error' ? 'assertive' : 'polite';
152
- Toast.setTimer(id, 'show', () => toast.setAttribute('aria-live', v), 10);
153
-
154
- if (duration > 0) {
155
- Toast.setTimer(id, 'hide', () => Toast.hide(toast), duration);
156
- }
157
-
158
- const disposeClick = listen(toast, 'click', () => Toast.hide(toast));
159
- Toast.disposers.set(toast, disposeClick);
160
-
161
- return toast;
162
- }
163
-
164
- static success(
165
- message = '',
166
- duration = 3000,
167
- options: ToastOptions = {}
168
- ): HTMLElement {
169
- return Toast.show(message, duration, 'success', options);
170
- }
171
-
172
- static info(
173
- message = '',
174
- duration = 3000,
175
- options: ToastOptions = {}
176
- ): HTMLElement {
177
- return Toast.show(message, duration, 'info', options);
178
- }
179
-
180
- static primary(
181
- message = '',
182
- duration = 3000,
183
- options: ToastOptions = {}
184
- ): HTMLElement {
185
- return Toast.show(message, duration, 'primary', options);
95
+ insert(document.body, container);
96
+ } else {
97
+ container.className = names.container;
186
98
  }
99
+ return container;
100
+ }
187
101
 
188
- static warning(
189
- message = '',
190
- duration = 3000,
191
- options: ToastOptions = {}
192
- ): HTMLElement {
193
- return Toast.show(message, duration, 'warning', options);
194
- }
102
+ function setToastTimer(
103
+ id: string,
104
+ action: string,
105
+ callback: () => void,
106
+ delay: number
107
+ ): string {
108
+ const key = `${id}-${action}`;
109
+ timers.add(key);
110
+ timer.start(key, delay, () => {
111
+ timers.delete(key);
112
+ callback();
113
+ });
114
+ return key;
115
+ }
195
116
 
196
- static error(
197
- message = '',
198
- duration = 3000,
199
- options: ToastOptions = {}
200
- ): HTMLElement {
201
- return Toast.show(message, duration, 'error', options);
117
+ function cancelToastTimers(id: string): void {
118
+ for (const key of Array.from(timers)) {
119
+ if (!key.startsWith(`${id}-`)) continue;
120
+ timer.cancel(key);
121
+ timers.delete(key);
202
122
  }
123
+ }
203
124
 
204
- static hide(toast: HTMLElement | null | undefined): void {
205
- if (!toast) return;
206
-
207
- Toast.disposers.get(toast)?.();
208
- Toast.disposers.delete(toast);
125
+ function removeToastElement(element: HTMLElement): void {
126
+ animations.get(element)?.cancel();
127
+ animations.delete(element);
128
+ operations.delete(element);
129
+ element.remove();
130
+ disposers.get(element)?.();
131
+ disposers.delete(element);
132
+ const container = q<HTMLElement>('[data-toast-container]');
133
+ if (container && container.children.length === 0) container.remove();
134
+ }
209
135
 
210
- toast.removeAttribute('aria-live');
211
- toast.setAttribute('aria-hidden', 'true');
136
+ function toastAnimationOptions(
137
+ element: HTMLElement,
138
+ duration: number,
139
+ easing: string
140
+ ): KeyframeAnimationOptions {
141
+ const reducedMotion =
142
+ element.ownerDocument.defaultView?.matchMedia?.(
143
+ '(prefers-reduced-motion: reduce)'
144
+ ).matches || false;
145
+ return {
146
+ duration: reducedMotion ? 0 : duration,
147
+ easing,
148
+ fill: 'both',
149
+ };
150
+ }
212
151
 
213
- const id = toast.dataset.toast || randomId();
214
- Toast.setTimer(
215
- id,
216
- 'remove',
217
- () => {
218
- toast.remove();
152
+ function waitForAnimation(animation: Animation): Promise<void> {
153
+ const finished = animation.finished.then(
154
+ () => undefined,
155
+ () => undefined
156
+ );
157
+ return finished;
158
+ }
219
159
 
220
- const container = q<HTMLElement>('[data-toast-container]');
221
- if (container && container.children.length === 0) {
222
- container.remove();
223
- }
224
- },
225
- 300
226
- );
160
+ function toastKeyframes(
161
+ element: HTMLElement,
162
+ phase: 'enter' | 'leave'
163
+ ): Keyframe[] {
164
+ const lite = element.hasAttribute('data-toast-lite');
165
+ if (lite && phase === 'enter') {
166
+ return [{ opacity: 0 }, { opacity: 1 }];
227
167
  }
228
-
229
- static lite(
230
- message = '',
231
- duration = 2000,
232
- options: ToastOptions = {}
233
- ): HTMLElement {
234
- validateParam('message', message, 'string', 'Toast.lite');
235
- validateParam('duration', duration, LITE_DURATION_RULE, 'Toast.lite');
236
-
237
- const className = Toast.resolveClassNames(options);
238
- q<HTMLElement>('[data-toast-lite]')?.remove();
239
-
240
- const id = randomId();
241
- const lite = jsx('div', {
242
- className: className.lite,
243
- 'data-toast': id,
244
- 'data-toast-lite': '',
245
- children: message,
246
- }) as HTMLElement;
247
-
248
- Toast.classNames.set(lite, className);
249
- document.body.appendChild(lite);
250
-
251
- Toast.setTimer(
252
- id,
253
- 'show',
254
- () => lite.setAttribute('aria-live', 'polite'),
255
- 10
256
- );
257
-
258
- Toast.setTimer(
259
- id,
260
- 'hide',
261
- () => {
262
- lite.removeAttribute('aria-live');
263
- lite.setAttribute('aria-hidden', 'true');
264
- Toast.setTimer(id, 'remove', () => lite.remove(), 300);
168
+ if (lite) {
169
+ return [
170
+ { opacity: 1, transform: 'translate(-50%, -50%)' },
171
+ {
172
+ opacity: 0,
173
+ transform: 'translate(-50%, calc(-50% - 8px))',
265
174
  },
266
- duration
267
- );
268
-
269
- return lite;
175
+ ];
270
176
  }
177
+ return phase === 'enter'
178
+ ? [
179
+ { opacity: 0, transform: 'translate3d(0, -16px, 0)' },
180
+ { opacity: 1, transform: 'translate3d(0, 0, 0)' },
181
+ ]
182
+ : [
183
+ { opacity: 1, transform: 'translate3d(0, 0, 0)' },
184
+ { opacity: 0, transform: 'translate3d(0, -16px, 0)' },
185
+ ];
186
+ }
271
187
 
272
- static action(message = '', props: ToastActionProps = {}): HTMLElement {
273
- validateParam('message', message, 'string', 'Toast.action');
274
- const c = t('Close', locales);
275
- const a = t('Confirm', locales);
276
- const className = Toast.resolveClassNames(props);
277
- const toastContainer = Toast.getOrCreateContainer(className);
278
- const id = randomId();
279
- const action = jsx('div', {
280
- className: className.action,
281
- 'data-toast': id,
282
- 'data-toast-action': '',
283
- children: [
284
- jsx('div', {
285
- className: className.message,
286
- 'data-toast-message': id,
287
- children: message,
288
- }),
289
- jsx('div', {
290
- className: className.actions,
291
- 'data-toast-actions': id,
292
- children: [
293
- jsx('button', {
294
- className: joinClasses(className.button, className.closeBtn),
295
- children: props.text?.close || c,
296
- 'data-action': 'close',
297
- 'aria-label': props.text?.close || c,
298
- onClick: async () => {
299
- await props.onClose?.();
300
- Toast.hide(action);
301
- },
302
- }),
303
- jsx('button', {
304
- className: joinClasses(className.button, className.actionBtn),
305
- children: props.text?.action || a,
306
- 'data-action': 'toast-action',
307
- 'aria-label': props.text?.action || a,
308
- onClick: async () => {
309
- await props.onAction?.();
310
- Toast.hide(action);
311
- },
312
- }),
313
- ],
314
- }),
315
- ],
316
- }) as HTMLElement;
317
-
318
- Toast.classNames.set(action, className);
319
- toastContainer.appendChild(action);
188
+ async function playToastAnimation(
189
+ element: HTMLElement,
190
+ phase: 'enter' | 'leave'
191
+ ): Promise<void> {
192
+ const operation = (operations.get(element) || 0) + 1;
193
+ operations.set(element, operation);
194
+ animations.get(element)?.cancel();
195
+ animations.delete(element);
196
+ if (typeof element.animate !== 'function') return;
197
+ const lite = element.hasAttribute('data-toast-lite');
198
+ const animation = element.animate(
199
+ toastKeyframes(element, phase),
200
+ toastAnimationOptions(
201
+ element,
202
+ phase === 'enter' ? (lite ? 150 : 240) : lite ? 120 : 180,
203
+ phase === 'enter'
204
+ ? 'cubic-bezier(0.16, 1, 0.3, 1)'
205
+ : 'cubic-bezier(0.4, 0, 1, 1)'
206
+ )
207
+ );
208
+ animations.set(element, animation);
209
+ await waitForAnimation(animation);
210
+ if (operations.get(element) !== operation) return;
211
+ if (animations.get(element) === animation) animations.delete(element);
212
+ }
320
213
 
321
- Toast.setTimer(
322
- id,
323
- 'show',
324
- () => {
325
- action.setAttribute('aria-live', 'polite');
326
- q<HTMLButtonElement>('[data-action="toast-action"]', action)?.focus();
327
- },
328
- 10
329
- );
214
+ function mountToast(
215
+ element: HTMLElement,
216
+ mount: () => void,
217
+ live: 'assertive' | 'polite',
218
+ onEntered?: () => void
219
+ ): void {
220
+ element.removeAttribute('data-mount');
221
+ element.setAttribute('aria-live', live);
222
+ mount();
223
+ element.getBoundingClientRect();
224
+ void playToastAnimation(element, 'enter').then(() => {
225
+ if (!element.isConnected || element.dataset.mount === 'false') return;
226
+ onEntered?.();
227
+ });
228
+ }
330
229
 
331
- return action;
332
- }
230
+ function hide(toast: HTMLElement | null | undefined): void {
231
+ if (!toast) return;
232
+ if (toast.getAttribute('data-mount') === 'false') return;
233
+ disposers.get(toast)?.();
234
+ disposers.delete(toast);
235
+ const id = toast.dataset.toast || randomId();
236
+ cancelToastTimers(id);
237
+ toast.removeAttribute('aria-live');
238
+ toast.setAttribute('data-mount', 'false');
239
+ void playToastAnimation(toast, 'leave').then(() => {
240
+ if (toast.dataset.mount === 'false') removeToastElement(toast);
241
+ });
242
+ }
333
243
 
334
- private static getOrCreateContainer(className: ToastClassNames): HTMLElement {
335
- let toastContainer = q<HTMLElement>('[data-toast-container]');
336
- if (!toastContainer) {
337
- toastContainer = jsx('div', {
338
- className: className.container,
339
- 'data-toast-container': '',
340
- }) as HTMLElement;
341
- document.body.appendChild(toastContainer);
342
- } else {
343
- toastContainer.className = className.container;
344
- }
345
- return toastContainer;
346
- }
244
+ function show(
245
+ message = '',
246
+ duration = 3000,
247
+ type: ToastType = 'info',
248
+ options: ToastOptions = {}
249
+ ): HTMLElement {
250
+ validateParam('message', message, 'string', 'Toast.show');
251
+ validateParam('duration', duration, TOAST_DURATION_RULE, 'Toast.show');
252
+ validateParam('type', type, TOAST_TYPE_RULE, 'Toast.show');
253
+
254
+ const names = resolveClassNames(options);
255
+ const id = randomId();
256
+ const toast = jsx('div', {
257
+ className: joinClasses(names.toast, names[type]),
258
+ 'data-toast': id,
259
+ role: 'alert',
260
+ 'aria-atomic': 'true',
261
+ children: [
262
+ jsx('span', {
263
+ className: names.icon,
264
+ 'data-toast-icon': id,
265
+ children: icon(type === 'primary' ? 'info' : type),
266
+ }),
267
+ jsx('span', {
268
+ className: names.message,
269
+ 'data-toast-message': id,
270
+ children: message,
271
+ }),
272
+ ],
273
+ }) as HTMLElement;
274
+ mountToast(
275
+ toast,
276
+ () => insert(getOrCreateContainer(names), toast),
277
+ type === 'error' ? 'assertive' : 'polite'
278
+ );
279
+ if (duration > 0) setToastTimer(id, 'hide', () => hide(toast), duration);
280
+ disposers.set(
281
+ toast,
282
+ listen(toast, 'click', () => hide(toast))
283
+ );
284
+ return toast;
285
+ }
347
286
 
348
- private static setTimer(
349
- id: string,
350
- action: string,
351
- callback: () => void,
352
- delay: number
353
- ): string {
354
- const key = `${id}-${action}`;
355
- Toast.timers.add(key);
356
- timer.start(key, delay, () => {
357
- Toast.timers.delete(key);
358
- callback();
359
- });
360
- return key;
287
+ function lite(
288
+ message = '',
289
+ duration = 2000,
290
+ options: ToastOptions = {}
291
+ ): HTMLElement {
292
+ validateParam('message', message, 'string', 'Toast.lite');
293
+ validateParam('duration', duration, LITE_DURATION_RULE, 'Toast.lite');
294
+
295
+ const names = resolveClassNames(options);
296
+ const previous = q<HTMLElement>('[data-toast-lite]');
297
+ if (previous) {
298
+ cancelToastTimers(previous.dataset.toast || '');
299
+ animations.get(previous)?.cancel();
300
+ removeToastElement(previous);
361
301
  }
302
+ const id = randomId();
303
+ const element = jsx('div', {
304
+ className: names.lite,
305
+ 'data-toast': id,
306
+ 'data-toast-lite': '',
307
+ children: message,
308
+ }) as HTMLElement;
309
+ mountToast(element, () => insert(document.body, element), 'polite');
310
+ setToastTimer(id, 'hide', () => hide(element), duration);
311
+ return element;
312
+ }
362
313
 
363
- static clearAll(): void {
364
- for (const key of Toast.timers) {
365
- timer.cancel(key);
314
+ function action(message = '', props: ToastActionProps = {}): HTMLElement {
315
+ validateParam('message', message, 'string', 'Toast.action');
316
+ const closeText = props.text?.close || t('Close', locales);
317
+ const actionText = props.text?.action || t('Confirm', locales);
318
+ const names = resolveClassNames(props);
319
+ const id = randomId();
320
+ const element = jsx('div', {
321
+ className: joinClasses(names.action, names[props.type || 'info']),
322
+ 'data-toast': id,
323
+ 'data-toast-action': '',
324
+ children: [
325
+ jsx('div', {
326
+ className: names.message,
327
+ 'data-toast-message': id,
328
+ children: message,
329
+ }),
330
+ jsx('div', {
331
+ className: names.actions,
332
+ 'data-toast-actions': id,
333
+ children: [
334
+ jsx('button', {
335
+ className: joinClasses(names.button, names.closeBtn),
336
+ children: closeText,
337
+ 'data-action': 'close',
338
+ 'aria-label': closeText,
339
+ onClick: async () => {
340
+ await props.onClose?.();
341
+ hide(element);
342
+ },
343
+ }),
344
+ jsx('button', {
345
+ className: joinClasses(names.button, names.actionBtn),
346
+ children: actionText,
347
+ 'data-action': 'toast-action',
348
+ 'aria-label': actionText,
349
+ onClick: async () => {
350
+ await props.onAction?.();
351
+ hide(element);
352
+ },
353
+ }),
354
+ ],
355
+ }),
356
+ ],
357
+ }) as HTMLElement;
358
+ mountToast(
359
+ element,
360
+ () => insert(getOrCreateContainer(names), element),
361
+ 'polite',
362
+ () => {
363
+ q<HTMLButtonElement>('[data-action="toast-action"]', element)?.focus();
366
364
  }
367
- Toast.timers.clear();
368
-
369
- for (const dispose of Toast.disposers.values()) dispose();
370
- Toast.disposers.clear();
371
-
372
- q<HTMLElement>('[data-toast-container]')?.remove();
373
- q<HTMLElement>('[data-toast-lite]')?.remove();
374
- }
365
+ );
366
+ return element;
367
+ }
375
368
 
376
- static destroyAll(): void {
377
- Toast.clearAll();
378
- }
369
+ function clearAll(): void {
370
+ for (const key of timers) timer.cancel(key);
371
+ timers.clear();
372
+ for (const dispose of disposers.values()) dispose();
373
+ disposers.clear();
374
+ for (const animation of animations.values()) animation.cancel();
375
+ animations.clear();
376
+ operations.clear();
377
+ q<HTMLElement>('[data-toast-container]')?.remove();
378
+ q<HTMLElement>('[data-toast-lite]')?.remove();
379
379
  }
380
+
381
+ export const Toast = {
382
+ timers,
383
+ disposers,
384
+ configure(options: ToastOptions = {}): ToastOptions {
385
+ classNames = mergeClassNames(options.className);
386
+ return { className: classNames };
387
+ },
388
+ show,
389
+ success: (message = '', duration = 3000, options: ToastOptions = {}) =>
390
+ show(message, duration, 'success', options),
391
+ info: (message = '', duration = 3000, options: ToastOptions = {}) =>
392
+ show(message, duration, 'info', options),
393
+ primary: (message = '', duration = 3000, options: ToastOptions = {}) =>
394
+ show(message, duration, 'primary', options),
395
+ warning: (message = '', duration = 3000, options: ToastOptions = {}) =>
396
+ show(message, duration, 'warning', options),
397
+ error: (message = '', duration = 3000, options: ToastOptions = {}) =>
398
+ show(message, duration, 'error', options),
399
+ hide,
400
+ lite,
401
+ action,
402
+ clearAll,
403
+ destroyAll: clearAll,
404
+ };