@planningcenter/react-beautiful-dnd 13.2.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 (243) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/LICENSE +13 -0
  3. package/README.md +178 -0
  4. package/dist/react-beautiful-dnd.cjs.js +8728 -0
  5. package/dist/react-beautiful-dnd.cjs.js.flow +3 -0
  6. package/dist/react-beautiful-dnd.esm.js +8715 -0
  7. package/dist/react-beautiful-dnd.js +11726 -0
  8. package/dist/react-beautiful-dnd.min.js +1 -0
  9. package/package.json +155 -0
  10. package/src/animation.js +75 -0
  11. package/src/debug/middleware/action-timing-average.js +52 -0
  12. package/src/debug/middleware/action-timing.js +16 -0
  13. package/src/debug/middleware/log.js +26 -0
  14. package/src/debug/middleware/user-timing.js +16 -0
  15. package/src/debug/timings.js +86 -0
  16. package/src/dev-warning.js +50 -0
  17. package/src/empty.js +6 -0
  18. package/src/index.js +67 -0
  19. package/src/invariant.js +33 -0
  20. package/src/native-with-fallback.js +69 -0
  21. package/src/screen-reader-message-preset.js +134 -0
  22. package/src/state/action-creators.js +328 -0
  23. package/src/state/auto-scroller/auto-scroller-types.js +8 -0
  24. package/src/state/auto-scroller/can-scroll.js +160 -0
  25. package/src/state/auto-scroller/fluid-scroller/config.js +25 -0
  26. package/src/state/auto-scroller/fluid-scroller/did-start-in-scrollable-area.js +1 -0
  27. package/src/state/auto-scroller/fluid-scroller/get-best-scrollable-droppable.js +77 -0
  28. package/src/state/auto-scroller/fluid-scroller/get-droppable-scroll-change.js +50 -0
  29. package/src/state/auto-scroller/fluid-scroller/get-percentage.js +25 -0
  30. package/src/state/auto-scroller/fluid-scroller/get-scroll/adjust-for-size-limits.js +30 -0
  31. package/src/state/auto-scroller/fluid-scroller/get-scroll/buffer-thresholds/calc-axis-scroll-conditions.js +68 -0
  32. package/src/state/auto-scroller/fluid-scroller/get-scroll/buffer-thresholds/get-scroll-conditions.js +56 -0
  33. package/src/state/auto-scroller/fluid-scroller/get-scroll/buffer-thresholds/index.js +66 -0
  34. package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/dampen-value-by-time.js +48 -0
  35. package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-distance-thresholds.js +31 -0
  36. package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-value-from-distance.js +67 -0
  37. package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-value.js +51 -0
  38. package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/index.js +50 -0
  39. package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/min-scroll.js +4 -0
  40. package/src/state/auto-scroller/fluid-scroller/get-scroll/index.js +139 -0
  41. package/src/state/auto-scroller/fluid-scroller/get-window-scroll-change.js +43 -0
  42. package/src/state/auto-scroller/fluid-scroller/index.js +99 -0
  43. package/src/state/auto-scroller/fluid-scroller/scroll.js +80 -0
  44. package/src/state/auto-scroller/index.js +59 -0
  45. package/src/state/auto-scroller/jump-scroller.js +139 -0
  46. package/src/state/axis.js +26 -0
  47. package/src/state/calculate-drag-impact/calculate-reorder-impact.js +136 -0
  48. package/src/state/can-start-drag.js +29 -0
  49. package/src/state/create-store.js +97 -0
  50. package/src/state/did-start-after-critical.js +9 -0
  51. package/src/state/dimension-marshal/dimension-marshal-types.js +46 -0
  52. package/src/state/dimension-marshal/dimension-marshal.js +218 -0
  53. package/src/state/dimension-marshal/get-initial-publish.js +66 -0
  54. package/src/state/dimension-marshal/while-dragging-publisher.js +146 -0
  55. package/src/state/dimension-structures.js +35 -0
  56. package/src/state/droppable/get-droppable.js +101 -0
  57. package/src/state/droppable/is-home-of.js +7 -0
  58. package/src/state/droppable/scroll-droppable.js +53 -0
  59. package/src/state/droppable/should-use-placeholder.js +7 -0
  60. package/src/state/droppable/util/clip.js +17 -0
  61. package/src/state/droppable/util/get-subject.js +63 -0
  62. package/src/state/droppable/what-is-dragged-over-from-result.js +16 -0
  63. package/src/state/droppable/what-is-dragged-over.js +16 -0
  64. package/src/state/droppable/with-placeholder.js +174 -0
  65. package/src/state/get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center.js +29 -0
  66. package/src/state/get-center-from-impact/get-client-border-box-center/index.js +44 -0
  67. package/src/state/get-center-from-impact/get-page-border-box-center/index.js +70 -0
  68. package/src/state/get-center-from-impact/get-page-border-box-center/when-combining.js +39 -0
  69. package/src/state/get-center-from-impact/get-page-border-box-center/when-reordering.js +112 -0
  70. package/src/state/get-center-from-impact/move-relative-to.js +66 -0
  71. package/src/state/get-combined-item-displacement.js +34 -0
  72. package/src/state/get-displaced-by.js +17 -0
  73. package/src/state/get-displacement-groups.js +130 -0
  74. package/src/state/get-drag-impact/get-combine-impact.js +130 -0
  75. package/src/state/get-drag-impact/get-reorder-impact.js +143 -0
  76. package/src/state/get-drag-impact/index.js +93 -0
  77. package/src/state/get-draggables-inside-droppable.js +31 -0
  78. package/src/state/get-droppable-over.js +158 -0
  79. package/src/state/get-frame.js +10 -0
  80. package/src/state/get-home-location.js +7 -0
  81. package/src/state/get-impact-location.js +16 -0
  82. package/src/state/get-is-displaced.js +11 -0
  83. package/src/state/get-lift-effect.js +82 -0
  84. package/src/state/get-max-scroll.js +30 -0
  85. package/src/state/is-movement-allowed.js +6 -0
  86. package/src/state/is-within.js +9 -0
  87. package/src/state/middleware/auto-scroll.js +38 -0
  88. package/src/state/middleware/dimension-marshal-stopper.js +20 -0
  89. package/src/state/middleware/drop/drop-animation-finish-middleware.js +21 -0
  90. package/src/state/middleware/drop/drop-animation-flush-on-scroll-middleware.js +63 -0
  91. package/src/state/middleware/drop/drop-middleware.js +146 -0
  92. package/src/state/middleware/drop/get-drop-duration.js +47 -0
  93. package/src/state/middleware/drop/get-drop-impact.js +77 -0
  94. package/src/state/middleware/drop/get-new-home-client-offset.js +54 -0
  95. package/src/state/middleware/drop/index.js +2 -0
  96. package/src/state/middleware/focus.js +42 -0
  97. package/src/state/middleware/lift.js +66 -0
  98. package/src/state/middleware/pending-drop.js +37 -0
  99. package/src/state/middleware/responders/async-marshal.js +55 -0
  100. package/src/state/middleware/responders/expiring-announce.js +44 -0
  101. package/src/state/middleware/responders/index.js +2 -0
  102. package/src/state/middleware/responders/is-equal.js +57 -0
  103. package/src/state/middleware/responders/publisher.js +253 -0
  104. package/src/state/middleware/responders/responders-middleware.js +75 -0
  105. package/src/state/middleware/scroll-listener.js +31 -0
  106. package/src/state/middleware/style.js +22 -0
  107. package/src/state/middleware/util/validate-dimensions.js +71 -0
  108. package/src/state/move-in-direction/index.js +84 -0
  109. package/src/state/move-in-direction/move-cross-axis/get-best-cross-axis-droppable.js +168 -0
  110. package/src/state/move-in-direction/move-cross-axis/get-closest-draggable.js +79 -0
  111. package/src/state/move-in-direction/move-cross-axis/index.js +109 -0
  112. package/src/state/move-in-direction/move-cross-axis/move-to-new-droppable.js +121 -0
  113. package/src/state/move-in-direction/move-cross-axis/without-starting-displacement.js +31 -0
  114. package/src/state/move-in-direction/move-in-direction-types.js +9 -0
  115. package/src/state/move-in-direction/move-to-next-place/index.js +132 -0
  116. package/src/state/move-in-direction/move-to-next-place/is-totally-visible-in-new-location.js +52 -0
  117. package/src/state/move-in-direction/move-to-next-place/move-to-next-combine/index.js +97 -0
  118. package/src/state/move-in-direction/move-to-next-place/move-to-next-index/from-combine.js +52 -0
  119. package/src/state/move-in-direction/move-to-next-place/move-to-next-index/from-reorder.js +43 -0
  120. package/src/state/move-in-direction/move-to-next-place/move-to-next-index/index.js +86 -0
  121. package/src/state/no-impact.js +33 -0
  122. package/src/state/patch-dimension-map.js +11 -0
  123. package/src/state/patch-droppable-map.js +10 -0
  124. package/src/state/position.js +58 -0
  125. package/src/state/post-reducer/when-moving/refresh-snap.js +67 -0
  126. package/src/state/post-reducer/when-moving/update.js +120 -0
  127. package/src/state/publish-while-dragging-in-virtual/adjust-additions-for-scroll-changes.js +58 -0
  128. package/src/state/publish-while-dragging-in-virtual/index.js +158 -0
  129. package/src/state/publish-while-dragging-in-virtual/offset-draggable.js +35 -0
  130. package/src/state/recompute-placeholders.js +99 -0
  131. package/src/state/rect.js +7 -0
  132. package/src/state/reducer.js +457 -0
  133. package/src/state/registry/create-registry.js +162 -0
  134. package/src/state/registry/registry-types.js +98 -0
  135. package/src/state/registry/use-registry.js +20 -0
  136. package/src/state/remove-draggable-from-list.js +13 -0
  137. package/src/state/scroll-viewport.js +34 -0
  138. package/src/state/spacing.js +45 -0
  139. package/src/state/store-types.js +16 -0
  140. package/src/state/update-displacement-visibility/recompute.js +54 -0
  141. package/src/state/update-displacement-visibility/speculatively-increase.js +111 -0
  142. package/src/state/visibility/is-partially-visible-through-frame.js +60 -0
  143. package/src/state/visibility/is-position-in-frame.js +12 -0
  144. package/src/state/visibility/is-totally-visible-through-frame-on-axis.js +19 -0
  145. package/src/state/visibility/is-totally-visible-through-frame.js +18 -0
  146. package/src/state/visibility/is-visible.js +102 -0
  147. package/src/state/with-scroll-change/with-all-displacement.js +15 -0
  148. package/src/state/with-scroll-change/with-droppable-displacement.js +13 -0
  149. package/src/state/with-scroll-change/with-droppable-scroll.js +13 -0
  150. package/src/state/with-scroll-change/with-viewport-displacement.js +7 -0
  151. package/src/types.js +542 -0
  152. package/src/view/animate-in-out/animate-in-out.jsx +95 -0
  153. package/src/view/animate-in-out/index.js +2 -0
  154. package/src/view/check-is-valid-inner-ref.js +15 -0
  155. package/src/view/context/app-context.js +19 -0
  156. package/src/view/context/droppable-context.js +11 -0
  157. package/src/view/context/store-context.js +5 -0
  158. package/src/view/data-attributes.js +37 -0
  159. package/src/view/drag-drop-context/app.jsx +273 -0
  160. package/src/view/drag-drop-context/check-doctype.js +39 -0
  161. package/src/view/drag-drop-context/check-react-version.js +71 -0
  162. package/src/view/drag-drop-context/drag-drop-context-types.js +7 -0
  163. package/src/view/drag-drop-context/drag-drop-context.jsx +68 -0
  164. package/src/view/drag-drop-context/error-boundary.jsx +88 -0
  165. package/src/view/drag-drop-context/index.js +2 -0
  166. package/src/view/drag-drop-context/use-startup-validation.js +13 -0
  167. package/src/view/drag-drop-context/use-unique-context-id.js +13 -0
  168. package/src/view/draggable/connected-draggable.js +372 -0
  169. package/src/view/draggable/draggable-api.jsx +48 -0
  170. package/src/view/draggable/draggable-types.js +191 -0
  171. package/src/view/draggable/draggable.jsx +171 -0
  172. package/src/view/draggable/get-style.js +109 -0
  173. package/src/view/draggable/index.js +2 -0
  174. package/src/view/draggable/use-validation.js +70 -0
  175. package/src/view/droppable/connected-droppable.js +280 -0
  176. package/src/view/droppable/droppable-types.js +91 -0
  177. package/src/view/droppable/droppable.jsx +167 -0
  178. package/src/view/droppable/index.js +2 -0
  179. package/src/view/droppable/use-validation.js +101 -0
  180. package/src/view/event-bindings/bind-events.js +39 -0
  181. package/src/view/event-bindings/event-types.js +14 -0
  182. package/src/view/get-body-element.js +8 -0
  183. package/src/view/get-border-box-center-position.js +5 -0
  184. package/src/view/get-document-element.js +8 -0
  185. package/src/view/get-elements/find-drag-handle.js +38 -0
  186. package/src/view/get-elements/find-draggable.js +30 -0
  187. package/src/view/is-strict-equal.js +2 -0
  188. package/src/view/is-type-of-element/is-element.js +6 -0
  189. package/src/view/is-type-of-element/is-html-element.js +6 -0
  190. package/src/view/is-type-of-element/is-svg-element.js +12 -0
  191. package/src/view/key-codes.js +13 -0
  192. package/src/view/placeholder/index.js +2 -0
  193. package/src/view/placeholder/placeholder-types.js +16 -0
  194. package/src/view/placeholder/placeholder.jsx +198 -0
  195. package/src/view/scroll-listener.js +72 -0
  196. package/src/view/throw-if-invalid-inner-ref.js +15 -0
  197. package/src/view/use-announcer/index.js +2 -0
  198. package/src/view/use-announcer/use-announcer.js +80 -0
  199. package/src/view/use-dev-setup-warning.js +22 -0
  200. package/src/view/use-dev.js +9 -0
  201. package/src/view/use-draggable-publisher/get-dimension.js +44 -0
  202. package/src/view/use-draggable-publisher/index.js +2 -0
  203. package/src/view/use-draggable-publisher/use-draggable-publisher.js +87 -0
  204. package/src/view/use-droppable-publisher/check-for-nested-scroll-container.js +27 -0
  205. package/src/view/use-droppable-publisher/get-closest-scrollable.js +95 -0
  206. package/src/view/use-droppable-publisher/get-dimension.js +139 -0
  207. package/src/view/use-droppable-publisher/get-env.js +31 -0
  208. package/src/view/use-droppable-publisher/get-listener-options.js +12 -0
  209. package/src/view/use-droppable-publisher/get-scroll.js +7 -0
  210. package/src/view/use-droppable-publisher/index.js +2 -0
  211. package/src/view/use-droppable-publisher/is-in-fixed-container.js +21 -0
  212. package/src/view/use-droppable-publisher/use-droppable-publisher.js +283 -0
  213. package/src/view/use-focus-marshal/focus-marshal-types.js +13 -0
  214. package/src/view/use-focus-marshal/index.js +2 -0
  215. package/src/view/use-focus-marshal/use-focus-marshal.js +129 -0
  216. package/src/view/use-hidden-text-element/index.js +2 -0
  217. package/src/view/use-hidden-text-element/use-hidden-text-element.js +60 -0
  218. package/src/view/use-isomorphic-layout-effect.js +18 -0
  219. package/src/view/use-previous-ref.js +14 -0
  220. package/src/view/use-required-context.js +9 -0
  221. package/src/view/use-sensor-marshal/closest.js +50 -0
  222. package/src/view/use-sensor-marshal/find-closest-draggable-id-from-event.js +50 -0
  223. package/src/view/use-sensor-marshal/index.js +5 -0
  224. package/src/view/use-sensor-marshal/is-event-in-interactive-element.js +66 -0
  225. package/src/view/use-sensor-marshal/lock.js +48 -0
  226. package/src/view/use-sensor-marshal/sensors/use-keyboard-sensor.js +243 -0
  227. package/src/view/use-sensor-marshal/sensors/use-mouse-sensor.js +386 -0
  228. package/src/view/use-sensor-marshal/sensors/use-touch-sensor.js +461 -0
  229. package/src/view/use-sensor-marshal/sensors/util/prevent-standard-key-events.js +19 -0
  230. package/src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name.js +29 -0
  231. package/src/view/use-sensor-marshal/use-sensor-marshal.js +495 -0
  232. package/src/view/use-sensor-marshal/use-validate-sensor-hooks.js +20 -0
  233. package/src/view/use-style-marshal/get-styles.js +170 -0
  234. package/src/view/use-style-marshal/index.js +2 -0
  235. package/src/view/use-style-marshal/style-marshal-types.js +8 -0
  236. package/src/view/use-style-marshal/use-style-marshal.js +126 -0
  237. package/src/view/use-unique-id.js +25 -0
  238. package/src/view/visually-hidden-style.js +16 -0
  239. package/src/view/window/get-max-window-scroll.js +19 -0
  240. package/src/view/window/get-viewport.js +49 -0
  241. package/src/view/window/get-window-from-el.js +3 -0
  242. package/src/view/window/get-window-scroll.js +30 -0
  243. package/src/view/window/scroll-window.js +7 -0
@@ -0,0 +1,120 @@
1
+ // @flow
2
+ import type { Position } from 'css-box-model';
3
+ import type {
4
+ DraggableDimension,
5
+ DraggingState,
6
+ ClientPositions,
7
+ PagePositions,
8
+ DragPositions,
9
+ DragImpact,
10
+ Viewport,
11
+ DimensionMap,
12
+ StateWhenUpdatesAllowed,
13
+ DroppableDimensionMap,
14
+ } from '../../../types';
15
+ import getDragImpact from '../../get-drag-impact';
16
+ import { add, subtract } from '../../position';
17
+ import recomputePlaceholders from '../../recompute-placeholders';
18
+
19
+ type Args = {|
20
+ state: StateWhenUpdatesAllowed,
21
+ clientSelection?: Position,
22
+ dimensions?: DimensionMap,
23
+ viewport?: Viewport,
24
+ // force a custom drag impact
25
+ impact?: ?DragImpact,
26
+ // provide a scroll jump request (optionally provided - and can be null)
27
+ scrollJumpRequest?: ?Position,
28
+ |};
29
+
30
+ export default ({
31
+ state,
32
+ clientSelection: forcedClientSelection,
33
+ dimensions: forcedDimensions,
34
+ viewport: forcedViewport,
35
+ impact: forcedImpact,
36
+ scrollJumpRequest,
37
+ }: Args): StateWhenUpdatesAllowed => {
38
+ // DRAGGING: can update position and impact
39
+ // COLLECTING: can update position but cannot update impact
40
+
41
+ const viewport: Viewport = forcedViewport || state.viewport;
42
+ const dimensions: DimensionMap = forcedDimensions || state.dimensions;
43
+ const clientSelection: Position =
44
+ forcedClientSelection || state.current.client.selection;
45
+
46
+ const offset: Position = subtract(
47
+ clientSelection,
48
+ state.initial.client.selection,
49
+ );
50
+
51
+ const client: ClientPositions = {
52
+ offset,
53
+ selection: clientSelection,
54
+ borderBoxCenter: add(state.initial.client.borderBoxCenter, offset),
55
+ };
56
+
57
+ const page: PagePositions = {
58
+ selection: add(client.selection, viewport.scroll.current),
59
+ borderBoxCenter: add(client.borderBoxCenter, viewport.scroll.current),
60
+ offset: add(client.offset, viewport.scroll.diff.value),
61
+ };
62
+
63
+ const current: DragPositions = {
64
+ client,
65
+ page,
66
+ };
67
+
68
+ // Not updating impact while bulk collecting
69
+ if (state.phase === 'COLLECTING') {
70
+ return {
71
+ // adding phase to appease flow (even though it will be overwritten by spread)
72
+ phase: 'COLLECTING',
73
+ ...state,
74
+ dimensions,
75
+ viewport,
76
+ current,
77
+ };
78
+ }
79
+
80
+ const draggable: DraggableDimension =
81
+ dimensions.draggables[state.critical.draggable.id];
82
+
83
+ const newImpact: DragImpact =
84
+ forcedImpact ||
85
+ getDragImpact({
86
+ pageOffset: page.offset,
87
+ draggable,
88
+ draggables: dimensions.draggables,
89
+ droppables: dimensions.droppables,
90
+ previousImpact: state.impact,
91
+ viewport,
92
+ afterCritical: state.afterCritical,
93
+ });
94
+
95
+ const withUpdatedPlaceholders: DroppableDimensionMap = recomputePlaceholders({
96
+ draggable,
97
+ impact: newImpact,
98
+ previousImpact: state.impact,
99
+ draggables: dimensions.draggables,
100
+ droppables: dimensions.droppables,
101
+ });
102
+ // dragging!
103
+ const result: DraggingState = {
104
+ ...state,
105
+ current,
106
+ dimensions: {
107
+ draggables: dimensions.draggables,
108
+ droppables: withUpdatedPlaceholders,
109
+ },
110
+ impact: newImpact,
111
+ viewport,
112
+ scrollJumpRequest: scrollJumpRequest || null,
113
+ // client updates can be applied as a part of a jump scroll
114
+ // this can be to immediately reverse movement to allow for a nice animation
115
+ // into the final position
116
+ forceShouldAnimate: scrollJumpRequest ? false : null,
117
+ };
118
+
119
+ return result;
120
+ };
@@ -0,0 +1,58 @@
1
+ // @flow
2
+ import { type Position } from 'css-box-model';
3
+ import type {
4
+ Viewport,
5
+ DraggableDimension,
6
+ DroppableDimension,
7
+ Scrollable,
8
+ DroppableDimensionMap,
9
+ DroppableId,
10
+ } from '../../types';
11
+ import { add } from '../position';
12
+ import offsetDraggable from './offset-draggable';
13
+ import getFrame from '../get-frame';
14
+
15
+ type Args = {|
16
+ additions: DraggableDimension[],
17
+ updatedDroppables: DroppableDimensionMap,
18
+ viewport: Viewport,
19
+ |};
20
+
21
+ export default ({
22
+ additions,
23
+ updatedDroppables,
24
+ viewport,
25
+ }: Args): DraggableDimension[] => {
26
+ // We need to adjust collected draggables so that they
27
+ // match the model we had when the drag started.
28
+ // When a draggable is dynamically collected it does not have
29
+ // the same relative client position. We need to unwind
30
+ // any changes in window scroll and droppable scroll so that
31
+ // the newly collected draggables fit in with our other draggables
32
+ // and give the same dimensions that would have had if they were
33
+ // collected at the start of the drag.
34
+
35
+ // Need to undo the displacement caused by window scroll changes
36
+ const windowScrollChange: Position = viewport.scroll.diff.value;
37
+ // These modified droppables have already had their scroll changes correctly updated
38
+
39
+ return additions.map((draggable: DraggableDimension): DraggableDimension => {
40
+ const droppableId: DroppableId = draggable.descriptor.droppableId;
41
+ const modified: DroppableDimension = updatedDroppables[droppableId];
42
+ const frame: Scrollable = getFrame(modified);
43
+ const droppableScrollChange: Position = frame.scroll.diff.value;
44
+
45
+ const totalChange: Position = add(
46
+ windowScrollChange,
47
+ droppableScrollChange,
48
+ );
49
+
50
+ const moved: DraggableDimension = offsetDraggable({
51
+ draggable,
52
+ offset: totalChange,
53
+ initialWindowScroll: viewport.scroll.initial,
54
+ });
55
+
56
+ return moved;
57
+ });
58
+ };
@@ -0,0 +1,158 @@
1
+ // @flow
2
+ import type {
3
+ DimensionMap,
4
+ DraggingState,
5
+ CollectingState,
6
+ DropPendingState,
7
+ Published,
8
+ DraggableId,
9
+ DraggableDimension,
10
+ DroppableDimensionMap,
11
+ DraggableDimensionMap,
12
+ DroppableDimension,
13
+ DragImpact,
14
+ DroppablePublish,
15
+ DroppableId,
16
+ } from '../../types';
17
+ import * as timings from '../../debug/timings';
18
+ import getDragImpact from '../get-drag-impact';
19
+ import adjustAdditionsForScrollChanges from './adjust-additions-for-scroll-changes';
20
+ import { toDraggableMap, toDroppableMap } from '../dimension-structures';
21
+ import getLiftEffect from '../get-lift-effect';
22
+ import scrollDroppable from '../droppable/scroll-droppable';
23
+ import whatIsDraggedOver from '../droppable/what-is-dragged-over';
24
+
25
+ type Args = {|
26
+ state: CollectingState | DropPendingState,
27
+ published: Published,
28
+ |};
29
+
30
+ const timingsKey: string = 'Processing dynamic changes';
31
+
32
+ export default ({
33
+ state,
34
+ published,
35
+ }: Args): DraggingState | DropPendingState => {
36
+ timings.start(timingsKey);
37
+
38
+ // TODO: update window scroll (needs to be a part of the published object)
39
+ // TODO: validate.
40
+ // - Check that all additions / removals have a droppable
41
+ // - Check that all droppables are virtual
42
+
43
+ // The scroll might be different to what is currently in the state
44
+ // We want to ensure the new draggables are in step with the state
45
+ const withScrollChange: DroppableDimension[] = published.modified.map(
46
+ (update: DroppablePublish): DroppableDimension => {
47
+ const existing: DroppableDimension =
48
+ state.dimensions.droppables[update.droppableId];
49
+
50
+ const scrolled: DroppableDimension = scrollDroppable(
51
+ existing,
52
+ update.scroll,
53
+ );
54
+ return scrolled;
55
+ },
56
+ );
57
+
58
+ const droppables: DroppableDimensionMap = {
59
+ ...state.dimensions.droppables,
60
+ ...toDroppableMap(withScrollChange),
61
+ };
62
+
63
+ const updatedAdditions: DraggableDimensionMap = toDraggableMap(
64
+ adjustAdditionsForScrollChanges({
65
+ additions: published.additions,
66
+ updatedDroppables: droppables,
67
+ viewport: state.viewport,
68
+ }),
69
+ );
70
+
71
+ const draggables: DraggableDimensionMap = {
72
+ ...state.dimensions.draggables,
73
+ ...updatedAdditions,
74
+ };
75
+
76
+ // remove all the old ones (except for the critical)
77
+ // we do this so that list operations remain fast
78
+ // TODO: need to test the impact of this like crazy
79
+ published.removals.forEach((id: DraggableId) => {
80
+ delete draggables[id];
81
+ });
82
+
83
+ const dimensions: DimensionMap = {
84
+ droppables,
85
+ draggables,
86
+ };
87
+
88
+ const wasOverId: ?DroppableId = whatIsDraggedOver(state.impact);
89
+ const wasOver: ?DroppableDimension = wasOverId
90
+ ? dimensions.droppables[wasOverId]
91
+ : null;
92
+
93
+ const draggable: DraggableDimension =
94
+ dimensions.draggables[state.critical.draggable.id];
95
+ const home: DroppableDimension =
96
+ dimensions.droppables[state.critical.droppable.id];
97
+
98
+ const { impact: onLiftImpact, afterCritical } = getLiftEffect({
99
+ draggable,
100
+ home,
101
+ draggables,
102
+ viewport: state.viewport,
103
+ });
104
+
105
+ const previousImpact: DragImpact =
106
+ wasOver && wasOver.isCombineEnabled
107
+ ? // Cheating here
108
+ // TODO: pursue a more robust approach
109
+ state.impact
110
+ : onLiftImpact;
111
+
112
+ const impact: DragImpact = getDragImpact({
113
+ pageOffset: state.current.page.offset,
114
+ draggable: dimensions.draggables[state.critical.draggable.id],
115
+ draggables: dimensions.draggables,
116
+ droppables: dimensions.droppables,
117
+ previousImpact,
118
+ viewport: state.viewport,
119
+ afterCritical,
120
+ });
121
+
122
+ timings.finish(timingsKey);
123
+
124
+ const draggingState: DraggingState = {
125
+ // appeasing flow
126
+ phase: 'DRAGGING',
127
+ ...state,
128
+ // eslint-disable-next-line
129
+ phase: 'DRAGGING',
130
+ impact,
131
+ onLiftImpact,
132
+ dimensions,
133
+ afterCritical,
134
+ // not animating this movement
135
+ forceShouldAnimate: false,
136
+ };
137
+
138
+ if (state.phase === 'COLLECTING') {
139
+ return draggingState;
140
+ }
141
+
142
+ // There was a DROP_PENDING
143
+ // Staying in the DROP_PENDING phase
144
+ // setting isWaiting for false
145
+
146
+ const dropPending: DropPendingState = {
147
+ // appeasing flow
148
+ phase: 'DROP_PENDING',
149
+ ...draggingState,
150
+ // eslint-disable-next-line
151
+ phase: 'DROP_PENDING',
152
+ // No longer waiting
153
+ reason: state.reason,
154
+ isWaiting: false,
155
+ };
156
+
157
+ return dropPending;
158
+ };
@@ -0,0 +1,35 @@
1
+ // @flow
2
+ import {
3
+ withScroll,
4
+ offset as offsetBox,
5
+ type Position,
6
+ type BoxModel,
7
+ } from 'css-box-model';
8
+ import type { DraggableDimension } from '../../types';
9
+
10
+ type Args = {|
11
+ draggable: DraggableDimension,
12
+ offset: Position,
13
+ initialWindowScroll: Position,
14
+ |};
15
+
16
+ export default ({
17
+ draggable,
18
+ offset,
19
+ initialWindowScroll,
20
+ }: Args): DraggableDimension => {
21
+ const client: BoxModel = offsetBox(draggable.client, offset);
22
+ const page: BoxModel = withScroll(client, initialWindowScroll);
23
+
24
+ const moved: DraggableDimension = {
25
+ ...draggable,
26
+ placeholder: {
27
+ ...draggable.placeholder,
28
+ client,
29
+ },
30
+ client,
31
+ page,
32
+ };
33
+
34
+ return moved;
35
+ };
@@ -0,0 +1,99 @@
1
+ // @flow
2
+ import {
3
+ addPlaceholder,
4
+ removePlaceholder,
5
+ } from './droppable/with-placeholder';
6
+ import whatIsDraggedOver from './droppable/what-is-dragged-over';
7
+ import type {
8
+ DroppableDimension,
9
+ DraggableDimensionMap,
10
+ DroppableDimensionMap,
11
+ DraggableDimension,
12
+ DragImpact,
13
+ DroppableId,
14
+ } from '../types';
15
+ import patchDroppableMap from './patch-droppable-map';
16
+ import isHomeOf from './droppable/is-home-of';
17
+
18
+ type ClearArgs = {|
19
+ previousImpact: DragImpact,
20
+ impact: DragImpact,
21
+ droppables: DroppableDimensionMap,
22
+ |};
23
+
24
+ const clearUnusedPlaceholder = ({
25
+ previousImpact,
26
+ impact,
27
+ droppables,
28
+ }: ClearArgs): DroppableDimensionMap => {
29
+ const last: ?DroppableId = whatIsDraggedOver(previousImpact);
30
+ const now: ?DroppableId = whatIsDraggedOver(impact);
31
+
32
+ if (!last) {
33
+ return droppables;
34
+ }
35
+
36
+ // no change - can keep the last state
37
+ if (last === now) {
38
+ return droppables;
39
+ }
40
+
41
+ const lastDroppable: DroppableDimension = droppables[last];
42
+
43
+ // nothing to clear
44
+ if (!lastDroppable.subject.withPlaceholder) {
45
+ return droppables;
46
+ }
47
+
48
+ const updated: DroppableDimension = removePlaceholder(lastDroppable);
49
+ return patchDroppableMap(droppables, updated);
50
+ };
51
+
52
+ type Args = {|
53
+ draggable: DraggableDimension,
54
+ draggables: DraggableDimensionMap,
55
+ droppables: DroppableDimensionMap,
56
+ impact: DragImpact,
57
+ previousImpact: DragImpact,
58
+ |};
59
+
60
+ export default ({
61
+ draggable,
62
+ draggables,
63
+ droppables,
64
+ previousImpact,
65
+ impact,
66
+ }: Args): DroppableDimensionMap => {
67
+ const cleaned: DroppableDimensionMap = clearUnusedPlaceholder({
68
+ previousImpact,
69
+ impact,
70
+ droppables,
71
+ });
72
+
73
+ const isOver: ?DroppableId = whatIsDraggedOver(impact);
74
+
75
+ if (!isOver) {
76
+ return cleaned;
77
+ }
78
+
79
+ const droppable: DroppableDimension = droppables[isOver];
80
+
81
+ // no need to add additional space to home droppable
82
+ if (isHomeOf(draggable, droppable)) {
83
+ return cleaned;
84
+ }
85
+
86
+ // already have a placeholder - nothing to do here!
87
+ if (droppable.subject.withPlaceholder) {
88
+ return cleaned;
89
+ }
90
+
91
+ // Need to patch the existing droppable
92
+ const patched: DroppableDimension = addPlaceholder(
93
+ droppable,
94
+ draggable,
95
+ draggables,
96
+ );
97
+
98
+ return patchDroppableMap(cleaned, patched);
99
+ };
@@ -0,0 +1,7 @@
1
+ // @flow
2
+ import { getRect } from 'css-box-model';
3
+ import type { Rect, Position } from 'css-box-model';
4
+ import { offsetByPosition } from './spacing';
5
+
6
+ export const offsetRectByPosition = (rect: Rect, point: Position): Rect =>
7
+ getRect(offsetByPosition(rect, point));