1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-18 20:59:44 +02:00

fix: Handle escape actions properly in mentions input

This commit is contained in:
Maksim Eltyshev 2025-06-06 12:48:43 +02:00
parent 63de346b0e
commit 2e6658221f
2 changed files with 28 additions and 21 deletions

View file

@ -31,8 +31,9 @@ const Add = React.memo(() => {
const [isOpened, setIsOpened] = useState(false); const [isOpened, setIsOpened] = useState(false);
const [selectTextFieldState, selectTextField] = useToggle(); const [selectTextFieldState, selectTextField] = useToggle();
const mentionsInputRef = useRef(null);
const textFieldRef = useRef(null); const textFieldRef = useRef(null);
const textMentionsRef = useRef(null);
const textInputRef = useRef(null);
const [buttonRef, handleButtonRef] = useNestedRef(); const [buttonRef, handleButtonRef] = useNestedRef();
const submit = useCallback(() => { const submit = useCallback(() => {
@ -42,24 +43,24 @@ const Add = React.memo(() => {
}; };
if (!cleanData.text) { if (!cleanData.text) {
textFieldRef.current.select(); textInputRef.current.select();
return; return;
} }
dispatch(entryActions.createCommentInCurrentCard(cleanData)); dispatch(entryActions.createCommentInCurrentCard(cleanData));
setData(DEFAULT_DATA); setData(DEFAULT_DATA);
selectTextField(); selectTextField();
}, [dispatch, data, setData, selectTextField, textFieldRef]); }, [dispatch, data, setData, selectTextField]);
const handleEscape = useCallback(() => { const handleEscape = useCallback(() => {
if (mentionsInputRef.current.isOpened()) { if (textMentionsRef.current.isOpened()) {
mentionsInputRef.current.clearSuggestions(); textMentionsRef.current.clearSuggestions();
return; return;
} }
setIsOpened(false); setIsOpened(false);
textFieldRef.current.blur(); textInputRef.current.blur();
}, [textFieldRef]); }, []);
const [activateEscapeInterceptor, deactivateEscapeInterceptor] = const [activateEscapeInterceptor, deactivateEscapeInterceptor] =
useEscapeInterceptor(handleEscape); useEscapeInterceptor(handleEscape);
@ -95,8 +96,8 @@ const Add = React.memo(() => {
}, []); }, []);
const handleClickAwayCancel = useCallback(() => { const handleClickAwayCancel = useCallback(() => {
textFieldRef.current.focus(); textInputRef.current.focus();
}, [textFieldRef]); }, []);
const clickAwayProps = useClickAwayListener( const clickAwayProps = useClickAwayListener(
[textFieldRef, buttonRef], [textFieldRef, buttonRef],
@ -123,18 +124,18 @@ const Add = React.memo(() => {
}, [isOpened]); }, [isOpened]);
useDidUpdate(() => { useDidUpdate(() => {
textFieldRef.current.focus(); textInputRef.current.focus();
}, [selectTextFieldState]); }, [selectTextFieldState]);
return ( return (
<Form onSubmit={handleSubmit}> <Form onSubmit={handleSubmit}>
<div className={styles.field}> <div ref={textFieldRef} className={styles.field}>
<MentionsInput <MentionsInput
{...clickAwayProps} // eslint-disable-line react/jsx-props-no-spreading {...clickAwayProps} // eslint-disable-line react/jsx-props-no-spreading
allowSpaceInQuery allowSpaceInQuery
allowSuggestionsAboveCursor allowSuggestionsAboveCursor
ref={mentionsInputRef} ref={textMentionsRef}
inputRef={textFieldRef} inputRef={textInputRef}
value={data.text} value={data.text}
placeholder={t('common.writeComment')} placeholder={t('common.writeComment')}
maxLength={1048576} maxLength={1048576}

View file

@ -42,8 +42,9 @@ const Edit = React.memo(({ commentId, onClose }) => {
...defaultData, ...defaultData,
})); }));
const mentionsInputRef = useRef(null);
const textFieldRef = useRef(null); const textFieldRef = useRef(null);
const textMentionsRef = useRef(null);
const textInputRef = useRef(null);
const [buttonRef, handleButtonRef] = useNestedRef(); const [buttonRef, handleButtonRef] = useNestedRef();
const submit = useCallback(() => { const submit = useCallback(() => {
@ -79,6 +80,11 @@ const Edit = React.memo(({ commentId, onClose }) => {
submit(); submit();
} }
} else if (event.key === 'Escape') { } else if (event.key === 'Escape') {
if (textMentionsRef.current.isOpened()) {
textMentionsRef.current.clearSuggestions();
return;
}
onClose(); onClose();
} }
}, },
@ -86,8 +92,8 @@ const Edit = React.memo(({ commentId, onClose }) => {
); );
const handleClickAwayCancel = useCallback(() => { const handleClickAwayCancel = useCallback(() => {
textFieldRef.current.focus(); textInputRef.current.focus();
}, [textFieldRef]); }, []);
const clickAwayProps = useClickAwayListener( const clickAwayProps = useClickAwayListener(
[textFieldRef, buttonRef], [textFieldRef, buttonRef],
@ -106,18 +112,18 @@ const Edit = React.memo(({ commentId, onClose }) => {
); );
useEffect(() => { useEffect(() => {
focusEnd(textFieldRef.current); focusEnd(textInputRef.current);
}, [textFieldRef]); }, []);
return ( return (
<Form onSubmit={handleSubmit}> <Form onSubmit={handleSubmit}>
<div className={styles.field}> <div ref={textFieldRef} className={styles.field}>
<MentionsInput <MentionsInput
{...clickAwayProps} // eslint-disable-line react/jsx-props-no-spreading {...clickAwayProps} // eslint-disable-line react/jsx-props-no-spreading
allowSpaceInQuery allowSpaceInQuery
allowSuggestionsAboveCursor allowSuggestionsAboveCursor
ref={mentionsInputRef} ref={textMentionsRef}
inputRef={textFieldRef} inputRef={textInputRef}
value={data.text} value={data.text}
maxLength={1048576} maxLength={1048576}
rows={3} rows={3}