2
2
3
3
import { useState , FormEvent , KeyboardEvent , useEffect , useRef } from "react" ;
4
4
import { Button } from "./ui/button" ;
5
- import { SendIcon } from "lucide-react" ;
5
+ import {
6
+ ArrowDownIcon ,
7
+ ArrowLeftIcon ,
8
+ ArrowRightIcon ,
9
+ ArrowUpIcon ,
10
+ CornerDownLeftIcon ,
11
+ DeleteIcon ,
12
+ SendIcon ,
13
+ } from "lucide-react" ;
6
14
import { Tabs , TabsList , TabsTrigger } from "./ui/tabs" ;
7
15
8
16
interface MessageInputProps {
@@ -167,38 +175,24 @@ export default function MessageInput({
167
175
</ div >
168
176
169
177
< div className = "flex items-center justify-between p-4" >
170
- < div className = "flex items-center gap-3" >
171
- < TabsList >
172
- < TabsTrigger
173
- value = "text"
174
- onClick = { ( ) => {
175
- textareaRef . current ?. focus ( ) ;
176
- } }
177
- >
178
- Text
179
- </ TabsTrigger >
180
- < TabsTrigger
181
- value = "control"
182
- onClick = { ( ) => {
183
- textareaRef . current ?. focus ( ) ;
184
- } }
185
- >
186
- Control
187
- </ TabsTrigger >
188
- </ TabsList >
189
-
190
- < span className = "text-xs text-muted-foreground" >
191
- { inputMode === "text" ? (
192
- < >
193
- Switch to < span className = "font-medium" > Control</ span > { " " }
194
- mode to send raw keystrokes (↑,↓,Tab,Ctrl+C,Ctrl+R)
195
- directly to the terminal
196
- </ >
197
- ) : (
198
- < > Control mode - keystrokes sent directly to terminal</ >
199
- ) }
200
- </ span >
201
- </ div >
178
+ < TabsList >
179
+ < TabsTrigger
180
+ value = "text"
181
+ onClick = { ( ) => {
182
+ textareaRef . current ?. focus ( ) ;
183
+ } }
184
+ >
185
+ Text
186
+ </ TabsTrigger >
187
+ < TabsTrigger
188
+ value = "control"
189
+ onClick = { ( ) => {
190
+ textareaRef . current ?. focus ( ) ;
191
+ } }
192
+ >
193
+ Control
194
+ </ TabsTrigger >
195
+ </ TabsList >
202
196
203
197
{ inputMode === "text" && (
204
198
< Button
@@ -217,17 +211,48 @@ export default function MessageInput({
217
211
{ sentChars . map ( ( char ) => (
218
212
< span
219
213
key = { char . id }
220
- className = "size-9 rounded border font-mono font-medium text-xs flex items-center justify-center animate-pulse"
214
+ className = "min-w-9 h-9 px-2 rounded border font-mono font-medium text-xs flex items-center justify-center animate-pulse"
221
215
>
222
- { char . char }
216
+ < Char char = { char . char } />
223
217
</ span >
224
218
) ) }
225
219
</ div >
226
220
) }
227
221
</ div >
228
222
</ div >
229
223
</ form >
224
+
225
+ < span className = "text-xs text-muted-foreground mt-2 block text-center" >
226
+ { inputMode === "text" ? (
227
+ < >
228
+ Switch to < span className = "font-medium" > Control</ span > mode to
229
+ send raw keystrokes (↑,↓,Tab,Ctrl+C,Ctrl+R) directly to the
230
+ terminal
231
+ </ >
232
+ ) : (
233
+ < > Control mode - keystrokes sent directly to terminal</ >
234
+ ) }
235
+ </ span >
230
236
</ div >
231
237
</ Tabs >
232
238
) ;
233
239
}
240
+
241
+ function Char ( { char } : { char : string } ) {
242
+ switch ( char ) {
243
+ case "ArrowUp" :
244
+ return < ArrowUpIcon className = "h-4 w-4" /> ;
245
+ case "ArrowDown" :
246
+ return < ArrowDownIcon className = "h-4 w-4" /> ;
247
+ case "ArrowRight" :
248
+ return < ArrowRightIcon className = "h-4 w-4" /> ;
249
+ case "ArrowLeft" :
250
+ return < ArrowLeftIcon className = "h-4 w-4" /> ;
251
+ case "⏎" :
252
+ return < CornerDownLeftIcon className = "h-4 w-4" /> ;
253
+ case "Backspace" :
254
+ return < DeleteIcon className = "h-4 w-4" /> ;
255
+ default :
256
+ return char ;
257
+ }
258
+ }
0 commit comments