Skip to content

Commit ef7675f

Browse files
authored
fix: Virtualized Tree DnD fixes (#8526)
* fix before-first drop indicator not showing * update useDndPersistedKeys to take level into account * update comment
1 parent 8e94a19 commit ef7675f

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

packages/@react-stately/layout/src/ListLayout.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ export class ListLayout<T, O extends ListLayoutOptions = ListLayoutOptions> exte
591591
let layoutInfo = this.getLayoutInfo(target.key)!;
592592
let rect: Rect;
593593
if (target.dropPosition === 'before') {
594-
rect = new Rect(layoutInfo.rect.x, layoutInfo.rect.y - this.dropIndicatorThickness / 2, layoutInfo.rect.width, this.dropIndicatorThickness);
594+
rect = new Rect(layoutInfo.rect.x, Math.max(0, layoutInfo.rect.y - this.dropIndicatorThickness / 2), layoutInfo.rect.width, this.dropIndicatorThickness);
595595
} else if (target.dropPosition === 'after') {
596596
// Render after last visible descendant of the drop target.
597597
let targetNode = this.collection.getItem(target.key);

packages/react-aria-components/src/DragAndDrop.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,26 @@ export function useDndPersistedKeys(selectionManager: MultipleSelectionManager,
7575
dropTargetKey = dropState.target.key;
7676
if (dropState.target.dropPosition === 'after') {
7777
// Normalize to the "before" drop position since we only render those to the DOM.
78-
dropTargetKey = dropState.collection.getKeyAfter(dropTargetKey) ?? dropTargetKey;
78+
let nextKey = dropState.collection.getKeyAfter(dropTargetKey);
79+
if (nextKey != null) {
80+
let targetLevel = dropState.collection.getItem(dropTargetKey)?.level ?? 0;
81+
// Skip over any rows that are descendants of the target ("after" position should be after all children)
82+
while (nextKey) {
83+
let node = dropState.collection.getItem(nextKey);
84+
// eslint-disable-next-line max-depth
85+
if (!node) {
86+
break;
87+
}
88+
// Stop once we find a node at the same level or higher
89+
// eslint-disable-next-line max-depth
90+
if ((node.level ?? 0) <= targetLevel) {
91+
break;
92+
}
93+
nextKey = dropState.collection.getKeyAfter(nextKey);
94+
}
95+
}
96+
97+
dropTargetKey = nextKey ?? dropTargetKey;
7998
}
8099
}
81100

0 commit comments

Comments
 (0)