@react-aria/dnd 3.0.0-alpha.8 → 3.0.0-nightly-641446f65-240905
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DragManager.main.js +432 -0
- package/dist/DragManager.main.js.map +1 -0
- package/dist/DragManager.mjs +423 -0
- package/dist/DragManager.module.js +423 -0
- package/dist/DragManager.module.js.map +1 -0
- package/dist/DragPreview.main.js +59 -0
- package/dist/DragPreview.main.js.map +1 -0
- package/dist/DragPreview.mjs +50 -0
- package/dist/DragPreview.module.js +50 -0
- package/dist/DragPreview.module.js.map +1 -0
- package/dist/ListDropTargetDelegate.main.js +123 -0
- package/dist/ListDropTargetDelegate.main.js.map +1 -0
- package/dist/ListDropTargetDelegate.mjs +118 -0
- package/dist/ListDropTargetDelegate.module.js +118 -0
- package/dist/ListDropTargetDelegate.module.js.map +1 -0
- package/dist/ar-AE.main.js +44 -0
- package/dist/ar-AE.main.js.map +1 -0
- package/dist/ar-AE.mjs +46 -0
- package/dist/ar-AE.module.js +46 -0
- package/dist/ar-AE.module.js.map +1 -0
- package/dist/bg-BG.main.js +44 -0
- package/dist/bg-BG.main.js.map +1 -0
- package/dist/bg-BG.mjs +46 -0
- package/dist/bg-BG.module.js +46 -0
- package/dist/bg-BG.module.js.map +1 -0
- package/dist/constants.main.js +65 -0
- package/dist/constants.main.js.map +1 -0
- package/dist/constants.mjs +53 -0
- package/dist/constants.module.js +53 -0
- package/dist/constants.module.js.map +1 -0
- package/dist/cs-CZ.main.js +45 -0
- package/dist/cs-CZ.main.js.map +1 -0
- package/dist/cs-CZ.mjs +47 -0
- package/dist/cs-CZ.module.js +47 -0
- package/dist/cs-CZ.module.js.map +1 -0
- package/dist/da-DK.main.js +44 -0
- package/dist/da-DK.main.js.map +1 -0
- package/dist/da-DK.mjs +46 -0
- package/dist/da-DK.module.js +46 -0
- package/dist/da-DK.module.js.map +1 -0
- package/dist/de-DE.main.js +44 -0
- package/dist/de-DE.main.js.map +1 -0
- package/dist/de-DE.mjs +46 -0
- package/dist/de-DE.module.js +46 -0
- package/dist/de-DE.module.js.map +1 -0
- package/dist/el-GR.main.js +44 -0
- package/dist/el-GR.main.js.map +1 -0
- package/dist/el-GR.mjs +46 -0
- package/dist/el-GR.module.js +46 -0
- package/dist/el-GR.module.js.map +1 -0
- package/dist/en-US.main.js +44 -0
- package/dist/en-US.main.js.map +1 -0
- package/dist/en-US.mjs +46 -0
- package/dist/en-US.module.js +46 -0
- package/dist/en-US.module.js.map +1 -0
- package/dist/es-ES.main.js +44 -0
- package/dist/es-ES.main.js.map +1 -0
- package/dist/es-ES.mjs +46 -0
- package/dist/es-ES.module.js +46 -0
- package/dist/es-ES.module.js.map +1 -0
- package/dist/et-EE.main.js +44 -0
- package/dist/et-EE.main.js.map +1 -0
- package/dist/et-EE.mjs +46 -0
- package/dist/et-EE.module.js +46 -0
- package/dist/et-EE.module.js.map +1 -0
- package/dist/fi-FI.main.js +44 -0
- package/dist/fi-FI.main.js.map +1 -0
- package/dist/fi-FI.mjs +46 -0
- package/dist/fi-FI.module.js +46 -0
- package/dist/fi-FI.module.js.map +1 -0
- package/dist/fr-FR.main.js +44 -0
- package/dist/fr-FR.main.js.map +1 -0
- package/dist/fr-FR.mjs +46 -0
- package/dist/fr-FR.module.js +46 -0
- package/dist/fr-FR.module.js.map +1 -0
- package/dist/he-IL.main.js +44 -0
- package/dist/he-IL.main.js.map +1 -0
- package/dist/he-IL.mjs +46 -0
- package/dist/he-IL.module.js +46 -0
- package/dist/he-IL.module.js.map +1 -0
- package/dist/hr-HR.main.js +44 -0
- package/dist/hr-HR.main.js.map +1 -0
- package/dist/hr-HR.mjs +46 -0
- package/dist/hr-HR.module.js +46 -0
- package/dist/hr-HR.module.js.map +1 -0
- package/dist/hu-HU.main.js +44 -0
- package/dist/hu-HU.main.js.map +1 -0
- package/dist/hu-HU.mjs +46 -0
- package/dist/hu-HU.module.js +46 -0
- package/dist/hu-HU.module.js.map +1 -0
- package/dist/import.mjs +39 -0
- package/dist/intlStrings.main.js +108 -0
- package/dist/intlStrings.main.js.map +1 -0
- package/dist/intlStrings.mjs +110 -0
- package/dist/intlStrings.module.js +110 -0
- package/dist/intlStrings.module.js.map +1 -0
- package/dist/it-IT.main.js +44 -0
- package/dist/it-IT.main.js.map +1 -0
- package/dist/it-IT.mjs +46 -0
- package/dist/it-IT.module.js +46 -0
- package/dist/it-IT.module.js.map +1 -0
- package/dist/ja-JP.main.js +44 -0
- package/dist/ja-JP.main.js.map +1 -0
- package/dist/ja-JP.mjs +46 -0
- package/dist/ja-JP.module.js +46 -0
- package/dist/ja-JP.module.js.map +1 -0
- package/dist/ko-KR.main.js +44 -0
- package/dist/ko-KR.main.js.map +1 -0
- package/dist/ko-KR.mjs +46 -0
- package/dist/ko-KR.module.js +46 -0
- package/dist/ko-KR.module.js.map +1 -0
- package/dist/lt-LT.main.js +44 -0
- package/dist/lt-LT.main.js.map +1 -0
- package/dist/lt-LT.mjs +46 -0
- package/dist/lt-LT.module.js +46 -0
- package/dist/lt-LT.module.js.map +1 -0
- package/dist/lv-LV.main.js +44 -0
- package/dist/lv-LV.main.js.map +1 -0
- package/dist/lv-LV.mjs +46 -0
- package/dist/lv-LV.module.js +46 -0
- package/dist/lv-LV.module.js.map +1 -0
- package/dist/main.js +38 -1855
- package/dist/main.js.map +1 -1
- package/dist/module.js +24 -1838
- package/dist/module.js.map +1 -1
- package/dist/nb-NO.main.js +44 -0
- package/dist/nb-NO.main.js.map +1 -0
- package/dist/nb-NO.mjs +46 -0
- package/dist/nb-NO.module.js +46 -0
- package/dist/nb-NO.module.js.map +1 -0
- package/dist/nl-NL.main.js +44 -0
- package/dist/nl-NL.main.js.map +1 -0
- package/dist/nl-NL.mjs +46 -0
- package/dist/nl-NL.module.js +46 -0
- package/dist/nl-NL.module.js.map +1 -0
- package/dist/pl-PL.main.js +44 -0
- package/dist/pl-PL.main.js.map +1 -0
- package/dist/pl-PL.mjs +46 -0
- package/dist/pl-PL.module.js +46 -0
- package/dist/pl-PL.module.js.map +1 -0
- package/dist/pt-BR.main.js +44 -0
- package/dist/pt-BR.main.js.map +1 -0
- package/dist/pt-BR.mjs +46 -0
- package/dist/pt-BR.module.js +46 -0
- package/dist/pt-BR.module.js.map +1 -0
- package/dist/pt-PT.main.js +44 -0
- package/dist/pt-PT.main.js.map +1 -0
- package/dist/pt-PT.mjs +46 -0
- package/dist/pt-PT.module.js +46 -0
- package/dist/pt-PT.module.js.map +1 -0
- package/dist/ro-RO.main.js +44 -0
- package/dist/ro-RO.main.js.map +1 -0
- package/dist/ro-RO.mjs +46 -0
- package/dist/ro-RO.module.js +46 -0
- package/dist/ro-RO.module.js.map +1 -0
- package/dist/ru-RU.main.js +44 -0
- package/dist/ru-RU.main.js.map +1 -0
- package/dist/ru-RU.mjs +46 -0
- package/dist/ru-RU.module.js +46 -0
- package/dist/ru-RU.module.js.map +1 -0
- package/dist/sk-SK.main.js +44 -0
- package/dist/sk-SK.main.js.map +1 -0
- package/dist/sk-SK.mjs +46 -0
- package/dist/sk-SK.module.js +46 -0
- package/dist/sk-SK.module.js.map +1 -0
- package/dist/sl-SI.main.js +44 -0
- package/dist/sl-SI.main.js.map +1 -0
- package/dist/sl-SI.mjs +46 -0
- package/dist/sl-SI.module.js +46 -0
- package/dist/sl-SI.module.js.map +1 -0
- package/dist/sr-SP.main.js +44 -0
- package/dist/sr-SP.main.js.map +1 -0
- package/dist/sr-SP.mjs +46 -0
- package/dist/sr-SP.module.js +46 -0
- package/dist/sr-SP.module.js.map +1 -0
- package/dist/sv-SE.main.js +44 -0
- package/dist/sv-SE.main.js.map +1 -0
- package/dist/sv-SE.mjs +46 -0
- package/dist/sv-SE.module.js +46 -0
- package/dist/sv-SE.module.js.map +1 -0
- package/dist/tr-TR.main.js +44 -0
- package/dist/tr-TR.main.js.map +1 -0
- package/dist/tr-TR.mjs +46 -0
- package/dist/tr-TR.module.js +46 -0
- package/dist/tr-TR.module.js.map +1 -0
- package/dist/types.d.ts +184 -32
- package/dist/types.d.ts.map +1 -1
- package/dist/uk-UA.main.js +44 -0
- package/dist/uk-UA.main.js.map +1 -0
- package/dist/uk-UA.mjs +46 -0
- package/dist/uk-UA.module.js +46 -0
- package/dist/uk-UA.module.js.map +1 -0
- package/dist/useAutoScroll.main.js +89 -0
- package/dist/useAutoScroll.main.js.map +1 -0
- package/dist/useAutoScroll.mjs +84 -0
- package/dist/useAutoScroll.module.js +84 -0
- package/dist/useAutoScroll.module.js.map +1 -0
- package/dist/useClipboard.main.js +107 -0
- package/dist/useClipboard.main.js.map +1 -0
- package/dist/useClipboard.mjs +102 -0
- package/dist/useClipboard.module.js +102 -0
- package/dist/useClipboard.module.js.map +1 -0
- package/dist/useDrag.main.js +286 -0
- package/dist/useDrag.main.js.map +1 -0
- package/dist/useDrag.mjs +281 -0
- package/dist/useDrag.module.js +281 -0
- package/dist/useDrag.module.js.map +1 -0
- package/dist/useDraggableCollection.main.js +27 -0
- package/dist/useDraggableCollection.main.js.map +1 -0
- package/dist/useDraggableCollection.mjs +22 -0
- package/dist/useDraggableCollection.module.js +22 -0
- package/dist/useDraggableCollection.module.js.map +1 -0
- package/dist/useDraggableItem.main.js +128 -0
- package/dist/useDraggableItem.main.js.map +1 -0
- package/dist/useDraggableItem.mjs +123 -0
- package/dist/useDraggableItem.module.js +123 -0
- package/dist/useDraggableItem.module.js.map +1 -0
- package/dist/useDrop.main.js +299 -0
- package/dist/useDrop.main.js.map +1 -0
- package/dist/useDrop.mjs +294 -0
- package/dist/useDrop.module.js +294 -0
- package/dist/useDrop.module.js.map +1 -0
- package/dist/useDropIndicator.main.js +93 -0
- package/dist/useDropIndicator.main.js.map +1 -0
- package/dist/useDropIndicator.mjs +88 -0
- package/dist/useDropIndicator.module.js +88 -0
- package/dist/useDropIndicator.module.js.map +1 -0
- package/dist/useDroppableCollection.main.js +592 -0
- package/dist/useDroppableCollection.main.js.map +1 -0
- package/dist/useDroppableCollection.mjs +587 -0
- package/dist/useDroppableCollection.module.js +587 -0
- package/dist/useDroppableCollection.module.js.map +1 -0
- package/dist/useDroppableItem.main.js +79 -0
- package/dist/useDroppableItem.main.js.map +1 -0
- package/dist/useDroppableItem.mjs +74 -0
- package/dist/useDroppableItem.module.js +74 -0
- package/dist/useDroppableItem.module.js.map +1 -0
- package/dist/useVirtualDrop.main.js +56 -0
- package/dist/useVirtualDrop.main.js.map +1 -0
- package/dist/useVirtualDrop.mjs +51 -0
- package/dist/useVirtualDrop.module.js +51 -0
- package/dist/useVirtualDrop.module.js.map +1 -0
- package/dist/utils.main.js +283 -0
- package/dist/utils.main.js.map +1 -0
- package/dist/utils.mjs +255 -0
- package/dist/utils.module.js +255 -0
- package/dist/utils.module.js.map +1 -0
- package/dist/zh-CN.main.js +44 -0
- package/dist/zh-CN.main.js.map +1 -0
- package/dist/zh-CN.mjs +46 -0
- package/dist/zh-CN.module.js +46 -0
- package/dist/zh-CN.module.js.map +1 -0
- package/dist/zh-TW.main.js +44 -0
- package/dist/zh-TW.main.js.map +1 -0
- package/dist/zh-TW.mjs +46 -0
- package/dist/zh-TW.module.js +46 -0
- package/dist/zh-TW.module.js.map +1 -0
- package/package.json +20 -16
- package/src/DragManager.ts +87 -52
- package/src/DragPreview.tsx +54 -0
- package/src/ListDropTargetDelegate.ts +173 -0
- package/src/constants.ts +2 -0
- package/src/index.ts +56 -7
- package/src/useAutoScroll.ts +26 -6
- package/src/useClipboard.ts +65 -59
- package/src/useDrag.ts +195 -61
- package/src/useDraggableCollection.ts +29 -0
- package/src/useDraggableItem.ts +106 -15
- package/src/useDrop.ts +273 -93
- package/src/useDropIndicator.ts +49 -23
- package/src/useDroppableCollection.ts +317 -122
- package/src/useDroppableItem.ts +35 -19
- package/src/useVirtualDrop.ts +5 -5
- package/src/utils.ts +92 -17
- package/LICENSE +0 -201
|
@@ -10,23 +10,47 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
clearGlobalDnDState,
|
|
15
|
+
DIRECTORY_DRAG_TYPE,
|
|
16
|
+
droppableCollectionMap,
|
|
17
|
+
getTypes,
|
|
18
|
+
globalDndState,
|
|
19
|
+
isInternalDropOperation,
|
|
20
|
+
setDropCollectionRef
|
|
21
|
+
} from './utils';
|
|
22
|
+
import {
|
|
23
|
+
Collection,
|
|
24
|
+
DropEvent,
|
|
25
|
+
DropOperation,
|
|
26
|
+
DroppableCollectionDropEvent,
|
|
27
|
+
DroppableCollectionProps,
|
|
28
|
+
DropPosition,
|
|
29
|
+
DropTarget,
|
|
30
|
+
DropTargetDelegate,
|
|
31
|
+
Key,
|
|
32
|
+
KeyboardDelegate,
|
|
33
|
+
Node,
|
|
34
|
+
RefObject
|
|
35
|
+
} from '@react-types/shared';
|
|
14
36
|
import * as DragManager from './DragManager';
|
|
15
37
|
import {DroppableCollectionState} from '@react-stately/dnd';
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {mergeProps, useLayoutEffect} from '@react-aria/utils';
|
|
38
|
+
import {HTMLAttributes, useCallback, useEffect, useRef} from 'react';
|
|
39
|
+
import {mergeProps, useId, useLayoutEffect} from '@react-aria/utils';
|
|
19
40
|
import {setInteractionModality} from '@react-aria/interactions';
|
|
20
41
|
import {useAutoScroll} from './useAutoScroll';
|
|
21
42
|
import {useDrop} from './useDrop';
|
|
22
|
-
import {
|
|
43
|
+
import {useLocale} from '@react-aria/i18n';
|
|
23
44
|
|
|
24
|
-
interface DroppableCollectionOptions extends DroppableCollectionProps {
|
|
45
|
+
export interface DroppableCollectionOptions extends DroppableCollectionProps {
|
|
46
|
+
/** A delegate object that implements behavior for keyboard focus movement. */
|
|
25
47
|
keyboardDelegate: KeyboardDelegate,
|
|
26
|
-
|
|
48
|
+
/** A delegate object that provides drop targets for pointer coordinates within the collection. */
|
|
49
|
+
dropTargetDelegate: DropTargetDelegate
|
|
27
50
|
}
|
|
28
51
|
|
|
29
|
-
interface DroppableCollectionResult {
|
|
52
|
+
export interface DroppableCollectionResult {
|
|
53
|
+
/** Props for the collection element. */
|
|
30
54
|
collectionProps: HTMLAttributes<HTMLElement>
|
|
31
55
|
}
|
|
32
56
|
|
|
@@ -34,12 +58,20 @@ interface DroppingState {
|
|
|
34
58
|
collection: Collection<Node<unknown>>,
|
|
35
59
|
focusedKey: Key,
|
|
36
60
|
selectedKeys: Set<Key>,
|
|
37
|
-
|
|
61
|
+
target: DropTarget,
|
|
62
|
+
draggingKeys: Set<Key>,
|
|
63
|
+
isInternal: boolean,
|
|
64
|
+
timeout: ReturnType<typeof setTimeout>
|
|
38
65
|
}
|
|
39
66
|
|
|
40
67
|
const DROP_POSITIONS: DropPosition[] = ['before', 'on', 'after'];
|
|
68
|
+
const DROP_POSITIONS_RTL: DropPosition[] = ['after', 'on', 'before'];
|
|
41
69
|
|
|
42
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Handles drop interactions for a collection component, with support for traditional mouse and touch
|
|
72
|
+
* based drag and drop, in addition to full parity for keyboard and screen reader users.
|
|
73
|
+
*/
|
|
74
|
+
export function useDroppableCollection(props: DroppableCollectionOptions, state: DroppableCollectionState, ref: RefObject<HTMLElement | null>): DroppableCollectionResult {
|
|
43
75
|
let localState = useRef({
|
|
44
76
|
props,
|
|
45
77
|
state,
|
|
@@ -49,46 +81,113 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
49
81
|
localState.props = props;
|
|
50
82
|
localState.state = state;
|
|
51
83
|
|
|
84
|
+
let defaultOnDrop = useCallback(async (e: DroppableCollectionDropEvent) => {
|
|
85
|
+
let {
|
|
86
|
+
onInsert,
|
|
87
|
+
onRootDrop,
|
|
88
|
+
onItemDrop,
|
|
89
|
+
onReorder,
|
|
90
|
+
acceptedDragTypes = 'all',
|
|
91
|
+
shouldAcceptItemDrop
|
|
92
|
+
} = localState.props;
|
|
93
|
+
|
|
94
|
+
let {draggingKeys} = globalDndState;
|
|
95
|
+
let isInternal = isInternalDropOperation(ref);
|
|
96
|
+
let {
|
|
97
|
+
target,
|
|
98
|
+
dropOperation,
|
|
99
|
+
items
|
|
100
|
+
} = e;
|
|
101
|
+
|
|
102
|
+
let filteredItems = items;
|
|
103
|
+
if (acceptedDragTypes !== 'all' || shouldAcceptItemDrop) {
|
|
104
|
+
filteredItems = items.filter(item => {
|
|
105
|
+
let itemTypes: Set<string | symbol>;
|
|
106
|
+
if (item.kind === 'directory') {
|
|
107
|
+
itemTypes = new Set([DIRECTORY_DRAG_TYPE]);
|
|
108
|
+
} else {
|
|
109
|
+
itemTypes = item.kind === 'file' ? new Set([item.type]) : item.types;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (acceptedDragTypes === 'all' || acceptedDragTypes.some(type => itemTypes.has(type))) {
|
|
113
|
+
// If we are performing a on item drop, check if the item in question accepts the dropped item since the item may have heavier restrictions
|
|
114
|
+
// than the droppable collection itself
|
|
115
|
+
if (target.type === 'item' && target.dropPosition === 'on' && shouldAcceptItemDrop) {
|
|
116
|
+
return shouldAcceptItemDrop(target, itemTypes);
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return false;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (filteredItems.length > 0) {
|
|
126
|
+
if (target.type === 'root' && onRootDrop) {
|
|
127
|
+
await onRootDrop({items: filteredItems, dropOperation});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (target.type === 'item') {
|
|
131
|
+
if (target.dropPosition === 'on' && onItemDrop) {
|
|
132
|
+
await onItemDrop({items: filteredItems, dropOperation, isInternal, target});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (target.dropPosition !== 'on') {
|
|
136
|
+
if (!isInternal && onInsert) {
|
|
137
|
+
await onInsert({items: filteredItems, dropOperation, target});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (isInternal && onReorder) {
|
|
141
|
+
await onReorder({keys: draggingKeys, dropOperation, target});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}, [localState, ref]);
|
|
147
|
+
|
|
52
148
|
let autoScroll = useAutoScroll(ref);
|
|
53
149
|
let {dropProps} = useDrop({
|
|
54
150
|
ref,
|
|
55
|
-
onDropEnter(
|
|
56
|
-
|
|
57
|
-
state.setTarget(target);
|
|
151
|
+
onDropEnter() {
|
|
152
|
+
state.setTarget(localState.nextTarget);
|
|
58
153
|
},
|
|
59
154
|
onDropMove(e) {
|
|
60
155
|
state.setTarget(localState.nextTarget);
|
|
61
156
|
autoScroll.move(e.x, e.y);
|
|
62
157
|
},
|
|
63
158
|
getDropOperationForPoint(types, allowedOperations, x, y) {
|
|
64
|
-
let
|
|
159
|
+
let {draggingKeys, dropCollectionRef} = globalDndState;
|
|
160
|
+
let isInternal = isInternalDropOperation(ref);
|
|
161
|
+
let isValidDropTarget = (target) => state.getDropOperation({target, types, allowedOperations, isInternal, draggingKeys}) !== 'cancel';
|
|
162
|
+
let target = props.dropTargetDelegate.getDropTargetFromPoint(x, y, isValidDropTarget);
|
|
65
163
|
if (!target) {
|
|
66
164
|
localState.dropOperation = 'cancel';
|
|
67
165
|
localState.nextTarget = null;
|
|
68
166
|
return 'cancel';
|
|
69
167
|
}
|
|
70
168
|
|
|
71
|
-
|
|
72
|
-
localState.nextTarget = target;
|
|
73
|
-
return localState.dropOperation;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
localState.dropOperation = state.getDropOperation(target, types, allowedOperations);
|
|
169
|
+
localState.dropOperation = state.getDropOperation({target, types, allowedOperations, isInternal, draggingKeys});
|
|
77
170
|
|
|
78
171
|
// If the target doesn't accept the drop, see if the root accepts it instead.
|
|
79
172
|
if (localState.dropOperation === 'cancel') {
|
|
80
173
|
let rootTarget: DropTarget = {type: 'root'};
|
|
81
|
-
let dropOperation = state.getDropOperation(rootTarget, types, allowedOperations);
|
|
174
|
+
let dropOperation = state.getDropOperation({target: rootTarget, types, allowedOperations, isInternal, draggingKeys});
|
|
82
175
|
if (dropOperation !== 'cancel') {
|
|
83
176
|
target = rootTarget;
|
|
84
177
|
localState.dropOperation = dropOperation;
|
|
85
178
|
}
|
|
86
179
|
}
|
|
87
180
|
|
|
181
|
+
// Only set dropCollectionRef if there is a valid drop target since we cleanup dropCollectionRef in onDropExit
|
|
182
|
+
// which only runs when leaving a valid drop target or if the dropEffect become none (mouse dnd only).
|
|
183
|
+
if (target && localState.dropOperation !== 'cancel' && ref?.current !== dropCollectionRef?.current) {
|
|
184
|
+
setDropCollectionRef(ref);
|
|
185
|
+
}
|
|
88
186
|
localState.nextTarget = localState.dropOperation === 'cancel' ? null : target;
|
|
89
187
|
return localState.dropOperation;
|
|
90
188
|
},
|
|
91
189
|
onDropExit() {
|
|
190
|
+
setDropCollectionRef(undefined);
|
|
92
191
|
state.setTarget(null);
|
|
93
192
|
autoScroll.stop();
|
|
94
193
|
},
|
|
@@ -103,29 +202,112 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
103
202
|
}
|
|
104
203
|
},
|
|
105
204
|
onDrop(e) {
|
|
106
|
-
|
|
205
|
+
setDropCollectionRef(ref);
|
|
206
|
+
if (state.target) {
|
|
107
207
|
onDrop(e, state.target);
|
|
108
208
|
}
|
|
209
|
+
|
|
210
|
+
// If there wasn't a collection being tracked as a dragged collection, then we are in a case where a non RSP drag is dropped on a
|
|
211
|
+
// RSP collection and thus we don't need to preserve the global DnD state for onDragEnd
|
|
212
|
+
let {draggingCollectionRef} = globalDndState;
|
|
213
|
+
if (draggingCollectionRef == null) {
|
|
214
|
+
clearGlobalDnDState();
|
|
215
|
+
}
|
|
109
216
|
}
|
|
110
217
|
});
|
|
111
218
|
|
|
112
219
|
let droppingState = useRef<DroppingState>(null);
|
|
113
|
-
let
|
|
220
|
+
let updateFocusAfterDrop = useCallback(() => {
|
|
114
221
|
let {state} = localState;
|
|
222
|
+
if (droppingState.current) {
|
|
223
|
+
let {
|
|
224
|
+
target,
|
|
225
|
+
collection: prevCollection,
|
|
226
|
+
selectedKeys: prevSelectedKeys,
|
|
227
|
+
focusedKey: prevFocusedKey,
|
|
228
|
+
isInternal,
|
|
229
|
+
draggingKeys
|
|
230
|
+
} = droppingState.current;
|
|
231
|
+
|
|
232
|
+
// If an insert occurs during a drop, we want to immediately select these items to give
|
|
233
|
+
// feedback to the user that a drop occurred. Only do this if the selection didn't change
|
|
234
|
+
// since the drop started so we don't override if the user or application did something.
|
|
235
|
+
if (
|
|
236
|
+
state.collection.size > prevCollection.size &&
|
|
237
|
+
state.selectionManager.isSelectionEqual(prevSelectedKeys)
|
|
238
|
+
) {
|
|
239
|
+
let newKeys = new Set<Key>();
|
|
240
|
+
for (let key of state.collection.getKeys()) {
|
|
241
|
+
if (!prevCollection.getItem(key)) {
|
|
242
|
+
newKeys.add(key);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
state.selectionManager.setSelectedKeys(newKeys);
|
|
115
247
|
|
|
116
|
-
|
|
117
|
-
|
|
248
|
+
// If the focused item didn't change since the drop occurred, also focus the first
|
|
249
|
+
// inserted item. If selection is disabled, then also show the focus ring so there
|
|
250
|
+
// is some indication that items were added.
|
|
251
|
+
if (state.selectionManager.focusedKey === prevFocusedKey) {
|
|
252
|
+
let first = newKeys.keys().next().value;
|
|
253
|
+
let item = state.collection.getItem(first);
|
|
254
|
+
|
|
255
|
+
// If this is a cell, focus the parent row.
|
|
256
|
+
if (item?.type === 'cell') {
|
|
257
|
+
first = item.parentKey;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
state.selectionManager.setFocusedKey(first);
|
|
261
|
+
|
|
262
|
+
if (state.selectionManager.selectionMode === 'none') {
|
|
263
|
+
setInteractionModality('keyboard');
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
} else if (
|
|
267
|
+
state.selectionManager.focusedKey === prevFocusedKey &&
|
|
268
|
+
isInternal &&
|
|
269
|
+
target.type === 'item' &&
|
|
270
|
+
target.dropPosition !== 'on' &&
|
|
271
|
+
draggingKeys.has(state.collection.getItem(prevFocusedKey)?.parentKey)
|
|
272
|
+
) {
|
|
273
|
+
// Focus row instead of cell when reordering.
|
|
274
|
+
state.selectionManager.setFocusedKey(state.collection.getItem(prevFocusedKey).parentKey);
|
|
275
|
+
setInteractionModality('keyboard');
|
|
276
|
+
} else if (
|
|
277
|
+
state.selectionManager.focusedKey === prevFocusedKey &&
|
|
278
|
+
target.type === 'item' &&
|
|
279
|
+
target.dropPosition === 'on' &&
|
|
280
|
+
state.collection.getItem(target.key) != null
|
|
281
|
+
) {
|
|
282
|
+
// If focus didn't move already (e.g. due to an insert), and the user dropped on an item,
|
|
283
|
+
// focus that item and show the focus ring to give the user feedback that the drop occurred.
|
|
284
|
+
// Also show the focus ring if the focused key is not selected, e.g. in case of a reorder.
|
|
285
|
+
state.selectionManager.setFocusedKey(target.key);
|
|
286
|
+
setInteractionModality('keyboard');
|
|
287
|
+
} else if (!state.selectionManager.isSelected(state.selectionManager.focusedKey)) {
|
|
288
|
+
setInteractionModality('keyboard');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
state.selectionManager.setFocused(true);
|
|
292
|
+
}
|
|
293
|
+
}, [localState]);
|
|
118
294
|
|
|
295
|
+
let onDrop = useCallback((e: DropEvent, target: DropTarget) => {
|
|
296
|
+
let {state} = localState;
|
|
297
|
+
|
|
119
298
|
// Save some state of the collection/selection before the drop occurs so we can compare later.
|
|
120
|
-
let focusedKey = state.selectionManager.focusedKey;
|
|
121
299
|
droppingState.current = {
|
|
122
300
|
timeout: null,
|
|
123
|
-
focusedKey,
|
|
301
|
+
focusedKey: state.selectionManager.focusedKey,
|
|
124
302
|
collection: state.collection,
|
|
125
|
-
selectedKeys: state.selectionManager.selectedKeys
|
|
303
|
+
selectedKeys: state.selectionManager.selectedKeys,
|
|
304
|
+
draggingKeys: globalDndState.draggingKeys,
|
|
305
|
+
isInternal: isInternalDropOperation(ref),
|
|
306
|
+
target
|
|
126
307
|
};
|
|
127
308
|
|
|
128
|
-
localState.props.onDrop
|
|
309
|
+
let onDropFn = localState.props.onDrop || defaultOnDrop;
|
|
310
|
+
onDropFn({
|
|
129
311
|
type: 'drop',
|
|
130
312
|
x: e.x, // todo
|
|
131
313
|
y: e.y,
|
|
@@ -135,27 +317,13 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
135
317
|
});
|
|
136
318
|
|
|
137
319
|
// Wait for a short time period after the onDrop is called to allow the data to be read asynchronously
|
|
138
|
-
// and for React to re-render. If
|
|
139
|
-
//
|
|
140
|
-
// selecting and focusing those items themselves.
|
|
320
|
+
// and for React to re-render. If the collection didn't already change during this time (handled below),
|
|
321
|
+
// update the focused key here.
|
|
141
322
|
droppingState.current.timeout = setTimeout(() => {
|
|
142
|
-
|
|
143
|
-
// focus that item and show the focus ring to give the user feedback that the drop occurred.
|
|
144
|
-
// Also show the focus ring if the focused key is not selected, e.g. in case of a reorder.
|
|
145
|
-
let {state} = localState;
|
|
146
|
-
if (state.selectionManager.focusedKey === focusedKey) {
|
|
147
|
-
if (target.type === 'item' && target.dropPosition === 'on' && state.collection.getItem(target.key) != null) {
|
|
148
|
-
state.selectionManager.setFocusedKey(target.key);
|
|
149
|
-
state.selectionManager.setFocused(true);
|
|
150
|
-
setInteractionModality('keyboard');
|
|
151
|
-
} else if (!state.selectionManager.isSelected(focusedKey)) {
|
|
152
|
-
setInteractionModality('keyboard');
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
323
|
+
updateFocusAfterDrop();
|
|
156
324
|
droppingState.current = null;
|
|
157
325
|
}, 50);
|
|
158
|
-
}, [localState]);
|
|
326
|
+
}, [localState, defaultOnDrop, ref, updateFocusAfterDrop]);
|
|
159
327
|
|
|
160
328
|
// eslint-disable-next-line arrow-body-style
|
|
161
329
|
useEffect(() => {
|
|
@@ -167,42 +335,15 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
167
335
|
}, []);
|
|
168
336
|
|
|
169
337
|
useLayoutEffect(() => {
|
|
170
|
-
// If
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (
|
|
174
|
-
droppingState.current &&
|
|
175
|
-
state.selectionManager.isFocused &&
|
|
176
|
-
state.collection.size > droppingState.current.collection.size &&
|
|
177
|
-
state.selectionManager.isSelectionEqual(droppingState.current.selectedKeys)
|
|
178
|
-
) {
|
|
179
|
-
let newKeys = new Set<Key>();
|
|
180
|
-
for (let key of state.collection.getKeys()) {
|
|
181
|
-
if (!droppingState.current.collection.getItem(key)) {
|
|
182
|
-
newKeys.add(key);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
state.selectionManager.setSelectedKeys(newKeys);
|
|
187
|
-
|
|
188
|
-
// If the focused item didn't change since the drop occurred, also focus the first
|
|
189
|
-
// inserted item. If selection is disabled, then also show the focus ring so there
|
|
190
|
-
// is some indication that items were added.
|
|
191
|
-
if (state.selectionManager.focusedKey === droppingState.current.focusedKey) {
|
|
192
|
-
let first = newKeys.keys().next().value;
|
|
193
|
-
state.selectionManager.setFocusedKey(first);
|
|
194
|
-
|
|
195
|
-
if (state.selectionManager.selectionMode === 'none') {
|
|
196
|
-
setInteractionModality('keyboard');
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
droppingState.current = null;
|
|
338
|
+
// If the collection changed after a drop, update the focused key.
|
|
339
|
+
if (droppingState.current && state.collection !== droppingState.current.collection) {
|
|
340
|
+
updateFocusAfterDrop();
|
|
201
341
|
}
|
|
202
342
|
});
|
|
203
343
|
|
|
344
|
+
let {direction} = useLocale();
|
|
204
345
|
useEffect(() => {
|
|
205
|
-
let getNextTarget = (target: DropTarget, wrap = true): DropTarget => {
|
|
346
|
+
let getNextTarget = (target: DropTarget, wrap = true, horizontal = false): DropTarget => {
|
|
206
347
|
if (!target) {
|
|
207
348
|
return {
|
|
208
349
|
type: 'root'
|
|
@@ -210,26 +351,38 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
210
351
|
}
|
|
211
352
|
|
|
212
353
|
let {keyboardDelegate} = localState.props;
|
|
213
|
-
let nextKey
|
|
214
|
-
|
|
215
|
-
: keyboardDelegate.
|
|
216
|
-
|
|
354
|
+
let nextKey: Key;
|
|
355
|
+
if (target?.type === 'item') {
|
|
356
|
+
nextKey = horizontal ? keyboardDelegate.getKeyRightOf(target.key) : keyboardDelegate.getKeyBelow(target.key);
|
|
357
|
+
} else {
|
|
358
|
+
nextKey = horizontal && direction === 'rtl' ? keyboardDelegate.getLastKey() : keyboardDelegate.getFirstKey();
|
|
359
|
+
}
|
|
360
|
+
let dropPositions = horizontal && direction === 'rtl' ? DROP_POSITIONS_RTL : DROP_POSITIONS;
|
|
361
|
+
let dropPosition: DropPosition = dropPositions[0];
|
|
217
362
|
|
|
218
363
|
if (target.type === 'item') {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
364
|
+
// If the the keyboard delegate returned the next key in the collection,
|
|
365
|
+
// first try the other positions in the current key. Otherwise (e.g. in a grid layout),
|
|
366
|
+
// jump to the same drop position in the new key.
|
|
367
|
+
let nextCollectionKey = horizontal && direction === 'rtl' ? localState.state.collection.getKeyBefore(target.key) : localState.state.collection.getKeyAfter(target.key);
|
|
368
|
+
if (nextKey == null || nextKey === nextCollectionKey) {
|
|
369
|
+
let positionIndex = dropPositions.indexOf(target.dropPosition);
|
|
370
|
+
let nextDropPosition = dropPositions[positionIndex + 1];
|
|
371
|
+
if (positionIndex < dropPositions.length - 1 && !(nextDropPosition === dropPositions[2] && nextKey != null)) {
|
|
372
|
+
return {
|
|
373
|
+
type: 'item',
|
|
374
|
+
key: target.key,
|
|
375
|
+
dropPosition: nextDropPosition
|
|
376
|
+
};
|
|
377
|
+
}
|
|
228
378
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
379
|
+
// If the last drop position was 'after', then 'before' on the next key is equivalent.
|
|
380
|
+
// Switch to 'on' instead.
|
|
381
|
+
if (target.dropPosition === dropPositions[2]) {
|
|
382
|
+
dropPosition = 'on';
|
|
383
|
+
}
|
|
384
|
+
} else {
|
|
385
|
+
dropPosition = target.dropPosition;
|
|
233
386
|
}
|
|
234
387
|
}
|
|
235
388
|
|
|
@@ -250,28 +403,40 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
250
403
|
};
|
|
251
404
|
};
|
|
252
405
|
|
|
253
|
-
let getPreviousTarget = (target: DropTarget, wrap = true): DropTarget => {
|
|
406
|
+
let getPreviousTarget = (target: DropTarget, wrap = true, horizontal = false): DropTarget => {
|
|
254
407
|
let {keyboardDelegate} = localState.props;
|
|
255
|
-
let nextKey
|
|
256
|
-
|
|
257
|
-
: keyboardDelegate.
|
|
258
|
-
|
|
408
|
+
let nextKey: Key;
|
|
409
|
+
if (target?.type === 'item') {
|
|
410
|
+
nextKey = horizontal ? keyboardDelegate.getKeyLeftOf(target.key) : keyboardDelegate.getKeyAbove(target.key);
|
|
411
|
+
} else {
|
|
412
|
+
nextKey = horizontal && direction === 'rtl' ? keyboardDelegate.getFirstKey() : keyboardDelegate.getLastKey();
|
|
413
|
+
}
|
|
414
|
+
let dropPositions = horizontal && direction === 'rtl' ? DROP_POSITIONS_RTL : DROP_POSITIONS;
|
|
415
|
+
let dropPosition: DropPosition = !target || target.type === 'root' ? dropPositions[2] : 'on';
|
|
259
416
|
|
|
260
417
|
if (target?.type === 'item') {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
418
|
+
// If the the keyboard delegate returned the previous key in the collection,
|
|
419
|
+
// first try the other positions in the current key. Otherwise (e.g. in a grid layout),
|
|
420
|
+
// jump to the same drop position in the new key.
|
|
421
|
+
let prevCollectionKey = horizontal && direction === 'rtl' ? localState.state.collection.getKeyAfter(target.key) : localState.state.collection.getKeyBefore(target.key);
|
|
422
|
+
if (nextKey == null || nextKey === prevCollectionKey) {
|
|
423
|
+
let positionIndex = dropPositions.indexOf(target.dropPosition);
|
|
424
|
+
let nextDropPosition = dropPositions[positionIndex - 1];
|
|
425
|
+
if (positionIndex > 0 && nextDropPosition !== dropPositions[2]) {
|
|
426
|
+
return {
|
|
427
|
+
type: 'item',
|
|
428
|
+
key: target.key,
|
|
429
|
+
dropPosition: nextDropPosition
|
|
430
|
+
};
|
|
431
|
+
}
|
|
270
432
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
433
|
+
// If the last drop position was 'before', then 'after' on the previous key is equivalent.
|
|
434
|
+
// Switch to 'on' instead.
|
|
435
|
+
if (target.dropPosition === dropPositions[0]) {
|
|
436
|
+
dropPosition = 'on';
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
dropPosition = target.dropPosition;
|
|
275
440
|
}
|
|
276
441
|
}
|
|
277
442
|
|
|
@@ -301,13 +466,15 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
301
466
|
): DropTarget => {
|
|
302
467
|
let seenRoot = 0;
|
|
303
468
|
let operation: DropOperation;
|
|
469
|
+
let {draggingKeys} = globalDndState;
|
|
470
|
+
let isInternal = isInternalDropOperation(ref);
|
|
304
471
|
do {
|
|
305
472
|
let nextTarget = getNextTarget(target, wrap);
|
|
306
473
|
if (!nextTarget) {
|
|
307
474
|
return null;
|
|
308
475
|
}
|
|
309
476
|
target = nextTarget;
|
|
310
|
-
operation = localState.state.getDropOperation(nextTarget, types, allowedDropOperations);
|
|
477
|
+
operation = localState.state.getDropOperation({target: nextTarget, types, allowedOperations: allowedDropOperations, isInternal, draggingKeys});
|
|
311
478
|
if (target.type === 'root') {
|
|
312
479
|
seenRoot++;
|
|
313
480
|
}
|
|
@@ -326,9 +493,12 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
326
493
|
|
|
327
494
|
return DragManager.registerDropTarget({
|
|
328
495
|
element: ref.current,
|
|
496
|
+
preventFocusOnDrop: true,
|
|
329
497
|
getDropOperation(types, allowedOperations) {
|
|
330
498
|
if (localState.state.target) {
|
|
331
|
-
|
|
499
|
+
let {draggingKeys} = globalDndState;
|
|
500
|
+
let isInternal = isInternalDropOperation(ref);
|
|
501
|
+
return localState.state.getDropOperation({target: localState.state.target, types, allowedOperations, isInternal, draggingKeys});
|
|
332
502
|
}
|
|
333
503
|
|
|
334
504
|
// Check if any of the targets accept the drop.
|
|
@@ -340,6 +510,8 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
340
510
|
let types = getTypes(drag.items);
|
|
341
511
|
let selectionManager = localState.state.selectionManager;
|
|
342
512
|
let target: DropTarget;
|
|
513
|
+
// Update the drop collection ref tracker for useDroppableItem's getDropOperation isInternal check
|
|
514
|
+
setDropCollectionRef(ref);
|
|
343
515
|
|
|
344
516
|
// When entering the droppable collection for the first time, the default drop target
|
|
345
517
|
// is after the focused key.
|
|
@@ -372,8 +544,10 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
372
544
|
dropPosition
|
|
373
545
|
};
|
|
374
546
|
|
|
547
|
+
let {draggingKeys} = globalDndState;
|
|
548
|
+
let isInternal = isInternalDropOperation(ref);
|
|
375
549
|
// If the default target is not valid, find the next one that is.
|
|
376
|
-
if (localState.state.getDropOperation(target, types, drag.allowedDropOperations) === 'cancel') {
|
|
550
|
+
if (localState.state.getDropOperation({target, types, allowedOperations: drag.allowedDropOperations, isInternal, draggingKeys}) === 'cancel') {
|
|
377
551
|
target = nextValidTarget(target, types, drag.allowedDropOperations, getNextTarget, false)
|
|
378
552
|
?? nextValidTarget(target, types, drag.allowedDropOperations, getPreviousTarget, false);
|
|
379
553
|
}
|
|
@@ -387,6 +561,7 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
387
561
|
localState.state.setTarget(target);
|
|
388
562
|
},
|
|
389
563
|
onDropExit() {
|
|
564
|
+
setDropCollectionRef(undefined);
|
|
390
565
|
localState.state.setTarget(null);
|
|
391
566
|
},
|
|
392
567
|
onDropTargetEnter(target) {
|
|
@@ -407,7 +582,8 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
407
582
|
}
|
|
408
583
|
},
|
|
409
584
|
onDrop(e, target) {
|
|
410
|
-
|
|
585
|
+
setDropCollectionRef(ref);
|
|
586
|
+
if (localState.state.target) {
|
|
411
587
|
onDrop(e, target || localState.state.target);
|
|
412
588
|
}
|
|
413
589
|
},
|
|
@@ -429,6 +605,20 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
429
605
|
}
|
|
430
606
|
break;
|
|
431
607
|
}
|
|
608
|
+
case 'ArrowLeft': {
|
|
609
|
+
if (keyboardDelegate.getKeyLeftOf) {
|
|
610
|
+
let target = nextValidTarget(localState.state.target, types, drag.allowedDropOperations, (target, wrap) => getPreviousTarget(target, wrap, true));
|
|
611
|
+
localState.state.setTarget(target);
|
|
612
|
+
}
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
615
|
+
case 'ArrowRight': {
|
|
616
|
+
if (keyboardDelegate.getKeyRightOf) {
|
|
617
|
+
let target = nextValidTarget(localState.state.target, types, drag.allowedDropOperations, (target, wrap) => getNextTarget(target, wrap, true));
|
|
618
|
+
localState.state.setTarget(target);
|
|
619
|
+
}
|
|
620
|
+
break;
|
|
621
|
+
}
|
|
432
622
|
case 'Home': {
|
|
433
623
|
if (keyboardDelegate.getFirstKey) {
|
|
434
624
|
let target = nextValidTarget(null, types, drag.allowedDropOperations, getNextTarget);
|
|
@@ -471,7 +661,9 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
471
661
|
|
|
472
662
|
// If the target does not accept the drop, find the next valid target.
|
|
473
663
|
// If no next valid target, find the previous valid target.
|
|
474
|
-
let
|
|
664
|
+
let {draggingCollectionRef, draggingKeys} = globalDndState;
|
|
665
|
+
let isInternal = draggingCollectionRef?.current === ref?.current;
|
|
666
|
+
let operation = localState.state.getDropOperation({target, types, allowedOperations: drag.allowedDropOperations, isInternal, draggingKeys});
|
|
475
667
|
if (operation === 'cancel') {
|
|
476
668
|
target = nextValidTarget(target, types, drag.allowedDropOperations, getNextTarget, false)
|
|
477
669
|
?? nextValidTarget(target, types, drag.allowedDropOperations, getPreviousTarget, false);
|
|
@@ -513,7 +705,9 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
513
705
|
|
|
514
706
|
// If the target does not accept the drop, find the previous valid target.
|
|
515
707
|
// If no next valid target, find the next valid target.
|
|
516
|
-
let
|
|
708
|
+
let {draggingKeys} = globalDndState;
|
|
709
|
+
let isInternal = isInternalDropOperation(ref);
|
|
710
|
+
let operation = localState.state.getDropOperation({target, types, allowedOperations: drag.allowedDropOperations, isInternal, draggingKeys});
|
|
517
711
|
if (operation === 'cancel') {
|
|
518
712
|
target = nextValidTarget(target, types, drag.allowedDropOperations, getPreviousTarget, false)
|
|
519
713
|
?? nextValidTarget(target, types, drag.allowedDropOperations, getNextTarget, false);
|
|
@@ -526,9 +720,10 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
526
720
|
}
|
|
527
721
|
}
|
|
528
722
|
});
|
|
529
|
-
}, [localState, ref, onDrop]);
|
|
723
|
+
}, [localState, ref, onDrop, direction]);
|
|
530
724
|
|
|
531
|
-
let id =
|
|
725
|
+
let id = useId();
|
|
726
|
+
droppableCollectionMap.set(state, {id, ref});
|
|
532
727
|
return {
|
|
533
728
|
collectionProps: mergeProps(dropProps, {
|
|
534
729
|
id,
|