@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,46 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Position } from 'css-box-model';
|
|
3
|
+
import type {
|
|
4
|
+
UpdateDroppableScrollArgs,
|
|
5
|
+
UpdateDroppableIsEnabledArgs,
|
|
6
|
+
UpdateDroppableIsCombineEnabledArgs,
|
|
7
|
+
} from '../action-creators';
|
|
8
|
+
import type {
|
|
9
|
+
DroppableId,
|
|
10
|
+
Critical,
|
|
11
|
+
DimensionMap,
|
|
12
|
+
LiftRequest,
|
|
13
|
+
Published,
|
|
14
|
+
Viewport,
|
|
15
|
+
} from '../../types';
|
|
16
|
+
|
|
17
|
+
export type StartPublishingResult = {|
|
|
18
|
+
critical: Critical,
|
|
19
|
+
dimensions: DimensionMap,
|
|
20
|
+
viewport: Viewport,
|
|
21
|
+
|};
|
|
22
|
+
|
|
23
|
+
export type DimensionMarshal = {|
|
|
24
|
+
// it is possible for a droppable to change whether it is enabled during a drag
|
|
25
|
+
updateDroppableIsEnabled: (id: DroppableId, isEnabled: boolean) => void,
|
|
26
|
+
// it is also possible to update whether combining is enabled
|
|
27
|
+
updateDroppableIsCombineEnabled: (
|
|
28
|
+
id: DroppableId,
|
|
29
|
+
isEnabled: boolean,
|
|
30
|
+
) => void,
|
|
31
|
+
updateDroppableScroll: (id: DroppableId, newScroll: Position) => void,
|
|
32
|
+
scrollDroppable: (id: DroppableId, change: Position) => void,
|
|
33
|
+
// Entry
|
|
34
|
+
startPublishing: (request: LiftRequest) => StartPublishingResult,
|
|
35
|
+
stopPublishing: () => void,
|
|
36
|
+
|};
|
|
37
|
+
|
|
38
|
+
export type Callbacks = {|
|
|
39
|
+
collectionStarting: () => mixed,
|
|
40
|
+
publishWhileDragging: (args: Published) => mixed,
|
|
41
|
+
updateDroppableScroll: (args: UpdateDroppableScrollArgs) => mixed,
|
|
42
|
+
updateDroppableIsEnabled: (args: UpdateDroppableIsEnabledArgs) => mixed,
|
|
43
|
+
updateDroppableIsCombineEnabled: (
|
|
44
|
+
args: UpdateDroppableIsCombineEnabledArgs,
|
|
45
|
+
) => mixed,
|
|
46
|
+
|};
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position } from 'css-box-model';
|
|
3
|
+
import { invariant } from '../../invariant';
|
|
4
|
+
import type {
|
|
5
|
+
DimensionMarshal,
|
|
6
|
+
Callbacks,
|
|
7
|
+
StartPublishingResult,
|
|
8
|
+
} from './dimension-marshal-types';
|
|
9
|
+
import createPublisher, {
|
|
10
|
+
type WhileDraggingPublisher,
|
|
11
|
+
} from './while-dragging-publisher';
|
|
12
|
+
import getInitialPublish from './get-initial-publish';
|
|
13
|
+
import type {
|
|
14
|
+
Registry,
|
|
15
|
+
DroppableEntry,
|
|
16
|
+
DraggableEntry,
|
|
17
|
+
Subscriber,
|
|
18
|
+
Unsubscribe,
|
|
19
|
+
RegistryEvent,
|
|
20
|
+
} from '../registry/registry-types';
|
|
21
|
+
import type {
|
|
22
|
+
DroppableId,
|
|
23
|
+
DroppableDescriptor,
|
|
24
|
+
LiftRequest,
|
|
25
|
+
Critical,
|
|
26
|
+
DraggableDescriptor,
|
|
27
|
+
} from '../../types';
|
|
28
|
+
import { warning } from '../../dev-warning';
|
|
29
|
+
|
|
30
|
+
type Collection = {|
|
|
31
|
+
critical: Critical,
|
|
32
|
+
unsubscribe: Unsubscribe,
|
|
33
|
+
|};
|
|
34
|
+
|
|
35
|
+
function shouldPublishUpdate(
|
|
36
|
+
registry: Registry,
|
|
37
|
+
dragging: DraggableDescriptor,
|
|
38
|
+
entry: DraggableEntry,
|
|
39
|
+
): boolean {
|
|
40
|
+
// do not publish updates for the critical draggable
|
|
41
|
+
if (entry.descriptor.id === dragging.id) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
// do not publish updates for draggables that are not of a type that we care about
|
|
45
|
+
if (entry.descriptor.type !== dragging.type) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const home: DroppableEntry = registry.droppable.getById(
|
|
50
|
+
entry.descriptor.droppableId,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if (home.descriptor.mode !== 'virtual') {
|
|
54
|
+
warning(`
|
|
55
|
+
You are attempting to add or remove a Draggable [id: ${entry.descriptor.id}]
|
|
56
|
+
while a drag is occurring. This is only supported for virtual lists.
|
|
57
|
+
|
|
58
|
+
See https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/patterns/virtual-lists.md
|
|
59
|
+
`);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default (registry: Registry, callbacks: Callbacks) => {
|
|
67
|
+
let collection: ?Collection = null;
|
|
68
|
+
|
|
69
|
+
const publisher: WhileDraggingPublisher = createPublisher({
|
|
70
|
+
callbacks: {
|
|
71
|
+
publish: callbacks.publishWhileDragging,
|
|
72
|
+
collectionStarting: callbacks.collectionStarting,
|
|
73
|
+
},
|
|
74
|
+
registry,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const updateDroppableIsEnabled = (id: DroppableId, isEnabled: boolean) => {
|
|
78
|
+
invariant(
|
|
79
|
+
registry.droppable.exists(id),
|
|
80
|
+
`Cannot update is enabled flag of Droppable ${id} as it is not registered`,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// no need to update the application state if a collection is not occurring
|
|
84
|
+
if (!collection) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// At this point a non primary droppable dimension might not yet be published
|
|
89
|
+
// but may have its enabled state changed. For now we still publish this change
|
|
90
|
+
// and let the reducer exit early if it cannot find the dimension in the state.
|
|
91
|
+
callbacks.updateDroppableIsEnabled({ id, isEnabled });
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const updateDroppableIsCombineEnabled = (
|
|
95
|
+
id: DroppableId,
|
|
96
|
+
isCombineEnabled: boolean,
|
|
97
|
+
) => {
|
|
98
|
+
// no need to update
|
|
99
|
+
if (!collection) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
invariant(
|
|
104
|
+
registry.droppable.exists(id),
|
|
105
|
+
`Cannot update isCombineEnabled flag of Droppable ${id} as it is not registered`,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
callbacks.updateDroppableIsCombineEnabled({ id, isCombineEnabled });
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const updateDroppableScroll = (id: DroppableId, newScroll: Position) => {
|
|
112
|
+
// no need to update the application state if a collection is not occurring
|
|
113
|
+
if (!collection) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
invariant(
|
|
118
|
+
registry.droppable.exists(id),
|
|
119
|
+
`Cannot update the scroll on Droppable ${id} as it is not registered`,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
callbacks.updateDroppableScroll({ id, newScroll });
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const scrollDroppable = (id: DroppableId, change: Position) => {
|
|
126
|
+
if (!collection) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
registry.droppable.getById(id).callbacks.scroll(change);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const stopPublishing = () => {
|
|
133
|
+
// This function can be called defensively
|
|
134
|
+
if (!collection) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
// Stop any pending dom collections or publish
|
|
138
|
+
publisher.stop();
|
|
139
|
+
|
|
140
|
+
// Tell all droppables to stop watching scroll
|
|
141
|
+
// all good if they where not already listening
|
|
142
|
+
const home: DroppableDescriptor = collection.critical.droppable;
|
|
143
|
+
registry.droppable
|
|
144
|
+
.getAllByType(home.type)
|
|
145
|
+
.forEach((entry: DroppableEntry) => entry.callbacks.dragStopped());
|
|
146
|
+
|
|
147
|
+
// Unsubscribe from registry updates
|
|
148
|
+
collection.unsubscribe();
|
|
149
|
+
// Finally - clear our collection
|
|
150
|
+
collection = null;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const subscriber: Subscriber = (event: RegistryEvent) => {
|
|
154
|
+
invariant(
|
|
155
|
+
collection,
|
|
156
|
+
'Should only be subscribed when a collection is occurring',
|
|
157
|
+
);
|
|
158
|
+
// The dragging item can be add and removed when using a clone
|
|
159
|
+
// We do not publish updates for the critical item
|
|
160
|
+
const dragging: DraggableDescriptor = collection.critical.draggable;
|
|
161
|
+
|
|
162
|
+
if (event.type === 'ADDITION') {
|
|
163
|
+
if (shouldPublishUpdate(registry, dragging, event.value)) {
|
|
164
|
+
publisher.add(event.value);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (event.type === 'REMOVAL') {
|
|
168
|
+
if (shouldPublishUpdate(registry, dragging, event.value)) {
|
|
169
|
+
publisher.remove(event.value);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const startPublishing = (request: LiftRequest): StartPublishingResult => {
|
|
175
|
+
invariant(
|
|
176
|
+
!collection,
|
|
177
|
+
'Cannot start capturing critical dimensions as there is already a collection',
|
|
178
|
+
);
|
|
179
|
+
const entry: DraggableEntry = registry.draggable.getById(
|
|
180
|
+
request.draggableId,
|
|
181
|
+
);
|
|
182
|
+
const home: DroppableEntry = registry.droppable.getById(
|
|
183
|
+
entry.descriptor.droppableId,
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
const critical: Critical = {
|
|
187
|
+
draggable: entry.descriptor,
|
|
188
|
+
droppable: home.descriptor,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const unsubscribe = registry.subscribe(subscriber);
|
|
192
|
+
|
|
193
|
+
collection = {
|
|
194
|
+
critical,
|
|
195
|
+
unsubscribe,
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
return getInitialPublish({
|
|
199
|
+
critical,
|
|
200
|
+
registry,
|
|
201
|
+
scrollOptions: request.scrollOptions,
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const marshal: DimensionMarshal = {
|
|
206
|
+
// Droppable changes
|
|
207
|
+
updateDroppableIsEnabled,
|
|
208
|
+
updateDroppableIsCombineEnabled,
|
|
209
|
+
scrollDroppable,
|
|
210
|
+
updateDroppableScroll,
|
|
211
|
+
|
|
212
|
+
// Entry
|
|
213
|
+
startPublishing,
|
|
214
|
+
stopPublishing,
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
return marshal;
|
|
218
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Position } from 'css-box-model';
|
|
3
|
+
import * as timings from '../../debug/timings';
|
|
4
|
+
import type { StartPublishingResult } from './dimension-marshal-types';
|
|
5
|
+
import type {
|
|
6
|
+
Registry,
|
|
7
|
+
DraggableEntry,
|
|
8
|
+
DroppableEntry,
|
|
9
|
+
} from '../registry/registry-types';
|
|
10
|
+
import { toDraggableMap, toDroppableMap } from '../dimension-structures';
|
|
11
|
+
import type {
|
|
12
|
+
DroppableDescriptor,
|
|
13
|
+
DroppableDimension,
|
|
14
|
+
DraggableDimension,
|
|
15
|
+
DimensionMap,
|
|
16
|
+
ScrollOptions,
|
|
17
|
+
Critical,
|
|
18
|
+
Viewport,
|
|
19
|
+
} from '../../types';
|
|
20
|
+
import getViewport from '../../view/window/get-viewport';
|
|
21
|
+
|
|
22
|
+
type Args = {|
|
|
23
|
+
critical: Critical,
|
|
24
|
+
scrollOptions: ScrollOptions,
|
|
25
|
+
registry: Registry,
|
|
26
|
+
|};
|
|
27
|
+
|
|
28
|
+
export default ({
|
|
29
|
+
critical,
|
|
30
|
+
scrollOptions,
|
|
31
|
+
registry,
|
|
32
|
+
}: Args): StartPublishingResult => {
|
|
33
|
+
const timingKey: string = 'Initial collection from DOM';
|
|
34
|
+
timings.start(timingKey);
|
|
35
|
+
const viewport: Viewport = getViewport();
|
|
36
|
+
const windowScroll: Position = viewport.scroll.current;
|
|
37
|
+
|
|
38
|
+
const home: DroppableDescriptor = critical.droppable;
|
|
39
|
+
|
|
40
|
+
const droppables: DroppableDimension[] = registry.droppable
|
|
41
|
+
.getAllByType(home.type)
|
|
42
|
+
.map((entry: DroppableEntry): DroppableDimension =>
|
|
43
|
+
entry.callbacks.getDimensionAndWatchScroll(windowScroll, scrollOptions),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const draggables: DraggableDimension[] = registry.draggable
|
|
47
|
+
.getAllByType(critical.draggable.type)
|
|
48
|
+
.map((entry: DraggableEntry): DraggableDimension =>
|
|
49
|
+
entry.getDimension(windowScroll),
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const dimensions: DimensionMap = {
|
|
53
|
+
draggables: toDraggableMap(draggables),
|
|
54
|
+
droppables: toDroppableMap(droppables),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
timings.finish(timingKey);
|
|
58
|
+
|
|
59
|
+
const result: StartPublishingResult = {
|
|
60
|
+
dimensions,
|
|
61
|
+
critical,
|
|
62
|
+
viewport,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return result;
|
|
66
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Position } from 'css-box-model';
|
|
3
|
+
import type {
|
|
4
|
+
DraggableId,
|
|
5
|
+
DroppableId,
|
|
6
|
+
DraggableDescriptor,
|
|
7
|
+
Published,
|
|
8
|
+
DraggableDimension,
|
|
9
|
+
DroppablePublish,
|
|
10
|
+
DroppableIdMap,
|
|
11
|
+
DraggableIdMap,
|
|
12
|
+
} from '../../types';
|
|
13
|
+
import type {
|
|
14
|
+
DroppableEntry,
|
|
15
|
+
Registry,
|
|
16
|
+
DraggableEntry,
|
|
17
|
+
DraggableEntryMap,
|
|
18
|
+
} from '../registry/registry-types';
|
|
19
|
+
import * as timings from '../../debug/timings';
|
|
20
|
+
import { origin } from '../position';
|
|
21
|
+
|
|
22
|
+
export type WhileDraggingPublisher = {|
|
|
23
|
+
add: (entry: DraggableEntry) => void,
|
|
24
|
+
remove: (entry: DraggableEntry) => void,
|
|
25
|
+
stop: () => void,
|
|
26
|
+
|};
|
|
27
|
+
|
|
28
|
+
type Staging = {|
|
|
29
|
+
additions: DraggableEntryMap,
|
|
30
|
+
removals: DraggableIdMap,
|
|
31
|
+
modified: DroppableIdMap,
|
|
32
|
+
|};
|
|
33
|
+
|
|
34
|
+
type Callbacks = {|
|
|
35
|
+
publish: (args: Published) => mixed,
|
|
36
|
+
collectionStarting: () => mixed,
|
|
37
|
+
|};
|
|
38
|
+
|
|
39
|
+
type Args = {|
|
|
40
|
+
registry: Registry,
|
|
41
|
+
callbacks: Callbacks,
|
|
42
|
+
|};
|
|
43
|
+
|
|
44
|
+
const clean = (): Staging => ({
|
|
45
|
+
additions: {},
|
|
46
|
+
removals: {},
|
|
47
|
+
modified: {},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const timingKey: string = 'Publish collection from DOM';
|
|
51
|
+
|
|
52
|
+
export default function createPublisher({
|
|
53
|
+
registry,
|
|
54
|
+
callbacks,
|
|
55
|
+
}: Args): WhileDraggingPublisher {
|
|
56
|
+
let staging: Staging = clean();
|
|
57
|
+
let frameId: ?AnimationFrameID = null;
|
|
58
|
+
|
|
59
|
+
const collect = () => {
|
|
60
|
+
if (frameId) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
callbacks.collectionStarting();
|
|
65
|
+
frameId = requestAnimationFrame(() => {
|
|
66
|
+
frameId = null;
|
|
67
|
+
timings.start(timingKey);
|
|
68
|
+
|
|
69
|
+
const { additions, removals, modified } = staging;
|
|
70
|
+
|
|
71
|
+
const added: DraggableDimension[] = Object.keys(additions)
|
|
72
|
+
.map(
|
|
73
|
+
// Using the origin as the window scroll. This will be adjusted when processing the published values
|
|
74
|
+
(id: DraggableId): DraggableDimension =>
|
|
75
|
+
registry.draggable.getById(id).getDimension(origin),
|
|
76
|
+
)
|
|
77
|
+
// Dimensions are not guarenteed to be ordered in the same order as keys
|
|
78
|
+
// So we need to sort them so they are in the correct order
|
|
79
|
+
.sort(
|
|
80
|
+
(a: DraggableDimension, b: DraggableDimension): number =>
|
|
81
|
+
a.descriptor.index - b.descriptor.index,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const updated: DroppablePublish[] = Object.keys(modified).map(
|
|
85
|
+
(id: DroppableId) => {
|
|
86
|
+
const entry: DroppableEntry = registry.droppable.getById(id);
|
|
87
|
+
|
|
88
|
+
const scroll: Position = entry.callbacks.getScrollWhileDragging();
|
|
89
|
+
return {
|
|
90
|
+
droppableId: id,
|
|
91
|
+
scroll,
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const result: Published = {
|
|
97
|
+
additions: added,
|
|
98
|
+
removals: Object.keys(removals),
|
|
99
|
+
modified: updated,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
staging = clean();
|
|
103
|
+
|
|
104
|
+
timings.finish(timingKey);
|
|
105
|
+
callbacks.publish(result);
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const add = (entry: DraggableEntry) => {
|
|
110
|
+
const id: DraggableId = entry.descriptor.id;
|
|
111
|
+
staging.additions[id] = entry;
|
|
112
|
+
staging.modified[entry.descriptor.droppableId] = true;
|
|
113
|
+
|
|
114
|
+
if (staging.removals[id]) {
|
|
115
|
+
delete staging.removals[id];
|
|
116
|
+
}
|
|
117
|
+
collect();
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const remove = (entry: DraggableEntry) => {
|
|
121
|
+
const descriptor: DraggableDescriptor = entry.descriptor;
|
|
122
|
+
staging.removals[descriptor.id] = true;
|
|
123
|
+
staging.modified[descriptor.droppableId] = true;
|
|
124
|
+
|
|
125
|
+
if (staging.additions[descriptor.id]) {
|
|
126
|
+
delete staging.additions[descriptor.id];
|
|
127
|
+
}
|
|
128
|
+
collect();
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const stop = () => {
|
|
132
|
+
if (!frameId) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
cancelAnimationFrame(frameId);
|
|
137
|
+
frameId = null;
|
|
138
|
+
staging = clean();
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
add,
|
|
143
|
+
remove,
|
|
144
|
+
stop,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import memoizeOne from 'memoize-one';
|
|
3
|
+
import { values } from '../native-with-fallback';
|
|
4
|
+
import type {
|
|
5
|
+
DroppableDimension,
|
|
6
|
+
DroppableDimensionMap,
|
|
7
|
+
DraggableDimension,
|
|
8
|
+
DraggableDimensionMap,
|
|
9
|
+
} from '../types';
|
|
10
|
+
|
|
11
|
+
export const toDroppableMap = memoizeOne(
|
|
12
|
+
(droppables: DroppableDimension[]): DroppableDimensionMap =>
|
|
13
|
+
droppables.reduce((previous, current) => {
|
|
14
|
+
previous[current.descriptor.id] = current;
|
|
15
|
+
return previous;
|
|
16
|
+
}, {}),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
export const toDraggableMap = memoizeOne(
|
|
20
|
+
(draggables: DraggableDimension[]): DraggableDimensionMap =>
|
|
21
|
+
draggables.reduce((previous, current) => {
|
|
22
|
+
previous[current.descriptor.id] = current;
|
|
23
|
+
return previous;
|
|
24
|
+
}, {}),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export const toDroppableList = memoizeOne(
|
|
28
|
+
(droppables: DroppableDimensionMap): DroppableDimension[] =>
|
|
29
|
+
values(droppables),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export const toDraggableList = memoizeOne(
|
|
33
|
+
(draggables: DraggableDimensionMap): DraggableDimension[] =>
|
|
34
|
+
values(draggables),
|
|
35
|
+
);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type BoxModel, type Position } from 'css-box-model';
|
|
3
|
+
import type {
|
|
4
|
+
Axis,
|
|
5
|
+
DroppableDimension,
|
|
6
|
+
DroppableDescriptor,
|
|
7
|
+
Scrollable,
|
|
8
|
+
DroppableSubject,
|
|
9
|
+
ScrollSize,
|
|
10
|
+
} from '../../types';
|
|
11
|
+
import { vertical, horizontal } from '../axis';
|
|
12
|
+
import { origin } from '../position';
|
|
13
|
+
import getMaxScroll from '../get-max-scroll';
|
|
14
|
+
import getSubject from './util/get-subject';
|
|
15
|
+
|
|
16
|
+
export type Closest = {|
|
|
17
|
+
client: BoxModel,
|
|
18
|
+
page: BoxModel,
|
|
19
|
+
scroll: Position,
|
|
20
|
+
scrollSize: ScrollSize,
|
|
21
|
+
shouldClipSubject: boolean,
|
|
22
|
+
|};
|
|
23
|
+
|
|
24
|
+
type Args = {|
|
|
25
|
+
descriptor: DroppableDescriptor,
|
|
26
|
+
isEnabled: boolean,
|
|
27
|
+
isCombineEnabled: boolean,
|
|
28
|
+
isFixedOnPage: boolean,
|
|
29
|
+
direction: 'vertical' | 'horizontal',
|
|
30
|
+
client: BoxModel,
|
|
31
|
+
// is null when in a fixed container
|
|
32
|
+
page: BoxModel,
|
|
33
|
+
closest?: ?Closest,
|
|
34
|
+
|};
|
|
35
|
+
|
|
36
|
+
export default ({
|
|
37
|
+
descriptor,
|
|
38
|
+
isEnabled,
|
|
39
|
+
isCombineEnabled,
|
|
40
|
+
isFixedOnPage,
|
|
41
|
+
direction,
|
|
42
|
+
client,
|
|
43
|
+
page,
|
|
44
|
+
closest,
|
|
45
|
+
}: Args): DroppableDimension => {
|
|
46
|
+
const frame: ?Scrollable = (() => {
|
|
47
|
+
if (!closest) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const { scrollSize, client: frameClient } = closest;
|
|
52
|
+
|
|
53
|
+
// scrollHeight and scrollWidth are based on the padding box
|
|
54
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight
|
|
55
|
+
const maxScroll: Position = getMaxScroll({
|
|
56
|
+
scrollHeight: scrollSize.scrollHeight,
|
|
57
|
+
scrollWidth: scrollSize.scrollWidth,
|
|
58
|
+
height: frameClient.paddingBox.height,
|
|
59
|
+
width: frameClient.paddingBox.width,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
pageMarginBox: closest.page.marginBox,
|
|
64
|
+
frameClient,
|
|
65
|
+
scrollSize,
|
|
66
|
+
shouldClipSubject: closest.shouldClipSubject,
|
|
67
|
+
scroll: {
|
|
68
|
+
initial: closest.scroll,
|
|
69
|
+
current: closest.scroll,
|
|
70
|
+
max: maxScroll,
|
|
71
|
+
diff: {
|
|
72
|
+
value: origin,
|
|
73
|
+
displacement: origin,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
})();
|
|
78
|
+
|
|
79
|
+
const axis: Axis = direction === 'vertical' ? vertical : horizontal;
|
|
80
|
+
|
|
81
|
+
const subject: DroppableSubject = getSubject({
|
|
82
|
+
page,
|
|
83
|
+
withPlaceholder: null,
|
|
84
|
+
axis,
|
|
85
|
+
frame,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const dimension: DroppableDimension = {
|
|
89
|
+
descriptor,
|
|
90
|
+
isCombineEnabled,
|
|
91
|
+
isFixedOnPage,
|
|
92
|
+
axis,
|
|
93
|
+
isEnabled,
|
|
94
|
+
client,
|
|
95
|
+
page,
|
|
96
|
+
frame,
|
|
97
|
+
subject,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return dimension;
|
|
101
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { type Position } from 'css-box-model';
|
|
3
|
+
import { invariant } from '../../invariant';
|
|
4
|
+
import type {
|
|
5
|
+
DroppableDimension,
|
|
6
|
+
Scrollable,
|
|
7
|
+
DroppableSubject,
|
|
8
|
+
} from '../../types';
|
|
9
|
+
import { negate, subtract } from '../position';
|
|
10
|
+
import getSubject from './util/get-subject';
|
|
11
|
+
|
|
12
|
+
export default (
|
|
13
|
+
droppable: DroppableDimension,
|
|
14
|
+
newScroll: Position,
|
|
15
|
+
): DroppableDimension => {
|
|
16
|
+
invariant(droppable.frame);
|
|
17
|
+
const scrollable: Scrollable = droppable.frame;
|
|
18
|
+
|
|
19
|
+
const scrollDiff: Position = subtract(newScroll, scrollable.scroll.initial);
|
|
20
|
+
// a positive scroll difference leads to a negative displacement
|
|
21
|
+
// (scrolling down pulls an item upwards)
|
|
22
|
+
const scrollDisplacement: Position = negate(scrollDiff);
|
|
23
|
+
|
|
24
|
+
// Sometimes it is possible to scroll beyond the max point.
|
|
25
|
+
// This can occur when scrolling a foreign list that now has a placeholder.
|
|
26
|
+
|
|
27
|
+
const frame: Scrollable = {
|
|
28
|
+
...scrollable,
|
|
29
|
+
scroll: {
|
|
30
|
+
initial: scrollable.scroll.initial,
|
|
31
|
+
current: newScroll,
|
|
32
|
+
diff: {
|
|
33
|
+
value: scrollDiff,
|
|
34
|
+
displacement: scrollDisplacement,
|
|
35
|
+
},
|
|
36
|
+
// TODO: rename 'softMax?'
|
|
37
|
+
max: scrollable.scroll.max,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const subject: DroppableSubject = getSubject({
|
|
42
|
+
page: droppable.subject.page,
|
|
43
|
+
withPlaceholder: droppable.subject.withPlaceholder,
|
|
44
|
+
axis: droppable.axis,
|
|
45
|
+
frame,
|
|
46
|
+
});
|
|
47
|
+
const result: DroppableDimension = {
|
|
48
|
+
...droppable,
|
|
49
|
+
frame,
|
|
50
|
+
subject,
|
|
51
|
+
};
|
|
52
|
+
return result;
|
|
53
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { DraggableDescriptor, DragImpact } from '../../types';
|
|
3
|
+
import whatIsDraggedOver from './what-is-dragged-over';
|
|
4
|
+
|
|
5
|
+
// use placeholder if dragged over
|
|
6
|
+
export default (descriptor: DraggableDescriptor, impact: DragImpact): boolean =>
|
|
7
|
+
whatIsDraggedOver(impact) === descriptor.droppableId;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { getRect, type Rect, type Spacing } from 'css-box-model';
|
|
3
|
+
|
|
4
|
+
export default (frame: Spacing, subject: Spacing): ?Rect => {
|
|
5
|
+
const result: Rect = getRect({
|
|
6
|
+
top: Math.max(subject.top, frame.top),
|
|
7
|
+
right: Math.min(subject.right, frame.right),
|
|
8
|
+
bottom: Math.min(subject.bottom, frame.bottom),
|
|
9
|
+
left: Math.max(subject.left, frame.left),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
if (result.width <= 0 || result.height <= 0) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return result;
|
|
17
|
+
};
|