@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,457 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Position } from 'css-box-model';
|
|
3
|
+
import { invariant } from '../invariant';
|
|
4
|
+
import type {
|
|
5
|
+
DimensionMap,
|
|
6
|
+
State,
|
|
7
|
+
StateWhenUpdatesAllowed,
|
|
8
|
+
DraggableDimension,
|
|
9
|
+
DroppableDimension,
|
|
10
|
+
IdleState,
|
|
11
|
+
DraggingState,
|
|
12
|
+
DragPositions,
|
|
13
|
+
ClientPositions,
|
|
14
|
+
CollectingState,
|
|
15
|
+
DropAnimatingState,
|
|
16
|
+
DropPendingState,
|
|
17
|
+
Viewport,
|
|
18
|
+
DropReason,
|
|
19
|
+
} from '../types';
|
|
20
|
+
import type { Action } from './store-types';
|
|
21
|
+
import type { PublicResult as MoveInDirectionResult } from './move-in-direction/move-in-direction-types';
|
|
22
|
+
import scrollDroppable from './droppable/scroll-droppable';
|
|
23
|
+
import moveInDirection from './move-in-direction';
|
|
24
|
+
import { add, isEqual, origin } from './position';
|
|
25
|
+
import scrollViewport from './scroll-viewport';
|
|
26
|
+
import isMovementAllowed from './is-movement-allowed';
|
|
27
|
+
import { toDroppableList } from './dimension-structures';
|
|
28
|
+
import update from './post-reducer/when-moving/update';
|
|
29
|
+
import refreshSnap from './post-reducer/when-moving/refresh-snap';
|
|
30
|
+
import getLiftEffect from './get-lift-effect';
|
|
31
|
+
import patchDimensionMap from './patch-dimension-map';
|
|
32
|
+
import publishWhileDraggingInVirtual from './publish-while-dragging-in-virtual';
|
|
33
|
+
|
|
34
|
+
const isSnapping = (state: StateWhenUpdatesAllowed): boolean =>
|
|
35
|
+
state.movementMode === 'SNAP';
|
|
36
|
+
|
|
37
|
+
const postDroppableChange = (
|
|
38
|
+
state: StateWhenUpdatesAllowed,
|
|
39
|
+
updated: DroppableDimension,
|
|
40
|
+
isEnabledChanging: boolean,
|
|
41
|
+
): StateWhenUpdatesAllowed => {
|
|
42
|
+
const dimensions: DimensionMap = patchDimensionMap(state.dimensions, updated);
|
|
43
|
+
|
|
44
|
+
// if the enabled state is changing, we need to force a update
|
|
45
|
+
if (!isSnapping(state) || isEnabledChanging) {
|
|
46
|
+
return update({
|
|
47
|
+
state,
|
|
48
|
+
dimensions,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return refreshSnap({
|
|
53
|
+
state,
|
|
54
|
+
dimensions,
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
function removeScrollJumpRequest(state: State): State {
|
|
59
|
+
if (state.isDragging && state.movementMode === 'SNAP') {
|
|
60
|
+
return {
|
|
61
|
+
// will be overwritten by spread
|
|
62
|
+
// needed for flow
|
|
63
|
+
phase: 'DRAGGING',
|
|
64
|
+
...state,
|
|
65
|
+
scrollJumpRequest: null,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return state;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const idle: IdleState = { phase: 'IDLE', completed: null, shouldFlush: false };
|
|
72
|
+
|
|
73
|
+
export default (state: State = idle, action: Action): State => {
|
|
74
|
+
if (action.type === 'FLUSH') {
|
|
75
|
+
return {
|
|
76
|
+
...idle,
|
|
77
|
+
shouldFlush: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (action.type === 'INITIAL_PUBLISH') {
|
|
82
|
+
invariant(
|
|
83
|
+
state.phase === 'IDLE',
|
|
84
|
+
'INITIAL_PUBLISH must come after a IDLE phase',
|
|
85
|
+
);
|
|
86
|
+
const {
|
|
87
|
+
critical,
|
|
88
|
+
clientSelection,
|
|
89
|
+
viewport,
|
|
90
|
+
dimensions,
|
|
91
|
+
movementMode,
|
|
92
|
+
} = action.payload;
|
|
93
|
+
|
|
94
|
+
const draggable: DraggableDimension =
|
|
95
|
+
dimensions.draggables[critical.draggable.id];
|
|
96
|
+
const home: DroppableDimension =
|
|
97
|
+
dimensions.droppables[critical.droppable.id];
|
|
98
|
+
|
|
99
|
+
const client: ClientPositions = {
|
|
100
|
+
selection: clientSelection,
|
|
101
|
+
borderBoxCenter: draggable.client.borderBox.center,
|
|
102
|
+
offset: origin,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const initial: DragPositions = {
|
|
106
|
+
client,
|
|
107
|
+
page: {
|
|
108
|
+
selection: add(client.selection, viewport.scroll.initial),
|
|
109
|
+
borderBoxCenter: add(client.selection, viewport.scroll.initial),
|
|
110
|
+
offset: add(client.selection, viewport.scroll.diff.value),
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// Can only auto scroll the window if every list is not fixed on the page
|
|
115
|
+
const isWindowScrollAllowed: boolean = toDroppableList(
|
|
116
|
+
dimensions.droppables,
|
|
117
|
+
).every((item: DroppableDimension) => !item.isFixedOnPage);
|
|
118
|
+
|
|
119
|
+
const { impact, afterCritical } = getLiftEffect({
|
|
120
|
+
draggable,
|
|
121
|
+
home,
|
|
122
|
+
draggables: dimensions.draggables,
|
|
123
|
+
viewport,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const result: DraggingState = {
|
|
127
|
+
phase: 'DRAGGING',
|
|
128
|
+
isDragging: true,
|
|
129
|
+
critical,
|
|
130
|
+
movementMode,
|
|
131
|
+
dimensions,
|
|
132
|
+
initial,
|
|
133
|
+
current: initial,
|
|
134
|
+
isWindowScrollAllowed,
|
|
135
|
+
impact,
|
|
136
|
+
afterCritical,
|
|
137
|
+
onLiftImpact: impact,
|
|
138
|
+
viewport,
|
|
139
|
+
scrollJumpRequest: null,
|
|
140
|
+
forceShouldAnimate: null,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (action.type === 'COLLECTION_STARTING') {
|
|
147
|
+
// A collection might have restarted. We do not care as we are already in the right phase
|
|
148
|
+
// TODO: remove?
|
|
149
|
+
if (state.phase === 'COLLECTING' || state.phase === 'DROP_PENDING') {
|
|
150
|
+
return state;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
invariant(
|
|
154
|
+
state.phase === 'DRAGGING',
|
|
155
|
+
`Collection cannot start from phase ${state.phase}`,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const result: CollectingState = {
|
|
159
|
+
// putting phase first to appease flow
|
|
160
|
+
phase: 'COLLECTING',
|
|
161
|
+
...state,
|
|
162
|
+
// eslint-disable-next-line
|
|
163
|
+
phase: 'COLLECTING',
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (action.type === 'PUBLISH_WHILE_DRAGGING') {
|
|
170
|
+
// Unexpected bulk publish
|
|
171
|
+
invariant(
|
|
172
|
+
state.phase === 'COLLECTING' || state.phase === 'DROP_PENDING',
|
|
173
|
+
`Unexpected ${action.type} received in phase ${state.phase}`,
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
return publishWhileDraggingInVirtual({
|
|
177
|
+
state,
|
|
178
|
+
published: action.payload,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (action.type === 'MOVE') {
|
|
183
|
+
// Not allowing any more movements
|
|
184
|
+
if (state.phase === 'DROP_PENDING') {
|
|
185
|
+
return state;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
invariant(
|
|
189
|
+
isMovementAllowed(state),
|
|
190
|
+
`${action.type} not permitted in phase ${state.phase}`,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const { client: clientSelection } = action.payload;
|
|
194
|
+
|
|
195
|
+
// nothing needs to be done
|
|
196
|
+
if (isEqual(clientSelection, state.current.client.selection)) {
|
|
197
|
+
return state;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return update({
|
|
201
|
+
state,
|
|
202
|
+
clientSelection,
|
|
203
|
+
// If we are snap moving - manual movements should not update the impact
|
|
204
|
+
impact: isSnapping(state) ? state.impact : null,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (action.type === 'UPDATE_DROPPABLE_SCROLL') {
|
|
209
|
+
// Not allowing changes while a drop is pending
|
|
210
|
+
// Cannot get this during a DROP_ANIMATING as the dimension
|
|
211
|
+
// marshal will cancel any pending scroll updates
|
|
212
|
+
if (state.phase === 'DROP_PENDING') {
|
|
213
|
+
return removeScrollJumpRequest(state);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// We will be updating the scroll in response to dynamic changes
|
|
217
|
+
// manually on the droppable so we can ignore this change
|
|
218
|
+
if (state.phase === 'COLLECTING') {
|
|
219
|
+
return removeScrollJumpRequest(state);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
invariant(
|
|
223
|
+
isMovementAllowed(state),
|
|
224
|
+
`${action.type} not permitted in phase ${state.phase}`,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
const { id, newScroll } = action.payload;
|
|
228
|
+
const target: ?DroppableDimension = state.dimensions.droppables[id];
|
|
229
|
+
|
|
230
|
+
// This is possible if a droppable has been asked to watch scroll but
|
|
231
|
+
// the dimension has not been published yet
|
|
232
|
+
if (!target) {
|
|
233
|
+
return state;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const scrolled: DroppableDimension = scrollDroppable(target, newScroll);
|
|
237
|
+
return postDroppableChange(state, scrolled, false);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (action.type === 'UPDATE_DROPPABLE_IS_ENABLED') {
|
|
241
|
+
// Things are locked at this point
|
|
242
|
+
if (state.phase === 'DROP_PENDING') {
|
|
243
|
+
return state;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
invariant(
|
|
247
|
+
isMovementAllowed(state),
|
|
248
|
+
`Attempting to move in an unsupported phase ${state.phase}`,
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const { id, isEnabled } = action.payload;
|
|
252
|
+
const target: ?DroppableDimension = state.dimensions.droppables[id];
|
|
253
|
+
|
|
254
|
+
invariant(
|
|
255
|
+
target,
|
|
256
|
+
`Cannot find Droppable[id: ${id}] to toggle its enabled state`,
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
invariant(
|
|
260
|
+
target.isEnabled !== isEnabled,
|
|
261
|
+
`Trying to set droppable isEnabled to ${String(isEnabled)}
|
|
262
|
+
but it is already ${String(target.isEnabled)}`,
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const updated: DroppableDimension = {
|
|
266
|
+
...target,
|
|
267
|
+
isEnabled,
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
return postDroppableChange(state, updated, true);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (action.type === 'UPDATE_DROPPABLE_IS_COMBINE_ENABLED') {
|
|
274
|
+
// Things are locked at this point
|
|
275
|
+
if (state.phase === 'DROP_PENDING') {
|
|
276
|
+
return state;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
invariant(
|
|
280
|
+
isMovementAllowed(state),
|
|
281
|
+
`Attempting to move in an unsupported phase ${state.phase}`,
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
const { id, isCombineEnabled } = action.payload;
|
|
285
|
+
const target: ?DroppableDimension = state.dimensions.droppables[id];
|
|
286
|
+
|
|
287
|
+
invariant(
|
|
288
|
+
target,
|
|
289
|
+
`Cannot find Droppable[id: ${id}] to toggle its isCombineEnabled state`,
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
invariant(
|
|
293
|
+
target.isCombineEnabled !== isCombineEnabled,
|
|
294
|
+
`Trying to set droppable isCombineEnabled to ${String(isCombineEnabled)}
|
|
295
|
+
but it is already ${String(target.isCombineEnabled)}`,
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
const updated: DroppableDimension = {
|
|
299
|
+
...target,
|
|
300
|
+
isCombineEnabled,
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
return postDroppableChange(state, updated, true);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (action.type === 'MOVE_BY_WINDOW_SCROLL') {
|
|
307
|
+
// No longer accepting changes
|
|
308
|
+
if (state.phase === 'DROP_PENDING' || state.phase === 'DROP_ANIMATING') {
|
|
309
|
+
return state;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
invariant(
|
|
313
|
+
isMovementAllowed(state),
|
|
314
|
+
`Cannot move by window in phase ${state.phase}`,
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
invariant(
|
|
318
|
+
state.isWindowScrollAllowed,
|
|
319
|
+
'Window scrolling is currently not supported for fixed lists',
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
const newScroll: Position = action.payload.newScroll;
|
|
323
|
+
|
|
324
|
+
// nothing needs to be done
|
|
325
|
+
if (isEqual(state.viewport.scroll.current, newScroll)) {
|
|
326
|
+
return removeScrollJumpRequest(state);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const viewport: Viewport = scrollViewport(state.viewport, newScroll);
|
|
330
|
+
|
|
331
|
+
if (isSnapping(state)) {
|
|
332
|
+
return refreshSnap({
|
|
333
|
+
state,
|
|
334
|
+
viewport,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return update({
|
|
339
|
+
state,
|
|
340
|
+
viewport,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (action.type === 'UPDATE_VIEWPORT_MAX_SCROLL') {
|
|
345
|
+
// Could occur if a transitionEnd occurs after a drag ends
|
|
346
|
+
if (!isMovementAllowed(state)) {
|
|
347
|
+
return state;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const maxScroll: Position = action.payload.maxScroll;
|
|
351
|
+
|
|
352
|
+
if (isEqual(maxScroll, state.viewport.scroll.max)) {
|
|
353
|
+
return state;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const withMaxScroll: Viewport = {
|
|
357
|
+
...state.viewport,
|
|
358
|
+
scroll: {
|
|
359
|
+
...state.viewport.scroll,
|
|
360
|
+
max: maxScroll,
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
// don't need to recalc any updates
|
|
365
|
+
return {
|
|
366
|
+
// phase will be overridden - appeasing flow
|
|
367
|
+
phase: 'DRAGGING',
|
|
368
|
+
...state,
|
|
369
|
+
viewport: withMaxScroll,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
if (
|
|
373
|
+
action.type === 'MOVE_UP' ||
|
|
374
|
+
action.type === 'MOVE_DOWN' ||
|
|
375
|
+
action.type === 'MOVE_LEFT' ||
|
|
376
|
+
action.type === 'MOVE_RIGHT'
|
|
377
|
+
) {
|
|
378
|
+
// Not doing keyboard movements during these phases
|
|
379
|
+
if (state.phase === 'COLLECTING' || state.phase === 'DROP_PENDING') {
|
|
380
|
+
return state;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
invariant(
|
|
384
|
+
state.phase === 'DRAGGING',
|
|
385
|
+
`${action.type} received while not in DRAGGING phase`,
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
const result: ?MoveInDirectionResult = moveInDirection({
|
|
389
|
+
state,
|
|
390
|
+
type: action.type,
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
// cannot move in that direction
|
|
394
|
+
if (!result) {
|
|
395
|
+
return state;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return update({
|
|
399
|
+
state,
|
|
400
|
+
impact: result.impact,
|
|
401
|
+
clientSelection: result.clientSelection,
|
|
402
|
+
scrollJumpRequest: result.scrollJumpRequest,
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (action.type === 'DROP_PENDING') {
|
|
407
|
+
const reason: DropReason = action.payload.reason;
|
|
408
|
+
invariant(
|
|
409
|
+
state.phase === 'COLLECTING',
|
|
410
|
+
'Can only move into the DROP_PENDING phase from the COLLECTING phase',
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
const newState: DropPendingState = {
|
|
414
|
+
// appeasing flow
|
|
415
|
+
phase: 'DROP_PENDING',
|
|
416
|
+
...state,
|
|
417
|
+
// eslint-disable-next-line
|
|
418
|
+
phase: 'DROP_PENDING',
|
|
419
|
+
isWaiting: true,
|
|
420
|
+
reason,
|
|
421
|
+
};
|
|
422
|
+
return newState;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (action.type === 'DROP_ANIMATE') {
|
|
426
|
+
const { completed, dropDuration, newHomeClientOffset } = action.payload;
|
|
427
|
+
invariant(
|
|
428
|
+
state.phase === 'DRAGGING' || state.phase === 'DROP_PENDING',
|
|
429
|
+
`Cannot animate drop from phase ${state.phase}`,
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
// Moving into a new phase
|
|
433
|
+
const result: DropAnimatingState = {
|
|
434
|
+
phase: 'DROP_ANIMATING',
|
|
435
|
+
completed,
|
|
436
|
+
dropDuration,
|
|
437
|
+
newHomeClientOffset,
|
|
438
|
+
dimensions: state.dimensions,
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
return result;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Action will be used by responders to call consumers
|
|
445
|
+
// We can simply return to the idle state
|
|
446
|
+
if (action.type === 'DROP_COMPLETE') {
|
|
447
|
+
const { completed } = action.payload;
|
|
448
|
+
|
|
449
|
+
return {
|
|
450
|
+
phase: 'IDLE',
|
|
451
|
+
completed,
|
|
452
|
+
shouldFlush: false,
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return state;
|
|
457
|
+
};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { invariant } from '../../invariant';
|
|
3
|
+
import type { TypeId, DraggableId, DroppableId } from '../../types';
|
|
4
|
+
import type {
|
|
5
|
+
Registry,
|
|
6
|
+
DraggableAPI,
|
|
7
|
+
DroppableAPI,
|
|
8
|
+
DraggableEntry,
|
|
9
|
+
DroppableEntry,
|
|
10
|
+
RegistryEvent,
|
|
11
|
+
Subscriber,
|
|
12
|
+
Unsubscribe,
|
|
13
|
+
DraggableEntryMap,
|
|
14
|
+
DroppableEntryMap,
|
|
15
|
+
} from './registry-types';
|
|
16
|
+
import { values } from '../../native-with-fallback';
|
|
17
|
+
|
|
18
|
+
type EntryMap = {
|
|
19
|
+
draggables: DraggableEntryMap,
|
|
20
|
+
droppables: DroppableEntryMap,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default function createRegistry(): Registry {
|
|
24
|
+
const entries: EntryMap = {
|
|
25
|
+
draggables: {},
|
|
26
|
+
droppables: {},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const subscribers: Subscriber[] = [];
|
|
30
|
+
|
|
31
|
+
function subscribe(cb: Subscriber): Unsubscribe {
|
|
32
|
+
subscribers.push(cb);
|
|
33
|
+
|
|
34
|
+
return function unsubscribe(): void {
|
|
35
|
+
const index: number = subscribers.indexOf(cb);
|
|
36
|
+
|
|
37
|
+
// might have been removed by a clean
|
|
38
|
+
if (index === -1) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
subscribers.splice(index, 1);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function notify(event: RegistryEvent) {
|
|
47
|
+
if (subscribers.length) {
|
|
48
|
+
subscribers.forEach((cb) => cb(event));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function findDraggableById(id: DraggableId): ?DraggableEntry {
|
|
53
|
+
return entries.draggables[id] || null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getDraggableById(id: DraggableId): DraggableEntry {
|
|
57
|
+
const entry: ?DraggableEntry = findDraggableById(id);
|
|
58
|
+
invariant(entry, `Cannot find draggable entry with id [${id}]`);
|
|
59
|
+
return entry;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const draggableAPI: DraggableAPI = {
|
|
63
|
+
register: (entry: DraggableEntry) => {
|
|
64
|
+
entries.draggables[entry.descriptor.id] = entry;
|
|
65
|
+
notify({ type: 'ADDITION', value: entry });
|
|
66
|
+
},
|
|
67
|
+
update: (entry: DraggableEntry, last: DraggableEntry) => {
|
|
68
|
+
const current: ?DraggableEntry = entries.draggables[last.descriptor.id];
|
|
69
|
+
|
|
70
|
+
// item already removed
|
|
71
|
+
if (!current) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// id already used for another mount
|
|
76
|
+
if (current.uniqueId !== entry.uniqueId) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// We are safe to delete the old entry and add a new one
|
|
81
|
+
delete entries.draggables[last.descriptor.id];
|
|
82
|
+
entries.draggables[entry.descriptor.id] = entry;
|
|
83
|
+
},
|
|
84
|
+
unregister: (entry: DraggableEntry) => {
|
|
85
|
+
const draggableId: DraggableId = entry.descriptor.id;
|
|
86
|
+
const current: ?DraggableEntry = findDraggableById(draggableId);
|
|
87
|
+
|
|
88
|
+
// can occur if cleaned before unregistration
|
|
89
|
+
if (!current) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// outdated uniqueId
|
|
94
|
+
if (entry.uniqueId !== current.uniqueId) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
delete entries.draggables[draggableId];
|
|
99
|
+
notify({ type: 'REMOVAL', value: entry });
|
|
100
|
+
},
|
|
101
|
+
getById: getDraggableById,
|
|
102
|
+
findById: findDraggableById,
|
|
103
|
+
exists: (id: DraggableId): boolean => Boolean(findDraggableById(id)),
|
|
104
|
+
getAllByType: (type: TypeId): DraggableEntry[] =>
|
|
105
|
+
values(entries.draggables).filter(
|
|
106
|
+
(entry: DraggableEntry): boolean => entry.descriptor.type === type,
|
|
107
|
+
),
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
function findDroppableById(id: DroppableId): ?DroppableEntry {
|
|
111
|
+
return entries.droppables[id] || null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function getDroppableById(id: DroppableId): DroppableEntry {
|
|
115
|
+
const entry: ?DroppableEntry = findDroppableById(id);
|
|
116
|
+
invariant(entry, `Cannot find droppable entry with id [${id}]`);
|
|
117
|
+
return entry;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const droppableAPI: DroppableAPI = {
|
|
121
|
+
register: (entry: DroppableEntry) => {
|
|
122
|
+
entries.droppables[entry.descriptor.id] = entry;
|
|
123
|
+
},
|
|
124
|
+
unregister: (entry: DroppableEntry) => {
|
|
125
|
+
const current: ?DroppableEntry = findDroppableById(entry.descriptor.id);
|
|
126
|
+
|
|
127
|
+
// can occur if cleaned before an unregistry
|
|
128
|
+
if (!current) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// already changed
|
|
133
|
+
if (entry.uniqueId !== current.uniqueId) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
delete entries.droppables[entry.descriptor.id];
|
|
138
|
+
},
|
|
139
|
+
getById: getDroppableById,
|
|
140
|
+
findById: findDroppableById,
|
|
141
|
+
exists: (id: DroppableId): boolean => Boolean(findDroppableById(id)),
|
|
142
|
+
getAllByType: (type: TypeId): DroppableEntry[] =>
|
|
143
|
+
values(entries.droppables).filter(
|
|
144
|
+
(entry: DroppableEntry): boolean => entry.descriptor.type === type,
|
|
145
|
+
),
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
function clean(): void {
|
|
149
|
+
// kill entries
|
|
150
|
+
entries.draggables = {};
|
|
151
|
+
entries.droppables = {};
|
|
152
|
+
// remove all subscribers
|
|
153
|
+
subscribers.length = 0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
draggable: draggableAPI,
|
|
158
|
+
droppable: droppableAPI,
|
|
159
|
+
subscribe,
|
|
160
|
+
clean,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Position } from 'css-box-model';
|
|
3
|
+
import type {
|
|
4
|
+
Id,
|
|
5
|
+
DraggableId,
|
|
6
|
+
DraggableDescriptor,
|
|
7
|
+
DraggableOptions,
|
|
8
|
+
DraggableDimension,
|
|
9
|
+
DroppableId,
|
|
10
|
+
ScrollOptions,
|
|
11
|
+
DroppableDescriptor,
|
|
12
|
+
DroppableDimension,
|
|
13
|
+
TypeId,
|
|
14
|
+
} from '../../types';
|
|
15
|
+
|
|
16
|
+
export type GetDraggableDimensionFn = (
|
|
17
|
+
windowScroll: Position,
|
|
18
|
+
) => DraggableDimension;
|
|
19
|
+
|
|
20
|
+
export type DraggableEntry = {|
|
|
21
|
+
uniqueId: Id,
|
|
22
|
+
descriptor: DraggableDescriptor,
|
|
23
|
+
options: DraggableOptions,
|
|
24
|
+
getDimension: GetDraggableDimensionFn,
|
|
25
|
+
|};
|
|
26
|
+
|
|
27
|
+
export type DraggableAPI = {|
|
|
28
|
+
register: (entry: DraggableEntry) => void,
|
|
29
|
+
update: (entry: DraggableEntry, last: DraggableEntry) => void,
|
|
30
|
+
unregister: (entry: DraggableEntry) => void,
|
|
31
|
+
exists: (id: DraggableId) => boolean,
|
|
32
|
+
getById: (id: DraggableId) => DraggableEntry,
|
|
33
|
+
findById: (id: DraggableId) => ?DraggableEntry,
|
|
34
|
+
getAllByType: (type: TypeId) => DraggableEntry[],
|
|
35
|
+
|};
|
|
36
|
+
|
|
37
|
+
export type GetDroppableDimensionFn = (
|
|
38
|
+
windowScroll: Position,
|
|
39
|
+
options: ScrollOptions,
|
|
40
|
+
) => DroppableDimension;
|
|
41
|
+
|
|
42
|
+
export type RecollectDroppableOptions = {|
|
|
43
|
+
withoutPlaceholder: boolean,
|
|
44
|
+
|};
|
|
45
|
+
|
|
46
|
+
export type DroppableCallbacks = {|
|
|
47
|
+
// a drag is starting
|
|
48
|
+
getDimensionAndWatchScroll: GetDroppableDimensionFn,
|
|
49
|
+
getScrollWhileDragging: () => Position,
|
|
50
|
+
// scroll a droppable
|
|
51
|
+
scroll: (change: Position) => void,
|
|
52
|
+
// If the Droppable is listening for scroll events - it needs to stop!
|
|
53
|
+
// Can be called on droppables that have not been asked to watch scroll
|
|
54
|
+
dragStopped: () => void,
|
|
55
|
+
|};
|
|
56
|
+
|
|
57
|
+
export type DroppableEntry = {|
|
|
58
|
+
uniqueId: Id,
|
|
59
|
+
descriptor: DroppableDescriptor,
|
|
60
|
+
callbacks: DroppableCallbacks,
|
|
61
|
+
|};
|
|
62
|
+
|
|
63
|
+
export type DraggableEntryMap = {
|
|
64
|
+
[id: DraggableId]: DraggableEntry,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type DroppableEntryMap = {
|
|
68
|
+
[id: DroppableId]: DroppableEntry,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type DroppableAPI = {|
|
|
72
|
+
register: (entry: DroppableEntry) => void,
|
|
73
|
+
unregister: (entry: DroppableEntry) => void,
|
|
74
|
+
exists: (id: DraggableId) => boolean,
|
|
75
|
+
getById: (id: DroppableId) => DroppableEntry,
|
|
76
|
+
findById: (id: DroppableId) => ?DroppableEntry,
|
|
77
|
+
getAllByType: (type: TypeId) => DroppableEntry[],
|
|
78
|
+
|};
|
|
79
|
+
|
|
80
|
+
export type RegistryEvent =
|
|
81
|
+
| {|
|
|
82
|
+
type: 'ADDITION',
|
|
83
|
+
value: DraggableEntry,
|
|
84
|
+
|}
|
|
85
|
+
| {|
|
|
86
|
+
type: 'REMOVAL',
|
|
87
|
+
value: DraggableEntry,
|
|
88
|
+
|};
|
|
89
|
+
|
|
90
|
+
export type Subscriber = (event: RegistryEvent) => void;
|
|
91
|
+
export type Unsubscribe = () => void;
|
|
92
|
+
|
|
93
|
+
export type Registry = {|
|
|
94
|
+
draggable: DraggableAPI,
|
|
95
|
+
droppable: DroppableAPI,
|
|
96
|
+
subscribe: (cb: Subscriber) => Unsubscribe,
|
|
97
|
+
clean: () => void,
|
|
98
|
+
|};
|