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,515 @@
1
+ import { validateRectMeasurement } from '../adapters/coordinates';
2
+ import type { LayoutLocation } from '../contracts';
3
+ import {
4
+ orderedSlots,
5
+ slotIndex,
6
+ slotPosition,
7
+ } from '../engine/gridPlacements';
8
+ import type { GridItemLayout } from '../engine/layoutMove';
9
+ import type { GridMovementPolicy } from '../engine/movementPolicy';
10
+ import { isCellSpan } from '../engine/validation';
11
+ import type { GridZone, ItemLocation, PositionedItem } from '../types';
12
+ import type {
13
+ DndMotion,
14
+ GridRegistration,
15
+ ListViewport,
16
+ ZoneRegistration,
17
+ } from '../runtime/dndRuntime';
18
+ import {
19
+ getCellGeometry,
20
+ isPlacementVisible,
21
+ isUsableRect,
22
+ itemRect,
23
+ readPointerTarget,
24
+ rectContains,
25
+ } from './geometry';
26
+ import { listTarget } from './listTarget';
27
+ import type { MeasuredZone, UiMotion } from '../runtime/gridRuntime';
28
+
29
+ type RegisteredZone = ZoneRegistration & { layoutVersion: number };
30
+ type Registrations = ReadonlyMap<string, RegisteredZone>;
31
+
32
+ /** Geometry-only immutable input for UI pointer targeting; no refs or renderers. */
33
+ export type PreparedGridTarget = Omit<MeasuredZone, 'rect' | 'zone'> & {
34
+ /** Ordered grids keep their `itemSpan` so slot targeting applies. */
35
+ zone: GridZone<undefined>;
36
+ zoneId: string;
37
+ revision: number;
38
+ layoutVersion: number;
39
+ };
40
+
41
+ const preparedGrids = new WeakMap<
42
+ GridRegistration['layout'],
43
+ PreparedGridTarget
44
+ >();
45
+
46
+ function sameGridInput(
47
+ prepared: PreparedGridTarget,
48
+ registration: GridRegistration & { layoutVersion: number },
49
+ ): boolean {
50
+ const { layout, geometry, cells } = registration;
51
+ const previous = prepared.geometry;
52
+ if (
53
+ prepared.zoneId !== registration.zoneId ||
54
+ prepared.revision !== registration.revision ||
55
+ prepared.layoutVersion !== registration.layoutVersion ||
56
+ prepared.pixelRatio !== registration.pixelRatio ||
57
+ prepared.cells.cellWidth !== cells.cellWidth ||
58
+ prepared.cells.cellHeight !== cells.cellHeight ||
59
+ prepared.zone.id !== layout.id ||
60
+ prepared.zone.rows !== layout.rows ||
61
+ prepared.zone.columns !== layout.columns ||
62
+ previous.mode !== geometry.mode ||
63
+ previous.rowGap !== geometry.rowGap ||
64
+ previous.columnGap !== geometry.columnGap ||
65
+ previous.padding.top !== geometry.padding.top ||
66
+ previous.padding.right !== geometry.padding.right ||
67
+ previous.padding.bottom !== geometry.padding.bottom ||
68
+ previous.padding.left !== geometry.padding.left ||
69
+ (previous.mode === 'fixed' &&
70
+ (geometry.mode !== 'fixed' ||
71
+ previous.cellWidth !== geometry.cellWidth ||
72
+ previous.cellHeight !== geometry.cellHeight)) ||
73
+ prepared.zone.items.length !== layout.placements.length ||
74
+ (prepared.zone.strategy === 'ordered') !==
75
+ (layout.itemSpan !== undefined) ||
76
+ (prepared.zone.strategy === 'ordered' &&
77
+ (prepared.zone.itemSpan.rows !== layout.itemSpan?.rows ||
78
+ prepared.zone.itemSpan.cols !== layout.itemSpan?.cols))
79
+ )
80
+ return false;
81
+ // Direct JS callers can mutate their typed registration. Compare known
82
+ // primitives against our detached snapshot instead of caching by identity
83
+ // alone. Providers prepare once when registering, outside the pointer path.
84
+ const ordered = prepared.zone.strategy === 'ordered';
85
+ return layout.placements.every((placement, index) => {
86
+ const item = prepared.zone.items[index] as PositionedOrOrdered;
87
+ return (
88
+ item.id === placement.itemId &&
89
+ (ordered ||
90
+ (item.position?.row === placement.position.row &&
91
+ item.position?.col === placement.position.col)) &&
92
+ item.span.rows === placement.span.rows &&
93
+ item.span.cols === placement.span.cols &&
94
+ item.placement === placement.placement
95
+ );
96
+ });
97
+ }
98
+
99
+ type PositionedOrOrdered = GridZone<undefined>['items'][number] & {
100
+ position?: { row: number; col: number };
101
+ };
102
+
103
+ /** Prepare on registration, then reuse the result on the UI runtime. */
104
+ export function prepareGridTarget(
105
+ registration: GridRegistration & { layoutVersion: number },
106
+ ): PreparedGridTarget {
107
+ const cached = preparedGrids.get(registration.layout);
108
+ if (cached && sameGridInput(cached, registration)) return cached;
109
+ const { layout, geometry } = registration;
110
+ const zone: GridZone<undefined> = layout.itemSpan
111
+ ? Object.freeze({
112
+ id: layout.id,
113
+ strategy: 'ordered' as const,
114
+ rows: layout.rows,
115
+ columns: layout.columns,
116
+ itemSpan: Object.freeze({
117
+ rows: layout.itemSpan.rows,
118
+ cols: layout.itemSpan.cols,
119
+ }),
120
+ // Ordered items carry no position; their slot follows from the order.
121
+ items: Object.freeze(
122
+ layout.placements.map(placement =>
123
+ Object.freeze({
124
+ id: placement.itemId,
125
+ data: undefined,
126
+ span: Object.freeze({
127
+ rows: placement.span.rows,
128
+ cols: placement.span.cols,
129
+ }),
130
+ placement: placement.placement,
131
+ }),
132
+ ),
133
+ ) as GridZone<undefined>['items'],
134
+ })
135
+ : Object.freeze({
136
+ id: layout.id,
137
+ strategy: 'spatial' as const,
138
+ rows: layout.rows,
139
+ columns: layout.columns,
140
+ items: Object.freeze(
141
+ layout.placements.map(placement =>
142
+ Object.freeze({
143
+ id: placement.itemId,
144
+ data: undefined,
145
+ position: Object.freeze({
146
+ row: placement.position.row,
147
+ col: placement.position.col,
148
+ }),
149
+ span: Object.freeze({
150
+ rows: placement.span.rows,
151
+ cols: placement.span.cols,
152
+ }),
153
+ placement: placement.placement,
154
+ }),
155
+ ),
156
+ ) as PositionedItem<undefined>[],
157
+ });
158
+ const prepared: PreparedGridTarget = Object.freeze({
159
+ zoneId: registration.zoneId,
160
+ revision: registration.revision,
161
+ layoutVersion: registration.layoutVersion,
162
+ zone,
163
+ geometry: Object.freeze({
164
+ ...(geometry.mode === 'fixed'
165
+ ? {
166
+ mode: 'fixed' as const,
167
+ cellWidth: geometry.cellWidth,
168
+ cellHeight: geometry.cellHeight,
169
+ }
170
+ : { mode: 'fit' as const }),
171
+ rowGap: geometry.rowGap,
172
+ columnGap: geometry.columnGap,
173
+ padding: Object.freeze({
174
+ top: geometry.padding.top,
175
+ right: geometry.padding.right,
176
+ bottom: geometry.padding.bottom,
177
+ left: geometry.padding.left,
178
+ }),
179
+ }),
180
+ cells: Object.freeze({
181
+ cellWidth: registration.cells.cellWidth,
182
+ cellHeight: registration.cells.cellHeight,
183
+ }),
184
+ pixelRatio: registration.pixelRatio,
185
+ });
186
+ preparedGrids.set(layout, prepared);
187
+ return prepared;
188
+ }
189
+
190
+ /** Attach current viewport coordinates without rebuilding baseline placements. */
191
+ export function measurePreparedGrid(
192
+ prepared: PreparedGridTarget,
193
+ measured: ListViewport,
194
+ ): MeasuredZone | null {
195
+ 'worklet';
196
+ if (
197
+ measured.zoneId !== prepared.zoneId ||
198
+ measured.layoutVersion !== prepared.layoutVersion ||
199
+ measured.viewport.revision !== prepared.revision ||
200
+ measured.viewport.source !== 'measured' ||
201
+ measured.viewport.space !== 'screen' ||
202
+ !Number.isSafeInteger(prepared.revision) ||
203
+ prepared.revision < 0 ||
204
+ !Number.isFinite(measured.viewport.timestampMs) ||
205
+ measured.viewport.timestampMs < 0 ||
206
+ measured.offset !== 0 ||
207
+ !isUsableRect(measured.viewport.rect)
208
+ )
209
+ return null;
210
+ const { zone, geometry, cells, pixelRatio } = prepared;
211
+ const currentCells = getCellGeometry(
212
+ zone,
213
+ geometry,
214
+ measured.viewport.rect.width,
215
+ measured.viewport.rect.height,
216
+ pixelRatio,
217
+ );
218
+ if (
219
+ zone.id !== prepared.zoneId ||
220
+ !currentCells ||
221
+ currentCells.cellWidth !== cells.cellWidth ||
222
+ currentCells.cellHeight !== cells.cellHeight
223
+ )
224
+ return null;
225
+ return { zone, geometry, cells, pixelRatio, rect: measured.viewport.rect };
226
+ }
227
+
228
+ function isCurrent(
229
+ state: DndMotion,
230
+ registration: RegisteredZone,
231
+ measured: ListViewport,
232
+ ignoreLayoutVersion = false,
233
+ ): boolean {
234
+ const checked = validateRectMeasurement(measured.viewport, {
235
+ revision: state.revision,
236
+ });
237
+ return (
238
+ checked.valid &&
239
+ checked.value.source === 'measured' &&
240
+ checked.value.space === 'screen' &&
241
+ registration.revision === state.revision &&
242
+ (ignoreLayoutVersion ||
243
+ registration.layoutVersion === measured.layoutVersion) &&
244
+ (registration.kind === 'grid'
245
+ ? measured.offset === 0
246
+ : registration.layout.revision === state.revision &&
247
+ Number.isFinite(measured.offset))
248
+ );
249
+ }
250
+
251
+ function measuredGrid(
252
+ registration: GridRegistration & { layoutVersion: number },
253
+ measured: ListViewport,
254
+ ): MeasuredZone | null {
255
+ const { layout, geometry, cells, pixelRatio } = registration;
256
+ const currentCells = getCellGeometry(
257
+ layout,
258
+ geometry,
259
+ measured.viewport.rect.width,
260
+ measured.viewport.rect.height,
261
+ pixelRatio,
262
+ );
263
+ if (
264
+ layout.id !== registration.zoneId ||
265
+ !currentCells ||
266
+ currentCells.cellWidth !== cells.cellWidth ||
267
+ currentCells.cellHeight !== cells.cellHeight
268
+ )
269
+ return null;
270
+ const prepared = prepareGridTarget(registration);
271
+ return {
272
+ zone: prepared.zone,
273
+ geometry: prepared.geometry,
274
+ cells: prepared.cells,
275
+ pixelRatio: prepared.pixelRatio,
276
+ rect: measured.viewport.rect,
277
+ };
278
+ }
279
+
280
+ /**
281
+ * Use committed list geometry and the existing grid pointer policy in one
282
+ * measured coordinate space. Grid recipes are captured by destination zone ID.
283
+ */
284
+ type LayoutTargetResolution = {
285
+ target: LayoutLocation | null;
286
+ /**
287
+ * The pointer is over a zone whose UI measurement predates the layout
288
+ * version registered on JS. The packet carries no new position; callers
289
+ * keep their current target until the UI publishes the new version.
290
+ */
291
+ stale: boolean;
292
+ };
293
+
294
+ export function layoutTarget(
295
+ state: DndMotion,
296
+ registrations: Registrations,
297
+ gridItemLayouts: ReadonlyMap<string, GridItemLayout>,
298
+ movementPolicy?: GridMovementPolicy,
299
+ previousTarget?: LayoutLocation | null,
300
+ ): LayoutLocation | null {
301
+ return resolveLayoutTarget(
302
+ state,
303
+ registrations,
304
+ gridItemLayouts,
305
+ movementPolicy,
306
+ previousTarget,
307
+ ).target;
308
+ }
309
+
310
+ export function resolveLayoutTarget(
311
+ state: DndMotion,
312
+ registrations: Registrations,
313
+ gridItemLayouts: ReadonlyMap<string, GridItemLayout>,
314
+ movementPolicy?: GridMovementPolicy,
315
+ previousTarget?: LayoutLocation | null,
316
+ ): LayoutTargetResolution {
317
+ const outside: LayoutTargetResolution = { target: null, stale: false };
318
+ if (
319
+ state.itemId === null ||
320
+ !isUsableRect(state.root) ||
321
+ !rectContains(state.root, state.pointer.x, state.pointer.y) ||
322
+ !Number.isFinite(state.width) ||
323
+ !Number.isFinite(state.height) ||
324
+ state.width <= 0 ||
325
+ state.height <= 0 ||
326
+ !Number.isFinite(state.grip.x) ||
327
+ !Number.isFinite(state.grip.y)
328
+ )
329
+ return outside;
330
+
331
+ // Keep an overlapping previous zone until the pointer actually leaves it,
332
+ // matching the old grid controller's zone selection policy.
333
+ const previous = state.zones.find(
334
+ measured => measured.zoneId === previousTarget?.zoneId,
335
+ );
336
+ const zones = previous
337
+ ? [previous, ...state.zones.filter(measured => measured !== previous)]
338
+ : state.zones;
339
+ let stale = false;
340
+ for (const measured of zones) {
341
+ const registration = registrations.get(measured.zoneId);
342
+ if (!registration) continue;
343
+ const inside = rectContains(
344
+ measured.viewport.rect,
345
+ state.pointer.x,
346
+ state.pointer.y,
347
+ );
348
+ if (!isCurrent(state, registration, measured)) {
349
+ if (inside && isCurrent(state, registration, measured, true))
350
+ stale = true;
351
+ continue;
352
+ }
353
+ if (!inside) continue;
354
+ if (registration.kind === 'list') {
355
+ return {
356
+ target: listTarget(
357
+ { ...state, zones: [measured] },
358
+ new Map([[measured.zoneId, registration]]),
359
+ ),
360
+ stale: false,
361
+ };
362
+ }
363
+
364
+ const recipe = gridItemLayouts.get(measured.zoneId);
365
+ const grid = measuredGrid(registration, measured);
366
+ if (!recipe || !isCellSpan(recipe.span) || !grid) return outside;
367
+ const content = itemRect(
368
+ { row: 0, col: 0 },
369
+ { rows: grid.zone.rows, cols: grid.zone.columns },
370
+ grid.geometry,
371
+ grid.cells,
372
+ );
373
+ // Padding cannot accept a grid drop even if clamping would fit its first cell.
374
+ if (
375
+ !rectContains(
376
+ { ...content, x: grid.rect.x + content.x, y: grid.rect.y + content.y },
377
+ state.pointer.x,
378
+ state.pointer.y,
379
+ )
380
+ )
381
+ continue;
382
+
383
+ const legacyMotion: UiMotion = {
384
+ token: state.token,
385
+ phase: 'dragging',
386
+ itemId: state.itemId,
387
+ sourceZoneId: state.sourceZoneId,
388
+ // Provider activation starts at sequence 1; the grid policy starts at 0.
389
+ seq: Math.max(0, state.seq - 1),
390
+ target:
391
+ previousTarget?.kind === 'grid'
392
+ ? legacyGridTarget(previousTarget, grid.zone)
393
+ : null,
394
+ span: recipe.span,
395
+ x: state.pointer.x - state.grip.x,
396
+ y: state.pointer.y - state.grip.y,
397
+ width: state.width,
398
+ height: state.height,
399
+ gripX: Math.max(0, Math.min(1, state.grip.x / state.width)),
400
+ gripY: Math.max(0, Math.min(1, state.grip.y / state.height)),
401
+ zones: [grid],
402
+ outlet: state.root,
403
+ validity: 'pending',
404
+ visible: state.visible,
405
+ destination: null,
406
+ movementPolicy,
407
+ baseRevision: state.revision,
408
+ };
409
+ const result = readPointerTarget(
410
+ legacyMotion,
411
+ state.pointer.x,
412
+ state.pointer.y,
413
+ );
414
+ if (result.target?.strategy === 'spatial') {
415
+ return {
416
+ target: {
417
+ kind: 'grid',
418
+ zoneId: result.target.zoneId,
419
+ position: result.target.position,
420
+ },
421
+ stale: false,
422
+ };
423
+ }
424
+ if (
425
+ result.target?.strategy === 'ordered' &&
426
+ grid.zone.strategy === 'ordered'
427
+ ) {
428
+ const slots = orderedSlots(grid.zone, grid.zone.itemSpan);
429
+ return {
430
+ target: {
431
+ kind: 'grid',
432
+ zoneId: result.target.zoneId,
433
+ position: slotPosition(
434
+ result.target.index,
435
+ grid.zone.itemSpan,
436
+ slots.perRow,
437
+ ),
438
+ },
439
+ stale: false,
440
+ };
441
+ }
442
+ }
443
+ return { target: null, stale };
444
+ }
445
+
446
+ /** Hand the grid pointer policy the previous target in its own vocabulary. */
447
+ function legacyGridTarget(
448
+ previous: Extract<LayoutLocation, { kind: 'grid' }>,
449
+ zone: GridZone<undefined>,
450
+ ): ItemLocation {
451
+ if (zone.strategy === 'ordered' && previous.zoneId === zone.id) {
452
+ const slots = orderedSlots(zone, zone.itemSpan);
453
+ const index = slotIndex(previous.position, zone.itemSpan, slots.perRow);
454
+ if (index !== null)
455
+ return { zoneId: previous.zoneId, strategy: 'ordered', index };
456
+ }
457
+ return {
458
+ zoneId: previous.zoneId,
459
+ strategy: 'spatial',
460
+ position: previous.position,
461
+ };
462
+ }
463
+
464
+ /** Recheck a resolved grid footprint after an exchange changes its position. */
465
+ export function isLayoutTargetVisible(
466
+ state: DndMotion,
467
+ registrations: Registrations,
468
+ target: LayoutLocation,
469
+ gridItemLayouts: ReadonlyMap<string, GridItemLayout>,
470
+ ): boolean {
471
+ if (!isUsableRect(state.root)) return false;
472
+ const registration = registrations.get(target.zoneId);
473
+ const measured = state.zones.find(entry => entry.zoneId === target.zoneId);
474
+ if (
475
+ !registration ||
476
+ !measured ||
477
+ registration.kind !== target.kind ||
478
+ !isCurrent(state, registration, measured)
479
+ )
480
+ return false;
481
+ if (target.kind === 'list' && registration.kind === 'list') {
482
+ const count = registration.layout.entries.filter(
483
+ entry => entry.itemId !== state.itemId,
484
+ ).length;
485
+ return (
486
+ Number.isSafeInteger(target.index) &&
487
+ target.index >= 0 &&
488
+ target.index <= count
489
+ );
490
+ }
491
+ if (target.kind !== 'grid' || registration.kind !== 'grid') return false;
492
+ const recipe = gridItemLayouts.get(target.zoneId);
493
+ const grid = measuredGrid(registration, measured);
494
+ if (!recipe || !grid || !isCellSpan(recipe.span)) return false;
495
+ if (grid.zone.strategy === 'ordered') {
496
+ // An ordered slot has the zone's span whatever the entering item asked for.
497
+ const slots = orderedSlots(grid.zone, grid.zone.itemSpan);
498
+ const index = slotIndex(target.position, grid.zone.itemSpan, slots.perRow);
499
+ return (
500
+ index !== null &&
501
+ isPlacementVisible(
502
+ [grid],
503
+ state.root,
504
+ { strategy: 'ordered', zoneId: target.zoneId, index },
505
+ grid.zone.itemSpan,
506
+ )
507
+ );
508
+ }
509
+ return isPlacementVisible(
510
+ [grid],
511
+ state.root,
512
+ { strategy: 'spatial', zoneId: target.zoneId, position: target.position },
513
+ recipe.span,
514
+ );
515
+ }
@@ -0,0 +1,174 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ makeMutable,
4
+ startMapper,
5
+ stopMapper,
6
+ withTiming,
7
+ type ReduceMotion,
8
+ type SharedValue,
9
+ } from 'react-native-reanimated';
10
+
11
+ import {
12
+ presentationRect,
13
+ type DndPresentation,
14
+ } from '../runtime/dndPresentation';
15
+ import type { DndRuntime } from '../runtime/dndRuntime';
16
+
17
+ type ListCellMotionArgs = {
18
+ zoneId: string;
19
+ itemId: string;
20
+ vertical: boolean;
21
+ fixed: boolean;
22
+ /** Committed main-axis start used when no validated candidate rect exists. */
23
+ start: number | SharedValue<number>;
24
+ /** Committed main-axis size used when no validated candidate rect exists. */
25
+ size: number;
26
+ presentation: DndRuntime['presentation'];
27
+ revision: number | SharedValue<number>;
28
+ hiddenItemId: SharedValue<string | null>;
29
+ animation: DndRuntime['animation'];
30
+ /**
31
+ * JS view of the geometry the Provider has already scheduled for the UI
32
+ * runtime. It is read once at mount for the initial style; the UI mapper
33
+ * adopts the actual UI geometry on its first run without animating.
34
+ */
35
+ initial: {
36
+ presentation: DndPresentation | undefined;
37
+ revision: number;
38
+ start: number;
39
+ };
40
+ };
41
+
42
+ type ListCellMotion = {
43
+ /** Animated main-axis content start in list content coordinates. */
44
+ animatedStart: SharedValue<number>;
45
+ /** Validated main-axis size for authoritative (fixed) item sizes. */
46
+ targetSize: SharedValue<number>;
47
+ };
48
+
49
+ /** Resolve the mount-time geometry from JS-owned data without UI reads. */
50
+ function resolveInitialListCellGeometry({
51
+ initial,
52
+ zoneId,
53
+ itemId,
54
+ vertical,
55
+ fixed,
56
+ size,
57
+ }: Pick<
58
+ ListCellMotionArgs,
59
+ 'initial' | 'zoneId' | 'itemId' | 'vertical' | 'fixed' | 'size'
60
+ >): { start: number; size: number } {
61
+ const rect =
62
+ initial.presentation !== undefined &&
63
+ initial.presentation.revision === initial.revision
64
+ ? presentationRect(initial.presentation, zoneId, itemId)
65
+ : undefined;
66
+ return {
67
+ start: rect ? (vertical ? rect.y : rect.x) : initial.start,
68
+ size: fixed && rect ? (vertical ? rect.height : rect.width) : size,
69
+ };
70
+ }
71
+
72
+ /**
73
+ * One UI mapper per cell selects the validated candidate rect and animates the
74
+ * content start. Mount reads no UI state: a synchronous shared-value read from
75
+ * JS blocks on the UI runtime and copies the whole presentation table. The
76
+ * first UI evaluation snaps to the UI geometry so a stale estimate never
77
+ * becomes the start of a timing animation.
78
+ */
79
+ export function useListCellMotion(args: ListCellMotionArgs): ListCellMotion {
80
+ const [values] = useState(() => {
81
+ const geometry = resolveInitialListCellGeometry(args);
82
+ return {
83
+ // NaN marks a target the UI runtime has not evaluated yet.
84
+ target: makeMutable(Number.NaN),
85
+ animatedStart: makeMutable(geometry.start),
86
+ targetSize: makeMutable(geometry.size),
87
+ };
88
+ });
89
+ const { target, animatedStart, targetSize } = values;
90
+ const {
91
+ zoneId,
92
+ itemId,
93
+ vertical,
94
+ fixed,
95
+ start,
96
+ size,
97
+ presentation,
98
+ revision,
99
+ hiddenItemId,
100
+ } = args;
101
+ const { durationMs, reduceMotion } = args.animation;
102
+ useEffect(() => {
103
+ const mapper = () => {
104
+ 'worklet';
105
+ const current = presentation?.get();
106
+ const committed =
107
+ typeof revision === 'number' ? revision : revision.get();
108
+ const rect =
109
+ current !== undefined && current.revision === committed
110
+ ? presentationRect(current, zoneId, itemId)
111
+ : undefined;
112
+ const nextTarget = rect
113
+ ? vertical
114
+ ? rect.y
115
+ : rect.x
116
+ : typeof start === 'number'
117
+ ? start
118
+ : start.get();
119
+ if (fixed) {
120
+ const nextSize = rect ? (vertical ? rect.height : rect.width) : size;
121
+ if (targetSize.get() !== nextSize) targetSize.set(nextSize);
122
+ }
123
+ const hidden = hiddenItemId.get() === itemId;
124
+ const previous = target.get();
125
+ if (Number.isNaN(previous)) {
126
+ // Adopt validated UI geometry without animating away from the JS
127
+ // estimate that produced the initial style.
128
+ target.set(nextTarget);
129
+ animatedStart.set(nextTarget);
130
+ return;
131
+ }
132
+ if (previous !== nextTarget) {
133
+ target.set(nextTarget);
134
+ animatedStart.set(
135
+ hidden
136
+ ? nextTarget
137
+ : withTiming(nextTarget, {
138
+ duration: durationMs,
139
+ reduceMotion: reduceMotion as ReduceMotion,
140
+ }),
141
+ );
142
+ } else if (hidden && animatedStart.get() !== nextTarget) {
143
+ // The hidden source sits exactly in its slot; stop in-flight motion.
144
+ animatedStart.set(nextTarget);
145
+ }
146
+ };
147
+ const mapperId = startMapper(
148
+ mapper,
149
+ [presentation, revision, start, hiddenItemId],
150
+ [
151
+ target as SharedValue<unknown>,
152
+ animatedStart as SharedValue<unknown>,
153
+ targetSize as SharedValue<unknown>,
154
+ ],
155
+ );
156
+ return () => stopMapper(mapperId);
157
+ }, [
158
+ animatedStart,
159
+ durationMs,
160
+ fixed,
161
+ hiddenItemId,
162
+ itemId,
163
+ presentation,
164
+ reduceMotion,
165
+ revision,
166
+ size,
167
+ start,
168
+ target,
169
+ targetSize,
170
+ vertical,
171
+ zoneId,
172
+ ]);
173
+ return { animatedStart, targetSize };
174
+ }