@octanejs/aria 0.0.40 → 0.0.41

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 (416) hide show
  1. package/LICENSE-APACHE-2.0 +201 -0
  2. package/README.md +20 -7
  3. package/UPSTREAM.md +108 -0
  4. package/package.json +10 -6
  5. package/src/calendar/useCalendar.tsx +36 -0
  6. package/src/calendar/useCalendarBase.tsx +142 -0
  7. package/src/calendar/useCalendarCell.tsx +416 -0
  8. package/src/calendar/useCalendarGrid.tsx +202 -0
  9. package/src/calendar/useCalendarHeading.tsx +85 -0
  10. package/src/calendar/useCalendarMonthPicker.tsx +92 -0
  11. package/src/calendar/useCalendarYearPicker.tsx +127 -0
  12. package/src/calendar/useRangeCalendar.tsx +121 -0
  13. package/src/calendar/utils.tsx +183 -0
  14. package/src/color/useColorArea.tsx +599 -0
  15. package/src/color/useColorAreaGradient.tsx +157 -0
  16. package/src/color/useColorChannelField.tsx +53 -0
  17. package/src/color/useColorField.tsx +170 -0
  18. package/src/color/useColorSlider.tsx +177 -0
  19. package/src/color/useColorSwatch.tsx +83 -0
  20. package/src/color/useColorWheel.tsx +401 -0
  21. package/src/compat/react.ts +111 -0
  22. package/src/components/Calendar.tsx +842 -0
  23. package/src/components/ColorArea.tsx +120 -0
  24. package/src/components/ColorField.tsx +304 -0
  25. package/src/components/ColorPicker.tsx +86 -0
  26. package/src/components/ColorSlider.tsx +144 -0
  27. package/src/components/ColorSwatch.tsx +72 -0
  28. package/src/components/ColorSwatchPicker.tsx +176 -0
  29. package/src/components/ColorThumb.tsx +140 -0
  30. package/src/components/ColorWheel.tsx +163 -0
  31. package/src/components/DateField.tsx +580 -0
  32. package/src/components/DatePicker.tsx +386 -0
  33. package/src/components/DropZone.tsx +181 -0
  34. package/src/components/FileTrigger.tsx +96 -0
  35. package/src/components/GridLayout.tsx +33 -0
  36. package/src/components/HiddenDateInput.tsx +169 -0
  37. package/src/components/TableLayout.tsx +39 -0
  38. package/src/components/Toast.tsx +336 -0
  39. package/src/components/Virtualizer.tsx +219 -0
  40. package/src/components/index.ts +257 -7
  41. package/src/components/useDragAndDrop.tsx +221 -0
  42. package/src/components/utils.ts +12 -89
  43. package/src/datepicker/useDateField.tsx +272 -0
  44. package/src/datepicker/useDatePicker.tsx +229 -0
  45. package/src/datepicker/useDatePickerGroup.tsx +147 -0
  46. package/src/datepicker/useDateRangePicker.tsx +288 -0
  47. package/src/datepicker/useDateSegment.tsx +439 -0
  48. package/src/datepicker/useDisplayNames.tsx +53 -0
  49. package/src/dnd/DragManager.tsx +718 -0
  50. package/src/dnd/DragPreview.tsx +100 -0
  51. package/src/dnd/DropTargetKeyboardNavigation.tsx +317 -0
  52. package/src/dnd/ListDropTargetDelegate.tsx +215 -0
  53. package/src/dnd/constants.tsx +93 -0
  54. package/src/dnd/useAutoScroll.tsx +116 -0
  55. package/src/dnd/useClipboard.tsx +160 -0
  56. package/src/dnd/useDrag.tsx +437 -0
  57. package/src/dnd/useDraggableCollection.tsx +35 -0
  58. package/src/dnd/useDraggableItem.tsx +168 -0
  59. package/src/dnd/useDrop.tsx +518 -0
  60. package/src/dnd/useDropIndicator.tsx +129 -0
  61. package/src/dnd/useDroppableCollection.tsx +808 -0
  62. package/src/dnd/useDroppableItem.tsx +99 -0
  63. package/src/dnd/useVirtualDrop.tsx +52 -0
  64. package/src/dnd/utils.tsx +430 -0
  65. package/src/intl/calendar/ar-AE.json +14 -0
  66. package/src/intl/calendar/bg-BG.json +14 -0
  67. package/src/intl/calendar/cs-CZ.json +14 -0
  68. package/src/intl/calendar/da-DK.json +14 -0
  69. package/src/intl/calendar/de-DE.json +14 -0
  70. package/src/intl/calendar/el-GR.json +14 -0
  71. package/src/intl/calendar/en-US.json +14 -0
  72. package/src/intl/calendar/es-ES.json +14 -0
  73. package/src/intl/calendar/et-EE.json +14 -0
  74. package/src/intl/calendar/fi-FI.json +14 -0
  75. package/src/intl/calendar/fr-FR.json +14 -0
  76. package/src/intl/calendar/he-IL.json +14 -0
  77. package/src/intl/calendar/hr-HR.json +14 -0
  78. package/src/intl/calendar/hu-HU.json +14 -0
  79. package/src/intl/calendar/index.ts +73 -0
  80. package/src/intl/calendar/it-IT.json +14 -0
  81. package/src/intl/calendar/ja-JP.json +14 -0
  82. package/src/intl/calendar/ko-KR.json +14 -0
  83. package/src/intl/calendar/lt-LT.json +14 -0
  84. package/src/intl/calendar/lv-LV.json +14 -0
  85. package/src/intl/calendar/nb-NO.json +14 -0
  86. package/src/intl/calendar/nl-NL.json +14 -0
  87. package/src/intl/calendar/pl-PL.json +14 -0
  88. package/src/intl/calendar/pt-BR.json +14 -0
  89. package/src/intl/calendar/pt-PT.json +14 -0
  90. package/src/intl/calendar/ro-RO.json +14 -0
  91. package/src/intl/calendar/ru-RU.json +14 -0
  92. package/src/intl/calendar/sk-SK.json +14 -0
  93. package/src/intl/calendar/sl-SI.json +14 -0
  94. package/src/intl/calendar/sr-SP.json +14 -0
  95. package/src/intl/calendar/sv-SE.json +14 -0
  96. package/src/intl/calendar/tr-TR.json +14 -0
  97. package/src/intl/calendar/uk-UA.json +14 -0
  98. package/src/intl/calendar/zh-CN.json +14 -0
  99. package/src/intl/calendar/zh-TW.json +14 -0
  100. package/src/intl/color/ar-AE.json +8 -0
  101. package/src/intl/color/bg-BG.json +8 -0
  102. package/src/intl/color/cs-CZ.json +8 -0
  103. package/src/intl/color/da-DK.json +8 -0
  104. package/src/intl/color/de-DE.json +8 -0
  105. package/src/intl/color/el-GR.json +8 -0
  106. package/src/intl/color/en-US.json +8 -0
  107. package/src/intl/color/es-ES.json +8 -0
  108. package/src/intl/color/et-EE.json +8 -0
  109. package/src/intl/color/fi-FI.json +8 -0
  110. package/src/intl/color/fr-FR.json +8 -0
  111. package/src/intl/color/he-IL.json +8 -0
  112. package/src/intl/color/hr-HR.json +8 -0
  113. package/src/intl/color/hu-HU.json +8 -0
  114. package/src/intl/color/index.ts +73 -0
  115. package/src/intl/color/it-IT.json +8 -0
  116. package/src/intl/color/ja-JP.json +8 -0
  117. package/src/intl/color/ko-KR.json +8 -0
  118. package/src/intl/color/lt-LT.json +8 -0
  119. package/src/intl/color/lv-LV.json +8 -0
  120. package/src/intl/color/nb-NO.json +8 -0
  121. package/src/intl/color/nl-NL.json +8 -0
  122. package/src/intl/color/pl-PL.json +8 -0
  123. package/src/intl/color/pt-BR.json +8 -0
  124. package/src/intl/color/pt-PT.json +8 -0
  125. package/src/intl/color/ro-RO.json +8 -0
  126. package/src/intl/color/ru-RU.json +8 -0
  127. package/src/intl/color/sk-SK.json +8 -0
  128. package/src/intl/color/sl-SI.json +8 -0
  129. package/src/intl/color/sr-SP.json +8 -0
  130. package/src/intl/color/sv-SE.json +8 -0
  131. package/src/intl/color/tr-TR.json +8 -0
  132. package/src/intl/color/uk-UA.json +8 -0
  133. package/src/intl/color/zh-CN.json +8 -0
  134. package/src/intl/color/zh-TW.json +8 -0
  135. package/src/intl/datepicker/ar-AE.json +18 -0
  136. package/src/intl/datepicker/bg-BG.json +18 -0
  137. package/src/intl/datepicker/cs-CZ.json +18 -0
  138. package/src/intl/datepicker/da-DK.json +18 -0
  139. package/src/intl/datepicker/de-DE.json +18 -0
  140. package/src/intl/datepicker/el-GR.json +18 -0
  141. package/src/intl/datepicker/en-US.json +18 -0
  142. package/src/intl/datepicker/es-ES.json +18 -0
  143. package/src/intl/datepicker/et-EE.json +18 -0
  144. package/src/intl/datepicker/fi-FI.json +18 -0
  145. package/src/intl/datepicker/fr-FR.json +18 -0
  146. package/src/intl/datepicker/he-IL.json +18 -0
  147. package/src/intl/datepicker/hr-HR.json +18 -0
  148. package/src/intl/datepicker/hu-HU.json +18 -0
  149. package/src/intl/datepicker/index.ts +73 -0
  150. package/src/intl/datepicker/it-IT.json +18 -0
  151. package/src/intl/datepicker/ja-JP.json +18 -0
  152. package/src/intl/datepicker/ko-KR.json +18 -0
  153. package/src/intl/datepicker/lt-LT.json +18 -0
  154. package/src/intl/datepicker/lv-LV.json +18 -0
  155. package/src/intl/datepicker/nb-NO.json +18 -0
  156. package/src/intl/datepicker/nl-NL.json +18 -0
  157. package/src/intl/datepicker/pl-PL.json +18 -0
  158. package/src/intl/datepicker/pt-BR.json +18 -0
  159. package/src/intl/datepicker/pt-PT.json +18 -0
  160. package/src/intl/datepicker/ro-RO.json +18 -0
  161. package/src/intl/datepicker/ru-RU.json +18 -0
  162. package/src/intl/datepicker/sk-SK.json +18 -0
  163. package/src/intl/datepicker/sl-SI.json +18 -0
  164. package/src/intl/datepicker/sr-SP.json +18 -0
  165. package/src/intl/datepicker/sv-SE.json +18 -0
  166. package/src/intl/datepicker/tr-TR.json +18 -0
  167. package/src/intl/datepicker/uk-UA.json +18 -0
  168. package/src/intl/datepicker/zh-CN.json +18 -0
  169. package/src/intl/datepicker/zh-TW.json +18 -0
  170. package/src/intl/dnd/ar-AE.json +29 -0
  171. package/src/intl/dnd/bg-BG.json +29 -0
  172. package/src/intl/dnd/cs-CZ.json +29 -0
  173. package/src/intl/dnd/da-DK.json +29 -0
  174. package/src/intl/dnd/de-DE.json +29 -0
  175. package/src/intl/dnd/el-GR.json +29 -0
  176. package/src/intl/dnd/en-US.json +29 -0
  177. package/src/intl/dnd/es-ES.json +29 -0
  178. package/src/intl/dnd/et-EE.json +29 -0
  179. package/src/intl/dnd/fi-FI.json +29 -0
  180. package/src/intl/dnd/fr-FR.json +29 -0
  181. package/src/intl/dnd/he-IL.json +29 -0
  182. package/src/intl/dnd/hr-HR.json +29 -0
  183. package/src/intl/dnd/hu-HU.json +29 -0
  184. package/src/intl/dnd/index.ts +73 -0
  185. package/src/intl/dnd/it-IT.json +29 -0
  186. package/src/intl/dnd/ja-JP.json +29 -0
  187. package/src/intl/dnd/ko-KR.json +29 -0
  188. package/src/intl/dnd/lt-LT.json +29 -0
  189. package/src/intl/dnd/lv-LV.json +29 -0
  190. package/src/intl/dnd/nb-NO.json +29 -0
  191. package/src/intl/dnd/nl-NL.json +29 -0
  192. package/src/intl/dnd/pl-PL.json +29 -0
  193. package/src/intl/dnd/pt-BR.json +29 -0
  194. package/src/intl/dnd/pt-PT.json +29 -0
  195. package/src/intl/dnd/ro-RO.json +29 -0
  196. package/src/intl/dnd/ru-RU.json +29 -0
  197. package/src/intl/dnd/sk-SK.json +29 -0
  198. package/src/intl/dnd/sl-SI.json +29 -0
  199. package/src/intl/dnd/sr-SP.json +29 -0
  200. package/src/intl/dnd/sv-SE.json +29 -0
  201. package/src/intl/dnd/tr-TR.json +29 -0
  202. package/src/intl/dnd/uk-UA.json +29 -0
  203. package/src/intl/dnd/zh-CN.json +29 -0
  204. package/src/intl/dnd/zh-TW.json +29 -0
  205. package/src/intl/react-aria-components/ar-AE.json +6 -0
  206. package/src/intl/react-aria-components/bg-BG.json +6 -0
  207. package/src/intl/react-aria-components/cs-CZ.json +6 -0
  208. package/src/intl/react-aria-components/da-DK.json +6 -0
  209. package/src/intl/react-aria-components/de-DE.json +6 -0
  210. package/src/intl/react-aria-components/el-GR.json +6 -0
  211. package/src/intl/react-aria-components/en-US.json +6 -0
  212. package/src/intl/react-aria-components/es-ES.json +6 -0
  213. package/src/intl/react-aria-components/et-EE.json +6 -0
  214. package/src/intl/react-aria-components/fi-FI.json +6 -0
  215. package/src/intl/react-aria-components/fr-FR.json +6 -0
  216. package/src/intl/react-aria-components/he-IL.json +6 -0
  217. package/src/intl/react-aria-components/hr-HR.json +6 -0
  218. package/src/intl/react-aria-components/hu-HU.json +6 -0
  219. package/src/intl/react-aria-components/index.ts +73 -0
  220. package/src/intl/react-aria-components/it-IT.json +6 -0
  221. package/src/intl/react-aria-components/ja-JP.json +6 -0
  222. package/src/intl/react-aria-components/ko-KR.json +6 -0
  223. package/src/intl/react-aria-components/lt-LT.json +6 -0
  224. package/src/intl/react-aria-components/lv-LV.json +6 -0
  225. package/src/intl/react-aria-components/nb-NO.json +6 -0
  226. package/src/intl/react-aria-components/nl-NL.json +6 -0
  227. package/src/intl/react-aria-components/pl-PL.json +6 -0
  228. package/src/intl/react-aria-components/pt-BR.json +6 -0
  229. package/src/intl/react-aria-components/pt-PT.json +6 -0
  230. package/src/intl/react-aria-components/ro-RO.json +6 -0
  231. package/src/intl/react-aria-components/ru-RU.json +6 -0
  232. package/src/intl/react-aria-components/sk-SK.json +6 -0
  233. package/src/intl/react-aria-components/sl-SI.json +6 -0
  234. package/src/intl/react-aria-components/sr-SP.json +6 -0
  235. package/src/intl/react-aria-components/sv-SE.json +6 -0
  236. package/src/intl/react-aria-components/tr-TR.json +6 -0
  237. package/src/intl/react-aria-components/uk-UA.json +6 -0
  238. package/src/intl/react-aria-components/zh-CN.json +6 -0
  239. package/src/intl/react-aria-components/zh-TW.json +6 -0
  240. package/src/intl/stately-color/ar-AE.json +39 -0
  241. package/src/intl/stately-color/bg-BG.json +39 -0
  242. package/src/intl/stately-color/cs-CZ.json +39 -0
  243. package/src/intl/stately-color/da-DK.json +39 -0
  244. package/src/intl/stately-color/de-DE.json +39 -0
  245. package/src/intl/stately-color/el-GR.json +39 -0
  246. package/src/intl/stately-color/en-US.json +39 -0
  247. package/src/intl/stately-color/es-ES.json +39 -0
  248. package/src/intl/stately-color/et-EE.json +39 -0
  249. package/src/intl/stately-color/fi-FI.json +39 -0
  250. package/src/intl/stately-color/fr-FR.json +39 -0
  251. package/src/intl/stately-color/he-IL.json +39 -0
  252. package/src/intl/stately-color/hr-HR.json +39 -0
  253. package/src/intl/stately-color/hu-HU.json +39 -0
  254. package/src/intl/stately-color/index.ts +73 -0
  255. package/src/intl/stately-color/it-IT.json +39 -0
  256. package/src/intl/stately-color/ja-JP.json +39 -0
  257. package/src/intl/stately-color/ko-KR.json +39 -0
  258. package/src/intl/stately-color/lt-LT.json +39 -0
  259. package/src/intl/stately-color/lv-LV.json +39 -0
  260. package/src/intl/stately-color/nb-NO.json +39 -0
  261. package/src/intl/stately-color/nl-NL.json +39 -0
  262. package/src/intl/stately-color/pl-PL.json +39 -0
  263. package/src/intl/stately-color/pt-BR.json +39 -0
  264. package/src/intl/stately-color/pt-PT.json +39 -0
  265. package/src/intl/stately-color/ro-RO.json +39 -0
  266. package/src/intl/stately-color/ru-RU.json +39 -0
  267. package/src/intl/stately-color/sk-SK.json +39 -0
  268. package/src/intl/stately-color/sl-SI.json +39 -0
  269. package/src/intl/stately-color/sr-SP.json +39 -0
  270. package/src/intl/stately-color/sv-SE.json +39 -0
  271. package/src/intl/stately-color/tr-TR.json +39 -0
  272. package/src/intl/stately-color/uk-UA.json +39 -0
  273. package/src/intl/stately-color/zh-CN.json +39 -0
  274. package/src/intl/stately-color/zh-TW.json +39 -0
  275. package/src/intl/toast/ar-AE.json +4 -0
  276. package/src/intl/toast/bg-BG.json +4 -0
  277. package/src/intl/toast/cs-CZ.json +4 -0
  278. package/src/intl/toast/da-DK.json +4 -0
  279. package/src/intl/toast/de-DE.json +4 -0
  280. package/src/intl/toast/el-GR.json +4 -0
  281. package/src/intl/toast/en-US.json +4 -0
  282. package/src/intl/toast/es-ES.json +4 -0
  283. package/src/intl/toast/et-EE.json +4 -0
  284. package/src/intl/toast/fi-FI.json +4 -0
  285. package/src/intl/toast/fr-FR.json +4 -0
  286. package/src/intl/toast/he-IL.json +4 -0
  287. package/src/intl/toast/hr-HR.json +4 -0
  288. package/src/intl/toast/hu-HU.json +4 -0
  289. package/src/intl/toast/index.ts +73 -0
  290. package/src/intl/toast/it-IT.json +4 -0
  291. package/src/intl/toast/ja-JP.json +4 -0
  292. package/src/intl/toast/ko-KR.json +4 -0
  293. package/src/intl/toast/lt-LT.json +4 -0
  294. package/src/intl/toast/lv-LV.json +4 -0
  295. package/src/intl/toast/nb-NO.json +4 -0
  296. package/src/intl/toast/nl-NL.json +4 -0
  297. package/src/intl/toast/pl-PL.json +4 -0
  298. package/src/intl/toast/pt-BR.json +4 -0
  299. package/src/intl/toast/pt-PT.json +4 -0
  300. package/src/intl/toast/ro-RO.json +4 -0
  301. package/src/intl/toast/ru-RU.json +4 -0
  302. package/src/intl/toast/sk-SK.json +4 -0
  303. package/src/intl/toast/sl-SI.json +4 -0
  304. package/src/intl/toast/sr-SP.json +4 -0
  305. package/src/intl/toast/sv-SE.json +4 -0
  306. package/src/intl/toast/tr-TR.json +4 -0
  307. package/src/intl/toast/uk-UA.json +4 -0
  308. package/src/intl/toast/zh-CN.json +4 -0
  309. package/src/intl/toast/zh-TW.json +4 -0
  310. package/src/landmark/useLandmark.tsx +569 -0
  311. package/src/stately/calendar/types.tsx +239 -0
  312. package/src/stately/calendar/useCalendarState.tsx +527 -0
  313. package/src/stately/calendar/useRangeCalendarState.tsx +323 -0
  314. package/src/stately/calendar/utils.tsx +175 -0
  315. package/src/stately/color/Color.tsx +889 -0
  316. package/src/stately/color/types.tsx +82 -0
  317. package/src/stately/color/useColor.tsx +30 -0
  318. package/src/stately/color/useColorAreaState.tsx +255 -0
  319. package/src/stately/color/useColorChannelFieldState.tsx +86 -0
  320. package/src/stately/color/useColorFieldState.tsx +220 -0
  321. package/src/stately/color/useColorPickerState.tsx +31 -0
  322. package/src/stately/color/useColorSliderState.tsx +143 -0
  323. package/src/stately/color/useColorWheelState.tsx +225 -0
  324. package/src/stately/data/useAsyncList.tsx +382 -0
  325. package/src/stately/data/useListData.tsx +447 -0
  326. package/src/stately/data/useTreeData.tsx +603 -0
  327. package/src/stately/datepicker/IncompleteDate.tsx +427 -0
  328. package/src/stately/datepicker/placeholders.tsx +116 -0
  329. package/src/stately/datepicker/types.tsx +169 -0
  330. package/src/stately/datepicker/useDateFieldState.tsx +564 -0
  331. package/src/stately/datepicker/useDatePickerState.tsx +244 -0
  332. package/src/stately/datepicker/useDateRangePickerState.tsx +397 -0
  333. package/src/stately/datepicker/useTimeFieldState.tsx +123 -0
  334. package/src/stately/datepicker/utils.tsx +316 -0
  335. package/src/stately/dnd/useDraggableCollectionState.tsx +191 -0
  336. package/src/stately/dnd/useDroppableCollectionState.tsx +288 -0
  337. package/src/stately/layout/GridLayout.tsx +449 -0
  338. package/src/stately/layout/ListLayout.tsx +872 -0
  339. package/src/stately/layout/TableLayout.tsx +793 -0
  340. package/src/stately/layout/WaterfallLayout.tsx +399 -0
  341. package/src/stately/toast/useToastState.tsx +219 -0
  342. package/src/stately/virtualizer/Layout.tsx +105 -0
  343. package/src/stately/virtualizer/LayoutInfo.tsx +127 -0
  344. package/src/stately/virtualizer/OverscanManager.tsx +56 -0
  345. package/src/stately/virtualizer/Point.tsx +47 -0
  346. package/src/stately/virtualizer/Rect.tsx +194 -0
  347. package/src/stately/virtualizer/ReusableView.tsx +101 -0
  348. package/src/stately/virtualizer/Size.tsx +48 -0
  349. package/src/stately/virtualizer/Virtualizer.tsx +408 -0
  350. package/src/stately/virtualizer/types.tsx +48 -0
  351. package/src/stately/virtualizer/useVirtualizerState.tsx +138 -0
  352. package/src/stately/virtualizer/utils.tsx +32 -0
  353. package/src/textfield/useTextField.ts +3 -0
  354. package/src/toast/useToast.tsx +105 -0
  355. package/src/toast/useToastRegion.tsx +223 -0
  356. package/src/upstream-exports/react-aria/I18nProvider.tsx +17 -0
  357. package/src/upstream-exports/react-aria/ListDropTargetDelegate.tsx +15 -0
  358. package/src/upstream-exports/react-aria/PortalProvider.tsx +19 -0
  359. package/src/upstream-exports/react-aria/SSRProvider.tsx +15 -0
  360. package/src/upstream-exports/react-aria/VisuallyHidden.tsx +15 -0
  361. package/src/upstream-exports/react-aria/filterDOMProps.tsx +3 -0
  362. package/src/upstream-exports/react-aria/mergeProps.tsx +14 -0
  363. package/src/upstream-exports/react-aria/private/dnd/DragManager.tsx +3 -0
  364. package/src/upstream-exports/react-aria/private/interactions/PressResponder.tsx +3 -0
  365. package/src/upstream-exports/react-aria/private/utils/isFocusable.tsx +3 -0
  366. package/src/upstream-exports/react-aria/private/utils/shadowdom/DOMFunctions.tsx +8 -0
  367. package/src/upstream-exports/react-aria/private/utils/useId.tsx +3 -0
  368. package/src/upstream-exports/react-aria/private/utils/useLabels.tsx +3 -0
  369. package/src/upstream-exports/react-aria/private/virtualizer/ScrollView.tsx +3 -0
  370. package/src/upstream-exports/react-aria/private/virtualizer/VirtualizerItem.tsx +3 -0
  371. package/src/upstream-exports/react-aria/useButton.tsx +22 -0
  372. package/src/upstream-exports/react-aria/useCalendar.tsx +37 -0
  373. package/src/upstream-exports/react-aria/useClipboard.tsx +23 -0
  374. package/src/upstream-exports/react-aria/useColorArea.tsx +19 -0
  375. package/src/upstream-exports/react-aria/useColorField.tsx +20 -0
  376. package/src/upstream-exports/react-aria/useColorSlider.tsx +19 -0
  377. package/src/upstream-exports/react-aria/useColorSwatch.tsx +15 -0
  378. package/src/upstream-exports/react-aria/useColorWheel.tsx +19 -0
  379. package/src/upstream-exports/react-aria/useDateField.tsx +23 -0
  380. package/src/upstream-exports/react-aria/useDatePicker.tsx +17 -0
  381. package/src/upstream-exports/react-aria/useDateRangePicker.tsx +24 -0
  382. package/src/upstream-exports/react-aria/useDraggableCollection.tsx +31 -0
  383. package/src/upstream-exports/react-aria/useDrop.tsx +33 -0
  384. package/src/upstream-exports/react-aria/useDroppableCollection.tsx +47 -0
  385. package/src/upstream-exports/react-aria/useFocusRing.tsx +16 -0
  386. package/src/upstream-exports/react-aria/useHover.tsx +17 -0
  387. package/src/upstream-exports/react-aria/useLocalizedStringFormatter.tsx +19 -0
  388. package/src/upstream-exports/react-aria/useObjectRef.tsx +14 -0
  389. package/src/upstream-exports/react-aria/useRangeCalendar.tsx +38 -0
  390. package/src/upstream-exports/react-aria/useTimeField.tsx +23 -0
  391. package/src/upstream-exports/react-aria/useToast.tsx +18 -0
  392. package/src/upstream-exports/react-stately/Color.tsx +23 -0
  393. package/src/upstream-exports/react-stately/private/form/useFormValidationState.tsx +11 -0
  394. package/src/upstream-exports/react-stately/useCalendarState.tsx +24 -0
  395. package/src/upstream-exports/react-stately/useColorAreaState.tsx +24 -0
  396. package/src/upstream-exports/react-stately/useColorFieldState.tsx +22 -0
  397. package/src/upstream-exports/react-stately/useColorPickerState.tsx +25 -0
  398. package/src/upstream-exports/react-stately/useColorSliderState.tsx +25 -0
  399. package/src/upstream-exports/react-stately/useColorWheelState.tsx +24 -0
  400. package/src/upstream-exports/react-stately/useDateFieldState.tsx +29 -0
  401. package/src/upstream-exports/react-stately/useDatePickerState.tsx +25 -0
  402. package/src/upstream-exports/react-stately/useDateRangePickerState.tsx +26 -0
  403. package/src/upstream-exports/react-stately/useDraggableCollectionState.tsx +19 -0
  404. package/src/upstream-exports/react-stately/useDroppableCollectionState.tsx +19 -0
  405. package/src/upstream-exports/react-stately/useRangeCalendarState.tsx +27 -0
  406. package/src/upstream-exports/react-stately/useTimeFieldState.tsx +26 -0
  407. package/src/upstream-exports/react-stately/useToastState.tsx +21 -0
  408. package/src/upstream-exports/react-stately/useVirtualizerState.tsx +22 -0
  409. package/src/utils/useLoadMore.tsx +89 -0
  410. package/src/virtualizer/ScrollView.tsx +401 -0
  411. package/src/virtualizer/Virtualizer.tsx +147 -0
  412. package/src/virtualizer/VirtualizerItem.tsx +108 -0
  413. package/src/virtualizer/useVirtualizerItem.tsx +57 -0
  414. package/src/virtualizer/utils.tsx +105 -0
  415. package/LICENSE +0 -21
  416. package/src/components/useDragAndDrop.ts +0 -164
@@ -0,0 +1,100 @@
1
+ /** @jsxImportSource octane */
2
+ // Ported from adobe/react-spectrum@1c84a49a1faf50b571c84e00bcf9c60b22ddd03e (packages/react-aria/src/dnd/DragPreview.tsx).
3
+ /*
4
+ * Copyright 2020 Adobe. All rights reserved.
5
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License. You may obtain a copy
7
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software distributed under
10
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
11
+ * OF ANY KIND, either express or implied. See the License for the specific language
12
+ * governing permissions and limitations under the License.
13
+ */
14
+
15
+ import { DragItem, DragPreviewRenderer } from '@react-types/shared';
16
+ import { flushSync } from 'octane';
17
+ import React, {
18
+ ForwardedRef,
19
+ JSX,
20
+ useEffect,
21
+ useImperativeHandle,
22
+ useRef,
23
+ useState,
24
+ } from '../compat/react';
25
+
26
+ export interface DragPreviewProps {
27
+ /**
28
+ * A render function which returns a preview element, or an object containing the element
29
+ * and a custom offset. If an object is returned, the provided `x` and `y` values will be
30
+ * used as the drag preview offset instead of the default calculation.
31
+ */
32
+ children: (
33
+ items: DragItem[],
34
+ ) => JSX.Element | { element: JSX.Element; x: number; y: number } | null;
35
+ }
36
+
37
+ export const DragPreview: React.ForwardRefExoticComponent<
38
+ DragPreviewProps & React.RefAttributes<DragPreviewRenderer | null>
39
+ > = React.forwardRef(function DragPreview(
40
+ props: DragPreviewProps,
41
+ ref: ForwardedRef<DragPreviewRenderer | null>,
42
+ ) {
43
+ let render = props.children;
44
+ let [children, setChildren] = useState<JSX.Element | null>(null);
45
+ let domRef = useRef<HTMLDivElement | null>(null);
46
+ let raf = useRef<ReturnType<typeof requestAnimationFrame> | undefined>(undefined);
47
+
48
+ useImperativeHandle(
49
+ ref,
50
+ () =>
51
+ (items: DragItem[], callback: (node: HTMLElement | null, x?: number, y?: number) => void) => {
52
+ // This will be called during the onDragStart event by useDrag. We need to render the
53
+ // preview synchronously before this event returns so we can call event.dataTransfer.setDragImage.
54
+
55
+ let result = render(items);
56
+ let element: JSX.Element | null;
57
+ let offsetX: number | undefined;
58
+ let offsetY: number | undefined;
59
+
60
+ if (result && typeof result === 'object' && 'element' in result) {
61
+ element = result.element;
62
+ offsetX = result.x;
63
+ offsetY = result.y;
64
+ } else {
65
+ element = result as JSX.Element | null;
66
+ }
67
+
68
+ flushSync(() => {
69
+ setChildren(element);
70
+ });
71
+
72
+ // Yield back to useDrag to set the drag image.
73
+ callback(domRef.current, offsetX, offsetY);
74
+
75
+ // Remove the preview from the DOM after a frame so the browser has time to paint.
76
+ raf.current = requestAnimationFrame(() => {
77
+ setChildren(null);
78
+ });
79
+ },
80
+ [render],
81
+ );
82
+
83
+ useEffect(() => {
84
+ return () => {
85
+ if (raf.current) {
86
+ cancelAnimationFrame(raf.current);
87
+ }
88
+ };
89
+ }, []);
90
+
91
+ if (!children) {
92
+ return null;
93
+ }
94
+
95
+ return (
96
+ <div style={{ zIndex: -100, position: 'fixed', top: 0, left: -100000 }} ref={domRef}>
97
+ {children}
98
+ </div>
99
+ );
100
+ });
@@ -0,0 +1,317 @@
1
+ /** @jsxImportSource octane */
2
+ // Ported from adobe/react-spectrum@1c84a49a1faf50b571c84e00bcf9c60b22ddd03e (packages/react-aria/src/dnd/DropTargetKeyboardNavigation.ts).
3
+ import { Collection, DropTarget, Key, KeyboardDelegate, Node } from '@react-types/shared';
4
+
5
+ export function navigate(
6
+ keyboardDelegate: KeyboardDelegate,
7
+ collection: Collection<Node<unknown>>,
8
+ target: DropTarget | null | undefined,
9
+ direction: 'left' | 'right' | 'up' | 'down',
10
+ rtl = false,
11
+ wrap = false,
12
+ ): DropTarget | null {
13
+ switch (direction) {
14
+ case 'left':
15
+ return rtl
16
+ ? nextDropTarget(keyboardDelegate, collection, target, wrap, 'left')
17
+ : previousDropTarget(keyboardDelegate, collection, target, wrap, 'left');
18
+ case 'right':
19
+ return rtl
20
+ ? previousDropTarget(keyboardDelegate, collection, target, wrap, 'right')
21
+ : nextDropTarget(keyboardDelegate, collection, target, wrap, 'right');
22
+ case 'up':
23
+ return previousDropTarget(keyboardDelegate, collection, target, wrap);
24
+ case 'down':
25
+ return nextDropTarget(keyboardDelegate, collection, target, wrap);
26
+ }
27
+ }
28
+
29
+ function nextDropTarget(
30
+ keyboardDelegate: KeyboardDelegate,
31
+ collection: Collection<Node<unknown>>,
32
+ target: DropTarget | null | undefined,
33
+ wrap = false,
34
+ horizontal: 'left' | 'right' | null = null,
35
+ ): DropTarget | null {
36
+ if (!target) {
37
+ return {
38
+ type: 'root',
39
+ };
40
+ }
41
+
42
+ if (target.type === 'root') {
43
+ let nextKey = keyboardDelegate.getFirstKey?.() ?? null;
44
+ if (nextKey != null) {
45
+ return {
46
+ type: 'item',
47
+ key: nextKey,
48
+ dropPosition: 'before',
49
+ };
50
+ }
51
+
52
+ return null;
53
+ }
54
+
55
+ if (target.type === 'item') {
56
+ let nextKey: Key | null | undefined = null;
57
+ if (horizontal) {
58
+ nextKey =
59
+ horizontal === 'right'
60
+ ? keyboardDelegate.getKeyRightOf?.(target.key, { includeDisabled: true })
61
+ : keyboardDelegate.getKeyLeftOf?.(target.key, { includeDisabled: true });
62
+ } else {
63
+ nextKey = keyboardDelegate.getKeyBelow?.(target.key, { includeDisabled: true });
64
+ }
65
+ let nextCollectionKey = getNextItem(collection, target.key, (key) =>
66
+ collection.getKeyAfter(key),
67
+ );
68
+
69
+ // If the keyboard delegate did not move to the next key in the collection,
70
+ // jump to that key with the same drop position. Otherwise, try the other
71
+ // drop positions on the current key first.
72
+ if (nextKey != null && nextKey !== nextCollectionKey) {
73
+ return {
74
+ type: 'item',
75
+ key: nextKey,
76
+ dropPosition: target.dropPosition,
77
+ };
78
+ }
79
+
80
+ switch (target.dropPosition) {
81
+ case 'before': {
82
+ return {
83
+ type: 'item',
84
+ key: target.key,
85
+ dropPosition: 'on',
86
+ };
87
+ }
88
+ case 'on': {
89
+ // If there are nested items, traverse to them prior to the "after" position of this target.
90
+ // If the next key is on the same level, then its "before" position is equivalent to this item's "after" position.
91
+ let targetNode = collection.getItem(target.key);
92
+ let nextNode = nextKey != null ? collection.getItem(nextKey) : null;
93
+ if (targetNode && nextNode && nextNode.level >= targetNode.level) {
94
+ return {
95
+ type: 'item',
96
+ key: nextNode.key,
97
+ dropPosition: 'before',
98
+ };
99
+ }
100
+
101
+ return {
102
+ type: 'item',
103
+ key: target.key,
104
+ dropPosition: 'after',
105
+ };
106
+ }
107
+ case 'after': {
108
+ // If this is the last sibling in a level, traverse to the parent.
109
+ let targetNode = collection.getItem(target.key);
110
+ let nextItemInSameLevel =
111
+ targetNode?.nextKey != null ? collection.getItem(targetNode.nextKey) : null;
112
+ while (nextItemInSameLevel != null && nextItemInSameLevel.type !== 'item') {
113
+ nextItemInSameLevel =
114
+ nextItemInSameLevel.nextKey != null
115
+ ? collection.getItem(nextItemInSameLevel.nextKey)
116
+ : null;
117
+ }
118
+
119
+ if (targetNode && nextItemInSameLevel == null && targetNode.parentKey != null) {
120
+ // If the parent item has an item after it, use the "before" position.
121
+ let parentNode = collection.getItem(targetNode.parentKey);
122
+ const nextNode =
123
+ parentNode?.nextKey != null ? collection.getItem(parentNode.nextKey) : null;
124
+ if (nextNode?.type === 'item') {
125
+ return {
126
+ type: 'item',
127
+ key: nextNode.key,
128
+ dropPosition: 'before',
129
+ };
130
+ }
131
+
132
+ if (parentNode?.type === 'item') {
133
+ return {
134
+ type: 'item',
135
+ key: parentNode.key,
136
+ dropPosition: 'after',
137
+ };
138
+ }
139
+ }
140
+
141
+ if (nextItemInSameLevel) {
142
+ return {
143
+ type: 'item',
144
+ key: nextItemInSameLevel.key,
145
+ dropPosition: 'on',
146
+ };
147
+ }
148
+ }
149
+ }
150
+ }
151
+
152
+ if (wrap) {
153
+ return {
154
+ type: 'root',
155
+ };
156
+ }
157
+
158
+ return null;
159
+ }
160
+
161
+ function previousDropTarget(
162
+ keyboardDelegate: KeyboardDelegate,
163
+ collection: Collection<Node<unknown>>,
164
+ target: DropTarget | null | undefined,
165
+ wrap = false,
166
+ horizontal: 'left' | 'right' | null = null,
167
+ ): DropTarget | null {
168
+ // Start after the last root-level item.
169
+ if (!target || (wrap && target.type === 'root')) {
170
+ // Keyboard delegate gets the deepest item but we want the shallowest.
171
+ let prevKey: Key | null = null;
172
+ let lastKey = keyboardDelegate.getLastKey?.();
173
+ while (lastKey != null) {
174
+ let node = collection.getItem(lastKey);
175
+ if (node?.type !== 'item') {
176
+ break;
177
+ }
178
+ prevKey = lastKey;
179
+ lastKey = node?.parentKey;
180
+ }
181
+
182
+ if (prevKey != null) {
183
+ return {
184
+ type: 'item',
185
+ key: prevKey,
186
+ dropPosition: 'after',
187
+ };
188
+ }
189
+
190
+ return null;
191
+ }
192
+
193
+ if (target.type === 'item') {
194
+ let prevKey: Key | null | undefined = null;
195
+ if (horizontal) {
196
+ prevKey =
197
+ horizontal === 'left'
198
+ ? keyboardDelegate.getKeyLeftOf?.(target.key, { includeDisabled: true })
199
+ : keyboardDelegate.getKeyRightOf?.(target.key, { includeDisabled: true });
200
+ } else {
201
+ prevKey = keyboardDelegate.getKeyAbove?.(target.key, { includeDisabled: true });
202
+ }
203
+ let prevCollectionKey = getNextItem(collection, target.key, (key) =>
204
+ collection.getKeyBefore(key),
205
+ );
206
+
207
+ // If the keyboard delegate did not move to the next key in the collection,
208
+ // jump to that key with the same drop position. Otherwise, try the other
209
+ // drop positions on the current key first.
210
+ if (prevKey != null && prevKey !== prevCollectionKey) {
211
+ return {
212
+ type: 'item',
213
+ key: prevKey,
214
+ dropPosition: target.dropPosition,
215
+ };
216
+ }
217
+
218
+ switch (target.dropPosition) {
219
+ case 'before': {
220
+ // Move after the last child of the previous item.
221
+ let targetNode = collection.getItem(target.key);
222
+ if (targetNode && targetNode.prevKey != null) {
223
+ let lastChild = getLastChild(collection, targetNode.prevKey);
224
+ if (lastChild) {
225
+ return lastChild;
226
+ }
227
+ }
228
+
229
+ if (prevKey != null) {
230
+ return {
231
+ type: 'item',
232
+ key: prevKey,
233
+ dropPosition: 'on',
234
+ };
235
+ }
236
+
237
+ return {
238
+ type: 'root',
239
+ };
240
+ }
241
+ case 'on': {
242
+ return {
243
+ type: 'item',
244
+ key: target.key,
245
+ dropPosition: 'before',
246
+ };
247
+ }
248
+ case 'after': {
249
+ // Move after the last child of this item.
250
+ let lastChild = getLastChild(collection, target.key);
251
+ if (lastChild) {
252
+ return lastChild;
253
+ }
254
+
255
+ return {
256
+ type: 'item',
257
+ key: target.key,
258
+ dropPosition: 'on',
259
+ };
260
+ }
261
+ }
262
+ }
263
+
264
+ if (target.type !== 'root') {
265
+ return {
266
+ type: 'root',
267
+ };
268
+ }
269
+
270
+ return null;
271
+ }
272
+
273
+ function getLastChild(collection: Collection<Node<unknown>>, key: Key): DropTarget | null {
274
+ // getChildNodes still returns child tree items even when the item is collapsed.
275
+ // Checking if the next item has a greater level is a silly way to determine if the item is expanded.
276
+ let targetNode = collection.getItem(key);
277
+ let nextKey = getNextItem(collection, key, (key) => collection.getKeyAfter(key));
278
+ let nextNode = nextKey != null ? collection.getItem(nextKey) : null;
279
+ if (targetNode && nextNode && nextNode.level > targetNode.level) {
280
+ let lastChild: Node<unknown> | null = null;
281
+ if ('lastChildKey' in targetNode) {
282
+ lastChild =
283
+ targetNode.lastChildKey != null ? collection.getItem(targetNode.lastChildKey) : null;
284
+ while (lastChild && lastChild.type !== 'item' && lastChild.prevKey != null) {
285
+ lastChild = collection.getItem(lastChild.prevKey)!;
286
+ }
287
+ } else {
288
+ lastChild =
289
+ Array.from(targetNode.childNodes).findLast((item) => item.type === 'item') || null;
290
+ }
291
+
292
+ if (lastChild) {
293
+ return {
294
+ type: 'item',
295
+ key: lastChild.key,
296
+ dropPosition: 'after',
297
+ };
298
+ }
299
+ }
300
+
301
+ return null;
302
+ }
303
+
304
+ // Find the next or previous item in a collection, skipping over other types of nodes (e.g. content).
305
+ function getNextItem(
306
+ collection: Collection<Node<unknown>>,
307
+ key: Key,
308
+ getNextKey: (key: Key) => Key | null,
309
+ ): Key | null {
310
+ let nextCollectionKey = getNextKey(key);
311
+ let nextCollectionNode = nextCollectionKey != null ? collection.getItem(nextCollectionKey) : null;
312
+ while (nextCollectionNode && nextCollectionNode.type !== 'item') {
313
+ nextCollectionKey = getNextKey(nextCollectionNode.key);
314
+ nextCollectionNode = nextCollectionKey != null ? collection.getItem(nextCollectionKey) : null;
315
+ }
316
+ return nextCollectionKey;
317
+ }
@@ -0,0 +1,215 @@
1
+ /** @jsxImportSource octane */
2
+ // Ported from adobe/react-spectrum@1c84a49a1faf50b571c84e00bcf9c60b22ddd03e (packages/react-aria/src/dnd/ListDropTargetDelegate.ts).
3
+ import {
4
+ Direction,
5
+ DropTarget,
6
+ DropTargetDelegate,
7
+ Node,
8
+ Orientation,
9
+ RefObject,
10
+ } from '@react-types/shared';
11
+
12
+ interface ListDropTargetDelegateOptions {
13
+ /**
14
+ * Whether the items are arranged in a stack or grid.
15
+ *
16
+ * @default 'stack'
17
+ */
18
+ layout?: 'stack' | 'grid';
19
+ /**
20
+ * The primary orientation of the items. Usually this is the
21
+ * direction that the collection scrolls.
22
+ *
23
+ * @default 'vertical'
24
+ */
25
+ orientation?: Orientation;
26
+ /**
27
+ * The horizontal layout direction.
28
+ *
29
+ * @default 'ltr'
30
+ */
31
+ direction?: Direction;
32
+ }
33
+
34
+ // Terms used in the below code:
35
+ // * "Primary" – The main layout direction. For stacks, this is the direction
36
+ // that the stack is arranged in (e.g. horizontal or vertical).
37
+ // For grids, this is the main scroll direction.
38
+ // * "Secondary" – The secondary layout direction. For stacks, there is no secondary
39
+ // layout direction. For grids, this is the opposite of the primary direction.
40
+ // * "Flow" – The flow direction of the items. For stacks, this is the the primary
41
+ // direction. For grids, it is the secondary direction.
42
+
43
+ export class ListDropTargetDelegate implements DropTargetDelegate {
44
+ private collection: Iterable<Node<unknown>>;
45
+ private ref: RefObject<HTMLElement | null>;
46
+ private layout: 'stack' | 'grid';
47
+ private orientation: Orientation;
48
+ protected direction: Direction;
49
+
50
+ constructor(
51
+ collection: Iterable<Node<unknown>>,
52
+ ref: RefObject<HTMLElement | null>,
53
+ options?: ListDropTargetDelegateOptions,
54
+ ) {
55
+ this.collection = collection;
56
+ this.ref = ref;
57
+ this.layout = options?.layout || 'stack';
58
+ this.orientation = options?.orientation || 'vertical';
59
+ this.direction = options?.direction || 'ltr';
60
+ }
61
+
62
+ private getPrimaryStart(rect: DOMRect) {
63
+ return this.orientation === 'horizontal' ? rect.left : rect.top;
64
+ }
65
+
66
+ private getPrimaryEnd(rect: DOMRect) {
67
+ return this.orientation === 'horizontal' ? rect.right : rect.bottom;
68
+ }
69
+
70
+ private getSecondaryStart(rect: DOMRect) {
71
+ return this.orientation === 'horizontal' ? rect.top : rect.left;
72
+ }
73
+
74
+ private getSecondaryEnd(rect: DOMRect) {
75
+ return this.orientation === 'horizontal' ? rect.bottom : rect.right;
76
+ }
77
+
78
+ private getFlowStart(rect: DOMRect) {
79
+ return this.layout === 'stack' ? this.getPrimaryStart(rect) : this.getSecondaryStart(rect);
80
+ }
81
+
82
+ private getFlowEnd(rect: DOMRect) {
83
+ return this.layout === 'stack' ? this.getPrimaryEnd(rect) : this.getSecondaryEnd(rect);
84
+ }
85
+
86
+ private getFlowSize(rect: DOMRect) {
87
+ return this.getFlowEnd(rect) - this.getFlowStart(rect);
88
+ }
89
+
90
+ getDropTargetFromPoint(
91
+ x: number,
92
+ y: number,
93
+ isValidDropTarget: (target: DropTarget) => boolean,
94
+ ): DropTarget {
95
+ if (this.collection[Symbol.iterator]().next().done || !this.ref.current) {
96
+ return { type: 'root' };
97
+ }
98
+
99
+ let rect: DOMRect | undefined = this.ref.current.getBoundingClientRect();
100
+ let primary = this.orientation === 'horizontal' ? x : y;
101
+ let secondary = this.orientation === 'horizontal' ? y : x;
102
+ primary += this.getPrimaryStart(rect);
103
+ secondary += this.getSecondaryStart(rect);
104
+
105
+ let flow = this.layout === 'stack' ? primary : secondary;
106
+ let isPrimaryRTL = this.orientation === 'horizontal' && this.direction === 'rtl';
107
+ let isSecondaryRTL =
108
+ this.layout === 'grid' && this.orientation === 'vertical' && this.direction === 'rtl';
109
+ let isFlowRTL = this.layout === 'stack' ? isPrimaryRTL : isSecondaryRTL;
110
+
111
+ let collection = this.ref.current?.dataset.collection;
112
+ let elements = this.ref.current.querySelectorAll(
113
+ collection ? `[data-collection="${CSS.escape(collection)}"]` : '[data-key]',
114
+ );
115
+ let elementMap = new Map<string, HTMLElement>();
116
+ for (let item of elements) {
117
+ if (item instanceof HTMLElement && item.dataset.key != null) {
118
+ elementMap.set(item.dataset.key, item);
119
+ }
120
+ }
121
+
122
+ // TODO: assume that only item type items are valid drop targets. This is to prevent a crash when dragging over the loader
123
+ // row since it doesn't have a data-key set on it. Will eventually need to handle the case with drag and drop and loaders located between rows aka tree.
124
+ // Can see https://github.com/adobe/react-spectrum/pull/4210/files#diff-21e555e0c597a28215e36137f5be076a65a1e1456c92cd0fdd60f866929aae2a for additional logic
125
+ // that may need to happen then
126
+ let items = [...this.collection].filter((item) => item.type === 'item');
127
+
128
+ if (items.length < 1) {
129
+ return { type: 'root' };
130
+ }
131
+
132
+ let low = 0;
133
+ let high = items.length;
134
+ while (low < high) {
135
+ let mid = Math.floor((low + high) / 2);
136
+ let item = items[mid];
137
+ let element = elementMap.get(String(item.key));
138
+ if (!element) {
139
+ break;
140
+ }
141
+ let rect = element.getBoundingClientRect();
142
+ let update = (isGreater: boolean) => {
143
+ if (isGreater) {
144
+ low = mid + 1;
145
+ } else {
146
+ high = mid;
147
+ }
148
+ };
149
+
150
+ if (primary < this.getPrimaryStart(rect)) {
151
+ update(isPrimaryRTL);
152
+ } else if (primary > this.getPrimaryEnd(rect)) {
153
+ update(!isPrimaryRTL);
154
+ } else if (secondary < this.getSecondaryStart(rect)) {
155
+ update(isSecondaryRTL);
156
+ } else if (secondary > this.getSecondaryEnd(rect)) {
157
+ update(!isSecondaryRTL);
158
+ } else {
159
+ let target: DropTarget = {
160
+ type: 'item',
161
+ key: item.key,
162
+ dropPosition: 'on',
163
+ };
164
+
165
+ if (isValidDropTarget(target)) {
166
+ // Otherwise, if dropping on the item is accepted, try the before/after positions if within 5px
167
+ // of the start or end of the item.
168
+ if (
169
+ flow <= this.getFlowStart(rect) + 5 &&
170
+ isValidDropTarget({ ...target, dropPosition: 'before' })
171
+ ) {
172
+ target.dropPosition = isFlowRTL ? 'after' : 'before';
173
+ } else if (
174
+ flow >= this.getFlowEnd(rect) - 5 &&
175
+ isValidDropTarget({ ...target, dropPosition: 'after' })
176
+ ) {
177
+ target.dropPosition = isFlowRTL ? 'before' : 'after';
178
+ }
179
+ } else {
180
+ // If dropping on the item isn't accepted, try the target before or after depending on the position.
181
+ let mid = this.getFlowStart(rect) + this.getFlowSize(rect) / 2;
182
+ if (flow <= mid && isValidDropTarget({ ...target, dropPosition: 'before' })) {
183
+ target.dropPosition = isFlowRTL ? 'after' : 'before';
184
+ } else if (flow >= mid && isValidDropTarget({ ...target, dropPosition: 'after' })) {
185
+ target.dropPosition = isFlowRTL ? 'before' : 'after';
186
+ }
187
+ }
188
+
189
+ return target;
190
+ }
191
+ }
192
+
193
+ let item = items[Math.min(low, items.length - 1)];
194
+ let element = elementMap.get(String(item.key));
195
+ rect = element?.getBoundingClientRect();
196
+
197
+ if (
198
+ rect &&
199
+ (primary < this.getPrimaryStart(rect) ||
200
+ Math.abs(flow - this.getFlowStart(rect)) < Math.abs(flow - this.getFlowEnd(rect)))
201
+ ) {
202
+ return {
203
+ type: 'item',
204
+ key: item.key,
205
+ dropPosition: isFlowRTL ? 'after' : 'before',
206
+ };
207
+ }
208
+
209
+ return {
210
+ type: 'item',
211
+ key: item.key,
212
+ dropPosition: isFlowRTL ? 'before' : 'after',
213
+ };
214
+ }
215
+ }