@atlaskit/editor-plugin-table 1.0.1 → 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.
Files changed (32) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/plugins/table/toolbar.js +24 -0
  3. package/dist/cjs/plugins/table/ui/FloatingContextualButton/styles.js +14 -16
  4. package/dist/cjs/plugins/table/ui/FloatingContextualMenu/styles.js +1 -3
  5. package/dist/cjs/plugins/table/ui/common-styles.js +1 -3
  6. package/dist/cjs/plugins/table/ui/consts.js +15 -17
  7. package/dist/cjs/plugins/table/ui/ui-styles.js +10 -12
  8. package/dist/cjs/plugins/table/utils/decoration.js +31 -1
  9. package/dist/cjs/version.json +1 -1
  10. package/dist/es2019/plugins/table/toolbar.js +25 -1
  11. package/dist/es2019/plugins/table/ui/FloatingContextualButton/styles.js +14 -15
  12. package/dist/es2019/plugins/table/ui/FloatingContextualMenu/styles.js +3 -4
  13. package/dist/es2019/plugins/table/ui/common-styles.js +20 -21
  14. package/dist/es2019/plugins/table/ui/consts.js +15 -16
  15. package/dist/es2019/plugins/table/ui/ui-styles.js +23 -24
  16. package/dist/es2019/plugins/table/utils/decoration.js +32 -2
  17. package/dist/es2019/version.json +1 -1
  18. package/dist/esm/plugins/table/toolbar.js +25 -1
  19. package/dist/esm/plugins/table/ui/FloatingContextualButton/styles.js +14 -15
  20. package/dist/esm/plugins/table/ui/FloatingContextualMenu/styles.js +1 -2
  21. package/dist/esm/plugins/table/ui/common-styles.js +1 -2
  22. package/dist/esm/plugins/table/ui/consts.js +15 -16
  23. package/dist/esm/plugins/table/ui/ui-styles.js +10 -11
  24. package/dist/esm/plugins/table/utils/decoration.js +32 -2
  25. package/dist/esm/version.json +1 -1
  26. package/package.json +4 -4
  27. package/report.api.md +15 -0
  28. package/src/__tests__/integration/__fixtures__/basic-table-with-merged-cell.ts +112 -0
  29. package/src/__tests__/integration/__snapshots__/floating-toolbar.ts.snap +292 -0
  30. package/src/__tests__/integration/floating-toolbar.ts +164 -8
  31. package/src/plugins/table/toolbar.tsx +23 -0
  32. package/src/plugins/table/utils/decoration.ts +27 -2
@@ -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