techprotrade's picture
download
raw
2.74 kB
import { useState, useRef, useEffect } from "react";
import { motion } from "framer-motion";
import { Send, Sparkles } from "lucide-react";
import { cn } from "@/lib/utils";
interface ChatInputProps {
onSend: (message: string) => void;
isLoading?: boolean;
placeholder?: string;
}
export const ChatInput = ({
onSend,
isLoading = false,
placeholder = "Command NEXUS...",
}: ChatInputProps) => {
const [input, setInput] = useState("");
const textareaRef = useRef<HTMLTextAreaElement>(null);
useEffect(() => {
if (textareaRef.current) {
textareaRef.current.style.height = "auto";
textareaRef.current.style.height = `${Math.min(textareaRef.current.scrollHeight, 200)}px`;
}
}, [input]);
const handleSubmit = () => {
if (!input.trim() || isLoading) return;
onSend(input.trim());
setInput("");
if (textareaRef.current) textareaRef.current.style.height = "auto";
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSubmit();
}
};
return (
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="relative">
<div className="relative bg-card border border-border rounded-xl overflow-hidden focus-within:border-primary/50 focus-within:glow-cyan transition-all duration-300">
<div className="flex items-end">
<textarea
ref={textareaRef}
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={handleKeyDown}
placeholder={placeholder}
disabled={isLoading}
rows={1}
className="flex-1 bg-transparent px-4 py-3.5 text-sm text-foreground placeholder:text-muted-foreground resize-none focus:outline-none min-h-[50px] max-h-[200px]"
/>
<div className="flex items-center gap-2 p-2">
<button
onClick={handleSubmit}
disabled={!input.trim() || isLoading}
className={cn(
"p-2.5 rounded-lg transition-all duration-300",
input.trim() && !isLoading
? "bg-gradient-cyber text-primary-foreground glow-cyan hover:glow-cyan-strong"
: "bg-secondary text-muted-foreground cursor-not-allowed"
)}
>
{isLoading ? <Sparkles size={18} className="animate-pulse" /> : <Send size={18} />}
</button>
</div>
</div>
</div>
<p className="text-center text-[10px] text-muted-foreground mt-2 font-mono tracking-wider">
NEXUS-AI • Neural Extended Universal System • ⌘K for commands
</p>
</motion.div>
);
};

Xet Storage Details

Size:
2.74 kB
·
Xet hash:
369273fae3c0aadc44727aca12e174d808f06da479919ebd79796ccb9cf28a3d

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.