@react-aria/dnd 3.11.5 → 3.12.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.
Files changed (281) hide show
  1. package/dist/import.mjs +8 -18
  2. package/dist/main.js +22 -32
  3. package/dist/main.js.map +1 -1
  4. package/dist/module.js +8 -18
  5. package/dist/module.js.map +1 -1
  6. package/dist/types/src/index.d.ts +13 -0
  7. package/package.json +16 -21
  8. package/src/index.ts +13 -56
  9. package/dist/DragManager.main.js +0 -519
  10. package/dist/DragManager.main.js.map +0 -1
  11. package/dist/DragManager.mjs +0 -510
  12. package/dist/DragManager.module.js +0 -510
  13. package/dist/DragManager.module.js.map +0 -1
  14. package/dist/DragPreview.main.js +0 -73
  15. package/dist/DragPreview.main.js.map +0 -1
  16. package/dist/DragPreview.mjs +0 -64
  17. package/dist/DragPreview.module.js +0 -64
  18. package/dist/DragPreview.module.js.map +0 -1
  19. package/dist/DropTargetKeyboardNavigation.main.js +0 -205
  20. package/dist/DropTargetKeyboardNavigation.main.js.map +0 -1
  21. package/dist/DropTargetKeyboardNavigation.mjs +0 -200
  22. package/dist/DropTargetKeyboardNavigation.module.js +0 -200
  23. package/dist/DropTargetKeyboardNavigation.module.js.map +0 -1
  24. package/dist/ListDropTargetDelegate.main.js +0 -129
  25. package/dist/ListDropTargetDelegate.main.js.map +0 -1
  26. package/dist/ListDropTargetDelegate.mjs +0 -124
  27. package/dist/ListDropTargetDelegate.module.js +0 -124
  28. package/dist/ListDropTargetDelegate.module.js.map +0 -1
  29. package/dist/ar-AE.main.js +0 -44
  30. package/dist/ar-AE.main.js.map +0 -1
  31. package/dist/ar-AE.mjs +0 -46
  32. package/dist/ar-AE.module.js +0 -46
  33. package/dist/ar-AE.module.js.map +0 -1
  34. package/dist/bg-BG.main.js +0 -44
  35. package/dist/bg-BG.main.js.map +0 -1
  36. package/dist/bg-BG.mjs +0 -46
  37. package/dist/bg-BG.module.js +0 -46
  38. package/dist/bg-BG.module.js.map +0 -1
  39. package/dist/constants.main.js +0 -64
  40. package/dist/constants.main.js.map +0 -1
  41. package/dist/constants.mjs +0 -52
  42. package/dist/constants.module.js +0 -52
  43. package/dist/constants.module.js.map +0 -1
  44. package/dist/cs-CZ.main.js +0 -45
  45. package/dist/cs-CZ.main.js.map +0 -1
  46. package/dist/cs-CZ.mjs +0 -47
  47. package/dist/cs-CZ.module.js +0 -47
  48. package/dist/cs-CZ.module.js.map +0 -1
  49. package/dist/da-DK.main.js +0 -44
  50. package/dist/da-DK.main.js.map +0 -1
  51. package/dist/da-DK.mjs +0 -46
  52. package/dist/da-DK.module.js +0 -46
  53. package/dist/da-DK.module.js.map +0 -1
  54. package/dist/de-DE.main.js +0 -44
  55. package/dist/de-DE.main.js.map +0 -1
  56. package/dist/de-DE.mjs +0 -46
  57. package/dist/de-DE.module.js +0 -46
  58. package/dist/de-DE.module.js.map +0 -1
  59. package/dist/el-GR.main.js +0 -44
  60. package/dist/el-GR.main.js.map +0 -1
  61. package/dist/el-GR.mjs +0 -46
  62. package/dist/el-GR.module.js +0 -46
  63. package/dist/el-GR.module.js.map +0 -1
  64. package/dist/en-US.main.js +0 -44
  65. package/dist/en-US.main.js.map +0 -1
  66. package/dist/en-US.mjs +0 -46
  67. package/dist/en-US.module.js +0 -46
  68. package/dist/en-US.module.js.map +0 -1
  69. package/dist/es-ES.main.js +0 -44
  70. package/dist/es-ES.main.js.map +0 -1
  71. package/dist/es-ES.mjs +0 -46
  72. package/dist/es-ES.module.js +0 -46
  73. package/dist/es-ES.module.js.map +0 -1
  74. package/dist/et-EE.main.js +0 -44
  75. package/dist/et-EE.main.js.map +0 -1
  76. package/dist/et-EE.mjs +0 -46
  77. package/dist/et-EE.module.js +0 -46
  78. package/dist/et-EE.module.js.map +0 -1
  79. package/dist/fi-FI.main.js +0 -44
  80. package/dist/fi-FI.main.js.map +0 -1
  81. package/dist/fi-FI.mjs +0 -46
  82. package/dist/fi-FI.module.js +0 -46
  83. package/dist/fi-FI.module.js.map +0 -1
  84. package/dist/fr-FR.main.js +0 -44
  85. package/dist/fr-FR.main.js.map +0 -1
  86. package/dist/fr-FR.mjs +0 -46
  87. package/dist/fr-FR.module.js +0 -46
  88. package/dist/fr-FR.module.js.map +0 -1
  89. package/dist/he-IL.main.js +0 -44
  90. package/dist/he-IL.main.js.map +0 -1
  91. package/dist/he-IL.mjs +0 -46
  92. package/dist/he-IL.module.js +0 -46
  93. package/dist/he-IL.module.js.map +0 -1
  94. package/dist/hr-HR.main.js +0 -44
  95. package/dist/hr-HR.main.js.map +0 -1
  96. package/dist/hr-HR.mjs +0 -46
  97. package/dist/hr-HR.module.js +0 -46
  98. package/dist/hr-HR.module.js.map +0 -1
  99. package/dist/hu-HU.main.js +0 -44
  100. package/dist/hu-HU.main.js.map +0 -1
  101. package/dist/hu-HU.mjs +0 -46
  102. package/dist/hu-HU.module.js +0 -46
  103. package/dist/hu-HU.module.js.map +0 -1
  104. package/dist/intlStrings.main.js +0 -108
  105. package/dist/intlStrings.main.js.map +0 -1
  106. package/dist/intlStrings.mjs +0 -110
  107. package/dist/intlStrings.module.js +0 -110
  108. package/dist/intlStrings.module.js.map +0 -1
  109. package/dist/it-IT.main.js +0 -44
  110. package/dist/it-IT.main.js.map +0 -1
  111. package/dist/it-IT.mjs +0 -46
  112. package/dist/it-IT.module.js +0 -46
  113. package/dist/it-IT.module.js.map +0 -1
  114. package/dist/ja-JP.main.js +0 -44
  115. package/dist/ja-JP.main.js.map +0 -1
  116. package/dist/ja-JP.mjs +0 -46
  117. package/dist/ja-JP.module.js +0 -46
  118. package/dist/ja-JP.module.js.map +0 -1
  119. package/dist/ko-KR.main.js +0 -44
  120. package/dist/ko-KR.main.js.map +0 -1
  121. package/dist/ko-KR.mjs +0 -46
  122. package/dist/ko-KR.module.js +0 -46
  123. package/dist/ko-KR.module.js.map +0 -1
  124. package/dist/lt-LT.main.js +0 -44
  125. package/dist/lt-LT.main.js.map +0 -1
  126. package/dist/lt-LT.mjs +0 -46
  127. package/dist/lt-LT.module.js +0 -46
  128. package/dist/lt-LT.module.js.map +0 -1
  129. package/dist/lv-LV.main.js +0 -44
  130. package/dist/lv-LV.main.js.map +0 -1
  131. package/dist/lv-LV.mjs +0 -46
  132. package/dist/lv-LV.module.js +0 -46
  133. package/dist/lv-LV.module.js.map +0 -1
  134. package/dist/nb-NO.main.js +0 -44
  135. package/dist/nb-NO.main.js.map +0 -1
  136. package/dist/nb-NO.mjs +0 -46
  137. package/dist/nb-NO.module.js +0 -46
  138. package/dist/nb-NO.module.js.map +0 -1
  139. package/dist/nl-NL.main.js +0 -44
  140. package/dist/nl-NL.main.js.map +0 -1
  141. package/dist/nl-NL.mjs +0 -46
  142. package/dist/nl-NL.module.js +0 -46
  143. package/dist/nl-NL.module.js.map +0 -1
  144. package/dist/pl-PL.main.js +0 -44
  145. package/dist/pl-PL.main.js.map +0 -1
  146. package/dist/pl-PL.mjs +0 -46
  147. package/dist/pl-PL.module.js +0 -46
  148. package/dist/pl-PL.module.js.map +0 -1
  149. package/dist/pt-BR.main.js +0 -44
  150. package/dist/pt-BR.main.js.map +0 -1
  151. package/dist/pt-BR.mjs +0 -46
  152. package/dist/pt-BR.module.js +0 -46
  153. package/dist/pt-BR.module.js.map +0 -1
  154. package/dist/pt-PT.main.js +0 -44
  155. package/dist/pt-PT.main.js.map +0 -1
  156. package/dist/pt-PT.mjs +0 -46
  157. package/dist/pt-PT.module.js +0 -46
  158. package/dist/pt-PT.module.js.map +0 -1
  159. package/dist/ro-RO.main.js +0 -44
  160. package/dist/ro-RO.main.js.map +0 -1
  161. package/dist/ro-RO.mjs +0 -46
  162. package/dist/ro-RO.module.js +0 -46
  163. package/dist/ro-RO.module.js.map +0 -1
  164. package/dist/ru-RU.main.js +0 -44
  165. package/dist/ru-RU.main.js.map +0 -1
  166. package/dist/ru-RU.mjs +0 -46
  167. package/dist/ru-RU.module.js +0 -46
  168. package/dist/ru-RU.module.js.map +0 -1
  169. package/dist/sk-SK.main.js +0 -44
  170. package/dist/sk-SK.main.js.map +0 -1
  171. package/dist/sk-SK.mjs +0 -46
  172. package/dist/sk-SK.module.js +0 -46
  173. package/dist/sk-SK.module.js.map +0 -1
  174. package/dist/sl-SI.main.js +0 -44
  175. package/dist/sl-SI.main.js.map +0 -1
  176. package/dist/sl-SI.mjs +0 -46
  177. package/dist/sl-SI.module.js +0 -46
  178. package/dist/sl-SI.module.js.map +0 -1
  179. package/dist/sr-SP.main.js +0 -44
  180. package/dist/sr-SP.main.js.map +0 -1
  181. package/dist/sr-SP.mjs +0 -46
  182. package/dist/sr-SP.module.js +0 -46
  183. package/dist/sr-SP.module.js.map +0 -1
  184. package/dist/sv-SE.main.js +0 -44
  185. package/dist/sv-SE.main.js.map +0 -1
  186. package/dist/sv-SE.mjs +0 -46
  187. package/dist/sv-SE.module.js +0 -46
  188. package/dist/sv-SE.module.js.map +0 -1
  189. package/dist/tr-TR.main.js +0 -44
  190. package/dist/tr-TR.main.js.map +0 -1
  191. package/dist/tr-TR.mjs +0 -46
  192. package/dist/tr-TR.module.js +0 -46
  193. package/dist/tr-TR.module.js.map +0 -1
  194. package/dist/types.d.ts +0 -244
  195. package/dist/types.d.ts.map +0 -1
  196. package/dist/uk-UA.main.js +0 -44
  197. package/dist/uk-UA.main.js.map +0 -1
  198. package/dist/uk-UA.mjs +0 -46
  199. package/dist/uk-UA.module.js +0 -46
  200. package/dist/uk-UA.module.js.map +0 -1
  201. package/dist/useAutoScroll.main.js +0 -89
  202. package/dist/useAutoScroll.main.js.map +0 -1
  203. package/dist/useAutoScroll.mjs +0 -84
  204. package/dist/useAutoScroll.module.js +0 -84
  205. package/dist/useAutoScroll.module.js.map +0 -1
  206. package/dist/useClipboard.main.js +0 -111
  207. package/dist/useClipboard.main.js.map +0 -1
  208. package/dist/useClipboard.mjs +0 -106
  209. package/dist/useClipboard.module.js +0 -106
  210. package/dist/useClipboard.module.js.map +0 -1
  211. package/dist/useDrag.main.js +0 -307
  212. package/dist/useDrag.main.js.map +0 -1
  213. package/dist/useDrag.mjs +0 -302
  214. package/dist/useDrag.module.js +0 -302
  215. package/dist/useDrag.module.js.map +0 -1
  216. package/dist/useDraggableCollection.main.js +0 -27
  217. package/dist/useDraggableCollection.main.js.map +0 -1
  218. package/dist/useDraggableCollection.mjs +0 -22
  219. package/dist/useDraggableCollection.module.js +0 -22
  220. package/dist/useDraggableCollection.module.js.map +0 -1
  221. package/dist/useDraggableItem.main.js +0 -128
  222. package/dist/useDraggableItem.main.js.map +0 -1
  223. package/dist/useDraggableItem.mjs +0 -123
  224. package/dist/useDraggableItem.module.js +0 -123
  225. package/dist/useDraggableItem.module.js.map +0 -1
  226. package/dist/useDrop.main.js +0 -295
  227. package/dist/useDrop.main.js.map +0 -1
  228. package/dist/useDrop.mjs +0 -290
  229. package/dist/useDrop.module.js +0 -290
  230. package/dist/useDrop.module.js.map +0 -1
  231. package/dist/useDropIndicator.main.js +0 -102
  232. package/dist/useDropIndicator.main.js.map +0 -1
  233. package/dist/useDropIndicator.mjs +0 -97
  234. package/dist/useDropIndicator.module.js +0 -97
  235. package/dist/useDropIndicator.module.js.map +0 -1
  236. package/dist/useDroppableCollection.main.js +0 -536
  237. package/dist/useDroppableCollection.main.js.map +0 -1
  238. package/dist/useDroppableCollection.mjs +0 -531
  239. package/dist/useDroppableCollection.module.js +0 -531
  240. package/dist/useDroppableCollection.module.js.map +0 -1
  241. package/dist/useDroppableItem.main.js +0 -81
  242. package/dist/useDroppableItem.main.js.map +0 -1
  243. package/dist/useDroppableItem.mjs +0 -76
  244. package/dist/useDroppableItem.module.js +0 -76
  245. package/dist/useDroppableItem.module.js.map +0 -1
  246. package/dist/useVirtualDrop.main.js +0 -56
  247. package/dist/useVirtualDrop.main.js.map +0 -1
  248. package/dist/useVirtualDrop.mjs +0 -51
  249. package/dist/useVirtualDrop.module.js +0 -51
  250. package/dist/useVirtualDrop.module.js.map +0 -1
  251. package/dist/utils.main.js +0 -285
  252. package/dist/utils.main.js.map +0 -1
  253. package/dist/utils.mjs +0 -257
  254. package/dist/utils.module.js +0 -257
  255. package/dist/utils.module.js.map +0 -1
  256. package/dist/zh-CN.main.js +0 -44
  257. package/dist/zh-CN.main.js.map +0 -1
  258. package/dist/zh-CN.mjs +0 -46
  259. package/dist/zh-CN.module.js +0 -46
  260. package/dist/zh-CN.module.js.map +0 -1
  261. package/dist/zh-TW.main.js +0 -44
  262. package/dist/zh-TW.main.js.map +0 -1
  263. package/dist/zh-TW.mjs +0 -46
  264. package/dist/zh-TW.module.js +0 -46
  265. package/dist/zh-TW.module.js.map +0 -1
  266. package/src/DragManager.ts +0 -656
  267. package/src/DragPreview.tsx +0 -81
  268. package/src/DropTargetKeyboardNavigation.ts +0 -282
  269. package/src/ListDropTargetDelegate.ts +0 -182
  270. package/src/constants.ts +0 -85
  271. package/src/useAutoScroll.ts +0 -105
  272. package/src/useClipboard.ts +0 -151
  273. package/src/useDrag.ts +0 -390
  274. package/src/useDraggableCollection.ts +0 -29
  275. package/src/useDraggableItem.ts +0 -158
  276. package/src/useDrop.ts +0 -444
  277. package/src/useDropIndicator.ts +0 -124
  278. package/src/useDroppableCollection.ts +0 -665
  279. package/src/useDroppableItem.ts +0 -86
  280. package/src/useVirtualDrop.ts +0 -49
  281. package/src/utils.ts +0 -385
@@ -1,86 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- import * as DragManager from './DragManager';
14
- import {DroppableCollectionState} from '@react-stately/dnd';
15
- import {DropTarget, FocusableElement, RefObject} from '@react-types/shared';
16
- import {getDroppableCollectionRef, getTypes, globalDndState, isInternalDropOperation} from './utils';
17
- import {HTMLAttributes, useEffect} from 'react';
18
- import {useVirtualDrop} from './useVirtualDrop';
19
-
20
- export interface DroppableItemOptions {
21
- /** The drop target represented by the item. */
22
- target: DropTarget,
23
- /** The ref to the activate button. */
24
- activateButtonRef?: RefObject<FocusableElement | null>
25
- }
26
-
27
- export interface DroppableItemResult {
28
- /** Props for the droppable element. */
29
- dropProps: HTMLAttributes<HTMLElement>,
30
- /** Whether the item is currently the active drop target. */
31
- isDropTarget: boolean
32
- }
33
-
34
- /**
35
- * Handles drop interactions for an item within a collection component.
36
- */
37
- export function useDroppableItem(options: DroppableItemOptions, state: DroppableCollectionState, ref: RefObject<HTMLElement | null>): DroppableItemResult {
38
- let {dropProps} = useVirtualDrop();
39
- let droppableCollectionRef = getDroppableCollectionRef(state);
40
- useEffect(() => {
41
- if (ref.current) {
42
- return DragManager.registerDropItem({
43
- element: ref.current,
44
- target: options.target,
45
- getDropOperation(types, allowedOperations) {
46
- let {draggingKeys} = globalDndState;
47
- let isInternal = isInternalDropOperation(droppableCollectionRef);
48
- return state.getDropOperation({
49
- target: options.target,
50
- types,
51
- allowedOperations,
52
- isInternal,
53
- draggingKeys
54
- });
55
- },
56
- activateButtonRef: options.activateButtonRef
57
- });
58
- }
59
- }, [ref, options.target, state, droppableCollectionRef, options.activateButtonRef]);
60
-
61
- let dragSession = DragManager.useDragSession();
62
- let {draggingKeys} = globalDndState;
63
- let isInternal = isInternalDropOperation(droppableCollectionRef);
64
- let isValidDropTarget = dragSession && state.getDropOperation({
65
- target: options.target,
66
- types: getTypes(dragSession.dragTarget.items),
67
- allowedOperations: dragSession.dragTarget.allowedDropOperations,
68
- isInternal,
69
- draggingKeys
70
- }) !== 'cancel';
71
-
72
- let isDropTarget = state.isDropTarget(options.target);
73
- useEffect(() => {
74
- if (dragSession && isDropTarget && ref.current) {
75
- ref.current.focus();
76
- }
77
- }, [isDropTarget, dragSession, ref]);
78
-
79
- return {
80
- dropProps: {
81
- ...dropProps,
82
- 'aria-hidden': !dragSession || isValidDropTarget ? undefined : 'true'
83
- },
84
- isDropTarget
85
- };
86
- }
@@ -1,49 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- import {AriaButtonProps} from '@react-types/button';
14
- import {DOMAttributes} from 'react';
15
- import * as DragManager from './DragManager';
16
- // @ts-ignore
17
- import intlMessages from '../intl/*.json';
18
- import {useDescription} from '@react-aria/utils';
19
- import {useDragModality} from './utils';
20
- import {useLocalizedStringFormatter} from '@react-aria/i18n';
21
-
22
- interface VirtualDropResult {
23
- dropProps: AriaButtonProps & DOMAttributes<HTMLDivElement>
24
- }
25
-
26
- const MESSAGES = {
27
- keyboard: 'dropDescriptionKeyboard',
28
- touch: 'dropDescriptionTouch',
29
- virtual: 'dropDescriptionVirtual'
30
- };
31
-
32
- export function useVirtualDrop(): VirtualDropResult {
33
- let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/dnd');
34
- let modality = useDragModality();
35
- let dragSession = DragManager.useDragSession();
36
- let descriptionProps = useDescription(dragSession ? stringFormatter.format(MESSAGES[modality]) : '');
37
-
38
- return {
39
- dropProps: {
40
- ...descriptionProps,
41
- // Mobile Safari does not properly bubble click events on elements except links or inputs
42
- // unless there is an onclick handler bound directly to the element itself. By adding this
43
- // handler, React will take care of adding that for us, and we are able to handle document
44
- // level click events in the DragManager.
45
- // See https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
46
- onClick: () => {}
47
- }
48
- };
49
- }
package/src/utils.ts DELETED
@@ -1,385 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- import {CUSTOM_DRAG_TYPE, DROP_OPERATION, GENERIC_TYPE, NATIVE_DRAG_TYPES} from './constants';
14
- import {DirectoryDropItem, DragItem, DropItem, FileDropItem, DragTypes as IDragTypes, Key, RefObject, TextDropItem} from '@react-types/shared';
15
- import {DroppableCollectionState} from '@react-stately/dnd';
16
- import {getInteractionModality, useInteractionModality} from '@react-aria/interactions';
17
-
18
- interface DroppableCollectionMap {
19
- id: string,
20
- ref: RefObject<HTMLElement | null>
21
- }
22
-
23
- export const droppableCollectionMap: WeakMap<DroppableCollectionState, DroppableCollectionMap> = new WeakMap<DroppableCollectionState, DroppableCollectionMap>();
24
- export const DIRECTORY_DRAG_TYPE: symbol = Symbol();
25
-
26
- export function getDroppableCollectionId(state: DroppableCollectionState): string {
27
- let {id} = droppableCollectionMap.get(state) || {};
28
- if (!id) {
29
- throw new Error('Droppable item outside a droppable collection');
30
- }
31
-
32
- return id;
33
- }
34
-
35
- export function getDroppableCollectionRef(state: DroppableCollectionState): RefObject<HTMLElement | null> {
36
- let {ref} = droppableCollectionMap.get(state) || {};
37
- if (!ref) {
38
- throw new Error('Droppable item outside a droppable collection');
39
- }
40
-
41
- return ref;
42
- }
43
-
44
- export function getTypes(items: DragItem[]): Set<string> {
45
- let types = new Set<string>();
46
- for (let item of items) {
47
- for (let type of Object.keys(item)) {
48
- types.add(type);
49
- }
50
- }
51
-
52
- return types;
53
- }
54
-
55
- function mapModality(modality: string | null) {
56
- if (!modality) {
57
- modality = 'virtual';
58
- }
59
-
60
- if (modality === 'pointer') {
61
- modality = 'virtual';
62
- }
63
-
64
- if (modality === 'virtual' && (typeof window !== 'undefined' && 'ontouchstart' in window)) {
65
- modality = 'touch';
66
- }
67
-
68
- return modality;
69
- }
70
-
71
- export function useDragModality(): string {
72
- return mapModality(useInteractionModality());
73
- }
74
-
75
- export function getDragModality(): string {
76
- return mapModality(getInteractionModality());
77
- }
78
-
79
- export function writeToDataTransfer(dataTransfer: DataTransfer, items: DragItem[]): void {
80
- // The data transfer API doesn't support more than one item of a given type at once.
81
- // In addition, only a small set of types are supported natively for transfer between applications.
82
- // We allow for both multiple items, as well as multiple representations of a single item.
83
- // In order to make our API work with the native API, we serialize all items to JSON and
84
- // store as a single native item. We only need to do this if there is more than one item
85
- // of the same type, or if an item has more than one representation. Otherwise the native
86
- // API is sufficient.
87
- //
88
- // The DataTransferItemList API also theoretically supports adding files, which would enable
89
- // dragging binary data out of the browser onto the user's desktop for example. Unfortunately,
90
- // this does not currently work in any browser, so it is not currently supported by our API.
91
- // See e.g. https://bugs.chromium.org/p/chromium/issues/detail?id=438479.
92
- let groupedByType = new Map<string, string[]>();
93
- let needsCustomData = false;
94
- let customData: Array<{}> = [];
95
- for (let item of items) {
96
- let types = Object.keys(item);
97
- if (types.length > 1) {
98
- needsCustomData = true;
99
- }
100
-
101
- let dataByType = {};
102
- for (let type of types) {
103
- let typeItems = groupedByType.get(type);
104
- if (!typeItems) {
105
- typeItems = [];
106
- groupedByType.set(type, typeItems);
107
- } else {
108
- needsCustomData = true;
109
- }
110
-
111
- let data = item[type];
112
- dataByType[type] = data;
113
- typeItems.push(data);
114
- }
115
-
116
- customData.push(dataByType);
117
- }
118
-
119
- for (let [type, items] of groupedByType) {
120
- if (NATIVE_DRAG_TYPES.has(type)) {
121
- // Only one item of a given type can be set on a data transfer.
122
- // Join all of the items together separated by newlines.
123
- let data = items.join('\n');
124
- dataTransfer.items.add(data, type);
125
- } else {
126
- // Set data to the first item so we have access to the list of types.
127
- dataTransfer.items.add(items[0], type);
128
- }
129
- }
130
-
131
- if (needsCustomData) {
132
- let data = JSON.stringify(customData);
133
- dataTransfer.items.add(data, CUSTOM_DRAG_TYPE);
134
- }
135
- }
136
-
137
- export class DragTypes implements IDragTypes {
138
- private types: Set<string>;
139
- private includesUnknownTypes: boolean;
140
-
141
- constructor(dataTransfer: DataTransfer) {
142
- this.types = new Set<string>();
143
-
144
- let hasFiles = false;
145
- for (let item of dataTransfer.items) {
146
- if (item.type !== CUSTOM_DRAG_TYPE) {
147
- if (item.kind === 'file') {
148
- hasFiles = true;
149
- }
150
-
151
- if (item.type) {
152
- this.types.add(item.type);
153
- } else {
154
- // Files with unknown types or extensions that don't map to a known mime type
155
- // are sometimes exposed as an empty string by the browser. Map to a generic
156
- // mime type instead. Note that this could also be a directory as there's no
157
- // way to determine if something is a file or directory until drop.
158
- this.types.add(GENERIC_TYPE);
159
- }
160
- }
161
- }
162
-
163
- // In Safari, when dragging files, the dataTransfer.items list is empty, but dataTransfer.types contains "Files".
164
- // Unfortunately, this doesn't tell us what types of files the user is dragging, so we need to assume that any
165
- // type the user checks for is included. See https://bugs.webkit.org/show_bug.cgi?id=223517.
166
- this.includesUnknownTypes = !hasFiles && dataTransfer.types.includes('Files');
167
- }
168
-
169
- has(type: string | symbol): boolean {
170
- if (this.includesUnknownTypes || (type === DIRECTORY_DRAG_TYPE && this.types.has(GENERIC_TYPE))) {
171
- return true;
172
- }
173
-
174
- return typeof type === 'string' && this.types.has(type);
175
- }
176
- }
177
-
178
- export function readFromDataTransfer(dataTransfer: DataTransfer): DropItem[] {
179
- let items: DropItem[] = [];
180
- if (!dataTransfer) {
181
- return items;
182
- }
183
-
184
- // If our custom drag type is available, use that. This is a JSON serialized
185
- // representation of all items in the drag, set when there are multiple items
186
- // of the same type, or an individual item has multiple representations.
187
- let hasCustomType = false;
188
- if (dataTransfer.types.includes(CUSTOM_DRAG_TYPE)) {
189
- try {
190
- let data = dataTransfer.getData(CUSTOM_DRAG_TYPE);
191
- let parsed = JSON.parse(data);
192
- for (let item of parsed) {
193
- items.push({
194
- kind: 'text',
195
- types: new Set(Object.keys(item)),
196
- getText: (type) => Promise.resolve(item[type])
197
- });
198
- }
199
-
200
- hasCustomType = true;
201
- } catch {
202
- // ignore
203
- }
204
- }
205
-
206
- // Otherwise, map native drag items to items of a single representation.
207
- if (!hasCustomType) {
208
- let stringItems = new Map();
209
- for (let item of dataTransfer.items) {
210
- if (item.kind === 'string') {
211
- // The data for all formats must be read here because the data transfer gets
212
- // cleared out after the event handler finishes. If the item has an empty string
213
- // as a type, the mime type is unknown. Map to a generic mime type instead.
214
- stringItems.set(item.type || GENERIC_TYPE, dataTransfer.getData(item.type));
215
- } else if (item.kind === 'file') {
216
- // Despite the name, webkitGetAsEntry is also implemented in Firefox and Edge.
217
- // In the future, we may use getAsFileSystemHandle instead, but that's currently
218
- // only implemented in Chrome.
219
- if (typeof item.webkitGetAsEntry === 'function') {
220
- let entry: FileSystemEntry | null = item.webkitGetAsEntry();
221
- // eslint-disable-next-line max-depth
222
- if (!entry) {
223
- // For some reason, Firefox includes an item with type image/png when copy
224
- // and pasting any file or directory (no matter the type), but returns `null` for both
225
- // item.getAsFile() and item.webkitGetAsEntry(). Safari works as expected. Ignore this
226
- // item if this happens. See https://bugzilla.mozilla.org/show_bug.cgi?id=1699743.
227
- // This was recently fixed in Chrome Canary: https://bugs.chromium.org/p/chromium/issues/detail?id=1175483.
228
- continue;
229
- }
230
-
231
- // eslint-disable-next-line max-depth
232
- if (entry.isFile) {
233
- items.push(createFileItem(item.getAsFile()));
234
- } else if (entry.isDirectory) {
235
- items.push(createDirectoryItem(entry));
236
- }
237
- } else {
238
- // Assume it's a file.
239
- items.push(createFileItem(item.getAsFile()));
240
- }
241
- }
242
- }
243
-
244
- // All string items are different representations of the same item. There's no way to have
245
- // multiple string items at once in the current DataTransfer API.
246
- if (stringItems.size > 0) {
247
- items.push({
248
- kind: 'text',
249
- types: new Set(stringItems.keys()),
250
- getText: (type) => Promise.resolve(stringItems.get(type))
251
- });
252
- }
253
- }
254
-
255
- return items;
256
- }
257
-
258
- function blobToString(blob: Blob): Promise<string> {
259
- if (typeof blob.text === 'function') {
260
- return blob.text();
261
- }
262
-
263
- // Safari doesn't have the Blob#text() method yet...
264
- return new Promise((resolve, reject) => {
265
- let reader = new FileReader;
266
- reader.onload = () => {
267
- resolve(reader.result as string);
268
- };
269
-
270
- reader.onerror = reject;
271
- reader.readAsText(blob);
272
- });
273
- }
274
-
275
- function createFileItem(file: File | null): FileDropItem {
276
- if (!file) {
277
- throw new Error('No file provided');
278
- }
279
- return {
280
- kind: 'file',
281
- type: file.type || GENERIC_TYPE,
282
- name: file.name,
283
- getText: () => blobToString(file),
284
- getFile: () => Promise.resolve(file)
285
- };
286
- }
287
-
288
- function createDirectoryItem(entry: any): DirectoryDropItem {
289
- return {
290
- kind: 'directory',
291
- name: entry.name,
292
- getEntries: () => getEntries(entry)
293
- };
294
- }
295
-
296
- async function *getEntries(item: FileSystemDirectoryEntry): AsyncIterable<FileDropItem | DirectoryDropItem> {
297
- let reader = item.createReader();
298
-
299
- // We must call readEntries repeatedly because there may be a limit to the
300
- // number of entries that are returned at once.
301
- let entries: FileSystemEntry[];
302
- do {
303
- entries = await new Promise((resolve, reject) => {
304
- reader.readEntries(resolve, reject);
305
- });
306
-
307
- for (let entry of entries) {
308
- if (entry.isFile) {
309
- let file = await getEntryFile(entry as FileSystemFileEntry);
310
- yield createFileItem(file);
311
- } else if (entry.isDirectory) {
312
- yield createDirectoryItem(entry);
313
- }
314
- }
315
- } while (entries.length > 0);
316
- }
317
-
318
- function getEntryFile(entry: FileSystemFileEntry): Promise<File> {
319
- return new Promise((resolve, reject) => entry.file(resolve, reject));
320
- }
321
-
322
- /** Returns whether a drop item contains text data. */
323
- export function isTextDropItem(dropItem: DropItem): dropItem is TextDropItem {
324
- return dropItem.kind === 'text';
325
- }
326
-
327
- /** Returns whether a drop item is a file. */
328
- export function isFileDropItem(dropItem: DropItem): dropItem is FileDropItem {
329
- return dropItem.kind === 'file';
330
- }
331
-
332
- /** Returns whether a drop item is a directory. */
333
- export function isDirectoryDropItem(dropItem: DropItem): dropItem is DirectoryDropItem {
334
- return dropItem.kind === 'directory';
335
- }
336
-
337
- // Global DnD collection state tracker.
338
- export interface DnDState {
339
- /** A ref for the of the drag items in the current drag session if any. */
340
- draggingCollectionRef?: RefObject<HTMLElement | null>,
341
- /** The set of currently dragged keys. */
342
- draggingKeys: Set<Key>,
343
- /** A ref for the collection that is targeted for a drop operation, if any. */
344
- dropCollectionRef?: RefObject<HTMLElement | null>
345
- }
346
-
347
- export let globalDndState: DnDState = {draggingKeys: new Set()};
348
-
349
- export function setDraggingCollectionRef(ref: RefObject<HTMLElement | null>): void {
350
- globalDndState.draggingCollectionRef = ref;
351
- }
352
-
353
- export function setDraggingKeys(keys: Set<Key>): void {
354
- globalDndState.draggingKeys = keys;
355
- }
356
-
357
- export function setDropCollectionRef(ref?: RefObject<HTMLElement | null>): void {
358
- globalDndState.dropCollectionRef = ref;
359
- }
360
-
361
- export function clearGlobalDnDState(): void {
362
- globalDndState = {draggingKeys: new Set()};
363
- }
364
-
365
- export function setGlobalDnDState(state: DnDState): void {
366
- globalDndState = state;
367
- }
368
-
369
- // Util function to check if the current dragging collection ref is the same as the current targeted droppable collection ref.
370
- // Allows a droppable ref arg in case the global drop collection ref hasn't been set
371
- export function isInternalDropOperation(ref?: RefObject<HTMLElement | null>): boolean {
372
- let {draggingCollectionRef, dropCollectionRef} = globalDndState;
373
- return draggingCollectionRef?.current != null && draggingCollectionRef.current === (ref?.current || dropCollectionRef?.current);
374
- }
375
-
376
- type DropEffect = 'none' | 'copy' | 'link' | 'move';
377
- export let globalDropEffect: DropEffect | undefined;
378
- export function setGlobalDropEffect(dropEffect: DropEffect | undefined): void {
379
- globalDropEffect = dropEffect;
380
- }
381
-
382
- export let globalAllowedDropOperations: DROP_OPERATION = DROP_OPERATION.none;
383
- export function setGlobalAllowedDropOperations(o: DROP_OPERATION): void {
384
- globalAllowedDropOperations = o;
385
- }