@@ -4,6 +4,7 @@ import { findDOMNode } from 'react-dom';
4
4
import throttle from 'lodash.throttle' ;
5
5
import raf from 'raf' ;
6
6
import getDisplayName from 'react-display-name' ;
7
+ import { Consumer as DragDropContextConsumer } from 'react-dnd/lib/DragDropContext' ;
7
8
import hoist from 'hoist-non-react-statics' ;
8
9
import { noop , intBetween , getCoords } from './util' ;
9
10
@@ -18,7 +19,8 @@ export function createHorizontalStrength(_buffer) {
18
19
if ( inBox ) {
19
20
if ( point . x < x + buffer ) {
20
21
return ( point . x - x - buffer ) / buffer ;
21
- } else if ( point . x > ( x + w - buffer ) ) {
22
+ }
23
+ if ( point . x > ( x + w - buffer ) ) {
22
24
return - ( x + w - point . x - buffer ) / buffer ;
23
25
}
24
26
}
@@ -36,7 +38,8 @@ export function createVerticalStrength(_buffer) {
36
38
if ( inBox ) {
37
39
if ( point . y < y + buffer ) {
38
40
return ( point . y - y - buffer ) / buffer ;
39
- } else if ( point . y > ( y + h - buffer ) ) {
41
+ }
42
+ if ( point . y > ( y + h - buffer ) ) {
40
43
return - ( y + h - point . y - buffer ) / buffer ;
41
44
}
42
45
}
@@ -50,12 +53,13 @@ export const defaultHorizontalStrength = createHorizontalStrength(DEFAULT_BUFFER
50
53
export const defaultVerticalStrength = createVerticalStrength ( DEFAULT_BUFFER ) ;
51
54
52
55
53
- export default function createScrollingComponent ( WrappedComponent ) {
56
+ export function createScrollingComponent ( WrappedComponent ) {
54
57
class ScrollingComponent extends Component {
55
-
56
58
static displayName = `Scrolling(${ getDisplayName ( WrappedComponent ) } )` ;
57
59
58
60
static propTypes = {
61
+ // eslint-disable-next-line react/forbid-prop-types
62
+ dragDropManager : PropTypes . object . isRequired ,
59
63
onScrollChange : PropTypes . func ,
60
64
verticalStrength : PropTypes . func ,
61
65
horizontalStrength : PropTypes . func ,
@@ -69,13 +73,33 @@ export default function createScrollingComponent(WrappedComponent) {
69
73
strengthMultiplier : 30 ,
70
74
} ;
71
75
72
- static contextTypes = {
73
- dragDropManager : PropTypes . object ,
74
- } ;
76
+ // Update scaleX and scaleY every 100ms or so
77
+ // and start scrolling if necessary
78
+ updateScrolling = throttle ( ( evt ) => {
79
+ const {
80
+ left : x , top : y , width : w , height : h ,
81
+ } = this . container . getBoundingClientRect ( ) ;
82
+ const box = {
83
+ x, y, w, h,
84
+ } ;
85
+ const coords = getCoords ( evt ) ;
86
+
87
+ // calculate strength
88
+ const { horizontalStrength, verticalStrength } = this . props ;
89
+ this . scaleX = horizontalStrength ( box , coords ) ;
90
+ this . scaleY = verticalStrength ( box , coords ) ;
91
+
92
+ // start scrolling if we need to
93
+ if ( ! this . frame && ( this . scaleX || this . scaleY ) ) {
94
+ this . startScrolling ( ) ;
95
+ }
96
+ } , 100 , { trailing : false } )
75
97
76
98
constructor ( props , ctx ) {
77
99
super ( props , ctx ) ;
78
100
101
+ this . wrappedInstance = React . createRef ( ) ;
102
+
79
103
this . scaleX = 0 ;
80
104
this . scaleY = 0 ;
81
105
this . frame = null ;
@@ -85,16 +109,17 @@ export default function createScrollingComponent(WrappedComponent) {
85
109
}
86
110
87
111
componentDidMount ( ) {
88
- this . container = findDOMNode ( this . wrappedInstance ) ;
112
+ // eslint-disable-next-line react/no-find-dom-node
113
+ this . container = findDOMNode ( this . wrappedInstance . current ) ;
89
114
this . container . addEventListener ( 'dragover' , this . handleEvent ) ;
90
115
// touchmove events don't seem to work across siblings, so we unfortunately
91
116
// have to attach the listeners to the body
92
117
window . document . body . addEventListener ( 'touchmove' , this . handleEvent ) ;
93
118
94
- this . clearMonitorSubscription = this . context
95
- . dragDropManager
96
- . getMonitor ( )
97
- . subscribeToStateChange ( ( ) => this . handleMonitorChange ( ) ) ;
119
+ const { dragDropManager } = this . props ;
120
+ this . clearMonitorSubscription = dragDropManager
121
+ . getMonitor ( )
122
+ . subscribeToStateChange ( ( ) => this . handleMonitorChange ( ) ) ;
98
123
}
99
124
100
125
componentWillUnmount ( ) {
@@ -112,7 +137,8 @@ export default function createScrollingComponent(WrappedComponent) {
112
137
}
113
138
114
139
handleMonitorChange ( ) {
115
- const isDragging = this . context . dragDropManager . getMonitor ( ) . isDragging ( ) ;
140
+ const { dragDropManager } = this . props ;
141
+ const isDragging = dragDropManager . getMonitor ( ) . isDragging ( ) ;
116
142
117
143
if ( ! this . dragging && isDragging ) {
118
144
this . dragging = true ;
@@ -134,23 +160,6 @@ export default function createScrollingComponent(WrappedComponent) {
134
160
window . document . body . removeEventListener ( 'touchmove' , this . updateScrolling ) ;
135
161
}
136
162
137
- // Update scaleX and scaleY every 100ms or so
138
- // and start scrolling if necessary
139
- updateScrolling = throttle ( evt => {
140
- const { left : x , top : y , width : w , height : h } = this . container . getBoundingClientRect ( ) ;
141
- const box = { x, y, w, h } ;
142
- const coords = getCoords ( evt ) ;
143
-
144
- // calculate strength
145
- this . scaleX = this . props . horizontalStrength ( box , coords ) ;
146
- this . scaleY = this . props . verticalStrength ( box , coords ) ;
147
-
148
- // start scrolling if we need to
149
- if ( ! this . frame && ( this . scaleX || this . scaleY ) ) {
150
- this . startScrolling ( ) ;
151
- }
152
- } , 100 , { trailing : false } )
153
-
154
163
startScrolling ( ) {
155
164
let i = 0 ;
156
165
const tick = ( ) => {
@@ -167,7 +176,8 @@ export default function createScrollingComponent(WrappedComponent) {
167
176
// mousemove events from a container that also emits a scroll
168
177
// event that same frame. So we double the strengthMultiplier and only adjust
169
178
// the scroll position at 30fps
170
- if ( i ++ % 2 ) {
179
+ i += 1 ;
180
+ if ( i % 2 ) {
171
181
const {
172
182
scrollLeft,
173
183
scrollTop,
@@ -181,15 +191,15 @@ export default function createScrollingComponent(WrappedComponent) {
181
191
? container . scrollLeft = intBetween (
182
192
0 ,
183
193
scrollWidth - clientWidth ,
184
- scrollLeft + scaleX * strengthMultiplier
194
+ scrollLeft + scaleX * strengthMultiplier ,
185
195
)
186
196
: scrollLeft ;
187
197
188
198
const newTop = scaleY
189
199
? container . scrollTop = intBetween (
190
200
0 ,
191
201
scrollHeight - clientHeight ,
192
- scrollTop + scaleY * strengthMultiplier
202
+ scrollTop + scaleY * strengthMultiplier ,
193
203
)
194
204
: scrollTop ;
195
205
@@ -220,12 +230,12 @@ export default function createScrollingComponent(WrappedComponent) {
220
230
horizontalStrength,
221
231
onScrollChange,
222
232
223
- ...props ,
233
+ ...props
224
234
} = this . props ;
225
235
226
236
return (
227
237
< WrappedComponent
228
- ref = { ( ref ) => { this . wrappedInstance = ref ; } }
238
+ ref = { this . wrappedInstance }
229
239
{ ...props }
230
240
/>
231
241
) ;
@@ -234,3 +244,16 @@ export default function createScrollingComponent(WrappedComponent) {
234
244
235
245
return hoist ( ScrollingComponent , WrappedComponent ) ;
236
246
}
247
+
248
+ export default function createScrollingComponentWithConsumer ( WrappedComponent ) {
249
+ const ScrollingComponent = createScrollingComponent ( WrappedComponent ) ;
250
+ return props => (
251
+ < DragDropContextConsumer >
252
+ { ( { dragDropManager } ) => (
253
+ dragDropManager === undefined
254
+ ? null
255
+ : < ScrollingComponent { ...props } dragDropManager = { dragDropManager } />
256
+ ) }
257
+ </ DragDropContextConsumer >
258
+ ) ;
259
+ }
0 commit comments