import { readFileSync } from "node:fs"; import { expect, it } from "vitest"; import { navItemAttrs } from "./listNav"; // The keyboard ring of a list item (`[data-nav-index]`) sits 2 px OUTSIDE the item: a card with a gap // round it has room. A table row, a log line or a row flush in a clipping card has none — the ring ran // under a sticky table head and past the table's sides, and in a Plex playlist show's card it was // clipped away so the focus was invisible (seen live). A `tr` is inset by its tag (a table // hand-built outside DataTable was the one first reported); the others ask for `inset`. jsdom does no // layout, so what is pinned is the attribute and the rule that draws it inside, with every selector the // outside ring uses (a `:has()` one outranks a plain attribute pair). const css = readFileSync(new URL("../index.css", import.meta.url), "utf8"); it("an inset item carries the marker, a plain one does not", () => { expect(navItemAttrs(3, "x", { inset: true })).toEqual({ "data-nav-index": 3, "data-nav-name": "x", "data-nav-inset": "", }); expect(navItemAttrs(3)).toEqual({ "data-nav-index": 3 }); }); it("index.css draws an inset item's ring inside, after the outside rule", () => { const outside = css.indexOf("[data-nav-index]:has([data-nav-open]:focus-visible)"); const at = css.indexOf(":is(tr, [data-nav-inset])[data-nav-index],"); expect(outside, "the outside ring").toBeGreaterThan(0); expect(at, "the inset rule comes later").toBeGreaterThan(outside); const rule = css.slice(at, css.indexOf("}", at)); expect(rule).toContain(":is(tr, [data-nav-inset])[data-nav-index]:focus-visible"); expect(rule).toContain( ":is(tr, [data-nav-inset])[data-nav-index]:has([data-nav-open]:focus-visible)", ); expect(rule).toMatch(/outline-offset:\s*-2px/); }); // The items that sit flush, by their source: a new one of the kind should be added here. const src = (p: string) => readFileSync(new URL(p, import.meta.url), "utf8"); // The history rows (runs, admin actions) and the log lines share one frame, HistoryRow. it.each([ ["../components/HistoryRow.tsx", /navItemAttrs\(navIndex, [^)]*\{ inset: true \}\)/], ["../components/LogLine.tsx", / { expect(src(file)).toMatch(re); });