UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

249 lines (243 loc) 9.99 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.growColumn = void 0; exports.reduceSpace = reduceSpace; exports.shrinkColumn = void 0; exports.updateAffectedColumn = updateAffectedColumn; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _columnState = require("./column-state"); var _resizeState = require("./resize-state"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var growColumn = exports.growColumn = function growColumn(state, colIndex, amount, selectedColumns) { // can't grow if columns don't exist or it's the last column if (!state.cols[colIndex] || !state.cols[colIndex + 1]) { return state; } var res = moveSpaceFrom(state, colIndex + 1, colIndex, amount); var remaining = amount - res.amount; var newState = res.state; if (remaining > 0) { newState = stackSpace(newState, colIndex, remaining).state; } if (selectedColumns && selectedColumns.length > 1) { return (0, _resizeState.bulkColumnsResize)(newState, selectedColumns, colIndex); } return newState; }; var shrinkColumn = exports.shrinkColumn = function shrinkColumn(state, colIndex, amount, selectedColumns) { // can't shrink if columns don't exist if (!state.cols[colIndex]) { return state; } // try to shrink dragging column by giving from the column to the right first var res = moveSpaceFrom(state, colIndex, colIndex + 1, -amount); var newState = res.state; var isOverflownTable = (0, _resizeState.getTotalWidth)(newState) > newState.maxSize; var isLastColumn = !newState.cols[colIndex + 1]; // stop resizing the last column once table is not overflown if (isLastColumn && !isOverflownTable) { return newState; } var remaining = amount + res.amount; if (remaining < 0) { newState = stackSpace(newState, colIndex + 1, remaining).state; } if (selectedColumns && selectedColumns.length > 1) { return (0, _resizeState.bulkColumnsResize)(newState, selectedColumns, colIndex); } return newState; }; function reduceSpace(state, amount) { var ignoreCols = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; var remaining = amount; // keep trying to resolve resize request until we run out of free space, // or nothing to resize var _loop = function _loop() { // filter candidates only with free space var candidates = state.cols.filter(function (column) { return (0, _columnState.getFreeSpace)(column) && ignoreCols.indexOf(column.index) === -1; }); if (candidates.length === 0) { return 0; // break } var requestedResize = Math.floor(remaining / candidates.length); if (requestedResize === 0) { return 0; // break } candidates.forEach(function (candidate) { var newWidth = candidate.width - requestedResize; if (newWidth < candidate.minWidth) { // If the new requested width is less than our min // Calc what width we didn't use, we'll try extract that // from other cols. var remainder = candidate.minWidth - newWidth; newWidth = candidate.minWidth; remaining = remaining - requestedResize + remainder; } else { remaining -= requestedResize; } state = _objectSpread(_objectSpread({}, state), {}, { cols: [].concat((0, _toConsumableArray2.default)(state.cols.slice(0, candidate.index)), [_objectSpread(_objectSpread({}, candidate), {}, { width: newWidth })], (0, _toConsumableArray2.default)(state.cols.slice(candidate.index + 1))) }); }); }, _ret; while (remaining > 0) { _ret = _loop(); if (_ret === 0) break; } return state; } var ColType = /*#__PURE__*/function (ColType) { ColType["SOURCE"] = "src"; ColType["DEST"] = "dest"; return ColType; }(ColType || {}); // TODO: ED-26961 - should handle when destIdx: // - is beyond the range, and then not give it back function moveSpaceFrom(state, srcIdx, destIdx, amount) { var useFreeSpace = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; var srcCol = state.cols[srcIdx]; var destCol = state.cols[destIdx]; if (useFreeSpace) { var freeSpace = (0, _columnState.getFreeSpace)(srcCol); // if taking more than source column's free space, only take that much if (amountFor(ColType.DEST)(amount) > freeSpace) { amount = amount > 0 ? freeSpace : -freeSpace; } } // if the source column shrinks past its min size, don't give the space away if (amountFor(ColType.SOURCE)(amount) < 0 && widthFor(ColType.SOURCE)(amount, srcCol, destCol) < srcCol.minWidth) { amount = srcCol.width - srcCol.minWidth; } var newDest = destCol ? _objectSpread(_objectSpread({}, destCol), {}, { width: widthFor(ColType.DEST)(amount, srcCol, destCol) }) : undefined; if (!newDest && amountFor(ColType.SOURCE)(amount) < 0) { // non-zero-sum game, ensure that we're not removing more than the total table width either var totalWidth = (0, _resizeState.getTotalWidth)(state); if (totalWidth - srcCol.width + widthFor(ColType.SOURCE)(amount, srcCol, destCol) < state.maxSize) { // would shrink table below max width, stop it amount = state.maxSize - (totalWidth - srcCol.width) - srcCol.width - 1; } } var newSrc = _objectSpread(_objectSpread({}, srcCol), {}, { width: widthFor(ColType.SOURCE)(amount, srcCol, destCol) }); var newCols = state.cols.map(function (existingCol, idx) { return idx === srcIdx ? newSrc : idx === destIdx ? newDest : existingCol; }).filter(Boolean); return { state: _objectSpread(_objectSpread({}, state), {}, { cols: newCols }), amount: amount }; } function stackSpace(state, destIdx, amount) { var candidates = getCandidates(state, destIdx, amount); var _loop2 = function _loop2() { // search for most (or least) free space in candidates var candidateIdx = findNextFreeColumn(candidates, amount); if (candidateIdx === -1) { // stack to the right -> growing the dragging column and go overflow if (amount > 0) { return { v: { state: _objectSpread(_objectSpread({}, state), {}, { cols: [].concat((0, _toConsumableArray2.default)(state.cols.slice(0, destIdx)), [_objectSpread(_objectSpread({}, state.cols[destIdx]), {}, { width: state.cols[destIdx].width + amount })], (0, _toConsumableArray2.default)(state.cols.slice(destIdx + 1))) }), remaining: amount } }; } // stacking to the left, if no free space remains return 0; // break } var column = candidates.find(function (col) { return col.index === candidateIdx; }); if (!column || (0, _columnState.getFreeSpace)(column) <= 0) { // no more columns with free space remain return 0; // break } var res = moveSpaceFrom(state, column.index, destIdx, amount); state = res.state; amount -= res.amount; candidates = candidates.filter(function (col) { return col.index !== candidateIdx; }); }, _ret2; while (candidates.length && amount) { _ret2 = _loop2(); if (_ret2 === 0) break; if (_ret2) return _ret2.v; } return { state: state, remaining: amount }; } function findNextFreeColumn(columns, amount) { if (columns.length === 0) { return -1; } var direction = amount < 0 ? 'left' : 'right'; if (direction === 'left') { columns = columns.slice().reverse(); } var freeIndex = -1; columns.forEach(function (column) { if ((0, _columnState.getFreeSpace)(column) && freeIndex === -1) { freeIndex = column.index; } }); if (freeIndex === -1) { return -1; } return freeIndex; } function amountFor(colType) { return function (amount) { return colType === ColType.SOURCE ? amount > 0 ? -amount : amount : amount < 0 ? -amount : amount; }; } function widthFor(colType) { return function (amount, srcCol, destCol) { return (colType === ColType.SOURCE ? srcCol : destCol).width + amountFor(colType)(amount); }; } function getCandidates(state, destIdx, amount) { var candidates = state.cols; // only consider rows after the selected column in the direction of resize return amount < 0 ? candidates.slice(0, destIdx) : candidates.slice(destIdx + 1); } /** * Update the given column based on resizeAmount, maintaining all other columns */ function updateAffectedColumn(resizeState, colIndex, resizeAmount) { var updatedCols = resizeState.cols.map(function (col, index) { if (index === colIndex) { var newWidth = Math.max(col.width + resizeAmount, col.minWidth); return _objectSpread(_objectSpread({}, col), {}, { width: newWidth }); } return col; }); return _objectSpread(_objectSpread({}, resizeState), {}, { tableWidth: updatedCols.reduce(function (acc, col) { return acc + col.width; }, 0), cols: updatedCols }); }