/
ChatForm.tsx
82 lines (76 loc) · 2.5 KB
/
ChatForm.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { Box, CircularProgress, Flex, Textarea, useBreakpointValue } from "@chakra-ui/react";
import { Send } from "lucide-react";
import { useTranslation } from "next-i18next";
import { forwardRef, KeyboardEvent, SyntheticEvent, useCallback, useEffect } from "react";
import TextareaAutosize from "react-textarea-autosize";
import { useFallbackRef } from "src/hooks/ui/useFallbackRef";
import { ChatConfigMobileTrigger } from "./ChatConfigMobile";
import { ChatInputIconButton } from "./ChatInputIconButton";
type ChatFormProps = {
isSending: boolean;
onSubmit: () => void;
};
// eslint-disable-next-line react/display-name
export const ChatForm = forwardRef<HTMLTextAreaElement, ChatFormProps>((props, forwardedRef) => {
const { isSending, onSubmit } = props;
const { t } = useTranslation("chat");
const handleSubmit = useCallback(
(e: SyntheticEvent) => {
e.preventDefault();
onSubmit();
},
[onSubmit]
);
const handleKeydown = useCallback(
(e: KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault(); // Prevents the addition of a new line
onSubmit();
}
},
[onSubmit]
);
const ref = useFallbackRef(forwardedRef);
const isDeskTop = useBreakpointValue({ base: false, md: true });
useEffect(() => {
if (isDeskTop) {
ref.current?.focus();
}
}, [isDeskTop, ref]);
return (
<Box as="form" maxWidth={{ base: "3xl", "2xl": "4xl" }} onSubmit={handleSubmit} className="py-2 w-full mx-auto">
<div className="relative">
<Textarea
as={TextareaAutosize}
ref={ref}
bg="gray.200"
borderRadius="md"
pe={{ base: "76px", xl: "48px" }}
rows={1}
maxRows={10}
py={{ base: 2, md: 3 }}
onKeyDown={handleKeydown}
placeholder={t("input_placeholder")}
_dark={{
bg: "whiteAlpha.100",
}}
border="0"
outline="none"
_focus={{
outline: "none !important",
boxShadow: "none",
}}
style={{ resize: "none" }}
/>
<Flex position="absolute" zIndex="10" className="ltr:right-0 rtl:left-0 top-0 h-full items-center px-4" gap="2">
<ChatConfigMobileTrigger />
{isSending ? (
<CircularProgress isIndeterminate size="20px" />
) : (
<ChatInputIconButton icon={Send} onClick={handleSubmit}></ChatInputIconButton>
)}
</Flex>
</div>
</Box>
);
});