import React, { useState, useRef, useEffect } from 'react'; import { __ } from '@wordpress/i18n'; import { X, ChevronDown, Search } from 'lucide-react'; interface Option { value: string; label: string; } interface MultiSelectProps { options: Option[]; value: string[]; onChange: (value: string[]) => void; placeholder?: string; className?: string; disabled?: boolean; } export const MultiSelect: React.FC = ({ options, value, onChange, placeholder, className = "", disabled = false }) => { const [isOpen, setIsOpen] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const containerRef = useRef(null); const searchInputRef = useRef(null); // Filter options based on search term const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchTerm.toLowerCase()) && !value.includes(option.value) ); // Get selected options const selectedOptions = options.filter(option => value.includes(option.value)); // Close dropdown when clicking outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setIsOpen(false); setSearchTerm(''); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); // Focus search input when dropdown opens useEffect(() => { if (isOpen && searchInputRef.current) { searchInputRef.current.focus(); } }, [isOpen]); const handleToggle = () => { if (!disabled) { setIsOpen(!isOpen); setSearchTerm(''); } }; const handleOptionSelect = (optionValue: string) => { onChange([...value, optionValue]); setSearchTerm(''); }; const handleOptionRemove = (optionValue: string) => { onChange(value.filter(v => v !== optionValue)); }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Escape') { setIsOpen(false); setSearchTerm(''); } else if (e.key === 'Enter' && filteredOptions.length > 0) { e.preventDefault(); handleOptionSelect(filteredOptions[0].value); } }; return (
{/* Main input area */}
{selectedOptions.length > 0 ? ( selectedOptions.map(option => ( {option.label} )) ) : ( {placeholder ?? __('Select options…', 'webhook-buttons')} )}
{/* Dropdown */} {isOpen && (
{/* Search input */}
setSearchTerm(e.target.value)} onKeyDown={handleKeyDown} placeholder={__('Search options…', 'webhook-buttons')} className="w-full pr-3 py-2 border border-gray-200 text-sm focus:outline-none focus:ring-2 focus:ring-[#2271b1] focus:border-[#2271b1] transition-colors" style={{ paddingLeft: '2.25rem' }} />
{/* Options list */}
{filteredOptions.length > 0 ? ( filteredOptions.map(option => ( )) ) : (
{searchTerm ? __('No options found', 'webhook-buttons') : __('All options selected', 'webhook-buttons')}
)}
)}
); };