"use client" import React, { useState, useRef, useCallback, useMemo } from "react" import { Command, CommandGroup, CommandItem, CommandList } from "@/components/ui/command" import { Command as CommandPrimitive } from "cmdk" import { motion, AnimatePresence } from "framer-motion" import { cn } from "@/lib/utils" interface GraphNode { name: string prettyName: string connectedTopics: string[] } interface AutocompleteProps { topics: GraphNode[] onSelect: (topic: GraphNode) => void onInputChange: (value: string) => void } export function Autocomplete({ topics = [], onSelect, onInputChange }: AutocompleteProps): JSX.Element { const inputRef = useRef(null) const [open, setOpen] = useState(false) const [inputValue, setInputValue] = useState("") const filteredTopics = useMemo(() => { if (!inputValue) { return topics.slice(0, 5) } const regex = new RegExp(inputValue.split("").join(".*"), "i") return topics.filter( topic => regex.test(topic.name) || regex.test(topic.prettyName) || topic.connectedTopics.some(connectedTopic => regex.test(connectedTopic)) ) }, [inputValue, topics]) const handleSelect = useCallback( (topic: GraphNode) => { setInputValue(topic.prettyName) setOpen(false) onSelect(topic) }, [onSelect] ) const handleKeyDown = useCallback( (e: React.KeyboardEvent) => { if (e.key === "Enter" && filteredTopics.length > 0) { handleSelect(filteredTopics[0]) } else if ((e.key === "Backspace" || e.key === "Delete") && inputRef.current?.value === "") { setOpen(true) } }, [filteredTopics, handleSelect] ) const handleInputChange = useCallback( (value: string) => { setInputValue(value) setOpen(true) onInputChange(value) }, [onInputChange] ) return (
setTimeout(() => setOpen(false), 100)} onFocus={() => setOpen(true)} placeholder="Search for a topic..." className={cn("placeholder:text-muted-foreground flex-1 bg-transparent px-2 py-1 outline-none", { "mb-1 border-b pb-2.5": open })} />
{open && ( {filteredTopics.map(topic => ( handleSelect(topic)} className="min-h-10 rounded-none px-3 py-1.5" > {topic.prettyName} {topic.connectedTopics.length > 0 ? topic.connectedTopics.join(", ") : "-"} ))} )}
) } export default Autocomplete