vgapp 1.1.4 → 1.1.6

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.
@@ -3,38 +3,40 @@ import EventHandler from "../../../utils/js/dom/event";
3
3
  import {dismissTrigger} from "../../module-fn";
4
4
  import {execute, isDisabled, makeRandomString, mergeDeepObject} from "../../../utils/js/functions";
5
5
  import Selectors from "../../../utils/js/dom/selectors";
6
+ import VGToastDrag from "./vgtoast.drag";
7
+ import VGToastResize from "./vgtoast.resize";
6
8
 
7
9
  /**
8
- * @constant {string} NAME - Имя модуля.
10
+ * @constant {string} NAME - Имя модуля.
9
11
  */
10
12
  const NAME = 'toast';
11
13
 
12
14
  /**
13
- * @constant {string} NAME_KEY - Пространство имён для событий.
15
+ * @constant {string} NAME_KEY - Пространство имён для событий.
14
16
  */
15
17
  const NAME_KEY = 'vg.toast';
16
18
 
17
19
  /**
18
- * @constant {string} SELECTOR_DATA_TOGGLE - Селектор для активации через data-атрибут.
20
+ * @constant {string} SELECTOR_DATA_TOGGLE - Селектор для активации через data-атрибут.
19
21
  */
20
22
  const SELECTOR_DATA_TOGGLE = '[data-vg-toggle="toast"]';
21
23
 
22
24
  /**
23
- * @constant {string} CLASS_NAME_OPEN - Класс, добавляемый к body при открытии любого тоста.
25
+ * @constant {string} CLASS_NAME_OPEN - Класс, добавляемый к body при открытии любого тоста.
24
26
  */
25
27
  const CLASS_NAME_OPEN = 'vg-toast-open';
26
28
 
27
29
  /**
28
- * @constant {string} CLASS_NAME_SHOW - Класс, показывающий, что тост видим.
30
+ * @constant {string} CLASS_NAME_SHOW - Класс, показывающий, что тост видим.
29
31
  */
30
32
  const CLASS_NAME_SHOW = 'show';
31
33
 
32
34
  /**
33
- * @constant {string} CLASS_NAME_SHOWN - Класс, добавляемый после завершения анимации появления.
35
+ * @constant {string} CLASS_NAME_SHOWN - Класс, добавляемый после завершения анимации появления.
34
36
  */
35
37
  const CLASS_NAME_SHOWN = 'shown';
36
38
 
37
- // События
39
+ // События
38
40
  const EVENT_KEY_HIDE = `${NAME_KEY}.hide`;
39
41
  const EVENT_KEY_HIDDEN = `${NAME_KEY}.hidden`;
40
42
  const EVENT_KEY_SHOW = `${NAME_KEY}.show`;
@@ -43,36 +45,39 @@ const EVENT_KEY_LOADED = `${NAME_KEY}.loaded`;
43
45
  const EVENT_KEY_KEYDOWN_DISMISS = `keydown.dismiss.${NAME_KEY}`;
44
46
  const EVENT_KEY_HIDE_PREVENTED = `hidePrevented.${NAME_KEY}`;
45
47
  const EVENT_KEY_CLICK_DATA_API = `click.${NAME_KEY}.data.api`;
48
+ const EVENT_KEY_POINTERDOWN_INTERACTION = `pointerdown.interaction.${NAME_KEY}`;
49
+ const EVENT_KEY_POINTERUP_INTERACTION = `pointerup.interaction.${NAME_KEY}`;
50
+ const EVENT_KEY_POINTERCANCEL_INTERACTION = `pointercancel.interaction.${NAME_KEY}`;
46
51
 
47
52
  /**
48
53
  * @typedef {Object} ToastParams
49
- * @property {boolean} static - Сохранять ли тост в DOM после скрытия.
50
- * @property {string} placement - Расположение: 'top left', 'bottom center' и т.д.
51
- * @property {boolean} autohide - Автоматически скрывать.
52
- * @property {number} delay - Задержка перед авто-скрытием (мс).
53
- * @property {boolean} enableClickToast - Закрывать по клику на тост.
54
- * @property {boolean} enableButtonClose - Добавить кнопку закрытия.
55
- * @property {boolean} keyboard - Закрывать по Esc.
56
- * @property {string} theme - Тема: 'dark', 'light' и т.д.
57
- * @property {Object} stack - Настройки стека уведомлений.
58
- * @property {boolean} stack.enable - Разрешить стек.
59
- * @property {number} stack.max - Макс. количество тостов одновременно.
60
- * @property {Object} animation - Анимация.
61
- * @property {boolean} animation.enable - Включить анимацию.
62
- * @property {string} animation.in - Анимация входа (Animate.css).
63
- * @property {string} animation.out - Анимация выхода.
64
- * @property {number} animation.delay - Длительность анимации.
65
- * @property {Object} ajax - Настройки AJAX.
66
- * @property {string} ajax.route - URL для загрузки.
67
- * @property {string} ajax.target - Селектор контейнера.
68
- * @property {string} ajax.method - HTTP-метод.
69
- * @property {boolean} ajax.loader - Показывать лоадер.
70
- * @property {boolean} ajax.once - Загружать один раз.
71
- * @property {boolean} ajax.output - Выводить результат.
54
+ * @property {boolean} static - Сохранять ли тост в DOM после скрытия.
55
+ * @property {string} placement - Расположение: 'top left', 'bottom center' и т.д.
56
+ * @property {boolean} autohide - Автоматически скрывать.
57
+ * @property {number} delay - Задержка перед авто-скрытием (мс).
58
+ * @property {boolean} enableClickToast - Закрывать по клику на тост.
59
+ * @property {boolean} enableButtonClose - Добавить кнопку закрытия.
60
+ * @property {boolean} keyboard - Закрывать по Esc.
61
+ * @property {string} theme - Тема: 'dark', 'light' и т.д.
62
+ * @property {Object} stack - Настройки стека уведомлений.
63
+ * @property {boolean} stack.enable - Разрешить стек.
64
+ * @property {number} stack.max - Макс. количество тостов одновременно.
65
+ * @property {Object} animation - Анимация.
66
+ * @property {boolean} animation.enable - Включить анимацию.
67
+ * @property {string} animation.in - Анимация входа (Animate.css).
68
+ * @property {string} animation.out - Анимация выхода.
69
+ * @property {number} animation.delay - Длительность анимации.
70
+ * @property {Object} ajax - Настройки AJAX.
71
+ * @property {string} ajax.route - URL для загрузки.
72
+ * @property {string} ajax.target - Селектор контейнера.
73
+ * @property {string} ajax.method - HTTP-метод.
74
+ * @property {boolean} ajax.loader - Показывать лоадер.
75
+ * @property {boolean} ajax.once - Загружать один раз.
76
+ * @property {boolean} ajax.output - Выводить результат.
72
77
  */
73
78
 
74
79
  /**
75
- * Параметры по умолчанию
80
+ * Параметры по умолчанию
76
81
  * @type {ToastParams}
77
82
  */
78
83
  const defaultParams = {
@@ -88,6 +93,20 @@ const defaultParams = {
88
93
  enable: true,
89
94
  max: 5
90
95
  },
96
+ drag: {
97
+ enable: false,
98
+ selector: '.vg-toast-wrapper',
99
+ threshold: 4,
100
+ resizeEdgeSize: 8,
101
+ debug: false,
102
+ },
103
+ resize: {
104
+ enable: false,
105
+ edgeSize: 8,
106
+ minWidth: 220,
107
+ minHeight: 64,
108
+ debug: false,
109
+ },
91
110
  animation: {
92
111
  enable: true,
93
112
  in: 'animate__backInUp',
@@ -105,20 +124,41 @@ const defaultParams = {
105
124
  };
106
125
 
107
126
  /**
108
- * Класс VGToast модуль уведомлений (тосты)
109
- * Поддерживает стек, анимации, авто-скрытие, AJAX-контент, горячие клавиши.
127
+ * Класс VGToast — модуль уведомлений (тосты)
128
+ * Поддерживает стек, анимации, авто-скрытие, AJAX-контент, горячие клавиши.
110
129
  */
111
130
  class VGToast extends BaseModule {
112
131
  /**
113
- * Создаёт экземпляр VGToast
114
- * @param {Element} element - HTML-элемент тоста.
115
- * @param {Partial<ToastParams>} params - Пользовательские параметры.
132
+ * Создаёт экземпляр VGToast
133
+ * @param {Element} element - HTML-элемент тоста.
134
+ * @param {Partial<ToastParams>} params - Пользовательские параметры.
116
135
  */
117
136
  constructor(element, params = {}) {
118
137
  super(element, params);
119
138
 
120
139
  /** @private */
140
+ this._interactionDefaults = {
141
+ drag: {
142
+ enable: false,
143
+ selector: '.vg-toast-wrapper',
144
+ threshold: 4,
145
+ resizeEdgeSize: 8,
146
+ debug: false,
147
+ },
148
+ resize: {
149
+ enable: false,
150
+ edgeSize: 8,
151
+ minWidth: 220,
152
+ minHeight: 64,
153
+ debug: false,
154
+ },
155
+ };
121
156
  this._params = this._getParams(element, mergeDeepObject(defaultParams, params));
157
+ this._dragHandler = new VGToastDrag(this._element, this._element);
158
+ this._resizeHandler = new VGToastResize(this._element, this._element);
159
+ this._interactionConfig = this._resolveInteractionConfig();
160
+ this._dragHandler.setOptions(this._interactionConfig.drag);
161
+ this._resizeHandler.setOptions(this._interactionConfig.resize);
122
162
  this._animation(this._element, VGToast.NAME_KEY, this._params.animation);
123
163
  this._dismissElement();
124
164
  this._addEventListeners();
@@ -128,7 +168,7 @@ class VGToast extends BaseModule {
128
168
  }
129
169
 
130
170
  /**
131
- * Имя модуля
171
+ * Имя модуля
132
172
  * @returns {string}
133
173
  */
134
174
  static get NAME() {
@@ -136,7 +176,7 @@ class VGToast extends BaseModule {
136
176
  }
137
177
 
138
178
  /**
139
- * Пространство имён событий
179
+ * Пространство имён событий
140
180
  * @returns {string}
141
181
  */
142
182
  static get NAME_KEY() {
@@ -144,10 +184,10 @@ class VGToast extends BaseModule {
144
184
  }
145
185
 
146
186
  /**
147
- * Глобальный метод для быстрого создания тоста
148
- * @param {string|Array<string>} text - Текст или [заголовок, тело].
149
- * @param {Partial<ToastParams>} [params] - Параметры.
150
- * @param {Function} [callback] - Вызывается после создания.
187
+ * Глобальный метод для быстрого создания тоста
188
+ * @param {string|Array<string>} text - Текст или [заголовок, тело].
189
+ * @param {Partial<ToastParams>} [params] - Параметры.
190
+ * @param {Function} [callback] - Вызывается после создания.
151
191
  * @returns {VGToast}
152
192
  */
153
193
  static run(text, params = {}, callback) {
@@ -155,26 +195,31 @@ class VGToast extends BaseModule {
155
195
  }
156
196
 
157
197
  /**
158
- * Создаёт и показывает новый тост
159
- * @param {string|Array<string>} text - Текст уведомления.
160
- * @param {Partial<ToastParams>} [params] - Параметры.
161
- * @param {Function} [callback] - Вызывается после появления.
198
+ * Создаёт и показывает новый тост
199
+ * @param {string|Array<string>} text - Текст уведомления.
200
+ * @param {Partial<ToastParams>} [params] - Параметры.
201
+ * @param {Function} [callback] - Вызывается после появления.
162
202
  * @returns {VGToast}
163
203
  */
164
204
  static build(text, params, callback) {
165
- params = mergeDeepObject(defaultParams, { static: false, autohide: true }, params);
205
+ const rawParams = params && typeof params === 'object' ? params : {};
206
+ const hasAutohideParam = Object.prototype.hasOwnProperty.call(rawParams, 'autohide');
207
+ params = mergeDeepObject(defaultParams, { static: false, autohide: true }, rawParams);
208
+ if (params.static && !hasAutohideParam) {
209
+ params.autohide = false;
210
+ }
166
211
 
167
212
  const id = 'vg-toast-' + makeRandomString();
168
213
  const target = document.createElement('div');
169
214
  target.classList.add('vg-toast');
170
215
  target.id = id;
171
216
 
172
- // Тема
217
+ // Тема
173
218
  if (params.theme) {
174
219
  target.classList.add(`vg-toast-${params.theme}`);
175
220
  }
176
221
 
177
- // Позиция
222
+ // Позиция
178
223
  if (params.placement) {
179
224
  params.placement.split(' ').forEach(cls => target.classList.add(cls));
180
225
  }
@@ -182,7 +227,7 @@ class VGToast extends BaseModule {
182
227
  const wrapper = document.createElement('div');
183
228
  wrapper.classList.add('vg-toast-wrapper');
184
229
 
185
- // Иконка (если задан тип)
230
+ // Иконка (если задан тип)
186
231
  if (params.type) {
187
232
  const icon = document.createElement('div');
188
233
  icon.classList.add('vg-toast-icon');
@@ -211,7 +256,7 @@ class VGToast extends BaseModule {
211
256
 
212
257
  wrapper.append(content);
213
258
 
214
- // Кнопка закрытия
259
+ // Кнопка закрытия
215
260
  if (params.enableButtonClose) {
216
261
  const button = document.createElement('div');
217
262
  button.classList.add('vg-toast-button');
@@ -234,8 +279,8 @@ class VGToast extends BaseModule {
234
279
  }
235
280
 
236
281
  /**
237
- * Переключает состояние (показать/скрыть)
238
- * @param {Element} [relatedTarget] - Элемент, вызвавший тост.
282
+ * Переключает состояние (показать/скрыть)
283
+ * @param {Element} [relatedTarget] - Элемент, вызвавший тост.
239
284
  * @returns {VGToast}
240
285
  */
241
286
  toggle(relatedTarget) {
@@ -243,14 +288,15 @@ class VGToast extends BaseModule {
243
288
  }
244
289
 
245
290
  /**
246
- * Показывает тост
247
- * @param {Element} [relatedTarget] - Элемент, инициировавший показ.
291
+ * Показывает тост
292
+ * @param {Element} [relatedTarget] - Элемент, инициировавший показ.
248
293
  * @returns {void}
249
294
  */
250
295
  show(relatedTarget) {
251
296
  if (isDisabled(this._element)) return;
252
297
 
253
298
  this._clearTimeout();
299
+ this._disableInteractionHandlers();
254
300
 
255
301
  this._params = this._getParams(relatedTarget || {}, this._params);
256
302
  this._route((status, data) => {
@@ -268,6 +314,8 @@ class VGToast extends BaseModule {
268
314
 
269
315
  const completeCallBack = () => {
270
316
  this._element.classList.add(CLASS_NAME_SHOWN);
317
+ this._toggleInteractionHandlers();
318
+ this._syncInteractiveBounds();
271
319
  this._scheduleHide();
272
320
  EventHandler.trigger(this._element, EVENT_KEY_SHOWN, { relatedTarget });
273
321
  };
@@ -276,7 +324,7 @@ class VGToast extends BaseModule {
276
324
  }
277
325
 
278
326
  /**
279
- * Скрывает тост
327
+ * Скрывает тост
280
328
  * @returns {void}
281
329
  */
282
330
  hide() {
@@ -287,6 +335,7 @@ class VGToast extends BaseModule {
287
335
  if (hideEvent.defaultPrevented) return;
288
336
 
289
337
  this._element.classList.remove(CLASS_NAME_SHOWN);
338
+ this._disableInteractionHandlers();
290
339
 
291
340
  setTimeout(() => {
292
341
  this._element.classList.remove(CLASS_NAME_SHOW);
@@ -310,11 +359,12 @@ class VGToast extends BaseModule {
310
359
  }
311
360
 
312
361
  /**
313
- * Удаляет тост из DOM и снимает обработчики
362
+ * Удаляет тост из DOM и снимает обработчики
314
363
  * @override
315
364
  */
316
365
  dispose() {
317
366
  this._clearTimeout();
367
+ this._disableInteractionHandlers();
318
368
  if (!this._params.static) {
319
369
  this._element.remove();
320
370
  }
@@ -322,17 +372,18 @@ class VGToast extends BaseModule {
322
372
  }
323
373
 
324
374
  /**
325
- * Устанавливает таймер на скрытие
375
+ * Устанавливает таймер на скрытие
326
376
  * @private
327
377
  */
328
378
  _scheduleHide() {
379
+ this._clearTimeout();
329
380
  if (!this._params.autohide) return;
330
381
 
331
382
  this._timeout = setTimeout(() => this.hide(), this._params.delay);
332
383
  }
333
384
 
334
385
  /**
335
- * Проверяет, показан ли тост
386
+ * Проверяет, показан ли тост
336
387
  * @private
337
388
  * @returns {boolean}
338
389
  */
@@ -341,17 +392,17 @@ class VGToast extends BaseModule {
341
392
  }
342
393
 
343
394
  /**
344
- * Возвращает список активных тостов с вертикальными смещениями
345
- * Учитывает стек и максимальное количество
395
+ * Возвращает список активных тостов с вертикальными смещениями
396
+ * Учитывает стек и максимальное количество
346
397
  * @private
347
398
  * @returns {Array<{el: Element, top: number}>}
348
399
  */
349
400
  _enableStack() {
350
401
  const placement = this._params.placement;
351
402
  const isTop = placement.includes('top');
352
- const isBottom = !isTop; // по умолчанию снизу
403
+ const isBottom = !isTop; // по умолчанию снизу
353
404
 
354
- // Фильтруем тосты с таким же направлением (top или bottom)
405
+ // Фильтруем тосты с таким же направлением (top или bottom)
355
406
  const stackClass = isTop ? 'top' : 'bottom';
356
407
  const elmsShown = Selectors.findAll(`.vg-toast.show.${stackClass}`)
357
408
  .filter(el => {
@@ -360,20 +411,20 @@ class VGToast extends BaseModule {
360
411
  });
361
412
 
362
413
  if (!this._params.stack.enable) {
363
- // Скрываем другие тосты, если стек выключен
414
+ // Скрываем другие тосты, если стек выключен
364
415
  elmsShown
365
416
  .filter(el => el !== this._element)
366
417
  .forEach(el => VGToast.getInstance(el).hide());
367
418
  return [{ el: this._element, top: 0 }];
368
419
  }
369
420
 
370
- // Ограничиваем по max
421
+ // Ограничиваем по max
371
422
  if (elmsShown.length >= this._params.stack.max) {
372
423
  const excess = elmsShown.slice(0, elmsShown.length - this._params.stack.max + 1);
373
424
  excess.forEach(el => VGToast.getInstance(el).hide());
374
425
  }
375
426
 
376
- // Вычисляем смещение (по высоте)
427
+ // Вычисляем смещение (по высоте)
377
428
  const prevEls = elmsShown.filter(el => el !== this._element);
378
429
  const offset = prevEls.reduce((sum, el) => sum + el.clientHeight, 0);
379
430
 
@@ -386,7 +437,7 @@ class VGToast extends BaseModule {
386
437
  }
387
438
 
388
439
  /**
389
- * Устанавливает позицию тостов с учётом стека
440
+ * Устанавливает позицию тостов с учётом стека
390
441
  * @private
391
442
  */
392
443
  _setPlacement() {
@@ -414,17 +465,17 @@ class VGToast extends BaseModule {
414
465
  style.top = '';
415
466
  style.bottom = '';
416
467
  style.transform = '';
417
- style.translate = ''; // <-- важно: сбрасываем translate отдельно
468
+ style.translate = ''; // <-- важно: сбрасываем translate отдельно
418
469
 
419
470
  if (isCenter) {
420
471
  style.left = '50%';
421
- style.translate = '-50% 0'; // <-- вместо transform: translateX(-50%)
472
+ style.translate = '-50% 0'; // <-- вместо transform: translateX(-50%)
422
473
  } else if (isLeft) {
423
474
  style.left = '0';
424
475
  } else if (isRight) {
425
476
  style.right = '0';
426
477
  } else {
427
- // по умолчанию: центрирование
478
+ // по умолчанию: центрирование
428
479
  style.left = '50%';
429
480
  style.translate = '-50% 0';
430
481
  }
@@ -440,9 +491,66 @@ class VGToast extends BaseModule {
440
491
  }
441
492
 
442
493
  /**
443
- * Очищает таймер
494
+ * Очищает таймер
444
495
  * @private
445
496
  */
497
+ _toggleInteractionHandlers() {
498
+ this._interactionConfig = this._resolveInteractionConfig();
499
+ this._dragHandler.setOptions(this._interactionConfig.drag);
500
+ this._resizeHandler.setOptions(this._interactionConfig.resize);
501
+
502
+ if (this._interactionConfig.drag.enable) {
503
+ this._dragHandler.enable();
504
+ } else {
505
+ this._dragHandler.disable();
506
+ }
507
+
508
+ if (this._interactionConfig.resize.enable) {
509
+ this._resizeHandler.enable();
510
+ } else {
511
+ this._resizeHandler.disable();
512
+ }
513
+ }
514
+
515
+ _disableInteractionHandlers() {
516
+ this._dragHandler.disable();
517
+ this._resizeHandler.disable();
518
+ }
519
+
520
+ _syncInteractiveBounds() {
521
+ if (this._interactionConfig.resize.enable) {
522
+ this._resizeHandler.syncToViewport();
523
+ }
524
+
525
+ if (this._interactionConfig.drag.enable) {
526
+ this._dragHandler.syncPosition();
527
+ }
528
+ }
529
+
530
+ _resolveInteractionConfig() {
531
+ return {
532
+ drag: this._normalizeInteractionParams(this._params.drag, this._interactionDefaults.drag),
533
+ resize: this._normalizeInteractionParams(this._params.resize, this._interactionDefaults.resize),
534
+ };
535
+ }
536
+
537
+ _normalizeInteractionParams(paramsValue, defaults) {
538
+ if (typeof paramsValue === 'boolean') {
539
+ return {...defaults, enable: paramsValue};
540
+ }
541
+
542
+ if (paramsValue && typeof paramsValue === 'object') {
543
+ const hasEnable = Object.prototype.hasOwnProperty.call(paramsValue, 'enable');
544
+ return {
545
+ ...defaults,
546
+ ...paramsValue,
547
+ enable: hasEnable ? Boolean(paramsValue.enable) : true,
548
+ };
549
+ }
550
+
551
+ return {...defaults};
552
+ }
553
+
446
554
  _clearTimeout() {
447
555
  if (this._timeout) {
448
556
  clearTimeout(this._timeout);
@@ -451,11 +559,11 @@ class VGToast extends BaseModule {
451
559
  }
452
560
 
453
561
  /**
454
- * Назначает обработчики событий
562
+ * Назначает обработчики событий
455
563
  * @private
456
564
  */
457
565
  _addEventListeners() {
458
- // Закрытие по Esc
566
+ // Закрытие по Esc
459
567
  if (this._params.keyboard) {
460
568
  EventHandler.on(document, EVENT_KEY_KEYDOWN_DISMISS, event => {
461
569
  if (event.key === 'Escape' && this._isShown()) {
@@ -464,21 +572,34 @@ class VGToast extends BaseModule {
464
572
  });
465
573
  }
466
574
 
467
- // Закрытие по клику на тост
575
+ // Закрытие по клику на тост
468
576
  if (this._params.enableClickToast) {
469
577
  this._element.classList.add('vg-toast-pointer');
470
578
  EventHandler.on(document, EVENT_KEY_CLICK_DATA_API, `#${this._element.id}`, () => {
471
579
  this.hide();
472
580
  });
473
581
  }
582
+
583
+ EventHandler.on(this._element, EVENT_KEY_POINTERDOWN_INTERACTION, () => {
584
+ this._clearTimeout();
585
+ });
586
+
587
+ const resumeHide = () => {
588
+ if (this._isShown()) {
589
+ this._scheduleHide();
590
+ }
591
+ };
592
+
593
+ EventHandler.on(this._element, EVENT_KEY_POINTERUP_INTERACTION, resumeHide);
594
+ EventHandler.on(this._element, EVENT_KEY_POINTERCANCEL_INTERACTION, resumeHide);
474
595
  }
475
596
  }
476
597
 
477
- // Автоматическое закрытие по data-vg-dismiss
598
+ // Автоматическое закрытие по data-vg-dismiss
478
599
  dismissTrigger(VGToast);
479
600
 
480
601
  /**
481
- * Реализация Data API
602
+ * Реализация Data API
482
603
  */
483
604
  EventHandler.on(document, EVENT_KEY_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
484
605
  const target = Selectors.getElementFromSelector(this);
@@ -497,3 +618,4 @@ EventHandler.on(document, EVENT_KEY_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, functi
497
618
  });
498
619
 
499
620
  export default VGToast;
621
+