@atlaskit/editor-plugin-table 12.1.15 → 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 (61) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/afm-dev-agents/tsconfig.json +3 -0
  4. package/afm-jira/tsconfig.json +3 -0
  5. package/afm-passionfruit/tsconfig.json +3 -0
  6. package/afm-post-office/tsconfig.json +3 -0
  7. package/afm-rovo-extension/tsconfig.json +3 -0
  8. package/afm-townsquare/tsconfig.json +3 -0
  9. package/dist/cjs/nodeviews/TableComponent.js +73 -22
  10. package/dist/cjs/nodeviews/TableContainer.js +270 -10
  11. package/dist/cjs/nodeviews/TableResizer.js +9 -2
  12. package/dist/cjs/nodeviews/table.js +12 -2
  13. package/dist/cjs/nodeviews/toDOM.js +23 -7
  14. package/dist/cjs/pm-plugins/main.js +57 -23
  15. package/dist/cjs/pm-plugins/table-resizing/utils/colgroup.js +72 -1
  16. package/dist/cjs/pm-plugins/table-resizing/utils/misc.js +70 -1
  17. package/dist/cjs/tablePlugin.js +17 -3
  18. package/dist/es2019/nodeviews/TableComponent.js +76 -22
  19. package/dist/es2019/nodeviews/TableContainer.js +256 -2
  20. package/dist/es2019/nodeviews/TableResizer.js +9 -2
  21. package/dist/es2019/nodeviews/table.js +12 -2
  22. package/dist/es2019/nodeviews/toDOM.js +24 -8
  23. package/dist/es2019/pm-plugins/main.js +57 -23
  24. package/dist/es2019/pm-plugins/table-resizing/utils/colgroup.js +72 -3
  25. package/dist/es2019/pm-plugins/table-resizing/utils/misc.js +70 -1
  26. package/dist/es2019/tablePlugin.js +17 -3
  27. package/dist/esm/nodeviews/TableComponent.js +73 -22
  28. package/dist/esm/nodeviews/TableContainer.js +270 -10
  29. package/dist/esm/nodeviews/TableResizer.js +9 -2
  30. package/dist/esm/nodeviews/table.js +12 -2
  31. package/dist/esm/nodeviews/toDOM.js +24 -8
  32. package/dist/esm/pm-plugins/main.js +57 -23
  33. package/dist/esm/pm-plugins/table-resizing/utils/colgroup.js +74 -3
  34. package/dist/esm/pm-plugins/table-resizing/utils/misc.js +70 -1
  35. package/dist/esm/tablePlugin.js +17 -3
  36. package/dist/types/nodeviews/TableContainer.d.ts +7 -2
  37. package/dist/types/nodeviews/TableResizer.d.ts +1 -1
  38. package/dist/types/nodeviews/toDOM.d.ts +5 -0
  39. package/dist/types/nodeviews/types.d.ts +1 -0
  40. package/dist/types/pm-plugins/table-resizing/utils/colgroup.d.ts +1 -0
  41. package/dist/types/pm-plugins/table-resizing/utils/misc.d.ts +41 -0
  42. package/dist/types-ts4.5/nodeviews/TableContainer.d.ts +7 -2
  43. package/dist/types-ts4.5/nodeviews/TableResizer.d.ts +1 -1
  44. package/dist/types-ts4.5/nodeviews/toDOM.d.ts +5 -0
  45. package/dist/types-ts4.5/nodeviews/types.d.ts +1 -0
  46. package/dist/types-ts4.5/pm-plugins/table-resizing/utils/colgroup.d.ts +1 -0
  47. package/dist/types-ts4.5/pm-plugins/table-resizing/utils/misc.d.ts +41 -0
  48. package/package.json +8 -7
  49. package/src/nodeviews/TableComponent.tsx +105 -19
  50. package/src/nodeviews/TableContainer.tsx +331 -2
  51. package/src/nodeviews/TableResizer.tsx +10 -5
  52. package/src/nodeviews/table.tsx +14 -0
  53. package/src/nodeviews/toDOM.ts +75 -9
  54. package/src/nodeviews/types.ts +1 -0
  55. package/src/pm-plugins/main.ts +41 -18
  56. package/src/pm-plugins/table-resizing/utils/colgroup.ts +139 -6
  57. package/src/pm-plugins/table-resizing/utils/misc.ts +87 -0
  58. package/src/tablePlugin.tsx +21 -0
  59. package/tsconfig.app.json +3 -0
  60. package/types/package.json +1 -1
  61. package/ui/common-styles/package.json +1 -1
@@ -147,6 +147,7 @@ interface TableState {
147
147
  [ShadowEvent.SHOW_AFTER_SHADOW]: boolean;
148
148
  tableWrapperWidth?: number;
149
149
  tableWrapperHeight?: number;
150
+ windowResized?: boolean;
150
151
  }
151
152
 
152
153
  // Generate a unique ID to prevent collisions when multiple plugin versions exist on the same page
@@ -172,6 +173,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
172
173
  [ShadowEvent.SHOW_AFTER_SHADOW]: false,
173
174
  tableWrapperWidth: undefined,
174
175
  tableWrapperHeight: undefined,
176
+ windowResized: false,
175
177
  };
176
178
 
177
179
  private wrapper?: HTMLDivElement | null;
@@ -308,16 +310,18 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
308
310
 
309
311
  const { tableWithFixedColumnWidthsOption = false } = getEditorFeatureFlags();
310
312
 
311
- if (isTableScalingEnabled && !tableWithFixedColumnWidthsOption) {
312
- this.handleColgroupUpdates(true);
313
- }
313
+ if (!expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true)) {
314
+ if (isTableScalingEnabled && !tableWithFixedColumnWidthsOption) {
315
+ this.handleColgroupUpdates(true);
316
+ }
314
317
 
315
- if (
316
- isTableScalingEnabled &&
317
- tableWithFixedColumnWidthsOption &&
318
- getNode().attrs.displayMode !== 'fixed'
319
- ) {
320
- this.handleColgroupUpdates(true);
318
+ if (
319
+ isTableScalingEnabled &&
320
+ tableWithFixedColumnWidthsOption &&
321
+ getNode().attrs.displayMode !== 'fixed'
322
+ ) {
323
+ this.handleColgroupUpdates(true);
324
+ }
321
325
  }
322
326
 
323
327
  if (this.wrapper) {
@@ -367,6 +371,8 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
367
371
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
368
372
  window.addEventListener('resize', this.handleWindowResizeDebounced);
369
373
  }
374
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
375
+ window.addEventListener('resize', this.handleWindowResizeNewDebounced);
370
376
  this.handleTableResizingDebounced();
371
377
  }
372
378
 
@@ -419,6 +425,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
419
425
  if (!allowTableResizing) {
420
426
  this.handleWindowResizeDebounced.cancel();
421
427
  }
428
+ this.handleWindowResizeNewDebounced.cancel();
422
429
 
423
430
  if (!allowTableResizing && allowColumnResizing) {
424
431
  // Ignored via go/ees005
@@ -426,6 +433,11 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
426
433
  window.removeEventListener('resize', this.handleWindowResizeDebounced);
427
434
  }
428
435
 
436
+ if (allowColumnResizing) {
437
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
438
+ window.removeEventListener('resize', this.handleWindowResizeNewDebounced);
439
+ }
440
+
429
441
  // Ignored via go/ees005
430
442
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
431
443
  this?.table?.removeEventListener('mouseenter', this.handleMouseEnter);
@@ -531,7 +543,9 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
531
543
  isTableWidthChanged ||
532
544
  (isTableResizedFullWidth && !options?.isCommentEditor) ||
533
545
  isNumberColumnChanged ||
534
- isNumberOfColumnsChanged;
546
+ isNumberOfColumnsChanged ||
547
+ (expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true) &&
548
+ this.state.windowResized);
535
549
 
536
550
  if (force || maybeScale || isFullWidthModeAndLineLengthChanged) {
537
551
  const isWidthChanged = this.containerWidth?.width !== containerWidthValue;
@@ -539,15 +553,18 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
539
553
  const isTableResized = hasTableBeenResized(tableNode);
540
554
  const isColumnsDistributed = wasTableResized && !isTableResized;
541
555
  const isTableDisplayModeChanged = this.node.attrs.displayMode !== tableNode.attrs.displayMode;
542
- const shouldUpdateColgroup =
543
- isWidthChanged ||
544
- isColumnsDistributed ||
545
- isTableResizedFullWidth ||
546
- isTableWidthChanged ||
547
- isTableDisplayModeChanged ||
548
- isNumberColumnChanged ||
549
- isNumberOfColumnsChanged ||
550
- isFullWidthModeAndLineLengthChanged;
556
+
557
+ const shouldUpdateColgroup = this.shouldUpdateColgroup({
558
+ isWindowResized: this.state.windowResized,
559
+ isWidthChanged,
560
+ isTableWidthChanged,
561
+ isColumnsDistributed,
562
+ isTableResizedFullWidth,
563
+ isTableDisplayModeChanged,
564
+ isNumberColumnChanged,
565
+ isNumberOfColumnsChanged,
566
+ isFullWidthModeAndLineLengthChanged,
567
+ });
551
568
 
552
569
  const { tableWithFixedColumnWidthsOption = false } = getEditorFeatureFlags();
553
570
 
@@ -692,6 +709,13 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
692
709
  shouldHandleColgroupUpdates = true;
693
710
  }
694
711
 
712
+ if (
713
+ expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true) &&
714
+ this.state.windowResized
715
+ ) {
716
+ shouldHandleColgroupUpdates = true;
717
+ }
718
+
695
719
  if (shouldHandleColgroupUpdates) {
696
720
  this.handleColgroupUpdates();
697
721
  }
@@ -1010,6 +1034,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
1010
1034
  tableWrapperHeight={this.state.tableWrapperHeight}
1011
1035
  isTableResizingEnabled={allowTableResizing}
1012
1036
  isResizing={isResizing}
1037
+ isWindowResized={this.state.windowResized}
1013
1038
  isTableScalingEnabled={isTableScalingEnabled}
1014
1039
  isTableWithFixedColumnWidthsOptionEnabled={tableWithFixedColumnWidthsOption}
1015
1040
  isWholeTableInDanger={isWholeTableInDanger}
@@ -1422,6 +1447,17 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
1422
1447
  });
1423
1448
  };
1424
1449
 
1450
+ // This is a new handler for window resize events that sets the windowResized state immediately
1451
+ // This is needed to update colgroup on window resize, to enforce the table scaling
1452
+ private handleWindowResizeNew = () => {
1453
+ // Set resizing to true immediately
1454
+ if (!this.state.windowResized) {
1455
+ this.setState({
1456
+ windowResized: true,
1457
+ });
1458
+ }
1459
+ };
1460
+
1425
1461
  private getParentNodeWidth = () => {
1426
1462
  const {
1427
1463
  getPos,
@@ -1454,11 +1490,61 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
1454
1490
  options || this.props.options || {},
1455
1491
  );
1456
1492
 
1493
+ private shouldUpdateColgroup = (params: {
1494
+ isWindowResized: boolean | undefined;
1495
+ isWidthChanged: boolean;
1496
+ isTableWidthChanged: boolean;
1497
+ isColumnsDistributed: boolean;
1498
+ isTableResizedFullWidth: boolean | undefined;
1499
+ isTableDisplayModeChanged: boolean;
1500
+ isNumberColumnChanged: boolean;
1501
+ isNumberOfColumnsChanged: boolean;
1502
+ isFullWidthModeAndLineLengthChanged: boolean | undefined;
1503
+ }): boolean => {
1504
+ const {
1505
+ isWindowResized,
1506
+ isWidthChanged,
1507
+ isTableWidthChanged,
1508
+ isColumnsDistributed,
1509
+ isTableResizedFullWidth,
1510
+ isTableDisplayModeChanged,
1511
+ isNumberColumnChanged,
1512
+ isNumberOfColumnsChanged,
1513
+ isFullWidthModeAndLineLengthChanged,
1514
+ } = params;
1515
+
1516
+ const isFullPageEditor =
1517
+ !this.props.options?.isCommentEditor && !this.props.options?.isChromelessEditor;
1518
+
1519
+ if (expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true) && isFullPageEditor) {
1520
+ return (
1521
+ !!isWindowResized ||
1522
+ isColumnsDistributed ||
1523
+ !!isTableResizedFullWidth ||
1524
+ isTableDisplayModeChanged ||
1525
+ isNumberColumnChanged ||
1526
+ isNumberOfColumnsChanged ||
1527
+ !!isFullWidthModeAndLineLengthChanged
1528
+ );
1529
+ }
1530
+ return (
1531
+ isWidthChanged ||
1532
+ isTableWidthChanged ||
1533
+ isColumnsDistributed ||
1534
+ !!isTableResizedFullWidth ||
1535
+ isTableDisplayModeChanged ||
1536
+ isNumberColumnChanged ||
1537
+ isNumberOfColumnsChanged ||
1538
+ !!isFullWidthModeAndLineLengthChanged
1539
+ );
1540
+ };
1541
+
1457
1542
  private scaleTableDebounced = rafSchedule(this.scaleTable);
1458
1543
  private handleTableResizingDebounced = rafSchedule(this.handleTableResizing);
1459
1544
  private handleScrollDebounced = rafSchedule(this.handleScroll);
1460
1545
  private handleAutoSizeDebounced = rafSchedule(this.handleAutoSize);
1461
1546
  private handleWindowResizeDebounced = rafSchedule(this.handleWindowResize);
1547
+ private handleWindowResizeNewDebounced = rafSchedule(this.handleWindowResizeNew);
1462
1548
  private updateShadowStateDebounced = rafSchedule(this.updateShadowState);
1463
1549
  }
1464
1550
 
@@ -8,6 +8,7 @@ import {
8
8
  INPUT_METHOD,
9
9
  type TableEventPayload,
10
10
  } from '@atlaskit/editor-common/analytics';
11
+ import { isSSR } from '@atlaskit/editor-common/core-utils';
11
12
  import type { GuidelineConfig } from '@atlaskit/editor-common/guideline';
12
13
  import {
13
14
  type NamedPluginStatesFromInjectionAPI,
@@ -27,6 +28,7 @@ import {
27
28
  akEditorMobileBreakoutPoint,
28
29
  } from '@atlaskit/editor-shared-styles';
29
30
  import { fg } from '@atlaskit/platform-feature-flags';
31
+ import { componentWithCondition } from '@atlaskit/platform-feature-flags-react';
30
32
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
31
33
 
32
34
  import { setTableAlignmentWithTableContentWithPosWithAnalytics } from '../pm-plugins/commands/commands-with-analytics';
@@ -35,6 +37,10 @@ import {
35
37
  TABLE_MAX_WIDTH,
36
38
  TABLE_OFFSET_IN_COMMENT_EDITOR,
37
39
  } from '../pm-plugins/table-resizing/utils/consts';
40
+ import {
41
+ getTableResizerContainerMaxWidthInCSS,
42
+ getTableResizerContainerForFullPageWidthInCSS,
43
+ } from '../pm-plugins/table-resizing/utils/misc';
38
44
  import { ALIGN_CENTER, ALIGN_START } from '../pm-plugins/utils/alignment';
39
45
  import type tablePlugin from '../tablePlugin';
40
46
  import type { PluginInjectionAPI, TableSharedStateInternal } from '../types';
@@ -210,6 +216,7 @@ type ResizableTableContainerProps = {
210
216
  getPos: () => number | undefined;
211
217
  tableRef: HTMLTableElement;
212
218
  isResizing?: boolean;
219
+ isWindowResized?: boolean;
213
220
  pluginInjectionApi?: PluginInjectionAPI;
214
221
  tableWrapperHeight?: number;
215
222
  isWholeTableInDanger?: boolean;
@@ -219,6 +226,7 @@ type ResizableTableContainerProps = {
219
226
  isTableAlignmentEnabled?: boolean;
220
227
  shouldUseIncreasedScalingPercent?: boolean;
221
228
  isCommentEditor?: boolean;
229
+ isChromelessEditor?: boolean;
222
230
  };
223
231
 
224
232
  const selector = (
@@ -264,7 +272,7 @@ const getPadding = (containerWidth: number) => {
264
272
  : akEditorGutterPaddingDynamic();
265
273
  };
266
274
 
267
- export const ResizableTableContainer = React.memo(
275
+ const ResizableTableContainerLegacy = React.memo(
268
276
  ({
269
277
  children,
270
278
  className,
@@ -500,6 +508,324 @@ export const ResizableTableContainer = React.memo(
500
508
  },
501
509
  );
502
510
 
511
+ const ResizableTableContainerNext = React.memo(
512
+ ({
513
+ children,
514
+ className,
515
+ node,
516
+ containerWidth,
517
+ lineLength,
518
+ editorView,
519
+ getPos,
520
+ tableRef,
521
+ isResizing,
522
+ isWindowResized,
523
+ pluginInjectionApi,
524
+ tableWrapperHeight,
525
+ isWholeTableInDanger,
526
+ isTableScalingEnabled,
527
+ isTableWithFixedColumnWidthsOptionEnabled,
528
+ isTableAlignmentEnabled,
529
+ shouldUseIncreasedScalingPercent,
530
+ isCommentEditor,
531
+ isChromelessEditor,
532
+ }: PropsWithChildren<ResizableTableContainerProps>) => {
533
+ const tableWidth = getTableContainerWidth(node);
534
+ const containerRef = useRef<HTMLDivElement | null>(null);
535
+ const tableWidthRef = useRef<number>(akEditorDefaultLayoutWidth);
536
+ const [resizing, setIsResizing] = useState(false);
537
+ const [tableMaxWidthForFullPageOnLoad, setTableMaxWidthForFullPageOnLoad] =
538
+ useState<number>(tableWidth);
539
+
540
+ const { tableState, editorViewModeState } = useSharedState(pluginInjectionApi);
541
+ const isFullWidthModeEnabled = tableState?.isFullWidthModeEnabled;
542
+ const mode = editorViewModeState?.mode;
543
+
544
+ const updateContainerHeight = useCallback((height: number | 'auto') => {
545
+ // current StickyHeader State is not stable to be fetch.
546
+ // we need to update stickyHeader plugin to make sure state can be
547
+ // consistently fetch and refactor below
548
+ const stickyHeaders = containerRef.current?.getElementsByClassName('pm-table-sticky');
549
+ if (!stickyHeaders || stickyHeaders.length < 1) {
550
+ // when starting to drag, we need to keep the original space,
551
+ // -- When sticky header not appear, margin top(24px) and margin bottom(16px), should be 40px,
552
+ // 1px is border width but collapse make it 0.5.
553
+ // -- When sticky header appear, we should add first row height but reduce
554
+ // collapsed border
555
+ return typeof height === 'number' ? `${height + 40.5}px` : 'auto';
556
+ } else {
557
+ const stickyHeaderHeight =
558
+ containerRef.current?.getElementsByTagName('th')[0].getBoundingClientRect().height || 0;
559
+
560
+ return typeof height === 'number' ? `${height + stickyHeaderHeight + 39.5}px` : 'auto';
561
+ }
562
+ }, []);
563
+
564
+ const onResizeStart = useCallback(() => {
565
+ setIsResizing(true);
566
+ }, []);
567
+
568
+ const onResizeStop = useCallback(() => {
569
+ setIsResizing(false);
570
+ }, []);
571
+
572
+ const updateWidth = useCallback((width?: number) => {
573
+ if (!containerRef.current) {
574
+ return;
575
+ }
576
+
577
+ // make sure during resizing
578
+ // the pm-table-resizer-container width is the same as its child div resizer-item
579
+ // otherwise when resize table from wider to narrower , pm-table-resizer-container stays wider
580
+ // and cause the fabric-editor-popup-scroll-parent to overflow
581
+ if (containerRef.current.style.width !== `${width}px`) {
582
+ containerRef.current.style.width = `${width}px`;
583
+ }
584
+ }, []);
585
+
586
+ const displayGuideline = useCallback(
587
+ (guidelines: GuidelineConfig[]) => {
588
+ return (
589
+ pluginInjectionApi?.guideline?.actions?.displayGuideline(editorView)({
590
+ guidelines,
591
+ }) ?? false
592
+ );
593
+ },
594
+ [pluginInjectionApi, editorView],
595
+ );
596
+
597
+ const attachAnalyticsEvent = useCallback(
598
+ (payload: TableEventPayload) => {
599
+ return pluginInjectionApi?.analytics?.actions.attachAnalyticsEvent(payload);
600
+ },
601
+ [pluginInjectionApi],
602
+ );
603
+
604
+ const displayGapCursor = useCallback(
605
+ (toggle: boolean) => {
606
+ return (
607
+ pluginInjectionApi?.core?.actions.execute(
608
+ pluginInjectionApi?.selection?.commands.displayGapCursor(toggle),
609
+ ) ?? false
610
+ );
611
+ },
612
+ [pluginInjectionApi],
613
+ );
614
+
615
+ const isFullPageAppearance = !isCommentEditor && !isChromelessEditor;
616
+
617
+ let responsiveContainerWidth = 0;
618
+ const resizeHandleSpacing = 12;
619
+ const padding = getPadding(containerWidth);
620
+ // When Full width editor enabled, a Mac OS user can change "ak-editor-content-area" width by
621
+ // updating Settings -> Appearance -> Show scroll bars from "When scrolling" to "Always". It causes
622
+ // issues when viwport width is less than full width Editor's width. To detect avoid them
623
+ // we need to use lineLength to defined responsiveWidth instead of containerWidth
624
+ // (which does not get updated when Mac setting changes) in Full-width editor.
625
+ if (isFullWidthModeEnabled) {
626
+ // When: Show scroll bars -> containerWidth = akEditorGutterPadding * 2 + lineLength;
627
+ // When: Always -> containerWidth = akEditorGutterPadding * 2 + lineLength + scrollbarWidth;
628
+ // scrollbarWidth can vary. Values can be 14, 15, 16 and up to 20px;
629
+ responsiveContainerWidth = isTableScalingEnabled
630
+ ? lineLength
631
+ : containerWidth - padding * 2 - resizeHandleSpacing;
632
+
633
+ // platform_editor_table_fw_numcol_overflow_fix:
634
+ // lineLength is undefined on first paint → width: NaN → wrapper expands to page
635
+ // width. rAF col-sizing then runs before the number-column padding and
636
+ // the final shrink, so column widths are locked in wrong.
637
+ // With the flag ON, if the value isn’t finite we fall back to gutterWidth
638
+ // for that first frame—no flash, no premature rAF.
639
+ //
640
+ // Type clean-up comes later:
641
+ // 1) ship this runtime guard (quick fix, no breakage);
642
+ // 2) TODO: widen lineLength to `number|undefined` and remove this block.
643
+ if (fg('platform_editor_table_fw_numcol_overflow_fix')) {
644
+ if (isTableScalingEnabled && !Number.isFinite(responsiveContainerWidth)) {
645
+ responsiveContainerWidth = containerWidth - padding * 2 - resizeHandleSpacing;
646
+ }
647
+ }
648
+ } else if (isCommentEditor) {
649
+ responsiveContainerWidth = containerWidth - TABLE_OFFSET_IN_COMMENT_EDITOR;
650
+ } else {
651
+ // 76 is currently an accepted padding value considering the spacing for resizer handle
652
+ // containerWidth = width of a DIV with test id="ak-editor-fp-content-area". It is a parent of
653
+ // a DIV with className="ak-editor-content-area". This DIV has padding left and padding right.
654
+ // padding left = padding right = akEditorGutterPadding = 32
655
+ responsiveContainerWidth = isTableScalingEnabled
656
+ ? containerWidth - padding * 2
657
+ : containerWidth - padding * 2 - resizeHandleSpacing;
658
+ }
659
+
660
+ const width =
661
+ !node.attrs.width && isCommentEditor
662
+ ? responsiveContainerWidth
663
+ : Math.min(tableWidth, responsiveContainerWidth);
664
+
665
+ if (!isResizing) {
666
+ tableWidthRef.current = width;
667
+ }
668
+
669
+ const maxResizerWidth = isCommentEditor
670
+ ? responsiveContainerWidth
671
+ : Math.min(responsiveContainerWidth, TABLE_MAX_WIDTH);
672
+
673
+ // CSS solution for table resizer item width
674
+ // The `width` is used for .resizer-item in <TableResizer>, and it has to be a number
675
+ // So we can't use min(var(--ak-editor-table-width), ${tableWidth}px) here
676
+ // We get the correct width from CSS value on page load
677
+ // After window resize, we use the width from plugin state
678
+ // After table resize, the table width attribute is used
679
+ const tableResizerItemWidth = useMemo(() => {
680
+ // if not on full page editor, we just rely on the width calculated from plugin state
681
+ // if on full page editor and after window resize, we use the width from plugin state
682
+ if (!isFullPageAppearance || (isFullPageAppearance && isWindowResized)) {
683
+ return width;
684
+ }
685
+ if (isResizing) {
686
+ return tableWidth;
687
+ }
688
+ // if on full page editor and on page load, we use the computed value from CSS
689
+ return Math.min(tableWidth, tableMaxWidthForFullPageOnLoad);
690
+ }, [
691
+ isWindowResized,
692
+ isResizing,
693
+ isFullPageAppearance,
694
+ tableMaxWidthForFullPageOnLoad,
695
+ tableWidth,
696
+ width,
697
+ ]);
698
+
699
+ // CSS Solution for table resizer container width
700
+ const tableResizerContainerWidth = useMemo(() => {
701
+ return getTableResizerContainerForFullPageWidthInCSS(node, isTableScalingEnabled);
702
+ }, [node, isTableScalingEnabled]);
703
+
704
+ // CSS Solution for table resizer max width
705
+ const tableResizerMaxWidth = React.useMemo(() => {
706
+ const isFullPageAppearance = !isCommentEditor && !isChromelessEditor;
707
+ const nonResizingMaxWidth = isFullPageAppearance
708
+ ? getTableResizerContainerMaxWidthInCSS(
709
+ isCommentEditor,
710
+ isChromelessEditor,
711
+ isTableScalingEnabled,
712
+ )
713
+ : maxResizerWidth;
714
+ // isResizing is needed, otherwise we can't resize table.
715
+ // when not resizing, maxWidth is calculated based on the container width via CSS
716
+ return !isResizing ? nonResizingMaxWidth : maxResizerWidth;
717
+ }, [isCommentEditor, isChromelessEditor, isTableScalingEnabled, isResizing, maxResizerWidth]);
718
+
719
+ // on SSR, the width would be the default state, which is tableWidth
720
+ // but because we have maxWidth set to the editor container width via CSS
721
+ // So it would work just fine
722
+ useEffect(() => {
723
+ if (!isSSR() && isFullPageAppearance && containerRef.current?.firstElementChild) {
724
+ // get the computed value of max-width from '.resizer-item', because it uses `cqw` unit in CSS
725
+ const computedStyle = window.getComputedStyle(containerRef.current.firstElementChild);
726
+ const containerWidth = computedStyle.maxWidth
727
+ ? parseFloat(computedStyle.maxWidth)
728
+ : tableWidth;
729
+ setTableMaxWidthForFullPageOnLoad(Math.min(containerWidth, tableWidth));
730
+ }
731
+ }, [tableWidthRef, tableWidth, isFullPageAppearance]);
732
+
733
+ const tableResizerProps = {
734
+ width: tableResizerItemWidth,
735
+ maxWidth: tableResizerMaxWidth,
736
+ containerWidth,
737
+ lineLength,
738
+ updateWidth,
739
+ editorView,
740
+ getPos,
741
+ node,
742
+ tableRef,
743
+ displayGuideline,
744
+ attachAnalyticsEvent,
745
+ displayGapCursor,
746
+ isTableAlignmentEnabled,
747
+ isFullWidthModeEnabled,
748
+ isTableScalingEnabled,
749
+ isTableWithFixedColumnWidthsOptionEnabled,
750
+ isWholeTableInDanger,
751
+ shouldUseIncreasedScalingPercent,
752
+ pluginInjectionApi,
753
+ onResizeStart,
754
+ onResizeStop,
755
+ isCommentEditor,
756
+ };
757
+
758
+ const isLivePageViewMode = mode === 'view';
759
+
760
+ return (
761
+ <AlignmentTableContainerWrapper
762
+ isTableAlignmentEnabled={isTableAlignmentEnabled}
763
+ node={node}
764
+ pluginInjectionApi={pluginInjectionApi}
765
+ getPos={getPos}
766
+ editorView={editorView}
767
+ >
768
+ <div
769
+ style={
770
+ {
771
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
772
+ '--ak-editor-table-gutter-padding':
773
+ 'calc(var(--ak-editor--large-gutter-padding) * 2)',
774
+ '--ak-editor-table-width': isFullPageAppearance
775
+ ? tableResizerContainerWidth
776
+ : `${tableWidthRef.current}px`,
777
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
778
+ width: 'var(--ak-editor-table-width)',
779
+ height: resizing ? updateContainerHeight(tableWrapperHeight ?? 'auto') : 'auto',
780
+ position: isLivePageViewMode ? 'relative' : 'unset',
781
+ } as React.CSSProperties
782
+ }
783
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
784
+ className={ClassName.TABLE_RESIZER_CONTAINER}
785
+ ref={containerRef}
786
+ >
787
+ {fg('platform_editor_live_page_prevent_table_recreation') ? null : isLivePageViewMode ? (
788
+ <InnerContainer
789
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
790
+ className={className}
791
+ node={node}
792
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
793
+ style={{ width: 'inherit' }}
794
+ >
795
+ {children}
796
+ </InnerContainer>
797
+ ) : (
798
+ // Ignored via go/ees005
799
+ // eslint-disable-next-line react/jsx-props-no-spreading
800
+ <TableResizer {...tableResizerProps}>
801
+ {/* eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 */}
802
+ <InnerContainer className={className} node={node}>
803
+ {children}
804
+ </InnerContainer>
805
+ </TableResizer>
806
+ )}
807
+ {fg('platform_editor_live_page_prevent_table_recreation') ? (
808
+ // Ignored via go/ees005
809
+ // eslint-disable-next-line react/jsx-props-no-spreading
810
+ <TableResizer {...tableResizerProps} disabled={isLivePageViewMode}>
811
+ {/* eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 */}
812
+ <InnerContainer className={className} node={node}>
813
+ {children}
814
+ </InnerContainer>
815
+ </TableResizer>
816
+ ) : null}
817
+ </div>
818
+ </AlignmentTableContainerWrapper>
819
+ );
820
+ },
821
+ );
822
+
823
+ export const ResizableTableContainer = componentWithCondition(
824
+ () => expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true),
825
+ ResizableTableContainerNext,
826
+ ResizableTableContainerLegacy,
827
+ );
828
+
503
829
  type TableContainerProps = {
504
830
  node: PMNode;
505
831
  className: string;
@@ -509,6 +835,7 @@ type TableContainerProps = {
509
835
  tableRef: HTMLTableElement;
510
836
  isNested: boolean;
511
837
  isResizing?: boolean;
838
+ isWindowResized?: boolean;
512
839
  pluginInjectionApi?: PluginInjectionAPI;
513
840
  tableWrapperHeight?: number;
514
841
  isWholeTableInDanger?: boolean;
@@ -533,6 +860,7 @@ export const TableContainer = ({
533
860
  isNested,
534
861
  tableWrapperHeight,
535
862
  isResizing,
863
+ isWindowResized,
536
864
  pluginInjectionApi,
537
865
  isWholeTableInDanger,
538
866
  isTableResizingEnabled,
@@ -560,6 +888,7 @@ export const TableContainer = ({
560
888
  tableRef={tableRef}
561
889
  tableWrapperHeight={tableWrapperHeight}
562
890
  isResizing={isResizing}
891
+ isWindowResized={isWindowResized}
563
892
  pluginInjectionApi={pluginInjectionApi}
564
893
  isTableScalingEnabled={isTableScalingEnabled}
565
894
  isTableWithFixedColumnWidthsOptionEnabled={isTableWithFixedColumnWidthsOptionEnabled}
@@ -567,6 +896,7 @@ export const TableContainer = ({
567
896
  isTableAlignmentEnabled={isTableAlignmentEnabled}
568
897
  shouldUseIncreasedScalingPercent={shouldUseIncreasedScalingPercent}
569
898
  isCommentEditor={isCommentEditor}
899
+ isChromelessEditor={isChromelessEditor}
570
900
  >
571
901
  {children}
572
902
  </ResizableTableContainer>
@@ -574,7 +904,6 @@ export const TableContainer = ({
574
904
  }
575
905
 
576
906
  const { isDragAndDropEnabled } = getPluginState(editorView.state);
577
-
578
907
  return (
579
908
  <InnerContainer
580
909
  node={node}
@@ -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();
@@ -119,10 +119,17 @@ export default class TableView extends ReactNodeView<Props> {
119
119
  }
120
120
 
121
121
  getContentDOM() {
122
+ const isNested = isTableNested(this.view.state, this.getPos());
122
123
  const tableDOMStructure = tableNodeSpecWithFixedToDOM({
123
124
  allowColumnResizing: !!this.reactComponentProps.allowColumnResizing,
124
125
  tableResizingEnabled: !!this.reactComponentProps.allowTableResizing,
125
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,
126
133
  }).toDOM(this.node);
127
134
 
128
135
  const rendered = DOMSerializer.renderSpec(document, tableDOMStructure) as {
@@ -486,6 +493,12 @@ export const createTableView = (
486
493
  const { allowColumnResizing, allowControls, allowTableResizing, allowTableAlignment } =
487
494
  getPluginConfig(pluginConfig);
488
495
 
496
+ const isTableFixedColumnWidthsOptionEnabled =
497
+ getEditorFeatureFlags?.().tableWithFixedColumnWidthsOption || false;
498
+
499
+ const shouldUseIncreasedScalingPercent =
500
+ isTableScalingEnabled && (isTableFixedColumnWidthsOptionEnabled || isCommentEditor);
501
+
489
502
  return new TableView({
490
503
  node,
491
504
  view,
@@ -507,6 +520,7 @@ export const createTableView = (
507
520
  isTableScalingEnabled, // same as options.isTableScalingEnabled
508
521
  isCommentEditor,
509
522
  isChromelessEditor,
523
+ shouldUseIncreasedScalingPercent,
510
524
  },
511
525
  getEditorContainerWidth,
512
526
  getEditorFeatureFlags,