@atlaskit/editor-plugin-table 1.0.2 → 1.0.3

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @atlaskit/editor-plugin-table
2
2
 
3
+ ## 1.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`20117f2de5a`](https://bitbucket.org/atlassian/atlassian-frontend/commits/20117f2de5a) - [ux] ED-16204 Fix table cell options floating toolbar context menu closes after clicking on disabled options
8
+ - [`c6c0cab10e0`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c6c0cab10e0) - [ux] ED-16205 - Fix missing yellow highlight on merged table cells when hover sort column options on table floating toolbar
9
+ - [`e3b699e5069`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e3b699e5069) - ED-15794 - Fix merged cells in table not highlighting on delete hover when in bottom right corner
10
+ - [`746d7339a88`](https://bitbucket.org/atlassian/atlassian-frontend/commits/746d7339a88) - [ux] ED-15823 - Table cells on the second column would change their color upon unchecking "Header Column" table option when the selection cursor was placed in the 3rd column. This was caused by a view update not identifying the cells to update correctly. This was causing table data cells to be changed to table header cells.
11
+ - Updated dependencies
12
+
3
13
  ## 1.0.2
4
14
 
5
15
  ### Patch Changes
@@ -264,6 +264,18 @@ var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(editorSta
264
264
  options.push({
265
265
  id: 'editor.table.sortColumnAsc',
266
266
  title: formatMessage(_ContextualMenu.messages.sortColumnASC),
267
+ onMouseOver: function onMouseOver(state, dispatch) {
268
+ if ((0, _utils.getMergedCellsPositions)(state.tr).length !== 0) {
269
+ (0, _commands.hoverMergedCells)()(state, dispatch);
270
+ return true;
271
+ }
272
+
273
+ return false;
274
+ },
275
+ onMouseOut: function onMouseOut(state, dispatch) {
276
+ (0, _commands.clearHoverSelection)()(state, dispatch);
277
+ return true;
278
+ },
267
279
  onClick: function onClick(state, dispatch) {
268
280
  (0, _commandsWithAnalytics.sortColumnWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.FLOATING_TB, initialSelectionRect.left, _steps.TableSortOrder.ASC)(state, dispatch);
269
281
  return true;
@@ -275,6 +287,18 @@ var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(editorSta
275
287
  options.push({
276
288
  id: 'editor.table.sortColumnDesc',
277
289
  title: formatMessage(_ContextualMenu.messages.sortColumnDESC),
290
+ onMouseOver: function onMouseOver(state, dispatch) {
291
+ if ((0, _utils.getMergedCellsPositions)(state.tr).length !== 0) {
292
+ (0, _commands.hoverMergedCells)()(state, dispatch);
293
+ return true;
294
+ }
295
+
296
+ return false;
297
+ },
298
+ onMouseOut: function onMouseOut(state, dispatch) {
299
+ (0, _commands.clearHoverSelection)()(state, dispatch);
300
+ return true;
301
+ },
278
302
  onClick: function onClick(state, dispatch) {
279
303
  (0, _commandsWithAnalytics.sortColumnWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.FLOATING_TB, initialSelectionRect.left, _steps.TableSortOrder.DESC)(state, dispatch);
280
304
  return true;
@@ -89,7 +89,37 @@ var createControlsHoverDecoration = function createControlsHoverDecoration(cells
89
89
  // to match the "clicked" selection
90
90
 
91
91
  if (danger) {
92
- var rect = map.rectBetween(min - table.start, max - table.start);
92
+ // Find the bounding rectangle of all the given cells, also considering
93
+ // merged cells.
94
+ var _cells$reduce3 = cells.reduce(function (acc, cell) {
95
+ var _map$findCell = map.findCell(cell.pos - table.start),
96
+ left = _map$findCell.left,
97
+ right = _map$findCell.right,
98
+ bottom = _map$findCell.bottom,
99
+ top = _map$findCell.top; // Finding the bounding rect requires finding the min left and top positions,
100
+ // and the max right and bottom positions of the cells
101
+
102
+
103
+ return {
104
+ recLeft: Math.min(acc.recLeft, left),
105
+ recTop: Math.min(acc.recTop, top),
106
+ recRight: Math.max(acc.recRight, right),
107
+ recBottom: Math.max(acc.recBottom, bottom)
108
+ };
109
+ }, // +-Infinity as initialisation vars which will always be overwritten
110
+ // by smaller/larger values respectively
111
+ {
112
+ recLeft: Infinity,
113
+ recTop: Infinity,
114
+ recRight: -Infinity,
115
+ recBottom: -Infinity
116
+ }),
117
+ recLeft = _cells$reduce3.recLeft,
118
+ recTop = _cells$reduce3.recTop,
119
+ recRight = _cells$reduce3.recRight,
120
+ recBottom = _cells$reduce3.recBottom;
121
+
122
+ var rect = new _tableMap.Rect(recLeft, recTop, recRight, recBottom);
93
123
  updatedCells = map.cellsInRect(rect).map(function (x) {
94
124
  return x + table.start;
95
125
  });
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "sideEffects": false
5
5
  }
@@ -3,7 +3,7 @@ import { jsx } from '@emotion/react';
3
3
  import { defineMessages } from 'react-intl-next';
4
4
  import RemoveIcon from '@atlaskit/icon/glyph/editor/remove';
5
5
  import commonMessages from '@atlaskit/editor-common/messages';
6
- import { clearHoverSelection, hoverTable, hoverColumns, hoverRows, removeDescendantNodes } from './commands';
6
+ import { clearHoverSelection, hoverTable, hoverColumns, hoverRows, removeDescendantNodes, hoverMergedCells } from './commands';
7
7
  import { deleteTableWithAnalytics, toggleHeaderColumnWithAnalytics, toggleHeaderRowWithAnalytics, toggleNumberColumnWithAnalytics, insertRowWithAnalytics, deleteRowsWithAnalytics, mergeCellsWithAnalytics, splitCellWithAnalytics, deleteColumnsWithAnalytics, emptyMultipleCellsWithAnalytics, insertColumnWithAnalytics, wrapTableInExpandWithAnalytics, sortColumnWithAnalytics, setColorWithAnalytics, distributeColumnsWidthsWithAnalytics } from './commands-with-analytics';
8
8
  import { getPluginState } from './pm-plugins/plugin-factory';
9
9
  import { pluginKey as tableResizingPluginKey } from './pm-plugins/table-resizing';
@@ -229,6 +229,18 @@ export const getToolbarCellOptionsConfig = (editorState, editorView, initialSele
229
229
  options.push({
230
230
  id: 'editor.table.sortColumnAsc',
231
231
  title: formatMessage(ContextualMenuMessages.sortColumnASC),
232
+ onMouseOver: (state, dispatch) => {
233
+ if (getMergedCellsPositions(state.tr).length !== 0) {
234
+ hoverMergedCells()(state, dispatch);
235
+ return true;
236
+ }
237
+
238
+ return false;
239
+ },
240
+ onMouseOut: (state, dispatch) => {
241
+ clearHoverSelection()(state, dispatch);
242
+ return true;
243
+ },
232
244
  onClick: (state, dispatch) => {
233
245
  sortColumnWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.FLOATING_TB, initialSelectionRect.left, SortOrder.ASC)(state, dispatch);
234
246
  return true;
@@ -240,6 +252,18 @@ export const getToolbarCellOptionsConfig = (editorState, editorView, initialSele
240
252
  options.push({
241
253
  id: 'editor.table.sortColumnDesc',
242
254
  title: formatMessage(ContextualMenuMessages.sortColumnDESC),
255
+ onMouseOver: (state, dispatch) => {
256
+ if (getMergedCellsPositions(state.tr).length !== 0) {
257
+ hoverMergedCells()(state, dispatch);
258
+ return true;
259
+ }
260
+
261
+ return false;
262
+ },
263
+ onMouseOut: (state, dispatch) => {
264
+ clearHoverSelection()(state, dispatch);
265
+ return true;
266
+ },
243
267
  onClick: (state, dispatch) => {
244
268
  sortColumnWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.FLOATING_TB, initialSelectionRect.left, SortOrder.DESC)(state, dispatch);
245
269
  return true;
@@ -1,4 +1,4 @@
1
- import { TableMap } from '@atlaskit/editor-tables/table-map';
1
+ import { Rect, TableMap } from '@atlaskit/editor-tables/table-map';
2
2
  import { findTable, getCellsInRow, getSelectionRect } from '@atlaskit/editor-tables/utils';
3
3
  import { Decoration } from 'prosemirror-view';
4
4
  import { nonNullable } from '@atlaskit/editor-common/utils';
@@ -43,7 +43,37 @@ export const createControlsHoverDecoration = (cells, type, tr, danger, selected)
43
43
  // to match the "clicked" selection
44
44
 
45
45
  if (danger) {
46
- const rect = map.rectBetween(min - table.start, max - table.start);
46
+ // Find the bounding rectangle of all the given cells, also considering
47
+ // merged cells.
48
+ const {
49
+ recLeft,
50
+ recTop,
51
+ recRight,
52
+ recBottom
53
+ } = cells.reduce((acc, cell) => {
54
+ const {
55
+ left,
56
+ right,
57
+ bottom,
58
+ top
59
+ } = map.findCell(cell.pos - table.start); // Finding the bounding rect requires finding the min left and top positions,
60
+ // and the max right and bottom positions of the cells
61
+
62
+ return {
63
+ recLeft: Math.min(acc.recLeft, left),
64
+ recTop: Math.min(acc.recTop, top),
65
+ recRight: Math.max(acc.recRight, right),
66
+ recBottom: Math.max(acc.recBottom, bottom)
67
+ };
68
+ }, // +-Infinity as initialisation vars which will always be overwritten
69
+ // by smaller/larger values respectively
70
+ {
71
+ recLeft: Infinity,
72
+ recTop: Infinity,
73
+ recRight: -Infinity,
74
+ recBottom: -Infinity
75
+ });
76
+ const rect = new Rect(recLeft, recTop, recRight, recBottom);
47
77
  updatedCells = map.cellsInRect(rect).map(x => x + table.start);
48
78
  }
49
79
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "sideEffects": false
5
5
  }
@@ -5,7 +5,7 @@ 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, hoverColumns, hoverRows, removeDescendantNodes } from './commands';
8
+ import { clearHoverSelection, hoverTable, hoverColumns, hoverRows, removeDescendantNodes, hoverMergedCells } 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';
@@ -229,6 +229,18 @@ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(ed
229
229
  options.push({
230
230
  id: 'editor.table.sortColumnAsc',
231
231
  title: formatMessage(ContextualMenuMessages.sortColumnASC),
232
+ onMouseOver: function onMouseOver(state, dispatch) {
233
+ if (getMergedCellsPositions(state.tr).length !== 0) {
234
+ hoverMergedCells()(state, dispatch);
235
+ return true;
236
+ }
237
+
238
+ return false;
239
+ },
240
+ onMouseOut: function onMouseOut(state, dispatch) {
241
+ clearHoverSelection()(state, dispatch);
242
+ return true;
243
+ },
232
244
  onClick: function onClick(state, dispatch) {
233
245
  sortColumnWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.FLOATING_TB, initialSelectionRect.left, SortOrder.ASC)(state, dispatch);
234
246
  return true;
@@ -240,6 +252,18 @@ export var getToolbarCellOptionsConfig = function getToolbarCellOptionsConfig(ed
240
252
  options.push({
241
253
  id: 'editor.table.sortColumnDesc',
242
254
  title: formatMessage(ContextualMenuMessages.sortColumnDESC),
255
+ onMouseOver: function onMouseOver(state, dispatch) {
256
+ if (getMergedCellsPositions(state.tr).length !== 0) {
257
+ hoverMergedCells()(state, dispatch);
258
+ return true;
259
+ }
260
+
261
+ return false;
262
+ },
263
+ onMouseOut: function onMouseOut(state, dispatch) {
264
+ clearHoverSelection()(state, dispatch);
265
+ return true;
266
+ },
243
267
  onClick: function onClick(state, dispatch) {
244
268
  sortColumnWithAnalytics(editorAnalyticsAPI)(INPUT_METHOD.FLOATING_TB, initialSelectionRect.left, SortOrder.DESC)(state, dispatch);
245
269
  return true;
@@ -1,5 +1,5 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import { TableMap } from '@atlaskit/editor-tables/table-map';
2
+ import { Rect, TableMap } from '@atlaskit/editor-tables/table-map';
3
3
  import { findTable, getCellsInRow, getSelectionRect } from '@atlaskit/editor-tables/utils';
4
4
  import { Decoration } from 'prosemirror-view';
5
5
  import { nonNullable } from '@atlaskit/editor-common/utils';
@@ -66,7 +66,37 @@ export var createControlsHoverDecoration = function createControlsHoverDecoratio
66
66
  // to match the "clicked" selection
67
67
 
68
68
  if (danger) {
69
- var rect = map.rectBetween(min - table.start, max - table.start);
69
+ // Find the bounding rectangle of all the given cells, also considering
70
+ // merged cells.
71
+ var _cells$reduce3 = cells.reduce(function (acc, cell) {
72
+ var _map$findCell = map.findCell(cell.pos - table.start),
73
+ left = _map$findCell.left,
74
+ right = _map$findCell.right,
75
+ bottom = _map$findCell.bottom,
76
+ top = _map$findCell.top; // Finding the bounding rect requires finding the min left and top positions,
77
+ // and the max right and bottom positions of the cells
78
+
79
+
80
+ return {
81
+ recLeft: Math.min(acc.recLeft, left),
82
+ recTop: Math.min(acc.recTop, top),
83
+ recRight: Math.max(acc.recRight, right),
84
+ recBottom: Math.max(acc.recBottom, bottom)
85
+ };
86
+ }, // +-Infinity as initialisation vars which will always be overwritten
87
+ // by smaller/larger values respectively
88
+ {
89
+ recLeft: Infinity,
90
+ recTop: Infinity,
91
+ recRight: -Infinity,
92
+ recBottom: -Infinity
93
+ }),
94
+ recLeft = _cells$reduce3.recLeft,
95
+ recTop = _cells$reduce3.recTop,
96
+ recRight = _cells$reduce3.recRight,
97
+ recBottom = _cells$reduce3.recBottom;
98
+
99
+ var rect = new Rect(recLeft, recTop, recRight, recBottom);
70
100
  updatedCells = map.cellsInRect(rect).map(function (x) {
71
101
  return x + table.start;
72
102
  });
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "sideEffects": false
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Table plugin for the @atlaskit/editor",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -18,8 +18,8 @@
18
18
  "releaseModel": "scheduled"
19
19
  },
20
20
  "dependencies": {
21
- "@atlaskit/adf-schema": "^25.0.0",
22
- "@atlaskit/editor-common": "^72.0.0",
21
+ "@atlaskit/adf-schema": "^25.1.0",
22
+ "@atlaskit/editor-common": "^72.1.0",
23
23
  "@atlaskit/editor-shared-styles": "^2.3.0",
24
24
  "@atlaskit/editor-tables": "^2.2.0",
25
25
  "@atlaskit/icon": "^21.11.0",
@@ -51,7 +51,7 @@
51
51
  "devDependencies": {
52
52
  "@atlaskit/analytics-next": "^8.3.3",
53
53
  "@atlaskit/button": "^16.5.0",
54
- "@atlaskit/editor-core": "^177.0.0",
54
+ "@atlaskit/editor-core": "^178.0.0",
55
55
  "@atlaskit/editor-test-helpers": "^18.0.0",
56
56
  "@atlaskit/link-provider": "^1.3.0",
57
57
  "@atlaskit/logo": "^13.10.0",
package/report.api.md CHANGED
@@ -8,6 +8,7 @@
8
8
  ### Table of contents
9
9
 
10
10
  - [Main Entry Types](#main-entry-types)
11
+ - [Peer Dependencies](#peer-dependencies)
11
12
 
12
13
  ### Main Entry Types
13
14
 
@@ -102,3 +103,17 @@ export const tablesPlugin: NextEditorPlugin<
102
103
  ```
103
104
 
104
105
  <!--SECTION END: Main Entry Types-->
106
+
107
+ ### Peer Dependencies
108
+
109
+ <!--SECTION START: Peer Dependencies-->
110
+
111
+ ```json
112
+ {
113
+ "react": "^16.8.0",
114
+ "react-dom": "^16.8.0",
115
+ "react-intl-next": "npm:react-intl@^5.18.1"
116
+ }
117
+ ```
118
+
119
+ <!--SECTION END: Peer Dependencies-->
@@ -0,0 +1,112 @@
1
+ export default {
2
+ version: 1,
3
+ type: 'doc',
4
+ content: [
5
+ {
6
+ type: 'table',
7
+ attrs: {
8
+ isNumberColumnEnabled: false,
9
+ layout: 'default',
10
+ },
11
+ content: [
12
+ {
13
+ type: 'tableRow',
14
+ content: [
15
+ {
16
+ type: 'tableHeader',
17
+ attrs: {},
18
+ content: [
19
+ {
20
+ type: 'paragraph',
21
+ content: [],
22
+ },
23
+ ],
24
+ },
25
+ {
26
+ type: 'tableHeader',
27
+ attrs: {},
28
+ content: [
29
+ {
30
+ type: 'paragraph',
31
+ content: [],
32
+ },
33
+ ],
34
+ },
35
+ {
36
+ type: 'tableHeader',
37
+ attrs: {},
38
+ content: [
39
+ {
40
+ type: 'paragraph',
41
+ content: [],
42
+ },
43
+ ],
44
+ },
45
+ ],
46
+ },
47
+ {
48
+ type: 'tableRow',
49
+ content: [
50
+ {
51
+ type: 'tableCell',
52
+ attrs: {},
53
+ content: [
54
+ {
55
+ type: 'paragraph',
56
+ content: [],
57
+ },
58
+ ],
59
+ },
60
+ {
61
+ type: 'tableCell',
62
+ attrs: {},
63
+ content: [
64
+ {
65
+ type: 'paragraph',
66
+ content: [],
67
+ },
68
+ ],
69
+ },
70
+ {
71
+ type: 'tableCell',
72
+ attrs: {},
73
+ content: [
74
+ {
75
+ type: 'paragraph',
76
+ content: [],
77
+ },
78
+ ],
79
+ },
80
+ ],
81
+ },
82
+ {
83
+ type: 'tableRow',
84
+ content: [
85
+ {
86
+ type: 'tableCell',
87
+ attrs: {},
88
+ content: [
89
+ {
90
+ type: 'paragraph',
91
+ content: [],
92
+ },
93
+ ],
94
+ },
95
+ {
96
+ type: 'tableCell',
97
+ attrs: {
98
+ colspan: 2,
99
+ },
100
+ content: [
101
+ {
102
+ type: 'paragraph',
103
+ content: [],
104
+ },
105
+ ],
106
+ },
107
+ ],
108
+ },
109
+ ],
110
+ },
111
+ ],
112
+ };
@@ -319,3 +319,295 @@ Object {
319
319
  "type": "doc",
320
320
  }
321
321
  `;
322
+
323
+ exports[`should show yellow highlight on the megred rows when hover disabled sort column ASC menu option 1`] = `
324
+ Object {
325
+ "content": Array [
326
+ Object {
327
+ "attrs": Object {
328
+ "__autoSize": false,
329
+ "isNumberColumnEnabled": false,
330
+ "layout": "default",
331
+ "localId": "abc-123",
332
+ },
333
+ "content": Array [
334
+ Object {
335
+ "content": Array [
336
+ Object {
337
+ "attrs": Object {
338
+ "background": null,
339
+ "colspan": 1,
340
+ "colwidth": null,
341
+ "rowspan": 1,
342
+ },
343
+ "content": Array [
344
+ Object {
345
+ "type": "paragraph",
346
+ },
347
+ ],
348
+ "type": "tableHeader",
349
+ },
350
+ Object {
351
+ "attrs": Object {
352
+ "background": null,
353
+ "colspan": 1,
354
+ "colwidth": null,
355
+ "rowspan": 1,
356
+ },
357
+ "content": Array [
358
+ Object {
359
+ "type": "paragraph",
360
+ },
361
+ ],
362
+ "type": "tableHeader",
363
+ },
364
+ Object {
365
+ "attrs": Object {
366
+ "background": null,
367
+ "colspan": 1,
368
+ "colwidth": null,
369
+ "rowspan": 1,
370
+ },
371
+ "content": Array [
372
+ Object {
373
+ "type": "paragraph",
374
+ },
375
+ ],
376
+ "type": "tableHeader",
377
+ },
378
+ ],
379
+ "type": "tableRow",
380
+ },
381
+ Object {
382
+ "content": Array [
383
+ Object {
384
+ "attrs": Object {
385
+ "background": null,
386
+ "colspan": 1,
387
+ "colwidth": null,
388
+ "rowspan": 1,
389
+ },
390
+ "content": Array [
391
+ Object {
392
+ "type": "paragraph",
393
+ },
394
+ ],
395
+ "type": "tableCell",
396
+ },
397
+ Object {
398
+ "attrs": Object {
399
+ "background": null,
400
+ "colspan": 1,
401
+ "colwidth": null,
402
+ "rowspan": 1,
403
+ },
404
+ "content": Array [
405
+ Object {
406
+ "type": "paragraph",
407
+ },
408
+ ],
409
+ "type": "tableCell",
410
+ },
411
+ Object {
412
+ "attrs": Object {
413
+ "background": null,
414
+ "colspan": 1,
415
+ "colwidth": null,
416
+ "rowspan": 1,
417
+ },
418
+ "content": Array [
419
+ Object {
420
+ "type": "paragraph",
421
+ },
422
+ ],
423
+ "type": "tableCell",
424
+ },
425
+ ],
426
+ "type": "tableRow",
427
+ },
428
+ Object {
429
+ "content": Array [
430
+ Object {
431
+ "attrs": Object {
432
+ "background": null,
433
+ "colspan": 1,
434
+ "colwidth": null,
435
+ "rowspan": 1,
436
+ },
437
+ "content": Array [
438
+ Object {
439
+ "type": "paragraph",
440
+ },
441
+ ],
442
+ "type": "tableCell",
443
+ },
444
+ Object {
445
+ "attrs": Object {
446
+ "background": null,
447
+ "colspan": 2,
448
+ "colwidth": null,
449
+ "rowspan": 1,
450
+ },
451
+ "content": Array [
452
+ Object {
453
+ "type": "paragraph",
454
+ },
455
+ ],
456
+ "type": "tableCell",
457
+ },
458
+ ],
459
+ "type": "tableRow",
460
+ },
461
+ ],
462
+ "type": "table",
463
+ },
464
+ ],
465
+ "type": "doc",
466
+ }
467
+ `;
468
+
469
+ exports[`should show yellow highlight on the megred rows when hover disabled sort column DESC menu option 1`] = `
470
+ Object {
471
+ "content": Array [
472
+ Object {
473
+ "attrs": Object {
474
+ "__autoSize": false,
475
+ "isNumberColumnEnabled": false,
476
+ "layout": "default",
477
+ "localId": "abc-123",
478
+ },
479
+ "content": Array [
480
+ Object {
481
+ "content": Array [
482
+ Object {
483
+ "attrs": Object {
484
+ "background": null,
485
+ "colspan": 1,
486
+ "colwidth": null,
487
+ "rowspan": 1,
488
+ },
489
+ "content": Array [
490
+ Object {
491
+ "type": "paragraph",
492
+ },
493
+ ],
494
+ "type": "tableHeader",
495
+ },
496
+ Object {
497
+ "attrs": Object {
498
+ "background": null,
499
+ "colspan": 1,
500
+ "colwidth": null,
501
+ "rowspan": 1,
502
+ },
503
+ "content": Array [
504
+ Object {
505
+ "type": "paragraph",
506
+ },
507
+ ],
508
+ "type": "tableHeader",
509
+ },
510
+ Object {
511
+ "attrs": Object {
512
+ "background": null,
513
+ "colspan": 1,
514
+ "colwidth": null,
515
+ "rowspan": 1,
516
+ },
517
+ "content": Array [
518
+ Object {
519
+ "type": "paragraph",
520
+ },
521
+ ],
522
+ "type": "tableHeader",
523
+ },
524
+ ],
525
+ "type": "tableRow",
526
+ },
527
+ Object {
528
+ "content": Array [
529
+ Object {
530
+ "attrs": Object {
531
+ "background": null,
532
+ "colspan": 1,
533
+ "colwidth": null,
534
+ "rowspan": 1,
535
+ },
536
+ "content": Array [
537
+ Object {
538
+ "type": "paragraph",
539
+ },
540
+ ],
541
+ "type": "tableCell",
542
+ },
543
+ Object {
544
+ "attrs": Object {
545
+ "background": null,
546
+ "colspan": 1,
547
+ "colwidth": null,
548
+ "rowspan": 1,
549
+ },
550
+ "content": Array [
551
+ Object {
552
+ "type": "paragraph",
553
+ },
554
+ ],
555
+ "type": "tableCell",
556
+ },
557
+ Object {
558
+ "attrs": Object {
559
+ "background": null,
560
+ "colspan": 1,
561
+ "colwidth": null,
562
+ "rowspan": 1,
563
+ },
564
+ "content": Array [
565
+ Object {
566
+ "type": "paragraph",
567
+ },
568
+ ],
569
+ "type": "tableCell",
570
+ },
571
+ ],
572
+ "type": "tableRow",
573
+ },
574
+ Object {
575
+ "content": Array [
576
+ Object {
577
+ "attrs": Object {
578
+ "background": null,
579
+ "colspan": 1,
580
+ "colwidth": null,
581
+ "rowspan": 1,
582
+ },
583
+ "content": Array [
584
+ Object {
585
+ "type": "paragraph",
586
+ },
587
+ ],
588
+ "type": "tableCell",
589
+ },
590
+ Object {
591
+ "attrs": Object {
592
+ "background": null,
593
+ "colspan": 2,
594
+ "colwidth": null,
595
+ "rowspan": 1,
596
+ },
597
+ "content": Array [
598
+ Object {
599
+ "type": "paragraph",
600
+ },
601
+ ],
602
+ "type": "tableCell",
603
+ },
604
+ ],
605
+ "type": "tableRow",
606
+ },
607
+ ],
608
+ "type": "table",
609
+ },
610
+ ],
611
+ "type": "doc",
612
+ }
613
+ `;
@@ -17,6 +17,7 @@ import { BrowserTestCase } from '@atlaskit/webdriver-runner/runner';
17
17
  import { TableCssClassName } from '../../plugins/table/types';
18
18
  import basicTable from './__fixtures__/basic-table';
19
19
  import { documentWithMergedCells } from './__fixtures__/merged-rows-and-cols-document';
20
+ import basicTableWithMergedCell from './__fixtures__/basic-table-with-merged-cell';
20
21
 
21
22
  BrowserTestCase(
22
23
  'should floating toolbar context menu sit above other context menu layers',
@@ -187,10 +188,8 @@ BrowserTestCase(
187
188
  defaultValue: documentWithMergedCells,
188
189
  });
189
190
  const tableFloatingToolbarContextMenuSelector = `div[aria-label="Table floating controls"][data-editor-popup=true]`;
190
- const sortAtoZButtonSelector =
191
+ const sortColumnButtonSelector =
191
192
  'div[data-role=droplistContent] div[role=presentation]';
192
- const sortZtoAButtonSelector =
193
- 'div[data-role=droplistContent] div[role=presentation]:nth-of-type(2)';
194
193
  const tooltipSelector = 'div.atlaskit-portal div[role=tooltip]';
195
194
 
196
195
  // Click on the cell on the table
@@ -206,18 +205,175 @@ BrowserTestCase(
206
205
  // No tooltip is shown
207
206
  expect((await page.$$(tooltipSelector)).length).toBe(0);
208
207
 
209
- // Hover Sort column A -> Z button then it should show tooltip
210
- const sortAtoZButton = await page.$(sortAtoZButtonSelector);
211
- await sortAtoZButton.moveTo();
208
+ // Expect there are 2 sort column tooltip menu option
209
+ const sortColumnButtons = await page.$$(sortColumnButtonSelector);
210
+ expect(sortColumnButtons.length).toBe(2);
212
211
  const tooltip = await page.$(tooltipSelector);
212
+
213
+ // Hover Sort column A -> Z button then it should show tooltip, and should be removed after mouseout
214
+ const sortAtoZButton = sortColumnButtons[0];
215
+ await sortAtoZButton.moveTo();
213
216
  await tooltip.waitForExist();
214
217
  expect((await page.$$(tooltipSelector)).length).toBe(1);
218
+ await cellOptionsMenuItem.moveTo();
219
+ await tooltip.waitUntil(async () => {
220
+ return (await page.$$(tooltipSelector)).length === 0;
221
+ });
215
222
 
216
- // Tooltip should be removed after mouseout to next button
217
- const sortZtoAButton = await page.$(sortZtoAButtonSelector);
223
+ // Hover Sort column Z -> A button then it should show tooltip, and should be removed after mouseout
224
+ const sortZtoAButton = sortColumnButtons[1];
218
225
  await sortZtoAButton.moveTo();
226
+ await tooltip.waitForExist();
227
+ expect((await page.$$(tooltipSelector)).length).toBe(1);
228
+ await cellOptionsMenuItem.moveTo();
219
229
  await tooltip.waitUntil(async () => {
220
230
  return (await page.$$(tooltipSelector)).length === 0;
221
231
  });
222
232
  },
223
233
  );
234
+
235
+ BrowserTestCase(
236
+ 'should show yellow highlight on the megred rows when hover disabled sort column ASC menu option',
237
+ { skip: ['safari'] }, // The test does not pass on CI but works on physical browser
238
+ async (client: any, testName: string) => {
239
+ const page = await goToEditorTestingWDExample(
240
+ client,
241
+ 'editor-plugin-table',
242
+ );
243
+ await mountEditor(page, {
244
+ appearance: fullpage.appearance,
245
+ allowTables: {
246
+ allowColumnSorting: true,
247
+ allowDistributeColumns: true,
248
+ allowCellOptionsInFloatingToolbar: true,
249
+ },
250
+ defaultValue: basicTableWithMergedCell,
251
+ });
252
+ const tableFloatingToolbarContextMenuSelector = `div[aria-label="Table floating controls"][data-editor-popup=true]`;
253
+
254
+ // Click on the cell on the table
255
+ await clickFirstCell(page);
256
+
257
+ // Table floating toolbar should appear, then hover on "Cell Options", which brings up another context menu
258
+ const cellOptionsMenuItem = await (
259
+ await page.$(tableFloatingToolbarContextMenuSelector)
260
+ ).$(`button=${tableSelectors.cellOptionsFloatingToolbarText}`);
261
+ await cellOptionsMenuItem.waitForClickable();
262
+ await cellOptionsMenuItem.click();
263
+
264
+ // Hover on the "Sort column ASC" menu option on the context menu
265
+ const sortColumnAscMenuItem = await (
266
+ await page.$(tableFloatingToolbarContextMenuSelector)
267
+ ).$(`button=${tableSelectors.sortColumnASC}`);
268
+ await sortColumnAscMenuItem.moveTo();
269
+ await animationFrame(page);
270
+
271
+ // Check there the yellow highlight background on the merged cells.
272
+ const highlightedCell = await page.$$(
273
+ `tbody tr:nth-child(3) td.${TableCssClassName.HOVERED_CELL_WARNING}`,
274
+ );
275
+ expect(highlightedCell.length).toBe(1);
276
+ await animationFrame(page);
277
+
278
+ const doc = await page.$eval(editable, getDocFromElement);
279
+ expect(doc).toMatchCustomDocSnapshot(testName);
280
+ },
281
+ );
282
+
283
+ BrowserTestCase(
284
+ 'should show yellow highlight on the megred rows when hover disabled sort column DESC menu option',
285
+ { skip: ['safari'] }, // The test does not pass on CI but works on physical browser
286
+ async (client: any, testName: string) => {
287
+ const page = await goToEditorTestingWDExample(
288
+ client,
289
+ 'editor-plugin-table',
290
+ );
291
+ await mountEditor(page, {
292
+ appearance: fullpage.appearance,
293
+ allowTables: {
294
+ allowColumnSorting: true,
295
+ allowDistributeColumns: true,
296
+ allowCellOptionsInFloatingToolbar: true,
297
+ },
298
+ defaultValue: basicTableWithMergedCell,
299
+ });
300
+ const tableFloatingToolbarContextMenuSelector = `div[aria-label="Table floating controls"][data-editor-popup=true]`;
301
+
302
+ // Click on the cell on the table
303
+ await clickFirstCell(page);
304
+
305
+ // Table floating toolbar should appear, then hover on "Cell Options", which brings up another context menu
306
+ const cellOptionsMenuItem = await (
307
+ await page.$(tableFloatingToolbarContextMenuSelector)
308
+ ).$(`button=${tableSelectors.cellOptionsFloatingToolbarText}`);
309
+ await cellOptionsMenuItem.waitForClickable();
310
+ await cellOptionsMenuItem.click();
311
+
312
+ // Hover on the "Sort column DESC" menu option on the context menu
313
+ const sortColumnDescMenuItem = await (
314
+ await page.$(tableFloatingToolbarContextMenuSelector)
315
+ ).$(`button=${tableSelectors.sortColumnDESC}`);
316
+ await sortColumnDescMenuItem.moveTo();
317
+ await animationFrame(page);
318
+
319
+ // Check there the yellow highlight background on the merged cells.
320
+ const highlightedCell = await page.$$(
321
+ `tbody tr:nth-child(3) td.${TableCssClassName.HOVERED_CELL_WARNING}`,
322
+ );
323
+ expect(highlightedCell.length).toBe(1);
324
+ await animationFrame(page);
325
+
326
+ const doc = await page.$eval(editable, getDocFromElement);
327
+ expect(doc).toMatchCustomDocSnapshot(testName);
328
+ },
329
+ );
330
+
331
+ BrowserTestCase(
332
+ 'should the context menu disabled item stay open when clicked.',
333
+ { skip: ['safari'] }, // The test does not pass on CI but works on physical browser
334
+ async (client: any, testName: string) => {
335
+ const page = await goToEditorTestingWDExample(
336
+ client,
337
+ 'editor-plugin-table',
338
+ );
339
+ await mountEditor(page, {
340
+ appearance: fullpage.appearance,
341
+ allowTables: {
342
+ allowColumnSorting: true,
343
+ allowDistributeColumns: true,
344
+ allowCellOptionsInFloatingToolbar: true,
345
+ },
346
+ defaultValue: basicTable,
347
+ });
348
+ const tableFloatingToolbarContextMenuSelector = `div[aria-label="Table floating controls"][data-editor-popup=true]`;
349
+
350
+ // First click on the cell
351
+ await clickFirstCell(page);
352
+
353
+ // Table floating toolbar should appear, then click on "Cell Options", which brings up another context menu
354
+ const tableFloatingToolbar = await page.$(
355
+ tableFloatingToolbarContextMenuSelector,
356
+ );
357
+ tableFloatingToolbar.waitForExist();
358
+ await animationFrame(page);
359
+
360
+ const cellOptionsMenuItem = await tableFloatingToolbar.$(
361
+ `button=${tableSelectors.cellOptionsFloatingToolbarText}`,
362
+ );
363
+ await cellOptionsMenuItem.waitForClickable();
364
+ await cellOptionsMenuItem.click();
365
+ await animationFrame(page);
366
+
367
+ // Hover on the "Merge Cell" menu option on the context menu (which should be disabled)
368
+ const mergeCellsMenuItem = await tableFloatingToolbar.$(
369
+ `button=${tableSelectors.mergeCellsText}`,
370
+ );
371
+ expect(await mergeCellsMenuItem.getAttribute('disabled')).toBe('true');
372
+ await mergeCellsMenuItem.moveTo();
373
+ await mergeCellsMenuItem.click();
374
+ await animationFrame(page);
375
+
376
+ // The context menu should remains open, thus the menu item should still be visible
377
+ expect(await mergeCellsMenuItem.isDisplayed()).toBe(true);
378
+ },
379
+ );
@@ -23,6 +23,7 @@ import {
23
23
  hoverColumns,
24
24
  hoverRows,
25
25
  removeDescendantNodes,
26
+ hoverMergedCells,
26
27
  } from './commands';
27
28
  import {
28
29
  deleteTableWithAnalytics,
@@ -339,6 +340,17 @@ export const getToolbarCellOptionsConfig = (
339
340
  options.push({
340
341
  id: 'editor.table.sortColumnAsc',
341
342
  title: formatMessage(ContextualMenuMessages.sortColumnASC),
343
+ onMouseOver: (state: EditorState, dispatch?: CommandDispatch) => {
344
+ if (getMergedCellsPositions(state.tr).length !== 0) {
345
+ hoverMergedCells()(state, dispatch);
346
+ return true;
347
+ }
348
+ return false;
349
+ },
350
+ onMouseOut: (state: EditorState, dispatch?: CommandDispatch) => {
351
+ clearHoverSelection()(state, dispatch);
352
+ return true;
353
+ },
342
354
  onClick: (state: EditorState, dispatch?: CommandDispatch) => {
343
355
  sortColumnWithAnalytics(editorAnalyticsAPI)(
344
356
  INPUT_METHOD.FLOATING_TB,
@@ -355,6 +367,17 @@ export const getToolbarCellOptionsConfig = (
355
367
  options.push({
356
368
  id: 'editor.table.sortColumnDesc',
357
369
  title: formatMessage(ContextualMenuMessages.sortColumnDESC),
370
+ onMouseOver: (state: EditorState, dispatch?: CommandDispatch) => {
371
+ if (getMergedCellsPositions(state.tr).length !== 0) {
372
+ hoverMergedCells()(state, dispatch);
373
+ return true;
374
+ }
375
+ return false;
376
+ },
377
+ onMouseOut: (state: EditorState, dispatch?: CommandDispatch) => {
378
+ clearHoverSelection()(state, dispatch);
379
+ return true;
380
+ },
358
381
  onClick: (state: EditorState, dispatch?: CommandDispatch) => {
359
382
  sortColumnWithAnalytics(editorAnalyticsAPI)(
360
383
  INPUT_METHOD.FLOATING_TB,
@@ -1,6 +1,6 @@
1
1
  import { Node as PmNode } from 'prosemirror-model';
2
2
  import { Selection, Transaction, ReadonlyTransaction } from 'prosemirror-state';
3
- import { TableMap } from '@atlaskit/editor-tables/table-map';
3
+ import { Rect, TableMap } from '@atlaskit/editor-tables/table-map';
4
4
  import { ContentNodeWithPos } from 'prosemirror-utils';
5
5
  import {
6
6
  findTable,
@@ -96,7 +96,32 @@ export const createControlsHoverDecoration = (
96
96
  // to match the "clicked" selection
97
97
 
98
98
  if (danger) {
99
- const rect = map.rectBetween(min - table.start, max - table.start);
99
+ // Find the bounding rectangle of all the given cells, also considering
100
+ // merged cells.
101
+ const { recLeft, recTop, recRight, recBottom } = cells.reduce(
102
+ (acc, cell) => {
103
+ const { left, right, bottom, top } = map.findCell(
104
+ cell.pos - table.start,
105
+ );
106
+ // Finding the bounding rect requires finding the min left and top positions,
107
+ // and the max right and bottom positions of the cells
108
+ return {
109
+ recLeft: Math.min(acc.recLeft, left),
110
+ recTop: Math.min(acc.recTop, top),
111
+ recRight: Math.max(acc.recRight, right),
112
+ recBottom: Math.max(acc.recBottom, bottom),
113
+ };
114
+ },
115
+ // +-Infinity as initialisation vars which will always be overwritten
116
+ // by smaller/larger values respectively
117
+ {
118
+ recLeft: Infinity,
119
+ recTop: Infinity,
120
+ recRight: -Infinity,
121
+ recBottom: -Infinity,
122
+ },
123
+ );
124
+ const rect = new Rect(recLeft, recTop, recRight, recBottom);
100
125
  updatedCells = map.cellsInRect(rect).map((x) => x + table.start);
101
126
  }
102
127