Skip to content

fix(RAC): Tree DnD followup + docs #8302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 50 commits into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
9027d3c
storybook: fix drop indicator style outside of iframe
reidbarber May 22, 2025
05bed6f
storybook: fix children not moving in drag
reidbarber May 22, 2025
efc836b
storybook: allow dragging in second tree
reidbarber May 22, 2025
896faa9
update getDropTargetFromPoint to handle ambiguous drop position: 'aft…
reidbarber May 23, 2025
b19f3c6
fix serializeItem to handle empty children
reidbarber May 23, 2025
48fdc0b
add `position: relative` to the drop indicator row to fix scrolling i…
reidbarber May 23, 2025
4a1037d
Merge remote-tracking branch 'origin/main' into tree-dnd-followup
reidbarber May 23, 2025
4668df8
add aria-expanded to TreeDropIndicator row
reidbarber May 23, 2025
9801975
fix drop indicator missing level style
reidbarber May 27, 2025
4e527ed
add docs
reidbarber May 27, 2025
b20347c
fix types
reidbarber May 27, 2025
b88bf29
remove aria-expanded from insertion indicator
reidbarber May 27, 2025
66f48a7
docs types fixes
reidbarber May 28, 2025
6ef333b
If dropping "after" an expanded item with children, change target to …
reidbarber May 29, 2025
4a3acfc
init TreeDropTargetDelegate
reidbarber May 30, 2025
3791c06
lint
reidbarber May 30, 2025
1c2ffec
add comment
reidbarber May 30, 2025
ce08af4
handle currentItem?.nextKey != null
reidbarber May 30, 2025
b2bb88e
add TreeDropTargetDelegate to exports and DropHooks
reidbarber May 30, 2025
5f58b9f
fixes and cleanup
devongovett May 30, 2025
9057f5e
cleanup
reidbarber May 30, 2025
ff89260
Merge branch 'main' into tree-dnd-followup
reidbarber May 30, 2025
4748904
fix indention in docs examples
reidbarber Jun 2, 2025
53d5df5
fix duplicate key dropping
reidbarber Jun 2, 2025
c6e1c43
fix directory example
reidbarber Jun 2, 2025
d047b11
Merge remote-tracking branch 'origin/main' into tree-dnd-followup
reidbarber Jun 2, 2025
715a918
up X_SWITCH_THRESHOLD to 10
reidbarber Jun 2, 2025
ee47e1d
add recursive rendering to docs examples
reidbarber Jun 2, 2025
d8787fb
fix dup keys in DroppableTree
reidbarber Jun 2, 2025
fe25424
Add indentation to drop indicator
devongovett Jun 2, 2025
cd0946f
Improve docs examples
devongovett Jun 3, 2025
c9f36ee
Fix insertion indicator indentation when checkboxes and drag buttons …
devongovett Jun 3, 2025
a5dbf6f
shorten duplicate item data in examples
devongovett Jun 3, 2025
2e6da1a
docs types
reidbarber Jun 3, 2025
fdc2454
fix dropping before first expanded parent
reidbarber Jun 3, 2025
7149ac5
add isValidDropTarget checks
reidbarber Jun 3, 2025
d8df953
handle reorder 'after' expanded parent should not be a target
reidbarber Jun 3, 2025
a40af8b
Allow dropping after dragged key, but not after one of its children
devongovett Jun 3, 2025
69e3510
Reorder examples
devongovett Jun 3, 2025
fcd9712
feat: Ensure that getKeys filters out selected child keys if parent k…
LFDanLu Jun 3, 2025
88624d8
add serializeItem to other examples so children get unique ids
reidbarber Jun 3, 2025
22bb676
docs: increase indention between levels
reidbarber Jun 3, 2025
bc7130a
default to root drop target if there are no potential targets
LFDanLu Jun 3, 2025
fc09ba7
allowsDragging should be false if dragging disabled
reidbarber Jun 3, 2025
bce764c
add unit tests
reidbarber Jun 3, 2025
0bb63dc
Merge branch 'tree-dnd-followup' of https://github.com/adobe/react-sp…
reidbarber Jun 3, 2025
ec39bb4
Merge remote-tracking branch 'origin/main' into tree-dnd-followup
reidbarber Jun 3, 2025
b509c66
Update packages/react-aria-components/docs/Tree.mdx
reidbarber Jun 4, 2025
b35a8bb
Merge remote-tracking branch 'origin/main' into tree-dnd-followup
reidbarber Jun 4, 2025
62a577f
optimize getKeys to be linear
reidbarber Jun 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@react-aria/dnd/src/ListDropTargetDelegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class ListDropTargetDelegate implements DropTargetDelegate {
private ref: RefObject<HTMLElement | null>;
private layout: 'stack' | 'grid';
private orientation: Orientation;
private direction: Direction;
protected direction: Direction;

constructor(collection: Iterable<Node<unknown>>, ref: RefObject<HTMLElement | null>, options?: ListDropTargetDelegateOptions) {
this.collection = collection;
Expand Down
34 changes: 27 additions & 7 deletions packages/@react-stately/dnd/src/useDraggableCollectionState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,35 @@ export function useDraggableCollectionState(props: DraggableCollectionStateOptio
let draggedKey = useRef<Key | null>(null);
let getKeys = (key: Key) => {
// The clicked item is always added to the drag. If it is selected, then all of the
// other selected items are also dragged. If it is not selected, the only the clicked
// other selected items are also dragged. If it is not selected, then only the clicked
// item is dragged. This matches native macOS behavior.
let keys = new Set(
selectionManager.isSelected(key)
? new Set([...selectionManager.selectedKeys].filter(key => !!collection.getItem(key)))
: []
);
// Additionally, we filter out any keys that are children of any of the other selected keys
let keys = new Set<Key>();
if (selectionManager.isSelected(key)) {
for (let currentKey of selectionManager.selectedKeys) {
let node = collection.getItem(currentKey);
if (node) {
let isChild = false;
let parentKey = node.parentKey;
while (parentKey != null) {
// eslint-disable-next-line max-depth
if (selectionManager.selectedKeys.has(parentKey)) {
isChild = true;
break;
}
let parentNode = collection.getItem(parentKey);
parentKey = parentNode ? parentNode.parentKey : null;
}

if (!isChild) {
keys.add(currentKey);
}
}
}
} else {
keys.add(key);
}

keys.add(key);
return keys;
};

Expand Down
12 changes: 6 additions & 6 deletions packages/@react-stately/dnd/src/useDroppableCollectionState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ export function useDroppableCollectionState(props: DroppableCollectionStateOptio

let getOppositeTarget = (target: ItemDropTarget): ItemDropTarget | null => {
if (target.dropPosition === 'before') {
let key = collection.getKeyBefore(target.key);
return key != null && collection.getItem(key)?.level === collection.getItem(target.key)?.level
? {type: 'item', key, dropPosition: 'after'}
let node = collection.getItem(target.key);
return node && node.prevKey != null
? {type: 'item', key: node.prevKey, dropPosition: 'after'}
: null;
} else if (target.dropPosition === 'after') {
let key = collection.getKeyAfter(target.key);
return key != null && collection.getItem(key)?.level === collection.getItem(target.key)?.level
? {type: 'item', key, dropPosition: 'before'}
let node = collection.getItem(target.key);
return node && node.nextKey != null
? {type: 'item', key: node.nextKey, dropPosition: 'before'}
: null;
}
return null;
Expand Down
Loading