vgapp 0.5.8 → 0.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/CHANGELOG.md +7 -0
- package/app/modules/base-module.js +10 -0
- package/app/modules/vgalert/index.js +0 -2
- package/app/modules/vgdropdown/index.js +0 -1
- package/app/modules/vgdropdown/js/vgdropdown.js +11 -10
- package/app/modules/vgformsender/index.js +0 -1
- package/app/modules/vglawcookie/index.js +0 -1
- package/app/modules/vgmodal/index.js +0 -1
- package/app/modules/vgmodal/scss/vgmodal.scss +0 -1
- package/app/modules/vgnav/!old/!vgnav.js +510 -0
- package/app/modules/vgnav/!old/scss/_breakpoints.scss +127 -0
- package/app/modules/vgnav/!old/scss/_hamburger.scss +62 -0
- package/app/modules/vgnav/!old/scss/_placement.scss +70 -0
- package/app/modules/vgnav/!old/scss/_toggle.scss +20 -0
- package/app/modules/vgnav/!old/scss/_variables.scss +70 -0
- package/app/modules/vgnav/!old/scss/vgnav.scss +164 -0
- package/app/modules/vgnav/index.js +0 -1
- package/app/modules/vgnav/js/vgnav.js +136 -254
- package/app/modules/vgnav/scss/_placement.scss +1 -1
- package/app/modules/vgnav/scss/_variables.scss +18 -18
- package/app/modules/vgnav/scss/vgnav.scss +13 -10
- package/app/modules/vgrollup/index.js +0 -1
- package/app/modules/vgselect/index.js +0 -1
- package/app/modules/vgselect/js/vgselect.js +9 -1
- package/app/modules/vgsidebar/index.js +0 -1
- package/app/modules/vgtabs/index.js +0 -1
- package/app/modules/vgtoast/index.js +0 -1
- package/app/utils/js/components/placement.js +58 -1
- package/build/vgapp.css +1508 -20
- package/build/vgapp.css.map +1 -1
- package/build/vgapp.js +30 -3
- package/build/vgapp.js.map +1 -1
- package/index.js +0 -4
- package/index.scss +38 -0
- package/package.json +1 -1
- package/webpack.config.js +1 -1
- package/app/modules/vgalert/scss/vgalert.css +0 -83
- package/app/modules/vgalert/scss/vgalert.css.map +0 -1
- package/app/modules/vgdatatable/index.js +0 -4
- package/app/modules/vgdatatable/js/vgdatatable.js +0 -146
- package/app/modules/vgdatatable/scss/_variables.scss +0 -19
- package/app/modules/vgdatatable/scss/vgdatatable.scss +0 -72
- package/app/modules/vgdropdown/scss/vgdropdown.css +0 -47
- package/app/modules/vgdropdown/scss/vgdropdown.css.map +0 -1
- package/app/modules/vgformsender/scss/vgformsender.css +0 -13
- package/app/modules/vgformsender/scss/vgformsender.css.map +0 -1
- package/app/modules/vglawcookie/scss/vglawcookie.css +0 -87
- package/app/modules/vglawcookie/scss/vglawcookie.css.map +0 -1
- package/app/modules/vgmodal/scss/vgmodal.css +0 -3824
- package/app/modules/vgmodal/scss/vgmodal.css.map +0 -1
- package/app/modules/vgnav/scss/vgnav.css +0 -312
- package/app/modules/vgnav/scss/vgnav.css.map +0 -1
- package/app/modules/vgrollup/scss/vgrollup.css +0 -44
- package/app/modules/vgrollup/scss/vgrollup.css.map +0 -1
- package/app/modules/vgselect/scss/vgselect.css +0 -256
- package/app/modules/vgselect/scss/vgselect.css.map +0 -1
- package/app/modules/vgsidebar/scss/vgsidebar.css +0 -86
- package/app/modules/vgsidebar/scss/vgsidebar.css.map +0 -1
- package/app/modules/vgtoast/scss/vgtoast.css +0 -133
- package/app/modules/vgtoast/scss/vgtoast.css.map +0 -1
- package/app/utils/js/components/responsive.js +0 -83
- package/build/vgapp.js.LICENSE.txt +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# VEGAS-APP 0.6.0 (Август, 20, 2025)
|
|
2
|
+
* Исправлены ошибки в разных модулях
|
|
3
|
+
|
|
4
|
+
# VEGAS-APP 0.5.6 - 0.5.9 (Август, 08, 2025)
|
|
5
|
+
* Разделение JS и CSS
|
|
6
|
+
* Исправлены ошибки в разных модулях
|
|
7
|
+
|
|
1
8
|
# VEGAS-APP 0.4.6 - 0.5.5 (Июнь, 21, 2025)
|
|
2
9
|
* Исправлены ошибки в разных модулях
|
|
3
10
|
|
|
@@ -96,6 +96,16 @@ class BaseModule {
|
|
|
96
96
|
new Animation(element, key, params);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
isMobileDevice() {
|
|
100
|
+
const userAgent = navigator.userAgent;
|
|
101
|
+
const isMobileUA = /Android|iPhone|iPad|iPod/i.test(userAgent);
|
|
102
|
+
const isTouchDevice = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
103
|
+
const isSmallScreen = window.innerWidth < 768;
|
|
104
|
+
const isHighDPI = window.devicePixelRatio >= 2;
|
|
105
|
+
|
|
106
|
+
return isMobileUA || (isTouchDevice && isSmallScreen && isHighDPI);
|
|
107
|
+
}
|
|
108
|
+
|
|
99
109
|
static getInstance(element) {
|
|
100
110
|
return Data.get(Selectors.find(element), this.NAME_KEY)
|
|
101
111
|
}
|
|
@@ -209,8 +209,9 @@ class VGDropdown extends BaseModule {
|
|
|
209
209
|
static init(element, params = {}) {
|
|
210
210
|
const instance = VGDropdown.getOrCreateInstance(element, params);
|
|
211
211
|
|
|
212
|
-
if (instance._params.hover) {
|
|
212
|
+
if (instance._params.hover && !instance.isMobileDevice()) {
|
|
213
213
|
let currentElem = null;
|
|
214
|
+
|
|
214
215
|
EventHandler.on(instance._parent, EVENT_MOUSEOVER_DATA_API, function (event) {
|
|
215
216
|
if (currentElem) return;
|
|
216
217
|
VGDropdown.hideOpenToggles(event);
|
|
@@ -236,16 +237,16 @@ class VGDropdown extends BaseModule {
|
|
|
236
237
|
currentElem = null;
|
|
237
238
|
instance._completeHide({relatedTarget: instance._element});
|
|
238
239
|
})
|
|
239
|
-
} else {
|
|
240
|
-
EventHandler.on(document, EVENT_KEYUP_DATA_API, SELECTOR_DATA_TOGGLE, VGDropdown.keydownHandler);
|
|
241
|
-
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, '.' + TARGET_CONTAINER, VGDropdown.keydownHandler);
|
|
242
|
-
EventHandler.on(document, EVENT_KEYUP_DATA_API, VGDropdown.clearDrops);
|
|
243
|
-
EventHandler.on(document, EVENT_CLICK_DATA_API, VGDropdown.clearDrops);
|
|
244
|
-
EventHandler.on(element, EVENT_CLICK_DATA_API, function (event) {
|
|
245
|
-
event.preventDefault();
|
|
246
|
-
instance.toggle();
|
|
247
|
-
});
|
|
248
240
|
}
|
|
241
|
+
|
|
242
|
+
EventHandler.on(document, EVENT_KEYUP_DATA_API, SELECTOR_DATA_TOGGLE, VGDropdown.keydownHandler);
|
|
243
|
+
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, '.' + TARGET_CONTAINER, VGDropdown.keydownHandler);
|
|
244
|
+
EventHandler.on(document, EVENT_KEYUP_DATA_API, VGDropdown.clearDrops);
|
|
245
|
+
EventHandler.on(document, EVENT_CLICK_DATA_API, VGDropdown.clearDrops);
|
|
246
|
+
EventHandler.on(element, EVENT_CLICK_DATA_API, function (event) {
|
|
247
|
+
event.preventDefault();
|
|
248
|
+
instance.toggle();
|
|
249
|
+
});
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
static hideOpenToggles(event) {
|
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import BaseModule from "../../base-module";
|
|
2
|
+
import Selectors from "../../../utils/js/dom/selectors";
|
|
3
|
+
import Responsive from "../../../utils/js/components/responsive";
|
|
4
|
+
import {getSVG} from "../../module-fn";
|
|
5
|
+
import {execute, isDisabled, isVisible, mergeDeepObject, noop, normalizeData} from "../../../utils/js/functions";
|
|
6
|
+
import EventHandler from "../../../utils/js/dom/event";
|
|
7
|
+
import {Manipulator} from "../../../utils/js/dom/manipulator";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Constants
|
|
11
|
+
*/
|
|
12
|
+
const NAME = 'nav';
|
|
13
|
+
const NAME_KEY = 'vg.nav';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Constants Classes
|
|
17
|
+
*/
|
|
18
|
+
const CLASS_NAME_SHOW = 'show';
|
|
19
|
+
const CLASS_NAME_FADE = 'fade';
|
|
20
|
+
const CLASS_NAME_ACTIVE = 'active';
|
|
21
|
+
const SELECTOR_DATA_TOGGLE = '.vg-nav a';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Constants Events
|
|
25
|
+
*/
|
|
26
|
+
const EVENT_KEY_HIDE = `${NAME_KEY}.hide`;
|
|
27
|
+
const EVENT_KEY_HIDDEN = `${NAME_KEY}.hidden`;
|
|
28
|
+
const EVENT_KEY_SHOW = `${NAME_KEY}.show`;
|
|
29
|
+
const EVENT_KEY_SHOWN = `${NAME_KEY}.shown`;
|
|
30
|
+
|
|
31
|
+
const EVENT_MOUSEOVER_DATA_API = `mouseover.${NAME_KEY}.data.api`;
|
|
32
|
+
const EVENT_MOUSEOUT_DATA_API = `mouseout.${NAME_KEY}.data.api`;
|
|
33
|
+
const EVENT_CLICK_DATA_API = `click.${NAME_KEY}.data.api`;
|
|
34
|
+
const EVENT_KEYUP_DATA_API = `keyup.${NAME_KEY}.data.api`;
|
|
35
|
+
const EVENT_RESIZE_DATA_API = `resize.${NAME_KEY}.data.api`;
|
|
36
|
+
|
|
37
|
+
class VGNav extends BaseModule {
|
|
38
|
+
constructor(element, params = {}) {
|
|
39
|
+
super(element);
|
|
40
|
+
|
|
41
|
+
this._params = this._getParams(element, mergeDeepObject({
|
|
42
|
+
breakpoint: false,
|
|
43
|
+
placement: 'horizontal',
|
|
44
|
+
classes: {
|
|
45
|
+
hamburgerActive: 'vg-nav-hamburger-active',
|
|
46
|
+
hamburgerAlways: 'vg-nav-hamburger-always',
|
|
47
|
+
hamburger: 'vg-nav-hamburger',
|
|
48
|
+
container: 'vg-nav-container',
|
|
49
|
+
wrapper: 'vg-nav-wrapper',
|
|
50
|
+
active: 'vg-nav-active',
|
|
51
|
+
expand: 'vg-nav-expand',
|
|
52
|
+
cloned: 'vg-nav-cloned',
|
|
53
|
+
hover: 'vg-nav-hover',
|
|
54
|
+
flip: 'vg-nav-flip',
|
|
55
|
+
XXXL: 'vg-nav-xxxl',
|
|
56
|
+
XXL: 'vg-nav-xxl',
|
|
57
|
+
XL: 'vg-nav-xl',
|
|
58
|
+
LG: 'vg-nav-lg',
|
|
59
|
+
MD: 'vg-nav-md',
|
|
60
|
+
SM: 'vg-nav-sm',
|
|
61
|
+
XS: 'vg-nav-xs'
|
|
62
|
+
},
|
|
63
|
+
expand: true,
|
|
64
|
+
hover: false,
|
|
65
|
+
position: true,
|
|
66
|
+
collapse: true,
|
|
67
|
+
toggle: '<span class="default"></span>',
|
|
68
|
+
hamburger: {
|
|
69
|
+
enable: true,
|
|
70
|
+
always: false,
|
|
71
|
+
title: '',
|
|
72
|
+
body: null
|
|
73
|
+
},
|
|
74
|
+
callback: noop,
|
|
75
|
+
animation: true,
|
|
76
|
+
timeoutAnimation: 300,
|
|
77
|
+
ajax: {
|
|
78
|
+
route: '',
|
|
79
|
+
target: '',
|
|
80
|
+
method: 'get',
|
|
81
|
+
loader: false,
|
|
82
|
+
once: false,
|
|
83
|
+
output: true,
|
|
84
|
+
}
|
|
85
|
+
}, params));
|
|
86
|
+
|
|
87
|
+
this._navigation = null;
|
|
88
|
+
this.navigation = '.' + this._params.classes.wrapper;
|
|
89
|
+
|
|
90
|
+
this.movedLinks = [];
|
|
91
|
+
this.$links = Selectors.findAll('.' + this._params.classes.wrapper + ' > li', this.navigation)
|
|
92
|
+
|
|
93
|
+
if (this._params.animation === false) {
|
|
94
|
+
this._params.timeoutAnimation = 10
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static get NAME() {
|
|
99
|
+
return NAME;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static get NAME_KEY() {
|
|
103
|
+
return NAME_KEY;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
get navigation() {
|
|
107
|
+
return this._navigation;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
set navigation(el) {
|
|
111
|
+
let elm = Selectors.find(el, this._element);
|
|
112
|
+
if (!elm) return;
|
|
113
|
+
this._navigation = elm;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
build() {
|
|
117
|
+
if (!this.navigation) return;
|
|
118
|
+
|
|
119
|
+
let params = this._params;
|
|
120
|
+
|
|
121
|
+
// Вешаем основные классы
|
|
122
|
+
this._element.classList.add(params.classes.container);
|
|
123
|
+
this._element.classList.add('vg-nav-' + params.placement);
|
|
124
|
+
|
|
125
|
+
// Если нужно оставить список меню или установить медиа точку
|
|
126
|
+
if (!params.breakpoint) {
|
|
127
|
+
params.expand = false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (!params.hamburger.always) {
|
|
131
|
+
if (!params.breakpoint || !params.expand) {
|
|
132
|
+
this._element.classList.add(params.classes.expand);
|
|
133
|
+
} else if (params.breakpoint !== false) {
|
|
134
|
+
this._element.classList.add('vg-nav-' + params.breakpoint);
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
this._element.classList.add(params.classes.hamburgerAlways);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Меню срабатывает при наведении, если это не мобильное устройство
|
|
141
|
+
if (params.hover) {
|
|
142
|
+
this._element.classList.add(params.classes.hover);
|
|
143
|
+
|
|
144
|
+
if (Responsive.checkMobileOrTablet()) {
|
|
145
|
+
this._element.classList.remove(params.classes.hover);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Устанавливаем гамбургер, если его нет в разметке
|
|
150
|
+
if (params.expand && !params.hamburger.body && params.hamburger.enable) {
|
|
151
|
+
let isHamburger = Selectors.find('.' + params.classes.hamburger, this._element);
|
|
152
|
+
|
|
153
|
+
if (isHamburger === null) {
|
|
154
|
+
let mTitle = '',
|
|
155
|
+
hamburger = '<span class="' + params.classes.hamburger + '--lines"><span></span><span></span><span></span></span>';
|
|
156
|
+
|
|
157
|
+
if (params.hamburger.title) {
|
|
158
|
+
mTitle = '<span class="' + params.classes.hamburger + '--title">'+ params.hamburger.title +'</span>';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (params.hamburger.body !== null) {
|
|
162
|
+
hamburger = params.hamburger.body;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this._element.insertAdjacentHTML('afterbegin','<a href="#sidebar-nav" class="' + params.classes.hamburger + '" data-vg-toggle="sidebar">' + mTitle + hamburger +'</a>');
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Устанавливаем указатель переключателя
|
|
170
|
+
if (params.toggle) {
|
|
171
|
+
let $dropdown_a = [...Selectors.findAll('.dropdown-mega > a, .dropdown > a', this._element)],
|
|
172
|
+
toggle = '<span class="toggle">' + params.toggle + '</span>';
|
|
173
|
+
|
|
174
|
+
if ($dropdown_a.length) {
|
|
175
|
+
$dropdown_a.forEach(function (elem) {
|
|
176
|
+
if (!elem.querySelector('.toggle') && !elem.closest('.dots')) {
|
|
177
|
+
elem.setAttribute('aria-expanded', 'false')
|
|
178
|
+
elem.insertAdjacentHTML('beforeend', toggle)
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (params.collapse && Responsive.check(this) && params.placement !== 'vertical') {
|
|
185
|
+
setCollapse(this);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if ('afterInit' in this._params.callback) {
|
|
189
|
+
execute(this._params.callback.afterInit, [this]);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Функция сворачивания
|
|
194
|
+
* TODO Придумать что то с мега меню, которое уходит в подменю
|
|
195
|
+
* TODO Так же есть косяки при ресайзе
|
|
196
|
+
*/
|
|
197
|
+
function setCollapse(_this) {
|
|
198
|
+
let width_navigation_responsive = _this.navigation.clientWidth,
|
|
199
|
+
width_all_links_responsive = 0,
|
|
200
|
+
$dots = Selectors.find('.dots', _this.navigation),
|
|
201
|
+
_dots = getSVG('dots');
|
|
202
|
+
|
|
203
|
+
if (_this.$links.length) {
|
|
204
|
+
if ($dots) {
|
|
205
|
+
width_all_links_responsive = $dots.clientWidth
|
|
206
|
+
} else {
|
|
207
|
+
let $a = Selectors.find('a', _this.$links[0]),
|
|
208
|
+
$linkStyle = getComputedStyle($a),
|
|
209
|
+
paddingLeft = normalizeData($linkStyle.paddingLeft.slice(0, -2)),
|
|
210
|
+
paddingRight = normalizeData($linkStyle.paddingRight.slice(0, -2)),
|
|
211
|
+
padding = paddingLeft + paddingRight;
|
|
212
|
+
|
|
213
|
+
// TODO не совсем верно, но мы точно знаем ширину точек в svg - 16px
|
|
214
|
+
width_all_links_responsive = padding + 16;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
for (let $link of _this.$links) {
|
|
218
|
+
let width = $link.getBoundingClientRect().width;
|
|
219
|
+
width_all_links_responsive = width_all_links_responsive + width;
|
|
220
|
+
|
|
221
|
+
if ((width_navigation_responsive) < width_all_links_responsive) {
|
|
222
|
+
_this.movedLinks.push($link);
|
|
223
|
+
$link.remove();
|
|
224
|
+
} else {
|
|
225
|
+
if (_this.movedLinks.length) {
|
|
226
|
+
if ($dots) {
|
|
227
|
+
_this.navigation.insertBefore(_this.movedLinks[0], $dots)
|
|
228
|
+
} else {
|
|
229
|
+
_this.navigation.appendChild(_this.movedLinks[0])
|
|
230
|
+
}
|
|
231
|
+
_this.movedLinks.splice(0, 1);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (_this.movedLinks.length) {
|
|
237
|
+
if (!$dots) {
|
|
238
|
+
_this.navigation.insertAdjacentHTML('beforeend','<li class="dropdown dots">' + '<a href="#" aria-expanded="false">'+ _dots +'</a></li>');
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
if ($dots) {
|
|
242
|
+
$dots.remove();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
let $d = _this.navigation.querySelector('.dots');
|
|
247
|
+
if ($d && _this.movedLinks.length) {
|
|
248
|
+
let $dropdown = $d.querySelector('ul');
|
|
249
|
+
if ($dropdown) {
|
|
250
|
+
for (let link of _this.movedLinks) {
|
|
251
|
+
$dropdown.prepend(link);
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
let $dropdown = document.createElement('ul');
|
|
255
|
+
$dropdown.classList.add('dropdown-content');
|
|
256
|
+
$dropdown.classList.add('right');
|
|
257
|
+
|
|
258
|
+
for (let link of _this.movedLinks) {
|
|
259
|
+
$dropdown.prepend(link);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
$d.appendChild($dropdown);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
show(relatedTarget) {
|
|
270
|
+
let target = relatedTarget.relatedTarget;
|
|
271
|
+
|
|
272
|
+
if (!target || isDisabled(target)) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (!target.closest('.dropdown-content')) {
|
|
277
|
+
target.classList.add('first');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const showEvent = EventHandler.trigger(target, EVENT_KEY_SHOW, { relatedTarget });
|
|
281
|
+
if (showEvent.defaultPrevented) return;
|
|
282
|
+
|
|
283
|
+
let drop = Selectors.find('.dropdown-content', target),
|
|
284
|
+
link = target.firstElementChild;
|
|
285
|
+
|
|
286
|
+
if (link) link.setAttribute('aria-expanded', 'true');
|
|
287
|
+
drop.classList.add(CLASS_NAME_SHOW);
|
|
288
|
+
target.classList.add(CLASS_NAME_ACTIVE);
|
|
289
|
+
|
|
290
|
+
setDropPosition(drop)
|
|
291
|
+
|
|
292
|
+
const completeCallBack = () => {
|
|
293
|
+
drop.classList.add(CLASS_NAME_FADE);
|
|
294
|
+
EventHandler.trigger(target, EVENT_KEY_SHOWN, relatedTarget)
|
|
295
|
+
}
|
|
296
|
+
this._queueCallback(completeCallBack, drop, true, 50);
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
*
|
|
300
|
+
* @param $drop
|
|
301
|
+
*/
|
|
302
|
+
function setDropPosition($drop) {
|
|
303
|
+
let {width, right} = $drop.getBoundingClientRect(),
|
|
304
|
+
window_width = window.innerWidth;
|
|
305
|
+
|
|
306
|
+
let N_right = window_width - right - width;
|
|
307
|
+
|
|
308
|
+
$drop.classList.remove('right');
|
|
309
|
+
$drop.classList.remove('left');
|
|
310
|
+
|
|
311
|
+
let $parent = $drop.closest('li'),
|
|
312
|
+
$ul = $parent.querySelectorAll('ul');
|
|
313
|
+
|
|
314
|
+
if (N_right > width) {
|
|
315
|
+
for (const $el of $ul) {
|
|
316
|
+
$el.classList.add('left');
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
for (const $el of $ul) {
|
|
320
|
+
$el.classList.add('right');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
hide(relatedTarget) {
|
|
327
|
+
const _this = this;
|
|
328
|
+
if ('ontouchstart' in document.documentElement) {
|
|
329
|
+
for (const element of [].concat(...document.body.children)) {
|
|
330
|
+
EventHandler.off(element, 'mouseover', noop);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
let element = relatedTarget.relatedTarget;
|
|
335
|
+
|
|
336
|
+
if ('elm' in relatedTarget && relatedTarget.elm) {
|
|
337
|
+
element = relatedTarget.elm
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (element) {
|
|
341
|
+
const hideEvent = EventHandler.trigger(element, EVENT_KEY_HIDE);
|
|
342
|
+
if (hideEvent.defaultPrevented) return;
|
|
343
|
+
|
|
344
|
+
element.classList.remove(CLASS_NAME_ACTIVE);
|
|
345
|
+
|
|
346
|
+
if (element.classList.contains('first')) {
|
|
347
|
+
element.classList.remove('first');
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
[...Selectors.findAll('.' + CLASS_NAME_SHOW, element)].forEach(function (el, index) {
|
|
351
|
+
el.classList.remove(CLASS_NAME_FADE);
|
|
352
|
+
|
|
353
|
+
let parent = el.closest('.dropdown');
|
|
354
|
+
if (parent.classList.contains(CLASS_NAME_ACTIVE)) {
|
|
355
|
+
parent.classList.remove(CLASS_NAME_ACTIVE);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
let link = el.previousElementSibling;
|
|
359
|
+
if (link) link.setAttribute('aria-expanded', 'false');
|
|
360
|
+
|
|
361
|
+
if (index === 0) {
|
|
362
|
+
const completeCallback = () => {
|
|
363
|
+
el.classList.remove(CLASS_NAME_SHOW);
|
|
364
|
+
EventHandler.trigger(el, EVENT_KEY_HIDDEN, relatedTarget)
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
_this._queueCallback(completeCallback, el, true, 500);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* TODO если на странице несколько навигаций, то есть косяки
|
|
375
|
+
* @param element
|
|
376
|
+
* @param params
|
|
377
|
+
*/
|
|
378
|
+
static init(element, params = {}) {
|
|
379
|
+
const instance = VGNav.getOrCreateInstance(element, params);
|
|
380
|
+
instance.build();
|
|
381
|
+
|
|
382
|
+
let drops = Selectors.findAll('.dropdown', instance._navigation)
|
|
383
|
+
|
|
384
|
+
if (instance._params.hover) {
|
|
385
|
+
[...drops].forEach(function (el) {
|
|
386
|
+
let currentElem = null;
|
|
387
|
+
EventHandler.on(el, EVENT_MOUSEOVER_DATA_API, function (event) {
|
|
388
|
+
if (currentElem) return;
|
|
389
|
+
VGNav.hideOpenDrops(event);
|
|
390
|
+
|
|
391
|
+
let target = event.target.closest('.dropdown');
|
|
392
|
+
if (!target) return;
|
|
393
|
+
|
|
394
|
+
if (!instance.navigation.contains(target)) return;
|
|
395
|
+
currentElem = target;
|
|
396
|
+
|
|
397
|
+
let relatedTarget = {
|
|
398
|
+
relatedTarget: target
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
instance.show(relatedTarget);
|
|
402
|
+
});
|
|
403
|
+
EventHandler.on(el, EVENT_MOUSEOUT_DATA_API, function (event) {
|
|
404
|
+
if (!currentElem) return;
|
|
405
|
+
|
|
406
|
+
let relatedTarget = event.relatedTarget.closest('.dropdown'),
|
|
407
|
+
elm = currentElem;
|
|
408
|
+
|
|
409
|
+
while (relatedTarget) {
|
|
410
|
+
if (relatedTarget === currentElem) return;
|
|
411
|
+
relatedTarget = relatedTarget.parentNode;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
currentElem = null;
|
|
415
|
+
instance.hide({relatedTarget: relatedTarget, elm: elm});
|
|
416
|
+
})
|
|
417
|
+
})
|
|
418
|
+
} else {
|
|
419
|
+
EventHandler.on(document, EVENT_KEYUP_DATA_API, VGNav.clearDrops);
|
|
420
|
+
EventHandler.on(document, EVENT_CLICK_DATA_API, VGNav.clearDrops);
|
|
421
|
+
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
|
422
|
+
if (!Manipulator.has(this, 'aria-expanded')) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if ('click' in instance._params.callback) {
|
|
427
|
+
execute(instance._params.callback.click, [this]);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
event.preventDefault();
|
|
431
|
+
|
|
432
|
+
let self = this.closest('.vg-nav'),
|
|
433
|
+
isFirst = self.querySelector('.first');
|
|
434
|
+
|
|
435
|
+
let target = this.closest('.dropdown');
|
|
436
|
+
if (!target) return;
|
|
437
|
+
|
|
438
|
+
if (isDisabled(target) && !isVisible(target)) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (isFirst && this.closest('.first')) {
|
|
443
|
+
if (target.classList.contains('active')) {
|
|
444
|
+
instance.hide({relatedTarget: target});
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
} else {
|
|
448
|
+
[...Selectors.findAll('.active', self)].forEach(function (el) {
|
|
449
|
+
if (el && el !== target) {
|
|
450
|
+
instance.hide({relatedTarget: el})
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
instance.show({relatedTarget: target});
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const vgNavSidebar = document.getElementById('sidebar-nav');
|
|
460
|
+
let hamburger = instance._element.querySelector('.' + instance._params.classes.hamburger);
|
|
461
|
+
|
|
462
|
+
if (vgNavSidebar && hamburger) {
|
|
463
|
+
vgNavSidebar.addEventListener('vg.sidebar.show', function () {
|
|
464
|
+
hamburger.classList.add(instance._params.classes.hamburgerActive);
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
vgNavSidebar.addEventListener('vg.sidebar.hide', function () {
|
|
468
|
+
hamburger.classList.remove(instance._params.classes.hamburgerActive);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
static clearDrops(event) {
|
|
474
|
+
if (event.button === 2 || (event.type === 'keyup' && event.key !== 'Tab')) {
|
|
475
|
+
return
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
VGNav.hideOpenDrops(event)
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
static hideOpenDrops(event) {
|
|
482
|
+
const openToggles = Selectors.findAll('.dropdown:not(.disabled):not(:disabled).active');
|
|
483
|
+
|
|
484
|
+
for (const toggle of openToggles) {
|
|
485
|
+
const context = VGNav.getInstance(toggle.closest('.vg-nav'));
|
|
486
|
+
if (!context) continue;
|
|
487
|
+
|
|
488
|
+
if (event.target.closest('.first')) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const relatedTarget = { relatedTarget: toggle }
|
|
493
|
+
|
|
494
|
+
if (event.type === 'click') {
|
|
495
|
+
relatedTarget.clickEvent = event
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
context.hide(relatedTarget)
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
EventHandler.on(window, EVENT_RESIZE_DATA_API, function () {
|
|
504
|
+
if (Selectors.find('.vg-nav')) {
|
|
505
|
+
const instance = VGNav.getOrCreateInstance('.vg-nav', {});
|
|
506
|
+
instance.build();
|
|
507
|
+
}
|
|
508
|
+
})
|
|
509
|
+
|
|
510
|
+
export default VGNav;
|