| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- import { useDocsSearch, type DocsSearchResult } from 'common'
- import { Book, Github, Loader2 } from 'lucide-react'
- import { cn } from 'ui'
- import { useChangedSync } from '@/hooks/misc/useChanged'
- import { DOCS_URL } from '@/lib/constants'
- function useDocsSuggestions(subject: string) {
- const { handleDocsSearchDebounced, resetSearch, searchState } = useDocsSearch()
- const trimmedSubject = subject.trim()
- const subjectChanged = useChangedSync(trimmedSubject)
- if (subjectChanged && trimmedSubject) {
- handleDocsSearchDebounced(trimmedSubject)
- } else if (subjectChanged && !trimmedSubject) {
- resetSearch()
- }
- return searchState
- }
- interface DocsSuggestionsProps {
- searchString: string
- }
- export function DocsSuggestions({ searchString }: DocsSuggestionsProps) {
- const searchState = useDocsSuggestions(searchString)
- const results =
- 'results' in searchState
- ? searchState.results
- : 'staleResults' in searchState
- ? searchState.staleResults
- : []
- const resultsStale = searchState.status === 'loading'
- return (
- <>
- {searchState.status === 'loading' && <DocsSuggestions_Loading />}
- {results.length > 0 && <DocsSuggestions_Results results={results} isStale={resultsStale} />}
- </>
- )
- }
- function DocsSuggestions_Loading() {
- return (
- <div className="flex items-center gap-2 text-sm text-foreground-light">
- <Loader2 className="animate-spin" size={14} />
- <span>Searching for relevant resources...</span>
- </div>
- )
- }
- interface DocsSuggestions_ResultsProps {
- results: DocsSearchResult[]
- isStale: boolean
- }
- function DocsSuggestions_Results({ results, isStale }: DocsSuggestions_ResultsProps) {
- return (
- <ul
- className={cn(
- 'flex flex-col gap-y-0.5 transition-opacity duration-200',
- isStale ? 'opacity-50' : 'opacity-100'
- )}
- >
- {results.slice(0, 5).map((page) => {
- return (
- <li key={page.id} className="flex items-center gap-x-1">
- {page.type === 'github-discussions' ? (
- <Github size={16} className="text-foreground-muted" />
- ) : (
- <Book size={16} className="text-foreground-muted" />
- )}
- <a
- href={page.type === 'github-discussions' ? page.path : `${DOCS_URL}${page.path}`}
- target="_blank"
- rel="noreferrer"
- className="text-sm text-foreground-light hover:text-foreground transition"
- >
- {page.title}
- </a>
- </li>
- )
- })}
- </ul>
- )
- }
|