'use client'; import React, { useState, KeyboardEvent, useEffect, useRef } from 'react'; import { X, Hash, Search, TrendingUp } from 'lucide-react'; interface Props { value: string[]; onChange: (value: string[]) => void; label?: string; placeholder?: string; suggestions?: string[]; onlySuggestions?: boolean; } export default function TagInput({ value, onChange, label, placeholder, suggestions = [], onlySuggestions = false }: Props) { const [inputValue, setInputValue] = useState(''); const [filteredSuggestions, setFilteredSuggestions] = useState([]); const [showSuggestions, setShowSuggestions] = useState(false); const [selectedIndex, setSelectedIndex] = useState(-1); const containerRef = useRef(null); useEffect(() => { if (inputValue.trim()) { const filtered = suggestions .filter(tag => tag.toLowerCase().includes(inputValue.toLowerCase()) && !value.includes(tag.toLowerCase()) ) .slice(0, 10); setFilteredSuggestions(filtered); setShowSuggestions(filtered.length > 0); } else if (showSuggestions && suggestions.length > 0) { const filtered = suggestions .filter(tag => !value.includes(tag.toLowerCase())) .slice(0, 8); setFilteredSuggestions(filtered); setShowSuggestions(filtered.length > 0); } else { setFilteredSuggestions([]); setShowSuggestions(false); } setSelectedIndex(-1); }, [inputValue, suggestions, value, showSuggestions]); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setShowSuggestions(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const addTag = (tagToAdd?: string) => { if (onlySuggestions && !tagToAdd) return; const tag = (tagToAdd || inputValue).trim().toLowerCase(); // If restricted, check if tag exists in suggestions if (onlySuggestions && tagToAdd && !suggestions.some(s => s.toLowerCase() === tag)) { return; } if (tag && !value.includes(tag)) { onChange([...value, tag]); } setInputValue(''); if (tagToAdd) setShowSuggestions(true); }; const removeTag = (tagToRemove: string) => { onChange(value.filter(tag => tag !== tagToRemove)); }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter') { e.preventDefault(); if (selectedIndex >= 0 && filteredSuggestions[selectedIndex]) { addTag(filteredSuggestions[selectedIndex]); } else if (!onlySuggestions) { addTag(); } } else if ((e.key === ',' || e.key === ';') && !onlySuggestions) { e.preventDefault(); addTag(); } else if (e.key === 'ArrowDown') { e.preventDefault(); if (!showSuggestions && suggestions.length > 0) { setShowSuggestions(true); } else { setSelectedIndex(prev => (prev < filteredSuggestions.length - 1 ? prev + 1 : prev)); } } else if (e.key === 'ArrowUp') { e.preventDefault(); setSelectedIndex(prev => (prev > -1 ? prev - 1 : -1)); } else if (e.key === 'Escape') { setShowSuggestions(false); } else if (e.key === 'Backspace' && !inputValue && value.length > 0) { removeTag(value[value.length - 1]); } }; return (
{label && }
{ const input = containerRef.current?.querySelector('input'); input?.focus(); }} > {value.map((tag) => ( {tag} ))} setInputValue(e.target.value)} onKeyDown={handleKeyDown} onFocus={() => setShowSuggestions(true)} placeholder={value.length === 0 ? (placeholder || "Ajouter des tags...") : ""} className="flex-1 bg-transparent border-none outline-none text-gray-900 text-sm min-w-[120px] p-1 placeholder:text-gray-400" />
{showSuggestions && filteredSuggestions.length > 0 && (

{inputValue ? : } {inputValue ? 'Suggestions' : 'Tags populaires'}

{filteredSuggestions.map((suggestion, index) => ( ))}
)}
); }