react-movable
Advanced tools
Comparing version 2.5.4 to 3.0.0
@@ -1,11 +0,3 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.arrayRemove = exports.arrayMove = exports.List = void 0; | ||
var List_1 = __importDefault(require("./List")); | ||
exports.List = List_1.default; | ||
var utils_1 = require("./utils"); | ||
Object.defineProperty(exports, "arrayMove", { enumerable: true, get: function () { return utils_1.arrayMove; } }); | ||
Object.defineProperty(exports, "arrayRemove", { enumerable: true, get: function () { return utils_1.arrayRemove; } }); | ||
import List from './List'; | ||
import { arrayMove, arrayRemove } from './utils'; | ||
export { List, arrayMove, arrayRemove }; |
560
lib/List.js
@@ -1,66 +0,20 @@ | ||
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var React = __importStar(require("react")); | ||
var ReactDOM = __importStar(require("react-dom")); | ||
var utils_1 = require("./utils"); | ||
var AUTOSCROLL_ACTIVE_OFFSET = 200; | ||
var AUTOSCROLL_SPEED_RATIO = 10; | ||
var List = /** @class */ (function (_super) { | ||
__extends(List, _super); | ||
function List(props) { | ||
var _this = _super.call(this, props) || this; | ||
_this.listRef = React.createRef(); | ||
_this.ghostRef = React.createRef(); | ||
_this.topOffsets = []; | ||
_this.itemTranslateOffsets = []; | ||
_this.initialYOffset = 0; | ||
_this.lastScroll = 0; | ||
_this.lastYOffset = 0; | ||
_this.lastListYOffset = 0; | ||
_this.needle = -1; | ||
_this.afterIndex = -2; | ||
_this.state = { | ||
import * as React from 'react'; | ||
import * as ReactDOM from 'react-dom'; | ||
import { getTranslateOffset, transformItem, setItemTransition, binarySearch, schd, isTouchEvent, checkIfInteractive } from './utils'; | ||
const AUTOSCROLL_ACTIVE_OFFSET = 200; | ||
const AUTOSCROLL_SPEED_RATIO = 10; | ||
class List extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
this.listRef = React.createRef(); | ||
this.ghostRef = React.createRef(); | ||
this.topOffsets = []; | ||
this.itemTranslateOffsets = []; | ||
this.initialYOffset = 0; | ||
this.lastScroll = 0; | ||
this.lastYOffset = 0; | ||
this.lastListYOffset = 0; | ||
this.needle = -1; | ||
this.afterIndex = -2; | ||
this.state = { | ||
itemDragged: -1, | ||
@@ -79,6 +33,6 @@ itemDraggedOutOfBounds: -1, | ||
}; | ||
_this.doScrolling = function () { | ||
var _a = _this.state, scrollingSpeed = _a.scrollingSpeed, scrollWindow = _a.scrollWindow; | ||
var listEl = _this.listRef.current; | ||
window.requestAnimationFrame(function () { | ||
this.doScrolling = () => { | ||
const { scrollingSpeed, scrollWindow } = this.state; | ||
const listEl = this.listRef.current; | ||
window.requestAnimationFrame(() => { | ||
if (scrollWindow) { | ||
@@ -91,9 +45,9 @@ window.scrollTo(window.pageXOffset, window.pageYOffset + scrollingSpeed * 1.5); | ||
if (scrollingSpeed !== 0) { | ||
_this.doScrolling(); | ||
this.doScrolling(); | ||
} | ||
}); | ||
}; | ||
_this.getChildren = function () { | ||
if (_this.listRef && _this.listRef.current) { | ||
return Array.from(_this.listRef.current.children); | ||
this.getChildren = () => { | ||
if (this.listRef && this.listRef.current) { | ||
return Array.from(this.listRef.current.children); | ||
} | ||
@@ -103,54 +57,52 @@ console.warn('No items found in the List container. Did you forget to pass & spread the `props` param in renderList?'); | ||
}; | ||
_this.calculateOffsets = function () { | ||
_this.topOffsets = _this.getChildren().map(function (item) { return item.getBoundingClientRect().top; }); | ||
_this.itemTranslateOffsets = _this.getChildren().map(function (item) { | ||
return utils_1.getTranslateOffset(item); | ||
}); | ||
this.calculateOffsets = () => { | ||
this.topOffsets = this.getChildren().map((item) => item.getBoundingClientRect().top); | ||
this.itemTranslateOffsets = this.getChildren().map((item) => getTranslateOffset(item)); | ||
}; | ||
_this.getTargetIndex = function (e) { | ||
return _this.getChildren().findIndex(function (child) { return child === e.target || child.contains(e.target); }); | ||
this.getTargetIndex = (e) => { | ||
return this.getChildren().findIndex((child) => child === e.target || child.contains(e.target)); | ||
}; | ||
_this.onMouseOrTouchStart = function (e) { | ||
if (_this.dropTimeout && _this.state.itemDragged > -1) { | ||
window.clearTimeout(_this.dropTimeout); | ||
_this.finishDrop(); | ||
this.onMouseOrTouchStart = (e) => { | ||
if (this.dropTimeout && this.state.itemDragged > -1) { | ||
window.clearTimeout(this.dropTimeout); | ||
this.finishDrop(); | ||
} | ||
var isTouch = utils_1.isTouchEvent(e); | ||
const isTouch = isTouchEvent(e); | ||
if (!isTouch && e.button !== 0) | ||
return; | ||
var index = _this.getTargetIndex(e); | ||
const index = this.getTargetIndex(e); | ||
if (index === -1 || | ||
// @ts-ignore | ||
(_this.props.values[index] && _this.props.values[index].disabled)) { | ||
if (_this.state.selectedItem !== -1) { | ||
_this.setState({ selectedItem: -1 }); | ||
_this.finishDrop(); | ||
(this.props.values[index] && this.props.values[index].disabled)) { | ||
if (this.state.selectedItem !== -1) { | ||
this.setState({ selectedItem: -1 }); | ||
this.finishDrop(); | ||
} | ||
return; | ||
} | ||
var listItemTouched = _this.getChildren()[index]; | ||
var handle = listItemTouched.querySelector('[data-movable-handle]'); | ||
const listItemTouched = this.getChildren()[index]; | ||
const handle = listItemTouched.querySelector('[data-movable-handle]'); | ||
if (handle && !handle.contains(e.target)) { | ||
return; | ||
} | ||
if (utils_1.checkIfInteractive(e.target, listItemTouched)) { | ||
if (checkIfInteractive(e.target, listItemTouched)) { | ||
return; | ||
} | ||
e.preventDefault(); | ||
_this.props.beforeDrag && | ||
_this.props.beforeDrag({ | ||
elements: _this.getChildren(), | ||
index: index | ||
this.props.beforeDrag && | ||
this.props.beforeDrag({ | ||
elements: this.getChildren(), | ||
index | ||
}); | ||
if (isTouch) { | ||
var opts = { passive: false }; | ||
const opts = { passive: false }; | ||
listItemTouched.style.touchAction = 'none'; | ||
document.addEventListener('touchend', _this.schdOnEnd, opts); | ||
document.addEventListener('touchmove', _this.schdOnTouchMove, opts); | ||
document.addEventListener('touchcancel', _this.schdOnEnd, opts); | ||
document.addEventListener('touchend', this.schdOnEnd, opts); | ||
document.addEventListener('touchmove', this.schdOnTouchMove, opts); | ||
document.addEventListener('touchcancel', this.schdOnEnd, opts); | ||
} | ||
else { | ||
document.addEventListener('mousemove', _this.schdOnMouseMove); | ||
document.addEventListener('mouseup', _this.schdOnEnd); | ||
var listItemDragged = _this.getChildren()[_this.state.itemDragged]; | ||
document.addEventListener('mousemove', this.schdOnMouseMove); | ||
document.addEventListener('mouseup', this.schdOnEnd); | ||
const listItemDragged = this.getChildren()[this.state.itemDragged]; | ||
if (listItemDragged && listItemDragged.style) { | ||
@@ -160,22 +112,22 @@ listItemDragged.style.touchAction = ''; | ||
} | ||
_this.onStart(listItemTouched, isTouch ? e.touches[0].clientX : e.clientX, isTouch ? e.touches[0].clientY : e.clientY, index); | ||
this.onStart(listItemTouched, isTouch ? e.touches[0].clientX : e.clientX, isTouch ? e.touches[0].clientY : e.clientY, index); | ||
}; | ||
_this.getYOffset = function () { | ||
var listScroll = _this.listRef.current | ||
? _this.listRef.current.scrollTop | ||
this.getYOffset = () => { | ||
const listScroll = this.listRef.current | ||
? this.listRef.current.scrollTop | ||
: 0; | ||
return window.pageYOffset + listScroll; | ||
}; | ||
_this.onStart = function (target, clientX, clientY, index) { | ||
if (_this.state.selectedItem > -1) { | ||
_this.setState({ selectedItem: -1 }); | ||
_this.needle = -1; | ||
this.onStart = (target, clientX, clientY, index) => { | ||
if (this.state.selectedItem > -1) { | ||
this.setState({ selectedItem: -1 }); | ||
this.needle = -1; | ||
} | ||
var targetRect = target.getBoundingClientRect(); | ||
var targetStyles = window.getComputedStyle(target); | ||
_this.calculateOffsets(); | ||
_this.initialYOffset = _this.getYOffset(); | ||
_this.lastYOffset = window.pageYOffset; | ||
_this.lastListYOffset = _this.listRef.current.scrollTop; | ||
_this.setState({ | ||
const targetRect = target.getBoundingClientRect(); | ||
const targetStyles = window.getComputedStyle(target); | ||
this.calculateOffsets(); | ||
this.initialYOffset = this.getYOffset(); | ||
this.lastYOffset = window.pageYOffset; | ||
this.lastListYOffset = this.listRef.current.scrollTop; | ||
this.setState({ | ||
itemDragged: index, | ||
@@ -190,48 +142,48 @@ targetX: targetRect.left - parseInt(targetStyles['margin-left'], 10), | ||
}; | ||
_this.onMouseMove = function (e) { | ||
this.onMouseMove = (e) => { | ||
e.cancelable && e.preventDefault(); | ||
_this.onMove(e.clientX, e.clientY); | ||
this.onMove(e.clientX, e.clientY); | ||
}; | ||
_this.onTouchMove = function (e) { | ||
this.onTouchMove = (e) => { | ||
e.cancelable && e.preventDefault(); | ||
_this.onMove(e.touches[0].clientX, e.touches[0].clientY); | ||
this.onMove(e.touches[0].clientX, e.touches[0].clientY); | ||
}; | ||
_this.onWheel = function (e) { | ||
if (_this.state.itemDragged < 0) | ||
this.onWheel = (e) => { | ||
if (this.state.itemDragged < 0) | ||
return; | ||
_this.lastScroll = _this.listRef.current.scrollTop += e.deltaY; | ||
_this.moveOtherItems(); | ||
this.lastScroll = this.listRef.current.scrollTop += e.deltaY; | ||
this.moveOtherItems(); | ||
}; | ||
_this.onMove = function (clientX, clientY) { | ||
if (_this.state.itemDragged === -1) | ||
this.onMove = (clientX, clientY) => { | ||
if (this.state.itemDragged === -1) | ||
return null; | ||
utils_1.transformItem(_this.ghostRef.current, clientY - _this.state.initialY, _this.props.lockVertically ? 0 : clientX - _this.state.initialX); | ||
_this.autoScrolling(clientY); | ||
_this.moveOtherItems(); | ||
transformItem(this.ghostRef.current, clientY - this.state.initialY, this.props.lockVertically ? 0 : clientX - this.state.initialX); | ||
this.autoScrolling(clientY); | ||
this.moveOtherItems(); | ||
}; | ||
_this.moveOtherItems = function () { | ||
var targetRect = _this.ghostRef.current.getBoundingClientRect(); | ||
var itemVerticalCenter = targetRect.top + targetRect.height / 2; | ||
var offset = utils_1.getTranslateOffset(_this.getChildren()[_this.state.itemDragged]); | ||
var currentYOffset = _this.getYOffset(); | ||
this.moveOtherItems = () => { | ||
const targetRect = this.ghostRef.current.getBoundingClientRect(); | ||
const itemVerticalCenter = targetRect.top + targetRect.height / 2; | ||
const offset = getTranslateOffset(this.getChildren()[this.state.itemDragged]); | ||
const currentYOffset = this.getYOffset(); | ||
// adjust offsets if scrolling happens during the item movement | ||
if (_this.initialYOffset !== currentYOffset) { | ||
_this.topOffsets = _this.topOffsets.map(function (offset) { return offset - (currentYOffset - _this.initialYOffset); }); | ||
_this.initialYOffset = currentYOffset; | ||
if (this.initialYOffset !== currentYOffset) { | ||
this.topOffsets = this.topOffsets.map((offset) => offset - (currentYOffset - this.initialYOffset)); | ||
this.initialYOffset = currentYOffset; | ||
} | ||
if (_this.isDraggedItemOutOfBounds() && _this.props.removableByMove) { | ||
_this.afterIndex = _this.topOffsets.length + 1; | ||
if (this.isDraggedItemOutOfBounds() && this.props.removableByMove) { | ||
this.afterIndex = this.topOffsets.length + 1; | ||
} | ||
else { | ||
_this.afterIndex = utils_1.binarySearch(_this.topOffsets, itemVerticalCenter); | ||
this.afterIndex = binarySearch(this.topOffsets, itemVerticalCenter); | ||
} | ||
_this.animateItems(_this.afterIndex === -1 ? 0 : _this.afterIndex, _this.state.itemDragged, offset); | ||
this.animateItems(this.afterIndex === -1 ? 0 : this.afterIndex, this.state.itemDragged, offset); | ||
}; | ||
_this.autoScrolling = function (clientY) { | ||
var _a = _this.listRef.current.getBoundingClientRect(), top = _a.top, bottom = _a.bottom, height = _a.height; | ||
var viewportHeight = window.innerHeight || document.documentElement.clientHeight; | ||
this.autoScrolling = (clientY) => { | ||
const { top, bottom, height } = this.listRef.current.getBoundingClientRect(); | ||
const viewportHeight = window.innerHeight || document.documentElement.clientHeight; | ||
// autoscrolling for the window (down) | ||
if (bottom > viewportHeight && | ||
viewportHeight - clientY < AUTOSCROLL_ACTIVE_OFFSET) { | ||
_this.setState({ | ||
this.setState({ | ||
scrollingSpeed: Math.round((AUTOSCROLL_ACTIVE_OFFSET - (viewportHeight - clientY)) / | ||
@@ -244,3 +196,3 @@ AUTOSCROLL_SPEED_RATIO), | ||
else if (top < 0 && clientY < AUTOSCROLL_ACTIVE_OFFSET) { | ||
_this.setState({ | ||
this.setState({ | ||
scrollingSpeed: Math.round((AUTOSCROLL_ACTIVE_OFFSET - clientY) / -AUTOSCROLL_SPEED_RATIO), | ||
@@ -251,8 +203,8 @@ scrollWindow: true | ||
else { | ||
if (_this.state.scrollWindow && _this.state.scrollingSpeed !== 0) { | ||
_this.setState({ scrollingSpeed: 0, scrollWindow: false }); | ||
if (this.state.scrollWindow && this.state.scrollingSpeed !== 0) { | ||
this.setState({ scrollingSpeed: 0, scrollWindow: false }); | ||
} | ||
// autoscrolling for containers with overflow | ||
if (height + 20 < _this.listRef.current.scrollHeight) { | ||
var scrollingSpeed = 0; | ||
if (height + 20 < this.listRef.current.scrollHeight) { | ||
let scrollingSpeed = 0; | ||
if (clientY - top < AUTOSCROLL_ACTIVE_OFFSET) { | ||
@@ -266,4 +218,4 @@ scrollingSpeed = Math.round((AUTOSCROLL_ACTIVE_OFFSET - (clientY - top)) / | ||
} | ||
if (_this.state.scrollingSpeed !== scrollingSpeed) { | ||
_this.setState({ scrollingSpeed: scrollingSpeed }); | ||
if (this.state.scrollingSpeed !== scrollingSpeed) { | ||
this.setState({ scrollingSpeed }); | ||
} | ||
@@ -273,105 +225,104 @@ } | ||
}; | ||
_this.animateItems = function (needle, movedItem, offset, animateMovedItem) { | ||
if (animateMovedItem === void 0) { animateMovedItem = false; } | ||
_this.getChildren().forEach(function (item, i) { | ||
utils_1.setItemTransition(item, _this.props.transitionDuration); | ||
this.animateItems = (needle, movedItem, offset, animateMovedItem = false) => { | ||
this.getChildren().forEach((item, i) => { | ||
setItemTransition(item, this.props.transitionDuration); | ||
if (movedItem === i && animateMovedItem) { | ||
if (movedItem === needle) { | ||
return utils_1.transformItem(item, null); | ||
return transformItem(item, null); | ||
} | ||
utils_1.transformItem(item, movedItem < needle | ||
? _this.itemTranslateOffsets | ||
transformItem(item, movedItem < needle | ||
? this.itemTranslateOffsets | ||
.slice(movedItem + 1, needle + 1) | ||
.reduce(function (a, b) { return a + b; }, 0) | ||
: _this.itemTranslateOffsets | ||
.reduce((a, b) => a + b, 0) | ||
: this.itemTranslateOffsets | ||
.slice(needle, movedItem) | ||
.reduce(function (a, b) { return a + b; }, 0) * -1); | ||
.reduce((a, b) => a + b, 0) * -1); | ||
} | ||
else if (movedItem < needle && i > movedItem && i <= needle) { | ||
utils_1.transformItem(item, -offset); | ||
transformItem(item, -offset); | ||
} | ||
else if (i < movedItem && movedItem > needle && i >= needle) { | ||
utils_1.transformItem(item, offset); | ||
transformItem(item, offset); | ||
} | ||
else { | ||
utils_1.transformItem(item, null); | ||
transformItem(item, null); | ||
} | ||
}); | ||
}; | ||
_this.isDraggedItemOutOfBounds = function () { | ||
var initialRect = _this.getChildren()[_this.state.itemDragged].getBoundingClientRect(); | ||
var targetRect = _this.ghostRef.current.getBoundingClientRect(); | ||
this.isDraggedItemOutOfBounds = () => { | ||
const initialRect = this.getChildren()[this.state.itemDragged].getBoundingClientRect(); | ||
const targetRect = this.ghostRef.current.getBoundingClientRect(); | ||
if (Math.abs(initialRect.left - targetRect.left) > targetRect.width) { | ||
if (_this.state.itemDraggedOutOfBounds === -1) { | ||
_this.setState({ itemDraggedOutOfBounds: _this.state.itemDragged }); | ||
if (this.state.itemDraggedOutOfBounds === -1) { | ||
this.setState({ itemDraggedOutOfBounds: this.state.itemDragged }); | ||
} | ||
return true; | ||
} | ||
if (_this.state.itemDraggedOutOfBounds > -1) { | ||
_this.setState({ itemDraggedOutOfBounds: -1 }); | ||
if (this.state.itemDraggedOutOfBounds > -1) { | ||
this.setState({ itemDraggedOutOfBounds: -1 }); | ||
} | ||
return false; | ||
}; | ||
_this.onEnd = function (e) { | ||
this.onEnd = (e) => { | ||
e.cancelable && e.preventDefault(); | ||
document.removeEventListener('mousemove', _this.schdOnMouseMove); | ||
document.removeEventListener('touchmove', _this.schdOnTouchMove); | ||
document.removeEventListener('mouseup', _this.schdOnEnd); | ||
document.removeEventListener('touchup', _this.schdOnEnd); | ||
document.removeEventListener('touchcancel', _this.schdOnEnd); | ||
var removeItem = _this.props.removableByMove && _this.isDraggedItemOutOfBounds(); | ||
document.removeEventListener('mousemove', this.schdOnMouseMove); | ||
document.removeEventListener('touchmove', this.schdOnTouchMove); | ||
document.removeEventListener('mouseup', this.schdOnEnd); | ||
document.removeEventListener('touchup', this.schdOnEnd); | ||
document.removeEventListener('touchcancel', this.schdOnEnd); | ||
const removeItem = this.props.removableByMove && this.isDraggedItemOutOfBounds(); | ||
if (!removeItem && | ||
_this.props.transitionDuration > 0 && | ||
_this.afterIndex !== -2) { | ||
this.props.transitionDuration > 0 && | ||
this.afterIndex !== -2) { | ||
// animate drop | ||
utils_1.schd(function () { | ||
utils_1.setItemTransition(_this.ghostRef.current, _this.props.transitionDuration, 'cubic-bezier(.2,1,.1,1)'); | ||
if (_this.afterIndex < 1 && _this.state.itemDragged === 0) { | ||
utils_1.transformItem(_this.ghostRef.current, 0, 0); | ||
schd(() => { | ||
setItemTransition(this.ghostRef.current, this.props.transitionDuration, 'cubic-bezier(.2,1,.1,1)'); | ||
if (this.afterIndex < 1 && this.state.itemDragged === 0) { | ||
transformItem(this.ghostRef.current, 0, 0); | ||
} | ||
else { | ||
utils_1.transformItem(_this.ghostRef.current, | ||
transformItem(this.ghostRef.current, | ||
// compensate window scroll | ||
-(window.pageYOffset - _this.lastYOffset) + | ||
-(window.pageYOffset - this.lastYOffset) + | ||
// compensate container scroll | ||
-(_this.listRef.current.scrollTop - _this.lastListYOffset) + | ||
(_this.state.itemDragged < _this.afterIndex | ||
? _this.itemTranslateOffsets | ||
.slice(_this.state.itemDragged + 1, _this.afterIndex + 1) | ||
.reduce(function (a, b) { return a + b; }, 0) | ||
: _this.itemTranslateOffsets | ||
.slice(_this.afterIndex < 0 ? 0 : _this.afterIndex, _this.state.itemDragged) | ||
.reduce(function (a, b) { return a + b; }, 0) * -1), 0); | ||
-(this.listRef.current.scrollTop - this.lastListYOffset) + | ||
(this.state.itemDragged < this.afterIndex | ||
? this.itemTranslateOffsets | ||
.slice(this.state.itemDragged + 1, this.afterIndex + 1) | ||
.reduce((a, b) => a + b, 0) | ||
: this.itemTranslateOffsets | ||
.slice(this.afterIndex < 0 ? 0 : this.afterIndex, this.state.itemDragged) | ||
.reduce((a, b) => a + b, 0) * -1), 0); | ||
} | ||
})(); | ||
} | ||
_this.dropTimeout = window.setTimeout(_this.finishDrop, removeItem || _this.afterIndex === -2 ? 0 : _this.props.transitionDuration); | ||
this.dropTimeout = window.setTimeout(this.finishDrop, removeItem || this.afterIndex === -2 ? 0 : this.props.transitionDuration); | ||
}; | ||
_this.finishDrop = function () { | ||
var removeItem = _this.props.removableByMove && _this.isDraggedItemOutOfBounds(); | ||
this.finishDrop = () => { | ||
const removeItem = this.props.removableByMove && this.isDraggedItemOutOfBounds(); | ||
if (removeItem || | ||
(_this.afterIndex > -2 && _this.state.itemDragged !== _this.afterIndex)) { | ||
_this.props.onChange({ | ||
oldIndex: _this.state.itemDragged, | ||
newIndex: removeItem ? -1 : Math.max(_this.afterIndex, 0), | ||
targetRect: _this.ghostRef.current.getBoundingClientRect() | ||
(this.afterIndex > -2 && this.state.itemDragged !== this.afterIndex)) { | ||
this.props.onChange({ | ||
oldIndex: this.state.itemDragged, | ||
newIndex: removeItem ? -1 : Math.max(this.afterIndex, 0), | ||
targetRect: this.ghostRef.current.getBoundingClientRect() | ||
}); | ||
} | ||
_this.getChildren().forEach(function (item) { | ||
utils_1.setItemTransition(item, 0); | ||
utils_1.transformItem(item, null); | ||
this.getChildren().forEach((item) => { | ||
setItemTransition(item, 0); | ||
transformItem(item, null); | ||
item.style.touchAction = ''; | ||
}); | ||
_this.setState({ itemDragged: -1, scrollingSpeed: 0 }); | ||
_this.afterIndex = -2; | ||
this.setState({ itemDragged: -1, scrollingSpeed: 0 }); | ||
this.afterIndex = -2; | ||
// sometimes the scroll gets messed up after the drop, fix: | ||
if (_this.lastScroll > 0) { | ||
_this.listRef.current.scrollTop = _this.lastScroll; | ||
_this.lastScroll = 0; | ||
if (this.lastScroll > 0) { | ||
this.listRef.current.scrollTop = this.lastScroll; | ||
this.lastScroll = 0; | ||
} | ||
}; | ||
_this.onKeyDown = function (e) { | ||
var selectedItem = _this.state.selectedItem; | ||
var index = _this.getTargetIndex(e); | ||
if (utils_1.checkIfInteractive(e.target, e.currentTarget)) { | ||
this.onKeyDown = (e) => { | ||
const selectedItem = this.state.selectedItem; | ||
const index = this.getTargetIndex(e); | ||
if (checkIfInteractive(e.target, e.currentTarget)) { | ||
return; | ||
@@ -384,27 +335,27 @@ } | ||
if (selectedItem === index) { | ||
if (selectedItem !== _this.needle) { | ||
_this.getChildren().forEach(function (item) { | ||
utils_1.setItemTransition(item, 0); | ||
utils_1.transformItem(item, null); | ||
if (selectedItem !== this.needle) { | ||
this.getChildren().forEach((item) => { | ||
setItemTransition(item, 0); | ||
transformItem(item, null); | ||
}); | ||
_this.props.onChange({ | ||
this.props.onChange({ | ||
oldIndex: selectedItem, | ||
newIndex: _this.needle, | ||
targetRect: _this.getChildren()[_this.needle].getBoundingClientRect() | ||
newIndex: this.needle, | ||
targetRect: this.getChildren()[this.needle].getBoundingClientRect() | ||
}); | ||
_this.getChildren()[_this.needle].focus(); | ||
this.getChildren()[this.needle].focus(); | ||
} | ||
_this.setState({ | ||
this.setState({ | ||
selectedItem: -1, | ||
liveText: _this.props.voiceover.dropped(selectedItem + 1, _this.needle + 1) | ||
liveText: this.props.voiceover.dropped(selectedItem + 1, this.needle + 1) | ||
}); | ||
_this.needle = -1; | ||
this.needle = -1; | ||
} | ||
else { | ||
_this.setState({ | ||
this.setState({ | ||
selectedItem: index, | ||
liveText: _this.props.voiceover.lifted(index + 1) | ||
liveText: this.props.voiceover.lifted(index + 1) | ||
}); | ||
_this.needle = index; | ||
_this.calculateOffsets(); | ||
this.needle = index; | ||
this.calculateOffsets(); | ||
} | ||
@@ -414,9 +365,9 @@ } | ||
selectedItem > -1 && | ||
_this.needle < _this.props.values.length - 1) { | ||
this.needle < this.props.values.length - 1) { | ||
e.preventDefault(); | ||
var offset = utils_1.getTranslateOffset(_this.getChildren()[selectedItem]); | ||
_this.needle++; | ||
_this.animateItems(_this.needle, selectedItem, offset, true); | ||
_this.setState({ | ||
liveText: _this.props.voiceover.moved(_this.needle + 1, false) | ||
const offset = getTranslateOffset(this.getChildren()[selectedItem]); | ||
this.needle++; | ||
this.animateItems(this.needle, selectedItem, offset, true); | ||
this.setState({ | ||
liveText: this.props.voiceover.moved(this.needle + 1, false) | ||
}); | ||
@@ -426,21 +377,21 @@ } | ||
selectedItem > -1 && | ||
_this.needle > 0) { | ||
this.needle > 0) { | ||
e.preventDefault(); | ||
var offset = utils_1.getTranslateOffset(_this.getChildren()[selectedItem]); | ||
_this.needle--; | ||
_this.animateItems(_this.needle, selectedItem, offset, true); | ||
_this.setState({ | ||
liveText: _this.props.voiceover.moved(_this.needle + 1, true) | ||
const offset = getTranslateOffset(this.getChildren()[selectedItem]); | ||
this.needle--; | ||
this.animateItems(this.needle, selectedItem, offset, true); | ||
this.setState({ | ||
liveText: this.props.voiceover.moved(this.needle + 1, true) | ||
}); | ||
} | ||
if (e.key === 'Escape' && selectedItem > -1) { | ||
_this.getChildren().forEach(function (item) { | ||
utils_1.setItemTransition(item, 0); | ||
utils_1.transformItem(item, null); | ||
this.getChildren().forEach((item) => { | ||
setItemTransition(item, 0); | ||
transformItem(item, null); | ||
}); | ||
_this.setState({ | ||
this.setState({ | ||
selectedItem: -1, | ||
liveText: _this.props.voiceover.canceled(selectedItem + 1) | ||
liveText: this.props.voiceover.canceled(selectedItem + 1) | ||
}); | ||
_this.needle = -1; | ||
this.needle = -1; | ||
} | ||
@@ -451,8 +402,7 @@ if ((e.key === 'Tab' || e.key === 'Enter') && selectedItem > -1) { | ||
}; | ||
_this.schdOnMouseMove = utils_1.schd(_this.onMouseMove); | ||
_this.schdOnTouchMove = utils_1.schd(_this.onTouchMove); | ||
_this.schdOnEnd = utils_1.schd(_this.onEnd); | ||
return _this; | ||
this.schdOnMouseMove = schd(this.onMouseMove); | ||
this.schdOnTouchMove = schd(this.onTouchMove); | ||
this.schdOnEnd = schd(this.onEnd); | ||
} | ||
List.prototype.componentDidMount = function () { | ||
componentDidMount() { | ||
this.calculateOffsets(); | ||
@@ -464,4 +414,4 @@ document.addEventListener('touchstart', this.onMouseOrTouchStart, { | ||
document.addEventListener('mousedown', this.onMouseOrTouchStart); | ||
}; | ||
List.prototype.componentDidUpdate = function (_prevProps, prevState) { | ||
} | ||
componentDidUpdate(_prevProps, prevState) { | ||
if (prevState.scrollingSpeed !== this.state.scrollingSpeed && | ||
@@ -471,10 +421,9 @@ prevState.scrollingSpeed === 0) { | ||
} | ||
}; | ||
List.prototype.componentWillUnmount = function () { | ||
} | ||
componentWillUnmount() { | ||
document.removeEventListener('touchstart', this.onMouseOrTouchStart); | ||
document.removeEventListener('mousedown', this.onMouseOrTouchStart); | ||
}; | ||
List.prototype.render = function () { | ||
var _this = this; | ||
var baseStyle = { | ||
} | ||
render() { | ||
const baseStyle = { | ||
userSelect: 'none', | ||
@@ -487,24 +436,36 @@ WebkitUserSelect: 'none', | ||
}; | ||
var ghostStyle = __assign(__assign({}, baseStyle), { top: this.state.targetY, left: this.state.targetX, width: this.state.targetWidth, height: this.state.targetHeight, position: 'fixed', marginTop: 0 }); | ||
const ghostStyle = { | ||
...baseStyle, | ||
top: this.state.targetY, | ||
left: this.state.targetX, | ||
width: this.state.targetWidth, | ||
height: this.state.targetHeight, | ||
position: 'fixed', | ||
marginTop: 0 | ||
}; | ||
return (React.createElement(React.Fragment, null, | ||
this.props.renderList({ | ||
children: this.props.values.map(function (value, index) { | ||
var isHidden = index === _this.state.itemDragged; | ||
var isSelected = index === _this.state.selectedItem; | ||
var isDisabled = | ||
children: this.props.values.map((value, index) => { | ||
const isHidden = index === this.state.itemDragged; | ||
const isSelected = index === this.state.selectedItem; | ||
const isDisabled = | ||
// @ts-ignore | ||
_this.props.values[index] && _this.props.values[index].disabled; | ||
var props = { | ||
this.props.values[index] && this.props.values[index].disabled; | ||
const props = { | ||
key: index, | ||
tabIndex: isDisabled ? -1 : 0, | ||
'aria-roledescription': _this.props.voiceover.item(index + 1), | ||
onKeyDown: _this.onKeyDown, | ||
style: __assign(__assign({}, baseStyle), { visibility: isHidden ? 'hidden' : undefined, zIndex: isSelected ? 5000 : 0 }) | ||
'aria-roledescription': this.props.voiceover.item(index + 1), | ||
onKeyDown: this.onKeyDown, | ||
style: { | ||
...baseStyle, | ||
visibility: isHidden ? 'hidden' : undefined, | ||
zIndex: isSelected ? 5000 : 0 | ||
} | ||
}; | ||
return _this.props.renderItem({ | ||
value: value, | ||
props: props, | ||
index: index, | ||
return this.props.renderItem({ | ||
value, | ||
props, | ||
index, | ||
isDragged: false, | ||
isSelected: isSelected, | ||
isSelected, | ||
isOutOfBounds: false | ||
@@ -542,27 +503,16 @@ }); | ||
} }, this.state.liveText))); | ||
}; | ||
List.defaultProps = { | ||
transitionDuration: 300, | ||
lockVertically: false, | ||
removableByMove: false, | ||
voiceover: { | ||
item: function (position) { | ||
return "You are currently at a draggable item at position " + position + ". Press space bar to lift."; | ||
}, | ||
lifted: function (position) { | ||
return "You have lifted item at position " + position + ". Press j to move down, k to move up, space bar to drop and escape to cancel."; | ||
}, | ||
moved: function (position, up) { | ||
return "You have moved the lifted item " + (up ? 'up' : 'down') + " to position " + position + ". Press j to move down, k to move up, space bar to drop and escape to cancel."; | ||
}, | ||
dropped: function (from, to) { | ||
return "You have dropped the item. It has moved from position " + from + " to " + to + "."; | ||
}, | ||
canceled: function (position) { | ||
return "You have cancelled the movement. The item has returned to its starting position of " + position + "."; | ||
} | ||
} | ||
}; | ||
return List; | ||
}(React.Component)); | ||
exports.default = List; | ||
} | ||
} | ||
List.defaultProps = { | ||
transitionDuration: 300, | ||
lockVertically: false, | ||
removableByMove: false, | ||
voiceover: { | ||
item: (position) => `You are currently at a draggable item at position ${position}. Press space bar to lift.`, | ||
lifted: (position) => `You have lifted item at position ${position}. Press j to move down, k to move up, space bar to drop and escape to cancel.`, | ||
moved: (position, up) => `You have moved the lifted item ${up ? 'up' : 'down'} to position ${position}. Press j to move down, k to move up, space bar to drop and escape to cancel.`, | ||
dropped: (from, to) => `You have dropped the item. It has moved from position ${from} to ${to}.`, | ||
canceled: (position) => `You have cancelled the movement. The item has returned to its starting position of ${position}.` | ||
} | ||
}; | ||
export default List; |
@@ -1,2 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.checkIfInteractive = exports.schd = exports.binarySearch = exports.setItemTransition = exports.isItemTransformed = exports.transformItem = exports.isTouchEvent = exports.getTranslateOffset = exports.arrayRemove = exports.arrayMove = void 0; | ||
function arrayMove(array, from, to) { | ||
export function arrayMove(array, from, to) { | ||
array = array.slice(); | ||
@@ -9,4 +6,3 @@ array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]); | ||
} | ||
exports.arrayMove = arrayMove; | ||
function arrayRemove(array, index) { | ||
export function arrayRemove(array, index) { | ||
array = array.slice(); | ||
@@ -16,16 +12,11 @@ array.splice(index, 1); | ||
} | ||
exports.arrayRemove = arrayRemove; | ||
function getTranslateOffset(element) { | ||
var style = window.getComputedStyle(element); | ||
export function getTranslateOffset(element) { | ||
const style = window.getComputedStyle(element); | ||
return (Math.max(parseInt(style['margin-top'], 10), parseInt(style['margin-bottom'], 10)) + element.getBoundingClientRect().height); | ||
} | ||
exports.getTranslateOffset = getTranslateOffset; | ||
function isTouchEvent(event) { | ||
export function isTouchEvent(event) { | ||
return ((event.touches && event.touches.length) || | ||
(event.changedTouches && event.changedTouches.length)); | ||
} | ||
exports.isTouchEvent = isTouchEvent; | ||
function transformItem(element, offsetY, offsetX) { | ||
if (offsetY === void 0) { offsetY = 0; } | ||
if (offsetX === void 0) { offsetX = 0; } | ||
export function transformItem(element, offsetY = 0, offsetX = 0) { | ||
if (!element) | ||
@@ -37,21 +28,18 @@ return; | ||
} | ||
element.style.transform = "translate(" + offsetX + "px, " + offsetY + "px)"; | ||
element.style.transform = `translate(${offsetX}px, ${offsetY}px)`; | ||
} | ||
exports.transformItem = transformItem; | ||
function isItemTransformed(element) { | ||
export function isItemTransformed(element) { | ||
return !!element.style.transform; | ||
} | ||
exports.isItemTransformed = isItemTransformed; | ||
function setItemTransition(element, duration, timing) { | ||
export function setItemTransition(element, duration, timing) { | ||
if (element) { | ||
element.style['transition'] = "transform " + duration + "ms" + (timing ? " " + timing : ''); | ||
element.style['transition'] = `transform ${duration}ms${timing ? ` ${timing}` : ''}`; | ||
} | ||
} | ||
exports.setItemTransition = setItemTransition; | ||
// returns the "slot" for the targetValue, aka where it should go | ||
// in an ordered "array", it starts with -1 index | ||
function binarySearch(array, targetValue) { | ||
var min = 0; | ||
var max = array.length - 1; | ||
var guess; | ||
export function binarySearch(array, targetValue) { | ||
let min = 0; | ||
let max = array.length - 1; | ||
let guess; | ||
while (min <= max) { | ||
@@ -72,12 +60,7 @@ guess = Math.floor((max + min) / 2); | ||
} | ||
exports.binarySearch = binarySearch; | ||
// adapted from https://github.com/alexreardon/raf-schd | ||
var schd = function (fn) { | ||
var lastArgs = []; | ||
var frameId = null; | ||
var wrapperFn = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
export const schd = (fn) => { | ||
let lastArgs = []; | ||
let frameId = null; | ||
const wrapperFn = (...args) => { | ||
lastArgs = args; | ||
@@ -87,5 +70,5 @@ if (frameId) { | ||
} | ||
frameId = requestAnimationFrame(function () { | ||
frameId = requestAnimationFrame(() => { | ||
frameId = null; | ||
fn.apply(void 0, lastArgs); | ||
fn(...lastArgs); | ||
}); | ||
@@ -95,5 +78,4 @@ }; | ||
}; | ||
exports.schd = schd; | ||
function checkIfInteractive(target, rootElement) { | ||
var DISABLED_ELEMENTS = [ | ||
export function checkIfInteractive(target, rootElement) { | ||
const DISABLED_ELEMENTS = [ | ||
'input', | ||
@@ -109,3 +91,3 @@ 'textarea', | ||
]; | ||
var DISABLED_ROLES = ['button', 'link', 'checkbox', 'tab']; | ||
const DISABLED_ROLES = ['button', 'link', 'checkbox', 'tab']; | ||
while (target !== rootElement) { | ||
@@ -118,3 +100,3 @@ if (target.getAttribute('data-movable-handle')) { | ||
} | ||
var role = target.getAttribute('role'); | ||
const role = target.getAttribute('role'); | ||
if (role && DISABLED_ROLES.includes(role.toLowerCase())) { | ||
@@ -132,2 +114,1 @@ return true; | ||
} | ||
exports.checkIfInteractive = checkIfInteractive; |
{ | ||
"name": "react-movable", | ||
"version": "2.5.4", | ||
"version": "3.0.0", | ||
"description": "Drag and drop lists.", | ||
@@ -47,3 +47,3 @@ "main": "lib/index.js", | ||
"devDependencies": { | ||
"@ladle/react": "0.0.11", | ||
"@ladle/react": "^0.2.4", | ||
"@types/expect-puppeteer": "^4.4.5", | ||
@@ -69,4 +69,4 @@ "@types/jest": "^26.0.20", | ||
"peerDependencies": { | ||
"react": "^16.3.0-0 || ^17.0.0-0", | ||
"react-dom": "^16.3.0-0 || ^17.0.0-0" | ||
"react": ">=16.3", | ||
"react-dom": ">=16.3" | ||
}, | ||
@@ -100,5 +100,5 @@ "jest": { | ||
"volta": { | ||
"node": "14.15.4", | ||
"yarn": "1.22.10" | ||
"node": "16.13.0", | ||
"yarn": "1.22.17" | ||
} | ||
} |
@@ -271,3 +271,2 @@ # react-movable | ||
- **Edge** (latest, windows) | ||
- **MSIE 11** (windows) | ||
@@ -274,0 +273,0 @@ ## Users |
50064
750
310