(search) add keyboard navigation to the search dialogue

This commit is contained in:
Andrea Vos 2024-12-29 14:31:33 +01:00
parent 7a0eec0b0e
commit 3c63c7c089

View File

@ -14,6 +14,7 @@ const queryValidation = computed(() => {
});
const searchAsyncData = useAsyncData('search', async () => {
selected.value = null;
if (queryValidation.value !== undefined) {
return [];
}
@ -41,6 +42,7 @@ const open = () => {
query.value = '';
searchAsyncData.clear();
dialogue.value?.showModal();
selected.value = null;
};
const close = () => {
@ -65,6 +67,34 @@ const onMousedown = (event: MouseEvent) => {
}
};
const selected = ref<number | null>(null);
const router = useRouter();
onKeyStroke('ArrowDown', () => {
selected.value = Math.min(
(selected.value ?? -1) + 1,
(searchAsyncData.data?.value?.length ?? 0) - 1,
);
});
onKeyStroke('ArrowUp', () => {
selected.value = Math.max(
(selected.value ?? -1) - 1,
0,
);
});
onKeyStroke('Enter', () => {
if (selected.value === null) {
return;
}
const document = searchAsyncData.data.value?.[selected.value];
if (!document) {
return;
}
router.push(document.url);
close();
});
defineExpose({ open, close });
</script>
@ -93,9 +123,9 @@ defineExpose({ open, close });
class="list-group"
>
<li
v-for="document of searchAsyncData.data.value"
v-for="(document, index) of searchAsyncData.data.value"
:key="`${document.kind}-${document.id}`"
class="list-group-item list-group-item-action p-0"
:class="['list-group-item list-group-item-action p-0', selected === index ? 'list-group-item-hover' : '']"
>
<SearchItem :document="document" @click="close()" />
</li>
@ -105,3 +135,12 @@ defineExpose({ open, close });
</div>
</dialog>
</template>
<style lang="scss">
@import "assets/variables";
.list-group-item-hover {
background-color: $list-group-hover-bg !important;
border-left: 3px solid $primary !important;
}
</style>