1
0

search-dialog.tsx 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. 'use client';
  2. import { create } from 'zbsearch';
  3. import { useDocsSearch } from 'fumadocs-core/search/client';
  4. import { staticClient } from 'fumadocs-core/search/client/orama-static';
  5. import {
  6. SearchDialog,
  7. SearchDialogClose,
  8. SearchDialogContent,
  9. SearchDialogHeader,
  10. SearchDialogIcon,
  11. SearchDialogInput,
  12. SearchDialogList,
  13. SearchDialogOverlay,
  14. } from 'fumadocs-ui/components/dialog/search';
  15. import { useI18n } from 'fumadocs-ui/contexts/i18n';
  16. import { useMemo } from 'react';
  17. interface SharedProps {
  18. open: boolean;
  19. onOpenChange: (open: boolean) => void;
  20. }
  21. // Fumadocs' default dialog passes the index's locale code as a tokenizer language,
  22. // and zbsearch throws on anything but a full name — so force "english" everywhere.
  23. export default function SearchDialogClient(props: SharedProps) {
  24. const { locale } = useI18n();
  25. const client = useMemo(
  26. () =>
  27. staticClient({
  28. from: '/api/search',
  29. locale,
  30. initDB: () => create({ schema: { _: 'string' }, language: 'english' }),
  31. }),
  32. [locale],
  33. );
  34. const { search, setSearch, query } = useDocsSearch({ client });
  35. return (
  36. <SearchDialog search={search} onSearchChange={setSearch} isLoading={query.isLoading} {...props}>
  37. <SearchDialogOverlay />
  38. <SearchDialogContent>
  39. <SearchDialogHeader>
  40. <SearchDialogIcon />
  41. <SearchDialogInput />
  42. <SearchDialogClose />
  43. </SearchDialogHeader>
  44. <SearchDialogList items={query.data !== 'empty' ? query.data : null} />
  45. </SearchDialogContent>
  46. </SearchDialog>
  47. );
  48. }