@atlaskit/editor-plugin-table 0.2.2 → 0.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 (83) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cjs/plugins/table/commands/hover.js +2 -1
  3. package/dist/cjs/plugins/table/event-handlers.js +9 -13
  4. package/dist/cjs/plugins/table/index.js +3 -1
  5. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +15 -5
  6. package/dist/cjs/plugins/table/pm-plugins/default-table-selection.js +1 -2
  7. package/dist/cjs/plugins/table/pm-plugins/main.js +2 -2
  8. package/dist/cjs/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +42 -8
  9. package/dist/cjs/plugins/table/pm-plugins/table-resizing/utils/resize-logic.js +1 -1
  10. package/dist/cjs/plugins/table/toolbar.js +42 -10
  11. package/dist/cjs/plugins/table/ui/FloatingContextualButton/index.js +7 -1
  12. package/dist/cjs/plugins/table/ui/FloatingContextualButton/styles.js +34 -6
  13. package/dist/cjs/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +4 -1
  14. package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
  15. package/dist/cjs/plugins/table/ui/consts.js +4 -4
  16. package/dist/cjs/plugins/table/ui/ui-styles.js +5 -5
  17. package/dist/cjs/version.json +1 -1
  18. package/dist/es2019/plugins/table/commands/hover.js +2 -1
  19. package/dist/es2019/plugins/table/event-handlers.js +10 -13
  20. package/dist/es2019/plugins/table/index.js +1 -1
  21. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +12 -1
  22. package/dist/es2019/plugins/table/pm-plugins/default-table-selection.js +1 -2
  23. package/dist/es2019/plugins/table/pm-plugins/main.js +2 -2
  24. package/dist/es2019/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +31 -4
  25. package/dist/es2019/plugins/table/pm-plugins/table-resizing/utils/resize-logic.js +1 -1
  26. package/dist/es2019/plugins/table/toolbar.js +43 -12
  27. package/dist/es2019/plugins/table/ui/FloatingContextualButton/index.js +6 -2
  28. package/dist/es2019/plugins/table/ui/FloatingContextualButton/styles.js +47 -8
  29. package/dist/es2019/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +4 -1
  30. package/dist/es2019/plugins/table/ui/common-styles.js +9 -9
  31. package/dist/es2019/plugins/table/ui/consts.js +5 -5
  32. package/dist/es2019/plugins/table/ui/ui-styles.js +5 -5
  33. package/dist/es2019/version.json +1 -1
  34. package/dist/esm/plugins/table/commands/hover.js +2 -1
  35. package/dist/esm/plugins/table/event-handlers.js +10 -14
  36. package/dist/esm/plugins/table/index.js +3 -1
  37. package/dist/esm/plugins/table/nodeviews/TableComponent.js +17 -6
  38. package/dist/esm/plugins/table/pm-plugins/default-table-selection.js +1 -2
  39. package/dist/esm/plugins/table/pm-plugins/main.js +2 -2
  40. package/dist/esm/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +43 -8
  41. package/dist/esm/plugins/table/pm-plugins/table-resizing/utils/resize-logic.js +1 -1
  42. package/dist/esm/plugins/table/toolbar.js +43 -12
  43. package/dist/esm/plugins/table/ui/FloatingContextualButton/index.js +8 -2
  44. package/dist/esm/plugins/table/ui/FloatingContextualButton/styles.js +28 -5
  45. package/dist/esm/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +4 -1
  46. package/dist/esm/plugins/table/ui/common-styles.js +1 -1
  47. package/dist/esm/plugins/table/ui/consts.js +5 -5
  48. package/dist/esm/plugins/table/ui/ui-styles.js +5 -5
  49. package/dist/esm/version.json +1 -1
  50. package/dist/types/plugins/table/event-handlers.d.ts +2 -2
  51. package/dist/types/plugins/table/pm-plugins/default-table-selection.d.ts +0 -1
  52. package/dist/types/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.d.ts +8 -0
  53. package/dist/types/plugins/table/toolbar.d.ts +3 -2
  54. package/dist/types/plugins/table/ui/FloatingContextualButton/styles.d.ts +3 -1
  55. package/dist/types/plugins/table/ui/FloatingContextualMenu/styles.d.ts +2 -2
  56. package/dist/types/plugins/table/ui/common-styles.d.ts +3 -3
  57. package/dist/types/plugins/table/ui/consts.d.ts +2 -2
  58. package/dist/types/plugins/table/ui/ui-styles.d.ts +14 -14
  59. package/package.json +4 -4
  60. package/src/__tests__/integration/__snapshots__/floating-toolbar.ts.snap +321 -0
  61. package/src/__tests__/integration/delete-last-column-in-full-width.ts +6 -5
  62. package/src/__tests__/integration/floating-toolbar.ts +169 -0
  63. package/src/__tests__/unit/get-toolbar-config.ts +1 -0
  64. package/src/__tests__/unit/nodeviews/TableComponent.tsx +146 -4
  65. package/src/__tests__/unit/pm-plugins/table-resizing/event-handlers.ts +82 -31
  66. package/src/__tests__/unit/toolbar.ts +165 -4
  67. package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-row-menu-item-should-remove-the-table-row-on-click-1-snap.png +2 -2
  68. package/src/plugins/table/commands/hover.ts +1 -0
  69. package/src/plugins/table/event-handlers.ts +6 -17
  70. package/src/plugins/table/index.tsx +1 -0
  71. package/src/plugins/table/nodeviews/TableComponent.tsx +10 -2
  72. package/src/plugins/table/nodeviews/tableCell.tsx +1 -1
  73. package/src/plugins/table/pm-plugins/default-table-selection.ts +0 -1
  74. package/src/plugins/table/pm-plugins/main.ts +26 -28
  75. package/src/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.ts +44 -9
  76. package/src/plugins/table/pm-plugins/table-resizing/utils/resize-logic.ts +1 -1
  77. package/src/plugins/table/toolbar.tsx +60 -13
  78. package/src/plugins/table/ui/FloatingContextualButton/index.tsx +12 -2
  79. package/src/plugins/table/ui/FloatingContextualButton/styles.ts +51 -7
  80. package/src/plugins/table/ui/FloatingContextualMenu/ContextualMenu.tsx +3 -0
  81. package/src/plugins/table/ui/common-styles.ts +24 -9
  82. package/src/plugins/table/ui/consts.ts +7 -5
  83. package/src/plugins/table/ui/ui-styles.ts +20 -5
@@ -1,4 +1,4 @@
1
- import { B200, B300, N0, N20, R400, R75, DN400, N200, DN30 } from '@atlaskit/theme/colors';
1
+ import { B200, B300, N20, R400, R75, DN400, N200, DN30, N0 } from '@atlaskit/theme/colors';
2
2
  import { tableCellBorderWidth, tableMarginTop } from '@atlaskit/editor-common/styles';
3
3
  import { akEditorTableBorder, akEditorTableBorderDark, akEditorTableToolbar, akEditorTableToolbarDark, akEditorTableToolbarSize, akEditorUnitZIndex, akRichMediaResizeZIndex } from '@atlaskit/editor-shared-styles';
4
4
  import { token } from '@atlaskit/tokens';
@@ -11,12 +11,12 @@ import { themed } from '@atlaskit/theme/components';
11
11
  // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
12
12
 
13
13
  export const tableCellBackgroundColor = themed({
14
- light: N0,
15
- dark: DN30
14
+ light: token('elevation.surface', N0),
15
+ dark: token('elevation.surface', DN30)
16
16
  });
17
17
  export const tableToolbarColor = themed({
18
- light: akEditorTableToolbar,
19
- dark: akEditorTableToolbarDark
18
+ light: token('color.background.neutral.subtle', akEditorTableToolbar),
19
+ dark: token('color.background.neutral.subtle', akEditorTableToolbarDark)
20
20
  });
21
21
  export const tableTextColor = themed({
22
22
  light: token('color.text.subtlest', N200),
@@ -82,21 +82,21 @@ export const HeaderButton = (props, cssString) => css`
82
82
 
83
83
  .active .${ClassName.CONTROLS_BUTTON} {
84
84
  color: ${token('color.icon.inverse', N0)};
85
- background-color: ${tableToolbarSelectedColor};
85
+ background-color: ${token('color.background.selected', tableToolbarSelectedColor)};
86
86
  border-color: ${tableBorderSelectedColor};
87
87
  }
88
88
  `;
89
89
  export const HeaderButtonHover = () => css`
90
90
  .${ClassName.CONTROLS_BUTTON}:hover {
91
91
  color: ${token('color.icon.inverse', N0)};
92
- background-color: ${tableToolbarSelectedColor};
92
+ background-color: ${token('color.background.selected', tableToolbarSelectedColor)};
93
93
  border-color: ${tableBorderSelectedColor};
94
94
  cursor: pointer;
95
95
  }
96
96
  `;
97
97
  export const HeaderButtonDanger = () => css`
98
98
  .${ClassName.HOVERED_CELL_IN_DANGER} .${ClassName.CONTROLS_BUTTON} {
99
- background-color: ${tableToolbarDeleteColor};
99
+ background-color: ${token('color.background.danger', tableToolbarDeleteColor)};
100
100
  border-color: ${tableBorderDeleteColor};
101
101
  position: relative;
102
102
  z-index: ${akEditorUnitZIndex};
@@ -245,7 +245,7 @@ const columnHeaderButton = (props, cssString) => css`
245
245
 
246
246
  const columnHeaderButtonSelected = css`
247
247
  color: ${token('color.text.inverse', N0)};
248
- background-color: ${tableToolbarSelectedColor};
248
+ background-color: ${token('color.background.selected', tableToolbarSelectedColor)};
249
249
  border-color: ${tableBorderSelectedColor};
250
250
  z-index: ${columnControlsSelectedZIndex};
251
251
  `;
@@ -318,7 +318,7 @@ export const columnControlsDecoration = props => css`
318
318
 
319
319
  &.${ClassName.HOVERED_CELL_IN_DANGER}
320
320
  .${ClassName.COLUMN_CONTROLS_DECORATIONS}::after {
321
- background-color: ${tableToolbarDeleteColor};
321
+ background-color: ${token('color.background.danger', tableToolbarDeleteColor)};
322
322
  border: 1px solid ${tableBorderDeleteColor};
323
323
  border-bottom: none;
324
324
  z-index: ${akEditorUnitZIndex * 100};
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "sideEffects": false
5
5
  }
@@ -122,7 +122,8 @@ export var clearHoverSelection = function clearHoverSelection() {
122
122
  return {
123
123
  type: 'CLEAR_HOVER_SELECTION',
124
124
  data: {
125
- decorationSet: updatePluginStateDecorations(state, [], TableDecorations.ALL_CONTROLS_HOVER)
125
+ decorationSet: updatePluginStateDecorations(state, [], TableDecorations.ALL_CONTROLS_HOVER),
126
+ isInDanger: false
126
127
  }
127
128
  };
128
129
  });
@@ -12,7 +12,7 @@ import { getPluginState } from './pm-plugins/plugin-factory';
12
12
  import { getPluginState as getResizePluginState } from './pm-plugins/table-resizing/plugin-factory';
13
13
  import { deleteColumns, deleteRows } from './transforms';
14
14
  import { RESIZE_HANDLE_AREA_DECORATION_GAP } from './types';
15
- import { getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, getSelectedCellInfo, isCell, isColumnControlsDecorations, isCornerButton, isInsertRowButton, isResizeHandleDecoration, isRowControlsButton, isTableControlsButton, isTableContainerOrWrapper } from './utils';
15
+ import { getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, getSelectedCellInfo, isCell, isColumnControlsDecorations, isCornerButton, isInsertRowButton, isResizeHandleDecoration, isRowControlsButton, isTableControlsButton, isTableContainerOrWrapper, hasResizeHandler } from './utils';
16
16
  import { getAllowAddColumnCustomStep } from './utils/get-allow-add-column-custom-step';
17
17
 
18
18
  var isFocusingCalendar = function isFocusingCalendar(event) {
@@ -207,7 +207,7 @@ export var handleMouseLeave = function handleMouseLeave(view, event) {
207
207
  return false;
208
208
  };
209
209
  export var handleMouseMove = function handleMouseMove(getEditorFeatureFlags) {
210
- return function (view, event, tableCellOptimization, elementContentRects) {
210
+ return function (view, event, elementContentRects) {
211
211
  if (!(event.target instanceof HTMLElement)) {
212
212
  return false;
213
213
  }
@@ -226,7 +226,7 @@ export var handleMouseMove = function handleMouseMove(getEditorFeatureFlags) {
226
226
  startIndex = _getColumnOrRowIndex10[0],
227
227
  endIndex = _getColumnOrRowIndex10[1];
228
228
 
229
- var positionColumn = getMousePositionHorizontalRelativeByElement(event, tableCellOptimization, elementContentRects) === 'right' ? endIndex : startIndex;
229
+ var positionColumn = getMousePositionHorizontalRelativeByElement(event, false, elementContentRects) === 'right' ? endIndex : startIndex;
230
230
 
231
231
  if (positionColumn !== insertColumnButtonIndex) {
232
232
  return showInsertColumnButton(positionColumn)(state, dispatch);
@@ -253,14 +253,10 @@ export var handleMouseMove = function handleMouseMove(getEditorFeatureFlags) {
253
253
  }
254
254
 
255
255
  var _getEditorFeatureFlag = getEditorFeatureFlags(),
256
- mouseMoveOptimization = _getEditorFeatureFlag.mouseMoveOptimization; // we only want to allow mouseMoveOptimisation when tableCellOptimization is enabled
257
- // because it relies on tableCell node view that is added via tableCellOptimization
258
-
259
-
260
- var useMouseMoveOptimisation = tableCellOptimization && mouseMoveOptimization;
256
+ mouseMoveOptimization = _getEditorFeatureFlag.mouseMoveOptimization;
261
257
 
262
258
  if (!isResizeHandleDecoration(element) && isCell(element)) {
263
- var positionColumn = getMousePositionHorizontalRelativeByElement(event, useMouseMoveOptimisation, elementContentRects, RESIZE_HANDLE_AREA_DECORATION_GAP);
259
+ var positionColumn = getMousePositionHorizontalRelativeByElement(event, mouseMoveOptimization, elementContentRects, RESIZE_HANDLE_AREA_DECORATION_GAP);
264
260
 
265
261
  if (positionColumn !== null) {
266
262
  var _state4 = view.state,
@@ -278,7 +274,10 @@ export var handleMouseMove = function handleMouseMove(getEditorFeatureFlags) {
278
274
  var columnEndIndexTarget = positionColumn === 'left' ? rect.left : rect.right;
279
275
  var rowIndexTarget = rect.top;
280
276
 
281
- if (columnEndIndexTarget !== resizeHandleColumnIndex || rowIndexTarget !== resizeHandleRowIndex) {
277
+ if (columnEndIndexTarget !== resizeHandleColumnIndex || rowIndexTarget !== resizeHandleRowIndex || !hasResizeHandler({
278
+ target: element,
279
+ columnEndIndexTarget: columnEndIndexTarget
280
+ })) {
282
281
  return addResizeHandleDecorations(rowIndexTarget, columnEndIndexTarget)(_state4, _dispatch5);
283
282
  }
284
283
  }
@@ -369,18 +368,15 @@ export var handleCut = function handleCut(oldTr, oldState, newState, editorAnaly
369
368
  };
370
369
  export var whenTableInFocus = function whenTableInFocus(eventHandler, elementContentRects) {
371
370
  return function (view, mouseEvent) {
372
- var _tablePluginState$plu;
373
-
374
371
  var tableResizePluginState = getResizePluginState(view.state);
375
372
  var tablePluginState = getPluginState(view.state);
376
373
  var isDragging = tableResizePluginState && !!tableResizePluginState.dragging;
377
374
  var hasTableNode = tablePluginState && tablePluginState.tableNode;
378
- var tableCellOptimization = tablePluginState === null || tablePluginState === void 0 ? void 0 : (_tablePluginState$plu = tablePluginState.pluginConfig) === null || _tablePluginState$plu === void 0 ? void 0 : _tablePluginState$plu.tableCellOptimization;
379
375
 
380
376
  if (!hasTableNode || isDragging) {
381
377
  return false;
382
378
  }
383
379
 
384
- return eventHandler(view, mouseEvent, tableCellOptimization, elementContentRects);
380
+ return eventHandler(view, mouseEvent, elementContentRects);
385
381
  };
386
382
  };
@@ -348,7 +348,9 @@ var tablesPlugin = function tablesPlugin(options) {
348
348
  }
349
349
  }];
350
350
  },
351
- floatingToolbar: getToolbarConfig(defaultGetEditorContainerWidth, options === null || options === void 0 ? void 0 : options.editorAnalyticsAPI, (options === null || options === void 0 ? void 0 : options.getEditorFeatureFlags) || defaultGetEditorFeatureFlags)(pluginConfig(options === null || options === void 0 ? void 0 : options.tableOptions))
351
+ floatingToolbar: getToolbarConfig(defaultGetEditorContainerWidth, options === null || options === void 0 ? void 0 : options.editorAnalyticsAPI, (options === null || options === void 0 ? void 0 : options.getEditorFeatureFlags) || defaultGetEditorFeatureFlags, function () {
352
+ return editorViewRef.current;
353
+ })(pluginConfig(options === null || options === void 0 ? void 0 : options.tableOptions))
352
354
  }
353
355
  };
354
356
  };
@@ -18,12 +18,13 @@ import React from 'react';
18
18
  import classnames from 'classnames';
19
19
  import { isTableSelected } from '@atlaskit/editor-tables/utils';
20
20
  import rafSchedule from 'raf-schd';
21
+ import { findTable } from '@atlaskit/editor-tables/utils';
21
22
  import { calcTableWidth, tableMarginSides } from '@atlaskit/editor-common/styles';
22
23
  import { browser, isValidPosition } from '@atlaskit/editor-common/utils';
23
24
  import { akEditorMobileBreakoutPoint, akEditorTableToolbarSize as tableToolbarSize } from '@atlaskit/editor-shared-styles';
24
25
  import { getParentNodeWidth } from '@atlaskit/editor-common/node-width';
25
26
  import { parsePx } from '@atlaskit/editor-common/utils';
26
- import { autoSizeTable } from '../commands';
27
+ import { autoSizeTable, clearHoverSelection } from '../commands';
27
28
  import { getPluginState } from '../pm-plugins/plugin-factory';
28
29
  import { findStickyHeaderForTable, pluginKey as stickyHeadersPluginKey } from '../pm-plugins/sticky-headers';
29
30
  import { scaleTable } from '../pm-plugins/table-resizing';
@@ -410,10 +411,20 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
410
411
  key: "componentDidUpdate",
411
412
  value: function componentDidUpdate(prevProps) {
412
413
  var _this$props8 = this.props,
414
+ view = _this$props8.view,
413
415
  getNode = _this$props8.getNode,
414
416
  isMediaFullscreen = _this$props8.isMediaFullscreen,
415
417
  allowColumnResizing = _this$props8.allowColumnResizing;
416
418
 
419
+ var _getPluginState = getPluginState(view.state),
420
+ isInDanger = _getPluginState.isInDanger;
421
+
422
+ var table = findTable(view.state.selection);
423
+
424
+ if (isInDanger && !table) {
425
+ clearHoverSelection()(view.state, view.dispatch);
426
+ }
427
+
417
428
  var _this$props$getEditor3 = this.props.getEditorFeatureFlags(),
418
429
  tableOverflowShadowsOptimization = _this$props$getEditor3.tableOverflowShadowsOptimization;
419
430
 
@@ -446,9 +457,9 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
446
457
  var previousTable = this.node;
447
458
 
448
459
  if (tablesHaveDifferentColumnWidths(currentTable, previousTable) || tablesHaveDifferentNoOfColumns(currentTable, previousTable)) {
449
- var view = this.props.view;
460
+ var _view = this.props.view;
450
461
  recreateResizeColsByNode(this.table, currentTable);
451
- updateControls(this.props.getEditorFeatureFlags)(view.state);
462
+ updateControls(this.props.getEditorFeatureFlags)(_view.state);
452
463
  }
453
464
 
454
465
  this.handleTableResizingDebounced();
@@ -491,9 +502,9 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
491
502
  showAfterShadow = _this$state.showAfterShadow;
492
503
  var node = getNode(); // doesn't work well with WithPluginState
493
504
 
494
- var _getPluginState = getPluginState(view.state),
495
- isInDanger = _getPluginState.isInDanger,
496
- hoveredRows = _getPluginState.hoveredRows;
505
+ var _getPluginState2 = getPluginState(view.state),
506
+ isInDanger = _getPluginState2.isInDanger,
507
+ hoveredRows = _getPluginState2.hoveredRows;
497
508
 
498
509
  var _this$props$getEditor4 = this.props.getEditorFeatureFlags(),
499
510
  stickyHeadersOptimization = _this$props$getEditor4.stickyHeadersOptimization,
@@ -1,5 +1,4 @@
1
1
  export var defaultTableSelection = {
2
2
  hoveredColumns: [],
3
- hoveredRows: [],
4
- isInDanger: false
3
+ hoveredRows: []
5
4
  };
@@ -54,14 +54,14 @@ export var createPlugin = function createPlugin(dispatchAnalyticsEvent, dispatch
54
54
  elementContentRects[entry.target.id] = entry.contentRect;
55
55
  });
56
56
  }) : undefined;
57
- var tableCellNodeview = pluginConfig.tableCellOptimization ? {
57
+ var tableCellNodeview = {
58
58
  tableCell: function tableCell(node, view, getPos) {
59
59
  return new TableCellNodeView(node, view, getPos, getEditorFeatureFlags, observer);
60
60
  },
61
61
  tableHeader: function tableHeader(node, view, getPos) {
62
62
  return new TableCellNodeView(node, view, getPos, getEditorFeatureFlags, observer);
63
63
  }
64
- } : {}; // Used to prevent invalid table cell spans being reported more than once per editor/document
64
+ }; // Used to prevent invalid table cell spans being reported more than once per editor/document
65
65
 
66
66
  var invalidTableIds = [];
67
67
  var editorViewRef = null;
@@ -13,18 +13,49 @@ import debounce from 'lodash/debounce';
13
13
  import throttle from 'lodash/throttle'; // limit scroll event calls
14
14
 
15
15
  var HEADER_ROW_SCROLL_THROTTLE_TIMEOUT = 200; // timeout for resetting the scroll class - if it’s too long then users won’t be able to click on the header cells,
16
- // if too short it would trigger too many dom udpates.
16
+ // if too short it would trigger too many dom updates.
17
17
 
18
18
  var HEADER_ROW_SCROLL_RESET_DEBOUNCE_TIMEOUT = 400;
19
- export var supportedHeaderRow = function supportedHeaderRow(node) {
20
- var allHeaders = mapChildren(node, function (child) {
21
- return child.type.name === 'tableHeader';
22
- }).every(Boolean);
23
- var someMerged = mapChildren(node, function (child) {
19
+
20
+ var anyChildCellMergedAcrossRow = function anyChildCellMergedAcrossRow(node) {
21
+ return mapChildren(node, function (child) {
24
22
  return child.attrs.rowspan || 0;
25
23
  }).some(function (rowspan) {
26
24
  return rowspan > 1;
27
25
  });
26
+ };
27
+ /**
28
+ * Compare two table row nodes and return true if the two table rows have a
29
+ * different number of table cells or if table cell row spans are different
30
+ */
31
+
32
+
33
+ var rowHasDifferentMergedCells = function rowHasDifferentMergedCells(prevNode, incomingNode) {
34
+ var incomingNodeChildrenRowSpan = mapChildren(prevNode, function (child) {
35
+ return child.attrs.rowspan || 0;
36
+ });
37
+ var currentNodeChildrenRowSpan = mapChildren(incomingNode, function (child) {
38
+ return child.attrs.rowspan || 0;
39
+ });
40
+ return incomingNodeChildrenRowSpan.length !== currentNodeChildrenRowSpan.length || currentNodeChildrenRowSpan.some(function (child, index) {
41
+ return child !== incomingNodeChildrenRowSpan[index];
42
+ });
43
+ };
44
+ /**
45
+ * Check if a given node is a header row with this definition:
46
+ * - all children are tableHeader cells
47
+ * - no table cells have been have merged with other table row cells
48
+ *
49
+ * @param node ProseMirror node
50
+ * @return boolean if it meets definition
51
+ */
52
+
53
+
54
+ export var supportedHeaderRow = function supportedHeaderRow(node) {
55
+ var allHeaders = mapChildren(node, function (child) {
56
+ return child.type.name === 'tableHeader';
57
+ }).every(Boolean);
58
+ var someMerged = anyChildCellMergedAcrossRow(node);
28
59
  return allHeaders && !someMerged;
29
60
  };
30
61
  export var TableRowNodeView = /*#__PURE__*/function () {
@@ -522,10 +553,14 @@ export var TableRowNodeView = /*#__PURE__*/function () {
522
553
  // changing away from one
523
554
 
524
555
 
525
- var newNodeisHeaderRow = supportedHeaderRow(node);
556
+ var newNodeIsHeaderRow = supportedHeaderRow(node);
526
557
 
527
- if (this.isHeaderRow !== newNodeisHeaderRow) {
558
+ if (this.isHeaderRow !== newNodeIsHeaderRow) {
528
559
  return false; // re-create nodeview
560
+ }
561
+
562
+ if (rowHasDifferentMergedCells(this.node, node)) {
563
+ return false;
529
564
  } // node is different but no need to re-create nodeview
530
565
 
531
566
 
@@ -30,7 +30,7 @@ export var growColumn = function growColumn(state, colIndex, amount, selectedCol
30
30
  };
31
31
  export var shrinkColumn = function shrinkColumn(state, colIndex, amount, selectedColumns) {
32
32
  // can't shrink if columns don't exist
33
- if (!state.cols[colIndex] || !state.cols[colIndex + 1]) {
33
+ if (!state.cols[colIndex]) {
34
34
  return state;
35
35
  } // try to shrink dragging column by giving from the column to the right first
36
36
 
@@ -5,12 +5,12 @@ import { jsx } from '@emotion/react';
5
5
  import { defineMessages } from 'react-intl-next';
6
6
  import RemoveIcon from '@atlaskit/icon/glyph/editor/remove';
7
7
  import commonMessages from '@atlaskit/editor-common/messages';
8
- import { clearHoverSelection, hoverTable } from './commands';
8
+ import { clearHoverSelection, hoverTable, hoverColumns, hoverRows } from './commands';
9
9
  import { deleteTableWithAnalytics, toggleHeaderColumnWithAnalytics, toggleHeaderRowWithAnalytics, toggleNumberColumnWithAnalytics, insertRowWithAnalytics, deleteRowsWithAnalytics, mergeCellsWithAnalytics, splitCellWithAnalytics, deleteColumnsWithAnalytics, emptyMultipleCellsWithAnalytics, insertColumnWithAnalytics, wrapTableInExpandWithAnalytics, sortColumnWithAnalytics, setColorWithAnalytics, distributeColumnsWidthsWithAnalytics } from './commands-with-analytics';
10
10
  import { getPluginState } from './pm-plugins/plugin-factory';
11
11
  import { pluginKey as tableResizingPluginKey } from './pm-plugins/table-resizing';
12
12
  import { TableCssClassName } from './types';
13
- import { getMergedCellsPositions } from './utils';
13
+ import { getMergedCellsPositions, getSelectedColumnIndexes, getSelectedRowIndexes } from './utils';
14
14
  import { isReferencedSource } from './utils/referentiality';
15
15
  import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
16
16
  import { findCellRectClosestToPos, findTable, getSelectionRect, isSelectionType } from '@atlaskit/editor-tables/utils';
@@ -25,6 +25,7 @@ import { getNewResizeStateFromSelectedColumns } from './pm-plugins/table-resizin
25
25
  import { TableSortOrder as SortOrder } from '@atlaskit/adf-schema/steps';
26
26
  import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut';
27
27
  import { cellBackgroundColorPalette, DEFAULT_BORDER_COLOR } from '@atlaskit/editor-common/ui-color';
28
+ import { akEditorFloatingPanelZIndex } from '@atlaskit/editor-shared-styles';
28
29
  export var messages = defineMessages({
29
30
  tableOptions: {
30
31
  id: 'fabric.editor.tableOptions',
@@ -93,7 +94,7 @@ export var getToolbarMenuConfig = function getToolbarMenuConfig(config, state, _
93
94
  // relay it to the native mobile. Native mobile displays the menu
94
95
  // with native widgets. It's enabled via a plugin config.
95
96
 
96
- export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(editorState, initialSelectionRect, _ref2, getEditorContainerWidth, editorAnalyticsAPI) {
97
+ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(editorState, editorView, initialSelectionRect, _ref2, getEditorContainerWidth, editorAnalyticsAPI) {
97
98
  var _pluginState$pluginCo, _pluginState$pluginCo2;
98
99
 
99
100
  var formatMessage = _ref2.formatMessage;
@@ -157,6 +158,17 @@ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(ed
157
158
 
158
159
  return true;
159
160
  },
161
+ onMouseOver: function onMouseOver(state, dispatch) {
162
+ var selectionRect = getClosestSelectionRect(state);
163
+
164
+ if (selectionRect) {
165
+ hoverColumns(getSelectedColumnIndexes(selectionRect), true)(state, dispatch);
166
+ return true;
167
+ }
168
+
169
+ return false;
170
+ },
171
+ onMouseLeave: clearHoverSelection(),
160
172
  selected: false,
161
173
  disabled: false
162
174
  }, {
@@ -173,6 +185,17 @@ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(ed
173
185
 
174
186
  return true;
175
187
  },
188
+ onMouseOver: function onMouseOver(state, dispatch) {
189
+ var selectionRect = getClosestSelectionRect(state);
190
+
191
+ if (selectionRect) {
192
+ hoverRows(getSelectedRowIndexes(selectionRect), true)(state, dispatch);
193
+ return true;
194
+ }
195
+
196
+ return false;
197
+ },
198
+ onMouseLeave: clearHoverSelection(),
176
199
  selected: false,
177
200
  disabled: false
178
201
  }, {
@@ -190,9 +213,12 @@ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(ed
190
213
  }];
191
214
 
192
215
  if (pluginState !== null && pluginState !== void 0 && (_pluginState$pluginCo = pluginState.pluginConfig) !== null && _pluginState$pluginCo !== void 0 && _pluginState$pluginCo.allowDistributeColumns) {
193
- var distributeColumnWidths = function distributeColumnWidths(state, dispatch, view) {
194
- var newResizeStateWithAnalytics = view ? getNewResizeStateFromSelectedColumns(initialSelectionRect, editorState, view.domAtPos.bind(view), getEditorContainerWidth) : undefined;
216
+ var _newResizeStateWithAn;
217
+
218
+ var newResizeStateWithAnalytics = editorView ? getNewResizeStateFromSelectedColumns(initialSelectionRect, editorState, editorView.domAtPos.bind(editorView), getEditorContainerWidth) : undefined;
219
+ var wouldChange = (_newResizeStateWithAn = newResizeStateWithAnalytics === null || newResizeStateWithAnalytics === void 0 ? void 0 : newResizeStateWithAnalytics.changed) !== null && _newResizeStateWithAn !== void 0 ? _newResizeStateWithAn : false;
195
220
 
221
+ var distributeColumnWidths = function distributeColumnWidths(state, dispatch) {
196
222
  if (newResizeStateWithAnalytics) {
197
223
  distributeColumnsWidthsWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.FLOATING_TB, newResizeStateWithAnalytics)(state, dispatch);
198
224
  return true;
@@ -206,12 +232,13 @@ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(ed
206
232
  title: formatMessage(ContextualMenuMessages.distributeColumns),
207
233
  onClick: distributeColumnWidths,
208
234
  selected: false,
209
- disabled: numberOfColumns <= 1
235
+ disabled: !wouldChange
210
236
  });
211
237
  }
212
238
 
213
239
  if (pluginState !== null && pluginState !== void 0 && (_pluginState$pluginCo2 = pluginState.pluginConfig) !== null && _pluginState$pluginCo2 !== void 0 && _pluginState$pluginCo2.allowColumnSorting) {
214
240
  var hasMergedCellsInTable = getMergedCellsPositions(editorState.tr).length > 0;
241
+ var warning = hasMergedCellsInTable ? formatMessage(ContextualMenuMessages.canNotSortTable) : undefined;
215
242
  options.push({
216
243
  id: 'editor.table.sortColumnAsc',
217
244
  title: formatMessage(ContextualMenuMessages.sortColumnASC),
@@ -220,7 +247,8 @@ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(ed
220
247
  return true;
221
248
  },
222
249
  selected: false,
223
- disabled: hasMergedCellsInTable
250
+ disabled: hasMergedCellsInTable,
251
+ tooltip: warning
224
252
  });
225
253
  options.push({
226
254
  id: 'editor.table.sortColumnDesc',
@@ -230,7 +258,8 @@ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(ed
230
258
  return true;
231
259
  },
232
260
  selected: false,
233
- disabled: hasMergedCellsInTable
261
+ disabled: hasMergedCellsInTable,
262
+ tooltip: warning
234
263
  });
235
264
  }
236
265
 
@@ -268,7 +297,7 @@ var getClosestSelectionRect = function getClosestSelectionRect(state) {
268
297
  return isSelectionType(selection, 'cell') ? getSelectionRect(selection) : findCellRectClosestToPos(selection.$from);
269
298
  };
270
299
 
271
- export var getToolbarConfig = function getToolbarConfig(getEditorContainerWidth, editorAnalyticsAPI, getEditorFeatureFlags) {
300
+ export var getToolbarConfig = function getToolbarConfig(getEditorContainerWidth, editorAnalyticsAPI, getEditorFeatureFlags, getEditorView) {
272
301
  return function (config) {
273
302
  return function (state, intl) {
274
303
  var tableObject = findTable(state.selection);
@@ -282,7 +311,7 @@ export var getToolbarConfig = function getToolbarConfig(getEditorContainerWidth,
282
311
  var _ref3 = getEditorFeatureFlags() || {},
283
312
  tableCellOptionsInFloatingToolbar = _ref3.tableCellOptionsInFloatingToolbar;
284
313
 
285
- var cellItems = getCellItems(config, state, intl, getEditorContainerWidth, editorAnalyticsAPI, tableCellOptionsInFloatingToolbar);
314
+ var cellItems = getCellItems(config, state, getEditorView(), intl, getEditorContainerWidth, editorAnalyticsAPI, tableCellOptionsInFloatingToolbar);
286
315
  var colorPicker = getColorPicker(state, menu, intl, getEditorContainerWidth, editorAnalyticsAPI, tableCellOptionsInFloatingToolbar); // Check if we need to show confirm dialog for delete button
287
316
 
288
317
  var confirmDialog;
@@ -316,6 +345,8 @@ export var getToolbarConfig = function getToolbarConfig(getEditorContainerWidth,
316
345
  getDomRef: getDomRef,
317
346
  nodeType: nodeType,
318
347
  offset: [0, 3],
348
+ zIndex: akEditorFloatingPanelZIndex + 1,
349
+ // Place the context menu slightly above the others
319
350
  items: [menu, separator(menu.hidden)].concat(_toConsumableArray(cellItems), _toConsumableArray(colorPicker), [{
320
351
  type: 'extensions-placeholder',
321
352
  separator: 'end'
@@ -358,14 +389,14 @@ var separator = function separator(hidden) {
358
389
  };
359
390
  };
360
391
 
361
- var getCellItems = function getCellItems(pluginConfig, state, _ref4, getEditorContainerWidth, editorAnalyticsAPI, tableCellOptionsInFloatingToolbar) {
392
+ var getCellItems = function getCellItems(pluginConfig, state, view, _ref4, getEditorContainerWidth, editorAnalyticsAPI, tableCellOptionsInFloatingToolbar) {
362
393
  var formatMessage = _ref4.formatMessage;
363
394
 
364
395
  if (pluginConfig.allowCellOptionsInFloatingToolbar || tableCellOptionsInFloatingToolbar) {
365
396
  var initialSelectionRect = getClosestSelectionRect(state);
366
397
 
367
398
  if (initialSelectionRect) {
368
- var cellOptions = getToolbarCellOptionsConfig(state, initialSelectionRect, {
399
+ var cellOptions = getToolbarCellOptionsConfig(state, view, initialSelectionRect, {
369
400
  formatMessage: formatMessage
370
401
  }, getEditorContainerWidth, editorAnalyticsAPI);
371
402
  return [cellOptions, separator(cellOptions.hidden)];
@@ -25,7 +25,7 @@ import { TableCssClassName as ClassName } from '../../types';
25
25
  import messages from '../../ui/messages';
26
26
  import { CONTENT_COMPONENT } from '@atlaskit/editor-common/analytics';
27
27
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
28
- import { tableFloatingCellButtonStyles } from './styles';
28
+ import { tableFloatingCellButtonStyles, tableFloatingCellButtonSelectedStyles } from './styles';
29
29
  import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
30
30
  export var FloatingContextualButtonInner = /*#__PURE__*/function (_React$Component) {
31
31
  _inherits(FloatingContextualButtonInner, _React$Component);
@@ -106,7 +106,13 @@ export var FloatingContextualButtonInner = /*#__PURE__*/function (_React$Compone
106
106
  var tableWrapper = closestElement(targetCellRef, ".".concat(ClassName.TABLE_NODE_WRAPPER));
107
107
  var labelCellOptions = formatMessage(messages.cellOptions);
108
108
  var button = jsx("div", {
109
- css: tableFloatingCellButtonStyles
109
+ css: function css(theme) {
110
+ return [tableFloatingCellButtonStyles({
111
+ theme: theme
112
+ }), isContextualMenuOpen && tableFloatingCellButtonSelectedStyles({
113
+ theme: theme
114
+ })];
115
+ }
110
116
  }, jsx(ToolbarButton, {
111
117
  className: ClassName.CONTEXTUAL_MENU_BUTTON,
112
118
  selected: isContextualMenuOpen,
@@ -1,11 +1,34 @@
1
1
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
2
 
3
- var _templateObject;
3
+ var _templateObject, _templateObject2;
4
4
 
5
5
  import { css } from '@emotion/react';
6
- import { N0, N20 } from '@atlaskit/theme/colors';
6
+ import { B75, DN0, DN60, N0, N20, N30A, N700 } from '@atlaskit/theme/colors';
7
7
  import { borderRadius } from '@atlaskit/theme/constants';
8
8
  import { contextualMenuTriggerSize } from '../consts';
9
- import { token } from '@atlaskit/tokens'; // TODO: https://product-fabric.atlassian.net/browse/DSP-4462
10
-
11
- export var tableFloatingCellButtonStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n > div {\n background: ", ";\n border-radius: ", "px;\n border: 2px solid ", ";\n display: flex;\n height: ", "px;\n flex-direction: column;\n }\n && button {\n flex-direction: column;\n padding: 0;\n height: 100%;\n display: flex;\n }\n && button > span {\n margin: 0px -4px;\n }\n && span {\n pointer-events: none;\n }\n"])), token('color.background.neutral', N20), borderRadius(), token('color.border.inverse', N0), contextualMenuTriggerSize - 2);
9
+ import { token } from '@atlaskit/tokens';
10
+ import { themed } from '@atlaskit/theme/components';
11
+ export var tableFloatingCellButtonStyles = function tableFloatingCellButtonStyles(props) {
12
+ return css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n > div {\n // Sits behind button to provide surface-color background\n background: ", ";\n border-radius: ", "px;\n display: flex;\n height: ", "px;\n flex-direction: column;\n }\n && button {\n background: ", ";\n flex-direction: column;\n margin: 2px;\n outline: 2px solid ", ";\n border-radius: 1px;\n padding: 0;\n height: calc(100% - 4px);\n display: flex;\n }\n && button:hover {\n background: ", ";\n }\n && button:active {\n background: ", ";\n }\n && button > span {\n margin: 0px -4px;\n }\n && span {\n pointer-events: none;\n }\n"])), token('elevation.surface', N20), borderRadius(), contextualMenuTriggerSize + 2, themed({
13
+ light: token('color.background.neutral', 'none'),
14
+ dark: token('color.background.neutral', 'none')
15
+ })(props), token('color.border', N0), themed({
16
+ light: token('color.background.neutral.hovered', N30A),
17
+ dark: token('color.background.neutral.hovered', DN60)
18
+ })(props), themed({
19
+ light: token('color.background.neutral.pressed', 'rgba(179, 212, 255, 0.6)'),
20
+ dark: token('color.background.neutral.pressed', B75)
21
+ })(props));
22
+ };
23
+ export var tableFloatingCellButtonSelectedStyles = function tableFloatingCellButtonSelectedStyles(props) {
24
+ return css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n && button {\n background: ", ";\n }\n && button:hover {\n background: ", ";\n }\n && button:active {\n background: ", ";\n }\n"])), themed({
25
+ light: token('color.background.selected', N700),
26
+ dark: token('color.background.selected', DN0)
27
+ })(props), themed({
28
+ light: token('color.background.selected.hovered', N700),
29
+ dark: token('color.background.selected.hovered', DN0)
30
+ })(props), themed({
31
+ light: token('color.background.selected.pressed', N700),
32
+ dark: token('color.background.selected.pressed', DN0)
33
+ })(props));
34
+ };
@@ -474,7 +474,10 @@ export var ContextualMenu = /*#__PURE__*/function (_Component) {
474
474
  "data-testid": "table-cell-contextual-menu",
475
475
  onMouseLeave: this.closeSubmenu
476
476
  }, jsx(DropdownMenu, {
477
- mountTo: mountPoint,
477
+ mountTo: mountPoint //This needs be removed when the a11y is completely handled
478
+ //Disabling key navigation now as it works only partially
479
+ ,
480
+ disableArrowKeyNavigation: true,
478
481
  items: items,
479
482
  isOpen: isOpen,
480
483
  onOpenChange: this.handleOpenChange,