@@ -4,6 +4,7 @@ import { findDOMNode } from 'react-dom';
44import throttle from 'lodash.throttle' ;
55import raf from 'raf' ;
66import getDisplayName from 'react-display-name' ;
7+ import { Consumer as DragDropContextConsumer } from 'react-dnd/lib/DragDropContext' ;
78import hoist from 'hoist-non-react-statics' ;
89import { noop , intBetween , getCoords } from './util' ;
910
@@ -18,7 +19,8 @@ export function createHorizontalStrength(_buffer) {
1819 if ( inBox ) {
1920 if ( point . x < x + buffer ) {
2021 return ( point . x - x - buffer ) / buffer ;
21- } else if ( point . x > ( x + w - buffer ) ) {
22+ }
23+ if ( point . x > ( x + w - buffer ) ) {
2224 return - ( x + w - point . x - buffer ) / buffer ;
2325 }
2426 }
@@ -36,7 +38,8 @@ export function createVerticalStrength(_buffer) {
3638 if ( inBox ) {
3739 if ( point . y < y + buffer ) {
3840 return ( point . y - y - buffer ) / buffer ;
39- } else if ( point . y > ( y + h - buffer ) ) {
41+ }
42+ if ( point . y > ( y + h - buffer ) ) {
4043 return - ( y + h - point . y - buffer ) / buffer ;
4144 }
4245 }
@@ -50,12 +53,13 @@ export const defaultHorizontalStrength = createHorizontalStrength(DEFAULT_BUFFER
5053export const defaultVerticalStrength = createVerticalStrength ( DEFAULT_BUFFER ) ;
5154
5255
53- export default function createScrollingComponent ( WrappedComponent ) {
56+ export function createScrollingComponent ( WrappedComponent ) {
5457 class ScrollingComponent extends Component {
55-
5658 static displayName = `Scrolling(${ getDisplayName ( WrappedComponent ) } )` ;
5759
5860 static propTypes = {
61+ // eslint-disable-next-line react/forbid-prop-types
62+ dragDropManager : PropTypes . object . isRequired ,
5963 onScrollChange : PropTypes . func ,
6064 verticalStrength : PropTypes . func ,
6165 horizontalStrength : PropTypes . func ,
@@ -69,13 +73,33 @@ export default function createScrollingComponent(WrappedComponent) {
6973 strengthMultiplier : 30 ,
7074 } ;
7175
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 } )
7597
7698 constructor ( props , ctx ) {
7799 super ( props , ctx ) ;
78100
101+ this . wrappedInstance = React . createRef ( ) ;
102+
79103 this . scaleX = 0 ;
80104 this . scaleY = 0 ;
81105 this . frame = null ;
@@ -85,16 +109,17 @@ export default function createScrollingComponent(WrappedComponent) {
85109 }
86110
87111 componentDidMount ( ) {
88- this . container = findDOMNode ( this . wrappedInstance ) ;
112+ // eslint-disable-next-line react/no-find-dom-node
113+ this . container = findDOMNode ( this . wrappedInstance . current ) ;
89114 this . container . addEventListener ( 'dragover' , this . handleEvent ) ;
90115 // touchmove events don't seem to work across siblings, so we unfortunately
91116 // have to attach the listeners to the body
92117 window . document . body . addEventListener ( 'touchmove' , this . handleEvent ) ;
93118
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 ( ) ) ;
98123 }
99124
100125 componentWillUnmount ( ) {
@@ -112,7 +137,8 @@ export default function createScrollingComponent(WrappedComponent) {
112137 }
113138
114139 handleMonitorChange ( ) {
115- const isDragging = this . context . dragDropManager . getMonitor ( ) . isDragging ( ) ;
140+ const { dragDropManager } = this . props ;
141+ const isDragging = dragDropManager . getMonitor ( ) . isDragging ( ) ;
116142
117143 if ( ! this . dragging && isDragging ) {
118144 this . dragging = true ;
@@ -134,23 +160,6 @@ export default function createScrollingComponent(WrappedComponent) {
134160 window . document . body . removeEventListener ( 'touchmove' , this . updateScrolling ) ;
135161 }
136162
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-
154163 startScrolling ( ) {
155164 let i = 0 ;
156165 const tick = ( ) => {
@@ -167,7 +176,8 @@ export default function createScrollingComponent(WrappedComponent) {
167176 // mousemove events from a container that also emits a scroll
168177 // event that same frame. So we double the strengthMultiplier and only adjust
169178 // the scroll position at 30fps
170- if ( i ++ % 2 ) {
179+ i += 1 ;
180+ if ( i % 2 ) {
171181 const {
172182 scrollLeft,
173183 scrollTop,
@@ -181,15 +191,15 @@ export default function createScrollingComponent(WrappedComponent) {
181191 ? container . scrollLeft = intBetween (
182192 0 ,
183193 scrollWidth - clientWidth ,
184- scrollLeft + scaleX * strengthMultiplier
194+ scrollLeft + scaleX * strengthMultiplier ,
185195 )
186196 : scrollLeft ;
187197
188198 const newTop = scaleY
189199 ? container . scrollTop = intBetween (
190200 0 ,
191201 scrollHeight - clientHeight ,
192- scrollTop + scaleY * strengthMultiplier
202+ scrollTop + scaleY * strengthMultiplier ,
193203 )
194204 : scrollTop ;
195205
@@ -220,12 +230,12 @@ export default function createScrollingComponent(WrappedComponent) {
220230 horizontalStrength,
221231 onScrollChange,
222232
223- ...props ,
233+ ...props
224234 } = this . props ;
225235
226236 return (
227237 < WrappedComponent
228- ref = { ( ref ) => { this . wrappedInstance = ref ; } }
238+ ref = { this . wrappedInstance }
229239 { ...props }
230240 />
231241 ) ;
@@ -234,3 +244,16 @@ export default function createScrollingComponent(WrappedComponent) {
234244
235245 return hoist ( ScrollingComponent , WrappedComponent ) ;
236246}
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