fuzzySearch.tsx 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import {useEffect, useState} from 'react';
  2. import type Fuse from 'fuse.js';
  3. // See http://fusejs.io/ for more information
  4. const DEFAULT_FUSE_OPTIONS: Fuse.IFuseOptions<any> = {
  5. includeScore: true,
  6. includeMatches: true,
  7. threshold: 0.4,
  8. location: 0,
  9. distance: 75,
  10. minMatchCharLength: 2,
  11. };
  12. export async function createFuzzySearch<
  13. T = string,
  14. Options extends Fuse.IFuseOptions<T> = Fuse.IFuseOptions<T>,
  15. >(objects: T[], options: Options): Promise<Fuse<T>> {
  16. if (!options.keys) {
  17. throw new Error('You need to define `options.keys`');
  18. }
  19. const fuseImported = await import('fuse.js');
  20. const fuse = {Fuse: fuseImported.default};
  21. return new fuse.Fuse(objects, {
  22. ...DEFAULT_FUSE_OPTIONS,
  23. ...options,
  24. });
  25. }
  26. // re-export fuse type to make it easier to use
  27. export type {Fuse};
  28. export function useFuzzySearch<
  29. T = string,
  30. Options extends Fuse.IFuseOptions<T> = Fuse.IFuseOptions<T>,
  31. >(objects: T[], options: Options): Fuse<T> | null {
  32. const [fuse, setFuse] = useState<Fuse<T> | null>(null);
  33. useEffect(() => {
  34. createFuzzySearch(objects, options).then(setFuse);
  35. }, [objects, options]);
  36. return fuse;
  37. }