1
+ import { useCallback , useEffect } from "react" ;
1
2
import useMessages , { type IMessage } from "../../../hooks/useMessages" ;
2
3
3
4
interface Props {
4
5
setMessages : React . Dispatch < React . SetStateAction < IMessage [ ] > > ;
5
6
isLoading : boolean ;
6
7
setIsLoading : React . Dispatch < React . SetStateAction < boolean > > ;
7
8
value : string ;
8
- inputRef : React . RefObject < HTMLInputElement | null > ;
9
- onChange : ( e : React . ChangeEvent < HTMLInputElement > ) => void ;
9
+ inputRef : React . RefObject < HTMLTextAreaElement | null > ;
10
+ onChange : ( e : React . ChangeEvent < HTMLTextAreaElement > ) => void ;
10
11
}
11
12
12
13
export default function InputField ( {
@@ -26,7 +27,9 @@ export default function InputField({
26
27
const userMessageId = Date . now ( ) . toString ( ) ;
27
28
const botMessageId = ( Date . now ( ) + 1 ) . toString ( ) ;
28
29
29
- onChange ( { target : { value : "" } } as React . ChangeEvent < HTMLInputElement > ) ;
30
+ onChange ( {
31
+ target : { value : "" } ,
32
+ } as React . ChangeEvent < HTMLTextAreaElement > ) ;
30
33
setIsLoading ( true ) ;
31
34
32
35
// Add user message
@@ -83,25 +86,38 @@ export default function InputField({
83
86
}
84
87
} ;
85
88
89
+ const resizeTextArea = useCallback ( ( ) => {
90
+ const inputElement = inputRef . current ;
91
+ if ( inputElement !== null ) {
92
+ inputElement . style . height = "auto" ;
93
+ inputElement . style . height = `${ inputElement . scrollHeight } px` ;
94
+ }
95
+ } , [ inputRef ] ) ;
96
+
97
+ useEffect ( ( ) => {
98
+ resizeTextArea ( ) ;
99
+ } , [ value , resizeTextArea ] ) ;
100
+
86
101
return (
87
- < div className = "flex gap-2 mt-4 h-11 items-stretch mx-auto max-w-[700px]" >
88
- < input
89
- type = "text"
102
+ < div className = "flex gap-2 mt-4 justify-center items-center mx-auto max-w-[700px]" >
103
+ < textarea
90
104
value = { value }
91
105
onChange = { onChange }
106
+ onInput = { resizeTextArea }
92
107
onKeyDown = { ( e ) => {
93
108
if ( e . key === "Enter" ) {
94
109
e . preventDefault ( ) ;
95
110
handleSend ( ) ;
96
111
}
97
112
} }
98
- className = "w-full p-3 border-1 border-[#ddd] rounded-md box-border transition-colors duration-300 focus:outline-0 focus:border-[#4a90e2] focus:shadow-[0_0_0_2px_rgba(74,144,226,0.2)]"
113
+ rows = { 1 }
114
+ className = "overflow-auto resize-none max-h-22 w-full px-3 py-2 border-1 border-[#ddd] rounded-md box-border transition-colors duration-300 focus:outline-0 focus:border-[#4a90e2] focus:shadow-[0_0_0_2px_rgba(74,144,226,0.2)]"
99
115
placeholder = "Type your message here..."
100
116
disabled = { isLoading }
101
117
ref = { inputRef }
102
118
/>
103
119
< button
104
- className = "px-6 bg-[#1F584F] hover:bg-[#4F8B82] text-white rounded-md cursor-pointer transition-color duration-300"
120
+ className = "px-6 h-10 bg-[#1F584F] hover:bg-[#4F8B82] text-white rounded-md cursor-pointer transition-color duration-300"
105
121
onClick = { handleSend }
106
122
disabled = { isLoading || ! value . trim ( ) }
107
123
>
0 commit comments