@atlaskit/editor-plugin-table 1.2.1 → 1.2.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 (67) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/i18n/en.js +43 -0
  3. package/dist/cjs/i18n/en_GB.js +43 -0
  4. package/dist/cjs/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
  5. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +17 -1
  6. package/dist/cjs/plugins/table/nodeviews/table.js +7 -0
  7. package/dist/cjs/plugins/table/transforms/delete-rows.js +1 -1
  8. package/dist/cjs/plugins/table/transforms/index.js +3 -3
  9. package/dist/cjs/plugins/table/transforms/merge.js +39 -54
  10. package/dist/cjs/plugins/table/ui/common-styles.js +12 -6
  11. package/dist/cjs/plugins/table/utils/row-controls.js +3 -2
  12. package/dist/cjs/version.json +1 -1
  13. package/dist/es2019/i18n/en.js +36 -0
  14. package/dist/es2019/i18n/en_GB.js +36 -0
  15. package/dist/es2019/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
  16. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +21 -1
  17. package/dist/es2019/plugins/table/nodeviews/table.js +7 -0
  18. package/dist/es2019/plugins/table/transforms/delete-rows.js +2 -2
  19. package/dist/es2019/plugins/table/transforms/index.js +1 -1
  20. package/dist/es2019/plugins/table/transforms/merge.js +39 -43
  21. package/dist/es2019/plugins/table/ui/common-styles.js +50 -8
  22. package/dist/es2019/plugins/table/utils/row-controls.js +3 -2
  23. package/dist/es2019/version.json +1 -1
  24. package/dist/esm/i18n/en.js +36 -0
  25. package/dist/esm/i18n/en_GB.js +36 -0
  26. package/dist/esm/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
  27. package/dist/esm/plugins/table/nodeviews/TableComponent.js +17 -1
  28. package/dist/esm/plugins/table/nodeviews/table.js +7 -0
  29. package/dist/esm/plugins/table/transforms/delete-rows.js +2 -2
  30. package/dist/esm/plugins/table/transforms/index.js +1 -1
  31. package/dist/esm/plugins/table/transforms/merge.js +38 -53
  32. package/dist/esm/plugins/table/ui/common-styles.js +12 -6
  33. package/dist/esm/plugins/table/utils/row-controls.js +3 -2
  34. package/dist/esm/version.json +1 -1
  35. package/dist/types/i18n/en.d.ts +35 -0
  36. package/dist/types/i18n/en_GB.d.ts +35 -0
  37. package/dist/types/plugins/table/nodeviews/OverflowShadowsObserver.d.ts +4 -5
  38. package/dist/types/plugins/table/nodeviews/TableComponent.d.ts +1 -0
  39. package/dist/types/plugins/table/nodeviews/__mocks__/OverflowShadowsObserver.d.ts +3 -3
  40. package/dist/types/plugins/table/transforms/index.d.ts +1 -1
  41. package/dist/types/plugins/table/transforms/merge.d.ts +1 -1
  42. package/dist/types/plugins/table/types.d.ts +2 -0
  43. package/package.json +7 -6
  44. package/src/__tests__/integration/__fixtures__/table-and-paragraph-adf.ts +130 -0
  45. package/src/__tests__/integration/horizontal-scroll-shadows.ts +199 -0
  46. package/src/__tests__/integration/meta-arrowup-cursor-in-first-row.ts +4 -2
  47. package/src/__tests__/unit/commands/sort.ts +4 -0
  48. package/src/__tests__/unit/commands.ts +2 -0
  49. package/src/__tests__/unit/index.ts +2 -0
  50. package/src/__tests__/unit/keymap.ts +4 -2
  51. package/src/__tests__/unit/layout.ts +2 -0
  52. package/src/__tests__/unit/nodeviews/OverflowShadowsObserver.ts +20 -11
  53. package/src/__tests__/unit/pm-plugins/main-with-allow-collapse.ts +2 -0
  54. package/src/__tests__/unit/transforms/delete-rows.ts +45 -0
  55. package/src/__tests__/unit/utils/collapse.ts +4 -1
  56. package/src/i18n/en.ts +36 -0
  57. package/src/i18n/en_GB.ts +36 -0
  58. package/src/plugins/table/nodeviews/OverflowShadowsObserver.ts +24 -40
  59. package/src/plugins/table/nodeviews/TableComponent.tsx +19 -2
  60. package/src/plugins/table/nodeviews/__mocks__/OverflowShadowsObserver.ts +3 -3
  61. package/src/plugins/table/nodeviews/table.tsx +12 -0
  62. package/src/plugins/table/transforms/delete-rows.ts +2 -2
  63. package/src/plugins/table/transforms/index.ts +1 -1
  64. package/src/plugins/table/transforms/merge.ts +41 -43
  65. package/src/plugins/table/ui/common-styles.ts +54 -5
  66. package/src/plugins/table/utils/row-controls.ts +3 -2
  67. package/src/__tests__/integration/__fixtures__/table-and-paragraph-adf.json +0 -130
@@ -0,0 +1,36 @@
1
+ /* prettier-ignore */
2
+ /**
3
+ * NOTE:
4
+ *
5
+ * This file is automatically generated by Traduki 2.0.
6
+ * DO NOT CHANGE IT BY HAND or your changes will be lost.
7
+ */
8
+ //
9
+ export default {
10
+ 'fabric.editor.canNotSortTable': "⚠️ You can't sort a table with merged cells",
11
+ 'fabric.editor.cellBackground': 'Cell background',
12
+ 'fabric.editor.cellOptions': 'Cell options',
13
+ 'fabric.editor.clearCells': 'Clear {0, plural, one {cell} other {cells}}',
14
+ 'fabric.editor.collapseTable': 'Collapse table',
15
+ 'fabric.editor.cornerControl': 'Highlight table',
16
+ 'fabric.editor.distributeColumns': 'Distribute columns',
17
+ 'fabric.editor.extension.confirmDeleteLinkedModalMessagePrefix': 'Deleting',
18
+ 'fabric.editor.extension.deleteElementTitle': 'Delete element',
19
+ 'fabric.editor.extension.sourceNoTitledName': 'this element',
20
+ 'fabric.editor.floatingToolbar.confirmModalCheckboxLabel': 'Also delete connected elements',
21
+ 'fabric.editor.headerColumn': 'Header column',
22
+ 'fabric.editor.headerRow': 'Header row',
23
+ 'fabric.editor.insertColumn': 'Insert column right',
24
+ 'fabric.editor.insertRow': 'Insert row below',
25
+ 'fabric.editor.mergeCells': 'Merge cells',
26
+ 'fabric.editor.numberedColumn': 'Numbered column',
27
+ 'fabric.editor.removeColumns': 'Delete {0, plural, one {column} other {columns}}',
28
+ 'fabric.editor.removeRows': 'Delete {0, plural, one {row} other {rows}}',
29
+ 'fabric.editor.rowControl': 'Highlight row',
30
+ 'fabric.editor.sortColumnASC': 'Sort column A → Z',
31
+ 'fabric.editor.sortColumnDESC': 'Sort column Z → A',
32
+ 'fabric.editor.splitCell': 'Split cell',
33
+ 'fabric.editor.tableOptions': 'Table options',
34
+ 'fabric.editor.tables.confirmDeleteLinkedModalMessage': 'Deleting {nodeName} will break anything connected to it.',
35
+ 'fabric.editor.tables.confirmDeleteLinkedModalOKButton': 'Delete'
36
+ };
@@ -0,0 +1,36 @@
1
+ /* prettier-ignore */
2
+ /**
3
+ * NOTE:
4
+ *
5
+ * This file is automatically generated by Traduki 2.0.
6
+ * DO NOT CHANGE IT BY HAND or your changes will be lost.
7
+ */
8
+ //English (United Kingdom)
9
+ export default {
10
+ 'fabric.editor.canNotSortTable': "⚠️ You can't sort a table with merged cells",
11
+ 'fabric.editor.cellBackground': 'Cell background',
12
+ 'fabric.editor.cellOptions': 'Cell options',
13
+ 'fabric.editor.clearCells': 'Clear {0, plural, one {cell} other {cells}}',
14
+ 'fabric.editor.collapseTable': 'Collapse table',
15
+ 'fabric.editor.cornerControl': 'Highlight table',
16
+ 'fabric.editor.distributeColumns': 'Distribute columns',
17
+ 'fabric.editor.extension.confirmDeleteLinkedModalMessagePrefix': 'Deleting',
18
+ 'fabric.editor.extension.deleteElementTitle': 'Delete element',
19
+ 'fabric.editor.extension.sourceNoTitledName': 'this element',
20
+ 'fabric.editor.floatingToolbar.confirmModalCheckboxLabel': 'Also delete connected elements',
21
+ 'fabric.editor.headerColumn': 'Header column',
22
+ 'fabric.editor.headerRow': 'Header row',
23
+ 'fabric.editor.insertColumn': 'Insert column right',
24
+ 'fabric.editor.insertRow': 'Insert row below',
25
+ 'fabric.editor.mergeCells': 'Merge cells',
26
+ 'fabric.editor.numberedColumn': 'Numbered column',
27
+ 'fabric.editor.removeColumns': 'Delete {0, plural, one {column} other {columns}}',
28
+ 'fabric.editor.removeRows': 'Delete {0, plural, one {row} other {rows}}',
29
+ 'fabric.editor.rowControl': 'Highlight row',
30
+ 'fabric.editor.sortColumnASC': 'Sort column A → Z',
31
+ 'fabric.editor.sortColumnDESC': 'Sort column Z → A',
32
+ 'fabric.editor.splitCell': 'Split cell',
33
+ 'fabric.editor.tableOptions': 'Table options',
34
+ 'fabric.editor.tables.confirmDeleteLinkedModalMessage': 'Deleting {nodeName} will break anything connected to it.',
35
+ 'fabric.editor.tables.confirmDeleteLinkedModalOKButton': 'Delete'
36
+ };
@@ -5,16 +5,9 @@ import { updateShadowListForStickyStyles } from './update-overflow-shadows';
5
5
  export class OverflowShadowsObserver {
6
6
  // updateShadowState is a method to update shadow key
7
7
  constructor(updateShadowState, _table, wrapper) {
8
- _defineProperty(this, "firstCell", null);
9
- _defineProperty(this, "lastCell", null);
10
- _defineProperty(this, "getFirstCell", (isSticky, hasHeaderRow) => {
11
- var _this$table;
12
- return (_this$table = this.table) === null || _this$table === void 0 ? void 0 : _this$table.querySelector(isSticky || !hasHeaderRow ? 'table tbody tr td' : 'table tbody tr th');
13
- });
14
- _defineProperty(this, "getLastCell", (isSticky, hasHeaderRow) => {
15
- var _this$table2;
16
- return (_this$table2 = this.table) === null || _this$table2 === void 0 ? void 0 : _this$table2.querySelector(isSticky || !hasHeaderRow ? 'table tbody tr td:last-child' : 'table tbody tr th:last-child');
17
- });
8
+ _defineProperty(this, "leftShadowSentinel", null);
9
+ _defineProperty(this, "rightShadowSentinel", null);
10
+ _defineProperty(this, "shadowsObserved", false);
18
11
  _defineProperty(this, "isSticky", false);
19
12
  _defineProperty(this, "stickyRowHeight", 0);
20
13
  _defineProperty(this, "init", () => {
@@ -28,11 +21,11 @@ export class OverflowShadowsObserver {
28
21
  if (!((_entry$rootBounds = entry.rootBounds) !== null && _entry$rootBounds !== void 0 && _entry$rootBounds.height) && !((_entry$rootBounds2 = entry.rootBounds) !== null && _entry$rootBounds2 !== void 0 && _entry$rootBounds2.width)) {
29
22
  return;
30
23
  }
31
- if (entry.target !== this.firstCell && entry.target !== this.lastCell) {
24
+ if (entry.target !== this.leftShadowSentinel && entry.target !== this.rightShadowSentinel) {
32
25
  return;
33
26
  }
34
27
  this.updateStickyShadowsHeightIfChanged();
35
- this.checkIntersectionEvent(entry, this.firstCell === entry.target ? ShadowEvent.SHOW_BEFORE_SHADOW : ShadowEvent.SHOW_AFTER_SHADOW);
28
+ this.checkIntersectionEvent(entry, this.leftShadowSentinel === entry.target ? ShadowEvent.SHOW_BEFORE_SHADOW : ShadowEvent.SHOW_AFTER_SHADOW);
36
29
  };
37
30
  this.tableIntersectionObserver = new IntersectionObserver((entries, _) => {
38
31
  entries.forEach(entry => intersectonOnbserverCallback(entry));
@@ -55,25 +48,19 @@ export class OverflowShadowsObserver {
55
48
  this.updateShadowState(shadowKey, true);
56
49
  }
57
50
  });
58
- _defineProperty(this, "observeCells", (isSticky, hasHeaderRow) => {
59
- const stickyChanged = !!isSticky !== this.isSticky;
51
+ _defineProperty(this, "observeShadowSentinels", isSticky => {
52
+ var _this$table, _this$table2;
60
53
  this.isSticky = !!isSticky;
61
54
 
62
55
  // update sticky shadows
63
56
  this.updateStickyShadowsHeightIfChanged();
64
- if (!stickyChanged) {
65
- const firstCell = this.getFirstCell(isSticky, hasHeaderRow);
66
- const lastCell = this.getLastCell(isSticky, hasHeaderRow);
67
- if (!firstCell || !lastCell || firstCell === this.firstCell && lastCell === this.lastCell) {
68
- return;
69
- }
70
- }
71
- this.firstCell = this.getFirstCell(isSticky, hasHeaderRow);
72
- this.lastCell = this.getLastCell(isSticky, hasHeaderRow);
73
- if (this.tableIntersectionObserver && this.firstCell && this.lastCell) {
57
+ this.leftShadowSentinel = (_this$table = this.table) === null || _this$table === void 0 ? void 0 : _this$table.querySelector(`.${ClassName.TABLE_SHADOW_SENTINEL_LEFT}`);
58
+ this.rightShadowSentinel = (_this$table2 = this.table) === null || _this$table2 === void 0 ? void 0 : _this$table2.querySelector(`.${ClassName.TABLE_SHADOW_SENTINEL_RIGHT}`);
59
+ if (this.tableIntersectionObserver && this.leftShadowSentinel && this.rightShadowSentinel && !this.shadowsObserved) {
74
60
  this.tableIntersectionObserver.disconnect();
75
- this.tableIntersectionObserver.observe(this.firstCell);
76
- this.tableIntersectionObserver.observe(this.lastCell);
61
+ this.tableIntersectionObserver.observe(this.leftShadowSentinel);
62
+ this.tableIntersectionObserver.observe(this.rightShadowSentinel);
63
+ this.shadowsObserved = true;
77
64
  }
78
65
  });
79
66
  _defineProperty(this, "updateStickyShadows", stickyRowHeight => {
@@ -48,6 +48,16 @@ class TableComponent extends React.Component {
48
48
  [shadowKey]: value
49
49
  });
50
50
  });
51
+ _defineProperty(this, "createShadowSentinels", table => {
52
+ if (table) {
53
+ const shadowSentinelLeft = document.createElement('span');
54
+ shadowSentinelLeft.className = ClassName.TABLE_SHADOW_SENTINEL_LEFT;
55
+ const shadowSentinelRight = document.createElement('span');
56
+ shadowSentinelRight.className = ClassName.TABLE_SHADOW_SENTINEL_RIGHT;
57
+ table.prepend(shadowSentinelLeft);
58
+ table.prepend(shadowSentinelRight);
59
+ }
60
+ });
51
61
  _defineProperty(this, "onStickyState", state => {
52
62
  const {
53
63
  tableOverflowShadowsOptimization
@@ -102,6 +112,15 @@ class TableComponent extends React.Component {
102
112
  if (!tableOverflowShadowsOptimization) {
103
113
  this.updateShadows();
104
114
  }
115
+ if (this.wrapper.scrollLeft === 0) {
116
+ this.setState({
117
+ [ShadowEvent.SHOW_BEFORE_SHADOW]: false
118
+ });
119
+ } else {
120
+ this.setState({
121
+ [ShadowEvent.SHOW_BEFORE_SHADOW]: true
122
+ });
123
+ }
105
124
  });
106
125
  _defineProperty(this, "handleTableResizing", () => {
107
126
  const {
@@ -369,7 +388,7 @@ class TableComponent extends React.Component {
369
388
  }
370
389
  if (this.overflowShadowsObserver) {
371
390
  var _this$state$stickyHea;
372
- this.overflowShadowsObserver.observeCells((_this$state$stickyHea = this.state.stickyHeader) === null || _this$state$stickyHea === void 0 ? void 0 : _this$state$stickyHea.sticky, containsHeaderRow(getNode()));
391
+ this.overflowShadowsObserver.observeShadowSentinels((_this$state$stickyHea = this.state.stickyHeader) === null || _this$state$stickyHea === void 0 ? void 0 : _this$state$stickyHea.sticky);
373
392
  }
374
393
  }
375
394
  const currentTable = getNode();
@@ -500,6 +519,7 @@ class TableComponent extends React.Component {
500
519
  const tableElement = elem.querySelector('table');
501
520
  if (tableElement !== this.table) {
502
521
  this.table = tableElement;
522
+ this.createShadowSentinels(this.table);
503
523
  }
504
524
  }
505
525
  }
@@ -151,6 +151,13 @@ export default class TableView extends ReactNodeView {
151
151
  if (type === 'selection' && (nodeName === null || nodeName === void 0 ? void 0 : nodeName.toUpperCase()) === 'DIV' && (firstChild === null || firstChild === void 0 ? void 0 : firstChild.nodeName.toUpperCase()) === 'TABLE') {
152
152
  return false;
153
153
  }
154
+
155
+ // ED-16668
156
+ // Do not remove this fixes an issue with windows firefox that relates to
157
+ // the addition of the shadow sentinels
158
+ if (type === 'selection' && (nodeName === null || nodeName === void 0 ? void 0 : nodeName.toUpperCase()) === 'TABLE' && ((firstChild === null || firstChild === void 0 ? void 0 : firstChild.nodeName.toUpperCase()) === 'COLGROUP' || (firstChild === null || firstChild === void 0 ? void 0 : firstChild.nodeName.toUpperCase()) === 'SPAN')) {
159
+ return false;
160
+ }
154
161
  return true;
155
162
  }
156
163
  destroy() {
@@ -1,7 +1,7 @@
1
1
  import { Selection } from 'prosemirror-state';
2
2
  import { TableMap } from '@atlaskit/editor-tables/table-map';
3
3
  import { findTable } from '@atlaskit/editor-tables/utils';
4
- import { removeEmptyColumns } from './merge';
4
+ import { mergeEmptyColumns } from './merge';
5
5
  import { setMeta } from './metadata';
6
6
  export const deleteRows = (rect, isHeaderRowRequired = false) => tr => {
7
7
  const table = findTable(tr.selection);
@@ -96,7 +96,7 @@ export const deleteRows = (rect, isHeaderRowRequired = false) => tr => {
96
96
  })(tr);
97
97
  }
98
98
  const newTable = table.node.type.createChecked(table.node.attrs, rows, table.node.marks);
99
- const fixedTable = removeEmptyColumns(newTable);
99
+ const fixedTable = mergeEmptyColumns(newTable);
100
100
  if (fixedTable === null) {
101
101
  return setMeta({
102
102
  type: 'DELETE_ROWS',
@@ -1,5 +1,5 @@
1
- export { mergeCells, canMergeCells, removeEmptyColumns } from './merge';
2
1
  export { fireAnalytics, fixTables, fixAutoSizedTable } from './fix-tables';
2
+ export { mergeCells, canMergeCells, mergeEmptyColumns } from './merge';
3
3
  export { deleteColumns } from './delete-columns';
4
4
  export { deleteRows } from './delete-rows';
5
5
  export { updateColumnWidths } from './column-width';
@@ -113,7 +113,7 @@ export function mergeCells(tr) {
113
113
  })(tr);
114
114
  }
115
115
  const newTable = table.node.type.createChecked(table.node.attrs, rows, table.node.marks);
116
- const fixedTable = removeEmptyColumns(newTable);
116
+ const fixedTable = mergeEmptyColumns(newTable);
117
117
  if (fixedTable === null) {
118
118
  return setMeta({
119
119
  type: 'MERGE_CELLS',
@@ -188,70 +188,66 @@ function cellsOverlapRectangle({
188
188
  }
189
189
 
190
190
  // returns an array of numbers, each number indicates the minimum colSpan in each column
191
- function getMinColSpans(table) {
191
+ function getEmptyColumnIndexes(table) {
192
192
  const map = TableMap.get(table);
193
- const minColspans = [];
194
- for (let colIndex = map.width - 1; colIndex >= 0; colIndex--) {
195
- const cellsPositions = map.cellsInRect({
193
+ const emptyColumnIndexes = new Set();
194
+
195
+ // Loop throuh each column
196
+ for (let colIndex = 0; colIndex < map.width; colIndex++) {
197
+ // Get the cells in each row for this column
198
+ const cellPositions = map.cellsInRect({
196
199
  left: colIndex,
197
200
  right: colIndex + 1,
198
201
  top: 0,
199
202
  bottom: map.height
200
203
  });
201
- if (cellsPositions.length) {
202
- const colspans = cellsPositions.map(cellPos => {
203
- const cell = table.nodeAt(cellPos);
204
- if (cell) {
205
- return cell.attrs.colspan;
206
- }
207
- });
208
- const minColspan = Math.min(...colspans);
209
- // only care about the case when the next column is invisible
210
- if (!minColspans[colIndex + 1]) {
211
- minColspans[colIndex] = minColspan;
212
- } else {
213
- minColspans[colIndex] = 1;
214
- }
204
+
205
+ // If no cells exist in that column it is empty
206
+ if (!cellPositions.length) {
207
+ emptyColumnIndexes.add(colIndex);
215
208
  }
216
209
  }
217
- return minColspans;
210
+ return emptyColumnIndexes;
218
211
  }
219
- export function removeEmptyColumns(table) {
212
+ export function mergeEmptyColumns(table) {
213
+ const rows = [];
220
214
  const map = TableMap.get(table);
221
- const minColSpans = getMinColSpans(table);
222
- if (!minColSpans.some(colspan => colspan > 1)) {
215
+ const emptyColumnIndexes = getEmptyColumnIndexes(table);
216
+
217
+ // We don't need to remove any so return early.
218
+ if (emptyColumnIndexes.size === 0) {
223
219
  return table;
224
220
  }
225
- const rows = [];
226
221
  for (let rowIndex = 0; rowIndex < map.height; rowIndex++) {
227
222
  const cellsByCols = {};
228
- const cols = Object.keys(minColSpans).map(Number);
229
- for (let idx in cols) {
230
- const colIndex = cols[idx];
223
+
224
+ // Work backwards so that calculating colwidths is easier with Array.slice
225
+ for (let colIndex = map.width - 1; colIndex >= 0; colIndex--) {
231
226
  const cellPos = map.map[colIndex + rowIndex * map.width];
232
227
  const rect = map.findCell(cellPos);
233
- const cell = cellsByCols[rect.left] || table.nodeAt(cellPos);
234
- if (cell && rect.top === rowIndex) {
235
- if (minColSpans[colIndex] > 1) {
236
- const colspan = cell.attrs.colspan - minColSpans[colIndex] + 1;
237
- if (colspan < 1) {
238
- return null;
239
- }
240
- const {
241
- colwidth
242
- } = cell.attrs;
243
- const newCell = cell.type.createChecked({
228
+ let cell = cellsByCols[rect.left] || table.nodeAt(cellPos);
229
+ if (rect.top !== rowIndex) {
230
+ continue;
231
+ }
232
+
233
+ // If this column is empty, we want to decrement the colspan of its corresponding
234
+ // cell as this column is being "merged"
235
+ if (emptyColumnIndexes.has(colIndex)) {
236
+ const {
237
+ colspan,
238
+ colwidth
239
+ } = cell.attrs;
240
+ if (colspan > 1) {
241
+ cell = cell.type.createChecked({
244
242
  ...cell.attrs,
245
- colspan,
243
+ colspan: colspan - 1,
246
244
  colwidth: colwidth ? colwidth.slice(0, colspan) : null
247
245
  }, cell.content, cell.marks);
248
- cellsByCols[rect.left] = newCell;
249
- } else {
250
- cellsByCols[rect.left] = cell;
251
246
  }
252
247
  }
248
+ cellsByCols[rect.left] = cell;
253
249
  }
254
- const rowCells = Object.keys(cellsByCols).map(col => cellsByCols[col]);
250
+ const rowCells = Object.values(cellsByCols);
255
251
  const row = table.child(rowIndex);
256
252
  if (row) {
257
253
  rows.push(row.type.createChecked(row.attrs, rowCells, row.marks));
@@ -47,7 +47,22 @@ const sentinelStyles = `.${ClassName.TABLE_CONTAINER} {
47
47
  }
48
48
  }
49
49
  }`;
50
-
50
+ const shadowSentinelStyles = `
51
+ .${ClassName.TABLE_SHADOW_SENTINEL_LEFT},
52
+ .${ClassName.TABLE_SHADOW_SENTINEL_RIGHT} {
53
+ position: absolute;
54
+ top: 0;
55
+ height: 100%;
56
+ width: 1px;
57
+ visibility: hidden;
58
+ }
59
+ .${ClassName.TABLE_SHADOW_SENTINEL_LEFT} {
60
+ left: 0;
61
+ }
62
+ .${ClassName.TABLE_SHADOW_SENTINEL_RIGHT} {
63
+ right: 0;
64
+ }
65
+ `;
51
66
  // previous styles to add spacing to numbered lists with
52
67
  // large item markers (e.g. 101, 102, ...) when nested inside tables
53
68
  const listLargeNumericMarkersOldStyles = `
@@ -55,10 +70,36 @@ const listLargeNumericMarkersOldStyles = `
55
70
  padding-left: revert;
56
71
  }
57
72
  `;
73
+ const breakoutWidthStyling = useFragmentMarkBreakoutWidthStylingFix => {
74
+ if (useFragmentMarkBreakoutWidthStylingFix) {
75
+ return css`
76
+ > *:not([data-mark-type='fragment'])
77
+ .${ClassName.NODEVIEW_WRAPPER}
78
+ .${ClassName.TABLE_CONTAINER} {
79
+ margin-left: unset !important;
80
+ width: 100% !important;
81
+ }
82
+
83
+ > [data-mark-type='fragment']
84
+ *
85
+ .${ClassName.NODEVIEW_WRAPPER}
86
+ .${ClassName.TABLE_CONTAINER} {
87
+ margin-left: unset !important;
88
+ width: 100% !important;
89
+ }
90
+ `;
91
+ }
92
+ return css`
93
+ > * .${ClassName.NODEVIEW_WRAPPER} .${ClassName.TABLE_CONTAINER} {
94
+ margin-left: unset !important;
95
+ width: 100% !important;
96
+ }
97
+ `;
98
+ };
58
99
 
59
100
  // TODO: https://product-fabric.atlassian.net/browse/DSP-4139
60
101
  export const tableStyles = props => {
61
- var _props$featureFlags, _props$featureFlags2;
102
+ var _props$featureFlags, _props$featureFlags$u, _props$featureFlags2, _props$featureFlags3;
62
103
  return css`
63
104
  .${ClassName.LAYOUT_BUTTON} button {
64
105
  background: ${`var(--ds-background-neutral, ${N20A})`};
@@ -326,11 +367,8 @@ export const tableStyles = props => {
326
367
  */
327
368
  }
328
369
 
329
- /* Breakout only works on top level */
330
- > * .${ClassName.NODEVIEW_WRAPPER} .${ClassName.TABLE_CONTAINER} {
331
- margin-left: unset !important;
332
- width: 100% !important;
333
- }
370
+ /* Breakout only works on top level unless wrapped in fragment mark */
371
+ ${breakoutWidthStyling((_props$featureFlags$u = (_props$featureFlags2 = props.featureFlags) === null || _props$featureFlags2 === void 0 ? void 0 : _props$featureFlags2.useFragmentMarkBreakoutWidthStylingFix) !== null && _props$featureFlags$u !== void 0 ? _props$featureFlags$u : true)}
334
372
 
335
373
  ${columnControlsDecoration(props)};
336
374
 
@@ -532,6 +570,8 @@ export const tableStyles = props => {
532
570
  border-top: none;
533
571
  // 1px border width offset added here to prevent unwanted overflow and scolling - ED-16212
534
572
  margin-right: -1px;
573
+ // Allows better positioning for the shadow sentinels - ED-16668
574
+ position: relative;
535
575
 
536
576
  > tbody > tr {
537
577
  white-space: pre-wrap;
@@ -646,7 +686,9 @@ export const tableStyles = props => {
646
686
  styles that handle this generally (in editor-common) so we can
647
687
  throw away the older table-specific styles here.
648
688
  */
649
- ${props !== null && props !== void 0 && (_props$featureFlags2 = props.featureFlags) !== null && _props$featureFlags2 !== void 0 && _props$featureFlags2.restartNumberedLists ? `` : listLargeNumericMarkersOldStyles}
689
+ ${props !== null && props !== void 0 && (_props$featureFlags3 = props.featureFlags) !== null && _props$featureFlags3 !== void 0 && _props$featureFlags3.restartNumberedLists ? `` : listLargeNumericMarkersOldStyles}
690
+
691
+ ${shadowSentinelStyles}
650
692
  `;
651
693
  };
652
694
  export const tableFullPageEditorStyles = css`
@@ -7,8 +7,9 @@ import { TableCssClassName as ClassName } from '../types';
7
7
  import { tableDeleteButtonSize } from '../ui/consts';
8
8
  export const getRowHeights = tableRef => {
9
9
  const heights = [];
10
- if (tableRef.lastChild) {
11
- const rows = tableRef.lastChild.childNodes;
10
+ const tableBody = tableRef.querySelector('tbody');
11
+ if (tableBody) {
12
+ const rows = tableBody.childNodes;
12
13
  for (let i = 0, count = rows.length; i < count; i++) {
13
14
  const row = rows[i];
14
15
  heights[i] = row.getBoundingClientRect().height + 1;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "sideEffects": false
5
5
  }
@@ -0,0 +1,36 @@
1
+ /* prettier-ignore */
2
+ /**
3
+ * NOTE:
4
+ *
5
+ * This file is automatically generated by Traduki 2.0.
6
+ * DO NOT CHANGE IT BY HAND or your changes will be lost.
7
+ */
8
+ //
9
+ export default {
10
+ 'fabric.editor.canNotSortTable': "⚠️ You can't sort a table with merged cells",
11
+ 'fabric.editor.cellBackground': 'Cell background',
12
+ 'fabric.editor.cellOptions': 'Cell options',
13
+ 'fabric.editor.clearCells': 'Clear {0, plural, one {cell} other {cells}}',
14
+ 'fabric.editor.collapseTable': 'Collapse table',
15
+ 'fabric.editor.cornerControl': 'Highlight table',
16
+ 'fabric.editor.distributeColumns': 'Distribute columns',
17
+ 'fabric.editor.extension.confirmDeleteLinkedModalMessagePrefix': 'Deleting',
18
+ 'fabric.editor.extension.deleteElementTitle': 'Delete element',
19
+ 'fabric.editor.extension.sourceNoTitledName': 'this element',
20
+ 'fabric.editor.floatingToolbar.confirmModalCheckboxLabel': 'Also delete connected elements',
21
+ 'fabric.editor.headerColumn': 'Header column',
22
+ 'fabric.editor.headerRow': 'Header row',
23
+ 'fabric.editor.insertColumn': 'Insert column right',
24
+ 'fabric.editor.insertRow': 'Insert row below',
25
+ 'fabric.editor.mergeCells': 'Merge cells',
26
+ 'fabric.editor.numberedColumn': 'Numbered column',
27
+ 'fabric.editor.removeColumns': 'Delete {0, plural, one {column} other {columns}}',
28
+ 'fabric.editor.removeRows': 'Delete {0, plural, one {row} other {rows}}',
29
+ 'fabric.editor.rowControl': 'Highlight row',
30
+ 'fabric.editor.sortColumnASC': 'Sort column A → Z',
31
+ 'fabric.editor.sortColumnDESC': 'Sort column Z → A',
32
+ 'fabric.editor.splitCell': 'Split cell',
33
+ 'fabric.editor.tableOptions': 'Table options',
34
+ 'fabric.editor.tables.confirmDeleteLinkedModalMessage': 'Deleting {nodeName} will break anything connected to it.',
35
+ 'fabric.editor.tables.confirmDeleteLinkedModalOKButton': 'Delete'
36
+ };
@@ -0,0 +1,36 @@
1
+ /* prettier-ignore */
2
+ /**
3
+ * NOTE:
4
+ *
5
+ * This file is automatically generated by Traduki 2.0.
6
+ * DO NOT CHANGE IT BY HAND or your changes will be lost.
7
+ */
8
+ //English (United Kingdom)
9
+ export default {
10
+ 'fabric.editor.canNotSortTable': "⚠️ You can't sort a table with merged cells",
11
+ 'fabric.editor.cellBackground': 'Cell background',
12
+ 'fabric.editor.cellOptions': 'Cell options',
13
+ 'fabric.editor.clearCells': 'Clear {0, plural, one {cell} other {cells}}',
14
+ 'fabric.editor.collapseTable': 'Collapse table',
15
+ 'fabric.editor.cornerControl': 'Highlight table',
16
+ 'fabric.editor.distributeColumns': 'Distribute columns',
17
+ 'fabric.editor.extension.confirmDeleteLinkedModalMessagePrefix': 'Deleting',
18
+ 'fabric.editor.extension.deleteElementTitle': 'Delete element',
19
+ 'fabric.editor.extension.sourceNoTitledName': 'this element',
20
+ 'fabric.editor.floatingToolbar.confirmModalCheckboxLabel': 'Also delete connected elements',
21
+ 'fabric.editor.headerColumn': 'Header column',
22
+ 'fabric.editor.headerRow': 'Header row',
23
+ 'fabric.editor.insertColumn': 'Insert column right',
24
+ 'fabric.editor.insertRow': 'Insert row below',
25
+ 'fabric.editor.mergeCells': 'Merge cells',
26
+ 'fabric.editor.numberedColumn': 'Numbered column',
27
+ 'fabric.editor.removeColumns': 'Delete {0, plural, one {column} other {columns}}',
28
+ 'fabric.editor.removeRows': 'Delete {0, plural, one {row} other {rows}}',
29
+ 'fabric.editor.rowControl': 'Highlight row',
30
+ 'fabric.editor.sortColumnASC': 'Sort column A → Z',
31
+ 'fabric.editor.sortColumnDESC': 'Sort column Z → A',
32
+ 'fabric.editor.splitCell': 'Split cell',
33
+ 'fabric.editor.tableOptions': 'Table options',
34
+ 'fabric.editor.tables.confirmDeleteLinkedModalMessage': 'Deleting {nodeName} will break anything connected to it.',
35
+ 'fabric.editor.tables.confirmDeleteLinkedModalOKButton': 'Delete'
36
+ };
@@ -9,16 +9,9 @@ export var OverflowShadowsObserver = /*#__PURE__*/function () {
9
9
  function OverflowShadowsObserver(updateShadowState, _table, wrapper) {
10
10
  var _this = this;
11
11
  _classCallCheck(this, OverflowShadowsObserver);
12
- _defineProperty(this, "firstCell", null);
13
- _defineProperty(this, "lastCell", null);
14
- _defineProperty(this, "getFirstCell", function (isSticky, hasHeaderRow) {
15
- var _this$table;
16
- return (_this$table = _this.table) === null || _this$table === void 0 ? void 0 : _this$table.querySelector(isSticky || !hasHeaderRow ? 'table tbody tr td' : 'table tbody tr th');
17
- });
18
- _defineProperty(this, "getLastCell", function (isSticky, hasHeaderRow) {
19
- var _this$table2;
20
- return (_this$table2 = _this.table) === null || _this$table2 === void 0 ? void 0 : _this$table2.querySelector(isSticky || !hasHeaderRow ? 'table tbody tr td:last-child' : 'table tbody tr th:last-child');
21
- });
12
+ _defineProperty(this, "leftShadowSentinel", null);
13
+ _defineProperty(this, "rightShadowSentinel", null);
14
+ _defineProperty(this, "shadowsObserved", false);
22
15
  _defineProperty(this, "isSticky", false);
23
16
  _defineProperty(this, "stickyRowHeight", 0);
24
17
  _defineProperty(this, "init", function () {
@@ -32,11 +25,11 @@ export var OverflowShadowsObserver = /*#__PURE__*/function () {
32
25
  if (!((_entry$rootBounds = entry.rootBounds) !== null && _entry$rootBounds !== void 0 && _entry$rootBounds.height) && !((_entry$rootBounds2 = entry.rootBounds) !== null && _entry$rootBounds2 !== void 0 && _entry$rootBounds2.width)) {
33
26
  return;
34
27
  }
35
- if (entry.target !== _this.firstCell && entry.target !== _this.lastCell) {
28
+ if (entry.target !== _this.leftShadowSentinel && entry.target !== _this.rightShadowSentinel) {
36
29
  return;
37
30
  }
38
31
  _this.updateStickyShadowsHeightIfChanged();
39
- _this.checkIntersectionEvent(entry, _this.firstCell === entry.target ? ShadowEvent.SHOW_BEFORE_SHADOW : ShadowEvent.SHOW_AFTER_SHADOW);
32
+ _this.checkIntersectionEvent(entry, _this.leftShadowSentinel === entry.target ? ShadowEvent.SHOW_BEFORE_SHADOW : ShadowEvent.SHOW_AFTER_SHADOW);
40
33
  };
41
34
  _this.tableIntersectionObserver = new IntersectionObserver(function (entries, _) {
42
35
  entries.forEach(function (entry) {
@@ -61,25 +54,19 @@ export var OverflowShadowsObserver = /*#__PURE__*/function () {
61
54
  _this.updateShadowState(shadowKey, true);
62
55
  }
63
56
  });
64
- _defineProperty(this, "observeCells", function (isSticky, hasHeaderRow) {
65
- var stickyChanged = !!isSticky !== _this.isSticky;
57
+ _defineProperty(this, "observeShadowSentinels", function (isSticky) {
58
+ var _this$table, _this$table2;
66
59
  _this.isSticky = !!isSticky;
67
60
 
68
61
  // update sticky shadows
69
62
  _this.updateStickyShadowsHeightIfChanged();
70
- if (!stickyChanged) {
71
- var firstCell = _this.getFirstCell(isSticky, hasHeaderRow);
72
- var lastCell = _this.getLastCell(isSticky, hasHeaderRow);
73
- if (!firstCell || !lastCell || firstCell === _this.firstCell && lastCell === _this.lastCell) {
74
- return;
75
- }
76
- }
77
- _this.firstCell = _this.getFirstCell(isSticky, hasHeaderRow);
78
- _this.lastCell = _this.getLastCell(isSticky, hasHeaderRow);
79
- if (_this.tableIntersectionObserver && _this.firstCell && _this.lastCell) {
63
+ _this.leftShadowSentinel = (_this$table = _this.table) === null || _this$table === void 0 ? void 0 : _this$table.querySelector(".".concat(ClassName.TABLE_SHADOW_SENTINEL_LEFT));
64
+ _this.rightShadowSentinel = (_this$table2 = _this.table) === null || _this$table2 === void 0 ? void 0 : _this$table2.querySelector(".".concat(ClassName.TABLE_SHADOW_SENTINEL_RIGHT));
65
+ if (_this.tableIntersectionObserver && _this.leftShadowSentinel && _this.rightShadowSentinel && !_this.shadowsObserved) {
80
66
  _this.tableIntersectionObserver.disconnect();
81
- _this.tableIntersectionObserver.observe(_this.firstCell);
82
- _this.tableIntersectionObserver.observe(_this.lastCell);
67
+ _this.tableIntersectionObserver.observe(_this.leftShadowSentinel);
68
+ _this.tableIntersectionObserver.observe(_this.rightShadowSentinel);
69
+ _this.shadowsObserved = true;
83
70
  }
84
71
  });
85
72
  _defineProperty(this, "updateStickyShadows", function (stickyRowHeight) {