From 76f3eead4218a617f91a5acbb9c4dfe99fc9ca40 Mon Sep 17 00:00:00 2001 From: chengyongru <61816729+chengyongru@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:41:23 +0800 Subject: [PATCH] style(webui): simplify Markdown code blocks (#5002) --- webui/src/components/CodeBlock.tsx | 77 ++++++++----------- webui/src/tests/code-block.test.tsx | 23 +++++- .../src/tests/markdown-text-renderer.test.tsx | 3 +- 3 files changed, 51 insertions(+), 52 deletions(-) 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);
});