import React, { useState, useRef, useEffect, useMemo } from "react"; import { Stack, Button, Text } from "@mantine/core"; import { useTranslation } from "react-i18next"; import { ToolRegistryEntry } from "../../../data/toolsTaxonomy"; import { TextInput } from "../../shared/TextInput"; import './ToolPicker.css'; interface ToolSearchProps { value: string; onChange: (value: string) => void; toolRegistry: Readonly>; onToolSelect?: (toolId: string) => void; mode: 'filter' | 'dropdown'; selectedToolKey?: string | null; } const ToolSearch = ({ value, onChange, toolRegistry, onToolSelect, mode = 'filter', selectedToolKey }: ToolSearchProps) => { const { t } = useTranslation(); const [dropdownOpen, setDropdownOpen] = useState(false); const searchRef = useRef(null); const filteredTools = useMemo(() => { if (!value.trim()) return []; return Object.entries(toolRegistry) .filter(([id, tool]) => { if (mode === 'dropdown' && id === selectedToolKey) return false; return tool.name.toLowerCase().includes(value.toLowerCase()) || tool.description.toLowerCase().includes(value.toLowerCase()); }) .slice(0, 6) .map(([id, tool]) => ({ id, tool })); }, [value, toolRegistry, mode, selectedToolKey]); const handleSearchChange = (searchValue: string) => { onChange(searchValue); if (mode === 'dropdown') { setDropdownOpen(searchValue.trim().length > 0 && filteredTools.length > 0); } }; useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (searchRef.current && !searchRef.current.contains(event.target as Node)) { setDropdownOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const searchInput = (
search} autoComplete="off" />
); if (mode === 'filter') { return searchInput; } return (
{searchInput} {dropdownOpen && filteredTools.length > 0 && (
{filteredTools.map(({ id, tool }) => ( ))}
)}
); }; export default ToolSearch;