vgapp 1.4.4 → 1.4.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.
- package/README.md +270 -270
- package/app/langs/en/buttons.json +17 -17
- package/app/langs/en/messages.json +36 -36
- package/app/langs/ru/buttons.json +17 -17
- package/app/langs/ru/messages.json +36 -36
- package/app/modules/vgalert/js/vgalert.js +266 -266
- package/app/modules/vgalert/scss/_variables.scss +16 -16
- package/app/modules/vgalert/scss/vgalert.scss +107 -107
- package/app/modules/vgcollapse/scss/_variables.scss +7 -7
- package/app/modules/vgcollapse/scss/vgcollapse.scss +5 -5
- package/app/modules/vgdropdown/scss/_variables.scss +14 -14
- package/app/modules/vgdropdown/scss/vgdropdown.scss +5 -5
- package/app/modules/vgdynamictable/index.js +4 -4
- package/app/modules/vgdynamictable/js/filters.js +21 -21
- package/app/modules/vgdynamictable/js/fixed.js +179 -179
- package/app/modules/vgdynamictable/js/options.js +3 -3
- package/app/modules/vgdynamictable/js/pagination.js +1 -1
- package/app/modules/vgdynamictable/js/search.js +12 -12
- package/app/modules/vgdynamictable/js/skeleton.js +27 -19
- package/app/modules/vgdynamictable/js/sortable.js +71 -71
- package/app/modules/vgdynamictable/js/summary-footer.js +28 -28
- package/app/modules/vgdynamictable/js/table-url-state.js +31 -31
- package/app/modules/vgdynamictable/js/utils/common.js +48 -48
- package/app/modules/vgdynamictable/js/vgdynamictable.js +79 -79
- package/app/modules/vgdynamictable/scss/_actions.scss +19 -19
- package/app/modules/vgdynamictable/scss/_pagination.scss +5 -5
- package/app/modules/vgdynamictable/scss/_skeleton.scss +11 -11
- package/app/modules/vgdynamictable/scss/_sortable.scss +28 -28
- package/app/modules/vgdynamictable/scss/_table.scss +7 -30
- package/app/modules/vgdynamictable/scss/_variables.scss +46 -46
- package/app/modules/vgdynamictable/scss/vgdynamictable.scss +28 -36
- package/app/modules/vgfilepreview/js/i18n.js +56 -56
- package/app/modules/vgfilepreview/js/renderers/image-modal.js +145 -145
- package/app/modules/vgfilepreview/js/renderers/image.js +92 -92
- package/app/modules/vgfilepreview/js/renderers/index.js +19 -19
- package/app/modules/vgfilepreview/js/renderers/office-modal.js +168 -168
- package/app/modules/vgfilepreview/js/renderers/office.js +79 -79
- package/app/modules/vgfilepreview/js/renderers/pdf-modal.js +260 -260
- package/app/modules/vgfilepreview/js/renderers/pdf.js +76 -76
- package/app/modules/vgfilepreview/js/renderers/playlist.js +71 -71
- package/app/modules/vgfilepreview/js/renderers/text-modal.js +343 -343
- package/app/modules/vgfilepreview/js/renderers/text.js +83 -83
- package/app/modules/vgfilepreview/js/renderers/video-modal.js +272 -272
- package/app/modules/vgfilepreview/js/renderers/video.js +80 -80
- package/app/modules/vgfilepreview/js/renderers/zip-modal.js +522 -522
- package/app/modules/vgfilepreview/js/renderers/zip.js +89 -89
- package/app/modules/vgfilepreview/js/vgfilepreview.js +7 -7
- package/app/modules/vgfilepreview/readme.md +68 -68
- package/app/modules/vgfilepreview/scss/_variables.scss +115 -115
- package/app/modules/vgfilepreview/scss/vgfilepreview.scss +463 -463
- package/app/modules/vgfiles/js/droppable.js +20 -9
- package/app/modules/vgfiles/js/render.js +153 -153
- package/app/modules/vgfiles/js/vgfiles.js +104 -104
- package/app/modules/vgfiles/readme.md +123 -123
- package/app/modules/vgfiles/scss/_mixins.scss +9 -9
- package/app/modules/vgfiles/scss/_variables.scss +41 -41
- package/app/modules/vgfiles/scss/vgfiles.scss +161 -161
- package/app/modules/vgformsender/js/hideshowpass.js +21 -16
- package/app/modules/vgformsender/js/vgformsender.js +4 -6
- package/app/modules/vgformsender/readme.md +1 -1
- package/app/modules/vgformsender/scss/_variables.scss +5 -5
- package/app/modules/vgformsender/scss/vgformsender.scss +42 -42
- package/app/modules/vglawcookie/js/vglawcookie.js +11 -8
- package/app/modules/vglawcookie/scss/_variables.scss +13 -13
- package/app/modules/vglawcookie/scss/vglawcookie.scss +5 -5
- package/app/modules/vgmodal/js/vgmodal.interaction.js +216 -216
- package/app/modules/vgmodal/js/vgmodal.js +355 -355
- package/app/modules/vgmodal/js/vgmodal.minimized.js +227 -227
- package/app/modules/vgmodal/scss/_variables.scss +17 -17
- package/app/modules/vgmodal/scss/vgmodal.scss +77 -77
- package/app/modules/vgnav/js/vgnav.js +180 -180
- package/app/modules/vgnav/scss/_breakpoints.scss +36 -36
- package/app/modules/vgnav/scss/_hamburger.scss +5 -5
- package/app/modules/vgnav/scss/_placement.scss +5 -5
- package/app/modules/vgnav/scss/_toggle.scss +5 -5
- package/app/modules/vgnav/scss/_variables.scss +26 -26
- package/app/modules/vgnav/scss/vgnav.scss +41 -41
- package/app/modules/vgnestable/README.md +39 -39
- package/app/modules/vgnestable/js/vgnestable.js +358 -358
- package/app/modules/vgnestable/scss/_variables.scss +35 -35
- package/app/modules/vgnestable/scss/vgnestable.scss +55 -55
- package/app/modules/vgrangeslider/js/skins.js +222 -222
- package/app/modules/vgrangeslider/js/vgrangeslider.js +704 -704
- package/app/modules/vgrangeslider/scss/_variables.scss +55 -55
- package/app/modules/vgrangeslider/scss/vgrangeslider.scss +239 -239
- package/app/modules/vgrollup/scss/_variables.scss +15 -15
- package/app/modules/vgrollup/scss/vgrollup.scss +6 -6
- package/app/modules/vgselect/js/vgselect.js +129 -129
- package/app/modules/vgselect/readme.md +11 -11
- package/app/modules/vgselect/scss/_variables.scss +50 -50
- package/app/modules/vgselect/scss/vgselect.scss +48 -48
- package/app/modules/vgsidebar/js/vgsidebar.js +79 -79
- package/app/modules/vgsidebar/scss/_variables.scss +10 -10
- package/app/modules/vgsidebar/scss/vgsidebar.scss +5 -5
- package/app/modules/vgtabs/scss/_variables.scss +23 -23
- package/app/modules/vgtabs/scss/vgtabs.scss +5 -5
- package/app/modules/vgtoast/scss/_variables.scss +13 -13
- package/app/modules/vgtoast/scss/vgtoast.scss +5 -5
- package/app/modules/vgtooltip/js/vgtooltip.js +107 -51
- package/app/modules/vgtooltip/scss/_variables.scss +10 -10
- package/app/modules/vgtooltip/scss/vgtooltip.scss +5 -5
- package/app/utils/js/components/audio-metadata.js +240 -240
- package/app/utils/js/components/backdrop.js +116 -116
- package/app/utils/js/components/file-icon.js +109 -109
- package/app/utils/js/components/file-preview.js +304 -304
- package/app/utils/js/components/sanitize.js +150 -150
- package/app/utils/js/components/video-metadata.js +140 -140
- package/app/utils/scss/_backdrop.scss +5 -5
- package/app/utils/scss/_theme-default.scss +12 -12
- package/app/utils/scss/_theme.scss +7 -7
- package/app/utils/scss/_tokens.scss +170 -170
- package/app/utils/scss/default.scss +9 -9
- package/app/utils/scss/functions.scss +21 -21
- package/app/utils/scss/index.scss +4 -4
- package/app/utils/scss/mixin.scss +16 -16
- package/app/utils/scss/variables.scss +105 -105
- package/app/vgapp.js +295 -295
- 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.scss +20 -20
- package/package.json +4 -2
|
@@ -48,61 +48,61 @@ class VGNav extends BaseModule {
|
|
|
48
48
|
constructor(element, params = {}) {
|
|
49
49
|
super(element);
|
|
50
50
|
|
|
51
|
-
this._params = this._getParams(element, mergeDeepObject({
|
|
52
|
-
// Брейкпоинт, с которого навигация отображается в расширенном виде.
|
|
53
|
-
breakpoint: 'lg',
|
|
54
|
-
// Направление меню: влияет на классы и поведение позиционирования.
|
|
55
|
-
placement: 'horizontal',
|
|
56
|
-
// Включает открытие выпадающих пунктов при наведении на десктопе.
|
|
57
|
-
hover: true,
|
|
58
|
-
// Включает ограничение высоты и overflow для списка внутри выпадающего меню.
|
|
59
|
-
dropListScroll: true,
|
|
60
|
-
// Настройки плавного переключения между соседними пунктами первого уровня.
|
|
61
|
-
hoversmoothfirstlevel: {
|
|
62
|
-
// Включает режим плавного перехода без мгновенного закрытия соседнего дропа.
|
|
63
|
-
enable: false,
|
|
64
|
-
// Ограничивает плавное переключение только горизонтальным движением курсора.
|
|
65
|
-
horizontalOnly: true
|
|
66
|
-
},
|
|
67
|
-
// Настройки анимации открытия и закрытия выпадающих пунктов.
|
|
68
|
-
animation: {
|
|
69
|
-
// Включает анимацию переходов.
|
|
70
|
-
enable: true,
|
|
71
|
-
// Длительность ожидания завершения анимации перед финальным состоянием.
|
|
72
|
-
timeout: 700
|
|
73
|
-
},
|
|
74
|
-
// HTML-разметка иконки-указателя для пунктов с выпадающим меню.
|
|
75
|
-
toggle: '<span class="default"></span>',
|
|
76
|
-
// Настройки кнопки-гамбургера для мобильной/адаптивной навигации.
|
|
77
|
-
hamburger: {
|
|
78
|
-
// Разрешает создавать и использовать кнопку-гамбургер.
|
|
79
|
-
enable: true,
|
|
80
|
-
// Принудительно показывает гамбургер всегда, независимо от брейкпоинта.
|
|
81
|
-
always: false,
|
|
82
|
-
// Текстовый заголовок рядом с иконкой гамбургера.
|
|
83
|
-
title: '',
|
|
84
|
-
// Пользовательская HTML-разметка тела гамбургера вместо стандартных линий.
|
|
85
|
-
body: null,
|
|
86
|
-
// CSS-селектор сайдбара, который открывает кнопка-гамбургер.
|
|
87
|
-
target: '#sidebar-nav'
|
|
88
|
-
},
|
|
89
|
-
// Пользовательские обработчики жизненного цикла навигации.
|
|
90
|
-
callbacks: {
|
|
91
|
-
// Вызывается после построения навигации.
|
|
92
|
-
afterInit: noop,
|
|
93
|
-
// Вызывается после клика по пункту навигации.
|
|
94
|
-
afterClick: noop,
|
|
95
|
-
}
|
|
96
|
-
}, params));
|
|
51
|
+
this._params = this._getParams(element, mergeDeepObject({
|
|
52
|
+
// Брейкпоинт, с которого навигация отображается в расширенном виде.
|
|
53
|
+
breakpoint: 'lg',
|
|
54
|
+
// Направление меню: влияет на классы и поведение позиционирования.
|
|
55
|
+
placement: 'horizontal',
|
|
56
|
+
// Включает открытие выпадающих пунктов при наведении на десктопе.
|
|
57
|
+
hover: true,
|
|
58
|
+
// Включает ограничение высоты и overflow для списка внутри выпадающего меню.
|
|
59
|
+
dropListScroll: true,
|
|
60
|
+
// Настройки плавного переключения между соседними пунктами первого уровня.
|
|
61
|
+
hoversmoothfirstlevel: {
|
|
62
|
+
// Включает режим плавного перехода без мгновенного закрытия соседнего дропа.
|
|
63
|
+
enable: false,
|
|
64
|
+
// Ограничивает плавное переключение только горизонтальным движением курсора.
|
|
65
|
+
horizontalOnly: true
|
|
66
|
+
},
|
|
67
|
+
// Настройки анимации открытия и закрытия выпадающих пунктов.
|
|
68
|
+
animation: {
|
|
69
|
+
// Включает анимацию переходов.
|
|
70
|
+
enable: true,
|
|
71
|
+
// Длительность ожидания завершения анимации перед финальным состоянием.
|
|
72
|
+
timeout: 700
|
|
73
|
+
},
|
|
74
|
+
// HTML-разметка иконки-указателя для пунктов с выпадающим меню.
|
|
75
|
+
toggle: '<span class="default"></span>',
|
|
76
|
+
// Настройки кнопки-гамбургера для мобильной/адаптивной навигации.
|
|
77
|
+
hamburger: {
|
|
78
|
+
// Разрешает создавать и использовать кнопку-гамбургер.
|
|
79
|
+
enable: true,
|
|
80
|
+
// Принудительно показывает гамбургер всегда, независимо от брейкпоинта.
|
|
81
|
+
always: false,
|
|
82
|
+
// Текстовый заголовок рядом с иконкой гамбургера.
|
|
83
|
+
title: '',
|
|
84
|
+
// Пользовательская HTML-разметка тела гамбургера вместо стандартных линий.
|
|
85
|
+
body: null,
|
|
86
|
+
// CSS-селектор сайдбара, который открывает кнопка-гамбургер.
|
|
87
|
+
target: '#sidebar-nav'
|
|
88
|
+
},
|
|
89
|
+
// Пользовательские обработчики жизненного цикла навигации.
|
|
90
|
+
callbacks: {
|
|
91
|
+
// Вызывается после построения навигации.
|
|
92
|
+
afterInit: noop,
|
|
93
|
+
// Вызывается после клика по пункту навигации.
|
|
94
|
+
afterClick: noop,
|
|
95
|
+
}
|
|
96
|
+
}, params));
|
|
97
97
|
|
|
98
98
|
this._classes = {
|
|
99
99
|
hamburgerActive: 'vg-nav-hamburger-active',
|
|
100
100
|
hamburgerAlways: 'vg-nav-hamburger-always',
|
|
101
|
-
hamburger: 'vg-nav-hamburger',
|
|
102
|
-
container: 'vg-nav-container',
|
|
103
|
-
wrapper: 'vg-nav-wrapper',
|
|
104
|
-
dropListScroll: 'vg-nav-drop-list-scroll',
|
|
105
|
-
active: 'vg-nav-active',
|
|
101
|
+
hamburger: 'vg-nav-hamburger',
|
|
102
|
+
container: 'vg-nav-container',
|
|
103
|
+
wrapper: 'vg-nav-wrapper',
|
|
104
|
+
dropListScroll: 'vg-nav-drop-list-scroll',
|
|
105
|
+
active: 'vg-nav-active',
|
|
106
106
|
expand: 'vg-nav-expand',
|
|
107
107
|
cloned: 'vg-nav-cloned',
|
|
108
108
|
hover: 'vg-nav-hover',
|
|
@@ -123,11 +123,11 @@ class VGNav extends BaseModule {
|
|
|
123
123
|
this._params.animation.timeout = 10;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
this._openDrops = new Map();
|
|
127
|
-
this._pointerPosition = null;
|
|
128
|
-
this._handleScroll = this._handleScroll.bind(this);
|
|
129
|
-
this._handleResize = this._handleResize.bind(this);
|
|
130
|
-
}
|
|
126
|
+
this._openDrops = new Map();
|
|
127
|
+
this._pointerPosition = null;
|
|
128
|
+
this._handleScroll = this._handleScroll.bind(this);
|
|
129
|
+
this._handleResize = this._handleResize.bind(this);
|
|
130
|
+
}
|
|
131
131
|
|
|
132
132
|
static get NAME() {
|
|
133
133
|
return NAME;
|
|
@@ -153,12 +153,12 @@ class VGNav extends BaseModule {
|
|
|
153
153
|
let params = this._params,
|
|
154
154
|
classes = this._classes;
|
|
155
155
|
|
|
156
|
-
// Вешаем основные классы
|
|
157
|
-
this._element.classList.add(classes.container);
|
|
158
|
-
this._element.classList.add('vg-nav-' + params.placement);
|
|
159
|
-
this._element.classList.toggle(classes.dropListScroll, !!params.dropListScroll);
|
|
160
|
-
|
|
161
|
-
if (!params.hamburger.always) {
|
|
156
|
+
// Вешаем основные классы
|
|
157
|
+
this._element.classList.add(classes.container);
|
|
158
|
+
this._element.classList.add('vg-nav-' + params.placement);
|
|
159
|
+
this._element.classList.toggle(classes.dropListScroll, !!params.dropListScroll);
|
|
160
|
+
|
|
161
|
+
if (!params.hamburger.always) {
|
|
162
162
|
if (!params.breakpoint) {
|
|
163
163
|
this._element.classList.add(classes.expand);
|
|
164
164
|
} else if (params.breakpoint !== false) {
|
|
@@ -350,128 +350,128 @@ class VGNav extends BaseModule {
|
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
-
_isElementInViewport(el) {
|
|
354
|
-
const rect = el.getBoundingClientRect();
|
|
355
|
-
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
356
|
-
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
353
|
+
_isElementInViewport(el) {
|
|
354
|
+
const rect = el.getBoundingClientRect();
|
|
355
|
+
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
356
|
+
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
357
357
|
|
|
358
358
|
const vertInView = (rect.top <= viewHeight) && ((rect.top + rect.height) >= 0);
|
|
359
359
|
const horInView = (rect.left <= viewWidth) && ((rect.left + rect.width) >= 0);
|
|
360
360
|
|
|
361
|
-
return vertInView && horInView;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
_updatePointerPosition(event) {
|
|
365
|
-
if (!event || typeof event.clientX !== 'number' || typeof event.clientY !== 'number') return;
|
|
366
|
-
this._pointerPosition = {
|
|
367
|
-
x: event.clientX,
|
|
368
|
-
y: event.clientY
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
_isHorizontalPointerMove(event) {
|
|
373
|
-
if (!this._pointerPosition || !event) return false;
|
|
374
|
-
|
|
375
|
-
const dx = event.clientX - this._pointerPosition.x;
|
|
376
|
-
const dy = event.clientY - this._pointerPosition.y;
|
|
377
|
-
|
|
378
|
-
return Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 0;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
_isFirstLevelDropdown(drop) {
|
|
382
|
-
return !!drop && !drop.closest('.dropdown-content');
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
_hasDirectDropdownContent(drop) {
|
|
386
|
-
if (!drop || !drop.children) return false;
|
|
387
|
-
return [...drop.children].some((child) => child.classList && child.classList.contains('dropdown-content'));
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
_isAdjacentDropdown(drop, relatedDrop) {
|
|
391
|
-
if (!drop || !relatedDrop) return false;
|
|
392
|
-
if (drop.parentElement !== relatedDrop.parentElement) return false;
|
|
393
|
-
return drop.previousElementSibling === relatedDrop || drop.nextElementSibling === relatedDrop;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
_canSmoothSwitchFirstLevel(event, currentDrop, relatedDrop) {
|
|
397
|
-
const smoothParams = this._params.hoversmoothfirstlevel || {};
|
|
398
|
-
if (!smoothParams.enable) return false;
|
|
399
|
-
if (!currentDrop || !relatedDrop || currentDrop === relatedDrop) return false;
|
|
400
|
-
if (!this._isFirstLevelDropdown(currentDrop) || !this._isFirstLevelDropdown(relatedDrop)) return false;
|
|
401
|
-
if (!this._hasDirectDropdownContent(currentDrop) || !this._hasDirectDropdownContent(relatedDrop)) return false;
|
|
402
|
-
if (!this._isAdjacentDropdown(currentDrop, relatedDrop)) return false;
|
|
403
|
-
if (smoothParams.horizontalOnly && !this._isHorizontalPointerMove(event)) return false;
|
|
404
|
-
|
|
405
|
-
return true;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
static init(element, params = {}) {
|
|
409
|
-
const instance = VGNav.getOrCreateInstance(element, params);
|
|
410
|
-
instance.build();
|
|
411
|
-
|
|
412
|
-
let drops = Selectors.findAll('.dropdown', instance.navigation);
|
|
413
|
-
|
|
414
|
-
if (instance._params.hover && !isMobileDevice()) {
|
|
415
|
-
EventHandler.on(instance.navigation, `mousemove.${NAME_KEY}.data.api`, function (event) {
|
|
416
|
-
instance._updatePointerPosition(event);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
[...drops].forEach(function (el) {
|
|
420
|
-
let currentElem = null;
|
|
421
|
-
|
|
422
|
-
EventHandler.on(el, EVENT_MOUSEOVER_DATA_API, function (event) {
|
|
423
|
-
if (currentElem) return;
|
|
424
|
-
|
|
425
|
-
let target = event.target.closest('.dropdown');
|
|
426
|
-
if (!target) return;
|
|
427
|
-
|
|
428
|
-
if (!instance.navigation.contains(target)) return;
|
|
429
|
-
currentElem = target;
|
|
430
|
-
|
|
431
|
-
const previousDrop = event.relatedTarget?.closest('.dropdown');
|
|
432
|
-
const useSmoothSwitch = instance._canSmoothSwitchFirstLevel(event, target, previousDrop);
|
|
433
|
-
|
|
434
|
-
if (!useSmoothSwitch) {
|
|
435
|
-
VGNav.hideOpenDrops(event);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
let relatedTarget = {
|
|
439
|
-
relatedTarget: target
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
instance.show(relatedTarget);
|
|
443
|
-
|
|
444
|
-
if (useSmoothSwitch && previousDrop && previousDrop.classList.contains(CLASS_NAME_ACTIVE)) {
|
|
445
|
-
instance.hide({ relatedTarget: previousDrop });
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
instance._updatePointerPosition(event);
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
EventHandler.on(el, EVENT_MOUSEOUT_DATA_API, function (event) {
|
|
452
|
-
if (!currentElem) return;
|
|
453
|
-
|
|
454
|
-
let nextDrop = event.relatedTarget?.closest('.dropdown'),
|
|
455
|
-
relatedTarget = nextDrop,
|
|
456
|
-
elm = currentElem;
|
|
457
|
-
|
|
458
|
-
while (relatedTarget) {
|
|
459
|
-
if (relatedTarget === currentElem) return;
|
|
460
|
-
relatedTarget = relatedTarget.parentNode;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
if (instance._canSmoothSwitchFirstLevel(event, elm, nextDrop)) {
|
|
464
|
-
currentElem = null;
|
|
465
|
-
instance._updatePointerPosition(event);
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
currentElem = null;
|
|
470
|
-
instance.hide({ relatedTarget: relatedTarget, elm: elm });
|
|
471
|
-
instance._updatePointerPosition(event);
|
|
472
|
-
});
|
|
473
|
-
});
|
|
474
|
-
}
|
|
361
|
+
return vertInView && horInView;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
_updatePointerPosition(event) {
|
|
365
|
+
if (!event || typeof event.clientX !== 'number' || typeof event.clientY !== 'number') return;
|
|
366
|
+
this._pointerPosition = {
|
|
367
|
+
x: event.clientX,
|
|
368
|
+
y: event.clientY
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
_isHorizontalPointerMove(event) {
|
|
373
|
+
if (!this._pointerPosition || !event) return false;
|
|
374
|
+
|
|
375
|
+
const dx = event.clientX - this._pointerPosition.x;
|
|
376
|
+
const dy = event.clientY - this._pointerPosition.y;
|
|
377
|
+
|
|
378
|
+
return Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 0;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
_isFirstLevelDropdown(drop) {
|
|
382
|
+
return !!drop && !drop.closest('.dropdown-content');
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
_hasDirectDropdownContent(drop) {
|
|
386
|
+
if (!drop || !drop.children) return false;
|
|
387
|
+
return [...drop.children].some((child) => child.classList && child.classList.contains('dropdown-content'));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
_isAdjacentDropdown(drop, relatedDrop) {
|
|
391
|
+
if (!drop || !relatedDrop) return false;
|
|
392
|
+
if (drop.parentElement !== relatedDrop.parentElement) return false;
|
|
393
|
+
return drop.previousElementSibling === relatedDrop || drop.nextElementSibling === relatedDrop;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
_canSmoothSwitchFirstLevel(event, currentDrop, relatedDrop) {
|
|
397
|
+
const smoothParams = this._params.hoversmoothfirstlevel || {};
|
|
398
|
+
if (!smoothParams.enable) return false;
|
|
399
|
+
if (!currentDrop || !relatedDrop || currentDrop === relatedDrop) return false;
|
|
400
|
+
if (!this._isFirstLevelDropdown(currentDrop) || !this._isFirstLevelDropdown(relatedDrop)) return false;
|
|
401
|
+
if (!this._hasDirectDropdownContent(currentDrop) || !this._hasDirectDropdownContent(relatedDrop)) return false;
|
|
402
|
+
if (!this._isAdjacentDropdown(currentDrop, relatedDrop)) return false;
|
|
403
|
+
if (smoothParams.horizontalOnly && !this._isHorizontalPointerMove(event)) return false;
|
|
404
|
+
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
static init(element, params = {}) {
|
|
409
|
+
const instance = VGNav.getOrCreateInstance(element, params);
|
|
410
|
+
instance.build();
|
|
411
|
+
|
|
412
|
+
let drops = Selectors.findAll('.dropdown', instance.navigation);
|
|
413
|
+
|
|
414
|
+
if (instance._params.hover && !isMobileDevice()) {
|
|
415
|
+
EventHandler.on(instance.navigation, `mousemove.${NAME_KEY}.data.api`, function (event) {
|
|
416
|
+
instance._updatePointerPosition(event);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
[...drops].forEach(function (el) {
|
|
420
|
+
let currentElem = null;
|
|
421
|
+
|
|
422
|
+
EventHandler.on(el, EVENT_MOUSEOVER_DATA_API, function (event) {
|
|
423
|
+
if (currentElem) return;
|
|
424
|
+
|
|
425
|
+
let target = event.target.closest('.dropdown');
|
|
426
|
+
if (!target) return;
|
|
427
|
+
|
|
428
|
+
if (!instance.navigation.contains(target)) return;
|
|
429
|
+
currentElem = target;
|
|
430
|
+
|
|
431
|
+
const previousDrop = event.relatedTarget?.closest('.dropdown');
|
|
432
|
+
const useSmoothSwitch = instance._canSmoothSwitchFirstLevel(event, target, previousDrop);
|
|
433
|
+
|
|
434
|
+
if (!useSmoothSwitch) {
|
|
435
|
+
VGNav.hideOpenDrops(event);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
let relatedTarget = {
|
|
439
|
+
relatedTarget: target
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
instance.show(relatedTarget);
|
|
443
|
+
|
|
444
|
+
if (useSmoothSwitch && previousDrop && previousDrop.classList.contains(CLASS_NAME_ACTIVE)) {
|
|
445
|
+
instance.hide({ relatedTarget: previousDrop });
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
instance._updatePointerPosition(event);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
EventHandler.on(el, EVENT_MOUSEOUT_DATA_API, function (event) {
|
|
452
|
+
if (!currentElem) return;
|
|
453
|
+
|
|
454
|
+
let nextDrop = event.relatedTarget?.closest('.dropdown'),
|
|
455
|
+
relatedTarget = nextDrop,
|
|
456
|
+
elm = currentElem;
|
|
457
|
+
|
|
458
|
+
while (relatedTarget) {
|
|
459
|
+
if (relatedTarget === currentElem) return;
|
|
460
|
+
relatedTarget = relatedTarget.parentNode;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (instance._canSmoothSwitchFirstLevel(event, elm, nextDrop)) {
|
|
464
|
+
currentElem = null;
|
|
465
|
+
instance._updatePointerPosition(event);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
currentElem = null;
|
|
470
|
+
instance.hide({ relatedTarget: relatedTarget, elm: elm });
|
|
471
|
+
instance._updatePointerPosition(event);
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
475
|
|
|
476
476
|
const vgNavSidebar = document.querySelector(instance._params.hamburger.target || '#sidebar-nav');
|
|
477
477
|
let hamburger = instance._element.querySelector('.' + instance._classes.hamburger);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
@use "sass:list";
|
|
2
|
-
@use "sass:map";
|
|
3
|
-
@use "variables" as vars;
|
|
4
|
-
|
|
5
|
-
// Breakpoint viewport sizes and media queries.
|
|
1
|
+
@use "sass:list";
|
|
2
|
+
@use "sass:map";
|
|
3
|
+
@use "variables" as vars;
|
|
4
|
+
|
|
5
|
+
// Breakpoint viewport sizes and media queries.
|
|
6
6
|
//
|
|
7
7
|
// Breakpoints are defined as a map of (name: minimum width), order from small to large:
|
|
8
8
|
//
|
|
@@ -18,27 +18,27 @@
|
|
|
18
18
|
// md
|
|
19
19
|
// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl))
|
|
20
20
|
// md
|
|
21
|
-
@function breakpoint-next($name, $breakpoints: vars.$grid-breakpoints, $breakpoint-names: map.keys($breakpoints)) {
|
|
22
|
-
$n: list.index($breakpoint-names, $name);
|
|
23
|
-
@if not $n {
|
|
24
|
-
@error "breakpoint `#{$name}` not found in `#{$breakpoints}`";
|
|
25
|
-
}
|
|
26
|
-
@if $n < list.length($breakpoint-names) {
|
|
27
|
-
@return list.nth($breakpoint-names, $n + 1);
|
|
28
|
-
}
|
|
29
|
-
@return null;
|
|
21
|
+
@function breakpoint-next($name, $breakpoints: vars.$grid-breakpoints, $breakpoint-names: map.keys($breakpoints)) {
|
|
22
|
+
$n: list.index($breakpoint-names, $name);
|
|
23
|
+
@if not $n {
|
|
24
|
+
@error "breakpoint `#{$name}` not found in `#{$breakpoints}`";
|
|
25
|
+
}
|
|
26
|
+
@if $n < list.length($breakpoint-names) {
|
|
27
|
+
@return list.nth($breakpoint-names, $n + 1);
|
|
28
|
+
}
|
|
29
|
+
@return null;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
// Minimum breakpoint width. Null for the smallest (first) breakpoint.
|
|
33
33
|
//
|
|
34
34
|
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
|
|
35
35
|
// 576px
|
|
36
|
-
@function breakpoint-min($name, $breakpoints: vars.$grid-breakpoints) {
|
|
37
|
-
$min: map.get($breakpoints, $name);
|
|
38
|
-
@if $min != 0 {
|
|
39
|
-
@return $min;
|
|
40
|
-
}
|
|
41
|
-
@return null;
|
|
36
|
+
@function breakpoint-min($name, $breakpoints: vars.$grid-breakpoints) {
|
|
37
|
+
$min: map.get($breakpoints, $name);
|
|
38
|
+
@if $min != 0 {
|
|
39
|
+
@return $min;
|
|
40
|
+
}
|
|
41
|
+
@return null;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// Maximum breakpoint width.
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
//
|
|
51
51
|
// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
|
|
52
52
|
// 767.98px
|
|
53
|
-
@function breakpoint-max($name, $breakpoints: vars.$grid-breakpoints) {
|
|
54
|
-
$max: map.get($breakpoints, $name);
|
|
55
|
-
@if $max and $max > 0 {
|
|
56
|
-
@return $max - .02;
|
|
57
|
-
}
|
|
58
|
-
@return null;
|
|
53
|
+
@function breakpoint-max($name, $breakpoints: vars.$grid-breakpoints) {
|
|
54
|
+
$max: map.get($breakpoints, $name);
|
|
55
|
+
@if $max and $max > 0 {
|
|
56
|
+
@return $max - .02;
|
|
57
|
+
}
|
|
58
|
+
@return null;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
|
|
@@ -65,16 +65,16 @@
|
|
|
65
65
|
// "" (Returns a blank string)
|
|
66
66
|
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
|
|
67
67
|
// "-sm"
|
|
68
|
-
@function breakpoint-infix($name, $breakpoints: vars.$grid-breakpoints) {
|
|
69
|
-
@if breakpoint-min($name, $breakpoints) == null {
|
|
70
|
-
@return "";
|
|
71
|
-
}
|
|
72
|
-
@return "-#{$name}";
|
|
68
|
+
@function breakpoint-infix($name, $breakpoints: vars.$grid-breakpoints) {
|
|
69
|
+
@if breakpoint-min($name, $breakpoints) == null {
|
|
70
|
+
@return "";
|
|
71
|
+
}
|
|
72
|
+
@return "-#{$name}";
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
|
|
76
76
|
// Makes the @content apply to the given breakpoint and wider.
|
|
77
|
-
@mixin media-breakpoint-up($name, $breakpoints: vars.$grid-breakpoints) {
|
|
77
|
+
@mixin media-breakpoint-up($name, $breakpoints: vars.$grid-breakpoints) {
|
|
78
78
|
$min: breakpoint-min($name, $breakpoints);
|
|
79
79
|
@if $min {
|
|
80
80
|
@media (min-width: $min) {
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
|
|
88
88
|
// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
|
|
89
89
|
// Makes the @content apply to the given breakpoint and narrower.
|
|
90
|
-
@mixin media-breakpoint-down($name, $breakpoints: vars.$grid-breakpoints) {
|
|
90
|
+
@mixin media-breakpoint-down($name, $breakpoints: vars.$grid-breakpoints) {
|
|
91
91
|
$max: breakpoint-max($name, $breakpoints);
|
|
92
92
|
@if $max {
|
|
93
93
|
@media (max-width: $max) {
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
|
|
101
101
|
// Media that spans multiple breakpoint widths.
|
|
102
102
|
// Makes the @content apply between the min and max breakpoints
|
|
103
|
-
@mixin media-breakpoint-between($lower, $upper, $breakpoints: vars.$grid-breakpoints) {
|
|
103
|
+
@mixin media-breakpoint-between($lower, $upper, $breakpoints: vars.$grid-breakpoints) {
|
|
104
104
|
$min: breakpoint-min($lower, $breakpoints);
|
|
105
105
|
$max: breakpoint-max($upper, $breakpoints);
|
|
106
106
|
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
// Media between the breakpoint's minimum and maximum widths.
|
|
123
123
|
// No minimum for the smallest breakpoint, and no maximum for the largest one.
|
|
124
124
|
// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
|
|
125
|
-
@mixin media-breakpoint-only($name, $breakpoints: vars.$grid-breakpoints) {
|
|
125
|
+
@mixin media-breakpoint-only($name, $breakpoints: vars.$grid-breakpoints) {
|
|
126
126
|
$min: breakpoint-min($name, $breakpoints);
|
|
127
127
|
$next: breakpoint-next($name, $breakpoints);
|
|
128
128
|
$max: breakpoint-max($next, $breakpoints);
|
|
@@ -140,4 +140,4 @@
|
|
|
140
140
|
@content;
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
|
-
}
|
|
143
|
+
}
|