@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.
- package/CHANGELOG.md +35 -0
- package/LICENSE +13 -0
- package/README.md +178 -0
- package/dist/react-beautiful-dnd.cjs.js +8728 -0
- package/dist/react-beautiful-dnd.cjs.js.flow +3 -0
- package/dist/react-beautiful-dnd.esm.js +8715 -0
- package/dist/react-beautiful-dnd.js +11726 -0
- package/dist/react-beautiful-dnd.min.js +1 -0
- package/package.json +155 -0
- package/src/animation.js +75 -0
- package/src/debug/middleware/action-timing-average.js +52 -0
- package/src/debug/middleware/action-timing.js +16 -0
- package/src/debug/middleware/log.js +26 -0
- package/src/debug/middleware/user-timing.js +16 -0
- package/src/debug/timings.js +86 -0
- package/src/dev-warning.js +50 -0
- package/src/empty.js +6 -0
- package/src/index.js +67 -0
- package/src/invariant.js +33 -0
- package/src/native-with-fallback.js +69 -0
- package/src/screen-reader-message-preset.js +134 -0
- package/src/state/action-creators.js +328 -0
- package/src/state/auto-scroller/auto-scroller-types.js +8 -0
- package/src/state/auto-scroller/can-scroll.js +160 -0
- package/src/state/auto-scroller/fluid-scroller/config.js +25 -0
- package/src/state/auto-scroller/fluid-scroller/did-start-in-scrollable-area.js +1 -0
- package/src/state/auto-scroller/fluid-scroller/get-best-scrollable-droppable.js +77 -0
- package/src/state/auto-scroller/fluid-scroller/get-droppable-scroll-change.js +50 -0
- package/src/state/auto-scroller/fluid-scroller/get-percentage.js +25 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/adjust-for-size-limits.js +30 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/buffer-thresholds/calc-axis-scroll-conditions.js +68 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/buffer-thresholds/get-scroll-conditions.js +56 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/buffer-thresholds/index.js +66 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/dampen-value-by-time.js +48 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-distance-thresholds.js +31 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-value-from-distance.js +67 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/get-value.js +51 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/index.js +50 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/get-scroll-on-axis/min-scroll.js +4 -0
- package/src/state/auto-scroller/fluid-scroller/get-scroll/index.js +139 -0
- package/src/state/auto-scroller/fluid-scroller/get-window-scroll-change.js +43 -0
- package/src/state/auto-scroller/fluid-scroller/index.js +99 -0
- package/src/state/auto-scroller/fluid-scroller/scroll.js +80 -0
- package/src/state/auto-scroller/index.js +59 -0
- package/src/state/auto-scroller/jump-scroller.js +139 -0
- package/src/state/axis.js +26 -0
- package/src/state/calculate-drag-impact/calculate-reorder-impact.js +136 -0
- package/src/state/can-start-drag.js +29 -0
- package/src/state/create-store.js +97 -0
- package/src/state/did-start-after-critical.js +9 -0
- package/src/state/dimension-marshal/dimension-marshal-types.js +46 -0
- package/src/state/dimension-marshal/dimension-marshal.js +218 -0
- package/src/state/dimension-marshal/get-initial-publish.js +66 -0
- package/src/state/dimension-marshal/while-dragging-publisher.js +146 -0
- package/src/state/dimension-structures.js +35 -0
- package/src/state/droppable/get-droppable.js +101 -0
- package/src/state/droppable/is-home-of.js +7 -0
- package/src/state/droppable/scroll-droppable.js +53 -0
- package/src/state/droppable/should-use-placeholder.js +7 -0
- package/src/state/droppable/util/clip.js +17 -0
- package/src/state/droppable/util/get-subject.js +63 -0
- package/src/state/droppable/what-is-dragged-over-from-result.js +16 -0
- package/src/state/droppable/what-is-dragged-over.js +16 -0
- package/src/state/droppable/with-placeholder.js +174 -0
- package/src/state/get-center-from-impact/get-client-border-box-center/get-client-from-page-border-box-center.js +29 -0
- package/src/state/get-center-from-impact/get-client-border-box-center/index.js +44 -0
- package/src/state/get-center-from-impact/get-page-border-box-center/index.js +70 -0
- package/src/state/get-center-from-impact/get-page-border-box-center/when-combining.js +39 -0
- package/src/state/get-center-from-impact/get-page-border-box-center/when-reordering.js +112 -0
- package/src/state/get-center-from-impact/move-relative-to.js +66 -0
- package/src/state/get-combined-item-displacement.js +34 -0
- package/src/state/get-displaced-by.js +17 -0
- package/src/state/get-displacement-groups.js +130 -0
- package/src/state/get-drag-impact/get-combine-impact.js +130 -0
- package/src/state/get-drag-impact/get-reorder-impact.js +143 -0
- package/src/state/get-drag-impact/index.js +93 -0
- package/src/state/get-draggables-inside-droppable.js +31 -0
- package/src/state/get-droppable-over.js +158 -0
- package/src/state/get-frame.js +10 -0
- package/src/state/get-home-location.js +7 -0
- package/src/state/get-impact-location.js +16 -0
- package/src/state/get-is-displaced.js +11 -0
- package/src/state/get-lift-effect.js +82 -0
- package/src/state/get-max-scroll.js +30 -0
- package/src/state/is-movement-allowed.js +6 -0
- package/src/state/is-within.js +9 -0
- package/src/state/middleware/auto-scroll.js +38 -0
- package/src/state/middleware/dimension-marshal-stopper.js +20 -0
- package/src/state/middleware/drop/drop-animation-finish-middleware.js +21 -0
- package/src/state/middleware/drop/drop-animation-flush-on-scroll-middleware.js +63 -0
- package/src/state/middleware/drop/drop-middleware.js +146 -0
- package/src/state/middleware/drop/get-drop-duration.js +47 -0
- package/src/state/middleware/drop/get-drop-impact.js +77 -0
- package/src/state/middleware/drop/get-new-home-client-offset.js +54 -0
- package/src/state/middleware/drop/index.js +2 -0
- package/src/state/middleware/focus.js +42 -0
- package/src/state/middleware/lift.js +66 -0
- package/src/state/middleware/pending-drop.js +37 -0
- package/src/state/middleware/responders/async-marshal.js +55 -0
- package/src/state/middleware/responders/expiring-announce.js +44 -0
- package/src/state/middleware/responders/index.js +2 -0
- package/src/state/middleware/responders/is-equal.js +57 -0
- package/src/state/middleware/responders/publisher.js +253 -0
- package/src/state/middleware/responders/responders-middleware.js +75 -0
- package/src/state/middleware/scroll-listener.js +31 -0
- package/src/state/middleware/style.js +22 -0
- package/src/state/middleware/util/validate-dimensions.js +71 -0
- package/src/state/move-in-direction/index.js +84 -0
- package/src/state/move-in-direction/move-cross-axis/get-best-cross-axis-droppable.js +168 -0
- package/src/state/move-in-direction/move-cross-axis/get-closest-draggable.js +79 -0
- package/src/state/move-in-direction/move-cross-axis/index.js +109 -0
- package/src/state/move-in-direction/move-cross-axis/move-to-new-droppable.js +121 -0
- package/src/state/move-in-direction/move-cross-axis/without-starting-displacement.js +31 -0
- package/src/state/move-in-direction/move-in-direction-types.js +9 -0
- package/src/state/move-in-direction/move-to-next-place/index.js +132 -0
- package/src/state/move-in-direction/move-to-next-place/is-totally-visible-in-new-location.js +52 -0
- package/src/state/move-in-direction/move-to-next-place/move-to-next-combine/index.js +97 -0
- package/src/state/move-in-direction/move-to-next-place/move-to-next-index/from-combine.js +52 -0
- package/src/state/move-in-direction/move-to-next-place/move-to-next-index/from-reorder.js +43 -0
- package/src/state/move-in-direction/move-to-next-place/move-to-next-index/index.js +86 -0
- package/src/state/no-impact.js +33 -0
- package/src/state/patch-dimension-map.js +11 -0
- package/src/state/patch-droppable-map.js +10 -0
- package/src/state/position.js +58 -0
- package/src/state/post-reducer/when-moving/refresh-snap.js +67 -0
- package/src/state/post-reducer/when-moving/update.js +120 -0
- package/src/state/publish-while-dragging-in-virtual/adjust-additions-for-scroll-changes.js +58 -0
- package/src/state/publish-while-dragging-in-virtual/index.js +158 -0
- package/src/state/publish-while-dragging-in-virtual/offset-draggable.js +35 -0
- package/src/state/recompute-placeholders.js +99 -0
- package/src/state/rect.js +7 -0
- package/src/state/reducer.js +457 -0
- package/src/state/registry/create-registry.js +162 -0
- package/src/state/registry/registry-types.js +98 -0
- package/src/state/registry/use-registry.js +20 -0
- package/src/state/remove-draggable-from-list.js +13 -0
- package/src/state/scroll-viewport.js +34 -0
- package/src/state/spacing.js +45 -0
- package/src/state/store-types.js +16 -0
- package/src/state/update-displacement-visibility/recompute.js +54 -0
- package/src/state/update-displacement-visibility/speculatively-increase.js +111 -0
- package/src/state/visibility/is-partially-visible-through-frame.js +60 -0
- package/src/state/visibility/is-position-in-frame.js +12 -0
- package/src/state/visibility/is-totally-visible-through-frame-on-axis.js +19 -0
- package/src/state/visibility/is-totally-visible-through-frame.js +18 -0
- package/src/state/visibility/is-visible.js +102 -0
- package/src/state/with-scroll-change/with-all-displacement.js +15 -0
- package/src/state/with-scroll-change/with-droppable-displacement.js +13 -0
- package/src/state/with-scroll-change/with-droppable-scroll.js +13 -0
- package/src/state/with-scroll-change/with-viewport-displacement.js +7 -0
- package/src/types.js +542 -0
- package/src/view/animate-in-out/animate-in-out.jsx +95 -0
- package/src/view/animate-in-out/index.js +2 -0
- package/src/view/check-is-valid-inner-ref.js +15 -0
- package/src/view/context/app-context.js +19 -0
- package/src/view/context/droppable-context.js +11 -0
- package/src/view/context/store-context.js +5 -0
- package/src/view/data-attributes.js +37 -0
- package/src/view/drag-drop-context/app.jsx +273 -0
- package/src/view/drag-drop-context/check-doctype.js +39 -0
- package/src/view/drag-drop-context/check-react-version.js +71 -0
- package/src/view/drag-drop-context/drag-drop-context-types.js +7 -0
- package/src/view/drag-drop-context/drag-drop-context.jsx +68 -0
- package/src/view/drag-drop-context/error-boundary.jsx +88 -0
- package/src/view/drag-drop-context/index.js +2 -0
- package/src/view/drag-drop-context/use-startup-validation.js +13 -0
- package/src/view/drag-drop-context/use-unique-context-id.js +13 -0
- package/src/view/draggable/connected-draggable.js +372 -0
- package/src/view/draggable/draggable-api.jsx +48 -0
- package/src/view/draggable/draggable-types.js +191 -0
- package/src/view/draggable/draggable.jsx +171 -0
- package/src/view/draggable/get-style.js +109 -0
- package/src/view/draggable/index.js +2 -0
- package/src/view/draggable/use-validation.js +70 -0
- package/src/view/droppable/connected-droppable.js +280 -0
- package/src/view/droppable/droppable-types.js +91 -0
- package/src/view/droppable/droppable.jsx +167 -0
- package/src/view/droppable/index.js +2 -0
- package/src/view/droppable/use-validation.js +101 -0
- package/src/view/event-bindings/bind-events.js +39 -0
- package/src/view/event-bindings/event-types.js +14 -0
- package/src/view/get-body-element.js +8 -0
- package/src/view/get-border-box-center-position.js +5 -0
- package/src/view/get-document-element.js +8 -0
- package/src/view/get-elements/find-drag-handle.js +38 -0
- package/src/view/get-elements/find-draggable.js +30 -0
- package/src/view/is-strict-equal.js +2 -0
- package/src/view/is-type-of-element/is-element.js +6 -0
- package/src/view/is-type-of-element/is-html-element.js +6 -0
- package/src/view/is-type-of-element/is-svg-element.js +12 -0
- package/src/view/key-codes.js +13 -0
- package/src/view/placeholder/index.js +2 -0
- package/src/view/placeholder/placeholder-types.js +16 -0
- package/src/view/placeholder/placeholder.jsx +198 -0
- package/src/view/scroll-listener.js +72 -0
- package/src/view/throw-if-invalid-inner-ref.js +15 -0
- package/src/view/use-announcer/index.js +2 -0
- package/src/view/use-announcer/use-announcer.js +80 -0
- package/src/view/use-dev-setup-warning.js +22 -0
- package/src/view/use-dev.js +9 -0
- package/src/view/use-draggable-publisher/get-dimension.js +44 -0
- package/src/view/use-draggable-publisher/index.js +2 -0
- package/src/view/use-draggable-publisher/use-draggable-publisher.js +87 -0
- package/src/view/use-droppable-publisher/check-for-nested-scroll-container.js +27 -0
- package/src/view/use-droppable-publisher/get-closest-scrollable.js +95 -0
- package/src/view/use-droppable-publisher/get-dimension.js +139 -0
- package/src/view/use-droppable-publisher/get-env.js +31 -0
- package/src/view/use-droppable-publisher/get-listener-options.js +12 -0
- package/src/view/use-droppable-publisher/get-scroll.js +7 -0
- package/src/view/use-droppable-publisher/index.js +2 -0
- package/src/view/use-droppable-publisher/is-in-fixed-container.js +21 -0
- package/src/view/use-droppable-publisher/use-droppable-publisher.js +283 -0
- package/src/view/use-focus-marshal/focus-marshal-types.js +13 -0
- package/src/view/use-focus-marshal/index.js +2 -0
- package/src/view/use-focus-marshal/use-focus-marshal.js +129 -0
- package/src/view/use-hidden-text-element/index.js +2 -0
- package/src/view/use-hidden-text-element/use-hidden-text-element.js +60 -0
- package/src/view/use-isomorphic-layout-effect.js +18 -0
- package/src/view/use-previous-ref.js +14 -0
- package/src/view/use-required-context.js +9 -0
- package/src/view/use-sensor-marshal/closest.js +50 -0
- package/src/view/use-sensor-marshal/find-closest-draggable-id-from-event.js +50 -0
- package/src/view/use-sensor-marshal/index.js +5 -0
- package/src/view/use-sensor-marshal/is-event-in-interactive-element.js +66 -0
- package/src/view/use-sensor-marshal/lock.js +48 -0
- package/src/view/use-sensor-marshal/sensors/use-keyboard-sensor.js +243 -0
- package/src/view/use-sensor-marshal/sensors/use-mouse-sensor.js +386 -0
- package/src/view/use-sensor-marshal/sensors/use-touch-sensor.js +461 -0
- package/src/view/use-sensor-marshal/sensors/util/prevent-standard-key-events.js +19 -0
- package/src/view/use-sensor-marshal/sensors/util/supported-page-visibility-event-name.js +29 -0
- package/src/view/use-sensor-marshal/use-sensor-marshal.js +495 -0
- package/src/view/use-sensor-marshal/use-validate-sensor-hooks.js +20 -0
- package/src/view/use-style-marshal/get-styles.js +170 -0
- package/src/view/use-style-marshal/index.js +2 -0
- package/src/view/use-style-marshal/style-marshal-types.js +8 -0
- package/src/view/use-style-marshal/use-style-marshal.js +126 -0
- package/src/view/use-unique-id.js +25 -0
- package/src/view/visually-hidden-style.js +16 -0
- package/src/view/window/get-max-window-scroll.js +19 -0
- package/src/view/window/get-viewport.js +49 -0
- package/src/view/window/get-window-from-el.js +3 -0
- package/src/view/window/get-window-scroll.js +30 -0
- package/src/view/window/scroll-window.js +7 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import rafSchd from 'raf-schd';
|
|
3
|
+
import { type Position } from 'css-box-model';
|
|
4
|
+
import type {
|
|
5
|
+
DraggingState,
|
|
6
|
+
DroppableId,
|
|
7
|
+
FluidScrollerOptions,
|
|
8
|
+
} from '../../../types';
|
|
9
|
+
import scroll from './scroll';
|
|
10
|
+
import { invariant } from '../../../invariant';
|
|
11
|
+
import * as timings from '../../../debug/timings';
|
|
12
|
+
|
|
13
|
+
export type PublicArgs = {|
|
|
14
|
+
scrollWindow: (change: Position) => void,
|
|
15
|
+
scrollDroppable: (id: DroppableId, change: Position) => void,
|
|
16
|
+
fluidScrollerOptions?: FluidScrollerOptions,
|
|
17
|
+
|};
|
|
18
|
+
|
|
19
|
+
export type FluidScroller = {|
|
|
20
|
+
scroll: (state: DraggingState) => void,
|
|
21
|
+
start: (state: DraggingState) => void,
|
|
22
|
+
stop: () => void,
|
|
23
|
+
fluidScrollerOptions?: FluidScrollerOptions,
|
|
24
|
+
|};
|
|
25
|
+
|
|
26
|
+
type WhileDragging = {|
|
|
27
|
+
dragStartTime: number,
|
|
28
|
+
shouldUseTimeDampening: boolean,
|
|
29
|
+
|};
|
|
30
|
+
|
|
31
|
+
export default ({
|
|
32
|
+
scrollWindow,
|
|
33
|
+
scrollDroppable,
|
|
34
|
+
fluidScrollerOptions,
|
|
35
|
+
}: PublicArgs): FluidScroller => {
|
|
36
|
+
const scheduleWindowScroll = rafSchd(scrollWindow);
|
|
37
|
+
const scheduleDroppableScroll = rafSchd(scrollDroppable);
|
|
38
|
+
let dragging: ?WhileDragging = null;
|
|
39
|
+
|
|
40
|
+
const tryScroll = (state: DraggingState): void => {
|
|
41
|
+
invariant(dragging, 'Cannot fluid scroll if not dragging');
|
|
42
|
+
const { shouldUseTimeDampening, dragStartTime } = dragging;
|
|
43
|
+
|
|
44
|
+
scroll({
|
|
45
|
+
state,
|
|
46
|
+
scrollWindow: scheduleWindowScroll,
|
|
47
|
+
scrollDroppable: scheduleDroppableScroll,
|
|
48
|
+
dragStartTime,
|
|
49
|
+
shouldUseTimeDampening,
|
|
50
|
+
fluidScrollerOptions,
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const start = (state: DraggingState) => {
|
|
55
|
+
timings.start('starting fluid scroller');
|
|
56
|
+
invariant(!dragging, 'Cannot start auto scrolling when already started');
|
|
57
|
+
const dragStartTime: number = Date.now();
|
|
58
|
+
|
|
59
|
+
let wasScrollNeeded: boolean = false;
|
|
60
|
+
const fakeScrollCallback = () => {
|
|
61
|
+
wasScrollNeeded = true;
|
|
62
|
+
};
|
|
63
|
+
scroll({
|
|
64
|
+
state,
|
|
65
|
+
dragStartTime: 0,
|
|
66
|
+
shouldUseTimeDampening: false,
|
|
67
|
+
scrollWindow: fakeScrollCallback,
|
|
68
|
+
scrollDroppable: fakeScrollCallback,
|
|
69
|
+
fluidScrollerOptions,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
dragging = {
|
|
73
|
+
dragStartTime,
|
|
74
|
+
shouldUseTimeDampening: wasScrollNeeded,
|
|
75
|
+
};
|
|
76
|
+
timings.finish('starting fluid scroller');
|
|
77
|
+
|
|
78
|
+
// we know an auto scroll is needed - let's do it!
|
|
79
|
+
if (wasScrollNeeded) {
|
|
80
|
+
tryScroll(state);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const stop = () => {
|
|
85
|
+
// can be called defensively
|
|
86
|
+
if (!dragging) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
scheduleWindowScroll.cancel();
|
|
90
|
+
scheduleDroppableScroll.cancel();
|
|
91
|
+
dragging = null;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
start,
|
|
96
|
+
stop,
|
|
97
|
+
scroll: tryScroll,
|
|
98
|
+
};
|
|
99
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position, type Rect } from 'css-box-model';
|
|
3
|
+
import type {
|
|
4
|
+
DraggingState,
|
|
5
|
+
DroppableId,
|
|
6
|
+
DraggableDimension,
|
|
7
|
+
DroppableDimension,
|
|
8
|
+
FluidScrollerOptions,
|
|
9
|
+
Viewport,
|
|
10
|
+
} from '../../../types';
|
|
11
|
+
import getBestScrollableDroppable from './get-best-scrollable-droppable';
|
|
12
|
+
import whatIsDraggedOver from '../../droppable/what-is-dragged-over';
|
|
13
|
+
import getWindowScrollChange from './get-window-scroll-change';
|
|
14
|
+
import getDroppableScrollChange from './get-droppable-scroll-change';
|
|
15
|
+
|
|
16
|
+
type Args = {|
|
|
17
|
+
state: DraggingState,
|
|
18
|
+
dragStartTime: number,
|
|
19
|
+
shouldUseTimeDampening: boolean,
|
|
20
|
+
scrollWindow: (scroll: Position) => void,
|
|
21
|
+
scrollDroppable: (id: DroppableId, scroll: Position) => void,
|
|
22
|
+
fluidScrollerOptions?: FluidScrollerOptions,
|
|
23
|
+
|};
|
|
24
|
+
|
|
25
|
+
export default ({
|
|
26
|
+
state,
|
|
27
|
+
dragStartTime,
|
|
28
|
+
shouldUseTimeDampening,
|
|
29
|
+
scrollWindow,
|
|
30
|
+
scrollDroppable,
|
|
31
|
+
fluidScrollerOptions,
|
|
32
|
+
}: Args): void => {
|
|
33
|
+
const center: Position = state.current.page.borderBoxCenter;
|
|
34
|
+
const centerInitial = state.initial.page.borderBoxCenter;
|
|
35
|
+
const draggable: DraggableDimension =
|
|
36
|
+
state.dimensions.draggables[state.critical.draggable.id];
|
|
37
|
+
const subject: Rect = draggable.page.marginBox;
|
|
38
|
+
// 1. Can we scroll the viewport?
|
|
39
|
+
if (state.isWindowScrollAllowed) {
|
|
40
|
+
const viewport: Viewport = state.viewport;
|
|
41
|
+
const change: ?Position = getWindowScrollChange({
|
|
42
|
+
dragStartTime,
|
|
43
|
+
viewport,
|
|
44
|
+
subject,
|
|
45
|
+
center,
|
|
46
|
+
centerInitial,
|
|
47
|
+
shouldUseTimeDampening,
|
|
48
|
+
fluidScrollerOptions,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (change) {
|
|
52
|
+
scrollWindow(change);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const droppable: ?DroppableDimension = getBestScrollableDroppable({
|
|
58
|
+
center,
|
|
59
|
+
destination: whatIsDraggedOver(state.impact),
|
|
60
|
+
droppables: state.dimensions.droppables,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (!droppable) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const change: ?Position = getDroppableScrollChange({
|
|
68
|
+
dragStartTime,
|
|
69
|
+
droppable,
|
|
70
|
+
subject,
|
|
71
|
+
center,
|
|
72
|
+
centerInitial,
|
|
73
|
+
shouldUseTimeDampening,
|
|
74
|
+
fluidScrollerOptions,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (change) {
|
|
78
|
+
scrollDroppable(droppable.descriptor.id, change);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position } from 'css-box-model';
|
|
3
|
+
import createFluidScroller, { type FluidScroller } from './fluid-scroller';
|
|
4
|
+
import createJumpScroller, { type JumpScroller } from './jump-scroller';
|
|
5
|
+
import type { AutoScroller } from './auto-scroller-types';
|
|
6
|
+
import type { DroppableId, FluidScrollerOptions, State } from '../../types';
|
|
7
|
+
import type { MoveArgs } from '../action-creators';
|
|
8
|
+
|
|
9
|
+
export type Args = {|
|
|
10
|
+
scrollWindow: (offset: Position) => void,
|
|
11
|
+
scrollDroppable: (id: DroppableId, change: Position) => void,
|
|
12
|
+
move: (args: MoveArgs) => mixed,
|
|
13
|
+
fluidScrollerOptions: FluidScrollerOptions,
|
|
14
|
+
|};
|
|
15
|
+
|
|
16
|
+
export default ({
|
|
17
|
+
scrollDroppable,
|
|
18
|
+
scrollWindow,
|
|
19
|
+
move,
|
|
20
|
+
fluidScrollerOptions,
|
|
21
|
+
}: Args): AutoScroller => {
|
|
22
|
+
const fluidScroller: FluidScroller = createFluidScroller({
|
|
23
|
+
scrollWindow,
|
|
24
|
+
scrollDroppable,
|
|
25
|
+
fluidScrollerOptions,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const jumpScroll: JumpScroller = createJumpScroller({
|
|
29
|
+
move,
|
|
30
|
+
scrollWindow,
|
|
31
|
+
scrollDroppable,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const scroll = (state: State) => {
|
|
35
|
+
// Only allowing auto scrolling in the DRAGGING phase
|
|
36
|
+
if (state.phase !== 'DRAGGING') {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (state.movementMode === 'FLUID') {
|
|
41
|
+
fluidScroller.scroll(state);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!state.scrollJumpRequest) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
jumpScroll(state);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const scroller: AutoScroller = {
|
|
53
|
+
scroll,
|
|
54
|
+
start: fluidScroller.start,
|
|
55
|
+
stop: fluidScroller.stop,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return scroller;
|
|
59
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position } from 'css-box-model';
|
|
3
|
+
import { invariant } from '../../invariant';
|
|
4
|
+
import { add, subtract } from '../position';
|
|
5
|
+
import {
|
|
6
|
+
canScrollWindow,
|
|
7
|
+
canScrollDroppable,
|
|
8
|
+
getWindowOverlap,
|
|
9
|
+
getDroppableOverlap,
|
|
10
|
+
} from './can-scroll';
|
|
11
|
+
import whatIsDraggedOver from '../droppable/what-is-dragged-over';
|
|
12
|
+
import { type MoveArgs } from '../action-creators';
|
|
13
|
+
import type {
|
|
14
|
+
DroppableDimension,
|
|
15
|
+
Viewport,
|
|
16
|
+
DraggingState,
|
|
17
|
+
DroppableId,
|
|
18
|
+
} from '../../types';
|
|
19
|
+
|
|
20
|
+
type Args = {|
|
|
21
|
+
scrollDroppable: (id: DroppableId, change: Position) => void,
|
|
22
|
+
scrollWindow: (offset: Position) => void,
|
|
23
|
+
move: (args: MoveArgs) => mixed,
|
|
24
|
+
|};
|
|
25
|
+
|
|
26
|
+
export type JumpScroller = (state: DraggingState) => void;
|
|
27
|
+
|
|
28
|
+
type Remainder = Position;
|
|
29
|
+
|
|
30
|
+
export default ({
|
|
31
|
+
move,
|
|
32
|
+
scrollDroppable,
|
|
33
|
+
scrollWindow,
|
|
34
|
+
}: Args): JumpScroller => {
|
|
35
|
+
const moveByOffset = (state: DraggingState, offset: Position) => {
|
|
36
|
+
const client: Position = add(state.current.client.selection, offset);
|
|
37
|
+
move({ client });
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const scrollDroppableAsMuchAsItCan = (
|
|
41
|
+
droppable: DroppableDimension,
|
|
42
|
+
change: Position,
|
|
43
|
+
): ?Remainder => {
|
|
44
|
+
// Droppable cannot absorb any of the scroll
|
|
45
|
+
if (!canScrollDroppable(droppable, change)) {
|
|
46
|
+
return change;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const overlap: ?Position = getDroppableOverlap(droppable, change);
|
|
50
|
+
|
|
51
|
+
// Droppable can absorb the entire change
|
|
52
|
+
if (!overlap) {
|
|
53
|
+
scrollDroppable(droppable.descriptor.id, change);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Droppable can only absorb a part of the change
|
|
58
|
+
const whatTheDroppableCanScroll: Position = subtract(change, overlap);
|
|
59
|
+
scrollDroppable(droppable.descriptor.id, whatTheDroppableCanScroll);
|
|
60
|
+
|
|
61
|
+
const remainder: Position = subtract(change, whatTheDroppableCanScroll);
|
|
62
|
+
return remainder;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const scrollWindowAsMuchAsItCan = (
|
|
66
|
+
isWindowScrollAllowed: boolean,
|
|
67
|
+
viewport: Viewport,
|
|
68
|
+
change: Position,
|
|
69
|
+
): ?Position => {
|
|
70
|
+
if (!isWindowScrollAllowed) {
|
|
71
|
+
return change;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!canScrollWindow(viewport, change)) {
|
|
75
|
+
// window cannot absorb any of the scroll
|
|
76
|
+
return change;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const overlap: ?Position = getWindowOverlap(viewport, change);
|
|
80
|
+
|
|
81
|
+
// window can absorb entire scroll
|
|
82
|
+
if (!overlap) {
|
|
83
|
+
scrollWindow(change);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// window can only absorb a part of the scroll
|
|
88
|
+
const whatTheWindowCanScroll: Position = subtract(change, overlap);
|
|
89
|
+
scrollWindow(whatTheWindowCanScroll);
|
|
90
|
+
|
|
91
|
+
const remainder: Position = subtract(change, whatTheWindowCanScroll);
|
|
92
|
+
return remainder;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const jumpScroller: JumpScroller = (state: DraggingState) => {
|
|
96
|
+
const request: ?Position = state.scrollJumpRequest;
|
|
97
|
+
|
|
98
|
+
if (!request) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const destination: ?DroppableId = whatIsDraggedOver(state.impact);
|
|
103
|
+
invariant(
|
|
104
|
+
destination,
|
|
105
|
+
'Cannot perform a jump scroll when there is no destination',
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// 1. We scroll the droppable first if we can to avoid the draggable
|
|
109
|
+
// leaving the list
|
|
110
|
+
|
|
111
|
+
const droppableRemainder: ?Position = scrollDroppableAsMuchAsItCan(
|
|
112
|
+
state.dimensions.droppables[destination],
|
|
113
|
+
request,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// droppable absorbed the entire scroll
|
|
117
|
+
if (!droppableRemainder) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const viewport: Viewport = state.viewport;
|
|
122
|
+
const windowRemainder: ?Position = scrollWindowAsMuchAsItCan(
|
|
123
|
+
state.isWindowScrollAllowed,
|
|
124
|
+
viewport,
|
|
125
|
+
droppableRemainder,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// window could absorb all the droppable remainder
|
|
129
|
+
if (!windowRemainder) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The entire scroll could not be absorbed by the droppable and window
|
|
134
|
+
// so we manually move whatever is left
|
|
135
|
+
moveByOffset(state, windowRemainder);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return jumpScroller;
|
|
139
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { HorizontalAxis, VerticalAxis } from '../types';
|
|
3
|
+
|
|
4
|
+
export const vertical: VerticalAxis = {
|
|
5
|
+
direction: 'vertical',
|
|
6
|
+
line: 'y',
|
|
7
|
+
crossAxisLine: 'x',
|
|
8
|
+
start: 'top',
|
|
9
|
+
end: 'bottom',
|
|
10
|
+
size: 'height',
|
|
11
|
+
crossAxisStart: 'left',
|
|
12
|
+
crossAxisEnd: 'right',
|
|
13
|
+
crossAxisSize: 'width',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const horizontal: HorizontalAxis = {
|
|
17
|
+
direction: 'horizontal',
|
|
18
|
+
line: 'x',
|
|
19
|
+
crossAxisLine: 'y',
|
|
20
|
+
start: 'left',
|
|
21
|
+
end: 'right',
|
|
22
|
+
size: 'width',
|
|
23
|
+
crossAxisStart: 'top',
|
|
24
|
+
crossAxisEnd: 'bottom',
|
|
25
|
+
crossAxisSize: 'height',
|
|
26
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type {
|
|
3
|
+
DraggableDimension,
|
|
4
|
+
DroppableDimension,
|
|
5
|
+
DragImpact,
|
|
6
|
+
DisplacementGroups,
|
|
7
|
+
Viewport,
|
|
8
|
+
DisplacedBy,
|
|
9
|
+
} from '../../types';
|
|
10
|
+
import removeDraggableFromList from '../remove-draggable-from-list';
|
|
11
|
+
import isHomeOf from '../droppable/is-home-of';
|
|
12
|
+
import { emptyGroups } from '../no-impact';
|
|
13
|
+
import { find } from '../../native-with-fallback';
|
|
14
|
+
import getDisplacementGroups from '../get-displacement-groups';
|
|
15
|
+
|
|
16
|
+
type Args = {|
|
|
17
|
+
draggable: DraggableDimension,
|
|
18
|
+
insideDestination: DraggableDimension[],
|
|
19
|
+
destination: DroppableDimension,
|
|
20
|
+
viewport: Viewport,
|
|
21
|
+
displacedBy: DisplacedBy,
|
|
22
|
+
last: DisplacementGroups,
|
|
23
|
+
index: ?number,
|
|
24
|
+
forceShouldAnimate?: boolean,
|
|
25
|
+
|};
|
|
26
|
+
|
|
27
|
+
function getIndexOfLastItem(
|
|
28
|
+
draggables: DraggableDimension[],
|
|
29
|
+
options: {| inHomeList: boolean |},
|
|
30
|
+
): number {
|
|
31
|
+
if (!draggables.length) {
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const indexOfLastItem: number =
|
|
36
|
+
draggables[draggables.length - 1].descriptor.index;
|
|
37
|
+
|
|
38
|
+
// When in a foreign list there will be an additional one item in the list
|
|
39
|
+
return options.inHomeList ? indexOfLastItem : indexOfLastItem + 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type GoAtEndArgs = {|
|
|
43
|
+
insideDestination: DraggableDimension[],
|
|
44
|
+
inHomeList: boolean,
|
|
45
|
+
displacedBy: DisplacedBy,
|
|
46
|
+
destination: DroppableDimension,
|
|
47
|
+
|};
|
|
48
|
+
|
|
49
|
+
function goAtEnd({
|
|
50
|
+
insideDestination,
|
|
51
|
+
inHomeList,
|
|
52
|
+
displacedBy,
|
|
53
|
+
destination,
|
|
54
|
+
}: GoAtEndArgs): DragImpact {
|
|
55
|
+
const newIndex: number = getIndexOfLastItem(insideDestination, {
|
|
56
|
+
inHomeList,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
displaced: emptyGroups,
|
|
61
|
+
displacedBy,
|
|
62
|
+
at: {
|
|
63
|
+
type: 'REORDER',
|
|
64
|
+
destination: {
|
|
65
|
+
droppableId: destination.descriptor.id,
|
|
66
|
+
index: newIndex,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default function calculateReorderImpact({
|
|
73
|
+
draggable,
|
|
74
|
+
insideDestination,
|
|
75
|
+
destination,
|
|
76
|
+
viewport,
|
|
77
|
+
displacedBy,
|
|
78
|
+
last,
|
|
79
|
+
index,
|
|
80
|
+
forceShouldAnimate,
|
|
81
|
+
}: Args): DragImpact {
|
|
82
|
+
const inHomeList: boolean = isHomeOf(draggable, destination);
|
|
83
|
+
|
|
84
|
+
// Go into last spot of list
|
|
85
|
+
if (index == null) {
|
|
86
|
+
return goAtEnd({
|
|
87
|
+
insideDestination,
|
|
88
|
+
inHomeList,
|
|
89
|
+
displacedBy,
|
|
90
|
+
destination,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// this might be the dragging item
|
|
95
|
+
const match: ?DraggableDimension = find(
|
|
96
|
+
insideDestination,
|
|
97
|
+
(item: DraggableDimension) => item.descriptor.index === index,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (!match) {
|
|
101
|
+
return goAtEnd({
|
|
102
|
+
insideDestination,
|
|
103
|
+
inHomeList,
|
|
104
|
+
displacedBy,
|
|
105
|
+
destination,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const withoutDragging: DraggableDimension[] = removeDraggableFromList(
|
|
109
|
+
draggable,
|
|
110
|
+
insideDestination,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const sliceFrom: number = insideDestination.indexOf(match);
|
|
114
|
+
const impacted: DraggableDimension[] = withoutDragging.slice(sliceFrom);
|
|
115
|
+
|
|
116
|
+
const displaced: DisplacementGroups = getDisplacementGroups({
|
|
117
|
+
afterDragging: impacted,
|
|
118
|
+
destination,
|
|
119
|
+
displacedBy,
|
|
120
|
+
last,
|
|
121
|
+
viewport: viewport.frame,
|
|
122
|
+
forceShouldAnimate,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
displaced,
|
|
127
|
+
displacedBy,
|
|
128
|
+
at: {
|
|
129
|
+
type: 'REORDER',
|
|
130
|
+
destination: {
|
|
131
|
+
droppableId: destination.descriptor.id,
|
|
132
|
+
index,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { State, DraggableId } from '../types';
|
|
3
|
+
|
|
4
|
+
export default (state: State, id: DraggableId): boolean => {
|
|
5
|
+
// Ready to go!
|
|
6
|
+
if (state.phase === 'IDLE') {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Can lift depending on the type of drop animation
|
|
11
|
+
if (state.phase !== 'DROP_ANIMATING') {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// - For a user drop we allow the user to drag other Draggables
|
|
16
|
+
// immediately as items are most likely already in their home
|
|
17
|
+
// - For a cancel items will be moving back to their original position
|
|
18
|
+
// as such it is a cleaner experience to block them from dragging until
|
|
19
|
+
// the drop animation is complete. Otherwise they will be grabbing
|
|
20
|
+
// items not in their original position which can lead to bad visuals
|
|
21
|
+
// Not allowing dragging of the dropping draggable
|
|
22
|
+
if (state.completed.result.draggableId === id) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// if dropping - allow lifting
|
|
27
|
+
// if cancelling - disallow lifting
|
|
28
|
+
return state.completed.result.reason === 'DROP';
|
|
29
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
/* eslint-disable no-underscore-dangle */
|
|
3
|
+
import { applyMiddleware, createStore, compose } from 'redux';
|
|
4
|
+
import reducer from './reducer';
|
|
5
|
+
import lift from './middleware/lift';
|
|
6
|
+
import style from './middleware/style';
|
|
7
|
+
import drop from './middleware/drop/drop-middleware';
|
|
8
|
+
import scrollListener from './middleware/scroll-listener';
|
|
9
|
+
import responders from './middleware/responders/responders-middleware';
|
|
10
|
+
import dropAnimationFinish from './middleware/drop/drop-animation-finish-middleware';
|
|
11
|
+
import dropAnimationFlushOnScroll from './middleware/drop/drop-animation-flush-on-scroll-middleware';
|
|
12
|
+
import dimensionMarshalStopper from './middleware/dimension-marshal-stopper';
|
|
13
|
+
import focus from './middleware/focus';
|
|
14
|
+
import autoScroll from './middleware/auto-scroll';
|
|
15
|
+
import pendingDrop from './middleware/pending-drop';
|
|
16
|
+
import type { DimensionMarshal } from './dimension-marshal/dimension-marshal-types';
|
|
17
|
+
import type { FocusMarshal } from '../view/use-focus-marshal/focus-marshal-types';
|
|
18
|
+
import type { StyleMarshal } from '../view/use-style-marshal/style-marshal-types';
|
|
19
|
+
import type { AutoScroller } from './auto-scroller/auto-scroller-types';
|
|
20
|
+
import type { Responders, Announce } from '../types';
|
|
21
|
+
import type { Store } from './store-types';
|
|
22
|
+
|
|
23
|
+
// We are checking if window is available before using it.
|
|
24
|
+
// This is needed for universal apps that render the component server side.
|
|
25
|
+
// Details: https://github.com/zalmoxisus/redux-devtools-extension#12-advanced-store-setup
|
|
26
|
+
const composeEnhancers =
|
|
27
|
+
process.env.NODE_ENV !== 'production' &&
|
|
28
|
+
typeof window !== 'undefined' &&
|
|
29
|
+
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
|
30
|
+
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
|
|
31
|
+
name: 'react-beautiful-dnd',
|
|
32
|
+
})
|
|
33
|
+
: compose;
|
|
34
|
+
|
|
35
|
+
type Args = {|
|
|
36
|
+
dimensionMarshal: DimensionMarshal,
|
|
37
|
+
focusMarshal: FocusMarshal,
|
|
38
|
+
styleMarshal: StyleMarshal,
|
|
39
|
+
getResponders: () => Responders,
|
|
40
|
+
announce: Announce,
|
|
41
|
+
autoScroller: AutoScroller,
|
|
42
|
+
|};
|
|
43
|
+
|
|
44
|
+
export default ({
|
|
45
|
+
dimensionMarshal,
|
|
46
|
+
focusMarshal,
|
|
47
|
+
styleMarshal,
|
|
48
|
+
getResponders,
|
|
49
|
+
announce,
|
|
50
|
+
autoScroller,
|
|
51
|
+
}: Args): Store =>
|
|
52
|
+
createStore(
|
|
53
|
+
reducer,
|
|
54
|
+
composeEnhancers(
|
|
55
|
+
applyMiddleware(
|
|
56
|
+
// ## Debug middleware
|
|
57
|
+
|
|
58
|
+
// > uncomment to use
|
|
59
|
+
// debugging logger
|
|
60
|
+
// require('../debug/middleware/log').default('light'),
|
|
61
|
+
// // user timing api
|
|
62
|
+
// require('../debug/middleware/user-timing').default,
|
|
63
|
+
// debugging timer
|
|
64
|
+
// require('../debug/middleware/action-timing').default,
|
|
65
|
+
// average action timer
|
|
66
|
+
// require('../debug/middleware/action-timing-average').default(200),
|
|
67
|
+
|
|
68
|
+
// ## Application middleware
|
|
69
|
+
|
|
70
|
+
// Style updates do not cause more actions. It is important to update styles
|
|
71
|
+
// before responders are called: specifically the onDragEnd responder. We need to clear
|
|
72
|
+
// the transition styles off the elements before a reorder to prevent strange
|
|
73
|
+
// post drag animations in firefox. Even though we clear the transition off
|
|
74
|
+
// a Draggable - if it is done after a reorder firefox will still apply the
|
|
75
|
+
// transition.
|
|
76
|
+
// Must be called before dimension marshal for lifting to apply collecting styles
|
|
77
|
+
style(styleMarshal),
|
|
78
|
+
// Stop the dimension marshal collecting anything
|
|
79
|
+
// when moving into a phase where collection is no longer needed.
|
|
80
|
+
// We need to stop the marshal before responders fire as responders can cause
|
|
81
|
+
// dimension registration changes in response to reordering
|
|
82
|
+
dimensionMarshalStopper(dimensionMarshal),
|
|
83
|
+
// Fire application responders in response to drag changes
|
|
84
|
+
lift(dimensionMarshal),
|
|
85
|
+
drop,
|
|
86
|
+
// When a drop animation finishes - fire a drop complete
|
|
87
|
+
dropAnimationFinish,
|
|
88
|
+
dropAnimationFlushOnScroll,
|
|
89
|
+
pendingDrop,
|
|
90
|
+
autoScroll(autoScroller),
|
|
91
|
+
scrollListener,
|
|
92
|
+
focus(focusMarshal),
|
|
93
|
+
// Fire responders for consumers (after update to store)
|
|
94
|
+
responders(getResponders, announce),
|
|
95
|
+
),
|
|
96
|
+
),
|
|
97
|
+
);
|