vgapp 0.7.7 → 0.7.8

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.
@@ -6,7 +6,6 @@ import Placement from "../../../utils/js/components/placement";
6
6
  import Overflow from "../../../utils/js/components/overflow";
7
7
  import Backdrop from "../../../utils/js/components/backdrop";
8
8
  import {dismissTrigger} from "../../module-fn";
9
- import VGSidebar from "../../vgsidebar";
10
9
 
11
10
  const NAME = 'dropdown';
12
11
  const NAME_KEY = 'vg.dropdown';
@@ -33,12 +32,11 @@ class VGDropdown extends BaseModule {
33
32
  super(element, params);
34
33
 
35
34
  let defaultParams = {
36
- offset: [0, 2],
37
35
  backdrop: false,
38
36
  overflow: false,
39
37
  keyboard: false,
40
- placement: 'bottom',
41
38
  timeoutAnimation: 10,
39
+ placement: 'auto',
42
40
  hover: false,
43
41
  ajax: {
44
42
  route: '',
@@ -49,30 +47,27 @@ class VGDropdown extends BaseModule {
49
47
  output: true,
50
48
  },
51
49
  animation: {
52
- fade: false,
50
+ fade: true,
53
51
  enable: false,
54
52
  in: 'animate__flipInY',
55
53
  out: 'animate__flipOutY',
56
- delay: 800,
54
+ delay: 300,
57
55
  },
58
- }
59
-
60
- if ('offset' in params && Array.isArray(params.offset)) {
61
- defaultParams.offset = params.offset;
62
- }
56
+ };
63
57
 
64
58
  this._params = this._getParams(element, mergeDeepObject(defaultParams, params));
65
59
 
66
60
  const target = Selectors.getElementFromSelector(this._element);
67
-
68
61
  this._parent = this._element.parentNode;
69
- this._drop = target || Selectors.find('.' + TARGET_CONTAINER, this._parent);
70
- this._isPlacement = false;
62
+ this._drop = target || Selectors.find(`.${TARGET_CONTAINER}`, this._parent);
63
+
64
+ if (!this._drop) return;
71
65
 
72
- this.isFade = this._params.animation.fade;
66
+ this._isPlacement = false;
67
+ this.isFade = this._params.animation.fade;
73
68
  this.isAnimation = this._params.animation.enable;
74
69
 
75
- this._params.animation.delay = !this.isAnimation ? 0 : this._params.animation.delay;
70
+ this._params.animation.delay = this.isAnimation ? this._params.animation.delay : 0;
76
71
  this._animation(this._drop, VGDropdown.NAME_KEY, this._params.animation);
77
72
  }
78
73
 
@@ -91,25 +86,22 @@ class VGDropdown extends BaseModule {
91
86
  show() {
92
87
  if (isDisabled(this._element) || this._isShown()) return;
93
88
 
94
- const relatedTarget = {
95
- relatedTarget: this._element
96
- }
89
+ const relatedTarget = { relatedTarget: this._element };
97
90
 
98
- const showEvent = EventHandler.trigger(this._drop, EVENT_KEY_SHOW, relatedTarget)
91
+ const showEvent = EventHandler.trigger(this._drop, EVENT_KEY_SHOW, relatedTarget);
99
92
  if (showEvent.defaultPrevented) return;
100
93
 
101
94
  if ('ontouchstart' in document.documentElement) {
102
- for (const element of [].concat(...document.body.children)) {
103
- EventHandler.on(element, 'mouseover', noop);
104
- }
95
+ [].concat(...document.body.children).forEach(el => {
96
+ EventHandler.on(el, 'mouseover', noop);
97
+ });
105
98
  }
106
99
 
107
- this._route();
108
-
109
- this._element.setAttribute('aria-expanded', true);
100
+ this._element.setAttribute('aria-expanded', 'true');
110
101
  this._element.classList.add(CLASS_NAME_SHOW);
111
102
  this._drop.classList.add(CLASS_NAME_SHOW);
112
103
  this._setPlacement();
104
+ this._route();
113
105
 
114
106
  if (this._params.backdrop && !this._params.hover) {
115
107
  Backdrop.show();
@@ -117,36 +109,28 @@ class VGDropdown extends BaseModule {
117
109
 
118
110
  if (this._params.overflow) {
119
111
  Overflow.append();
120
- document.body.classList.add('dropdown-open')
112
+ document.body.classList.add('dropdown-open');
121
113
  }
122
114
 
123
- const completeCallBack = () => {
115
+ const completeCallback = () => {
124
116
  if (this.isFade) {
125
117
  this._drop.classList.add(CLASS_NAME_FADE);
126
- } else if(!this.isAnimation) {
118
+ } else if (!this.isAnimation) {
127
119
  this._drop.classList.add(CLASS_NAME_OPEN);
128
120
  }
121
+ EventHandler.trigger(this._drop, EVENT_KEY_SHOWN, relatedTarget);
122
+ };
129
123
 
130
- EventHandler.trigger(this._drop, EVENT_KEY_SHOWN, relatedTarget)
131
- }
132
-
133
- this._queueCallback(completeCallBack, this._drop, this.isAnimation || this.isFade, 50);
124
+ this._queueCallback(completeCallback, this._drop, this.isAnimation || this.isFade, 50);
134
125
  }
135
126
 
136
127
  hide() {
137
- if (isDisabled(this._element) || !this._isShown()) {
138
- return;
139
- }
140
-
141
- const relatedTarget = {
142
- relatedTarget: this._element
143
- }
144
-
145
- this._completeHide(relatedTarget);
128
+ if (isDisabled(this._element) || !this._isShown()) return;
129
+ this._completeHide({ relatedTarget: this._element });
146
130
  }
147
131
 
148
132
  dispose() {
149
- return super.dispose();
133
+ super.dispose();
150
134
  }
151
135
 
152
136
  _isShown() {
@@ -154,30 +138,27 @@ class VGDropdown extends BaseModule {
154
138
  }
155
139
 
156
140
  _completeHide(relatedTarget) {
157
- const hideEvent = EventHandler.trigger(this._drop, EVENT_KEY_HIDE, relatedTarget)
158
- if (hideEvent.defaultPrevented) {
159
- return;
160
- }
141
+ const hideEvent = EventHandler.trigger(this._drop, EVENT_KEY_HIDE, relatedTarget);
142
+ if (hideEvent.defaultPrevented) return;
161
143
 
162
144
  if ('ontouchstart' in document.documentElement) {
163
- for (const element of [].concat(...document.body.children)) {
164
- EventHandler.off(element, 'mouseover', noop);
165
- }
145
+ [].concat(...document.body.children).forEach(el => {
146
+ EventHandler.off(el, 'mouseover', noop);
147
+ });
166
148
  }
167
149
 
150
+ this._element.classList.remove(CLASS_NAME_SHOW);
151
+ this._element.setAttribute('aria-expanded', 'false');
152
+
168
153
  if (this.isFade) {
169
154
  this._drop.classList.remove(CLASS_NAME_FADE);
170
- } else if(!this.isAnimation) {
155
+ } else if (!this.isAnimation) {
171
156
  this._drop.classList.remove(CLASS_NAME_OPEN);
172
157
  }
173
158
 
174
- this._element.classList.remove(CLASS_NAME_SHOW);
175
- this._element.setAttribute('aria-expanded', 'false');
176
-
177
159
  if (this._params.backdrop && !this._params.hover) {
178
- const _this = this;
179
- Backdrop.hide(function () {
180
- if (_this._params.overflow) {
160
+ Backdrop.hide(() => {
161
+ if (this._params.overflow) {
181
162
  Overflow.destroy();
182
163
  }
183
164
  });
@@ -192,29 +173,40 @@ class VGDropdown extends BaseModule {
192
173
  const completeCallback = () => {
193
174
  this._drop.classList.remove(CLASS_NAME_SHOW);
194
175
  EventHandler.trigger(this._drop, EVENT_KEY_HIDDEN, relatedTarget);
195
- }
176
+ };
196
177
  this._queueCallback(completeCallback, this._drop, this.isAnimation || this.isFade);
197
178
  }, this._params.animation.delay);
198
179
  }
199
180
 
200
- // TODO class Placement isn't done
201
181
  _setPlacement() {
202
- const _this = this;
203
-
204
- if (!_this._isPlacement) {
205
- const $placement = new Placement({
206
- drop: _this._drop
207
- })
182
+ if (!this._drop) return;
183
+
184
+ if (!this._isPlacement) {
185
+ let placementDefault = 'bottom-start',
186
+ autoFlip = false,
187
+ overflowProtection = false;
188
+
189
+ if (this._params.placement === 'auto') {
190
+ autoFlip = true;
191
+ overflowProtection = true;
192
+ } else {
193
+ placementDefault = this._params.placement
194
+ }
208
195
 
209
- $placement._setPlacement();
210
- }
196
+ const placement = new Placement({
197
+ reference: this._element,
198
+ drop: this._drop,
199
+ placement: placementDefault,
200
+ boundary: 'clippingParents',
201
+ autoFlip: autoFlip,
202
+ overflowProtection: overflowProtection,
203
+ fallbackPlacements: ['top-start', 'bottom-end', 'top-end'],
204
+ });
211
205
 
212
- if (_this._params.offset) {
213
- _this._drop.style.paddingTop = _this._params.offset[1] + 'px';
214
- _this._drop.style.paddingRight = _this._params.offset[0] + 'px';
206
+ placement._setPlacement(); // позиционируем
215
207
  }
216
208
 
217
- _this._isPlacement = true;
209
+ this._isPlacement = true;
218
210
  }
219
211
 
220
212
  static init(element, params = {}) {
@@ -223,109 +215,103 @@ class VGDropdown extends BaseModule {
223
215
  if (instance._params.hover && !instance.isMobileDevice()) {
224
216
  let currentElem = null;
225
217
 
226
- EventHandler.on(instance._parent, EVENT_MOUSEOVER_DATA_API, function (event) {
218
+ EventHandler.on(instance._parent, EVENT_MOUSEOVER_DATA_API, (event) => {
227
219
  if (currentElem) return;
220
+
228
221
  VGDropdown.hideOpenToggles(event);
229
222
 
230
- let target = event.target.closest('.' + PARENT_CONTAINER);
231
- if (!target) return;
223
+ const target = event.target.closest(`.${PARENT_CONTAINER}`);
224
+ if (!target || !instance._parent.contains(target)) return;
232
225
 
233
- if (!instance._parent.contains(target)) return;
234
226
  currentElem = target;
235
227
  instance.show();
236
228
  });
237
229
 
238
- EventHandler.on(instance._parent, EVENT_MOUSEOUT_DATA_API, function (event) {
230
+ EventHandler.on(instance._parent, EVENT_MOUSEOUT_DATA_API, (event) => {
239
231
  if (!currentElem) return;
240
232
 
241
233
  let relatedTarget = event.relatedTarget;
242
-
243
- while (relatedTarget) {
244
- if (relatedTarget === currentElem) return;
234
+ while (relatedTarget && relatedTarget !== currentElem) {
245
235
  relatedTarget = relatedTarget.parentNode;
246
236
  }
247
237
 
238
+ if (relatedTarget === currentElem) return;
239
+
248
240
  currentElem = null;
249
- instance._completeHide({relatedTarget: instance._element});
250
- })
241
+ instance._completeHide({ relatedTarget: instance._element });
242
+ });
251
243
  }
252
244
 
245
+ // Клавиатурные события
253
246
  EventHandler.on(document, EVENT_KEYUP_DATA_API, SELECTOR_DATA_TOGGLE, VGDropdown.keydownHandler);
254
- EventHandler.on(document, EVENT_KEYDOWN_DATA_API, '.' + TARGET_CONTAINER, VGDropdown.keydownHandler);
247
+ EventHandler.on(document, EVENT_KEYDOWN_DATA_API, `.${TARGET_CONTAINER}`, VGDropdown.keydownHandler);
255
248
  EventHandler.on(document, EVENT_KEYUP_DATA_API, VGDropdown.clearDrops);
256
249
  EventHandler.on(document, EVENT_CLICK_DATA_API, VGDropdown.clearDrops);
257
- EventHandler.on(element, EVENT_CLICK_DATA_API, function (event) {
250
+
251
+ // Клик по тоглу
252
+ EventHandler.on(element, EVENT_CLICK_DATA_API, (event) => {
258
253
  event.preventDefault();
259
254
  instance.toggle();
260
255
  });
261
256
  }
262
257
 
263
258
  static hideOpenToggles(event) {
264
- const openToggles = Selectors.findAll('[data-vg-toggle="dropdown"]:not(.disabled):not(:disabled).show');
259
+ const openToggles = Selectors.findAll(`${SELECTOR_DATA_TOGGLE}:not(.disabled):not(:disabled).${CLASS_NAME_SHOW}`);
265
260
  for (const toggle of openToggles) {
266
261
  const context = VGDropdown.getInstance(toggle);
267
- if (!context) {
268
- continue;
269
- }
262
+ if (!context) continue;
270
263
 
271
- if (event.target.closest('.' + TARGET_CONTAINER) === context._drop) {
264
+ if (event.target.closest(`.${TARGET_CONTAINER}`) === context._drop) {
272
265
  return;
273
266
  }
274
267
 
275
- const composedPath = event.composedPath();
268
+ const composedPath = event.composedPath?.() || [];
276
269
  if (composedPath.includes(context._element)) {
277
- continue
270
+ continue;
278
271
  }
279
272
 
280
- const relatedTarget = { relatedTarget: context._element }
281
-
273
+ const relatedTarget = { relatedTarget: context._element };
282
274
  if (event.type === 'click') {
283
- relatedTarget.clickEvent = event
275
+ relatedTarget.clickEvent = event;
284
276
  }
285
277
 
286
- context._completeHide(relatedTarget)
278
+ context._completeHide(relatedTarget);
287
279
  }
288
280
  }
289
281
 
290
282
  static keydownHandler(event) {
291
- const isInput = /input|textarea/i.test(event.target.tagName)
292
- const isEscapeEvent = event.key === 'Escape'
293
- const isUpOrDownEvent = ['ArrowUp', 'ArrowDown'].includes(event.key)
283
+ const isInput = /input|textarea/i.test(event.target.tagName);
284
+ const isEscapeEvent = event.key === 'Escape';
285
+ const isUpOrDownEvent = ['ArrowUp', 'ArrowDown'].includes(event.key);
294
286
 
295
- if (!isUpOrDownEvent && !isEscapeEvent) {
296
- return
297
- }
287
+ if (!isUpOrDownEvent && !isEscapeEvent) return;
288
+ if (isInput && !isEscapeEvent) return;
298
289
 
299
- if (isInput && !isEscapeEvent) {
300
- return
301
- }
290
+ event.preventDefault();
302
291
 
303
- event.preventDefault()
292
+ const toggle = this.matches(SELECTOR_DATA_TOGGLE)
293
+ ? this
294
+ : Selectors.find(SELECTOR_DATA_TOGGLE, event.delegateTarget?.parentNode);
304
295
 
305
- const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ?
306
- this : (Selectors.find(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode))
296
+ if (!toggle) return;
307
297
 
308
- const instance = VGDropdown.getOrCreateInstance(getToggleButton)
298
+ const instance = VGDropdown.getOrCreateInstance(toggle);
309
299
 
310
300
  if (isUpOrDownEvent) {
311
- event.stopPropagation()
312
- instance.show()
313
- return
314
- }
315
-
316
- if (instance._isShown()) {
317
- event.stopPropagation()
318
- instance.hide()
319
- getToggleButton.focus()
301
+ event.stopPropagation();
302
+ instance.show();
303
+ } else if (instance._isShown()) {
304
+ event.stopPropagation();
305
+ instance.hide();
306
+ toggle.focus();
320
307
  }
321
308
  }
322
309
 
323
310
  static clearDrops(event) {
324
311
  if (event.button === 2 || (event.type === 'keyup' && event.key !== 'Tab')) {
325
- return
312
+ return;
326
313
  }
327
-
328
- VGDropdown.hideOpenToggles(event)
314
+ VGDropdown.hideOpenToggles(event);
329
315
  }
330
316
  }
331
317
 
@@ -22,8 +22,7 @@
22
22
  min-width: var(--vg-dropdown-min-width);
23
23
  position: absolute;
24
24
  opacity: 0;
25
- left: 0;
26
- top: 100%;
25
+ padding-top: 2px;
27
26
 
28
27
  &.open {
29
28
  transition: none;
@@ -2,8 +2,8 @@ import BaseModule from "../../base-module";
2
2
  import EventHandler from "../../../utils/js/dom/event";
3
3
  import Selectors from "../../../utils/js/dom/selectors";
4
4
  import {isDisabled, mergeDeepObject} from "../../../utils/js/functions";
5
- import Templater from "../../../utils/js/components/templater";
6
5
  import {Manipulator} from "../../../utils/js/dom/manipulator";
6
+ import Html from "../../../utils/js/components/templater";
7
7
 
8
8
  /**
9
9
  * Constants
@@ -61,13 +61,16 @@ class VGHideShowPass extends BaseModule{
61
61
  }
62
62
 
63
63
  build(isShow = false) {
64
+ let classes = this._params.classes.join(' '), elm = '';
65
+ const HTML = Html('string');
66
+
64
67
  if (!isShow) {
65
- this._params.template = 'pass-close';
68
+ elm = HTML.component('eye', {class: classes});
66
69
  } else {
67
- this._params.template = 'pass-open';
70
+ elm = HTML.component('eye', {class: classes, type: 'hide'});
68
71
  }
69
72
 
70
- new Templater(this._element, this._params).render();
73
+ this._element.insertAdjacentHTML(this._params.insert, elm);
71
74
  }
72
75
  }
73
76