From fd6c12950ae2450ed3e16b678d2fe933492aa718 Mon Sep 17 00:00:00 2001 From: Luke Parker <10430890+Hona@users.noreply.github.com> Date: Mon, 19 Oct 2026 18:05:17 +1000 Subject: [PATCH] feat(session-ui): style markdown tables like generated UI tables (#57002) --- .../session-ui/src/components/markdown.css | 36 +++++++++++++------ .../src/components/markdown.stories.tsx | 19 ++++++++++ .../session-ui/src/components/markdown.tsx | 11 ++++++ 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/packages/session-ui/src/components/markdown.css b/packages/session-ui/src/components/markdown.css index f7e008d4d6c..4ab9383a5d7 100644 --- a/packages/session-ui/src/components/markdown.css +++ b/packages/session-ui/src/components/markdown.css @@ -382,29 +382,43 @@ text-underline-offset: 2px; } - /* Tables */ + /* Tables: same frame, header and rows as generated UI tables (genui.css) */ + [data-component="markdown-table"] { + margin: 16px 0; + overflow-x: auto; + border-radius: 6px; + box-shadow: inset 0 0 0 0.5px var(--v2-border-border-muted); + } + table { width: 100%; - border-collapse: collapse; - margin: 16px 0; - font-size: var(--font-size-base); - display: block; - overflow-x: auto; + border-collapse: separate; + border-spacing: 0; + color: var(--v2-text-text-base); + font-size: 13px; + font-variant-numeric: tabular-nums; + font-weight: 440; + line-height: var(--line-height-compact); + letter-spacing: -0.04px; } th, td { - /* Minimal borders for structure, matching TUI "lines" roughly but keeping it web-clean */ + padding: 8px 12px; border-bottom: 0.5px solid var(--v2-border-border-muted); - padding: 12px; text-align: start; vertical-align: top; } th { - color: var(--v2-text-text-base); - font-weight: var(--font-weight-medium); - border-bottom: 0.5px solid var(--v2-border-border-base); + border-bottom-color: var(--v2-border-border-base); + background: var(--v2-background-bg-layer-01); + color: var(--v2-text-text-muted); + font-weight: 530; + } + + tr:last-child td { + border-bottom: 0; } /* Images */ diff --git a/packages/session-ui/src/components/markdown.stories.tsx b/packages/session-ui/src/components/markdown.stories.tsx index ecdcef0181d..0d8a145decc 100644 --- a/packages/session-ui/src/components/markdown.stories.tsx +++ b/packages/session-ui/src/components/markdown.stories.tsx @@ -34,6 +34,25 @@ export const CompactResult = { ), } +export const Table = { + render: () => ( +
+ +
+ ), +} + const streamed = "Streaming Markdown now keeps existing elements alive while each newly arriving word fades into the response." diff --git a/packages/session-ui/src/components/markdown.tsx b/packages/session-ui/src/components/markdown.tsx index 1ee3359236a..da9a6fd2314 100644 --- a/packages/session-ui/src/components/markdown.tsx +++ b/packages/session-ui/src/components/markdown.tsx @@ -326,6 +326,16 @@ function markCodeLinks(root: HTMLDivElement) { } } +// Tables scroll inside a rounded frame, matching generated UI tables. +function wrapTables(root: HTMLDivElement) { + root.querySelectorAll("table").forEach((table) => { + const wrapper = document.createElement("div") + wrapper.dataset.component = "markdown-table" + table.replaceWith(wrapper) + wrapper.appendChild(table) + }) +} + const publicFaviconHost = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/ const privateFaviconSuffix = /\.(?:alt|example|internal|invalid|local|localhost|onion|test|ts\.net)$/ @@ -916,6 +926,7 @@ function updateBlock( source.innerHTML = block.html markInlineCode(source, next, block.mode === "live", localFileExists) markCodeLinks(source) + wrapTables(source) if (sessionLinks) markSessionLinks(source) markExternalLinkFavicons(source)