refactor(inset): the bottom-inset arithmetic becomes testable, and is tested

The measurement lived inside the view, where the only way to check it was to
run Obsidian on a phone. It moves to a pure `insetFor(leaf, bars, visible)`
against the numbers a phone reports - including the case the events hid: while
the keyboard is up the navbar is behind it, so the deeper of the two is the
inset and adding them would push the composer twice as far as it must go.
This commit is contained in:
hh
2026-09-05 00:49:54 +02:00
parent 413d68fc87
commit 70cf985aa1
3 changed files with 128 additions and 20 deletions
+67
View File
@@ -0,0 +1,67 @@
import { describe, expect, it } from "vitest";
import type { Rect } from "../src/inset";
import { insetFor } from "../src/inset";
const rect = (over: Partial<Rect> = {}): Rect => ({
bottom: 780,
height: 780,
left: 0,
right: 390,
top: 0,
...over,
});
// A phone: 780 tall, a 56px navbar over the bottom, 340px of keyboard.
const NAVBAR = rect({ bottom: 780, height: 56, top: 724 });
describe("insetFor", () => {
it("clears nothing when the leaf stands alone", () => {
expect(insetFor(rect(), [], null)).toBe(0);
});
it("clears the navbar that paints over the leaf", () => {
expect(insetFor(rect(), [NAVBAR], null)).toBe(56);
});
it("clears the keyboard, which shortens no layout", () => {
expect(insetFor(rect(), [], { height: 440, offsetTop: 0 })).toBe(340);
});
it("takes the deeper of the two rather than their sum", () => {
// While the keyboard is up the navbar is behind it: adding them would
// push the composer twice as far as it has to go.
expect(insetFor(rect(), [NAVBAR], { height: 440, offsetTop: 0 })).toBe(340);
});
it("comes back to the navbar once the keyboard goes", () => {
expect(insetFor(rect(), [NAVBAR], { height: 780, offsetTop: 0 })).toBe(56);
});
it("ignores a bar that sits beside the leaf, not over it", () => {
// The desktop status bar floats bottom-right; a left-hand sidedock never
// reaches it.
const sidedock = rect({ right: 300 });
const statusBar = rect({
bottom: 780,
height: 20,
left: 700,
right: 980,
top: 760,
});
expect(insetFor(sidedock, [statusBar], null)).toBe(0);
});
it("measures from where the visible area starts, not from zero", () => {
// iOS scrolls the page up under the keyboard instead of resizing it.
expect(insetFor(rect(), [], { height: 440, offsetTop: 100 })).toBe(240);
});
it("says nothing about a leaf with no height yet", () => {
expect(insetFor(rect({ bottom: 0, height: 0 }), [NAVBAR], null)).toBe(0);
});
it("never returns a negative inset", () => {
const short = rect({ bottom: 300, height: 300 });
expect(insetFor(short, [], { height: 780, offsetTop: 0 })).toBe(0);
});
});