Skip to content

Commit 5f61f4f

Browse files
committed
feat: target parent when dragging on child (#219)
1 parent 2d4c6e3 commit 5f61f4f

File tree

5 files changed

+48
-15
lines changed

5 files changed

+48
-15
lines changed

next-release-notes.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
<!--
2-
### Breaking Changes
3-
4-
### Features
5-
61
### Bug Fixes and Improvements
72

8-
### Other Changes
9-
-->
3+
* Dragging on a non-folder item with `canDropOnNonFolder=false` and
4+
`canReorderItems=false` will now target the item's parent. (#219)

packages/core/src/controlledEnvironment/useGetParentOfLinearItem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const useGetGetParentOfLinearItem = () => {
2222
parentLinearIndex = 0;
2323
}
2424

25-
return parent;
25+
return { parent, parentLinearIndex };
2626
},
2727
[environment.linearItems, environment.trees]
2828
);

packages/core/src/controlledEnvironment/useGetViableDragPositions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const useGetViableDragPositions = () => {
1414
const linearItems = environment.linearItems[treeId];
1515
return linearItems
1616
.map<DraggingPosition[]>(({ item, depth }, linearIndex) => {
17-
const parent = getParentOfLinearItem(linearIndex, treeId);
17+
const { parent } = getParentOfLinearItem(linearIndex, treeId);
1818
const childIndex =
1919
environment.items[parent.item].children!.indexOf(item);
2020

packages/core/src/controlledEnvironment/useOnDragOverTreeHandler.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ const getHoveringPosition = (
1818
treeId: string,
1919
items: Record<TreeItemIndex, TreeItem>,
2020
canDropOnFolder?: boolean,
21-
canDropOnNonFolder?: boolean
21+
canDropOnNonFolder?: boolean,
22+
canReorderItems?: boolean
2223
) => {
2324
const hoveringPosition = (clientY - treeTop) / itemHeight;
2425

@@ -38,8 +39,11 @@ const getHoveringPosition = (
3839
const targetItem = items[targetLinearItem.item];
3940
let offset: 'top' | 'bottom' | undefined;
4041

41-
const lineThreshold =
42-
(targetItem?.isFolder && canDropOnFolder) || canDropOnNonFolder ? 0.2 : 0.5;
42+
const lineThreshold = !canReorderItems
43+
? 0
44+
: (targetItem?.isFolder && canDropOnFolder) || canDropOnNonFolder
45+
? 0.2
46+
: 0.5;
4347

4448
if (hoveringPosition % 1 < lineThreshold) {
4549
offset = 'top';
@@ -114,7 +118,8 @@ export const useOnDragOverTreeHandler = (
114118
treeId,
115119
items,
116120
canDropOnFolder,
117-
canDropOnNonFolder
121+
canDropOnNonFolder,
122+
canReorderItems
118123
);
119124

120125
const nextDragCode = outsideContainer
@@ -137,7 +142,21 @@ export const useOnDragOverTreeHandler = (
137142
return;
138143
}
139144

140-
const targetItem = linearItems[treeId][linearIndex];
145+
let targetItem = linearItems[treeId][linearIndex];
146+
const redirectTargetToParent =
147+
!canReorderItems &&
148+
!canDropOnNonFolder &&
149+
!items[targetItem.item].isFolder;
150+
151+
if (redirectTargetToParent) {
152+
const { parentLinearIndex, parent } = getParentOfLinearItem(
153+
linearIndex,
154+
treeId
155+
);
156+
targetItem = parent;
157+
linearIndex = parentLinearIndex;
158+
}
159+
141160
const { depth } = targetItem;
142161
const targetItemData = items[targetItem.item];
143162

@@ -156,7 +175,7 @@ export const useOnDragOverTreeHandler = (
156175
return;
157176
}
158177

159-
const parent = getParentOfLinearItem(linearIndex, treeId);
178+
const { parent } = getParentOfLinearItem(linearIndex, treeId);
160179

161180
if (
162181
draggingItems.some(

packages/core/test/dnd-restrictions.spec.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,25 @@ describe('dnd restrictions', () => {
159159
await test.expectTreeUnchanged();
160160
await test.expectOpenViewState();
161161
});
162+
163+
it('dropping on undroppable nonfolder targets parent', async () => {
164+
const test = await new TestUtil().renderOpenTree({
165+
canReorderItems: false,
166+
canDropOnNonFolder: false,
167+
});
168+
await test.startDrag('aaa');
169+
await test.dragOver('aba');
170+
await test.drop();
171+
await test.expectVisibleItemContents('aa', ['aab', 'aac', 'aad']);
172+
await test.expectVisibleItemContents('ab', [
173+
'aba',
174+
'abb',
175+
'abc',
176+
'abd',
177+
'aaa',
178+
]);
179+
await test.expectOpenViewState();
180+
});
162181
});
163182

164183
describe('item.canMove', () => {

0 commit comments

Comments
 (0)