Skip to content

Updated dependencies and support for react-dnd@6 #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions .babelrc

This file was deleted.

9 changes: 9 additions & 0 deletions .babelrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-react',
],
plugins: [
'@babel/plugin-proposal-class-properties',
],
}
13 changes: 0 additions & 13 deletions .eslintrc

This file was deleted.

15 changes: 15 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
parser: 'babel-eslint',
extends: 'airbnb',

rules: {
'react/jsx-filename-extension': 0,
'no-unused-vars': 0,
'react/prop-types': 0,
},

env: {
browser: true,
mocha: true
},
}
43 changes: 24 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,35 @@
},
"license": "MIT",
"dependencies": {
"hoist-non-react-statics": "^1.2.0",
"hoist-non-react-statics": "^3.1.0",
"lodash.throttle": "^4.0.1",
"prop-types": "^15.5.9",
"raf": "^3.2.0",
"react-display-name": "^0.2.0"
"react": "^16.3.0",
"react-display-name": "^0.2.0",
"react-dom": "^16.3.0"
},
"devDependencies": {
"babel-cli": "^6.4.5",
"babel-eslint": "^6.0.4",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-1": "^6.3.13",
"babel-register": "^6.4.3",
"chai": "^3.4.1",
"eslint": "^2.12.0",
"eslint-config-airbnb": "^9.0.1",
"eslint-plugin-import": "^1.8.1",
"eslint-plugin-jsx-a11y": "^1.4.2",
"eslint-plugin-react": "^5.1.1",
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/register": "^7.0.0",
"babel-eslint": "^10.0.1",
"chai": "^4.2.0",
"eslint": "^5.9.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.2",
"eslint-plugin-react": "^7.11.1",
"in-publish": "^2.0.0",
"mocha": "^2.3.4",
"react": "^15.1.0",
"react-dom": "^15.1.0",
"sinon": "^1.17.2",
"sinon-chai": "^2.8.0"
"mocha": "^5.2.0",
"react-dnd": "^7.0.2",
"sinon": "^7.1.1",
"sinon-chai": "^3.2.0"
},
"peerDependencies": {
"react-dnd": "^6.0.0 || ^7.0.0"
}
}
101 changes: 64 additions & 37 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ import { findDOMNode } from 'react-dom';
import throttle from 'lodash.throttle';
import raf from 'raf';
import getDisplayName from 'react-display-name';
import { Consumer as DragDropContextConsumer } from 'react-dnd/lib/DragDropContext';
import hoist from 'hoist-non-react-statics';
import { noop, intBetween, getCoords } from './util';

const DEFAULT_BUFFER = 150;

export function createHorizontalStrength(_buffer) {
return function defaultHorizontalStrength({ x, w, y, h }, point) {
return function defaultHorizontalStrength({
x, w, y, h,
}, point) {
const buffer = Math.min(w / 2, _buffer);
const inRange = point.x >= x && point.x <= x + w;
const inBox = inRange && point.y >= y && point.y <= y + h;

if (inBox) {
if (point.x < x + buffer) {
return (point.x - x - buffer) / buffer;
} else if (point.x > (x + w - buffer)) {
}
if (point.x > (x + w - buffer)) {
return -(x + w - point.x - buffer) / buffer;
}
}
Expand All @@ -28,15 +32,18 @@ export function createHorizontalStrength(_buffer) {
}

export function createVerticalStrength(_buffer) {
return function defaultVerticalStrength({ y, h, x, w }, point) {
return function defaultVerticalStrength({
y, h, x, w,
}, point) {
const buffer = Math.min(h / 2, _buffer);
const inRange = point.y >= y && point.y <= y + h;
const inBox = inRange && point.x >= x && point.x <= x + w;

if (inBox) {
if (point.y < y + buffer) {
return (point.y - y - buffer) / buffer;
} else if (point.y > (y + h - buffer)) {
}
if (point.y > (y + h - buffer)) {
return -(y + h - point.y - buffer) / buffer;
}
}
Expand All @@ -50,12 +57,13 @@ export const defaultHorizontalStrength = createHorizontalStrength(DEFAULT_BUFFER
export const defaultVerticalStrength = createVerticalStrength(DEFAULT_BUFFER);


export default function createScrollingComponent(WrappedComponent) {
export function createScrollingComponent(WrappedComponent) {
class ScrollingComponent extends Component {

static displayName = `Scrolling(${getDisplayName(WrappedComponent)})`;

static propTypes = {
// eslint-disable-next-line react/forbid-prop-types
dragDropManager: PropTypes.object.isRequired,
onScrollChange: PropTypes.func,
verticalStrength: PropTypes.func,
horizontalStrength: PropTypes.func,
Expand All @@ -69,13 +77,33 @@ export default function createScrollingComponent(WrappedComponent) {
strengthMultiplier: 30,
};

static contextTypes = {
dragDropManager: PropTypes.object,
};
// Update scaleX and scaleY every 100ms or so
// and start scrolling if necessary
updateScrolling = throttle((evt) => {
const {
left: x, top: y, width: w, height: h,
} = this.container.getBoundingClientRect();
const box = {
x, y, w, h,
};
const coords = getCoords(evt);

// calculate strength
const { horizontalStrength, verticalStrength } = this.props;
this.scaleX = horizontalStrength(box, coords);
this.scaleY = verticalStrength(box, coords);

// start scrolling if we need to
if (!this.frame && (this.scaleX || this.scaleY)) {
this.startScrolling();
}
}, 100, { trailing: false })

constructor(props, ctx) {
super(props, ctx);

this.wrappedInstance = React.createRef();

this.scaleX = 0;
this.scaleY = 0;
this.frame = null;
Expand All @@ -85,16 +113,17 @@ export default function createScrollingComponent(WrappedComponent) {
}

componentDidMount() {
this.container = findDOMNode(this.wrappedInstance);
// eslint-disable-next-line react/no-find-dom-node
this.container = findDOMNode(this.wrappedInstance.current);
this.container.addEventListener('dragover', this.handleEvent);
// touchmove events don't seem to work across siblings, so we unfortunately
// have to attach the listeners to the body
window.document.body.addEventListener('touchmove', this.handleEvent);

this.clearMonitorSubscription = this.context
.dragDropManager
.getMonitor()
.subscribeToStateChange(() => this.handleMonitorChange());
const { dragDropManager } = this.props;
this.clearMonitorSubscription = dragDropManager
.getMonitor()
.subscribeToStateChange(() => this.handleMonitorChange());
}

componentWillUnmount() {
Expand All @@ -112,7 +141,8 @@ export default function createScrollingComponent(WrappedComponent) {
}

handleMonitorChange() {
const isDragging = this.context.dragDropManager.getMonitor().isDragging();
const { dragDropManager } = this.props;
const isDragging = dragDropManager.getMonitor().isDragging();

if (!this.dragging && isDragging) {
this.dragging = true;
Expand All @@ -134,23 +164,6 @@ export default function createScrollingComponent(WrappedComponent) {
window.document.body.removeEventListener('touchmove', this.updateScrolling);
}

// Update scaleX and scaleY every 100ms or so
// and start scrolling if necessary
updateScrolling = throttle(evt => {
const { left: x, top: y, width: w, height: h } = this.container.getBoundingClientRect();
const box = { x, y, w, h };
const coords = getCoords(evt);

// calculate strength
this.scaleX = this.props.horizontalStrength(box, coords);
this.scaleY = this.props.verticalStrength(box, coords);

// start scrolling if we need to
if (!this.frame && (this.scaleX || this.scaleY)) {
this.startScrolling();
}
}, 100, { trailing: false })

startScrolling() {
let i = 0;
const tick = () => {
Expand All @@ -167,7 +180,8 @@ export default function createScrollingComponent(WrappedComponent) {
// mousemove events from a container that also emits a scroll
// event that same frame. So we double the strengthMultiplier and only adjust
// the scroll position at 30fps
if (i++ % 2) {
i += 1;
if (i % 2) {
const {
scrollLeft,
scrollTop,
Expand All @@ -181,15 +195,15 @@ export default function createScrollingComponent(WrappedComponent) {
? container.scrollLeft = intBetween(
0,
scrollWidth - clientWidth,
scrollLeft + scaleX * strengthMultiplier
scrollLeft + scaleX * strengthMultiplier,
)
: scrollLeft;

const newTop = scaleY
? container.scrollTop = intBetween(
0,
scrollHeight - clientHeight,
scrollTop + scaleY * strengthMultiplier
scrollTop + scaleY * strengthMultiplier,
)
: scrollTop;

Expand Down Expand Up @@ -220,12 +234,12 @@ export default function createScrollingComponent(WrappedComponent) {
horizontalStrength,
onScrollChange,

...props,
...props
} = this.props;

return (
<WrappedComponent
ref={(ref) => { this.wrappedInstance = ref; }}
ref={this.wrappedInstance}
{...props}
/>
);
Expand All @@ -234,3 +248,16 @@ export default function createScrollingComponent(WrappedComponent) {

return hoist(ScrollingComponent, WrappedComponent);
}

export default function createScrollingComponentWithConsumer(WrappedComponent) {
const ScrollingComponent = createScrollingComponent(WrappedComponent);
return props => (
<DragDropContextConsumer>
{({ dragDropManager }) => (
dragDropManager === undefined
? null
: <ScrollingComponent {...props} dragDropManager={dragDropManager} />
)}
</DragDropContextConsumer>
);
}
2 changes: 1 addition & 1 deletion src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function noop() {

export function intBetween(min, max, val) {
return Math.floor(
Math.min(max, Math.max(min, val))
Math.min(max, Math.max(min, val)),
);
}

Expand Down
2 changes: 1 addition & 1 deletion test/mocha.opts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
--require babel-register
--require @babel/register
--require test/setup
--check-leaks
--throw-deprecation