Skip to content

Commit

Permalink
Resolves regression issue by introducing useBodyAsOrigin to <Dragga…
Browse files Browse the repository at this point in the history
…bleCore>

Allows nodes to use the body 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
  • Loading branch information
Aeneas Rekkas (arekkas) authored and aeneasr committed Jul 19, 2016
1 parent 549669e commit 7bc42f1
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ on itself and thus must have callbacks attached to be useful.
cancel: string,
disabled: boolean,
enableUserSelectHack: boolean,
useBodyAsOrigin: boolean,
grid: [number, number],
handle: string,
onStart: DraggableEventHandler,
Expand Down
13 changes: 13 additions & 0 deletions lib/DraggableCore.es6
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ export default class DraggableCore extends React.Component {
*/
enableUserSelectHack: PropTypes.bool,

/**
* `useBodyAsOrigin`, if true, uses the <body> node to compute offsets.
* If false, the <Draggable>'s parent node will be used instead.
*
* Using this attribute will break <Draggable> inside of scrollable
* elements, except <body>, but makes sense, if <Draggable>'s parent
* node is moving around.
*
* Defaults to `false`.
*/
useBodyAsOrigin: PropTypes.bool,

/**
* `grid` specifies the x and y that dragging should snap to.
*/
Expand Down Expand Up @@ -152,6 +164,7 @@ export default class DraggableCore extends React.Component {
cancel: null,
disabled: false,
enableUserSelectHack: true,
useBodyAsOrigin: false,
handle: null,
grid: null,
transform: null,
Expand Down
6 changes: 3 additions & 3 deletions lib/utils/domFns.es6
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ export function innerWidth(node: HTMLElement): number {
}

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

const x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;
const y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/positionFns.es6
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function canDragY(draggable: Draggable): boolean {
export function getControlPosition(e: MouseEvent, touchIdentifier: ?number, draggableCore: DraggableCore): ?ControlPosition {
const touchObj = typeof touchIdentifier === 'number' ? getTouch(e, touchIdentifier) : null;
if (typeof touchIdentifier === 'number' && !touchObj) return null; // not the right touch
return offsetXYFromParentOf(touchObj || e, ReactDOM.findDOMNode(draggableCore));
return offsetXYFromParentOf(touchObj || e, ReactDOM.findDOMNode(draggableCore), draggableCore);
}

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

0 comments on commit 7bc42f1

Please sign in to comment.