aloha-vue 1.2.261 → 1.2.263

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/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "Vue.js"
15
15
  ],
16
16
  "homepage": "https://github.com/ilia-brykin/aloha/#README.md",
17
- "version": "1.2.261",
17
+ "version": "1.2.263",
18
18
  "author": {
19
19
  "name": "Ilia Brykin",
20
20
  "email": "brykin.ilia@gmail.com"
@@ -20,6 +20,7 @@ import AMenuBlockerClickAPI from "./compositionAPI/AMenuBlockerClickAPI";
20
20
  import BackdropAPI from "./compositionAPI/BackdropAPI";
21
21
  import CheckRoutesAPI from "./compositionAPI/CheckRoutesAPI";
22
22
  import DataAPI from "./compositionAPI/DataAPI";
23
+ import KeydownAPI from "./compositionAPI/KeydownAPI";
23
24
  import LinkClickAPI from "./compositionAPI/LinkClickAPI";
24
25
  import MenuAttributesAPI from "./compositionAPI/MenuAttributesAPI";
25
26
  import PanelMainAPI from "./compositionAPI/PanelMainAPI";
@@ -183,12 +184,23 @@ export default {
183
184
  required: false,
184
185
  default: true,
185
186
  },
187
+ useEscapeForMobile: {
188
+ type: Boolean,
189
+ required: false,
190
+ default: true,
191
+ },
186
192
  },
187
193
  setup(props) {
188
194
  const isLinkTruncated = toRef(props, "isLinkTruncated");
189
195
  const showCountChildren = toRef(props, "showCountChildren");
190
196
  const breadcrumbsTruncatedOffset = toRef(props, "breadcrumbsTruncatedOffset");
191
197
 
198
+ const {
199
+ menuRef,
200
+ removeListenerForKeydown,
201
+ setListenerForKeydown,
202
+ } = KeydownAPI(props);
203
+
192
204
  const {
193
205
  dataKeyById,
194
206
  dataProParent,
@@ -221,7 +233,10 @@ export default {
221
233
  isMenuOpen,
222
234
  removeBodyClasses,
223
235
  toggleMenu,
224
- } = ToggleAPI(props);
236
+ } = ToggleAPI(props, {
237
+ removeListenerForKeydown,
238
+ setListenerForKeydown,
239
+ });
225
240
 
226
241
  const {
227
242
  clickOnSearchBtn,
@@ -233,6 +248,8 @@ export default {
233
248
 
234
249
  const {
235
250
  attributesMenuClick,
251
+ attributesMobile,
252
+ headerId,
236
253
  } = MenuAttributesAPI(props, {
237
254
  isMenuOpen,
238
255
  toggleMenu,
@@ -245,6 +262,7 @@ export default {
245
262
  isMenuInitialized,
246
263
  isMobileWidth,
247
264
  } = ResizeAPI(props, {
265
+ removeListenerForKeydown,
248
266
  toggleMenu,
249
267
  });
250
268
 
@@ -279,9 +297,9 @@ export default {
279
297
 
280
298
  const {
281
299
  destroyPopover,
282
- menuRef,
283
300
  startPopper,
284
301
  } = PopoverAPI(props, {
302
+ menuRef,
285
303
  isMenuOpen,
286
304
  panelParentsOpen,
287
305
  });
@@ -317,6 +335,9 @@ export default {
317
335
  closeAllPanels();
318
336
  if (newValue) {
319
337
  destroyPopover();
338
+ setListenerForKeydown();
339
+ } else {
340
+ removeListenerForKeydown();
320
341
  }
321
342
  });
322
343
 
@@ -342,17 +363,20 @@ export default {
342
363
  removeBodyClasses();
343
364
  destroyEventBusUpdateViewOnResize();
344
365
  destroyPopover();
366
+ removeListenerForKeydown();
345
367
  });
346
368
 
347
369
  return {
348
370
  activeRoutesIds,
349
371
  attributesBlockerClick,
350
372
  attributesMenuClick,
373
+ attributesMobile,
351
374
  checkAllRoutes,
352
375
  clickAttributesBackdrop,
353
376
  clickOnSearchBtn,
354
377
  dataKeyById,
355
378
  dataProParent,
379
+ headerId,
356
380
  isBackdropVisible,
357
381
  isLeastOnePanelOpenAndMenuClosed,
358
382
  isMenuOpen,
@@ -377,6 +401,7 @@ export default {
377
401
  return h("nav", {
378
402
  ref: "menuRef",
379
403
  id: this.menuId,
404
+ "aria-labelledby": this.headerId,
380
405
  class: [
381
406
  "a_menu_2",
382
407
  {
@@ -386,6 +411,7 @@ export default {
386
411
  a_menu_2_mobile: this.isMobileWidth,
387
412
  },
388
413
  ],
414
+ ...this.attributesMobile,
389
415
  ...this.attributesMenuClick,
390
416
  }, [
391
417
  h("div", {
@@ -415,6 +441,7 @@ export default {
415
441
  class: "a_menu_2__navbar_top_sub",
416
442
  }, [
417
443
  h(ATranslation, {
444
+ id: this.headerId,
418
445
  class: "a_menu_2__navbar_top_sub__text",
419
446
  tag: "strong",
420
447
  text: "_A_MENU_2_MAIN_MENU_",
@@ -0,0 +1,83 @@
1
+ import {
2
+ ref,
3
+ toRef,
4
+ } from "vue";
5
+
6
+ import AMobileAPI from "../../compositionAPI/AMobileAPI";
7
+
8
+ import AKeysCode from "../../const/AKeysCode";
9
+ import {
10
+ focusableSelector,
11
+ } from "../../const/AFocusableElements";
12
+
13
+ export default function KeydownAPI(props) {
14
+ const useEscapeForMobile = toRef(props, "useEscapeForMobile");
15
+
16
+ const menuRef = ref(undefined);
17
+
18
+ const {
19
+ isMobileWidth,
20
+ } = AMobileAPI();
21
+
22
+ const trapFocus = EVENT => {
23
+ if (!menuRef.value) {
24
+ return;
25
+ }
26
+
27
+ const FOCUSABLE_ELEMENTS = menuRef.value.querySelectorAll(focusableSelector);
28
+ if (FOCUSABLE_ELEMENTS.length === 0) {
29
+ EVENT.preventDefault();
30
+ return;
31
+ }
32
+
33
+ const FIRST_FOCUSABLE_ELEMENT = FOCUSABLE_ELEMENTS[0];
34
+ const LAST_FOCUSABLE_ELEMENT = FOCUSABLE_ELEMENTS[FOCUSABLE_ELEMENTS.length - 1];
35
+ if (EVENT.shiftKey) { // Shift + Tab
36
+ if (document.activeElement === FIRST_FOCUSABLE_ELEMENT) {
37
+ LAST_FOCUSABLE_ELEMENT.focus();
38
+ EVENT.preventDefault();
39
+ }
40
+ } else { // Tab
41
+ if (document.activeElement === LAST_FOCUSABLE_ELEMENT) {
42
+ FIRST_FOCUSABLE_ELEMENT.focus();
43
+ EVENT.preventDefault();
44
+ }
45
+ }
46
+ };
47
+
48
+ const pressEscape = $event => {
49
+ if (!useEscapeForMobile.value) {
50
+ return;
51
+ }
52
+
53
+ close.value();
54
+ $event.preventDefault();
55
+ $event.stopPropagation();
56
+ };
57
+
58
+ const keydown = $event => {
59
+ const EVENT = $event || window.$event;
60
+ if (EVENT.key === "Escape" || EVENT.keyCode === AKeysCode.escape) {
61
+ pressEscape($event);
62
+ } else if (EVENT.key === "Tab" || EVENT.keyCode === AKeysCode.tab) {
63
+ trapFocus(EVENT);
64
+ }
65
+ };
66
+
67
+ const setListenerForKeydown = () => {
68
+ if (isMobileWidth.value) {
69
+ document.addEventListener("keydown", keydown);
70
+ }
71
+ };
72
+
73
+
74
+ const removeListenerForKeydown = () => {
75
+ document.removeEventListener("keydown", keydown);
76
+ };
77
+
78
+ return {
79
+ menuRef,
80
+ removeListenerForKeydown,
81
+ setListenerForKeydown,
82
+ };
83
+ }
@@ -4,11 +4,33 @@ import {
4
4
  toRef,
5
5
  } from "vue";
6
6
 
7
+ import AMobileAPI from "../../compositionAPI/AMobileAPI";
8
+
7
9
  export default function MenuAttributesAPI(props, {
8
10
  isMenuOpen = ref(false),
9
11
  toggleMenu = () => {},
10
12
  }) {
11
13
  const isBlockerClickable = toRef(props, "isBlockerClickable");
14
+ const menuId = toRef(props, "menuId");
15
+
16
+ const {
17
+ isMobileWidth,
18
+ } = AMobileAPI();
19
+
20
+ const attributesMobile = computed(() => {
21
+ if (isMobileWidth.value) {
22
+ return {
23
+ role: "dialog",
24
+ ariaModal: true,
25
+ };
26
+ }
27
+
28
+ return {};
29
+ });
30
+
31
+ const headerId = computed(() => {
32
+ return `${ menuId.value }_header`;
33
+ });
12
34
 
13
35
  const attributesMenuClick = computed(() => {
14
36
  const ATTRIBUTES = {};
@@ -22,5 +44,7 @@ export default function MenuAttributesAPI(props, {
22
44
 
23
45
  return {
24
46
  attributesMenuClick,
47
+ attributesMobile,
48
+ headerId,
25
49
  };
26
50
  }
@@ -20,13 +20,13 @@ import {
20
20
  } from "lodash-es";
21
21
 
22
22
  export default function PopoverAPI(props, {
23
+ menuRef = ref(undefined),
23
24
  isMenuOpen = computed(() => false),
24
25
  panelParentsOpen = ref([]),
25
26
  }) {
26
27
  const menuId = toRef(props, "menuId");
27
28
 
28
29
  const cleanupPopper = ref({});
29
- const menuRef = ref(undefined);
30
30
  const isEventCloseClickStarted = ref(false);
31
31
 
32
32
  const getElementLink = ({ id }) => {
@@ -133,7 +133,6 @@ export default function PopoverAPI(props, {
133
133
 
134
134
  return {
135
135
  destroyPopover,
136
- menuRef,
137
136
  startPopper,
138
137
  };
139
138
  }
@@ -8,7 +8,8 @@ import AMobileAPI from "../../compositionAPI/AMobileAPI";
8
8
  import EventBus from "../../utils/EventBus";
9
9
 
10
10
  export default function ResizeAPI(props, {
11
- toggleMenu,
11
+ removeListenerForKeydown = () => {},
12
+ toggleMenu = () => {},
12
13
  }) {
13
14
  const isMenuOpenInitial = toRef(props, "isMenuOpenInitial");
14
15
 
@@ -23,6 +24,7 @@ export default function ResizeAPI(props, {
23
24
  toggleMenu({ isOpen: false });
24
25
  } else {
25
26
  toggleMenu({ isOpen: isMenuOpenInitial.value });
27
+ removeListenerForKeydown();
26
28
  }
27
29
  };
28
30