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,621 @@
1
+ "use strict";
2
+
3
+ import { samePlacement } from "../engine/gridPlacements.js";
4
+ import { computeValidatedLayoutMove } from "../engine/layoutMove.js";
5
+ import { validateLayoutState } from "../engine/layoutState.js";
6
+ import { isCellSpan, isPositiveInteger, isRecord } from "../engine/validation.js";
7
+ import { DEFAULT_SEARCH_BUDGET } from "../defaults.js";
8
+ import { resolveGridMovementPolicy, validateGridMovementPolicy } from "../engine/movementPolicy.js";
9
+ import { respondToValidatedDndProposal } from "./dndState.js";
10
+ import { now, reportCallbackError as reportFailure } from "./coordinatorBase.js";
11
+ import { layoutLocation, sameLayoutLocation } from "./locations.js";
12
+ import { PreviewPath } from "./previewPath.js";
13
+ import { SessionCore, validatedDecision } from "./sessionCore.js";
14
+ let instanceCounter = 0;
15
+
16
+ /** Capture structure by value so an in-place same-revision edit still invalidates a drag. */
17
+ function layoutKey(value) {
18
+ return JSON.stringify([value.revision, value.items.map(item => item.id).sort(), value.zones.map(zone => zone.kind === 'list' ? [zone.id, zone.kind, zone.orientation, [...zone.itemIds]] : [zone.id, zone.kind, zone.rows, zone.columns, zone.placements.map(item => [item.itemId, item.position.row, item.position.col, item.span.rows, item.span.cols, item.placement]).sort((a, b) => String(a[0]).localeCompare(String(b[0])))]).sort((a, b) => String(a[0]).localeCompare(String(b[0])))]);
19
+ }
20
+ function sameTarget(first, second) {
21
+ if (!first || !second) return first === second;
22
+ if (first.zoneId !== second.zoneId) return false;
23
+ return first.kind === 'list' && second.kind === 'list' ? first.index === second.index : first.kind === 'grid' && second.kind === 'grid' && first.position?.row === second.position?.row && first.position?.col === second.position?.col;
24
+ }
25
+ /** Compare generated layout containers without reading or copying opaque data. */
26
+ function samePreviewStructure(first, second, structure) {
27
+ if (Object.is(first, second)) return true;
28
+ if (first === null || second === null || typeof first !== 'object' || typeof second !== 'object' || Object.getPrototypeOf(first) !== Object.getPrototypeOf(second)) return false;
29
+ const keys = Reflect.ownKeys(first);
30
+ const otherKeys = Reflect.ownKeys(second);
31
+ return keys.length === otherKeys.length && keys.every((key, index) => {
32
+ if (key !== otherKeys[index]) return false;
33
+ const a = Object.getOwnPropertyDescriptor(first, key);
34
+ const b = Object.getOwnPropertyDescriptor(second, key);
35
+ if (!('value' in a) || !('value' in b) || a.enumerable !== b.enumerable) return false;
36
+ let child;
37
+ if (structure === 'state' && key === 'zones') child = 'zones';else if (structure === 'zone' && key === 'itemIds') child = 'itemIds';else if (structure === 'zone' && key === 'placements') child = 'placements';else if (structure === 'placement' && (key === 'position' || key === 'span') || structure === 'target' && key === 'position') child = 'coordinates';else if ((structure === 'zones' || structure === 'placements') && typeof key === 'string' && /^(0|[1-9]\d*)$/.test(key)) child = structure === 'zones' ? 'zone' : 'placement';
38
+ // Item arrays and extra metadata retain their exact identity. In
39
+ // particular, equality never traverses caller-owned item.data objects.
40
+ return child ? samePreviewStructure(a.value, b.value, child) : Object.is(a.value, b.value);
41
+ });
42
+ }
43
+ function sameVisibleSnapshot(first, second) {
44
+ return Object.keys(first).every(key => key === 'seq' || (key === 'candidate' || key === 'displayValue' ? samePreviewStructure(first[key], second[key], 'state') : key === 'target' ? samePreviewStructure(first[key], second[key], 'target') : Object.is(first[key], second[key])));
45
+ }
46
+ function settingsKey(options) {
47
+ return JSON.stringify([options.searchBudget ?? DEFAULT_SEARCH_BUDGET, options.responseTimeoutMs ?? 2000, resolveGridMovementPolicy(options.movementPolicy)]);
48
+ }
49
+ function copyMovementPolicy(policy) {
50
+ const resolved = resolveGridMovementPolicy(policy);
51
+ return Object.freeze({
52
+ ...resolved,
53
+ candidateOrder: Object.freeze([...resolved.candidateOrder]),
54
+ pointer: Object.freeze({
55
+ ...resolved.pointer
56
+ })
57
+ });
58
+ }
59
+ function copyGridItemLayout(value) {
60
+ if (!isRecord(value) || !isCellSpan(value.span) || value.placement !== undefined && value.placement !== 'insert' && value.placement !== 'exchange') return null;
61
+ return Object.freeze({
62
+ span: Object.freeze({
63
+ rows: value.span.rows,
64
+ cols: value.span.cols
65
+ }),
66
+ ...(value.placement === undefined ? {} : {
67
+ placement: value.placement
68
+ })
69
+ });
70
+ }
71
+ function checkOptions(options) {
72
+ const checked = validateLayoutState(options.value);
73
+ const issues = checked.valid ? [] : [...checked.issues];
74
+ const policy = validateGridMovementPolicy(options.movementPolicy);
75
+ if (!policy.valid) issues.push(...policy.issues);
76
+ const budgetValid = isPositiveInteger(options.searchBudget === undefined ? DEFAULT_SEARCH_BUDGET : options.searchBudget);
77
+ const timeoutValid = isPositiveInteger(options.responseTimeoutMs ?? 2000);
78
+ if (!budgetValid) issues.push({
79
+ code: 'invalid-budget',
80
+ message: 'searchBudget must be a positive safe integer.'
81
+ });
82
+ if (options.responseTimeoutMs !== undefined && !isPositiveInteger(options.responseTimeoutMs) || options.disabled !== undefined && typeof options.disabled !== 'boolean' || typeof options.onChange !== 'function' || ['canDrop', 'onDragStart', 'onDragEnd', 'onValidationError', 'getGridItemLayout'].some(key => {
83
+ const callback = options[key];
84
+ return callback !== undefined && typeof callback !== 'function';
85
+ })) {
86
+ issues.push({
87
+ code: 'invalid-configuration',
88
+ message: 'Session callbacks, disabled or response timeout are invalid.'
89
+ });
90
+ }
91
+ return {
92
+ layoutValid: checked.valid,
93
+ issues,
94
+ movementPolicy: copyMovementPolicy(policy.valid ? options.movementPolicy : undefined),
95
+ settingsKey: policy.valid && budgetValid && timeoutValid ? settingsKey(options) : null
96
+ };
97
+ }
98
+ function reportCallbackError(error) {
99
+ reportFailure('LayoutDnD', error);
100
+ }
101
+
102
+ /** Give a stored preview the item objects of a same-layout recommit. */
103
+ function rebaseLayoutState(value, committed) {
104
+ return value.items === committed.items ? value : {
105
+ ...value,
106
+ items: committed.items
107
+ };
108
+ }
109
+
110
+ /** Compare zone layouts by ID; revision and caller items are not layout. */
111
+ function sameLayoutZones(first, second) {
112
+ if (first.zones.length !== second.zones.length) return false;
113
+ const zones = new Map(second.zones.map(zone => [zone.id, zone]));
114
+ return first.zones.every(zone => {
115
+ const other = zones.get(zone.id);
116
+ if (!other) return false;
117
+ if (zone === other) return true;
118
+ if (zone.kind === 'list') return other.kind === 'list' && zone.itemIds.length === other.itemIds.length && zone.itemIds.every((id, index) => id === other.itemIds[index]);
119
+ if (other.kind !== 'grid' || zone.placements.length !== other.placements.length) return false;
120
+ const placements = new Map(other.placements.map(item => [item.itemId, item]));
121
+ return zone.placements.every(item => {
122
+ const match = placements.get(item.itemId);
123
+ return match !== undefined && samePlacement(item, match);
124
+ });
125
+ });
126
+ }
127
+
128
+ /** Express a candidate built on an earlier preview relative to the committed value. */
129
+ function relativeToCommitted(committed, from, result) {
130
+ if (sameLayoutZones(committed, result.value)) return {
131
+ ...result,
132
+ value: committed,
133
+ from,
134
+ changed: false
135
+ };
136
+ if (committed.revision === Number.MAX_SAFE_INTEGER) return {
137
+ status: 'invalid',
138
+ issues: [{
139
+ code: 'invalid-revision',
140
+ message: 'The layout revision cannot exceed a safe integer.'
141
+ }]
142
+ };
143
+ const revision = committed.revision + 1;
144
+ const value = result.value.revision === revision && result.value.items === committed.items ? result.value : {
145
+ ...result.value,
146
+ revision,
147
+ items: committed.items
148
+ };
149
+ return {
150
+ ...result,
151
+ value,
152
+ from,
153
+ changed: true
154
+ };
155
+ }
156
+
157
+ /** UI-independent normalized session; screen/scroll measurements stay in the adapter. */
158
+ export class DndSessionCoordinator extends SessionCore {
159
+ instanceId = ++instanceCounter;
160
+ sessionCounter = 0;
161
+ validationNotification = null;
162
+ previewInputVersion = 0;
163
+ operationVersion = 0;
164
+ constructor(options) {
165
+ const checked = checkOptions(options);
166
+ const lastValidValue = checked.layoutValid ? options.value : null;
167
+ super({
168
+ value: lastValidValue,
169
+ displayValue: lastValidValue,
170
+ candidate: null,
171
+ phase: 'idle',
172
+ sessionId: null,
173
+ itemId: null,
174
+ sourceZoneId: null,
175
+ targetZoneId: null,
176
+ target: null,
177
+ seq: 0,
178
+ validity: checked.issues.length ? 'invalid' : 'valid',
179
+ disabled: checked.issues.length > 0 || options.disabled === true,
180
+ gridItemLayouts: new Map(),
181
+ movementPolicy: checked.movementPolicy,
182
+ failureReason: null
183
+ }, lastValidValue);
184
+ this.options = options;
185
+ this.lastLayoutKey = checked.layoutValid ? layoutKey(options.value) : null;
186
+ }
187
+
188
+ /** Every batch is one operation; a refresh may only fold into its own. */
189
+ batchStarted() {
190
+ this.operationVersion++;
191
+ }
192
+ diagnosticObserver() {
193
+ return typeof this.options.onDiagnostic === 'function' ? this.options.onDiagnostic : undefined;
194
+ }
195
+
196
+ /** Commit owner state after render; ordinary scroll updates do not enter this contract. */
197
+ commit(options) {
198
+ this.batch(() => {
199
+ this.disposed = false;
200
+ const previousValue = this.lastValidValue;
201
+ const checked = checkOptions(options);
202
+ const key = checked.layoutValid ? layoutKey(options.value) : null;
203
+ const layoutChanged = key !== this.lastLayoutKey;
204
+ if (options.value !== this.options.value || options.canDrop !== this.options.canDrop) this.previewInputVersion++;
205
+ this.options = options;
206
+ this.lastLayoutKey = key;
207
+ if (checked.layoutValid) this.lastValidValue = options.value;
208
+ const disabled = checked.issues.length > 0 || options.disabled === true;
209
+ this.update({
210
+ value: this.lastValidValue,
211
+ disabled
212
+ });
213
+ const session = this.session;
214
+ const settingsChanged = !!session && (checked.settingsKey !== session.settingsKey || options.getGridItemLayout !== session.getGridItemLayout);
215
+ if (!session) {
216
+ this.update({
217
+ displayValue: this.lastValidValue,
218
+ validity: disabled ? 'invalid' : 'valid',
219
+ ...(JSON.stringify(this.snapshot.movementPolicy) !== JSON.stringify(checked.movementPolicy) ? {
220
+ movementPolicy: checked.movementPolicy
221
+ } : {})
222
+ });
223
+ } else if (this.snapshot.phase === 'awaiting-response') {
224
+ const response = isRecord(options.value) ? options.value.proposalResponse : undefined;
225
+ const matches = isRecord(response) && response.sessionId === session.sessionId && response.baseRevision === session.baseRevision && typeof response.accepted === 'boolean';
226
+ if (session.deadline !== undefined && now() >= session.deadline) {
227
+ this.settle(session, 'expired');
228
+ } else if (settingsChanged) {
229
+ this.interrupt(session, 'input-changed');
230
+ } else if (matches) {
231
+ // Acceptance is judged by layout and revision (the layout key). The
232
+ // owner may rebuild item objects or data in the accepting commit,
233
+ // as a store that derives a dock item from a page item does.
234
+ this.settle(session, response.accepted === false ? 'rejected' : checked.layoutValid && key === session.proposalKey ? 'accepted' : 'mismatch');
235
+ } else if (layoutChanged) {
236
+ this.interrupt(session, key === session.proposalKey ? 'response-missing' : 'input-changed');
237
+ } else if (disabled) {
238
+ this.interrupt(session, 'disabled');
239
+ }
240
+ } else if (layoutChanged) {
241
+ this.cancelWith('input-changed');
242
+ } else if (disabled) {
243
+ this.cancelWith('disabled');
244
+ } else if (settingsChanged) {
245
+ this.cancelWith('input-changed');
246
+ } else if (this.snapshot.displayValue === previousValue) {
247
+ this.update({
248
+ displayValue: this.lastValidValue
249
+ });
250
+ }
251
+ const notification = checked.issues.length ? JSON.stringify(checked.issues) : null;
252
+ if (notification !== this.validationNotification) {
253
+ this.validationNotification = notification;
254
+ if (notification && typeof options.onValidationError === 'function') {
255
+ try {
256
+ options.onValidationError(checked.issues);
257
+ } catch (error) {
258
+ reportCallbackError(error);
259
+ }
260
+ }
261
+ }
262
+ });
263
+ }
264
+ start(itemId, baseRevision) {
265
+ return this.batch(() => {
266
+ if (this.disposed || this.session || this.snapshot.disabled || !this.lastValidValue || baseRevision !== undefined && baseRevision !== this.lastValidValue.revision) return null;
267
+ const checked = checkOptions(this.options);
268
+ if (checked.issues.length) {
269
+ this.commit(this.options);
270
+ return null;
271
+ }
272
+ const source = this.lastValidValue.zones.find(zone => zone.kind === 'list' ? zone.itemIds.includes(itemId) : zone.placements.some(item => item.itemId === itemId));
273
+ if (!source) return null;
274
+ const base = this.lastValidValue;
275
+ const gridSource = source.kind === 'grid' ? source.placements.find(item => item.itemId === itemId) : null;
276
+ const from = source.kind === 'list' ? {
277
+ kind: 'list',
278
+ zoneId: source.id,
279
+ index: source.itemIds.indexOf(itemId)
280
+ } : {
281
+ kind: 'grid',
282
+ zoneId: source.id,
283
+ position: {
284
+ ...gridSource.position
285
+ }
286
+ };
287
+ const session = {
288
+ sessionId: `layout-dnd:${this.instanceId}:${++this.sessionCounter}`,
289
+ itemId,
290
+ sourceZoneId: source.id,
291
+ baseRevision: this.lastValidValue.revision,
292
+ seq: -1,
293
+ target: null,
294
+ path: new PreviewPath(sameLayoutLocation, rebaseLayoutState),
295
+ gridItemLayouts: new Map(),
296
+ gridItemLayoutErrors: new Map(),
297
+ movementPolicy: checked.movementPolicy,
298
+ searchBudget: this.options.searchBudget ?? DEFAULT_SEARCH_BUDGET,
299
+ responseTimeoutMs: this.options.responseTimeoutMs ?? 2000,
300
+ settingsKey: settingsKey(this.options),
301
+ getGridItemLayout: this.options.getGridItemLayout,
302
+ resolving: true,
303
+ previewSeq: null,
304
+ previewInputVersion: this.previewInputVersion
305
+ };
306
+ this.session = session;
307
+ this.update({
308
+ phase: 'dragging',
309
+ sessionId: session.sessionId,
310
+ itemId,
311
+ sourceZoneId: source.id,
312
+ targetZoneId: null,
313
+ target: null,
314
+ candidate: null,
315
+ seq: -1,
316
+ displayValue: this.lastValidValue,
317
+ validity: 'pending',
318
+ failureReason: null,
319
+ gridItemLayouts: new Map(),
320
+ movementPolicy: session.movementPolicy
321
+ });
322
+ try {
323
+ const item = base.items.find(candidate => candidate.id === itemId);
324
+ for (const target of base.zones) {
325
+ if (target.kind !== 'grid') continue;
326
+ const descriptor = target.id === source.id ? gridSource : session.getGridItemLayout ? session.getGridItemLayout({
327
+ item,
328
+ from,
329
+ target,
330
+ value: base
331
+ }) : gridSource;
332
+ if (this.session !== session) return null;
333
+ const copied = copyGridItemLayout(descriptor);
334
+ if (copied) session.gridItemLayouts.set(target.id, copied);else session.gridItemLayoutErrors.set(target.id, descriptor === null || descriptor === undefined ? 'missing-grid-item-layout' : 'invalid-grid-item-layout');
335
+ }
336
+ } catch (error) {
337
+ if (this.session === session) this.cancelWith('policy-error', error);else reportCallbackError(error);
338
+ return null;
339
+ }
340
+ session.resolving = false;
341
+ this.update({
342
+ gridItemLayouts: new Map(session.gridItemLayouts)
343
+ });
344
+ try {
345
+ this.options.onDragStart?.(this.event(session));
346
+ } catch (error) {
347
+ if (this.session === session) this.cancelWith('start-handler-error', error);else reportCallbackError(error);
348
+ }
349
+ return this.session === session ? session.sessionId : null;
350
+ });
351
+ }
352
+ requestTarget(sessionId, seq, to, options) {
353
+ this.batch(() => {
354
+ const session = this.acceptsRequest(sessionId, seq, false);
355
+ if (!session || session.resolving) return;
356
+ // The adapter can certify that measurements and policy inputs have not
357
+ // changed. Pointer movement within one target then needs only the private
358
+ // sequence guard; publishing it would rerender every sortable child.
359
+ if (options?.refresh === false && session.previewSeq === session.seq && session.previewInputVersion === this.previewInputVersion && sameTarget(session.target, to)) {
360
+ session.seq = seq;
361
+ session.previewSeq = seq;
362
+ // Pointer movement inside one logical cell. Reported so an observer can
363
+ // tell a coalesced packet from one that never arrived.
364
+ this.lifecycle('request-coalesced', session);
365
+ return;
366
+ }
367
+ const inputVersion = this.previewInputVersion;
368
+ const previous = this.snapshot;
369
+ const previousChanged = this.changed;
370
+ const operationVersion = this.operationVersion;
371
+ this.lifecycle('request', session);
372
+ this.calculate(session, seq, to, false);
373
+ // Reentrant callbacks may already have completed a newer request. Never
374
+ // mark that request as reusable using this older request's inputs.
375
+ if (this.session === session && session.seq === seq && this.snapshot.phase === 'dragging') {
376
+ session.previewSeq = seq;
377
+ session.previewInputVersion = inputVersion;
378
+ if (options?.refresh === true && this.batchDepth === 1 && this.operationVersion === operationVersion && this.previewInputVersion === inputVersion && sameTarget(previous.target, to) && sameVisibleSnapshot(previous, this.snapshot)) {
379
+ // Scrolling can require a fresh visibility/canDrop check without
380
+ // changing anything React displays. Keep sequence ownership private,
381
+ // just as for refresh:false, after every validation has completed.
382
+ this.restore(previous, previousChanged);
383
+ }
384
+ }
385
+ });
386
+ }
387
+ release(sessionId, seq, to) {
388
+ this.batch(() => {
389
+ const session = this.acceptsRequest(sessionId, seq, true);
390
+ if (!session || session.resolving) return;
391
+ // This is receipt on JS, not the physical touch-release timestamp.
392
+ this.lifecycle('release', session);
393
+ this.calculate(session, seq, to, true);
394
+ });
395
+ }
396
+ calculate(session, seq, target, final) {
397
+ // The path accumulates inside one grid zone only; any other target builds
398
+ // on the committed value again, as the display does.
399
+ if (!target || target.kind !== 'grid' || target.zoneId !== session.target?.zoneId) session.path.reset();
400
+ session.seq = seq;
401
+ session.target = target && (target.kind === 'grid' ? {
402
+ ...target,
403
+ position: {
404
+ ...target.position
405
+ }
406
+ } : {
407
+ ...target
408
+ });
409
+ this.update({
410
+ seq,
411
+ target: session.target,
412
+ targetZoneId: target?.zoneId ?? null,
413
+ validity: 'pending',
414
+ failureReason: null
415
+ });
416
+ this.calculateCandidate(session, final);
417
+ }
418
+ location(value, itemId) {
419
+ return layoutLocation(value, itemId);
420
+ }
421
+ isSpatial(target) {
422
+ return target.kind === 'grid';
423
+ }
424
+
425
+ /** Grid destinations need the span captured at activation. */
426
+ precheck(session, target) {
427
+ if (target.kind !== 'grid' || session.gridItemLayouts.has(target.zoneId)) return null;
428
+ return session.gridItemLayoutErrors.get(target.zoneId) ?? 'invalid-target';
429
+ }
430
+ compute(session, target, baseline, committed, from) {
431
+ // lastValidValue passed validateLayoutState when it was committed, the
432
+ // API requires immutable values, and an earlier preview was validated as
433
+ // a complete candidate. Pointer updates therefore validate only the new
434
+ // candidate instead of the whole baseline again.
435
+ const result = this.timed(session, 'compute-move', () => computeValidatedLayoutMove({
436
+ value: baseline.cumulative ? {
437
+ ...baseline.base,
438
+ revision: committed.revision
439
+ } : committed,
440
+ itemId: session.itemId,
441
+ to: target,
442
+ gridItem: target.kind === 'grid' ? session.gridItemLayouts.get(target.zoneId) : undefined,
443
+ movementPolicy: session.movementPolicy,
444
+ searchBudget: session.searchBudget
445
+ }), computed => computed.status, computed => 'attempts' in computed ? computed.attempts : undefined);
446
+ if (result.status !== 'ok') return {
447
+ status: result.status
448
+ };
449
+ const relative = baseline.cumulative && from ? relativeToCommitted(committed, from, result) : result;
450
+ return relative.status === 'ok' ? relative : {
451
+ status: relative.status
452
+ };
453
+ }
454
+
455
+ // A transient gap between legal positions inside the source grid must not
456
+ // bounce neighbors back to the committed layout (the same rule as the grid
457
+ // controller). This affects display only; release still computes its own
458
+ // candidate and reports the failure reason.
459
+ keepsPreview(session, target, status) {
460
+ return target.kind === 'grid' && target.zoneId === session.sourceZoneId && (status === 'impossible' || status === 'unresolved');
461
+ }
462
+ prepareProposal(session, result) {
463
+ return {
464
+ sessionId: session.sessionId,
465
+ baseRevision: session.baseRevision,
466
+ itemId: session.itemId,
467
+ from: result.from,
468
+ to: result.to,
469
+ value: result.value
470
+ };
471
+ }
472
+ askPolicy(_session, _committed, proposal) {
473
+ return validatedDecision(this.options.canDrop ? this.options.canDrop(proposal) : {
474
+ allowed: true
475
+ });
476
+ }
477
+ policyFailed(session, seq, error) {
478
+ if (this.session === session && session.seq === seq && this.snapshot.phase === 'dragging') this.cancelWith('policy-error', error);else reportCallbackError(error);
479
+ }
480
+
481
+ // Policy callbacks receive the complete candidate. Validate it again if a
482
+ // callback was allowed to run before issuing an atomic state proposal.
483
+ revalidate(_session, committed, proposal) {
484
+ return !this.options.canDrop || respondToValidatedDndProposal(this.lastValidValue ?? committed, proposal, true).status === 'accepted';
485
+ }
486
+ showCandidate(result) {
487
+ this.update({
488
+ validity: 'valid',
489
+ candidate: result.value,
490
+ displayValue: result.value
491
+ });
492
+ }
493
+ showFailure(committed, failure, keepPreview) {
494
+ this.update({
495
+ validity: 'invalid',
496
+ failureReason: failure,
497
+ ...(keepPreview ? {} : {
498
+ candidate: null,
499
+ displayValue: committed
500
+ })
501
+ });
502
+ }
503
+ expectedPhase() {
504
+ return 'dragging';
505
+ }
506
+ sessionEnded() {
507
+ return false;
508
+ }
509
+ finishUnchanged(session) {
510
+ this.finish(session, {
511
+ ...this.event(session),
512
+ outcome: 'unchanged'
513
+ });
514
+ }
515
+ registerProposal(session, proposal, result) {
516
+ session.proposal = proposal;
517
+ session.proposalKey = layoutKey(result.value);
518
+ session.deadline = now() + session.responseTimeoutMs;
519
+ this.update({
520
+ phase: 'awaiting-response'
521
+ });
522
+ this.armTimer(session);
523
+ this.lifecycle('proposal', session);
524
+ }
525
+ emitChange(proposal, result) {
526
+ this.options.onChange(result.value, proposal);
527
+ }
528
+ changeFailed(session, error) {
529
+ if (this.session === session) this.interrupt(session, 'change-handler-error', error);else reportCallbackError(error);
530
+ }
531
+ armTimer(session) {
532
+ this.armDeadline(session.deadline, () => this.session === session, () => this.settle(session, 'expired'));
533
+ }
534
+ settle(session, response) {
535
+ if (!session.proposal) return;
536
+ this.finish(session, {
537
+ ...this.event(session),
538
+ outcome: 'proposed',
539
+ proposal: session.proposal,
540
+ targetZoneId: session.proposal.to.zoneId,
541
+ response
542
+ });
543
+ }
544
+ interrupt(session, reason, error) {
545
+ if (!session.proposal) return;
546
+ this.finish(session, {
547
+ ...this.event(session),
548
+ outcome: 'proposed',
549
+ proposal: session.proposal,
550
+ targetZoneId: session.proposal.to.zoneId,
551
+ response: 'interrupted',
552
+ reason,
553
+ ...(error === undefined ? {} : {
554
+ error
555
+ })
556
+ });
557
+ }
558
+ cancelWith(reason, error, policyReason) {
559
+ const session = this.session;
560
+ if (!session) return;
561
+ if (session.proposal) {
562
+ this.interrupt(session, reason, error);
563
+ return;
564
+ }
565
+ this.finish(session, {
566
+ ...this.event(session),
567
+ outcome: 'cancelled',
568
+ reason,
569
+ ...(session.target ? {
570
+ targetZoneId: session.target.zoneId
571
+ } : {}),
572
+ ...(error === undefined ? {} : {
573
+ error
574
+ }),
575
+ ...(policyReason === undefined ? {} : {
576
+ policyReason
577
+ })
578
+ });
579
+ }
580
+ cancel(reason) {
581
+ this.batch(() => this.cancelWith(reason));
582
+ }
583
+ finish(session, event) {
584
+ if (this.session !== session) return;
585
+ if (event.outcome === 'proposed') this.lifecycle('response', session);
586
+ this.lifecycle('end', session);
587
+ this.clearDeadline();
588
+ // Clear before callbacks so reentrant end handlers can safely start a new drag.
589
+ this.session = null;
590
+ this.update({
591
+ phase: 'idle',
592
+ sessionId: null,
593
+ itemId: null,
594
+ sourceZoneId: null,
595
+ targetZoneId: null,
596
+ target: null,
597
+ candidate: null,
598
+ seq: 0,
599
+ displayValue: this.lastValidValue,
600
+ validity: this.snapshot.disabled ? 'invalid' : 'valid',
601
+ gridItemLayouts: new Map(),
602
+ failureReason: null
603
+ });
604
+ try {
605
+ this.options.onDragEnd?.(event);
606
+ } catch (error) {
607
+ reportCallbackError(error);
608
+ }
609
+ }
610
+ dispose() {
611
+ this.batch(() => {
612
+ this.disposed = true;
613
+ this.clearDeadline();
614
+ this.update({
615
+ disabled: true
616
+ });
617
+ this.cancelWith('unmounted');
618
+ });
619
+ }
620
+ }
621
+ //# sourceMappingURL=dndSession.js.map