From 0ff322cf43d898810a125f3ec0ab1e30421c17b8 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Sun, 5 Apr 2026 20:24:51 +0200 Subject: [PATCH] fix(web): fix line highlight full-width and visibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Switch lines from table-row to block display so highlight background spans the full container width - Use GitHub-style yellow highlight (rgba(255,235,59,0.25)) instead of subtle accent color - Fix line count (was showing 0 — use text split instead of hast tree traversal) Co-Authored-By: Claude Opus 4.6 (1M context) --- webui2/src/components/code/file-viewer.tsx | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/webui2/src/components/code/file-viewer.tsx b/webui2/src/components/code/file-viewer.tsx index 0177d3a6942e86f4e5f58f7f122ccdc5a09020dd..e3271e7b32ec6ffb13e12bf7194b22c6fdc907f4 100644 --- a/webui2/src/components/code/file-viewer.tsx +++ b/webui2/src/components/code/file-viewer.tsx @@ -2,7 +2,6 @@ // Uses Shiki codeToHast → hast-util-to-jsx-runtime for native React rendering. // Line selection syncs with the URL hash (e.g. #L12 or #L12:25). -import type { Element } from "hast"; import { toJsxRuntime } from "hast-util-to-jsx-runtime"; import { Copy } from "lucide-react"; import { useState, useEffect, useCallback, Fragment, type ReactNode } from "react"; @@ -225,13 +224,7 @@ export function FileViewer({ blob }: FileViewerProps) { }); const node = toJsxRuntime(hast, { Fragment, jsx, jsxs }); - - // Count lines from the hast tree (number of .line spans in ) - const pre = hast.children[0] as Element; - const code = pre.children[0] as Element; - const lineCount = code.children.filter( - (c) => c.type === "element" && (c.properties?.className as string[] | undefined)?.includes("line"), - ).length; + const lineCount = blob.text!.split("\n").length; setHighlighted({ node, lineCount }); })(); @@ -299,7 +292,7 @@ function CodeBlock({ selectedRange, onLineClick, children }: CodeBlockProps) { selectors.push(`.code-lines code > .line:nth-child(${i})`); } return ( - + ); })(); @@ -322,11 +315,9 @@ function CodeBlock({ selectedRange, onLineClick, children }: CodeBlockProps) { className={cn( "[&_.shiki]:!bg-transparent", "[&_pre]:!m-0 [&_pre]:!p-0", - // Each .line is a table-row with line number + code "[&_code]:block [&_code]:py-2", - "[&_code>.line]:table-row", - "[&_code>.line::before]:table-cell [&_code>.line::before]:w-12 [&_code>.line::before]:pr-4 [&_code>.line::before]:pl-4 [&_code>.line::before]:text-right [&_code>.line::before]:text-muted-foreground/50 [&_code>.line::before]:select-none [&_code>.line::before]:cursor-pointer [&_code>.line::before]:content-[attr(data-line-number)]", - "[&_code>.line]:pr-4", + "[&_code>.line]:block [&_code>.line]:min-w-full [&_code>.line]:pr-4", + "[&_code>.line::before]:inline-block [&_code>.line::before]:w-12 [&_code>.line::before]:mr-4 [&_code>.line::before]:text-right [&_code>.line::before]:text-muted-foreground/50 [&_code>.line::before]:select-none [&_code>.line::before]:cursor-pointer [&_code>.line::before]:content-[attr(data-line-number)]", )} > {children}