diff options
author | 2022-12-16 18:10:50 +0100 | |
---|---|---|
committer | 2022-12-16 18:10:50 +0100 | |
commit | 1b5d4e72bdb222dd721a1e484c3e5d73bb62d2b1 (patch) | |
tree | 3e3430a05511b61ccd34376ca4be8fca231100ab /src | |
parent | 8476cf319b7ebae87c7928592604a54833ac56ef (diff) | |
download | it-tools-1b5d4e72bdb222dd721a1e484c3e5d73bb62d2b1.tar.gz it-tools-1b5d4e72bdb222dd721a1e484c3e5d73bb62d2b1.tar.zst it-tools-1b5d4e72bdb222dd721a1e484c3e5d73bb62d2b1.zip |
refactor(search-bar): improved tool fuzzy search
Diffstat (limited to 'src')
-rw-r--r-- | src/components/SearchBar.vue | 24 | ||||
-rw-r--r-- | src/composable/fuzzySearch.ts | 23 |
2 files changed, 31 insertions, 16 deletions
diff --git a/src/components/SearchBar.vue b/src/components/SearchBar.vue index 7305239..b1645ec 100644 --- a/src/components/SearchBar.vue +++ b/src/components/SearchBar.vue @@ -1,30 +1,22 @@ <script lang="ts" setup> +import { useFuzzySearch } from '@/composable/fuzzySearch'; import { tools } from '@/tools'; import { SearchRound } from '@vicons/material'; import { useMagicKeys, whenever } from '@vueuse/core'; -import { deburr } from 'lodash'; import { computed, ref } from 'vue'; import { useRouter } from 'vue-router'; const router = useRouter(); const queryString = ref(''); -const cleanString = (s: string) => deburr(s.trim().toLowerCase()); - -const searchableTools = tools.map(({ name, description, keywords, path }) => ({ - searchableText: [name, description, ...keywords].map(cleanString).join(' '), - path, - name, -})); - -const options = computed(() => { - const query = cleanString(queryString.value); - - return searchableTools - .filter(({ searchableText }) => searchableText.includes(query)) - .map(({ name, path }) => ({ label: name, value: path })); +const { searchResult } = useFuzzySearch({ + search: queryString, + data: tools, + options: { keys: [{ name: 'name', weight: 2 }, 'description', 'keywords'] }, }); +const options = computed(() => searchResult.value.map(({ name, path }) => ({ label: name, value: path }))); + function onSelect(path: string) { router.push(path); queryString.value = ''; @@ -52,7 +44,7 @@ whenever(keys.ctrl_k, () => { v-model:value="queryString" :options="options" :input-props="{ autocomplete: 'disabled' }" - :on-select="onSelect" + :on-select="(value) => onSelect(String(value))" > <template #default="{ handleInput, handleBlur, handleFocus, value: slotValue }"> <n-input diff --git a/src/composable/fuzzySearch.ts b/src/composable/fuzzySearch.ts new file mode 100644 index 0000000..b46f9de --- /dev/null +++ b/src/composable/fuzzySearch.ts @@ -0,0 +1,23 @@ +import { get, type MaybeRef } from '@vueuse/core'; +import Fuse from 'fuse.js'; +import { computed } from 'vue'; + +export { useFuzzySearch }; + +function useFuzzySearch<Data>({ + search, + data, + options = {}, +}: { + search: MaybeRef<string>; + data: Data[]; + options?: Fuse.IFuseOptions<Data>; +}) { + const fuse = new Fuse(data, options); + + const searchResult = computed(() => { + return fuse.search(get(search)).map(({ item }) => item); + }); + + return { searchResult }; +} |