@atlaskit/editor-plugin-table 7.6.2 → 7.6.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 (119) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/commands/misc.js +3 -2
  3. package/dist/cjs/nodeviews/TableComponent.js +25 -11
  4. package/dist/cjs/nodeviews/TableComponentWithSharedState.js +87 -0
  5. package/dist/cjs/nodeviews/TableContainer.js +37 -21
  6. package/dist/cjs/nodeviews/TableResizer.js +40 -29
  7. package/dist/cjs/nodeviews/table.js +21 -1
  8. package/dist/cjs/plugin.js +25 -2
  9. package/dist/cjs/toolbar.js +5 -4
  10. package/dist/cjs/types.js +3 -0
  11. package/dist/cjs/ui/FloatingContextualMenu/ContextualMenu.js +16 -16
  12. package/dist/cjs/ui/FloatingDragMenu/DragMenu.js +3 -3
  13. package/dist/cjs/ui/FloatingDragMenu/DropdownMenu.js +21 -28
  14. package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +6 -2
  15. package/dist/cjs/ui/TableFloatingColumnControls/index.js +5 -2
  16. package/dist/cjs/ui/TableFloatingControls/CornerControls/DragCornerControls.js +48 -1
  17. package/dist/cjs/ui/TableFloatingControls/CornerControls/index.js +6 -0
  18. package/dist/cjs/ui/TableFloatingControls/FloatingControlsWithSelection.js +47 -0
  19. package/dist/cjs/ui/TableFloatingControls/RowControls/ClassicControls.js +3 -2
  20. package/dist/cjs/ui/TableFloatingControls/index.js +25 -3
  21. package/dist/cjs/ui/common-styles.js +11 -6
  22. package/dist/cjs/utils/guidelines.js +1 -1
  23. package/dist/es2019/commands/misc.js +6 -2
  24. package/dist/es2019/nodeviews/TableComponent.js +27 -12
  25. package/dist/es2019/nodeviews/TableComponentWithSharedState.js +83 -0
  26. package/dist/es2019/nodeviews/TableContainer.js +24 -6
  27. package/dist/es2019/nodeviews/TableResizer.js +27 -19
  28. package/dist/es2019/nodeviews/table.js +21 -1
  29. package/dist/es2019/plugin.js +26 -3
  30. package/dist/es2019/toolbar.js +5 -4
  31. package/dist/es2019/types.js +3 -0
  32. package/dist/es2019/ui/FloatingContextualMenu/ContextualMenu.js +16 -16
  33. package/dist/es2019/ui/FloatingDragMenu/DragMenu.js +3 -3
  34. package/dist/es2019/ui/FloatingDragMenu/DropdownMenu.js +20 -27
  35. package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +7 -2
  36. package/dist/es2019/ui/TableFloatingColumnControls/index.js +5 -2
  37. package/dist/es2019/ui/TableFloatingControls/CornerControls/DragCornerControls.js +55 -0
  38. package/dist/es2019/ui/TableFloatingControls/CornerControls/index.js +1 -1
  39. package/dist/es2019/ui/TableFloatingControls/FloatingControlsWithSelection.js +42 -0
  40. package/dist/es2019/ui/TableFloatingControls/RowControls/ClassicControls.js +3 -2
  41. package/dist/es2019/ui/TableFloatingControls/index.js +26 -4
  42. package/dist/es2019/ui/common-styles.js +589 -588
  43. package/dist/es2019/utils/guidelines.js +1 -1
  44. package/dist/esm/commands/misc.js +3 -2
  45. package/dist/esm/nodeviews/TableComponent.js +25 -11
  46. package/dist/esm/nodeviews/TableComponentWithSharedState.js +80 -0
  47. package/dist/esm/nodeviews/TableContainer.js +37 -21
  48. package/dist/esm/nodeviews/TableResizer.js +41 -30
  49. package/dist/esm/nodeviews/table.js +21 -1
  50. package/dist/esm/plugin.js +26 -3
  51. package/dist/esm/toolbar.js +5 -4
  52. package/dist/esm/types.js +3 -0
  53. package/dist/esm/ui/FloatingContextualMenu/ContextualMenu.js +16 -16
  54. package/dist/esm/ui/FloatingDragMenu/DragMenu.js +3 -3
  55. package/dist/esm/ui/FloatingDragMenu/DropdownMenu.js +21 -28
  56. package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +6 -2
  57. package/dist/esm/ui/TableFloatingColumnControls/index.js +5 -2
  58. package/dist/esm/ui/TableFloatingControls/CornerControls/DragCornerControls.js +47 -0
  59. package/dist/esm/ui/TableFloatingControls/CornerControls/index.js +1 -1
  60. package/dist/esm/ui/TableFloatingControls/FloatingControlsWithSelection.js +40 -0
  61. package/dist/esm/ui/TableFloatingControls/RowControls/ClassicControls.js +3 -2
  62. package/dist/esm/ui/TableFloatingControls/index.js +26 -4
  63. package/dist/esm/ui/common-styles.js +10 -5
  64. package/dist/esm/utils/guidelines.js +1 -1
  65. package/dist/types/commands/misc.d.ts +2 -1
  66. package/dist/types/nodeviews/TableComponent.d.ts +7 -2
  67. package/dist/types/nodeviews/TableComponentWithSharedState.d.ts +27 -0
  68. package/dist/types/nodeviews/TableContainer.d.ts +4 -2
  69. package/dist/types/nodeviews/TableResizer.d.ts +4 -1
  70. package/dist/types/nodeviews/types.d.ts +1 -0
  71. package/dist/types/plugin.d.ts +11 -7
  72. package/dist/types/types.d.ts +13 -4
  73. package/dist/types/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +113 -1
  74. package/dist/types/ui/TableFloatingColumnControls/index.d.ts +3 -2
  75. package/dist/types/ui/TableFloatingControls/CornerControls/DragCornerControls.d.ts +223 -0
  76. package/dist/types/ui/TableFloatingControls/CornerControls/index.d.ts +1 -1
  77. package/dist/types/ui/TableFloatingControls/FloatingControlsWithSelection.d.ts +20 -0
  78. package/dist/types/ui/TableFloatingControls/RowControls/ClassicControls.d.ts +2 -0
  79. package/dist/types/ui/TableFloatingControls/index.d.ts +113 -1
  80. package/dist/types/ui/common-styles.d.ts +3 -0
  81. package/dist/types-ts4.5/commands/misc.d.ts +2 -1
  82. package/dist/types-ts4.5/nodeviews/TableComponent.d.ts +7 -2
  83. package/dist/types-ts4.5/nodeviews/TableComponentWithSharedState.d.ts +27 -0
  84. package/dist/types-ts4.5/nodeviews/TableContainer.d.ts +4 -2
  85. package/dist/types-ts4.5/nodeviews/TableResizer.d.ts +4 -1
  86. package/dist/types-ts4.5/nodeviews/types.d.ts +1 -0
  87. package/dist/types-ts4.5/plugin.d.ts +11 -7
  88. package/dist/types-ts4.5/types.d.ts +13 -4
  89. package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +144 -1
  90. package/dist/types-ts4.5/ui/TableFloatingColumnControls/index.d.ts +3 -2
  91. package/dist/types-ts4.5/ui/TableFloatingControls/CornerControls/DragCornerControls.d.ts +285 -0
  92. package/dist/types-ts4.5/ui/TableFloatingControls/CornerControls/index.d.ts +1 -1
  93. package/dist/types-ts4.5/ui/TableFloatingControls/FloatingControlsWithSelection.d.ts +20 -0
  94. package/dist/types-ts4.5/ui/TableFloatingControls/RowControls/ClassicControls.d.ts +2 -0
  95. package/dist/types-ts4.5/ui/TableFloatingControls/index.d.ts +144 -1
  96. package/dist/types-ts4.5/ui/common-styles.d.ts +3 -0
  97. package/package.json +6 -6
  98. package/src/commands/misc.ts +6 -3
  99. package/src/nodeviews/TableComponent.tsx +36 -7
  100. package/src/nodeviews/TableComponentWithSharedState.tsx +125 -0
  101. package/src/nodeviews/TableContainer.tsx +24 -3
  102. package/src/nodeviews/TableResizer.tsx +36 -21
  103. package/src/nodeviews/table.tsx +22 -1
  104. package/src/nodeviews/types.ts +1 -0
  105. package/src/plugin.tsx +47 -6
  106. package/src/toolbar.tsx +20 -19
  107. package/src/types.ts +33 -4
  108. package/src/ui/FloatingContextualMenu/ContextualMenu.tsx +66 -112
  109. package/src/ui/FloatingDragMenu/DragMenu.tsx +3 -12
  110. package/src/ui/FloatingDragMenu/DropdownMenu.tsx +19 -28
  111. package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +10 -2
  112. package/src/ui/TableFloatingColumnControls/index.tsx +13 -1
  113. package/src/ui/TableFloatingControls/CornerControls/DragCornerControls.tsx +58 -0
  114. package/src/ui/TableFloatingControls/CornerControls/index.tsx +4 -1
  115. package/src/ui/TableFloatingControls/FloatingControlsWithSelection.tsx +68 -0
  116. package/src/ui/TableFloatingControls/RowControls/ClassicControls.tsx +4 -1
  117. package/src/ui/TableFloatingControls/index.tsx +42 -8
  118. package/src/ui/common-styles.ts +611 -610
  119. package/src/utils/guidelines.ts +5 -4
@@ -57,7 +57,7 @@ import {
57
57
  import { hasTableBeenResized } from '../pm-plugins/table-resizing/utils/colgroup';
58
58
  import { TABLE_EDITOR_MARGIN } from '../pm-plugins/table-resizing/utils/consts';
59
59
  import { updateControls } from '../pm-plugins/table-resizing/utils/dom';
60
- import type { PluginInjectionAPI } from '../types';
60
+ import type { CellHoverMeta, PluginInjectionAPI } from '../types';
61
61
  import { TableCssClassName as ClassName, ShadowEvent } from '../types';
62
62
  import {
63
63
  tableOverflowShadowWidth,
@@ -107,11 +107,18 @@ export interface ComponentProps {
107
107
  isDragAndDropEnabled?: boolean;
108
108
  isTableScalingEnabled?: boolean;
109
109
  tableActive: boolean;
110
- ordering: TableColumnOrdering;
110
+ ordering?: TableColumnOrdering;
111
111
  isResizing?: boolean;
112
112
  getEditorFeatureFlags: GetEditorFeatureFlags;
113
113
  dispatchAnalyticsEvent: DispatchAnalyticsEvent;
114
114
  pluginInjectionApi?: PluginInjectionAPI;
115
+
116
+ // marking props as option to ensure backward compatibility when platform.editor.table.use-shared-state-hook disabled
117
+ isInDanger?: boolean;
118
+ hoveredRows?: number[];
119
+ hoveredCell?: CellHoverMeta;
120
+ isTableHovered?: boolean;
121
+ isWholeTableInDanger?: boolean;
115
122
  }
116
123
 
117
124
  interface TableState {
@@ -392,9 +399,15 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
392
399
  isTableScalingEnabled,
393
400
  getPos,
394
401
  } = this.props;
395
- const { isInDanger } = getPluginState(view.state);
402
+ let { isInDanger } = this.props;
403
+
396
404
  const table = findTable(view.state.selection);
397
405
 
406
+ if (!getBooleanFF('platform.editor.table.use-shared-state-hook')) {
407
+ const pluginState = getPluginState(view.state);
408
+ isInDanger = pluginState.isInDanger;
409
+ }
410
+
398
411
  if (isTableScalingEnabled) {
399
412
  this.handleColgroupUpdates();
400
413
  }
@@ -454,7 +467,6 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
454
467
  isNoOfColumnsChanged
455
468
  ) {
456
469
  const { view } = this.props;
457
-
458
470
  const shouldRecreateResizeCols =
459
471
  !options?.isTableResizingEnabled ||
460
472
  !isResizing ||
@@ -570,11 +582,25 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
570
582
  isTableScalingEnabled,
571
583
  } = this.props;
572
584
 
585
+ let {
586
+ isInDanger,
587
+ hoveredRows,
588
+ hoveredCell,
589
+ isTableHovered,
590
+ isWholeTableInDanger,
591
+ } = this.props;
592
+
573
593
  const { showBeforeShadow, showAfterShadow } = this.state;
574
594
  const node = getNode();
575
- // doesn't work well with WithPluginState
576
- const { isInDanger, hoveredRows, hoveredCell, isTableHovered } =
577
- getPluginState(view.state);
595
+
596
+ if (!getBooleanFF('platform.editor.table.use-shared-state-hook')) {
597
+ const pluginState = getPluginState(view.state);
598
+ isInDanger = pluginState.isInDanger;
599
+ hoveredRows = pluginState.hoveredRows;
600
+ hoveredCell = pluginState.hoveredCell;
601
+ isTableHovered = pluginState.isTableHovered;
602
+ isWholeTableInDanger = pluginState.isWholeTableInDanger;
603
+ }
578
604
 
579
605
  const tableRef = this.table || undefined;
580
606
  const headerRow = tableRef
@@ -604,6 +630,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
604
630
  headerRowHeight={headerRow ? headerRow.offsetHeight : undefined}
605
631
  stickyHeader={this.state.stickyHeader}
606
632
  tableWrapperWidth={this.state.tableWrapperWidth}
633
+ api={pluginInjectionApi}
607
634
  />
608
635
  );
609
636
  const tableContainerWidth = getTableContainerWidth(node);
@@ -629,6 +656,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
629
656
  isNumberColumnEnabled={node.attrs.isNumberColumnEnabled}
630
657
  getScrollOffset={() => this.wrapper?.scrollLeft || 0}
631
658
  tableWrapperHeight={this.state.tableWrapperHeight}
659
+ api={pluginInjectionApi}
632
660
  />
633
661
  ) : null;
634
662
 
@@ -685,6 +713,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
685
713
  isTableResizingEnabled={options?.isTableResizingEnabled}
686
714
  isResizing={isResizing}
687
715
  isTableScalingEnabled={isTableScalingEnabled}
716
+ isWholeTableInDanger={isWholeTableInDanger}
688
717
  >
689
718
  <div
690
719
  className={ClassName.TABLE_STICKY_SENTINEL_TOP}
@@ -0,0 +1,125 @@
1
+ import React from 'react';
2
+
3
+ import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
4
+ import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
5
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
6
+ import type {
7
+ GetEditorFeatureFlags,
8
+ getPosHandlerNode,
9
+ } from '@atlaskit/editor-common/types';
10
+ import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
11
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
12
+ import { findTable } from '@atlaskit/editor-tables';
13
+
14
+ import type { PluginInjectionAPI, TableSharedStateInternal } from '../types';
15
+
16
+ import TableComponent from './TableComponent';
17
+ import type { TableOptions } from './types';
18
+
19
+ type ForwardRef = (node: HTMLElement | null) => any;
20
+
21
+ type TableComponentWithSharedStateProps = {
22
+ view: EditorView;
23
+ options?: TableOptions;
24
+ getNode: () => PmNode;
25
+ dispatchAnalyticsEvent: DispatchAnalyticsEvent;
26
+ getEditorFeatureFlags: GetEditorFeatureFlags;
27
+ api?: PluginInjectionAPI;
28
+ eventDispatcher: EventDispatcher;
29
+ forwardRef: ForwardRef;
30
+ getPos: getPosHandlerNode;
31
+ allowColumnResizing?: boolean;
32
+ allowControls?: boolean;
33
+ };
34
+
35
+ /**
36
+ * Use useSharedPluginState to control re-renders from plugin dependencies
37
+ */
38
+ export const TableComponentWithSharedState = ({
39
+ view,
40
+ options,
41
+ getNode,
42
+ dispatchAnalyticsEvent,
43
+ api,
44
+ getEditorFeatureFlags,
45
+ eventDispatcher,
46
+ allowColumnResizing,
47
+ allowControls,
48
+ getPos,
49
+ forwardRef,
50
+ }: TableComponentWithSharedStateProps) => {
51
+ const { widthState, tableState, mediaState } = useSharedPluginState(api, [
52
+ 'width',
53
+ 'table',
54
+ 'media',
55
+ ]);
56
+
57
+ if (!tableState) {
58
+ return null;
59
+ }
60
+
61
+ const {
62
+ isTableResizing,
63
+ isHeaderColumnEnabled,
64
+ isHeaderRowEnabled,
65
+ ordering,
66
+ isResizing,
67
+ isInDanger,
68
+ hoveredCell,
69
+ hoveredRows,
70
+ isTableHovered,
71
+ isWholeTableInDanger,
72
+ } = tableState as TableSharedStateInternal;
73
+
74
+ /**
75
+ * ED-19810
76
+ * There is a getPos issue coming from this code. We need to apply this workaround for now and apply a patch
77
+ * directly to confluence since this bug is now in production.
78
+ */
79
+ let currentTablePos: number | undefined;
80
+ try {
81
+ currentTablePos = getPos ? getPos() : undefined;
82
+ } catch (e) {
83
+ currentTablePos = undefined;
84
+ }
85
+
86
+ const selectedTable = findTable(view.state.selection);
87
+
88
+ const tablePos = selectedTable && selectedTable.start - 1;
89
+
90
+ const tableActive =
91
+ typeof currentTablePos === 'number' &&
92
+ typeof tablePos === 'number' &&
93
+ currentTablePos === tablePos &&
94
+ !isTableResizing;
95
+
96
+ return (
97
+ <TableComponent
98
+ view={view}
99
+ allowColumnResizing={allowColumnResizing}
100
+ eventDispatcher={eventDispatcher}
101
+ getPos={getPos}
102
+ isMediaFullscreen={mediaState?.isFullscreen}
103
+ options={options}
104
+ allowControls={!!allowControls}
105
+ isHeaderRowEnabled={isHeaderRowEnabled}
106
+ isHeaderColumnEnabled={isHeaderColumnEnabled}
107
+ isDragAndDropEnabled={options?.isDragAndDropEnabled}
108
+ isTableScalingEnabled={options?.isTableScalingEnabled}
109
+ tableActive={tableActive}
110
+ ordering={ordering}
111
+ isResizing={isResizing}
112
+ getNode={getNode}
113
+ containerWidth={widthState!}
114
+ contentDOM={forwardRef}
115
+ getEditorFeatureFlags={getEditorFeatureFlags}
116
+ dispatchAnalyticsEvent={dispatchAnalyticsEvent}
117
+ pluginInjectionApi={api}
118
+ isInDanger={!!isInDanger}
119
+ hoveredRows={hoveredRows}
120
+ hoveredCell={hoveredCell}
121
+ isTableHovered={isTableHovered}
122
+ isWholeTableInDanger={isWholeTableInDanger}
123
+ />
124
+ );
125
+ };
@@ -5,6 +5,7 @@ import classNames from 'classnames';
5
5
 
6
6
  import type { TableEventPayload } from '@atlaskit/editor-common/analytics';
7
7
  import type { GuidelineConfig } from '@atlaskit/editor-common/guideline';
8
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
8
9
  import { getTableContainerWidth } from '@atlaskit/editor-common/node-width';
9
10
  import { calcTableWidth } from '@atlaskit/editor-common/styles';
10
11
  import type { EditorContainerWidth } from '@atlaskit/editor-common/types';
@@ -19,7 +20,7 @@ import {
19
20
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
20
21
 
21
22
  import { TABLE_MAX_WIDTH } from '../pm-plugins/table-resizing/utils';
22
- import type { PluginInjectionAPI } from '../types';
23
+ import type { PluginInjectionAPI, TableSharedStateInternal } from '../types';
23
24
  import { TableCssClassName as ClassName } from '../types';
24
25
 
25
26
  import { TableResizer } from './TableResizer';
@@ -61,7 +62,7 @@ export const InnerContainer = forwardRef<
61
62
  className={className}
62
63
  data-number-column={node.attrs.isNumberColumnEnabled}
63
64
  data-layout={node.attrs.layout}
64
- data-test-id="table-container"
65
+ data-testid="table-container"
65
66
  >
66
67
  {children}
67
68
  </div>
@@ -79,6 +80,7 @@ type ResizableTableContainerProps = {
79
80
  pluginInjectionApi?: PluginInjectionAPI;
80
81
  isTableScalingEnabled?: boolean;
81
82
  tableWrapperHeight?: number;
83
+ isWholeTableInDanger?: boolean;
82
84
  };
83
85
 
84
86
  export const ResizableTableContainer = React.memo(
@@ -94,6 +96,7 @@ export const ResizableTableContainer = React.memo(
94
96
  pluginInjectionApi,
95
97
  isTableScalingEnabled,
96
98
  tableWrapperHeight,
99
+ isWholeTableInDanger,
97
100
  }: PropsWithChildren<ResizableTableContainerProps>) => {
98
101
  const containerRef = useRef<HTMLDivElement | null>(null);
99
102
  const tableWidthRef = useRef<number>(akEditorDefaultLayoutWidth);
@@ -178,6 +181,10 @@ export const ResizableTableContainer = React.memo(
178
181
  );
179
182
 
180
183
  const tableWidth = getTableContainerWidth(node);
184
+ const { tableState } = useSharedPluginState(pluginInjectionApi, ['table']);
185
+ const { widthToWidest } = tableState as TableSharedStateInternal;
186
+ const currentTableNodeLocalId = node?.attrs?.localId ?? '';
187
+
181
188
  // 76 is currently an accepted padding value considering the spacing for resizer handle
182
189
  const responsiveContainerWidth = isTableScalingEnabled
183
190
  ? containerWidth -
@@ -187,7 +194,16 @@ export const ResizableTableContainer = React.memo(
187
194
  akEditorGutterPadding * 2 -
188
195
  akEditorMediaResizeHandlerPaddingWide;
189
196
 
190
- const width = Math.min(tableWidth, responsiveContainerWidth);
197
+ let width = Math.min(tableWidth, responsiveContainerWidth);
198
+
199
+ if (
200
+ isTableScalingEnabled &&
201
+ currentTableNodeLocalId &&
202
+ widthToWidest &&
203
+ widthToWidest[currentTableNodeLocalId]
204
+ ) {
205
+ width = TABLE_MAX_WIDTH;
206
+ }
191
207
 
192
208
  if (!isResizing) {
193
209
  tableWidthRef.current = width;
@@ -207,6 +223,8 @@ export const ResizableTableContainer = React.memo(
207
223
  attachAnalyticsEvent,
208
224
  displayGapCursor,
209
225
  isTableScalingEnabled,
226
+ isWholeTableInDanger,
227
+ pluginInjectionApi,
210
228
  };
211
229
 
212
230
  if (getBooleanFF('platform.editor.resizing-table-height-improvement')) {
@@ -259,6 +277,7 @@ type TableContainerProps = {
259
277
  pluginInjectionApi?: PluginInjectionAPI;
260
278
  isTableScalingEnabled?: boolean;
261
279
  tableWrapperHeight?: number;
280
+ isWholeTableInDanger?: boolean;
262
281
  };
263
282
 
264
283
  export const TableContainer = ({
@@ -276,6 +295,7 @@ export const TableContainer = ({
276
295
  isResizing,
277
296
  pluginInjectionApi,
278
297
  isTableScalingEnabled,
298
+ isWholeTableInDanger,
279
299
  }: PropsWithChildren<TableContainerProps>) => {
280
300
  if (isTableResizingEnabled && !isNested) {
281
301
  return (
@@ -290,6 +310,7 @@ export const TableContainer = ({
290
310
  isResizing={isResizing}
291
311
  pluginInjectionApi={pluginInjectionApi}
292
312
  isTableScalingEnabled={isTableScalingEnabled}
313
+ isWholeTableInDanger={isWholeTableInDanger}
293
314
  >
294
315
  {children}
295
316
  </ResizableTableContainer>
@@ -16,6 +16,7 @@ import type { TableEventPayload } from '@atlaskit/editor-common/analytics';
16
16
  import { TABLE_OVERFLOW_CHANGE_TRIGGER } from '@atlaskit/editor-common/analytics';
17
17
  import { getGuidelinesWithHighlights } from '@atlaskit/editor-common/guideline';
18
18
  import type { GuidelineConfig } from '@atlaskit/editor-common/guideline';
19
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
19
20
  import {
20
21
  focusTableResizer,
21
22
  ToolTipContent,
@@ -27,21 +28,21 @@ import { browser } from '@atlaskit/editor-common/utils';
27
28
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
28
29
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
29
30
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
30
- import { akEditorFullWidthLayoutWidth } from '@atlaskit/editor-shared-styles';
31
31
  import { findTable } from '@atlaskit/editor-tables/utils';
32
32
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
33
33
  import { token } from '@atlaskit/tokens';
34
34
 
35
35
  import { updateWidthToWidest } from '../commands/misc';
36
- import { getPluginState } from '../pm-plugins/plugin-factory';
37
36
  import { META_KEYS } from '../pm-plugins/table-analytics';
38
37
  import {
39
38
  COLUMN_MIN_WIDTH,
40
39
  getColgroupChildrenLength,
41
40
  previewScaleTable,
42
41
  scaleTable,
42
+ TABLE_MAX_WIDTH,
43
43
  } from '../pm-plugins/table-resizing/utils';
44
44
  import { pluginKey as tableWidthPluginKey } from '../pm-plugins/table-width';
45
+ import type { PluginInjectionAPI, TableSharedStateInternal } from '../types';
45
46
  import {
46
47
  TABLE_GUIDELINE_VISIBLE_ADJUSTMENT,
47
48
  TABLE_HIGHLIGHT_GAP,
@@ -77,7 +78,9 @@ interface TableResizerProps {
77
78
  payload: TableEventPayload,
78
79
  ) => ((tr: Transaction) => boolean) | undefined;
79
80
  displayGapCursor: (toggle: boolean) => boolean;
81
+ pluginInjectionApi?: PluginInjectionAPI;
80
82
  isTableScalingEnabled?: boolean;
83
+ isWholeTableInDanger?: boolean;
81
84
  }
82
85
 
83
86
  export interface TableResizerImprovementProps extends TableResizerProps {
@@ -170,13 +173,17 @@ export const TableResizer = ({
170
173
  attachAnalyticsEvent,
171
174
  displayGapCursor,
172
175
  isTableScalingEnabled,
176
+ isWholeTableInDanger,
177
+ pluginInjectionApi,
173
178
  }: PropsWithChildren<TableResizerImprovementProps>) => {
174
179
  const currentGap = useRef(0);
175
180
  // track resizing state - use ref over state to avoid re-render
176
181
  const isResizing = useRef(false);
177
182
  const areResizeMetaKeysPressed = useRef(false);
178
-
183
+ const [localTableWidth, setLocalTableWidth] = useState(width);
179
184
  const resizerRef = useRef<ResizerNextHandler>(null);
185
+ const { tableState } = useSharedPluginState(pluginInjectionApi, ['table']);
186
+ const { widthToWidest } = tableState as TableSharedStateInternal;
180
187
 
181
188
  // used to reposition tooltip when table is resizing via keyboard
182
189
  const updateTooltip = React.useRef<() => void>();
@@ -208,7 +215,6 @@ export const TableResizer = ({
208
215
 
209
216
  const resizerMinWidth = getResizerMinWidth(node);
210
217
  const handleSize = getResizerHandleHeight(tableRef);
211
- const { isWholeTableInDanger } = getPluginState(editorView.state);
212
218
 
213
219
  const { startMeasure, endMeasure, countFrames } = useMeasureFramerate();
214
220
 
@@ -348,25 +354,28 @@ export const TableResizer = ({
348
354
  // and a table is resized to fit the widest guideline when view port width is between 1011 and 1800
349
355
  // set the width of the table to 1800 pixels.
350
356
  const { state, dispatch } = editorView;
351
- const widestGuideLineWidthString = defaultGuidelinesForPreserveTable(
357
+ const currentTableNodeLocalId = node?.attrs?.localId ?? '';
358
+
359
+ const widestGuideline = defaultGuidelinesForPreserveTable(
352
360
  containerWidth,
353
- )[16]
354
- .key?.match(/[\d]*[.]{0,1}[\d]+/g)
355
- ?.join('');
356
- const widestGuideLineWidth = parseInt(
357
- widestGuideLineWidthString || '',
358
- 10,
359
- );
361
+ ).filter((guideline) => guideline.isFullWidth)[0];
362
+ const widestGuideLineWidth = widestGuideline
363
+ ? ((widestGuideline.position?.x || 0) as number) * 2
364
+ : null;
360
365
  const shouldUpdateWidthToWidest = !!(
361
366
  isTableScalingEnabled &&
362
- defaultGuidelinesForPreserveTable(containerWidth).length === 17 &&
363
- widestGuideLineWidth - newWidth <= 1
367
+ widestGuideLineWidth &&
368
+ Math.abs(widestGuideLineWidth - newWidth) <= 1
364
369
  );
365
- updateWidthToWidest(shouldUpdateWidthToWidest)(state, dispatch);
370
+ shouldUpdateWidthToWidest
371
+ ? setLocalTableWidth(TABLE_MAX_WIDTH)
372
+ : setLocalTableWidth(newWidth);
366
373
 
367
- updateWidth(
368
- shouldUpdateWidthToWidest ? akEditorFullWidthLayoutWidth : newWidth,
369
- );
374
+ updateWidthToWidest({
375
+ [currentTableNodeLocalId]: shouldUpdateWidthToWidest,
376
+ })(state, dispatch);
377
+
378
+ updateWidth(shouldUpdateWidthToWidest ? TABLE_MAX_WIDTH : newWidth);
370
379
 
371
380
  return newWidth;
372
381
  },
@@ -391,8 +400,13 @@ export const TableResizer = ({
391
400
  let newWidth = originalState.width + delta.width;
392
401
  const { state, dispatch } = editorView;
393
402
  const pos = getPos();
394
- const { widthToWidest } = getPluginState(editorView.state);
395
- newWidth = widthToWidest ? akEditorFullWidthLayoutWidth : newWidth;
403
+ const currentTableNodeLocalId = node?.attrs?.localId ?? '';
404
+ newWidth =
405
+ widthToWidest &&
406
+ currentTableNodeLocalId &&
407
+ widthToWidest[currentTableNodeLocalId]
408
+ ? TABLE_MAX_WIDTH
409
+ : newWidth;
396
410
 
397
411
  let tr = state.tr.setMeta(tableWidthPluginKey, { resizing: false });
398
412
  const frameRateSamples = endMeasure();
@@ -466,6 +480,7 @@ export const TableResizer = ({
466
480
  endMeasure,
467
481
  onResizeStop,
468
482
  isTableScalingEnabled,
483
+ widthToWidest,
469
484
  ],
470
485
  );
471
486
 
@@ -616,7 +631,7 @@ export const TableResizer = ({
616
631
  <ResizerNext
617
632
  ref={resizerRef}
618
633
  enable={handles}
619
- width={width}
634
+ width={localTableWidth}
620
635
  handleAlignmentMethod="sticky"
621
636
  handleSize={handleSize}
622
637
  handleStyles={handleStyles}
@@ -25,6 +25,7 @@ import type {
25
25
  import type { EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
26
26
  import { akEditorTableNumberColumnWidth } from '@atlaskit/editor-shared-styles';
27
27
  import { TableMap } from '@atlaskit/editor-tables/table-map';
28
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
28
29
 
29
30
  import { pluginConfig as getPluginConfig } from '../create-plugin-config';
30
31
  import { pluginKey as tableDragAndDropPluginKey } from '../pm-plugins/drag-and-drop';
@@ -37,6 +38,7 @@ import type { PluginInjectionAPI } from '../types';
37
38
  import { isTableNested } from '../utils';
38
39
 
39
40
  import TableComponent from './TableComponent';
41
+ import { TableComponentWithSharedState } from './TableComponentWithSharedState';
40
42
  import type { Props } from './types';
41
43
 
42
44
  type ForwardRef = (node: HTMLElement | null) => void;
@@ -182,6 +184,24 @@ export default class TableView extends ReactNodeView<Props> {
182
184
  };
183
185
 
184
186
  render(props: Props, forwardRef: ForwardRef) {
187
+ if (getBooleanFF('platform.editor.table.use-shared-state-hook')) {
188
+ return (
189
+ <TableComponentWithSharedState
190
+ forwardRef={forwardRef}
191
+ getNode={this.getNode}
192
+ view={props.view}
193
+ options={props.options}
194
+ eventDispatcher={props.eventDispatcher}
195
+ api={props.pluginInjectionApi}
196
+ allowColumnResizing={props.allowColumnResizing}
197
+ allowControls={props.allowControls}
198
+ getPos={props.getPos}
199
+ getEditorFeatureFlags={props.getEditorFeatureFlags}
200
+ dispatchAnalyticsEvent={props.dispatchAnalyticsEvent}
201
+ />
202
+ );
203
+ }
204
+
185
205
  // TODO: ED-15663
186
206
  // Please, do not copy or use this kind of code below
187
207
  // @ts-ignore
@@ -363,13 +383,14 @@ export const createTableView = (
363
383
  isDragAndDropEnabled,
364
384
  isTableScalingEnabled,
365
385
  } = getPluginState(view.state);
366
- const { allowColumnResizing } = getPluginConfig(pluginConfig);
386
+ const { allowColumnResizing, allowControls } = getPluginConfig(pluginConfig);
367
387
  const hasIntlContext = true;
368
388
 
369
389
  return new TableView({
370
390
  node,
371
391
  view,
372
392
  allowColumnResizing,
393
+ allowControls,
373
394
  portalProviderAPI,
374
395
  eventDispatcher,
375
396
  getPos: getPos as getPosHandlerNode,
@@ -23,6 +23,7 @@ export interface Props {
23
23
  node: PmNode;
24
24
  view: EditorView;
25
25
  allowColumnResizing?: boolean;
26
+ allowControls?: boolean;
26
27
  cellMinWidth?: number;
27
28
  portalProviderAPI: PortalProviderAPI;
28
29
  eventDispatcher: EventDispatcher;
package/src/plugin.tsx CHANGED
@@ -28,6 +28,7 @@ import type {
28
28
  GetEditorContainerWidth,
29
29
  GetEditorFeatureFlags,
30
30
  NextEditorPlugin,
31
+ OptionalPlugin,
31
32
  } from '@atlaskit/editor-common/types';
32
33
  import { browser } from '@atlaskit/editor-common/utils';
33
34
  import { WithPluginState } from '@atlaskit/editor-common/with-plugin-state';
@@ -64,6 +65,7 @@ import { createPlugin as createTableOverflowAnalyticsPlugin } from './pm-plugins
64
65
  import { createPlugin as createTableLocalIdPlugin } from './pm-plugins/table-local-id';
65
66
  import {
66
67
  createPlugin as createFlexiResizingPlugin,
68
+ getPluginState as getFlexiResizingPlugin,
67
69
  pluginKey as tableResizingPluginKey,
68
70
  } from './pm-plugins/table-resizing';
69
71
  import { tableSelectionKeymapPlugin } from './pm-plugins/table-selection-keymap';
@@ -72,7 +74,11 @@ import {
72
74
  pluginKey as tableWidthPluginKey,
73
75
  } from './pm-plugins/table-width';
74
76
  import { getToolbarConfig } from './toolbar';
75
- import type { ColumnResizingPluginState, PluginConfig } from './types';
77
+ import type {
78
+ ColumnResizingPluginState,
79
+ PluginConfig,
80
+ TableSharedState,
81
+ } from './types';
76
82
  import FloatingContextualButton from './ui/FloatingContextualButton';
77
83
  import FloatingContextualMenu from './ui/FloatingContextualMenu';
78
84
  import FloatingDeleteButton from './ui/FloatingDeleteButton';
@@ -100,6 +106,17 @@ type InsertTableAction = (analyticsPayload: AnalyticsEventPayload) => Command;
100
106
 
101
107
  const defaultGetEditorFeatureFlags = () => ({});
102
108
 
109
+ // TODO: duplicating type instead of importing media plugin causing a circular dependency
110
+ type MediaPlugin = NextEditorPlugin<
111
+ 'media',
112
+ {
113
+ pluginConfiguration: any;
114
+ dependencies: any;
115
+ sharedState: any;
116
+ actions: any;
117
+ }
118
+ >;
119
+
103
120
  export type TablePlugin = NextEditorPlugin<
104
121
  'table',
105
122
  {
@@ -107,10 +124,7 @@ export type TablePlugin = NextEditorPlugin<
107
124
  actions: {
108
125
  insertTable: InsertTableAction;
109
126
  };
110
- sharedState: {
111
- isFullWidthModeEnabled: boolean;
112
- wasFullWidthModeEnabled: boolean;
113
- };
127
+ sharedState?: TableSharedState;
114
128
  commands: {
115
129
  insertTableWithSize: (
116
130
  rowsCount: number,
@@ -124,6 +138,7 @@ export type TablePlugin = NextEditorPlugin<
124
138
  WidthPlugin,
125
139
  GuidelinePlugin,
126
140
  SelectionPlugin,
141
+ OptionalPlugin<MediaPlugin>,
127
142
  ];
128
143
  }
129
144
  >;
@@ -148,10 +163,36 @@ const tablesPlugin: TablePlugin = ({ config: options, api }) => {
148
163
 
149
164
  // Use getSharedState to store fullWidthEnabled and wasFullWidthModeEnabled to guarantee access
150
165
  // to most up to date values - passing to createPluginState will not re-initialise the state
151
- getSharedState: () => {
166
+ getSharedState: (editorState) => {
167
+ if (!editorState) {
168
+ return undefined;
169
+ }
170
+
171
+ const tablePluginState = getPluginState(editorState);
172
+ const tableResizingPluginState = getFlexiResizingPlugin(editorState);
173
+ const tableWidthResizingPluginState =
174
+ tableWidthPluginKey.getState(editorState);
175
+
152
176
  return {
153
177
  isFullWidthModeEnabled: !!options?.fullWidthEnabled,
154
178
  wasFullWidthModeEnabled: !!options?.wasFullWidthEnabled,
179
+ isHeaderRowEnabled: tablePluginState.isHeaderRowEnabled,
180
+ isHeaderColumnEnabled: tablePluginState.isHeaderColumnEnabled,
181
+ ordering: tablePluginState.ordering,
182
+ isResizing: !!(
183
+ tableResizingPluginState?.dragging ||
184
+ tableWidthResizingPluginState?.resizing
185
+ ),
186
+ isTableResizing: tableWidthResizingPluginState?.resizing,
187
+ isInDanger: tablePluginState.isInDanger,
188
+ hoveredRows: tablePluginState.hoveredRows,
189
+ hoveredCell: tablePluginState.hoveredCell,
190
+ isTableHovered: tablePluginState.isTableHovered,
191
+ isWholeTableInDanger: tablePluginState.isWholeTableInDanger,
192
+ // IMPORTANT: Need to continue to pass tableNode to control re-renders
193
+ // TableComponent listens for node attribute changes to update colgroups
194
+ tableNode: tablePluginState.tableNode,
195
+ widthToWidest: tablePluginState.widthToWidest,
155
196
  };
156
197
  },
157
198