feat(TypeaheadInput): enhance external update handling and suggestion management

This commit is contained in:
ryan 2025-06-20 18:04:51 +03:00
parent b0a8271040
commit e1992af634

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect, useRef, useCallback } from 'react';
import React, { useState, useEffect, useCallback, useRef } from 'react';
import { WikidataSuggestion } from '@/types/database';
interface TypeaheadInputProps {
@ -27,15 +27,33 @@ export function TypeaheadInput({
const [showSuggestions, setShowSuggestions] = useState(false);
const [selectedIndex, setSelectedIndex] = useState(-1);
const [isLoading, setIsLoading] = useState(false);
const [isExternalUpdate, setIsExternalUpdate] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const suggestionsRef = useRef<HTMLDivElement>(null);
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
// Update local value when prop changes
// Update local value when prop changes (including external updates)
useEffect(() => {
setLocalValue(value);
}, [value]);
if (value !== localValue) {
setLocalValue(value);
setIsExternalUpdate(true);
// Clear suggestions when externally updated
setSuggestions([]);
setShowSuggestions(false);
setSelectedIndex(-1);
}
}, [value, localValue]);
// Reset external update flag after a short delay
useEffect(() => {
if (isExternalUpdate) {
const timer = setTimeout(() => {
setIsExternalUpdate(false);
}, 100);
return () => clearTimeout(timer);
}
}, [isExternalUpdate]);
// Debounced suggestion fetching
const debouncedFetchSuggestions = useCallback(async (query: string) => {
@ -73,8 +91,12 @@ export function TypeaheadInput({
const newValue = e.target.value;
setLocalValue(newValue);
onInput(newValue);
debouncedFetchSuggestions(newValue);
}, [onInput, debouncedFetchSuggestions]);
// Only fetch suggestions if this is user input, not external update
if (!isExternalUpdate) {
debouncedFetchSuggestions(newValue);
}
}, [onInput, debouncedFetchSuggestions, isExternalUpdate]);
// Handle keyboard navigation
const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
@ -136,11 +158,13 @@ export function TypeaheadInput({
// Update local value with the selected suggestion
const newValue = suggestion.label || '';
setLocalValue(newValue);
onInput(newValue);
// Call the selection handler
// Call the selection handler first (this will update the parent)
onSelect(suggestion);
// Then update the input value
onInput(newValue);
// Hide suggestions
setShowSuggestions(false);
setSelectedIndex(-1);