From 7f6dcc8ef6fd1efec266ffeee16d34678a469f98 Mon Sep 17 00:00:00 2001 From: Will Gordon Date: Sun, 3 May 2026 15:22:12 -0400 Subject: [PATCH 1/3] fix(ui): compact age hover uses Kobalte Tooltip Replace native HTML title attribute on compact mode time element with the Kobalte Tooltip component and relative z-10 positioning. The native title was blocked by the full-row overlay link intercepting pointer events. --- src/app/components/dashboard/ItemRow.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/app/components/dashboard/ItemRow.tsx b/src/app/components/dashboard/ItemRow.tsx index 7b1920cb..dc68b71a 100644 --- a/src/app/components/dashboard/ItemRow.tsx +++ b/src/app/components/dashboard/ItemRow.tsx @@ -172,9 +172,11 @@ export default function ItemRow(props: ItemRowProps) { {props.author} {" · "} - + + + From 1f0a0798f52a94cc0cfa3277ef8ade1902fee07e Mon Sep 17 00:00:00 2001 From: Will Gordon Date: Sun, 3 May 2026 15:36:00 -0400 Subject: [PATCH 2/3] test(ui): adds compact mode date tooltip hover test Mirrors the comfortable layout tooltip hover tests to verify the Kobalte Tooltip renders correct content on pointer enter in compact density mode. --- tests/components/ItemRow.test.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/components/ItemRow.test.tsx b/tests/components/ItemRow.test.tsx index daab24ea..374dfa29 100644 --- a/tests/components/ItemRow.test.tsx +++ b/tests/components/ItemRow.test.tsx @@ -151,6 +151,25 @@ describe("ItemRow", () => { const timeEls = container.querySelectorAll("time"); expect(timeEls.length).toBe(1); }); + + it("shows updated date tooltip content on hover in compact mode", () => { + vi.useFakeTimers(); + const { container, unmount } = render(() => ); + const updatedTrigger = container.querySelector( + `time[datetime="${defaultProps.updatedAt}"]` + )?.closest("span.inline-flex"); + expect(updatedTrigger).not.toBeNull(); + expect(updatedTrigger!.className).toContain("z-10"); + fireEvent.pointerEnter(updatedTrigger!); + vi.advanceTimersByTime(300); + expect(document.body.textContent).toContain( + `Updated: ${new Date(defaultProps.updatedAt).toLocaleString()}` + ); + fireEvent.pointerLeave(updatedTrigger!); + vi.advanceTimersByTime(500); + unmount(); + vi.useRealTimers(); + }); }); it("renders no labels section when labels array is empty", () => { From c1c5ea4b89afb4aecdcbe5fbe77a3123056fb5a0 Mon Sep 17 00:00:00 2001 From: Will Gordon Date: Sun, 3 May 2026 15:50:48 -0400 Subject: [PATCH 3/3] feat(ui): compact tooltip shows both updated and created dates Combines both timestamps in the compact mode hover tooltip with updated first (matching the displayed value) and created second, separated by a line break via whitespace-pre-line. --- src/app/components/dashboard/ItemRow.tsx | 9 ++++++++- tests/components/ItemRow.test.tsx | 5 ++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/app/components/dashboard/ItemRow.tsx b/src/app/components/dashboard/ItemRow.tsx index dc68b71a..4f3c5025 100644 --- a/src/app/components/dashboard/ItemRow.tsx +++ b/src/app/components/dashboard/ItemRow.tsx @@ -58,6 +58,13 @@ export default function ItemRow(props: ItemRowProps) { return created !== "" && updated !== "" && created !== updated; }); + const compactDateTooltip = createMemo(() => { + if (shouldShowUpdated()) { + return `${staticDateInfo().updatedTitle}\n${staticDateInfo().createdTitle}`; + } + return staticDateInfo().createdTitle; + }); + const compactLabelTooltip = createMemo(() => { const parts: string[] = []; if (props.labels.length > 0) { @@ -172,7 +179,7 @@ export default function ItemRow(props: ItemRowProps) { {props.author} {" · "} - + diff --git a/tests/components/ItemRow.test.tsx b/tests/components/ItemRow.test.tsx index 374dfa29..d9c43b4c 100644 --- a/tests/components/ItemRow.test.tsx +++ b/tests/components/ItemRow.test.tsx @@ -152,7 +152,7 @@ describe("ItemRow", () => { expect(timeEls.length).toBe(1); }); - it("shows updated date tooltip content on hover in compact mode", () => { + it("shows both updated and created dates in tooltip on hover", () => { vi.useFakeTimers(); const { container, unmount } = render(() => ); const updatedTrigger = container.querySelector( @@ -165,6 +165,9 @@ describe("ItemRow", () => { expect(document.body.textContent).toContain( `Updated: ${new Date(defaultProps.updatedAt).toLocaleString()}` ); + expect(document.body.textContent).toContain( + `Created: ${new Date(defaultProps.createdAt).toLocaleString()}` + ); fireEvent.pointerLeave(updatedTrigger!); vi.advanceTimersByTime(500); unmount();