Changeset View
Changeset View
Standalone View
Standalone View
web/chat/chat-input-text-area.react.js
// @flow | // @flow | ||||
import invariant from 'invariant'; | import invariant from 'invariant'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import css from './chat-input-bar.css'; | import css from './chat-input-bar.css'; | ||||
type Props = { | type Props = { | ||||
+send?: () => mixed, | +send?: () => mixed, | ||||
+escape?: () => void, | +escape?: () => void, | ||||
+focus: boolean, | +focus: boolean, | ||||
+currentText: string, | +currentText: string, | ||||
+setCurrentText: (text: string) => void, | +setCurrentText: (text: string) => void, | ||||
+onChangePosition: () => void, | |||||
ashoat: It never hurts to be flexible with props (and with input parameters). If we don't care about… | |||||
}; | }; | ||||
const ChatInputTextArea: React.ComponentType<Props> = React.memo<Props>( | const ChatInputTextArea: React.ComponentType<Props> = React.memo<Props>( | ||||
function ChatInputTextArea(props: Props) { | function ChatInputTextArea(props: Props) { | ||||
const { currentText, focus, escape, send, setCurrentText } = props; | const { | ||||
currentText, | |||||
focus, | |||||
escape, | |||||
send, | |||||
setCurrentText, | |||||
onChangePosition, | |||||
} = props; | |||||
const textareaRef = React.useRef(null); | const textareaRef = React.useRef(null); | ||||
const focusAndUpdateText = React.useCallback(() => { | const focusAndUpdateText = React.useCallback(() => { | ||||
if (!focus) { | if (!focus) { | ||||
return; | return; | ||||
} | } | ||||
// We need to call focus() first on Safari, otherwise the cursor | // We need to call focus() first on Safari, otherwise the cursor | ||||
Show All 16 Lines | function ChatInputTextArea(props: Props) { | ||||
const updateHeight = React.useCallback(() => { | const updateHeight = React.useCallback(() => { | ||||
const textarea = textareaRef.current; | const textarea = textareaRef.current; | ||||
if (textarea) { | if (textarea) { | ||||
textarea.style.height = 'auto'; | textarea.style.height = 'auto'; | ||||
const newHeight = Math.min(textarea.scrollHeight, 150); | const newHeight = Math.min(textarea.scrollHeight, 150); | ||||
textarea.style.height = `${newHeight}px`; | textarea.style.height = `${newHeight}px`; | ||||
} | } | ||||
}, []); | onChangePosition(); | ||||
}, [onChangePosition]); | |||||
React.useEffect(() => { | React.useEffect(() => { | ||||
updateHeight(); | updateHeight(); | ||||
focusAndUpdateText(); | focusAndUpdateText(); | ||||
// eslint-disable-next-line react-hooks/exhaustive-deps | // eslint-disable-next-line react-hooks/exhaustive-deps | ||||
}, []); | }, []); | ||||
const onKeyDown = (event: SyntheticKeyboardEvent<HTMLTextAreaElement>) => { | const onKeyDown = (event: SyntheticKeyboardEvent<HTMLTextAreaElement>) => { | ||||
Show All 39 Lines |
It never hurts to be flexible with props (and with input parameters). If we don't care about the return, we do not need to insist on the function returning void. It can return anything, and it won't matter to us