react-beautiful-dnd
Version:
Beautiful, accessible drag and drop for lists with React.js
271 lines (203 loc) • 6.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.forcePressThreshold = exports.timeForLongPress = undefined;
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _stopEvent = require('../util/stop-event');
var _stopEvent2 = _interopRequireDefault(_stopEvent);
var _createScheduler = require('../util/create-scheduler');
var _createScheduler2 = _interopRequireDefault(_createScheduler);
var _getWindowFromRef = require('../../get-window-from-ref');
var _getWindowFromRef2 = _interopRequireDefault(_getWindowFromRef);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var timeForLongPress = exports.timeForLongPress = 150;
var forcePressThreshold = exports.forcePressThreshold = 0.15;
var noop = function noop() {};
var initial = {
isDragging: false,
pending: null,
hasMoved: false,
preventClick: false,
longPressTimerId: null
};
exports.default = function (_ref) {
var callbacks = _ref.callbacks,
getDraggableRef = _ref.getDraggableRef,
canStartCapturing = _ref.canStartCapturing;
var state = initial;
var setState = function setState(partial) {
state = (0, _extends3.default)({}, state, partial);
};
var isDragging = function isDragging() {
return state.isDragging;
};
var isCapturing = function isCapturing() {
return Boolean(state.pending || state.isDragging || state.longPressTimerId);
};
var schedule = (0, _createScheduler2.default)(callbacks, isDragging);
var startDragging = function startDragging() {
var pending = state.pending;
if (!pending) {
console.error('cannot start a touch drag without a pending position');
kill();
return;
}
setState({
isDragging: true,
hasMoved: false,
pending: null,
longPressTimerId: null
});
callbacks.onLift({
client: pending,
isScrollAllowed: false
});
};
var stopDragging = function stopDragging() {
var fn = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop;
unbindWindowEvents();
setState((0, _extends3.default)({}, initial, {
preventClick: true
}));
fn();
};
var startPendingDrag = function startPendingDrag(event) {
var touch = event.touches[0];
var clientX = touch.clientX,
clientY = touch.clientY;
var point = {
x: clientX,
y: clientY
};
var longPressTimerId = setTimeout(startDragging, timeForLongPress);
setState({
longPressTimerId: longPressTimerId,
pending: point,
isDragging: false,
hasMoved: false
});
bindWindowEvents();
};
var stopPendingDrag = function stopPendingDrag() {
clearTimeout(state.longPressTimerId);
unbindWindowEvents();
setState(initial);
};
var kill = function kill() {
var fn = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop;
if (state.pending) {
stopPendingDrag();
return;
}
stopDragging(fn);
};
var cancel = function cancel() {
kill(callbacks.onCancel);
};
var windowBindings = {
touchmove: function touchmove(event) {
if (state.pending) {
stopPendingDrag();
return;
}
if (!state.hasMoved) {
setState({
hasMoved: true
});
}
(0, _stopEvent2.default)(event);
var _event$touches$ = event.touches[0],
clientX = _event$touches$.clientX,
clientY = _event$touches$.clientY;
var point = {
x: clientX,
y: clientY
};
schedule.move(point);
},
touchend: function touchend(event) {
if (state.pending) {
stopPendingDrag();
return;
}
stopDragging(callbacks.onDrop);
(0, _stopEvent2.default)(event);
},
touchcancel: cancel,
touchstart: function touchstart() {
if (isDragging()) {
console.error('touch start fired while already dragging');
cancel();
}
},
orientationchange: cancel,
resize: cancel,
scroll: cancel,
contextmenu: _stopEvent2.default,
keydown: cancel,
touchforcechange: function touchforcechange(event) {
if (state.hasMoved) {
return;
}
var touch = event.touches[0];
if (touch.force >= forcePressThreshold) {
cancel();
}
}
};
var eventKeys = (0, _keys2.default)(windowBindings);
var bindWindowEvents = function bindWindowEvents() {
var win = (0, _getWindowFromRef2.default)(getDraggableRef());
eventKeys.forEach(function (eventKey) {
var fn = windowBindings[eventKey];
if (eventKey === 'touchmove') {
win.addEventListener(eventKey, fn, { passive: false });
return;
}
win.addEventListener(eventKey, fn);
});
};
var unbindWindowEvents = function unbindWindowEvents() {
var win = (0, _getWindowFromRef2.default)(getDraggableRef());
eventKeys.forEach(function (eventKey) {
return win.removeEventListener(eventKey, windowBindings[eventKey]);
});
};
var onTouchStart = function onTouchStart(event) {
if (!canStartCapturing(event)) {
return;
}
if (isCapturing()) {
console.error('should not be able to perform a touch start while a drag or pending drag is occurring');
cancel();
return;
}
event.stopPropagation();
startPendingDrag(event);
};
var onTouchMove = function onTouchMove() {
if (state.pending) {
stopPendingDrag();
}
};
var onClick = function onClick(event) {
if (!state.preventClick) {
return;
}
(0, _stopEvent2.default)(event);
setState(initial);
};
var sensor = {
onTouchStart: onTouchStart,
onTouchMove: onTouchMove,
onClick: onClick,
kill: kill,
isCapturing: isCapturing,
isDragging: isDragging
};
return sensor;
};