From c289e0b77bb2713962f81d613b996324d9298d12 Mon Sep 17 00:00:00 2001 From: Norman Yee <155019+funkadelic@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:28:09 -0700 Subject: [PATCH 1/2] feat(table): highlight the row under the pointer Uses the existing --color-surface-hover token, so it follows the theme. --- src/components/DataTable/DataTable.module.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/DataTable/DataTable.module.scss b/src/components/DataTable/DataTable.module.scss index f2f5868..5ffe765 100644 --- a/src/components/DataTable/DataTable.module.scss +++ b/src/components/DataTable/DataTable.module.scss @@ -48,6 +48,10 @@ font-variant-numeric: tabular-nums; } + tbody tr:hover { + background-color: var(--color-surface-hover); + } + tbody tr:last-child td { border-bottom: none; // last in row needs no border otherwise it will have thicker border due to the parent container border } From b7f89c3cccde5f383b85aa7eec8110519b560aaa Mon Sep 17 00:00:00 2001 From: Norman Yee <155019+funkadelic@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:33:32 -0700 Subject: [PATCH 2/2] test(e2e): assert the row highlight appears under the pointer Pins the colour the hover rule produces onto the row so the archive Chromatic replays carries it, since the pointer is not part of that archive. --- e2e/visual.spec.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/e2e/visual.spec.ts b/e2e/visual.spec.ts index e78b826..3dde5cf 100644 --- a/e2e/visual.spec.ts +++ b/e2e/visual.spec.ts @@ -82,3 +82,31 @@ test("empty results", async ({ page }) => { timeout: DATASET_READY_TIMEOUT_MS, }); }); + +test("hovered row", async ({ page }) => { + await page.goto("/"); + await expect(page.getByRole("table")).toBeVisible({ + timeout: DATASET_READY_TIMEOUT_MS, + }); + + const row = page.locator("tbody tr").first(); + const background = () => + row.evaluate((el) => getComputedStyle(el).backgroundColor); + const resting = await background(); + + await row.hover(); + const hovered = await background(); + expect(hovered).not.toBe(resting); + + // The archive Chromatic replays carries the DOM, never the pointer, so a + // :hover rule paints in none of it. Writing the colour the rule just produced + // onto the row puts it somewhere the archive reaches. Read from the rendered + // page rather than restated here, so a token change moves the snapshot and a + // deleted rule fails the assertion above before this line runs. Set through + // the CSSOM because the shell's style-src forbids a style attribute. + await row.evaluate((el, color) => { + el.style.backgroundColor = color; + }, hovered); + await page.mouse.move(0, 0); + await expect.poll(background).toBe(hovered); +});