From 1643a78f6354c731a05f3c7b4236da3367b5c5f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 10 May 2026 21:22:32 +0200 Subject: [PATCH] fix(admin): drop whitespace-nowrap on api-tokens date cells (5th attempt) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /admin/api-tokens page has been painting a residual horizontal scrollbar for four releases despite column-hide, mobile card-list, and the admin section-strip `no-scrollbar` fixes. A fresh production probe confirmed the actual culprit: the "Last used" and "Created" ``s carry `whitespace-nowrap`, and `formatDateTime` renders strings like "05.05.2026, 21:46" (~110px) that exceed the 12% colgroup allotment (~84px on a 700px content area). `whitespace-nowrap` wins over `table-fixed`'s width contract, so the table's intrinsic width exceeds 100% and the wrapping `overflow-x-auto` paints the scrollbar. Dropping the two `whitespace-nowrap` classes lets the date+time wrap to two lines on narrow viewports. The card grows by one row but no scrollbar — and at >1024px desktop the unwrapped string already fits in the 12% allotment so the visual is unchanged for the common case. Picked option 1 of the three W1a probe found (drop nowrap, switch to formatDateShort, or hide "Created" at md): smallest two-line diff, no i18n surface impact, no information loss. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../api-token-overview-responsive.test.tsx | 28 +++++++++++++++++++ .../admin/api-token-overview-section.tsx | 17 +++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/components/admin/__tests__/api-token-overview-responsive.test.tsx b/src/components/admin/__tests__/api-token-overview-responsive.test.tsx index 6e2cb877d..b0f0c47ea 100644 --- a/src/components/admin/__tests__/api-token-overview-responsive.test.tsx +++ b/src/components/admin/__tests__/api-token-overview-responsive.test.tsx @@ -122,6 +122,34 @@ describe("ApiTokenOverviewSection — responsive", () => { expect(html).toMatch(/class="[^"]*\bp-4\b[^"]*sm:p-6/); }); + it("desktop date cells drop whitespace-nowrap (v1.4.22 C2 5th-attempt fix)", () => { + const html = render(); + // The "Last used" + "Created" ``s no longer carry + // `whitespace-nowrap`. The v1.4.19 production probe confirmed that + // class was the actual culprit behind the residual horizontal + // scrollbar at 768-1280px: a formatted date+time string + // ("05.05.2026, 21:46") overflowed its 12% colgroup allotment + // (~84px on a 700px content area) and won over `table-fixed`'s + // width contract, so the table's intrinsic width exceeded 100% + // and the wrapping `overflow-x-auto` painted a scrollbar. Letting + // the cell wrap to two lines costs one row of height but kills + // the bar. + const tableMatch = html.match(//); + expect(tableMatch).not.toBeNull(); + const tableMarkup = tableMatch![0]; + // Pick every inside the desktop table that renders one of the + // two date columns (text-right + text-xs is unique to those cells) + // and assert none carries whitespace-nowrap. + const dateCellMatches = + tableMarkup.match( + /]*\btext-right\b[^>]*\btext-xs\b[^>]*>/g, + ) ?? []; + expect(dateCellMatches.length).toBeGreaterThanOrEqual(2); + for (const cell of dateCellMatches) { + expect(cell).not.toContain("whitespace-nowrap"); + } + }); + it("mobile timestamp lines wrap (no nowrap on the meta paragraphs)", () => { const html = render(); const mobileMatch = html.match(/]*md:hidden[^>]*>([\s\S]*?)<\/ul>/); diff --git a/src/components/admin/api-token-overview-section.tsx b/src/components/admin/api-token-overview-section.tsx index 9efec6d92..c44293cd6 100644 --- a/src/components/admin/api-token-overview-section.tsx +++ b/src/components/admin/api-token-overview-section.tsx @@ -222,12 +222,25 @@ export function ApiTokenOverviewSection() { )} - + {/* v1.4.22 C2 (5th attempt) — drop + `whitespace-nowrap` on the date cells. The + v1.4.19 A7 probe confirmed `formatDateTime` + renders "05.05.2026, 21:46" (~110px) which + exceeds the 12% `` allotment (~84px on + a 700px content area); `whitespace-nowrap` + wins over `table-fixed`'s width contract, + so the table's intrinsic width exceeds 100% + and the wrapper's `overflow-x-auto` paints + the scrollbar the maintainer kept reporting + for the 5th time. Letting the date+time + wrap to two lines on narrow viewports costs + one row of height but eliminates the bar. */} + {token.lastUsedAt ? formatDateTime(token.lastUsedAt) : t("admin.tokenNeverUsed")} - + {formatDate(token.createdAt)}