@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,37 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
export const prefix: string = 'data-rbd';
|
|
3
|
+
export const dragHandle = (() => {
|
|
4
|
+
const base = `${prefix}-drag-handle`;
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
base,
|
|
8
|
+
draggableId: `${base}-draggable-id`,
|
|
9
|
+
contextId: `${base}-context-id`,
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
|
|
13
|
+
export const draggable = (() => {
|
|
14
|
+
const base: string = `${prefix}-draggable`;
|
|
15
|
+
return {
|
|
16
|
+
base,
|
|
17
|
+
contextId: `${base}-context-id`,
|
|
18
|
+
id: `${base}-id`,
|
|
19
|
+
};
|
|
20
|
+
})();
|
|
21
|
+
|
|
22
|
+
export const droppable = (() => {
|
|
23
|
+
const base: string = `${prefix}-droppable`;
|
|
24
|
+
return {
|
|
25
|
+
base,
|
|
26
|
+
contextId: `${base}-context-id`,
|
|
27
|
+
id: `${base}-id`,
|
|
28
|
+
};
|
|
29
|
+
})();
|
|
30
|
+
|
|
31
|
+
export const placeholder = {
|
|
32
|
+
contextId: `${prefix}-placeholder-context-id`,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const scrollContainer = {
|
|
36
|
+
contextId: `${prefix}-scroll-container-context-id`,
|
|
37
|
+
};
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import React, { useEffect, useRef, type Node } from 'react';
|
|
3
|
+
import { bindActionCreators } from 'redux';
|
|
4
|
+
import { Provider } from 'react-redux';
|
|
5
|
+
import { useMemo, useCallback } from 'use-memo-one';
|
|
6
|
+
import { invariant } from '../../invariant';
|
|
7
|
+
import createStore from '../../state/create-store';
|
|
8
|
+
import createDimensionMarshal from '../../state/dimension-marshal/dimension-marshal';
|
|
9
|
+
import canStartDrag from '../../state/can-start-drag';
|
|
10
|
+
import scrollWindow from '../window/scroll-window';
|
|
11
|
+
import createAutoScroller from '../../state/auto-scroller';
|
|
12
|
+
import useStyleMarshal from '../use-style-marshal/use-style-marshal';
|
|
13
|
+
import useFocusMarshal from '../use-focus-marshal';
|
|
14
|
+
import useRegistry from '../../state/registry/use-registry';
|
|
15
|
+
import type { Registry } from '../../state/registry/registry-types';
|
|
16
|
+
import type { FocusMarshal } from '../use-focus-marshal/focus-marshal-types';
|
|
17
|
+
import type { AutoScroller } from '../../state/auto-scroller/auto-scroller-types';
|
|
18
|
+
import type { StyleMarshal } from '../use-style-marshal/style-marshal-types';
|
|
19
|
+
import type {
|
|
20
|
+
DimensionMarshal,
|
|
21
|
+
Callbacks as DimensionMarshalCallbacks,
|
|
22
|
+
} from '../../state/dimension-marshal/dimension-marshal-types';
|
|
23
|
+
import type {
|
|
24
|
+
DraggableId,
|
|
25
|
+
State,
|
|
26
|
+
Responders,
|
|
27
|
+
Announce,
|
|
28
|
+
Sensor,
|
|
29
|
+
ElementId,
|
|
30
|
+
FluidScrollerOptions,
|
|
31
|
+
} from '../../types';
|
|
32
|
+
import type { Store, Action } from '../../state/store-types';
|
|
33
|
+
import type { SetAppCallbacks, AppCallbacks } from './drag-drop-context-types';
|
|
34
|
+
import StoreContext from '../context/store-context';
|
|
35
|
+
import {
|
|
36
|
+
move,
|
|
37
|
+
publishWhileDragging,
|
|
38
|
+
updateDroppableScroll,
|
|
39
|
+
updateDroppableIsEnabled,
|
|
40
|
+
updateDroppableIsCombineEnabled,
|
|
41
|
+
collectionStarting,
|
|
42
|
+
flush,
|
|
43
|
+
} from '../../state/action-creators';
|
|
44
|
+
import isMovementAllowed from '../../state/is-movement-allowed';
|
|
45
|
+
import useAnnouncer from '../use-announcer';
|
|
46
|
+
import useHiddenTextElement from '../use-hidden-text-element';
|
|
47
|
+
import AppContext, { type AppContextValue } from '../context/app-context';
|
|
48
|
+
import useStartupValidation from './use-startup-validation';
|
|
49
|
+
import usePrevious from '../use-previous-ref';
|
|
50
|
+
import { warning } from '../../dev-warning';
|
|
51
|
+
import useSensorMarshal from '../use-sensor-marshal/use-sensor-marshal';
|
|
52
|
+
|
|
53
|
+
export type Props = {|
|
|
54
|
+
...Responders,
|
|
55
|
+
contextId: string,
|
|
56
|
+
setCallbacks: SetAppCallbacks,
|
|
57
|
+
nonce?: string,
|
|
58
|
+
// we do not technically need any children for this component
|
|
59
|
+
children: Node | null,
|
|
60
|
+
|
|
61
|
+
// sensors
|
|
62
|
+
sensors?: Sensor[],
|
|
63
|
+
enableDefaultSensors?: ?boolean,
|
|
64
|
+
|
|
65
|
+
// screen reader
|
|
66
|
+
dragHandleUsageInstructions: string,
|
|
67
|
+
|
|
68
|
+
// fluidScroller behavior options
|
|
69
|
+
fluidScrollerOptions?: FluidScrollerOptions,
|
|
70
|
+
|};
|
|
71
|
+
|
|
72
|
+
const createResponders = (props: Props): Responders => ({
|
|
73
|
+
onBeforeCapture: props.onBeforeCapture,
|
|
74
|
+
onBeforeDragStart: props.onBeforeDragStart,
|
|
75
|
+
onDragStart: props.onDragStart,
|
|
76
|
+
onDragEnd: props.onDragEnd,
|
|
77
|
+
onDragUpdate: props.onDragUpdate,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// flow does not support MutableRefObject
|
|
81
|
+
// type LazyStoreRef = MutableRefObject<?Store>;
|
|
82
|
+
type LazyStoreRef = {| current: ?Store |};
|
|
83
|
+
|
|
84
|
+
function getStore(lazyRef: LazyStoreRef): Store {
|
|
85
|
+
invariant(lazyRef.current, 'Could not find store from lazy ref');
|
|
86
|
+
return lazyRef.current;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default function App(props: Props) {
|
|
90
|
+
const {
|
|
91
|
+
contextId,
|
|
92
|
+
setCallbacks,
|
|
93
|
+
sensors,
|
|
94
|
+
nonce,
|
|
95
|
+
dragHandleUsageInstructions,
|
|
96
|
+
fluidScrollerOptions,
|
|
97
|
+
} = props;
|
|
98
|
+
const lazyStoreRef: LazyStoreRef = useRef<?Store>(null);
|
|
99
|
+
|
|
100
|
+
useStartupValidation();
|
|
101
|
+
|
|
102
|
+
// lazy collection of responders using a ref - update on ever render
|
|
103
|
+
const lastPropsRef = usePrevious<Props>(props);
|
|
104
|
+
|
|
105
|
+
const getResponders: () => Responders = useCallback(() => {
|
|
106
|
+
return createResponders(lastPropsRef.current);
|
|
107
|
+
}, [lastPropsRef]);
|
|
108
|
+
|
|
109
|
+
const announce: Announce = useAnnouncer(contextId);
|
|
110
|
+
|
|
111
|
+
const dragHandleUsageInstructionsId: ElementId = useHiddenTextElement({
|
|
112
|
+
contextId,
|
|
113
|
+
text: dragHandleUsageInstructions,
|
|
114
|
+
});
|
|
115
|
+
const styleMarshal: StyleMarshal = useStyleMarshal(contextId, nonce);
|
|
116
|
+
|
|
117
|
+
const lazyDispatch: (Action) => void = useCallback((action: Action): void => {
|
|
118
|
+
getStore(lazyStoreRef).dispatch(action);
|
|
119
|
+
}, []);
|
|
120
|
+
|
|
121
|
+
const marshalCallbacks: DimensionMarshalCallbacks = useMemo(
|
|
122
|
+
() =>
|
|
123
|
+
bindActionCreators(
|
|
124
|
+
{
|
|
125
|
+
publishWhileDragging,
|
|
126
|
+
updateDroppableScroll,
|
|
127
|
+
updateDroppableIsEnabled,
|
|
128
|
+
updateDroppableIsCombineEnabled,
|
|
129
|
+
collectionStarting,
|
|
130
|
+
},
|
|
131
|
+
// $FlowFixMe - not sure why this is wrong
|
|
132
|
+
lazyDispatch,
|
|
133
|
+
),
|
|
134
|
+
[lazyDispatch],
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const registry: Registry = useRegistry();
|
|
138
|
+
|
|
139
|
+
const dimensionMarshal: DimensionMarshal = useMemo<DimensionMarshal>(() => {
|
|
140
|
+
return createDimensionMarshal(registry, marshalCallbacks);
|
|
141
|
+
}, [registry, marshalCallbacks]);
|
|
142
|
+
|
|
143
|
+
const fluidScrollerOptionsRef = useRef(fluidScrollerOptions);
|
|
144
|
+
|
|
145
|
+
const autoScroller: AutoScroller = useMemo<AutoScroller>(
|
|
146
|
+
() =>
|
|
147
|
+
createAutoScroller({
|
|
148
|
+
scrollWindow,
|
|
149
|
+
scrollDroppable: dimensionMarshal.scrollDroppable,
|
|
150
|
+
...bindActionCreators(
|
|
151
|
+
{
|
|
152
|
+
move,
|
|
153
|
+
},
|
|
154
|
+
// $FlowFixMe - not sure why this is wrong
|
|
155
|
+
lazyDispatch,
|
|
156
|
+
),
|
|
157
|
+
fluidScrollerOptions: fluidScrollerOptionsRef.current,
|
|
158
|
+
}),
|
|
159
|
+
[dimensionMarshal.scrollDroppable, lazyDispatch],
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const focusMarshal: FocusMarshal = useFocusMarshal(contextId);
|
|
163
|
+
|
|
164
|
+
const store: Store = useMemo<Store>(
|
|
165
|
+
() =>
|
|
166
|
+
createStore({
|
|
167
|
+
announce,
|
|
168
|
+
autoScroller,
|
|
169
|
+
dimensionMarshal,
|
|
170
|
+
focusMarshal,
|
|
171
|
+
getResponders,
|
|
172
|
+
styleMarshal,
|
|
173
|
+
}),
|
|
174
|
+
[
|
|
175
|
+
announce,
|
|
176
|
+
autoScroller,
|
|
177
|
+
dimensionMarshal,
|
|
178
|
+
focusMarshal,
|
|
179
|
+
getResponders,
|
|
180
|
+
styleMarshal,
|
|
181
|
+
],
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// Checking for unexpected store changes
|
|
185
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
186
|
+
if (lazyStoreRef.current && lazyStoreRef.current !== store) {
|
|
187
|
+
warning('unexpected store change');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// assigning lazy store ref
|
|
192
|
+
lazyStoreRef.current = store;
|
|
193
|
+
|
|
194
|
+
const tryResetStore = useCallback(() => {
|
|
195
|
+
const current: Store = getStore(lazyStoreRef);
|
|
196
|
+
const state: State = current.getState();
|
|
197
|
+
if (state.phase !== 'IDLE') {
|
|
198
|
+
current.dispatch(flush());
|
|
199
|
+
}
|
|
200
|
+
}, []);
|
|
201
|
+
|
|
202
|
+
const isDragging = useCallback((): boolean => {
|
|
203
|
+
const state: State = getStore(lazyStoreRef).getState();
|
|
204
|
+
return state.isDragging || state.phase === 'DROP_ANIMATING';
|
|
205
|
+
}, []);
|
|
206
|
+
|
|
207
|
+
const appCallbacks: AppCallbacks = useMemo(
|
|
208
|
+
() => ({
|
|
209
|
+
isDragging,
|
|
210
|
+
tryAbort: tryResetStore,
|
|
211
|
+
}),
|
|
212
|
+
[isDragging, tryResetStore],
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// doing this in render rather than a side effect so any errors on the
|
|
216
|
+
// initial mount are caught
|
|
217
|
+
setCallbacks(appCallbacks);
|
|
218
|
+
|
|
219
|
+
const getCanLift = useCallback(
|
|
220
|
+
(id: DraggableId) => canStartDrag(getStore(lazyStoreRef).getState(), id),
|
|
221
|
+
[],
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const getIsMovementAllowed = useCallback(
|
|
225
|
+
() => isMovementAllowed(getStore(lazyStoreRef).getState()),
|
|
226
|
+
[],
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const appContext: AppContextValue = useMemo(
|
|
230
|
+
() => ({
|
|
231
|
+
marshal: dimensionMarshal,
|
|
232
|
+
focus: focusMarshal,
|
|
233
|
+
contextId,
|
|
234
|
+
canLift: getCanLift,
|
|
235
|
+
isMovementAllowed: getIsMovementAllowed,
|
|
236
|
+
dragHandleUsageInstructionsId,
|
|
237
|
+
registry,
|
|
238
|
+
fluidScrollerOptions,
|
|
239
|
+
}),
|
|
240
|
+
[
|
|
241
|
+
contextId,
|
|
242
|
+
dimensionMarshal,
|
|
243
|
+
dragHandleUsageInstructionsId,
|
|
244
|
+
focusMarshal,
|
|
245
|
+
getCanLift,
|
|
246
|
+
getIsMovementAllowed,
|
|
247
|
+
registry,
|
|
248
|
+
fluidScrollerOptions,
|
|
249
|
+
],
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
useSensorMarshal({
|
|
253
|
+
contextId,
|
|
254
|
+
store,
|
|
255
|
+
registry,
|
|
256
|
+
customSensors: sensors,
|
|
257
|
+
// default to 'true' unless 'false' is explicitly passed
|
|
258
|
+
enableDefaultSensors: props.enableDefaultSensors !== false,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Clean store when unmounting
|
|
262
|
+
useEffect(() => {
|
|
263
|
+
return tryResetStore;
|
|
264
|
+
}, [tryResetStore]);
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<AppContext.Provider value={appContext}>
|
|
268
|
+
<Provider context={StoreContext} store={store}>
|
|
269
|
+
{props.children}
|
|
270
|
+
</Provider>
|
|
271
|
+
</AppContext.Provider>
|
|
272
|
+
);
|
|
273
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { warning } from '../../dev-warning';
|
|
3
|
+
|
|
4
|
+
const suffix: string = `
|
|
5
|
+
We expect a html5 doctype: <!doctype html>
|
|
6
|
+
This is to ensure consistent browser layout and measurement
|
|
7
|
+
|
|
8
|
+
More information: https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/doctype.md
|
|
9
|
+
`;
|
|
10
|
+
|
|
11
|
+
export default (doc: Document) => {
|
|
12
|
+
const doctype: ?DocumentType = doc.doctype;
|
|
13
|
+
|
|
14
|
+
if (!doctype) {
|
|
15
|
+
warning(`
|
|
16
|
+
No <!doctype html> found.
|
|
17
|
+
|
|
18
|
+
${suffix}
|
|
19
|
+
`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (doctype.name.toLowerCase() !== 'html') {
|
|
24
|
+
warning(`
|
|
25
|
+
Unexpected <!doctype> found: (${doctype.name})
|
|
26
|
+
|
|
27
|
+
${suffix}
|
|
28
|
+
`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (doctype.publicId !== '') {
|
|
32
|
+
warning(`
|
|
33
|
+
Unexpected <!doctype> publicId found: (${doctype.publicId})
|
|
34
|
+
A html5 doctype does not have a publicId
|
|
35
|
+
|
|
36
|
+
${suffix}
|
|
37
|
+
`);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { invariant } from '../../invariant';
|
|
3
|
+
import { warning } from '../../dev-warning';
|
|
4
|
+
|
|
5
|
+
type Version = {|
|
|
6
|
+
major: number,
|
|
7
|
+
minor: number,
|
|
8
|
+
patch: number,
|
|
9
|
+
raw: string,
|
|
10
|
+
|};
|
|
11
|
+
|
|
12
|
+
// We can use a simple regex here given that:
|
|
13
|
+
// - the version that react supplies is always full: eg 16.5.2
|
|
14
|
+
// - our peer dependency version is to a full version (eg ^16.3.1)
|
|
15
|
+
const semver: RegExp = /(\d+)\.(\d+)\.(\d+)/;
|
|
16
|
+
const getVersion = (value: string): Version => {
|
|
17
|
+
const result: ?(string[]) = semver.exec(value);
|
|
18
|
+
|
|
19
|
+
invariant(result != null, `Unable to parse React version ${value}`);
|
|
20
|
+
|
|
21
|
+
const major: number = Number(result[1]);
|
|
22
|
+
const minor: number = Number(result[2]);
|
|
23
|
+
const patch: number = Number(result[3]);
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
major,
|
|
27
|
+
minor,
|
|
28
|
+
patch,
|
|
29
|
+
raw: value,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const isSatisfied = (expected: Version, actual: Version): boolean => {
|
|
34
|
+
if (actual.major > expected.major) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (actual.major < expected.major) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// major is equal, continue on
|
|
43
|
+
|
|
44
|
+
if (actual.minor > expected.minor) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (actual.minor < expected.minor) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// minor is equal, continue on
|
|
53
|
+
|
|
54
|
+
return actual.patch >= expected.patch;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default (peerDepValue: string, actualValue: string) => {
|
|
58
|
+
const peerDep: Version = getVersion(peerDepValue);
|
|
59
|
+
const actual: Version = getVersion(actualValue);
|
|
60
|
+
|
|
61
|
+
if (isSatisfied(peerDep, actual)) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
warning(`
|
|
66
|
+
React version: [${actual.raw}]
|
|
67
|
+
does not satisfy expected peer dependency version: [${peerDep.raw}]
|
|
68
|
+
|
|
69
|
+
This can result in run time bugs, and even fatal crashes
|
|
70
|
+
`);
|
|
71
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import React, { type Node } from 'react';
|
|
3
|
+
import type {
|
|
4
|
+
FluidScrollerOptions,
|
|
5
|
+
Responders,
|
|
6
|
+
ContextId,
|
|
7
|
+
Sensor,
|
|
8
|
+
} from '../../types';
|
|
9
|
+
import ErrorBoundary from './error-boundary';
|
|
10
|
+
import preset from '../../screen-reader-message-preset';
|
|
11
|
+
import App from './app';
|
|
12
|
+
import useUniqueContextId, {
|
|
13
|
+
reset as resetContextId,
|
|
14
|
+
} from './use-unique-context-id';
|
|
15
|
+
import { reset as resetUniqueIds } from '../use-unique-id';
|
|
16
|
+
|
|
17
|
+
type Props = {|
|
|
18
|
+
...Responders,
|
|
19
|
+
// We do not technically need any children for this component
|
|
20
|
+
children: Node | null,
|
|
21
|
+
// Read out by screen readers when focusing on a drag handle
|
|
22
|
+
dragHandleUsageInstructions?: string,
|
|
23
|
+
// Used for strict content security policies
|
|
24
|
+
// See our [content security policy guide](/docs/guides/content-security-policy.md)
|
|
25
|
+
nonce?: string,
|
|
26
|
+
// See our [sensor api](/docs/sensors/sensor-api.md)
|
|
27
|
+
sensors?: Sensor[],
|
|
28
|
+
enableDefaultSensors?: ?boolean,
|
|
29
|
+
// fluid scroller options
|
|
30
|
+
fluidScrollerOptions?: FluidScrollerOptions,
|
|
31
|
+
|};
|
|
32
|
+
|
|
33
|
+
// Reset any context that gets persisted across server side renders
|
|
34
|
+
export function resetServerContext() {
|
|
35
|
+
resetContextId();
|
|
36
|
+
resetUniqueIds();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default function DragDropContext(props: Props) {
|
|
40
|
+
const contextId: ContextId = useUniqueContextId();
|
|
41
|
+
const dragHandleUsageInstructions: string =
|
|
42
|
+
props.dragHandleUsageInstructions || preset.dragHandleUsageInstructions;
|
|
43
|
+
|
|
44
|
+
// We need the error boundary to be on the outside of App
|
|
45
|
+
// so that it can catch any errors caused by App
|
|
46
|
+
return (
|
|
47
|
+
<ErrorBoundary>
|
|
48
|
+
{(setCallbacks) => (
|
|
49
|
+
<App
|
|
50
|
+
nonce={props.nonce}
|
|
51
|
+
contextId={contextId}
|
|
52
|
+
setCallbacks={setCallbacks}
|
|
53
|
+
dragHandleUsageInstructions={dragHandleUsageInstructions}
|
|
54
|
+
enableDefaultSensors={props.enableDefaultSensors}
|
|
55
|
+
sensors={props.sensors}
|
|
56
|
+
onBeforeCapture={props.onBeforeCapture}
|
|
57
|
+
onBeforeDragStart={props.onBeforeDragStart}
|
|
58
|
+
onDragStart={props.onDragStart}
|
|
59
|
+
onDragUpdate={props.onDragUpdate}
|
|
60
|
+
onDragEnd={props.onDragEnd}
|
|
61
|
+
fluidScrollerOptions={props.fluidScrollerOptions}
|
|
62
|
+
>
|
|
63
|
+
{props.children}
|
|
64
|
+
</App>
|
|
65
|
+
)}
|
|
66
|
+
</ErrorBoundary>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import React, { type Node } from 'react';
|
|
3
|
+
import { warning, error } from '../../dev-warning';
|
|
4
|
+
import { noop } from '../../empty';
|
|
5
|
+
import bindEvents from '../event-bindings/bind-events';
|
|
6
|
+
import { RbdInvariant } from '../../invariant';
|
|
7
|
+
import type { AppCallbacks } from './drag-drop-context-types';
|
|
8
|
+
|
|
9
|
+
type Props = {|
|
|
10
|
+
children: (setCallbacks: (callbacks: AppCallbacks) => void) => Node,
|
|
11
|
+
|};
|
|
12
|
+
|
|
13
|
+
// Lame that this is not in flow
|
|
14
|
+
type ErrorEvent = Event & {
|
|
15
|
+
error: ?Error,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default class ErrorBoundary extends React.Component<Props> {
|
|
19
|
+
callbacks: ?AppCallbacks = null;
|
|
20
|
+
unbind: () => void = noop;
|
|
21
|
+
|
|
22
|
+
componentDidMount() {
|
|
23
|
+
this.unbind = bindEvents(window, [
|
|
24
|
+
{
|
|
25
|
+
eventName: 'error',
|
|
26
|
+
fn: this.onWindowError,
|
|
27
|
+
},
|
|
28
|
+
]);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
componentDidCatch(err: Error) {
|
|
32
|
+
if (err instanceof RbdInvariant) {
|
|
33
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
34
|
+
error(err.message);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.setState({});
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// throwing error for other error boundaries
|
|
42
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
componentWillUnmount() {
|
|
47
|
+
this.unbind();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
onWindowError = (event: ErrorEvent) => {
|
|
51
|
+
const callbacks: AppCallbacks = this.getCallbacks();
|
|
52
|
+
|
|
53
|
+
if (callbacks.isDragging()) {
|
|
54
|
+
callbacks.tryAbort();
|
|
55
|
+
warning(`
|
|
56
|
+
An error was caught by our window 'error' event listener while a drag was occurring.
|
|
57
|
+
The active drag has been aborted.
|
|
58
|
+
`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const err: ?Error = event.error;
|
|
62
|
+
|
|
63
|
+
if (err instanceof RbdInvariant) {
|
|
64
|
+
// Marking the event as dealt with.
|
|
65
|
+
// This will prevent any 'uncaught' error warnings in the console
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
68
|
+
error(err.message);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
getCallbacks = (): AppCallbacks => {
|
|
74
|
+
if (!this.callbacks) {
|
|
75
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
76
|
+
throw new Error('Unable to find AppCallbacks in <ErrorBoundary/>');
|
|
77
|
+
}
|
|
78
|
+
return this.callbacks;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
setCallbacks = (callbacks: AppCallbacks) => {
|
|
82
|
+
this.callbacks = callbacks;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
render() {
|
|
86
|
+
return this.props.children(this.setCallbacks);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { peerDependencies } from '../../../package.json';
|
|
4
|
+
import checkReactVersion from './check-react-version';
|
|
5
|
+
import checkDoctype from './check-doctype';
|
|
6
|
+
import useDevSetupWarning from '../use-dev-setup-warning';
|
|
7
|
+
|
|
8
|
+
export default function useStartupValidation() {
|
|
9
|
+
useDevSetupWarning(() => {
|
|
10
|
+
checkReactVersion(peerDependencies.react, React.version);
|
|
11
|
+
checkDoctype(document);
|
|
12
|
+
}, []);
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { useMemo } from 'use-memo-one';
|
|
3
|
+
import type { ContextId } from '../../types';
|
|
4
|
+
|
|
5
|
+
let count = 0;
|
|
6
|
+
|
|
7
|
+
export function reset() {
|
|
8
|
+
count = 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function useInstanceCount(): ContextId {
|
|
12
|
+
return useMemo(() => `${count++}`, []);
|
|
13
|
+
}
|