main
tsx 97 lines 2.7 KB
Raw
1 'use client';
2
3 import * as React from 'react'
4 import Textarea from 'react-textarea-autosize'
5 import { UseChatHelpers } from 'ai/react'
6 import {
7 Tooltip,
8 TooltipContent,
9 TooltipTrigger
10 } from './tooltip'
11 import { IconArrowElbow, IconPlus } from './icons'
12 import { useRouter } from 'next/navigation'
13 import { Button, buttonVariants } from './button';
14
15 export interface PromptProps
16 extends Pick<UseChatHelpers, 'input' | 'setInput'> {
17 onSubmit: (value: string) => void
18 isLoading: boolean
19 }
20
21 export function PromptForm({
22 onSubmit,
23 input,
24 setInput,
25 isLoading
26 }: PromptProps) {
27 const { formRef, onKeyDown } = useEnterSubmit()
28 const inputRef = React.useRef<HTMLTextAreaElement>(null)
29 const router = useRouter()
30 React.useEffect(() => {
31 if (inputRef.current) {
32 inputRef.current.focus()
33 }
34 }, [])
35
36 return (
37 <form
38 onSubmit={async e => {
39 e.preventDefault()
40 if (!input?.trim()) {
41 return
42 }
43 setInput('')
44 await onSubmit(input)
45 }}
46 ref={formRef}
47 >
48 <div className="relative flex flex-col w-full px-8 overflow-hidden max-h-60 grow bg-background sm:rounded-md sm:border sm:px-12">
49 <Tooltip>
50 <TooltipTrigger asChild>
51 <button
52 onClick={e => {
53 e.preventDefault()
54 router.refresh()
55 router.push('/')
56 }}
57 className={cn(
58 buttonVariants({ size: 'sm', variant: 'outline' }),
59 'absolute left-0 top-4 size-8 rounded-full bg-background p-0 sm:left-4'
60 )}
61 >
62 <IconPlus />
63 <span className="sr-only">New Chat</span>
64 </button>
65 </TooltipTrigger>
66 <TooltipContent>New Chat</TooltipContent>
67 </Tooltip>
68 <Textarea
69 ref={inputRef}
70 tabIndex={0}
71 onKeyDown={onKeyDown}
72 rows={1}
73 value={input}
74 onChange={e => setInput(e.target.value)}
75 placeholder="Send a message."
76 spellCheck={false}
77 className="min-h-[60px] w-full resize-none bg-transparent px-4 py-[1.3rem] focus-within:outline-none sm:text-sm"
78 />
79 <div className="absolute right-0 top-4 sm:right-4">
80 <Tooltip>
81 <TooltipTrigger asChild>
82 <Button
83 type="submit"
84 size="icon"
85 disabled={isLoading || input === ''}
86 >
87 <IconArrowElbow />
88 <span className="sr-only">Send message</span>
89 </Button>
90 </TooltipTrigger>
91 <TooltipContent>Send message</TooltipContent>
92 </Tooltip>
93 </div>
94 </div>
95 </form>
96 )
97 }