vgapp 1.4.8 → 1.4.9
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 +24 -2
- package/app/modules/base-module.js +14 -2
- package/app/modules/module-fn.js +5 -4
- package/app/modules/vgalert/js/vgalert.js +21 -1
- package/app/modules/vgalert/scss/vgalert.scss +48 -0
- package/app/modules/vgdropdown/js/vgdropdown.js +58 -27
- package/app/modules/vgfilepreview/js/renderers/video-modal.js +5 -1
- package/app/modules/vgfilepreview/js/renderers/video.js +6 -1
- package/app/modules/vgfilepreview/js/vgfilepreview.js +5 -1
- package/app/modules/vgfiles/js/base.js +22 -10
- package/app/modules/vgfiles/js/droppable.js +37 -31
- package/app/modules/vgfiles/js/vgfiles.js +5 -2
- package/app/modules/vgfiles/scss/_variables.scss +3 -1
- package/app/modules/vgfiles/scss/vgfiles.scss +55 -10
- package/app/modules/vgformsender/js/vgformsender.js +5 -2
- package/app/modules/vgloadmore/js/vgloadmore.js +35 -7
- package/app/modules/vgnestable/js/vgnestable.js +140 -0
- package/app/modules/vgnestable/scss/_variables.scss +16 -9
- package/app/modules/vgnestable/scss/vgnestable.scss +35 -2
- package/app/modules/vgtable/index.js +3 -0
- package/app/modules/vgtable/js/_columns.js +567 -0
- package/app/modules/vgtable/js/_expandable.js +242 -0
- package/app/modules/vgtable/js/_filters.js +264 -0
- package/app/modules/vgtable/js/_fixed-columns.js +249 -0
- package/app/modules/vgtable/js/_i18n.js +75 -0
- package/app/modules/vgtable/js/_options.js +428 -0
- package/app/modules/vgtable/js/_pagination.js +491 -0
- package/app/modules/vgtable/js/_panning.js +124 -0
- package/app/modules/vgtable/js/_params-groups.js +21 -0
- package/app/modules/vgtable/js/_remote.js +395 -0
- package/app/modules/vgtable/js/_row-reorder.js +268 -0
- package/app/modules/vgtable/js/_search.js +134 -0
- package/app/modules/vgtable/js/_selection.js +113 -0
- package/app/modules/vgtable/js/_skeleton.js +123 -0
- package/app/modules/vgtable/js/_sorting.js +340 -0
- package/app/modules/vgtable/js/_states.js +143 -0
- package/app/modules/vgtable/js/_sticky-header.js +193 -0
- package/app/modules/vgtable/js/_url-state.js +178 -0
- package/app/modules/vgtable/js/vgtable.js +1444 -0
- package/app/modules/vgtable/readme.md +922 -0
- package/app/modules/vgtable/scss/_columns.scss +52 -0
- package/app/modules/vgtable/scss/_expandable.scss +54 -0
- package/app/modules/vgtable/scss/_fixed-columns.scss +117 -0
- package/app/modules/vgtable/scss/_pagination.scss +191 -0
- package/app/modules/vgtable/scss/_row-reorder.scss +45 -0
- package/app/modules/vgtable/scss/_skeleton.scss +65 -0
- package/app/modules/vgtable/scss/_sorting.scss +89 -0
- package/app/modules/vgtable/scss/_states.scss +70 -0
- package/app/modules/vgtable/scss/_sticky-header.scss +121 -0
- package/app/modules/vgtable/scss/_variables.scss +296 -0
- package/app/modules/vgtable/scss/vgtable.scss +206 -0
- package/app/utils/js/components/placement.js +64 -10
- package/app/vgapp.js +3 -3
- package/build/vgapp.css +1 -1
- package/build/vgapp.css.map +1 -1
- package/build/vgapp.js +1 -1
- package/build/vgapp.js.map +1 -1
- package/index.js +1 -1
- package/index.scss +3 -3
- package/package.json +4 -4
- package/app/modules/vgdynamictable/index.js +0 -4
- package/app/modules/vgdynamictable/js/editable.js +0 -438
- package/app/modules/vgdynamictable/js/expandable.js +0 -248
- package/app/modules/vgdynamictable/js/filters.js +0 -450
- package/app/modules/vgdynamictable/js/fixed.js +0 -566
- package/app/modules/vgdynamictable/js/options.js +0 -650
- package/app/modules/vgdynamictable/js/pagination.js +0 -623
- package/app/modules/vgdynamictable/js/search.js +0 -82
- package/app/modules/vgdynamictable/js/skeleton.js +0 -144
- package/app/modules/vgdynamictable/js/sortable.js +0 -442
- package/app/modules/vgdynamictable/js/summary-footer.js +0 -284
- package/app/modules/vgdynamictable/js/table-remote.js +0 -821
- package/app/modules/vgdynamictable/js/table-state.js +0 -243
- package/app/modules/vgdynamictable/js/table-url-state.js +0 -444
- package/app/modules/vgdynamictable/js/utils/common.js +0 -48
- package/app/modules/vgdynamictable/js/vgdynamictable.js +0 -3870
- package/app/modules/vgdynamictable/js/viewport.js +0 -322
- package/app/modules/vgdynamictable/readme.md +0 -251
- package/app/modules/vgdynamictable/scss/_actions.scss +0 -196
- package/app/modules/vgdynamictable/scss/_pagination.scss +0 -186
- package/app/modules/vgdynamictable/scss/_skeleton.scss +0 -63
- package/app/modules/vgdynamictable/scss/_sortable.scss +0 -66
- package/app/modules/vgdynamictable/scss/_table.scss +0 -137
- package/app/modules/vgdynamictable/scss/_variables.scss +0 -138
- package/app/modules/vgdynamictable/scss/vgdynamictable.scss +0 -264
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# VEGAS APP (VGApp)
|
|
2
2
|
[FUNC.TRUE?!](http://func-true.ru)
|
|
3
3
|
|
|
4
4
|
VGApp — набор фронтенд‑модулей (UI‑компонентов и утилит) на чистом JavaScript от Vegas Studio.
|
|
@@ -20,7 +20,6 @@ VGApp — набор фронтенд‑модулей (UI‑компонент
|
|
|
20
20
|
- `VGAlert` — диалоги подтверждения и уведомления с поддержкой AJAX‑сценариев.
|
|
21
21
|
- `VGCollapse` — сворачиваемые секции и аккордеоны с анимацией.
|
|
22
22
|
- `VGDropdown` — выпадающие меню с гибким открытием и позиционированием.
|
|
23
|
-
- `VGDynamicTable` — интерактивные таблицы с сортировкой, фильтрацией, remote-режимом и состоянием.
|
|
24
23
|
- `VGFiles` — загрузка и управление файлами (dropzone, валидация, AJAX, сортировка).
|
|
25
24
|
- `VGFilePreview` — предпросмотр файлов разных типов и действия по файлу (preview/download).
|
|
26
25
|
- `VGFormSender` — отправка форм (AJAX/нативно), обработка состояний и ответов.
|
|
@@ -35,6 +34,7 @@ VGApp — набор фронтенд‑модулей (UI‑компонент
|
|
|
35
34
|
- `VGSidebar` — боковые панели с управлением открытием/закрытием.
|
|
36
35
|
- `VGSpy` — scroll‑spy для подсветки активных ссылок по секциям.
|
|
37
36
|
- `VGTabs` — вкладки с переключением контента и поддержкой URL/hash.
|
|
37
|
+
- `VGTable` — базовый модуль таблиц.
|
|
38
38
|
- `VGToast` — всплывающие уведомления со стеком и автозакрытием.
|
|
39
39
|
- `VGTooltip` — tooltip/popover подсказки с Data API, автопозиционированием и закрытием по `Esc`/клику вне элемента.
|
|
40
40
|
|
|
@@ -268,3 +268,25 @@ CSS-переменные темы генерируются в `app/utils/scss/_t
|
|
|
268
268
|
|
|
269
269
|
## License
|
|
270
270
|
Is published under the [MIT license](http://www.opensource.org/licenses/mit-license)
|
|
271
|
+
|
|
272
|
+
## Проекты на VGApp
|
|
273
|
+
|
|
274
|
+
Используете VGApp в публичном сайте, внутреннем сервисе или open-source проекте? Расскажите об этом сообществу — создайте Pull Request или Issue и укажите:
|
|
275
|
+
|
|
276
|
+
- название проекта;
|
|
277
|
+
- ссылку, если проект публичный;
|
|
278
|
+
- используемые модули VGApp;
|
|
279
|
+
- короткое описание или отзыв;
|
|
280
|
+
- можно ли публиковать название, ссылку и логотип.
|
|
281
|
+
|
|
282
|
+
Для закрытого проекта ссылку раскрывать не обязательно: его можно указать без названия, например «Внутренняя CRM автосервиса».
|
|
283
|
+
|
|
284
|
+
```md
|
|
285
|
+
| Проект | Сайт | Модули VGApp | Описание |
|
|
286
|
+
|---|---|---|---|
|
|
287
|
+
| Название проекта | https://example.com | VGModal, VGSelect | Короткое описание проекта |
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Список формируется добровольно. VGApp не использует скрытую телеметрию и не собирает адреса сайтов. Статистика скачиваний npm публикуется отдельно и не считается количеством проектов или сайтов.
|
|
291
|
+
|
|
292
|
+
Спасибо за интерес к VGApp, использование библиотеки в своих проектах, обратную связь и вклад в её развитие. Каждый новый проект помогает делать VGApp полезнее, надёжнее и удобнее для всего сообщества.
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: базовый класс модулей VGApp с общими параметрами, жизненным циклом и сетевыми запросами.
|
|
3
|
+
* Возможности: хранит экземпляры, нормализует Data API, управляет событиями и выполняет AJAX-запросы.
|
|
4
|
+
*/
|
|
1
5
|
import {
|
|
2
6
|
execute,
|
|
3
7
|
executeAfterTransition,
|
|
@@ -54,7 +58,7 @@ class BaseModule {
|
|
|
54
58
|
* - timeout = задержка перед отправкой, по умолчанию 0
|
|
55
59
|
* @param callback
|
|
56
60
|
*/
|
|
57
|
-
_route(callback) {
|
|
61
|
+
_route(callback, errorCallback) {
|
|
58
62
|
if (typeof callback !== 'function') {
|
|
59
63
|
return this._requestRoute(callback);
|
|
60
64
|
}
|
|
@@ -121,13 +125,21 @@ class BaseModule {
|
|
|
121
125
|
completeAjaxRequest(data, 'success')
|
|
122
126
|
},
|
|
123
127
|
onError: (err) => {
|
|
128
|
+
if ('loader' in this._params.ajax && this._params.ajax.loader) setData('');
|
|
129
|
+
|
|
130
|
+
if (typeof errorCallback === 'function') {
|
|
131
|
+
execute(errorCallback, [err]);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
124
135
|
completeAjaxRequest(err, 'error')
|
|
125
136
|
}
|
|
126
137
|
}
|
|
127
138
|
|
|
128
139
|
setTimeout(() => {
|
|
129
140
|
if (this._params.ajax.method.toLowerCase() === 'get') {
|
|
130
|
-
|
|
141
|
+
const route = this._buildRouteUrl(this._params.ajax.data, this._params.ajax.route);
|
|
142
|
+
ajax.get(route.toString(), ajaxData);
|
|
131
143
|
}
|
|
132
144
|
|
|
133
145
|
if (this._params.ajax.method.toLowerCase() === 'post') {
|
package/app/modules/module-fn.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: общие SVG-ресурсы и вспомогательные функции Data API модулей VGApp.
|
|
3
|
+
* Возможности: выдаёт системные и файловые иконки и подключает обработчики dismiss.
|
|
4
|
+
*/
|
|
1
5
|
import EventHandler from "../utils/js/dom/event";
|
|
2
6
|
import {isDisabled, isEmptyObj} from "../utils/js/functions";
|
|
3
7
|
import Selectors from "../utils/js/dom/selectors";
|
|
4
8
|
import {getSVG as resolveSVGByFile} from "../utils/js/components/file-icon";
|
|
5
9
|
|
|
6
|
-
/**
|
|
7
|
-
* Тут собраны вспомогательные скрипты для работы модулей
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
10
|
/**
|
|
11
11
|
* Набор svg элементов
|
|
12
12
|
* @param name
|
|
@@ -24,6 +24,7 @@ const getSVG = (name) => {
|
|
|
24
24
|
warning: '<svg width="72" height="72" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M36.5 5C44.8543 5 52.8665 8.31874 58.7739 14.2261C64.6813 20.1335 68 28.1457 68 36.5C68 44.8543 64.6813 52.8665 58.7739 58.7739C52.8665 64.6813 44.8543 68 36.5 68C28.1457 68 20.1335 64.6813 14.2261 58.7739C8.31874 52.8665 5 44.8543 5 36.5C5 28.1457 8.31874 20.1335 14.2261 14.2261C20.1335 8.31874 28.1457 5 36.5 5ZM36.5 18.5C35.9287 18.4995 35.3635 18.6181 34.8406 18.8484C34.3178 19.0786 33.8487 19.4154 33.4633 19.8372C33.0779 20.259 32.7848 20.7565 32.6025 21.298C32.4203 21.8395 32.353 22.413 32.405 22.982L34.0475 41.009C34.1112 41.6151 34.397 42.1761 34.8499 42.5839C35.3028 42.9917 35.8906 43.2173 36.5 43.2173C37.1094 43.2173 37.6972 42.9917 38.1501 42.5839C38.603 42.1761 38.8888 41.6151 38.9525 41.009L40.5905 22.982C40.6424 22.4134 40.5753 21.8403 40.3933 21.2991C40.2114 20.7579 39.9186 20.2606 39.5337 19.8389C39.1488 19.4171 38.6803 19.0803 38.1579 18.8498C37.6356 18.6192 37.0709 18.5001 36.5 18.5ZM36.5 54.5C37.4548 54.5 38.3705 54.1207 39.0456 53.4456C39.7207 52.7705 40.1 51.8548 40.1 50.9C40.1 49.9452 39.7207 49.0295 39.0456 48.3544C38.3705 47.6793 37.4548 47.3 36.5 47.3C35.5452 47.3 34.6295 47.6793 33.9544 48.3544C33.2793 49.0295 32.9 49.9452 32.9 50.9C32.9 51.8548 33.2793 52.7705 33.9544 53.4456C34.6295 54.1207 35.5452 54.5 36.5 54.5Z" fill="#000000"/></svg>',
|
|
25
25
|
info: '<svg width="72" height="72" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M36 4.5C18.6047 4.5 4.5 18.6047 4.5 36C4.5 53.3953 18.6047 67.5 36 67.5C53.3953 67.5 67.5 53.3953 67.5 36C67.5 18.6047 53.3953 4.5 36 4.5ZM33.75 20.8125C33.75 20.5031 34.0031 20.25 34.3125 20.25H37.6875C37.9969 20.25 38.25 20.5031 38.25 20.8125V39.9375C38.25 40.2469 37.9969 40.5 37.6875 40.5H34.3125C34.0031 40.5 33.75 40.2469 33.75 39.9375V20.8125ZM36 51.75C35.1168 51.732 34.2759 51.3685 33.6577 50.7375C33.0395 50.1065 32.6932 49.2584 32.6932 48.375C32.6932 47.4916 33.0395 46.6435 33.6577 46.0125C34.2759 45.3815 35.1168 45.018 36 45C36.8832 45.018 37.7241 45.3815 38.3423 46.0125C38.9605 46.6435 39.3068 47.4916 39.3068 48.375C39.3068 49.2584 38.9605 50.1065 38.3423 50.7375C37.7241 51.3685 36.8832 51.732 36 51.75Z" fill="#000000"/></svg>',
|
|
26
26
|
dots: '<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 17C11.1046 17 12 16.1046 12 15C12 13.8954 11.1046 13 10 13C8.89543 13 8 13.8954 8 15C8 16.1046 8.89543 17 10 17Z" fill="black"/><path d="M10 12C11.1046 12 12 11.1046 12 10C12 8.89543 11.1046 8 10 8C8.89543 8 8 8.89543 8 10C8 11.1046 8.89543 12 10 12Z" fill="black"/><path d="M10 7C11.1046 7 12 6.10457 12 5C12 3.89543 11.1046 3 10 3C8.89543 3 8 3.89543 8 5C8 6.10457 8.89543 7 10 7Z" fill="black"/></svg>',
|
|
27
|
+
remove: '<svg class="vg-icon-remove" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M7.05 5.636 12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414L12 13.414l-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636Z" fill="currentColor"/></svg>',
|
|
27
28
|
cross: '<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.3149 0.340332C15.4478 0.20752 15.6027 0.118978 15.7798 0.074707C15.9569 0.0249023 16.134 0.0249023 16.311 0.074707C16.4881 0.118978 16.6431 0.20752 16.7759 0.340332C16.9142 0.473145 17.0055 0.630859 17.0498 0.813477C17.0941 0.99056 17.0941 1.16764 17.0498 1.34473C17.0055 1.52181 16.917 1.67676 16.7842 1.80957L1.80127 16.8008C1.67399 16.9281 1.52181 17.0111 1.34473 17.0498C1.16764 17.0941 0.987793 17.0941 0.805176 17.0498C0.628092 17.0111 0.470378 16.9253 0.332031 16.7925C0.199219 16.6597 0.110677 16.502 0.0664062 16.3193C0.0221354 16.1423 0.0221354 15.9652 0.0664062 15.7881C0.110677 15.611 0.196452 15.4588 0.32373 15.3315L15.3149 0.340332ZM16.7842 15.3232C16.917 15.4561 17.0028 15.6082 17.0415 15.7798C17.0858 15.9569 17.0858 16.134 17.0415 16.311C17.0028 16.4937 16.9142 16.6541 16.7759 16.7925C16.6431 16.9253 16.4881 17.0138 16.311 17.0581C16.134 17.1024 15.9569 17.1024 15.7798 17.0581C15.6027 17.0138 15.4478 16.9253 15.3149 16.7925L0.32373 1.80127C0.201986 1.67952 0.116211 1.53011 0.0664062 1.35303C0.0221354 1.17594 0.0221354 0.996094 0.0664062 0.813477C0.116211 0.630859 0.204753 0.473145 0.332031 0.340332C0.464844 0.20752 0.622559 0.118978 0.805176 0.074707C0.987793 0.0304362 1.16488 0.0304362 1.33643 0.074707C1.51351 0.118978 1.66846 0.204753 1.80127 0.332031L16.7842 15.3232Z" fill="#000"/></svg>',
|
|
28
29
|
'eye-open': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M288 80c-65.2 0-118.8 29.6-159.9 67.7C89.6 183.5 63 226 49.4 256c13.6 30 40.2 72.5 78.6 108.3C169.2 402.4 222.8 432 288 432s118.8-29.6 159.9-67.7C486.4 328.5 513 286 526.6 256c-13.6-30-40.2-72.5-78.6-108.3C406.8 109.6 353.2 80 288 80zM95.4 112.6C142.5 68.8 207.2 32 288 32s145.5 36.8 192.6 80.6c46.8 43.5 78.1 95.4 93 131.1c3.3 7.9 3.3 16.7 0 24.6c-14.9 35.7-46.2 87.7-93 131.1C433.5 443.2 368.8 480 288 480s-145.5-36.8-192.6-80.6C48.6 356 17.3 304 2.5 268.3c-3.3-7.9-3.3-16.7 0-24.6C17.3 208 48.6 156 95.4 112.6zM288 336c44.2 0 80-35.8 80-80s-35.8-80-80-80c-.7 0-1.3 0-2 0c1.3 5.1 2 10.5 2 16c0 35.3-28.7 64-64 64c-5.5 0-10.9-.7-16-2c0 .7 0 1.3 0 2c0 44.2 35.8 80 80 80zm0-208a128 128 0 1 1 0 256 128 128 0 1 1 0-256z"/></svg>',
|
|
29
30
|
'eye-hide': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zm151 118.3C226 97.7 269.5 80 320 80c65.2 0 118.8 29.6 159.9 67.7C518.4 183.5 545 226 558.6 256c-12.6 28-36.6 66.8-70.9 100.9l-53.8-42.2c9.1-17.6 14.2-37.5 14.2-58.7c0-70.7-57.3-128-128-128c-32.2 0-61.7 11.9-84.2 31.5l-46.1-36.1zM394.9 284.2l-81.5-63.9c4.2-8.5 6.6-18.2 6.6-28.3c0-5.5-.7-10.9-2-16c.7 0 1.3 0 2 0c44.2 0 80 35.8 80 80c0 9.9-1.8 19.4-5.1 28.2zm9.4 130.3C378.8 425.4 350.7 432 320 432c-65.2 0-118.8-29.6-159.9-67.7C121.6 328.5 95 286 81.4 256c8.3-18.4 21.5-41.5 39.4-64.8L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5l-41.9-33zM192 256c0 70.7 57.3 128 128 128c13.3 0 26.1-2 38.2-5.8L302 334c-23.5-5.4-43.1-21.2-53.7-42.3l-56.1-44.2c-.2 2.8-.3 5.6-.3 8.5z"/></svg>',
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: компонент подтверждений и информационных сообщений VGAlert.
|
|
3
|
+
* Возможности: modal, overlay и dropdown-рендер, компактный размер, Data API, AJAX и Promise-сценарии.
|
|
4
|
+
*/
|
|
1
5
|
import BaseModule from "../../base-module";
|
|
2
6
|
import VGModal from "../../vgmodal";
|
|
3
7
|
import VGDropdown from "../../vgdropdown";
|
|
@@ -18,6 +22,7 @@ const CLASS_NAME_ALERT = "vg-alert";
|
|
|
18
22
|
const CLASS_NAME_SHOW = "show";
|
|
19
23
|
const CLASS_NAME_FADE = "fade";
|
|
20
24
|
const CLASS_NAME_CLOSING = "closing";
|
|
25
|
+
const CLASS_NAME_COMPACT = `${CLASS_NAME_ALERT}-compact`;
|
|
21
26
|
const DATA_AGREE = "data-vg-alert-agree";
|
|
22
27
|
const DATA_CANCEL = "data-vg-alert-cancel";
|
|
23
28
|
|
|
@@ -31,6 +36,7 @@ class VGAlert {
|
|
|
31
36
|
constructor(params = {}, lang = 'ru') {
|
|
32
37
|
this.lang = lang;
|
|
33
38
|
this._defaultParams = {
|
|
39
|
+
size: "default", // default or compact
|
|
34
40
|
render: {
|
|
35
41
|
type: "modal", // modal, overlay or dropdown
|
|
36
42
|
dismiss: false,
|
|
@@ -349,6 +355,7 @@ class VGAlert {
|
|
|
349
355
|
|
|
350
356
|
_setParams(params) {
|
|
351
357
|
const merged = mergeDeepObject(this._defaultParams, params);
|
|
358
|
+
merged.size = merged.size === "compact" ? "compact" : "default";
|
|
352
359
|
merged.buttons = mergeDeepObject(this._elementsDefault.buttons, merged.buttons);
|
|
353
360
|
merged.message = mergeDeepObject(this._elementsDefault.message, merged.message);
|
|
354
361
|
merged.icon = this._elementsDefault.icons[merged.theme];
|
|
@@ -356,11 +363,20 @@ class VGAlert {
|
|
|
356
363
|
return merged;
|
|
357
364
|
}
|
|
358
365
|
|
|
366
|
+
_applySizeClass(element) {
|
|
367
|
+
if (this._params.size === "compact") {
|
|
368
|
+
element?.classList.add(CLASS_NAME_COMPACT);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return element;
|
|
372
|
+
}
|
|
373
|
+
|
|
359
374
|
_buildModal() {
|
|
360
375
|
const id = `${CLASS_NAME_ALERT}-${makeRandomString()}`;
|
|
361
376
|
|
|
362
377
|
return VGModal.build(id, this._params.modal, (modal) => {
|
|
363
378
|
modal._element.classList.add(`${CLASS_NAME_ALERT}-modal`);
|
|
379
|
+
this._applySizeClass(modal._element);
|
|
364
380
|
const body = Selectors.find(".vg-modal-body", modal._element);
|
|
365
381
|
body.append(this._buildContent());
|
|
366
382
|
});
|
|
@@ -391,8 +407,10 @@ class VGAlert {
|
|
|
391
407
|
this._createButton(buttons, "cancel");
|
|
392
408
|
}
|
|
393
409
|
|
|
410
|
+
const sizeClass = this._params.size === "compact" ? ` ${CLASS_NAME_COMPACT}` : "";
|
|
411
|
+
|
|
394
412
|
return html.div(
|
|
395
|
-
{class: `${CLASS_NAME_ALERT}-wrapper ${CLASS_NAME_ALERT}-${this._params.theme}`},
|
|
413
|
+
{class: `${CLASS_NAME_ALERT}-wrapper ${CLASS_NAME_ALERT}-${this._params.theme}${sizeClass}`},
|
|
396
414
|
[
|
|
397
415
|
html.div(
|
|
398
416
|
{class: `${CLASS_NAME_ALERT}-content`},
|
|
@@ -438,6 +456,7 @@ class VGAlert {
|
|
|
438
456
|
const overlay = document.createElement('div');
|
|
439
457
|
|
|
440
458
|
overlay.className = `${CLASS_NAME_ALERT}-overlay`;
|
|
459
|
+
this._applySizeClass(overlay);
|
|
441
460
|
overlay.append(this._buildContent());
|
|
442
461
|
|
|
443
462
|
container.append(overlay);
|
|
@@ -533,6 +552,7 @@ class VGAlert {
|
|
|
533
552
|
|
|
534
553
|
container.id = id;
|
|
535
554
|
container.className = `vg-dropdown-content ${CLASS_NAME_ALERT}-dropdown`;
|
|
555
|
+
this._applySizeClass(container);
|
|
536
556
|
container.setAttribute('tabindex', '-1');
|
|
537
557
|
container.setAttribute('role', 'dialog');
|
|
538
558
|
container._vgAlertDropdownParent = parent;
|
|
@@ -154,3 +154,51 @@
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
.vg-alert-modal.vg-alert-compact {
|
|
158
|
+
--vg-modal-width: 420px !important;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.vg-alert-overlay.vg-alert-compact {
|
|
162
|
+
.vg-alert-wrapper {
|
|
163
|
+
width: min(420px, calc(100% - 2rem));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.vg-alert-dropdown.vg-alert-compact {
|
|
168
|
+
width: 280px;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.vg-alert-wrapper.vg-alert-compact {
|
|
172
|
+
.vg-alert-content {
|
|
173
|
+
padding: .75rem;
|
|
174
|
+
gap: .75rem;
|
|
175
|
+
|
|
176
|
+
.vg-alert-content--title {
|
|
177
|
+
font-size: 1rem;
|
|
178
|
+
line-height: 1.25;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.vg-alert-content--description {
|
|
182
|
+
font-size: .8125rem;
|
|
183
|
+
line-height: 1.35;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.vg-alert-content--icon {
|
|
187
|
+
svg {
|
|
188
|
+
width: 24px;
|
|
189
|
+
height: 24px;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.vg-alert-buttons {
|
|
195
|
+
padding: .5rem .75rem;
|
|
196
|
+
|
|
197
|
+
.btn {
|
|
198
|
+
padding: .375rem .75rem;
|
|
199
|
+
font-size: .8125rem;
|
|
200
|
+
line-height: 1.25;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: выпадающее меню VGDropdown с управлением мышью и клавиатурой.
|
|
3
|
+
* Возможности: автоматическое размещение, hover/click режимы, outside-click, анимация и AJAX-контент.
|
|
4
|
+
*/
|
|
1
5
|
import BaseModule from "../../base-module";
|
|
2
6
|
import EventHandler from "../../../utils/js/dom/event";
|
|
3
7
|
import Selectors from "../../../utils/js/dom/selectors";
|
|
@@ -45,6 +49,8 @@ const EVENT_CLICK_DATA_API = `click.${NAME_KEY}.data.api`;
|
|
|
45
49
|
const EVENT_MOUSEOVER_DATA_API = `mouseover.${NAME_KEY}.data.api`;
|
|
46
50
|
const EVENT_MOUSEOUT_DATA_API = `mouseout.${NAME_KEY}.data.api`;
|
|
47
51
|
|
|
52
|
+
let isDocumentDataApiInitialized = false;
|
|
53
|
+
|
|
48
54
|
/**
|
|
49
55
|
* Компонент выпадающего списка (Dropdown).
|
|
50
56
|
*
|
|
@@ -179,6 +185,7 @@ class VGDropdown extends BaseModule {
|
|
|
179
185
|
this._setPlacement();
|
|
180
186
|
|
|
181
187
|
const completeCallback = () => {
|
|
188
|
+
if (!this._element || !this._drop || !this._params) return;
|
|
182
189
|
this._route((status, data) => {
|
|
183
190
|
EventHandler.trigger(this._element, EVENT_KEY_LOADED, { stats: status, data });
|
|
184
191
|
});
|
|
@@ -210,6 +217,13 @@ class VGDropdown extends BaseModule {
|
|
|
210
217
|
* @return {void}
|
|
211
218
|
*/
|
|
212
219
|
dispose() {
|
|
220
|
+
if (this._element) {
|
|
221
|
+
this._element.classList.remove(CLASS_NAME_SHOW);
|
|
222
|
+
this._element.setAttribute('aria-expanded', 'false');
|
|
223
|
+
}
|
|
224
|
+
if (this._drop) {
|
|
225
|
+
this._drop.classList.remove(CLASS_NAME_SHOW, CLASS_NAME_FADE, CLASS_NAME_OPEN);
|
|
226
|
+
}
|
|
213
227
|
super.dispose();
|
|
214
228
|
}
|
|
215
229
|
|
|
@@ -247,7 +261,9 @@ class VGDropdown extends BaseModule {
|
|
|
247
261
|
}
|
|
248
262
|
|
|
249
263
|
setTimeout(() => {
|
|
264
|
+
if (!this._element || !this._drop || !this._params) return;
|
|
250
265
|
const completeCallback = () => {
|
|
266
|
+
if (!this._element || !this._drop) return;
|
|
251
267
|
this._drop.classList.remove(CLASS_NAME_SHOW);
|
|
252
268
|
EventHandler.trigger(this._drop, EVENT_KEY_HIDDEN, relatedTarget);
|
|
253
269
|
};
|
|
@@ -262,30 +278,28 @@ class VGDropdown extends BaseModule {
|
|
|
262
278
|
_setPlacement() {
|
|
263
279
|
if (!this._drop) return;
|
|
264
280
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
overflowProtection = false;
|
|
281
|
+
let placementDefault = 'bottom-start',
|
|
282
|
+
autoFlip = false,
|
|
283
|
+
overflowProtection = false;
|
|
269
284
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
285
|
+
if (this._params.placement === 'auto') {
|
|
286
|
+
autoFlip = true;
|
|
287
|
+
overflowProtection = true;
|
|
288
|
+
} else {
|
|
289
|
+
placementDefault = this._params.placement
|
|
290
|
+
}
|
|
276
291
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
292
|
+
const placement = new Placement({
|
|
293
|
+
reference: this._element,
|
|
294
|
+
drop: this._drop,
|
|
295
|
+
placement: placementDefault,
|
|
296
|
+
boundary: 'clippingParents',
|
|
297
|
+
autoFlip: autoFlip,
|
|
298
|
+
overflowProtection: overflowProtection,
|
|
299
|
+
fallbackPlacements: ['bottom-end', 'top-start', 'top-end', 'right-start', 'left-start', 'right-end', 'left-end'],
|
|
300
|
+
});
|
|
286
301
|
|
|
287
|
-
|
|
288
|
-
}
|
|
302
|
+
placement._setPlacement(); // позиционируем при каждом открытии
|
|
289
303
|
|
|
290
304
|
this._isPlacement = true;
|
|
291
305
|
}
|
|
@@ -298,6 +312,9 @@ class VGDropdown extends BaseModule {
|
|
|
298
312
|
*/
|
|
299
313
|
static init(element, params = {}) {
|
|
300
314
|
const instance = VGDropdown.getOrCreateInstance(element, params);
|
|
315
|
+
if (instance._isDataApiInitialized) return instance;
|
|
316
|
+
|
|
317
|
+
instance._isDataApiInitialized = true;
|
|
301
318
|
|
|
302
319
|
if (instance._params.hover && !isMobileDevice()) {
|
|
303
320
|
let currentElem = null;
|
|
@@ -329,11 +346,14 @@ class VGDropdown extends BaseModule {
|
|
|
329
346
|
});
|
|
330
347
|
}
|
|
331
348
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
349
|
+
if (!isDocumentDataApiInitialized) {
|
|
350
|
+
// Клавиатура и outside-click подключаются один раз для всех экземпляров.
|
|
351
|
+
EventHandler.on(document, EVENT_KEYUP_DATA_API, SELECTOR_DATA_TOGGLE, VGDropdown.keydownHandler);
|
|
352
|
+
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, `.${TARGET_CONTAINER}`, VGDropdown.keydownHandler);
|
|
353
|
+
EventHandler.on(document, EVENT_KEYUP_DATA_API, VGDropdown.clearDrops);
|
|
354
|
+
EventHandler.on(document, EVENT_CLICK_DATA_API, VGDropdown.clearDrops);
|
|
355
|
+
isDocumentDataApiInitialized = true;
|
|
356
|
+
}
|
|
337
357
|
|
|
338
358
|
// Клик по тоглу
|
|
339
359
|
EventHandler.on(element, EVENT_CLICK_DATA_API, (event) => {
|
|
@@ -344,6 +364,17 @@ class VGDropdown extends BaseModule {
|
|
|
344
364
|
return instance;
|
|
345
365
|
}
|
|
346
366
|
|
|
367
|
+
/**
|
|
368
|
+
* Инициализирует все Dropdown-триггеры в документе.
|
|
369
|
+
* Повторный вызов безопасен и возвращает уже созданные экземпляры.
|
|
370
|
+
* @param {Object} [params] - Общие параметры для найденных элементов.
|
|
371
|
+
* @return {VGDropdown[]} Экземпляры найденных Dropdown.
|
|
372
|
+
*/
|
|
373
|
+
static initAll(params = {}) {
|
|
374
|
+
return Selectors.findAll(SELECTOR_DATA_TOGGLE)
|
|
375
|
+
.map(element => VGDropdown.init(element, params));
|
|
376
|
+
}
|
|
377
|
+
|
|
347
378
|
/**
|
|
348
379
|
* Скрывает все открытые выпадающие списки.
|
|
349
380
|
* @param {Event} event - Событие, инициировавшее скрытие.
|
|
@@ -419,4 +450,4 @@ class VGDropdown extends BaseModule {
|
|
|
419
450
|
}
|
|
420
451
|
}
|
|
421
452
|
|
|
422
|
-
export default VGDropdown;
|
|
453
|
+
export default VGDropdown;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: модальное окно видеопредпросмотра VGFilePreview.
|
|
3
|
+
* Возможности: воспроизводит видео и переключает соседние записи плейлиста кнопками и горячими клавишами.
|
|
4
|
+
*/
|
|
1
5
|
import VGModal from "../../../vgmodal";
|
|
2
6
|
|
|
3
7
|
class VideoModal {
|
|
@@ -139,7 +143,7 @@ class VideoModal {
|
|
|
139
143
|
this._video.addEventListener('ended', () => this._goNext(true));
|
|
140
144
|
|
|
141
145
|
header.appendChild(this._title);
|
|
142
|
-
|
|
146
|
+
header.appendChild(navigation);
|
|
143
147
|
body.appendChild(this._video);
|
|
144
148
|
|
|
145
149
|
this._bindEvents(element);
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: рендерер видеофайлов для VGFilePreview.
|
|
3
|
+
* Возможности: создаёт действие предпросмотра и собирает актуальный плейлист соседних видео при открытии.
|
|
4
|
+
*/
|
|
1
5
|
import VideoModal from "./video-modal";
|
|
2
6
|
import { buildMediaPlaylist } from "./playlist";
|
|
3
7
|
|
|
@@ -31,7 +35,6 @@ class VideoFilePreviewRenderer {
|
|
|
31
35
|
return false;
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
const playlist = buildMediaPlaylist(context?.element, (ext) => VIDEO_EXTENSIONS.has(ext));
|
|
35
38
|
const labels = {
|
|
36
39
|
prev: i18n?.button('prev') || '',
|
|
37
40
|
next: i18n?.button('next') || ''
|
|
@@ -42,6 +45,8 @@ class VideoFilePreviewRenderer {
|
|
|
42
45
|
event.preventDefault();
|
|
43
46
|
}
|
|
44
47
|
|
|
48
|
+
const playlist = buildMediaPlaylist(context?.element, (ext) => VIDEO_EXTENSIONS.has(ext));
|
|
49
|
+
|
|
45
50
|
this._modal.open({
|
|
46
51
|
src,
|
|
47
52
|
title: context?.fileMeta?.name || i18n?.message('video_title') || '',
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: основной контроллер предпросмотра файлов и синхронизации полей карточки.
|
|
3
|
+
* Возможности: валидирует путь, выбирает рендерер, управляет медиа, скачиванием, состояниями и публичным API.
|
|
4
|
+
*/
|
|
1
5
|
import BaseModule from "../../base-module";
|
|
2
6
|
import {mergeDeepObject} from "../../../utils/js/functions";
|
|
3
7
|
import FilePreviewHelper from "../../../utils/js/components/file-preview";
|
|
@@ -761,7 +765,7 @@ class VGFilePreview extends BaseModule {
|
|
|
761
765
|
}
|
|
762
766
|
|
|
763
767
|
if (this._isImageFile()) {
|
|
764
|
-
return
|
|
768
|
+
return this._isPreviewGroupEnabled('image');
|
|
765
769
|
}
|
|
766
770
|
|
|
767
771
|
if (this._isOfficeFile()) {
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: базовая логика выбора, валидации и отображения файлов VGFiles.
|
|
3
|
+
* Возможности: управляет набором файлов, ошибками, списками, статистикой и скрытыми полями формы.
|
|
4
|
+
*/
|
|
1
5
|
import BaseModule from "../../base-module";
|
|
2
6
|
import {mergeDeepObject} from "../../../utils/js/functions";
|
|
3
7
|
import Html from "../../../utils/js/components/templater";
|
|
@@ -140,14 +144,14 @@ class VGFilesBase extends BaseModule {
|
|
|
140
144
|
Boolean(this._params?.replace) &&
|
|
141
145
|
isSingle;
|
|
142
146
|
|
|
143
|
-
if (shouldReplaceOnSingle) {
|
|
144
|
-
this.clear(false);
|
|
145
|
-
this.append(filesArray, true);
|
|
146
|
-
this._revokeUrls();
|
|
147
|
-
this._cleanupFakeInputs();
|
|
148
|
-
if (this._params.prepend) this._files.reverse();
|
|
149
|
-
|
|
150
|
-
this.build();
|
|
147
|
+
if (shouldReplaceOnSingle) {
|
|
148
|
+
this.clear(false);
|
|
149
|
+
this.append(filesArray, true);
|
|
150
|
+
this._revokeUrls();
|
|
151
|
+
this._cleanupFakeInputs();
|
|
152
|
+
if (this._params.prepend) this._files.reverse();
|
|
153
|
+
|
|
154
|
+
this.build();
|
|
151
155
|
return;
|
|
152
156
|
}
|
|
153
157
|
|
|
@@ -547,7 +551,11 @@ class VGFilesBase extends BaseModule {
|
|
|
547
551
|
|
|
548
552
|
this._initFilePreviewInInfo($list);
|
|
549
553
|
|
|
550
|
-
|
|
554
|
+
if (files.length) {
|
|
555
|
+
Classes.add(this._nodes.info, 'show');
|
|
556
|
+
} else {
|
|
557
|
+
Classes.remove(this._nodes.info, 'show');
|
|
558
|
+
}
|
|
551
559
|
}
|
|
552
560
|
|
|
553
561
|
_getInfoItemSignature(file, index) {
|
|
@@ -898,7 +906,11 @@ class VGFilesBase extends BaseModule {
|
|
|
898
906
|
$count.innerHTML = this._files.length ? `${this._files.length}<span>[${totalSize}]</span>` : '';
|
|
899
907
|
}
|
|
900
908
|
|
|
901
|
-
|
|
909
|
+
if (this._files.length) {
|
|
910
|
+
Classes.add(this._nodes.stat, 'show');
|
|
911
|
+
} else {
|
|
912
|
+
Classes.remove(this._nodes.stat, 'show');
|
|
913
|
+
}
|
|
902
914
|
}
|
|
903
915
|
|
|
904
916
|
_generateHiddenInputs(files) {
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Описание: Управляет локальными и smartdrop-событиями файловых dropzone VGFiles.
|
|
3
|
+
* Возможности: Отличает внешнее добавление файлов от внутренней сортировки, подсвечивает активную зону и передаёт файлы input-элементу.
|
|
4
|
+
*/
|
|
1
5
|
import { isElement } from "../../../utils/js/functions";
|
|
2
6
|
import EventHandler from "../../../utils/js/dom/event";
|
|
3
7
|
import Selectors from "../../../utils/js/dom/selectors";
|
|
4
8
|
import { Classes } from "../../../utils/js/dom/manipulator";
|
|
5
9
|
import BaseModule from "../../base-module";
|
|
6
10
|
|
|
7
|
-
const CLASS_NAME_CONTAINER = 'vg-files';
|
|
8
|
-
const CLASS_NAME_DROP = `${CLASS_NAME_CONTAINER}-drop`;
|
|
9
|
-
const CLASS_NAME_DROP_LIST = `${CLASS_NAME_DROP}--list`;
|
|
11
|
+
const CLASS_NAME_CONTAINER = 'vg-files';
|
|
12
|
+
const CLASS_NAME_DROP = `${CLASS_NAME_CONTAINER}-drop`;
|
|
13
|
+
const CLASS_NAME_DROP_LIST = `${CLASS_NAME_DROP}--list`;
|
|
10
14
|
|
|
11
15
|
const CLASS_NAME_DROP_ACTIVE = 'drop-active';
|
|
12
16
|
const CLASS_NAME_DROP_HOVER = 'drop-hover';
|
|
@@ -59,34 +63,24 @@ class VGFilesDroppable extends BaseModule {
|
|
|
59
63
|
/**
|
|
60
64
|
* Настройка событий перетаскивания
|
|
61
65
|
*/
|
|
62
|
-
_setupEvents() {
|
|
63
|
-
if (!isElement(this._element)) return;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
EventHandler.on(this._element, `click.${NAME_KEY}`, (e) => {
|
|
76
|
-
if (this._element.tagName !== 'LABEL') return;
|
|
77
|
-
|
|
78
|
-
const fileList = e.target?.closest?.(`.${CLASS_NAME_DROP_LIST}`);
|
|
79
|
-
if (fileList && this._element.contains(fileList)) {
|
|
80
|
-
e.preventDefault();
|
|
81
|
-
}
|
|
82
|
-
});
|
|
66
|
+
_setupEvents() {
|
|
67
|
+
if (!isElement(this._element)) return;
|
|
68
|
+
|
|
69
|
+
EventHandler.on(this._element, `click.${NAME_KEY}`, (e) => {
|
|
70
|
+
if (this._element.tagName !== 'LABEL') return;
|
|
71
|
+
|
|
72
|
+
const fileList = e.target?.closest?.(`.${CLASS_NAME_DROP_LIST}`);
|
|
73
|
+
if (fileList && this._element.contains(fileList)) {
|
|
74
|
+
e.preventDefault();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
83
77
|
|
|
84
78
|
EventHandler.on(this._element, 'dragover', (e) => {
|
|
85
79
|
e.preventDefault();
|
|
86
80
|
e.stopPropagation();
|
|
87
81
|
|
|
88
82
|
// ✅ Сортировка: НЕ подсвечиваем dropzone
|
|
89
|
-
if (
|
|
83
|
+
if (this._isSortableDrag(e)) {
|
|
90
84
|
Classes.remove(this._element, [CLASS_NAME_DROP_ACTIVE, CLASS_NAME_DROP_HOVER]);
|
|
91
85
|
VGFilesDroppable._setDropMessageTitleState(this._element, false);
|
|
92
86
|
e.dataTransfer.dropEffect = 'none';
|
|
@@ -103,7 +97,7 @@ class VGFilesDroppable extends BaseModule {
|
|
|
103
97
|
e.stopPropagation();
|
|
104
98
|
|
|
105
99
|
// ✅ Сортировка: НЕ подсвечиваем dropzone
|
|
106
|
-
if (
|
|
100
|
+
if (this._isSortableDrag(e)) {
|
|
107
101
|
Classes.remove(this._element, [CLASS_NAME_DROP_ACTIVE, CLASS_NAME_DROP_HOVER]);
|
|
108
102
|
VGFilesDroppable._setDropMessageTitleState(this._element, false);
|
|
109
103
|
return;
|
|
@@ -118,7 +112,7 @@ class VGFilesDroppable extends BaseModule {
|
|
|
118
112
|
e.stopPropagation();
|
|
119
113
|
|
|
120
114
|
// ✅ Сортировка: гарантированно без подсветки
|
|
121
|
-
if (
|
|
115
|
+
if (this._isSortableDrag(e)) {
|
|
122
116
|
Classes.remove(this._element, [CLASS_NAME_DROP_ACTIVE, CLASS_NAME_DROP_HOVER]);
|
|
123
117
|
VGFilesDroppable._setDropMessageTitleState(this._element, false);
|
|
124
118
|
return;
|
|
@@ -143,7 +137,7 @@ class VGFilesDroppable extends BaseModule {
|
|
|
143
137
|
VGFilesDroppable._setDropMessageTitleState(this._element, false);
|
|
144
138
|
|
|
145
139
|
// ✅ сортировка: не трогаем input
|
|
146
|
-
if (
|
|
140
|
+
if (this._isSortableDrag(e)) {
|
|
147
141
|
return;
|
|
148
142
|
}
|
|
149
143
|
|
|
@@ -238,6 +232,8 @@ class VGFilesDroppable extends BaseModule {
|
|
|
238
232
|
|
|
239
233
|
_isFileDrag(e) {
|
|
240
234
|
try {
|
|
235
|
+
if (this._isSortableDrag(e)) return false;
|
|
236
|
+
|
|
241
237
|
const dt = e?.dataTransfer;
|
|
242
238
|
if (!dt) return false;
|
|
243
239
|
|
|
@@ -257,6 +253,16 @@ class VGFilesDroppable extends BaseModule {
|
|
|
257
253
|
}
|
|
258
254
|
}
|
|
259
255
|
|
|
256
|
+
_isSortableDrag(e) {
|
|
257
|
+
if (document.querySelector('.dragging')) return true;
|
|
258
|
+
|
|
259
|
+
try {
|
|
260
|
+
return (e?.dataTransfer?.getData?.('text/plain') || '') === 'vgsortable';
|
|
261
|
+
} catch (_) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
260
266
|
_getVisibleDropZonesInViewport() {
|
|
261
267
|
const dropZones = Array.from(Selectors.findAll(`.${CLASS_NAME_DROP}`) || []);
|
|
262
268
|
return dropZones.filter((el) => this._isVisibleInViewport(el));
|
|
@@ -334,9 +340,9 @@ class VGFilesDroppable extends BaseModule {
|
|
|
334
340
|
return this._files;
|
|
335
341
|
}
|
|
336
342
|
|
|
337
|
-
dispose() {
|
|
338
|
-
EventHandler.off(this._element, `click.${NAME_KEY}`);
|
|
339
|
-
EventHandler.off(this._element, 'dragover');
|
|
343
|
+
dispose() {
|
|
344
|
+
EventHandler.off(this._element, `click.${NAME_KEY}`);
|
|
345
|
+
EventHandler.off(this._element, 'dragover');
|
|
340
346
|
EventHandler.off(this._element, 'dragenter');
|
|
341
347
|
EventHandler.off(this._element, 'dragleave');
|
|
342
348
|
EventHandler.off(this._element, 'drop');
|