aloha-vue 1.2.261 → 1.2.262

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.262",
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,7 @@ export default {
233
248
 
234
249
  const {
235
250
  attributesMenuClick,
251
+ attributesMobile,
236
252
  } = MenuAttributesAPI(props, {
237
253
  isMenuOpen,
238
254
  toggleMenu,
@@ -245,6 +261,7 @@ export default {
245
261
  isMenuInitialized,
246
262
  isMobileWidth,
247
263
  } = ResizeAPI(props, {
264
+ removeListenerForKeydown,
248
265
  toggleMenu,
249
266
  });
250
267
 
@@ -279,9 +296,9 @@ export default {
279
296
 
280
297
  const {
281
298
  destroyPopover,
282
- menuRef,
283
299
  startPopper,
284
300
  } = PopoverAPI(props, {
301
+ menuRef,
285
302
  isMenuOpen,
286
303
  panelParentsOpen,
287
304
  });
@@ -317,6 +334,9 @@ export default {
317
334
  closeAllPanels();
318
335
  if (newValue) {
319
336
  destroyPopover();
337
+ setListenerForKeydown();
338
+ } else {
339
+ removeListenerForKeydown();
320
340
  }
321
341
  });
322
342
 
@@ -342,12 +362,14 @@ export default {
342
362
  removeBodyClasses();
343
363
  destroyEventBusUpdateViewOnResize();
344
364
  destroyPopover();
365
+ removeListenerForKeydown();
345
366
  });
346
367
 
347
368
  return {
348
369
  activeRoutesIds,
349
370
  attributesBlockerClick,
350
371
  attributesMenuClick,
372
+ attributesMobile,
351
373
  checkAllRoutes,
352
374
  clickAttributesBackdrop,
353
375
  clickOnSearchBtn,
@@ -386,6 +408,7 @@ export default {
386
408
  a_menu_2_mobile: this.isMobileWidth,
387
409
  },
388
410
  ],
411
+ ...this.attributesMobile,
389
412
  ...this.attributesMenuClick,
390
413
  }, [
391
414
  h("div", {
@@ -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,12 +4,29 @@ 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");
12
14
 
15
+ const {
16
+ isMobileWidth,
17
+ } = AMobileAPI();
18
+
19
+ const attributesMobile = computed(() => {
20
+ if (isMobileWidth.value) {
21
+ return {
22
+ role: "dialog",
23
+ ariaModal: true,
24
+ };
25
+ }
26
+
27
+ return {};
28
+ });
29
+
13
30
  const attributesMenuClick = computed(() => {
14
31
  const ATTRIBUTES = {};
15
32
  if (isBlockerClickable.value &&
@@ -22,5 +39,6 @@ export default function MenuAttributesAPI(props, {
22
39
 
23
40
  return {
24
41
  attributesMenuClick,
42
+ attributesMobile,
25
43
  };
26
44
  }
@@ -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