react-native-layout-dnd 0.1.0-alpha.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 (340) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +262 -0
  3. package/lib/module/adapters/coordinates.js +135 -0
  4. package/lib/module/adapters/coordinates.js.map +1 -0
  5. package/lib/module/adapters/scroll.js +81 -0
  6. package/lib/module/adapters/scroll.js.map +1 -0
  7. package/lib/module/adapters/virtualizedList.js +69 -0
  8. package/lib/module/adapters/virtualizedList.js.map +1 -0
  9. package/lib/module/components/DndProvider.js +1144 -0
  10. package/lib/module/components/DndProvider.js.map +1 -0
  11. package/lib/module/components/DragHandle.js +65 -0
  12. package/lib/module/components/DragHandle.js.map +1 -0
  13. package/lib/module/components/GridController.js +151 -0
  14. package/lib/module/components/GridController.js.map +1 -0
  15. package/lib/module/components/GridDragHandle.js +15 -0
  16. package/lib/module/components/GridDragHandle.js.map +1 -0
  17. package/lib/module/components/GridZoneView.js +59 -0
  18. package/lib/module/components/GridZoneView.js.map +1 -0
  19. package/lib/module/components/SortableGrid.js +305 -0
  20. package/lib/module/components/SortableGrid.js.map +1 -0
  21. package/lib/module/components/SortableList.js +714 -0
  22. package/lib/module/components/SortableList.js.map +1 -0
  23. package/lib/module/components/dndTypes.js +4 -0
  24. package/lib/module/components/dndTypes.js.map +1 -0
  25. package/lib/module/components/gridTypes.js +4 -0
  26. package/lib/module/components/gridTypes.js.map +1 -0
  27. package/lib/module/components/handleViewProps.js +13 -0
  28. package/lib/module/components/handleViewProps.js.map +1 -0
  29. package/lib/module/contracts.js +4 -0
  30. package/lib/module/contracts.js.map +1 -0
  31. package/lib/module/controller/approval.js +98 -0
  32. package/lib/module/controller/approval.js.map +1 -0
  33. package/lib/module/controller/coordinatorBase.js +93 -0
  34. package/lib/module/controller/coordinatorBase.js.map +1 -0
  35. package/lib/module/controller/dndSession.js +621 -0
  36. package/lib/module/controller/dndSession.js.map +1 -0
  37. package/lib/module/controller/dndState.js +103 -0
  38. package/lib/module/controller/dndState.js.map +1 -0
  39. package/lib/module/controller/gridAdapter.js +191 -0
  40. package/lib/module/controller/gridAdapter.js.map +1 -0
  41. package/lib/module/controller/gridState.js +101 -0
  42. package/lib/module/controller/gridState.js.map +1 -0
  43. package/lib/module/controller/locations.js +48 -0
  44. package/lib/module/controller/locations.js.map +1 -0
  45. package/lib/module/controller/previewPath.js +73 -0
  46. package/lib/module/controller/previewPath.js.map +1 -0
  47. package/lib/module/controller/sessionCore.js +222 -0
  48. package/lib/module/controller/sessionCore.js.map +1 -0
  49. package/lib/module/controller/useDndState.js +9 -0
  50. package/lib/module/controller/useDndState.js.map +1 -0
  51. package/lib/module/controller/useGridState.js +9 -0
  52. package/lib/module/controller/useGridState.js.map +1 -0
  53. package/lib/module/controller/useStoreState.js +15 -0
  54. package/lib/module/controller/useStoreState.js.map +1 -0
  55. package/lib/module/defaults.js +7 -0
  56. package/lib/module/defaults.js.map +1 -0
  57. package/lib/module/diagnostics.js +16 -0
  58. package/lib/module/diagnostics.js.map +1 -0
  59. package/lib/module/engine/gridPlacements.js +54 -0
  60. package/lib/module/engine/gridPlacements.js.map +1 -0
  61. package/lib/module/engine/index.js +19 -0
  62. package/lib/module/engine/index.js.map +1 -0
  63. package/lib/module/engine/layout.js +36 -0
  64. package/lib/module/engine/layout.js.map +1 -0
  65. package/lib/module/engine/layoutMove.js +326 -0
  66. package/lib/module/engine/layoutMove.js.map +1 -0
  67. package/lib/module/engine/layoutState.js +344 -0
  68. package/lib/module/engine/layoutState.js.map +1 -0
  69. package/lib/module/engine/list.js +172 -0
  70. package/lib/module/engine/list.js.map +1 -0
  71. package/lib/module/engine/listIndex.js +125 -0
  72. package/lib/module/engine/listIndex.js.map +1 -0
  73. package/lib/module/engine/move.js +216 -0
  74. package/lib/module/engine/move.js.map +1 -0
  75. package/lib/module/engine/movementPolicy.js +77 -0
  76. package/lib/module/engine/movementPolicy.js.map +1 -0
  77. package/lib/module/engine/orderedTarget.js +71 -0
  78. package/lib/module/engine/orderedTarget.js.map +1 -0
  79. package/lib/module/engine/pack.js +30 -0
  80. package/lib/module/engine/pack.js.map +1 -0
  81. package/lib/module/engine/rectangles.js +12 -0
  82. package/lib/module/engine/rectangles.js.map +1 -0
  83. package/lib/module/engine/sameLayout.js +29 -0
  84. package/lib/module/engine/sameLayout.js.map +1 -0
  85. package/lib/module/engine/search.js +159 -0
  86. package/lib/module/engine/search.js.map +1 -0
  87. package/lib/module/engine/spatial.js +27 -0
  88. package/lib/module/engine/spatial.js.map +1 -0
  89. package/lib/module/engine/spatialAppRotation.js +39 -0
  90. package/lib/module/engine/spatialAppRotation.js.map +1 -0
  91. package/lib/module/engine/spatialExchange.js +164 -0
  92. package/lib/module/engine/spatialExchange.js.map +1 -0
  93. package/lib/module/engine/spatialInsertion.js +135 -0
  94. package/lib/module/engine/spatialInsertion.js.map +1 -0
  95. package/lib/module/engine/spatialPolicy.js +41 -0
  96. package/lib/module/engine/spatialPolicy.js.map +1 -0
  97. package/lib/module/engine/spatialRotation.js +48 -0
  98. package/lib/module/engine/spatialRotation.js.map +1 -0
  99. package/lib/module/engine/validation.js +205 -0
  100. package/lib/module/engine/validation.js.map +1 -0
  101. package/lib/module/gesture/DndGestureGroup.js +268 -0
  102. package/lib/module/gesture/DndGestureGroup.js.map +1 -0
  103. package/lib/module/gesture/DndGestureHost.js +32 -0
  104. package/lib/module/gesture/DndGestureHost.js.map +1 -0
  105. package/lib/module/gesture/gestureConfig.js +81 -0
  106. package/lib/module/gesture/gestureConfig.js.map +1 -0
  107. package/lib/module/gesture/gestureGrouping.js +122 -0
  108. package/lib/module/gesture/gestureGrouping.js.map +1 -0
  109. package/lib/module/gesture/gestureHost.js +106 -0
  110. package/lib/module/gesture/gestureHost.js.map +1 -0
  111. package/lib/module/index.js +23 -0
  112. package/lib/module/index.js.map +1 -0
  113. package/lib/module/package.json +1 -0
  114. package/lib/module/pointer/dndTarget.js +101 -0
  115. package/lib/module/pointer/dndTarget.js.map +1 -0
  116. package/lib/module/pointer/geometry.js +363 -0
  117. package/lib/module/pointer/geometry.js.map +1 -0
  118. package/lib/module/pointer/layoutTarget.js +307 -0
  119. package/lib/module/pointer/layoutTarget.js.map +1 -0
  120. package/lib/module/pointer/listCellMotion.js +99 -0
  121. package/lib/module/pointer/listCellMotion.js.map +1 -0
  122. package/lib/module/pointer/listTarget.js +42 -0
  123. package/lib/module/pointer/listTarget.js.map +1 -0
  124. package/lib/module/pointer/motion.js +37 -0
  125. package/lib/module/pointer/motion.js.map +1 -0
  126. package/lib/module/runtime/dndPresentation.js +81 -0
  127. package/lib/module/runtime/dndPresentation.js.map +1 -0
  128. package/lib/module/runtime/dndRenderStore.js +129 -0
  129. package/lib/module/runtime/dndRenderStore.js.map +1 -0
  130. package/lib/module/runtime/dndRuntime.js +135 -0
  131. package/lib/module/runtime/dndRuntime.js.map +1 -0
  132. package/lib/module/runtime/dndSettlement.js +77 -0
  133. package/lib/module/runtime/dndSettlement.js.map +1 -0
  134. package/lib/module/runtime/gridRuntime.js +37 -0
  135. package/lib/module/runtime/gridRuntime.js.map +1 -0
  136. package/lib/module/types.js +4 -0
  137. package/lib/module/types.js.map +1 -0
  138. package/lib/typescript/package.json +1 -0
  139. package/lib/typescript/src/adapters/coordinates.d.ts +9 -0
  140. package/lib/typescript/src/adapters/coordinates.d.ts.map +1 -0
  141. package/lib/typescript/src/adapters/scroll.d.ts +49 -0
  142. package/lib/typescript/src/adapters/scroll.d.ts.map +1 -0
  143. package/lib/typescript/src/adapters/virtualizedList.d.ts +22 -0
  144. package/lib/typescript/src/adapters/virtualizedList.d.ts.map +1 -0
  145. package/lib/typescript/src/components/DndProvider.d.ts +4 -0
  146. package/lib/typescript/src/components/DndProvider.d.ts.map +1 -0
  147. package/lib/typescript/src/components/DragHandle.d.ts +4 -0
  148. package/lib/typescript/src/components/DragHandle.d.ts.map +1 -0
  149. package/lib/typescript/src/components/GridController.d.ts +21 -0
  150. package/lib/typescript/src/components/GridController.d.ts.map +1 -0
  151. package/lib/typescript/src/components/GridDragHandle.d.ts +8 -0
  152. package/lib/typescript/src/components/GridDragHandle.d.ts.map +1 -0
  153. package/lib/typescript/src/components/GridZoneView.d.ts +8 -0
  154. package/lib/typescript/src/components/GridZoneView.d.ts.map +1 -0
  155. package/lib/typescript/src/components/SortableGrid.d.ts +4 -0
  156. package/lib/typescript/src/components/SortableGrid.d.ts.map +1 -0
  157. package/lib/typescript/src/components/SortableList.d.ts +4 -0
  158. package/lib/typescript/src/components/SortableList.d.ts.map +1 -0
  159. package/lib/typescript/src/components/dndTypes.d.ts +94 -0
  160. package/lib/typescript/src/components/dndTypes.d.ts.map +1 -0
  161. package/lib/typescript/src/components/gridTypes.d.ts +84 -0
  162. package/lib/typescript/src/components/gridTypes.d.ts.map +1 -0
  163. package/lib/typescript/src/components/handleViewProps.d.ts +6 -0
  164. package/lib/typescript/src/components/handleViewProps.d.ts.map +1 -0
  165. package/lib/typescript/src/contracts.d.ts +145 -0
  166. package/lib/typescript/src/contracts.d.ts.map +1 -0
  167. package/lib/typescript/src/controller/approval.d.ts +66 -0
  168. package/lib/typescript/src/controller/approval.d.ts.map +1 -0
  169. package/lib/typescript/src/controller/coordinatorBase.d.ts +37 -0
  170. package/lib/typescript/src/controller/coordinatorBase.d.ts.map +1 -0
  171. package/lib/typescript/src/controller/dndSession.d.ts +152 -0
  172. package/lib/typescript/src/controller/dndSession.d.ts.map +1 -0
  173. package/lib/typescript/src/controller/dndState.d.ts +27 -0
  174. package/lib/typescript/src/controller/dndState.d.ts.map +1 -0
  175. package/lib/typescript/src/controller/gridAdapter.d.ts +44 -0
  176. package/lib/typescript/src/controller/gridAdapter.d.ts.map +1 -0
  177. package/lib/typescript/src/controller/gridState.d.ts +18 -0
  178. package/lib/typescript/src/controller/gridState.d.ts.map +1 -0
  179. package/lib/typescript/src/controller/locations.d.ts +9 -0
  180. package/lib/typescript/src/controller/locations.d.ts.map +1 -0
  181. package/lib/typescript/src/controller/previewPath.d.ts +49 -0
  182. package/lib/typescript/src/controller/previewPath.d.ts.map +1 -0
  183. package/lib/typescript/src/controller/sessionCore.d.ts +106 -0
  184. package/lib/typescript/src/controller/sessionCore.d.ts.map +1 -0
  185. package/lib/typescript/src/controller/useDndState.d.ts +8 -0
  186. package/lib/typescript/src/controller/useDndState.d.ts.map +1 -0
  187. package/lib/typescript/src/controller/useGridState.d.ts +8 -0
  188. package/lib/typescript/src/controller/useGridState.d.ts.map +1 -0
  189. package/lib/typescript/src/controller/useStoreState.d.ts +16 -0
  190. package/lib/typescript/src/controller/useStoreState.d.ts.map +1 -0
  191. package/lib/typescript/src/defaults.d.ts +5 -0
  192. package/lib/typescript/src/defaults.d.ts.map +1 -0
  193. package/lib/typescript/src/diagnostics.d.ts +9 -0
  194. package/lib/typescript/src/diagnostics.d.ts.map +1 -0
  195. package/lib/typescript/src/engine/gridPlacements.d.ts +22 -0
  196. package/lib/typescript/src/engine/gridPlacements.d.ts.map +1 -0
  197. package/lib/typescript/src/engine/index.d.ts +28 -0
  198. package/lib/typescript/src/engine/index.d.ts.map +1 -0
  199. package/lib/typescript/src/engine/layout.d.ts +4 -0
  200. package/lib/typescript/src/engine/layout.d.ts.map +1 -0
  201. package/lib/typescript/src/engine/layoutMove.d.ts +46 -0
  202. package/lib/typescript/src/engine/layoutMove.d.ts.map +1 -0
  203. package/lib/typescript/src/engine/layoutState.d.ts +22 -0
  204. package/lib/typescript/src/engine/layoutState.d.ts.map +1 -0
  205. package/lib/typescript/src/engine/list.d.ts +68 -0
  206. package/lib/typescript/src/engine/list.d.ts.map +1 -0
  207. package/lib/typescript/src/engine/listIndex.d.ts +32 -0
  208. package/lib/typescript/src/engine/listIndex.d.ts.map +1 -0
  209. package/lib/typescript/src/engine/move.d.ts +10 -0
  210. package/lib/typescript/src/engine/move.d.ts.map +1 -0
  211. package/lib/typescript/src/engine/movementPolicy.d.ts +34 -0
  212. package/lib/typescript/src/engine/movementPolicy.d.ts.map +1 -0
  213. package/lib/typescript/src/engine/orderedTarget.d.ts +32 -0
  214. package/lib/typescript/src/engine/orderedTarget.d.ts.map +1 -0
  215. package/lib/typescript/src/engine/pack.d.ts +3 -0
  216. package/lib/typescript/src/engine/pack.d.ts.map +1 -0
  217. package/lib/typescript/src/engine/rectangles.d.ts +9 -0
  218. package/lib/typescript/src/engine/rectangles.d.ts.map +1 -0
  219. package/lib/typescript/src/engine/sameLayout.d.ts +4 -0
  220. package/lib/typescript/src/engine/sameLayout.d.ts.map +1 -0
  221. package/lib/typescript/src/engine/search.d.ts +28 -0
  222. package/lib/typescript/src/engine/search.d.ts.map +1 -0
  223. package/lib/typescript/src/engine/spatial.d.ts +16 -0
  224. package/lib/typescript/src/engine/spatial.d.ts.map +1 -0
  225. package/lib/typescript/src/engine/spatialAppRotation.d.ts +4 -0
  226. package/lib/typescript/src/engine/spatialAppRotation.d.ts.map +1 -0
  227. package/lib/typescript/src/engine/spatialExchange.d.ts +5 -0
  228. package/lib/typescript/src/engine/spatialExchange.d.ts.map +1 -0
  229. package/lib/typescript/src/engine/spatialInsertion.d.ts +5 -0
  230. package/lib/typescript/src/engine/spatialInsertion.d.ts.map +1 -0
  231. package/lib/typescript/src/engine/spatialPolicy.d.ts +9 -0
  232. package/lib/typescript/src/engine/spatialPolicy.d.ts.map +1 -0
  233. package/lib/typescript/src/engine/spatialRotation.d.ts +8 -0
  234. package/lib/typescript/src/engine/spatialRotation.d.ts.map +1 -0
  235. package/lib/typescript/src/engine/validation.d.ts +9 -0
  236. package/lib/typescript/src/engine/validation.d.ts.map +1 -0
  237. package/lib/typescript/src/gesture/DndGestureGroup.d.ts +33 -0
  238. package/lib/typescript/src/gesture/DndGestureGroup.d.ts.map +1 -0
  239. package/lib/typescript/src/gesture/DndGestureHost.d.ts +12 -0
  240. package/lib/typescript/src/gesture/DndGestureHost.d.ts.map +1 -0
  241. package/lib/typescript/src/gesture/gestureConfig.d.ts +15 -0
  242. package/lib/typescript/src/gesture/gestureConfig.d.ts.map +1 -0
  243. package/lib/typescript/src/gesture/gestureGrouping.d.ts +66 -0
  244. package/lib/typescript/src/gesture/gestureGrouping.d.ts.map +1 -0
  245. package/lib/typescript/src/gesture/gestureHost.d.ts +23 -0
  246. package/lib/typescript/src/gesture/gestureHost.d.ts.map +1 -0
  247. package/lib/typescript/src/index.d.ts +38 -0
  248. package/lib/typescript/src/index.d.ts.map +1 -0
  249. package/lib/typescript/src/pointer/dndTarget.d.ts +14 -0
  250. package/lib/typescript/src/pointer/dndTarget.d.ts.map +1 -0
  251. package/lib/typescript/src/pointer/geometry.d.ts +28 -0
  252. package/lib/typescript/src/pointer/geometry.d.ts.map +1 -0
  253. package/lib/typescript/src/pointer/layoutTarget.d.ts +43 -0
  254. package/lib/typescript/src/pointer/layoutTarget.d.ts.map +1 -0
  255. package/lib/typescript/src/pointer/listCellMotion.d.ts +43 -0
  256. package/lib/typescript/src/pointer/listCellMotion.d.ts.map +1 -0
  257. package/lib/typescript/src/pointer/listTarget.d.ts +7 -0
  258. package/lib/typescript/src/pointer/listTarget.d.ts.map +1 -0
  259. package/lib/typescript/src/pointer/motion.d.ts +20 -0
  260. package/lib/typescript/src/pointer/motion.d.ts.map +1 -0
  261. package/lib/typescript/src/runtime/dndPresentation.d.ts +37 -0
  262. package/lib/typescript/src/runtime/dndPresentation.d.ts.map +1 -0
  263. package/lib/typescript/src/runtime/dndRenderStore.d.ts +46 -0
  264. package/lib/typescript/src/runtime/dndRenderStore.d.ts.map +1 -0
  265. package/lib/typescript/src/runtime/dndRuntime.d.ts +138 -0
  266. package/lib/typescript/src/runtime/dndRuntime.d.ts.map +1 -0
  267. package/lib/typescript/src/runtime/dndSettlement.d.ts +18 -0
  268. package/lib/typescript/src/runtime/dndSettlement.d.ts.map +1 -0
  269. package/lib/typescript/src/runtime/gridRuntime.d.ts +54 -0
  270. package/lib/typescript/src/runtime/gridRuntime.d.ts.map +1 -0
  271. package/lib/typescript/src/types.d.ts +180 -0
  272. package/lib/typescript/src/types.d.ts.map +1 -0
  273. package/package.json +136 -0
  274. package/src/adapters/coordinates.ts +181 -0
  275. package/src/adapters/scroll.ts +147 -0
  276. package/src/adapters/virtualizedList.ts +112 -0
  277. package/src/components/DndProvider.tsx +1836 -0
  278. package/src/components/DragHandle.tsx +89 -0
  279. package/src/components/GridController.tsx +213 -0
  280. package/src/components/GridDragHandle.tsx +11 -0
  281. package/src/components/GridZoneView.tsx +57 -0
  282. package/src/components/SortableGrid.tsx +449 -0
  283. package/src/components/SortableList.tsx +1028 -0
  284. package/src/components/dndTypes.ts +102 -0
  285. package/src/components/gridTypes.ts +90 -0
  286. package/src/components/handleViewProps.ts +35 -0
  287. package/src/contracts.ts +149 -0
  288. package/src/controller/approval.ts +179 -0
  289. package/src/controller/coordinatorBase.ts +118 -0
  290. package/src/controller/dndSession.ts +1058 -0
  291. package/src/controller/dndState.ts +198 -0
  292. package/src/controller/gridAdapter.ts +268 -0
  293. package/src/controller/gridState.ts +187 -0
  294. package/src/controller/locations.ts +67 -0
  295. package/src/controller/previewPath.ts +90 -0
  296. package/src/controller/sessionCore.ts +390 -0
  297. package/src/controller/useDndState.ts +26 -0
  298. package/src/controller/useGridState.ts +22 -0
  299. package/src/controller/useStoreState.ts +27 -0
  300. package/src/defaults.ts +4 -0
  301. package/src/diagnostics.ts +23 -0
  302. package/src/engine/gridPlacements.ts +85 -0
  303. package/src/engine/index.ts +99 -0
  304. package/src/engine/layout.ts +29 -0
  305. package/src/engine/layoutMove.ts +401 -0
  306. package/src/engine/layoutState.ts +490 -0
  307. package/src/engine/list.ts +307 -0
  308. package/src/engine/listIndex.ts +174 -0
  309. package/src/engine/move.ts +274 -0
  310. package/src/engine/movementPolicy.ts +151 -0
  311. package/src/engine/orderedTarget.ts +131 -0
  312. package/src/engine/pack.ts +24 -0
  313. package/src/engine/rectangles.ts +18 -0
  314. package/src/engine/sameLayout.ts +50 -0
  315. package/src/engine/search.ts +174 -0
  316. package/src/engine/spatial.ts +36 -0
  317. package/src/engine/spatialAppRotation.ts +53 -0
  318. package/src/engine/spatialExchange.ts +212 -0
  319. package/src/engine/spatialInsertion.ts +157 -0
  320. package/src/engine/spatialPolicy.ts +48 -0
  321. package/src/engine/spatialRotation.ts +56 -0
  322. package/src/engine/validation.ts +358 -0
  323. package/src/gesture/DndGestureGroup.tsx +357 -0
  324. package/src/gesture/DndGestureHost.tsx +50 -0
  325. package/src/gesture/gestureConfig.ts +123 -0
  326. package/src/gesture/gestureGrouping.ts +210 -0
  327. package/src/gesture/gestureHost.tsx +163 -0
  328. package/src/index.ts +162 -0
  329. package/src/pointer/dndTarget.ts +213 -0
  330. package/src/pointer/geometry.ts +584 -0
  331. package/src/pointer/layoutTarget.ts +515 -0
  332. package/src/pointer/listCellMotion.ts +174 -0
  333. package/src/pointer/listTarget.ts +56 -0
  334. package/src/pointer/motion.ts +66 -0
  335. package/src/runtime/dndPresentation.ts +113 -0
  336. package/src/runtime/dndRenderStore.ts +246 -0
  337. package/src/runtime/dndRuntime.ts +311 -0
  338. package/src/runtime/dndSettlement.ts +117 -0
  339. package/src/runtime/gridRuntime.ts +73 -0
  340. package/src/types.ts +189 -0
@@ -0,0 +1,210 @@
1
+ import type { PanGesture } from 'react-native-gesture-handler';
2
+
3
+ import { sameGestureRelations } from './gestureConfig';
4
+
5
+ import type { GestureRelations } from '../components/gridTypes';
6
+
7
+ /** One registered handle as the gesture host sees it. */
8
+ export type GestureOwner<Registration> = {
9
+ id: number;
10
+ registration: Registration;
11
+ };
12
+
13
+ export type GestureRegistry<Registration> = {
14
+ getSnapshot(): readonly GestureOwner<Registration>[];
15
+ subscribe(listener: () => void): () => void;
16
+ setOwners(next: readonly GestureOwner<Registration>[]): void;
17
+ };
18
+
19
+ /** Handle mounts update their native owners without rendering the controller. */
20
+ export function createGestureRegistry<
21
+ Registration,
22
+ >(): GestureRegistry<Registration> {
23
+ let owners: readonly GestureOwner<Registration>[] = [];
24
+ const listeners = new Set<() => void>();
25
+ return {
26
+ getSnapshot: () => owners,
27
+ subscribe(listener) {
28
+ listeners.add(listener);
29
+ return () => {
30
+ listeners.delete(listener);
31
+ };
32
+ },
33
+ setOwners(next) {
34
+ if (
35
+ next.length === owners.length &&
36
+ next.every(
37
+ (owner, index) =>
38
+ owner.id === owners[index]!.id &&
39
+ owner.registration === owners[index]!.registration,
40
+ )
41
+ )
42
+ return;
43
+ owners = next.map(({ id, registration }) => ({ id, registration }));
44
+ for (const listener of Array.from(listeners)) listener();
45
+ },
46
+ };
47
+ }
48
+
49
+ /**
50
+ * Delivers a group's hit targets without re-rendering the group. A re-render
51
+ * would make Reanimated and Gesture Handler rebuild and re-register the native
52
+ * event handler, which costs a serialization of every callback closure.
53
+ */
54
+ export type TargetChannel<Target> = {
55
+ readonly targets: readonly Target[];
56
+ subscribe(listener: (targets: readonly Target[]) => void): () => void;
57
+ };
58
+
59
+ export type PublishedTargetChannel<Target> = TargetChannel<Target> & {
60
+ set(targets: readonly Target[]): void;
61
+ };
62
+
63
+ export function createTargetChannel<Target>(
64
+ initial: readonly Target[],
65
+ ): PublishedTargetChannel<Target> {
66
+ let targets = initial;
67
+ const listeners = new Set<(targets: readonly Target[]) => void>();
68
+ return {
69
+ get targets() {
70
+ return targets;
71
+ },
72
+ set(next) {
73
+ if (next === targets) return;
74
+ targets = next;
75
+ for (const listener of Array.from(listeners)) listener(next);
76
+ },
77
+ subscribe(listener) {
78
+ listeners.add(listener);
79
+ return () => {
80
+ listeners.delete(listener);
81
+ };
82
+ },
83
+ };
84
+ }
85
+
86
+ /** Props of one shared-recognizer component rendered by a gesture host. */
87
+ export type GestureGroupProps<Runtime, Target> = {
88
+ groupId: number;
89
+ relations: GestureRelations | undefined;
90
+ channel: TargetChannel<Target>;
91
+ runtime: Runtime;
92
+ publish(groupId: number, gesture: PanGesture | null): void;
93
+ };
94
+
95
+ /** Handles sharing one relation signature share one native recognizer. */
96
+ export type GestureGroupSnapshot<Target> = {
97
+ groupId: number;
98
+ relations: GestureRelations | undefined;
99
+ targets: readonly Target[];
100
+ /** Stable per group; the group element never re-renders for target changes. */
101
+ channel: PublishedTargetChannel<Target>;
102
+ };
103
+
104
+ export type GroupingState<Registration, Target> = {
105
+ targets: Map<number, { registration: Registration; target: Target }>;
106
+ signatures: Array<{
107
+ relations: GestureRelations | undefined;
108
+ groupId: number;
109
+ }>;
110
+ nextGroupId: number;
111
+ groups: readonly GestureGroupSnapshot<Target>[];
112
+ };
113
+
114
+ export function createGroupingState<Registration, Target>(): GroupingState<
115
+ Registration,
116
+ Target
117
+ > {
118
+ return { targets: new Map(), signatures: [], nextGroupId: 0, groups: [] };
119
+ }
120
+
121
+ function sameTargets<Target>(
122
+ previous: readonly Target[],
123
+ next: readonly Target[],
124
+ ): boolean {
125
+ return (
126
+ previous.length === next.length &&
127
+ previous.every((target, index) => target === next[index])
128
+ );
129
+ }
130
+
131
+ /**
132
+ * Groups the published owners by gesture relation signature. Target objects
133
+ * stay identical while their registration is unchanged and a group's target
134
+ * array stays identical while its content is unchanged, so an unchanged group
135
+ * publishes nothing to the UI runtime.
136
+ */
137
+ export function groupGestureOwners<
138
+ Registration extends { gestureRelations?: GestureRelations },
139
+ Target,
140
+ >(
141
+ owners: readonly GestureOwner<Registration>[],
142
+ state: GroupingState<Registration, Target>,
143
+ toTarget: (owner: GestureOwner<Registration>) => Target,
144
+ ): readonly GestureGroupSnapshot<Target>[] {
145
+ const targets = new Map<
146
+ number,
147
+ { registration: Registration; target: Target }
148
+ >();
149
+ const collected = new Map<
150
+ number,
151
+ { relations: GestureRelations | undefined; targets: Target[] }
152
+ >();
153
+ for (const owner of owners) {
154
+ const cached = state.targets.get(owner.id);
155
+ const target =
156
+ cached?.registration === owner.registration
157
+ ? cached.target
158
+ : toTarget(owner);
159
+ targets.set(owner.id, { registration: owner.registration, target });
160
+ let signature = state.signatures.find(entry =>
161
+ sameGestureRelations(
162
+ entry.relations,
163
+ owner.registration.gestureRelations,
164
+ ),
165
+ );
166
+ if (!signature) {
167
+ signature = {
168
+ relations: owner.registration.gestureRelations,
169
+ groupId: ++state.nextGroupId,
170
+ };
171
+ state.signatures.push(signature);
172
+ }
173
+ const group = collected.get(signature.groupId);
174
+ if (group) group.targets.push(target);
175
+ else
176
+ collected.set(signature.groupId, {
177
+ relations: signature.relations,
178
+ targets: [target],
179
+ });
180
+ }
181
+ state.targets = targets;
182
+ // A signature without handles releases its native recognizer.
183
+ state.signatures = state.signatures.filter(entry =>
184
+ collected.has(entry.groupId),
185
+ );
186
+ const groups = Array.from(collected, ([groupId, group]) => {
187
+ const previous = state.groups.find(entry => entry.groupId === groupId);
188
+ const hitTargets =
189
+ previous && sameTargets(previous.targets, group.targets)
190
+ ? previous.targets
191
+ : group.targets;
192
+ return {
193
+ groupId,
194
+ relations: previous?.relations ?? group.relations,
195
+ targets: hitTargets,
196
+ channel: previous?.channel ?? createTargetChannel(hitTargets),
197
+ };
198
+ });
199
+ state.groups =
200
+ groups.length === state.groups.length &&
201
+ groups.every(
202
+ (group, index) =>
203
+ group.groupId === state.groups[index]!.groupId &&
204
+ group.targets === state.groups[index]!.targets &&
205
+ group.relations === state.groups[index]!.relations,
206
+ )
207
+ ? state.groups
208
+ : groups;
209
+ return state.groups;
210
+ }
@@ -0,0 +1,163 @@
1
+ import {
2
+ createContext,
3
+ memo,
4
+ useCallback,
5
+ useContext,
6
+ useLayoutEffect,
7
+ useMemo,
8
+ useRef,
9
+ useState,
10
+ useSyncExternalStore,
11
+ type ComponentType,
12
+ type ReactElement,
13
+ } from 'react';
14
+ import {
15
+ GestureDetector,
16
+ useCompetingGestures,
17
+ useManualGesture,
18
+ type ManualGestureConfig,
19
+ type PanGesture,
20
+ } from 'react-native-gesture-handler';
21
+
22
+ import {
23
+ createGroupingState,
24
+ groupGestureOwners,
25
+ type GestureGroupProps,
26
+ type GestureOwner,
27
+ type GestureRegistry,
28
+ } from './gestureGrouping';
29
+ import type { GestureRelations } from '../components/gridTypes';
30
+
31
+ export type GestureHostProps<Registration, Runtime> = {
32
+ registry: GestureRegistry<Registration>;
33
+ runtime: Runtime;
34
+ };
35
+
36
+ const SENTINEL_CONFIG: ManualGestureConfig = {
37
+ enabled: false,
38
+ onTouchesDown: () => {
39
+ 'worklet';
40
+ },
41
+ };
42
+
43
+ /**
44
+ * Builds a host that owns one native recognizer per gesture relation
45
+ * signature. Handle mounts publish through the registry; the host groups them,
46
+ * renders one `Group` per signature and composes their recognizers on a single
47
+ * detector around the root content. Root content updates never render the
48
+ * detector or the groups.
49
+ */
50
+ export function createGestureHost<
51
+ Registration extends { gestureRelations?: GestureRelations },
52
+ Target,
53
+ Runtime,
54
+ >({
55
+ Group,
56
+ toTarget,
57
+ }: {
58
+ Group: ComponentType<GestureGroupProps<Runtime, Target>>;
59
+ toTarget(owner: GestureOwner<Registration>): Target;
60
+ }) {
61
+ const RootContentContext = createContext<ReactElement | null>(null);
62
+
63
+ // Only this descendant consumes changing root content. Its context update does
64
+ // not render the detector or re-run the gesture composition hooks above it.
65
+ function NativeRoot() {
66
+ return useContext(RootContentContext);
67
+ }
68
+
69
+ const GestureGroup = memo(Group);
70
+
71
+ const NativeGestureDetector = memo(function NativeGestureDetectorImpl({
72
+ nativeGestures,
73
+ }: {
74
+ nativeGestures: ReadonlyMap<number, PanGesture>;
75
+ }) {
76
+ // Keep the native component type stable while no handle is registered.
77
+ const sentinel = useManualGesture(SENTINEL_CONFIG);
78
+ const gesture = useCompetingGestures(sentinel, ...nativeGestures.values());
79
+ return (
80
+ <GestureDetector gesture={gesture}>
81
+ <NativeRoot />
82
+ </GestureDetector>
83
+ );
84
+ });
85
+
86
+ const GestureHost = memo(function GestureHostImpl({
87
+ registry,
88
+ runtime,
89
+ }: GestureHostProps<Registration, Runtime>) {
90
+ const owners = useSyncExternalStore(
91
+ registry.subscribe,
92
+ registry.getSnapshot,
93
+ registry.getSnapshot,
94
+ );
95
+ const mounted = useRef(true);
96
+ const gestureValues = useRef(new Map<number, PanGesture>());
97
+ const [gestureVersion, setGestureVersion] = useState(0);
98
+ // Group layout effects can publish several changes in one commit. Update
99
+ // their private map in O(1), then copy once when React renders the combined
100
+ // update. Never mutate the snapshot passed to the memoized detector.
101
+ const nativeGestures = useMemo(
102
+ () => new Map(gestureValues.current),
103
+ // The version explicitly invalidates this snapshot of the mutable registry.
104
+ // eslint-disable-next-line react-hooks/exhaustive-deps
105
+ [gestureVersion],
106
+ );
107
+ useLayoutEffect(() => {
108
+ mounted.current = true;
109
+ return () => {
110
+ mounted.current = false;
111
+ };
112
+ }, []);
113
+ const publish = useCallback((id: number, gesture: PanGesture | null) => {
114
+ if (!mounted.current) return;
115
+ const current = gestureValues.current;
116
+ if (gesture ? current.get(id) === gesture : !current.has(id)) return;
117
+ if (gesture) current.set(id, gesture);
118
+ else current.delete(id);
119
+ setGestureVersion(version => version + 1);
120
+ }, []);
121
+ const grouping = useRef(
122
+ createGroupingState<Registration, Target>(),
123
+ ).current;
124
+ // Re-running this for the same owners is idempotent, which keeps StrictMode
125
+ // and discarded renders from producing different group identities.
126
+ const groups = useMemo(
127
+ () => groupGestureOwners(owners, grouping, toTarget),
128
+ [owners, grouping],
129
+ );
130
+ // Publish after commit: the group's subscription effect is registered first.
131
+ useLayoutEffect(() => {
132
+ for (const group of groups) group.channel.set(group.targets);
133
+ }, [groups]);
134
+
135
+ return (
136
+ <>
137
+ <NativeGestureDetector nativeGestures={nativeGestures} />
138
+ {groups.map(group => (
139
+ <GestureGroup
140
+ key={group.groupId}
141
+ groupId={group.groupId}
142
+ relations={group.relations}
143
+ channel={group.channel}
144
+ runtime={runtime}
145
+ publish={publish}
146
+ />
147
+ ))}
148
+ </>
149
+ );
150
+ });
151
+
152
+ return function Host({
153
+ children,
154
+ registry,
155
+ runtime,
156
+ }: GestureHostProps<Registration, Runtime> & { children: ReactElement }) {
157
+ return (
158
+ <RootContentContext value={children}>
159
+ <GestureHost registry={registry} runtime={runtime} />
160
+ </RootContentContext>
161
+ );
162
+ };
163
+ }
package/src/index.ts ADDED
@@ -0,0 +1,162 @@
1
+ export { GridController } from './components/GridController';
2
+ export { DndProvider } from './components/DndProvider';
3
+ export { SortableList } from './components/SortableList';
4
+ export { SortableGrid } from './components/SortableGrid';
5
+ export { resolveListVirtualization } from './adapters/virtualizedList';
6
+ export type {
7
+ ListVirtualizationOptions,
8
+ ListVirtualizationResult,
9
+ } from './adapters/virtualizedList';
10
+ export { DragHandle } from './components/DragHandle';
11
+ export type {
12
+ DndProviderHandle,
13
+ DndProviderProps,
14
+ SortableListProps,
15
+ SortableGridProps,
16
+ GridItemRenderArgs,
17
+ DragHandleProps,
18
+ DragHandleViewProps,
19
+ ListItemRenderArgs,
20
+ DndPreviewArgs,
21
+ DndMotionConfig,
22
+ } from './components/dndTypes';
23
+ export { useDndState } from './controller/useDndState';
24
+ export type { DndState } from './controller/useDndState';
25
+ export {
26
+ createDndStateStore,
27
+ respondToDndProposal,
28
+ } from './controller/dndState';
29
+ export type {
30
+ DndValue,
31
+ DndProposal,
32
+ DndProposalResult,
33
+ DndStateStore,
34
+ DndStateUpdate,
35
+ } from './controller/dndState';
36
+ export type {
37
+ DndCancelReason,
38
+ DndDragEndEvent,
39
+ DndDropFailureReason,
40
+ GridItemLayoutResolverArgs,
41
+ } from './controller/dndSession';
42
+ export {
43
+ computeListLayout,
44
+ computeListIndex,
45
+ ListSizeCache,
46
+ } from './engine/list';
47
+ export type {
48
+ ListLayout,
49
+ ListLayoutEntry,
50
+ ListLayoutInput,
51
+ ListLayoutResult,
52
+ ListMeasurementContext,
53
+ } from './engine/list';
54
+ export { computeLayoutMove } from './engine/layoutMove';
55
+ export type {
56
+ GridItemLayout,
57
+ LayoutMoveInput,
58
+ LayoutMoveResult,
59
+ } from './engine/layoutMove';
60
+ export {
61
+ computeAutoScroll,
62
+ constrainDragPoint,
63
+ validateAutoScrollOptions,
64
+ } from './adapters/scroll';
65
+ export type {
66
+ AutoScrollInput,
67
+ AutoScrollOptions,
68
+ AutoScrollOptionsValidationResult,
69
+ AutoScrollResult,
70
+ DragAxis,
71
+ } from './adapters/scroll';
72
+ export { GridDragHandle } from './components/GridDragHandle';
73
+ export { GridZoneView } from './components/GridZoneView';
74
+ export { useGridState } from './controller/useGridState';
75
+ export type { GridState } from './controller/useGridState';
76
+ export {
77
+ createGridStateStore,
78
+ respondToGridProposal,
79
+ } from './controller/gridState';
80
+ export type {
81
+ GridStateStore,
82
+ GridStateUpdate,
83
+ GridProposalResult,
84
+ } from './controller/gridState';
85
+ export type { GridMotionConfig } from './pointer/motion';
86
+ export type { HandleViewProps } from './components/handleViewProps';
87
+ export { DEFAULT_ACTIVATION_DELAY_MS, DEFAULT_SEARCH_BUDGET } from './defaults';
88
+ export {
89
+ DEFAULT_GRID_MOVEMENT_POLICY,
90
+ HOME_GRID_MOVEMENT_POLICY,
91
+ resolveGridMovementPolicy,
92
+ validateGridMovementPolicy,
93
+ } from './engine/movementPolicy';
94
+ export type {
95
+ GridMoveCandidate,
96
+ GridMovementPolicy,
97
+ ResolvedGridMovementPolicy,
98
+ } from './engine/movementPolicy';
99
+ export type * from './contracts';
100
+ export {
101
+ validateLayoutState,
102
+ fromGridValue,
103
+ toGridValue,
104
+ } from './engine/layoutState';
105
+ export {
106
+ screenToContent,
107
+ contentToScreen,
108
+ screenRectToContent,
109
+ contentRectToScreen,
110
+ validateRectMeasurement,
111
+ } from './adapters/coordinates';
112
+ export type {
113
+ DragPreviewArgs,
114
+ GestureRelations,
115
+ GridControllerHandle,
116
+ GridControllerProps,
117
+ GridDragHandleProps,
118
+ GridInsets,
119
+ GridZoneViewProps,
120
+ ItemRenderArgs,
121
+ ZoneGeometry,
122
+ } from './components/gridTypes';
123
+ export type { OrderedIndexInput, OrderedIndexResult } from './engine';
124
+ export {
125
+ computeMove,
126
+ computeOrderedIndex,
127
+ computeZoneLayout,
128
+ hasSameLayout,
129
+ packItems,
130
+ validateValue,
131
+ } from './engine';
132
+ export type {
133
+ CancelReason,
134
+ CanDropArgs,
135
+ CellPosition,
136
+ CellSpan,
137
+ CleanupReason,
138
+ DragEndEvent,
139
+ DragStartEvent,
140
+ DropDecision,
141
+ GridChange,
142
+ GridDiagnosticEvent,
143
+ GridItem,
144
+ GridProposal,
145
+ GridValue,
146
+ GridZone,
147
+ ItemLocation,
148
+ ItemPlacement,
149
+ MoveInput,
150
+ MoveResult,
151
+ OrderedZone,
152
+ PackInput,
153
+ PackResult,
154
+ PositionedItem,
155
+ RevisionedGridValue,
156
+ ProposalInterruptReason,
157
+ SpatialZone,
158
+ ValidationCode,
159
+ ValidationIssue,
160
+ ValidationResult,
161
+ ZoneLayoutResult,
162
+ } from './types';