@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,20 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { useMemo } from 'use-memo-one';
|
|
4
|
+
import type { Registry } from './registry-types';
|
|
5
|
+
import createRegistry from './create-registry';
|
|
6
|
+
|
|
7
|
+
export default function useRegistry(): Registry {
|
|
8
|
+
const registry: Registry = useMemo(createRegistry, []);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
return function unmount() {
|
|
12
|
+
// clean up the registry to avoid any leaks
|
|
13
|
+
// doing it after an animation frame so that other things unmounting
|
|
14
|
+
// can continue to interact with the registry
|
|
15
|
+
requestAnimationFrame(registry.clean);
|
|
16
|
+
};
|
|
17
|
+
}, [registry]);
|
|
18
|
+
|
|
19
|
+
return registry;
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import memoizeOne from 'memoize-one';
|
|
3
|
+
import type { DraggableDimension } from '../types';
|
|
4
|
+
|
|
5
|
+
export default memoizeOne(
|
|
6
|
+
(
|
|
7
|
+
remove: DraggableDimension,
|
|
8
|
+
list: DraggableDimension[],
|
|
9
|
+
): DraggableDimension[] =>
|
|
10
|
+
list.filter(
|
|
11
|
+
(item: DraggableDimension) => item.descriptor.id !== remove.descriptor.id,
|
|
12
|
+
),
|
|
13
|
+
);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { getRect, type Rect } from 'css-box-model';
|
|
3
|
+
import type { Position } from 'css-box-model';
|
|
4
|
+
import { subtract, negate } from './position';
|
|
5
|
+
import type { Viewport } from '../types';
|
|
6
|
+
|
|
7
|
+
export default (viewport: Viewport, newScroll: Position): Viewport => {
|
|
8
|
+
const diff: Position = subtract(newScroll, viewport.scroll.initial);
|
|
9
|
+
const displacement: Position = negate(diff);
|
|
10
|
+
|
|
11
|
+
// We need to update the frame so that it is always a live value
|
|
12
|
+
// The top / left of the frame should always match the newScroll position
|
|
13
|
+
const frame: Rect = getRect({
|
|
14
|
+
top: newScroll.y,
|
|
15
|
+
bottom: newScroll.y + viewport.frame.height,
|
|
16
|
+
left: newScroll.x,
|
|
17
|
+
right: newScroll.x + viewport.frame.width,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const updated: Viewport = {
|
|
21
|
+
frame,
|
|
22
|
+
scroll: {
|
|
23
|
+
initial: viewport.scroll.initial,
|
|
24
|
+
max: viewport.scroll.max,
|
|
25
|
+
current: newScroll,
|
|
26
|
+
diff: {
|
|
27
|
+
value: diff,
|
|
28
|
+
displacement,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return updated;
|
|
34
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Spacing, Position } from 'css-box-model';
|
|
3
|
+
|
|
4
|
+
// TODO add test
|
|
5
|
+
export const isEqual = (first: Spacing, second: Spacing): boolean =>
|
|
6
|
+
first.top === second.top &&
|
|
7
|
+
first.right === second.right &&
|
|
8
|
+
first.bottom === second.bottom &&
|
|
9
|
+
first.left === second.left;
|
|
10
|
+
|
|
11
|
+
export const offsetByPosition = (
|
|
12
|
+
spacing: Spacing,
|
|
13
|
+
point: Position,
|
|
14
|
+
): Spacing => ({
|
|
15
|
+
top: spacing.top + point.y,
|
|
16
|
+
left: spacing.left + point.x,
|
|
17
|
+
bottom: spacing.bottom + point.y,
|
|
18
|
+
right: spacing.right + point.x,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const expandByPosition = (
|
|
22
|
+
spacing: Spacing,
|
|
23
|
+
position: Position,
|
|
24
|
+
): Spacing => ({
|
|
25
|
+
// pulling back to increase size
|
|
26
|
+
top: spacing.top - position.y,
|
|
27
|
+
left: spacing.left - position.x,
|
|
28
|
+
// pushing forward to increase size
|
|
29
|
+
right: spacing.right + position.x,
|
|
30
|
+
bottom: spacing.bottom + position.y,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export const getCorners = (spacing: Spacing): Position[] => [
|
|
34
|
+
{ x: spacing.left, y: spacing.top },
|
|
35
|
+
{ x: spacing.right, y: spacing.top },
|
|
36
|
+
{ x: spacing.left, y: spacing.bottom },
|
|
37
|
+
{ x: spacing.right, y: spacing.bottom },
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export const noSpacing: Spacing = {
|
|
41
|
+
top: 0,
|
|
42
|
+
right: 0,
|
|
43
|
+
bottom: 0,
|
|
44
|
+
left: 0,
|
|
45
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
// This file exists to avoid a circular dependency between types.js and action-creators.js
|
|
3
|
+
import type {
|
|
4
|
+
Store as ReduxStore,
|
|
5
|
+
Dispatch as ReduxDispatch,
|
|
6
|
+
Middleware as ReduxMiddleware,
|
|
7
|
+
MiddlewareAPI as ReduxMiddlewareAPI,
|
|
8
|
+
} from 'redux';
|
|
9
|
+
import type { Action as ActionCreators } from './action-creators';
|
|
10
|
+
import type { State } from '../types';
|
|
11
|
+
|
|
12
|
+
export type Action = ActionCreators;
|
|
13
|
+
export type Dispatch = ReduxDispatch<Action>;
|
|
14
|
+
export type Store = ReduxStore<State, Action, Dispatch>;
|
|
15
|
+
export type Middleware = ReduxMiddleware<State, Action, Dispatch>;
|
|
16
|
+
export type MiddlewareStore = ReduxMiddlewareAPI<State, Action, Dispatch>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type {
|
|
3
|
+
DraggableDimension,
|
|
4
|
+
DroppableDimension,
|
|
5
|
+
DraggableDimensionMap,
|
|
6
|
+
DragImpact,
|
|
7
|
+
Viewport,
|
|
8
|
+
DraggableId,
|
|
9
|
+
DisplacementGroups,
|
|
10
|
+
} from '../../types';
|
|
11
|
+
import getDisplacementGroups from '../get-displacement-groups';
|
|
12
|
+
|
|
13
|
+
type RecomputeArgs = {|
|
|
14
|
+
impact: DragImpact,
|
|
15
|
+
draggables: DraggableDimensionMap,
|
|
16
|
+
destination: DroppableDimension,
|
|
17
|
+
viewport: Viewport,
|
|
18
|
+
forceShouldAnimate?: boolean,
|
|
19
|
+
|};
|
|
20
|
+
|
|
21
|
+
function getDraggables(
|
|
22
|
+
ids: DraggableId[],
|
|
23
|
+
draggables: DraggableDimensionMap,
|
|
24
|
+
): DraggableDimension[] {
|
|
25
|
+
return ids.map((id: DraggableId): DraggableDimension => draggables[id]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default ({
|
|
29
|
+
impact,
|
|
30
|
+
viewport,
|
|
31
|
+
draggables,
|
|
32
|
+
destination,
|
|
33
|
+
forceShouldAnimate,
|
|
34
|
+
}: RecomputeArgs): DragImpact => {
|
|
35
|
+
const last: DisplacementGroups = impact.displaced;
|
|
36
|
+
const afterDragging: DraggableDimension[] = getDraggables(
|
|
37
|
+
last.all,
|
|
38
|
+
draggables,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const displaced: DisplacementGroups = getDisplacementGroups({
|
|
42
|
+
afterDragging,
|
|
43
|
+
destination,
|
|
44
|
+
displacedBy: impact.displacedBy,
|
|
45
|
+
viewport: viewport.frame,
|
|
46
|
+
forceShouldAnimate,
|
|
47
|
+
last,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
...impact,
|
|
52
|
+
displaced,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Position } from 'css-box-model';
|
|
3
|
+
import type {
|
|
4
|
+
DraggableId,
|
|
5
|
+
DroppableDimension,
|
|
6
|
+
DraggableDimension,
|
|
7
|
+
DraggableDimensionMap,
|
|
8
|
+
DragImpact,
|
|
9
|
+
Displacement,
|
|
10
|
+
DisplacementGroups,
|
|
11
|
+
DraggableIdMap,
|
|
12
|
+
DisplacementMap,
|
|
13
|
+
Viewport,
|
|
14
|
+
} from '../../types';
|
|
15
|
+
import scrollViewport from '../scroll-viewport';
|
|
16
|
+
import scrollDroppable from '../droppable/scroll-droppable';
|
|
17
|
+
import { add } from '../position';
|
|
18
|
+
import getDisplacementGroups from '../get-displacement-groups';
|
|
19
|
+
|
|
20
|
+
type SpeculativeArgs = {|
|
|
21
|
+
impact: DragImpact,
|
|
22
|
+
destination: DroppableDimension,
|
|
23
|
+
viewport: Viewport,
|
|
24
|
+
draggables: DraggableDimensionMap,
|
|
25
|
+
maxScrollChange: Position,
|
|
26
|
+
|};
|
|
27
|
+
|
|
28
|
+
function getDraggables(
|
|
29
|
+
ids: DraggableId[],
|
|
30
|
+
draggables: DraggableDimensionMap,
|
|
31
|
+
): DraggableDimension[] {
|
|
32
|
+
return ids.map((id: DraggableId): DraggableDimension => draggables[id]);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function tryGetVisible(
|
|
36
|
+
id: DraggableId,
|
|
37
|
+
groups: DisplacementGroups[],
|
|
38
|
+
): ?Displacement {
|
|
39
|
+
for (let i = 0; i < groups.length; i++) {
|
|
40
|
+
const displacement: ?Displacement = groups[i].visible[id];
|
|
41
|
+
if (displacement) {
|
|
42
|
+
return displacement;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default ({
|
|
49
|
+
impact,
|
|
50
|
+
viewport,
|
|
51
|
+
destination,
|
|
52
|
+
draggables,
|
|
53
|
+
maxScrollChange,
|
|
54
|
+
}: SpeculativeArgs): DragImpact => {
|
|
55
|
+
const scrolledViewport: Viewport = scrollViewport(
|
|
56
|
+
viewport,
|
|
57
|
+
add(viewport.scroll.current, maxScrollChange),
|
|
58
|
+
);
|
|
59
|
+
const scrolledDroppable: DroppableDimension = destination.frame
|
|
60
|
+
? scrollDroppable(
|
|
61
|
+
destination,
|
|
62
|
+
add(destination.frame.scroll.current, maxScrollChange),
|
|
63
|
+
)
|
|
64
|
+
: destination;
|
|
65
|
+
|
|
66
|
+
const last: DisplacementGroups = impact.displaced;
|
|
67
|
+
const withViewportScroll: DisplacementGroups = getDisplacementGroups({
|
|
68
|
+
afterDragging: getDraggables(last.all, draggables),
|
|
69
|
+
destination,
|
|
70
|
+
displacedBy: impact.displacedBy,
|
|
71
|
+
viewport: scrolledViewport.frame,
|
|
72
|
+
last,
|
|
73
|
+
// we want the addition to be animated
|
|
74
|
+
forceShouldAnimate: false,
|
|
75
|
+
});
|
|
76
|
+
const withDroppableScroll: DisplacementGroups = getDisplacementGroups({
|
|
77
|
+
afterDragging: getDraggables(last.all, draggables),
|
|
78
|
+
destination: scrolledDroppable,
|
|
79
|
+
displacedBy: impact.displacedBy,
|
|
80
|
+
viewport: viewport.frame,
|
|
81
|
+
last,
|
|
82
|
+
// we want the addition to be animated
|
|
83
|
+
forceShouldAnimate: false,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const invisible: DraggableIdMap = {};
|
|
87
|
+
const visible: DisplacementMap = {};
|
|
88
|
+
const groups: DisplacementGroups[] = [
|
|
89
|
+
// this will populate the previous entries with the correct animation values
|
|
90
|
+
last,
|
|
91
|
+
withViewportScroll,
|
|
92
|
+
withDroppableScroll,
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
last.all.forEach((id: DraggableId) => {
|
|
96
|
+
const displacement: ?Displacement = tryGetVisible(id, groups);
|
|
97
|
+
|
|
98
|
+
if (displacement) {
|
|
99
|
+
visible[id] = displacement;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
invisible[id] = true;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const newImpact: DragImpact = {
|
|
106
|
+
...impact,
|
|
107
|
+
displaced: { all: last.all, invisible, visible },
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
return newImpact;
|
|
111
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Spacing } from 'css-box-model';
|
|
3
|
+
import isWithin from '../is-within';
|
|
4
|
+
|
|
5
|
+
export default (frame: Spacing) => {
|
|
6
|
+
const isWithinVertical = isWithin(frame.top, frame.bottom);
|
|
7
|
+
const isWithinHorizontal = isWithin(frame.left, frame.right);
|
|
8
|
+
|
|
9
|
+
return (subject: Spacing) => {
|
|
10
|
+
// situations where target is visible:
|
|
11
|
+
// 1. is completely contained within frame
|
|
12
|
+
// 2. is partially visible on both axis within frame
|
|
13
|
+
// 3. is bigger than frame on both axis
|
|
14
|
+
// 4. is bigger than frame on one axis and is partially visible on the other
|
|
15
|
+
|
|
16
|
+
// completely contained
|
|
17
|
+
const isContained: boolean =
|
|
18
|
+
isWithinVertical(subject.top) &&
|
|
19
|
+
isWithinVertical(subject.bottom) &&
|
|
20
|
+
isWithinHorizontal(subject.left) &&
|
|
21
|
+
isWithinHorizontal(subject.right);
|
|
22
|
+
|
|
23
|
+
if (isContained) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const isPartiallyVisibleVertically: boolean =
|
|
28
|
+
isWithinVertical(subject.top) || isWithinVertical(subject.bottom);
|
|
29
|
+
const isPartiallyVisibleHorizontally: boolean =
|
|
30
|
+
isWithinHorizontal(subject.left) || isWithinHorizontal(subject.right);
|
|
31
|
+
|
|
32
|
+
// partially visible on both axis
|
|
33
|
+
const isPartiallyContained: boolean =
|
|
34
|
+
isPartiallyVisibleVertically && isPartiallyVisibleHorizontally;
|
|
35
|
+
|
|
36
|
+
if (isPartiallyContained) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const isBiggerVertically: boolean =
|
|
41
|
+
subject.top < frame.top && subject.bottom > frame.bottom;
|
|
42
|
+
const isBiggerHorizontally: boolean =
|
|
43
|
+
subject.left < frame.left && subject.right > frame.right;
|
|
44
|
+
|
|
45
|
+
// is bigger than frame on both axis
|
|
46
|
+
const isTargetBiggerThanFrame: boolean =
|
|
47
|
+
isBiggerVertically && isBiggerHorizontally;
|
|
48
|
+
|
|
49
|
+
if (isTargetBiggerThanFrame) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// is bigger on one axis, and partially visible on another
|
|
54
|
+
const isTargetBiggerOnOneAxis: boolean =
|
|
55
|
+
(isBiggerVertically && isPartiallyVisibleHorizontally) ||
|
|
56
|
+
(isBiggerHorizontally && isPartiallyVisibleVertically);
|
|
57
|
+
|
|
58
|
+
return isTargetBiggerOnOneAxis;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position, type Spacing } from 'css-box-model';
|
|
3
|
+
import isWithin from '../is-within';
|
|
4
|
+
|
|
5
|
+
export default function isPositionInFrame(frame: Spacing) {
|
|
6
|
+
const isWithinVertical = isWithin(frame.top, frame.bottom);
|
|
7
|
+
const isWithinHorizontal = isWithin(frame.left, frame.right);
|
|
8
|
+
|
|
9
|
+
return function run(point: Position) {
|
|
10
|
+
return isWithinVertical(point.y) && isWithinHorizontal(point.x);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Spacing } from 'css-box-model';
|
|
3
|
+
import type { Axis } from '../../types';
|
|
4
|
+
import isWithin from '../is-within';
|
|
5
|
+
import { vertical } from '../axis';
|
|
6
|
+
|
|
7
|
+
export default (axis: Axis) => (frame: Spacing) => {
|
|
8
|
+
const isWithinVertical = isWithin(frame.top, frame.bottom);
|
|
9
|
+
const isWithinHorizontal = isWithin(frame.left, frame.right);
|
|
10
|
+
|
|
11
|
+
return (subject: Spacing) => {
|
|
12
|
+
if (axis === vertical) {
|
|
13
|
+
return isWithinVertical(subject.top) && isWithinVertical(subject.bottom);
|
|
14
|
+
}
|
|
15
|
+
return (
|
|
16
|
+
isWithinHorizontal(subject.left) && isWithinHorizontal(subject.right)
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Spacing } from 'css-box-model';
|
|
3
|
+
import isWithin from '../is-within';
|
|
4
|
+
|
|
5
|
+
export default (frame: Spacing) => {
|
|
6
|
+
const isWithinVertical = isWithin(frame.top, frame.bottom);
|
|
7
|
+
const isWithinHorizontal = isWithin(frame.left, frame.right);
|
|
8
|
+
|
|
9
|
+
return (subject: Spacing) => {
|
|
10
|
+
const isContained: boolean =
|
|
11
|
+
isWithinVertical(subject.top) &&
|
|
12
|
+
isWithinVertical(subject.bottom) &&
|
|
13
|
+
isWithinHorizontal(subject.left) &&
|
|
14
|
+
isWithinHorizontal(subject.right);
|
|
15
|
+
|
|
16
|
+
return isContained;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position, type Spacing, type Rect } from 'css-box-model';
|
|
3
|
+
import type { DroppableDimension } from '../../types';
|
|
4
|
+
import isPartiallyVisibleThroughFrame from './is-partially-visible-through-frame';
|
|
5
|
+
import isTotallyVisibleThroughFrame from './is-totally-visible-through-frame';
|
|
6
|
+
import isTotallyVisibleThroughFrameOnAxis from './is-totally-visible-through-frame-on-axis';
|
|
7
|
+
import { offsetByPosition } from '../spacing';
|
|
8
|
+
import { origin } from '../position';
|
|
9
|
+
|
|
10
|
+
export type Args = {|
|
|
11
|
+
target: Spacing,
|
|
12
|
+
destination: DroppableDimension,
|
|
13
|
+
viewport: Rect,
|
|
14
|
+
withDroppableDisplacement: boolean,
|
|
15
|
+
shouldCheckDroppable?: boolean,
|
|
16
|
+
shouldCheckViewport?: boolean,
|
|
17
|
+
|};
|
|
18
|
+
|
|
19
|
+
type IsVisibleThroughFrameFn = (
|
|
20
|
+
frame: Spacing,
|
|
21
|
+
) => (subject: Spacing) => boolean;
|
|
22
|
+
|
|
23
|
+
type InternalArgs = {|
|
|
24
|
+
...Args,
|
|
25
|
+
isVisibleThroughFrameFn: IsVisibleThroughFrameFn,
|
|
26
|
+
|};
|
|
27
|
+
|
|
28
|
+
const getDroppableDisplaced = (
|
|
29
|
+
target: Spacing,
|
|
30
|
+
destination: DroppableDimension,
|
|
31
|
+
): Spacing => {
|
|
32
|
+
const displacement: Position = destination.frame
|
|
33
|
+
? destination.frame.scroll.diff.displacement
|
|
34
|
+
: origin;
|
|
35
|
+
|
|
36
|
+
return offsetByPosition(target, displacement);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const isVisibleInDroppable = (
|
|
40
|
+
target: Spacing,
|
|
41
|
+
destination: DroppableDimension,
|
|
42
|
+
isVisibleThroughFrameFn: IsVisibleThroughFrameFn,
|
|
43
|
+
): boolean => {
|
|
44
|
+
// destination subject is totally hidden by frame
|
|
45
|
+
// this should never happen - but just guarding against it
|
|
46
|
+
if (!destination.subject.active) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// When considering if the target is visible in the droppable we need
|
|
51
|
+
// to consider the change in scroll of the droppable. We need to
|
|
52
|
+
// adjust for the scroll as the clipped viewport takes into account
|
|
53
|
+
// the scroll of the droppable.
|
|
54
|
+
|
|
55
|
+
return isVisibleThroughFrameFn(destination.subject.active)(target);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const isVisibleInViewport = (
|
|
59
|
+
target: Spacing,
|
|
60
|
+
viewport: Rect,
|
|
61
|
+
isVisibleThroughFrameFn: IsVisibleThroughFrameFn,
|
|
62
|
+
): boolean => isVisibleThroughFrameFn(viewport)(target);
|
|
63
|
+
|
|
64
|
+
const isVisible = ({
|
|
65
|
+
target: toBeDisplaced,
|
|
66
|
+
destination,
|
|
67
|
+
viewport,
|
|
68
|
+
withDroppableDisplacement,
|
|
69
|
+
isVisibleThroughFrameFn,
|
|
70
|
+
}: InternalArgs): boolean => {
|
|
71
|
+
const displacedTarget: Spacing = withDroppableDisplacement
|
|
72
|
+
? getDroppableDisplaced(toBeDisplaced, destination)
|
|
73
|
+
: toBeDisplaced;
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
isVisibleInDroppable(
|
|
77
|
+
displacedTarget,
|
|
78
|
+
destination,
|
|
79
|
+
isVisibleThroughFrameFn,
|
|
80
|
+
) && isVisibleInViewport(displacedTarget, viewport, isVisibleThroughFrameFn)
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const isPartiallyVisible = (args: Args): boolean =>
|
|
85
|
+
isVisible({
|
|
86
|
+
...args,
|
|
87
|
+
isVisibleThroughFrameFn: isPartiallyVisibleThroughFrame,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
export const isTotallyVisible = (args: Args): boolean =>
|
|
91
|
+
isVisible({
|
|
92
|
+
...args,
|
|
93
|
+
isVisibleThroughFrameFn: isTotallyVisibleThroughFrame,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
export const isTotallyVisibleOnAxis = (args: Args): boolean =>
|
|
97
|
+
isVisible({
|
|
98
|
+
...args,
|
|
99
|
+
isVisibleThroughFrameFn: isTotallyVisibleThroughFrameOnAxis(
|
|
100
|
+
args.destination.axis,
|
|
101
|
+
),
|
|
102
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Position } from 'css-box-model';
|
|
3
|
+
import type { DroppableDimension, Viewport } from '../../types';
|
|
4
|
+
import withDroppableDisplacement from './with-droppable-displacement';
|
|
5
|
+
import withViewportDisplacement from './with-viewport-displacement';
|
|
6
|
+
|
|
7
|
+
export default (
|
|
8
|
+
page: Position,
|
|
9
|
+
droppable: DroppableDimension,
|
|
10
|
+
viewport: Viewport,
|
|
11
|
+
): Position =>
|
|
12
|
+
withDroppableDisplacement(
|
|
13
|
+
droppable,
|
|
14
|
+
withViewportDisplacement(viewport, page),
|
|
15
|
+
);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position } from 'css-box-model';
|
|
3
|
+
import { add } from '../position';
|
|
4
|
+
import type { Scrollable, DroppableDimension } from '../../types';
|
|
5
|
+
|
|
6
|
+
export default (droppable: DroppableDimension, point: Position): Position => {
|
|
7
|
+
const frame: ?Scrollable = droppable.frame;
|
|
8
|
+
if (!frame) {
|
|
9
|
+
return point;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return add(point, frame.scroll.diff.displacement);
|
|
13
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Rect } from 'css-box-model';
|
|
3
|
+
import type { Scrollable, DroppableDimension } from '../../types';
|
|
4
|
+
import { offsetRectByPosition } from '../rect';
|
|
5
|
+
|
|
6
|
+
export default (droppable: DroppableDimension, area: Rect): Rect => {
|
|
7
|
+
const frame: ?Scrollable = droppable.frame;
|
|
8
|
+
if (!frame) {
|
|
9
|
+
return area;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return offsetRectByPosition(area, frame.scroll.diff.value);
|
|
13
|
+
};
|