@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,328 @@
1
+ // @flow
2
+ import type { Position } from 'css-box-model';
3
+ import type {
4
+ Critical,
5
+ DraggableId,
6
+ DroppableId,
7
+ CompletedDrag,
8
+ MovementMode,
9
+ Viewport,
10
+ DimensionMap,
11
+ DropReason,
12
+ Published,
13
+ } from '../types';
14
+
15
+ export type BeforeInitialCaptureArgs = {|
16
+ draggableId: DraggableId,
17
+ movementMode: MovementMode,
18
+ |};
19
+
20
+ export type BeforeInitialCaptureAction = {|
21
+ type: 'BEFORE_INITIAL_CAPTURE',
22
+ payload: BeforeInitialCaptureArgs,
23
+ |};
24
+
25
+ export const beforeInitialCapture = (
26
+ args: BeforeInitialCaptureArgs,
27
+ ): BeforeInitialCaptureAction => ({
28
+ type: 'BEFORE_INITIAL_CAPTURE',
29
+ payload: args,
30
+ });
31
+
32
+ export type LiftArgs = {|
33
+ // lifting with DraggableId rather than descriptor
34
+ // as the descriptor might change after a drop is flushed
35
+ id: DraggableId,
36
+ clientSelection: Position,
37
+ movementMode: MovementMode,
38
+ |};
39
+
40
+ export type LiftAction = {|
41
+ type: 'LIFT',
42
+ payload: LiftArgs,
43
+ |};
44
+
45
+ export const lift = (args: LiftArgs): LiftAction => ({
46
+ type: 'LIFT',
47
+ payload: args,
48
+ });
49
+
50
+ export type InitialPublishArgs = {|
51
+ critical: Critical,
52
+ dimensions: DimensionMap,
53
+ clientSelection: Position,
54
+ viewport: Viewport,
55
+ movementMode: MovementMode,
56
+ |};
57
+
58
+ export type InitialPublishAction = {|
59
+ type: 'INITIAL_PUBLISH',
60
+ payload: InitialPublishArgs,
61
+ |};
62
+
63
+ export const initialPublish = (
64
+ args: InitialPublishArgs,
65
+ ): InitialPublishAction => ({
66
+ type: 'INITIAL_PUBLISH',
67
+ payload: args,
68
+ });
69
+
70
+ export type WhileDraggingPublishAction = {|
71
+ type: 'PUBLISH_WHILE_DRAGGING',
72
+ payload: Published,
73
+ |};
74
+
75
+ export const publishWhileDragging = (
76
+ args: Published,
77
+ ): WhileDraggingPublishAction => ({
78
+ type: 'PUBLISH_WHILE_DRAGGING',
79
+ payload: args,
80
+ });
81
+
82
+ export type CollectionStartingAction = {|
83
+ type: 'COLLECTION_STARTING',
84
+ payload: null,
85
+ |};
86
+
87
+ export const collectionStarting = (): CollectionStartingAction => ({
88
+ type: 'COLLECTION_STARTING',
89
+ payload: null,
90
+ });
91
+
92
+ export type UpdateDroppableScrollArgs = {
93
+ id: DroppableId,
94
+ newScroll: Position,
95
+ };
96
+
97
+ export type UpdateDroppableScrollAction = {|
98
+ type: 'UPDATE_DROPPABLE_SCROLL',
99
+ payload: UpdateDroppableScrollArgs,
100
+ |};
101
+
102
+ export const updateDroppableScroll = (
103
+ args: UpdateDroppableScrollArgs,
104
+ ): UpdateDroppableScrollAction => ({
105
+ type: 'UPDATE_DROPPABLE_SCROLL',
106
+ payload: args,
107
+ });
108
+
109
+ export type UpdateDroppableIsEnabledArgs = {|
110
+ id: DroppableId,
111
+ isEnabled: boolean,
112
+ |};
113
+
114
+ export type UpdateDroppableIsEnabledAction = {|
115
+ type: 'UPDATE_DROPPABLE_IS_ENABLED',
116
+ payload: UpdateDroppableIsEnabledArgs,
117
+ |};
118
+
119
+ export const updateDroppableIsEnabled = (
120
+ args: UpdateDroppableIsEnabledArgs,
121
+ ): UpdateDroppableIsEnabledAction => ({
122
+ type: 'UPDATE_DROPPABLE_IS_ENABLED',
123
+ payload: args,
124
+ });
125
+
126
+ export type UpdateDroppableIsCombineEnabledArgs = {|
127
+ id: DroppableId,
128
+ isCombineEnabled: boolean,
129
+ |};
130
+
131
+ export type UpdateDroppableIsCombineEnabledAction = {|
132
+ type: 'UPDATE_DROPPABLE_IS_COMBINE_ENABLED',
133
+ payload: UpdateDroppableIsCombineEnabledArgs,
134
+ |};
135
+
136
+ export const updateDroppableIsCombineEnabled = (
137
+ args: UpdateDroppableIsCombineEnabledArgs,
138
+ ): UpdateDroppableIsCombineEnabledAction => ({
139
+ type: 'UPDATE_DROPPABLE_IS_COMBINE_ENABLED',
140
+ payload: args,
141
+ });
142
+
143
+ export type MoveArgs = {|
144
+ client: Position,
145
+ |};
146
+
147
+ export type MoveAction = {|
148
+ type: 'MOVE',
149
+ payload: MoveArgs,
150
+ |};
151
+
152
+ export const move = (args: MoveArgs): MoveAction => ({
153
+ type: 'MOVE',
154
+ payload: args,
155
+ });
156
+
157
+ type MoveByWindowScrollArgs = {|
158
+ newScroll: Position,
159
+ |};
160
+
161
+ export type MoveByWindowScrollAction = {|
162
+ type: 'MOVE_BY_WINDOW_SCROLL',
163
+ payload: MoveByWindowScrollArgs,
164
+ |};
165
+
166
+ export const moveByWindowScroll = (
167
+ args: MoveByWindowScrollArgs,
168
+ ): MoveByWindowScrollAction => ({
169
+ type: 'MOVE_BY_WINDOW_SCROLL',
170
+ payload: args,
171
+ });
172
+
173
+ export type UpdateViewportMaxScrollArgs = {|
174
+ maxScroll: Position,
175
+ |};
176
+
177
+ type UpdateViewportMaxScrollAction = {|
178
+ type: 'UPDATE_VIEWPORT_MAX_SCROLL',
179
+ payload: UpdateViewportMaxScrollArgs,
180
+ |};
181
+
182
+ export const updateViewportMaxScroll = (
183
+ args: UpdateViewportMaxScrollArgs,
184
+ ): UpdateViewportMaxScrollAction => ({
185
+ type: 'UPDATE_VIEWPORT_MAX_SCROLL',
186
+ payload: args,
187
+ });
188
+
189
+ export type MoveUpAction = {|
190
+ type: 'MOVE_UP',
191
+ payload: null,
192
+ |};
193
+
194
+ export const moveUp = (): MoveUpAction => ({
195
+ type: 'MOVE_UP',
196
+ payload: null,
197
+ });
198
+
199
+ export type MoveDownAction = {|
200
+ type: 'MOVE_DOWN',
201
+ payload: null,
202
+ |};
203
+
204
+ export const moveDown = (): MoveDownAction => ({
205
+ type: 'MOVE_DOWN',
206
+ payload: null,
207
+ });
208
+
209
+ export type MoveRightAction = {|
210
+ type: 'MOVE_RIGHT',
211
+ payload: null,
212
+ |};
213
+
214
+ export const moveRight = (): MoveRightAction => ({
215
+ type: 'MOVE_RIGHT',
216
+ payload: null,
217
+ });
218
+
219
+ export type MoveLeftAction = {|
220
+ type: 'MOVE_LEFT',
221
+ payload: null,
222
+ |};
223
+
224
+ export const moveLeft = (): MoveLeftAction => ({
225
+ type: 'MOVE_LEFT',
226
+ payload: null,
227
+ });
228
+
229
+ type FlushAction = {|
230
+ type: 'FLUSH',
231
+ payload: null,
232
+ |};
233
+
234
+ export const flush = (): FlushAction => ({
235
+ type: 'FLUSH',
236
+ payload: null,
237
+ });
238
+
239
+ export type AnimateDropArgs = {|
240
+ completed: CompletedDrag,
241
+ newHomeClientOffset: Position,
242
+ dropDuration: number,
243
+ |};
244
+
245
+ export type DropAnimateAction = {
246
+ type: 'DROP_ANIMATE',
247
+ payload: AnimateDropArgs,
248
+ };
249
+
250
+ export const animateDrop = (args: AnimateDropArgs): DropAnimateAction => ({
251
+ type: 'DROP_ANIMATE',
252
+ payload: args,
253
+ });
254
+
255
+ export type DropCompleteArgs = {|
256
+ completed: CompletedDrag,
257
+ |};
258
+
259
+ export type DropCompleteAction = {
260
+ type: 'DROP_COMPLETE',
261
+ payload: DropCompleteArgs,
262
+ };
263
+
264
+ export const completeDrop = (args: DropCompleteArgs): DropCompleteAction => ({
265
+ type: 'DROP_COMPLETE',
266
+ payload: args,
267
+ });
268
+
269
+ type DropArgs = {|
270
+ reason: DropReason,
271
+ |};
272
+
273
+ export type DropAction = {|
274
+ type: 'DROP',
275
+ payload: DropArgs,
276
+ |};
277
+
278
+ export const drop = (args: DropArgs) => ({
279
+ type: 'DROP',
280
+ payload: args,
281
+ });
282
+
283
+ export const cancel = () => drop({ reason: 'CANCEL' });
284
+
285
+ export type DropPendingAction = {|
286
+ type: 'DROP_PENDING',
287
+ payload: DropArgs,
288
+ |};
289
+
290
+ export const dropPending = (args: DropArgs): DropPendingAction => ({
291
+ type: 'DROP_PENDING',
292
+ payload: args,
293
+ });
294
+
295
+ export type DropAnimationFinishedAction = {|
296
+ type: 'DROP_ANIMATION_FINISHED',
297
+ payload: null,
298
+ |};
299
+
300
+ export const dropAnimationFinished = (): DropAnimationFinishedAction => ({
301
+ type: 'DROP_ANIMATION_FINISHED',
302
+ payload: null,
303
+ });
304
+
305
+ export type Action =
306
+ | BeforeInitialCaptureAction
307
+ | LiftAction
308
+ | InitialPublishAction
309
+ | WhileDraggingPublishAction
310
+ | CollectionStartingAction
311
+ | UpdateDroppableScrollAction
312
+ | UpdateDroppableIsEnabledAction
313
+ | UpdateDroppableIsCombineEnabledAction
314
+ | MoveByWindowScrollAction
315
+ | UpdateViewportMaxScrollAction
316
+ // | PostJumpScrollAction
317
+ // | PostSnapDestinationChangeAction
318
+ | MoveAction
319
+ | MoveUpAction
320
+ | MoveDownAction
321
+ | MoveRightAction
322
+ | MoveLeftAction
323
+ | DropPendingAction
324
+ | DropAction
325
+ | DropAnimateAction
326
+ | DropAnimationFinishedAction
327
+ | DropCompleteAction
328
+ | FlushAction;
@@ -0,0 +1,8 @@
1
+ // @flow
2
+ import type { State, DraggingState } from '../../types';
3
+
4
+ export type AutoScroller = {|
5
+ start: (state: DraggingState) => void,
6
+ stop: () => void,
7
+ scroll: (state: State) => void,
8
+ |};
@@ -0,0 +1,160 @@
1
+ // @flow
2
+ import { type Position } from 'css-box-model';
3
+ import { add, apply, isEqual, origin } from '../position';
4
+ import type { DroppableDimension, Viewport, Scrollable } from '../../types';
5
+
6
+ type CanPartiallyScrollArgs = {|
7
+ max: Position,
8
+ current: Position,
9
+ change: Position,
10
+ |};
11
+
12
+ const smallestSigned = apply((value: number) => {
13
+ if (value === 0) {
14
+ return 0;
15
+ }
16
+ return value > 0 ? 1 : -1;
17
+ });
18
+
19
+ type GetRemainderArgs = {|
20
+ current: Position,
21
+ max: Position,
22
+ change: Position,
23
+ |};
24
+
25
+ // We need to figure out how much of the movement
26
+ // cannot be done with a scroll
27
+ export const getOverlap = (() => {
28
+ const getRemainder = (target: number, max: number): number => {
29
+ if (target < 0) {
30
+ return target;
31
+ }
32
+ if (target > max) {
33
+ return target - max;
34
+ }
35
+ return 0;
36
+ };
37
+
38
+ return ({ current, max, change }: GetRemainderArgs): ?Position => {
39
+ const targetScroll: Position = add(current, change);
40
+
41
+ const overlap: Position = {
42
+ x: getRemainder(targetScroll.x, max.x),
43
+ y: getRemainder(targetScroll.y, max.y),
44
+ };
45
+
46
+ if (isEqual(overlap, origin)) {
47
+ return null;
48
+ }
49
+
50
+ return overlap;
51
+ };
52
+ })();
53
+
54
+ export const canPartiallyScroll = ({
55
+ max: rawMax,
56
+ current,
57
+ change,
58
+ }: CanPartiallyScrollArgs): boolean => {
59
+ // It is possible for the max scroll to be greater than the current scroll
60
+ // when there are scrollbars on the cross axis. We adjust for this by
61
+ // increasing the max scroll point if needed
62
+ // This will allow movements backwards even if the current scroll is greater than the max scroll
63
+ const max: Position = {
64
+ x: Math.max(current.x, rawMax.x),
65
+ y: Math.max(current.y, rawMax.y),
66
+ };
67
+
68
+ // Only need to be able to move the smallest amount in the desired direction
69
+ const smallestChange: Position = smallestSigned(change);
70
+
71
+ const overlap: ?Position = getOverlap({
72
+ max,
73
+ current,
74
+ change: smallestChange,
75
+ });
76
+
77
+ // no overlap at all - we can move there!
78
+ if (!overlap) {
79
+ return true;
80
+ }
81
+
82
+ // if there was an x value, but there is no x overlap - then we can scroll on the x!
83
+ if (smallestChange.x !== 0 && overlap.x === 0) {
84
+ return true;
85
+ }
86
+
87
+ // if there was an y value, but there is no y overlap - then we can scroll on the y!
88
+ if (smallestChange.y !== 0 && overlap.y === 0) {
89
+ return true;
90
+ }
91
+
92
+ return false;
93
+ };
94
+
95
+ export const canScrollWindow = (
96
+ viewport: Viewport,
97
+ change: Position,
98
+ ): boolean =>
99
+ canPartiallyScroll({
100
+ current: viewport.scroll.current,
101
+ max: viewport.scroll.max,
102
+ change,
103
+ });
104
+
105
+ export const getWindowOverlap = (
106
+ viewport: Viewport,
107
+ change: Position,
108
+ ): ?Position => {
109
+ if (!canScrollWindow(viewport, change)) {
110
+ return null;
111
+ }
112
+
113
+ const max: Position = viewport.scroll.max;
114
+ const current: Position = viewport.scroll.current;
115
+
116
+ return getOverlap({
117
+ current,
118
+ max,
119
+ change,
120
+ });
121
+ };
122
+
123
+ export const canScrollDroppable = (
124
+ droppable: DroppableDimension,
125
+ change: Position,
126
+ ): boolean => {
127
+ const frame: ?Scrollable = droppable.frame;
128
+
129
+ // Cannot scroll when there is no scrollable
130
+ if (!frame) {
131
+ return false;
132
+ }
133
+
134
+ return canPartiallyScroll({
135
+ current: frame.scroll.current,
136
+ max: frame.scroll.max,
137
+ change,
138
+ });
139
+ };
140
+
141
+ export const getDroppableOverlap = (
142
+ droppable: DroppableDimension,
143
+ change: Position,
144
+ ): ?Position => {
145
+ const frame: ?Scrollable = droppable.frame;
146
+
147
+ if (!frame) {
148
+ return null;
149
+ }
150
+
151
+ if (!canScrollDroppable(droppable, change)) {
152
+ return null;
153
+ }
154
+
155
+ return getOverlap({
156
+ current: frame.scroll.current,
157
+ max: frame.scroll.max,
158
+ change,
159
+ });
160
+ };
@@ -0,0 +1,25 @@
1
+ // @flow
2
+
3
+ // Values used to control how the fluid auto scroll feels
4
+ const config = {
5
+ // percentage distance from edge of container:
6
+ startFromPercentage: 0.25,
7
+ maxScrollAtPercentage: 0.05,
8
+ // pixels per frame
9
+ maxPixelScroll: 28,
10
+
11
+ // A function used to ease a percentage value
12
+ // A simple linear function would be: (percentage) => percentage;
13
+ // percentage is between 0 and 1
14
+ // result must be between 0 and 1
15
+ ease: (percentage: number): number => Math.pow(percentage, 2),
16
+
17
+ durationDampening: {
18
+ // ms: how long to dampen the speed of an auto scroll from the start of a drag
19
+ stopDampeningAt: 1200,
20
+ // ms: when to start accelerating the reduction of duration dampening
21
+ accelerateAt: 360,
22
+ },
23
+ };
24
+
25
+ export default config;
@@ -0,0 +1,77 @@
1
+ // @flow
2
+ import memoizeOne from 'memoize-one';
3
+ import { type Position } from 'css-box-model';
4
+ import type {
5
+ DroppableDimension,
6
+ DroppableDimensionMap,
7
+ DroppableId,
8
+ } from '../../../types';
9
+ import { invariant } from '../../../invariant';
10
+ import isPositionInFrame from '../../visibility/is-position-in-frame';
11
+ import { toDroppableList } from '../../dimension-structures';
12
+ import { find } from '../../../native-with-fallback';
13
+
14
+ const getScrollableDroppables = memoizeOne(
15
+ (droppables: DroppableDimensionMap): DroppableDimension[] =>
16
+ toDroppableList(droppables).filter(
17
+ (droppable: DroppableDimension): boolean => {
18
+ // exclude disabled droppables
19
+ if (!droppable.isEnabled) {
20
+ return false;
21
+ }
22
+
23
+ // only want droppables that are scrollable
24
+ if (!droppable.frame) {
25
+ return false;
26
+ }
27
+
28
+ return true;
29
+ },
30
+ ),
31
+ );
32
+
33
+ const getScrollableDroppableOver = (
34
+ target: Position,
35
+ droppables: DroppableDimensionMap,
36
+ ): ?DroppableDimension => {
37
+ const maybe: ?DroppableDimension = find(
38
+ getScrollableDroppables(droppables),
39
+ (droppable: DroppableDimension): boolean => {
40
+ invariant(droppable.frame, 'Invalid result');
41
+ return isPositionInFrame(droppable.frame.pageMarginBox)(target);
42
+ },
43
+ );
44
+
45
+ return maybe;
46
+ };
47
+
48
+ type Api = {|
49
+ center: Position,
50
+ destination: ?DroppableId,
51
+ droppables: DroppableDimensionMap,
52
+ |};
53
+
54
+ export default ({
55
+ center,
56
+ destination,
57
+ droppables,
58
+ }: Api): ?DroppableDimension => {
59
+ // We need to scroll the best droppable frame we can so that the
60
+ // placeholder buffer logic works correctly
61
+
62
+ if (destination) {
63
+ const dimension: DroppableDimension = droppables[destination];
64
+ if (!dimension.frame) {
65
+ return null;
66
+ }
67
+ return dimension;
68
+ }
69
+
70
+ // 2. If we are not over a droppable - are we over a droppable frame?
71
+ const dimension: ?DroppableDimension = getScrollableDroppableOver(
72
+ center,
73
+ droppables,
74
+ );
75
+
76
+ return dimension;
77
+ };
@@ -0,0 +1,50 @@
1
+ // @flow
2
+ import type { Position, Rect } from 'css-box-model';
3
+ import type {
4
+ DroppableDimension,
5
+ FluidScrollerOptions,
6
+ Scrollable,
7
+ } from '../../../types';
8
+ import getScroll from './get-scroll';
9
+ import { canScrollDroppable } from '../can-scroll';
10
+
11
+ type Args = {|
12
+ droppable: DroppableDimension,
13
+ subject: Rect,
14
+ center: Position,
15
+ centerInitial: Position,
16
+ dragStartTime: number,
17
+ shouldUseTimeDampening: boolean,
18
+ fluidScrollerOptions?: FluidScrollerOptions,
19
+ |};
20
+
21
+ export default ({
22
+ droppable,
23
+ subject,
24
+ center,
25
+ centerInitial,
26
+ dragStartTime,
27
+ shouldUseTimeDampening,
28
+ fluidScrollerOptions,
29
+ }: Args): ?Position => {
30
+ // We know this has a closestScrollable
31
+ const frame: ?Scrollable = droppable.frame;
32
+
33
+ // this should never happen - just being safe
34
+ if (!frame) {
35
+ return null;
36
+ }
37
+
38
+ const scroll: ?Position = getScroll({
39
+ dragStartTime,
40
+ container: frame.pageMarginBox,
41
+ containerScroll: frame.scroll,
42
+ subject,
43
+ center,
44
+ centerInitial,
45
+ shouldUseTimeDampening,
46
+ fluidScrollerOptions,
47
+ });
48
+
49
+ return scroll && canScrollDroppable(droppable, scroll) ? scroll : null;
50
+ };
@@ -0,0 +1,25 @@
1
+ // @flow
2
+ import { warning } from '../../../dev-warning';
3
+
4
+ type Args = {|
5
+ startOfRange: number,
6
+ endOfRange: number,
7
+ current: number,
8
+ |};
9
+
10
+ export default ({ startOfRange, endOfRange, current }: Args): number => {
11
+ const range: number = endOfRange - startOfRange;
12
+
13
+ if (range === 0) {
14
+ warning(`
15
+ Detected distance range of 0 in the fluid auto scroller
16
+ This is unexpected and would cause a divide by 0 issue.
17
+ Not allowing an auto scroll
18
+ `);
19
+ return 0;
20
+ }
21
+
22
+ const currentInRange: number = current - startOfRange;
23
+ const percentage: number = currentInRange / range;
24
+ return percentage;
25
+ };
@@ -0,0 +1,30 @@
1
+ // @flow
2
+ import type { Rect, Position } from 'css-box-model';
3
+
4
+ type Args = {|
5
+ container: Rect,
6
+ subject: Rect,
7
+ proposedScroll: Position,
8
+ |};
9
+
10
+ export default ({ container, subject, proposedScroll }: Args): ?Position => {
11
+ const isTooBigVertically: boolean = subject.height > container.height;
12
+ const isTooBigHorizontally: boolean = subject.width > container.width;
13
+
14
+ // not too big on any axis
15
+ if (!isTooBigHorizontally && !isTooBigVertically) {
16
+ return proposedScroll;
17
+ }
18
+
19
+ // too big on both axis
20
+ if (isTooBigHorizontally && isTooBigVertically) {
21
+ return null;
22
+ }
23
+
24
+ // Only too big on one axis
25
+ // Exclude the axis that we cannot scroll on
26
+ return {
27
+ x: isTooBigHorizontally ? 0 : proposedScroll.x,
28
+ y: isTooBigVertically ? 0 : proposedScroll.y,
29
+ };
30
+ };