Skip to content

Commit a242744

Browse files
committed
fix(drag-reorder): expand target column height during cross-column drag
When dragging a card into a different kanban column, the gap/slot system shifts cards down via translateY but the column's max-height constraint clips the bottom cards off-screen. The source column already locks its height to prevent collapse, but the target column was not expanded to accommodate the incoming card. The target column and its task container now have their max-height temporarily increased by the drag gap amount when a card enters. Both are reset in cleanupDragShift on drag end or container change.
1 parent 6f303b3 commit a242744

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

src/bases/KanbanView.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export class KanbanView extends BasesViewBase {
3636
private dragContainer: HTMLElement | null = null; // Container holding siblings during drag
3737
private currentInsertionIndex: number = -1; // Current gap/slot position
3838
private dragSourceColumnEl: HTMLElement | null = null; // Source column element (height-locked during drag)
39+
private dragTargetColumnEl: HTMLElement | null = null; // Target column element (max-height expanded during drag)
3940
private draggedSourceColumns: Map<string, string> = new Map(); // Track source column per task for batch operations
4041
private draggedSourceSwimlanes: Map<string, string> = new Map(); // Track source swimlane per task for batch operations
4142
private taskInfoCache = new Map<string, TaskInfo>();
@@ -1541,9 +1542,22 @@ export class KanbanView extends BasesViewBase {
15411542
: 60;
15421543
const gapStr = getComputedStyle(container).gap;
15431544
const gap = parseFloat(gapStr) || 4;
1544-
container.style.setProperty("--tn-drag-gap", `${draggedHeight + gap}px`);
1545+
const totalGap = draggedHeight + gap;
1546+
container.style.setProperty("--tn-drag-gap", `${totalGap}px`);
15451547
container.style.overflowY = "clip";
15461548

1549+
// Expand target column/cell max-height to accommodate the gap
1550+
// so shifted cards aren't clipped off the bottom
1551+
const parentCol = container.closest<HTMLElement>(
1552+
".kanban-view__column, .kanban-view__swimlane-column"
1553+
);
1554+
if (parentCol) {
1555+
const currentMax = parentCol.getBoundingClientRect().height;
1556+
parentCol.style.maxHeight = `${currentMax + totalGap}px`;
1557+
this.dragTargetColumnEl = parentCol;
1558+
}
1559+
container.style.maxHeight = "none";
1560+
15471561
const siblings = container.querySelectorAll<HTMLElement>(".kanban-view__card-wrapper");
15481562
for (const sib of siblings) {
15491563
if (!this.draggedTaskPaths.includes(sib.dataset.taskPath || "")) {
@@ -1803,6 +1817,7 @@ export class KanbanView extends BasesViewBase {
18031817
if (this.dragContainer) {
18041818
this.dragContainer.style.removeProperty("--tn-drag-gap");
18051819
this.dragContainer.style.overflowY = "";
1820+
this.dragContainer.style.maxHeight = "";
18061821
const wrappers = this.dragContainer.querySelectorAll<HTMLElement>(
18071822
".kanban-view__card-wrapper--drag-shift, .kanban-view__card-wrapper--shift-down"
18081823
);
@@ -1812,6 +1827,12 @@ export class KanbanView extends BasesViewBase {
18121827
this.dragContainer = null;
18131828
}
18141829

1830+
// Reset target column max-height
1831+
if (this.dragTargetColumnEl) {
1832+
this.dragTargetColumnEl.style.maxHeight = "";
1833+
this.dragTargetColumnEl = null;
1834+
}
1835+
18151836
// Also clean any wrappers on the entire board (safety net for cross-column)
18161837
this.boardEl?.querySelectorAll<HTMLElement>(
18171838
".kanban-view__card-wrapper--drag-shift, .kanban-view__card-wrapper--shift-down"

0 commit comments

Comments
 (0)