diff --git a/tine20/Tinebase/js/TineBar/TApplicationMenu.vue b/tine20/Tinebase/js/TineBar/TApplicationMenu.vue index 1d7525662e..90560a707b 100644 --- a/tine20/Tinebase/js/TineBar/TApplicationMenu.vue +++ b/tine20/Tinebase/js/TineBar/TApplicationMenu.vue @@ -13,6 +13,9 @@ :visible="visibleInternal" :placement="placement" @hide="hide($event)" + @keydown.esc="hide($event)" + @keydown.enter="selectAppInFocus($event)" + @keydown.up.down.left.right.stop="moveFocusAround($event)" >
@@ -20,12 +23,14 @@
@@ -85,19 +90,56 @@ const visibleInternal = ref(false) const searchField = ref() watch(() => props.visible, newVal => { - visibleInternal.value = newVal if (newVal) { + appInFocus.value = 0 + searchTerm.value = '' nextTick(() => { searchField.value.focus() }) } + visibleInternal.value = newVal }, { immediate: true }) const hide = (e) => { visibleInternal.value = false - searchTerm.value = '' emits('hide', e) } + +const appInFocus = ref(0) + +watch(menuItemsInternal, (newVal) => { + if (appInFocus.value > newVal.length) appInFocus.value = newVal.length - 1 +}) + +const selectAppInFocus = (e) => { + const app = menuItemsInternal.value[appInFocus.value] + emits('itemClicked', app.name) + hide(e) +} + +const moveFocusAround = (e) => { + function moveFocusToIdx (idx) { + if (idx < 0 || idx > menuItemsInternal.value.length - 1) return + appInFocus.value = idx + } + + switch (e.key) { + case 'ArrowLeft': + moveFocusToIdx(appInFocus.value - 1) + break + case 'ArrowRight': + moveFocusToIdx(appInFocus.value + 1) + break + case 'ArrowUp': + moveFocusToIdx(appInFocus.value - 3) + break + case 'ArrowDown': + moveFocusToIdx(appInFocus.value + 3) + break + default: + } +} +