fix(studio): the resting quick buttons are visually hidden, not display:none, so a keyboard can still reach them

03943d8a84 hid them with display:none, which made Pin and Archive unfocusable and failed perf/sessquick.mjs (keyboard focus reveals both actions). A row's buttons are now clipped to 1px with opacity 0 until the row is hovered or holds focus.
This commit is contained in:
esengine committed 2026-11-07 16:39:31 -08:00
1 parent 7b783209fd
commit f75b0624a6
3 files changed
+11 -8

No files matched your search

@@ -14,7 +14,7 @@ try {
const shown = (row, selector) =>
row.evaluate((el, sel) => {
const node = el.querySelector(sel);
return !!node && getComputedStyle(node).display !== "none" && node.getBoundingClientRect().width > 0;
return !!node && getComputedStyle(node).display !== "none" && getComputedStyle(node).opacity !== "0" && node.getBoundingClientRect().width > 2;
}, selector);
const rows = page.locator(".ds-row.sessrow");
await page.mouse.move(700, 450);
+3 -3
View File
@@ -47,9 +47,9 @@
.ds-row:is(:hover, :focus-within) > :is(.ds-meta, .ds-pin) { display: none; }
@media (hover: none) { .ds-row .ds-more { display: grid; } }
.ds-row .ds-pin { width: 12px; height: 12px; flex: none; }
.ds-row .sessquick, .ds-row .sesspin-action { flex: none; display: none; }
.ds-row:is(:hover, :focus-within) .sessquick { display: flex; }
.ds-row:is(:hover, :focus-within) .sesspin-action { display: grid; }
.ds-row .sessquick { flex: none; display: flex; }
.ds-row .sesspin-action { flex: none; display: grid; }
.ds-row:not(:is(:hover, :focus-within)) :is(.sessquick, .sesspin-action) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); opacity: 0; pointer-events: none; }
.ds-row .sessquick > button, .ds-row .sesspin-action { width: 24px; height: 28px; padding: 0; place-items: center; border: 0; border-radius: var(--r-xs); background: transparent; color: var(--faint); cursor: pointer; }
.ds-row .sessquick > button { display: grid; }
.ds-row .sessquick > button:hover, .ds-row .sesspin-action:hover { background: var(--raised); color: var(--text); }
@@ -33,9 +33,12 @@ describe("session and project rows follow the board", () => {
expect(rule(".ds-row:is(:hover, :focus-within) .ds-more")).toMatch(/display:\s*grid/);
});
it("keeps the pin button hidden until the row is hovered or focused", () => {
expect(rule(".ds-row .sessquick, .ds-row .sesspin-action")).toMatch(/display:\s*none/);
expect(rule(".ds-row .sessquick > button, .ds-row .sesspin-action")).not.toMatch(/display:/);
expect(rule(".ds-row:is(:hover, :focus-within) .sesspin-action")).toMatch(/display:\s*grid/);
it("hides the quick buttons until the row is hovered or focused, without taking them out of the tab order", () => {
const hidden = rule(".ds-row:not(:is(:hover, :focus-within)) :is(.sessquick, .sesspin-action)");
expect(hidden).toMatch(/opacity:\s*0/);
expect(hidden).toMatch(/pointer-events:\s*none/);
expect(hidden).not.toMatch(/display:\s*none/);
expect(rule(".ds-row .sesspin-action")).toMatch(/display:\s*grid/);
expect(rule(".ds-row .sessquick, .ds-row .sesspin-action")).not.toMatch(/display:\s*none/);
});
});