tahamajs/IE / Projects /front /src /components /threads /ThreadReplyInput.tsx
tahamajs's picture
download
raw
2.87 kB
// src/components/threads/ThreadReplyInput.tsx
import { useRef, useEffect } from "react";
import { Send, Sparkles, Loader2, Paperclip } from "lucide-react";
interface ThreadReplyInputProps {
value: string;
onChange: (val: string) => void;
onSend: () => void;
sending: boolean;
onAiAsk: () => void;
placeholder?: string;
disabled?: boolean;
}
export function ThreadReplyInput({
value,
onChange,
onSend,
sending,
onAiAsk,
placeholder = "Reply in thread...",
disabled = false,
}: ThreadReplyInputProps) {
const textareaRef = useRef<HTMLTextAreaElement>(null);
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
onChange(e.target.value);
// Auto-resize
e.target.style.height = "auto";
e.target.style.height = `${Math.min(e.target.scrollHeight, 120)}px`;
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
onSend();
}
};
// Focus on mount
useEffect(() => {
textareaRef.current?.focus();
}, []);
return (
<div className="border-t border-gray-100 bg-white p-3 dark:border-gray-700 dark:bg-gray-800">
<div className="flex items-end gap-2">
<button
onClick={onAiAsk}
disabled={disabled || sending}
className="rounded-lg p-2 text-purple-400 transition hover:bg-purple-50 hover:text-purple-600 dark:hover:bg-purple-900/20 disabled:opacity-50"
title="Ask AI for help in this thread"
aria-label="Ask AI"
>
<Sparkles className="h-5 w-5" />
</button>
<button
disabled={disabled || sending}
className="rounded-lg p-2 text-gray-400 transition hover:bg-gray-100 hover:text-gray-600 dark:hover:bg-gray-700 disabled:opacity-50"
title="Attach file (coming soon)"
aria-label="Attach file"
>
<Paperclip className="h-5 w-5" />
</button>
<textarea
ref={textareaRef}
value={value}
onChange={handleChange}
onKeyDown={handleKeyDown}
placeholder={placeholder}
disabled={disabled || sending}
rows={1}
className="flex-1 resize-none rounded-xl bg-gray-100 px-3 py-2 text-sm text-gray-800 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-primary dark:bg-gray-700 dark:text-gray-100"
style={{ minHeight: "38px", maxHeight: "120px" }}
/>
<button
onClick={onSend}
disabled={!value.trim() || sending || disabled}
className="rounded-xl bg-primary p-2 text-white transition hover:bg-primary/90 disabled:opacity-50"
aria-label="Send reply"
>
{sending ? <Loader2 className="h-5 w-5 animate-spin" /> : <Send className="h-5 w-5" />}
</button>
</div>
</div>
);
}

Xet Storage Details

Size:
2.87 kB
·
Xet hash:
ce1e4b1924cdde173aa68c96eb06de4672a9a560138ca284c35b1a2f39fd8e9b

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