Fix missing ref to textarea

This commit is contained in:
Claire 2023-10-30 16:26:55 +01:00
parent d6a0b54e19
commit bf0a87893a
2 changed files with 14 additions and 13 deletions

View File

@ -1,5 +1,5 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useCallback, useRef, useState, useEffect } from 'react'; import { useCallback, useRef, useState, useEffect, forwardRef } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
@ -37,7 +37,7 @@ const textAtCursorMatchesToken = (str, caretPosition) => {
} }
}; };
const AutosuggestTextarea = ({ const AutosuggestTextarea = forwardRef(({
value, value,
suggestions, suggestions,
disabled, disabled,
@ -53,7 +53,7 @@ const AutosuggestTextarea = ({
autoFocus = true, autoFocus = true,
lang, lang,
children, children,
}) => { }, textareaRef) => {
const [suggestionsHidden, setSuggestionsHidden] = useState(true); const [suggestionsHidden, setSuggestionsHidden] = useState(true);
const [selectedSuggestion, setSelectedSuggestion] = useState(0); const [selectedSuggestion, setSelectedSuggestion] = useState(0);
@ -61,7 +61,6 @@ const AutosuggestTextarea = ({
const focusedRef = useRef(false); const focusedRef = useRef(false);
const lastTokenRef = useRef(null); const lastTokenRef = useRef(null);
const tokenStartRef = useRef(0); const tokenStartRef = useRef(0);
const textareaRef = useRef(null);
const handleChange = useCallback((e) => { const handleChange = useCallback((e) => {
const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart); const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart);
@ -151,7 +150,7 @@ const AutosuggestTextarea = ({
e.preventDefault(); e.preventDefault();
onSuggestionSelected(tokenStartRef.current, lastTokenRef.current, suggestion); onSuggestionSelected(tokenStartRef.current, lastTokenRef.current, suggestion);
textareaRef.current?.focus(); textareaRef.current?.focus();
}, [suggestions, onSuggestionSelected]); }, [suggestions, onSuggestionSelected, textareaRef]);
const handlePaste = useCallback((e) => { const handlePaste = useCallback((e) => {
if (e.clipboardData && e.clipboardData.files.length === 1) { if (e.clipboardData && e.clipboardData.files.length === 1) {
@ -223,7 +222,7 @@ const AutosuggestTextarea = ({
</div> </div>
</div>, </div>,
]; ];
}; });
AutosuggestTextarea.propTypes = { AutosuggestTextarea.propTypes = {
value: PropTypes.string, value: PropTypes.string,
@ -237,6 +236,8 @@ AutosuggestTextarea.propTypes = {
onKeyUp: PropTypes.func, onKeyUp: PropTypes.func,
onKeyDown: PropTypes.func, onKeyDown: PropTypes.func,
onPaste: PropTypes.func.isRequired, onPaste: PropTypes.func.isRequired,
onFocus:PropTypes.func,
children: PropTypes.node,
autoFocus: PropTypes.bool, autoFocus: PropTypes.bool,
lang: PropTypes.string, lang: PropTypes.string,
}; };

View File

@ -102,10 +102,10 @@ class ComposeForm extends ImmutablePureComponent {
}; };
handleSubmit = (e) => { handleSubmit = (e) => {
if (this.props.text !== this.autosuggestTextarea.textarea.value) { if (this.props.text !== this.autosuggestTextarea.value) {
// Something changed the text inside the textarea (e.g. browser extensions like Grammarly) // Something changed the text inside the textarea (e.g. browser extensions like Grammarly)
// Update the state to match the current text // Update the state to match the current text
this.props.onChange(this.autosuggestTextarea.textarea.value); this.props.onChange(this.autosuggestTextarea.value);
} }
if (!this.canSubmit()) { if (!this.canSubmit()) {
@ -184,18 +184,18 @@ class ComposeForm extends ImmutablePureComponent {
// immediately selectable, we have to wait for observers to run, as // immediately selectable, we have to wait for observers to run, as
// described in https://github.com/WICG/inert#performance-and-gotchas // described in https://github.com/WICG/inert#performance-and-gotchas
Promise.resolve().then(() => { Promise.resolve().then(() => {
this.autosuggestTextarea.textarea.setSelectionRange(selectionStart, selectionEnd); this.autosuggestTextarea.setSelectionRange(selectionStart, selectionEnd);
this.autosuggestTextarea.textarea.focus(); this.autosuggestTextarea.focus();
this.setState({ highlighted: true }); this.setState({ highlighted: true });
this.timeout = setTimeout(() => this.setState({ highlighted: false }), 700); this.timeout = setTimeout(() => this.setState({ highlighted: false }), 700);
}).catch(console.error); }).catch(console.error);
} else if(prevProps.isSubmitting && !this.props.isSubmitting) { } else if(prevProps.isSubmitting && !this.props.isSubmitting) {
this.autosuggestTextarea.textarea.focus(); this.autosuggestTextarea.focus();
} else if (this.props.spoiler !== prevProps.spoiler) { } else if (this.props.spoiler !== prevProps.spoiler) {
if (this.props.spoiler) { if (this.props.spoiler) {
this.spoilerText.input.focus(); this.spoilerText.input.focus();
} else if (prevProps.spoiler) { } else if (prevProps.spoiler) {
this.autosuggestTextarea.textarea.focus(); this.autosuggestTextarea.focus();
} }
} }
}; };
@ -214,7 +214,7 @@ class ComposeForm extends ImmutablePureComponent {
handleEmojiPick = (data) => { handleEmojiPick = (data) => {
const { text } = this.props; const { text } = this.props;
const position = this.autosuggestTextarea.textarea.selectionStart; const position = this.textarea.selectionStart;
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]); const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
this.props.onPickEmoji(position, data, needsSpace); this.props.onPickEmoji(position, data, needsSpace);