@react-aria/dnd 3.2.2-nightly.3993 → 3.3.0
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/import.mjs +121 -47
- package/dist/main.js +120 -46
- package/dist/main.js.map +1 -1
- package/dist/module.js +121 -47
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +20 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/ListDropTargetDelegate.ts +102 -22
- package/src/useDroppableCollection.ts +78 -37
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DirectoryDropItem, DropItem, FileDropItem, TextDropItem, DropActivateEvent, DropEnterEvent, DropEvent, DropExitEvent, DropMoveEvent, DropOperation, DragTypes, DroppableCollectionProps, DropTargetDelegate, KeyboardDelegate, DropTarget, DragEndEvent, DragItem, DragMoveEvent, DragPreviewRenderer, DragStartEvent, DOMAttributes, Collection, Node } from "@react-types/shared";
|
|
1
|
+
import { DirectoryDropItem, DropItem, FileDropItem, TextDropItem, DropActivateEvent, DropEnterEvent, DropEvent, DropExitEvent, DropMoveEvent, DropOperation, DragTypes, DroppableCollectionProps, DropTargetDelegate, KeyboardDelegate, DropTarget, DragEndEvent, DragItem, DragMoveEvent, DragPreviewRenderer, DragStartEvent, DOMAttributes, Collection, Direction, Node, Orientation } from "@react-types/shared";
|
|
2
2
|
import { AriaButtonProps } from "@react-types/button";
|
|
3
3
|
import React, { HTMLAttributes, RefObject, Key } from "react";
|
|
4
4
|
import { DroppableCollectionState, DraggableCollectionState } from "@react-stately/dnd";
|
|
@@ -190,8 +190,26 @@ export interface ClipboardResult {
|
|
|
190
190
|
* data types, and integrates with the operating system native clipboard.
|
|
191
191
|
*/
|
|
192
192
|
export function useClipboard(options: ClipboardProps): ClipboardResult;
|
|
193
|
+
interface ListDropTargetDelegateOptions {
|
|
194
|
+
/**
|
|
195
|
+
* Whether the items are arranged in a stack or grid.
|
|
196
|
+
* @default 'stack'
|
|
197
|
+
*/
|
|
198
|
+
layout?: 'stack' | 'grid';
|
|
199
|
+
/**
|
|
200
|
+
* The primary orientation of the items. Usually this is the
|
|
201
|
+
* direction that the collection scrolls.
|
|
202
|
+
* @default 'vertical'
|
|
203
|
+
*/
|
|
204
|
+
orientation?: Orientation;
|
|
205
|
+
/**
|
|
206
|
+
* The horizontal layout direction.
|
|
207
|
+
* @default 'ltr'
|
|
208
|
+
*/
|
|
209
|
+
direction?: Direction;
|
|
210
|
+
}
|
|
193
211
|
export class ListDropTargetDelegate implements DropTargetDelegate {
|
|
194
|
-
constructor(collection: Collection<Node<unknown>>, ref: RefObject<HTMLElement
|
|
212
|
+
constructor(collection: Collection<Node<unknown>>, ref: RefObject<HTMLElement>, options?: ListDropTargetDelegateOptions);
|
|
195
213
|
getDropTargetFromPoint(x: number, y: number, isValidDropTarget: (target: DropTarget) => boolean): DropTarget;
|
|
196
214
|
}
|
|
197
215
|
export type { DirectoryDropItem, DragEndEvent, DraggableCollectionEndEvent, DraggableCollectionMoveEvent, DraggableCollectionStartEvent, DragItem, DragMoveEvent, DragPreviewRenderer, DragStartEvent, DragTypes, DropEnterEvent, DropEvent, DropExitEvent, DropItem, DropMoveEvent, DropOperation, DroppableCollectionDropEvent, DroppableCollectionEnterEvent, DroppableCollectionExitEvent, DroppableCollectionInsertDropEvent, DroppableCollectionMoveEvent, DroppableCollectionOnItemDropEvent, DroppableCollectionReorderEvent, DroppableCollectionRootDropEvent, DropPosition, DropTarget, DropTargetDelegate, FileDropItem, ItemDropTarget, RootDropTarget, TextDropItem } from '@react-types/shared';
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;ACwBA,OAAO,MAAM,kCAA8B,CAAC;AAoS5C,sDAAsD;AACtD,+BAA+B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,IAAI,YAAY,CAE3E;AAED,6CAA6C;AAC7C,+BAA+B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,IAAI,YAAY,CAE3E;AAED,kDAAkD;AAClD,oCAAoC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,IAAI,iBAAiB,CAErF;ACvOD,eAAe;AACf,qCAAqC,OAAO,CAE3C;AGhFD;IACE,uCAAuC;IACvC,GAAG,EAAE,UAAU,WAAW,CAAC,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,SAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,KAAK,aAAa,CAAC;IAC5F,yFAAyF;IACzF,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE,SAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,aAAa,CAAC;IAC1H,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;IAC1C,gFAAgF;IAChF,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAChD,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IACxC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;IAChC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;IACE,uCAAuC;IACvC,SAAS,EAAE,eAAe,WAAW,CAAC,CAAC;IACvC,+DAA+D;IAC/D,YAAY,EAAE,OAAO,CAAC;IACtB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,eAAe,CAAA;CAElC;AAID;;;GAGG;AACH,wBAAwB,OAAO,EAAE,WAAW,GAAG,UAAU,CAiRxD;
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/constants.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/utils.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/DragManager.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useAutoScroll.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useVirtualDrop.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useDrop.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useDroppableCollection.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useDroppableItem.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useDropIndicator.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useDrag.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useDraggableItem.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useDraggableCollection.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/DragPreview.tsx","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/useClipboard.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/ListDropTargetDelegate.ts","packages/@react-aria/dnd/src/packages/@react-aria/dnd/src/index.ts","packages/@react-aria/dnd/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport type {DroppableCollectionOptions, DroppableCollectionResult} from './useDroppableCollection';\nexport type {DroppableItemOptions, DroppableItemResult} from './useDroppableItem';\nexport type {DropIndicatorProps, DropIndicatorAria} from './useDropIndicator';\nexport type {DraggableItemProps, DraggableItemResult} from './useDraggableItem';\nexport type {DraggableCollectionOptions} from './useDraggableCollection';\nexport type {DragPreviewProps} from './DragPreview';\nexport type {DragOptions, DragResult} from './useDrag';\nexport type {DropOptions, DropResult} from './useDrop';\nexport type {ClipboardProps, ClipboardResult} from './useClipboard';\nexport type {\n DirectoryDropItem,\n DragEndEvent,\n DraggableCollectionEndEvent,\n DraggableCollectionMoveEvent,\n DraggableCollectionStartEvent,\n DragItem,\n DragMoveEvent,\n DragPreviewRenderer,\n DragStartEvent,\n DragTypes,\n DropEnterEvent,\n DropEvent,\n DropExitEvent,\n DropItem,\n DropMoveEvent,\n DropOperation,\n DroppableCollectionDropEvent,\n DroppableCollectionEnterEvent,\n DroppableCollectionExitEvent,\n DroppableCollectionInsertDropEvent,\n DroppableCollectionMoveEvent,\n DroppableCollectionOnItemDropEvent,\n DroppableCollectionReorderEvent,\n DroppableCollectionRootDropEvent,\n DropPosition,\n DropTarget,\n DropTargetDelegate,\n FileDropItem,\n ItemDropTarget,\n RootDropTarget,\n TextDropItem\n} from '@react-types/shared';\n\nexport {DIRECTORY_DRAG_TYPE} from './utils';\nexport {useDrag} from './useDrag';\nexport {useDrop} from './useDrop';\nexport {useDroppableCollection} from './useDroppableCollection';\nexport {useDroppableItem} from './useDroppableItem';\nexport {useDropIndicator} from './useDropIndicator';\nexport {useDraggableItem} from './useDraggableItem';\nexport {useDraggableCollection} from './useDraggableCollection';\nexport {useClipboard} from './useClipboard';\nexport {DragPreview} from './DragPreview';\nexport {ListDropTargetDelegate} from './ListDropTargetDelegate';\nexport {isVirtualDragging} from './DragManager';\nexport {isDirectoryDropItem, isFileDropItem, isTextDropItem} from './utils';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-aria/dnd",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Spectrum UI components in React",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"url": "https://github.com/adobe/react-spectrum"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@internationalized/string": "3.1.1
|
|
26
|
-
"@react-aria/i18n": "3.
|
|
27
|
-
"@react-aria/interactions": "3.
|
|
28
|
-
"@react-aria/live-announcer": "3.
|
|
29
|
-
"@react-aria/overlays": "3.
|
|
30
|
-
"@react-aria/utils": "3.
|
|
31
|
-
"@react-aria/visually-hidden": "3.
|
|
32
|
-
"@react-stately/dnd": "3.2.2
|
|
33
|
-
"@react-types/button": "3.7.
|
|
34
|
-
"@react-types/shared": "3.
|
|
25
|
+
"@internationalized/string": "^3.1.1",
|
|
26
|
+
"@react-aria/i18n": "^3.8.0",
|
|
27
|
+
"@react-aria/interactions": "^3.16.0",
|
|
28
|
+
"@react-aria/live-announcer": "^3.3.1",
|
|
29
|
+
"@react-aria/overlays": "^3.15.0",
|
|
30
|
+
"@react-aria/utils": "^3.18.0",
|
|
31
|
+
"@react-aria/visually-hidden": "^3.8.2",
|
|
32
|
+
"@react-stately/dnd": "^3.2.2",
|
|
33
|
+
"@react-types/button": "^3.7.3",
|
|
34
|
+
"@react-types/shared": "^3.18.1",
|
|
35
35
|
"@swc/helpers": "^0.5.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "504e40e0a50c1b20ed0fb3ba9561a263b6d5565e"
|
|
45
45
|
}
|
|
@@ -1,13 +1,75 @@
|
|
|
1
|
-
import {Collection, DropTarget, DropTargetDelegate, Node} from '@react-types/shared';
|
|
1
|
+
import {Collection, Direction, DropTarget, DropTargetDelegate, Node, Orientation} from '@react-types/shared';
|
|
2
2
|
import {RefObject} from 'react';
|
|
3
3
|
|
|
4
|
+
interface ListDropTargetDelegateOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Whether the items are arranged in a stack or grid.
|
|
7
|
+
* @default 'stack'
|
|
8
|
+
*/
|
|
9
|
+
layout?: 'stack' | 'grid',
|
|
10
|
+
/**
|
|
11
|
+
* The primary orientation of the items. Usually this is the
|
|
12
|
+
* direction that the collection scrolls.
|
|
13
|
+
* @default 'vertical'
|
|
14
|
+
*/
|
|
15
|
+
orientation?: Orientation,
|
|
16
|
+
/**
|
|
17
|
+
* The horizontal layout direction.
|
|
18
|
+
* @default 'ltr'
|
|
19
|
+
*/
|
|
20
|
+
direction?: Direction
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Terms used in the below code:
|
|
24
|
+
// * "Primary" – The main layout direction. For stacks, this is the direction
|
|
25
|
+
// that the stack is arranged in (e.g. horizontal or vertical).
|
|
26
|
+
// For grids, this is the main scroll direction.
|
|
27
|
+
// * "Secondary" – The secondary layout direction. For stacks, there is no secondary
|
|
28
|
+
// layout direction. For grids, this is the opposite of the primary direction.
|
|
29
|
+
// * "Flow" – The flow direction of the items. For stacks, this is the the primary
|
|
30
|
+
// direction. For grids, it is the secondary direction.
|
|
31
|
+
|
|
4
32
|
export class ListDropTargetDelegate implements DropTargetDelegate {
|
|
5
33
|
private collection: Collection<Node<unknown>>;
|
|
6
34
|
private ref: RefObject<HTMLElement>;
|
|
35
|
+
private layout: 'stack' | 'grid';
|
|
36
|
+
private orientation: Orientation;
|
|
37
|
+
private direction: Direction;
|
|
7
38
|
|
|
8
|
-
constructor(collection: Collection<Node<unknown>>, ref: RefObject<HTMLElement
|
|
39
|
+
constructor(collection: Collection<Node<unknown>>, ref: RefObject<HTMLElement>, options?: ListDropTargetDelegateOptions) {
|
|
9
40
|
this.collection = collection;
|
|
10
41
|
this.ref = ref;
|
|
42
|
+
this.layout = options?.layout || 'stack';
|
|
43
|
+
this.orientation = options?.orientation || 'vertical';
|
|
44
|
+
this.direction = options?.direction || 'ltr';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private getPrimaryStart(rect: DOMRect) {
|
|
48
|
+
return this.orientation === 'horizontal' ? rect.left : rect.top;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private getPrimaryEnd(rect: DOMRect) {
|
|
52
|
+
return this.orientation === 'horizontal' ? rect.right : rect.bottom;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private getSecondaryStart(rect: DOMRect) {
|
|
56
|
+
return this.orientation === 'horizontal' ? rect.top : rect.left;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private getSecondaryEnd(rect: DOMRect) {
|
|
60
|
+
return this.orientation === 'horizontal' ? rect.bottom : rect.right;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private getFlowStart(rect: DOMRect) {
|
|
64
|
+
return this.layout === 'stack' ? this.getPrimaryStart(rect) : this.getSecondaryStart(rect);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private getFlowEnd(rect: DOMRect) {
|
|
68
|
+
return this.layout === 'stack' ? this.getPrimaryEnd(rect) : this.getSecondaryEnd(rect);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private getFlowSize(rect: DOMRect) {
|
|
72
|
+
return this.getFlowEnd(rect) - this.getFlowStart(rect);
|
|
11
73
|
}
|
|
12
74
|
|
|
13
75
|
getDropTargetFromPoint(x: number, y: number, isValidDropTarget: (target: DropTarget) => boolean): DropTarget {
|
|
@@ -16,8 +78,15 @@ export class ListDropTargetDelegate implements DropTargetDelegate {
|
|
|
16
78
|
}
|
|
17
79
|
|
|
18
80
|
let rect = this.ref.current.getBoundingClientRect();
|
|
19
|
-
|
|
20
|
-
|
|
81
|
+
let primary = this.orientation === 'horizontal' ? x : y;
|
|
82
|
+
let secondary = this.orientation === 'horizontal' ? y : x;
|
|
83
|
+
primary += this.getPrimaryStart(rect);
|
|
84
|
+
secondary += this.getSecondaryStart(rect);
|
|
85
|
+
|
|
86
|
+
let flow = this.layout === 'stack' ? primary : secondary;
|
|
87
|
+
let isPrimaryRTL = this.orientation === 'horizontal' && this.direction === 'rtl';
|
|
88
|
+
let isSecondaryRTL = this.layout === 'grid' && this.orientation === 'vertical' && this.direction === 'rtl';
|
|
89
|
+
let isFlowRTL = this.layout === 'stack' ? isPrimaryRTL : isSecondaryRTL;
|
|
21
90
|
|
|
22
91
|
let elements = this.ref.current.querySelectorAll('[data-key]');
|
|
23
92
|
let elementMap = new Map<string, HTMLElement>();
|
|
@@ -35,11 +104,22 @@ export class ListDropTargetDelegate implements DropTargetDelegate {
|
|
|
35
104
|
let item = items[mid];
|
|
36
105
|
let element = elementMap.get(String(item.key));
|
|
37
106
|
let rect = element.getBoundingClientRect();
|
|
107
|
+
let update = (isGreater: boolean) => {
|
|
108
|
+
if (isGreater) {
|
|
109
|
+
low = mid + 1;
|
|
110
|
+
} else {
|
|
111
|
+
high = mid;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
38
114
|
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
} else if (
|
|
42
|
-
|
|
115
|
+
if (primary < this.getPrimaryStart(rect)) {
|
|
116
|
+
update(isPrimaryRTL);
|
|
117
|
+
} else if (primary > this.getPrimaryEnd(rect)) {
|
|
118
|
+
update(!isPrimaryRTL);
|
|
119
|
+
} else if (secondary < this.getSecondaryStart(rect)) {
|
|
120
|
+
update(isSecondaryRTL);
|
|
121
|
+
} else if (secondary > this.getSecondaryEnd(rect)) {
|
|
122
|
+
update(!isSecondaryRTL);
|
|
43
123
|
} else {
|
|
44
124
|
let target: DropTarget = {
|
|
45
125
|
type: 'item',
|
|
@@ -49,19 +129,19 @@ export class ListDropTargetDelegate implements DropTargetDelegate {
|
|
|
49
129
|
|
|
50
130
|
if (isValidDropTarget(target)) {
|
|
51
131
|
// Otherwise, if dropping on the item is accepted, try the before/after positions if within 5px
|
|
52
|
-
// of the
|
|
53
|
-
if (
|
|
54
|
-
target.dropPosition = 'before';
|
|
55
|
-
} else if (
|
|
56
|
-
target.dropPosition = 'after';
|
|
132
|
+
// of the start or end of the item.
|
|
133
|
+
if (flow <= this.getFlowStart(rect) + 5 && isValidDropTarget({...target, dropPosition: 'before'})) {
|
|
134
|
+
target.dropPosition = isFlowRTL ? 'after' : 'before';
|
|
135
|
+
} else if (flow >= this.getFlowEnd(rect) - 5 && isValidDropTarget({...target, dropPosition: 'after'})) {
|
|
136
|
+
target.dropPosition = isFlowRTL ? 'before' : 'after';
|
|
57
137
|
}
|
|
58
138
|
} else {
|
|
59
|
-
// If dropping on the item isn't accepted, try the target before or after depending on the
|
|
60
|
-
let
|
|
61
|
-
if (
|
|
62
|
-
target.dropPosition = 'before';
|
|
63
|
-
} else if (
|
|
64
|
-
target.dropPosition = 'after';
|
|
139
|
+
// If dropping on the item isn't accepted, try the target before or after depending on the position.
|
|
140
|
+
let mid = this.getFlowStart(rect) + this.getFlowSize(rect) / 2;
|
|
141
|
+
if (flow <= mid && isValidDropTarget({...target, dropPosition: 'before'})) {
|
|
142
|
+
target.dropPosition = isFlowRTL ? 'after' : 'before';
|
|
143
|
+
} else if (flow >= mid && isValidDropTarget({...target, dropPosition: 'after'})) {
|
|
144
|
+
target.dropPosition = isFlowRTL ? 'before' : 'after';
|
|
65
145
|
}
|
|
66
146
|
}
|
|
67
147
|
|
|
@@ -73,18 +153,18 @@ export class ListDropTargetDelegate implements DropTargetDelegate {
|
|
|
73
153
|
let element = elementMap.get(String(item.key));
|
|
74
154
|
rect = element.getBoundingClientRect();
|
|
75
155
|
|
|
76
|
-
if (Math.abs(
|
|
156
|
+
if (primary < this.getPrimaryStart(rect) || Math.abs(flow - this.getFlowStart(rect)) < Math.abs(flow - this.getFlowEnd(rect))) {
|
|
77
157
|
return {
|
|
78
158
|
type: 'item',
|
|
79
159
|
key: item.key,
|
|
80
|
-
dropPosition: 'before'
|
|
160
|
+
dropPosition: isFlowRTL ? 'after' : 'before'
|
|
81
161
|
};
|
|
82
162
|
}
|
|
83
163
|
|
|
84
164
|
return {
|
|
85
165
|
type: 'item',
|
|
86
166
|
key: item.key,
|
|
87
|
-
dropPosition: 'after'
|
|
167
|
+
dropPosition: isFlowRTL ? 'before' : 'after'
|
|
88
168
|
};
|
|
89
169
|
}
|
|
90
170
|
}
|
|
@@ -38,6 +38,7 @@ import {mergeProps, useId, useLayoutEffect} from '@react-aria/utils';
|
|
|
38
38
|
import {setInteractionModality} from '@react-aria/interactions';
|
|
39
39
|
import {useAutoScroll} from './useAutoScroll';
|
|
40
40
|
import {useDrop} from './useDrop';
|
|
41
|
+
import {useLocale} from '@react-aria/i18n';
|
|
41
42
|
|
|
42
43
|
export interface DroppableCollectionOptions extends DroppableCollectionProps {
|
|
43
44
|
/** A delegate object that implements behavior for keyboard focus movement. */
|
|
@@ -59,6 +60,7 @@ interface DroppingState {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
const DROP_POSITIONS: DropPosition[] = ['before', 'on', 'after'];
|
|
63
|
+
const DROP_POSITIONS_RTL: DropPosition[] = ['after', 'on', 'before'];
|
|
62
64
|
|
|
63
65
|
/**
|
|
64
66
|
* Handles drop interactions for a collection component, with support for traditional mouse and touch
|
|
@@ -315,8 +317,9 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
315
317
|
}
|
|
316
318
|
});
|
|
317
319
|
|
|
320
|
+
let {direction} = useLocale();
|
|
318
321
|
useEffect(() => {
|
|
319
|
-
let getNextTarget = (target: DropTarget, wrap = true): DropTarget => {
|
|
322
|
+
let getNextTarget = (target: DropTarget, wrap = true, horizontal = false): DropTarget => {
|
|
320
323
|
if (!target) {
|
|
321
324
|
return {
|
|
322
325
|
type: 'root'
|
|
@@ -324,26 +327,38 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
324
327
|
}
|
|
325
328
|
|
|
326
329
|
let {keyboardDelegate} = localState.props;
|
|
327
|
-
let nextKey
|
|
328
|
-
|
|
329
|
-
: keyboardDelegate.
|
|
330
|
-
|
|
330
|
+
let nextKey: Key;
|
|
331
|
+
if (target?.type === 'item') {
|
|
332
|
+
nextKey = horizontal ? keyboardDelegate.getKeyRightOf(target.key) : keyboardDelegate.getKeyBelow(target.key);
|
|
333
|
+
} else {
|
|
334
|
+
nextKey = horizontal && direction === 'rtl' ? keyboardDelegate.getLastKey() : keyboardDelegate.getFirstKey();
|
|
335
|
+
}
|
|
336
|
+
let dropPositions = horizontal && direction === 'rtl' ? DROP_POSITIONS_RTL : DROP_POSITIONS;
|
|
337
|
+
let dropPosition: DropPosition = dropPositions[0];
|
|
331
338
|
|
|
332
339
|
if (target.type === 'item') {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
340
|
+
// If the the keyboard delegate returned the next key in the collection,
|
|
341
|
+
// first try the other positions in the current key. Otherwise (e.g. in a grid layout),
|
|
342
|
+
// jump to the same drop position in the new key.
|
|
343
|
+
let nextCollectionKey = horizontal && direction === 'rtl' ? localState.state.collection.getKeyBefore(target.key) : localState.state.collection.getKeyAfter(target.key);
|
|
344
|
+
if (nextKey == null || nextKey === nextCollectionKey) {
|
|
345
|
+
let positionIndex = dropPositions.indexOf(target.dropPosition);
|
|
346
|
+
let nextDropPosition = dropPositions[positionIndex + 1];
|
|
347
|
+
if (positionIndex < dropPositions.length - 1 && !(nextDropPosition === dropPositions[2] && nextKey != null)) {
|
|
348
|
+
return {
|
|
349
|
+
type: 'item',
|
|
350
|
+
key: target.key,
|
|
351
|
+
dropPosition: nextDropPosition
|
|
352
|
+
};
|
|
353
|
+
}
|
|
342
354
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
355
|
+
// If the last drop position was 'after', then 'before' on the next key is equivalent.
|
|
356
|
+
// Switch to 'on' instead.
|
|
357
|
+
if (target.dropPosition === dropPositions[2]) {
|
|
358
|
+
dropPosition = 'on';
|
|
359
|
+
}
|
|
360
|
+
} else {
|
|
361
|
+
dropPosition = target.dropPosition;
|
|
347
362
|
}
|
|
348
363
|
}
|
|
349
364
|
|
|
@@ -364,28 +379,40 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
364
379
|
};
|
|
365
380
|
};
|
|
366
381
|
|
|
367
|
-
let getPreviousTarget = (target: DropTarget, wrap = true): DropTarget => {
|
|
382
|
+
let getPreviousTarget = (target: DropTarget, wrap = true, horizontal = false): DropTarget => {
|
|
368
383
|
let {keyboardDelegate} = localState.props;
|
|
369
|
-
let nextKey
|
|
370
|
-
|
|
371
|
-
: keyboardDelegate.
|
|
372
|
-
|
|
384
|
+
let nextKey: Key;
|
|
385
|
+
if (target?.type === 'item') {
|
|
386
|
+
nextKey = horizontal ? keyboardDelegate.getKeyLeftOf(target.key) : keyboardDelegate.getKeyAbove(target.key);
|
|
387
|
+
} else {
|
|
388
|
+
nextKey = horizontal && direction === 'rtl' ? keyboardDelegate.getFirstKey() : keyboardDelegate.getLastKey();
|
|
389
|
+
}
|
|
390
|
+
let dropPositions = horizontal && direction === 'rtl' ? DROP_POSITIONS_RTL : DROP_POSITIONS;
|
|
391
|
+
let dropPosition: DropPosition = !target || target.type === 'root' ? dropPositions[2] : 'on';
|
|
373
392
|
|
|
374
393
|
if (target?.type === 'item') {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
394
|
+
// If the the keyboard delegate returned the previous key in the collection,
|
|
395
|
+
// first try the other positions in the current key. Otherwise (e.g. in a grid layout),
|
|
396
|
+
// jump to the same drop position in the new key.
|
|
397
|
+
let prevCollectionKey = horizontal && direction === 'rtl' ? localState.state.collection.getKeyAfter(target.key) : localState.state.collection.getKeyBefore(target.key);
|
|
398
|
+
if (nextKey == null || nextKey === prevCollectionKey) {
|
|
399
|
+
let positionIndex = dropPositions.indexOf(target.dropPosition);
|
|
400
|
+
let nextDropPosition = dropPositions[positionIndex - 1];
|
|
401
|
+
if (positionIndex > 0 && nextDropPosition !== dropPositions[2]) {
|
|
402
|
+
return {
|
|
403
|
+
type: 'item',
|
|
404
|
+
key: target.key,
|
|
405
|
+
dropPosition: nextDropPosition
|
|
406
|
+
};
|
|
407
|
+
}
|
|
384
408
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
409
|
+
// If the last drop position was 'before', then 'after' on the previous key is equivalent.
|
|
410
|
+
// Switch to 'on' instead.
|
|
411
|
+
if (target.dropPosition === dropPositions[0]) {
|
|
412
|
+
dropPosition = 'on';
|
|
413
|
+
}
|
|
414
|
+
} else {
|
|
415
|
+
dropPosition = target.dropPosition;
|
|
389
416
|
}
|
|
390
417
|
}
|
|
391
418
|
|
|
@@ -553,6 +580,20 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
553
580
|
}
|
|
554
581
|
break;
|
|
555
582
|
}
|
|
583
|
+
case 'ArrowLeft': {
|
|
584
|
+
if (keyboardDelegate.getKeyLeftOf) {
|
|
585
|
+
let target = nextValidTarget(localState.state.target, types, drag.allowedDropOperations, (target, wrap) => getPreviousTarget(target, wrap, true));
|
|
586
|
+
localState.state.setTarget(target);
|
|
587
|
+
}
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
case 'ArrowRight': {
|
|
591
|
+
if (keyboardDelegate.getKeyRightOf) {
|
|
592
|
+
let target = nextValidTarget(localState.state.target, types, drag.allowedDropOperations, (target, wrap) => getNextTarget(target, wrap, true));
|
|
593
|
+
localState.state.setTarget(target);
|
|
594
|
+
}
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
556
597
|
case 'Home': {
|
|
557
598
|
if (keyboardDelegate.getFirstKey) {
|
|
558
599
|
let target = nextValidTarget(null, types, drag.allowedDropOperations, getNextTarget);
|
|
@@ -654,7 +695,7 @@ export function useDroppableCollection(props: DroppableCollectionOptions, state:
|
|
|
654
695
|
}
|
|
655
696
|
}
|
|
656
697
|
});
|
|
657
|
-
}, [localState, ref, onDrop]);
|
|
698
|
+
}, [localState, ref, onDrop, direction]);
|
|
658
699
|
|
|
659
700
|
let id = useId();
|
|
660
701
|
droppableCollectionMap.set(state, {id, ref});
|