@atlaskit/editor-plugin-table 12.1.14 → 12.2.0

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 (137) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/afm-cc/tsconfig.json +6 -0
  3. package/afm-dev-agents/tsconfig.json +6 -0
  4. package/afm-jira/tsconfig.json +6 -0
  5. package/afm-passionfruit/tsconfig.json +120 -0
  6. package/afm-post-office/tsconfig.json +6 -0
  7. package/afm-rovo-extension/tsconfig.json +6 -0
  8. package/afm-townsquare/tsconfig.json +6 -0
  9. package/afm-volt/tsconfig.json +13 -4
  10. package/dist/cjs/nodeviews/TableComponent.js +77 -26
  11. package/dist/cjs/nodeviews/TableContainer.js +270 -10
  12. package/dist/cjs/nodeviews/TableResizer.js +9 -2
  13. package/dist/cjs/nodeviews/TableRow.js +24 -1
  14. package/dist/cjs/nodeviews/table-node-views.js +1 -1
  15. package/dist/cjs/nodeviews/table.js +22 -7
  16. package/dist/cjs/nodeviews/toDOM.js +23 -7
  17. package/dist/cjs/pm-plugins/main.js +57 -22
  18. package/dist/cjs/pm-plugins/table-resizing/utils/colgroup.js +72 -1
  19. package/dist/cjs/pm-plugins/table-resizing/utils/misc.js +70 -1
  20. package/dist/cjs/tablePlugin.js +17 -3
  21. package/dist/cjs/ui/TableFloatingControls/NumberColumn/index.js +2 -7
  22. package/dist/es2019/nodeviews/TableComponent.js +80 -26
  23. package/dist/es2019/nodeviews/TableContainer.js +256 -2
  24. package/dist/es2019/nodeviews/TableResizer.js +9 -2
  25. package/dist/es2019/nodeviews/TableRow.js +24 -1
  26. package/dist/es2019/nodeviews/table-node-views.js +1 -1
  27. package/dist/es2019/nodeviews/table.js +21 -6
  28. package/dist/es2019/nodeviews/toDOM.js +24 -8
  29. package/dist/es2019/pm-plugins/main.js +57 -22
  30. package/dist/es2019/pm-plugins/table-resizing/utils/colgroup.js +72 -3
  31. package/dist/es2019/pm-plugins/table-resizing/utils/misc.js +70 -1
  32. package/dist/es2019/tablePlugin.js +17 -3
  33. package/dist/es2019/ui/TableFloatingControls/NumberColumn/index.js +5 -14
  34. package/dist/esm/nodeviews/TableComponent.js +77 -26
  35. package/dist/esm/nodeviews/TableContainer.js +270 -10
  36. package/dist/esm/nodeviews/TableResizer.js +9 -2
  37. package/dist/esm/nodeviews/TableRow.js +24 -1
  38. package/dist/esm/nodeviews/table-node-views.js +1 -1
  39. package/dist/esm/nodeviews/table.js +22 -7
  40. package/dist/esm/nodeviews/toDOM.js +24 -8
  41. package/dist/esm/pm-plugins/main.js +57 -22
  42. package/dist/esm/pm-plugins/table-resizing/utils/colgroup.js +74 -3
  43. package/dist/esm/pm-plugins/table-resizing/utils/misc.js +70 -1
  44. package/dist/esm/tablePlugin.js +17 -3
  45. package/dist/esm/ui/TableFloatingControls/NumberColumn/index.js +1 -6
  46. package/dist/types/nodeviews/ExternalDropTargets.d.ts +1 -1
  47. package/dist/types/nodeviews/TableComponent.d.ts +1 -0
  48. package/dist/types/nodeviews/TableContainer.d.ts +7 -2
  49. package/dist/types/nodeviews/TableResizer.d.ts +1 -1
  50. package/dist/types/nodeviews/TableRow.d.ts +3 -1
  51. package/dist/types/nodeviews/table.d.ts +1 -1
  52. package/dist/types/nodeviews/toDOM.d.ts +5 -0
  53. package/dist/types/nodeviews/types.d.ts +1 -0
  54. package/dist/types/pm-plugins/analytics/commands.d.ts +2 -2
  55. package/dist/types/pm-plugins/analytics/plugin-factory.d.ts +1 -1
  56. package/dist/types/pm-plugins/analytics/utils/moved-event.d.ts +1 -1
  57. package/dist/types/pm-plugins/commands/column-resize.d.ts +10 -10
  58. package/dist/types/pm-plugins/commands/commands-with-analytics.d.ts +1 -1
  59. package/dist/types/pm-plugins/commands/go-to-next-cell.d.ts +1 -1
  60. package/dist/types/pm-plugins/commands/misc.d.ts +2 -2
  61. package/dist/types/pm-plugins/commands/selection.d.ts +6 -6
  62. package/dist/types/pm-plugins/drag-and-drop/commands-with-analytics.d.ts +3 -3
  63. package/dist/types/pm-plugins/drag-and-drop/commands.d.ts +1 -1
  64. package/dist/types/pm-plugins/drag-and-drop/plugin-factory.d.ts +1 -1
  65. package/dist/types/pm-plugins/plugin-factory.d.ts +1 -1
  66. package/dist/types/pm-plugins/sticky-headers/plugin-state.d.ts +1 -1
  67. package/dist/types/pm-plugins/table-resizing/plugin-factory.d.ts +1 -1
  68. package/dist/types/pm-plugins/table-resizing/utils/colgroup.d.ts +1 -0
  69. package/dist/types/pm-plugins/table-resizing/utils/misc.d.ts +41 -0
  70. package/dist/types/pm-plugins/utils/create.d.ts +10 -10
  71. package/dist/types/pm-plugins/utils/decoration.d.ts +3 -3
  72. package/dist/types/pm-plugins/utils/dom.d.ts +2 -2
  73. package/dist/types/pm-plugins/utils/drag-menu.d.ts +3 -3
  74. package/dist/types/pm-plugins/utils/merged-cells.d.ts +3 -2
  75. package/dist/types/tablePluginType.d.ts +2 -0
  76. package/dist/types/ui/DragHandle/index.d.ts +4 -14
  77. package/dist/types/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +1 -7
  78. package/dist/types/ui/TableFloatingControls/CornerControls/DragCornerControls.d.ts +4 -14
  79. package/dist/types/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -1
  80. package/dist/types/ui/TableFloatingControls/index.d.ts +1 -7
  81. package/dist/types/ui/global-styles.d.ts +2 -8
  82. package/dist/types/ui/hooks/useInternalTablePluginStateSelector.d.ts +1 -1
  83. package/dist/types-ts4.5/nodeviews/ExternalDropTargets.d.ts +1 -1
  84. package/dist/types-ts4.5/nodeviews/TableComponent.d.ts +1 -0
  85. package/dist/types-ts4.5/nodeviews/TableContainer.d.ts +7 -2
  86. package/dist/types-ts4.5/nodeviews/TableResizer.d.ts +1 -1
  87. package/dist/types-ts4.5/nodeviews/TableRow.d.ts +3 -1
  88. package/dist/types-ts4.5/nodeviews/table.d.ts +1 -1
  89. package/dist/types-ts4.5/nodeviews/toDOM.d.ts +5 -0
  90. package/dist/types-ts4.5/nodeviews/types.d.ts +1 -0
  91. package/dist/types-ts4.5/pm-plugins/analytics/commands.d.ts +2 -2
  92. package/dist/types-ts4.5/pm-plugins/analytics/plugin-factory.d.ts +1 -1
  93. package/dist/types-ts4.5/pm-plugins/analytics/utils/moved-event.d.ts +1 -1
  94. package/dist/types-ts4.5/pm-plugins/commands/column-resize.d.ts +10 -10
  95. package/dist/types-ts4.5/pm-plugins/commands/commands-with-analytics.d.ts +1 -1
  96. package/dist/types-ts4.5/pm-plugins/commands/go-to-next-cell.d.ts +1 -1
  97. package/dist/types-ts4.5/pm-plugins/commands/misc.d.ts +2 -2
  98. package/dist/types-ts4.5/pm-plugins/commands/selection.d.ts +6 -6
  99. package/dist/types-ts4.5/pm-plugins/drag-and-drop/commands-with-analytics.d.ts +3 -3
  100. package/dist/types-ts4.5/pm-plugins/drag-and-drop/commands.d.ts +1 -1
  101. package/dist/types-ts4.5/pm-plugins/drag-and-drop/plugin-factory.d.ts +1 -1
  102. package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +1 -1
  103. package/dist/types-ts4.5/pm-plugins/sticky-headers/plugin-state.d.ts +1 -1
  104. package/dist/types-ts4.5/pm-plugins/table-resizing/plugin-factory.d.ts +1 -1
  105. package/dist/types-ts4.5/pm-plugins/table-resizing/utils/colgroup.d.ts +1 -0
  106. package/dist/types-ts4.5/pm-plugins/table-resizing/utils/misc.d.ts +41 -0
  107. package/dist/types-ts4.5/pm-plugins/utils/create.d.ts +10 -10
  108. package/dist/types-ts4.5/pm-plugins/utils/decoration.d.ts +3 -3
  109. package/dist/types-ts4.5/pm-plugins/utils/dom.d.ts +2 -2
  110. package/dist/types-ts4.5/pm-plugins/utils/drag-menu.d.ts +3 -3
  111. package/dist/types-ts4.5/pm-plugins/utils/merged-cells.d.ts +3 -2
  112. package/dist/types-ts4.5/tablePluginType.d.ts +2 -0
  113. package/dist/types-ts4.5/ui/DragHandle/index.d.ts +4 -14
  114. package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +1 -7
  115. package/dist/types-ts4.5/ui/TableFloatingControls/CornerControls/DragCornerControls.d.ts +4 -14
  116. package/dist/types-ts4.5/ui/TableFloatingControls/RowControls/DragControls.d.ts +1 -1
  117. package/dist/types-ts4.5/ui/TableFloatingControls/index.d.ts +1 -7
  118. package/dist/types-ts4.5/ui/global-styles.d.ts +2 -8
  119. package/dist/types-ts4.5/ui/hooks/useInternalTablePluginStateSelector.d.ts +1 -1
  120. package/package.json +10 -11
  121. package/src/nodeviews/TableComponent.tsx +113 -23
  122. package/src/nodeviews/TableContainer.tsx +331 -2
  123. package/src/nodeviews/TableResizer.tsx +10 -5
  124. package/src/nodeviews/TableRow.ts +38 -1
  125. package/src/nodeviews/table-node-views.ts +1 -1
  126. package/src/nodeviews/table.tsx +23 -0
  127. package/src/nodeviews/toDOM.ts +75 -9
  128. package/src/nodeviews/types.ts +1 -0
  129. package/src/pm-plugins/main.ts +41 -18
  130. package/src/pm-plugins/table-resizing/utils/colgroup.ts +139 -6
  131. package/src/pm-plugins/table-resizing/utils/misc.ts +87 -0
  132. package/src/tablePlugin.tsx +21 -0
  133. package/src/tablePluginType.ts +2 -0
  134. package/src/ui/TableFloatingControls/NumberColumn/index.tsx +5 -14
  135. package/tsconfig.app.json +6 -0
  136. package/types/package.json +1 -1
  137. package/ui/common-styles/package.json +1 -1
@@ -81,7 +81,7 @@ import {
81
81
 
82
82
  interface TableResizerProps {
83
83
  width: number;
84
- maxWidth: number;
84
+ maxWidth: number | string;
85
85
  containerWidth: number;
86
86
  lineLength: number;
87
87
  updateWidth: (width: number) => void;
@@ -717,9 +717,15 @@ export const TableResizer = ({
717
717
  const handleTableSizeChangeOnKeypress = useCallback(
718
718
  (step: number) => {
719
719
  const newWidth = width + step;
720
-
721
- if (newWidth > maxWidth || newWidth < resizerMinWidth) {
722
- return;
720
+ if (expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true)) {
721
+ if (newWidth < resizerMinWidth) {
722
+ return;
723
+ }
724
+ } else {
725
+ // maxWidth when platform_editor_tables_scaling_css off is always a number
726
+ if (newWidth > (maxWidth as number) || newWidth < resizerMinWidth) {
727
+ return;
728
+ }
723
729
  }
724
730
  handleResizeStop({ width: width, x: 0, y: 0, height: 0 }, { width: step, height: 0 });
725
731
  },
@@ -739,7 +745,6 @@ export const TableResizer = ({
739
745
  if (event.altKey || metaKey || event.shiftKey) {
740
746
  areResizeMetaKeysPressed.current = true;
741
747
  }
742
-
743
748
  if (event.altKey && metaKey) {
744
749
  if (isBracketKey) {
745
750
  event.preventDefault();
@@ -20,7 +20,11 @@ import type { TableDOMElements } from '../pm-plugins/utils/dom';
20
20
  import { getTop, getTree } from '../pm-plugins/utils/dom';
21
21
  import { supportedHeaderRow } from '../pm-plugins/utils/nodes';
22
22
  import type { TablePluginState } from '../types';
23
- import { TableCssClassName as ClassName, TableCssClassName } from '../types';
23
+ import {
24
+ TableCssClassName as ClassName,
25
+ TableCssClassName,
26
+ type PluginInjectionAPI,
27
+ } from '../types';
24
28
  import {
25
29
  stickyHeaderBorderBottomWidth,
26
30
  stickyRowOffsetTop,
@@ -46,11 +50,31 @@ const HEADER_ROW_SCROLL_RESET_DEBOUNCE_TIMEOUT = 400;
46
50
  export default class TableRow extends TableNodeView<HTMLTableRowElement> implements NodeView {
47
51
  private nodeVisibilityObserverCleanupFn?: () => void;
48
52
 
53
+ cleanup = () => {
54
+ if (this.isStickyHeaderEnabled) {
55
+ this.unsubscribe();
56
+
57
+ this.nodeVisibilityObserverCleanupFn && this.nodeVisibilityObserverCleanupFn();
58
+
59
+ const tree = getTree(this.dom);
60
+ if (tree) {
61
+ this.makeRowHeaderNotSticky(tree.table, true);
62
+ }
63
+
64
+ this.emitOff(false);
65
+ }
66
+
67
+ if (this.tableContainerObserver) {
68
+ this.tableContainerObserver.disconnect();
69
+ }
70
+ };
71
+
49
72
  constructor(
50
73
  node: PMNode,
51
74
  view: EditorView,
52
75
  getPos: () => number | undefined,
53
76
  eventDispatcher: EventDispatcher,
77
+ api?: PluginInjectionAPI,
54
78
  ) {
55
79
  super(node, view, getPos, eventDispatcher);
56
80
 
@@ -60,6 +84,16 @@ export default class TableRow extends TableNodeView<HTMLTableRowElement> impleme
60
84
  const { pluginConfig } = getPluginState(view.state);
61
85
 
62
86
  this.isStickyHeaderEnabled = !!pluginConfig.stickyHeaders;
87
+
88
+ if (
89
+ api?.limitedMode?.sharedState.currentState()?.limitedModePluginKey.getState(view.state)
90
+ ?.documentSizeBreachesThreshold
91
+ ) {
92
+ this.isStickyHeaderEnabled = false;
93
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
94
+ document.addEventListener('limited-mode-activated', this.cleanup);
95
+ }
96
+
63
97
  const pos = this.getPos();
64
98
  this.isInNestedTable = false;
65
99
  if (pos) {
@@ -177,6 +211,9 @@ export default class TableRow extends TableNodeView<HTMLTableRowElement> impleme
177
211
  this.emitOff(true);
178
212
  }
179
213
 
214
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
215
+ document.removeEventListener('limited-mode-activated', this.cleanup);
216
+
180
217
  if (this.tableContainerObserver) {
181
218
  this.tableContainerObserver.disconnect();
182
219
  }
@@ -71,6 +71,6 @@ export const tableHeaderView = (options: TableCellViewOptions) => {
71
71
 
72
72
  export const tableRowView = (options: TableCellViewOptions) => {
73
73
  return (node: PMNode, view: EditorView, getPos: () => number | undefined) => {
74
- return new TableRow(node, view, getPos, options.eventDispatcher);
74
+ return new TableRow(node, view, getPos, options.eventDispatcher, options.pluginInjectionApi);
75
75
  };
76
76
  };
@@ -13,6 +13,7 @@ import type {
13
13
  getPosHandlerNode,
14
14
  } from '@atlaskit/editor-common/types';
15
15
  import { WithPluginState } from '@atlaskit/editor-common/with-plugin-state';
16
+ import type { LimitedModePluginState } from '@atlaskit/editor-plugin-limited-mode';
16
17
  import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
17
18
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
18
19
  import {
@@ -104,6 +105,10 @@ export default class TableView extends ReactNodeView<Props> {
104
105
  props.portalProviderAPI,
105
106
  props.eventDispatcher,
106
107
  props,
108
+ undefined,
109
+ undefined,
110
+ // @portal-render-immediately
111
+ true,
107
112
  );
108
113
  this.getPos = props.getPos;
109
114
  this.eventDispatcher = props.eventDispatcher;
@@ -114,10 +119,17 @@ export default class TableView extends ReactNodeView<Props> {
114
119
  }
115
120
 
116
121
  getContentDOM() {
122
+ const isNested = isTableNested(this.view.state, this.getPos());
117
123
  const tableDOMStructure = tableNodeSpecWithFixedToDOM({
118
124
  allowColumnResizing: !!this.reactComponentProps.allowColumnResizing,
119
125
  tableResizingEnabled: !!this.reactComponentProps.allowTableResizing,
120
126
  getEditorContainerWidth: this.reactComponentProps.getEditorContainerWidth,
127
+ isTableScalingEnabled: this.reactComponentProps.options?.isTableScalingEnabled,
128
+ shouldUseIncreasedScalingPercent:
129
+ this.reactComponentProps.options?.shouldUseIncreasedScalingPercent,
130
+ isCommentEditor: this.reactComponentProps.options?.isCommentEditor,
131
+ isChromelessEditor: this.reactComponentProps.options?.isChromelessEditor,
132
+ isNested,
121
133
  }).toDOM(this.node);
122
134
 
123
135
  const rendered = DOMSerializer.renderSpec(document, tableDOMStructure) as {
@@ -306,6 +318,9 @@ export default class TableView extends ReactNodeView<Props> {
306
318
  widthPlugin: fakePluginKey,
307
319
  mediaState: fakeMediaPluginKey,
308
320
  tableDragAndDropState: tableDragAndDropPluginKey,
321
+
322
+ limitedModePlugin: props.pluginInjectionApi?.limitedMode?.sharedState.currentState()
323
+ ?.limitedModePluginKey as PluginKey<LimitedModePluginState>,
309
324
  }}
310
325
  editorView={props.view}
311
326
  render={(pluginStates) => {
@@ -370,6 +385,7 @@ export default class TableView extends ReactNodeView<Props> {
370
385
  getEditorFeatureFlags={props.getEditorFeatureFlags}
371
386
  dispatchAnalyticsEvent={props.dispatchAnalyticsEvent}
372
387
  pluginInjectionApi={props.pluginInjectionApi}
388
+ limitedMode={pluginStates.limitedModePlugin?.documentSizeBreachesThreshold ?? false}
373
389
  />
374
390
  );
375
391
  }}
@@ -477,6 +493,12 @@ export const createTableView = (
477
493
  const { allowColumnResizing, allowControls, allowTableResizing, allowTableAlignment } =
478
494
  getPluginConfig(pluginConfig);
479
495
 
496
+ const isTableFixedColumnWidthsOptionEnabled =
497
+ getEditorFeatureFlags?.().tableWithFixedColumnWidthsOption || false;
498
+
499
+ const shouldUseIncreasedScalingPercent =
500
+ isTableScalingEnabled && (isTableFixedColumnWidthsOptionEnabled || isCommentEditor);
501
+
480
502
  return new TableView({
481
503
  node,
482
504
  view,
@@ -498,6 +520,7 @@ export const createTableView = (
498
520
  isTableScalingEnabled, // same as options.isTableScalingEnabled
499
521
  isCommentEditor,
500
522
  isChromelessEditor,
523
+ shouldUseIncreasedScalingPercent,
501
524
  },
502
525
  getEditorContainerWidth,
503
526
  getEditorFeatureFlags,
@@ -7,8 +7,17 @@ import type { DOMOutputSpec, NodeSpec, Node as PMNode } from '@atlaskit/editor-p
7
7
  import { akEditorGutterPaddingDynamic } from '@atlaskit/editor-shared-styles';
8
8
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
9
9
 
10
- import { generateColgroup, getResizerMinWidth } from '../pm-plugins/table-resizing/utils/colgroup';
10
+ import {
11
+ generateColgroup,
12
+ generateColgroupFromNode,
13
+ getResizerMinWidth,
14
+ } from '../pm-plugins/table-resizing/utils/colgroup';
11
15
  import { TABLE_MAX_WIDTH } from '../pm-plugins/table-resizing/utils/consts';
16
+ import {
17
+ getTableResizerContainerMaxWidthInCSS,
18
+ getTableResizerContainerForFullPageWidthInCSS,
19
+ getTableResizerItemWidthInCSS,
20
+ } from '../pm-plugins/table-resizing/utils/misc';
12
21
 
13
22
  import { getAlignmentStyle } from './table-container-styles';
14
23
 
@@ -17,6 +26,11 @@ type Config = {
17
26
  tableResizingEnabled: boolean;
18
27
  getEditorContainerWidth: GetEditorContainerWidth;
19
28
  isNestingSupported?: boolean;
29
+ isTableScalingEnabled?: boolean;
30
+ shouldUseIncreasedScalingPercent?: boolean;
31
+ isCommentEditor?: boolean;
32
+ isChromelessEditor?: boolean;
33
+ isNested?: boolean;
20
34
  };
21
35
  export const tableNodeSpecWithFixedToDOM = (
22
36
  config: Config,
@@ -40,6 +54,10 @@ export const tableNodeSpecWithFixedToDOM = (
40
54
 
41
55
  const tableMinWidth = getResizerMinWidth(node);
42
56
 
57
+ const tableWidthAttribute = node.attrs.width ? `${node.attrs.width}px` : `100%`;
58
+
59
+ const isFullPageEditor = !config.isChromelessEditor && !config.isCommentEditor;
60
+
43
61
  const attrs = {
44
62
  'data-number-column': node.attrs.isNumberColumnEnabled,
45
63
  'data-layout': node.attrs.layout,
@@ -48,12 +66,40 @@ export const tableNodeSpecWithFixedToDOM = (
48
66
  'data-table-width': node.attrs.width,
49
67
  };
50
68
 
69
+ // This would be used for table scaling in colgroup CSS
70
+ // cqw, or px is well supported
71
+ const resizableTableWidth = expValEquals(
72
+ 'platform_editor_tables_scaling_css',
73
+ 'isEnabled',
74
+ true,
75
+ )
76
+ ? isFullPageEditor
77
+ ? getTableResizerContainerForFullPageWidthInCSS(node, config.isTableScalingEnabled)
78
+ : `calc(100cqw - calc(var(--ak-editor--large-gutter-padding) * 2))`
79
+ : `min(calc(100cqw - calc(var(--ak-editor--large-gutter-padding) * 2)), ${node.attrs.width ?? '100%'})`;
80
+
51
81
  let colgroup: DOMOutputSpec = '';
52
82
 
53
83
  if (config.allowColumnResizing) {
54
- colgroup = ['colgroup', {}, ...generateColgroup(node)];
84
+ if (expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true)) {
85
+ colgroup = [
86
+ 'colgroup',
87
+ {},
88
+ ...generateColgroupFromNode(
89
+ node,
90
+ config.isCommentEditor,
91
+ config.isChromelessEditor,
92
+ config.isNested,
93
+ config.isTableScalingEnabled,
94
+ config.shouldUseIncreasedScalingPercent,
95
+ ),
96
+ ];
97
+ } else {
98
+ colgroup = ['colgroup', {}, ...generateColgroup(node)];
99
+ }
55
100
  }
56
101
 
102
+ // For Chromeless editor, and nested tables in full page editor
57
103
  const tableContainerDiv = [
58
104
  'div',
59
105
  {
@@ -113,7 +159,10 @@ export const tableNodeSpecWithFixedToDOM = (
113
159
  ],
114
160
  ];
115
161
 
116
- if (!config.tableResizingEnabled) {
162
+ if (
163
+ !config.tableResizingEnabled ||
164
+ (expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true) && config.isNested)
165
+ ) {
117
166
  return [
118
167
  'div',
119
168
  {
@@ -124,8 +173,6 @@ export const tableNodeSpecWithFixedToDOM = (
124
173
  ];
125
174
  }
126
175
 
127
- const tableWidthAttribute = node.attrs.width ? `${node.attrs.width}px` : `100%`;
128
-
129
176
  const tableResizingDiv = [
130
177
  'div',
131
178
  {
@@ -136,7 +183,15 @@ export const tableNodeSpecWithFixedToDOM = (
136
183
  'div',
137
184
  {
138
185
  class: 'pm-table-resizer-container',
139
- style: `width: min(calc(100cqw - ${gutterPadding()}), ${tableWidthAttribute});`,
186
+ style: convertToInlineCss({
187
+ '--ak-editor-table-gutter-padding': config.isTableScalingEnabled
188
+ ? 'calc(var(--ak-editor--large-gutter-padding) * 2)'
189
+ : 'calc(var(--ak-editor--large-gutter-padding) * 2 - var(--ak-editor-resizer-handle-spacing))',
190
+ '--ak-editor-table-width': resizableTableWidth,
191
+ width: expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true)
192
+ ? `var(--ak-editor-table-width)`
193
+ : `min(calc(100cqw - ${gutterPadding()}), ${tableWidthAttribute})`,
194
+ }),
140
195
  },
141
196
  [
142
197
  'div',
@@ -146,12 +201,23 @@ export const tableNodeSpecWithFixedToDOM = (
146
201
  position: 'relative',
147
202
  userSelect: 'auto',
148
203
  boxSizing: 'border-box',
149
- '--ak-editor-table-gutter-padding': `${gutterPadding()}`,
150
204
  '--ak-editor-table-max-width': `${TABLE_MAX_WIDTH}px`,
151
205
  '--ak-editor-table-min-width': `${tableMinWidth}px`,
152
206
  minWidth: 'var(--ak-editor-table-min-width)',
153
- maxWidth: `min(calc(100cqw - var(--ak-editor-table-gutter-padding)), var(--ak-editor-table-max-width))`,
154
- width: `min(calc(100cqw - var(--ak-editor-table-gutter-padding)), ${tableWidthAttribute})`,
207
+ maxWidth: expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true)
208
+ ? getTableResizerContainerMaxWidthInCSS(
209
+ config.isCommentEditor,
210
+ config.isChromelessEditor,
211
+ config.isTableScalingEnabled,
212
+ )
213
+ : `min(calc(100cqw - var(--ak-editor-table-gutter-padding)), var(--ak-editor-table-max-width))`,
214
+ width: expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true)
215
+ ? getTableResizerItemWidthInCSS(
216
+ node,
217
+ config.isCommentEditor,
218
+ config.isChromelessEditor,
219
+ )
220
+ : `min(calc(100cqw - var(--ak-editor-table-gutter-padding)), ${tableWidthAttribute})`,
155
221
  }),
156
222
  },
157
223
  [
@@ -14,6 +14,7 @@ export type TableOptions = {
14
14
  isTableScalingEnabled?: boolean;
15
15
  isCommentEditor?: boolean;
16
16
  isChromelessEditor?: boolean;
17
+ shouldUseIncreasedScalingPercent?: boolean;
17
18
  };
18
19
 
19
20
  export interface Props {
@@ -26,6 +26,7 @@ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
26
26
  import { TableMap } from '@atlaskit/editor-tables';
27
27
  import { findTable } from '@atlaskit/editor-tables/utils';
28
28
  import { fg } from '@atlaskit/platform-feature-flags';
29
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
29
30
 
30
31
  import {
31
32
  tableCellView,
@@ -131,24 +132,46 @@ export const createPlugin = (
131
132
  return editorView.state;
132
133
  };
133
134
 
134
- const nodeViews =
135
- isSSR() && fg('platform_editor_table_fallback_to_dom_on_ssr')
136
- ? undefined
137
- : {
138
- table: tableView({
139
- portalProviderAPI,
140
- eventDispatcher,
141
- getEditorContainerWidth,
142
- getEditorFeatureFlags,
143
- dispatchAnalyticsEvent,
144
- pluginInjectionApi,
145
- isCommentEditor,
146
- isChromelessEditor,
147
- }),
148
- tableRow: tableRowView({ eventDispatcher }),
149
- tableCell: tableCellView({ eventDispatcher, pluginInjectionApi }),
150
- tableHeader: tableHeaderView({ eventDispatcher, pluginInjectionApi }),
151
- };
135
+ const getNodeView = () => {
136
+ // Because the layout shift issues has been fixed under experiment platform_editor_tables_scaling_css, so still want to load nodeview on SSR if experiment is enabled
137
+ if (expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true)) {
138
+ return {
139
+ table: tableView({
140
+ portalProviderAPI,
141
+ eventDispatcher,
142
+ getEditorContainerWidth,
143
+ getEditorFeatureFlags,
144
+ dispatchAnalyticsEvent,
145
+ pluginInjectionApi,
146
+ isCommentEditor,
147
+ isChromelessEditor,
148
+ }),
149
+ tableRow: tableRowView({ eventDispatcher, pluginInjectionApi }),
150
+ tableCell: tableCellView({ eventDispatcher, pluginInjectionApi }),
151
+ tableHeader: tableHeaderView({ eventDispatcher, pluginInjectionApi }),
152
+ };
153
+ }
154
+ if (isSSR() && fg('platform_editor_table_fallback_to_dom_on_ssr')) {
155
+ return undefined;
156
+ }
157
+ return {
158
+ table: tableView({
159
+ portalProviderAPI,
160
+ eventDispatcher,
161
+ getEditorContainerWidth,
162
+ getEditorFeatureFlags,
163
+ dispatchAnalyticsEvent,
164
+ pluginInjectionApi,
165
+ isCommentEditor,
166
+ isChromelessEditor,
167
+ }),
168
+ tableRow: tableRowView({ eventDispatcher, pluginInjectionApi }),
169
+ tableCell: tableCellView({ eventDispatcher, pluginInjectionApi }),
170
+ tableHeader: tableHeaderView({ eventDispatcher, pluginInjectionApi }),
171
+ };
172
+ };
173
+
174
+ const nodeViews = getNodeView();
152
175
  return new SafePlugin({
153
176
  state: state,
154
177
  key: pluginKey,
@@ -1,11 +1,20 @@
1
1
  import { tableCellMinWidth } from '@atlaskit/editor-common/styles';
2
- import { getFragmentBackingArray } from '@atlaskit/editor-common/utils';
2
+ import { calcTableColumnWidths, getFragmentBackingArray } from '@atlaskit/editor-common/utils';
3
3
  import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
4
4
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
5
+ import { akEditorTableNumberColumnWidth } from '@atlaskit/editor-shared-styles';
5
6
  import { TableMap } from '@atlaskit/editor-tables/table-map';
6
7
 
7
- import { COLUMN_MIN_WIDTH } from './consts';
8
- import { getScalingPercentForTableWithoutWidth, getTableScalingPercent } from './misc';
8
+ import {
9
+ COLUMN_MIN_WIDTH,
10
+ MAX_SCALING_PERCENT,
11
+ MAX_SCALING_PERCENT_TABLES_WITH_FIXED_COLUMN_WIDTHS_OPTION,
12
+ } from './consts';
13
+ import {
14
+ getScalingPercentForTableWithoutWidth,
15
+ getTableContainerElementWidth,
16
+ getTableScalingPercent,
17
+ } from './misc';
9
18
 
10
19
  type Col = Array<string | { [name: string]: string }>;
11
20
 
@@ -18,6 +27,131 @@ type Col = Array<string | { [name: string]: string }>;
18
27
  export const getColWidthFix = (colwidth: number, tableColumnCount: number) =>
19
28
  colwidth - 1 / tableColumnCount;
20
29
 
30
+ const generateColStyle = (
31
+ fixedColWidth: number,
32
+ tableWidth: number,
33
+ isCommentEditor?: boolean,
34
+ isChromelessEditor?: boolean,
35
+ isNested?: boolean,
36
+ shouldUseIncreasedScalingPercent?: boolean,
37
+ isNumberColumnEnabled?: boolean,
38
+ isTableHasWidth?: boolean,
39
+ hasTableBeenResized?: boolean,
40
+ ) => {
41
+ const maxScalingPercent = shouldUseIncreasedScalingPercent
42
+ ? MAX_SCALING_PERCENT_TABLES_WITH_FIXED_COLUMN_WIDTHS_OPTION
43
+ : MAX_SCALING_PERCENT;
44
+ const maxScaledRatio = 1 - maxScalingPercent;
45
+
46
+ const isFullPageEditor = !isChromelessEditor && !isCommentEditor;
47
+
48
+ // for nested tables, or chromeless editor, which used non resizable table container
49
+ if (isNested || isChromelessEditor) {
50
+ if (hasTableBeenResized) {
51
+ return `width: max(${fixedColWidth}px, ${tableCellMinWidth}px)`;
52
+ }
53
+ return `width: ${tableCellMinWidth}px)`;
54
+ }
55
+ if (isFullPageEditor || (!isFullPageEditor && isTableHasWidth)) {
56
+ const scaledPercent = isNumberColumnEnabled
57
+ ? `calc(calc(var(--ak-editor-table-width) - ${akEditorTableNumberColumnWidth}px - 1px)/${tableWidth})`
58
+ : `calc(calc(var(--ak-editor-table-width) - 1px)/${tableWidth})`;
59
+ return `width: max(calc(${fixedColWidth}px * ${maxScaledRatio}), calc(${fixedColWidth} * ${scaledPercent}), ${tableCellMinWidth}px)`;
60
+ }
61
+ // table resized to full-width in comment editor
62
+ // it doesn't have a width attribute, and cols has been resized
63
+ if (hasTableBeenResized) {
64
+ const scaledPercent = isNumberColumnEnabled
65
+ ? `calc(calc(var(--ak-editor-table-width) - ${akEditorTableNumberColumnWidth}px - 1px)/${tableWidth})`
66
+ : `calc(calc(var(--ak-editor-table-width) - 1px)/${tableWidth})`;
67
+ return `width: max(calc(${fixedColWidth} * ${scaledPercent}), ${tableCellMinWidth}px)`;
68
+ }
69
+ return `width: ${tableCellMinWidth}px`;
70
+ };
71
+
72
+ export const generateColgroupFromNode = (
73
+ table: PmNode,
74
+ isCommentEditor?: boolean,
75
+ isChromelessEditor?: boolean,
76
+ isNested?: boolean,
77
+ isTableScalingEnabled?: boolean,
78
+ shouldUseIncreasedScalingPercent?: boolean,
79
+ ) => {
80
+ const cols: Col[] = [];
81
+ const map = TableMap.get(table);
82
+ const isTableHasWidth = !!table.attrs.width;
83
+ const isNumberColumnEnabled = table.attrs.isNumberColumnEnabled || false;
84
+ const isFullPageEditor = !isChromelessEditor && !isCommentEditor;
85
+
86
+ // Ignored via go/ees005
87
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
88
+ table.content.firstChild!.content.forEach((cell) => {
89
+ const colspan = cell.attrs.colspan || 1;
90
+ // if the table has been resized
91
+ if (Array.isArray(cell.attrs.colwidth)) {
92
+ cell.attrs.colwidth.slice(0, colspan).forEach((width) => {
93
+ // existing logic for calculating the width of the column
94
+ const fixedColWidth = getColWidthFix(width, map.width);
95
+ const tableWidth =
96
+ isFullPageEditor || (!isFullPageEditor && isTableHasWidth)
97
+ ? getTableContainerElementWidth(table)
98
+ : calcTableColumnWidths(table).reduce((sum, width) => sum + width, 0);
99
+ if (isTableScalingEnabled) {
100
+ cols.push([
101
+ 'col',
102
+ {
103
+ style: generateColStyle(
104
+ fixedColWidth,
105
+ tableWidth,
106
+ isCommentEditor,
107
+ isChromelessEditor,
108
+ isNested,
109
+ shouldUseIncreasedScalingPercent,
110
+ isNumberColumnEnabled,
111
+ isTableHasWidth,
112
+ true,
113
+ ),
114
+ },
115
+ ]);
116
+ } else {
117
+ cols.push([
118
+ 'col',
119
+ {
120
+ style: `width: max(${fixedColWidth}px, ${tableCellMinWidth}px)`,
121
+ },
122
+ ]);
123
+ }
124
+ });
125
+ } else {
126
+ // columns has not been resized, so distribute the width evenly
127
+ cols.push(
128
+ ...Array.from({ length: colspan }, (_) => {
129
+ const tableWidth = getTableContainerElementWidth(table);
130
+ const columnWidth = tableWidth / map.width || 0;
131
+ const fixedColWidth = getColWidthFix(columnWidth, map.width || 0);
132
+
133
+ return [
134
+ 'col',
135
+ {
136
+ style: generateColStyle(
137
+ fixedColWidth,
138
+ tableWidth,
139
+ isCommentEditor,
140
+ isChromelessEditor,
141
+ isNested,
142
+ shouldUseIncreasedScalingPercent,
143
+ isNumberColumnEnabled,
144
+ isTableHasWidth,
145
+ ),
146
+ },
147
+ ];
148
+ }),
149
+ );
150
+ }
151
+ });
152
+ return cols;
153
+ };
154
+
21
155
  export const generateColgroup = (
22
156
  table: PmNode,
23
157
  tableRef?: HTMLElement,
@@ -37,7 +171,6 @@ export const generateColgroup = (
37
171
  if (tableRef) {
38
172
  // if we have tableRef here, isTableScalingEnabled is true
39
173
  let scalePercent = 1;
40
-
41
174
  if (isCommentEditor && !table.attrs?.width) {
42
175
  scalePercent = getScalingPercentForTableWithoutWidth(table, tableRef);
43
176
  } else {
@@ -45,6 +178,7 @@ export const generateColgroup = (
45
178
  }
46
179
 
47
180
  cell.attrs.colwidth.slice(0, colspan).forEach((width) => {
181
+ // existing logic for calculating the width of the column
48
182
  const fixedColWidth = getColWidthFix(width, map.width);
49
183
  const scaledWidth = fixedColWidth * scalePercent;
50
184
  const finalWidth = Math.max(scaledWidth, tableCellMinWidth);
@@ -80,7 +214,6 @@ export const generateColgroup = (
80
214
  );
81
215
  }
82
216
  });
83
-
84
217
  return cols;
85
218
  };
86
219
 
@@ -101,7 +234,7 @@ export const insertColgroupFromNode = (
101
234
 
102
235
  colgroup = renderColgroupFromNode(
103
236
  table,
104
- isTableScalingEnabled ? tableRef ?? undefined : undefined,
237
+ isTableScalingEnabled ? (tableRef ?? undefined) : undefined,
105
238
  shouldUseIncreasedScalingPercent,
106
239
  isCommentEditor,
107
240
  );