vgapp 1.5.8 → 1.6.0
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/app/modules/module-fn.js +1 -1
- package/app/modules/vgalert/js/vgalert.js +7 -4
- package/app/modules/vgalert/scss/vgalert.scss +13 -6
- package/app/modules/vgnav/js/vgnav.js +317 -36
- package/app/modules/vgnav/scss/vgnav.scss +35 -0
- package/app/modules/vgtable/scss/_fixed-columns.scss +23 -25
- package/app/modules/vgtooltip/js/vgtooltip.js +27 -17
- package/app/modules/vgtooltip/scss/_variables.scss +2 -2
- package/app/modules/vgtooltip/scss/vgtooltip.scss +25 -4
- package/app/utils/js/dom/event.js +25 -23
- 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/package.json +1 -1
package/app/modules/module-fn.js
CHANGED
|
@@ -23,7 +23,7 @@ const getSVG = (name) => {
|
|
|
23
23
|
waiting: '<svg width="72" height="72" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M51 10.02C55.5248 12.6326 59.2888 16.3816 61.9194 20.8959C64.5501 25.4103 65.9561 30.5334 65.9983 35.7581C66.0405 40.9828 64.7174 46.1279 62.1601 50.6841C59.6027 55.2404 55.8997 59.0497 51.4177 61.735C46.9357 64.4203 41.8301 65.8885 36.6063 65.9942C31.3825 66.1 26.2216 64.8395 21.6347 62.3378C17.0477 59.836 13.1936 56.1796 10.454 51.7306C7.71439 47.2816 6.18423 42.1942 6.015 36.972L6 36L6.015 35.028C6.18301 29.847 7.69064 24.7979 10.3909 20.373C13.0912 15.9481 16.892 12.2984 21.4227 9.77969C25.9534 7.26098 31.0594 5.95923 36.243 6.00136C41.4266 6.04348 46.5108 7.42804 51 10.02ZM36 18C35.2652 18.0001 34.556 18.2699 34.0069 18.7582C33.4578 19.2465 33.107 19.9193 33.021 20.649L33 21V36L33.027 36.393C33.0954 36.9135 33.2992 37.407 33.618 37.824L33.879 38.124L42.879 47.124L43.161 47.37C43.6871 47.7782 44.3341 47.9998 45 47.9998C45.6659 47.9998 46.3129 47.7782 46.839 47.37L47.121 47.121L47.37 46.839C47.7782 46.3129 47.9998 45.6659 47.9998 45C47.9998 44.3341 47.7782 43.6872 47.37 43.161L47.121 42.879L39 34.755V21L38.979 20.649C38.893 19.9193 38.5422 19.2465 37.9931 18.7582C37.444 18.2699 36.7348 18.0001 36 18Z" fill="black"/></svg>',
|
|
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
|
-
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="
|
|
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="currentColor"/><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="currentColor"/><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="currentColor"/></svg>',
|
|
27
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>',
|
|
28
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>',
|
|
29
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>',
|
|
@@ -456,10 +456,13 @@ class VGAlert {
|
|
|
456
456
|
: VGModal.getOrCreateInstance(containerWrap);
|
|
457
457
|
const container = Selectors.find('.vg-modal-content', containerWrap) || containerWrap;
|
|
458
458
|
|
|
459
|
-
const overlay = document.createElement('div');
|
|
460
|
-
|
|
461
|
-
overlay.className = `${CLASS_NAME_ALERT}-overlay`;
|
|
462
|
-
|
|
459
|
+
const overlay = document.createElement('div');
|
|
460
|
+
|
|
461
|
+
overlay.className = `${CLASS_NAME_ALERT}-overlay`;
|
|
462
|
+
if (containerWrap.classList.contains('vg-modal')) {
|
|
463
|
+
overlay.classList.add(`${CLASS_NAME_ALERT}-overlay--modal`);
|
|
464
|
+
}
|
|
465
|
+
this._applySizeClass(overlay);
|
|
463
466
|
overlay.append(this._buildContent());
|
|
464
467
|
|
|
465
468
|
container.append(overlay);
|
|
@@ -55,17 +55,24 @@
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
.vg-alert-wrapper {
|
|
59
|
-
background-color: var(--vg-alert-overlay-wrapper-bg);
|
|
60
|
-
width: var(--vg-alert-overlay-wrapper-width);
|
|
58
|
+
.vg-alert-wrapper {
|
|
59
|
+
background-color: var(--vg-alert-overlay-wrapper-bg);
|
|
60
|
+
width: var(--vg-alert-overlay-wrapper-width);
|
|
61
61
|
position: absolute;
|
|
62
62
|
left: var(--vg-alert-overlay-wrapper-start);
|
|
63
63
|
z-index: 1;
|
|
64
64
|
transform: var(--vg-alert-overlay-wrapper-transform);
|
|
65
65
|
top: var(--vg-alert-overlay-wrapper-top);
|
|
66
|
-
transition: var(--vg-alert-overlay-wrapper-transition);
|
|
67
|
-
}
|
|
68
|
-
|
|
66
|
+
transition: var(--vg-alert-overlay-wrapper-transition);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
&--modal {
|
|
70
|
+
.vg-alert-wrapper {
|
|
71
|
+
position: sticky;
|
|
72
|
+
top: calc(var(--vg-alert-overlay-wrapper-top) + 1rem);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
69
76
|
|
|
70
77
|
&-dropdown {
|
|
71
78
|
width: 360px;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Описание: адаптивная навигация VGNav с выпадающими пунктами и гамбургером.
|
|
3
|
-
* Возможности: click/hover, вложенные меню, позиционирование, события и интеграция с VGSidebar.
|
|
3
|
+
* Возможности: click/hover, overflow первого уровня, вложенные меню, позиционирование, события и интеграция с VGSidebar.
|
|
4
4
|
*/
|
|
5
5
|
import BaseModule from "../../base-module";
|
|
6
6
|
import Selectors from "../../../utils/js/dom/selectors";
|
|
7
7
|
import {
|
|
8
|
-
execute,
|
|
9
|
-
|
|
8
|
+
execute,
|
|
9
|
+
getTransitionDurationFromElement,
|
|
10
|
+
isDisabled,
|
|
10
11
|
isMobileDevice,
|
|
11
12
|
isVisible,
|
|
12
13
|
mergeDeepObject,
|
|
@@ -14,7 +15,8 @@ import {
|
|
|
14
15
|
} from "../../../utils/js/functions";
|
|
15
16
|
import EventHandler from "../../../utils/js/dom/event";
|
|
16
17
|
import {Manipulator} from "../../../utils/js/dom/manipulator";
|
|
17
|
-
import Placement from "../../../utils/js/components/placement";
|
|
18
|
+
import Placement from "../../../utils/js/components/placement";
|
|
19
|
+
import {getSVG} from "../../module-fn";
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* Constants
|
|
@@ -59,8 +61,22 @@ class VGNav extends BaseModule {
|
|
|
59
61
|
placement: 'horizontal',
|
|
60
62
|
// Включает открытие выпадающих пунктов при наведении на десктопе.
|
|
61
63
|
hover: true,
|
|
62
|
-
// Включает ограничение высоты и overflow для списка внутри выпадающего меню.
|
|
63
|
-
dropListScroll: true,
|
|
64
|
+
// Включает ограничение высоты и overflow для списка внутри выпадающего меню.
|
|
65
|
+
dropListScroll: true,
|
|
66
|
+
// Переносит лишние пункты первого уровня горизонтального меню в dropdown.
|
|
67
|
+
overflow: {
|
|
68
|
+
enable: false,
|
|
69
|
+
// Максимум видимых исходных пунктов; 0 оставляет только ограничение по ширине.
|
|
70
|
+
count: 0,
|
|
71
|
+
// Элементы, которые нельзя переносить (megamenu сохраняет геометрию первого уровня).
|
|
72
|
+
keep: '.dropdown-mega, [data-vg-nav-overflow="keep"]',
|
|
73
|
+
trigger: {
|
|
74
|
+
icon: 'dots',
|
|
75
|
+
body: null,
|
|
76
|
+
label: '',
|
|
77
|
+
ariaLabel: 'Другие разделы'
|
|
78
|
+
}
|
|
79
|
+
},
|
|
64
80
|
// Настройки плавного переключения между соседними пунктами первого уровня.
|
|
65
81
|
hoversmoothfirstlevel: {
|
|
66
82
|
// Включает режим плавного перехода без мгновенного закрытия соседнего дропа.
|
|
@@ -104,8 +120,11 @@ class VGNav extends BaseModule {
|
|
|
104
120
|
hamburgerAlways: 'vg-nav-hamburger-always',
|
|
105
121
|
hamburger: 'vg-nav-hamburger',
|
|
106
122
|
container: 'vg-nav-container',
|
|
107
|
-
wrapper: 'vg-nav-wrapper',
|
|
108
|
-
dropListScroll: 'vg-nav-drop-list-scroll',
|
|
123
|
+
wrapper: 'vg-nav-wrapper',
|
|
124
|
+
dropListScroll: 'vg-nav-drop-list-scroll',
|
|
125
|
+
overflowEnabled: 'vg-nav-overflow-enabled',
|
|
126
|
+
overflow: 'vg-nav-overflow',
|
|
127
|
+
overflowList: 'vg-nav-overflow-list',
|
|
109
128
|
active: 'vg-nav-active',
|
|
110
129
|
expand: 'vg-nav-expand',
|
|
111
130
|
cloned: 'vg-nav-cloned',
|
|
@@ -127,10 +146,19 @@ class VGNav extends BaseModule {
|
|
|
127
146
|
this._params.animation.timeout = 10;
|
|
128
147
|
}
|
|
129
148
|
|
|
130
|
-
this._openDrops = new Map();
|
|
131
|
-
this._pointerPosition = null;
|
|
132
|
-
this.
|
|
133
|
-
this.
|
|
149
|
+
this._openDrops = new Map();
|
|
150
|
+
this._pointerPosition = null;
|
|
151
|
+
this._smoothSwitch = null;
|
|
152
|
+
this._handleScroll = this._handleScroll.bind(this);
|
|
153
|
+
this._handleResize = this._handleResize.bind(this);
|
|
154
|
+
this._handleOverflowResize = this._handleOverflowResize.bind(this);
|
|
155
|
+
this._overflowTrigger = null;
|
|
156
|
+
this._overflowList = null;
|
|
157
|
+
this._overflowItems = [];
|
|
158
|
+
this._overflowAnchors = new Map();
|
|
159
|
+
this._overflowObserver = null;
|
|
160
|
+
this._overflowFrame = null;
|
|
161
|
+
this._overflowWindowFallback = false;
|
|
134
162
|
}
|
|
135
163
|
|
|
136
164
|
static get NAME() {
|
|
@@ -160,7 +188,8 @@ class VGNav extends BaseModule {
|
|
|
160
188
|
// Вешаем основные классы
|
|
161
189
|
this._element.classList.add(classes.container);
|
|
162
190
|
this._element.classList.add('vg-nav-' + params.placement);
|
|
163
|
-
this._element.classList.toggle(classes.dropListScroll, !!params.dropListScroll);
|
|
191
|
+
this._element.classList.toggle(classes.dropListScroll, !!params.dropListScroll);
|
|
192
|
+
this._setupOverflow();
|
|
164
193
|
|
|
165
194
|
if (!params.hamburger.always) {
|
|
166
195
|
if (!params.breakpoint) {
|
|
@@ -200,7 +229,7 @@ class VGNav extends BaseModule {
|
|
|
200
229
|
}
|
|
201
230
|
|
|
202
231
|
// Устанавливаем указатель дропа
|
|
203
|
-
if (params.toggle) {
|
|
232
|
+
if (params.toggle) {
|
|
204
233
|
let $dropdown_a = [...Selectors.findAll('.dropdown > a', this._element)],
|
|
205
234
|
toggle = '<span class="toggle">' + params.toggle + '</span>';
|
|
206
235
|
|
|
@@ -211,10 +240,12 @@ class VGNav extends BaseModule {
|
|
|
211
240
|
elem.insertAdjacentHTML('beforeend', toggle);
|
|
212
241
|
}
|
|
213
242
|
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
this.refresh();
|
|
247
|
+
|
|
248
|
+
if ('afterInit' in this._params.callbacks) {
|
|
218
249
|
execute(this._params.callbacks.afterInit, [this]);
|
|
219
250
|
}
|
|
220
251
|
}
|
|
@@ -397,7 +428,7 @@ class VGNav extends BaseModule {
|
|
|
397
428
|
return drop.previousElementSibling === relatedDrop || drop.nextElementSibling === relatedDrop;
|
|
398
429
|
}
|
|
399
430
|
|
|
400
|
-
_canSmoothSwitchFirstLevel(event, currentDrop, relatedDrop) {
|
|
431
|
+
_canSmoothSwitchFirstLevel(event, currentDrop, relatedDrop) {
|
|
401
432
|
const smoothParams = this._params.hoversmoothfirstlevel || {};
|
|
402
433
|
if (!smoothParams.enable) return false;
|
|
403
434
|
if (!currentDrop || !relatedDrop || currentDrop === relatedDrop) return false;
|
|
@@ -406,8 +437,251 @@ class VGNav extends BaseModule {
|
|
|
406
437
|
if (!this._isAdjacentDropdown(currentDrop, relatedDrop)) return false;
|
|
407
438
|
if (smoothParams.horizontalOnly && !this._isHorizontalPointerMove(event)) return false;
|
|
408
439
|
|
|
409
|
-
return true;
|
|
410
|
-
}
|
|
440
|
+
return true;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
_scheduleSmoothSwitchCompletion(dropContent, callback) {
|
|
444
|
+
const duration = getTransitionDurationFromElement(dropContent);
|
|
445
|
+
if (!duration) {
|
|
446
|
+
callback();
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
window.setTimeout(callback, duration);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Пересчитывает пункты первого уровня, перенесённые в overflow-dropdown.
|
|
455
|
+
* Полезно вызывать после динамического изменения состава или текста меню.
|
|
456
|
+
*/
|
|
457
|
+
refresh() {
|
|
458
|
+
if (!this._isOverflowEnabled()) return;
|
|
459
|
+
this._collectOverflowItems();
|
|
460
|
+
this._redistributeOverflowItems();
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
_isOverflowEnabled() {
|
|
464
|
+
return !!this._params.overflow?.enable && this._params.placement === 'horizontal';
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
_setupOverflow() {
|
|
468
|
+
if (!this._isOverflowEnabled() || this._overflowTrigger) return;
|
|
469
|
+
|
|
470
|
+
this._element.classList.add(this._classes.overflowEnabled);
|
|
471
|
+
const triggerParams = this._params.overflow.trigger || {};
|
|
472
|
+
const item = document.createElement('li');
|
|
473
|
+
item.classList.add('dropdown', 'dots', this._classes.overflow);
|
|
474
|
+
item.hidden = true;
|
|
475
|
+
|
|
476
|
+
const link = document.createElement('a');
|
|
477
|
+
link.href = '#';
|
|
478
|
+
link.setAttribute('aria-expanded', 'false');
|
|
479
|
+
link.setAttribute('aria-label', triggerParams.ariaLabel || 'Другие разделы');
|
|
480
|
+
|
|
481
|
+
const icon = document.createElement('span');
|
|
482
|
+
icon.classList.add(this._classes.overflow + '-icon');
|
|
483
|
+
icon.setAttribute('aria-hidden', 'true');
|
|
484
|
+
icon.innerHTML = triggerParams.body !== null
|
|
485
|
+
? triggerParams.body
|
|
486
|
+
: (getSVG(triggerParams.icon || 'dots') || '');
|
|
487
|
+
link.append(icon);
|
|
488
|
+
|
|
489
|
+
if (triggerParams.label) {
|
|
490
|
+
const label = document.createElement('span');
|
|
491
|
+
label.classList.add(this._classes.overflow + '-label');
|
|
492
|
+
label.textContent = triggerParams.label;
|
|
493
|
+
link.append(label);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const content = document.createElement('div');
|
|
497
|
+
content.classList.add('dropdown-content');
|
|
498
|
+
const list = document.createElement('ul');
|
|
499
|
+
list.classList.add('vg-nav-drop-list', this._classes.overflowList);
|
|
500
|
+
content.append(list);
|
|
501
|
+
item.append(link, content);
|
|
502
|
+
this.navigation.append(item);
|
|
503
|
+
|
|
504
|
+
this._overflowTrigger = item;
|
|
505
|
+
this._overflowList = list;
|
|
506
|
+
this._collectOverflowItems();
|
|
507
|
+
this._startOverflowObserver();
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
_collectOverflowItems() {
|
|
511
|
+
if (!this.navigation || !this._overflowTrigger) return;
|
|
512
|
+
|
|
513
|
+
[...this.navigation.children].forEach((item) => {
|
|
514
|
+
if (item === this._overflowTrigger || this._overflowAnchors.has(item)) return;
|
|
515
|
+
const anchor = document.createComment('vg-nav-overflow-item');
|
|
516
|
+
this.navigation.insertBefore(anchor, item);
|
|
517
|
+
this._overflowAnchors.set(item, anchor);
|
|
518
|
+
this._overflowItems.push(item);
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
_restoreOverflowItems(removeAnchors = false) {
|
|
523
|
+
this._overflowItems.forEach((item) => {
|
|
524
|
+
const anchor = this._overflowAnchors.get(item);
|
|
525
|
+
if (!anchor?.parentNode) return;
|
|
526
|
+
if (removeAnchors) {
|
|
527
|
+
anchor.replaceWith(item);
|
|
528
|
+
} else {
|
|
529
|
+
anchor.after(item);
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
if (removeAnchors) this._overflowAnchors.clear();
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
_redistributeOverflowItems() {
|
|
537
|
+
if (!this.navigation || !this._overflowTrigger || !this._overflowList) return;
|
|
538
|
+
|
|
539
|
+
this._closeOverflowDrops();
|
|
540
|
+
this._restoreOverflowItems();
|
|
541
|
+
this._overflowTrigger.hidden = true;
|
|
542
|
+
|
|
543
|
+
if (!this._isOverflowMeasurable()) return;
|
|
544
|
+
|
|
545
|
+
const moved = new Set();
|
|
546
|
+
const movable = this._overflowItems.filter((item) => !this._isOverflowKept(item));
|
|
547
|
+
const count = Math.max(0, Number.parseInt(this._params.overflow.count, 10) || 0);
|
|
548
|
+
let visibleCount = this._overflowItems.length;
|
|
549
|
+
|
|
550
|
+
if (count > 0) {
|
|
551
|
+
for (let index = movable.length - 1; index >= 0 && visibleCount > count; index--) {
|
|
552
|
+
moved.add(movable[index]);
|
|
553
|
+
this._overflowList.prepend(movable[index]);
|
|
554
|
+
visibleCount--;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (moved.size || !this._overflowFits()) {
|
|
559
|
+
this._overflowTrigger.hidden = false;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
for (let index = movable.length - 1; index >= 0 && !this._overflowFits(); index--) {
|
|
563
|
+
const item = movable[index];
|
|
564
|
+
if (moved.has(item)) continue;
|
|
565
|
+
moved.add(item);
|
|
566
|
+
this._overflowList.prepend(item);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
this._overflowItems.forEach((item) => {
|
|
570
|
+
if (moved.has(item)) this._overflowList.append(item);
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
this._overflowTrigger.hidden = moved.size === 0;
|
|
574
|
+
this._element.classList.toggle(this._classes.overflow + '-active', moved.size > 0);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
_isOverflowKept(item) {
|
|
578
|
+
const selector = String(this._params.overflow.keep || '').trim();
|
|
579
|
+
return !!selector && item.matches(selector);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
_isOverflowMeasurable() {
|
|
583
|
+
if (!this._element.isConnected) return false;
|
|
584
|
+
if (this.navigation.getClientRects().length === 0) return false;
|
|
585
|
+
return this.navigation.clientWidth > 0 || this.navigation.getBoundingClientRect().width > 0;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
_overflowFits() {
|
|
589
|
+
const width = this.navigation.clientWidth || this.navigation.getBoundingClientRect().width;
|
|
590
|
+
if (!width) return true;
|
|
591
|
+
|
|
592
|
+
const style = window.getComputedStyle(this.navigation);
|
|
593
|
+
const gap = Number.parseFloat(style.columnGap) || 0;
|
|
594
|
+
const children = [...this.navigation.children].filter((item) => !item.hidden);
|
|
595
|
+
const used = children.reduce((sum, item) => {
|
|
596
|
+
const itemStyle = window.getComputedStyle(item);
|
|
597
|
+
return sum + item.getBoundingClientRect().width
|
|
598
|
+
+ (Number.parseFloat(itemStyle.marginLeft) || 0)
|
|
599
|
+
+ (Number.parseFloat(itemStyle.marginRight) || 0);
|
|
600
|
+
}, 0) + Math.max(0, children.length - 1) * gap;
|
|
601
|
+
|
|
602
|
+
return used <= width + 0.5;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
_closeOverflowDrops() {
|
|
606
|
+
[...this.navigation.querySelectorAll('.dropdown.active')].forEach((item) => {
|
|
607
|
+
this.hide({relatedTarget: item});
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
_startOverflowObserver() {
|
|
612
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
613
|
+
this._overflowObserver = new ResizeObserver(this._handleOverflowResize);
|
|
614
|
+
this._overflowObserver.observe(this.navigation);
|
|
615
|
+
this._overflowObserver.observe(this._element);
|
|
616
|
+
} else {
|
|
617
|
+
window.addEventListener('resize', this._handleOverflowResize);
|
|
618
|
+
this._overflowWindowFallback = true;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
if (document.fonts?.ready) {
|
|
622
|
+
document.fonts.ready.then(() => {
|
|
623
|
+
if (this._element) this._handleOverflowResize();
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
_handleOverflowResize() {
|
|
629
|
+
if (this._overflowFrame !== null) return;
|
|
630
|
+
const schedule = typeof window.requestAnimationFrame === 'function'
|
|
631
|
+
? window.requestAnimationFrame.bind(window)
|
|
632
|
+
: (callback) => window.setTimeout(callback, 0);
|
|
633
|
+
|
|
634
|
+
this._overflowFrame = schedule(() => {
|
|
635
|
+
this._overflowFrame = null;
|
|
636
|
+
this.refresh();
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
dispose() {
|
|
641
|
+
if (this._overflowObserver) this._overflowObserver.disconnect();
|
|
642
|
+
if (this._overflowWindowFallback) window.removeEventListener('resize', this._handleOverflowResize);
|
|
643
|
+
if (this._overflowFrame !== null && typeof window.cancelAnimationFrame === 'function') {
|
|
644
|
+
window.cancelAnimationFrame(this._overflowFrame);
|
|
645
|
+
}
|
|
646
|
+
this._restoreOverflowItems(true);
|
|
647
|
+
this._overflowTrigger?.remove();
|
|
648
|
+
this._element.classList.remove(this._classes.overflowEnabled, this._classes.overflow + '-active');
|
|
649
|
+
super.dispose();
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
_startSmoothSwitch(currentDrop, previousDrop, dropContent) {
|
|
653
|
+
const staleSwitch = this._smoothSwitch;
|
|
654
|
+
const transfer = { currentDrop, previousDrop };
|
|
655
|
+
this._smoothSwitch = transfer;
|
|
656
|
+
|
|
657
|
+
if (
|
|
658
|
+
staleSwitch?.previousDrop
|
|
659
|
+
&& staleSwitch.previousDrop !== currentDrop
|
|
660
|
+
&& staleSwitch.previousDrop !== previousDrop
|
|
661
|
+
&& staleSwitch.previousDrop.classList.contains(CLASS_NAME_ACTIVE)
|
|
662
|
+
) {
|
|
663
|
+
this.hide({ relatedTarget: staleSwitch.previousDrop });
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
this._scheduleSmoothSwitchCompletion(dropContent, () => {
|
|
667
|
+
if (this._smoothSwitch !== transfer) return;
|
|
668
|
+
this._smoothSwitch = null;
|
|
669
|
+
if (!currentDrop.isConnected || !previousDrop.isConnected) return;
|
|
670
|
+
if (!currentDrop.classList.contains(CLASS_NAME_ACTIVE)) return;
|
|
671
|
+
if (previousDrop.classList.contains(CLASS_NAME_ACTIVE)) {
|
|
672
|
+
this.hide({ relatedTarget: previousDrop });
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
_cancelSmoothSwitch(exceptDrop = null) {
|
|
678
|
+
const transfer = this._smoothSwitch;
|
|
679
|
+
this._smoothSwitch = null;
|
|
680
|
+
if (!transfer?.previousDrop || transfer.previousDrop === exceptDrop) return;
|
|
681
|
+
if (transfer.previousDrop.classList.contains(CLASS_NAME_ACTIVE)) {
|
|
682
|
+
this.hide({ relatedTarget: transfer.previousDrop });
|
|
683
|
+
}
|
|
684
|
+
}
|
|
411
685
|
|
|
412
686
|
static init(element, params = {}) {
|
|
413
687
|
const instance = VGNav.getOrCreateInstance(element, params);
|
|
@@ -435,19 +709,24 @@ class VGNav extends BaseModule {
|
|
|
435
709
|
const previousDrop = event.relatedTarget?.closest('.dropdown');
|
|
436
710
|
const useSmoothSwitch = instance._canSmoothSwitchFirstLevel(event, target, previousDrop);
|
|
437
711
|
|
|
438
|
-
if (!useSmoothSwitch) {
|
|
439
|
-
|
|
712
|
+
if (!useSmoothSwitch) {
|
|
713
|
+
instance._cancelSmoothSwitch(target);
|
|
714
|
+
VGNav.hideOpenDrops(event);
|
|
440
715
|
}
|
|
441
716
|
|
|
442
717
|
let relatedTarget = {
|
|
443
718
|
relatedTarget: target
|
|
444
719
|
};
|
|
445
720
|
|
|
446
|
-
instance.show(relatedTarget);
|
|
447
|
-
|
|
448
|
-
if (useSmoothSwitch && previousDrop && previousDrop.classList.contains(CLASS_NAME_ACTIVE)) {
|
|
449
|
-
|
|
450
|
-
|
|
721
|
+
instance.show(relatedTarget);
|
|
722
|
+
|
|
723
|
+
if (useSmoothSwitch && previousDrop && previousDrop.classList.contains(CLASS_NAME_ACTIVE)) {
|
|
724
|
+
const nextDropContent = Selectors.find(':scope > .dropdown-content', target);
|
|
725
|
+
if (nextDropContent) {
|
|
726
|
+
nextDropContent.classList.add(CLASS_NAME_FADE);
|
|
727
|
+
instance._startSmoothSwitch(target, previousDrop, nextDropContent);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
451
730
|
|
|
452
731
|
instance._updatePointerPosition(event);
|
|
453
732
|
});
|
|
@@ -464,14 +743,16 @@ class VGNav extends BaseModule {
|
|
|
464
743
|
relatedTarget = relatedTarget.parentNode;
|
|
465
744
|
}
|
|
466
745
|
|
|
467
|
-
if (instance._canSmoothSwitchFirstLevel(event, elm, nextDrop)) {
|
|
468
|
-
currentElem = null;
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
746
|
+
if (instance._canSmoothSwitchFirstLevel(event, elm, nextDrop)) {
|
|
747
|
+
currentElem = null;
|
|
748
|
+
// Сохраняем предыдущую точку до mouseover соседнего пункта:
|
|
749
|
+
// она нужна повторной проверке направления и передаче открытого состояния.
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
currentElem = null;
|
|
754
|
+
instance._cancelSmoothSwitch(elm);
|
|
755
|
+
instance.hide({ relatedTarget: relatedTarget, elm: elm });
|
|
475
756
|
instance._updatePointerPosition(event);
|
|
476
757
|
});
|
|
477
758
|
});
|
|
@@ -150,6 +150,41 @@
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
&.vg-nav-overflow-enabled.vg-nav-horizontal {
|
|
154
|
+
> .vg-nav-wrapper {
|
|
155
|
+
width: 100%;
|
|
156
|
+
min-width: 0;
|
|
157
|
+
flex-wrap: nowrap;
|
|
158
|
+
|
|
159
|
+
> li {
|
|
160
|
+
flex: 0 0 auto;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.vg-nav-overflow {
|
|
165
|
+
> a {
|
|
166
|
+
align-items: center;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
&-icon {
|
|
171
|
+
display: inline-flex;
|
|
172
|
+
align-items: center;
|
|
173
|
+
justify-content: center;
|
|
174
|
+
line-height: 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
&-label:not(:first-child) {
|
|
178
|
+
margin-left: .375rem;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
> .dropdown-content > .vg-nav-overflow-list {
|
|
182
|
+
max-height: none;
|
|
183
|
+
overflow: visible;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
153
188
|
/** set placement **/
|
|
154
189
|
@include placement.placement();
|
|
155
190
|
|
|
@@ -54,31 +54,29 @@
|
|
|
54
54
|
inset-inline-end: var(--vg-table-fixed-offset);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
tbody tr > [data-vg-table-fixed-side],
|
|
58
|
-
tfoot tr > [data-vg-table-fixed-side] {
|
|
59
|
-
background-color: var(--vg-table-fixed-cell-bg);
|
|
60
|
-
background-image: none;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
tbody tr.vg-table-row-selected > [data-vg-table-fixed-side] {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
background-image: linear-gradient(var(--vg-table-selection-row-background-hovered), var(--vg-table-selection-row-background-hovered));
|
|
81
|
-
}
|
|
57
|
+
tbody tr > [data-vg-table-fixed-side],
|
|
58
|
+
tfoot tr > [data-vg-table-fixed-side] {
|
|
59
|
+
background-color: var(--vg-table-fixed-cell-bg);
|
|
60
|
+
background-image: none;
|
|
61
|
+
box-shadow: inset 0 0 0 100vmax transparent;
|
|
62
|
+
transition: var(--vg-table-transition);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.vg-table-striped tbody tr:nth-child(even) > [data-vg-table-fixed-side] {
|
|
66
|
+
box-shadow: inset 0 0 0 100vmax var(--vg-table-tbody-bg-striped);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.vg-table-hovered tbody tr:hover > [data-vg-table-fixed-side] {
|
|
70
|
+
box-shadow: inset 0 0 0 100vmax var(--vg-table-tbody-bg-hovered);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
tbody tr.vg-table-row-selected > [data-vg-table-fixed-side] {
|
|
74
|
+
box-shadow: inset 0 0 0 100vmax var(--vg-table-selection-row-background);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
tbody tr.vg-table-row-selected:hover > [data-vg-table-fixed-side] {
|
|
78
|
+
box-shadow: inset 0 0 0 100vmax var(--vg-table-selection-row-background-hovered);
|
|
79
|
+
}
|
|
82
80
|
|
|
83
81
|
[data-vg-table-fixed-edge]::after {
|
|
84
82
|
content: "";
|