@rpcbase/client 0.180.0 → 0.181.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/package.json +1 -1
- package/ui/LottiePlayer/index.js +1 -1
- package/ui/Tabs/index.js +158 -0
- package/ui/Tabs/tabs.scss +53 -0
- package/ui/helpers/stopEventPropagation.js +5 -0
- package/ui/helpers/useThrottledMeasure/index.js +49 -0
- package/ui/{withSuspense → helpers/withSuspense}/index.js +2 -4
- package/ui/sortable-hoc/AutoScroller.js +76 -0
- package/ui/sortable-hoc/DragHandle.js +31 -0
- package/ui/sortable-hoc/Manager.js +54 -0
- package/ui/sortable-hoc/README.md +1 -0
- package/ui/sortable-hoc/SortableContainer/defaultGetHelperDimensions.js +7 -0
- package/ui/sortable-hoc/SortableContainer/defaultShouldCancelStart.js +24 -0
- package/ui/sortable-hoc/SortableContainer/index.js +994 -0
- package/ui/sortable-hoc/SortableContainer/props.js +81 -0
- package/ui/sortable-hoc/SortableElement.js +111 -0
- package/ui/sortable-hoc/SortableHandle.js +45 -0
- package/ui/sortable-hoc/drag-handle.scss +14 -0
- package/ui/sortable-hoc/index.js +9 -0
- package/ui/sortable-hoc/utils.js +292 -0
|
@@ -0,0 +1,994 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import invariant from "invariant"
|
|
5
|
+
|
|
6
|
+
import Manager from "../Manager"
|
|
7
|
+
import {isSortableHandle} from "../SortableHandle"
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
cloneNode,
|
|
11
|
+
closest,
|
|
12
|
+
events,
|
|
13
|
+
getScrollingParent,
|
|
14
|
+
getContainerGridGap,
|
|
15
|
+
getEdgeOffset,
|
|
16
|
+
getElementMargin,
|
|
17
|
+
getLockPixelOffsets,
|
|
18
|
+
getPosition,
|
|
19
|
+
isTouchEvent,
|
|
20
|
+
limit,
|
|
21
|
+
NodeType,
|
|
22
|
+
omit,
|
|
23
|
+
provideDisplayName,
|
|
24
|
+
setInlineStyles,
|
|
25
|
+
setTransitionDuration,
|
|
26
|
+
setTranslate3d,
|
|
27
|
+
getTargetIndex,
|
|
28
|
+
getScrollAdjustedBoundingClientRect,
|
|
29
|
+
} from "../utils"
|
|
30
|
+
|
|
31
|
+
import AutoScroller from "../AutoScroller"
|
|
32
|
+
import {defaultProps, omittedProps, propTypes, validateProps, defaultKeyCodes} from "./props"
|
|
33
|
+
|
|
34
|
+
export const SortableContext = React.createContext({
|
|
35
|
+
manager: {},
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
export default function SortableContainer(WrappedComponent, config = {withRef: false}) {
|
|
39
|
+
return class WithSortableContainer extends React.Component {
|
|
40
|
+
constructor(props) {
|
|
41
|
+
super(props)
|
|
42
|
+
const manager = new Manager()
|
|
43
|
+
|
|
44
|
+
validateProps(props)
|
|
45
|
+
|
|
46
|
+
this.manager = manager
|
|
47
|
+
this.wrappedInstance = React.createRef()
|
|
48
|
+
this.containerRef = React.createRef()
|
|
49
|
+
this.sortableContextValue = {manager}
|
|
50
|
+
this.events = {
|
|
51
|
+
end: this.handleEnd,
|
|
52
|
+
move: this.handleMove,
|
|
53
|
+
start: this.handleStart,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
state = {}
|
|
58
|
+
|
|
59
|
+
static displayName = provideDisplayName("sortableList", WrappedComponent)
|
|
60
|
+
static defaultProps = defaultProps
|
|
61
|
+
static propTypes = propTypes
|
|
62
|
+
|
|
63
|
+
componentDidMount() {
|
|
64
|
+
const {useWindowAsScrollContainer} = this.props
|
|
65
|
+
|
|
66
|
+
const container = this.getContainer()
|
|
67
|
+
|
|
68
|
+
Promise.resolve(container).then((containerNode) => {
|
|
69
|
+
|
|
70
|
+
this.container = containerNode
|
|
71
|
+
this.document = this.container.ownerDocument || document
|
|
72
|
+
|
|
73
|
+
/*
|
|
74
|
+
* Set our own default rather than using defaultProps because Jest
|
|
75
|
+
* snapshots will serialize window, causing a RangeError
|
|
76
|
+
* https://github.com/clauderic/react-sortable-hoc/issues/249
|
|
77
|
+
*/
|
|
78
|
+
const contentWindow = this.props.contentWindow || this.document.defaultView || window
|
|
79
|
+
|
|
80
|
+
this.contentWindow = typeof contentWindow === "function" ? contentWindow() : contentWindow
|
|
81
|
+
|
|
82
|
+
this.scrollContainer = useWindowAsScrollContainer
|
|
83
|
+
? this.document.scrollingElement || this.document.documentElement
|
|
84
|
+
: getScrollingParent(this.container) || this.container
|
|
85
|
+
|
|
86
|
+
this.autoScroller = new AutoScroller(this.scrollContainer, this.onAutoScroll)
|
|
87
|
+
|
|
88
|
+
Object.keys(this.events).forEach((key) =>
|
|
89
|
+
events[key].forEach((eventName) =>
|
|
90
|
+
this.container.addEventListener(eventName, this.events[key], {passive: false}),
|
|
91
|
+
),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
this.container.addEventListener("keydown", this.handleKeyDown)
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
componentWillUnmount() {
|
|
99
|
+
if (this.helper && this.helper.parentNode) {
|
|
100
|
+
this.helper.parentNode.removeChild(this.helper)
|
|
101
|
+
}
|
|
102
|
+
if (!this.container) {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Object.keys(this.events).forEach((key) =>
|
|
107
|
+
events[key].forEach((eventName) =>
|
|
108
|
+
this.container.removeEventListener(eventName, this.events[key]),
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
this.container.removeEventListener("keydown", this.handleKeyDown)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
handleStart = (event) => {
|
|
115
|
+
const {distance, shouldCancelStart} = this.props
|
|
116
|
+
|
|
117
|
+
if (event.button === 2 || shouldCancelStart(event)) {
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.touched = true
|
|
122
|
+
this.position = getPosition(event)
|
|
123
|
+
|
|
124
|
+
const node = closest(event.target, (el) => el.sortableInfo != null)
|
|
125
|
+
|
|
126
|
+
if (node && node.sortableInfo && this.nodeIsChild(node) && !this.state.sorting) {
|
|
127
|
+
const {useDragHandle} = this.props
|
|
128
|
+
const {index, collection, disabled} = node.sortableInfo
|
|
129
|
+
|
|
130
|
+
if (disabled) {
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (useDragHandle && !closest(event.target, isSortableHandle)) {
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
this.manager.active = {collection, index}
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
* Fixes a bug in Firefox where the :active state of anchor tags
|
|
142
|
+
* prevent subsequent 'mousemove' events from being fired
|
|
143
|
+
* (see https://github.com/clauderic/react-sortable-hoc/issues/118)
|
|
144
|
+
*/
|
|
145
|
+
if (!isTouchEvent(event) && event.target.tagName === NodeType.Anchor) {
|
|
146
|
+
// console.log("event.preventDefault()")
|
|
147
|
+
event.preventDefault()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!distance) {
|
|
151
|
+
if (this.props.pressDelay === 0) {
|
|
152
|
+
this.handlePress(event)
|
|
153
|
+
} else {
|
|
154
|
+
this.pressTimer = setTimeout(() => this.handlePress(event), this.props.pressDelay)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
nodeIsChild = (node) => {
|
|
161
|
+
return node.sortableInfo.manager === this.manager
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
handleMove = (event) => {
|
|
165
|
+
const {distance, pressThreshold} = this.props
|
|
166
|
+
|
|
167
|
+
if (!this.state.sorting && this.touched && !this._awaitingUpdateBeforeSortStart) {
|
|
168
|
+
const position = getPosition(event)
|
|
169
|
+
const delta = {
|
|
170
|
+
x: this.position.x - position.x,
|
|
171
|
+
y: this.position.y - position.y,
|
|
172
|
+
}
|
|
173
|
+
const combinedDelta = Math.abs(delta.x) + Math.abs(delta.y)
|
|
174
|
+
|
|
175
|
+
this.delta = delta
|
|
176
|
+
|
|
177
|
+
if (!distance && (!pressThreshold || combinedDelta >= pressThreshold)) {
|
|
178
|
+
clearTimeout(this.cancelTimer)
|
|
179
|
+
this.cancelTimer = setTimeout(this.cancel, 0)
|
|
180
|
+
} else if (distance && combinedDelta >= distance && this.manager.isActive()) {
|
|
181
|
+
this.handlePress(event)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
handleEnd = () => {
|
|
187
|
+
this.touched = false
|
|
188
|
+
this.cancel()
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
cancel = () => {
|
|
192
|
+
const {distance} = this.props
|
|
193
|
+
const {sorting} = this.state
|
|
194
|
+
|
|
195
|
+
if (!sorting) {
|
|
196
|
+
if (!distance) {
|
|
197
|
+
clearTimeout(this.pressTimer)
|
|
198
|
+
}
|
|
199
|
+
this.manager.active = null
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
handlePress = async (event) => {
|
|
204
|
+
const active = this.manager.getActive()
|
|
205
|
+
|
|
206
|
+
if (active) {
|
|
207
|
+
const {
|
|
208
|
+
axis,
|
|
209
|
+
getHelperDimensions,
|
|
210
|
+
helperClass,
|
|
211
|
+
hideSortableGhost,
|
|
212
|
+
updateBeforeSortStart,
|
|
213
|
+
onSortStart,
|
|
214
|
+
useWindowAsScrollContainer,
|
|
215
|
+
} = this.props
|
|
216
|
+
const {node, collection} = active
|
|
217
|
+
const {isKeySorting} = this.manager
|
|
218
|
+
|
|
219
|
+
if (typeof updateBeforeSortStart === "function") {
|
|
220
|
+
this._awaitingUpdateBeforeSortStart = true
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
const {index} = node.sortableInfo
|
|
224
|
+
await updateBeforeSortStart({collection, index, node, isKeySorting}, event)
|
|
225
|
+
} finally {
|
|
226
|
+
this._awaitingUpdateBeforeSortStart = false
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Need to get the latest value for `index` in case it changes during `updateBeforeSortStart`
|
|
231
|
+
const {index} = node.sortableInfo
|
|
232
|
+
const margin = getElementMargin(node)
|
|
233
|
+
const gridGap = getContainerGridGap(this.container)
|
|
234
|
+
const containerBoundingRect = this.scrollContainer.getBoundingClientRect()
|
|
235
|
+
const dimensions = getHelperDimensions({index, node, collection})
|
|
236
|
+
|
|
237
|
+
this.node = node
|
|
238
|
+
this.margin = margin
|
|
239
|
+
this.gridGap = gridGap
|
|
240
|
+
this.width = dimensions.width
|
|
241
|
+
this.height = dimensions.height
|
|
242
|
+
this.marginOffset = {
|
|
243
|
+
x: this.margin.left + this.margin.right + this.gridGap.x,
|
|
244
|
+
y: Math.max(this.margin.top, this.margin.bottom, this.gridGap.y),
|
|
245
|
+
}
|
|
246
|
+
this.boundingClientRect = node.getBoundingClientRect()
|
|
247
|
+
this.containerBoundingRect = containerBoundingRect
|
|
248
|
+
this.index = index
|
|
249
|
+
this.newIndex = index
|
|
250
|
+
|
|
251
|
+
this.axis = {
|
|
252
|
+
x: axis.indexOf("x") >= 0,
|
|
253
|
+
y: axis.indexOf("y") >= 0,
|
|
254
|
+
}
|
|
255
|
+
this.offsetEdge = getEdgeOffset(node, this.container)
|
|
256
|
+
|
|
257
|
+
if (isKeySorting) {
|
|
258
|
+
this.initialOffset = getPosition({
|
|
259
|
+
...event,
|
|
260
|
+
pageX: this.boundingClientRect.left,
|
|
261
|
+
pageY: this.boundingClientRect.top,
|
|
262
|
+
})
|
|
263
|
+
} else {
|
|
264
|
+
this.initialOffset = getPosition(event)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
this.initialScroll = {
|
|
268
|
+
left: this.scrollContainer.scrollLeft,
|
|
269
|
+
top: this.scrollContainer.scrollTop,
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
this.initialWindowScroll = {
|
|
273
|
+
left: window.pageXOffset,
|
|
274
|
+
top: window.pageYOffset,
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
this.helper = this.helperContainer.appendChild(cloneNode(node))
|
|
278
|
+
|
|
279
|
+
setInlineStyles(this.helper, {
|
|
280
|
+
boxSizing: "border-box",
|
|
281
|
+
height: `${this.height}px`,
|
|
282
|
+
left: `${this.boundingClientRect.left - margin.left}px`,
|
|
283
|
+
pointerEvents: "none",
|
|
284
|
+
position: "fixed",
|
|
285
|
+
top: `${this.boundingClientRect.top - margin.top}px`,
|
|
286
|
+
width: `${this.width}px`,
|
|
287
|
+
zIndex: 4000,
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
if (isKeySorting) {
|
|
291
|
+
this.helper.focus()
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (hideSortableGhost) {
|
|
295
|
+
this.sortableGhost = node
|
|
296
|
+
|
|
297
|
+
setInlineStyles(node, {
|
|
298
|
+
opacity: 0,
|
|
299
|
+
visibility: "hidden",
|
|
300
|
+
})
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
this.minTranslate = {}
|
|
304
|
+
this.maxTranslate = {}
|
|
305
|
+
|
|
306
|
+
if (isKeySorting) {
|
|
307
|
+
const {
|
|
308
|
+
top: containerTop,
|
|
309
|
+
left: containerLeft,
|
|
310
|
+
width: containerWidth,
|
|
311
|
+
height: containerHeight,
|
|
312
|
+
} = useWindowAsScrollContainer
|
|
313
|
+
? {
|
|
314
|
+
top: 0,
|
|
315
|
+
left: 0,
|
|
316
|
+
width: this.contentWindow.innerWidth,
|
|
317
|
+
height: this.contentWindow.innerHeight,
|
|
318
|
+
}
|
|
319
|
+
: this.containerBoundingRect
|
|
320
|
+
const containerBottom = containerTop + containerHeight
|
|
321
|
+
const containerRight = containerLeft + containerWidth
|
|
322
|
+
|
|
323
|
+
if (this.axis.x) {
|
|
324
|
+
this.minTranslate.x = containerLeft - this.boundingClientRect.left
|
|
325
|
+
this.maxTranslate.x = containerRight - (this.boundingClientRect.left + this.width)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (this.axis.y) {
|
|
329
|
+
this.minTranslate.y = containerTop - this.boundingClientRect.top
|
|
330
|
+
this.maxTranslate.y = containerBottom - (this.boundingClientRect.top + this.height)
|
|
331
|
+
}
|
|
332
|
+
} else {
|
|
333
|
+
if (this.axis.x) {
|
|
334
|
+
this.minTranslate.x =
|
|
335
|
+
(useWindowAsScrollContainer ? 0 : containerBoundingRect.left) -
|
|
336
|
+
this.boundingClientRect.left -
|
|
337
|
+
this.width / 2
|
|
338
|
+
this.maxTranslate.x =
|
|
339
|
+
(useWindowAsScrollContainer
|
|
340
|
+
? this.contentWindow.innerWidth
|
|
341
|
+
: containerBoundingRect.left + containerBoundingRect.width) -
|
|
342
|
+
this.boundingClientRect.left -
|
|
343
|
+
this.width / 2
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (this.axis.y) {
|
|
347
|
+
this.minTranslate.y =
|
|
348
|
+
(useWindowAsScrollContainer ? 0 : containerBoundingRect.top) -
|
|
349
|
+
this.boundingClientRect.top -
|
|
350
|
+
this.height / 2
|
|
351
|
+
this.maxTranslate.y =
|
|
352
|
+
(useWindowAsScrollContainer
|
|
353
|
+
? this.contentWindow.innerHeight
|
|
354
|
+
: containerBoundingRect.top + containerBoundingRect.height) -
|
|
355
|
+
this.boundingClientRect.top -
|
|
356
|
+
this.height / 2
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (helperClass) {
|
|
361
|
+
helperClass.split(" ").forEach((className) => this.helper.classList.add(className))
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
this.listenerNode = event.touches ? event.target : this.contentWindow
|
|
365
|
+
|
|
366
|
+
if (isKeySorting) {
|
|
367
|
+
this.listenerNode.addEventListener("wheel", this.handleKeyEnd, true)
|
|
368
|
+
this.listenerNode.addEventListener("mousedown", this.handleKeyEnd, true)
|
|
369
|
+
this.listenerNode.addEventListener("keydown", this.handleKeyDown)
|
|
370
|
+
} else {
|
|
371
|
+
events.move.forEach((eventName) =>
|
|
372
|
+
this.listenerNode.addEventListener(eventName, this.handleSortMove, false),
|
|
373
|
+
)
|
|
374
|
+
events.end.forEach((eventName) =>
|
|
375
|
+
this.listenerNode.addEventListener(eventName, this.handleSortEnd, false),
|
|
376
|
+
)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
this.setState({
|
|
380
|
+
sorting: true,
|
|
381
|
+
sortingIndex: index,
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
if (onSortStart) {
|
|
385
|
+
onSortStart(
|
|
386
|
+
{
|
|
387
|
+
node,
|
|
388
|
+
index,
|
|
389
|
+
collection,
|
|
390
|
+
isKeySorting,
|
|
391
|
+
nodes: this.manager.getOrderedRefs(),
|
|
392
|
+
helper: this.helper,
|
|
393
|
+
},
|
|
394
|
+
event,
|
|
395
|
+
)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (isKeySorting) {
|
|
399
|
+
// Readjust positioning in case re-rendering occurs onSortStart
|
|
400
|
+
this.keyMove(0)
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
handleSortMove = (event) => {
|
|
406
|
+
const {onSortMove} = this.props
|
|
407
|
+
|
|
408
|
+
// Prevent scrolling on mobile
|
|
409
|
+
if (typeof event.preventDefault === "function" && event.cancelable) {
|
|
410
|
+
event.preventDefault()
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
this.updateHelperPosition(event)
|
|
414
|
+
this.animateNodes()
|
|
415
|
+
this.autoscroll()
|
|
416
|
+
|
|
417
|
+
if (onSortMove) {
|
|
418
|
+
onSortMove(event)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
handleSortEnd = (event) => {
|
|
423
|
+
const {hideSortableGhost, onSortEnd} = this.props
|
|
424
|
+
const {
|
|
425
|
+
active: {collection},
|
|
426
|
+
isKeySorting,
|
|
427
|
+
} = this.manager
|
|
428
|
+
const nodes = this.manager.getOrderedRefs()
|
|
429
|
+
|
|
430
|
+
// Remove the event listeners if the node is still in the DOM
|
|
431
|
+
if (this.listenerNode) {
|
|
432
|
+
if (isKeySorting) {
|
|
433
|
+
this.listenerNode.removeEventListener("wheel", this.handleKeyEnd, true)
|
|
434
|
+
this.listenerNode.removeEventListener("mousedown", this.handleKeyEnd, true)
|
|
435
|
+
this.listenerNode.removeEventListener("keydown", this.handleKeyDown)
|
|
436
|
+
} else {
|
|
437
|
+
events.move.forEach((eventName) =>
|
|
438
|
+
this.listenerNode.removeEventListener(eventName, this.handleSortMove),
|
|
439
|
+
)
|
|
440
|
+
events.end.forEach((eventName) =>
|
|
441
|
+
this.listenerNode.removeEventListener(eventName, this.handleSortEnd),
|
|
442
|
+
)
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Remove the helper from the DOM
|
|
447
|
+
this.helper.parentNode.removeChild(this.helper)
|
|
448
|
+
|
|
449
|
+
if (hideSortableGhost && this.sortableGhost) {
|
|
450
|
+
setInlineStyles(this.sortableGhost, {
|
|
451
|
+
opacity: "",
|
|
452
|
+
visibility: "",
|
|
453
|
+
})
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
for (let i = 0, len = nodes.length; i < len; i++) {
|
|
457
|
+
const node = nodes[i]
|
|
458
|
+
const el = node.node
|
|
459
|
+
|
|
460
|
+
// Clear the cached offset/boundingClientRect
|
|
461
|
+
node.edgeOffset = null
|
|
462
|
+
node.boundingClientRect = null
|
|
463
|
+
|
|
464
|
+
// Remove the transforms / transitions
|
|
465
|
+
setTranslate3d(el, null)
|
|
466
|
+
setTransitionDuration(el, null)
|
|
467
|
+
node.translate = null
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// Stop autoscroll
|
|
471
|
+
this.autoScroller.clear()
|
|
472
|
+
|
|
473
|
+
// Update manager state
|
|
474
|
+
this.manager.active = null
|
|
475
|
+
this.manager.isKeySorting = false
|
|
476
|
+
|
|
477
|
+
this.setState({
|
|
478
|
+
sorting: false,
|
|
479
|
+
sortingIndex: null,
|
|
480
|
+
})
|
|
481
|
+
|
|
482
|
+
if (typeof onSortEnd === "function") {
|
|
483
|
+
onSortEnd(
|
|
484
|
+
{
|
|
485
|
+
collection,
|
|
486
|
+
newIndex: this.newIndex,
|
|
487
|
+
oldIndex: this.index,
|
|
488
|
+
isKeySorting,
|
|
489
|
+
nodes,
|
|
490
|
+
},
|
|
491
|
+
event,
|
|
492
|
+
)
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
this.touched = false
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
updateHelperPosition(event) {
|
|
499
|
+
const {
|
|
500
|
+
lockAxis,
|
|
501
|
+
lockOffset,
|
|
502
|
+
lockToContainerEdges,
|
|
503
|
+
transitionDuration,
|
|
504
|
+
keyboardSortingTransitionDuration = transitionDuration,
|
|
505
|
+
} = this.props
|
|
506
|
+
const {isKeySorting} = this.manager
|
|
507
|
+
const {ignoreTransition} = event
|
|
508
|
+
|
|
509
|
+
const offset = getPosition(event)
|
|
510
|
+
const translate = {
|
|
511
|
+
x: offset.x - this.initialOffset.x,
|
|
512
|
+
y: offset.y - this.initialOffset.y,
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Adjust for window scroll
|
|
516
|
+
translate.y -= window.pageYOffset - this.initialWindowScroll.top
|
|
517
|
+
translate.x -= window.pageXOffset - this.initialWindowScroll.left
|
|
518
|
+
|
|
519
|
+
this.translate = translate
|
|
520
|
+
|
|
521
|
+
if (lockToContainerEdges) {
|
|
522
|
+
const [minLockOffset, maxLockOffset] = getLockPixelOffsets({
|
|
523
|
+
height: this.height,
|
|
524
|
+
lockOffset,
|
|
525
|
+
width: this.width,
|
|
526
|
+
})
|
|
527
|
+
const minOffset = {
|
|
528
|
+
x: this.width / 2 - minLockOffset.x,
|
|
529
|
+
y: this.height / 2 - minLockOffset.y,
|
|
530
|
+
}
|
|
531
|
+
const maxOffset = {
|
|
532
|
+
x: this.width / 2 - maxLockOffset.x,
|
|
533
|
+
y: this.height / 2 - maxLockOffset.y,
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
translate.x = limit(
|
|
537
|
+
this.minTranslate.x + minOffset.x,
|
|
538
|
+
this.maxTranslate.x - maxOffset.x,
|
|
539
|
+
translate.x,
|
|
540
|
+
)
|
|
541
|
+
translate.y = limit(
|
|
542
|
+
this.minTranslate.y + minOffset.y,
|
|
543
|
+
this.maxTranslate.y - maxOffset.y,
|
|
544
|
+
translate.y,
|
|
545
|
+
)
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (lockAxis === "x") {
|
|
549
|
+
translate.y = 0
|
|
550
|
+
} else if (lockAxis === "y") {
|
|
551
|
+
translate.x = 0
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (isKeySorting && keyboardSortingTransitionDuration && !ignoreTransition) {
|
|
555
|
+
setTransitionDuration(this.helper, keyboardSortingTransitionDuration)
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
setTranslate3d(this.helper, translate)
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
animateNodes() {
|
|
562
|
+
const {transitionDuration, hideSortableGhost, onSortOver} = this.props
|
|
563
|
+
const {containerScrollDelta, windowScrollDelta} = this
|
|
564
|
+
const nodes = this.manager.getOrderedRefs()
|
|
565
|
+
const sortingOffset = {
|
|
566
|
+
left: this.offsetEdge.left + this.translate.x + containerScrollDelta.left,
|
|
567
|
+
top: this.offsetEdge.top + this.translate.y + containerScrollDelta.top,
|
|
568
|
+
}
|
|
569
|
+
const {isKeySorting} = this.manager
|
|
570
|
+
|
|
571
|
+
const prevIndex = this.newIndex
|
|
572
|
+
this.newIndex = null
|
|
573
|
+
|
|
574
|
+
for (let i = 0, len = nodes.length; i < len; i++) {
|
|
575
|
+
const {node} = nodes[i]
|
|
576
|
+
const {index} = node.sortableInfo
|
|
577
|
+
const width = node.offsetWidth
|
|
578
|
+
const height = node.offsetHeight
|
|
579
|
+
const offset = {
|
|
580
|
+
height: this.height > height ? height / 2 : this.height / 2,
|
|
581
|
+
width: this.width > width ? width / 2 : this.width / 2,
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// For keyboard sorting, we want user input to dictate the position of the nodes
|
|
585
|
+
const mustShiftBackward = isKeySorting && index > this.index && index <= prevIndex
|
|
586
|
+
const mustShiftForward = isKeySorting && index < this.index && index >= prevIndex
|
|
587
|
+
|
|
588
|
+
const translate = {
|
|
589
|
+
x: 0,
|
|
590
|
+
y: 0,
|
|
591
|
+
}
|
|
592
|
+
let {edgeOffset} = nodes[i]
|
|
593
|
+
|
|
594
|
+
// If we haven't cached the node's offsetTop / offsetLeft value
|
|
595
|
+
if (!edgeOffset) {
|
|
596
|
+
edgeOffset = getEdgeOffset(node, this.container)
|
|
597
|
+
nodes[i].edgeOffset = edgeOffset
|
|
598
|
+
// While we're at it, cache the boundingClientRect, used during keyboard sorting
|
|
599
|
+
if (isKeySorting) {
|
|
600
|
+
nodes[i].boundingClientRect = getScrollAdjustedBoundingClientRect(
|
|
601
|
+
node,
|
|
602
|
+
containerScrollDelta,
|
|
603
|
+
)
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Get a reference to the next and previous node
|
|
608
|
+
const nextNode = i < nodes.length - 1 && nodes[i + 1]
|
|
609
|
+
const prevNode = i > 0 && nodes[i - 1]
|
|
610
|
+
|
|
611
|
+
// Also cache the next node's edge offset if needed.
|
|
612
|
+
// We need this for calculating the animation in a grid setup
|
|
613
|
+
if (nextNode && !nextNode.edgeOffset) {
|
|
614
|
+
nextNode.edgeOffset = getEdgeOffset(nextNode.node, this.container)
|
|
615
|
+
if (isKeySorting) {
|
|
616
|
+
nextNode.boundingClientRect = getScrollAdjustedBoundingClientRect(
|
|
617
|
+
nextNode.node,
|
|
618
|
+
containerScrollDelta,
|
|
619
|
+
)
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// If the node is the one we're currently animating, skip it
|
|
624
|
+
if (index === this.index) {
|
|
625
|
+
if (hideSortableGhost) {
|
|
626
|
+
/*
|
|
627
|
+
* With windowing libraries such as `react-virtualized`, the sortableGhost
|
|
628
|
+
* node may change while scrolling down and then back up (or vice-versa),
|
|
629
|
+
* so we need to update the reference to the new node just to be safe.
|
|
630
|
+
*/
|
|
631
|
+
this.sortableGhost = node
|
|
632
|
+
|
|
633
|
+
setInlineStyles(node, {
|
|
634
|
+
opacity: 0,
|
|
635
|
+
visibility: "hidden",
|
|
636
|
+
})
|
|
637
|
+
}
|
|
638
|
+
continue
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
if (transitionDuration) {
|
|
642
|
+
setTransitionDuration(node, transitionDuration)
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
if (this.axis.x) {
|
|
646
|
+
if (this.axis.y) {
|
|
647
|
+
// Calculations for a grid setup
|
|
648
|
+
if (
|
|
649
|
+
mustShiftForward ||
|
|
650
|
+
(index < this.index &&
|
|
651
|
+
((sortingOffset.left + windowScrollDelta.left - offset.width <= edgeOffset.left &&
|
|
652
|
+
sortingOffset.top + windowScrollDelta.top <= edgeOffset.top + offset.height) ||
|
|
653
|
+
sortingOffset.top + windowScrollDelta.top + offset.height <= edgeOffset.top))
|
|
654
|
+
) {
|
|
655
|
+
// If the current node is to the left on the same row, or above the node that's being dragged
|
|
656
|
+
// then move it to the right
|
|
657
|
+
translate.x = this.width + this.marginOffset.x
|
|
658
|
+
if (
|
|
659
|
+
edgeOffset.left + translate.x >
|
|
660
|
+
this.containerBoundingRect.width - offset.width * 2
|
|
661
|
+
) {
|
|
662
|
+
// If it moves passed the right bounds, then animate it to the first position of the next row.
|
|
663
|
+
// We just use the offset of the next node to calculate where to move, because that node's original position
|
|
664
|
+
// is exactly where we want to go
|
|
665
|
+
if (nextNode) {
|
|
666
|
+
translate.x = nextNode.edgeOffset.left - edgeOffset.left
|
|
667
|
+
translate.y = nextNode.edgeOffset.top - edgeOffset.top
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
if (this.newIndex === null) {
|
|
671
|
+
this.newIndex = index
|
|
672
|
+
}
|
|
673
|
+
} else if (
|
|
674
|
+
mustShiftBackward ||
|
|
675
|
+
(index > this.index &&
|
|
676
|
+
((sortingOffset.left + windowScrollDelta.left + offset.width >= edgeOffset.left &&
|
|
677
|
+
sortingOffset.top + windowScrollDelta.top + offset.height >= edgeOffset.top) ||
|
|
678
|
+
sortingOffset.top + windowScrollDelta.top + offset.height >=
|
|
679
|
+
edgeOffset.top + height))
|
|
680
|
+
) {
|
|
681
|
+
// If the current node is to the right on the same row, or below the node that's being dragged
|
|
682
|
+
// then move it to the left
|
|
683
|
+
translate.x = -(this.width + this.marginOffset.x)
|
|
684
|
+
if (edgeOffset.left + translate.x < this.containerBoundingRect.left + offset.width) {
|
|
685
|
+
// If it moves passed the left bounds, then animate it to the last position of the previous row.
|
|
686
|
+
// We just use the offset of the previous node to calculate where to move, because that node's original position
|
|
687
|
+
// is exactly where we want to go
|
|
688
|
+
if (prevNode) {
|
|
689
|
+
translate.x = prevNode.edgeOffset.left - edgeOffset.left
|
|
690
|
+
translate.y = prevNode.edgeOffset.top - edgeOffset.top
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
this.newIndex = index
|
|
694
|
+
}
|
|
695
|
+
} else {
|
|
696
|
+
if (
|
|
697
|
+
mustShiftBackward ||
|
|
698
|
+
(index > this.index &&
|
|
699
|
+
sortingOffset.left + windowScrollDelta.left + offset.width >= edgeOffset.left)
|
|
700
|
+
) {
|
|
701
|
+
translate.x = -(this.width + this.marginOffset.x)
|
|
702
|
+
this.newIndex = index
|
|
703
|
+
} else if (
|
|
704
|
+
mustShiftForward ||
|
|
705
|
+
(index < this.index &&
|
|
706
|
+
sortingOffset.left + windowScrollDelta.left <= edgeOffset.left + offset.width)
|
|
707
|
+
) {
|
|
708
|
+
translate.x = this.width + this.marginOffset.x
|
|
709
|
+
|
|
710
|
+
if (this.newIndex == null) {
|
|
711
|
+
this.newIndex = index
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
} else if (this.axis.y) {
|
|
716
|
+
if (
|
|
717
|
+
mustShiftBackward ||
|
|
718
|
+
(index > this.index &&
|
|
719
|
+
sortingOffset.top + windowScrollDelta.top + offset.height >= edgeOffset.top)
|
|
720
|
+
) {
|
|
721
|
+
translate.y = -(this.height + this.marginOffset.y)
|
|
722
|
+
this.newIndex = index
|
|
723
|
+
} else if (
|
|
724
|
+
mustShiftForward ||
|
|
725
|
+
(index < this.index &&
|
|
726
|
+
sortingOffset.top + windowScrollDelta.top <= edgeOffset.top + offset.height)
|
|
727
|
+
) {
|
|
728
|
+
translate.y = this.height + this.marginOffset.y
|
|
729
|
+
if (this.newIndex == null) {
|
|
730
|
+
this.newIndex = index
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
setTranslate3d(node, translate)
|
|
736
|
+
nodes[i].translate = translate
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
if (this.newIndex == null) {
|
|
740
|
+
this.newIndex = this.index
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
if (isKeySorting) {
|
|
744
|
+
// If keyboard sorting, we want the user input to dictate index, not location of the helper
|
|
745
|
+
this.newIndex = prevIndex
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
const oldIndex = isKeySorting ? this.prevIndex : prevIndex
|
|
749
|
+
if (onSortOver && this.newIndex !== oldIndex) {
|
|
750
|
+
onSortOver({
|
|
751
|
+
collection: this.manager.active.collection,
|
|
752
|
+
index: this.index,
|
|
753
|
+
newIndex: this.newIndex,
|
|
754
|
+
oldIndex,
|
|
755
|
+
isKeySorting,
|
|
756
|
+
nodes,
|
|
757
|
+
helper: this.helper,
|
|
758
|
+
})
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
autoscroll = () => {
|
|
763
|
+
const {disableAutoscroll} = this.props
|
|
764
|
+
const {isKeySorting} = this.manager
|
|
765
|
+
|
|
766
|
+
if (disableAutoscroll) {
|
|
767
|
+
this.autoScroller.clear()
|
|
768
|
+
return
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
if (isKeySorting) {
|
|
772
|
+
const translate = {...this.translate}
|
|
773
|
+
let scrollX = 0
|
|
774
|
+
let scrollY = 0
|
|
775
|
+
|
|
776
|
+
if (this.axis.x) {
|
|
777
|
+
translate.x = Math.min(
|
|
778
|
+
this.maxTranslate.x,
|
|
779
|
+
Math.max(this.minTranslate.x, this.translate.x),
|
|
780
|
+
)
|
|
781
|
+
scrollX = this.translate.x - translate.x
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (this.axis.y) {
|
|
785
|
+
translate.y = Math.min(
|
|
786
|
+
this.maxTranslate.y,
|
|
787
|
+
Math.max(this.minTranslate.y, this.translate.y),
|
|
788
|
+
)
|
|
789
|
+
scrollY = this.translate.y - translate.y
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
this.translate = translate
|
|
793
|
+
setTranslate3d(this.helper, this.translate)
|
|
794
|
+
this.scrollContainer.scrollLeft += scrollX
|
|
795
|
+
this.scrollContainer.scrollTop += scrollY
|
|
796
|
+
|
|
797
|
+
return
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
this.autoScroller.update({
|
|
801
|
+
height: this.height,
|
|
802
|
+
maxTranslate: this.maxTranslate,
|
|
803
|
+
minTranslate: this.minTranslate,
|
|
804
|
+
translate: this.translate,
|
|
805
|
+
width: this.width,
|
|
806
|
+
})
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
onAutoScroll = (offset) => {
|
|
810
|
+
this.translate.x += offset.left
|
|
811
|
+
this.translate.y += offset.top
|
|
812
|
+
|
|
813
|
+
this.animateNodes()
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
getWrappedInstance() {
|
|
817
|
+
invariant(
|
|
818
|
+
config.withRef,
|
|
819
|
+
"To access the wrapped instance, you need to pass in {withRef: true} as the second argument of the SortableContainer() call",
|
|
820
|
+
)
|
|
821
|
+
|
|
822
|
+
return this.wrappedInstance.current
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
getContainer() {
|
|
826
|
+
const {getContainer} = this.props
|
|
827
|
+
|
|
828
|
+
if (typeof getContainer !== "function") {
|
|
829
|
+
return this.containerRef.current
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
return getContainer(config.withRef ? this.getWrappedInstance() : undefined);
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
handleKeyDown = (event) => {
|
|
836
|
+
const {keyCode} = event
|
|
837
|
+
const {shouldCancelStart, keyCodes: customKeyCodes = {}} = this.props
|
|
838
|
+
|
|
839
|
+
const keyCodes = {
|
|
840
|
+
...defaultKeyCodes,
|
|
841
|
+
...customKeyCodes,
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
if (
|
|
845
|
+
(this.manager.active && !this.manager.isKeySorting) ||
|
|
846
|
+
(!this.manager.active &&
|
|
847
|
+
(!keyCodes.lift.includes(keyCode) ||
|
|
848
|
+
shouldCancelStart(event) ||
|
|
849
|
+
!this.isValidSortingTarget(event)))
|
|
850
|
+
) {
|
|
851
|
+
return
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
event.stopPropagation()
|
|
855
|
+
event.preventDefault()
|
|
856
|
+
|
|
857
|
+
if (keyCodes.lift.includes(keyCode) && !this.manager.active) {
|
|
858
|
+
this.keyLift(event)
|
|
859
|
+
} else if (keyCodes.drop.includes(keyCode) && this.manager.active) {
|
|
860
|
+
this.keyDrop(event)
|
|
861
|
+
} else if (keyCodes.cancel.includes(keyCode)) {
|
|
862
|
+
this.newIndex = this.manager.active.index
|
|
863
|
+
this.keyDrop(event)
|
|
864
|
+
} else if (keyCodes.up.includes(keyCode)) {
|
|
865
|
+
this.keyMove(-1)
|
|
866
|
+
} else if (keyCodes.down.includes(keyCode)) {
|
|
867
|
+
this.keyMove(1)
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
keyLift = (event) => {
|
|
872
|
+
const {target} = event
|
|
873
|
+
const node = closest(target, (el) => el.sortableInfo != null)
|
|
874
|
+
const {index, collection} = node.sortableInfo
|
|
875
|
+
|
|
876
|
+
this.initialFocusedNode = target
|
|
877
|
+
|
|
878
|
+
this.manager.isKeySorting = true
|
|
879
|
+
this.manager.active = {
|
|
880
|
+
index,
|
|
881
|
+
collection,
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
this.handlePress(event)
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
keyMove = (shift) => {
|
|
888
|
+
const nodes = this.manager.getOrderedRefs()
|
|
889
|
+
const {index: lastIndex} = nodes[nodes.length - 1].node.sortableInfo
|
|
890
|
+
const newIndex = this.newIndex + shift
|
|
891
|
+
const prevIndex = this.newIndex
|
|
892
|
+
|
|
893
|
+
if (newIndex < 0 || newIndex > lastIndex) {
|
|
894
|
+
return
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
this.prevIndex = prevIndex
|
|
898
|
+
this.newIndex = newIndex
|
|
899
|
+
|
|
900
|
+
const targetIndex = getTargetIndex(this.newIndex, this.prevIndex, this.index)
|
|
901
|
+
const target = nodes.find(({node}) => node.sortableInfo.index === targetIndex)
|
|
902
|
+
const {node: targetNode} = target
|
|
903
|
+
|
|
904
|
+
const scrollDelta = this.containerScrollDelta
|
|
905
|
+
const targetBoundingClientRect =
|
|
906
|
+
target.boundingClientRect || getScrollAdjustedBoundingClientRect(targetNode, scrollDelta)
|
|
907
|
+
const targetTranslate = target.translate || {x: 0, y: 0}
|
|
908
|
+
|
|
909
|
+
const targetPosition = {
|
|
910
|
+
top: targetBoundingClientRect.top + targetTranslate.y - scrollDelta.top,
|
|
911
|
+
left: targetBoundingClientRect.left + targetTranslate.x - scrollDelta.left,
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
const shouldAdjustForSize = prevIndex < newIndex
|
|
915
|
+
const sizeAdjustment = {
|
|
916
|
+
x: shouldAdjustForSize && this.axis.x ? targetNode.offsetWidth - this.width : 0,
|
|
917
|
+
y: shouldAdjustForSize && this.axis.y ? targetNode.offsetHeight - this.height : 0,
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
this.handleSortMove({
|
|
921
|
+
pageX: targetPosition.left + sizeAdjustment.x,
|
|
922
|
+
pageY: targetPosition.top + sizeAdjustment.y,
|
|
923
|
+
ignoreTransition: shift === 0,
|
|
924
|
+
})
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
keyDrop = (event) => {
|
|
928
|
+
this.handleSortEnd(event)
|
|
929
|
+
|
|
930
|
+
if (this.initialFocusedNode) {
|
|
931
|
+
this.initialFocusedNode.focus()
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
handleKeyEnd = (event) => {
|
|
936
|
+
if (this.manager.active) {
|
|
937
|
+
this.keyDrop(event)
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
isValidSortingTarget = (event) => {
|
|
942
|
+
const {useDragHandle} = this.props
|
|
943
|
+
const {target} = event
|
|
944
|
+
const node = closest(target, (el) => el.sortableInfo != null)
|
|
945
|
+
|
|
946
|
+
return (
|
|
947
|
+
node &&
|
|
948
|
+
node.sortableInfo &&
|
|
949
|
+
!node.sortableInfo.disabled &&
|
|
950
|
+
(useDragHandle ? isSortableHandle(target) : target.sortableInfo)
|
|
951
|
+
)
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
render() {
|
|
955
|
+
const ref = config.withRef ? this.wrappedInstance : this.containerRef; // Attach the ref
|
|
956
|
+
|
|
957
|
+
return (
|
|
958
|
+
<SortableContext.Provider value={this.sortableContextValue}>
|
|
959
|
+
<WrappedComponent ref={ref} {...omit(this.props, omittedProps)} />
|
|
960
|
+
</SortableContext.Provider>
|
|
961
|
+
)
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
get helperContainer() {
|
|
965
|
+
const {helperContainer} = this.props
|
|
966
|
+
|
|
967
|
+
if (typeof helperContainer === "function") {
|
|
968
|
+
return helperContainer()
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
return this.props.helperContainer || this.document.body
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
get containerScrollDelta() {
|
|
975
|
+
const {useWindowAsScrollContainer} = this.props
|
|
976
|
+
|
|
977
|
+
if (useWindowAsScrollContainer) {
|
|
978
|
+
return {left: 0, top: 0}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
return {
|
|
982
|
+
left: this.scrollContainer.scrollLeft - this.initialScroll.left,
|
|
983
|
+
top: this.scrollContainer.scrollTop - this.initialScroll.top,
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
get windowScrollDelta() {
|
|
988
|
+
return {
|
|
989
|
+
left: this.contentWindow.pageXOffset - this.initialWindowScroll.left,
|
|
990
|
+
top: this.contentWindow.pageYOffset - this.initialWindowScroll.top,
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|