@atlaskit/editor-plugin-table 5.5.3 → 5.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/plugins/table/commands/index.js +12 -0
  3. package/dist/cjs/plugins/table/commands/misc.js +61 -1
  4. package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +2 -3
  5. package/dist/cjs/plugins/table/ui/FloatingInsertButton/index.js +0 -3
  6. package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +8 -2
  7. package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +9 -2
  8. package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +11 -0
  9. package/dist/cjs/plugins/table/utils/index.js +6 -0
  10. package/dist/cjs/plugins/table/utils/merged-cells.js +75 -1
  11. package/dist/es2019/plugins/table/commands/index.js +1 -1
  12. package/dist/es2019/plugins/table/commands/misc.js +46 -1
  13. package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +3 -4
  14. package/dist/es2019/plugins/table/ui/FloatingInsertButton/index.js +0 -3
  15. package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +9 -3
  16. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +9 -2
  17. package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +16 -1
  18. package/dist/es2019/plugins/table/utils/index.js +1 -1
  19. package/dist/es2019/plugins/table/utils/merged-cells.js +63 -1
  20. package/dist/esm/plugins/table/commands/index.js +1 -1
  21. package/dist/esm/plugins/table/commands/misc.js +61 -1
  22. package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +3 -4
  23. package/dist/esm/plugins/table/ui/FloatingInsertButton/index.js +0 -3
  24. package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +9 -3
  25. package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +9 -2
  26. package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +12 -1
  27. package/dist/esm/plugins/table/utils/index.js +1 -1
  28. package/dist/esm/plugins/table/utils/merged-cells.js +73 -0
  29. package/dist/types/plugins/table/commands/index.d.ts +1 -1
  30. package/dist/types/plugins/table/commands/misc.d.ts +2 -0
  31. package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -0
  32. package/dist/types/plugins/table/ui/TableFloatingControls/index.d.ts +1 -0
  33. package/dist/types/plugins/table/utils/index.d.ts +1 -1
  34. package/dist/types/plugins/table/utils/merged-cells.d.ts +3 -0
  35. package/dist/types-ts4.5/plugins/table/commands/index.d.ts +1 -1
  36. package/dist/types-ts4.5/plugins/table/commands/misc.d.ts +2 -0
  37. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -0
  38. package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/index.d.ts +1 -0
  39. package/dist/types-ts4.5/plugins/table/utils/index.d.ts +1 -1
  40. package/dist/types-ts4.5/plugins/table/utils/merged-cells.d.ts +3 -0
  41. package/package.json +1 -1
  42. package/src/__tests__/unit/ui/FloatingInsertButton.tsx +3 -3
  43. package/src/__tests__/unit/ui/RowDragControls.tsx +2 -0
  44. package/src/__tests__/unit/utils/merged-cells.ts +156 -0
  45. package/src/plugins/table/commands/index.ts +2 -0
  46. package/src/plugins/table/commands/misc.ts +78 -0
  47. package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +11 -9
  48. package/src/plugins/table/ui/FloatingInsertButton/index.tsx +0 -3
  49. package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +22 -2
  50. package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +21 -2
  51. package/src/plugins/table/ui/TableFloatingControls/index.tsx +12 -1
  52. package/src/plugins/table/utils/index.ts +5 -1
  53. package/src/plugins/table/utils/merged-cells.ts +82 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-table
2
2
 
3
+ ## 5.5.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#59951](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/59951) [`a42a17e8af1b`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a42a17e8af1b) - ED-21106: Remove nonPrivacySafeAttributes from editor operational events
8
+ - [#59453](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/59453) [`e23de3e96559`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e23de3e96559) - Fix drop table row/column next to merged cells
9
+
10
+ ## 5.5.4
11
+
12
+ ### Patch Changes
13
+
14
+ - [#60278](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/60278) [`bc2785a02329`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/bc2785a02329) - Selection of multiple rows / column should remain when clicking the drag handle
15
+ - [#60323](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/60323) [`e0c900d97140`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e0c900d97140) - Fix undo of drag and drop using keyboard
16
+
3
17
  ## 5.5.3
4
18
 
5
19
  ### Patch Changes
@@ -135,12 +135,24 @@ Object.defineProperty(exports, "selectColumn", {
135
135
  return _misc.selectColumn;
136
136
  }
137
137
  });
138
+ Object.defineProperty(exports, "selectColumns", {
139
+ enumerable: true,
140
+ get: function get() {
141
+ return _misc.selectColumns;
142
+ }
143
+ });
138
144
  Object.defineProperty(exports, "selectRow", {
139
145
  enumerable: true,
140
146
  get: function get() {
141
147
  return _misc.selectRow;
142
148
  }
143
149
  });
150
+ Object.defineProperty(exports, "selectRows", {
151
+ enumerable: true,
152
+ get: function get() {
153
+ return _misc.selectRows;
154
+ }
155
+ });
144
156
  Object.defineProperty(exports, "setCellAttr", {
145
157
  enumerable: true,
146
158
  get: function get() {
@@ -4,7 +4,8 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.updateResizeHandleDecorations = exports.triggerUnlessTableHeader = exports.transformSliceToRemoveColumnsWidths = exports.transformSliceToAddTableHeaders = exports.transformSliceRemoveCellBackgroundColor = exports.showInsertRowButton = exports.showInsertColumnButton = exports.setTableRef = exports.setMultipleCellAttrs = exports.setEditorFocus = exports.setCellAttr = exports.selectRow = exports.selectColumn = exports.removeResizeHandleDecorations = exports.moveCursorBackward = exports.isInsideFirstCellOfRowOrColumn = exports.hideInsertColumnOrRowButton = exports.getTableSelectionType = exports.getTableElementMoveTypeBySlice = exports.deleteTableIfSelected = exports.deleteTable = exports.countCellsInSlice = exports.convertFirstRowToHeader = exports.autoSizeTable = exports.addResizeHandleDecorations = exports.addBoldInEmptyHeaderCells = void 0;
7
+ exports.updateResizeHandleDecorations = exports.triggerUnlessTableHeader = exports.transformSliceToRemoveColumnsWidths = exports.transformSliceToAddTableHeaders = exports.transformSliceRemoveCellBackgroundColor = exports.showInsertRowButton = exports.showInsertColumnButton = exports.setTableRef = exports.setMultipleCellAttrs = exports.setEditorFocus = exports.setCellAttr = exports.selectRows = exports.selectRow = exports.selectColumns = exports.selectColumn = exports.removeResizeHandleDecorations = exports.moveCursorBackward = exports.isInsideFirstCellOfRowOrColumn = exports.hideInsertColumnOrRowButton = exports.getTableSelectionType = exports.getTableElementMoveTypeBySlice = exports.deleteTableIfSelected = exports.deleteTable = exports.countCellsInSlice = exports.convertFirstRowToHeader = exports.autoSizeTable = exports.addResizeHandleDecorations = exports.addBoldInEmptyHeaderCells = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
8
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
10
  var _utils = require("@atlaskit/editor-common/utils");
10
11
  var _state = require("@atlaskit/editor-prosemirror/state");
@@ -346,6 +347,37 @@ var selectColumn = exports.selectColumn = function selectColumn(column, expand)
346
347
  return (0, _utils2.selectColumn)(column, expand)(tr).setMeta('addToHistory', false);
347
348
  });
348
349
  };
350
+ var selectColumns = exports.selectColumns = function selectColumns(columnIndexes) {
351
+ return (0, _pluginFactory.createCommand)(function (state) {
352
+ if (!columnIndexes) {
353
+ return false;
354
+ }
355
+ var cells = columnIndexes.map(function (column) {
356
+ return (0, _utils2.getCellsInColumn)(column)(state.tr.selection);
357
+ }).flat();
358
+ if (!cells || !cells.length || cells.some(function (cell) {
359
+ return cell && typeof cell.pos !== 'number';
360
+ })) {
361
+ return false;
362
+ }
363
+ var decorations = (0, _decoration.createColumnSelectedDecoration)((0, _utils2.selectColumns)(columnIndexes)(state.tr));
364
+ var decorationSet = (0, _updatePluginStateDecorations.updatePluginStateDecorations)(state, decorations, _types.TableDecorations.COLUMN_SELECTED);
365
+ var cellsInFirstColumn = (0, _utils2.getCellsInColumn)(Math.min.apply(Math, (0, _toConsumableArray2.default)(columnIndexes)))(state.tr.selection);
366
+ if (!cellsInFirstColumn || cellsInFirstColumn.length === 0) {
367
+ return false;
368
+ }
369
+ var targetCellPosition = cellsInFirstColumn[0].pos;
370
+ return {
371
+ type: 'SELECT_COLUMN',
372
+ data: {
373
+ targetCellPosition: targetCellPosition,
374
+ decorationSet: decorationSet
375
+ }
376
+ };
377
+ }, function (tr) {
378
+ return (0, _utils2.selectColumns)(columnIndexes)(tr).setMeta('addToHistory', false);
379
+ });
380
+ };
349
381
  var selectRow = exports.selectRow = function selectRow(row, expand) {
350
382
  return (0, _pluginFactory.createCommand)(function (state) {
351
383
  var targetCellPosition;
@@ -363,6 +395,34 @@ var selectRow = exports.selectRow = function selectRow(row, expand) {
363
395
  return (0, _utils2.selectRow)(row, expand)(tr).setMeta('addToHistory', false);
364
396
  });
365
397
  };
398
+ var selectRows = exports.selectRows = function selectRows(rowIndexes) {
399
+ return (0, _pluginFactory.createCommand)(function (state) {
400
+ if (rowIndexes.length === 0) {
401
+ return false;
402
+ }
403
+ var cells = rowIndexes.map(function (row) {
404
+ return (0, _utils2.getCellsInRow)(row)(state.tr.selection);
405
+ }).flat();
406
+ if (!cells || !cells.length || cells.some(function (cell) {
407
+ return cell && typeof cell.pos !== 'number';
408
+ })) {
409
+ return false;
410
+ }
411
+ var cellsInFirstRow = (0, _utils2.getCellsInRow)(Math.min.apply(Math, (0, _toConsumableArray2.default)(rowIndexes)))(state.tr.selection);
412
+ if (!cellsInFirstRow || cellsInFirstRow.length === 0) {
413
+ return false;
414
+ }
415
+ var targetCellPosition = cellsInFirstRow[0].pos;
416
+ return {
417
+ type: 'SET_TARGET_CELL_POSITION',
418
+ data: {
419
+ targetCellPosition: targetCellPosition
420
+ }
421
+ };
422
+ }, function (tr) {
423
+ return (0, _utils2.selectRows)(rowIndexes)(tr).setMeta('addToHistory', false);
424
+ });
425
+ };
366
426
  var showInsertColumnButton = exports.showInsertColumnButton = function showInsertColumnButton(columnIndex) {
367
427
  return (0, _pluginFactory.createCommand)(function (_) {
368
428
  return columnIndex > -1 ? {
@@ -13,7 +13,6 @@ var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
13
13
  var _utils = require("@atlaskit/editor-tables/utils");
14
14
  var _element = require("@atlaskit/pragmatic-drag-and-drop/adapter/element");
15
15
  var _utils2 = require("../../utils");
16
- var _mergedCells = require("../../utils/merged-cells");
17
16
  var _pluginFactory = require("../plugin-factory");
18
17
  var _pluginKey = require("../plugin-key");
19
18
  var _actions = require("./actions");
@@ -182,8 +181,7 @@ var createPlugin = exports.createPlugin = function createPlugin(dispatch, eventD
182
181
  }
183
182
 
184
183
  // If the drop target index contains merged cells then we should not allow the drop to occur.
185
- var hasMergedCells = sourceType === 'table-row' ? _mergedCells.hasMergedCellsInRow : _mergedCells.hasMergedCellsInColumn;
186
- if (hasMergedCells(targetAdjustedIndex)(editorView.state.selection)) {
184
+ if ((0, _utils2.hasMergedCellsInBetween)([targetAdjustedIndex - 1, targetAdjustedIndex], sourceType === 'table-row' ? _consts.DropTargetType.ROW : _consts.DropTargetType.COLUMN)(editorView.state.selection)) {
187
185
  (0, _commands.clearDropTarget)(tr)(editorView.state, editorView.dispatch);
188
186
  return;
189
187
  }
@@ -191,6 +189,7 @@ var createPlugin = exports.createPlugin = function createPlugin(dispatch, eventD
191
189
  sourceIndex = _sourceIndexes[0];
192
190
  requestAnimationFrame(function () {
193
191
  (0, _commands.moveSource)(sourceType, sourceIndex, targetAdjustedIndex + (direction === -1 ? 0 : -1), tr)(editorView.state, editorView.dispatch);
192
+ editorView.focus();
194
193
  });
195
194
  }
196
195
  })
@@ -105,9 +105,6 @@ var FloatingInsertButton = exports.FloatingInsertButton = /*#__PURE__*/function
105
105
  position: pos,
106
106
  docSize: editorView.state.doc.nodeSize,
107
107
  error: error === null || error === void 0 ? void 0 : error.toString()
108
- },
109
- nonPrivacySafeAttributes: {
110
- errorStack: error.stack || undefined
111
108
  }
112
109
  };
113
110
  dispatchAnalyticsEvent(payload);
@@ -56,8 +56,14 @@ var ColumnControls = exports.ColumnControls = function ColumnControls(_ref) {
56
56
  var handleClick = (0, _react.useCallback)(function (event) {
57
57
  var state = editorView.state,
58
58
  dispatch = editorView.dispatch;
59
- (0, _commands.selectColumn)(colIndex, event.shiftKey)(state, dispatch);
60
- }, [colIndex, editorView]);
59
+ var isClickOutsideSelectedCols = selectedColIndexes.length >= 1 && !selectedColIndexes.includes(colIndex);
60
+ if (!selectedColIndexes || selectedColIndexes.length === 0 || isClickOutsideSelectedCols) {
61
+ (0, _commands.selectColumn)(colIndex, event.shiftKey)(state, dispatch);
62
+ }
63
+ if (selectedColIndexes.length > 1 && selectedColIndexes.includes(colIndex) && !event.shiftKey) {
64
+ (0, _commands.selectColumns)(selectedColIndexes)(state, dispatch);
65
+ }
66
+ }, [colIndex, selectedColIndexes, editorView]);
61
67
  var handleMouseOver = (0, _react.useCallback)(function () {
62
68
  var state = editorView.state,
63
69
  dispatch = editorView.dispatch;
@@ -48,6 +48,7 @@ var DragControlsComponent = function DragControlsComponent(_ref) {
48
48
  canDrag = _ref.canDrag,
49
49
  hoverRows = _ref.hoverRows,
50
50
  selectRow = _ref.selectRow,
51
+ selectRows = _ref.selectRows,
51
52
  updateCellHoverLocation = _ref.updateCellHoverLocation;
52
53
  var _useState = (0, _react.useState)(false),
53
54
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
@@ -113,8 +114,14 @@ var DragControlsComponent = function DragControlsComponent(_ref) {
113
114
  hoverRows([rowIndex]);
114
115
  }, [hoverRows, rowIndex]);
115
116
  var handleClick = (0, _react.useCallback)(function (e) {
116
- selectRow(rowIndex, e === null || e === void 0 ? void 0 : e.shiftKey);
117
- }, [rowIndex, selectRow]);
117
+ var isClickOutsideSelectedRows = selectedRowIndexes.length >= 1 && !selectedRowIndexes.includes(rowIndex);
118
+ if (!selectedRowIndexes || selectedRowIndexes.length === 0 || isClickOutsideSelectedRows) {
119
+ selectRow(rowIndex, e.shiftKey);
120
+ }
121
+ if (selectedRowIndexes.length > 1 && selectedRowIndexes.includes(rowIndex) && !e.shiftKey) {
122
+ selectRows(selectedRowIndexes);
123
+ }
124
+ }, [rowIndex, selectRow, selectRows, selectedRowIndexes]);
118
125
  var generateHandleByType = function generateHandleByType(type) {
119
126
  if (!hoveredCell) {
120
127
  return null;
@@ -45,6 +45,16 @@ var TableFloatingControls = exports.default = /*#__PURE__*/function (_Component)
45
45
  }
46
46
  (0, _commands.selectRow)(row, expand)(state, dispatch);
47
47
  });
48
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "selectRows", function (rowIndexes) {
49
+ var editorView = _this.props.editorView;
50
+ var state = editorView.state,
51
+ dispatch = editorView.dispatch;
52
+ // fix for issue ED-4665
53
+ if (_utils.browser.ie_version === 11) {
54
+ editorView.dom.blur();
55
+ }
56
+ (0, _commands.selectRows)(rowIndexes)(state, dispatch);
57
+ });
48
58
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "hoverRows", function (rows, danger) {
49
59
  var _this$props$editorVie = _this.props.editorView,
50
60
  state = _this$props$editorVie.state,
@@ -208,6 +218,7 @@ var TableFloatingControls = exports.default = /*#__PURE__*/function (_Component)
208
218
  tableWidth: this.state.tableWrapperWidth,
209
219
  hoverRows: this.hoverRows,
210
220
  selectRow: this.selectRow,
221
+ selectRows: this.selectRows,
211
222
  updateCellHoverLocation: this.updateCellHoverLocation,
212
223
  canDrag: canDrag
213
224
  })) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_CornerControls.CornerControls, {
@@ -213,6 +213,12 @@ Object.defineProperty(exports, "getTableWidth", {
213
213
  return _nodes.getTableWidth;
214
214
  }
215
215
  });
216
+ Object.defineProperty(exports, "hasMergedCellsInBetween", {
217
+ enumerable: true,
218
+ get: function get() {
219
+ return _mergedCells.hasMergedCellsInBetween;
220
+ }
221
+ });
216
222
  Object.defineProperty(exports, "hasMergedCellsInColumn", {
217
223
  enumerable: true,
218
224
  get: function get() {
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
- exports.hasMergedCellsInRow = exports.hasMergedCellsInColumn = void 0;
7
+ exports.hasMergedCellsInRow = exports.hasMergedCellsInColumn = exports.hasMergedCellsInBetween = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
7
9
  var _editorTables = require("@atlaskit/editor-tables");
8
10
  var hasMergedCells = function hasMergedCells(indexes, normalizeRect) {
9
11
  return function (selection) {
@@ -63,4 +65,76 @@ var hasMergedCellsInRow = exports.hasMergedCellsInRow = function hasMergedCellsI
63
65
  bottom: y === index ? y + 1 : y
64
66
  };
65
67
  });
68
+ };
69
+ var getRect = function getRect(index, type, map) {
70
+ if (type === 'column') {
71
+ var x = Math.max(Math.min(index, map.width - 1), 0); // clamped index
72
+ return {
73
+ left: x,
74
+ right: x === index ? x + 1 : x,
75
+ top: 0,
76
+ bottom: map.height
77
+ };
78
+ } else {
79
+ var y = Math.max(Math.min(index, map.height - 1), 0); // clamped index
80
+ return {
81
+ left: 0,
82
+ right: map.width,
83
+ top: y,
84
+ bottom: y === index ? y + 1 : y
85
+ };
86
+ }
87
+ };
88
+ var hasMergedCellsInBetween = exports.hasMergedCellsInBetween = function hasMergedCellsInBetween(indexes, type) {
89
+ return function (selection) {
90
+ var table = (0, _editorTables.findTable)(selection);
91
+ if (!table) {
92
+ return false;
93
+ }
94
+ var map = _editorTables.TableMap.get(table.node);
95
+ var cellPositions = new Set();
96
+ var mergedCells = new Set();
97
+ map.map.forEach(function (value) {
98
+ if (cellPositions.has(value)) {
99
+ mergedCells.add(value);
100
+ } else {
101
+ cellPositions.add(value);
102
+ }
103
+ });
104
+ if (!mergedCells.size) {
105
+ return false;
106
+ }
107
+ var getMergedCellsInRect = function getMergedCellsInRect(index, type) {
108
+ var rect = getRect(index, type, map);
109
+ var isValidRectangle = rect.left < rect.right && rect.top < rect.bottom;
110
+ if (!isValidRectangle) {
111
+ return [];
112
+ }
113
+ var cells = map.cellsInRect(rect);
114
+ var allCellsInRect = [];
115
+ if (type === 'column') {
116
+ allCellsInRect = map.map.filter(function (_, key) {
117
+ return key % map.width === index;
118
+ });
119
+ } else {
120
+ allCellsInRect = map.map.filter(function (_, key) {
121
+ return Math.floor(key / map.width) === index;
122
+ });
123
+ }
124
+ var mergedCell = allCellsInRect.filter(function (nodePos) {
125
+ return !cells.includes(nodePos) // cell exists in Rect but not show in the map.cellsInRect list => merged cell
126
+ ? true : mergedCells.has(nodePos); // cell includes in mergedCells => merged cell
127
+ });
128
+
129
+ return (0, _toConsumableArray2.default)(new Set(mergedCell));
130
+ };
131
+ var mergedCellsInRectArr = indexes.map(function (index) {
132
+ return getMergedCellsInRect(index, type);
133
+ });
134
+
135
+ // Currently only support 2 indexes, but we can extend this to support more indexes in the future.
136
+ return mergedCellsInRectArr[0].some(function (cell) {
137
+ return mergedCellsInRectArr[1].includes(cell);
138
+ });
139
+ };
66
140
  };
@@ -2,7 +2,7 @@ export { hoverColumns, hoverRows, hoverTable, hoverCell, hoverMergedCells, clear
2
2
  export { insertColumn, insertRow, createTable } from './insert';
3
3
  export { getNextLayout, toggleContextualMenu, toggleHeaderColumn, toggleHeaderRow, toggleNumberColumn, toggleTableLayout } from './toggle';
4
4
  export { clearMultipleCells } from './clear';
5
- export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectRow, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations } from './misc';
5
+ export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectColumns, selectRow, selectRows, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations } from './misc';
6
6
  export { sortByColumn } from './sort';
7
7
  export { goToNextCell } from './go-to-next-cell';
8
8
  export { removeDescendantNodes } from './referentiality';
@@ -2,7 +2,7 @@ import { closestElement, isParagraph, isTextSelection, mapSlice } from '@atlaski
2
2
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
3
3
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
4
4
  import { TableMap } from '@atlaskit/editor-tables/table-map';
5
- import { findCellClosestToPos, findTable, getCellsInColumn, getCellsInRow, getSelectionRect, isSelectionType, isTableSelected, removeTable, selectColumn as selectColumnTransform, selectionCell, selectRow as selectRowTransform, setCellAttrs } from '@atlaskit/editor-tables/utils';
5
+ import { findCellClosestToPos, findTable, getCellsInColumn, getCellsInRow, getSelectionRect, isSelectionType, isTableSelected, removeTable, selectColumns as selectColumnsTransform, selectColumn as selectColumnTransform, selectionCell, selectRows as selectRowsTransform, selectRow as selectRowTransform, setCellAttrs } from '@atlaskit/editor-tables/utils';
6
6
  import { getDecorations } from '../pm-plugins/decorations/plugin';
7
7
  import { buildColumnResizingDecorations, clearColumnResizingDecorations } from '../pm-plugins/decorations/utils';
8
8
  import { createCommand, getPluginState } from '../pm-plugins/plugin-factory';
@@ -350,6 +350,31 @@ export const selectColumn = (column, expand) => createCommand(state => {
350
350
  }
351
351
  };
352
352
  }, tr => selectColumnTransform(column, expand)(tr).setMeta('addToHistory', false));
353
+ export const selectColumns = columnIndexes => createCommand(state => {
354
+ if (!columnIndexes) {
355
+ return false;
356
+ }
357
+ const cells = columnIndexes.map(column => getCellsInColumn(column)(state.tr.selection)).flat();
358
+ if (!cells || !cells.length || cells.some(cell => cell && typeof cell.pos !== 'number')) {
359
+ return false;
360
+ }
361
+ const decorations = createColumnSelectedDecoration(selectColumnsTransform(columnIndexes)(state.tr));
362
+ const decorationSet = updatePluginStateDecorations(state, decorations, TableDecorations.COLUMN_SELECTED);
363
+ const cellsInFirstColumn = getCellsInColumn(Math.min(...columnIndexes))(state.tr.selection);
364
+ if (!cellsInFirstColumn || cellsInFirstColumn.length === 0) {
365
+ return false;
366
+ }
367
+ const targetCellPosition = cellsInFirstColumn[0].pos;
368
+ return {
369
+ type: 'SELECT_COLUMN',
370
+ data: {
371
+ targetCellPosition,
372
+ decorationSet
373
+ }
374
+ };
375
+ }, tr => {
376
+ return selectColumnsTransform(columnIndexes)(tr).setMeta('addToHistory', false);
377
+ });
353
378
  export const selectRow = (row, expand) => createCommand(state => {
354
379
  let targetCellPosition;
355
380
  const cells = getCellsInRow(row)(state.tr.selection);
@@ -363,6 +388,26 @@ export const selectRow = (row, expand) => createCommand(state => {
363
388
  }
364
389
  };
365
390
  }, tr => selectRowTransform(row, expand)(tr).setMeta('addToHistory', false));
391
+ export const selectRows = rowIndexes => createCommand(state => {
392
+ if (rowIndexes.length === 0) {
393
+ return false;
394
+ }
395
+ const cells = rowIndexes.map(row => getCellsInRow(row)(state.tr.selection)).flat();
396
+ if (!cells || !cells.length || cells.some(cell => cell && typeof cell.pos !== 'number')) {
397
+ return false;
398
+ }
399
+ const cellsInFirstRow = getCellsInRow(Math.min(...rowIndexes))(state.tr.selection);
400
+ if (!cellsInFirstRow || cellsInFirstRow.length === 0) {
401
+ return false;
402
+ }
403
+ const targetCellPosition = cellsInFirstRow[0].pos;
404
+ return {
405
+ type: 'SET_TARGET_CELL_POSITION',
406
+ data: {
407
+ targetCellPosition
408
+ }
409
+ };
410
+ }, tr => selectRowsTransform(rowIndexes)(tr).setMeta('addToHistory', false));
366
411
  export const showInsertColumnButton = columnIndex => createCommand(_ => columnIndex > -1 ? {
367
412
  type: 'SHOW_INSERT_COLUMN_BUTTON',
368
413
  data: {
@@ -3,8 +3,7 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
3
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
4
4
  import { getCellsInRow } from '@atlaskit/editor-tables/utils';
5
5
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
6
- import { findNearestCellIndexToPoint } from '../../utils';
7
- import { hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils/merged-cells';
6
+ import { findNearestCellIndexToPoint, hasMergedCellsInBetween } from '../../utils';
8
7
  import { getPluginState as getTablePluginState } from '../plugin-factory';
9
8
  import { pluginKey as tablePluginKey } from '../plugin-key';
10
9
  import { DragAndDropActionType } from './actions';
@@ -184,14 +183,14 @@ export const createPlugin = (dispatch, eventDispatcher) => {
184
183
  }
185
184
 
186
185
  // If the drop target index contains merged cells then we should not allow the drop to occur.
187
- const hasMergedCells = sourceType === 'table-row' ? hasMergedCellsInRow : hasMergedCellsInColumn;
188
- if (hasMergedCells(targetAdjustedIndex)(editorView.state.selection)) {
186
+ if (hasMergedCellsInBetween([targetAdjustedIndex - 1, targetAdjustedIndex], sourceType === 'table-row' ? DropTargetType.ROW : DropTargetType.COLUMN)(editorView.state.selection)) {
189
187
  clearDropTarget(tr)(editorView.state, editorView.dispatch);
190
188
  return;
191
189
  }
192
190
  const [sourceIndex] = sourceIndexes;
193
191
  requestAnimationFrame(() => {
194
192
  moveSource(sourceType, sourceIndex, targetAdjustedIndex + (direction === -1 ? 0 : -1), tr)(editorView.state, editorView.dispatch);
193
+ editorView.focus();
195
194
  });
196
195
  }
197
196
  })
@@ -85,9 +85,6 @@ export class FloatingInsertButton extends React.Component {
85
85
  position: pos,
86
86
  docSize: editorView.state.doc.nodeSize,
87
87
  error: error === null || error === void 0 ? void 0 : error.toString()
88
- },
89
- nonPrivacySafeAttributes: {
90
- errorStack: error.stack || undefined
91
88
  }
92
89
  };
93
90
  dispatchAnalyticsEvent(payload);
@@ -4,7 +4,7 @@ import React, { useCallback, useMemo } from 'react';
4
4
  import { tableCellMinWidth } from '@atlaskit/editor-common/styles';
5
5
  import { CellSelection } from '@atlaskit/editor-tables';
6
6
  import { getSelectionRect } from '@atlaskit/editor-tables/utils';
7
- import { clearHoverSelection, hoverCell, hoverColumns, selectColumn } from '../../../commands';
7
+ import { clearHoverSelection, hoverCell, hoverColumns, selectColumn, selectColumns } from '../../../commands';
8
8
  import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
9
9
  import { TableCssClassName as ClassName } from '../../../types';
10
10
  import { getRowsParams, getSelectedColumnIndexes } from '../../../utils';
@@ -48,8 +48,14 @@ export const ColumnControls = ({
48
48
  state,
49
49
  dispatch
50
50
  } = editorView;
51
- selectColumn(colIndex, event.shiftKey)(state, dispatch);
52
- }, [colIndex, editorView]);
51
+ const isClickOutsideSelectedCols = selectedColIndexes.length >= 1 && !selectedColIndexes.includes(colIndex);
52
+ if (!selectedColIndexes || selectedColIndexes.length === 0 || isClickOutsideSelectedCols) {
53
+ selectColumn(colIndex, event.shiftKey)(state, dispatch);
54
+ }
55
+ if (selectedColIndexes.length > 1 && selectedColIndexes.includes(colIndex) && !event.shiftKey) {
56
+ selectColumns(selectedColIndexes)(state, dispatch);
57
+ }
58
+ }, [colIndex, selectedColIndexes, editorView]);
53
59
  const handleMouseOver = useCallback(() => {
54
60
  const {
55
61
  state,
@@ -36,6 +36,7 @@ const DragControlsComponent = ({
36
36
  canDrag,
37
37
  hoverRows,
38
38
  selectRow,
39
+ selectRows,
39
40
  updateCellHoverLocation
40
41
  }) => {
41
42
  var _tableNode$attrs$loca, _tableNode$attrs;
@@ -103,8 +104,14 @@ const DragControlsComponent = ({
103
104
  hoverRows([rowIndex]);
104
105
  }, [hoverRows, rowIndex]);
105
106
  const handleClick = useCallback(e => {
106
- selectRow(rowIndex, e === null || e === void 0 ? void 0 : e.shiftKey);
107
- }, [rowIndex, selectRow]);
107
+ const isClickOutsideSelectedRows = selectedRowIndexes.length >= 1 && !selectedRowIndexes.includes(rowIndex);
108
+ if (!selectedRowIndexes || selectedRowIndexes.length === 0 || isClickOutsideSelectedRows) {
109
+ selectRow(rowIndex, e.shiftKey);
110
+ }
111
+ if (selectedRowIndexes.length > 1 && selectedRowIndexes.includes(rowIndex) && !e.shiftKey) {
112
+ selectRows(selectedRowIndexes);
113
+ }
114
+ }, [rowIndex, selectRow, selectRows, selectedRowIndexes]);
108
115
  const generateHandleByType = type => {
109
116
  if (!hoveredCell) {
110
117
  return null;
@@ -1,7 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React, { Component } from 'react';
3
3
  import { browser } from '@atlaskit/editor-common/utils';
4
- import { hoverCell, hoverRows, selectRow } from '../../commands';
4
+ import { hoverCell, hoverRows, selectRow, selectRows } from '../../commands';
5
5
  import { TableCssClassName as ClassName } from '../../types';
6
6
  import { isSelectionUpdated } from '../../utils';
7
7
  import { CornerControls, DragCornerControls } from './CornerControls';
@@ -24,6 +24,20 @@ export default class TableFloatingControls extends Component {
24
24
  }
25
25
  selectRow(row, expand)(state, dispatch);
26
26
  });
27
+ _defineProperty(this, "selectRows", rowIndexes => {
28
+ const {
29
+ editorView
30
+ } = this.props;
31
+ const {
32
+ state,
33
+ dispatch
34
+ } = editorView;
35
+ // fix for issue ED-4665
36
+ if (browser.ie_version === 11) {
37
+ editorView.dom.blur();
38
+ }
39
+ selectRows(rowIndexes)(state, dispatch);
40
+ });
27
41
  _defineProperty(this, "hoverRows", (rows, danger) => {
28
42
  const {
29
43
  state,
@@ -167,6 +181,7 @@ export default class TableFloatingControls extends Component {
167
181
  tableWidth: this.state.tableWrapperWidth,
168
182
  hoverRows: this.hoverRows,
169
183
  selectRow: this.selectRow,
184
+ selectRows: this.selectRows,
170
185
  updateCellHoverLocation: this.updateCellHoverLocation,
171
186
  canDrag: canDrag
172
187
  })) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CornerControls, {
@@ -8,4 +8,4 @@ export { getRowHeights, isRowDeleteButtonVisible, getRowDeleteButtonParams, getR
8
8
  export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
9
9
  export { getMergedCellsPositions } from './table';
10
10
  export { updatePluginStateDecorations } from './update-plugin-state-decorations';
11
- export { hasMergedCellsInColumn, hasMergedCellsInRow } from './merged-cells';
11
+ export { hasMergedCellsInColumn, hasMergedCellsInRow, hasMergedCellsInBetween } from './merged-cells';
@@ -45,4 +45,66 @@ export const hasMergedCellsInRow = rowIndexes => hasMergedCells(rowIndexes, (ind
45
45
  top: y,
46
46
  bottom: y === index ? y + 1 : y
47
47
  };
48
- });
48
+ });
49
+ const getRect = (index, type, map) => {
50
+ if (type === 'column') {
51
+ const x = Math.max(Math.min(index, map.width - 1), 0); // clamped index
52
+ return {
53
+ left: x,
54
+ right: x === index ? x + 1 : x,
55
+ top: 0,
56
+ bottom: map.height
57
+ };
58
+ } else {
59
+ const y = Math.max(Math.min(index, map.height - 1), 0); // clamped index
60
+ return {
61
+ left: 0,
62
+ right: map.width,
63
+ top: y,
64
+ bottom: y === index ? y + 1 : y
65
+ };
66
+ }
67
+ };
68
+ export const hasMergedCellsInBetween = (indexes, type) => selection => {
69
+ const table = findTable(selection);
70
+ if (!table) {
71
+ return false;
72
+ }
73
+ const map = TableMap.get(table.node);
74
+ const cellPositions = new Set();
75
+ const mergedCells = new Set();
76
+ map.map.forEach(value => {
77
+ if (cellPositions.has(value)) {
78
+ mergedCells.add(value);
79
+ } else {
80
+ cellPositions.add(value);
81
+ }
82
+ });
83
+ if (!mergedCells.size) {
84
+ return false;
85
+ }
86
+ const getMergedCellsInRect = (index, type) => {
87
+ const rect = getRect(index, type, map);
88
+ const isValidRectangle = rect.left < rect.right && rect.top < rect.bottom;
89
+ if (!isValidRectangle) {
90
+ return [];
91
+ }
92
+ const cells = map.cellsInRect(rect);
93
+ let allCellsInRect = [];
94
+ if (type === 'column') {
95
+ allCellsInRect = map.map.filter((_, key) => key % map.width === index);
96
+ } else {
97
+ allCellsInRect = map.map.filter((_, key) => Math.floor(key / map.width) === index);
98
+ }
99
+ const mergedCell = allCellsInRect.filter(nodePos => {
100
+ return !cells.includes(nodePos) // cell exists in Rect but not show in the map.cellsInRect list => merged cell
101
+ ? true : mergedCells.has(nodePos); // cell includes in mergedCells => merged cell
102
+ });
103
+
104
+ return [...new Set(mergedCell)];
105
+ };
106
+ const mergedCellsInRectArr = indexes.map(index => getMergedCellsInRect(index, type));
107
+
108
+ // Currently only support 2 indexes, but we can extend this to support more indexes in the future.
109
+ return mergedCellsInRectArr[0].some(cell => mergedCellsInRectArr[1].includes(cell));
110
+ };
@@ -2,7 +2,7 @@ export { hoverColumns, hoverRows, hoverTable, hoverCell, hoverMergedCells, clear
2
2
  export { insertColumn, insertRow, createTable } from './insert';
3
3
  export { getNextLayout, toggleContextualMenu, toggleHeaderColumn, toggleHeaderRow, toggleNumberColumn, toggleTableLayout } from './toggle';
4
4
  export { clearMultipleCells } from './clear';
5
- export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectRow, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations } from './misc';
5
+ export { autoSizeTable, convertFirstRowToHeader, deleteTable, hideInsertColumnOrRowButton, moveCursorBackward, selectColumn, selectColumns, selectRow, selectRows, setCellAttr, setEditorFocus, setMultipleCellAttrs, setTableRef, showInsertColumnButton, showInsertRowButton, transformSliceToAddTableHeaders, triggerUnlessTableHeader, addBoldInEmptyHeaderCells, addResizeHandleDecorations } from './misc';
6
6
  export { sortByColumn } from './sort';
7
7
  export { goToNextCell } from './go-to-next-cell';
8
8
  export { removeDescendantNodes } from './referentiality';