Skip to content

Commit 33e0a04

Browse files
Aeneas Rekkas (arekkas)aeneasr
authored andcommitted
Resolves regression issue by introducing offsetParent to <DraggableCore>
Allows nodes to use an arbitrary node as origin instead of the parent. This is useful, when the parent's position is changing. When used, resolves react-grid-layout#170 This issue was introduced by a398097
1 parent 510d27c commit 33e0a04

File tree

4 files changed

+19
-6
lines changed

4 files changed

+19
-6
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ on itself and thus must have callbacks attached to be useful.
249249
cancel: string,
250250
disabled: boolean,
251251
enableUserSelectHack: boolean,
252+
offsetParent: HTMLElement,
252253
grid: [number, number],
253254
handle: string,
254255
onStart: DraggableEventHandler,

lib/DraggableCore.es6

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ export default class DraggableCore extends React.Component {
6666
*/
6767
enableUserSelectHack: PropTypes.bool,
6868

69+
/**
70+
* `offsetParent`, if set, uses the passed DOM node to compute drag offsets
71+
* instead of using the parent node.
72+
*/
73+
offsetParent: function(props, propName) {
74+
if (process.browser && props[propName] && props[propName].nodeType !== 1) {
75+
throw new Error('Draggable\'s offsetParent must be a DOM Node.');
76+
}
77+
},
78+
6979
/**
7080
* `grid` specifies the x and y that dragging should snap to.
7181
*/
@@ -152,6 +162,7 @@ export default class DraggableCore extends React.Component {
152162
cancel: null,
153163
disabled: false,
154164
enableUserSelectHack: true,
165+
offsetParent: null,
155166
handle: null,
156167
grid: null,
157168
transform: null,

lib/utils/domFns.es6

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import {findInArray, isFunction, int} from './shims';
33
import browserPrefix, {getPrefix, browserPrefixToStyle, browserPrefixToKey} from './getPrefix';
44

5+
import type DraggableCore from '../DraggableCore';
56
import type {ControlPosition} from './types';
67

78
let matchesSelectorFunc = '';
@@ -95,9 +96,9 @@ export function innerWidth(node: HTMLElement): number {
9596
}
9697

9798
// Get from offsetParent
98-
export function offsetXYFromParentOf(evt: {clientX: number, clientY: number}, node: HTMLElement & {offsetParent: HTMLElement}): ControlPosition {
99-
const offsetParent = node.offsetParent || document.body;
100-
const offsetParentRect = node.offsetParent === document.body ? {left: 0, top: 0} : offsetParent.getBoundingClientRect();
99+
export function offsetXYFromParentOf(evt: {clientX: number, clientY: number}, node: HTMLElement & {offsetParent: HTMLElement}, draggableCore: DraggableCore): ControlPosition {
100+
const offsetParent = draggableCore.props.offsetParent || node.offsetParent || document.body;
101+
const offsetParentRect = offsetParent ? {left: 0, top: 0} : offsetParent.getBoundingClientRect();
101102

102103
const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;
103104
const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;
@@ -116,12 +117,12 @@ export function createSVGTransform({x, y}: {x: number, y: number}): string {
116117

117118
export function getTouch(e: MouseEvent, identifier: number): ?{clientX: number, clientY: number} {
118119
return (e.targetTouches && findInArray(e.targetTouches, t => identifier === t.identifier)) ||
119-
(e.changedTouches && findInArray(e.changedTouches, t => identifier === t.identifier));
120+
(e.changedTouches && findInArray(e.changedTouches, t => identifier === t.identifier));
120121
}
121122

122123
export function getTouchIdentifier(e: MouseEvent): ?number {
123124
if (e.targetTouches && e.targetTouches[0]) return e.targetTouches[0].identifier;
124-
if (e.changedTouches && e.changedTouches[0]) return e.changedTouches[0].identifier;
125+
if (e.changedTouches && e.changedTouches[0]) return e.changedTouches[0].identifier;
125126
}
126127

127128
// User-select Hacks:

lib/utils/positionFns.es6

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export function canDragY(draggable: Draggable): boolean {
6666
export function getControlPosition(e: MouseEvent, touchIdentifier: ?number, draggableCore: DraggableCore): ?ControlPosition {
6767
const touchObj = typeof touchIdentifier === 'number' ? getTouch(e, touchIdentifier) : null;
6868
if (typeof touchIdentifier === 'number' && !touchObj) return null; // not the right touch
69-
return offsetXYFromParentOf(touchObj || e, ReactDOM.findDOMNode(draggableCore));
69+
return offsetXYFromParentOf(touchObj || e, ReactDOM.findDOMNode(draggableCore), draggableCore);
7070
}
7171

7272
// Create an data object exposed by <DraggableCore>'s events

0 commit comments

Comments
 (0)