UNPKG

react-beautiful-dnd

Version:

Beautiful, accessible drag and drop for lists with React.js

373 lines (286 loc) 10 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray'); var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _extends4 = require('babel-runtime/helpers/extends'); var _extends5 = _interopRequireDefault(_extends4); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = function (callbacks) { var state = { droppables: {}, draggables: {}, isCollecting: false, request: null, frameId: null }; var setState = function setState(partial) { var newState = (0, _extends5.default)({}, state, partial); state = newState; }; var cancel = function cancel() { var _console; (_console = console).error.apply(_console, arguments); if (!state.isCollecting) { return; } stopCollecting(); callbacks.cancel(); }; var registerDraggable = function registerDraggable(descriptor, getDimension) { var id = descriptor.id; if (!state.droppables[descriptor.droppableId]) { cancel('Cannot register Draggable ' + id + ' as there is no entry for the Droppable ' + descriptor.droppableId); return; } var entry = { descriptor: descriptor, getDimension: getDimension }; var draggables = (0, _extends5.default)({}, state.draggables, (0, _defineProperty3.default)({}, id, entry)); setState({ draggables: draggables }); if (!state.isCollecting) { return; } var dimension = entry.getDimension(); callbacks.publishDraggables([dimension]); }; var registerDroppable = function registerDroppable(descriptor, droppableCallbacks) { var id = descriptor.id; var entry = { descriptor: descriptor, callbacks: droppableCallbacks }; var droppables = (0, _extends5.default)({}, state.droppables, (0, _defineProperty3.default)({}, id, entry)); setState({ droppables: droppables }); if (!state.isCollecting) { return; } var dimension = entry.callbacks.getDimension(); callbacks.publishDroppables([dimension]); entry.callbacks.watchScroll(); }; var updateDroppableIsEnabled = function updateDroppableIsEnabled(id, isEnabled) { if (!state.droppables[id]) { cancel('Cannot update the scroll on Droppable ' + id + ' as it is not registered'); return; } if (!state.isCollecting) { return; } callbacks.updateDroppableIsEnabled(id, isEnabled); }; var updateDroppableScroll = function updateDroppableScroll(id, newScroll) { if (!state.droppables[id]) { cancel('Cannot update the scroll on Droppable ' + id + ' as it is not registered'); return; } if (!state.isCollecting) { return; } callbacks.updateDroppableScroll(id, newScroll); }; var unregisterDraggable = function unregisterDraggable(descriptor) { var entry = state.draggables[descriptor.id]; if (!entry) { cancel('Cannot unregister Draggable with id ' + descriptor.id + ' as it is not registered'); return; } if (entry.descriptor !== descriptor) { return; } var newMap = (0, _extends5.default)({}, state.draggables); delete newMap[descriptor.id]; setState({ draggables: newMap }); if (!state.isCollecting) { return; } console.warn('currently not supporting unmounting a Draggable during a drag'); }; var unregisterDroppable = function unregisterDroppable(descriptor) { var entry = state.droppables[descriptor.id]; if (!entry) { cancel('Cannot unregister Droppable with id ' + descriptor.id + ' as as it is not registered'); return; } if (entry.descriptor !== descriptor) { return; } var newMap = (0, _extends5.default)({}, state.droppables); delete newMap[descriptor.id]; setState({ droppables: newMap }); if (!state.isCollecting) { return; } console.warn('currently not supporting unmounting a Droppable during a drag'); }; var getToBeCollected = function getToBeCollected() { var draggables = state.draggables; var droppables = state.droppables; var request = state.request; if (!request) { console.error('cannot find request in state'); return []; } var descriptor = draggables[request].descriptor; var home = droppables[descriptor.droppableId].descriptor; var draggablesToBeCollected = (0, _keys2.default)(draggables).map(function (id) { return draggables[id].descriptor; }).filter(function (item) { return item.id !== descriptor.id; }).filter(function (item) { var entry = droppables[item.droppableId]; if (!entry) { console.warn('Orphan Draggable found ' + item.id + ' which says it belongs to unknown Droppable ' + item.droppableId); return false; } return entry.descriptor.type === home.type; }); var droppablesToBeCollected = (0, _keys2.default)(droppables).map(function (id) { return droppables[id].descriptor; }).filter(function (item) { return item.id !== home.id; }).filter(function (item) { var droppable = droppables[item.id].descriptor; return droppable.type === home.type; }); var toBeCollected = [].concat((0, _toConsumableArray3.default)(droppablesToBeCollected), (0, _toConsumableArray3.default)(draggablesToBeCollected)); return toBeCollected; }; var processPrimaryDimensions = function processPrimaryDimensions(request) { if (state.isCollecting) { cancel('Cannot start capturing dimensions for a drag it is already dragging'); return; } if (!request) { cancel('Cannot start capturing dimensions with an invalid request', request); return; } setState({ isCollecting: true, request: request }); var draggables = state.draggables; var droppables = state.droppables; var draggableEntry = draggables[request]; if (!draggableEntry) { cancel('Cannot find Draggable with id ' + request + ' to start collecting dimensions'); return; } var homeEntry = droppables[draggableEntry.descriptor.droppableId]; if (!homeEntry) { cancel('Cannot find home Droppable [id:' + draggableEntry.descriptor.droppableId + '] for Draggable [id:' + request + ']'); return; } var home = homeEntry.callbacks.getDimension(); var draggable = draggableEntry.getDimension(); callbacks.publishDroppables([home]); callbacks.publishDraggables([draggable]); homeEntry.callbacks.watchScroll(); }; var setFrameId = function setFrameId(frameId) { setState({ frameId: frameId }); }; var processSecondaryDimensions = function processSecondaryDimensions() { if (!state.isCollecting) { cancel('Cannot collect secondary dimensions when collection is not occurring'); return; } var toBeCollected = getToBeCollected(); var collectFrameId = requestAnimationFrame(function () { var toBePublishedBuffer = toBeCollected.map(function (descriptor) { if (descriptor.type) { return state.droppables[descriptor.id].callbacks.getDimension(); } return state.draggables[descriptor.id].getDimension(); }); var publishFrameId = requestAnimationFrame(function () { var toBePublished = toBePublishedBuffer.reduce(function (previous, dimension) { if (dimension.placeholder) { previous.draggables.push(dimension); } else { previous.droppables.push(dimension); } return previous; }, { draggables: [], droppables: [] }); if (toBePublished.droppables.length) { callbacks.publishDroppables(toBePublished.droppables); } if (toBePublished.draggables.length) { callbacks.publishDraggables(toBePublished.draggables); } toBePublished.droppables.forEach(function (dimension) { var entry = state.droppables[dimension.descriptor.id]; entry.callbacks.watchScroll(); }); setFrameId(null); }); setFrameId(publishFrameId); }); setFrameId(collectFrameId); }; var stopCollecting = function stopCollecting() { (0, _keys2.default)(state.droppables).forEach(function (id) { return state.droppables[id].callbacks.unwatchScroll(); }); if (state.frameId) { cancelAnimationFrame(state.frameId); } setState({ isCollecting: false, request: null, frameId: null }); }; var onPhaseChange = function onPhaseChange(current) { var phase = current.phase; if (phase === 'COLLECTING_INITIAL_DIMENSIONS') { processPrimaryDimensions(current.dimension.request); return; } if (phase === 'DRAGGING') { if (current.dimension.request !== state.request) { cancel('Request in local state does not match that of the store'); return; } processSecondaryDimensions(); return; } if (phase === 'DROP_ANIMATING' || phase === 'DROP_COMPLETE') { if (state.isCollecting) { stopCollecting(); } return; } if (phase === 'IDLE') { if (state.isCollecting) { stopCollecting(); } } }; var marshal = { registerDraggable: registerDraggable, unregisterDraggable: unregisterDraggable, registerDroppable: registerDroppable, unregisterDroppable: unregisterDroppable, updateDroppableIsEnabled: updateDroppableIsEnabled, updateDroppableScroll: updateDroppableScroll, onPhaseChange: onPhaseChange }; return marshal; };