@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
package/src/types.js ADDED
@@ -0,0 +1,542 @@
1
+ // @flow
2
+ import type { BoxModel, Rect, Position, Spacing } from 'css-box-model';
3
+
4
+ export type Id = string;
5
+ export type DraggableId = Id;
6
+ export type DroppableId = Id;
7
+ export type TypeId = Id;
8
+ export type ContextId = Id;
9
+ export type ElementId = Id;
10
+
11
+ export type DroppableMode = 'standard' | 'virtual';
12
+ export type DroppableDescriptor = {|
13
+ id: DroppableId,
14
+ type: TypeId,
15
+ mode: DroppableMode,
16
+ |};
17
+
18
+ export type DraggableDescriptor = {|
19
+ id: DraggableId,
20
+ index: number,
21
+ // Inherited from Droppable
22
+ droppableId: DroppableId,
23
+ // This is technically redundant but it avoids
24
+ // needing to look up a parent droppable just to get its type
25
+ type: TypeId,
26
+ |};
27
+
28
+ export type DraggableOptions = {|
29
+ canDragInteractiveElements: boolean,
30
+ shouldRespectForcePress: boolean,
31
+ isEnabled: boolean,
32
+ |};
33
+
34
+ export type Direction = 'horizontal' | 'vertical';
35
+
36
+ export type VerticalAxis = {|
37
+ direction: 'vertical',
38
+ line: 'y',
39
+ start: 'top',
40
+ end: 'bottom',
41
+ size: 'height',
42
+ crossAxisLine: 'x',
43
+ crossAxisStart: 'left',
44
+ crossAxisEnd: 'right',
45
+ crossAxisSize: 'width',
46
+ |};
47
+
48
+ export type HorizontalAxis = {|
49
+ direction: 'horizontal',
50
+ line: 'x',
51
+ start: 'left',
52
+ end: 'right',
53
+ size: 'width',
54
+ crossAxisLine: 'y',
55
+ crossAxisStart: 'top',
56
+ crossAxisEnd: 'bottom',
57
+ crossAxisSize: 'height',
58
+ |};
59
+
60
+ export type Axis = VerticalAxis | HorizontalAxis;
61
+
62
+ export type ScrollSize = {|
63
+ scrollHeight: number,
64
+ scrollWidth: number,
65
+ |};
66
+
67
+ export type ScrollDetails = {|
68
+ initial: Position,
69
+ current: Position,
70
+ // the maximum allowable scroll for the frame
71
+ max: Position,
72
+ diff: {|
73
+ value: Position,
74
+ // The actual displacement as a result of a scroll is in the opposite
75
+ // direction to the scroll itself. When scrolling down items are displaced
76
+ // upwards. This value is the negated version of the 'value'
77
+ displacement: Position,
78
+ |},
79
+ |};
80
+
81
+ export type AxisScrollConditions = {|
82
+ inThresholdStart: boolean,
83
+ inThresholdEnd: boolean,
84
+ draggedTowardsStart: boolean,
85
+ draggedTowardsEnd: boolean,
86
+ scrolledTowardsStart: boolean,
87
+ scrolledTowardsEnd: boolean,
88
+ |};
89
+
90
+ export type ScrollConditions = {|
91
+ xAxis: AxisScrollConditions,
92
+ yAxis: AxisScrollConditions,
93
+ |};
94
+
95
+ export type Placeholder = {|
96
+ client: BoxModel,
97
+ tagName: string,
98
+ display: string,
99
+ |};
100
+
101
+ export type DraggableDimension = {|
102
+ descriptor: DraggableDescriptor,
103
+ // the placeholder for the draggable
104
+ placeholder: Placeholder,
105
+ // relative to the viewport when the drag started
106
+ client: BoxModel,
107
+ // relative to the whole page
108
+ page: BoxModel,
109
+ // how much displacement the draggable causes
110
+ // this is the size of the marginBox
111
+ displaceBy: Position,
112
+ |};
113
+
114
+ export type Scrollable = {|
115
+ // This is the window through which the droppable is observed
116
+ // It does not change during a drag
117
+ pageMarginBox: Rect,
118
+ // Used for comparision with dynamic recollecting
119
+ frameClient: BoxModel,
120
+ scrollSize: ScrollSize,
121
+ // Whether or not we should clip the subject by the frame
122
+ // Is controlled by the ignoreContainerClipping prop
123
+ shouldClipSubject: boolean,
124
+ scroll: ScrollDetails,
125
+ |};
126
+
127
+ export type PlaceholderInSubject = {|
128
+ // might not actually be increased by
129
+ // placeholder if there is no required space
130
+ increasedBy: ?Position,
131
+ placeholderSize: Position,
132
+ // max scroll before placeholder added
133
+ // will be null if there was no frame
134
+ oldFrameMaxScroll: ?Position,
135
+ |};
136
+
137
+ export type DroppableSubject = {|
138
+ // raw, unchanging
139
+ page: BoxModel,
140
+ withPlaceholder: ?PlaceholderInSubject,
141
+ // The hitbox for a droppable
142
+ // - page margin box
143
+ // - with scroll changes
144
+ // - with any additional droppable placeholder
145
+ // - clipped by frame
146
+ // The subject will be null if the hit area is completely empty
147
+ active: ?Rect,
148
+ |};
149
+
150
+ export type DroppableDimension = {|
151
+ descriptor: DroppableDescriptor,
152
+ axis: Axis,
153
+ isEnabled: boolean,
154
+ isCombineEnabled: boolean,
155
+ // relative to the current viewport
156
+ client: BoxModel,
157
+ // relative to the whole page
158
+ isFixedOnPage: boolean,
159
+ // relative to the page
160
+ page: BoxModel,
161
+ // The container of the droppable
162
+ frame: ?Scrollable,
163
+ // what is visible through the frame
164
+ subject: DroppableSubject,
165
+ |};
166
+ export type DraggableLocation = {|
167
+ droppableId: DroppableId,
168
+ index: number,
169
+ |};
170
+
171
+ export type DraggableIdMap = {
172
+ [id: DraggableId]: true,
173
+ };
174
+
175
+ export type DroppableIdMap = {
176
+ [id: DroppableId]: true,
177
+ };
178
+
179
+ export type DraggableDimensionMap = { [key: DraggableId]: DraggableDimension };
180
+ export type DroppableDimensionMap = { [key: DroppableId]: DroppableDimension };
181
+
182
+ export type Displacement = {|
183
+ draggableId: DraggableId,
184
+ shouldAnimate: boolean,
185
+ |};
186
+
187
+ export type DisplacementMap = { [key: DraggableId]: Displacement };
188
+
189
+ export type DisplacedBy = {|
190
+ value: number,
191
+ point: Position,
192
+ |};
193
+
194
+ export type Combine = {|
195
+ draggableId: DraggableId,
196
+ droppableId: DroppableId,
197
+ |};
198
+ export type DisplacementGroups = {|
199
+ all: DraggableId[],
200
+ visible: DisplacementMap,
201
+ invisible: DraggableIdMap,
202
+ |};
203
+
204
+ export type ReorderImpact = {|
205
+ type: 'REORDER',
206
+ destination: DraggableLocation,
207
+ |};
208
+
209
+ export type CombineImpact = {|
210
+ type: 'COMBINE',
211
+ combine: Combine,
212
+ |};
213
+
214
+ export type ImpactLocation = ReorderImpact | CombineImpact;
215
+
216
+ export type Displaced = {|
217
+ forwards: DisplacementGroups,
218
+ backwards: DisplacementGroups,
219
+ |};
220
+
221
+ export type DragImpact = {|
222
+ displaced: DisplacementGroups,
223
+ displacedBy: DisplacedBy,
224
+ at: ?ImpactLocation,
225
+ |};
226
+
227
+ export type ClientPositions = {|
228
+ // where the user initially selected
229
+ // This point is not used to calculate the impact of a dragging item
230
+ // It is used to calculate the offset from the initial selection point
231
+ selection: Position,
232
+ // the current center of the item
233
+ borderBoxCenter: Position,
234
+ // how far the item has moved from its original position
235
+ offset: Position,
236
+ |};
237
+
238
+ export type PagePositions = {|
239
+ selection: Position,
240
+ borderBoxCenter: Position,
241
+ // how much the page position has changed from the initial
242
+ offset: Position,
243
+ |};
244
+
245
+ // There are two seperate modes that a drag can be in
246
+ // FLUID: everything is done in response to highly granular input (eg mouse)
247
+ // SNAP: items move in response to commands (eg keyboard);
248
+ export type MovementMode = 'FLUID' | 'SNAP';
249
+
250
+ export type DragPositions = {|
251
+ client: ClientPositions,
252
+ page: PagePositions,
253
+ |};
254
+
255
+ export type DraggableRubric = {|
256
+ draggableId: DraggableId,
257
+ type: TypeId,
258
+ source: DraggableLocation,
259
+ |};
260
+
261
+ // Published in onBeforeCapture
262
+ // We cannot give more information as things might change in the
263
+ // onBeforeCapture responder!
264
+ export type BeforeCapture = {|
265
+ draggableId: DraggableId,
266
+ mode: MovementMode,
267
+ |};
268
+
269
+ // published when a drag starts
270
+ export type DragStart = {|
271
+ ...DraggableRubric,
272
+ mode: MovementMode,
273
+ |};
274
+
275
+ export type DragUpdate = {|
276
+ ...DragStart,
277
+ // may not have any destination (drag to nowhere)
278
+ destination: ?DraggableLocation,
279
+ // populated when a draggable is dragging over another in combine mode
280
+ combine: ?Combine,
281
+ |};
282
+
283
+ export type DropReason = 'DROP' | 'CANCEL';
284
+
285
+ // published when a drag finishes
286
+ export type DropResult = {|
287
+ ...DragUpdate,
288
+ reason: DropReason,
289
+ |};
290
+
291
+ export type ScrollOptions = {|
292
+ shouldPublishImmediately: boolean,
293
+ |};
294
+
295
+ // all in pixels
296
+ export type DistanceThresholds = {|
297
+ startScrollingFrom: number,
298
+ maxScrollValueAt: number,
299
+ |};
300
+
301
+ // all in ms
302
+ export type DurationDampening = {|
303
+ stopDampeningAt?: number,
304
+ accelerateAt?: number,
305
+ |};
306
+
307
+ export type FluidScrollerConfigOverride = {|
308
+ // percentage distance from edge of container, decimal
309
+ startFromPercentage?: number,
310
+ maxScrollAtPercentage?: number,
311
+ // pixels per frame
312
+ ease?: (percentage: number) => number,
313
+ maxPixelScroll?: number,
314
+ durationDampening?: DurationDampening,
315
+ |};
316
+
317
+ export type FluidScrollerOptions = {|
318
+ // opt into new autoscroll behavior: if the draggable originates inside a scroll threshold
319
+ // don't autoscroll in that threshold's direction until dragged in that direction
320
+ bufferThresholds?: boolean,
321
+ // the distance required to cause a scroll to occur inside a buffered threshold
322
+ bufferMinScroll?: number,
323
+ configOverride?: FluidScrollerConfigOverride,
324
+ // customize your own fluid scroll logic
325
+ thruGetScroll?: (args: {|
326
+ center: Position,
327
+ centerInitial: Position,
328
+ container: Rect,
329
+ containerScroll: ScrollDetails,
330
+ distanceToEdges: Spacing,
331
+ scroll: Position,
332
+ thresholdsHorizontal: DistanceThresholds,
333
+ thresholdsVertical: DistanceThresholds,
334
+ windowScrollOffset: Position,
335
+ |}) => Position,
336
+ |};
337
+
338
+ // using the draggable id rather than the descriptor as the descriptor
339
+ // may change as a result of the initial flush. This means that the lift
340
+ // descriptor may not be the same as the actual descriptor. To avoid
341
+ // confusion the request is just an id which is looked up
342
+ // in the dimension-marshal post-flush
343
+ // Not including droppableId as it might change in a drop flush
344
+ export type LiftRequest = {|
345
+ draggableId: DraggableId,
346
+ scrollOptions: ScrollOptions,
347
+ |};
348
+
349
+ export type Critical = {|
350
+ draggable: DraggableDescriptor,
351
+ droppable: DroppableDescriptor,
352
+ |};
353
+
354
+ export type Viewport = {|
355
+ // live updates with the latest values
356
+ frame: Rect,
357
+ scroll: ScrollDetails,
358
+ |};
359
+
360
+ export type LiftEffect = {|
361
+ inVirtualList: boolean,
362
+ effected: DraggableIdMap,
363
+ displacedBy: DisplacedBy,
364
+ |};
365
+
366
+ export type DimensionMap = {|
367
+ draggables: DraggableDimensionMap,
368
+ droppables: DroppableDimensionMap,
369
+ |};
370
+
371
+ export type DroppablePublish = {|
372
+ droppableId: DroppableId,
373
+ scroll: Position,
374
+ |};
375
+ export type Published = {|
376
+ additions: DraggableDimension[],
377
+ removals: DraggableId[],
378
+ modified: DroppablePublish[],
379
+ |};
380
+
381
+ export type CompletedDrag = {|
382
+ critical: Critical,
383
+ result: DropResult,
384
+ impact: DragImpact,
385
+ afterCritical: LiftEffect,
386
+ |};
387
+
388
+ export type IdleState = {|
389
+ phase: 'IDLE',
390
+ completed: ?CompletedDrag,
391
+ shouldFlush: boolean,
392
+ |};
393
+
394
+ export type DraggingState = {|
395
+ phase: 'DRAGGING',
396
+ isDragging: true,
397
+ critical: Critical,
398
+ movementMode: MovementMode,
399
+ dimensions: DimensionMap,
400
+ initial: DragPositions,
401
+ current: DragPositions,
402
+ impact: DragImpact,
403
+ viewport: Viewport,
404
+ afterCritical: LiftEffect,
405
+ onLiftImpact: DragImpact,
406
+ // when there is a fixed list we want to opt out of this behaviour
407
+ isWindowScrollAllowed: boolean,
408
+ // if we need to jump the scroll (keyboard dragging)
409
+ scrollJumpRequest: ?Position,
410
+ // whether or not draggable movements should be animated
411
+ forceShouldAnimate: ?boolean,
412
+ |};
413
+
414
+ // While dragging we can enter into a bulk collection phase
415
+ // During this phase no drag updates are permitted.
416
+ // If a drop occurs during this phase, it must wait until it is
417
+ // completed before continuing with the drop
418
+ // TODO: rename to BulkCollectingState
419
+ export type CollectingState = {|
420
+ ...DraggingState,
421
+ phase: 'COLLECTING',
422
+ |};
423
+
424
+ // If a drop action occurs during a bulk collection we need to
425
+ // wait for the collection to finish before performing the drop.
426
+ // This is to ensure that everything has the correct index after
427
+ // a drop
428
+ export type DropPendingState = {|
429
+ ...DraggingState,
430
+ phase: 'DROP_PENDING',
431
+ isWaiting: boolean,
432
+ reason: DropReason,
433
+ |};
434
+
435
+ // An optional phase for animating the drop / cancel if it is needed
436
+ export type DropAnimatingState = {|
437
+ phase: 'DROP_ANIMATING',
438
+ completed: CompletedDrag,
439
+ newHomeClientOffset: Position,
440
+ dropDuration: number,
441
+ // We still need to render placeholders and fix the dimensions of the dragging item
442
+ dimensions: DimensionMap,
443
+ |};
444
+
445
+ export type State =
446
+ | IdleState
447
+ | DraggingState
448
+ | CollectingState
449
+ | DropPendingState
450
+ | DropAnimatingState;
451
+
452
+ export type StateWhenUpdatesAllowed = DraggingState | CollectingState;
453
+
454
+ export type Announce = (message: string) => void;
455
+
456
+ export type InOutAnimationMode = 'none' | 'open' | 'close';
457
+
458
+ export type ResponderProvided = {|
459
+ announce: Announce,
460
+ |};
461
+
462
+ export type OnBeforeCaptureResponder = (before: BeforeCapture) => mixed;
463
+ export type OnBeforeDragStartResponder = (start: DragStart) => mixed;
464
+ export type OnDragStartResponder = (
465
+ start: DragStart,
466
+ provided: ResponderProvided,
467
+ ) => mixed;
468
+ export type OnDragUpdateResponder = (
469
+ update: DragUpdate,
470
+ provided: ResponderProvided,
471
+ ) => mixed;
472
+ export type OnDragEndResponder = (
473
+ result: DropResult,
474
+ provided: ResponderProvided,
475
+ ) => mixed;
476
+
477
+ export type Responders = {|
478
+ onBeforeCapture?: OnBeforeCaptureResponder,
479
+ onBeforeDragStart?: OnBeforeDragStartResponder,
480
+ onDragStart?: OnDragStartResponder,
481
+ onDragUpdate?: OnDragUpdateResponder,
482
+ // always required
483
+ onDragEnd: OnDragEndResponder,
484
+ |};
485
+
486
+ // ## Sensors
487
+ export type StopDragOptions = {|
488
+ shouldBlockNextClick: boolean,
489
+ |};
490
+
491
+ type DragActions = {|
492
+ drop: (args?: StopDragOptions) => void,
493
+ cancel: (args?: StopDragOptions) => void,
494
+ isActive: () => boolean,
495
+ shouldRespectForcePress: () => boolean,
496
+ |};
497
+
498
+ export type FluidDragActions = {|
499
+ ...DragActions,
500
+ move: (clientSelection: Position) => void,
501
+ |};
502
+
503
+ export type SnapDragActions = {|
504
+ ...DragActions,
505
+ moveUp: () => void,
506
+ moveDown: () => void,
507
+ moveRight: () => void,
508
+ moveLeft: () => void,
509
+ |};
510
+
511
+ export type PreDragActions = {|
512
+ // discover if the lock is still active
513
+ isActive: () => boolean,
514
+ // whether it has been indicated if force press should be respected
515
+ shouldRespectForcePress: () => boolean,
516
+ // lift the current item
517
+ fluidLift: (clientSelection: Position) => FluidDragActions,
518
+ snapLift: () => SnapDragActions,
519
+ // cancel the pre drag without starting a drag. Releases the lock
520
+ abort: () => void,
521
+ |};
522
+
523
+ export type TryGetLockOptions = {
524
+ sourceEvent?: Event,
525
+ };
526
+
527
+ export type TryGetLock = (
528
+ draggableId: DraggableId,
529
+ forceStop?: () => void,
530
+ options?: TryGetLockOptions,
531
+ ) => ?PreDragActions;
532
+
533
+ export type SensorAPI = {|
534
+ tryGetLock: TryGetLock,
535
+ canGetLock: (id: DraggableId) => boolean,
536
+ isLockClaimed: () => boolean,
537
+ tryReleaseLock: () => void,
538
+ findClosestDraggableId: (event: Event) => ?DraggableId,
539
+ findOptionsForDraggable: (id: DraggableId) => ?DraggableOptions,
540
+ |};
541
+
542
+ export type Sensor = (api: SensorAPI) => void;
@@ -0,0 +1,95 @@
1
+ // @flow
2
+ import React, { type Node } from 'react';
3
+ import type { InOutAnimationMode } from '../../types';
4
+
5
+ export type AnimateProvided = {|
6
+ onClose: () => void,
7
+ animate: InOutAnimationMode,
8
+ data: mixed,
9
+ |};
10
+
11
+ type Props = {|
12
+ on: mixed,
13
+ shouldAnimate: boolean,
14
+ children: (provided: AnimateProvided) => Node,
15
+ |};
16
+
17
+ type State = {|
18
+ data: mixed,
19
+ isVisible: boolean,
20
+ animate: InOutAnimationMode,
21
+ |};
22
+
23
+ // Using a class here rather than hooks because
24
+ // getDerivedStateFromProps results in far less renders.
25
+ // Using hooks to implement this was quite messy and resulted in lots of additional renders
26
+
27
+ export default class AnimateInOut extends React.PureComponent<Props, State> {
28
+ state: State = {
29
+ isVisible: Boolean(this.props.on),
30
+ data: this.props.on,
31
+ // not allowing to animate close on mount
32
+ animate: this.props.shouldAnimate && this.props.on ? 'open' : 'none',
33
+ };
34
+
35
+ static getDerivedStateFromProps(props: Props, state: State): State {
36
+ if (!props.shouldAnimate) {
37
+ return {
38
+ isVisible: Boolean(props.on),
39
+ data: props.on,
40
+ animate: 'none',
41
+ };
42
+ }
43
+
44
+ // need to animate in
45
+ if (props.on) {
46
+ return {
47
+ isVisible: true,
48
+ // have new data to animate in with
49
+ data: props.on,
50
+ animate: 'open',
51
+ };
52
+ }
53
+
54
+ // need to animate out if there was data
55
+
56
+ if (state.isVisible) {
57
+ return {
58
+ isVisible: true,
59
+ // use old data for animating out
60
+ data: state.data,
61
+ animate: 'close',
62
+ };
63
+ }
64
+
65
+ // close animation no longer visible
66
+ return {
67
+ isVisible: false,
68
+ animate: 'close',
69
+ data: null,
70
+ };
71
+ }
72
+
73
+ onClose = () => {
74
+ if (this.state.animate !== 'close') {
75
+ return;
76
+ }
77
+
78
+ this.setState({
79
+ isVisible: false,
80
+ });
81
+ };
82
+
83
+ render() {
84
+ if (!this.state.isVisible) {
85
+ return null;
86
+ }
87
+
88
+ const provided: AnimateProvided = {
89
+ onClose: this.onClose,
90
+ data: this.state.data,
91
+ animate: this.state.animate,
92
+ };
93
+ return this.props.children(provided);
94
+ }
95
+ }
@@ -0,0 +1,2 @@
1
+ // @flow
2
+ export { default } from './animate-in-out';
@@ -0,0 +1,15 @@
1
+ // @flow
2
+ import { invariant } from '../invariant';
3
+ import isHtmlElement from './is-type-of-element/is-html-element';
4
+
5
+ export default function checkIsValidInnerRef(el: ?HTMLElement) {
6
+ invariant(
7
+ el && isHtmlElement(el),
8
+ `
9
+ provided.innerRef has not been provided with a HTMLElement.
10
+
11
+ You can find a guide on using the innerRef callback functions at:
12
+ https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/using-inner-ref.md
13
+ `,
14
+ );
15
+ }
@@ -0,0 +1,19 @@
1
+ // @flow
2
+ import React from 'react';
3
+ import type { DraggableId, ContextId, ElementId } from '../../types';
4
+ import type { DimensionMarshal } from '../../state/dimension-marshal/dimension-marshal-types';
5
+ import type { FocusMarshal } from '../use-focus-marshal/focus-marshal-types';
6
+ import type { Registry } from '../../state/registry/registry-types';
7
+
8
+ export type AppContextValue = {|
9
+ focus: FocusMarshal,
10
+ contextId: ContextId,
11
+ canLift: (id: DraggableId) => boolean,
12
+ isMovementAllowed: () => boolean,
13
+ dragHandleUsageInstructionsId: ElementId,
14
+ marshal: DimensionMarshal,
15
+ registry: Registry,
16
+ fluidScrollerOptions: Object,
17
+ |};
18
+
19
+ export default React.createContext<?AppContextValue>(null);
@@ -0,0 +1,11 @@
1
+ // @flow
2
+ import React from 'react';
3
+ import type { DraggableId, DroppableId, TypeId } from '../../types';
4
+
5
+ export type DroppableContextValue = {|
6
+ isUsingCloneFor: ?DraggableId,
7
+ droppableId: DroppableId,
8
+ type: TypeId,
9
+ |};
10
+
11
+ export default React.createContext<?DroppableContextValue>(null);
@@ -0,0 +1,5 @@
1
+ // @flow
2
+ import React from 'react';
3
+ import type { Store } from '../../state/store-types';
4
+
5
+ export default React.createContext<?Store>(null);