"use client"; import { CommandItem } from "@mdxui/primitives/command"; import { ChevronRight, Hash } from "lucide-react"; import type { SearchMatch, SearchResultItemProps } from "../searchbox-types"; function highlightMatches(text: string, query: string): React.ReactNode { if (!query.trim()) return text; const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const regex = new RegExp(`(${escaped})`, "gi"); const parts = text.split(regex).filter((part) => part !== ""); return ( <> {parts.map((part, i) => part.toLowerCase() === query.toLowerCase() ? ( {part} ) : ( part ), )} ); } export function SearchResultItem({ result, onSelect, query = "", }: SearchResultItemProps) { return (
{/* Document header */} onSelect(result)} className="flex flex-col items-start gap-0.5 mx-2 px-3 py-2 rounded-md" > {/* Breadcrumb */} {result.breadcrumbs && result.breadcrumbs.length > 0 && ( {result.breadcrumbs.map((crumb, i) => ( {i > 0 && } {crumb} ))} )} {result.title} {/* Matches */} {result.matches.length > 0 && (
{result.matches.map((match, i) => ( onSelect(result)} query={query} /> ))}
)}
); } function MatchItem({ match, resultId, index, onSelect, query, }: { match: SearchMatch; resultId: string; index: number; onSelect: () => void; query: string; }) { if (match.type === "section") { return ( {highlightMatches(match.heading, query)} {highlightMatches(match.snippet, query)} ); } // Content match return ( {highlightMatches(match.snippet, query)} ); }