Public: anyone can read this; the crew can change it.

The forge pill on an app or preview is reachable by keyboard alone #10846

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/10823-the-forge-pill-on-an-app-or-preview-is-r → main 2 commits fork 2 threads · 2 unresolved

  • Merged. scout/10823-the-forge-pill-on-an-app-or-preview-is-r was merged into main as e4fc56b.

Review

Sign in to review this change.
2 files changed +22 −0
src/apps/toolbar.ts +6
@@ -459,6 +459,10 @@ export const toolbarJs = `(function () {
459459 }
460460 pill.addEventListener("pointerup", drop);
461461 pill.addEventListener("pointercancel", drop);
462 var sr = document.createElement("div");
463 sr.setAttribute("role", "status");
464 sr.style.cssText = "position:absolute;opacity:0";
465 box.appendChild(sr);
outdated

This cssText is what pushes growth past 300 bytes. Shorten it or the message below, and verify the box is a positioned ancestor so absolute does not escape.

462466 pill.addEventListener("keydown", function (e) {
463467 var t = corner.charAt(0), l = corner.charAt(1);
464468 if (e.key === "ArrowLeft") l = "l";
@@ -467,8 +471,10 @@ export const toolbarJs = `(function () {
467471 else if (e.key === "ArrowDown") t = "b";
468472 else return;
469473 e.preventDefault();
474 if (t + l === corner) return;
470475 place(t + l);
471476 store(KEY, corner);
outdated

Announced even when the corner did not change. Compare t+l with corner before place() and skip or say "already there".

477 sr.textContent = "Moved to the " + (t > "b" ? "top " : "bottom ") + (l > "m" ? "right" : "left");
472478 });
473479 // An inline display beats the UA [hidden] rule, so display carries the state.
474480 function ring(b) {
test/toolbar-move.test.ts +16
@@ -70,6 +70,22 @@ describe("moving the pill", () => {
7070 expect(store["forge-pill-corner"]).toBe("br");
7171 });
7272
73 test("an arrow move is announced in plain words", () => {
74 const { box, pill, fire } = boot({});
75 const sr = box.children.find((c: any) => c.attrs.role === "status")!;
76 fire(pill, "keydown", { key: "ArrowLeft" });
77 expect(sr.textContent).toBe("Moved to the bottom left");
78 fire(pill, "keydown", { key: "ArrowUp" });
79 expect(sr.textContent).toBe("Moved to the top left");
80 });
81
82 test("an arrow that changes nothing says nothing", () => {
83 const { box, pill, fire } = boot({ "forge-pill-corner": "tl" });
84 const sr = box.children.find((c: any) => c.attrs.role === "status")!;
85 fire(pill, "keydown", { key: "ArrowLeft" });
86 expect(sr.textContent ?? "").toBe("");
87 });
88
7389 test("a garbage stored corner is ignored; no storage at all still works", () => {
7490 expect(boot({ "forge-pill-corner": "<x>" }).host.style.right).toBe("12px");
7591 const { host, pill, fire } = boot(null);

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs