Output/GPT4_Turbo/JS/extracted_code/generation/GenerateBaseComponent/index.tsx (85 lines of code) (raw):

import React, { useState, useRef, useEffect, KeyboardEvent, ChangeEvent } from 'react'; import './index.css'; interface Option { value: string; label: string; } interface SearchableSelectProps { options: Option[]; placeholder?: string; onChange: (value: string) => void; } const SearchableSelect: React.FC<SearchableSelectProps> = ({ options, placeholder, onChange }) => { const [isOpen, setIsOpen] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const [highlightedIndex, setHighlightedIndex] = useState(0); const containerRef = useRef<HTMLDivElement>(null); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setIsOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchTerm.toLowerCase()) ); const handleSelect = (value: string) => { onChange(value); setIsOpen(false); setSearchTerm(''); }; const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => { switch (event.key) { case 'Enter': isOpen ? handleSelect(filteredOptions[highlightedIndex].value) : setIsOpen(true); break; case 'ArrowDown': setHighlightedIndex((prevIndex) => prevIndex < filteredOptions.length - 1 ? prevIndex + 1 : prevIndex ); break; case 'ArrowUp': setHighlightedIndex((prevIndex) => (prevIndex > 0 ? prevIndex - 1 : prevIndex)); break; case 'Escape': setIsOpen(false); break; default: break; } }; const handleChange = (event: ChangeEvent<HTMLInputElement>) => { setSearchTerm(event.target.value); setHighlightedIndex(0); }; return ( <div className="select-container" ref={containerRef} onKeyDown={handleKeyDown} tabIndex={0}> <input className="select-input" placeholder={placeholder} value={searchTerm} onChange={handleChange} onClick={() => setIsOpen(!isOpen)} readOnly={!isOpen} /> {isOpen && ( <ul className="select-dropdown"> {filteredOptions.map((option, index) => ( <li key={option.value} className={`select-option ${index === highlightedIndex ? 'highlighted' : ''}`} onClick={() => handleSelect(option.value)} onMouseEnter={() => setHighlightedIndex(index)} > {option.label} </li> ))} </ul> )} </div> ); }; export default SearchableSelect;