MCPcopy Create free account
hub / github.com/callumalpass/tasknotes / setupContainerDragHandlers

Method setupContainerDragHandlers

src/bases/TaskListView.ts:1237–1322  ·  view source on GitHub ↗

* Container-level drag event delegation. * Handles dragenter/dragover/drop/dragleave on the itemsContainer so it * works with both normal and virtual-scrolling rendering. * * IMPORTANT: Both dragenter and dragover must call e.preventDefault() to * tell the browser this container accepts dr

()

Source from the content-addressed store, hash-verified

1235 * the cursor is between cards or over the dragged card itself.
1236 */
1237 private setupContainerDragHandlers(): void {
1238 if (!this.itemsContainer) return;
1239
1240 // dragenter: required by the HTML5 DnD spec alongside dragover to
1241 // indicate this container is a valid drop zone.
1242 this.itemsContainer.addEventListener("dragenter", (e: DragEvent) => {
1243 if (!this.draggedTaskPath) return;
1244 e.preventDefault();
1245 if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
1246 });
1247
1248 this.itemsContainer.addEventListener("dragover", (e: DragEvent) => {
1249 if (!this.draggedTaskPath) return;
1250
1251 // Always accept – must be unconditional so the browser keeps
1252 // the drop zone active even when the cursor is between cards.
1253 e.preventDefault();
1254 if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
1255
1256 // Throttle visual updates via rAF
1257 this.pendingDragClientY = e.clientY;
1258 if (!this.dragOverRafId) {
1259 this.dragOverRafId = window.requestAnimationFrame(() => {
1260 this.dragOverRafId = 0;
1261
1262 const clientY = this.pendingDragClientY;
1263 this.pendingDragClientY = null;
1264 if (clientY === null) return;
1265
1266 this.updateResolvedInsertionSlot(clientY);
1267 });
1268 }
1269 });
1270
1271 this.itemsContainer.addEventListener("dragleave", (e: DragEvent) => {
1272 // Only clear if leaving the container entirely (not moving between children)
1273 const related = e.relatedTarget as HTMLElement | null;
1274 if (!related || !this.itemsContainer?.contains(related)) {
1275 this.clearDropIndicators();
1276 }
1277 });
1278
1279 this.itemsContainer.addEventListener("drop", (e: DragEvent) => {
1280 void (async () => {
1281 e.preventDefault();
1282 if (!this.draggedTaskPath) return;
1283
1284 if (!this.flushPendingInsertionSlot(e.clientY) && this.currentInsertionIndex < 0)
1285 return;
1286
1287 const draggedPath = this.draggedTaskPath;
1288 const sourceGroupKey = this.dragGroupKey;
1289 const targetGroupKey = this.currentInsertionGroupKey;
1290 const targetVisiblePaths = this.getVisibleSortScopePathsForDrag(targetGroupKey);
1291 const insertionSegmentIndex = this.currentInsertionSegmentIndex;
1292 const insertionIndex = this.currentInsertionIndex;
1293 const dropTarget =
1294 insertionSegmentIndex >= 0 && insertionIndex >= 0

Callers 1

setupContainerMethod · 0.95

Tested by

no test coverage detected