diff --git a/apps/desktop/src/components/editor/AiAssistant.vue b/apps/desktop/src/components/editor/AiAssistant.vue index 134b02214f..60c68abfed 100644 --- a/apps/desktop/src/components/editor/AiAssistant.vue +++ b/apps/desktop/src/components/editor/AiAssistant.vue @@ -3015,6 +3015,37 @@ async function openExternalUrl(url: string) { border-radius: 0.375rem; border: 1px solid var(--border); } +/* WebKit/Chromium-only styling. Do NOT set scrollbar-width/scrollbar-color here: + per CSS Scrollbars spec, a non-auto scrollbar-width makes engines ignore the + ::-webkit-scrollbar* rules below (both Tauri webviews support them). */ +.ai-markdown :deep(.ai-markdown-table-wrap::-webkit-scrollbar) { + width: 6px; + height: 6px; +} +.ai-markdown :deep(.ai-markdown-table-wrap::-webkit-scrollbar-track) { + background: transparent; +} +.ai-markdown :deep(.ai-markdown-table-wrap::-webkit-scrollbar-thumb) { + border: 1px solid transparent; + border-radius: 999px; + background: rgba(82, 82, 82, 0.28); + background: color-mix(in oklch, var(--foreground) 28%, transparent); + background-clip: padding-box; +} +.ai-markdown :deep(.ai-markdown-table-wrap:hover::-webkit-scrollbar-thumb) { + border: 0; + background: rgba(82, 82, 82, 0.45); + background: color-mix(in oklch, var(--foreground) 45%, transparent); +} +html.dbx-legacy-webview.dark .ai-markdown :deep(.ai-markdown-table-wrap::-webkit-scrollbar-thumb) { + background: rgba(212, 212, 216, 0.28); +} +html.dbx-legacy-webview.dark .ai-markdown :deep(.ai-markdown-table-wrap:hover::-webkit-scrollbar-thumb) { + background: rgba(212, 212, 216, 0.45); +} +.ai-markdown :deep(.ai-markdown-table-wrap::-webkit-scrollbar-corner) { + background: transparent; +} .ai-markdown :deep(.ai-markdown-table-wrap table) { border: none; margin: 0; diff --git a/apps/desktop/src/styles/__tests__/legacyWebviewFallback.spec.ts b/apps/desktop/src/styles/__tests__/legacyWebviewFallback.spec.ts index 82878c1e71..0e6aa45c81 100644 --- a/apps/desktop/src/styles/__tests__/legacyWebviewFallback.spec.ts +++ b/apps/desktop/src/styles/__tests__/legacyWebviewFallback.spec.ts @@ -14,6 +14,7 @@ const tunnelProfileManagerSource = readFileSync(new URL("../../components/connec const changelogPanelSource = readFileSync(new URL("../../components/settings/ChangelogPanel.vue", import.meta.url), "utf8"); const editorSettingsDialogSource = readFileSync(new URL("../../components/editor/EditorSettingsDialog.vue", import.meta.url), "utf8"); const switchSource = readFileSync(new URL("../../components/ui/switch/Switch.vue", import.meta.url), "utf8"); +const aiAssistantSource = readFileSync(new URL("../../components/editor/AiAssistant.vue", import.meta.url), "utf8"); const desktopIndexSource = readFileSync(new URL("../../../index.html", import.meta.url), "utf8"); const connectionDialogLegacyCss = readFileSync(new URL("../../../public/connection-dialog-legacy.css", import.meta.url), "utf8"); const legacyWebViewSource = readFileSync(new URL("../../lib/ui/legacyWebView.ts", import.meta.url), "utf8"); @@ -141,6 +142,24 @@ describe("legacy WebView CSS fallbacks", () => { expect(connectionTreeSource).toContain("background: rgba(212, 212, 216, 0.42);"); }); + it("keeps AI table scrollbars visible without OKLCH color mixing", () => { + const thumbStart = aiAssistantSource.indexOf(".ai-markdown :deep(.ai-markdown-table-wrap::-webkit-scrollbar-thumb) {"); + const hoverStart = aiAssistantSource.indexOf(".ai-markdown :deep(.ai-markdown-table-wrap:hover::-webkit-scrollbar-thumb) {"); + const legacyStart = aiAssistantSource.indexOf("html.dbx-legacy-webview.dark .ai-markdown", hoverStart); + const thumb = aiAssistantSource.slice(thumbStart, hoverStart); + const hover = aiAssistantSource.slice(hoverStart, legacyStart); + + expect(thumbStart).toBeGreaterThan(-1); + expect(hoverStart).toBeGreaterThan(thumbStart); + expect(legacyStart).toBeGreaterThan(hoverStart); + expect(thumb.indexOf("background: rgba(82, 82, 82, 0.28);")).toBeGreaterThan(-1); + expect(thumb.indexOf("background: rgba(82, 82, 82, 0.28);")).toBeLessThan(thumb.indexOf("background: color-mix(in oklch, var(--foreground) 28%, transparent);")); + expect(hover.indexOf("background: rgba(82, 82, 82, 0.45);")).toBeGreaterThan(-1); + expect(hover.indexOf("background: rgba(82, 82, 82, 0.45);")).toBeLessThan(hover.indexOf("background: color-mix(in oklch, var(--foreground) 45%, transparent);")); + expect(aiAssistantSource).toContain("background: rgba(212, 212, 216, 0.28);"); + expect(aiAssistantSource).toContain("background: rgba(212, 212, 216, 0.45);"); + }); + it("keeps selected tiles readable in WebViews without color-mix support", () => { const fallbackStart = globalsCss.indexOf("@supports not (background-color: color-mix(in srgb, black 10%, transparent))"); const choiceFallback = globalsCss.indexOf(".dbx-choice-selected", fallbackStart);