"use client"; import { RemoveScroll } from "react-remove-scroll"; import { type ComponentProps, createContext, type SyntheticEvent, use, useEffect, useMemo, useRef, useState, } from "react"; import { Loader2, SearchIcon, Send, X } from "lucide-react"; import { cn } from "@/lib/utils"; import { buttonVariants } from "fumadocs-ui/components/ui/button"; import Link from "fumadocs-core/link"; import { Markdown } from "./markdown"; import { Presence } from "@radix-ui/react-presence"; import { betterFetch } from "@better-fetch/fetch"; const Context = createContext<{ open: boolean; setOpen: (open: boolean) => void; messages: Array<{ id: string; role: "user" | "assistant"; content: string }>; isLoading: boolean; sendMessage: (text: string) => void; clearMessages: () => void; } | null>(null); function useChatContext() { return use(Context)!; } function SearchAIActions() { const { messages, isLoading, clearMessages } = useChatContext(); if (messages.length === 0) return null; return ( <> ); } function SearchAIInput(props: ComponentProps<"form">) { const { sendMessage, isLoading } = useChatContext(); const [input, setInput] = useState(""); const onStart = (e?: SyntheticEvent) => { e?.preventDefault(); if (input.trim()) { sendMessage(input.trim()); setInput(""); } }; useEffect(() => { if (isLoading) document.getElementById("nd-ai-input")?.focus(); }, [isLoading]); return (
{ setInput(e.target.value); }} onKeyDown={(event) => { if (!event.shiftKey && event.key === "Enter") { onStart(event); } }} />
); } function List(props: Omit, "dir">) { const containerRef = useRef(null); useEffect(() => { if (!containerRef.current) return; function callback() { const container = containerRef.current; if (!container) return; container.scrollTo({ top: container.scrollHeight, behavior: "instant", }); } const observer = new ResizeObserver(callback); callback(); const element = containerRef.current?.firstElementChild; if (element) { observer.observe(element); } return () => { observer.disconnect(); }; }, []); return (
{props.children}
); } function Input(props: ComponentProps<"textarea">) { const ref = useRef(null); const shared = cn("col-start-1 row-start-1", props.className); return (