summaryrefslogtreecommitdiffhomepage
path: root/src/features/workspaces/ui
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-09-07 17:40:29 +0900
committerAdam Malczewski <[email protected]>2026-09-07 17:40:29 +0900
commit46b5f9d30f149c3e80f483c91f563c0a6fc75b25 (patch)
treed6554c2634b624ead9f87881ff506506f88a7cbe /src/features/workspaces/ui
parent828d4e4fb822ec2925c8a625bc5bf326c3425964 (diff)
downloaddispatch-web-46b5f9d30f149c3e80f483c91f563c0a6fc75b25.tar.gz
dispatch-web-46b5f9d30f149c3e80f483c91f563c0a6fc75b25.zip
feat(workspaces): bound the drag append area — 3 columns past the content edge
Dragging a tile far right grew the wide canvas endlessly (the target cell resolved from the pointer with no upper bound), making precise placement impossible. Add a pure `dragAppendLimit(placements, geometry, extra = 3)`: the drag target may aim at most 3 columns (wide) / rows (tall) past the current span-aware content edge. The bound is measured on the COMMITTED layout — never the live preview — so it can't ratchet mid-drag; it steps forward only when a drop commits new content. cellAt applies it on the growth axis (wide: col, tall: row); the fixed cross-axis clamps are unchanged. Exported via the unit index. Verification: svelte-check 0 errors/0 warnings; vitest 1693/1693 (4 new dragAppendLimit tests); biome clean on touched files; build ok.
Diffstat (limited to 'src/features/workspaces/ui')
-rw-r--r--src/features/workspaces/ui/HomeTileGrid.svelte13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/features/workspaces/ui/HomeTileGrid.svelte b/src/features/workspaces/ui/HomeTileGrid.svelte
index 1ec31e5..adcdf08 100644
--- a/src/features/workspaces/ui/HomeTileGrid.svelte
+++ b/src/features/workspaces/ui/HomeTileGrid.svelte
@@ -6,6 +6,7 @@
import { nextDragPhase, type DragEvent, type DragPhase } from "../logic/drag-controller";
import {
displacePlace,
+ dragAppendLimit,
type Cell,
type GridGeometry,
type Placement,
@@ -203,6 +204,14 @@
const pitchX = $derived(geometry.unit.width + geometry.unit.gap);
const pitchY = $derived(geometry.unit.height + geometry.unit.gap);
+ /**
+ * The drag target's clamp on the growth axis — at most 3 columns (wide) /
+ * rows (tall) past the current content edge. Measured on the COMMITTED
+ * placements (the drag preview never ratchets the limit mid-drag), so the
+ * canvas can't endlessly grow when dragging far right / down.
+ */
+ const appendLimit = $derived(dragAppendLimit(placements, geometry));
+
function cellAt(clientX: number, clientY: number): Cell | null {
const el = gridEl;
if (!el) return null;
@@ -213,8 +222,8 @@
const col = Math.max(1, Math.floor((clientX - rect.left) / cellW) + 1);
const row = Math.max(1, Math.floor((clientY - rect.top) / pitchY) + 1);
return {
- col: wide ? col : Math.min(col, geometry.flowCols),
- row: wide ? Math.min(row, geometry.flowRows) : row,
+ col: wide ? Math.min(col, appendLimit) : Math.min(col, geometry.flowCols),
+ row: wide ? Math.min(row, geometry.flowRows) : Math.min(row, appendLimit),
};
}