53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { useRef } from 'react'
|
|
import { useWordAutocomplete } from './useWordAutocomplete'
|
|
import { WordSuggestions } from './WordSuggestions'
|
|
|
|
export interface WordInputWithAutocompleteProps {
|
|
index: number
|
|
value: string
|
|
onChange: (value: string) => void
|
|
onFocus: () => void
|
|
onBlur: () => void
|
|
}
|
|
|
|
export function WordInputWithAutocomplete(params: WordInputWithAutocompleteProps): React.ReactElement {
|
|
const inputRef = useRef<HTMLInputElement>(null)
|
|
const autocomplete = useWordAutocomplete({ value: params.value, onChange: params.onChange, inputRef })
|
|
|
|
return (
|
|
<div className="relative">
|
|
<label htmlFor={`word-${params.index}`} className="block text-sm font-medium text-gray-700 mb-2">
|
|
Mot {params.index + 1}
|
|
</label>
|
|
<input
|
|
ref={inputRef}
|
|
id={`word-${params.index}`}
|
|
type="text"
|
|
value={params.value}
|
|
onChange={autocomplete.handleChange}
|
|
onKeyDown={autocomplete.handleKeyDown}
|
|
onFocus={params.onFocus}
|
|
onBlur={() => hideSuggestionsOnBlur({ onBlur: params.onBlur, setShowSuggestions: autocomplete.setShowSuggestions })}
|
|
className="w-full px-3 py-2 border border-gray-300 rounded-lg font-mono text-lg text-center"
|
|
autoComplete="off"
|
|
autoCapitalize="off"
|
|
autoCorrect="off"
|
|
spellCheck="false"
|
|
/>
|
|
<WordSuggestions
|
|
showSuggestions={autocomplete.showSuggestions}
|
|
suggestions={autocomplete.suggestions}
|
|
selectedIndex={autocomplete.selectedIndex}
|
|
onSuggestionClick={autocomplete.applySuggestion}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function hideSuggestionsOnBlur(params: { onBlur: () => void; setShowSuggestions: (value: boolean) => void }): void {
|
|
setTimeout(() => {
|
|
params.setShowSuggestions(false)
|
|
params.onBlur()
|
|
}, 200)
|
|
}
|