- Marked several UI/UX tasks as complete in TODO.md, including improvements for Kanban icons, tag visibility, recent tasks display, and header responsiveness. - Updated PriorityDistributionChart to adjust height for better layout. - Refined IntegrationFilter to improve filter display and added new trigger class for dropdowns. - Replaced RecentTaskTimeline with TaskCard in RecentTasks for better consistency. - Enhanced TagDistributionChart with improved tooltip and legend styling. - Updated DesktopControls and MobileControls to use lucide-react icons for filters and search functionality. - Removed RecentTaskTimeline component for cleaner codebase.
79 lines
2.1 KiB
TypeScript
79 lines
2.1 KiB
TypeScript
import { InputHTMLAttributes, forwardRef, useState, useEffect, useRef, useCallback } from 'react';
|
|
import { Input } from './Input';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface SearchInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
|
|
value?: string;
|
|
onChange?: (value: string) => void;
|
|
onDebouncedChange?: (value: string) => void;
|
|
debounceMs?: number;
|
|
placeholder?: string;
|
|
className?: string;
|
|
}
|
|
|
|
const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(
|
|
({
|
|
value = '',
|
|
onChange,
|
|
onDebouncedChange,
|
|
debounceMs = 300,
|
|
placeholder = "Rechercher...",
|
|
className,
|
|
...props
|
|
}, ref) => {
|
|
const [localValue, setLocalValue] = useState(value);
|
|
const timeoutRef = useRef<number | undefined>(undefined);
|
|
|
|
// Fonction debouncée pour les changements
|
|
const debouncedChange = useCallback((searchValue: string) => {
|
|
if (timeoutRef.current) {
|
|
window.clearTimeout(timeoutRef.current);
|
|
}
|
|
|
|
timeoutRef.current = window.setTimeout(() => {
|
|
onDebouncedChange?.(searchValue);
|
|
}, debounceMs);
|
|
}, [onDebouncedChange, debounceMs]);
|
|
|
|
// Gérer les changements locaux
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const newValue = e.target.value;
|
|
setLocalValue(newValue);
|
|
onChange?.(newValue);
|
|
debouncedChange(newValue);
|
|
};
|
|
|
|
// Synchroniser l'état local quand la valeur externe change
|
|
useEffect(() => {
|
|
setLocalValue(value);
|
|
}, [value]);
|
|
|
|
// Nettoyer le timeout au démontage
|
|
useEffect(() => {
|
|
return () => {
|
|
if (timeoutRef.current) {
|
|
window.clearTimeout(timeoutRef.current);
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div className={cn('flex-1 min-w-0', className)}>
|
|
<Input
|
|
ref={ref}
|
|
type="text"
|
|
value={localValue}
|
|
onChange={handleChange}
|
|
placeholder={placeholder}
|
|
className="bg-[var(--card)] border-[var(--border)] w-full h-[34px]"
|
|
{...props}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
|
|
SearchInput.displayName = 'SearchInput';
|
|
|
|
export { SearchInput };
|