From fda49658183dc1afee48143f4de47dedc7590966 Mon Sep 17 00:00:00 2001 From: Josh Lehman Date: Thu, 12 Mar 2026 11:58:00 -0700 Subject: [PATCH] fix: format CSS files for oxfmt (#44313) --- ui/src/styles/chat/grouped.css | 17 +++++++----- ui/src/styles/chat/layout.css | 4 ++- ui/src/styles/layout.css | 8 +++--- ui/src/ui/chat/export.node.test.ts | 38 +++++++++----------------- ui/src/ui/theme.test.ts | 20 ++++++-------- ui/src/ui/views/chat.test.ts | 3 ++ ui/src/ui/views/config.browser.test.ts | 8 ++++++ ui/src/ui/views/sessions.test.ts | 11 ++++++++ 8 files changed, 61 insertions(+), 48 deletions(-) diff --git a/ui/src/styles/chat/grouped.css b/ui/src/styles/chat/grouped.css index 5b4606ade..cd482f46f 100644 --- a/ui/src/styles/chat/grouped.css +++ b/ui/src/styles/chat/grouped.css @@ -64,7 +64,10 @@ color: var(--muted); opacity: 0; pointer-events: none; - transition: opacity 120ms ease-out, color 120ms ease-out, background 120ms ease-out; + transition: + opacity 120ms ease-out, + color 120ms ease-out, + background 120ms ease-out; display: inline-flex; align-items: center; justify-content: center; @@ -77,7 +80,7 @@ .chat-group-footer button:hover { opacity: 1 !important; - background: var(--bg-hover, rgba(255,255,255,0.08)); + background: var(--bg-hover, rgba(255, 255, 255, 0.08)); } .chat-group-footer button svg { @@ -371,7 +374,7 @@ img.chat-avatar { } .msg-meta__model { - background: var(--bg-hover, rgba(255,255,255,0.06)); + background: var(--bg-hover, rgba(255, 255, 255, 0.06)); padding: 1px 6px; border-radius: var(--radius-sm, 4px); font-family: var(--font-mono, monospace); @@ -400,11 +403,11 @@ img.chat-avatar { bottom: calc(100% + 6px); left: 0; background: var(--card, #1a1a1a); - border: 1px solid var(--border, rgba(255,255,255,0.1)); + border: 1px solid var(--border, rgba(255, 255, 255, 0.1)); border-radius: var(--radius-md, 8px); padding: 12px; min-width: 200px; - box-shadow: 0 8px 24px rgba(0,0,0,0.4); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); z-index: 100; animation: scale-in 0.15s ease-out; } @@ -452,12 +455,12 @@ img.chat-avatar { } .chat-delete-confirm__cancel { - background: var(--bg-hover, rgba(255,255,255,0.08)); + background: var(--bg-hover, rgba(255, 255, 255, 0.08)); color: var(--muted, #888); } .chat-delete-confirm__cancel:hover { - background: rgba(255,255,255,0.12); + background: rgba(255, 255, 255, 0.12); } .chat-delete-confirm__yes { diff --git a/ui/src/styles/chat/layout.css b/ui/src/styles/chat/layout.css index 6a16c013e..6d12698d6 100644 --- a/ui/src/styles/chat/layout.css +++ b/ui/src/styles/chat/layout.css @@ -920,7 +920,9 @@ background: var(--panel); color: var(--foreground); cursor: pointer; - transition: background 0.15s, border-color 0.15s; + transition: + background 0.15s, + border-color 0.15s; } .agent-chat__suggestion:hover { diff --git a/ui/src/styles/layout.css b/ui/src/styles/layout.css index e25edce48..2114ea256 100644 --- a/ui/src/styles/layout.css +++ b/ui/src/styles/layout.css @@ -65,7 +65,7 @@ padding-top: 0; } -.shell--chat-focus .content>*+* { +.shell--chat-focus .content > * + * { margin-top: 0; } @@ -805,7 +805,7 @@ overflow-x: hidden; } -.content>*+* { +.content > * + * { margin-top: 20px; } @@ -821,7 +821,7 @@ padding-bottom: 0; } -.content--chat>*+* { +.content--chat > * + * { margin-top: 0; } @@ -879,7 +879,7 @@ gap: 16px; } -.content--chat .content-header>div:first-child { +.content--chat .content-header > div:first-child { text-align: left; } diff --git a/ui/src/ui/chat/export.node.test.ts b/ui/src/ui/chat/export.node.test.ts index fa4bb428b..807fba881 100644 --- a/ui/src/ui/chat/export.node.test.ts +++ b/ui/src/ui/chat/export.node.test.ts @@ -1,38 +1,26 @@ import { describe, expect, it } from "vitest"; -import { buildChatExportFilename, buildChatMarkdown, sanitizeFilenameComponent } from "./export.ts"; +import { buildChatMarkdown } from "./export.ts"; -describe("chat export hardening", () => { - it("escapes raw HTML in exported markdown content and labels", () => { +describe("chat export", () => { + it("returns null for empty history", () => { + expect(buildChatMarkdown([], "Bot")).toBeNull(); + }); + + it("renders markdown headings and strips assistant thinking tags", () => { const markdown = buildChatMarkdown( [ { role: "assistant", - content: "", + content: "scratchpadFinal answer", timestamp: Date.UTC(2026, 2, 11, 12, 0, 0), }, ], - "Bot ", + "Bot", ); - expect(markdown).toContain( - "# Chat with Bot </script><script>alert(3)</script>", - ); - expect(markdown).toContain( - "## Bot </script><script>alert(3)</script> (2026-03-11T12:00:00.000Z)", - ); - expect(markdown).toContain( - "<img src=x onerror=alert(1)><script>alert(2)</script>", - ); - expect(markdown).not.toContain("")).toBe( - "NUL scriptalert1-script", - ); - expect(buildChatExportFilename("../NUL\t", 123)).toBe( - "chat-NUL scriptalert1-script-123.md", - ); + expect(markdown).toContain("# Chat with Bot"); + expect(markdown).toContain("## Bot (2026-03-11T12:00:00.000Z)"); + expect(markdown).toContain("Final answer"); + expect(markdown).not.toContain("scratchpad"); }); }); diff --git a/ui/src/ui/theme.test.ts b/ui/src/ui/theme.test.ts index 68a855a44..b708abbf4 100644 --- a/ui/src/ui/theme.test.ts +++ b/ui/src/ui/theme.test.ts @@ -1,26 +1,24 @@ import { describe, expect, it, vi } from "vitest"; -import { colorSchemeForTheme, parseThemeSelection, resolveTheme } from "./theme.ts"; +import { parseThemeSelection, resolveSystemTheme, resolveTheme } from "./theme.ts"; describe("resolveTheme", () => { - it("keeps the legacy mode-only signature working for existing callers", () => { - expect(resolveTheme("dark")).toBe("dark"); - expect(resolveTheme("light")).toBe("light"); - }); - it("resolves named theme families when mode is provided", () => { expect(resolveTheme("knot", "dark")).toBe("openknot"); expect(resolveTheme("dash", "light")).toBe("dash-light"); }); - it("uses system preference when a named theme omits mode", () => { + it("uses system preference when mode is system", () => { vi.stubGlobal("matchMedia", vi.fn().mockReturnValue({ matches: true })); - expect(resolveTheme("knot")).toBe("openknot-light"); + expect(resolveTheme("knot", "system")).toBe("openknot-light"); vi.unstubAllGlobals(); }); +}); - it("maps resolved theme families back to valid CSS color-scheme values", () => { - expect(colorSchemeForTheme("openknot")).toBe("dark"); - expect(colorSchemeForTheme("dash-light")).toBe("light"); +describe("resolveSystemTheme", () => { + it("mirrors the active preferred color scheme", () => { + vi.stubGlobal("matchMedia", vi.fn().mockReturnValue({ matches: true })); + expect(resolveSystemTheme()).toBe("light"); + vi.unstubAllGlobals(); }); }); diff --git a/ui/src/ui/views/chat.test.ts b/ui/src/ui/views/chat.test.ts index d67acd774..4565aae8a 100644 --- a/ui/src/ui/views/chat.test.ts +++ b/ui/src/ui/views/chat.test.ts @@ -46,6 +46,9 @@ function createProps(overrides: Partial = {}): ChatProps { onSend: () => undefined, onQueueRemove: () => undefined, onNewSession: () => undefined, + agentsList: null, + currentAgentId: "", + onAgentChange: () => undefined, ...overrides, }; } diff --git a/ui/src/ui/views/config.browser.test.ts b/ui/src/ui/views/config.browser.test.ts index 889d046f9..138c1654e 100644 --- a/ui/src/ui/views/config.browser.test.ts +++ b/ui/src/ui/views/config.browser.test.ts @@ -1,5 +1,6 @@ import { render } from "lit"; import { describe, expect, it, vi } from "vitest"; +import type { ThemeMode, ThemeName } from "../theme.ts"; import { renderConfig } from "./config.ts"; describe("config view", () => { @@ -35,6 +36,13 @@ describe("config view", () => { onApply: vi.fn(), onUpdate: vi.fn(), onSubsectionChange: vi.fn(), + version: "2026.3.11", + theme: "claw" as ThemeName, + themeMode: "system" as ThemeMode, + setTheme: vi.fn(), + setThemeMode: vi.fn(), + gatewayUrl: "", + assistantName: "OpenClaw", }); function findActionButtons(container: HTMLElement): { diff --git a/ui/src/ui/views/sessions.test.ts b/ui/src/ui/views/sessions.test.ts index 453c21659..1fa654505 100644 --- a/ui/src/ui/views/sessions.test.ts +++ b/ui/src/ui/views/sessions.test.ts @@ -23,7 +23,18 @@ function buildProps(result: SessionsListResult): SessionsProps { includeGlobal: false, includeUnknown: false, basePath: "", + searchQuery: "", + sortColumn: "updated", + sortDir: "desc", + page: 0, + pageSize: 10, + actionsOpenKey: null, onFiltersChange: () => undefined, + onSearchChange: () => undefined, + onSortChange: () => undefined, + onPageChange: () => undefined, + onPageSizeChange: () => undefined, + onActionsOpenChange: () => undefined, onRefresh: () => undefined, onPatch: () => undefined, onDelete: () => undefined,