@atlaskit/editor-plugin-table 24.2.2 → 24.2.4

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 (59) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/pm-plugins/commands/active-table-menu.js +14 -5
  3. package/dist/cjs/pm-plugins/drag-and-drop/plugin.js +3 -1
  4. package/dist/cjs/pm-plugins/main.js +3 -1
  5. package/dist/cjs/pm-plugins/utils/column-controls.js +119 -2
  6. package/dist/cjs/pm-plugins/utils/dom.js +23 -1
  7. package/dist/cjs/pm-plugins/utils/row-controls.js +43 -1
  8. package/dist/cjs/pm-plugins/utils/selection.js +74 -1
  9. package/dist/cjs/ui/DragHandle/index.js +46 -4
  10. package/dist/cjs/ui/FloatingInsertButton/getPopupOptions.js +19 -5
  11. package/dist/cjs/ui/FloatingInsertButton/index.js +37 -3
  12. package/dist/cjs/ui/FloatingTableMenu/index.js +4 -7
  13. package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +26 -15
  14. package/dist/cjs/ui/TableFloatingColumnControls/index.js +1 -1
  15. package/dist/cjs/ui/TableFloatingControls/RowControls/DragControls.js +29 -12
  16. package/dist/cjs/ui/common-styles.js +6 -1
  17. package/dist/cjs/ui/event-handlers.js +61 -8
  18. package/dist/es2019/pm-plugins/commands/active-table-menu.js +14 -5
  19. package/dist/es2019/pm-plugins/drag-and-drop/plugin.js +3 -1
  20. package/dist/es2019/pm-plugins/main.js +1 -1
  21. package/dist/es2019/pm-plugins/utils/column-controls.js +114 -2
  22. package/dist/es2019/pm-plugins/utils/dom.js +20 -0
  23. package/dist/es2019/pm-plugins/utils/row-controls.js +42 -0
  24. package/dist/es2019/pm-plugins/utils/selection.js +73 -0
  25. package/dist/es2019/ui/DragHandle/index.js +47 -4
  26. package/dist/es2019/ui/FloatingInsertButton/getPopupOptions.js +24 -5
  27. package/dist/es2019/ui/FloatingInsertButton/index.js +35 -3
  28. package/dist/es2019/ui/FloatingTableMenu/index.js +4 -7
  29. package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +27 -16
  30. package/dist/es2019/ui/TableFloatingColumnControls/index.js +2 -2
  31. package/dist/es2019/ui/TableFloatingControls/RowControls/DragControls.js +30 -12
  32. package/dist/es2019/ui/common-styles.js +26 -1
  33. package/dist/es2019/ui/event-handlers.js +61 -8
  34. package/dist/esm/pm-plugins/commands/active-table-menu.js +14 -5
  35. package/dist/esm/pm-plugins/drag-and-drop/plugin.js +3 -1
  36. package/dist/esm/pm-plugins/main.js +3 -1
  37. package/dist/esm/pm-plugins/utils/column-controls.js +118 -1
  38. package/dist/esm/pm-plugins/utils/dom.js +22 -0
  39. package/dist/esm/pm-plugins/utils/row-controls.js +42 -0
  40. package/dist/esm/pm-plugins/utils/selection.js +73 -0
  41. package/dist/esm/ui/DragHandle/index.js +47 -5
  42. package/dist/esm/ui/FloatingInsertButton/getPopupOptions.js +19 -5
  43. package/dist/esm/ui/FloatingInsertButton/index.js +37 -3
  44. package/dist/esm/ui/FloatingTableMenu/index.js +4 -7
  45. package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +28 -17
  46. package/dist/esm/ui/TableFloatingColumnControls/index.js +2 -2
  47. package/dist/esm/ui/TableFloatingControls/RowControls/DragControls.js +31 -14
  48. package/dist/esm/ui/common-styles.js +7 -2
  49. package/dist/esm/ui/event-handlers.js +63 -10
  50. package/dist/types/pm-plugins/commands/active-table-menu.d.ts +3 -1
  51. package/dist/types/pm-plugins/utils/column-controls.d.ts +35 -1
  52. package/dist/types/pm-plugins/utils/dom.d.ts +11 -0
  53. package/dist/types/pm-plugins/utils/row-controls.d.ts +16 -0
  54. package/dist/types/pm-plugins/utils/selection.d.ts +20 -0
  55. package/dist/types/ui/DragHandle/index.d.ts +3 -2
  56. package/dist/types/ui/FloatingInsertButton/getPopupOptions.d.ts +1 -1
  57. package/dist/types/ui/FloatingInsertButton/index.d.ts +1 -0
  58. package/dist/types/ui/event-handlers.d.ts +1 -1
  59. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @atlaskit/editor-plugin-table
2
2
 
3
+ ## 24.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`2a5949df6125f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2a5949df6125f) -
8
+ Under platform_editor_table_menu_updates, keep the selection toolbar suppressed after the
9
+ row/column drag menu closes while that drag-handle selection persists; any other selection
10
+ re-enables the toolbar.
11
+ - Updated dependencies
12
+
13
+ ## 24.2.3
14
+
15
+ ### Patch Changes
16
+
17
+ - [`bd776b48c8623`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bd776b48c8623) -
18
+ [ux] Fix table drag-handle menu edge cases for merged cells in the first row/column behind the
19
+ `platform_editor_table_menu_updates` experiment.
20
+ - [`e850980f5a66f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e850980f5a66f) -
21
+ [EDITOR-6790] Block-controls drag-handle wrapper's background is removed and instead set
22
+ on`::before` on `.pm-table-container.pm-table-sticky` to keep masking the row insert dots when
23
+ legacy sticky header is activated while also not overlapping the column insert button.
24
+ - Updated dependencies
25
+
3
26
  ## 24.2.2
4
27
 
5
28
  ### Patch Changes
@@ -5,14 +5,21 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.toggleActiveTableMenu = exports.closeActiveTableMenu = void 0;
7
7
  var _pluginKey = require("../plugin-key");
8
+ var _selection = require("../utils/selection");
8
9
  var applyMenuUserIntent = function applyMenuUserIntent(tr, api, nextActiveTableMenu) {
9
- var _api$userIntent;
10
- var isRowOrColumnMenuOpen = nextActiveTableMenu.type === 'row' || nextActiveTableMenu.type === 'column';
11
- api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || _api$userIntent.commands.setCurrentUserIntent(isRowOrColumnMenuOpen ? 'tableDragMenuPopupOpen' : 'default')({
10
+ var _api$userIntent2;
11
+ if (nextActiveTableMenu.type === 'row' || nextActiveTableMenu.type === 'column') {
12
+ var _api$userIntent;
13
+ api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || _api$userIntent.commands.setCurrentUserIntent('tableDragMenuPopupOpen')({
14
+ tr: tr
15
+ });
16
+ return;
17
+ }
18
+ api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || _api$userIntent2.commands.setCurrentUserIntent((0, _selection.isFullRowOrColumnSelected)(tr.selection) ? 'dragHandleSelected' : 'default')({
12
19
  tr: tr
13
20
  });
14
21
  };
15
- var closeActiveTableMenu = exports.closeActiveTableMenu = function closeActiveTableMenu(api) {
22
+ var closeActiveTableMenu = exports.closeActiveTableMenu = function closeActiveTableMenu(api, options) {
16
23
  return function (_ref) {
17
24
  var tr = _ref.tr;
18
25
  var nextActiveTableMenu = {
@@ -24,7 +31,9 @@ var closeActiveTableMenu = exports.closeActiveTableMenu = function closeActiveTa
24
31
  activeTableMenu: nextActiveTableMenu
25
32
  }
26
33
  });
27
- applyMenuUserIntent(tr, api, nextActiveTableMenu);
34
+ if (!(options !== null && options !== void 0 && options.skipUserIntent)) {
35
+ applyMenuUserIntent(tr, api, nextActiveTableMenu);
36
+ }
28
37
  if (!tr.docChanged) {
29
38
  tr.setMeta('addToHistory', false);
30
39
  }
@@ -96,7 +96,9 @@ var destroyFn = function destroyFn(editorView, editorAnalyticsAPI, isTableScalin
96
96
  api === null || api === void 0 || api.core.actions.execute(function (_ref7) {
97
97
  var _api$userIntent;
98
98
  var tr = _ref7.tr;
99
- (0, _activeTableMenu.closeActiveTableMenu)(api)({
99
+ (0, _activeTableMenu.closeActiveTableMenu)(api, {
100
+ skipUserIntent: true
101
+ })({
100
102
  tr: tr
101
103
  });
102
104
  api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || _api$userIntent.commands.setCurrentUserIntent('dragging')({
@@ -348,7 +348,9 @@ var createPlugin = exports.createPlugin = function createPlugin(dispatchAnalytic
348
348
  handleDOMEvents: {
349
349
  focus: _eventHandlers.handleFocus,
350
350
  blur: _eventHandlers.handleBlur,
351
- mousedown: (0, _eventHandlers.withCellTracking)(_eventHandlers.handleMouseDown),
351
+ mousedown: (0, _eventHandlers.withCellTracking)(function (view, event) {
352
+ return (0, _eventHandlers.handleMouseDown)(view, event, pluginInjectionApi);
353
+ }),
352
354
  mouseleave: _eventHandlers.handleMouseLeave,
353
355
  mousemove: (0, _eventHandlers.whenTableInFocus)((0, _eventHandlers.handleMouseMove)(nodeViewPortalProviderAPI), pluginInjectionApi),
354
356
  mouseenter: _eventHandlers.handleMouseEnter,
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.getColumnsWidths = exports.getColumnIndexMappedToColumnIndexInFirstRow = exports.getColumnDeleteButtonParams = exports.convertHTMLCellIndexToColumnIndex = exports.colWidthsForRow = void 0;
7
+ exports.getProportionalColumnWidths = exports.getColumnsWidthsWithMergedCells = exports.getColumnsWidths = exports.getColumnIndexMappedToColumnIndexInFirstRow = exports.getColumnIndexByMousePosition = exports.getColumnDeleteButtonParams = exports.convertHTMLCellIndexToColumnIndex = exports.colWidthsForRow = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
9
  var _utils = require("@atlaskit/editor-common/utils");
10
10
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
@@ -40,6 +40,73 @@ var getColumnsWidths = exports.getColumnsWidths = function getColumnsWidths(view
40
40
  }
41
41
  return widths;
42
42
  };
43
+
44
+ /**
45
+ * Splits a merged cell's rendered width by `colwidth` ratios, falling back to an even split when
46
+ * usable ratios are unavailable.
47
+ */
48
+ var getProportionalColumnWidths = exports.getProportionalColumnWidths = function getProportionalColumnWidths(totalWidth, columnCount, ratios) {
49
+ var evenSplit = function evenSplit() {
50
+ return new Array(columnCount).fill(totalWidth / columnCount);
51
+ };
52
+ if (!ratios || ratios.length !== columnCount) {
53
+ return evenSplit();
54
+ }
55
+ var total = ratios.reduce(function (sum, ratio) {
56
+ return sum + (ratio > 0 ? ratio : 0);
57
+ }, 0);
58
+ if (total <= 0) {
59
+ return evenSplit();
60
+ }
61
+ return ratios.map(function (ratio) {
62
+ return totalWidth * ((ratio > 0 ? ratio : 0) / total);
63
+ });
64
+ };
65
+
66
+ /**
67
+ * Like `getColumnsWidths`, but fills every visual column under a first-row `colspan` so column
68
+ * controls can render one grid track per column.
69
+ */
70
+ var getColumnsWidthsWithMergedCells = exports.getColumnsWidthsWithMergedCells = function getColumnsWidthsWithMergedCells(view) {
71
+ var selection = view.state.selection;
72
+ var table = (0, _utils3.findTable)(selection);
73
+ if (!table) {
74
+ return [];
75
+ }
76
+ var map = _tableMap.TableMap.get(table.node);
77
+ var domAtPos = view.domAtPos.bind(view);
78
+ var widths = Array.from({
79
+ length: map.width
80
+ });
81
+ for (var i = 0; i < map.width; i++) {
82
+ var _node$attrs$colspan;
83
+ if (map.isCellMergedTopLeft(0, i)) {
84
+ continue;
85
+ }
86
+
87
+ // Ignored via go/ees005
88
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
89
+ var node = table.node.nodeAt(map.map[i]);
90
+ var pos = map.map[i] + table.start;
91
+ // Ignored via go/ees005
92
+ // eslint-disable-next-line @atlaskit/editor/no-as-casting
93
+ var cellRef = (0, _utils2.findDomRefAtPos)(pos, domAtPos);
94
+ var rect = cellRef.getBoundingClientRect();
95
+ var measuredWidth = (rect ? rect.width : cellRef.offsetWidth) + 1;
96
+ var colspan = (_node$attrs$colspan = node.attrs.colspan) !== null && _node$attrs$colspan !== void 0 ? _node$attrs$colspan : 1;
97
+ if (colspan <= 1) {
98
+ widths[i] = measuredWidth;
99
+ continue;
100
+ }
101
+ var colwidth = Array.isArray(node.attrs.colwidth) ? node.attrs.colwidth : undefined;
102
+ var perColumnWidths = getProportionalColumnWidths(measuredWidth, colspan, colwidth);
103
+ for (var span = 0; span < colspan && i + span < map.width; span++) {
104
+ widths[i + span] = perColumnWidths[span];
105
+ }
106
+ i += colspan - 1;
107
+ }
108
+ return widths;
109
+ };
43
110
  var getColumnDeleteButtonParams = exports.getColumnDeleteButtonParams = function getColumnDeleteButtonParams(columnsWidths, selection) {
44
111
  var rect = (0, _utils3.getSelectionRect)(selection);
45
112
  if (!rect) {
@@ -122,6 +189,9 @@ var getRelativeDomCellWidths = function getRelativeDomCellWidths(_ref) {
122
189
  });
123
190
  };
124
191
  var colWidthsForRow = exports.colWidthsForRow = function colWidthsForRow(tr) {
192
+ var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
193
+ _ref2$useColwidthRati = _ref2.useColwidthRatios,
194
+ useColwidthRatios = _ref2$useColwidthRati === void 0 ? false : _ref2$useColwidthRati;
125
195
  // get the colspans
126
196
  var rowColSpans = (0, _utils.maphElem)(tr, function (cell) {
127
197
  return Number(cell.getAttribute('colspan') || 1 /* default to span of 1 */);
@@ -149,7 +219,7 @@ var colWidthsForRow = exports.colWidthsForRow = function colWidthsForRow(tr) {
149
219
  // reverse engineer cell widths from table widths
150
220
  var domBasedCellWidths = [];
151
221
  cellInfos.map(function (cell) {
152
- domBasedCellWidths.push.apply(domBasedCellWidths, (0, _toConsumableArray2.default)(getRelativeDomCellWidths(cell)));
222
+ domBasedCellWidths.push.apply(domBasedCellWidths, (0, _toConsumableArray2.default)(useColwidthRatios ? getRelativeDomCellWidths(cell) : new Array(cell.colspan).fill(cell.width / cell.colspan)));
153
223
  });
154
224
  if (cellInfos.reduce(function (acc, cell) {
155
225
  return acc + cell.width;
@@ -173,6 +243,53 @@ var colWidthsForRow = exports.colWidthsForRow = function colWidthsForRow(tr) {
173
243
  return "".concat(pct, "%");
174
244
  }).join(' ');
175
245
  };
246
+
247
+ /**
248
+ * Returns the visual column index that the mouse pointer is over within a column-spanned
249
+ * cell, by walking the per-column boundaries of the spanned cell and finding the column whose
250
+ * horizontal range contains `mouseEvent.clientX`.
251
+ *
252
+ * `<td>.cellIndex` for a cell with `colspan > 1` only resolves to the first column the cell
253
+ * occupies, so hovering anywhere inside a colspanned first-row cell pins the column drag handle
254
+ * to that first column. This resolver disambiguates which visual column the pointer is actually
255
+ * over so the handle/menu can target a single column.
256
+ *
257
+ * The search is restricted to columns in `[startIndex, endIndex)` (the cell's own span). The
258
+ * spanned cell's bounding rect is read once and split into per-column boundaries using the cell's
259
+ * `data-colwidth` ratios (falling back to an even split for unresized columns) — this keeps the
260
+ * work bounded by the colspan size and avoids measuring the whole table.
261
+ *
262
+ * Returns `undefined` when the mouse is outside the spanned range (so callers can fall back to
263
+ * the converted HTML column index).
264
+ */
265
+ var getColumnIndexByMousePosition = exports.getColumnIndexByMousePosition = function getColumnIndexByMousePosition(cellElement, mouseEvent, columnIndexRange) {
266
+ var _cellElement$dataset$;
267
+ var startIndex = columnIndexRange.startIndex,
268
+ endIndex = columnIndexRange.endIndex;
269
+ var columnCount = endIndex - startIndex;
270
+ if (columnCount <= 0) {
271
+ return undefined;
272
+ }
273
+ var cellRect = cellElement.getBoundingClientRect();
274
+ if (mouseEvent.clientX < cellRect.left || mouseEvent.clientX >= cellRect.right) {
275
+ return undefined;
276
+ }
277
+
278
+ // Read DOM ratios here to avoid resolving the ProseMirror node on this mouse-move path.
279
+ var ratios = (_cellElement$dataset$ = cellElement.dataset.colwidth) === null || _cellElement$dataset$ === void 0 ? void 0 : _cellElement$dataset$.split(',').map(Number).filter(function (value) {
280
+ return !Number.isNaN(value);
281
+ });
282
+ var perColumnWidths = getProportionalColumnWidths(cellRect.width, columnCount, ratios);
283
+ var offsetFromLeft = mouseEvent.clientX - cellRect.left;
284
+ var cumulativeWidth = 0;
285
+ for (var column = 0; column < columnCount; column++) {
286
+ cumulativeWidth += perColumnWidths[column];
287
+ if (offsetFromLeft < cumulativeWidth) {
288
+ return startIndex + column;
289
+ }
290
+ }
291
+ return endIndex - 1;
292
+ };
176
293
  var convertHTMLCellIndexToColumnIndex = exports.convertHTMLCellIndexToColumnIndex = function convertHTMLCellIndexToColumnIndex(htmlColIndex, htmlRowIndex, tableMap) {
177
294
  // Same numbers (positions) in tableMap.map array mean that there are merged cells.
178
295
  // Cells can be merged across columns. So we need to check if the cell on the left and current cell have the same value.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isTableControlsButton = exports.isTableContainerOrWrapper = exports.isRowControlsButton = exports.isResizeHandleDecoration = exports.isInsertRowButton = exports.isDragRowFloatingInsertDot = exports.isDragCornerButton = exports.isDragColumnFloatingInsertDot = exports.isCornerButton = exports.isColumnControlsDecorations = exports.isCell = exports.hasResizeHandler = exports.getTree = exports.getTop = exports.getMousePositionVerticalRelativeByElement = exports.getMousePositionHorizontalRelativeByElement = exports.getColumnOrRowIndex = exports.findNearestCellIndexToPoint = exports.areAllRectsZero = void 0;
6
+ exports.isTableDragHandleButton = exports.isTableControlsButton = exports.isTableContainerOrWrapper = exports.isRowControlsButton = exports.isResizeHandleDecoration = exports.isInsertRowButton = exports.isDragRowFloatingInsertDot = exports.isDragCornerButton = exports.isDragColumnFloatingInsertDot = exports.isCornerButton = exports.isColumnControlsDecorations = exports.isCell = exports.hasResizeHandler = exports.getTree = exports.getTop = exports.getMousePositionVerticalRelativeByElement = exports.getMousePositionHorizontalRelativeByElement = exports.getIndexAttributeSourceElement = exports.getColumnOrRowIndex = exports.findNearestCellIndexToPoint = exports.areAllRectsZero = void 0;
7
7
  var _utils = require("@atlaskit/editor-common/utils");
8
8
  var _types = require("../../types");
9
9
  var isCell = exports.isCell = function isCell(node) {
@@ -18,6 +18,25 @@ var isInsertRowButton = exports.isInsertRowButton = function isInsertRowButton(n
18
18
  var getColumnOrRowIndex = exports.getColumnOrRowIndex = function getColumnOrRowIndex(target) {
19
19
  return [parseInt(target.getAttribute('data-start-index') || '-1', 10), parseInt(target.getAttribute('data-end-index') || '-1', 10)];
20
20
  };
21
+
22
+ /**
23
+ * Returns the element that carries the `data-start-index` / `data-end-index` attributes for a
24
+ * column/row control.
25
+ *
26
+ * The floating insert dot is a child of a wrapper that holds the index attributes, so when the
27
+ * pointer is directly over the dot the attributes are not on the event target. This walks up to
28
+ * the nearest ancestor that has `data-start-index`, falling back to the original element so the
29
+ * behaviour is unchanged when the target already carries the attributes.
30
+ */
31
+ var getIndexAttributeSourceElement = exports.getIndexAttributeSourceElement = function getIndexAttributeSourceElement(target) {
32
+ if (target.hasAttribute('data-start-index')) {
33
+ return target;
34
+ }
35
+ // Ignored via go/ees005
36
+ // eslint-disable-next-line @atlaskit/editor/no-as-casting
37
+ var closestWithIndex = target.closest('[data-start-index]');
38
+ return closestWithIndex !== null && closestWithIndex !== void 0 ? closestWithIndex : target;
39
+ };
21
40
  var isColumnControlsDecorations = exports.isColumnControlsDecorations = function isColumnControlsDecorations(node) {
22
41
  return (0, _utils.containsClassName)(node, _types.TableCssClassName.COLUMN_CONTROLS_DECORATIONS);
23
42
  };
@@ -44,6 +63,9 @@ var isDragColumnFloatingInsertDot = exports.isDragColumnFloatingInsertDot = func
44
63
  var isDragCornerButton = exports.isDragCornerButton = function isDragCornerButton(node) {
45
64
  return (0, _utils.containsClassName)(node, _types.TableCssClassName.DRAG_CORNER_BUTTON) || (0, _utils.containsClassName)(node, _types.TableCssClassName.DRAG_CORNER_BUTTON_INNER);
46
65
  };
66
+ var isTableDragHandleButton = exports.isTableDragHandleButton = function isTableDragHandleButton(target) {
67
+ return target instanceof HTMLElement && Boolean(target.closest(".".concat(_types.TableCssClassName.DRAG_HANDLE_BUTTON_CONTAINER)));
68
+ };
47
69
 
48
70
  /*
49
71
  * This function returns which side of a given element the mouse cursor is,
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.getRowsParams = exports.getRowHeights = exports.getRowDeleteButtonParams = exports.getRowClassNames = exports.copyPreviousRow = void 0;
7
+ exports.getRowsParams = exports.getRowIndexByMousePosition = exports.getRowHeights = exports.getRowDeleteButtonParams = exports.getRowClassNames = exports.copyPreviousRow = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _utils = require("@atlaskit/editor-common/utils");
10
10
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
@@ -85,6 +85,48 @@ var getRowsParams = exports.getRowsParams = function getRowsParams(rowsHeights)
85
85
  }
86
86
  return rows;
87
87
  };
88
+
89
+ /**
90
+ * Returns the visual row index that the mouse pointer is over, by walking the row heights
91
+ * inside `tbody` and finding the row whose vertical range contains `mouseEvent.clientY`.
92
+ *
93
+ * When `rowIndexRange` is provided, the search is restricted to rows in that range (the
94
+ * `endIndex` is exclusive). This is the hot path used on `mousemove` when hovering over a
95
+ * row-spanned cell — restricting the range to `[startIndex, endIndex)` keeps the number
96
+ * of forced layout reads bounded by the row-span size, not the table size.
97
+ *
98
+ * Returns `undefined` when the mouse is above the search range or below it (so callers can
99
+ * fall back to the HTML row index).
100
+ */
101
+ var getRowIndexByMousePosition = exports.getRowIndexByMousePosition = function getRowIndexByMousePosition(tableRef, mouseEvent, rowIndexRange) {
102
+ var _rowIndexRange$startI, _rowIndexRange$endInd;
103
+ var tableBody = tableRef.querySelector('tbody');
104
+ if (!tableBody) {
105
+ return undefined;
106
+ }
107
+ var rows = tableBody.children;
108
+ var startIndex = (_rowIndexRange$startI = rowIndexRange === null || rowIndexRange === void 0 ? void 0 : rowIndexRange.startIndex) !== null && _rowIndexRange$startI !== void 0 ? _rowIndexRange$startI : 0;
109
+ var endIndex = Math.min((_rowIndexRange$endInd = rowIndexRange === null || rowIndexRange === void 0 ? void 0 : rowIndexRange.endIndex) !== null && _rowIndexRange$endInd !== void 0 ? _rowIndexRange$endInd : rows.length, rows.length);
110
+ if (startIndex >= endIndex) {
111
+ return undefined;
112
+ }
113
+ var firstRowRect = rows[startIndex].getBoundingClientRect();
114
+ if (mouseEvent.clientY < firstRowRect.top) {
115
+ return undefined;
116
+ }
117
+ var rowBottom = firstRowRect.bottom;
118
+ if (mouseEvent.clientY < rowBottom) {
119
+ return startIndex;
120
+ }
121
+ for (var rowIndex = startIndex + 1; rowIndex < endIndex; rowIndex++) {
122
+ var rowRect = rows[rowIndex].getBoundingClientRect();
123
+ rowBottom = rowRect.bottom;
124
+ if (mouseEvent.clientY < rowBottom) {
125
+ return rowIndex;
126
+ }
127
+ }
128
+ return undefined;
129
+ };
88
130
  var getRowClassNames = exports.getRowClassNames = function getRowClassNames(index, selection) {
89
131
  var hoveredRows = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
90
132
  var isInDanger = arguments.length > 3 ? arguments[3] : undefined;
@@ -3,7 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getSelectedRowIndexes = exports.getSelectedColumnIndexes = void 0;
6
+ exports.isRowSelectionWithMergedFirstColumn = exports.isFullRowOrColumnSelected = exports.isColumnSelectionWithMergedFirstRow = exports.getSelectedRowIndexes = exports.getSelectedColumnIndexes = void 0;
7
+ var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
8
+ var _tableMap = require("@atlaskit/editor-tables/table-map");
9
+ var _utils = require("@atlaskit/editor-tables/utils");
7
10
  var getSelectedColumnIndexes = exports.getSelectedColumnIndexes = function getSelectedColumnIndexes(selectionRect) {
8
11
  var columnIndexes = [];
9
12
  for (var i = selectionRect.left; i < selectionRect.right; i++) {
@@ -17,4 +20,74 @@ var getSelectedRowIndexes = exports.getSelectedRowIndexes = function getSelected
17
20
  rowIndexes.push(i);
18
21
  }
19
22
  return rowIndexes;
23
+ };
24
+
25
+ /**
26
+ * Treats a column as fully selected when its first-row area is covered by a horizontal merge and
27
+ * the explicit `CellSelection` starts below that merged cell. `CellSelection.isColSelection()`
28
+ * returns `false` in this case because the selection does not include the merged first-row cell.
29
+ */
30
+ var isColumnSelectionWithMergedFirstRow = exports.isColumnSelectionWithMergedFirstRow = function isColumnSelectionWithMergedFirstRow(selection) {
31
+ var rect = (0, _utils.getSelectionRect)(selection);
32
+ if (!rect) {
33
+ return false;
34
+ }
35
+ var table = (0, _utils.findTableClosestToPos)(selection.$anchorCell);
36
+ if (!table) {
37
+ return false;
38
+ }
39
+ var map = _tableMap.TableMap.get(table.node);
40
+ if (rect.bottom !== map.height || rect.top === 0) {
41
+ return false;
42
+ }
43
+ for (var col = rect.left; col < rect.right; col++) {
44
+ var topCellRect = map.findCell(map.map[col]);
45
+ var isHorizontallyMerged = topCellRect.right - topCellRect.left > 1;
46
+ var bridgesGapAboveSelection = topCellRect.bottom >= rect.top;
47
+ if (!isHorizontallyMerged || !bridgesGapAboveSelection) {
48
+ return false;
49
+ }
50
+ }
51
+ return true;
52
+ };
53
+
54
+ /**
55
+ * Treats a row as fully selected when its first-column area is covered by a vertical merge and the
56
+ * explicit `CellSelection` starts to the right of that merged cell. `CellSelection.isRowSelection()`
57
+ * returns `false` in this case because the selection does not include the merged first-column cell.
58
+ */
59
+ var isRowSelectionWithMergedFirstColumn = exports.isRowSelectionWithMergedFirstColumn = function isRowSelectionWithMergedFirstColumn(selection) {
60
+ var rect = (0, _utils.getSelectionRect)(selection);
61
+ if (!rect) {
62
+ return false;
63
+ }
64
+ var table = (0, _utils.findTableClosestToPos)(selection.$anchorCell);
65
+ if (!table) {
66
+ return false;
67
+ }
68
+ var map = _tableMap.TableMap.get(table.node);
69
+ if (rect.right !== map.width || rect.left === 0) {
70
+ return false;
71
+ }
72
+ for (var row = rect.top; row < rect.bottom; row++) {
73
+ var leftCellRect = map.findCell(map.map[row * map.width]);
74
+ var isVerticallyMerged = leftCellRect.bottom - leftCellRect.top > 1;
75
+ var bridgesGapLeftOfSelection = leftCellRect.right >= rect.left;
76
+ if (!isVerticallyMerged || !bridgesGapLeftOfSelection) {
77
+ return false;
78
+ }
79
+ }
80
+ return true;
81
+ };
82
+
83
+ /**
84
+ * Returns `true` when the selection covers one or more complete rows or columns (the kind of
85
+ * selection produced by clicking a row/column drag handle), including the merged-cell variants
86
+ * where `CellSelection.isRowSelection()` / `isColSelection()` return `false`.
87
+ */
88
+ var isFullRowOrColumnSelected = exports.isFullRowOrColumnSelected = function isFullRowOrColumnSelected(selection) {
89
+ if (!(selection instanceof _cellSelection.CellSelection)) {
90
+ return false;
91
+ }
92
+ return selection.isRowSelection() || selection.isColSelection() || isRowSelectionWithMergedFirstColumn(selection) || isColumnSelectionWithMergedFirstRow(selection);
20
93
  };
@@ -19,6 +19,7 @@ var _editorTables = require("@atlaskit/editor-tables");
19
19
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
20
20
  var _setCustomNativeDragPreview = require("@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview");
21
21
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
22
+ var _activeTableMenu = require("../../pm-plugins/commands/active-table-menu");
22
23
  var _pluginFactory = require("../../pm-plugins/drag-and-drop/plugin-factory");
23
24
  var _mergedCells = require("../../pm-plugins/utils/merged-cells");
24
25
  var _types = require("../../types");
@@ -29,7 +30,8 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
29
30
  /* eslint-disable @atlaskit/design-system/no-html-button */
30
31
 
31
32
  var DragHandleComponent = function DragHandleComponent(_ref) {
32
- var isDragMenuTarget = _ref.isDragMenuTarget,
33
+ var api = _ref.api,
34
+ isDragMenuTarget = _ref.isDragMenuTarget,
33
35
  tableLocalId = _ref.tableLocalId,
34
36
  _ref$direction = _ref.direction,
35
37
  direction = _ref$direction === void 0 ? 'row' : _ref$direction,
@@ -160,6 +162,35 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
160
162
  }, [tableLocalId, direction, indexes, isRow, editorView.state.selection, hasMergedCells]);
161
163
  var showDragMenuAnchorId = isRow ? 'drag-handle-button-row' : 'drag-handle-button-column';
162
164
  var browser = (0, _browser.getBrowserInfo)();
165
+
166
+ // Clicking the drag handle's clickable zone is a plain row/column selection (not the menu
167
+ // trigger), so the selection toolbar should appear. The floating menu defers closing for clicks
168
+ // inside the drag controls, so we close it here and reset the user intent to 'default' (in the
169
+ // same transaction) so the toolbar is shown.
170
+ var closeActiveDragMenuAndShowToolbar = (0, _react.useCallback)(function () {
171
+ var _api$table, _api$core;
172
+ if (!api) {
173
+ return;
174
+ }
175
+ var activeTableMenu = (_api$table = api.table) === null || _api$table === void 0 || (_api$table = _api$table.sharedState.currentState()) === null || _api$table === void 0 ? void 0 : _api$table.activeTableMenu;
176
+ var isActiveTableMenuOpen = (activeTableMenu === null || activeTableMenu === void 0 ? void 0 : activeTableMenu.type) === 'row' || (activeTableMenu === null || activeTableMenu === void 0 ? void 0 : activeTableMenu.type) === 'column';
177
+ if (!isActiveTableMenuOpen) {
178
+ return;
179
+ }
180
+ (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref5) {
181
+ var _api$userIntent;
182
+ var tr = _ref5.tr;
183
+ (0, _activeTableMenu.closeActiveTableMenu)(api, {
184
+ skipUserIntent: true
185
+ })({
186
+ tr: tr
187
+ });
188
+ (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || _api$userIntent.commands.setCurrentUserIntent('default')({
189
+ tr: tr
190
+ });
191
+ return tr;
192
+ });
193
+ }, [api]);
163
194
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("button", {
164
195
  type: "button"
165
196
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -185,7 +216,10 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
185
216
  // return focus to editor so copying table selections whilst still works, i cannot call e.preventDefault in a mousemove event as this stops dragstart events from firing
186
217
  // -> this is bad for a11y but is the current standard new copy/paste keyboard shortcuts should be introduced instead
187
218
  editorView.focus();
188
- if (isDragMenuOpen) {
219
+ if ((0, _expValEquals.expValEquals)('platform_editor_table_menu_updates', 'isEnabled', true)) {
220
+ // New menu: close the open row/column menu (and show the selection toolbar).
221
+ closeActiveDragMenuAndShowToolbar();
222
+ } else if (isDragMenuOpen) {
189
223
  toggleDragMenu && toggleDragMenu('mouse', e);
190
224
  }
191
225
  },
@@ -224,12 +258,20 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
224
258
  // return focus to editor so copying table selections whilst still works, i cannot call e.preventDefault in a mousemove event as this stops dragstart events from firing
225
259
  // -> this is bad for a11y but is the current standard new copy/paste keyboard shortcuts should be introduced instead
226
260
  editorView.focus();
227
- toggleDragMenu && toggleDragMenu('mouse', e);
261
+ if ((0, _expValEquals.expValEquals)('platform_editor_table_menu_updates', 'isEnabled', true)) {
262
+ toggleDragMenu && toggleDragMenu('mouse', e, indexes[0]);
263
+ } else {
264
+ toggleDragMenu && toggleDragMenu('mouse', e);
265
+ }
228
266
  },
229
267
  onClick: onClick,
230
268
  onKeyDown: function onKeyDown(e) {
231
269
  if (e.key === 'Enter' || e.key === ' ') {
232
- toggleDragMenu && toggleDragMenu('keyboard');
270
+ if ((0, _expValEquals.expValEquals)('platform_editor_table_menu_updates', 'isEnabled', true)) {
271
+ toggleDragMenu && toggleDragMenu('keyboard', undefined, indexes[0]);
272
+ } else {
273
+ toggleDragMenu && toggleDragMenu('keyboard');
274
+ }
233
275
  }
234
276
  }
235
277
  }, appearance !== 'placeholder' ?
@@ -38,6 +38,7 @@ function getRowOptions(index) {
38
38
  });
39
39
  }
40
40
  function getColumnOptions(index, tableContainer, hasNumberedColumns) {
41
+ var verticalOffsetCorrection = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
41
42
  var options = {
42
43
  alignX: 'end',
43
44
  alignY: 'top',
@@ -48,20 +49,32 @@ function getColumnOptions(index, tableContainer, hasNumberedColumns) {
48
49
  // we should always set the InsertButton on the start,
49
50
  // considering the offset from the first column
50
51
  onPositionCalculated: function onPositionCalculated(position) {
52
+ // Move the popup upward whether the offset parent provides `top` or `bottom`.
53
+ var verticalCorrection;
54
+ if (verticalOffsetCorrection) {
55
+ if (position.top !== undefined) {
56
+ verticalCorrection = {
57
+ top: position.top - verticalOffsetCorrection
58
+ };
59
+ } else if (position.bottom !== undefined) {
60
+ verticalCorrection = {
61
+ bottom: position.bottom + verticalOffsetCorrection
62
+ };
63
+ }
64
+ }
51
65
  var left = position.left;
52
66
  if (!left) {
53
- // If not left, lest skip expensive next calculations.
54
- return position;
67
+ return _objectSpread(_objectSpread({}, position), verticalCorrection);
55
68
  }
56
69
  if (index === 0) {
57
- return _objectSpread(_objectSpread({}, position), {}, {
70
+ return _objectSpread(_objectSpread(_objectSpread({}, position), verticalCorrection), {}, {
58
71
  left: hasNumberedColumns ? HORIZONTAL_ALIGN_NUMBERED_COLUMN_BUTTON : HORIZONTAL_ALIGN_COLUMN_BUTTON
59
72
  });
60
73
  }
61
74
 
62
75
  // Check if current position is greater than the available container width
63
76
  var rect = tableContainer ? tableContainer.getBoundingClientRect() : null;
64
- return _objectSpread(_objectSpread({}, position), {}, {
77
+ return _objectSpread(_objectSpread(_objectSpread({}, position), verticalCorrection), {}, {
65
78
  left: rect && left > rect.width ? rect.width : left
66
79
  });
67
80
  }
@@ -78,9 +91,10 @@ function getColumnOptions(index, tableContainer, hasNumberedColumns) {
78
91
  return options;
79
92
  }
80
93
  function getPopupOptions(direction, index, hasNumberedColumns, tableContainer) {
94
+ var verticalOffsetCorrection = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
81
95
  switch (direction) {
82
96
  case 'column':
83
- return getColumnOptions(index, tableContainer, hasNumberedColumns);
97
+ return getColumnOptions(index, tableContainer, hasNumberedColumns, verticalOffsetCorrection);
84
98
  case 'row':
85
99
  return getRowOptions(index);
86
100
  default: