@atlaskit/editor-plugin-table 5.7.2 → 5.7.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 (86) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/commands/insert.js +1 -1
  3. package/dist/cjs/nodeviews/TableComponent.js +4 -1
  4. package/dist/cjs/plugin.js +2 -1
  5. package/dist/cjs/pm-plugins/main.js +5 -16
  6. package/dist/cjs/pm-plugins/table-resizing/event-handlers.js +0 -4
  7. package/dist/cjs/transforms/column-width.js +3 -105
  8. package/dist/cjs/transforms/delete-columns.js +2 -5
  9. package/dist/cjs/types.js +0 -2
  10. package/dist/cjs/ui/FloatingDragMenu/index.js +5 -2
  11. package/dist/cjs/ui/FloatingInsertButton/InsertButton.js +3 -3
  12. package/dist/cjs/ui/FloatingInsertButton/index.js +1 -1
  13. package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +39 -8
  14. package/dist/cjs/ui/TableFloatingColumnControls/index.js +17 -8
  15. package/dist/cjs/ui/common-styles.js +1 -1
  16. package/dist/cjs/utils/decoration.js +48 -34
  17. package/dist/cjs/utils/dom.js +1 -19
  18. package/dist/cjs/utils/index.js +0 -6
  19. package/dist/es2019/commands/insert.js +1 -1
  20. package/dist/es2019/nodeviews/TableComponent.js +5 -2
  21. package/dist/es2019/plugin.js +2 -1
  22. package/dist/es2019/pm-plugins/main.js +1 -12
  23. package/dist/es2019/pm-plugins/table-resizing/event-handlers.js +1 -5
  24. package/dist/es2019/transforms/column-width.js +4 -102
  25. package/dist/es2019/transforms/delete-columns.js +2 -5
  26. package/dist/es2019/types.js +0 -2
  27. package/dist/es2019/ui/FloatingDragMenu/index.js +6 -3
  28. package/dist/es2019/ui/FloatingInsertButton/InsertButton.js +3 -3
  29. package/dist/es2019/ui/FloatingInsertButton/index.js +2 -2
  30. package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +34 -4
  31. package/dist/es2019/ui/TableFloatingColumnControls/index.js +18 -9
  32. package/dist/es2019/ui/common-styles.js +6 -1
  33. package/dist/es2019/utils/decoration.js +47 -33
  34. package/dist/es2019/utils/dom.js +0 -18
  35. package/dist/es2019/utils/index.js +1 -1
  36. package/dist/esm/commands/insert.js +1 -1
  37. package/dist/esm/nodeviews/TableComponent.js +5 -2
  38. package/dist/esm/plugin.js +2 -1
  39. package/dist/esm/pm-plugins/main.js +1 -12
  40. package/dist/esm/pm-plugins/table-resizing/event-handlers.js +1 -5
  41. package/dist/esm/transforms/column-width.js +4 -106
  42. package/dist/esm/transforms/delete-columns.js +2 -5
  43. package/dist/esm/types.js +0 -2
  44. package/dist/esm/ui/FloatingDragMenu/index.js +6 -3
  45. package/dist/esm/ui/FloatingInsertButton/InsertButton.js +3 -3
  46. package/dist/esm/ui/FloatingInsertButton/index.js +2 -2
  47. package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +35 -4
  48. package/dist/esm/ui/TableFloatingColumnControls/index.js +18 -9
  49. package/dist/esm/ui/common-styles.js +2 -2
  50. package/dist/esm/utils/decoration.js +48 -34
  51. package/dist/esm/utils/dom.js +0 -18
  52. package/dist/esm/utils/index.js +1 -1
  53. package/dist/types/transforms/column-width.d.ts +1 -14
  54. package/dist/types/types.d.ts +0 -1
  55. package/dist/types/ui/FloatingDragMenu/index.d.ts +3 -1
  56. package/dist/types/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +3 -1
  57. package/dist/types/ui/TableFloatingColumnControls/index.d.ts +2 -0
  58. package/dist/types/utils/dom.d.ts +0 -1
  59. package/dist/types/utils/index.d.ts +1 -1
  60. package/dist/types-ts4.5/transforms/column-width.d.ts +1 -14
  61. package/dist/types-ts4.5/types.d.ts +0 -1
  62. package/dist/types-ts4.5/ui/FloatingDragMenu/index.d.ts +3 -1
  63. package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +3 -1
  64. package/dist/types-ts4.5/ui/TableFloatingColumnControls/index.d.ts +2 -0
  65. package/dist/types-ts4.5/utils/dom.d.ts +0 -1
  66. package/dist/types-ts4.5/utils/index.d.ts +1 -1
  67. package/package.json +6 -9
  68. package/src/__tests__/unit/commands/insert.ts +7 -0
  69. package/src/__tests__/unit/transforms/delete-columns.ts +147 -368
  70. package/src/commands/insert.ts +1 -3
  71. package/src/nodeviews/TableComponent.tsx +7 -2
  72. package/src/plugin.tsx +1 -0
  73. package/src/pm-plugins/main.ts +0 -18
  74. package/src/pm-plugins/table-resizing/event-handlers.ts +1 -8
  75. package/src/transforms/column-width.ts +4 -137
  76. package/src/transforms/delete-columns.ts +3 -9
  77. package/src/types.ts +0 -2
  78. package/src/ui/FloatingDragMenu/index.tsx +14 -2
  79. package/src/ui/FloatingInsertButton/InsertButton.tsx +6 -2
  80. package/src/ui/FloatingInsertButton/index.tsx +4 -2
  81. package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +48 -3
  82. package/src/ui/TableFloatingColumnControls/index.tsx +23 -11
  83. package/src/ui/common-styles.ts +6 -0
  84. package/src/utils/decoration.ts +41 -28
  85. package/src/utils/dom.ts +0 -23
  86. package/src/utils/index.ts +0 -1
@@ -20,7 +20,7 @@ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
20
20
 
21
21
  import { updateResizeHandleDecorations } from '../../commands/misc';
22
22
  import { updateColumnWidths } from '../../transforms';
23
- import { getSelectedColumnIndexes, updateResizeHandles } from '../../utils';
23
+ import { getSelectedColumnIndexes } from '../../utils';
24
24
  import { META_KEYS } from '../table-analytics';
25
25
 
26
26
  import { evenColumns, setDragging, stopResizing } from './commands';
@@ -228,13 +228,6 @@ export const handleMouseDown = (
228
228
  resizeColumn(resizeState, colIndex, clientX - dragging.startX, dom);
229
229
 
230
230
  updateControls()(state);
231
- // Remove updateResizeHandles
232
- if (
233
- getBooleanFF('platform.editor.table-remove-update-resize-handles_djvab')
234
- ) {
235
- } else {
236
- updateResizeHandles(dom);
237
- }
238
231
  }
239
232
 
240
233
  window.addEventListener('mouseup', finish);
@@ -1,26 +1,17 @@
1
1
  import type { CellAttributes } from '@atlaskit/adf-schema';
2
2
  import { tableCellMinWidth } from '@atlaskit/editor-common/styles';
3
- import type { GetEditorContainerWidth } from '@atlaskit/editor-common/types';
4
3
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
4
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
6
5
  import { AttrStep } from '@atlaskit/editor-prosemirror/transform';
7
6
  import type { ContentNodeWithPos } from '@atlaskit/editor-prosemirror/utils';
8
7
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
9
- import { akEditorDefaultLayoutWidth } from '@atlaskit/editor-shared-styles';
10
- import {
11
- TableMap,
12
- tableNewColumnMinWidth,
13
- } from '@atlaskit/editor-tables/table-map';
8
+ import { TableMap } from '@atlaskit/editor-tables/table-map';
14
9
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
15
10
 
16
11
  import type { ResizeState } from '../pm-plugins/table-resizing/utils';
17
12
  import { hasTableBeenResized } from '../pm-plugins/table-resizing/utils';
18
13
  import { isMinCellWidthTable } from '../pm-plugins/table-resizing/utils/colgroup';
19
- import { getTableMaxWidth } from '../pm-plugins/table-resizing/utils/misc';
20
- import {
21
- getResizeState,
22
- normaliseTableLayout,
23
- } from '../pm-plugins/table-resizing/utils/resize-state';
14
+ import { getResizeState } from '../pm-plugins/table-resizing/utils/resize-state';
24
15
  import { scaleTableTo } from '../pm-plugins/table-resizing/utils/scale-table';
25
16
  import { insertColumnButtonOffset } from '../ui/common-styles';
26
17
 
@@ -112,7 +103,7 @@ export const updateColumnWidths =
112
103
  * @param view
113
104
  * @returns Updated transaction with rescaled columns for a given table
114
105
  */
115
- export const rescaleColumnsNew =
106
+ export const rescaleColumns =
116
107
  () =>
117
108
  (table: ContentNodeWithPos, view: EditorView | undefined) =>
118
109
  (tr: Transaction): Transaction => {
@@ -138,8 +129,7 @@ export const rescaleColumnsNew =
138
129
  possibleMaxWidth: getBooleanFF('platform.editor.custom-table-width')
139
130
  ? tableRef?.parentElement?.clientWidth || 0
140
131
  : (tableRef?.parentElement?.clientWidth || 0) -
141
- insertColumnButtonOffset -
142
- 1,
132
+ insertColumnButtonOffset,
143
133
  isResized,
144
134
  };
145
135
 
@@ -223,126 +213,3 @@ export const rescaleColumnsNew =
223
213
 
224
214
  return updateColumnWidths(resizeState, table.node, table.start)(tr);
225
215
  };
226
-
227
- /**
228
- * This function is called when user inserts/deletes a column in a table to;
229
- * - rescale all columns (if the table did not overflow before the insertion)
230
- * - and update column widths.
231
- *
232
- * This is done manually to avoid a multi-dispatch in TableComponent. See [ED-8288].
233
- * @param table
234
- * @param view
235
- * @returns Updated transaction with rescaled columns for a given table
236
- */
237
- export const rescaleColumnsOld =
238
- (getEditorContainerWidth: GetEditorContainerWidth) =>
239
- (table: ContentNodeWithPos, view: EditorView | undefined) =>
240
- (tr: Transaction): Transaction => {
241
- if (!view) {
242
- return tr;
243
- }
244
-
245
- const pos = table.pos;
246
- const newTable = tr.doc.nodeAt(pos);
247
- const { state } = view;
248
- const domAtPos = view.domAtPos.bind(view);
249
- const maybeTable = domAtPos(table.start).node as HTMLElement;
250
- const tableRef = maybeTable.closest('table');
251
-
252
- if (!tableRef || !newTable) {
253
- return tr;
254
- }
255
-
256
- const layout = normaliseTableLayout(tableRef?.dataset.layout);
257
- // The is the width the table can reach before overflowing
258
- const maxSize = getTableMaxWidth({
259
- table: table.node,
260
- tableStart: table.start,
261
- state,
262
- layout,
263
- getEditorContainerWidth,
264
- });
265
-
266
- const tableWidth = tableRef.clientWidth || akEditorDefaultLayoutWidth;
267
- let tableMaxWidth = tableRef?.parentElement?.clientWidth || 0;
268
- tableMaxWidth -= insertColumnButtonOffset;
269
- const newTableMap = TableMap.get(newTable);
270
- const noOfColumns = newTableMap.width;
271
- if (!noOfColumns || noOfColumns <= 0) {
272
- return tr;
273
- }
274
- const columnWidthUnresized = tableWidth / noOfColumns;
275
-
276
- // If the table has not been resized, and the column width is bigger than the minimum column width
277
- // we skip updating the size of columns here.
278
- if (
279
- !hasTableBeenResized(table.node) &&
280
- columnWidthUnresized > tableCellMinWidth
281
- ) {
282
- return tr;
283
- }
284
-
285
- // If the table has not been resized, and the column width is smaller than the minimum column width
286
- // Or if the table has been resized, but each column width is either 48px or null
287
- // we update the table to have 48px for each column
288
- if (
289
- (!hasTableBeenResized(table.node) &&
290
- columnWidthUnresized <= tableCellMinWidth) ||
291
- (hasTableBeenResized(table.node) && isMinCellWidthTable(table.node))
292
- ) {
293
- const widths: Array<number> = new Array(noOfColumns).fill(
294
- tableCellMinWidth,
295
- );
296
- const cols = widths.map((_, index) => ({
297
- width: tableCellMinWidth,
298
- minWidth: tableCellMinWidth,
299
- index,
300
- }));
301
- const overflow = tableWidth > maxSize;
302
- const minWidthResizeState = {
303
- cols,
304
- widths,
305
- maxSize,
306
- tableWidth,
307
- overflow,
308
- };
309
- return updateColumnWidths(
310
- minWidthResizeState,
311
- table.node,
312
- table.start,
313
- )(tr);
314
- }
315
-
316
- let resizeState = getResizeState({
317
- minWidth: tableCellMinWidth,
318
- table: table.node,
319
- start: table.start,
320
- tableRef,
321
- domAtPos,
322
- maxSize,
323
- });
324
- const previousTableWidth = resizeState.tableWidth - tableNewColumnMinWidth;
325
- const tableDidntPreviouslyOverflow =
326
- previousTableWidth <= Math.max(maxSize, tableMaxWidth);
327
-
328
- // If the new table width will result in the table going into an overflow state
329
- // we resize the cells to avoid the overflow occuring
330
- if (tableDidntPreviouslyOverflow && resizeState.overflow) {
331
- resizeState = scaleTableTo(resizeState, maxSize);
332
- }
333
-
334
- return updateColumnWidths(resizeState, table.node, table.start)(tr);
335
- };
336
-
337
- export const rescaleColumns = (
338
- getEditorContainerWidth?: GetEditorContainerWidth,
339
- ) => {
340
- if (
341
- getBooleanFF(
342
- 'platform.editor.table-update-colwidths-after-column-is-deleted',
343
- )
344
- ) {
345
- return rescaleColumnsNew();
346
- }
347
- return rescaleColumnsOld(getEditorContainerWidth!);
348
- };
@@ -8,7 +8,6 @@ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
8
8
  import type { Rect } from '@atlaskit/editor-tables/table-map';
9
9
  import { TableMap } from '@atlaskit/editor-tables/table-map';
10
10
  import { findTable } from '@atlaskit/editor-tables/utils';
11
- import { getBooleanFF } from '@atlaskit/platform-feature-flags';
12
11
 
13
12
  import { META_KEYS } from '../pm-plugins/table-analytics';
14
13
 
@@ -263,14 +262,9 @@ export const deleteColumns =
263
262
  updatedTr = deleteColumnsLegacy(rect)(updatedTr);
264
263
  }
265
264
  const table = findTable(updatedTr.selection);
266
- if (
267
- getBooleanFF(
268
- 'platform.editor.table-update-colwidths-after-column-is-deleted',
269
- )
270
- ) {
271
- if (table) {
272
- updatedTr = rescaleColumns()(table, view)(updatedTr);
273
- }
265
+
266
+ if (table) {
267
+ updatedTr = rescaleColumns()(table, view)(updatedTr);
274
268
  }
275
269
  return updatedTr;
276
270
  };
package/src/types.ts CHANGED
@@ -359,8 +359,6 @@ export const TableCssClassName = {
359
359
  RESIZE_CURSOR: `${tablePrefixSelector}-resize-cursor`,
360
360
  IS_RESIZING: `${tablePrefixSelector}-is-resizing`,
361
361
 
362
- // Resize handle is going to be removed together with updateResizeHandles - table's utility function
363
- RESIZE_HANDLE: `${tablePrefixSelector}-resize-handle`,
364
362
  RESIZE_HANDLE_DECORATION: `${tablePrefixSelector}-resize-decoration`,
365
363
 
366
364
  CONTEXTUAL_SUBMENU: `${tablePrefixSelector}-contextual-submenu`,
@@ -5,9 +5,13 @@ import type { GetEditorContainerWidth } from '@atlaskit/editor-common/types';
5
5
  import { Popup } from '@atlaskit/editor-common/ui';
6
6
  import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
7
7
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
8
- import { akEditorFloatingOverlapPanelZIndex } from '@atlaskit/editor-shared-styles';
8
+ import {
9
+ akEditorFloatingDialogZIndex,
10
+ akEditorFloatingOverlapPanelZIndex,
11
+ } from '@atlaskit/editor-shared-styles';
9
12
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
10
13
 
14
+ import type { RowStickyState } from '../../pm-plugins/sticky-headers';
11
15
  import type { TableDirection } from '../../types';
12
16
  import { dragMenuDropdownWidth } from '../consts';
13
17
 
@@ -27,6 +31,7 @@ export interface Props {
27
31
  getEditorContainerWidth: GetEditorContainerWidth;
28
32
  canDrag?: boolean;
29
33
  editorAnalyticsAPI?: EditorAnalyticsAPI;
34
+ stickyHeaders?: RowStickyState;
30
35
  }
31
36
 
32
37
  const FloatingDragMenu = ({
@@ -42,6 +47,7 @@ const FloatingDragMenu = ({
42
47
  getEditorContainerWidth,
43
48
  canDrag,
44
49
  editorAnalyticsAPI,
50
+ stickyHeaders,
45
51
  }: Props) => {
46
52
  if (
47
53
  !isOpen ||
@@ -50,6 +56,7 @@ const FloatingDragMenu = ({
50
56
  ) {
51
57
  return null;
52
58
  }
59
+ const inStickyMode = stickyHeaders?.sticky;
53
60
 
54
61
  const targetHandleRef =
55
62
  direction === 'row'
@@ -77,7 +84,12 @@ const FloatingDragMenu = ({
77
84
  fitWidth={dragMenuDropdownWidth}
78
85
  // z-index value below is to ensure that this menu is above other floating menu
79
86
  // in table, but below floating dialogs like typeaheads, pickers, etc.
80
- zIndex={akEditorFloatingOverlapPanelZIndex}
87
+ // In sticky mode, we want to show the menu above the sticky header
88
+ zIndex={
89
+ inStickyMode
90
+ ? akEditorFloatingDialogZIndex
91
+ : akEditorFloatingOverlapPanelZIndex
92
+ }
81
93
  forcePlacement={true}
82
94
  offset={offset}
83
95
  stick={true}
@@ -32,6 +32,7 @@ export interface ButtonProps {
32
32
  const getInsertLineHeight = (
33
33
  tableRef: HTMLElement,
34
34
  hasStickyHeaders: boolean,
35
+ isDragAndDropEnabled?: boolean,
35
36
  ) => {
36
37
  // The line gets height 100% from the table,
37
38
  // but since we have an overflow on the left,
@@ -39,7 +40,9 @@ const getInsertLineHeight = (
39
40
  const LINE_OFFSET = 3;
40
41
 
41
42
  const ADDITIONAL_HEIGHT = hasStickyHeaders
42
- ? tableRef.getBoundingClientRect().top - tableMarginTop * 4 - LINE_OFFSET
43
+ ? tableRef.getBoundingClientRect().top -
44
+ tableMarginTop * (isDragAndDropEnabled ? 3 : 4) -
45
+ LINE_OFFSET
43
46
  : tableToolbarSize + LINE_OFFSET;
44
47
  return tableRef.offsetHeight + ADDITIONAL_HEIGHT;
45
48
  };
@@ -140,7 +143,8 @@ export const InsertButtonForDragAndDrop = ({
140
143
  left: token('space.150', '12px'),
141
144
  }
142
145
  : {
143
- height: getInsertLineHeight(tableRef, hasStickyHeaders) - 8,
146
+ height:
147
+ getInsertLineHeight(tableRef, hasStickyHeaders, true) - 8,
144
148
  top: '-3px',
145
149
  }
146
150
  }
@@ -21,7 +21,7 @@ import { closestElement } from '@atlaskit/editor-common/utils';
21
21
  import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
22
22
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
23
23
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
24
- import { akEditorTableCellOnStickyHeaderZIndex } from '@atlaskit/editor-shared-styles';
24
+ import { akEditorTableInsertButtonOnStickyHeaderZIndex } from '@atlaskit/editor-shared-styles';
25
25
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
26
26
  import { TableMap } from '@atlaskit/editor-tables/table-map';
27
27
  import { findTable } from '@atlaskit/editor-tables/utils';
@@ -192,7 +192,9 @@ export class FloatingInsertButton extends React.Component<
192
192
  // Only when inserting a column, otherwise set to undefined
193
193
  // Need to set z-index in the Popup, set z-index in the <InsertButton /> will not work
194
194
  const zIndex: number | undefined =
195
- type === 'column' ? akEditorTableCellOnStickyHeaderZIndex : undefined;
195
+ type === 'column'
196
+ ? akEditorTableInsertButtonOnStickyHeaderZIndex
197
+ : undefined;
196
198
 
197
199
  return (
198
200
  <Popup
@@ -1,10 +1,12 @@
1
1
  /* eslint-disable @atlaskit/design-system/prefer-primitives */
2
2
  import type { MouseEvent } from 'react';
3
- import React, { useCallback, useMemo } from 'react';
3
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
4
4
 
5
5
  import { tableCellMinWidth } from '@atlaskit/editor-common/styles';
6
+ import { closestElement } from '@atlaskit/editor-common/utils';
6
7
  import type { Selection } from '@atlaskit/editor-prosemirror/state';
7
8
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
9
+ import { akEditorTableNumberColumnWidth } from '@atlaskit/editor-shared-styles';
8
10
  import { CellSelection } from '@atlaskit/editor-tables';
9
11
  import { getSelectionRect } from '@atlaskit/editor-tables/utils';
10
12
 
@@ -35,6 +37,8 @@ export interface ColumnControlsProps {
35
37
  hasHeaderColumn?: boolean;
36
38
  isTableHovered?: boolean;
37
39
  canDrag?: boolean;
40
+ tableContainerWidth?: number;
41
+ isNumberColumnEnabled?: boolean;
38
42
  }
39
43
 
40
44
  const getSelectedColumns = (selection: Selection) => {
@@ -62,10 +66,18 @@ export const ColumnControls = ({
62
66
  hasHeaderColumn,
63
67
  isTableHovered,
64
68
  canDrag,
69
+ tableContainerWidth,
70
+ isNumberColumnEnabled,
65
71
  }: ColumnControlsProps) => {
72
+ const columnControlsRef = useRef<HTMLDivElement>(null);
66
73
  const widths =
67
- colWidths?.map((width) => (width ? `${width - 1}px` : '0px')).join(' ') ??
68
- '0px';
74
+ colWidths
75
+ ?.map((width) =>
76
+ // when there is sticky header, a `margin-right: -1px` applied to `tr.sticky th` so it causes colWidths to be 1px wider
77
+ // we need to reduce the width by 1px to avoid misalignment of column controls.
78
+ width ? (stickyTop ? `${width - 2}px` : `${width - 1}px`) : '0px',
79
+ )
80
+ .join(' ') ?? '0px';
69
81
  // TODO: reusing getRowsParams here because it's generic enough to work for columns -> rename
70
82
  const columnParams = getRowsParams(colWidths ?? []);
71
83
  const colIndex = hoveredCell?.colIndex;
@@ -153,6 +165,32 @@ export const ColumnControls = ({
153
165
  const colIndexes = useMemo(() => {
154
166
  return [colIndex!];
155
167
  }, [colIndex]);
168
+ const tableWrapper = closestElement(
169
+ tableRef,
170
+ `.${ClassName.TABLE_NODE_WRAPPER}`,
171
+ );
172
+ const handleScroll = useCallback(
173
+ (event?: Event) => {
174
+ if (stickyTop) {
175
+ if (columnControlsRef && columnControlsRef.current) {
176
+ columnControlsRef.current.scrollLeft = tableWrapper?.scrollLeft ?? 0;
177
+ }
178
+ }
179
+ },
180
+ [stickyTop, tableWrapper],
181
+ );
182
+
183
+ useEffect(() => {
184
+ handleScroll();
185
+ }, [handleScroll]);
186
+
187
+ useEffect(() => {
188
+ tableWrapper?.addEventListener('scroll', handleScroll);
189
+
190
+ return () => {
191
+ tableWrapper?.removeEventListener('scroll', handleScroll);
192
+ };
193
+ }, [tableWrapper, handleScroll]);
156
194
 
157
195
  const generateHandleByType = (type: HandleTypes): JSX.Element | null => {
158
196
  if (!hoveredCell || !colWidths?.length) {
@@ -260,17 +298,24 @@ export const ColumnControls = ({
260
298
  : sortedHandles.reverse();
261
299
  };
262
300
 
301
+ const containerWidth =
302
+ isNumberColumnEnabled && tableContainerWidth
303
+ ? tableContainerWidth - akEditorTableNumberColumnWidth
304
+ : tableContainerWidth;
263
305
  return (
264
306
  <div
265
307
  className={ClassName.DRAG_COLUMN_CONTROLS}
266
308
  onMouseMove={handleMouseMove}
267
309
  >
268
310
  <div
311
+ ref={columnControlsRef}
269
312
  className={ClassName.DRAG_COLUMN_CONTROLS_INNER}
270
313
  data-testid="table-floating-column-controls"
271
314
  style={{
272
315
  gridTemplateColumns: widths,
273
316
  marginTop,
317
+ width: stickyTop ? containerWidth : undefined,
318
+ overflowX: stickyTop ? 'hidden' : 'visible',
274
319
  }}
275
320
  >
276
321
  {!isResizing &&
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useState } from 'react';
1
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import type { TableColumnOrdering } from '@atlaskit/custom-steps';
4
4
  import type { GetEditorFeatureFlags } from '@atlaskit/editor-common/types';
@@ -36,6 +36,8 @@ export interface Props {
36
36
  stickyHeader?: RowStickyState;
37
37
  isTableHovered?: boolean;
38
38
  canDrag?: boolean;
39
+ tableContainerWidth?: number;
40
+ isNumberColumnEnabled?: boolean;
39
41
  }
40
42
 
41
43
  export const TableFloatingColumnControls: React.FC<Props> = ({
@@ -51,15 +53,22 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
51
53
  isInDanger,
52
54
  isTableHovered,
53
55
  canDrag,
56
+ tableContainerWidth,
57
+ isNumberColumnEnabled,
54
58
  }) => {
55
59
  const [tableRect, setTableRect] = useState<{ width: number; height: number }>(
56
60
  { width: 0, height: 0 },
57
61
  );
58
-
59
62
  const [hasDropTargets, setHasDropTargets] = useState(false);
63
+ const containerRef = useRef<HTMLDivElement>(null);
64
+
60
65
  const node = getNode();
61
66
  const currentNodeLocalId = node?.attrs.localId;
62
67
  const hasHeaderColumn = containsHeaderColumn(node);
68
+ const stickyTop =
69
+ stickyHeader && stickyHeader.sticky && hasHeaderRow
70
+ ? stickyHeader.top
71
+ : undefined;
63
72
 
64
73
  useEffect(() => {
65
74
  if (tableRef && window?.ResizeObserver) {
@@ -118,19 +127,20 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
118
127
 
119
128
  const colWidths = getColumnsWidths(editorView);
120
129
 
121
- const stickyTop =
122
- stickyHeader && stickyHeader.sticky && hasHeaderRow
123
- ? stickyHeader.top
124
- : undefined;
125
-
126
- // TODO - Removing column controls for now because they are causing the table
127
- // to overflow and scroll. Update this when sticky header support is added ED-21088
128
- if (stickyHeader && stickyHeader.sticky) {
129
- return null;
130
+ if (stickyTop) {
131
+ const headerRowHeight =
132
+ hasHeaderRow && stickyTop !== undefined ? rowHeights?.[0] ?? 0 : 0;
133
+ containerRef?.current?.style.setProperty(
134
+ 'top',
135
+ `${stickyTop! - headerRowHeight + 33}px`, // 33px is padding and margin applied on tr.sticky
136
+ );
137
+ } else {
138
+ containerRef?.current?.style.removeProperty('top');
130
139
  }
131
140
 
132
141
  return (
133
142
  <div
143
+ ref={containerRef}
134
144
  className={ClassName.DRAG_COLUMN_CONTROLS_WRAPPER}
135
145
  data-testid="table-floating-column-controls-wrapper"
136
146
  >
@@ -148,6 +158,8 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
148
158
  colWidths={colWidths}
149
159
  hasHeaderColumn={hasHeaderColumn}
150
160
  canDrag={canDrag}
161
+ tableContainerWidth={tableContainerWidth}
162
+ isNumberColumnEnabled={isNumberColumnEnabled}
151
163
  />
152
164
  {hasDropTargets && (
153
165
  <ColumnDropTargets
@@ -7,6 +7,7 @@ import {
7
7
  import type { FeatureFlags } from '@atlaskit/editor-common/types';
8
8
  import { browser } from '@atlaskit/editor-common/utils';
9
9
  import {
10
+ akEditorFloatingDialogZIndex,
10
11
  akEditorSelectedNodeClassName,
11
12
  akEditorSmallZIndex,
12
13
  akEditorStickyHeaderZIndex,
@@ -1049,6 +1050,11 @@ export const tableStyles = (props: { featureFlags?: FeatureFlags }) => css`
1049
1050
  top: ${tableMarginTop}px;
1050
1051
  }
1051
1052
 
1053
+ .${ClassName.TABLE_STICKY} .${ClassName.DRAG_COLUMN_CONTROLS_WRAPPER} {
1054
+ position: fixed;
1055
+ z-index: ${akEditorFloatingDialogZIndex};
1056
+ }
1057
+
1052
1058
  ${tableWrapperStyles()}
1053
1059
  }
1054
1060
 
@@ -22,6 +22,7 @@ import {
22
22
  getCellsInRow,
23
23
  getSelectionRect,
24
24
  } from '@atlaskit/editor-tables/utils';
25
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
25
26
 
26
27
  import type { Cell, CellColumnPositioning } from '../types';
27
28
  import { TableCssClassName as ClassName, TableDecorations } from '../types';
@@ -101,34 +102,46 @@ export const createControlsHoverDecoration = (
101
102
  // So If the table cells are in danger we want to create a "rectangle" selection
102
103
  // to match the "clicked" selection
103
104
 
104
- if (danger) {
105
- // Find the bounding rectangle of all the given cells, also considering
106
- // merged cells.
107
- const { recLeft, recTop, recRight, recBottom } = cells.reduce(
108
- (acc, cell) => {
109
- const { left, right, bottom, top } = map.findCell(
110
- cell.pos - table.start,
111
- );
112
- // Finding the bounding rect requires finding the min left and top positions,
113
- // and the max right and bottom positions of the cells
114
- return {
115
- recLeft: Math.min(acc.recLeft, left),
116
- recTop: Math.min(acc.recTop, top),
117
- recRight: Math.max(acc.recRight, right),
118
- recBottom: Math.max(acc.recBottom, bottom),
119
- };
120
- },
121
- // +-Infinity as initialisation vars which will always be overwritten
122
- // by smaller/larger values respectively
123
- {
124
- recLeft: Infinity,
125
- recTop: Infinity,
126
- recRight: -Infinity,
127
- recBottom: -Infinity,
128
- },
129
- );
130
- const rect = new Rect(recLeft, recTop, recRight, recBottom);
131
- updatedCells = map.cellsInRect(rect).map((x) => x + table.start);
105
+ if (getBooleanFF('platform.editor.table.in-danger-hover-merged-cells-fix')) {
106
+ if (danger && type !== 'table') {
107
+ const { selection } = tr;
108
+ const table = findTable(selection);
109
+ const rect = getSelectionRect(selection);
110
+
111
+ if (table && rect) {
112
+ updatedCells = map.cellsInRect(rect).map((x) => x + table.start);
113
+ }
114
+ }
115
+ } else {
116
+ if (danger) {
117
+ // Find the bounding rectangle of all the given cells, also considering
118
+ // merged cells.
119
+ const { recLeft, recTop, recRight, recBottom } = cells.reduce(
120
+ (acc, cell) => {
121
+ const { left, right, bottom, top } = map.findCell(
122
+ cell.pos - table.start,
123
+ );
124
+ // Finding the bounding rect requires finding the min left and top positions,
125
+ // and the max right and bottom positions of the cells
126
+ return {
127
+ recLeft: Math.min(acc.recLeft, left),
128
+ recTop: Math.min(acc.recTop, top),
129
+ recRight: Math.max(acc.recRight, right),
130
+ recBottom: Math.max(acc.recBottom, bottom),
131
+ };
132
+ },
133
+ // +-Infinity as initialisation vars which will always be overwritten
134
+ // by smaller/larger values respectively
135
+ {
136
+ recLeft: Infinity,
137
+ recTop: Infinity,
138
+ recRight: -Infinity,
139
+ recBottom: -Infinity,
140
+ },
141
+ );
142
+ const rect = new Rect(recLeft, recTop, recRight, recBottom);
143
+ updatedCells = map.cellsInRect(rect).map((x) => x + table.start);
144
+ }
132
145
  }
133
146
 
134
147
  return updatedCells.map((pos) => {
package/src/utils/dom.ts CHANGED
@@ -5,7 +5,6 @@ import {
5
5
 
6
6
  import { TableCssClassName as ClassName } from '../types';
7
7
  import type { ElementContentRects } from '../types';
8
- import { tableToolbarSize } from '../ui/consts';
9
8
 
10
9
  const SELECTOR_TABLE_LEAFS = `.${ClassName.TABLE_CELL}, .${ClassName.TABLE_HEADER_CELL}`;
11
10
 
@@ -178,28 +177,6 @@ export const getMousePositionVerticalRelativeByElement = (
178
177
  return null;
179
178
  };
180
179
 
181
- // This function is deprecated
182
- export const updateResizeHandles = (tableRef?: HTMLElement) => {
183
- if (!tableRef) {
184
- return;
185
- }
186
-
187
- // see ED-7600
188
- const nodes = Array.from(
189
- tableRef.querySelectorAll(
190
- `.${ClassName.RESIZE_HANDLE}`,
191
- ) as NodeListOf<HTMLElement>,
192
- );
193
- if (!nodes || !nodes.length) {
194
- return;
195
- }
196
-
197
- const height = tableRef.offsetHeight + tableToolbarSize;
198
- nodes.forEach((node) => {
199
- node.style.height = `${height}px`;
200
- });
201
- };
202
-
203
180
  export const hasResizeHandler = ({
204
181
  columnEndIndexTarget,
205
182
  target,
@@ -54,7 +54,6 @@ export {
54
54
  getColumnOrRowIndex,
55
55
  getMousePositionHorizontalRelativeByElement,
56
56
  getMousePositionVerticalRelativeByElement,
57
- updateResizeHandles,
58
57
  isResizeHandleDecoration,
59
58
  hasResizeHandler,
60
59
  findNearestCellIndexToPoint,