story-kit: merge 82_story_shift_enter_inserts_newline_instead_of_sending_in_chat_input
This commit is contained in:
@@ -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 { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import { api } from "../api/client";
|
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(<Chat projectPath="/tmp/project" onCloseProject={vi.fn()} />);
|
||||||
|
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(<Chat projectPath="/tmp/project" onCloseProject={vi.fn()} />);
|
||||||
|
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(<Chat projectPath="/tmp/project" onCloseProject={vi.fn()} />);
|
||||||
|
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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
|
|||||||
|
|
||||||
const wsRef = useRef<ChatWebSocket | null>(null);
|
const wsRef = useRef<ChatWebSocket | null>(null);
|
||||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLTextAreaElement>(null);
|
||||||
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||||
const shouldAutoScrollRef = useRef(true);
|
const shouldAutoScrollRef = useRef(true);
|
||||||
const lastScrollTopRef = useRef(0);
|
const lastScrollTopRef = useRef(0);
|
||||||
@@ -652,16 +652,18 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<input
|
<textarea
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={(e) => setInput(e.target.value)}
|
onChange={(e) => setInput(e.target.value)}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter" && !e.shiftKey) {
|
||||||
|
e.preventDefault();
|
||||||
sendMessage();
|
sendMessage();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
placeholder="Send a message..."
|
placeholder="Send a message..."
|
||||||
|
rows={1}
|
||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: "14px 20px",
|
padding: "14px 20px",
|
||||||
@@ -673,6 +675,9 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
|
|||||||
background: "#2f2f2f",
|
background: "#2f2f2f",
|
||||||
color: "#ececec",
|
color: "#ececec",
|
||||||
boxShadow: "0 2px 6px rgba(0,0,0,0.02)",
|
boxShadow: "0 2px 6px rgba(0,0,0,0.02)",
|
||||||
|
resize: "none",
|
||||||
|
overflowY: "auto",
|
||||||
|
fontFamily: "inherit",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user