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