@atlaskit/renderer 128.8.0 → 128.9.1

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.
@@ -1,5 +1,6 @@
1
- import React from 'react';
1
+ import React, { useContext } from 'react';
2
2
  import { tableCellBorderWidth, tableCellMinWidth } from '@atlaskit/editor-common/styles';
3
+ import { WidthContext } from '@atlaskit/editor-common/ui';
3
4
  import { akEditorTableNumberColumnWidth, akEditorTableLegacyCellMinWidth, akEditorTableCellMinWidth } from '@atlaskit/editor-shared-styles';
4
5
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
5
6
  import { getTableContainerWidth } from '@atlaskit/editor-common/node-width';
@@ -21,7 +22,8 @@ const isTableColumnResized = columnWidths => {
21
22
  const fixColumnWidth = ({
22
23
  columnWidth,
23
24
  zeroWidthColumnsCount,
24
- scaleDownPercent
25
+ scaleDownPercent,
26
+ skipMinWidth
25
27
  }) => {
26
28
  if (columnWidth === 0) {
27
29
  return columnWidth;
@@ -30,11 +32,14 @@ const fixColumnWidth = ({
30
32
  // If the tables total width (including no zero widths col or cols without width) is less than the current layout
31
33
  // We scale up the columns to meet the minimum of the table layout.
32
34
  if (zeroWidthColumnsCount === 0 && scaleDownPercent) {
33
- return Math.max(Math.floor((1 - scaleDownPercent) * columnWidth), tableCellMinWidth);
35
+ const scaled = Math.floor((1 - scaleDownPercent) * columnWidth);
36
+ return skipMinWidth ? scaled : Math.max(scaled, tableCellMinWidth);
34
37
  }
35
- return Math.max(
36
- // We need to take tableCellBorderWidth, to avoid unnecessary overflow.
37
- columnWidth - tableCellBorderWidth, zeroWidthColumnsCount ? akEditorTableLegacyCellMinWidth : tableCellMinWidth);
38
+ const adjusted = columnWidth - tableCellBorderWidth;
39
+ if (skipMinWidth) {
40
+ return adjusted;
41
+ }
42
+ return Math.max(adjusted, zeroWidthColumnsCount ? akEditorTableLegacyCellMinWidth : tableCellMinWidth);
38
43
  };
39
44
  const calcScalePercent = ({
40
45
  renderWidth,
@@ -50,6 +55,80 @@ const calcScalePercent = ({
50
55
  return diffPercent < maxScale ? isNumberColumnEnabled ? 1 - numColumnScalePercent : diffPercent : maxScale;
51
56
  };
52
57
  export const colWidthSum = columnWidths => columnWidths.reduce((prev, curr) => curr + prev, 0);
58
+
59
+ /**
60
+ * Returns the data-column available width: total width minus the fixed number column if enabled.
61
+ */
62
+ const getDataColumnWidth = (totalWidth, isNumberColumnEnabled) => isNumberColumnEnabled ? totalWidth - akEditorTableNumberColumnWidth : totalWidth;
63
+
64
+ /**
65
+ * Scales column widths proportionally to fit within availableWidth, matching the editor's
66
+ * scaleTableTo(): floors each column to the nearest pixel, then redistributes any rounding
67
+ * remainder to the first column that can absorb it without going below tableCellMinWidth.
68
+ */
69
+ const scaleColumnsToWidth = (columnWidths, availableWidth) => {
70
+ const rawTotalWidth = columnWidths.reduce((sum, w) => sum + w, 0);
71
+ const scaleFactor = availableWidth / rawTotalWidth;
72
+ const scaledWidths = columnWidths.map(colWidth => Math.max(Math.floor(colWidth * scaleFactor), tableCellMinWidth));
73
+ const totalScaled = scaledWidths.reduce((sum, w) => sum + w, 0);
74
+ const diff = availableWidth - totalScaled;
75
+ if (diff !== 0 && Math.abs(diff) < tableCellMinWidth) {
76
+ for (let i = 0; i < scaledWidths.length; i++) {
77
+ if (scaledWidths[i] + diff > tableCellMinWidth) {
78
+ scaledWidths[i] += diff;
79
+ break;
80
+ }
81
+ }
82
+ }
83
+ return scaledWidths.map(width => ({
84
+ width: `${width}px`
85
+ }));
86
+ };
87
+
88
+ /**
89
+ * Computes column widths for tables inside sync blocks, matching the editor's scaleTableTo() exactly.
90
+ * Returns null if the flag is off or not inside a sync block.
91
+ *
92
+ * For nested tables (isInsideOfTable=true, gated by platform_synced_block_patch_9), we use
93
+ * getTableContainerWidth(tableNode) as the reference — the width the editor saved, which already
94
+ * accounts for the parent cell's available space (colwidth minus tableCellPadding * 2).
95
+ * This matches bodiedSyncBlock where isRendererNested=false, so renderScaleDownColgroup uses
96
+ * getTableContainerWidth(tableNode). For syncBlock the nested renderer has isRendererNested=true,
97
+ * which incorrectly overrides tableContainerWidth with renderWidth (the full container), causing
98
+ * overflow by 2 * tableCellPadding (16px).
99
+ */
100
+ const renderSyncBlockColgroup = ({
101
+ isInsideOfSyncBlock,
102
+ isInsideOfTable,
103
+ tableNode,
104
+ columnWidths,
105
+ isNumberColumnEnabled,
106
+ renderWidth: renderWidthProp,
107
+ contextWidth
108
+ }) => {
109
+ if (!isInsideOfSyncBlock || !fg('platform_synced_block_patch_9')) {
110
+ return null;
111
+ }
112
+ const rawTotalWidth = columnWidths.reduce((sum, w) => sum + w, 0);
113
+ if (isInsideOfTable) {
114
+ return null;
115
+ }
116
+
117
+ // SSR / first render before WidthContext measures. Output % of original ADF proportions so
118
+ // columns are stable — the CSS container query (100cqw) handles actual scaling width.
119
+ if (contextWidth <= 0 && renderWidthProp <= 0) {
120
+ const fullTableWidth = isNumberColumnEnabled ? rawTotalWidth + akEditorTableNumberColumnWidth : rawTotalWidth;
121
+ return columnWidths.map(colWidth => ({
122
+ width: `${colWidth / fullTableWidth * 100}%`
123
+ }));
124
+ }
125
+
126
+ // contextWidth measures the sync block content area. Subtract 2 to match the editor's
127
+ // getParentNodeWidth() border offset. Fall back to renderWidthProp for the non-CSS path.
128
+ const effectiveRenderWidth = contextWidth > 0 ? contextWidth - 2 : renderWidthProp;
129
+ const availableWidth = getDataColumnWidth(effectiveRenderWidth, isNumberColumnEnabled);
130
+ return scaleColumnsToWidth(columnWidths, availableWidth);
131
+ };
53
132
  const renderScaleDownColgroup = props => {
54
133
  var _props$tableNode;
55
134
  const {
@@ -64,8 +143,10 @@ const renderScaleDownColgroup = props => {
64
143
  isTableScalingEnabled,
65
144
  isTableFixedColumnWidthsOptionEnabled,
66
145
  allowTableResizing,
67
- isTopLevelRenderer
146
+ isTopLevelRenderer,
147
+ isInsideOfSyncBlock
68
148
  } = props;
149
+ const skipMinWidth = fg('platform_synced_block_patch_9') && !!(isInsideOfTable && isInsideOfSyncBlock);
69
150
  if (!columnWidths || columnWidths.every(width => width === 0) && fg('platform_editor_numbered_column_in_include')) {
70
151
  return [];
71
152
  }
@@ -169,7 +250,8 @@ const renderScaleDownColgroup = props => {
169
250
  const fixedColWidths = targetWidths.map(width => fixColumnWidth({
170
251
  columnWidth: width,
171
252
  zeroWidthColumnsCount,
172
- scaleDownPercent
253
+ scaleDownPercent,
254
+ skipMinWidth
173
255
  }) || cellMinWidth);
174
256
  const sumFixedColumnWidths = colWidthSum(fixedColWidths);
175
257
  return fixedColWidths.map(colWidth => {
@@ -195,7 +277,8 @@ const renderScaleDownColgroup = props => {
195
277
  const width = fixColumnWidth({
196
278
  columnWidth: colWidth,
197
279
  zeroWidthColumnsCount,
198
- scaleDownPercent
280
+ scaleDownPercent,
281
+ skipMinWidth
199
282
  }) || cellMinWidth;
200
283
  const style = width ? {
201
284
  width: `${width}px`
@@ -204,22 +287,43 @@ const renderScaleDownColgroup = props => {
204
287
  });
205
288
  };
206
289
  export const Colgroup = props => {
207
- var _ref;
290
+ var _ref, _renderSyncBlockColgr;
208
291
  const {
209
- isTopLevelRenderer
292
+ isTopLevelRenderer,
293
+ nestedRendererType
210
294
  } = useRendererContext();
211
295
  const {
212
296
  columnWidths,
213
297
  isNumberColumnEnabled
214
298
  } = props;
299
+ const {
300
+ width: contextWidth
301
+ } = useContext(WidthContext);
215
302
  const flags = useFeatureFlags();
216
303
  if (!columnWidths) {
217
304
  return null;
218
305
  }
219
306
  const isTableFixedColumnWidthsOptionEnabled = (_ref = fg('platform_editor_table_fixed_column_width_prop') ? props.allowFixedColumnWidthOption : flags && 'tableWithFixedColumnWidthsOption' in flags && flags.tableWithFixedColumnWidthsOption) !== null && _ref !== void 0 ? _ref : false;
220
- const colStyles = renderScaleDownColgroup({
307
+
308
+ // For referenced sync blocks, nestedRendererType='syncedBlock' is set via RendererContextProvider
309
+ // in AKRendererWrapper. ReactSerializer is a class and cannot read React context, so we detect
310
+ // it here in the Colgroup component via useRendererContext() instead of prop-drilling.
311
+ const isInsideOfSyncBlock = nestedRendererType === 'syncedBlock';
312
+
313
+ // renderSyncBlockColgroup returns null when not applicable (flag off, SSR, not a sync block),
314
+ // in which case ?? falls back to the standard renderScaleDownColgroup path.
315
+ const colStyles = (_renderSyncBlockColgr = renderSyncBlockColgroup({
316
+ isInsideOfSyncBlock,
317
+ isInsideOfTable: !!props.isInsideOfTable,
318
+ tableNode: props.tableNode,
319
+ columnWidths,
320
+ isNumberColumnEnabled: !!isNumberColumnEnabled,
321
+ renderWidth: props.renderWidth,
322
+ contextWidth
323
+ })) !== null && _renderSyncBlockColgr !== void 0 ? _renderSyncBlockColgr : renderScaleDownColgroup({
221
324
  ...props,
222
325
  isTopLevelRenderer,
326
+ isInsideOfSyncBlock,
223
327
  isTableScalingEnabled: props.rendererAppearance === 'full-page' || props.rendererAppearance === 'full-width' || props.rendererAppearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) || props.rendererAppearance === 'comment' && editorExperiment('support_table_in_comment', true, {
224
328
  exposure: true
225
329
  }) || props.rendererAppearance === 'comment' && editorExperiment('support_table_in_comment_jira', true, {
@@ -299,6 +299,14 @@ const headingAnchorStyles = css({
299
299
  }
300
300
  }
301
301
  });
302
+ const headingAnchorButtonFocusVisibleStyles = css({
303
+ [`.${HeadingAnchorWrapperClassName}`]: {
304
+ 'button:focus-visible': {
305
+ outline: `2px solid ${"var(--ds-border-focused, #4688EC)"}`,
306
+ borderRadius: "var(--ds-radius-small, 3px)"
307
+ }
308
+ }
309
+ });
302
310
  const akEditorBreakpointForSmallDevice = '1266px';
303
311
  const responsiveBreakoutWidth = css({
304
312
  '--ak-editor--breakout-container-without-gutter-width': `calc(100cqw - ${akEditorGutterPadding}px * 2)`,
@@ -849,11 +857,13 @@ const listItemHiddenMarkerStyles = css({
849
857
  'li:has(> ul:only-child) > ul, li:has(> ol:only-child) > ol': {
850
858
  marginTop: 0
851
859
  },
852
- // Collapse wrapper task items (empty task items followed by a sibling nested task list)
853
- // Only hides empty task items that are actual wrappers, not regular empty task items
854
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-selectors
855
- 'div[data-task-local-id]:has([data-component="content"]:empty):has(+ div[data-node-type="actionList"])': {
856
- display: 'none'
860
+ // Remove top margin from nested taskLists not preceded by a sibling taskItem
861
+ 'div[data-task-list-local-id] > div[data-task-list-local-id]': {
862
+ marginTop: 0
863
+ },
864
+ // Restore margin when a nested taskList follows a taskItem
865
+ 'div[data-task-local-id] + div[data-task-list-local-id]': {
866
+ marginTop: "var(--ds-space-050, 4px)"
857
867
  }
858
868
  });
859
869
  const indentationSharedStyles = css({
@@ -2033,6 +2043,7 @@ const rendererTableSortableColumnStyles = css({
2033
2043
  width: '100%',
2034
2044
  height: '100%',
2035
2045
  padding: `${tableCellPadding}px`,
2046
+ // eslint-disable-next-line @atlaskit/design-system/use-tokens-shape
2036
2047
  borderWidth: '1.5px',
2037
2048
  borderStyle: 'solid',
2038
2049
  borderColor: `transparent`,
@@ -2514,6 +2525,11 @@ const denseStyles = css({
2514
2525
  }
2515
2526
  }
2516
2527
  });
2528
+ const syncBlockRendererStyles = css({
2529
+ margin: 0,
2530
+ maxWidth: 'none',
2531
+ padding: 0
2532
+ });
2517
2533
  const syncBlockStyles = css({
2518
2534
  [`.${SyncBlockSharedCssClassName.renderer}, .${BodiedSyncBlockSharedCssClassName.renderer}, .${SyncBlockSharedCssClassName.error}, .${SyncBlockSharedCssClassName.loading}`]: {
2519
2535
  borderRadius: "var(--ds-radius-small, 3px)",
@@ -2553,7 +2569,8 @@ export const RendererStyleContainer = props => {
2553
2569
  useBlockRenderForCodeBlock,
2554
2570
  children,
2555
2571
  innerRef,
2556
- testId
2572
+ testId,
2573
+ isInsideSyncBlock
2557
2574
  } = props;
2558
2575
  const isAdvancedLayoutsOn = editorExperiment('advanced_layouts', true);
2559
2576
  const isPreviewPanelResponsivenessOn = editorExperiment('platform_editor_preview_panel_responsiveness', true, {
@@ -2582,7 +2599,7 @@ export const RendererStyleContainer = props => {
2582
2599
  '--ak-renderer-editor-font-small-text': editorUGCToken('editor.font.body.small')
2583
2600
  })
2584
2601
  },
2585
- css: [expValEquals('confluence_ttvc_inline_extensions', 'isEnabled', true) ? baseFontStyle : originalBaseFontLineHeight, baseStyles, expValEquals('platform_editor_small_font_size', 'isEnabled', true) && fontSizeStyles, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? headingAnchorStyles : headingAnchorStylesDuplicateAnchor, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? hideHeadingCopyLinkWrapperStyles : hideHeadingCopyLinkWrapperStylesDuplicateAnchor, appearance === 'full-page' && isPreviewPanelResponsivenessOn && rendererFullPageStylesWithReducedPadding, appearance === 'full-page' && !isPreviewPanelResponsivenessOn && rendererFullPageStyles, appearance === 'full-width' && (expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? rendererFullWidthStyles : oldRendererFullWidthStyles), (appearance === 'full-width' || appearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true))) && !isTableResizingEnabled(appearance) && rendererFullWidthStylesForTableResizing, appearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) && (expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? rendererMaxWidthStyles : oldRendererMaxWidthStyles), rovoTelepointerStyles, whitespaceSharedStyles, blockquoteSharedStyles, headingsSharedStyles, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) && headingWrapperInlineFlowStyles, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? headingWithAlignmentStyles : headingWithAlignmentStylesDuplicateAnchor, ruleSharedStyles, contentMode === 'compact' && isCompactModeSupported && extensionStyle, fg('platform_editor_typography_ugc') ? isCompactModeSupported ? paragraphStylesUGCScaledMargin : paragraphSharedStylesWithEditorUGC : isCompactModeSupported ? paragraphSharedStyleScaledMargin : paragraphSharedStyles, listsSharedStyles, browser.gecko && listsSharedStylesForGekko, expValEquals('platform_editor_flexible_list_schema', 'isEnabled', true) && listItemHiddenMarkerStyles, indentationSharedStyles, fg('platform_editor__renderer_indentation_text_margin') && indentationSharedStylesWithMarginFix, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? blockMarksSharedStyles : blockMarksSharedStylesDuplicateAnchor, codeMarkSharedStyles, shadowSharedStyle, dateSharedStyle, textColorStyles, backgroundColorStyles,
2602
+ css: [expValEquals('confluence_ttvc_inline_extensions', 'isEnabled', true) ? baseFontStyle : originalBaseFontLineHeight, baseStyles, expValEquals('platform_editor_small_font_size', 'isEnabled', true) && fontSizeStyles, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? headingAnchorStyles : headingAnchorStylesDuplicateAnchor, fg('ally_30945_accessibility_outline_fix') && headingAnchorButtonFocusVisibleStyles, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? hideHeadingCopyLinkWrapperStyles : hideHeadingCopyLinkWrapperStylesDuplicateAnchor, appearance === 'full-page' && isPreviewPanelResponsivenessOn && rendererFullPageStylesWithReducedPadding, appearance === 'full-page' && !isPreviewPanelResponsivenessOn && rendererFullPageStyles, appearance === 'full-width' && (expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? rendererFullWidthStyles : oldRendererFullWidthStyles), (appearance === 'full-width' || appearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true))) && !isTableResizingEnabled(appearance) && rendererFullWidthStylesForTableResizing, appearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) && (expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? rendererMaxWidthStyles : oldRendererMaxWidthStyles), rovoTelepointerStyles, whitespaceSharedStyles, blockquoteSharedStyles, headingsSharedStyles, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) && headingWrapperInlineFlowStyles, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? headingWithAlignmentStyles : headingWithAlignmentStylesDuplicateAnchor, ruleSharedStyles, contentMode === 'compact' && isCompactModeSupported && extensionStyle, fg('platform_editor_typography_ugc') ? isCompactModeSupported ? paragraphStylesUGCScaledMargin : paragraphSharedStylesWithEditorUGC : isCompactModeSupported ? paragraphSharedStyleScaledMargin : paragraphSharedStyles, listsSharedStyles, browser.gecko && listsSharedStylesForGekko, expValEquals('platform_editor_flexible_list_schema', 'isEnabled', true) && listItemHiddenMarkerStyles, indentationSharedStyles, fg('platform_editor__renderer_indentation_text_margin') && indentationSharedStylesWithMarginFix, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? blockMarksSharedStyles : blockMarksSharedStylesDuplicateAnchor, codeMarkSharedStyles, shadowSharedStyle, dateSharedStyle, textColorStyles, backgroundColorStyles,
2586
2603
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values
2587
2604
  textHighlightPaddingStyles, tasksAndDecisionsStyles, expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) && headingPanelStyles, smartCardStyles, smartCardStylesAvatarFix, editorExperiment('platform_editor_preview_panel_linking_exp', true) && headerSmartCardStyles, smartCardStylesAvatarMarginFix, smartCardStylesAvatarListZeroMarginTop, fg('editor_inline_comments_on_inline_nodes') && (expValEquals('confluence_fe_renderer_inline_node_mark_color_fix', 'isEnabled', true) ? rendererAnnotationStyles : rendererAnnotationStylesOld),
2588
2605
  // eslint-disable-next-line @atlaskit/platform/no-preconditioning
@@ -2590,7 +2607,7 @@ export const RendererStyleContainer = props => {
2590
2607
  // this should be placed after baseOtherStyles
2591
2608
  expValEquals('platform_editor_render_bodied_extension_as_inline', 'isEnabled', true) && (expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? extensionAsInlineStyle : oldExtensionAsInlineStyle), inlineExtensionRendererMarginFix, allowNestedHeaderLinks && (expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? alignedHeadingAnchorStyle : alignedHeadingAnchorStyleDuplicateAnchor), mediaSingleSharedStyle,
2592
2609
  // merge firstWrappedMediaStyles with mediaSingleSharedStyle when clean up platform_editor_fix_media_in_renderer
2593
- fg('platform_editor_fix_media_in_renderer') && firstWrappedMediaStyles, tableSharedStyle, tableRendererHeaderStylesForTableCellOnly, fg('platform_editor_bordered_panel_nested_in_table') && tableRendererNestedPanelStyles, isBackgroundClipBrowserFixNeeded() && tableStylesBackGroundClipForGeckoForTableCellOnly, fg('platform_editor_nested_dnd_styles_changes') ? firstNodeWithNotMarginTopWithNestedDnD : firstNodeWithNotMarginTop, rendererTableStyles, isStickyScrollbarEnabled(appearance) && stickyScrollbarStyles, rendererTableHeaderEqualHeightStylesForTableCellOnly, allowColumnSorting && rendererTableSortableColumnStyles, allowColumnSorting && allowNestedHeaderLinks && (expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? rendererTableHeaderEqualHeightStylesAllowNestedHeaderLinks : rendererTableHeaderEqualHeightStylesAllowNestedHeaderLinksDuplicateAnchor), rendererTableColumnStyles, stickyHeaderStyles, codeBlockAndLayoutStyles, columnLayoutSharedStyle, isAdvancedLayoutsOn && columnLayoutResponsiveSharedStyle, isAdvancedLayoutsOn && columnLayoutResponsiveRendererStyles, isAdvancedLayoutsOn && layoutSectionForAdvancedLayoutsStyles, !useBlockRenderForCodeBlock && gridRenderForCodeBlockStyles, browser.safari && codeBlockInListSafariFixStyles, appearance === 'full-page' && !isPreviewPanelResponsivenessOn && responsiveBreakoutWidth, appearance === 'full-page' && isPreviewPanelResponsivenessOn && responsiveBreakoutWidthWithReducedPadding, (appearance === 'full-width' || appearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true))) && responsiveBreakoutWidthFullWidth, expValEquals('platform_editor_lovability_emoji_scaling', 'isEnabled', true) ? isCompactModeEnabled ? scaledDenseEmojiStyles : scaledEmojiStyles : isCompactModeEnabled ? denseStyles : undefined, editorExperiment('platform_synced_block', true) && syncBlockStyles, centerWrapperStyles],
2610
+ fg('platform_editor_fix_media_in_renderer') && firstWrappedMediaStyles, tableSharedStyle, tableRendererHeaderStylesForTableCellOnly, fg('platform_editor_bordered_panel_nested_in_table') && tableRendererNestedPanelStyles, isBackgroundClipBrowserFixNeeded() && tableStylesBackGroundClipForGeckoForTableCellOnly, fg('platform_editor_nested_dnd_styles_changes') ? firstNodeWithNotMarginTopWithNestedDnD : firstNodeWithNotMarginTop, rendererTableStyles, isStickyScrollbarEnabled(appearance) && stickyScrollbarStyles, rendererTableHeaderEqualHeightStylesForTableCellOnly, allowColumnSorting && rendererTableSortableColumnStyles, allowColumnSorting && allowNestedHeaderLinks && (expValEquals('platform_editor_copy_link_a11y_inconsistency_fix', 'isEnabled', true) ? rendererTableHeaderEqualHeightStylesAllowNestedHeaderLinks : rendererTableHeaderEqualHeightStylesAllowNestedHeaderLinksDuplicateAnchor), rendererTableColumnStyles, stickyHeaderStyles, codeBlockAndLayoutStyles, columnLayoutSharedStyle, isAdvancedLayoutsOn && columnLayoutResponsiveSharedStyle, isAdvancedLayoutsOn && columnLayoutResponsiveRendererStyles, isAdvancedLayoutsOn && layoutSectionForAdvancedLayoutsStyles, !useBlockRenderForCodeBlock && gridRenderForCodeBlockStyles, browser.safari && codeBlockInListSafariFixStyles, appearance === 'full-page' && !isPreviewPanelResponsivenessOn && responsiveBreakoutWidth, appearance === 'full-page' && isPreviewPanelResponsivenessOn && responsiveBreakoutWidthWithReducedPadding, (appearance === 'full-width' || appearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true))) && responsiveBreakoutWidthFullWidth, expValEquals('platform_editor_lovability_emoji_scaling', 'isEnabled', true) ? isCompactModeEnabled ? scaledDenseEmojiStyles : scaledEmojiStyles : isCompactModeEnabled ? denseStyles : undefined, editorExperiment('platform_synced_block', true) && syncBlockStyles, centerWrapperStyles, editorExperiment('platform_synced_block', true) && isInsideSyncBlock && fg('platform_synced_block_patch_9') ? syncBlockRendererStyles : null],
2594
2611
  "data-testid": testId
2595
2612
  }, children);
2596
2613
  };
@@ -57,7 +57,7 @@ export const DEGRADED_SEVERITY_THRESHOLD = 3000;
57
57
  const TABLE_INFO_TIMEOUT = 10000;
58
58
  const RENDER_EVENT_SAMPLE_RATE = 0.2;
59
59
  const packageName = "@atlaskit/renderer";
60
- const packageVersion = "128.7.2";
60
+ const packageVersion = "128.9.0";
61
61
  const setAsQueryContainerStyles = css({
62
62
  containerName: 'ak-renderer-wrapper',
63
63
  containerType: 'inline-size'
@@ -187,9 +187,14 @@ export const RendererFunctionalComponent = props => {
187
187
  const normalizedFeatureFlags = normalizeFeatureFlags(featureFlags);
188
188
  return {
189
189
  featureFlags: normalizedFeatureFlags,
190
- isTopLevelRenderer: isTopLevelRenderer === undefined
190
+ isTopLevelRenderer: isTopLevelRenderer === undefined,
191
+ // Propagate nestedRendererType into the inner RendererContextProvider so that
192
+ // React components inside the renderer (e.g. Colgroup) can read it via
193
+ // useRendererContext(). Without this, the inner provider overwrites the outer
194
+ // AKRendererWrapper context and nestedRendererType becomes undefined.
195
+ nestedRendererType
191
196
  };
192
- }, []);
197
+ }, [nestedRendererType]);
193
198
  const fireAnalyticsEventOld = useCallback(event => {
194
199
  const {
195
200
  createAnalyticsEvent
@@ -615,6 +620,9 @@ const RendererWrapper = /*#__PURE__*/React.memo(props => {
615
620
  return telepointer;
616
621
  };
617
622
  const initialUpdate = React.useRef(true);
623
+ const {
624
+ nestedRendererType
625
+ } = useRendererContext();
618
626
  useEffect(() => {
619
627
  // We must check if window is defined, if it isn't we are in a SSR environment
620
628
  // and we don't want to add the telepointer
@@ -710,7 +718,8 @@ const RendererWrapper = /*#__PURE__*/React.memo(props => {
710
718
  useBlockRenderForCodeBlock: useBlockRenderForCodeBlock,
711
719
  allowAnnotations: props.allowAnnotations,
712
720
  allowTableResizing: allowTableResizing,
713
- allowRendererContainerStyles: allowRendererContainerStyles
721
+ allowRendererContainerStyles: allowRendererContainerStyles,
722
+ isInsideSyncBlock: nestedRendererType === 'syncedBlock'
714
723
  }, children))));
715
724
 
716
725
  // We can only make the wrapper div query container when we have a known width.
@@ -5,7 +5,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  * @jsx jsx
6
6
  */
7
7
  /* eslint-disable jsdoc/check-tag-names */
8
- import { Fragment, useState, useMemo } from 'react';
8
+ import { Fragment, useState, useMemo, useEffect } from 'react';
9
9
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
10
10
  import { jsx } from '@emotion/react';
11
11
  import { useSmartCardContext } from '@atlaskit/link-provider';
@@ -21,6 +21,7 @@ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
21
21
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
22
22
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
23
23
  import { SmartLinkDraggable, SMART_LINK_DRAG_TYPES, SMART_LINK_APPEARANCE } from '@atlaskit/editor-smart-link-draggable';
24
+ import { useProvider } from '@atlaskit/editor-common/provider-factory';
24
25
  import { CardErrorBoundary } from './fallback';
25
26
  import { withSmartCardStorage } from '../../ui/SmartCardStorage';
26
27
  import { getCardClickHandler } from '../utils/getCardClickHandler';
@@ -145,6 +146,7 @@ var InlineCard = function InlineCard(props) {
145
146
  onSetLinkTarget = props.onSetLinkTarget;
146
147
  var portal = usePortal(props);
147
148
  var cardContext = useSmartCardContext();
149
+ var provider = useProvider('cardProvider');
148
150
  var SuspenseWrapperForUrl = smartLinks === null || smartLinks === void 0 ? void 0 : smartLinks.SuspenseWrapperForUrl;
149
151
 
150
152
  // Helper fn to conditionally wrap cards when suspense boundary is passed in via product
@@ -195,6 +197,21 @@ var InlineCard = function InlineCard(props) {
195
197
  throw err;
196
198
  }
197
199
  };
200
+ useEffect(function () {
201
+ if (expValEquals('platform_editor_smartlink_local_cache', 'isEnabled', true) && url) {
202
+ // Refresh cache in the background
203
+ provider === null || provider === void 0 || provider.then(function (providerInstance) {
204
+ var _refreshCache, _ref5;
205
+ (_refreshCache = (_ref5 = providerInstance).refreshCache) === null || _refreshCache === void 0 || _refreshCache.call(_ref5, {
206
+ // It's ok to cast any resourceUrl to inlineCard here, because only URL is important for the request.
207
+ type: 'inlineCard',
208
+ attrs: {
209
+ url: url
210
+ }
211
+ });
212
+ });
213
+ }
214
+ }, [provider, url]);
198
215
  var MaybeOverlay = cardContext !== null && cardContext !== void 0 && cardContext.value ? OverlayWithCardContext : HoverLinkOverlayNoop;
199
216
  if ((ssr || cardState && expValEquals('platform_editor_smartlink_local_cache', 'isEnabled', true)) && url && !editorExperiment('platform_editor_preview_panel_linking_exp', true, {
200
217
  exposure: true
@@ -1,8 +1,9 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
- import React from 'react';
4
+ import React, { useContext } from 'react';
5
5
  import { tableCellBorderWidth, tableCellMinWidth } from '@atlaskit/editor-common/styles';
6
+ import { WidthContext } from '@atlaskit/editor-common/ui';
6
7
  import { akEditorTableNumberColumnWidth, akEditorTableLegacyCellMinWidth, akEditorTableCellMinWidth } from '@atlaskit/editor-shared-styles';
7
8
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
9
  import { getTableContainerWidth } from '@atlaskit/editor-common/node-width';
@@ -26,7 +27,8 @@ var isTableColumnResized = function isTableColumnResized(columnWidths) {
26
27
  var fixColumnWidth = function fixColumnWidth(_ref) {
27
28
  var columnWidth = _ref.columnWidth,
28
29
  zeroWidthColumnsCount = _ref.zeroWidthColumnsCount,
29
- scaleDownPercent = _ref.scaleDownPercent;
30
+ scaleDownPercent = _ref.scaleDownPercent,
31
+ skipMinWidth = _ref.skipMinWidth;
30
32
  if (columnWidth === 0) {
31
33
  return columnWidth;
32
34
  }
@@ -34,11 +36,14 @@ var fixColumnWidth = function fixColumnWidth(_ref) {
34
36
  // If the tables total width (including no zero widths col or cols without width) is less than the current layout
35
37
  // We scale up the columns to meet the minimum of the table layout.
36
38
  if (zeroWidthColumnsCount === 0 && scaleDownPercent) {
37
- return Math.max(Math.floor((1 - scaleDownPercent) * columnWidth), tableCellMinWidth);
39
+ var scaled = Math.floor((1 - scaleDownPercent) * columnWidth);
40
+ return skipMinWidth ? scaled : Math.max(scaled, tableCellMinWidth);
38
41
  }
39
- return Math.max(
40
- // We need to take tableCellBorderWidth, to avoid unnecessary overflow.
41
- columnWidth - tableCellBorderWidth, zeroWidthColumnsCount ? akEditorTableLegacyCellMinWidth : tableCellMinWidth);
42
+ var adjusted = columnWidth - tableCellBorderWidth;
43
+ if (skipMinWidth) {
44
+ return adjusted;
45
+ }
46
+ return Math.max(adjusted, zeroWidthColumnsCount ? akEditorTableLegacyCellMinWidth : tableCellMinWidth);
42
47
  };
43
48
  var calcScalePercent = function calcScalePercent(_ref2) {
44
49
  var renderWidth = _ref2.renderWidth,
@@ -57,6 +62,93 @@ export var colWidthSum = function colWidthSum(columnWidths) {
57
62
  return curr + prev;
58
63
  }, 0);
59
64
  };
65
+
66
+ /**
67
+ * Returns the data-column available width: total width minus the fixed number column if enabled.
68
+ */
69
+ var getDataColumnWidth = function getDataColumnWidth(totalWidth, isNumberColumnEnabled) {
70
+ return isNumberColumnEnabled ? totalWidth - akEditorTableNumberColumnWidth : totalWidth;
71
+ };
72
+
73
+ /**
74
+ * Scales column widths proportionally to fit within availableWidth, matching the editor's
75
+ * scaleTableTo(): floors each column to the nearest pixel, then redistributes any rounding
76
+ * remainder to the first column that can absorb it without going below tableCellMinWidth.
77
+ */
78
+ var scaleColumnsToWidth = function scaleColumnsToWidth(columnWidths, availableWidth) {
79
+ var rawTotalWidth = columnWidths.reduce(function (sum, w) {
80
+ return sum + w;
81
+ }, 0);
82
+ var scaleFactor = availableWidth / rawTotalWidth;
83
+ var scaledWidths = columnWidths.map(function (colWidth) {
84
+ return Math.max(Math.floor(colWidth * scaleFactor), tableCellMinWidth);
85
+ });
86
+ var totalScaled = scaledWidths.reduce(function (sum, w) {
87
+ return sum + w;
88
+ }, 0);
89
+ var diff = availableWidth - totalScaled;
90
+ if (diff !== 0 && Math.abs(diff) < tableCellMinWidth) {
91
+ for (var i = 0; i < scaledWidths.length; i++) {
92
+ if (scaledWidths[i] + diff > tableCellMinWidth) {
93
+ scaledWidths[i] += diff;
94
+ break;
95
+ }
96
+ }
97
+ }
98
+ return scaledWidths.map(function (width) {
99
+ return {
100
+ width: "".concat(width, "px")
101
+ };
102
+ });
103
+ };
104
+
105
+ /**
106
+ * Computes column widths for tables inside sync blocks, matching the editor's scaleTableTo() exactly.
107
+ * Returns null if the flag is off or not inside a sync block.
108
+ *
109
+ * For nested tables (isInsideOfTable=true, gated by platform_synced_block_patch_9), we use
110
+ * getTableContainerWidth(tableNode) as the reference — the width the editor saved, which already
111
+ * accounts for the parent cell's available space (colwidth minus tableCellPadding * 2).
112
+ * This matches bodiedSyncBlock where isRendererNested=false, so renderScaleDownColgroup uses
113
+ * getTableContainerWidth(tableNode). For syncBlock the nested renderer has isRendererNested=true,
114
+ * which incorrectly overrides tableContainerWidth with renderWidth (the full container), causing
115
+ * overflow by 2 * tableCellPadding (16px).
116
+ */
117
+ var renderSyncBlockColgroup = function renderSyncBlockColgroup(_ref3) {
118
+ var isInsideOfSyncBlock = _ref3.isInsideOfSyncBlock,
119
+ isInsideOfTable = _ref3.isInsideOfTable,
120
+ tableNode = _ref3.tableNode,
121
+ columnWidths = _ref3.columnWidths,
122
+ isNumberColumnEnabled = _ref3.isNumberColumnEnabled,
123
+ renderWidthProp = _ref3.renderWidth,
124
+ contextWidth = _ref3.contextWidth;
125
+ if (!isInsideOfSyncBlock || !fg('platform_synced_block_patch_9')) {
126
+ return null;
127
+ }
128
+ var rawTotalWidth = columnWidths.reduce(function (sum, w) {
129
+ return sum + w;
130
+ }, 0);
131
+ if (isInsideOfTable) {
132
+ return null;
133
+ }
134
+
135
+ // SSR / first render before WidthContext measures. Output % of original ADF proportions so
136
+ // columns are stable — the CSS container query (100cqw) handles actual scaling width.
137
+ if (contextWidth <= 0 && renderWidthProp <= 0) {
138
+ var fullTableWidth = isNumberColumnEnabled ? rawTotalWidth + akEditorTableNumberColumnWidth : rawTotalWidth;
139
+ return columnWidths.map(function (colWidth) {
140
+ return {
141
+ width: "".concat(colWidth / fullTableWidth * 100, "%")
142
+ };
143
+ });
144
+ }
145
+
146
+ // contextWidth measures the sync block content area. Subtract 2 to match the editor's
147
+ // getParentNodeWidth() border offset. Fall back to renderWidthProp for the non-CSS path.
148
+ var effectiveRenderWidth = contextWidth > 0 ? contextWidth - 2 : renderWidthProp;
149
+ var availableWidth = getDataColumnWidth(effectiveRenderWidth, isNumberColumnEnabled);
150
+ return scaleColumnsToWidth(columnWidths, availableWidth);
151
+ };
60
152
  var renderScaleDownColgroup = function renderScaleDownColgroup(props) {
61
153
  var _props$tableNode;
62
154
  var columnWidths = props.columnWidths,
@@ -70,7 +162,9 @@ var renderScaleDownColgroup = function renderScaleDownColgroup(props) {
70
162
  isTableScalingEnabled = props.isTableScalingEnabled,
71
163
  isTableFixedColumnWidthsOptionEnabled = props.isTableFixedColumnWidthsOptionEnabled,
72
164
  allowTableResizing = props.allowTableResizing,
73
- isTopLevelRenderer = props.isTopLevelRenderer;
165
+ isTopLevelRenderer = props.isTopLevelRenderer,
166
+ isInsideOfSyncBlock = props.isInsideOfSyncBlock;
167
+ var skipMinWidth = fg('platform_synced_block_patch_9') && !!(isInsideOfTable && isInsideOfSyncBlock);
74
168
  if (!columnWidths || columnWidths.every(function (width) {
75
169
  return width === 0;
76
170
  }) && fg('platform_editor_numbered_column_in_include')) {
@@ -177,7 +271,8 @@ var renderScaleDownColgroup = function renderScaleDownColgroup(props) {
177
271
  return fixColumnWidth({
178
272
  columnWidth: width,
179
273
  zeroWidthColumnsCount: zeroWidthColumnsCount,
180
- scaleDownPercent: scaleDownPercent
274
+ scaleDownPercent: scaleDownPercent,
275
+ skipMinWidth: skipMinWidth
181
276
  }) || cellMinWidth;
182
277
  });
183
278
  var sumFixedColumnWidths = colWidthSum(fixedColWidths);
@@ -204,7 +299,8 @@ var renderScaleDownColgroup = function renderScaleDownColgroup(props) {
204
299
  var width = fixColumnWidth({
205
300
  columnWidth: colWidth,
206
301
  zeroWidthColumnsCount: zeroWidthColumnsCount,
207
- scaleDownPercent: scaleDownPercent
302
+ scaleDownPercent: scaleDownPercent,
303
+ skipMinWidth: skipMinWidth
208
304
  }) || cellMinWidth;
209
305
  var style = width ? {
210
306
  width: "".concat(width, "px")
@@ -213,18 +309,38 @@ var renderScaleDownColgroup = function renderScaleDownColgroup(props) {
213
309
  });
214
310
  };
215
311
  export var Colgroup = function Colgroup(props) {
216
- var _ref3;
312
+ var _ref4, _renderSyncBlockColgr;
217
313
  var _useRendererContext = useRendererContext(),
218
- isTopLevelRenderer = _useRendererContext.isTopLevelRenderer;
314
+ isTopLevelRenderer = _useRendererContext.isTopLevelRenderer,
315
+ nestedRendererType = _useRendererContext.nestedRendererType;
219
316
  var columnWidths = props.columnWidths,
220
317
  isNumberColumnEnabled = props.isNumberColumnEnabled;
318
+ var _useContext = useContext(WidthContext),
319
+ contextWidth = _useContext.width;
221
320
  var flags = useFeatureFlags();
222
321
  if (!columnWidths) {
223
322
  return null;
224
323
  }
225
- var isTableFixedColumnWidthsOptionEnabled = (_ref3 = fg('platform_editor_table_fixed_column_width_prop') ? props.allowFixedColumnWidthOption : flags && 'tableWithFixedColumnWidthsOption' in flags && flags.tableWithFixedColumnWidthsOption) !== null && _ref3 !== void 0 ? _ref3 : false;
226
- var colStyles = renderScaleDownColgroup(_objectSpread(_objectSpread({}, props), {}, {
324
+ var isTableFixedColumnWidthsOptionEnabled = (_ref4 = fg('platform_editor_table_fixed_column_width_prop') ? props.allowFixedColumnWidthOption : flags && 'tableWithFixedColumnWidthsOption' in flags && flags.tableWithFixedColumnWidthsOption) !== null && _ref4 !== void 0 ? _ref4 : false;
325
+
326
+ // For referenced sync blocks, nestedRendererType='syncedBlock' is set via RendererContextProvider
327
+ // in AKRendererWrapper. ReactSerializer is a class and cannot read React context, so we detect
328
+ // it here in the Colgroup component via useRendererContext() instead of prop-drilling.
329
+ var isInsideOfSyncBlock = nestedRendererType === 'syncedBlock';
330
+
331
+ // renderSyncBlockColgroup returns null when not applicable (flag off, SSR, not a sync block),
332
+ // in which case ?? falls back to the standard renderScaleDownColgroup path.
333
+ var colStyles = (_renderSyncBlockColgr = renderSyncBlockColgroup({
334
+ isInsideOfSyncBlock: isInsideOfSyncBlock,
335
+ isInsideOfTable: !!props.isInsideOfTable,
336
+ tableNode: props.tableNode,
337
+ columnWidths: columnWidths,
338
+ isNumberColumnEnabled: !!isNumberColumnEnabled,
339
+ renderWidth: props.renderWidth,
340
+ contextWidth: contextWidth
341
+ })) !== null && _renderSyncBlockColgr !== void 0 ? _renderSyncBlockColgr : renderScaleDownColgroup(_objectSpread(_objectSpread({}, props), {}, {
227
342
  isTopLevelRenderer: isTopLevelRenderer,
343
+ isInsideOfSyncBlock: isInsideOfSyncBlock,
228
344
  isTableScalingEnabled: props.rendererAppearance === 'full-page' || props.rendererAppearance === 'full-width' || props.rendererAppearance === 'max' && (expValEquals('editor_tinymce_full_width_mode', 'isEnabled', true) || expValEquals('confluence_max_width_content_appearance', 'isEnabled', true)) || props.rendererAppearance === 'comment' && editorExperiment('support_table_in_comment', true, {
229
345
  exposure: true
230
346
  }) || props.rendererAppearance === 'comment' && editorExperiment('support_table_in_comment_jira', true, {