diff --git a/packages/hoppscotch-app/components/app/Fuse.vue b/packages/hoppscotch-app/components/app/Fuse.vue
index ee19a31fb..05358f460 100644
--- a/packages/hoppscotch-app/components/app/Fuse.vue
+++ b/packages/hoppscotch-app/components/app/Fuse.vue
@@ -4,6 +4,7 @@
v-for="(shortcut, shortcutIndex) in searchResults"
:key="`shortcut-${shortcutIndex}`"
:ref="`item-${shortcutIndex}`"
+ :active="shortcutIndex === selectedEntry"
:shortcut="shortcut.item"
@action="$emit('action', shortcut.item.action)"
/>
@@ -20,8 +21,15 @@
diff --git a/packages/hoppscotch-app/components/app/PowerSearch.vue b/packages/hoppscotch-app/components/app/PowerSearch.vue
index 8825d2bb2..61ced7ff9 100644
--- a/packages/hoppscotch-app/components/app/PowerSearch.vue
+++ b/packages/hoppscotch-app/components/app/PowerSearch.vue
@@ -47,6 +47,7 @@
v-for="(shortcut, shortcutIndex) in map.shortcuts"
:key="`map-${mapIndex}-shortcut-${shortcutIndex}`"
:shortcut="shortcut"
+ :active="shortcutsItems.indexOf(shortcut) === selectedEntry"
@action="runAction"
/>
@@ -56,9 +57,10 @@
diff --git a/packages/hoppscotch-app/components/app/PowerSearchEntry.vue b/packages/hoppscotch-app/components/app/PowerSearchEntry.vue
index 497e8b030..62c85c0fb 100644
--- a/packages/hoppscotch-app/components/app/PowerSearchEntry.vue
+++ b/packages/hoppscotch-app/components/app/PowerSearchEntry.vue
@@ -13,6 +13,7 @@
focus-visible:bg-primaryLight
search-entry
"
+ :class="{ active, 'outline-none': active, 'focus-visible': active }"
tabindex="0"
@click="$emit('action', shortcut.action)"
@keydown.enter="$emit('action', shortcut.action)"
@@ -26,6 +27,7 @@
group-hover:text-secondaryDark group-hover:opacity-100
group-focus:opacity-100
"
+ :class="{ 'opacity-100': active, 'text-secondaryDark': active }"
:name="shortcut.icon"
/>
{{ $t(shortcut.label) }}
@@ -52,6 +55,7 @@
@@ -73,7 +77,8 @@ defineProps<{
}
&:hover::after,
- &:focus::after {
+ &:focus::after,
+ &.active::after {
@apply bg-accentLight;
}
}
diff --git a/packages/hoppscotch-app/helpers/powerSearchNavigation.ts b/packages/hoppscotch-app/helpers/powerSearchNavigation.ts
new file mode 100644
index 000000000..02fa6b860
--- /dev/null
+++ b/packages/hoppscotch-app/helpers/powerSearchNavigation.ts
@@ -0,0 +1,54 @@
+import { ref } from "@nuxtjs/composition-api"
+
+const NAVIGATION_KEYS = ["ArrowDown", "ArrowUp", "Enter"]
+
+export function useArrowKeysNavigation(searchItems: any, options: any = {}) {
+ function handleArrowKeysNavigation(
+ event: any,
+ itemIndex: any,
+ preventPropagation: Boolean
+ ) {
+ if (!NAVIGATION_KEYS.includes(event.key)) return
+
+ if (preventPropagation) event.stopImmediatePropagation()
+
+ const itemsLength = searchItems.value.length
+ const lastItemIndex = itemsLength - 1
+ const itemIndexValue = itemIndex.value
+ const action = searchItems.value[itemIndexValue].action
+
+ if (action && event.key === "Enter" && options.onEnter) {
+ options.onEnter(action)
+ return
+ }
+
+ if (event.key === "ArrowDown") {
+ itemIndex.value = itemIndexValue < lastItemIndex ? itemIndexValue + 1 : 0
+ } else if (itemIndexValue === 0) itemIndex.value = lastItemIndex
+ else if (event.key === "ArrowUp") itemIndex.value = itemIndexValue - 1
+ }
+
+ const preventPropagation = options && options.stopPropagation
+
+ const selectedEntry = ref(0)
+
+ const onKeyUp = (event: any) => {
+ handleArrowKeysNavigation(event, selectedEntry, preventPropagation)
+ }
+
+ function bindArrowKeysListerners() {
+ window.addEventListener("keydown", onKeyUp, { capture: preventPropagation })
+ }
+
+ function unbindArrowKeysListerners() {
+ window.removeEventListener("keydown", onKeyUp, {
+ capture: preventPropagation,
+ })
+ }
+
+ return {
+ bindArrowKeysListerners,
+ unbindArrowKeysListerners,
+ selectedEntry,
+ }
+}