diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/data-table.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/data-table.tsx index 2ba7a2e3131..a8471c89d3d 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/data-table.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/data-table.tsx @@ -25,6 +25,10 @@ type EditingCell = { row: number; col: number } | null * Tabular renderer for CSV and XLSX previews. Chrome (borders, padding, typography, header fill) * comes entirely from `document-table.css`, the definition shared with markdown tables in the rich * markdown editor — the only classes here are the optional edit affordances. + * + * Scrolling belongs to the caller's bounded container, which already scrolls vertically. A preview + * table is wider than its frame, so an `overflow-x` of its own would put the horizontal scrollbar + * at the foot of all {@link CSV_PREVIEW_MAX_ROWS} rows instead of at the bottom of the viewport. */ const DataTableBase = forwardRef(function DataTable( { headers, rows, editConfig }, @@ -100,7 +104,7 @@ const DataTableBase = forwardRef(function DataT editingCell?.row === row && editingCell?.col === col return ( -
+
diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/document-table.css b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/document-table.css index d8832305035..43e6809375e 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/document-table.css +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/document-table.css @@ -2,8 +2,10 @@ * Canonical table chrome for the file viewer. Both surfaces that render a table for a file — the * rich markdown editor (`.rich-markdown-prose table`) and the tabular previews CSV/XLSX render * through `DataTable` (`.document-table`) — share this one definition so a table looks the same - * whichever file it came from. Editor-only concerns (prose block margin, fixed layout for column - * resizing, cell paragraph reset) stay in rich-markdown-editor.css. + * whichever file it came from. Chrome is shared; *sizing* is not — prose fits the document width + * while a preview sizes to its data and scrolls (see the two rules below). Editor-only concerns + * (prose block margin, fixed layout for column resizing, cell paragraph reset) stay in + * rich-markdown-editor.css. */ /* `overflow-wrap` matches what `.rich-markdown-prose` sets on its own root: cells hold arbitrary @@ -15,11 +17,34 @@ .rich-markdown-prose table, .document-table table { - width: 100%; border-collapse: collapse; overflow: hidden; } +.rich-markdown-prose table { + width: 100%; +} + +/* A preview table is data, not prose. A CSV can carry dozens of columns, so sizing the table to the + frame (`width: 100%`) divides that frame between them and — with `overflow-wrap: anywhere` able to + break every column down to one character — renders each header a vertical column of letters. + `max-content` sizes columns to their values and lets the table exceed the frame, which the + caller's own scroll container then scrolls; `min-width: 100%` keeps a narrow table filling the + frame rather than hugging the left edge. */ +.document-table table { + width: max-content; + min-width: 100%; +} + +/* Bounds for a content-sized column: no column collapses to a sliver, and one long value (a URL, a + pasted paragraph) wraps at `max-width` instead of pushing every other column off-screen. 80px is + the tables grid's own `COL_WIDTH_MIN`; 320px is the capped content width used across the app. */ +.document-table th, +.document-table td { + min-width: 80px; + max-width: 320px; +} + .rich-markdown-prose th, .rich-markdown-prose td, .document-table th, diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/document-table.test.ts b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/document-table.test.ts index 0fb8336c705..fda1bbb36da 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/document-table.test.ts +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/document-table.test.ts @@ -115,6 +115,28 @@ describe('document-table chrome is shared with markdown tables', () => { expect(getComputedStyle(preview.root).getPropertyValue('overflow-wrap')).toBe(wrap) }) + it('the preview table sizes to its content while the prose table fits the frame', () => { + const prose = mountTable('rich-markdown-prose') + const preview = mountTable('document-table') + + const proseTable = prose.root.querySelector('table') + const previewTable = preview.root.querySelector('table') + if (!proseTable || !previewTable) throw new Error('tables not found') + + expect(getComputedStyle(proseTable).getPropertyValue('width')).toBe('100%') + expect(getComputedStyle(previewTable).getPropertyValue('width')).toBe('max-content') + expect(getComputedStyle(previewTable).getPropertyValue('min-width')).toBe('100%') + }) + + it('a preview column is bounded so no value collapses or monopolises the row', () => { + const { th, td } = mountTable('document-table') + + for (const cell of [th, td]) { + expect(getComputedStyle(cell).getPropertyValue('min-width')).toBe('80px') + expect(getComputedStyle(cell).getPropertyValue('max-width')).toBe('320px') + } + }) + it('the resolved values are the markdown editor values, not jsdom defaults', () => { const { th, td } = mountTable('document-table')