From 89508405e1413e8790915e89552b41b80b1fa529 Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Sat, 11 Jul 2026 17:37:16 -0700 Subject: [PATCH] fix(ui): make resizable DataTable columns fill available width When a resizable DataTable pinned its width to table.getTotalSize(), the table became exactly the summed pixel width of its visible columns. Hiding columns via the view options menu shrank that sum below the container, so the table stopped filling its box and left an empty strip on the right Set the table to width 100% with min-width floored at the summed columns instead. The columns now stretch to fill the container and redistribute when columns are hidden, while still scrolling rather than squishing once the summed widths exceed the container. This mirrors the min-width pattern the view_logs table already uses, and fixes every resizable table built on the shared component at once --- .../shared/DataTable/DataTable.test.tsx | 49 +++++++++++++++++++ .../components/shared/DataTable/DataTable.tsx | 4 +- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test.tsx b/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test.tsx index ef0d842ad3e..7b16f24ebb6 100644 --- a/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test.tsx +++ b/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test.tsx @@ -507,6 +507,55 @@ describe("DataTable layout", () => { }); }); +describe("DataTable resizing width", () => { + const sizedColumns: ColumnDef[] = [ + { + accessorKey: "name", + header: "Name", + size: 100, + cell: ({ row }) => {row.original.name}, + }, + { + accessorKey: "email", + header: "Email", + size: 200, + cell: ({ row }) => {row.original.email}, + }, + ]; + + const tableEl = (container: HTMLElement): HTMLTableElement | null => + container.querySelector('[data-slot="table"]'); + + it("fills the container and only floors the width at the summed column pixels", () => { + const { container } = render(); + const table = tableEl(container); + // width tracks the container, not a fixed pixel sum, so leftover space is absorbed + expect(table?.style.width).toBe("100%"); + // min-width preserves the summed columns so it scrolls rather than squishing when cramped + expect(table?.style.minWidth).toBe("300px"); + }); + + it("keeps filling the container after a column is hidden", async () => { + const user = userEvent.setup(); + const { container } = render( + } + />, + ); + + await user.click(screen.getByTestId("view-options-trigger")); + await user.click(await screen.findByTestId("view-option-email")); + await waitFor(() => expect(container.querySelector('th[data-header-id="email"]')).toBeNull()); + + const table = tableEl(container); + expect(table?.style.width).toBe("100%"); + expect(table?.style.minWidth).toBe("100px"); + }); +}); + describe("DataTable misconfiguration guards", () => { it("throws when server sorting is missing required props", () => { const spy = vi.spyOn(console, "error").mockImplementation(() => {}); diff --git a/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.tsx b/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.tsx index 758ca5a597b..ee6991c6627 100644 --- a/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.tsx +++ b/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.tsx @@ -508,7 +508,9 @@ export function DataTable(props: DataTableProps { if (paginationSlot !== undefined) {