Skip to content
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ There are already a number of great Drag & Drop libraries out there (for instanc
| getHelperDimensions | Function | [Function](https://github.com/clauderic/react-sortable-hoc/blob/master/src/SortableContainer/index.js#L74-L77) | Optional `function({node, index, collection})` that should return the computed dimensions of the SortableHelper. See [default implementation](https://github.com/clauderic/react-sortable-hoc/blob/master/src/SortableContainer/defaultGetHelperDimensions.js) for more details |
| helperContainer | HTMLElement | Function | `document.body` | By default, the cloned sortable helper is appended to the document body. Use this prop to specify a different container for the sortable clone to be appended to. Accepts an `HTMLElement` or a function returning an `HTMLElement` that will be invoked before right before sorting begins |
| disableAutoscroll | Boolean | `false` | Disables autoscrolling while dragging |
| rtl | Boolean | `false` | If the direction of page or container is "RTL", the "rtl" props must be `true`. |

\* `OffsetValue` can either be a finite `Number` or a `String` made up of a number and a unit (`px` or `%`).
Examples: `10` (which is the same as `"10px"`), `"50%"`
Expand Down
6 changes: 3 additions & 3 deletions src/AutoScroller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class AutoScroller {
this.interval = null;
}

update({translate, minTranslate, maxTranslate, width, height}) {
update({translate, minTranslate, maxTranslate, width, height, rtl = false}) {
const direction = {
x: 0,
y: 0,
Expand All @@ -38,8 +38,8 @@ export default class AutoScroller {

const isTop = scrollTop === 0;
const isBottom = scrollHeight - scrollTop - clientHeight === 0;
const isLeft = scrollLeft === 0;
const isRight = scrollWidth - scrollLeft - clientWidth === 0;
const isLeft = scrollLeft === (!rtl ? 0 : clientWidth - scrollWidth);
const isRight = scrollLeft === (!rtl ? scrollWidth - clientWidth : 0);

if (translate.y >= maxTranslate.y - height / 2 && !isBottom) {
// Scroll Down
Expand Down
56 changes: 39 additions & 17 deletions src/SortableContainer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ export default function sortableContainer(
}

animateNodes() {
const {transitionDuration, hideSortableGhost, onSortOver} = this.props;
const {rtl, transitionDuration, hideSortableGhost, onSortOver} = this.props;
const {containerScrollDelta, windowScrollDelta} = this;
const nodes = this.manager.getOrderedRefs();
const sortingOffset = {
Expand Down Expand Up @@ -706,25 +706,31 @@ export default function sortableContainer(
setTransitionDuration(node, transitionDuration);
}

const translateXFactor = rtl ? -1 : 1;

if (this.axis.x) {
if (this.axis.y) {
// Calculations for a grid setup
if (
mustShiftForward ||
(index < this.index &&
((sortingOffset.left + windowScrollDelta.left - offset.width <=
edgeOffset.left &&
(((
(!rtl && (sortingOffset.left + windowScrollDelta.left - offset.width <= edgeOffset.left))
||
(rtl && (sortingOffset.left + windowScrollDelta.left + offset.width >= edgeOffset.left))
) &&
sortingOffset.top + windowScrollDelta.top <=
edgeOffset.top + offset.height) ||
sortingOffset.top + windowScrollDelta.top + offset.height <=
edgeOffset.top))
) {
// If the current node is to the left on the same row, or above the node that's being dragged
// then move it to the right
translate.x = this.width + this.marginOffset.x;
translate.x = translateXFactor * (this.width + this.marginOffset.x);
if (
edgeOffset.left + translate.x >
this.containerBoundingRect.width - offset.width * 2
(!rtl && (edgeOffset.left + translate.x > this.containerBoundingRect.width - offset.width * 2))
||
(rtl && edgeOffset.left + translate.x < this.containerBoundingRect.left + offset.width)
) {
// If it moves passed the right bounds, then animate it to the first position of the next row.
// We just use the offset of the next node to calculate where to move, because that node's original position
Expand All @@ -740,19 +746,23 @@ export default function sortableContainer(
} else if (
mustShiftBackward ||
(index > this.index &&
((sortingOffset.left + windowScrollDelta.left + offset.width >=
edgeOffset.left &&
(((
(!rtl && (sortingOffset.left + windowScrollDelta.left + offset.width >= edgeOffset.left))
||
(rtl && (sortingOffset.left + windowScrollDelta.left - offset.width <= edgeOffset.left))
) &&
sortingOffset.top + windowScrollDelta.top + offset.height >=
edgeOffset.top) ||
sortingOffset.top + windowScrollDelta.top + offset.height >=
edgeOffset.top + height))
) {
// If the current node is to the right on the same row, or below the node that's being dragged
// then move it to the left
translate.x = -(this.width + this.marginOffset.x);
translate.x = - 1 * translateXFactor * (this.width + this.marginOffset.x);
if (
edgeOffset.left + translate.x <
this.containerBoundingRect.left + offset.width
(!rtl && (edgeOffset.left + translate.x < this.containerBoundingRect.left + offset.width))
||
(rtl && (edgeOffset.left + translate.x > this.containerBoundingRect.width - this.containerBoundingRect.left - offset.width * 2))
) {
// If it moves passed the left bounds, then animate it to the last position of the previous row.
// We just use the offset of the previous node to calculate where to move, because that node's original position
Expand All @@ -768,18 +778,26 @@ export default function sortableContainer(
if (
mustShiftBackward ||
(index > this.index &&
sortingOffset.left + windowScrollDelta.left + offset.width >=
edgeOffset.left)
(
(!rtl && (sortingOffset.left + windowScrollDelta.left + offset.width >= edgeOffset.left))
||
(rtl && (sortingOffset.left + windowScrollDelta.left - offset.width <= edgeOffset.left))
)
)
) {
translate.x = -(this.width + this.marginOffset.x);
translate.x = -1 * translateXFactor * (this.width + this.marginOffset.x);
this.newIndex = index;
} else if (
mustShiftForward ||
(index < this.index &&
sortingOffset.left + windowScrollDelta.left <=
edgeOffset.left + offset.width)
(
(!rtl && (sortingOffset.left + windowScrollDelta.left - offset.width <= edgeOffset.left))
||
(rtl && (sortingOffset.left + windowScrollDelta.left + offset.width >= edgeOffset.left))
)
)
) {
translate.x = this.width + this.marginOffset.x;
translate.x = translateXFactor * (this.width + this.marginOffset.x);

if (this.newIndex == null) {
this.newIndex = index;
Expand Down Expand Up @@ -879,6 +897,7 @@ export default function sortableContainer(
minTranslate: this.minTranslate,
translate: this.translate,
width: this.width,
rtl: this.props.rtl
});
};

Expand Down Expand Up @@ -963,6 +982,9 @@ export default function sortableContainer(
};

keyMove = (shift) => {
if (this.props.rtl && this.props.axis.indexOf('x') !== -1) {
shift = -1 * shift;
}
const nodes = this.manager.getOrderedRefs();
const {index: lastIndex} = nodes[nodes.length - 1].node.sortableInfo;
const newIndex = this.newIndex + shift;
Expand Down
2 changes: 2 additions & 0 deletions src/SortableContainer/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import defaultGetHelperDimensions from './defaultGetHelperDimensions';
import defaultShouldCancelStart from './defaultShouldCancelStart';

export const propTypes = {
rtl: PropTypes.bool,
axis: PropTypes.oneOf(['x', 'y', 'xy']),
contentWindow: PropTypes.any,
disableAutoscroll: PropTypes.bool,
Expand Down Expand Up @@ -59,6 +60,7 @@ export const defaultKeyCodes = {
};

export const defaultProps = {
rtl: false,
axis: 'y',
disableAutoscroll: false,
distance: 0,
Expand Down