Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32089007
chat-input-text-area.react.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
chat-input-text-area.react.js
View Options
// @flow
import
invariant
from
'invariant'
;
import
*
as
React
from
'react'
;
import
{
defaultMaxTextAreaHeight
}
from
'./chat-constants.js'
;
import
css
from
'./chat-input-bar.css'
;
type
Props
=
{
+
send
?:
()
=>
mixed
,
+
escape
?:
()
=>
void
,
+
focus
:
boolean
,
+
currentText
:
string
,
+
setCurrentText
:
(
text
:
string
)
=>
void
,
+
onChangePosition
:
()
=>
void
,
+
maxHeight
?:
number
,
};
const
ChatInputTextArea
:
React
.
ComponentType
<
Props
>
=
React
.
memo
<
Props
>
(
function
ChatInputTextArea
(
props
:
Props
)
{
const
{
currentText
,
focus
,
escape
,
send
,
setCurrentText
,
onChangePosition
,
maxHeight
=
defaultMaxTextAreaHeight
,
}
=
props
;
const
textareaRef
=
React
.
useRef
<?
HTMLTextAreaElement
>
(
null
);
const
focusAndUpdateText
=
React
.
useCallback
(()
=>
{
if
(
!
focus
)
{
return
;
}
// We need to call focus() first on Safari, otherwise the cursor
// ends up at the start instead of the end for some reason
const
textarea
=
textareaRef
.
current
;
invariant
(
textarea
,
'textarea should be set'
);
textarea
.
focus
();
// We reset the textarea to an empty string at the start so that
// the cursor always ends up at the end, even if the text doesn't
// actually change
textarea
.
value
=
''
;
if
(
currentText
)
{
textarea
.
value
=
currentText
;
}
// The above strategies make sure the cursor is at the end,
// but we also need to make sure that we're scrolled to the bottom
textarea
.
scrollTop
=
textarea
.
scrollHeight
;
},
[
currentText
,
focus
]);
const
updateHeight
=
React
.
useCallback
(()
=>
{
const
textarea
=
textareaRef
.
current
;
if
(
textarea
)
{
textarea
.
style
.
height
=
'auto'
;
const
newHeight
=
Math
.
min
(
textarea
.
scrollHeight
,
maxHeight
);
textarea
.
style
.
height
=
`
${
newHeight
}
px`
;
}
onChangePosition
();
},
[
maxHeight
,
onChangePosition
]);
React
.
useEffect
(()
=>
{
focusAndUpdateText
();
// eslint-disable-next-line react-hooks/exhaustive-deps
},
[]);
React
.
useEffect
(()
=>
{
updateHeight
();
// We want to update the height when the text changes. We can't include
// updateHeight in the dep list because it causes a stack overflow... see
// comments on D8035 for more details
// eslint-disable-next-line react-hooks/exhaustive-deps
},
[
currentText
]);
const
onKeyDown
=
(
event
:
SyntheticKeyboardEvent
<
HTMLTextAreaElement
>
)
=>
{
if
(
event
.
key
===
'Escape'
)
{
event
.
preventDefault
();
if
(
!
escape
)
{
return
;
}
escape
();
}
else
if
(
event
.
key
===
'Enter'
&&
!
event
.
shiftKey
)
{
event
.
preventDefault
();
if
(
!
send
)
{
return
;
}
send
();
}
};
const
onChangeMessageText
=
(
event
:
SyntheticEvent
<
HTMLTextAreaElement
>
,
)
=>
{
setCurrentText
(
event
.
currentTarget
.
value
);
updateHeight
();
};
return
(
<
div
className
=
{
css
.
inputBarTextInput
}
>
<
textarea
rows
=
"1"
placeholder
=
"Type your message"
value
=
{
currentText
}
onChange
=
{
onChangeMessageText
}
onKeyDown
=
{
onKeyDown
}
ref
=
{
textareaRef
}
autoFocus
/>
<
/div>
);
},
);
export
default
ChatInputTextArea
;
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Sun, Dec 7, 7:55 AM (2 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5618354
Default Alt Text
chat-input-text-area.react.js (3 KB)
Attached To
Mode
rCOMM Comm
Attached
Detach File
Event Timeline
Log In to Comment