Created
December 28, 2023 14:26
-
-
Save colelawrence/aa18d5eda4c90db656161f6b6c8687a6 to your computer and use it in GitHub Desktop.
Qwik hook for searching items with Fuse.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { NoSerialize, Signal } from "@builder.io/qwik"; | |
import { noSerialize, useSignal, useVisibleTask$ } from "@builder.io/qwik"; | |
import type { IFuseOptions } from "fuse.js"; | |
import Fuse from "fuse.js"; | |
export function useFuseSearch<T>( | |
config: { | |
items: Signal<T[]> | T[]; | |
search: Signal<string> | string; | |
}, | |
options?: Omit<IFuseOptions<T>, "getFn" | "sortFn" | "keys"> & { | |
keys: Array<NestedKeyOf<T> | { name: NestedKeyOf<T>; weight: number }>; | |
}, | |
): Signal<T[]> { | |
const fuse = useSignal<NoSerialize<Fuse<T>>>(); | |
const filtered = useSignal<T[]>( | |
Array.isArray(config.items) ? config.items : config.items.value, | |
); | |
// eslint-disable-next-line qwik/no-use-visible-task | |
useVisibleTask$(({ track }) => { | |
fuse.value = noSerialize( | |
new Fuse( | |
track(() => | |
Array.isArray(config.items) ? config.items : config.items.value, | |
), | |
options, | |
), | |
); | |
}); | |
// eslint-disable-next-line qwik/no-use-visible-task | |
useVisibleTask$(({ track }) => { | |
const searchValue = track(() => | |
typeof config.search === "string" ? config.search : config.search.value, | |
); | |
const fuseValue = track(() => fuse.value); | |
if (searchValue && fuseValue) { | |
filtered.value = fuseValue | |
.search(searchValue) | |
.map((result) => ({ ...result.item })); | |
} else { | |
filtered.value = track(() => | |
Array.isArray(config.items) ? config.items : config.items.value, | |
); | |
} | |
}); | |
return filtered; | |
} | |
type NestedKeyOf<ObjectType> = { | |
[Key in keyof ObjectType & (number | string)]: ObjectType[Key] extends Array< | |
infer ArrayType | |
> | |
? | |
| `${Key}.${number}` | |
| `${Key}` | |
| (ArrayType extends object | |
? `${Key}.${number}.${NestedKeyOf<ArrayType>}` | |
: never) | |
: ObjectType[Key] extends object | |
? `${Key}.${NestedKeyOf<ObjectType[Key]>}` | `${Key}` | |
: `${Key}`; | |
}[keyof ObjectType & (number | string)]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment