"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)}
);
}