@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,495 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import rafSchd from 'raf-schd';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { useCallback, useMemo } from 'use-memo-one';
|
|
5
|
+
import type { Position } from 'css-box-model';
|
|
6
|
+
import { invariant } from '../../invariant';
|
|
7
|
+
import type {
|
|
8
|
+
ContextId,
|
|
9
|
+
State,
|
|
10
|
+
Sensor,
|
|
11
|
+
StopDragOptions,
|
|
12
|
+
PreDragActions,
|
|
13
|
+
FluidDragActions,
|
|
14
|
+
SnapDragActions,
|
|
15
|
+
DraggableId,
|
|
16
|
+
SensorAPI,
|
|
17
|
+
TryGetLock,
|
|
18
|
+
TryGetLockOptions,
|
|
19
|
+
DraggableOptions,
|
|
20
|
+
} from '../../types';
|
|
21
|
+
import create, { type Lock, type LockAPI } from './lock';
|
|
22
|
+
import type { Store, Action } from '../../state/store-types';
|
|
23
|
+
import canStartDrag from '../../state/can-start-drag';
|
|
24
|
+
import {
|
|
25
|
+
move as moveAction,
|
|
26
|
+
moveUp as moveUpAction,
|
|
27
|
+
moveRight as moveRightAction,
|
|
28
|
+
moveDown as moveDownAction,
|
|
29
|
+
moveLeft as moveLeftAction,
|
|
30
|
+
drop as dropAction,
|
|
31
|
+
lift as liftAction,
|
|
32
|
+
type LiftArgs as LiftActionArgs,
|
|
33
|
+
flush,
|
|
34
|
+
} from '../../state/action-creators';
|
|
35
|
+
import type {
|
|
36
|
+
Registry,
|
|
37
|
+
DraggableEntry,
|
|
38
|
+
} from '../../state/registry/registry-types';
|
|
39
|
+
import useMouseSensor from './sensors/use-mouse-sensor';
|
|
40
|
+
import useKeyboardSensor from './sensors/use-keyboard-sensor';
|
|
41
|
+
import useTouchSensor from './sensors/use-touch-sensor';
|
|
42
|
+
import useValidateSensorHooks from './use-validate-sensor-hooks';
|
|
43
|
+
import isEventInInteractiveElement from './is-event-in-interactive-element';
|
|
44
|
+
import getBorderBoxCenterPosition from '../get-border-box-center-position';
|
|
45
|
+
import { warning } from '../../dev-warning';
|
|
46
|
+
import useLayoutEffect from '../use-isomorphic-layout-effect';
|
|
47
|
+
import { noop } from '../../empty';
|
|
48
|
+
import findClosestDraggableIdFromEvent from './find-closest-draggable-id-from-event';
|
|
49
|
+
import findDraggable from '../get-elements/find-draggable';
|
|
50
|
+
import bindEvents from '../event-bindings/bind-events';
|
|
51
|
+
|
|
52
|
+
function preventDefault(event: Event) {
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type LockPhase = 'PRE_DRAG' | 'DRAGGING' | 'COMPLETED';
|
|
57
|
+
|
|
58
|
+
type IsActiveArgs = {|
|
|
59
|
+
expected: LockPhase,
|
|
60
|
+
phase: LockPhase,
|
|
61
|
+
isLockActive: () => boolean,
|
|
62
|
+
shouldWarn: boolean,
|
|
63
|
+
|};
|
|
64
|
+
|
|
65
|
+
function isActive({
|
|
66
|
+
expected,
|
|
67
|
+
phase,
|
|
68
|
+
isLockActive,
|
|
69
|
+
shouldWarn,
|
|
70
|
+
}: IsActiveArgs): boolean {
|
|
71
|
+
// lock is no longer active
|
|
72
|
+
if (!isLockActive()) {
|
|
73
|
+
if (shouldWarn) {
|
|
74
|
+
warning(`
|
|
75
|
+
Cannot perform action.
|
|
76
|
+
The sensor no longer has an action lock.
|
|
77
|
+
|
|
78
|
+
Tips:
|
|
79
|
+
|
|
80
|
+
- Throw away your action handlers when forceStop() is called
|
|
81
|
+
- Check actions.isActive() if you really need to
|
|
82
|
+
`);
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
// wrong phase
|
|
87
|
+
if (expected !== phase) {
|
|
88
|
+
if (shouldWarn) {
|
|
89
|
+
warning(`
|
|
90
|
+
Cannot perform action.
|
|
91
|
+
The actions you used belong to an outdated phase
|
|
92
|
+
|
|
93
|
+
Current phase: ${expected}
|
|
94
|
+
You called an action from outdated phase: ${phase}
|
|
95
|
+
|
|
96
|
+
Tips:
|
|
97
|
+
|
|
98
|
+
- Do not use preDragActions actions after calling preDragActions.lift()
|
|
99
|
+
`);
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type CanStartArgs = {|
|
|
107
|
+
lockAPI: LockAPI,
|
|
108
|
+
registry: Registry,
|
|
109
|
+
store: Store,
|
|
110
|
+
draggableId: DraggableId,
|
|
111
|
+
|};
|
|
112
|
+
|
|
113
|
+
function canStart({
|
|
114
|
+
lockAPI,
|
|
115
|
+
store,
|
|
116
|
+
registry,
|
|
117
|
+
draggableId,
|
|
118
|
+
}: CanStartArgs): boolean {
|
|
119
|
+
// lock is already claimed - cannot start
|
|
120
|
+
if (lockAPI.isClaimed()) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const entry: ?DraggableEntry = registry.draggable.findById(draggableId);
|
|
125
|
+
|
|
126
|
+
if (!entry) {
|
|
127
|
+
warning(`Unable to find draggable with id: ${draggableId}`);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// draggable is not enabled - cannot start
|
|
132
|
+
if (!entry.options.isEnabled) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Application might now allow dragging right now
|
|
137
|
+
if (!canStartDrag(store.getState(), draggableId)) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
type TryStartArgs = {|
|
|
145
|
+
lockAPI: LockAPI,
|
|
146
|
+
contextId: ContextId,
|
|
147
|
+
registry: Registry,
|
|
148
|
+
store: Store,
|
|
149
|
+
draggableId: DraggableId,
|
|
150
|
+
forceSensorStop: ?() => void,
|
|
151
|
+
sourceEvent: ?Event,
|
|
152
|
+
|};
|
|
153
|
+
|
|
154
|
+
function tryStart({
|
|
155
|
+
lockAPI,
|
|
156
|
+
contextId,
|
|
157
|
+
store,
|
|
158
|
+
registry,
|
|
159
|
+
draggableId,
|
|
160
|
+
forceSensorStop,
|
|
161
|
+
sourceEvent,
|
|
162
|
+
}: TryStartArgs): ?PreDragActions {
|
|
163
|
+
const shouldStart: boolean = canStart({
|
|
164
|
+
lockAPI,
|
|
165
|
+
store,
|
|
166
|
+
registry,
|
|
167
|
+
draggableId,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
if (!shouldStart) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const entry: DraggableEntry = registry.draggable.getById(draggableId);
|
|
175
|
+
const el: ?HTMLElement = findDraggable(contextId, entry.descriptor.id);
|
|
176
|
+
|
|
177
|
+
if (!el) {
|
|
178
|
+
warning(`Unable to find draggable element with id: ${draggableId}`);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Do not allow dragging from interactive elements
|
|
183
|
+
if (
|
|
184
|
+
sourceEvent &&
|
|
185
|
+
!entry.options.canDragInteractiveElements &&
|
|
186
|
+
isEventInInteractiveElement(el, sourceEvent)
|
|
187
|
+
) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// claiming lock
|
|
192
|
+
const lock: Lock = lockAPI.claim(forceSensorStop || noop);
|
|
193
|
+
let phase: LockPhase = 'PRE_DRAG';
|
|
194
|
+
|
|
195
|
+
function getShouldRespectForcePress(): boolean {
|
|
196
|
+
// not looking up the entry as it might have been removed in a virtual list
|
|
197
|
+
return entry.options.shouldRespectForcePress;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function isLockActive(): boolean {
|
|
201
|
+
return lockAPI.isActive(lock);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function tryDispatch(expected: LockPhase, getAction: () => Action): void {
|
|
205
|
+
if (isActive({ expected, phase, isLockActive, shouldWarn: true })) {
|
|
206
|
+
store.dispatch(getAction());
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const tryDispatchWhenDragging = tryDispatch.bind(null, 'DRAGGING');
|
|
211
|
+
|
|
212
|
+
type LiftArgs = {|
|
|
213
|
+
liftActionArgs: LiftActionArgs,
|
|
214
|
+
cleanup: () => void,
|
|
215
|
+
actions: Object,
|
|
216
|
+
|};
|
|
217
|
+
|
|
218
|
+
function lift(args: LiftArgs) {
|
|
219
|
+
function completed() {
|
|
220
|
+
lockAPI.release();
|
|
221
|
+
phase = 'COMPLETED';
|
|
222
|
+
}
|
|
223
|
+
// Double lift = bad
|
|
224
|
+
if (phase !== 'PRE_DRAG') {
|
|
225
|
+
completed();
|
|
226
|
+
invariant(phase === 'PRE_DRAG', `Cannot lift in phase ${phase}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
store.dispatch(liftAction(args.liftActionArgs));
|
|
230
|
+
|
|
231
|
+
// We are now in the DRAGGING phase
|
|
232
|
+
phase = 'DRAGGING';
|
|
233
|
+
|
|
234
|
+
function finish(
|
|
235
|
+
reason: 'CANCEL' | 'DROP',
|
|
236
|
+
options?: StopDragOptions = { shouldBlockNextClick: false },
|
|
237
|
+
) {
|
|
238
|
+
args.cleanup();
|
|
239
|
+
|
|
240
|
+
// block next click if requested
|
|
241
|
+
if (options.shouldBlockNextClick) {
|
|
242
|
+
const unbind = bindEvents(window, [
|
|
243
|
+
{
|
|
244
|
+
eventName: 'click',
|
|
245
|
+
fn: preventDefault,
|
|
246
|
+
options: {
|
|
247
|
+
// only blocking a single click
|
|
248
|
+
once: true,
|
|
249
|
+
passive: false,
|
|
250
|
+
capture: true,
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
]);
|
|
254
|
+
// Sometimes the click is swallowed, such as when there is reparenting
|
|
255
|
+
// The click event (in the message queue) will occur before the next setTimeout expiry
|
|
256
|
+
// https://codesandbox.io/s/click-behaviour-pkfk2
|
|
257
|
+
setTimeout(unbind);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// releasing
|
|
261
|
+
completed();
|
|
262
|
+
store.dispatch(dropAction({ reason }));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
isActive: () =>
|
|
267
|
+
isActive({
|
|
268
|
+
expected: 'DRAGGING',
|
|
269
|
+
phase,
|
|
270
|
+
isLockActive,
|
|
271
|
+
// Do not want to want warnings for boolean checks
|
|
272
|
+
shouldWarn: false,
|
|
273
|
+
}),
|
|
274
|
+
shouldRespectForcePress: getShouldRespectForcePress,
|
|
275
|
+
drop: (options?: StopDragOptions) => finish('DROP', options),
|
|
276
|
+
cancel: (options?: StopDragOptions) => finish('CANCEL', options),
|
|
277
|
+
...args.actions,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function fluidLift(clientSelection: Position): FluidDragActions {
|
|
282
|
+
const move = rafSchd((client: Position) => {
|
|
283
|
+
tryDispatchWhenDragging(() => moveAction({ client }));
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
const api = lift({
|
|
287
|
+
liftActionArgs: {
|
|
288
|
+
id: draggableId,
|
|
289
|
+
clientSelection,
|
|
290
|
+
movementMode: 'FLUID',
|
|
291
|
+
},
|
|
292
|
+
cleanup: () => move.cancel(),
|
|
293
|
+
actions: { move },
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
...api,
|
|
298
|
+
move,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function snapLift(): SnapDragActions {
|
|
303
|
+
const actions = {
|
|
304
|
+
moveUp: () => tryDispatchWhenDragging(moveUpAction),
|
|
305
|
+
moveRight: () => tryDispatchWhenDragging(moveRightAction),
|
|
306
|
+
moveDown: () => tryDispatchWhenDragging(moveDownAction),
|
|
307
|
+
moveLeft: () => tryDispatchWhenDragging(moveLeftAction),
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
return lift({
|
|
311
|
+
liftActionArgs: {
|
|
312
|
+
id: draggableId,
|
|
313
|
+
clientSelection: getBorderBoxCenterPosition(el),
|
|
314
|
+
movementMode: 'SNAP',
|
|
315
|
+
},
|
|
316
|
+
cleanup: noop,
|
|
317
|
+
actions,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function abortPreDrag() {
|
|
322
|
+
const shouldRelease: boolean = isActive({
|
|
323
|
+
expected: 'PRE_DRAG',
|
|
324
|
+
phase,
|
|
325
|
+
isLockActive,
|
|
326
|
+
shouldWarn: true,
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
if (shouldRelease) {
|
|
330
|
+
lockAPI.release();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const preDrag: PreDragActions = {
|
|
335
|
+
isActive: () =>
|
|
336
|
+
isActive({
|
|
337
|
+
expected: 'PRE_DRAG',
|
|
338
|
+
phase,
|
|
339
|
+
isLockActive,
|
|
340
|
+
// Do not want to want warnings for boolean checks
|
|
341
|
+
shouldWarn: false,
|
|
342
|
+
}),
|
|
343
|
+
shouldRespectForcePress: getShouldRespectForcePress,
|
|
344
|
+
fluidLift,
|
|
345
|
+
snapLift,
|
|
346
|
+
abort: abortPreDrag,
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
return preDrag;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
type SensorMarshalArgs = {|
|
|
353
|
+
contextId: ContextId,
|
|
354
|
+
registry: Registry,
|
|
355
|
+
store: Store,
|
|
356
|
+
customSensors: ?(Sensor[]),
|
|
357
|
+
enableDefaultSensors: boolean,
|
|
358
|
+
|};
|
|
359
|
+
|
|
360
|
+
// default sensors are now exported to library consumers
|
|
361
|
+
const defaultSensors: Sensor[] = [
|
|
362
|
+
useMouseSensor,
|
|
363
|
+
useKeyboardSensor,
|
|
364
|
+
useTouchSensor,
|
|
365
|
+
];
|
|
366
|
+
|
|
367
|
+
export default function useSensorMarshal({
|
|
368
|
+
contextId,
|
|
369
|
+
store,
|
|
370
|
+
registry,
|
|
371
|
+
customSensors,
|
|
372
|
+
enableDefaultSensors,
|
|
373
|
+
}: SensorMarshalArgs) {
|
|
374
|
+
const useSensors: Sensor[] = [
|
|
375
|
+
...(enableDefaultSensors ? defaultSensors : []),
|
|
376
|
+
...(customSensors || []),
|
|
377
|
+
];
|
|
378
|
+
const lockAPI: LockAPI = useState(() => create())[0];
|
|
379
|
+
|
|
380
|
+
const tryAbandonLock = useCallback(
|
|
381
|
+
function tryAbandonLock(previous: State, current: State) {
|
|
382
|
+
if (previous.isDragging && !current.isDragging) {
|
|
383
|
+
lockAPI.tryAbandon();
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
[lockAPI],
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
// We need to abort any capturing if there is no longer a drag
|
|
390
|
+
useLayoutEffect(
|
|
391
|
+
function listenToStore() {
|
|
392
|
+
let previous: State = store.getState();
|
|
393
|
+
const unsubscribe = store.subscribe(() => {
|
|
394
|
+
const current: State = store.getState();
|
|
395
|
+
tryAbandonLock(previous, current);
|
|
396
|
+
previous = current;
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// unsubscribe from store when unmounting
|
|
400
|
+
return unsubscribe;
|
|
401
|
+
},
|
|
402
|
+
[lockAPI, store, tryAbandonLock],
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
// abort any lock on unmount
|
|
406
|
+
useLayoutEffect(() => {
|
|
407
|
+
return lockAPI.tryAbandon;
|
|
408
|
+
}, [lockAPI.tryAbandon]);
|
|
409
|
+
|
|
410
|
+
const canGetLock = useCallback(
|
|
411
|
+
(draggableId: DraggableId): boolean => {
|
|
412
|
+
return canStart({
|
|
413
|
+
lockAPI,
|
|
414
|
+
registry,
|
|
415
|
+
store,
|
|
416
|
+
draggableId,
|
|
417
|
+
});
|
|
418
|
+
},
|
|
419
|
+
[lockAPI, registry, store],
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
const tryGetLock: TryGetLock = useCallback(
|
|
423
|
+
(
|
|
424
|
+
draggableId: DraggableId,
|
|
425
|
+
forceStop?: () => void,
|
|
426
|
+
options?: TryGetLockOptions,
|
|
427
|
+
): ?PreDragActions =>
|
|
428
|
+
tryStart({
|
|
429
|
+
lockAPI,
|
|
430
|
+
registry,
|
|
431
|
+
contextId,
|
|
432
|
+
store,
|
|
433
|
+
draggableId,
|
|
434
|
+
forceSensorStop: forceStop,
|
|
435
|
+
sourceEvent:
|
|
436
|
+
options && options.sourceEvent ? options.sourceEvent : null,
|
|
437
|
+
}),
|
|
438
|
+
[contextId, lockAPI, registry, store],
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
const findClosestDraggableId = useCallback(
|
|
442
|
+
(event: Event): ?DraggableId =>
|
|
443
|
+
findClosestDraggableIdFromEvent(contextId, event),
|
|
444
|
+
[contextId],
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
const findOptionsForDraggable = useCallback(
|
|
448
|
+
(id: DraggableId): ?DraggableOptions => {
|
|
449
|
+
const entry: ?DraggableEntry = registry.draggable.findById(id);
|
|
450
|
+
return entry ? entry.options : null;
|
|
451
|
+
},
|
|
452
|
+
[registry.draggable],
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
const tryReleaseLock = useCallback(
|
|
456
|
+
function tryReleaseLock() {
|
|
457
|
+
if (!lockAPI.isClaimed()) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
lockAPI.tryAbandon();
|
|
462
|
+
|
|
463
|
+
if (store.getState().phase !== 'IDLE') {
|
|
464
|
+
store.dispatch(flush());
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
[lockAPI, store],
|
|
468
|
+
);
|
|
469
|
+
const isLockClaimed = useCallback(lockAPI.isClaimed, [lockAPI]);
|
|
470
|
+
|
|
471
|
+
const api: SensorAPI = useMemo(
|
|
472
|
+
() => ({
|
|
473
|
+
canGetLock,
|
|
474
|
+
tryGetLock,
|
|
475
|
+
findClosestDraggableId,
|
|
476
|
+
findOptionsForDraggable,
|
|
477
|
+
tryReleaseLock,
|
|
478
|
+
isLockClaimed,
|
|
479
|
+
}),
|
|
480
|
+
[
|
|
481
|
+
canGetLock,
|
|
482
|
+
tryGetLock,
|
|
483
|
+
findClosestDraggableId,
|
|
484
|
+
findOptionsForDraggable,
|
|
485
|
+
tryReleaseLock,
|
|
486
|
+
isLockClaimed,
|
|
487
|
+
],
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
// Bad ass
|
|
491
|
+
useValidateSensorHooks(useSensors);
|
|
492
|
+
for (let i = 0; i < useSensors.length; i++) {
|
|
493
|
+
useSensors[i](api);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
3
|
+
import { invariant } from '../../invariant';
|
|
4
|
+
import type { Sensor } from '../../types';
|
|
5
|
+
import usePreviousRef from '../use-previous-ref';
|
|
6
|
+
import useDevSetupWarning from '../use-dev-setup-warning';
|
|
7
|
+
import useDev from '../use-dev';
|
|
8
|
+
|
|
9
|
+
export default function useValidateSensorHooks(sensorHooks: Sensor[]) {
|
|
10
|
+
useDev(() => {
|
|
11
|
+
const previousRef = usePreviousRef<Sensor[]>(sensorHooks);
|
|
12
|
+
|
|
13
|
+
useDevSetupWarning(() => {
|
|
14
|
+
invariant(
|
|
15
|
+
previousRef.current.length === sensorHooks.length,
|
|
16
|
+
'Cannot change the amount of sensor hooks after mounting',
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { ContextId } from '../../types';
|
|
3
|
+
import { transitions } from '../../animation';
|
|
4
|
+
import * as attributes from '../data-attributes';
|
|
5
|
+
|
|
6
|
+
export type Styles = {|
|
|
7
|
+
always: string,
|
|
8
|
+
dragging: string,
|
|
9
|
+
resting: string,
|
|
10
|
+
dropAnimating: string,
|
|
11
|
+
userCancel: string,
|
|
12
|
+
|};
|
|
13
|
+
|
|
14
|
+
type Rule = {|
|
|
15
|
+
selector: string,
|
|
16
|
+
styles: {|
|
|
17
|
+
always?: string,
|
|
18
|
+
resting?: string,
|
|
19
|
+
dragging?: string,
|
|
20
|
+
dropAnimating?: string,
|
|
21
|
+
userCancel?: string,
|
|
22
|
+
|},
|
|
23
|
+
|};
|
|
24
|
+
|
|
25
|
+
const makeGetSelector = (context: string) => (attribute: string) =>
|
|
26
|
+
`[${attribute}="${context}"]`;
|
|
27
|
+
|
|
28
|
+
const getStyles = (rules: Rule[], property: string): string =>
|
|
29
|
+
rules
|
|
30
|
+
.map((rule: Rule): string => {
|
|
31
|
+
const value: ?string = rule.styles[property];
|
|
32
|
+
if (!value) {
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return `${rule.selector} { ${value} }`;
|
|
37
|
+
})
|
|
38
|
+
.join(' ');
|
|
39
|
+
|
|
40
|
+
const noPointerEvents: string = 'pointer-events: none;';
|
|
41
|
+
|
|
42
|
+
export default (contextId: ContextId): Styles => {
|
|
43
|
+
const getSelector = makeGetSelector(contextId);
|
|
44
|
+
|
|
45
|
+
// ## Drag handle styles
|
|
46
|
+
|
|
47
|
+
// -webkit-touch-callout
|
|
48
|
+
// A long press on anchors usually pops a content menu that has options for
|
|
49
|
+
// the link such as 'Open in new tab'. Because long press is used to start
|
|
50
|
+
// a drag we need to opt out of this behavior
|
|
51
|
+
|
|
52
|
+
// -webkit-tap-highlight-color
|
|
53
|
+
// Webkit based browsers add a grey overlay to anchors when they are active.
|
|
54
|
+
// We remove this tap overlay as it is confusing for users
|
|
55
|
+
// https://css-tricks.com/snippets/css/remove-gray-highlight-when-tapping-links-in-mobile-safari/
|
|
56
|
+
|
|
57
|
+
// touch-action: manipulation
|
|
58
|
+
// Avoid the *pull to refresh action* and *delayed anchor focus* on Android Chrome
|
|
59
|
+
|
|
60
|
+
// cursor: grab
|
|
61
|
+
// We apply this by default for an improved user experience. It is such a common default that we
|
|
62
|
+
// bake it right in. Consumers can opt out of this by adding a selector with higher specificity
|
|
63
|
+
// The cursor will not apply when pointer-events is set to none
|
|
64
|
+
|
|
65
|
+
// pointer-events: none
|
|
66
|
+
// this is used to prevent pointer events firing on draggables during a drag
|
|
67
|
+
// Reasons:
|
|
68
|
+
// 1. performance: it stops the other draggables from processing mouse events
|
|
69
|
+
// 2. scrolling: it allows the user to scroll through the current draggable
|
|
70
|
+
// to scroll the list behind
|
|
71
|
+
// 3.* function: it blocks other draggables from starting. This is not relied on though as there
|
|
72
|
+
// is a function on the context (canLift) which is a more robust way of controlling this
|
|
73
|
+
|
|
74
|
+
const dragHandle: Rule = (() => {
|
|
75
|
+
const grabCursor = `
|
|
76
|
+
cursor: -webkit-grab;
|
|
77
|
+
cursor: grab;
|
|
78
|
+
`;
|
|
79
|
+
return {
|
|
80
|
+
selector: getSelector(attributes.dragHandle.contextId),
|
|
81
|
+
styles: {
|
|
82
|
+
always: `
|
|
83
|
+
-webkit-touch-callout: none;
|
|
84
|
+
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
|
85
|
+
touch-action: manipulation;
|
|
86
|
+
`,
|
|
87
|
+
resting: grabCursor,
|
|
88
|
+
dragging: noPointerEvents,
|
|
89
|
+
// it is fine for users to start dragging another item when a drop animation is occurring
|
|
90
|
+
dropAnimating: grabCursor,
|
|
91
|
+
// Not applying grab cursor during a user cancel as it is not possible for users to reorder
|
|
92
|
+
// items during a cancel
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
})();
|
|
96
|
+
|
|
97
|
+
// ## Draggable styles
|
|
98
|
+
|
|
99
|
+
// transition: transform
|
|
100
|
+
// This controls the animation of draggables that are moving out of the way
|
|
101
|
+
// The main draggable is controlled by react-motion.
|
|
102
|
+
|
|
103
|
+
const draggable: Rule = (() => {
|
|
104
|
+
const transition: string = `
|
|
105
|
+
transition: ${transitions.outOfTheWay};
|
|
106
|
+
`;
|
|
107
|
+
return {
|
|
108
|
+
selector: getSelector(attributes.draggable.contextId),
|
|
109
|
+
styles: {
|
|
110
|
+
dragging: transition,
|
|
111
|
+
dropAnimating: transition,
|
|
112
|
+
userCancel: transition,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
})();
|
|
116
|
+
|
|
117
|
+
// ## Droppable styles
|
|
118
|
+
|
|
119
|
+
// overflow-anchor: none;
|
|
120
|
+
// Opting out of the browser feature which tries to maintain
|
|
121
|
+
// the scroll position when the DOM changes above the fold.
|
|
122
|
+
// This does not work well with reordering DOM nodes.
|
|
123
|
+
// When we drop a Draggable it already has the correct scroll applied.
|
|
124
|
+
|
|
125
|
+
const droppable: Rule = {
|
|
126
|
+
selector: getSelector(attributes.droppable.contextId),
|
|
127
|
+
styles: {
|
|
128
|
+
always: `overflow-anchor: none;`,
|
|
129
|
+
// need pointer events on the droppable to allow manual scrolling
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// ## Body styles
|
|
134
|
+
|
|
135
|
+
// cursor: grab
|
|
136
|
+
// We apply this by default for an improved user experience. It is such a common default that we
|
|
137
|
+
// bake it right in. Consumers can opt out of this by adding a selector with higher specificity
|
|
138
|
+
|
|
139
|
+
// user-select: none
|
|
140
|
+
// This prevents the user from selecting text on the page while dragging
|
|
141
|
+
|
|
142
|
+
// overflow-anchor: none
|
|
143
|
+
// We are in control and aware of all of the window scrolls that occur
|
|
144
|
+
// we do not want the browser to have behaviors we do not expect
|
|
145
|
+
|
|
146
|
+
const body: Rule = {
|
|
147
|
+
selector: 'body',
|
|
148
|
+
styles: {
|
|
149
|
+
dragging: `
|
|
150
|
+
cursor: grabbing;
|
|
151
|
+
cursor: -webkit-grabbing;
|
|
152
|
+
user-select: none;
|
|
153
|
+
-webkit-user-select: none;
|
|
154
|
+
-moz-user-select: none;
|
|
155
|
+
-ms-user-select: none;
|
|
156
|
+
overflow-anchor: none;
|
|
157
|
+
`,
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const rules: Rule[] = [draggable, dragHandle, droppable, body];
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
always: getStyles(rules, 'always'),
|
|
165
|
+
resting: getStyles(rules, 'resting'),
|
|
166
|
+
dragging: getStyles(rules, 'dragging'),
|
|
167
|
+
dropAnimating: getStyles(rules, 'dropAnimating'),
|
|
168
|
+
userCancel: getStyles(rules, 'userCancel'),
|
|
169
|
+
};
|
|
170
|
+
};
|