@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/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';
@@ -1 +1 @@
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"}
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.2.2-nightly.3993+bf8fac4cf",
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-nightly.3993+bf8fac4cf",
26
- "@react-aria/i18n": "3.0.0-nightly.2291+bf8fac4cf",
27
- "@react-aria/interactions": "3.0.0-nightly.2291+bf8fac4cf",
28
- "@react-aria/live-announcer": "3.0.0-nightly.2291+bf8fac4cf",
29
- "@react-aria/overlays": "3.0.0-nightly.2291+bf8fac4cf",
30
- "@react-aria/utils": "3.0.0-nightly.2291+bf8fac4cf",
31
- "@react-aria/visually-hidden": "3.0.0-nightly.2291+bf8fac4cf",
32
- "@react-stately/dnd": "3.2.2-nightly.3993+bf8fac4cf",
33
- "@react-types/button": "3.7.4-nightly.3993+bf8fac4cf",
34
- "@react-types/shared": "3.0.0-nightly.2291+bf8fac4cf",
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": "bf8fac4cf85da695bf3bcaa4fed721f398aa19ba"
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
- x += rect.x;
20
- y += rect.y;
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 (y < rect.top) {
40
- high = mid;
41
- } else if (y > rect.bottom) {
42
- low = mid + 1;
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 top or bottom of the item.
53
- if (y <= rect.top + 5 && isValidDropTarget({...target, dropPosition: 'before'})) {
54
- target.dropPosition = 'before';
55
- } else if (y >= rect.bottom - 5 && isValidDropTarget({...target, dropPosition: 'after'})) {
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 y position.
60
- let midY = rect.top + rect.height / 2;
61
- if (y <= midY && isValidDropTarget({...target, dropPosition: 'before'})) {
62
- target.dropPosition = 'before';
63
- } else if (y >= midY && isValidDropTarget({...target, dropPosition: 'after'})) {
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(y - rect.top) < Math.abs(y - rect.bottom)) {
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 = target.type === 'item'
328
- ? keyboardDelegate.getKeyBelow(target.key)
329
- : keyboardDelegate.getFirstKey();
330
- let dropPosition: DropPosition = 'before';
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
- let positionIndex = DROP_POSITIONS.indexOf(target.dropPosition);
334
- let nextDropPosition = DROP_POSITIONS[positionIndex + 1];
335
- if (positionIndex < DROP_POSITIONS.length - 1 && !(nextDropPosition === 'after' && nextKey != null)) {
336
- return {
337
- type: 'item',
338
- key: target.key,
339
- dropPosition: nextDropPosition
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
- // If the last drop position was 'after', then 'before' on the next key is equivalent.
344
- // Switch to 'on' instead.
345
- if (target.dropPosition === 'after') {
346
- dropPosition = 'on';
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 = target?.type === 'item'
370
- ? keyboardDelegate.getKeyAbove(target.key)
371
- : keyboardDelegate.getLastKey();
372
- let dropPosition: DropPosition = !target || target.type === 'root' ? 'after' : 'on';
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
- let positionIndex = DROP_POSITIONS.indexOf(target.dropPosition);
376
- let nextDropPosition = DROP_POSITIONS[positionIndex - 1];
377
- if (positionIndex > 0 && nextDropPosition !== 'after') {
378
- return {
379
- type: 'item',
380
- key: target.key,
381
- dropPosition: nextDropPosition
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
- // If the last drop position was 'before', then 'after' on the previous key is equivalent.
386
- // Switch to 'on' instead.
387
- if (target.dropPosition === 'before') {
388
- dropPosition = 'on';
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});