UNPKG

@beisen/ethos

Version:

beisencloud pc react components

235 lines (176 loc) • 6.01 kB
'use strict'; var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var assign = require('object-assign'); var getSelected = require('./getSelected'); var hasOwn = function hasOwn(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }; /** * Here is how multi selection is implemented - trying to emulate behavior in OSX Finder * * When there is no selection, and an initial click for selection is done, keep that index (SELINDEX) * * Next, if we shift+click, we mark as selected the items from initial index to current click index. * * Now, if we ctrl+click elsewhere, keep the selection, but also add the selected file, * and set SELINDEX to the new index. Now on any subsequent clicks, have the same behavior, * selecting/deselecting items starting from SELINDEX to the new click index */ module.exports = { findInitialSelectionIndex: function findInitialSelectionIndex() { var selected = getSelected(this.p, this.state); var index = undefined; if (!(0, _keys2.default)(selected).length) { return index; } var i = 0; var data = this.p.data; var len = data.length; var id; var idProperty = this.props.idProperty; for (; i < len; i++) { id = data[i][idProperty]; if (selected[id]) { index = i; } } return index; }, notifySelection: function notifySelection(selected, data) { if (typeof this.props.onSelectionChange == 'function') { this.props.onSelectionChange(selected, data); } if (!hasOwn(this.props, 'selected')) { this.cleanCache(); this.setState({ defaultSelected: selected }); } }, handleSingleSelection: function handleSingleSelection(data, event) { var props = this.p; var rowSelected = this.isRowSelected(data); var newSelected = !rowSelected; var ctrlKey = event.metaKey || event.ctrlKey; if (rowSelected && event && !ctrlKey) { //if already selected and not ctrl, keep selected newSelected = true; } var selectedId = newSelected ? data[props.idProperty] : null; this.notifySelection(selectedId, data); }, handleMultiSelection: function handleMultiSelection(data, event, config) { var selIndex = config.selIndex; var prevShiftKeyIndex = config.prevShiftKeyIndex; var props = this.p; var map = selIndex == null ? {} : assign({}, getSelected(props, this.state)); if (prevShiftKeyIndex != null && selIndex != null) { var min = Math.min(prevShiftKeyIndex, selIndex); var max = Math.max(prevShiftKeyIndex, selIndex); var removeArray = props.data.slice(min, max + 1) || []; removeArray.forEach(function (item) { if (item) { var id = item[props.idProperty]; delete map[id]; } }); } data.forEach(function (item) { if (item) { var id = item[props.idProperty]; map[id] = item; } }); this.notifySelection(map, data); }, handleMultiSelectionRowToggle: function handleMultiSelectionRowToggle(data, event) { var selected = getSelected(this.p, this.state); var isSelected = this.isRowSelected(data); var clone = assign({}, selected); var id = data[this.p.idProperty]; if (isSelected) { delete clone[id]; } else { clone[id] = data; } this.notifySelection(clone, data); return isSelected; }, handleSelection: function handleSelection(rowProps, event) { var props = this.p; if (!hasOwn(props, 'selected') && !hasOwn(props, 'defaultSelected')) { return; } var isSelected = this.isRowSelected(rowProps.data); var multiSelect = this.isMultiSelect(); if (!multiSelect) { this.handleSingleSelection(rowProps.data, event); return; } if (this.selIndex === undefined) { this.selIndex = this.findInitialSelectionIndex(); } var selIndex = this.selIndex; //multi selection var index = rowProps.index; var prevShiftKeyIndex = this.shiftKeyIndex; var start; var end; var data; if (event.metaKey || event.ctrlKey) { this.selIndex = index; this.shiftKeyIndex = null; var unselect = this.handleMultiSelectionRowToggle(props.data[index], event); if (unselect) { this.selIndex++; this.shiftKeyIndex = prevShiftKeyIndex; } return; } if (!event.shiftKey) { //set selIndex, for future use this.selIndex = index; this.shiftKeyIndex = null; //should not select many, so make selIndex null selIndex = null; } else { this.shiftKeyIndex = index; } if (selIndex == null) { data = [props.data[index]]; } else { start = Math.min(index, selIndex); end = Math.max(index, selIndex) + 1; data = props.data.slice(start, end); } this.handleMultiSelection(data, event, { selIndex: selIndex, prevShiftKeyIndex: prevShiftKeyIndex }); }, isRowSelected: function isRowSelected(data) { var selectedMap = this.getSelectedMap(); var id = data[this.props.idProperty]; return selectedMap[id]; }, isMultiSelect: function isMultiSelect() { var selected = getSelected(this.p, this.state); return selected && (typeof selected === 'undefined' ? 'undefined' : (0, _typeof3.default)(selected)) == 'object'; }, getSelectedMap: function getSelectedMap() { var selected = getSelected(this.p, this.state); var multiSelect = selected && (typeof selected === 'undefined' ? 'undefined' : (0, _typeof3.default)(selected)) == 'object'; var map; if (multiSelect) { map = selected; } else { map = {}; map[selected] = true; } return map; } };