@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,372 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position } from 'css-box-model';
|
|
3
|
+
// eslint-disable-next-line
|
|
4
|
+
import { Component } from 'react';
|
|
5
|
+
import memoizeOne from 'memoize-one';
|
|
6
|
+
import { connect } from 'react-redux';
|
|
7
|
+
import Draggable from './draggable';
|
|
8
|
+
import { origin, negate } from '../../state/position';
|
|
9
|
+
import isStrictEqual from '../is-strict-equal';
|
|
10
|
+
import * as animation from '../../animation';
|
|
11
|
+
import { dropAnimationFinished as dropAnimationFinishedAction } from '../../state/action-creators';
|
|
12
|
+
import type {
|
|
13
|
+
State,
|
|
14
|
+
DraggableId,
|
|
15
|
+
DroppableId,
|
|
16
|
+
DraggableDimension,
|
|
17
|
+
Displacement,
|
|
18
|
+
CompletedDrag,
|
|
19
|
+
DragImpact,
|
|
20
|
+
MovementMode,
|
|
21
|
+
DropResult,
|
|
22
|
+
LiftEffect,
|
|
23
|
+
Combine,
|
|
24
|
+
} from '../../types';
|
|
25
|
+
import type {
|
|
26
|
+
MapProps,
|
|
27
|
+
OwnProps,
|
|
28
|
+
DispatchProps,
|
|
29
|
+
Selector,
|
|
30
|
+
StateSnapshot,
|
|
31
|
+
DropAnimation,
|
|
32
|
+
} from './draggable-types';
|
|
33
|
+
import whatIsDraggedOver from '../../state/droppable/what-is-dragged-over';
|
|
34
|
+
import StoreContext from '../context/store-context';
|
|
35
|
+
import whatIsDraggedOverFromResult from '../../state/droppable/what-is-dragged-over-from-result';
|
|
36
|
+
import { tryGetCombine } from '../../state/get-impact-location';
|
|
37
|
+
|
|
38
|
+
const getCombineWithFromResult = (result: DropResult): ?DraggableId => {
|
|
39
|
+
return result.combine ? result.combine.draggableId : null;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const getCombineWithFromImpact = (impact: DragImpact): ?DraggableId => {
|
|
43
|
+
return impact.at && impact.at.type === 'COMBINE'
|
|
44
|
+
? impact.at.combine.draggableId
|
|
45
|
+
: null;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
type TrySelect = (state: State, ownProps: OwnProps) => ?MapProps;
|
|
49
|
+
|
|
50
|
+
function getDraggableSelector(): TrySelect {
|
|
51
|
+
const memoizedOffset = memoizeOne((x: number, y: number): Position => ({
|
|
52
|
+
x,
|
|
53
|
+
y,
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
const getMemoizedSnapshot = memoizeOne(
|
|
57
|
+
(
|
|
58
|
+
mode: MovementMode,
|
|
59
|
+
isClone: boolean,
|
|
60
|
+
draggingOver: ?DroppableId,
|
|
61
|
+
combineWith: ?DraggableId,
|
|
62
|
+
dropping: ?DropAnimation,
|
|
63
|
+
): StateSnapshot => ({
|
|
64
|
+
isDragging: true,
|
|
65
|
+
isClone,
|
|
66
|
+
isDropAnimating: Boolean(dropping),
|
|
67
|
+
dropAnimation: dropping,
|
|
68
|
+
mode,
|
|
69
|
+
draggingOver,
|
|
70
|
+
combineWith,
|
|
71
|
+
combineTargetFor: null,
|
|
72
|
+
}),
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const getMemoizedProps = memoizeOne((
|
|
76
|
+
offset: Position,
|
|
77
|
+
mode: MovementMode,
|
|
78
|
+
dimension: DraggableDimension,
|
|
79
|
+
isClone: boolean,
|
|
80
|
+
// the id of the droppable you are over
|
|
81
|
+
draggingOver: ?DroppableId,
|
|
82
|
+
// the id of a draggable you are grouping with
|
|
83
|
+
combineWith: ?DraggableId,
|
|
84
|
+
forceShouldAnimate: ?boolean,
|
|
85
|
+
): MapProps => ({
|
|
86
|
+
mapped: {
|
|
87
|
+
type: 'DRAGGING',
|
|
88
|
+
dropping: null,
|
|
89
|
+
draggingOver,
|
|
90
|
+
combineWith,
|
|
91
|
+
mode,
|
|
92
|
+
offset,
|
|
93
|
+
dimension,
|
|
94
|
+
forceShouldAnimate,
|
|
95
|
+
snapshot: getMemoizedSnapshot(
|
|
96
|
+
mode,
|
|
97
|
+
isClone,
|
|
98
|
+
draggingOver,
|
|
99
|
+
combineWith,
|
|
100
|
+
null,
|
|
101
|
+
),
|
|
102
|
+
},
|
|
103
|
+
}));
|
|
104
|
+
|
|
105
|
+
const selector: TrySelect = (state: State, ownProps: OwnProps): ?MapProps => {
|
|
106
|
+
// Dragging
|
|
107
|
+
if (state.isDragging) {
|
|
108
|
+
// not the dragging item
|
|
109
|
+
if (state.critical.draggable.id !== ownProps.draggableId) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const offset: Position = state.current.client.offset;
|
|
114
|
+
const dimension: DraggableDimension =
|
|
115
|
+
state.dimensions.draggables[ownProps.draggableId];
|
|
116
|
+
// const shouldAnimateDragMovement: boolean = state.shouldAnimate;
|
|
117
|
+
const draggingOver: ?DroppableId = whatIsDraggedOver(state.impact);
|
|
118
|
+
const combineWith: ?DraggableId = getCombineWithFromImpact(state.impact);
|
|
119
|
+
const forceShouldAnimate: ?boolean = state.forceShouldAnimate;
|
|
120
|
+
|
|
121
|
+
return getMemoizedProps(
|
|
122
|
+
memoizedOffset(offset.x, offset.y),
|
|
123
|
+
state.movementMode,
|
|
124
|
+
dimension,
|
|
125
|
+
ownProps.isClone,
|
|
126
|
+
draggingOver,
|
|
127
|
+
combineWith,
|
|
128
|
+
forceShouldAnimate,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Dropping
|
|
133
|
+
if (state.phase === 'DROP_ANIMATING') {
|
|
134
|
+
const completed: CompletedDrag = state.completed;
|
|
135
|
+
if (completed.result.draggableId !== ownProps.draggableId) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const isClone: boolean = ownProps.isClone;
|
|
140
|
+
const dimension: DraggableDimension =
|
|
141
|
+
state.dimensions.draggables[ownProps.draggableId];
|
|
142
|
+
const result: DropResult = completed.result;
|
|
143
|
+
const mode: MovementMode = result.mode;
|
|
144
|
+
// these need to be pulled from the result as they can be different to the final impact
|
|
145
|
+
const draggingOver: ?DroppableId = whatIsDraggedOverFromResult(result);
|
|
146
|
+
const combineWith: ?DraggableId = getCombineWithFromResult(result);
|
|
147
|
+
const duration: number = state.dropDuration;
|
|
148
|
+
|
|
149
|
+
// not memoized as it is the only execution
|
|
150
|
+
const dropping: DropAnimation = {
|
|
151
|
+
duration,
|
|
152
|
+
curve: animation.curves.drop,
|
|
153
|
+
moveTo: state.newHomeClientOffset,
|
|
154
|
+
opacity: combineWith ? animation.combine.opacity.drop : null,
|
|
155
|
+
scale: combineWith ? animation.combine.scale.drop : null,
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
mapped: {
|
|
160
|
+
type: 'DRAGGING',
|
|
161
|
+
offset: state.newHomeClientOffset,
|
|
162
|
+
dimension,
|
|
163
|
+
dropping,
|
|
164
|
+
draggingOver,
|
|
165
|
+
combineWith,
|
|
166
|
+
mode,
|
|
167
|
+
forceShouldAnimate: null,
|
|
168
|
+
snapshot: getMemoizedSnapshot(
|
|
169
|
+
mode,
|
|
170
|
+
isClone,
|
|
171
|
+
draggingOver,
|
|
172
|
+
combineWith,
|
|
173
|
+
dropping,
|
|
174
|
+
),
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return null;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
return selector;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function getSecondarySnapshot(combineTargetFor: ?DraggableId): StateSnapshot {
|
|
186
|
+
return {
|
|
187
|
+
isDragging: false,
|
|
188
|
+
isDropAnimating: false,
|
|
189
|
+
isClone: false,
|
|
190
|
+
dropAnimation: null,
|
|
191
|
+
mode: null,
|
|
192
|
+
draggingOver: null,
|
|
193
|
+
combineTargetFor,
|
|
194
|
+
combineWith: null,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const atRest: MapProps = {
|
|
199
|
+
mapped: {
|
|
200
|
+
type: 'SECONDARY',
|
|
201
|
+
offset: origin,
|
|
202
|
+
combineTargetFor: null,
|
|
203
|
+
shouldAnimateDisplacement: true,
|
|
204
|
+
snapshot: getSecondarySnapshot(null),
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
function getSecondarySelector(): TrySelect {
|
|
209
|
+
const memoizedOffset = memoizeOne((x: number, y: number): Position => ({
|
|
210
|
+
x,
|
|
211
|
+
y,
|
|
212
|
+
}));
|
|
213
|
+
|
|
214
|
+
const getMemoizedSnapshot = memoizeOne(getSecondarySnapshot);
|
|
215
|
+
|
|
216
|
+
const getMemoizedProps = memoizeOne(
|
|
217
|
+
(
|
|
218
|
+
offset: Position,
|
|
219
|
+
combineTargetFor: ?DraggableId = null,
|
|
220
|
+
shouldAnimateDisplacement: boolean,
|
|
221
|
+
): MapProps => ({
|
|
222
|
+
mapped: {
|
|
223
|
+
type: 'SECONDARY',
|
|
224
|
+
offset,
|
|
225
|
+
combineTargetFor,
|
|
226
|
+
shouldAnimateDisplacement,
|
|
227
|
+
snapshot: getMemoizedSnapshot(combineTargetFor),
|
|
228
|
+
},
|
|
229
|
+
}),
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// Is we are the combine target for something then we need to publish that
|
|
233
|
+
// otherwise we will return null to get the default props
|
|
234
|
+
const getFallback = (combineTargetFor: ?DraggableId): ?MapProps => {
|
|
235
|
+
return combineTargetFor
|
|
236
|
+
? getMemoizedProps(origin, combineTargetFor, true)
|
|
237
|
+
: null;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const getProps = (
|
|
241
|
+
ownId: DraggableId,
|
|
242
|
+
draggingId: DraggableId,
|
|
243
|
+
impact: DragImpact,
|
|
244
|
+
afterCritical: LiftEffect,
|
|
245
|
+
): ?MapProps => {
|
|
246
|
+
const visualDisplacement: ?Displacement = impact.displaced.visible[ownId];
|
|
247
|
+
const isAfterCriticalInVirtualList: boolean = Boolean(
|
|
248
|
+
afterCritical.inVirtualList && afterCritical.effected[ownId],
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const combine: ?Combine = tryGetCombine(impact);
|
|
252
|
+
const combineTargetFor: ?DraggableId =
|
|
253
|
+
combine && combine.draggableId === ownId ? draggingId : null;
|
|
254
|
+
|
|
255
|
+
if (!visualDisplacement) {
|
|
256
|
+
if (!isAfterCriticalInVirtualList) {
|
|
257
|
+
return getFallback(combineTargetFor);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// After critical but not visibly displaced in a virtual list
|
|
261
|
+
// This can occur if:
|
|
262
|
+
// 1. the item is not visible (displaced.invisible)
|
|
263
|
+
// 2. We have moved out of the home list.
|
|
264
|
+
|
|
265
|
+
// Don't need to do anything - item is invisible
|
|
266
|
+
if (impact.displaced.invisible[ownId]) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// We are no longer over the home list.
|
|
271
|
+
// We need to move backwards to close the gap that the dragging item has left
|
|
272
|
+
const change: Position = negate(afterCritical.displacedBy.point);
|
|
273
|
+
const offset: Position = memoizedOffset(change.x, change.y);
|
|
274
|
+
return getMemoizedProps(offset, combineTargetFor, true);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (isAfterCriticalInVirtualList) {
|
|
278
|
+
// In a virtual list the removal of a dragging item does
|
|
279
|
+
// not cause the list to collapse. So when something is 'displaced'
|
|
280
|
+
// we can just leave it in the original spot.
|
|
281
|
+
return getFallback(combineTargetFor);
|
|
282
|
+
}
|
|
283
|
+
const displaceBy: Position = impact.displacedBy.point;
|
|
284
|
+
const offset: Position = memoizedOffset(displaceBy.x, displaceBy.y);
|
|
285
|
+
|
|
286
|
+
return getMemoizedProps(
|
|
287
|
+
offset,
|
|
288
|
+
combineTargetFor,
|
|
289
|
+
visualDisplacement.shouldAnimate,
|
|
290
|
+
);
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const selector: TrySelect = (state: State, ownProps: OwnProps): ?MapProps => {
|
|
294
|
+
// Dragging
|
|
295
|
+
if (state.isDragging) {
|
|
296
|
+
// we do not care about the dragging item
|
|
297
|
+
if (state.critical.draggable.id === ownProps.draggableId) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return getProps(
|
|
302
|
+
ownProps.draggableId,
|
|
303
|
+
state.critical.draggable.id,
|
|
304
|
+
state.impact,
|
|
305
|
+
state.afterCritical,
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Dropping
|
|
310
|
+
if (state.phase === 'DROP_ANIMATING') {
|
|
311
|
+
const completed: CompletedDrag = state.completed;
|
|
312
|
+
// do nothing if this was the dragging item
|
|
313
|
+
if (completed.result.draggableId === ownProps.draggableId) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
return getProps(
|
|
317
|
+
ownProps.draggableId,
|
|
318
|
+
completed.result.draggableId,
|
|
319
|
+
completed.impact,
|
|
320
|
+
completed.afterCritical,
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Otherwise
|
|
325
|
+
return null;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
return selector;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Returning a function to ensure each
|
|
332
|
+
// Draggable gets its own selector
|
|
333
|
+
export const makeMapStateToProps = (): Selector => {
|
|
334
|
+
const draggingSelector: TrySelect = getDraggableSelector();
|
|
335
|
+
const secondarySelector: TrySelect = getSecondarySelector();
|
|
336
|
+
|
|
337
|
+
const selector = (state: State, ownProps: OwnProps): MapProps =>
|
|
338
|
+
draggingSelector(state, ownProps) ||
|
|
339
|
+
secondarySelector(state, ownProps) ||
|
|
340
|
+
atRest;
|
|
341
|
+
|
|
342
|
+
return selector;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const mapDispatchToProps: DispatchProps = {
|
|
346
|
+
dropAnimationFinished: dropAnimationFinishedAction,
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
// Leaning heavily on the default shallow equality checking
|
|
350
|
+
// that `connect` provides.
|
|
351
|
+
// It avoids needing to do it own within `<Draggable />`
|
|
352
|
+
const ConnectedDraggable = connect(
|
|
353
|
+
// returning a function so each component can do its own memoization
|
|
354
|
+
makeMapStateToProps,
|
|
355
|
+
mapDispatchToProps,
|
|
356
|
+
// mergeProps: use default
|
|
357
|
+
null,
|
|
358
|
+
// options
|
|
359
|
+
// $FlowFixMe: current react-redux type does not know about context property
|
|
360
|
+
{
|
|
361
|
+
// Using our own context for the store to avoid clashing with consumers
|
|
362
|
+
context: StoreContext,
|
|
363
|
+
// Default value, but being really clear
|
|
364
|
+
pure: true,
|
|
365
|
+
// When pure, compares the result of mapStateToProps to its previous value.
|
|
366
|
+
// Default value: shallowEqual
|
|
367
|
+
// Switching to a strictEqual as we return a memoized object on changes
|
|
368
|
+
areStatePropsEqual: isStrictEqual,
|
|
369
|
+
},
|
|
370
|
+
)(Draggable);
|
|
371
|
+
|
|
372
|
+
export default ConnectedDraggable;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { DraggableId } from '../../types';
|
|
4
|
+
import type { PublicOwnProps, PrivateOwnProps } from './draggable-types';
|
|
5
|
+
import ConnectedDraggable from './connected-draggable';
|
|
6
|
+
import useRequiredContext from '../use-required-context';
|
|
7
|
+
import DroppableContext, {
|
|
8
|
+
type DroppableContextValue,
|
|
9
|
+
} from '../context/droppable-context';
|
|
10
|
+
|
|
11
|
+
// We can use this to render a draggable with more control
|
|
12
|
+
// It is used by a Droppable to render a clone
|
|
13
|
+
export function PrivateDraggable(props: PrivateOwnProps) {
|
|
14
|
+
const droppableContext: DroppableContextValue = useRequiredContext(
|
|
15
|
+
DroppableContext,
|
|
16
|
+
);
|
|
17
|
+
// The droppable can render a clone of the draggable item.
|
|
18
|
+
// In that case we unmount the existing dragging item
|
|
19
|
+
const isUsingCloneFor: ?DraggableId = droppableContext.isUsingCloneFor;
|
|
20
|
+
if (isUsingCloneFor === props.draggableId && !props.isClone) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return <ConnectedDraggable {...props} />;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// What we give to consumers
|
|
28
|
+
export function PublicDraggable(props: PublicOwnProps) {
|
|
29
|
+
// default values for props
|
|
30
|
+
const isEnabled: boolean =
|
|
31
|
+
typeof props.isDragDisabled === 'boolean' ? !props.isDragDisabled : true;
|
|
32
|
+
const canDragInteractiveElements: boolean = Boolean(
|
|
33
|
+
props.disableInteractiveElementBlocking,
|
|
34
|
+
);
|
|
35
|
+
const shouldRespectForcePress: boolean = Boolean(
|
|
36
|
+
props.shouldRespectForcePress,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<PrivateDraggable
|
|
41
|
+
{...props}
|
|
42
|
+
isClone={false}
|
|
43
|
+
isEnabled={isEnabled}
|
|
44
|
+
canDragInteractiveElements={canDragInteractiveElements}
|
|
45
|
+
shouldRespectForcePress={shouldRespectForcePress}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position } from 'css-box-model';
|
|
3
|
+
import { type Node } from 'react';
|
|
4
|
+
import type {
|
|
5
|
+
DraggableId,
|
|
6
|
+
DroppableId,
|
|
7
|
+
DraggableDimension,
|
|
8
|
+
State,
|
|
9
|
+
MovementMode,
|
|
10
|
+
ContextId,
|
|
11
|
+
ElementId,
|
|
12
|
+
DraggableRubric,
|
|
13
|
+
} from '../../types';
|
|
14
|
+
import { dropAnimationFinished } from '../../state/action-creators';
|
|
15
|
+
|
|
16
|
+
export type DraggingStyle = {|
|
|
17
|
+
position: 'fixed',
|
|
18
|
+
top: number,
|
|
19
|
+
left: number,
|
|
20
|
+
boxSizing: 'border-box',
|
|
21
|
+
width: number,
|
|
22
|
+
height: number,
|
|
23
|
+
transition: string,
|
|
24
|
+
transform: ?string,
|
|
25
|
+
zIndex: number,
|
|
26
|
+
|
|
27
|
+
// for combining
|
|
28
|
+
opacity: ?number,
|
|
29
|
+
|
|
30
|
+
// Avoiding any processing of mouse events.
|
|
31
|
+
// This is already applied by the shared styles during a drag.
|
|
32
|
+
// During a drop it prevents a draggable from being dragged.
|
|
33
|
+
// canStartDrag() will prevent drags in some cases for non primary draggable.
|
|
34
|
+
// It is also a minor performance optimisation
|
|
35
|
+
pointerEvents: 'none',
|
|
36
|
+
|};
|
|
37
|
+
|
|
38
|
+
export type NotDraggingStyle = {|
|
|
39
|
+
transform: ?string,
|
|
40
|
+
// null: use the global animation style
|
|
41
|
+
// none: skip animation (used in certain displacement situations)
|
|
42
|
+
transition: null | 'none',
|
|
43
|
+
|};
|
|
44
|
+
|
|
45
|
+
export type DraggableStyle = DraggingStyle | NotDraggingStyle;
|
|
46
|
+
|
|
47
|
+
export type ZIndexOptions = {|
|
|
48
|
+
dragging: number,
|
|
49
|
+
dropAnimating: number,
|
|
50
|
+
|};
|
|
51
|
+
|
|
52
|
+
// Props that can be spread onto the element directly
|
|
53
|
+
export type DraggableProps = {|
|
|
54
|
+
// inline style
|
|
55
|
+
style: ?DraggableStyle,
|
|
56
|
+
// used for shared global styles
|
|
57
|
+
'data-rbd-draggable-context-id': ContextId,
|
|
58
|
+
// used for lookups
|
|
59
|
+
'data-rbd-draggable-id': DraggableId,
|
|
60
|
+
// used to know when a transition ends
|
|
61
|
+
onTransitionEnd: ?(event: TransitionEvent) => void,
|
|
62
|
+
|};
|
|
63
|
+
|
|
64
|
+
export type DragHandleProps = {|
|
|
65
|
+
// what draggable the handle belongs to
|
|
66
|
+
'data-rbd-drag-handle-draggable-id': DraggableId,
|
|
67
|
+
|
|
68
|
+
// What DragDropContext the drag handle is in
|
|
69
|
+
'data-rbd-drag-handle-context-id': ContextId,
|
|
70
|
+
|
|
71
|
+
// We need a drag handle to be a widget in order to correctly set accessibility properties
|
|
72
|
+
// Note: JAWS and VoiceOver don't need the element to be a 'widget' to read the accessibility properties, but NVDA does
|
|
73
|
+
// Using `role="button"` but leaving the public API as a string to allow for changing without a major
|
|
74
|
+
role: string,
|
|
75
|
+
|
|
76
|
+
// Overriding default role to have a more descriptive text ("Draggable item")
|
|
77
|
+
// Sadly we cannot use this right now due an issue with lighthouse
|
|
78
|
+
// https://github.com/atlassian/react-beautiful-dnd/issues/1742
|
|
79
|
+
// 'aria-roledescription': string,
|
|
80
|
+
|
|
81
|
+
// Using the description property of the drag handle to provide usage instructions
|
|
82
|
+
'aria-describedby': ElementId,
|
|
83
|
+
|
|
84
|
+
// Allow tabbing to this element
|
|
85
|
+
// Adding a tab index marks the element as interactive content: https://www.w3.org/TR/html51/dom.html#kinds-of-content-interactive-content
|
|
86
|
+
tabIndex: number,
|
|
87
|
+
|
|
88
|
+
// Opting out of html5 drag and drop
|
|
89
|
+
draggable: boolean,
|
|
90
|
+
onDragStart: (event: DragEvent) => void,
|
|
91
|
+
|};
|
|
92
|
+
|
|
93
|
+
export type Provided = {|
|
|
94
|
+
draggableProps: DraggableProps,
|
|
95
|
+
// will be null if the draggable is disabled
|
|
96
|
+
dragHandleProps: ?DragHandleProps,
|
|
97
|
+
// The following props will be removed once we move to react 16
|
|
98
|
+
innerRef: (?HTMLElement) => void,
|
|
99
|
+
|};
|
|
100
|
+
|
|
101
|
+
// to easily enable patching of styles
|
|
102
|
+
export type DropAnimation = {|
|
|
103
|
+
duration: number,
|
|
104
|
+
curve: string,
|
|
105
|
+
moveTo: Position,
|
|
106
|
+
opacity: ?number,
|
|
107
|
+
scale: ?number,
|
|
108
|
+
|};
|
|
109
|
+
|
|
110
|
+
export type StateSnapshot = {|
|
|
111
|
+
isDragging: boolean,
|
|
112
|
+
isDropAnimating: boolean,
|
|
113
|
+
isClone: boolean,
|
|
114
|
+
dropAnimation: ?DropAnimation,
|
|
115
|
+
draggingOver: ?DroppableId,
|
|
116
|
+
combineWith: ?DraggableId,
|
|
117
|
+
combineTargetFor: ?DraggableId,
|
|
118
|
+
mode: ?MovementMode,
|
|
119
|
+
|};
|
|
120
|
+
|
|
121
|
+
export type DispatchProps = {|
|
|
122
|
+
dropAnimationFinished: typeof dropAnimationFinished,
|
|
123
|
+
|};
|
|
124
|
+
|
|
125
|
+
export type DraggingMapProps = {|
|
|
126
|
+
type: 'DRAGGING',
|
|
127
|
+
offset: Position,
|
|
128
|
+
mode: MovementMode,
|
|
129
|
+
dropping: ?DropAnimation,
|
|
130
|
+
draggingOver: ?DraggableId,
|
|
131
|
+
combineWith: ?DraggableId,
|
|
132
|
+
dimension: DraggableDimension,
|
|
133
|
+
forceShouldAnimate: ?boolean,
|
|
134
|
+
snapshot: StateSnapshot,
|
|
135
|
+
|};
|
|
136
|
+
|
|
137
|
+
export type SecondaryMapProps = {|
|
|
138
|
+
type: 'SECONDARY',
|
|
139
|
+
offset: Position,
|
|
140
|
+
combineTargetFor: ?DraggableId,
|
|
141
|
+
shouldAnimateDisplacement: boolean,
|
|
142
|
+
snapshot: StateSnapshot,
|
|
143
|
+
|};
|
|
144
|
+
|
|
145
|
+
export type MappedProps = DraggingMapProps | SecondaryMapProps;
|
|
146
|
+
|
|
147
|
+
export type MapProps = {|
|
|
148
|
+
// when an item is being displaced by a dragging item,
|
|
149
|
+
// we need to know if that movement should be animated
|
|
150
|
+
mapped: MappedProps,
|
|
151
|
+
// dragging: ?DraggingMapProps,
|
|
152
|
+
// secondary: ?SecondaryMapProps,
|
|
153
|
+
|};
|
|
154
|
+
|
|
155
|
+
export type ChildrenFn = (
|
|
156
|
+
Provided,
|
|
157
|
+
StateSnapshot,
|
|
158
|
+
DraggableRubric,
|
|
159
|
+
) => Node | null;
|
|
160
|
+
|
|
161
|
+
export type PublicOwnProps = {|
|
|
162
|
+
draggableId: DraggableId,
|
|
163
|
+
index: number,
|
|
164
|
+
children: ChildrenFn,
|
|
165
|
+
|
|
166
|
+
// optional own props
|
|
167
|
+
isDragDisabled?: boolean,
|
|
168
|
+
disableInteractiveElementBlocking?: boolean,
|
|
169
|
+
shouldRespectForcePress?: boolean,
|
|
170
|
+
|};
|
|
171
|
+
|
|
172
|
+
export type PrivateOwnProps = {|
|
|
173
|
+
...PublicOwnProps,
|
|
174
|
+
isClone: boolean,
|
|
175
|
+
// no longer optional
|
|
176
|
+
isEnabled: boolean,
|
|
177
|
+
canDragInteractiveElements: boolean,
|
|
178
|
+
shouldRespectForcePress: boolean,
|
|
179
|
+
|};
|
|
180
|
+
|
|
181
|
+
export type OwnProps = {|
|
|
182
|
+
...PrivateOwnProps,
|
|
183
|
+
|};
|
|
184
|
+
|
|
185
|
+
export type Props = {|
|
|
186
|
+
...MapProps,
|
|
187
|
+
...DispatchProps,
|
|
188
|
+
...OwnProps,
|
|
189
|
+
|};
|
|
190
|
+
|
|
191
|
+
export type Selector = (state: State, ownProps: OwnProps) => MapProps;
|