diff --git a/src/components/PaginatedTablePicker.test.tsx b/src/components/PaginatedTablePicker.test.tsx index 20521ee6c..0a0269253 100644 --- a/src/components/PaginatedTablePicker.test.tsx +++ b/src/components/PaginatedTablePicker.test.tsx @@ -471,11 +471,12 @@ describe("paginated table picker contract", () => { ); expect(headerIndex).toBeGreaterThanOrEqual(0); - expect(stringWidth(lines[headerIndex + 1]!)).toBe(width); + expect(stringWidth(lines[headerIndex + 1]!)).toBe(width - 1); expect(rowLines.every((line) => line !== undefined)).toBe(true); expect(new Set(rowLines.map((line) => lines.indexOf(line!))).size).toBe(suffixes.length); - expect(rowLines.every((line) => stringWidth(line!) <= width)).toBe(true); + expect(rowLines.every((line) => stringWidth(line!) <= width - 1)).toBe(true); expect(rowLines.every((line) => /runtime_\d-[A-Za-z0-9…]+\s+\d/.test(line!))).toBe(true); + expect(rowLines.every((line) => line!.includes("2026-07-19 01:02"))).toBe(true); if (width >= 80) { expect(rowLines.every((line, index) => line!.includes(suffixes[index]!))).toBe(true); } diff --git a/src/components/ui/data-table/DataTable.test.tsx b/src/components/ui/data-table/DataTable.test.tsx index b580ff783..c214b47b0 100644 --- a/src/components/ui/data-table/DataTable.test.tsx +++ b/src/components/ui/data-table/DataTable.test.tsx @@ -3,6 +3,7 @@ import { Box } from "ink"; import { cleanup, render } from "ink-testing-library"; import stringWidth from "string-width"; import { DataTable, type DataTableColumn } from "./DataTable"; +import { TERMINAL_RIGHT_GUTTER_WIDTH } from "./columnWidths"; afterEach(cleanup); @@ -40,6 +41,16 @@ function renderTableAt(columnsWide: number) { } describe("DataTable layout", () => { + test("reserves a one-column gutter at the terminal's right edge", () => { + const terminalWidth = 60; + const divider = renderTableAt(terminalWidth) + .split("\n") + .find((line) => /^─+$/.test(line)); + + expect(divider).toBeDefined(); + expect(stringWidth(divider!)).toBe(terminalWidth - TERMINAL_RIGHT_GUTTER_WIDTH); + }); + test("keeps the selection marker and each logical row on one line at 12 columns", () => { const lines = renderTableAt(12).split("\n"); const rowLines = lines.filter( diff --git a/src/components/ui/data-table/DataTable.tsx b/src/components/ui/data-table/DataTable.tsx index fb79e962c..b33a9894f 100644 --- a/src/components/ui/data-table/DataTable.tsx +++ b/src/components/ui/data-table/DataTable.tsx @@ -9,6 +9,7 @@ import { computeColumnWidths, resolveBorderWidth, SELECTION_MARKER_WIDTH, + TERMINAL_RIGHT_GUTTER_WIDTH, } from "./columnWidths.js"; import type { ColumnSizing } from "./columnWidths.js"; @@ -200,7 +201,8 @@ export function DataTable>({ left: borderLeft, right: borderRight, }); - const computedWidths = computeColumnWidths(columns, terminalWidth, { + const tableWidth = Math.max(0, terminalWidth - TERMINAL_RIGHT_GUTTER_WIDTH); + const computedWidths = computeColumnWidths(columns, tableWidth, { selectable, borderWidth, }); diff --git a/src/components/ui/data-table/columnWidths.ts b/src/components/ui/data-table/columnWidths.ts index 8e57b7a99..830d4e083 100644 --- a/src/components/ui/data-table/columnWidths.ts +++ b/src/components/ui/data-table/columnWidths.ts @@ -1,6 +1,7 @@ export const COLUMN_GAP = 1; export const FLEX_MIN_WIDTH = 16; export const SELECTION_MARKER_WIDTH = 1; +export const TERMINAL_RIGHT_GUTTER_WIDTH = 1; export type ColumnSizing = | { flex: true; width?: never; minWidth?: never }