Fuse.vue 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. <template>
  2. <div key="outputHash" class="flex flex-col">
  3. <AppPowerSearchEntry
  4. v-for="(shortcut, shortcutIndex) in searchResults"
  5. :key="`shortcut-${shortcutIndex}`"
  6. :ref="`item-${shortcutIndex}`"
  7. :active="shortcutIndex === selectedEntry"
  8. :shortcut="shortcut.item"
  9. @action="$emit('action', shortcut.item.action)"
  10. @mouseover.native="selectedEntry = shortcutIndex"
  11. />
  12. <div
  13. v-if="searchResults.length === 0"
  14. class="flex flex-col text-secondaryLight p-4 items-center justify-center"
  15. >
  16. <i class="opacity-75 pb-2 material-icons">manage_search</i>
  17. <span class="text-center">
  18. {{ t("state.nothing_found") }} "{{ search }}"
  19. </span>
  20. </div>
  21. </div>
  22. </template>
  23. <script setup lang="ts">
  24. import { computed, onUnmounted, onMounted } from "@nuxtjs/composition-api"
  25. import Fuse from "fuse.js"
  26. import { useArrowKeysNavigation } from "~/helpers/powerSearchNavigation"
  27. import { HoppAction } from "~/helpers/actions"
  28. import { useI18n } from "~/helpers/utils/composables"
  29. const t = useI18n()
  30. const props = defineProps<{
  31. input: Record<string, any>[]
  32. search: string
  33. }>()
  34. const emit = defineEmits<{
  35. (e: "action", action: HoppAction): void
  36. }>()
  37. const options = {
  38. keys: ["keys", "label", "action", "tags"],
  39. }
  40. const fuse = new Fuse(props.input, options)
  41. const searchResults = computed(() => fuse.search(props.search))
  42. const searchResultsItems = computed(() =>
  43. searchResults.value.map((searchResult: any) => searchResult.item)
  44. )
  45. const emitSearchAction = (action: HoppAction) => emit("action", action)
  46. const { bindArrowKeysListerners, unbindArrowKeysListerners, selectedEntry } =
  47. useArrowKeysNavigation(searchResultsItems, {
  48. onEnter: emitSearchAction,
  49. stopPropagation: true,
  50. })
  51. onMounted(() => {
  52. bindArrowKeysListerners()
  53. })
  54. onUnmounted(() => {
  55. unbindArrowKeysListerners()
  56. })
  57. </script>