diff --git a/lib/KDropdownMenu.vue b/lib/KDropdownMenu.vue
index 6d4f3d354..e00a6fbb2 100644
--- a/lib/KDropdownMenu.vue
+++ b/lib/KDropdownMenu.vue
@@ -18,6 +18,7 @@
@open="handleOpen"
>
@@ -97,11 +98,15 @@
},
},
beforeDestroy() {
- window.removeEventListener('keyup', this.handleKeyUp, true);
+ window.removeEventListener('keydown', this.handleOpenMenuNavigation, true);
},
methods: {
handleOpen() {
- window.addEventListener('keyup', this.handleKeyUp, true);
+ this.$nextTick(() => this.setFocus());
+ window.addEventListener('keydown', this.handleOpenMenuNavigation, true);
+ },
+ setFocus() {
+ this.$refs.menu.$el.querySelector('li').focus();
},
handleClose() {
const focusedElement = document.activeElement;
@@ -116,14 +121,34 @@
}
window.removeEventListener('keyup', this.handleKeyUp, true);
},
- handleKeyUp(event) {
- if (event.shiftKey && event.keyCode == 9) {
- const popover = this.$refs.popover.$el;
- const popoverIsOpen = popover.clientWidth > 0 && popover.clientHeight > 0;
- if (popoverIsOpen && !popover.contains(document.activeElement)) {
- this.closePopover();
- this.focusOnButton();
- }
+ handleOpenMenuNavigation(event) {
+ // identify the menu state and length
+ if (!this.$refs.popover && !this.$refs.popover.$el) {
+ return;
+ }
+ const popover = this.$refs.popover.$el;
+ const menuElements = this.$refs.menu.$el.querySelector('div').children;
+ const lastChild = menuElements[menuElements.length - 1];
+ const popoverIsOpen = popover.clientWidth > 0 && popover.clientHeight > 0;
+ // set current element and its siblings
+ let focusedElement = document.activeElement;
+ let sibling = focusedElement.nextElementSibling;
+ let prevSibling = focusedElement.previousElementSibling;
+
+ // manage rotating through the options using arrow keys
+ // UP arrow: .keyCode is depricated and should used only as a fallback
+ if ((event.key == 'ArrowUp' || event.keyCode == 38) && popoverIsOpen) {
+ event.preventDefault();
+ prevSibling
+ ? this.$nextTick(() => prevSibling.focus())
+ : this.$nextTick(() => lastChild.focus());
+ // DOWN arrow
+ } else if ((event.key == 'ArrowDown' || event.keyCode == 40) && popoverIsOpen) {
+ event.preventDefault();
+ sibling ? this.$nextTick(() => sibling.focus()) : this.$nextTick(() => this.setFocus());
+ // if a TAB key, not an arrow key, close the popover and advance to next item in the tab index
+ } else if ((event.key == 'Tab' || event.keyCode == 9) && popoverIsOpen) {
+ this.closePopover();
}
},
handleSelection(selection) {
diff --git a/lib/keen/UiMenu.vue b/lib/keen/UiMenu.vue
index c2779e8ba..6221d95b5 100644
--- a/lib/keen/UiMenu.vue
+++ b/lib/keen/UiMenu.vue
@@ -8,7 +8,6 @@
lazy
:class="classes"
- :contain-focus="containFocus"
>
@@ -101,6 +101,9 @@
'has-secondary-text': this.hasSecondaryText,
};
},
+ activeOutline() {
+ return this.isActive ? this.$coreOutline : {};
+ },
},
methods: {
@@ -112,7 +115,6 @@
this.$emit('select', option);
this.closeMenu();
},
-
closeMenu() {
this.$emit('close');
},
diff --git a/lib/keen/UiMenuOption.vue b/lib/keen/UiMenuOption.vue
index 278ce90ad..4f6cb6cf6 100644
--- a/lib/keen/UiMenuOption.vue
+++ b/lib/keen/UiMenuOption.vue
@@ -3,9 +3,12 @@