vgapp 0.8.1 → 0.8.2
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/CHANGELOG.md +10 -0
- package/app/langs/en/buttons.json +8 -0
- package/app/langs/en/messages.json +3 -0
- package/app/langs/en/titles.json +3 -0
- package/app/langs/ru/buttons.json +8 -0
- package/app/langs/ru/messages.json +3 -0
- package/app/langs/ru/titles.json +3 -0
- package/app/modules/vgloadmore/js/vgloadmore.js +159 -8
- package/app/modules/vgrollup/js/vgrollup.js +328 -160
- package/app/modules/vgrollup/readme.md +196 -0
- package/app/modules/vgselect/js/handlers.js +220 -0
- package/app/modules/vgselect/js/vgselect.js +783 -298
- package/app/modules/vgselect/readme.md +180 -0
- package/app/modules/vgselect/scss/_variables.scss +20 -0
- package/app/modules/vgselect/scss/vgselect.scss +42 -2
- package/app/modules/vgsidebar/js/vgsidebar.js +194 -84
- package/app/modules/vgsidebar/readme.md +157 -0
- package/app/modules/vgspy/js/vgspy.js +236 -132
- package/app/modules/vgspy/readme.md +105 -0
- package/app/modules/vgtabs/js/vgtabs.js +290 -182
- package/app/modules/vgtabs/readme.md +156 -0
- package/app/modules/vgtoast/js/vgtoast.js +260 -156
- package/app/modules/vgtoast/readme.md +145 -0
- package/build/vgapp.css +1 -1
- package/build/vgapp.css.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
# VEGAS-APP 0.8.2 (Январь, 4, 2025)
|
|
2
|
+
* Оптимизирован модуль VGRollup, см. файл readme.md
|
|
3
|
+
* Оптимизирован модуль VGSidebar, см. файл readme.md
|
|
4
|
+
* Оптимизирован модуль VGTabs, см. файл readme.md
|
|
5
|
+
* Оптимизирован модуль VGSpy, см. файл readme.md
|
|
6
|
+
* Оптимизирован модуль VGToast, см. файл readme.md
|
|
7
|
+
* Оптимизирован и дополнен модуль VGSelect, см. файл readme.md
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
1
11
|
# VEGAS-APP 0.8.1 (Январь, 2, 2025)
|
|
2
12
|
* Оптимизирован и дополнен модуль VGLoadMore, см. файл readme.md
|
|
3
13
|
|
package/app/langs/en/titles.json
CHANGED
package/app/langs/ru/titles.json
CHANGED
|
@@ -3,10 +3,65 @@ import EventHandler from "../../../utils/js/dom/event";
|
|
|
3
3
|
import { execute, isObject, mergeDeepObject, normalizeData } from "../../../utils/js/functions";
|
|
4
4
|
import Selectors from "../../../utils/js/dom/selectors";
|
|
5
5
|
import { Manipulator } from "../../../utils/js/dom/manipulator";
|
|
6
|
-
import {lang_buttons} from "../../../utils/js/components/lang";
|
|
6
|
+
import { lang_buttons } from "../../../utils/js/components/lang";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} VGLoadMoreParams
|
|
10
|
+
* @property {string} [lang='ru'] - Язык интерфейса (используется для локализации)
|
|
11
|
+
* @property {number} limit - Количество элементов, загружаемых за один раз
|
|
12
|
+
* @property {number} offset - Начальный сдвиг при загрузке
|
|
13
|
+
* @property {boolean} output - Вставлять ли ответ в DOM
|
|
14
|
+
* @property {boolean} autohide - Автоматически скрывать/удалять кнопку при достижении конца
|
|
15
|
+
* @property {boolean} animate - Анимировать появление новых элементов
|
|
16
|
+
* @property {string} append - Позиция вставки: 'after' (в конец) или 'before' (в начало)
|
|
17
|
+
* @property {string} mode - Режим загрузки: 'button' или 'scroll'
|
|
18
|
+
* @property {number} threshold - Отступ в пикселях для срабатывания при прокрутке
|
|
19
|
+
* @property {boolean} debug - Включить отладочные сообщения в консоли
|
|
20
|
+
* @property {boolean} detach - Удалять кнопку из DOM после использования
|
|
21
|
+
* @property {Object} button - Настройки кнопки
|
|
22
|
+
* @property {string} button.text - Текст кнопки по умолчанию
|
|
23
|
+
* @property {string} button.send - Текст во время AJAX-загрузки
|
|
24
|
+
* @property {string} button.show - Текст во время статической загрузки
|
|
25
|
+
* @property {boolean} button.loader - Показывать лоадер
|
|
26
|
+
* @property {string[]} button.classes - CSS-классы кнопки
|
|
27
|
+
* @property {Object} ajax - Настройки AJAX-запроса
|
|
28
|
+
* @property {string} ajax.route - URL для загрузки данных
|
|
29
|
+
* @property {string} ajax.target - Селектор контейнера для вставки
|
|
30
|
+
* @property {string} ajax.method - HTTP-метод ('get', 'post')
|
|
31
|
+
* @property {boolean} ajax.loader - Использовать лоадер
|
|
32
|
+
* @property {boolean} ajax.once - Загружать только один раз
|
|
33
|
+
* @property {boolean} ajax.output - Выводить ли ответ
|
|
34
|
+
* @property {Object} ajax.data - Дополнительные данные для запроса
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @class VGLoadMore
|
|
39
|
+
* @extends BaseModule
|
|
40
|
+
* @description
|
|
41
|
+
* Модуль подгрузки контента по кнопке или при прокрутке.
|
|
42
|
+
* Поддерживает как статическую подгрузку скрытых элементов из DOM,
|
|
43
|
+
* так и AJAX-загрузку с сервера. Имеет гибкую настройку через data-атрибуты,
|
|
44
|
+
* поддержку языков, анимаций и отладку.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* <!-- Простая подгрузка по кнопке -->
|
|
48
|
+
* <div data-vgloadmore data-limit="3" data-elements="item">
|
|
49
|
+
* <div class="item vg-collapse">Элемент 1</div>
|
|
50
|
+
* <div class="item vg-collapse">Элемент 2</div>
|
|
51
|
+
* ...
|
|
52
|
+
* </div>
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* <!-- AJAX-подгрузка при прокрутке -->
|
|
56
|
+
* <div data-vgloadmore
|
|
57
|
+
* data-ajax-route="/api/load"
|
|
58
|
+
* data-mode="scroll"
|
|
59
|
+
* data-threshold="200">
|
|
60
|
+
* </div>
|
|
61
|
+
*/
|
|
7
62
|
|
|
8
63
|
const NAME = 'loadmore';
|
|
9
|
-
const NAME_KEY = 'vg.
|
|
64
|
+
const NAME_KEY = 'vg.' + NAME;
|
|
10
65
|
const SELECTOR_DATA_TOGGLE = '[data-vg-toggle="loadmore"]';
|
|
11
66
|
const SELECTOR_DATA_MODULE = '[data-vgloadmore]';
|
|
12
67
|
|
|
@@ -17,9 +72,29 @@ const CLASS_NAME_SHOW = 'show';
|
|
|
17
72
|
const EVENT_KEY_CLICK_DATA_API = `click.${NAME_KEY}.data.api`;
|
|
18
73
|
|
|
19
74
|
class VGLoadMore extends BaseModule {
|
|
75
|
+
/**
|
|
76
|
+
* Имя модуля
|
|
77
|
+
* @type {string}
|
|
78
|
+
*/
|
|
79
|
+
static get NAME() { return NAME; }
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Ключ события модуля
|
|
83
|
+
* @type {string}
|
|
84
|
+
*/
|
|
85
|
+
static get NAME_KEY() { return NAME_KEY; }
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
20
90
|
constructor(element, params) {
|
|
21
91
|
super(element, params);
|
|
22
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Параметры модуля
|
|
95
|
+
* @type {VGLoadMoreParams}
|
|
96
|
+
* @private
|
|
97
|
+
*/
|
|
23
98
|
this._params = this._getParams(element, mergeDeepObject({
|
|
24
99
|
lang: document.documentElement.lang || 'ru',
|
|
25
100
|
limit: 0,
|
|
@@ -50,10 +125,28 @@ class VGLoadMore extends BaseModule {
|
|
|
50
125
|
}
|
|
51
126
|
}, params));
|
|
52
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Обсервер пересечения (для режима scroll)
|
|
130
|
+
* @type {IntersectionObserver|null}
|
|
131
|
+
* @private
|
|
132
|
+
*/
|
|
53
133
|
this._observer = null;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Режим прокрутки включён
|
|
137
|
+
* @type {boolean}
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
54
140
|
this._isScrollMode = this._params.mode === 'scroll';
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Элемент является триггером (имеет data-vg-toggle)
|
|
144
|
+
* @type {boolean}
|
|
145
|
+
* @private
|
|
146
|
+
*/
|
|
55
147
|
this._isToggleElement = element.hasAttribute('data-vg-toggle');
|
|
56
148
|
|
|
149
|
+
// Локализация текстов кнопок
|
|
57
150
|
this._params.button.send = lang_buttons(this._params.lang, NAME)['send'];
|
|
58
151
|
this._params.button.show = lang_buttons(this._params.lang, NAME)['show'];
|
|
59
152
|
|
|
@@ -70,15 +163,20 @@ class VGLoadMore extends BaseModule {
|
|
|
70
163
|
}
|
|
71
164
|
}
|
|
72
165
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Инициализация, если элемент — кнопка-триггер
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
76
170
|
_initializeAsButton() {
|
|
77
171
|
if (this._isScrollMode) {
|
|
78
172
|
this._initScrollMode();
|
|
79
173
|
}
|
|
80
174
|
}
|
|
81
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Инициализация контейнера с элементами
|
|
178
|
+
* @private
|
|
179
|
+
*/
|
|
82
180
|
_initializeContainer() {
|
|
83
181
|
const { elements: itemClass, limit } = this._params;
|
|
84
182
|
const container = this._element;
|
|
@@ -104,6 +202,11 @@ class VGLoadMore extends BaseModule {
|
|
|
104
202
|
}
|
|
105
203
|
}
|
|
106
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Создаёт и вставляет кнопку управления
|
|
207
|
+
* @param {HTMLElement} container - Контейнер, рядом с которым вставляется кнопка
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
107
210
|
_createAndInsertButton(container) {
|
|
108
211
|
const button = document.createElement('button');
|
|
109
212
|
const buttonText = normalizeData(container.dataset.buttonText) || this._params.button.text;
|
|
@@ -136,11 +239,19 @@ class VGLoadMore extends BaseModule {
|
|
|
136
239
|
container.parentNode.insertBefore(button, container.nextSibling);
|
|
137
240
|
}
|
|
138
241
|
|
|
242
|
+
/**
|
|
243
|
+
* Инициализирует режим прокрутки
|
|
244
|
+
* @private
|
|
245
|
+
*/
|
|
139
246
|
_initScrollMode() {
|
|
140
247
|
this._setupIntersectionObserver();
|
|
141
248
|
this._observeLastVisibleItem();
|
|
142
249
|
}
|
|
143
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Настраивает IntersectionObserver для отслеживания видимости последнего элемента
|
|
253
|
+
* @private
|
|
254
|
+
*/
|
|
144
255
|
_setupIntersectionObserver() {
|
|
145
256
|
if (this._observer) return;
|
|
146
257
|
|
|
@@ -158,6 +269,10 @@ class VGLoadMore extends BaseModule {
|
|
|
158
269
|
});
|
|
159
270
|
}
|
|
160
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Начинает отслеживание последнего видимого элемента
|
|
274
|
+
* @private
|
|
275
|
+
*/
|
|
161
276
|
_observeLastVisibleItem() {
|
|
162
277
|
if (!this._observer) return;
|
|
163
278
|
|
|
@@ -173,6 +288,13 @@ class VGLoadMore extends BaseModule {
|
|
|
173
288
|
}
|
|
174
289
|
}
|
|
175
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Основной метод подгрузки — вызывается по клику или при прокрутке
|
|
293
|
+
* @param {Function} [callback] - Колбэк, вызываемый после загрузки
|
|
294
|
+
* @fires VGLoadMore#vg.loadmore.before.load
|
|
295
|
+
* @fires VGLoadMore#vg.loadmore.loaded
|
|
296
|
+
* @public
|
|
297
|
+
*/
|
|
176
298
|
toggle(callback) {
|
|
177
299
|
this._params.debug && console.log('[VGLoadMore] toggle()');
|
|
178
300
|
|
|
@@ -187,6 +309,11 @@ class VGLoadMore extends BaseModule {
|
|
|
187
309
|
this._params.ajax.route ? this.ajax(callback) : this.staticLoad(callback);
|
|
188
310
|
}
|
|
189
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Выполняет AJAX-запрос для подгрузки данных
|
|
314
|
+
* @param {Function} [callback] - Колбэк после завершения
|
|
315
|
+
* @private
|
|
316
|
+
*/
|
|
190
317
|
ajax(callback) {
|
|
191
318
|
const targetSelector = this._params.ajax.target?.trim();
|
|
192
319
|
let targetEl = null;
|
|
@@ -194,16 +321,16 @@ class VGLoadMore extends BaseModule {
|
|
|
194
321
|
if (targetSelector) {
|
|
195
322
|
targetEl = Selectors.find(targetSelector);
|
|
196
323
|
} else {
|
|
197
|
-
targetEl = this._element
|
|
324
|
+
targetEl = this._element;
|
|
198
325
|
}
|
|
199
326
|
|
|
200
|
-
const originalText = this._params.button.text;
|
|
201
|
-
|
|
202
327
|
if (!targetEl) {
|
|
203
328
|
console.error('[VGLoadMore] target элемент не найден:', this._params.ajax.target);
|
|
204
329
|
return;
|
|
205
330
|
}
|
|
206
331
|
|
|
332
|
+
const originalText = this._params.button.text;
|
|
333
|
+
|
|
207
334
|
this._params.ajax.data = { limit: this._params.limit, offset: this._params.offset };
|
|
208
335
|
|
|
209
336
|
this._route((status, data, responseTarget) => {
|
|
@@ -233,6 +360,11 @@ class VGLoadMore extends BaseModule {
|
|
|
233
360
|
});
|
|
234
361
|
}
|
|
235
362
|
|
|
363
|
+
/**
|
|
364
|
+
* Подгружает элементы из DOM (статический режим)
|
|
365
|
+
* @param {Function} [callback] - Колбэк после завершения
|
|
366
|
+
* @private
|
|
367
|
+
*/
|
|
236
368
|
staticLoad(callback) {
|
|
237
369
|
const container = Selectors.find(this._params.target) || this._element.parentNode;
|
|
238
370
|
const items = Selectors.findAll(`.${this._params.elements}`, container);
|
|
@@ -270,6 +402,11 @@ class VGLoadMore extends BaseModule {
|
|
|
270
402
|
execute(callback, [this, this._element]);
|
|
271
403
|
}
|
|
272
404
|
|
|
405
|
+
/**
|
|
406
|
+
* Восстанавливает состояние кнопки (включает, устанавливает текст)
|
|
407
|
+
* @param {string} text - Текст кнопки
|
|
408
|
+
* @private
|
|
409
|
+
*/
|
|
273
410
|
_restoreElementState(text) {
|
|
274
411
|
const isButton = this._isToggleElement || this._element.tagName === 'BUTTON';
|
|
275
412
|
if (isButton && !this._isScrollMode) {
|
|
@@ -278,6 +415,10 @@ class VGLoadMore extends BaseModule {
|
|
|
278
415
|
}
|
|
279
416
|
}
|
|
280
417
|
|
|
418
|
+
/**
|
|
419
|
+
* Автоматически скрывает или удаляет элемент при завершении
|
|
420
|
+
* @private
|
|
421
|
+
*/
|
|
281
422
|
_autohideTrigger() {
|
|
282
423
|
if (this._isScrollMode) {
|
|
283
424
|
this._observer?.disconnect();
|
|
@@ -287,12 +428,19 @@ class VGLoadMore extends BaseModule {
|
|
|
287
428
|
}
|
|
288
429
|
}
|
|
289
430
|
|
|
431
|
+
/**
|
|
432
|
+
* Полная деинициализация модуля
|
|
433
|
+
* @override
|
|
434
|
+
*/
|
|
290
435
|
dispose() {
|
|
291
436
|
this._observer?.disconnect();
|
|
292
437
|
super.dispose();
|
|
293
438
|
}
|
|
294
439
|
}
|
|
295
440
|
|
|
441
|
+
/**
|
|
442
|
+
* Автоматическая инициализация на элементах с data-vgloadmore
|
|
443
|
+
*/
|
|
296
444
|
EventHandler.on(document, 'DOMContentLoaded', () => {
|
|
297
445
|
Selectors.findAll(SELECTOR_DATA_MODULE).forEach(el => {
|
|
298
446
|
!el.dataset.initialized && VGLoadMore.getOrCreateInstance(el);
|
|
@@ -300,6 +448,9 @@ EventHandler.on(document, 'DOMContentLoaded', () => {
|
|
|
300
448
|
});
|
|
301
449
|
});
|
|
302
450
|
|
|
451
|
+
/**
|
|
452
|
+
* Обработка кликов по элементам с data-vg-toggle="loadmore"
|
|
453
|
+
*/
|
|
303
454
|
EventHandler.on(document, EVENT_KEY_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
|
304
455
|
['A', 'AREA'].includes(this.tagName) && event.preventDefault();
|
|
305
456
|
VGLoadMore.getOrCreateInstance(this).toggle();
|