diff --git a/app.vue b/app.vue index c4659aa86..882239f65 100644 --- a/app.vue +++ b/app.vue @@ -56,6 +56,7 @@ useSeoMeta({ diff --git a/components/FilterBar.vue b/components/FilterBar.vue index 49e599d9d..726ce1023 100644 --- a/components/FilterBar.vue +++ b/components/FilterBar.vue @@ -4,7 +4,7 @@ import type { Category } from '~/src/classes.ts'; const filter = defineModel(); const filterCategory = defineModel('category'); -defineProps<{ +const props = defineProps<{ categories?: Category[] | undefined; submitButton?: boolean; }>(); @@ -17,10 +17,32 @@ const filterInput = useTemplateRef('filterInput'); const { $translator: translator } = useNuxtApp(); const allCategory: Category = { key: '', text: translator.translate('crud.all'), icon: 'clipboard-list' }; +const categoriesWithAllCategory = computed(() => [allCategory, ...(props.categories ?? [])]); defineExpose({ focus: () => filterInput.value?.focus(), }); + +const categoryList = useTemplateRef('categoryList'); +const categoryButtonKeydown = (event: KeyboardEvent) => { + if (filterCategory.value === undefined) { + return; + } + const activeIndex = categoriesWithAllCategory.value.map((category) => category.key).indexOf(filterCategory.value); + if (activeIndex === -1) { + return; + } + + if ((event.key === 'ArrowUp' || event.key === 'ArrowLeft') && + activeIndex > 0) { + filterCategory.value = categoriesWithAllCategory.value[activeIndex - 1].key; + (categoryList.value?.children[activeIndex - 1] as HTMLButtonElement | undefined)?.focus(); + } else if ((event.key === 'ArrowDown' || event.key === 'ArrowRight') && + activeIndex < categoriesWithAllCategory.value.length - 1) { + filterCategory.value = categoriesWithAllCategory.value[activeIndex + 1].key; + (categoryList.value?.children[activeIndex + 1] as HTMLButtonElement | undefined)?.focus(); + } +};