diff --git a/frontend/src/components/Chat.test.tsx b/frontend/src/components/Chat.test.tsx
index 62ca5ba..d36ea54 100644
--- a/frontend/src/components/Chat.test.tsx
+++ b/frontend/src/components/Chat.test.tsx
@@ -1,4 +1,10 @@
-import { act, render, screen, waitFor } from "@testing-library/react";
+import {
+ act,
+ fireEvent,
+ render,
+ screen,
+ waitFor,
+} from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { api } from "../api/client";
@@ -261,3 +267,46 @@ describe("Chat two-column layout", () => {
});
});
});
+
+describe("Chat input Shift+Enter behavior", () => {
+ beforeEach(() => {
+ capturedWsHandlers = null;
+ setupMocks();
+ });
+
+ it("renders a textarea element for the chat input (AC3)", async () => {
+ render();
+ const input = screen.getByPlaceholderText("Send a message...");
+ expect(input.tagName.toLowerCase()).toBe("textarea");
+ });
+
+ it("sends message on Enter key press without Shift (AC2)", async () => {
+ render();
+ const input = screen.getByPlaceholderText("Send a message...");
+
+ await act(async () => {
+ fireEvent.change(input, { target: { value: "Hello" } });
+ });
+ await act(async () => {
+ fireEvent.keyDown(input, { key: "Enter", shiftKey: false });
+ });
+
+ await waitFor(() => {
+ expect((input as HTMLTextAreaElement).value).toBe("");
+ });
+ });
+
+ it("does not send message on Shift+Enter (AC1)", async () => {
+ render();
+ const input = screen.getByPlaceholderText("Send a message...");
+
+ await act(async () => {
+ fireEvent.change(input, { target: { value: "Hello" } });
+ });
+ await act(async () => {
+ fireEvent.keyDown(input, { key: "Enter", shiftKey: true });
+ });
+
+ expect((input as HTMLTextAreaElement).value).toBe("Hello");
+ });
+});
diff --git a/frontend/src/components/Chat.tsx b/frontend/src/components/Chat.tsx
index 04c64f4..5d9a6a2 100644
--- a/frontend/src/components/Chat.tsx
+++ b/frontend/src/components/Chat.tsx
@@ -44,7 +44,7 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
const wsRef = useRef(null);
const messagesEndRef = useRef(null);
- const inputRef = useRef(null);
+ const inputRef = useRef(null);
const scrollContainerRef = useRef(null);
const shouldAutoScrollRef = useRef(true);
const lastScrollTopRef = useRef(0);
@@ -652,16 +652,18 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
alignItems: "center",
}}
>
- setInput(e.target.value)}
onKeyDown={(e) => {
- if (e.key === "Enter") {
+ if (e.key === "Enter" && !e.shiftKey) {
+ e.preventDefault();
sendMessage();
}
}}
placeholder="Send a message..."
+ rows={1}
style={{
flex: 1,
padding: "14px 20px",
@@ -673,6 +675,9 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
background: "#2f2f2f",
color: "#ececec",
boxShadow: "0 2px 6px rgba(0,0,0,0.02)",
+ resize: "none",
+ overflowY: "auto",
+ fontFamily: "inherit",
}}
/>