summaryrefslogtreecommitdiffhomepage
path: root/src/features/workspaces/ui/HomeTileGrid.test.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-09-07 17:45:57 +0900
committerAdam Malczewski <[email protected]>2026-09-07 17:45:57 +0900
commit9ede1f079a545cbc215d91ba09b4d1bc2a0b99ee (patch)
tree5df22c5e273ddebba325b959792eb64aec1daa32 /src/features/workspaces/ui/HomeTileGrid.test.ts
parent46b5f9d30f149c3e80f483c91f563c0a6fc75b25 (diff)
downloaddispatch-web-9ede1f079a545cbc215d91ba09b4d1bc2a0b99ee.tar.gz
dispatch-web-9ede1f079a545cbc215d91ba09b4d1bc2a0b99ee.zip
feat(workspaces): reserve the append canvas for the whole drag — no scrollbar change mid-drag
Previously the grid kept `width: max-content` during a drag, so the canvas grew/shrunk as the preview placed the tile at each hovered cell — the scrollbar resized mid-drag, making placement harder. Now the moment a drag starts the grid's growth axis becomes a FIXED reservation: the append limit (committed content edge + 3, span-aware) computed at drag start, so the 3 spaces "pop in" immediately, the scroller size is constant for the entire gesture, and the unused reservation disappears when the drag ends (the canvas returns to max-content / auto). The dragged tile's span room is included so its body always stays inside the reserved canvas. Also: the scroll-measure effect now tracks `dragging`, so canPan and the scroll indicator re-measure when the reservation appears and disappears. Test: the drag test now asserts the grid's style is a fixed px width while dragging (never max-content) and back to max-content after the drop. (This caught a missing `px` unit that would have silently voided the reservation.) Update the handoff bullet to describe the reservation. Verification: svelte-check 0 errors/0 warnings; vitest 1693/1693; biome clean on touched files; build ok.
Diffstat (limited to 'src/features/workspaces/ui/HomeTileGrid.test.ts')
-rw-r--r--src/features/workspaces/ui/HomeTileGrid.test.ts10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/features/workspaces/ui/HomeTileGrid.test.ts b/src/features/workspaces/ui/HomeTileGrid.test.ts
index d70c673..9f163fd 100644
--- a/src/features/workspaces/ui/HomeTileGrid.test.ts
+++ b/src/features/workspaces/ui/HomeTileGrid.test.ts
@@ -105,10 +105,18 @@ describe("HomeTileGrid", () => {
});
const wrapper = screen.getByRole("button", { name: "Open workspace Workspace A" });
+ const grid = container.querySelector(".grid");
// The cell math resolves against the grid element's rect (jsdom: 0s).
fireEvent.pointerDown(wrapper, { button: 0, clientX: 10, clientY: 10, pointerType: "mouse" });
fireEvent.pointerMove(wrapper, { clientX: 80, clientY: 40 });
+ // While dragging the canvas is a FIXED reservation (content edge + 3, plus
+ // the dragged tile's span room) — never max-content, so the scroller can't
+ // resize mid-drag.
+ const pitchX = WIDE.unit.width + WIDE.unit.gap;
+ expect(grid?.getAttribute("style")).toContain(`width: ${5 * pitchX - WIDE.unit.gap}px`);
+ expect(grid?.getAttribute("style")).not.toContain("width: max-content");
+
// The dashed landing ghost appears…
const ghost = container.querySelector("[aria-hidden='true'].border-dashed");
expect(ghost).not.toBeNull();
@@ -119,6 +127,8 @@ describe("HomeTileGrid", () => {
fireEvent.pointerUp(wrapper);
// The ghost + follow disappear on drop…
expect(container.querySelector("[aria-hidden='true'].border-dashed")).toBeNull();
+ // …and the reservation is gone too (the canvas hugs the committed content).
+ expect(grid?.getAttribute("style")).toContain("width: max-content");
// …and the drop committed a PLACE at the hovered cell (a lands where it
// already was — the pointer hovered its own slot; a no-move drop).
expect(props.onPlace).toHaveBeenCalledWith("a", { col: 1, row: 1 });