From 214b1825a8c2750e42ed18c82302f3b9cdbd0647 Mon Sep 17 00:00:00 2001 From: Amir Raminfar Date: Wed, 12 Jun 2024 09:23:10 -0700 Subject: [PATCH] feat: improves search by showing all matches within threshold and enable scrolling instead (#3029) --- assets/components/FuzzySearchModal.spec.ts | 4 +- assets/components/FuzzySearchModal.vue | 112 ++++++++++----------- 2 files changed, 56 insertions(+), 60 deletions(-) diff --git a/assets/components/FuzzySearchModal.spec.ts b/assets/components/FuzzySearchModal.spec.ts index 388a123c..441ff4eb 100644 --- a/assets/components/FuzzySearchModal.spec.ts +++ b/assets/components/FuzzySearchModal.spec.ts @@ -57,9 +57,9 @@ describe("", () => { vi.mocked(useRouter().push).mockReset(); }); - test("shows running all", async () => { + test("shows none initially", async () => { const wrapper = createFuzzySearchModal(); - expect(wrapper.findAll("li").length).toBe(3); + expect(wrapper.findAll("li").length).toBe(0); }); test("search for foo", async () => { diff --git a/assets/components/FuzzySearchModal.vue b/assets/components/FuzzySearchModal.vue index 50eb877e..62b99c8e 100644 --- a/assets/components/FuzzySearchModal.vue +++ b/assets/components/FuzzySearchModal.vue @@ -15,44 +15,49 @@ /> - + @@ -61,14 +66,11 @@ import { ContainerState } from "@/types/Container"; import { useFuse } from "@vueuse/integrations/useFuse"; import { type FuseResult } from "fuse.js"; -const { maxResults = 10 } = defineProps<{ - maxResults?: number; -}>(); - const close = defineEmit(); const query = ref(""); const input = ref(); +const listItems = ref(); const selectedIndex = ref(0); const router = useRouter(); @@ -133,26 +135,22 @@ const { results } = useFuse(query, list, { threshold: 0.3, includeMatches: true, }, - resultLimit: 10, - matchAllWhenSearchEmpty: true, }); const data = computed(() => { - return [...results.value] - .sort((a: FuseResult, b: FuseResult) => { - if (a.score === b.score) { - if (a.item.state === b.item.state) { - return b.item.created.getTime() - a.item.created.getTime(); - } else if (a.item.state === "running" && b.item.state !== "running") { - return -1; - } else { - return 1; - } + return [...results.value].sort((a: FuseResult, b: FuseResult) => { + if (a.score === b.score) { + if (a.item.state === b.item.state) { + return b.item.created.getTime() - a.item.created.getTime(); + } else if (a.item.state === "running" && b.item.state !== "running") { + return -1; } else { - return (a.score ?? 0) - (b.score ?? 0); + return 1; } - }) - .slice(0, maxResults); + } else { + return (a.score ?? 0) - (b.score ?? 0); + } + }); }); watch(query, (data) => { @@ -161,6 +159,8 @@ watch(query, (data) => { } }); +watch(selectedIndex, () => listItems.value?.[selectedIndex.value].scrollIntoView({ behavior: "smooth", block: "end" })); + useFocus(input, { initialValue: true }); function selected(item: Item) { @@ -202,8 +202,4 @@ function matchedName({ item, matches = [] }: FuseResult) { :deep(mark) { @apply bg-transparent text-inherit underline underline-offset-2; } - -.menu a { - @apply transition-none duration-0; -}