11import React from 'react' ;
2- import { DropEvent , TextAreaProps } from '@patternfly/react-core' ;
2+ import { DropEvent , TextArea , TextAreaProps , TextInput } from '@patternfly/react-core' ;
33import { AutoTextArea } from 'react-textarea-auto-witdth-height' ;
44
55// Import Chatbot components
@@ -63,11 +63,79 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
6363 // --------------------------------------------------------------------------
6464 const [ message , setMessage ] = React . useState < string > ( '' ) ;
6565 const [ isListeningMessage , setIsListeningMessage ] = React . useState < boolean > ( false ) ;
66+ const [ height , setHeight ] = React . useState < number > ( ) ;
6667
67- const textareaRef = React . useRef ( null ) ;
68+ const textareaRef = React . useRef < HTMLTextAreaElement > ( null ) ;
6869 const attachButtonRef = React . useRef < HTMLButtonElement > ( null ) ;
6970
71+ const setInitialLineHeight = ( field : HTMLTextAreaElement ) => {
72+ field . style . setProperty ( 'line-height' , '1rem' ) ;
73+ const parent = field . parentElement ;
74+ if ( parent ) {
75+ parent . style . setProperty ( 'margin-top' , `0rem` ) ;
76+ parent . style . setProperty ( 'margin-bottom' , `0rem` ) ;
77+ }
78+ } ;
79+
80+ const setAutoHeight = ( field : HTMLTextAreaElement ) => {
81+ const parent = field . parentElement ;
82+ if ( parent ) {
83+ parent . style . setProperty ( 'height' , 'inherit' ) ;
84+ const computed = window . getComputedStyle ( field ) ;
85+ // Calculate the height
86+ const height =
87+ parseInt ( computed . getPropertyValue ( 'border-top-width' ) ) +
88+ parseInt ( computed . getPropertyValue ( 'padding-top' ) ) +
89+ field . scrollHeight +
90+ parseInt ( computed . getPropertyValue ( 'padding-bottom' ) ) +
91+ parseInt ( computed . getPropertyValue ( 'border-bottom-width' ) ) ;
92+ parent . style . setProperty ( 'height' , `${ height } px` ) ;
93+
94+ if ( height > 32 || window . innerWidth <= 359 ) {
95+ parent . style . setProperty ( 'margin-bottom' , `1rem` ) ;
96+ parent . style . setProperty ( 'margin-top' , `1rem` ) ;
97+ }
98+
99+ setHeight ( height ) ;
100+ }
101+ } ;
102+
103+ const handleNewLine = ( field : HTMLTextAreaElement ) => {
104+ const parent = field . parentElement ;
105+ const oldHeight = height ?? 0 ;
106+ if ( parent ) {
107+ if ( oldHeight === 0 ) {
108+ parent . style . setProperty ( 'margin-bottom' , `1rem` ) ;
109+ parent . style . setProperty ( 'margin-top' , `1rem` ) ;
110+ } else {
111+ parent . style . setProperty ( 'height' , `${ oldHeight + 16 } px` ) ;
112+ }
113+ }
114+ } ;
115+
116+ const handleMobileHeight = ( field : HTMLTextAreaElement ) => {
117+ const parent = field . parentElement ;
118+ if ( parent ) {
119+ parent . style . setProperty ( 'margin-bottom' , `1rem` ) ;
120+ parent . style . setProperty ( 'margin-top' , `1rem` ) ;
121+ }
122+ } ;
123+
124+ React . useEffect ( ( ) => {
125+ const field = textareaRef . current ;
126+ if ( field ) {
127+ setInitialLineHeight ( field ) ;
128+ setAutoHeight ( field ) ;
129+ }
130+ } , [ ] ) ;
131+
70132 const handleChange = React . useCallback ( ( event ) => {
133+ if ( textareaRef . current ) {
134+ if ( event . target . value === '' ) {
135+ setInitialLineHeight ( textareaRef . current ) ;
136+ }
137+ setAutoHeight ( textareaRef . current ) ;
138+ }
71139 setMessage ( event . target . value ) ;
72140 } , [ ] ) ;
73141
@@ -79,6 +147,13 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
79147 } ) ;
80148 } , [ onSendMessage ] ) ;
81149
150+ // want to exclude things like delete, shift, etc.
151+ const isTypeableKey = ( key ) => {
152+ if ( key . length > 1 ) {
153+ return false ;
154+ }
155+ return true ;
156+ } ;
82157 const handleKeyDown = React . useCallback (
83158 ( event ) => {
84159 if ( event . key === 'Enter' && ! event . shiftKey ) {
@@ -87,6 +162,16 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
87162 handleSend ( ) ;
88163 }
89164 }
165+ if ( event . key === 'Enter' && event . shiftKey ) {
166+ if ( textareaRef . current ) {
167+ handleNewLine ( textareaRef . current ) ;
168+ }
169+ }
170+ if ( window . innerWidth <= 411 && isTypeableKey ( event . key ) ) {
171+ if ( textareaRef . current ) {
172+ handleMobileHeight ( textareaRef . current ) ;
173+ }
174+ }
90175 } ,
91176 [ handleSend ]
92177 ) ;
@@ -99,7 +184,7 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
99184 const messageBarContents = (
100185 < >
101186 < div className = "pf-chatbot__message-bar-input" >
102- < AutoTextArea
187+ { /* <AutoTextArea
103188 ref={textareaRef}
104189 className="pf-chatbot__message-textarea"
105190 value={message as any} // Added any to make the third part TextArea component types happy. Remove when replced with PF TextArea
@@ -108,6 +193,16 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
108193 placeholder={isListeningMessage ? 'Listening' : 'Send a message...'}
109194 aria-label={isListeningMessage ? 'Listening' : 'Send a message...'}
110195 {...props}
196+ />*/ }
197+ < TextArea
198+ className = "pf-chatbot__message-textarea"
199+ value = { message }
200+ onChange = { handleChange }
201+ aria-label = { isListeningMessage ? 'Listening' : 'Send a message...' }
202+ placeholder = { isListeningMessage ? 'Listening' : 'Send a message...' }
203+ ref = { textareaRef }
204+ onKeyDown = { handleKeyDown }
205+ { ...props }
111206 />
112207 </ div >
113208 < div className = "pf-chatbot__message-bar-actions" >
0 commit comments