vgapp 1.1.5 → 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.
Files changed (58) hide show
  1. package/CHANGELOG.md +28 -21
  2. package/README.md +48 -48
  3. package/agents.md +7 -0
  4. package/app/langs/en/buttons.json +17 -17
  5. package/app/langs/en/messages.json +36 -36
  6. package/app/langs/ru/buttons.json +17 -17
  7. package/app/langs/ru/messages.json +36 -36
  8. package/app/modules/vgfilepreview/js/i18n.js +56 -56
  9. package/app/modules/vgfilepreview/js/renderers/image-modal.js +145 -145
  10. package/app/modules/vgfilepreview/js/renderers/image.js +92 -92
  11. package/app/modules/vgfilepreview/js/renderers/index.js +19 -19
  12. package/app/modules/vgfilepreview/js/renderers/office-modal.js +168 -168
  13. package/app/modules/vgfilepreview/js/renderers/office.js +79 -79
  14. package/app/modules/vgfilepreview/js/renderers/pdf-modal.js +260 -260
  15. package/app/modules/vgfilepreview/js/renderers/pdf.js +76 -76
  16. package/app/modules/vgfilepreview/js/renderers/playlist.js +71 -71
  17. package/app/modules/vgfilepreview/js/renderers/text-modal.js +343 -343
  18. package/app/modules/vgfilepreview/js/renderers/text.js +83 -83
  19. package/app/modules/vgfilepreview/js/renderers/video-modal.js +272 -272
  20. package/app/modules/vgfilepreview/js/renderers/video.js +80 -80
  21. package/app/modules/vgfilepreview/js/renderers/zip-modal.js +522 -522
  22. package/app/modules/vgfilepreview/js/renderers/zip.js +89 -89
  23. package/app/modules/vgfilepreview/js/vgfilepreview.js +10 -5
  24. package/app/modules/vgfilepreview/readme.md +68 -68
  25. package/app/modules/vgfilepreview/scss/_variables.scss +113 -113
  26. package/app/modules/vgfilepreview/scss/vgfilepreview.scss +464 -464
  27. package/app/modules/vgfiles/js/base.js +18 -0
  28. package/app/modules/vgfiles/js/droppable.js +260 -260
  29. package/app/modules/vgfiles/js/render.js +153 -153
  30. package/app/modules/vgfiles/js/vgfiles.js +41 -41
  31. package/app/modules/vgfiles/readme.md +123 -123
  32. package/app/modules/vgfiles/scss/_variables.scss +18 -18
  33. package/app/modules/vgfiles/scss/vgfiles.scss +148 -148
  34. package/app/modules/vgformsender/js/vgformsender.js +13 -13
  35. package/app/modules/vgmodal/js/vgmodal.drag.js +332 -332
  36. package/app/modules/vgmodal/js/vgmodal.js +33 -33
  37. package/app/modules/vgmodal/js/vgmodal.resize.js +435 -435
  38. package/app/modules/vgnav/js/vgnav.js +135 -135
  39. package/app/modules/vgnav/readme.md +67 -67
  40. package/app/modules/vgnestable/README.md +307 -307
  41. package/app/modules/vgnestable/scss/_variables.scss +60 -60
  42. package/app/modules/vgnestable/scss/vgnestable.scss +163 -163
  43. package/app/modules/vgselect/js/vgselect.js +39 -39
  44. package/app/modules/vgselect/scss/vgselect.scss +22 -22
  45. package/app/modules/vgspy/readme.md +28 -28
  46. package/app/modules/vgtoast/js/vgtoast.drag.js +335 -0
  47. package/app/modules/vgtoast/js/vgtoast.js +198 -76
  48. package/app/modules/vgtoast/js/vgtoast.resize.js +437 -0
  49. package/app/utils/js/components/audio-metadata.js +240 -240
  50. package/app/utils/js/components/file-icon.js +109 -109
  51. package/app/utils/js/components/file-preview.js +304 -304
  52. package/app/utils/js/components/sanitize.js +150 -150
  53. package/app/utils/js/components/video-metadata.js +140 -140
  54. package/build/vgapp.css +1 -1
  55. package/build/vgapp.css.map +1 -1
  56. package/build/vgapp.js.map +1 -1
  57. package/index.scss +9 -9
  58. package/package.json +1 -1
@@ -47,10 +47,10 @@
47
47
  |--------|------|-------------|----------|
48
48
  | `offset` | `number` | `null` | *(устарело)* Смещение активации (в пикселях). Используйте `rootMargin` вместо этого. |
49
49
  | `rootMargin` | `string` | `'0px 0px -25%'` | Отступы для `IntersectionObserver`. Управляет, насколько "внутрь" должна зайти секция, чтобы стать активной. |
50
- | `smoothScroll` | `boolean` | `true` | Включить плавную прокрутку при клике на якорные ссылки. |
51
- | `target` | `HTMLElement \| string` | элемент с `data-vg-toggle="spy"` | Контейнер, внутри которого происходит прокрутка. Если не указан — используется `window`. |
52
- | `scrollbar` | `Object \| null` | `null` | Инстанс `smooth-scrollbar` или Scrollbar API (если `smooth-scrollbar` импортирован как модуль и не лежит в `window.Scrollbar`). |
53
- | `threshold` | `number[] \| string` | `[0.1, 0.5, 1]` | Пороги видимости (от 0 до 1), при которых срабатывает активация. Можно передать строку: `'0.1, 0.5, 1'`. |
50
+ | `smoothScroll` | `boolean` | `true` | Включить плавную прокрутку при клике на якорные ссылки. |
51
+ | `target` | `HTMLElement \| string` | элемент с `data-vg-toggle="spy"` | Контейнер, внутри которого происходит прокрутка. Если не указан — используется `window`. |
52
+ | `scrollbar` | `Object \| null` | `null` | Инстанс `smooth-scrollbar` или Scrollbar API (если `smooth-scrollbar` импортирован как модуль и не лежит в `window.Scrollbar`). |
53
+ | `threshold` | `number[] \| string` | `[0.1, 0.5, 1]` | Пороги видимости (от 0 до 1), при которых срабатывает активация. Можно передать строку: `'0.1, 0.5, 1'`. |
54
54
 
55
55
  ---
56
56
 
@@ -86,29 +86,29 @@
86
86
 
87
87
  ---
88
88
 
89
- ## 📚 Заметки
90
-
91
- - Убедитесь, что все целевые секции имеют `id`, соответствующий `href` ссылки.
92
- - Секции должны быть видимы (`display: block`, `visibility: visible`).
93
- - Работает с динамически добавленным контентом, но требует вызова `refresh()` после вставки.
94
- - Если прокрутка виртуальная (например, `smooth-scrollbar`), передайте `target` как контейнер, на который был инициализирован `smooth-scrollbar`, и при модульном импорте также передайте `scrollbar`.
95
-
96
- Пример (модульный импорт `smooth-scrollbar`):
97
-
98
- ```js
99
- import Scrollbar from 'smooth-scrollbar';
100
- import VGSpy from './app/modules/vgspy';
101
-
102
- const scrollRoot = document.querySelector('.my-scroll-root');
103
- Scrollbar.init(scrollRoot);
104
-
105
- VGSpy.getOrCreateInstance(document.querySelector('[data-vg-toggle="spy"]'), {
106
- target: scrollRoot,
107
- scrollbar: Scrollbar,
108
- });
109
- ```
110
-
111
- ---
89
+ ## 📚 Заметки
90
+
91
+ - Убедитесь, что все целевые секции имеют `id`, соответствующий `href` ссылки.
92
+ - Секции должны быть видимы (`display: block`, `visibility: visible`).
93
+ - Работает с динамически добавленным контентом, но требует вызова `refresh()` после вставки.
94
+ - Если прокрутка виртуальная (например, `smooth-scrollbar`), передайте `target` как контейнер, на который был инициализирован `smooth-scrollbar`, и при модульном импорте также передайте `scrollbar`.
95
+
96
+ Пример (модульный импорт `smooth-scrollbar`):
97
+
98
+ ```js
99
+ import Scrollbar from 'smooth-scrollbar';
100
+ import VGSpy from './app/modules/vgspy';
101
+
102
+ const scrollRoot = document.querySelector('.my-scroll-root');
103
+ Scrollbar.init(scrollRoot);
104
+
105
+ VGSpy.getOrCreateInstance(document.querySelector('[data-vg-toggle="spy"]'), {
106
+ target: scrollRoot,
107
+ scrollbar: Scrollbar,
108
+ });
109
+ ```
110
+
111
+ ---
112
112
 
113
113
 
114
114
  ## 📝 Лицензия
@@ -119,4 +119,4 @@ MIT. Свободно использовать и модифицировать.
119
119
 
120
120
  📌 *Разработано в рамках фронтенд-системы VG Modules.*
121
121
  > 🚀 Автор: VEGAS STUDIO (vegas-dev.com)
122
- > 📍 Поддерживается в проектах VEGAS
122
+ > 📍 Поддерживается в проектах VEGAS
@@ -0,0 +1,335 @@
1
+ const DEFAULT_OPTIONS = {
2
+ enable: false,
3
+ selector: '.vg-toast-wrapper',
4
+ threshold: 4,
5
+ resizeEdgeSize: 8,
6
+ debug: false,
7
+ };
8
+
9
+ class VGToastDrag {
10
+ constructor(modalElement, dialogElement, options = {}) {
11
+ this._modalElement = modalElement;
12
+ this._dialogElement = dialogElement;
13
+ this._options = this._normalizeOptions(options);
14
+ this._pointerId = null;
15
+ this._dragTarget = null;
16
+ this._isDragging = false;
17
+ this._startX = 0;
18
+ this._startY = 0;
19
+ this._currentX = 0;
20
+ this._currentY = 0;
21
+ this._dialogStartLeft = 0;
22
+ this._dialogStartTop = 0;
23
+ this._dialogWidth = 0;
24
+ this._dialogHeight = 0;
25
+ this._isEnabled = false;
26
+ this._previousUserSelect = '';
27
+ this._previousTransition = '';
28
+ this._previousWillChange = '';
29
+ this._initialRect = null;
30
+ this._lockedIframes = [];
31
+ this._debugElement = null;
32
+
33
+ this._onPointerMove = this._onPointerMove.bind(this);
34
+ this._onPointerUp = this._onPointerUp.bind(this);
35
+ this._onPointerDown = this._onPointerDown.bind(this);
36
+ this._onNativeDragStart = this._onNativeDragStart.bind(this);
37
+ }
38
+
39
+ setOptions(options = {}) {
40
+ this._options = this._normalizeOptions(options, this._options);
41
+ this._updateDebugOverlay();
42
+ }
43
+
44
+ enable() {
45
+ if (!this._dialogElement || this._isEnabled) return;
46
+
47
+ this._updateDebugOverlay();
48
+ this._dialogElement.addEventListener('pointerdown', this._onPointerDown);
49
+ this._isEnabled = true;
50
+ }
51
+
52
+ disable() {
53
+ if (!this._dialogElement || !this._isEnabled) return;
54
+
55
+ this._dialogElement.removeEventListener('pointerdown', this._onPointerDown);
56
+ document.removeEventListener('pointermove', this._onPointerMove);
57
+ document.removeEventListener('pointerup', this._onPointerUp);
58
+ document.removeEventListener('pointercancel', this._onPointerUp);
59
+ document.removeEventListener('dragstart', this._onNativeDragStart, true);
60
+ this._dialogElement.style.touchAction = '';
61
+ document.body.style.userSelect = this._previousUserSelect;
62
+ this._pointerId = null;
63
+ this._dragTarget = null;
64
+ this._isDragging = false;
65
+ this._initialRect = null;
66
+ this._unlockEmbeddedFrames();
67
+ this._restoreDragStyles();
68
+ delete this._modalElement.dataset.vgToastDragging;
69
+ this._setDebugVisibility(false);
70
+ this._isEnabled = false;
71
+ }
72
+
73
+ syncPosition() {
74
+ if (!this._isEnabled) return;
75
+ if (!this._isPreparedForInteraction()) return;
76
+
77
+ const rect = this._dialogElement.getBoundingClientRect();
78
+ const width = this._dialogElement.offsetWidth || rect.width;
79
+ const height = this._dialogElement.offsetHeight || rect.height;
80
+ const currentLeft = Number.parseFloat(this._dialogElement.style.left);
81
+ const currentTop = Number.parseFloat(this._dialogElement.style.top);
82
+ const left = Number.isFinite(currentLeft) ? currentLeft : rect.left;
83
+ const top = Number.isFinite(currentTop) ? currentTop : rect.top;
84
+ const maxLeft = Math.max(0, window.innerWidth - width);
85
+ const maxTop = Math.max(0, window.innerHeight - height);
86
+ const nextLeft = Math.min(maxLeft, Math.max(0, left));
87
+ const nextTop = Math.min(maxTop, Math.max(0, top));
88
+
89
+ this._dialogElement.style.left = `${nextLeft}px`;
90
+ this._dialogElement.style.top = `${nextTop}px`;
91
+ this._updateDebugValues('synced');
92
+ }
93
+
94
+ _onPointerDown(event) {
95
+ if (event.button !== 0) return;
96
+
97
+ const dragArea = this._resolveDragArea(event.target);
98
+ if (!dragArea || !this._dialogElement.contains(dragArea)) return;
99
+ if (this._isPointerOnResizeEdge(event)) return;
100
+ if (event.target.closest('input, textarea, select, button, a, [contenteditable="true"]')) return;
101
+ if (dragArea && dragArea.closest('[data-vg-dismiss="toast"]')) return;
102
+
103
+ this._pointerId = event.pointerId;
104
+ this._dragTarget = event.target;
105
+ this._isDragging = false;
106
+ event.preventDefault();
107
+ this._previousUserSelect = document.body.style.userSelect;
108
+ document.body.style.userSelect = 'none';
109
+ this._initialRect = this._dialogElement.getBoundingClientRect();
110
+ this._dialogStartLeft = this._initialRect.left;
111
+ this._dialogStartTop = this._initialRect.top;
112
+ this._dialogWidth = this._initialRect.width;
113
+ this._dialogHeight = this._initialRect.height;
114
+ this._startX = event.clientX;
115
+ this._startY = event.clientY;
116
+ this._currentX = event.clientX;
117
+ this._currentY = event.clientY;
118
+ this._lockEmbeddedFrames();
119
+ this._modalElement.dataset.vgToastDragging = 'true';
120
+ this._setDebugVisibility(true);
121
+ this._updateDebugValues('armed');
122
+
123
+ document.addEventListener('dragstart', this._onNativeDragStart, true);
124
+
125
+ if (this._dialogElement && this._dialogElement.setPointerCapture) {
126
+ this._dialogElement.setPointerCapture(event.pointerId);
127
+ }
128
+
129
+ document.addEventListener('pointermove', this._onPointerMove);
130
+ document.addEventListener('pointerup', this._onPointerUp);
131
+ document.addEventListener('pointercancel', this._onPointerUp);
132
+ }
133
+
134
+ _onPointerMove(event) {
135
+ if (event.pointerId !== this._pointerId) return;
136
+
137
+ this._currentX = event.clientX;
138
+ this._currentY = event.clientY;
139
+ if (!this._isDragging) {
140
+ const deltaX = this._currentX - this._startX;
141
+ const deltaY = this._currentY - this._startY;
142
+ const distance = Math.hypot(deltaX, deltaY);
143
+ if (distance < this._options.threshold) return;
144
+
145
+ this._isDragging = true;
146
+ this._dialogElement.style.touchAction = 'none';
147
+ this._applyDragStyles();
148
+ this._preparePosition(this._initialRect);
149
+ event.preventDefault();
150
+ this._updateDebugValues('dragging');
151
+ }
152
+ this._applyDragPosition();
153
+ }
154
+
155
+ _onPointerUp(event) {
156
+ if (event.pointerId !== this._pointerId) return;
157
+
158
+ document.removeEventListener('pointermove', this._onPointerMove);
159
+ document.removeEventListener('pointerup', this._onPointerUp);
160
+ document.removeEventListener('pointercancel', this._onPointerUp);
161
+ document.removeEventListener('dragstart', this._onNativeDragStart, true);
162
+ if (this._isDragging) {
163
+ this._applyDragPosition();
164
+ }
165
+ this._dialogElement.style.touchAction = '';
166
+ document.body.style.userSelect = this._previousUserSelect;
167
+
168
+ if (this._dialogElement && this._dialogElement.releasePointerCapture) {
169
+ this._dialogElement.releasePointerCapture(event.pointerId);
170
+ }
171
+
172
+ this._pointerId = null;
173
+ this._dragTarget = null;
174
+ this._isDragging = false;
175
+ this._initialRect = null;
176
+ this._unlockEmbeddedFrames();
177
+ this._restoreDragStyles();
178
+ delete this._modalElement.dataset.vgToastDragging;
179
+ this._setDebugVisibility(this._options.debug);
180
+ this._updateDebugValues('idle');
181
+ }
182
+
183
+ _preparePosition(rect = null) {
184
+ if (!this._dialogElement) return;
185
+
186
+ const currentRect = rect || this._dialogElement.getBoundingClientRect();
187
+ this._dialogElement.style.position = 'fixed';
188
+ this._dialogElement.style.margin = '0';
189
+ this._dialogElement.style.left = `${currentRect.left}px`;
190
+ this._dialogElement.style.top = `${currentRect.top}px`;
191
+ this._dialogElement.style.width = `${currentRect.width}px`;
192
+ this._dialogElement.style.height = `${currentRect.height}px`;
193
+ this._dialogElement.style.transform = 'none';
194
+ this._dialogElement.style.translate = 'none';
195
+ }
196
+
197
+ _isPreparedForInteraction() {
198
+ return this._dialogElement.style.position === 'fixed' && this._dialogElement.style.transform === 'none';
199
+ }
200
+
201
+ _isPointerOnResizeEdge(event) {
202
+ const rect = this._dialogElement.getBoundingClientRect();
203
+ const offsetX = event.clientX - rect.left;
204
+ const offsetY = event.clientY - rect.top;
205
+ const edgeSize = this._options.resizeEdgeSize;
206
+
207
+ const nearTop = offsetY >= 0 && offsetY <= edgeSize;
208
+ const nearBottom = offsetY <= rect.height && offsetY >= rect.height - edgeSize;
209
+ const nearLeft = offsetX >= 0 && offsetX <= edgeSize;
210
+ const nearRight = offsetX <= rect.width && offsetX >= rect.width - edgeSize;
211
+
212
+ return nearTop || nearBottom || nearLeft || nearRight;
213
+ }
214
+
215
+ _applyDragPosition() {
216
+ if (this._pointerId === null || !this._isDragging) return;
217
+
218
+ const deltaX = this._currentX - this._startX;
219
+ const deltaY = this._currentY - this._startY;
220
+ const maxLeft = Math.max(0, window.innerWidth - this._dialogWidth);
221
+ const maxTop = Math.max(0, window.innerHeight - this._dialogHeight);
222
+ const nextLeft = Math.min(maxLeft, Math.max(0, this._dialogStartLeft + deltaX));
223
+ const nextTop = Math.min(maxTop, Math.max(0, this._dialogStartTop + deltaY));
224
+
225
+ this._dialogElement.style.left = `${nextLeft}px`;
226
+ this._dialogElement.style.top = `${nextTop}px`;
227
+ this._updateDebugValues('dragging');
228
+ }
229
+
230
+ _onNativeDragStart(event) {
231
+ if (this._pointerId === null) return;
232
+ event.preventDefault();
233
+ }
234
+
235
+ _applyDragStyles() {
236
+ this._previousTransition = this._dialogElement.style.transition;
237
+ this._previousWillChange = this._dialogElement.style.willChange;
238
+ this._dialogElement.style.transition = 'none';
239
+ this._dialogElement.style.willChange = 'left, top';
240
+ }
241
+
242
+ _restoreDragStyles() {
243
+ this._dialogElement.style.transition = this._previousTransition;
244
+ this._dialogElement.style.willChange = this._previousWillChange;
245
+ }
246
+
247
+ _lockEmbeddedFrames() {
248
+ if (!this._dialogElement || this._lockedIframes.length) return;
249
+
250
+ const iframes = this._dialogElement.querySelectorAll('iframe');
251
+ for (const frame of iframes) {
252
+ this._lockedIframes.push({
253
+ element: frame,
254
+ pointerEvents: frame.style.pointerEvents,
255
+ });
256
+ frame.style.pointerEvents = 'none';
257
+ }
258
+ }
259
+
260
+ _unlockEmbeddedFrames() {
261
+ if (!this._lockedIframes.length) return;
262
+
263
+ for (const item of this._lockedIframes) {
264
+ item.element.style.pointerEvents = item.pointerEvents;
265
+ }
266
+ this._lockedIframes = [];
267
+ }
268
+
269
+ _normalizeOptions(options, base = DEFAULT_OPTIONS) {
270
+ const merged = {...base, ...options};
271
+ const threshold = Number(merged.threshold);
272
+ const resizeEdgeSize = Number(merged.resizeEdgeSize);
273
+ const selector = typeof merged.selector === 'string' && merged.selector.trim()
274
+ ? merged.selector
275
+ : DEFAULT_OPTIONS.selector;
276
+
277
+ return {
278
+ ...merged,
279
+ selector,
280
+ threshold: Number.isFinite(threshold) && threshold >= 0 ? threshold : DEFAULT_OPTIONS.threshold,
281
+ resizeEdgeSize: Number.isFinite(resizeEdgeSize) && resizeEdgeSize > 0 ? resizeEdgeSize : DEFAULT_OPTIONS.resizeEdgeSize,
282
+ debug: Boolean(merged.debug),
283
+ };
284
+ }
285
+
286
+ _resolveDragArea(target) {
287
+ try {
288
+ return target.closest(this._options.selector);
289
+ } catch (error) {
290
+ return target.closest(DEFAULT_OPTIONS.selector);
291
+ }
292
+ }
293
+
294
+ _updateDebugOverlay() {
295
+ if (!this._options.debug) {
296
+ this._setDebugVisibility(false);
297
+ return;
298
+ }
299
+
300
+ if (!this._debugElement) {
301
+ this._debugElement = document.createElement('div');
302
+ this._debugElement.style.position = 'absolute';
303
+ this._debugElement.style.left = '170px';
304
+ this._debugElement.style.bottom = '8px';
305
+ this._debugElement.style.zIndex = '7';
306
+ this._debugElement.style.padding = '4px 6px';
307
+ this._debugElement.style.borderRadius = '4px';
308
+ this._debugElement.style.background = 'rgba(0, 0, 0, 0.72)';
309
+ this._debugElement.style.color = '#fff';
310
+ this._debugElement.style.fontSize = '11px';
311
+ this._debugElement.style.lineHeight = '1.3';
312
+ this._debugElement.style.pointerEvents = 'none';
313
+ this._dialogElement.append(this._debugElement);
314
+ }
315
+
316
+ this._setDebugVisibility(true);
317
+ this._updateDebugValues(this._isDragging ? 'dragging' : 'idle');
318
+ }
319
+
320
+ _setDebugVisibility(visible) {
321
+ if (!this._debugElement) return;
322
+ this._debugElement.style.display = visible ? 'block' : 'none';
323
+ }
324
+
325
+ _updateDebugValues(state = 'idle') {
326
+ if (!this._debugElement || !this._options.debug) return;
327
+
328
+ const rect = this._dialogElement.getBoundingClientRect();
329
+ this._debugElement.textContent = `drag:${state} x:${Math.round(rect.left)} y:${Math.round(rect.top)} w:${Math.round(rect.width)} h:${Math.round(rect.height)}`;
330
+ }
331
+ }
332
+
333
+ export default VGToastDrag;
334
+
335
+