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

On a phone, the forge pill in a top corner sits 48 px down, clear of the camera, and opening its panel moves nothing #7717

Merged opened this

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

Merged

scout/forge:scout/7714-on-a-phone-the-forge-pill-in-a-top-corne → main 3 commits fork 1 thread · 1 unresolved

  • Merged. scout/7714-on-a-phone-the-forge-pill-in-a-top-corne was merged into main as a732647.

Review

Sign in to review this change.
3 files changed +58 −4
src/apps/toolbar.ts +5 −1
@@ -362,10 +362,14 @@ export const toolbarJs = `(function () {
362362 var saved = window.localStorage.getItem(KEY);
363363 if (CORNERS.indexOf(saved) >= 0) corner = saved;
364364 } catch (e) {}
365 var NARROW_MAX = 600, CAMERA_TOP = "48px";
365366 function place(c) {
366367 corner = c;
367368 var top = c.charAt(0) === "t", left = c.charAt(1) === "l";
368 host.style.top = top ? "12px" : "auto";
369 var narrow = top && window.innerWidth <= NARROW_MAX;
370 host.style.top = top ? (narrow ? CAMERA_TOP : "12px") : "auto";
371 // The cssText cap assumes a pill 12px down; 36px lower, the cap drops by as much.
372 panel.style.maxHeight = narrow ? "min(70vh,calc(100vh - 124px))" : "";
369373 host.style.bottom = top ? "auto" : "12px";
370374 host.style.left = left ? "12px" : "auto";
371375 host.style.right = left ? "auto" : "12px";
test/toolbar-camera.test.ts added +50
@@ -0,0 +1,50 @@
1 /**
2 * On a phone a top-corner pill sits clear of the camera (#7714), and opening
3 * the panel moves nothing.
4 */
5
6 import { describe, expect, test } from "bun:test";

Non-blocking: this import re-runs every test in toolbar-move.test.ts. Extract boot into a helper module both files import.

7 import { boot } from "./toolbar-move.test.ts";
8
9 const at = (corner: string, width: number) => boot({ "forge-pill-corner": corner }, width, 844);
10
11 describe("the pill and the camera", () => {
12 for (const c of ["tl", "tr"]) {
13 test(`${c} sits 48px down at 390 wide and 360 wide, 12px at 1440`, () => {
14 expect(at(c, 390).host.style.top).toBe("48px");
15 expect(at(c, 360).host.style.top).toBe("48px");
16 expect(at(c, 600).host.style.top).toBe("48px");
17 expect(at(c, 601).host.style.top).toBe("12px");
18 expect(at(c, 1440).host.style.top).toBe("12px");
19 });
20 }
21
22 for (const c of ["bl", "br"]) {
23 test(`${c} keeps bottom:12px at any width`, () => {
24 for (const w of [360, 390, 1440]) {
25 const { host, panel } = at(c, w);
26 expect(host.style.bottom).toBe("12px");
27 expect(host.style.top).toBe("auto");
28 expect(panel.style.maxHeight ?? "").toBe("");
29 }
30 });
31 }
32
33 test("a narrow top-corner panel is capped for the lower pill; others keep the pinned cap", () => {
34 expect(at("tr", 390).panel.style.maxHeight).toBe("min(70vh,calc(100vh - 124px))");
35 expect(at("tr", 1440).panel.style.maxHeight).toBe("");
36 });
37
38 test("opening and closing the panel leaves the host where it was", () => {
39 for (const [c, w] of [["tr", 390], ["tl", 390], ["tr", 1440], ["br", 390]] as const) {
40 const { host, pill, panel, fire } = at(c, w);
41 const before = { ...host.style };
42 fire(pill, "click");
43 expect(panel.style.display).toBe("flex");
44 expect(host.style).toEqual(before);
45 fire(pill, "click");
46 expect(panel.style.display).toBe("none");
47 expect(host.style).toEqual(before);
48 }
49 });
50 });
test/toolbar-move.test.ts +3 −3
@@ -33,7 +33,7 @@ const make = (tag: string): El => ({
3333 });
3434 const all = (el: El): El[] => [el, ...el.children.flatMap(all)];
3535
36 function boot(store: Record<string, string> | null, width = 400, height = 800) {
36 export function boot(store: Record<string, string> | null, width = 400, height = 800) {
3737 let root!: El;
3838 const host = { el: null as El | null };
3939 const doc = {
@@ -80,7 +80,7 @@ describe("moving the pill", () => {
8080 fire(pill, "pointermove", { clientX: 100, clientY: 60 });
8181 expect(host.style.left).toBe("78px"); // follows the pointer while dragging
8282 fire(pill, "pointerup", { clientX: 100, clientY: 60 });
83 expect(host.style.top).toBe("12px");
83 expect(host.style.top).toBe("48px");
8484 expect(host.style.left).toBe("12px");
8585 expect(host.style.right).toBe("auto");
8686 expect(box.style.flexDirection).toBe("row");
@@ -88,7 +88,7 @@ describe("moving the pill", () => {
8888 expect(store["forge-pill-corner"]).toBe("tl");
8989 // The next page load puts it there again.
9090 expect(boot(store).host.style.left).toBe("12px");
91 expect(boot(store).host.style.top).toBe("12px");
91 expect(boot(store).host.style.top).toBe("48px");
9292 });
9393
9494 test("a press that barely moves is a tap, not a drag", () => {

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs