diff --git a/webui/src/components/CodeBlock.tsx b/webui/src/components/CodeBlock.tsx index 2254eedd..e1e78076 100644 --- a/webui/src/components/CodeBlock.tsx +++ b/webui/src/components/CodeBlock.tsx @@ -40,8 +40,6 @@ const CODE_FONT_STACK = [ ].join(", "); const ANSI_LANGUAGES = new Set(["ansi", "ansi-output"]); -const CODE_SURFACE_LIGHT = "#f4f4f5"; -const CODE_SURFACE_DARK = "#27272a"; const LazyHighlightedCode = lazy(async () => { const [ @@ -81,15 +79,11 @@ const LazyHighlightedCode = lazy(async () => { language={language || "text"} style={transparentTheme} customStyle={{ - background: chrome === "none" - ? "transparent" - : isDark - ? CODE_SURFACE_DARK - : CODE_SURFACE_LIGHT, + background: "transparent", margin: 0, - padding: chrome === "none" ? "0.75rem 1rem" : "1rem", + padding: chrome === "none" ? "0.75rem 1rem" : "1rem 3.5rem 1rem 1.25rem", fontFamily: CODE_FONT_STACK, - fontSize: chrome === "none" ? "13px" : "0.875rem", + fontSize: "13px", lineHeight: chrome === "none" ? 1.55 : 1.6, tabSize: 2, }} @@ -148,10 +142,11 @@ function CodeTextBlock({ return (
 {
     void copyTextToClipboard(renderAnsi ? stripAnsi(code) : code).then((ok) => {
@@ -205,44 +201,12 @@ export function CodeBlock({
   return (
     
- {hasChrome ? ( -
- - {language || t("code.fallbackLanguage")} - - -
- ) : null} {renderAnsi ? ( )} + {hasChrome ? ( + + ) : null}
); } diff --git a/webui/src/tests/code-block.test.tsx b/webui/src/tests/code-block.test.tsx index a48440a8..65c19a13 100644 --- a/webui/src/tests/code-block.test.tsx +++ b/webui/src/tests/code-block.test.tsx @@ -48,8 +48,20 @@ describe("CodeBlock", () => { expect(screen.queryByTestId("highlighted-code")).not.toBeInTheDocument(); expect(screen.getByText("const value = 1;")).toBeInTheDocument(); - expect(screen.getByText("ts")).toBeInTheDocument(); + expect(screen.queryByText("ts")).not.toBeInTheDocument(); expect(screen.getByTestId("plain-code-fallback")).toHaveClass("text-foreground/90"); + expect(screen.getByTestId("plain-code-fallback")).toHaveClass("bg-transparent"); + expect(screen.getByTestId("plain-code-fallback")).toHaveClass("py-4", "pl-5", "pr-14"); + + const container = screen.getByTestId("plain-code-fallback").closest(".not-prose"); + expect(container).toHaveClass("relative", "rounded-[18px]", "bg-secondary/70"); + expect(container).not.toHaveClass("border"); + expect(container).toHaveAttribute("data-language", "ts"); + + const copyButton = screen.getByRole("button", { name: "Copy code" }); + expect(copyButton.parentElement).toBe(container); + expect(copyButton).toHaveClass("absolute", "h-8", "w-8", "rounded-full"); + expect(copyButton).toHaveTextContent(""); }); it("can render without chat-style chrome for file previews", () => { @@ -115,8 +127,11 @@ describe("CodeBlock", () => { expect(screen.queryByTestId("highlighted-code")).not.toBeInTheDocument(); expect(screen.getByTestId("ansi-code")).toBeInTheDocument(); - expect(screen.getByTestId("ansi-code").closest(".not-prose")).toBeTruthy(); - expect(screen.getByText("ansi")).toBeInTheDocument(); + expect(screen.getByTestId("ansi-code").closest(".not-prose")).toHaveAttribute( + "data-language", + "ansi", + ); + expect(screen.queryByText("ansi")).not.toBeInTheDocument(); expect(screen.getByText("PASS")).toHaveStyle({ color: "#0dbc79" }); expect(screen.getByText("")).toBeInTheDocument(); expect(document.querySelector("script")).toBeNull(); @@ -183,7 +198,7 @@ describe("CodeBlock", () => { await user.click(screen.getByRole("button", { name: /copy/i })); await waitFor(() => expect(execCommand).toHaveBeenCalledWith("copy")); - expect(screen.getByText("Copied")).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Copied" })).toBeInTheDocument(); } finally { Reflect.deleteProperty(navigator, "clipboard"); Reflect.deleteProperty(document, "execCommand"); diff --git a/webui/src/tests/markdown-text-renderer.test.tsx b/webui/src/tests/markdown-text-renderer.test.tsx index 9f54159e..ba12c4ec 100644 --- a/webui/src/tests/markdown-text-renderer.test.tsx +++ b/webui/src/tests/markdown-text-renderer.test.tsx @@ -163,7 +163,8 @@ describe("MarkdownTextRenderer", () => { ); expect(screen.getByText("code without language")).toBeInTheDocument(); - expect(screen.getByText("text")).toBeInTheDocument(); + expect(screen.queryByText("text")).not.toBeInTheDocument(); + expect(container.querySelector(".not-prose")).toHaveAttribute("data-language", "text"); expect(container.querySelectorAll("pre")).toHaveLength(1); });