import type { CompositionEvent, } from 'react'; import type React from 'react'; import { useCallback, useState, } from 'react'; import type { SubmittableInputProps } from './types'; export const useSubmittable = (props: SubmittableInputProps): Partial> => { const { value, onChange, onBlur, onCompositionStart, onCompositionEnd, onSubmit, onCancel, } = props; const [inputText, setInputText] = useState(value ?? ''); const [isComposing, setComposing] = useState(false); const changeHandler = useCallback(async(e: React.ChangeEvent) => { const inputText = e.target.value; setInputText(inputText); onChange?.(e); }, [onChange]); const keyDownHandler = useCallback((e) => { switch (e.key) { case 'Enter': // Do nothing when composing if (isComposing) { return; } onSubmit?.(inputText.trim()); break; case 'Escape': if (isComposing) { return; } onCancel?.(); break; } }, [inputText, isComposing, onCancel, onSubmit]); const blurHandler = useCallback((e) => { // submit on blur onSubmit?.(inputText.trim()); onBlur?.(e); }, [inputText, onSubmit, onBlur]); const compositionStartHandler = useCallback((e: CompositionEvent) => { setComposing(true); onCompositionStart?.(e); }, [onCompositionStart]); const compositionEndHandler = useCallback((e: CompositionEvent) => { setComposing(false); onCompositionEnd?.(e); }, [onCompositionEnd]); const { // eslint-disable-next-line @typescript-eslint/no-unused-vars value: _value, onSubmit: _onSubmit, onCancel: _onCancel, ...cleanedProps } = props; return { ...cleanedProps, value: inputText, onChange: changeHandler, onKeyDown: keyDownHandler, onBlur: blurHandler, onCompositionStart: compositionStartHandler, onCompositionEnd: compositionEndHandler, }; };