127 lines
4.5 KiB
TypeScript
127 lines
4.5 KiB
TypeScript
import { useState, useRef, useEffect, type KeyboardEvent } from "react";
|
|
import { Send, Square } from "lucide-react";
|
|
import { motion } from "motion/react";
|
|
|
|
interface ChatInputBarProps {
|
|
onSendMessage: (message: string) => void;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
export function ChatInputBar({ onSendMessage, disabled = false }: ChatInputBarProps) {
|
|
const [inputText, setInputText] = useState("");
|
|
const inputRef = useRef<HTMLTextAreaElement>(null);
|
|
|
|
const canSend = inputText.trim().length > 0 && !disabled;
|
|
|
|
const handleSend = () => {
|
|
if (!canSend) return;
|
|
onSendMessage(inputText.trim());
|
|
setInputText("");
|
|
|
|
// Reset height after send and refocus
|
|
setTimeout(() => {
|
|
if (inputRef.current) {
|
|
inputRef.current.style.height = "24px";
|
|
inputRef.current.focus();
|
|
}
|
|
}, 0);
|
|
};
|
|
|
|
const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {
|
|
if (e.key !== "Enter") {
|
|
return;
|
|
}
|
|
// Keep Enter behavior as newline (same as Shift+Enter).
|
|
// Sending is intentionally limited to the send button.
|
|
};
|
|
|
|
// Auto-resize textarea based on content
|
|
useEffect(() => {
|
|
if (inputRef.current) {
|
|
inputRef.current.style.height = "auto";
|
|
const scrollHeight = inputRef.current.scrollHeight;
|
|
const maxHeight = 96; // max-h-24 = 6rem = 96px
|
|
inputRef.current.style.height = `${Math.min(scrollHeight, maxHeight)}px`;
|
|
}
|
|
}, [inputText]);
|
|
|
|
return (
|
|
<div className="px-3">
|
|
<div
|
|
className="flex min-h-[62px] items-center gap-2 rounded-[32px] p-2"
|
|
style={{
|
|
backgroundImage:
|
|
"linear-gradient(180deg, #2E1B3D 0%, #23183E 100%), linear-gradient(120deg, #7c3aed 0%, #f97316 58%, #facc15 100%)",
|
|
backgroundOrigin: "border-box",
|
|
backgroundClip: "padding-box, border-box",
|
|
border: "0.5px solid transparent",
|
|
boxShadow:
|
|
"0 -7px 20px rgba(7, 0, 18, 0.5), 0 6px 14px rgba(5, 2, 12, 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 2px 5px rgba(255, 222, 255, 0.09), inset 0 -2px 0 rgba(12, 7, 27, 0.72), inset 0 -8px 14px rgba(8, 4, 18, 0.34), inset 0 0 0 1px rgba(255, 255, 255, 0.045), inset 0 0 0 2px rgba(17, 10, 35, 0.32)",
|
|
backdropFilter: "blur(14px)",
|
|
WebkitBackdropFilter: "blur(14px)",
|
|
}}
|
|
>
|
|
{/* Text Input */}
|
|
<textarea
|
|
ref={inputRef}
|
|
value={inputText}
|
|
onChange={(e) => setInputText(e.target.value)}
|
|
onKeyDown={handleKeyDown}
|
|
placeholder="پیام خود را بنویسید..."
|
|
rows={1}
|
|
dir="rtl"
|
|
disabled={disabled}
|
|
aria-label="پیام خود را بنویسید"
|
|
className="chat-input-textarea block flex-1 resize-none bg-transparent py-0 text-right text-white outline-none placeholder:text-[rgba(207,168,212,0.7)] disabled:opacity-50"
|
|
style={{
|
|
fontFamily: "Alibaba, sans-serif",
|
|
textAlign: "right",
|
|
minHeight: "24px",
|
|
maxHeight: "96px",
|
|
lineHeight: "24px",
|
|
overflow: "hidden",
|
|
padding: 0,
|
|
fontSize: "16px", // حداقل 16px برای جلوگیری از zoom در iOS Safari
|
|
}}
|
|
/>
|
|
|
|
{/* Send Button */}
|
|
<motion.button
|
|
type="button"
|
|
whileTap={{ scale: 0.92 }}
|
|
onClick={handleSend}
|
|
disabled={!canSend}
|
|
aria-label="ارسال پیام"
|
|
className="flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full"
|
|
style={{
|
|
background: canSend
|
|
? "linear-gradient(145deg, #F06EA8 0%, #C9579C 52%, #8A4FCF 100%)"
|
|
: "linear-gradient(145deg, rgba(72, 58, 105, 0.72) 0%, rgba(42, 35, 77, 0.76) 100%)",
|
|
boxShadow: canSend
|
|
? "0 0 18px rgba(240, 110, 168, 0.42), inset 0 1px 0 rgba(255,255,255,0.22)"
|
|
: "inset 0 1px 0 rgba(255,255,255,0.12), 0 0 12px rgba(203,117,171,0.12)",
|
|
border: canSend ? "1px solid rgba(255, 189, 228, 0.5)" : "1px solid rgba(198, 111, 177, 0.22)",
|
|
}}
|
|
>
|
|
{disabled ? (
|
|
<Square className="h-4 w-4 text-[#CFA8D4]/80" />
|
|
) : (
|
|
<Send className={`h-5 w-5 ${canSend ? "text-white" : "text-[#CFA8D4]/70"}`} />
|
|
)}
|
|
</motion.button>
|
|
</div>
|
|
|
|
<style>{`
|
|
.chat-input-textarea {
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
}
|
|
|
|
.chat-input-textarea::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
`}</style>
|
|
</div>
|
|
);
|
|
}
|