From 9f469068fc9d828d0a79d30e066e152f412e5bd7 Mon Sep 17 00:00:00 2001 From: Dave Date: Wed, 25 Feb 2026 18:16:46 +0000 Subject: [PATCH] story-kit: merge 195_story_preserve_newlines_in_chat_message_submission --- frontend/src/components/MessageItem.test.tsx | 18 ++++++++++++++++++ frontend/src/components/MessageItem.tsx | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/MessageItem.test.tsx b/frontend/src/components/MessageItem.test.tsx index 036d685..c5a36d7 100644 --- a/frontend/src/components/MessageItem.test.tsx +++ b/frontend/src/components/MessageItem.test.tsx @@ -59,6 +59,24 @@ describe("MessageItem component (Story 178 AC3)", () => { expect(screen.getByText("Read(src/main.rs)")).toBeInTheDocument(); }); + it("user messages use pre-wrap whitespace to preserve newlines (Story 195)", () => { + const { container } = render( + , + ); + + // The bubble div wrapping user text must have white-space: pre-wrap + // so newlines are rendered as visual line breaks + const divs = Array.from(container.querySelectorAll("div")); + const bubble = divs.find( + (div) => + div.style.whiteSpace === "pre-wrap" && + div.textContent?.includes("First line"), + ); + expect(bubble).toBeDefined(); + }); + it("is wrapped in React.memo (has displayName or $$typeof memo)", () => { // React.memo wraps the component — verify the export is memoized // by checking that the component has a memo wrapper diff --git a/frontend/src/components/MessageItem.tsx b/frontend/src/components/MessageItem.tsx index 686cd92..8846cad 100644 --- a/frontend/src/components/MessageItem.tsx +++ b/frontend/src/components/MessageItem.tsx @@ -53,7 +53,8 @@ function MessageItemInner({ msg }: MessageItemProps) { fontFamily: msg.role === "tool" ? "monospace" : "inherit", fontSize: msg.role === "tool" ? "0.85em" : "1em", fontWeight: "500", - whiteSpace: msg.role === "tool" ? "pre-wrap" : "normal", + whiteSpace: + msg.role === "tool" || msg.role === "user" ? "pre-wrap" : "normal", lineHeight: "1.6", }} >