Skip to content

Add offsetParent prop for alternative offset calculations #173

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

Closed
wants to merge 1 commit into from
Closed
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
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,
offsetParent: HTMLElement,
grid: [number, number],
handle: string,
onStart: DraggableEventHandler,
Expand Down
11 changes: 11 additions & 0 deletions lib/DraggableCore.es6
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ export default class DraggableCore extends React.Component {
*/
enableUserSelectHack: PropTypes.bool,

/**
* `offsetParent`, if set, uses the passed DOM node to compute drag offsets
* instead of using the parent node.
*/
offsetParent: function(props, propName) {
if (process.browser && props[propName] && props[propName].nodeType !== 1) {
throw new Error('Draggable\'s offsetParent must be a DOM Node.');
}
},

/**
* `grid` specifies the x and y that dragging should snap to.
*/
Expand Down Expand Up @@ -152,6 +162,7 @@ export default class DraggableCore extends React.Component {
cancel: null,
disabled: false,
enableUserSelectHack: true,
offsetParent: null,
handle: null,
grid: null,
transform: null,
Expand Down
7 changes: 4 additions & 3 deletions lib/utils/domFns.es6
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import {findInArray, isFunction, int} from './shims';
import browserPrefix, {getPrefix, browserPrefixToStyle, browserPrefixToKey} from './getPrefix';

import type DraggableCore from '../DraggableCore';
import type {ControlPosition} from './types';

let matchesSelectorFunc = '';
Expand Down Expand Up @@ -95,9 +96,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.offsetParent || node.offsetParent || document.body;
const offsetParentRect = offsetParent ? {left: 0, top: 0} : offsetParent.getBoundingClientRect();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition will always be true.

I'm going to refactor this a bit and push. Thanks for the contribution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, thank you!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right this should be offsetParent === document.body

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, but we can't even use document.body, we have to use node.ownerDocument.

Almost done, just writing a test to verify.


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