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 { defaultMaxTextAreaHeight } from './chat-constants.js'; | |||||
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, | +onChangePosition: () => void, | ||||
+maxHeight?: number, | |||||
}; | }; | ||||
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 { | const { | ||||
currentText, | currentText, | ||||
focus, | focus, | ||||
escape, | escape, | ||||
send, | send, | ||||
setCurrentText, | setCurrentText, | ||||
onChangePosition, | onChangePosition, | ||||
maxHeight = defaultMaxTextAreaHeight, | |||||
} = props; | } = 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; | ||||
} | } | ||||
Show All 14 Lines | const focusAndUpdateText = React.useCallback(() => { | ||||
// but we also need to make sure that we're scrolled to the bottom | // but we also need to make sure that we're scrolled to the bottom | ||||
textarea.scrollTop = textarea.scrollHeight; | textarea.scrollTop = textarea.scrollHeight; | ||||
}, [currentText, focus]); | }, [currentText, focus]); | ||||
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, maxHeight); | ||||
textarea.style.height = `${newHeight}px`; | textarea.style.height = `${newHeight}px`; | ||||
} | } | ||||
onChangePosition(); | onChangePosition(); | ||||
}, [onChangePosition]); | }, [maxHeight, onChangePosition]); | ||||
React.useEffect(() => { | React.useEffect(() => { | ||||
focusAndUpdateText(); | focusAndUpdateText(); | ||||
// eslint-disable-next-line react-hooks/exhaustive-deps | // eslint-disable-next-line react-hooks/exhaustive-deps | ||||
}, []); | }, []); | ||||
React.useEffect(() => { | React.useEffect(() => { | ||||
updateHeight(); | updateHeight(); | ||||
▲ Show 20 Lines • Show All 46 Lines • Show Last 20 Lines |