@atlaskit/editor-plugin-block-controls 13.0.4 → 13.0.6

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 13.0.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [`e850980f5a66f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e850980f5a66f) -
8
+ [EDITOR-6790] Block-controls drag-handle wrapper's background is removed and instead set
9
+ on`::before` on `.pm-table-container.pm-table-sticky` to keep masking the row insert dots when
10
+ legacy sticky header is activated while also not overlapping the column insert button.
11
+ - [`7754772ebfa47`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7754772ebfa47) -
12
+ Fix table text length calculation for Remix/Improve Writing hero prompts: use
13
+ tableNode.textContent for CellSelection instead of textBetween which only spans anchor/head cell
14
+ range
15
+ - Updated dependencies
16
+
17
+ ## 13.0.5
18
+
19
+ ### Patch Changes
20
+
21
+ - [`086e779e3490c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/086e779e3490c) -
22
+ Add drag and drop support for panel_c1 - allow tables to be dropped into panel_c1, allow panel_c1
23
+ -> panel when dropping in parents that allow panel (e.g., expand, table) via generic transform
24
+ functions for future variants
25
+ - Updated dependencies
26
+
3
27
  ## 13.0.4
4
28
 
5
29
  ### Patch Changes
@@ -10,7 +10,9 @@ var _react = _interopRequireDefault(require("react"));
10
10
  var _selection = require("@atlaskit/editor-common/selection");
11
11
  var _toolbarFlagCheck = require("@atlaskit/editor-common/toolbar-flag-check");
12
12
  var _state = require("@atlaskit/editor-prosemirror/state");
13
+ var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
13
14
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
14
16
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
15
17
  var _handleKeyDownWithPreservedSelection = require("./editor-commands/handle-key-down-with-preserved-selection");
16
18
  var _mapPreservedSelection2 = require("./editor-commands/map-preserved-selection");
@@ -44,6 +46,27 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
44
46
  var blockControlsState = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState();
45
47
  var preservedSelection = blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.preservedSelection;
46
48
  if (preservedSelection && preservedSelection.from !== preservedSelection.to) {
49
+ // CellSelection covers a table: collect each selected cell's text joined with spaces
50
+ // so that adjacent cells are not fused (e.g. 'hello world' + 'foo' must not
51
+ // become 'hello worldfoo'). Intl.Segmenter word-counting requires correct
52
+ // word boundaries, which raw textContent fusion breaks.
53
+ if (preservedSelection instanceof _cellSelection.CellSelection && (0, _expValEquals.expValEquals)('remix_iw_block_menu_table_calc_fix', 'isEnabled', true)) {
54
+ // Use node(1) to reliably target the table node regardless of $anchorCell depth.
55
+ // node(-1) would return tableRow if $anchorCell is at tableCell depth.
56
+ var tableNode = preservedSelection.$anchorCell.node(1);
57
+ var cellTexts = [];
58
+ if (tableNode) {
59
+ // forEachCell iterates only the selected cells, not all cells in the table.
60
+ preservedSelection.forEachCell(function (cell) {
61
+ cellTexts.push(cell.textContent);
62
+ });
63
+ }
64
+ var _textContent = cellTexts.filter(Boolean).join(' ');
65
+ return {
66
+ textLength: _textContent.length,
67
+ textContent: _textContent
68
+ };
69
+ }
47
70
  var from = preservedSelection.from,
48
71
  to = preservedSelection.to;
49
72
  var textContent = editorView.state.doc.textBetween(from, to, '\n');
@@ -51,12 +51,23 @@ function transformSourceSlice(nodeCopy, destType) {
51
51
  var destTypeInTable = (0, _validation.isInsideTable)(destType);
52
52
  var destTypeInDocOrLayoutCol = [doc, layoutColumn].includes(destType);
53
53
 
54
- // No need to loop over slice content if destination requires no transformations
55
- if (!destTypeInTable && !destTypeInDocOrLayoutCol) {
54
+ // Only run transformation loop if destination may need node conversions:
55
+ // - Table destinations may need expand → nestedExpand
56
+ // - Doc/layoutColumn destinations may need nestedExpand → expand
57
+ // - When panel_c1 experiment is on:
58
+ // - Expand/table/bodied extension destinations may need panel_c1 → panel downgrade
59
+ // - Doc/layoutColumn destinations may need panel → panel_c1 upgrade
60
+ var needsTransformCheck = destTypeInTable || destTypeInDocOrLayoutCol || (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true);
61
+ if (!needsTransformCheck) {
56
62
  return nodeCopy;
57
63
  }
58
64
  var containsExpand = false;
59
65
  var containsNestedExpand = false;
66
+ // Track variant nodes (e.g. panel_c1) and their base forms (e.g. panel).
67
+ // Uses getBaseNodeTypeName to auto-detect variants — new variants only need
68
+ // to be added to variantToBaseNameMap, no changes needed in the detection loop.
69
+ var variantType = null;
70
+ var baseOfVariantType = null;
60
71
  for (var i = 0; i < nodeCopy.content.childCount; i++) {
61
72
  var node = nodeCopy.content.child(i);
62
73
  if (node.type === schema.nodes.expand) {
@@ -64,7 +75,15 @@ function transformSourceSlice(nodeCopy, destType) {
64
75
  } else if (node.type === schema.nodes.nestedExpand) {
65
76
  containsNestedExpand = true;
66
77
  }
67
- if (containsExpand && containsNestedExpand) {
78
+ if ((0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
79
+ var baseName = (0, _nodeTypeUtils.getBaseNodeTypeName)(node.type);
80
+ if (baseName !== node.type.name) {
81
+ variantType = node.type.name;
82
+ } else if (schema.nodes["".concat(baseName, "_c1")]) {
83
+ baseOfVariantType = node.type.name;
84
+ }
85
+ }
86
+ if (containsExpand && containsNestedExpand && (variantType || baseOfVariantType)) {
68
87
  break;
69
88
  }
70
89
  }
@@ -73,6 +92,26 @@ function transformSourceSlice(nodeCopy, destType) {
73
92
  } else if (containsNestedExpand && destTypeInDocOrLayoutCol) {
74
93
  return (0, _transforms.transformSliceNestedExpandToExpand)(nodeCopy, schema);
75
94
  }
95
+
96
+ // Downgrade variant → base (e.g. panel_c1 → panel) when dest doesn't support the variant
97
+ if (variantType && schema.nodes[variantType]) {
98
+ var destParent = destType.createAndFill();
99
+ if (destParent && !(0, _nodeTypeUtils.isNodeTypeValidChildOf)(variantType, destParent, schema)) {
100
+ var _baseName = (0, _nodeTypeUtils.getBaseNodeTypeName)(schema.nodes[variantType]);
101
+ return (0, _validation.transformSliceNodeType)(nodeCopy, schema, variantType, _baseName);
102
+ }
103
+ }
104
+
105
+ // Upgrade base → variant (e.g. panel → panel_c1) when dest supports the variant
106
+ if (baseOfVariantType) {
107
+ var variantName = "".concat(baseOfVariantType, "_c1");
108
+ if (schema.nodes[variantName]) {
109
+ var _destParent = destType.createAndFill();
110
+ if (_destParent && (0, _nodeTypeUtils.isNodeTypeValidChildOf)(variantName, _destParent, schema)) {
111
+ return (0, _validation.transformSliceNodeType)(nodeCopy, schema, baseOfVariantType, variantName);
112
+ }
113
+ }
114
+ }
76
115
  return nodeCopy;
77
116
  }
78
117
  var nodesSupportDragLayoutColumnInto = ['tableCell', 'tableHeader', 'panel', 'expand', 'nestedExpand'];
@@ -10,6 +10,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
  var _reactDom = _interopRequireDefault(require("react-dom"));
12
12
  var _uuid = _interopRequireDefault(require("uuid"));
13
+ var _nodeTypeUtils = require("@atlaskit/editor-common/utils/node-type-utils");
13
14
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
14
15
  var _validation = require("./utils/validation");
15
16
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
@@ -33,7 +34,8 @@ var getSubType = function getSubType(node) {
33
34
  };
34
35
  var getNodeTypeWithLevel = exports.getNodeTypeWithLevel = function getNodeTypeWithLevel(node) {
35
36
  var subType = (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? getSubType(node) : node.attrs.level ? "-".concat(node.attrs.level) : '';
36
- return node.type.name + subType;
37
+ var typeName = (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) ? (0, _nodeTypeUtils.getBaseNodeTypeName)(node.type) : node.type.name;
38
+ return typeName + subType;
37
39
  };
38
40
  var ObjHash = /*#__PURE__*/function () {
39
41
  function ObjHash() {
@@ -9,6 +9,7 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
9
9
  var _memoizeOne = _interopRequireDefault(require("memoize-one"));
10
10
  var _selection = require("@atlaskit/editor-common/selection");
11
11
  var _utils = require("@atlaskit/editor-common/utils");
12
+ var _nodeTypeUtils = require("@atlaskit/editor-common/utils/node-type-utils");
12
13
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
13
14
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
15
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
@@ -33,7 +34,8 @@ var getContainerNodeTypes = (0, _memoizeOne.default)(function () {
33
34
  return [].concat(PARENT_WITH_END_DROP_TARGET, (0, _toConsumableArray2.default)((0, _platformFeatureFlags.fg)('confluence_frontend_native_tabs_extension') ? ['multiBodiedExtension'] : []), (0, _toConsumableArray2.default)((0, _experiments.editorExperiment)('platform_synced_block', true) ? ['bodiedSyncBlock'] : []));
34
35
  });
35
36
  var isContainerNode = function isContainerNode(node) {
36
- return getContainerNodeTypes().includes(node.type.name);
37
+ var nodeName = (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) ? (0, _nodeTypeUtils.getBaseNodeTypeName)(node.type) : node.type.name;
38
+ return getContainerNodeTypes().includes(nodeName);
37
39
  };
38
40
  var canMoveNodeOrSliceToPos = exports.canMoveNodeOrSliceToPos = function canMoveNodeOrSliceToPos(state, node, parent, index, $toPos, activeNode) {
39
41
  // For deciding to show drop targets or not when multiple nodes are selected
@@ -7,9 +7,10 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.canCreateNodeWithContentInsideAnotherNode = void 0;
8
8
  exports.canMoveNodeToIndex = canMoveNodeToIndex;
9
9
  exports.canMoveSliceToIndex = canMoveSliceToIndex;
10
- exports.transformSliceExpandToNestedExpand = exports.transformFragmentExpandToNestedExpand = exports.transformExpandToNestedExpand = exports.memoizedTransformExpandToNestedExpand = exports.isNestedExpand = exports.isLayoutColumn = exports.isInsideTable = exports.isInSameLayout = exports.isFontSizeMarkActive = exports.isExpand = exports.isDoc = void 0;
10
+ exports.transformSliceNodeType = exports.transformSliceExpandToNestedExpand = exports.transformFragmentNodeType = exports.transformFragmentExpandToNestedExpand = exports.transformExpandToNestedExpand = exports.memoizedTransformExpandToNestedExpand = exports.isNestedExpand = exports.isLayoutColumn = exports.isInsideTable = exports.isInSameLayout = exports.isFontSizeMarkActive = exports.isExpand = exports.isDoc = void 0;
11
11
  var _memoizeOne = _interopRequireDefault(require("memoize-one"));
12
12
  var _nesting = require("@atlaskit/editor-common/nesting");
13
+ var _nodeTypeUtils = require("@atlaskit/editor-common/utils/node-type-utils");
13
14
  var _model = require("@atlaskit/editor-prosemirror/model");
14
15
  var _utils = require("@atlaskit/editor-prosemirror/utils");
15
16
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
@@ -79,6 +80,41 @@ var transformFragmentExpandToNestedExpand = exports.transformFragmentExpandToNes
79
80
  }
80
81
  return _model.Fragment.fromArray(children);
81
82
  };
83
+
84
+ /**
85
+ * Generic fragment transformer — converts all nodes of `fromType` to `toType`,
86
+ * preserving attrs, content, and marks.
87
+ */
88
+ var transformFragmentNodeType = exports.transformFragmentNodeType = function transformFragmentNodeType(fragment, schema, fromType, toType) {
89
+ var children = [];
90
+ var targetType = schema.nodes[toType];
91
+ if (!targetType) {
92
+ return null;
93
+ }
94
+ try {
95
+ fragment.forEach(function (node) {
96
+ if (node.type.name === fromType) {
97
+ children.push(targetType.create(node.attrs, node.content, node.marks));
98
+ } else {
99
+ children.push(node);
100
+ }
101
+ });
102
+ } catch (e) {
103
+ return null;
104
+ }
105
+ return _model.Fragment.fromArray(children);
106
+ };
107
+
108
+ /**
109
+ * Generic slice transformer — converts all nodes of `fromType` to `toType`.
110
+ */
111
+ var transformSliceNodeType = exports.transformSliceNodeType = function transformSliceNodeType(slice, schema, fromType, toType) {
112
+ var fragment = transformFragmentNodeType(slice.content, schema, fromType, toType);
113
+ if (!fragment) {
114
+ return null;
115
+ }
116
+ return new _model.Slice(fragment, slice.openStart, slice.openEnd);
117
+ };
82
118
  var transformSliceExpandToNestedExpand = exports.transformSliceExpandToNestedExpand = function transformSliceExpandToNestedExpand(slice) {
83
119
  var fragment = transformFragmentExpandToNestedExpand(slice.content);
84
120
  if (!fragment) {
@@ -163,6 +199,19 @@ function canMoveNodeToIndex(destParent, indexIntoParent, srcNode, $destNodePos,
163
199
  } else if ((isDoc(destParent.type) || isLayoutColumn(destParent.type)) && isNestedExpand(srcNodeType)) {
164
200
  srcNodeType = expand;
165
201
  }
202
+
203
+ // Downgrade variant node (e.g. panel_c1 → panel) when dest doesn't support it
204
+ if ((0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
205
+ var baseName = (0, _nodeTypeUtils.getBaseNodeTypeName)(srcNodeType);
206
+ if (baseName !== srcNodeType.name && !destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType)) {
207
+ var baseType = schema.nodes[baseName];
208
+ // Check if the node's content is valid in the base type (e.g. panel with table can't be downgraded)
209
+ if (!baseType || !baseType.validContent(srcNode.content)) {
210
+ return false;
211
+ }
212
+ srcNodeType = baseType;
213
+ }
214
+ }
166
215
  return destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType);
167
216
  }
168
217
  function canMoveSliceToIndex(slice, sliceFromPos, sliceToPos, destParent, indexIntoParent, $destNodePos, destNode) {
@@ -82,6 +82,37 @@ var buttonWrapperStyles = (0, _react2.css)({
82
82
  boxSizing: 'border-box'
83
83
  }
84
84
  });
85
+
86
+ // EDITOR-6790 - When the `platform_editor_table_col_insert` experiment is enabled,
87
+ // drop the linear-gradient background that paints over the legacy `tr.sticky` table
88
+ // header so the new left-edge column-insert affordance is not visually clipped.
89
+ // Keep all paddings / margins identical to `buttonWrapperStyles` so the drag-handle
90
+ // layout does not shift between the two variants.
91
+ var buttonWrapperStylesNoBackground = (0, _react2.css)({
92
+ display: 'flex',
93
+ justifyContent: 'center',
94
+ alignItems: 'center',
95
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
96
+ '[data-blocks-drag-handle-container]:has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
97
+ marginBottom: "var(--ds-space-negative-200, -16px)",
98
+ paddingBottom: "var(--ds-space-200, 16px)",
99
+ marginTop: "var(--ds-space-negative-400, -32px)",
100
+ paddingTop: "calc(".concat("var(--ds-space-400, 32px)", " - 1px)"),
101
+ marginRight: "var(--ds-space-negative-150, -12px)",
102
+ paddingRight: "var(--ds-space-150, 12px)",
103
+ boxSizing: 'border-box'
104
+ },
105
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
106
+ '[data-prosemirror-mark-name="breakout"]:has([data-blocks-drag-handle-container]):has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
107
+ marginBottom: "var(--ds-space-negative-200, -16px)",
108
+ paddingBottom: "var(--ds-space-200, 16px)",
109
+ marginTop: "var(--ds-space-negative-400, -32px)",
110
+ paddingTop: "calc(".concat("var(--ds-space-400, 32px)", " - 1px)"),
111
+ marginRight: "var(--ds-space-negative-150, -12px)",
112
+ paddingRight: "var(--ds-space-150, 12px)",
113
+ boxSizing: 'border-box'
114
+ }
115
+ });
85
116
  var buttonWrapperStylesPatch = (0, _react2.css)({
86
117
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
87
118
  '[data-blocks-drag-handle-container]:has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls [data-number-column="true"] tr.sticky) &': {
@@ -1092,7 +1123,10 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
1092
1123
  });
1093
1124
  }
1094
1125
  }, (0, _react2.jsx)("span", {
1095
- css: [(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && buttonWrapperStyles, buttonWrapperStylesPatch]
1126
+ css: [(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && (
1127
+ // EDITOR-6790 - drop the masking background under the new
1128
+ // column-insert experiment so the left-edge dot is not clipped.
1129
+ (0, _expValEquals.expValEquals)('platform_editor_table_col_insert', 'isEnabled', true) ? buttonWrapperStylesNoBackground : buttonWrapperStyles), buttonWrapperStylesPatch]
1096
1130
  }, renderButton()))));
1097
1131
  };
1098
1132
  var stickyWithoutTooltip = function stickyWithoutTooltip() {
@@ -1108,7 +1142,10 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
1108
1142
  }, (0, _react2.jsx)("span", {
1109
1143
  css: [tooltipContainerStyles, (0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithMask, !(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithoutMask]
1110
1144
  }, (0, _react2.jsx)("span", {
1111
- css: [(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && buttonWrapperStyles, buttonWrapperStylesPatch]
1145
+ css: [(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && (
1146
+ // EDITOR-6790 - drop the masking background under the new
1147
+ // column-insert experiment so the left-edge dot is not clipped.
1148
+ (0, _expValEquals.expValEquals)('platform_editor_table_col_insert', 'isEnabled', true) ? buttonWrapperStylesNoBackground : buttonWrapperStyles), buttonWrapperStylesPatch]
1112
1149
  }, renderButton())));
1113
1150
  };
1114
1151
  var buttonWithTooltip = function buttonWithTooltip() {
@@ -11,6 +11,7 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
11
11
  var _react = require("react");
12
12
  var _react2 = require("@emotion/react");
13
13
  var _hooks = require("@atlaskit/editor-common/hooks");
14
+ var _nodeTypeUtils = require("@atlaskit/editor-common/utils/node-type-utils");
14
15
  var _box = require("@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box");
15
16
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
16
17
  var _constants = require("@atlaskit/theme/constants");
@@ -232,7 +233,7 @@ var DropTarget = exports.DropTarget = function DropTarget(props) {
232
233
  };
233
234
  var dynamicStyle = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({
234
235
  width: isNestedDropTarget ? 'unset' : '100%'
235
- }, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH, isNestedDropTarget ? '100%' : "".concat(lineLength || DEFAULT_DROP_INDICATOR_WIDTH, "px")), EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN, isNestedDropTarget ? (0, _consts.getNestedNodeLeftPaddingMargin)(parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) : '0'), EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX, _constants.layers.navigation());
236
+ }, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH, isNestedDropTarget ? '100%' : "".concat(lineLength || DEFAULT_DROP_INDICATOR_WIDTH, "px")), EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN, isNestedDropTarget ? (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) && parentNode !== null && parentNode !== void 0 && parentNode.type ? (0, _consts.getNestedNodeLeftPaddingMargin)((0, _nodeTypeUtils.getBaseNodeTypeName)(parentNode.type)) : (0, _consts.getNestedNodeLeftPaddingMargin)(parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) : '0'), EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX, _constants.layers.navigation());
236
237
  var isShowInlineDropTarget = (0, _inlineDropTarget.shouldAllowInlineDropTarget)(isNestedDropTarget, nextNode, isSameLayout, activeNode, parentNode);
237
238
  return (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)(HoverZone
238
239
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
@@ -2,7 +2,9 @@ import React from 'react';
2
2
  import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
3
3
  import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check';
4
4
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
5
+ import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
5
6
  import { fg } from '@atlaskit/platform-feature-flags';
7
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
8
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
7
9
  import { handleKeyDownWithPreservedSelection } from './editor-commands/handle-key-down-with-preserved-selection';
8
10
  import { mapPreservedSelection } from './editor-commands/map-preserved-selection';
@@ -35,6 +37,27 @@ export const blockControlsPlugin = ({
35
37
  const blockControlsState = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState();
36
38
  const preservedSelection = blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.preservedSelection;
37
39
  if (preservedSelection && preservedSelection.from !== preservedSelection.to) {
40
+ // CellSelection covers a table: collect each selected cell's text joined with spaces
41
+ // so that adjacent cells are not fused (e.g. 'hello world' + 'foo' must not
42
+ // become 'hello worldfoo'). Intl.Segmenter word-counting requires correct
43
+ // word boundaries, which raw textContent fusion breaks.
44
+ if (preservedSelection instanceof CellSelection && expValEquals('remix_iw_block_menu_table_calc_fix', 'isEnabled', true)) {
45
+ // Use node(1) to reliably target the table node regardless of $anchorCell depth.
46
+ // node(-1) would return tableRow if $anchorCell is at tableCell depth.
47
+ const tableNode = preservedSelection.$anchorCell.node(1);
48
+ const cellTexts = [];
49
+ if (tableNode) {
50
+ // forEachCell iterates only the selected cells, not all cells in the table.
51
+ preservedSelection.forEachCell(cell => {
52
+ cellTexts.push(cell.textContent);
53
+ });
54
+ }
55
+ const textContent = cellTexts.filter(Boolean).join(' ');
56
+ return {
57
+ textLength: textContent.length,
58
+ textContent
59
+ };
60
+ }
38
61
  const {
39
62
  from,
40
63
  to
@@ -5,7 +5,7 @@ import { expandSelectionBounds, GapCursorSelection } from '@atlaskit/editor-comm
5
5
  import { transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
6
6
  import { DIRECTION } from '@atlaskit/editor-common/types';
7
7
  import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
8
- import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
8
+ import { isNodeTypeValidChildOf, getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
9
9
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
10
10
  import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
11
11
  import { Mapping, StepMap } from '@atlaskit/editor-prosemirror/transform';
@@ -21,7 +21,7 @@ import { setCursorPositionAtMovedNode } from '../pm-plugins/utils/getSelection';
21
21
  import { removeFromSource } from '../pm-plugins/utils/remove-from-source';
22
22
  import { getSelectedSlicePosition } from '../pm-plugins/utils/selection';
23
23
  import { getInsertLayoutStep, updateSelection } from '../pm-plugins/utils/update-selection';
24
- import { canMoveNodeToIndex, isInsideTable, transformFragmentExpandToNestedExpand, transformSliceExpandToNestedExpand } from '../pm-plugins/utils/validation';
24
+ import { canMoveNodeToIndex, isInsideTable, transformFragmentExpandToNestedExpand, transformSliceExpandToNestedExpand, transformSliceNodeType } from '../pm-plugins/utils/validation';
25
25
  import { getPosWhenMoveNodeDown, getPosWhenMoveNodeUp } from './utils/move-node-utils';
26
26
 
27
27
  /**
@@ -43,12 +43,23 @@ function transformSourceSlice(nodeCopy, destType) {
43
43
  const destTypeInTable = isInsideTable(destType);
44
44
  const destTypeInDocOrLayoutCol = [doc, layoutColumn].includes(destType);
45
45
 
46
- // No need to loop over slice content if destination requires no transformations
47
- if (!destTypeInTable && !destTypeInDocOrLayoutCol) {
46
+ // Only run transformation loop if destination may need node conversions:
47
+ // - Table destinations may need expand → nestedExpand
48
+ // - Doc/layoutColumn destinations may need nestedExpand → expand
49
+ // - When panel_c1 experiment is on:
50
+ // - Expand/table/bodied extension destinations may need panel_c1 → panel downgrade
51
+ // - Doc/layoutColumn destinations may need panel → panel_c1 upgrade
52
+ const needsTransformCheck = destTypeInTable || destTypeInDocOrLayoutCol || expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true);
53
+ if (!needsTransformCheck) {
48
54
  return nodeCopy;
49
55
  }
50
56
  let containsExpand = false;
51
57
  let containsNestedExpand = false;
58
+ // Track variant nodes (e.g. panel_c1) and their base forms (e.g. panel).
59
+ // Uses getBaseNodeTypeName to auto-detect variants — new variants only need
60
+ // to be added to variantToBaseNameMap, no changes needed in the detection loop.
61
+ let variantType = null;
62
+ let baseOfVariantType = null;
52
63
  for (let i = 0; i < nodeCopy.content.childCount; i++) {
53
64
  const node = nodeCopy.content.child(i);
54
65
  if (node.type === schema.nodes.expand) {
@@ -56,7 +67,15 @@ function transformSourceSlice(nodeCopy, destType) {
56
67
  } else if (node.type === schema.nodes.nestedExpand) {
57
68
  containsNestedExpand = true;
58
69
  }
59
- if (containsExpand && containsNestedExpand) {
70
+ if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
71
+ const baseName = getBaseNodeTypeName(node.type);
72
+ if (baseName !== node.type.name) {
73
+ variantType = node.type.name;
74
+ } else if (schema.nodes[`${baseName}_c1`]) {
75
+ baseOfVariantType = node.type.name;
76
+ }
77
+ }
78
+ if (containsExpand && containsNestedExpand && (variantType || baseOfVariantType)) {
60
79
  break;
61
80
  }
62
81
  }
@@ -65,6 +84,26 @@ function transformSourceSlice(nodeCopy, destType) {
65
84
  } else if (containsNestedExpand && destTypeInDocOrLayoutCol) {
66
85
  return transformSliceNestedExpandToExpand(nodeCopy, schema);
67
86
  }
87
+
88
+ // Downgrade variant → base (e.g. panel_c1 → panel) when dest doesn't support the variant
89
+ if (variantType && schema.nodes[variantType]) {
90
+ const destParent = destType.createAndFill();
91
+ if (destParent && !isNodeTypeValidChildOf(variantType, destParent, schema)) {
92
+ const baseName = getBaseNodeTypeName(schema.nodes[variantType]);
93
+ return transformSliceNodeType(nodeCopy, schema, variantType, baseName);
94
+ }
95
+ }
96
+
97
+ // Upgrade base → variant (e.g. panel → panel_c1) when dest supports the variant
98
+ if (baseOfVariantType) {
99
+ const variantName = `${baseOfVariantType}_c1`;
100
+ if (schema.nodes[variantName]) {
101
+ const destParent = destType.createAndFill();
102
+ if (destParent && isNodeTypeValidChildOf(variantName, destParent, schema)) {
103
+ return transformSliceNodeType(nodeCopy, schema, baseOfVariantType, variantName);
104
+ }
105
+ }
106
+ }
68
107
  return nodeCopy;
69
108
  }
70
109
  const nodesSupportDragLayoutColumnInto = ['tableCell', 'tableHeader', 'panel', 'expand', 'nestedExpand'];
@@ -2,6 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import ReactDOM from 'react-dom';
3
3
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
4
4
  import uuid from 'uuid';
5
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
5
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
7
  import { isFontSizeMarkActive } from './utils/validation';
7
8
  export const TYPE_DROP_TARGET_DEC = 'drop-target-decoration';
@@ -23,7 +24,8 @@ const getSubType = node => {
23
24
  };
24
25
  export const getNodeTypeWithLevel = node => {
25
26
  const subType = expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getSubType(node) : node.attrs.level ? `-${node.attrs.level}` : '';
26
- return node.type.name + subType;
27
+ const typeName = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? getBaseNodeTypeName(node.type) : node.type.name;
28
+ return typeName + subType;
27
29
  };
28
30
  class ObjHash {
29
31
  static getForNode(node) {
@@ -1,6 +1,7 @@
1
1
  import memoizeOne from 'memoize-one';
2
2
  import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
3
3
  import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
4
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
4
5
  import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
5
6
  import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -24,7 +25,8 @@ const NODE_WITH_NO_PARENT_POS = ['tableCell', 'tableHeader', 'layoutColumn'];
24
25
  const UNSUPPORTED_LAYOUT_CONTENT = ['syncBlock', 'bodiedSyncBlock'];
25
26
  const getContainerNodeTypes = memoizeOne(() => [...PARENT_WITH_END_DROP_TARGET, ...(fg('confluence_frontend_native_tabs_extension') ? ['multiBodiedExtension'] : []), ...(editorExperiment('platform_synced_block', true) ? ['bodiedSyncBlock'] : [])]);
26
27
  const isContainerNode = node => {
27
- return getContainerNodeTypes().includes(node.type.name);
28
+ const nodeName = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? getBaseNodeTypeName(node.type) : node.type.name;
29
+ return getContainerNodeTypes().includes(nodeName);
28
30
  };
29
31
  export const canMoveNodeOrSliceToPos = (state, node, parent, index, $toPos, activeNode) => {
30
32
  // For deciding to show drop targets or not when multiple nodes are selected
@@ -1,5 +1,6 @@
1
1
  import memoizeOne from 'memoize-one';
2
2
  import { getParentOfTypeCount, isNestedTablesSupported } from '@atlaskit/editor-common/nesting';
3
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
3
4
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
4
5
  import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
5
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -69,6 +70,41 @@ export const transformFragmentExpandToNestedExpand = fragment => {
69
70
  }
70
71
  return Fragment.fromArray(children);
71
72
  };
73
+
74
+ /**
75
+ * Generic fragment transformer — converts all nodes of `fromType` to `toType`,
76
+ * preserving attrs, content, and marks.
77
+ */
78
+ export const transformFragmentNodeType = (fragment, schema, fromType, toType) => {
79
+ const children = [];
80
+ const targetType = schema.nodes[toType];
81
+ if (!targetType) {
82
+ return null;
83
+ }
84
+ try {
85
+ fragment.forEach(node => {
86
+ if (node.type.name === fromType) {
87
+ children.push(targetType.create(node.attrs, node.content, node.marks));
88
+ } else {
89
+ children.push(node);
90
+ }
91
+ });
92
+ } catch (e) {
93
+ return null;
94
+ }
95
+ return Fragment.fromArray(children);
96
+ };
97
+
98
+ /**
99
+ * Generic slice transformer — converts all nodes of `fromType` to `toType`.
100
+ */
101
+ export const transformSliceNodeType = (slice, schema, fromType, toType) => {
102
+ const fragment = transformFragmentNodeType(slice.content, schema, fromType, toType);
103
+ if (!fragment) {
104
+ return null;
105
+ }
106
+ return new Slice(fragment, slice.openStart, slice.openEnd);
107
+ };
72
108
  export const transformSliceExpandToNestedExpand = slice => {
73
109
  const fragment = transformFragmentExpandToNestedExpand(slice.content);
74
110
  if (!fragment) {
@@ -152,6 +188,19 @@ export function canMoveNodeToIndex(destParent, indexIntoParent, srcNode, $destNo
152
188
  } else if ((isDoc(destParent.type) || isLayoutColumn(destParent.type)) && isNestedExpand(srcNodeType)) {
153
189
  srcNodeType = expand;
154
190
  }
191
+
192
+ // Downgrade variant node (e.g. panel_c1 → panel) when dest doesn't support it
193
+ if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
194
+ const baseName = getBaseNodeTypeName(srcNodeType);
195
+ if (baseName !== srcNodeType.name && !destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType)) {
196
+ const baseType = schema.nodes[baseName];
197
+ // Check if the node's content is valid in the base type (e.g. panel with table can't be downgraded)
198
+ if (!baseType || !baseType.validContent(srcNode.content)) {
199
+ return false;
200
+ }
201
+ srcNodeType = baseType;
202
+ }
203
+ }
155
204
  return destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType);
156
205
  }
157
206
  export function canMoveSliceToIndex(slice, sliceFromPos, sliceToPos, destParent, indexIntoParent, $destNodePos, destNode) {
@@ -73,6 +73,37 @@ const buttonWrapperStyles = css({
73
73
  boxSizing: 'border-box'
74
74
  }
75
75
  });
76
+
77
+ // EDITOR-6790 - When the `platform_editor_table_col_insert` experiment is enabled,
78
+ // drop the linear-gradient background that paints over the legacy `tr.sticky` table
79
+ // header so the new left-edge column-insert affordance is not visually clipped.
80
+ // Keep all paddings / margins identical to `buttonWrapperStyles` so the drag-handle
81
+ // layout does not shift between the two variants.
82
+ const buttonWrapperStylesNoBackground = css({
83
+ display: 'flex',
84
+ justifyContent: 'center',
85
+ alignItems: 'center',
86
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
87
+ '[data-blocks-drag-handle-container]:has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
88
+ marginBottom: "var(--ds-space-negative-200, -16px)",
89
+ paddingBottom: "var(--ds-space-200, 16px)",
90
+ marginTop: "var(--ds-space-negative-400, -32px)",
91
+ paddingTop: `calc(${"var(--ds-space-400, 32px)"} - 1px)`,
92
+ marginRight: "var(--ds-space-negative-150, -12px)",
93
+ paddingRight: "var(--ds-space-150, 12px)",
94
+ boxSizing: 'border-box'
95
+ },
96
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
97
+ '[data-prosemirror-mark-name="breakout"]:has([data-blocks-drag-handle-container]):has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
98
+ marginBottom: "var(--ds-space-negative-200, -16px)",
99
+ paddingBottom: "var(--ds-space-200, 16px)",
100
+ marginTop: "var(--ds-space-negative-400, -32px)",
101
+ paddingTop: `calc(${"var(--ds-space-400, 32px)"} - 1px)`,
102
+ marginRight: "var(--ds-space-negative-150, -12px)",
103
+ paddingRight: "var(--ds-space-150, 12px)",
104
+ boxSizing: 'border-box'
105
+ }
106
+ });
76
107
  const buttonWrapperStylesPatch = css({
77
108
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
78
109
  '[data-blocks-drag-handle-container]:has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls [data-number-column="true"] tr.sticky) &': {
@@ -1071,7 +1102,10 @@ export const DragHandle = ({
1071
1102
  });
1072
1103
  }
1073
1104
  }, jsx("span", {
1074
- css: [shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && buttonWrapperStyles, buttonWrapperStylesPatch]
1105
+ css: [shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && (
1106
+ // EDITOR-6790 - drop the masking background under the new
1107
+ // column-insert experiment so the left-edge dot is not clipped.
1108
+ expValEquals('platform_editor_table_col_insert', 'isEnabled', true) ? buttonWrapperStylesNoBackground : buttonWrapperStyles), buttonWrapperStylesPatch]
1075
1109
  }, renderButton()))));
1076
1110
  const stickyWithoutTooltip = () => jsx(Box
1077
1111
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
@@ -1085,7 +1119,10 @@ export const DragHandle = ({
1085
1119
  }, jsx("span", {
1086
1120
  css: [tooltipContainerStyles, shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithMask, !shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithoutMask]
1087
1121
  }, jsx("span", {
1088
- css: [shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && buttonWrapperStyles, buttonWrapperStylesPatch]
1122
+ css: [shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && (
1123
+ // EDITOR-6790 - drop the masking background under the new
1124
+ // column-insert experiment so the left-edge dot is not clipped.
1125
+ expValEquals('platform_editor_table_col_insert', 'isEnabled', true) ? buttonWrapperStylesNoBackground : buttonWrapperStyles), buttonWrapperStylesPatch]
1089
1126
  }, renderButton())));
1090
1127
  const buttonWithTooltip = () => jsx(Tooltip, {
1091
1128
  content: tooltipContent,
@@ -7,6 +7,7 @@ import { Fragment, useEffect, useMemo, useRef, useState } from 'react';
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
8
8
  import { css, jsx } from '@emotion/react';
9
9
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
10
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
10
11
  import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
11
12
  import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
12
13
  import { layers } from '@atlaskit/theme/constants';
@@ -222,7 +223,7 @@ export const DropTarget = props => {
222
223
  const dynamicStyle = {
223
224
  width: isNestedDropTarget ? 'unset' : '100%',
224
225
  [EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH]: isNestedDropTarget ? '100%' : `${lineLength || DEFAULT_DROP_INDICATOR_WIDTH}px`,
225
- [EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN]: isNestedDropTarget ? getNestedNodeLeftPaddingMargin(parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) : '0',
226
+ [EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN]: isNestedDropTarget ? expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) && parentNode !== null && parentNode !== void 0 && parentNode.type ? getNestedNodeLeftPaddingMargin(getBaseNodeTypeName(parentNode.type)) : getNestedNodeLeftPaddingMargin(parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) : '0',
226
227
  [EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX]: layers.navigation()
227
228
  };
228
229
  const isShowInlineDropTarget = shouldAllowInlineDropTarget(isNestedDropTarget, nextNode, isSameLayout, activeNode, parentNode);
@@ -5,7 +5,9 @@ import React from 'react';
5
5
  import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
6
6
  import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check';
7
7
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
8
+ import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
8
9
  import { fg } from '@atlaskit/platform-feature-flags';
10
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
9
11
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
10
12
  import { handleKeyDownWithPreservedSelection } from './editor-commands/handle-key-down-with-preserved-selection';
11
13
  import { mapPreservedSelection as _mapPreservedSelection } from './editor-commands/map-preserved-selection';
@@ -37,6 +39,27 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
37
39
  var blockControlsState = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState();
38
40
  var preservedSelection = blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.preservedSelection;
39
41
  if (preservedSelection && preservedSelection.from !== preservedSelection.to) {
42
+ // CellSelection covers a table: collect each selected cell's text joined with spaces
43
+ // so that adjacent cells are not fused (e.g. 'hello world' + 'foo' must not
44
+ // become 'hello worldfoo'). Intl.Segmenter word-counting requires correct
45
+ // word boundaries, which raw textContent fusion breaks.
46
+ if (preservedSelection instanceof CellSelection && expValEquals('remix_iw_block_menu_table_calc_fix', 'isEnabled', true)) {
47
+ // Use node(1) to reliably target the table node regardless of $anchorCell depth.
48
+ // node(-1) would return tableRow if $anchorCell is at tableCell depth.
49
+ var tableNode = preservedSelection.$anchorCell.node(1);
50
+ var cellTexts = [];
51
+ if (tableNode) {
52
+ // forEachCell iterates only the selected cells, not all cells in the table.
53
+ preservedSelection.forEachCell(function (cell) {
54
+ cellTexts.push(cell.textContent);
55
+ });
56
+ }
57
+ var _textContent = cellTexts.filter(Boolean).join(' ');
58
+ return {
59
+ textLength: _textContent.length,
60
+ textContent: _textContent
61
+ };
62
+ }
40
63
  var from = preservedSelection.from,
41
64
  to = preservedSelection.to;
42
65
  var textContent = editorView.state.doc.textBetween(from, to, '\n');
@@ -8,7 +8,7 @@ import { expandSelectionBounds, GapCursorSelection } from '@atlaskit/editor-comm
8
8
  import { transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
9
9
  import { DIRECTION } from '@atlaskit/editor-common/types';
10
10
  import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
11
- import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
11
+ import { isNodeTypeValidChildOf, getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
12
12
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
13
13
  import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
14
14
  import { Mapping, StepMap } from '@atlaskit/editor-prosemirror/transform';
@@ -24,7 +24,7 @@ import { setCursorPositionAtMovedNode } from '../pm-plugins/utils/getSelection';
24
24
  import { removeFromSource } from '../pm-plugins/utils/remove-from-source';
25
25
  import { getSelectedSlicePosition } from '../pm-plugins/utils/selection';
26
26
  import { getInsertLayoutStep, updateSelection } from '../pm-plugins/utils/update-selection';
27
- import { canMoveNodeToIndex, isInsideTable, transformFragmentExpandToNestedExpand, transformSliceExpandToNestedExpand } from '../pm-plugins/utils/validation';
27
+ import { canMoveNodeToIndex, isInsideTable, transformFragmentExpandToNestedExpand, transformSliceExpandToNestedExpand, transformSliceNodeType } from '../pm-plugins/utils/validation';
28
28
  import { getPosWhenMoveNodeDown, getPosWhenMoveNodeUp } from './utils/move-node-utils';
29
29
 
30
30
  /**
@@ -45,12 +45,23 @@ function transformSourceSlice(nodeCopy, destType) {
45
45
  var destTypeInTable = isInsideTable(destType);
46
46
  var destTypeInDocOrLayoutCol = [doc, layoutColumn].includes(destType);
47
47
 
48
- // No need to loop over slice content if destination requires no transformations
49
- if (!destTypeInTable && !destTypeInDocOrLayoutCol) {
48
+ // Only run transformation loop if destination may need node conversions:
49
+ // - Table destinations may need expand → nestedExpand
50
+ // - Doc/layoutColumn destinations may need nestedExpand → expand
51
+ // - When panel_c1 experiment is on:
52
+ // - Expand/table/bodied extension destinations may need panel_c1 → panel downgrade
53
+ // - Doc/layoutColumn destinations may need panel → panel_c1 upgrade
54
+ var needsTransformCheck = destTypeInTable || destTypeInDocOrLayoutCol || expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true);
55
+ if (!needsTransformCheck) {
50
56
  return nodeCopy;
51
57
  }
52
58
  var containsExpand = false;
53
59
  var containsNestedExpand = false;
60
+ // Track variant nodes (e.g. panel_c1) and their base forms (e.g. panel).
61
+ // Uses getBaseNodeTypeName to auto-detect variants — new variants only need
62
+ // to be added to variantToBaseNameMap, no changes needed in the detection loop.
63
+ var variantType = null;
64
+ var baseOfVariantType = null;
54
65
  for (var i = 0; i < nodeCopy.content.childCount; i++) {
55
66
  var node = nodeCopy.content.child(i);
56
67
  if (node.type === schema.nodes.expand) {
@@ -58,7 +69,15 @@ function transformSourceSlice(nodeCopy, destType) {
58
69
  } else if (node.type === schema.nodes.nestedExpand) {
59
70
  containsNestedExpand = true;
60
71
  }
61
- if (containsExpand && containsNestedExpand) {
72
+ if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
73
+ var baseName = getBaseNodeTypeName(node.type);
74
+ if (baseName !== node.type.name) {
75
+ variantType = node.type.name;
76
+ } else if (schema.nodes["".concat(baseName, "_c1")]) {
77
+ baseOfVariantType = node.type.name;
78
+ }
79
+ }
80
+ if (containsExpand && containsNestedExpand && (variantType || baseOfVariantType)) {
62
81
  break;
63
82
  }
64
83
  }
@@ -67,6 +86,26 @@ function transformSourceSlice(nodeCopy, destType) {
67
86
  } else if (containsNestedExpand && destTypeInDocOrLayoutCol) {
68
87
  return transformSliceNestedExpandToExpand(nodeCopy, schema);
69
88
  }
89
+
90
+ // Downgrade variant → base (e.g. panel_c1 → panel) when dest doesn't support the variant
91
+ if (variantType && schema.nodes[variantType]) {
92
+ var destParent = destType.createAndFill();
93
+ if (destParent && !isNodeTypeValidChildOf(variantType, destParent, schema)) {
94
+ var _baseName = getBaseNodeTypeName(schema.nodes[variantType]);
95
+ return transformSliceNodeType(nodeCopy, schema, variantType, _baseName);
96
+ }
97
+ }
98
+
99
+ // Upgrade base → variant (e.g. panel → panel_c1) when dest supports the variant
100
+ if (baseOfVariantType) {
101
+ var variantName = "".concat(baseOfVariantType, "_c1");
102
+ if (schema.nodes[variantName]) {
103
+ var _destParent = destType.createAndFill();
104
+ if (_destParent && isNodeTypeValidChildOf(variantName, _destParent, schema)) {
105
+ return transformSliceNodeType(nodeCopy, schema, baseOfVariantType, variantName);
106
+ }
107
+ }
108
+ }
70
109
  return nodeCopy;
71
110
  }
72
111
  var nodesSupportDragLayoutColumnInto = ['tableCell', 'tableHeader', 'panel', 'expand', 'nestedExpand'];
@@ -4,6 +4,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  import ReactDOM from 'react-dom';
5
5
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
6
6
  import uuid from 'uuid';
7
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
7
8
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
8
9
  import { isFontSizeMarkActive } from './utils/validation';
9
10
  export var TYPE_DROP_TARGET_DEC = 'drop-target-decoration';
@@ -25,7 +26,8 @@ var getSubType = function getSubType(node) {
25
26
  };
26
27
  export var getNodeTypeWithLevel = function getNodeTypeWithLevel(node) {
27
28
  var subType = expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getSubType(node) : node.attrs.level ? "-".concat(node.attrs.level) : '';
28
- return node.type.name + subType;
29
+ var typeName = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? getBaseNodeTypeName(node.type) : node.type.name;
30
+ return typeName + subType;
29
31
  };
30
32
  var ObjHash = /*#__PURE__*/function () {
31
33
  function ObjHash() {
@@ -2,6 +2,7 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import memoizeOne from 'memoize-one';
3
3
  import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
4
4
  import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
5
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
5
6
  import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
6
7
  import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -27,7 +28,8 @@ var getContainerNodeTypes = memoizeOne(function () {
27
28
  return [].concat(PARENT_WITH_END_DROP_TARGET, _toConsumableArray(fg('confluence_frontend_native_tabs_extension') ? ['multiBodiedExtension'] : []), _toConsumableArray(editorExperiment('platform_synced_block', true) ? ['bodiedSyncBlock'] : []));
28
29
  });
29
30
  var isContainerNode = function isContainerNode(node) {
30
- return getContainerNodeTypes().includes(node.type.name);
31
+ var nodeName = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? getBaseNodeTypeName(node.type) : node.type.name;
32
+ return getContainerNodeTypes().includes(nodeName);
31
33
  };
32
34
  export var canMoveNodeOrSliceToPos = function canMoveNodeOrSliceToPos(state, node, parent, index, $toPos, activeNode) {
33
35
  // For deciding to show drop targets or not when multiple nodes are selected
@@ -1,5 +1,6 @@
1
1
  import memoizeOne from 'memoize-one';
2
2
  import { getParentOfTypeCount, isNestedTablesSupported } from '@atlaskit/editor-common/nesting';
3
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
3
4
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
4
5
  import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
5
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -69,6 +70,41 @@ export var transformFragmentExpandToNestedExpand = function transformFragmentExp
69
70
  }
70
71
  return Fragment.fromArray(children);
71
72
  };
73
+
74
+ /**
75
+ * Generic fragment transformer — converts all nodes of `fromType` to `toType`,
76
+ * preserving attrs, content, and marks.
77
+ */
78
+ export var transformFragmentNodeType = function transformFragmentNodeType(fragment, schema, fromType, toType) {
79
+ var children = [];
80
+ var targetType = schema.nodes[toType];
81
+ if (!targetType) {
82
+ return null;
83
+ }
84
+ try {
85
+ fragment.forEach(function (node) {
86
+ if (node.type.name === fromType) {
87
+ children.push(targetType.create(node.attrs, node.content, node.marks));
88
+ } else {
89
+ children.push(node);
90
+ }
91
+ });
92
+ } catch (e) {
93
+ return null;
94
+ }
95
+ return Fragment.fromArray(children);
96
+ };
97
+
98
+ /**
99
+ * Generic slice transformer — converts all nodes of `fromType` to `toType`.
100
+ */
101
+ export var transformSliceNodeType = function transformSliceNodeType(slice, schema, fromType, toType) {
102
+ var fragment = transformFragmentNodeType(slice.content, schema, fromType, toType);
103
+ if (!fragment) {
104
+ return null;
105
+ }
106
+ return new Slice(fragment, slice.openStart, slice.openEnd);
107
+ };
72
108
  export var transformSliceExpandToNestedExpand = function transformSliceExpandToNestedExpand(slice) {
73
109
  var fragment = transformFragmentExpandToNestedExpand(slice.content);
74
110
  if (!fragment) {
@@ -153,6 +189,19 @@ export function canMoveNodeToIndex(destParent, indexIntoParent, srcNode, $destNo
153
189
  } else if ((isDoc(destParent.type) || isLayoutColumn(destParent.type)) && isNestedExpand(srcNodeType)) {
154
190
  srcNodeType = expand;
155
191
  }
192
+
193
+ // Downgrade variant node (e.g. panel_c1 → panel) when dest doesn't support it
194
+ if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
195
+ var baseName = getBaseNodeTypeName(srcNodeType);
196
+ if (baseName !== srcNodeType.name && !destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType)) {
197
+ var baseType = schema.nodes[baseName];
198
+ // Check if the node's content is valid in the base type (e.g. panel with table can't be downgraded)
199
+ if (!baseType || !baseType.validContent(srcNode.content)) {
200
+ return false;
201
+ }
202
+ srcNodeType = baseType;
203
+ }
204
+ }
156
205
  return destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType);
157
206
  }
158
207
  export function canMoveSliceToIndex(slice, sliceFromPos, sliceToPos, destParent, indexIntoParent, $destNodePos, destNode) {
@@ -78,6 +78,37 @@ var buttonWrapperStyles = css({
78
78
  boxSizing: 'border-box'
79
79
  }
80
80
  });
81
+
82
+ // EDITOR-6790 - When the `platform_editor_table_col_insert` experiment is enabled,
83
+ // drop the linear-gradient background that paints over the legacy `tr.sticky` table
84
+ // header so the new left-edge column-insert affordance is not visually clipped.
85
+ // Keep all paddings / margins identical to `buttonWrapperStyles` so the drag-handle
86
+ // layout does not shift between the two variants.
87
+ var buttonWrapperStylesNoBackground = css({
88
+ display: 'flex',
89
+ justifyContent: 'center',
90
+ alignItems: 'center',
91
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
92
+ '[data-blocks-drag-handle-container]:has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
93
+ marginBottom: "var(--ds-space-negative-200, -16px)",
94
+ paddingBottom: "var(--ds-space-200, 16px)",
95
+ marginTop: "var(--ds-space-negative-400, -32px)",
96
+ paddingTop: "calc(".concat("var(--ds-space-400, 32px)", " - 1px)"),
97
+ marginRight: "var(--ds-space-negative-150, -12px)",
98
+ paddingRight: "var(--ds-space-150, 12px)",
99
+ boxSizing: 'border-box'
100
+ },
101
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
102
+ '[data-prosemirror-mark-name="breakout"]:has([data-blocks-drag-handle-container]):has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
103
+ marginBottom: "var(--ds-space-negative-200, -16px)",
104
+ paddingBottom: "var(--ds-space-200, 16px)",
105
+ marginTop: "var(--ds-space-negative-400, -32px)",
106
+ paddingTop: "calc(".concat("var(--ds-space-400, 32px)", " - 1px)"),
107
+ marginRight: "var(--ds-space-negative-150, -12px)",
108
+ paddingRight: "var(--ds-space-150, 12px)",
109
+ boxSizing: 'border-box'
110
+ }
111
+ });
81
112
  var buttonWrapperStylesPatch = css({
82
113
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
83
114
  '[data-blocks-drag-handle-container]:has(+ [data-prosemirror-node-name="table"] .pm-table-with-controls [data-number-column="true"] tr.sticky) &': {
@@ -1088,7 +1119,10 @@ export var DragHandle = function DragHandle(_ref) {
1088
1119
  });
1089
1120
  }
1090
1121
  }, jsx("span", {
1091
- css: [shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && buttonWrapperStyles, buttonWrapperStylesPatch]
1122
+ css: [shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && (
1123
+ // EDITOR-6790 - drop the masking background under the new
1124
+ // column-insert experiment so the left-edge dot is not clipped.
1125
+ expValEquals('platform_editor_table_col_insert', 'isEnabled', true) ? buttonWrapperStylesNoBackground : buttonWrapperStyles), buttonWrapperStylesPatch]
1092
1126
  }, renderButton()))));
1093
1127
  };
1094
1128
  var stickyWithoutTooltip = function stickyWithoutTooltip() {
@@ -1104,7 +1138,10 @@ export var DragHandle = function DragHandle(_ref) {
1104
1138
  }, jsx("span", {
1105
1139
  css: [tooltipContainerStyles, shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithMask, !shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithoutMask]
1106
1140
  }, jsx("span", {
1107
- css: [shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && buttonWrapperStyles, buttonWrapperStylesPatch]
1141
+ css: [shouldMaskNodeControls(nodeType, isTopLevelNodeValue) && (
1142
+ // EDITOR-6790 - drop the masking background under the new
1143
+ // column-insert experiment so the left-edge dot is not clipped.
1144
+ expValEquals('platform_editor_table_col_insert', 'isEnabled', true) ? buttonWrapperStylesNoBackground : buttonWrapperStyles), buttonWrapperStylesPatch]
1108
1145
  }, renderButton())));
1109
1146
  };
1110
1147
  var buttonWithTooltip = function buttonWithTooltip() {
@@ -9,6 +9,7 @@ import { Fragment, useEffect, useMemo, useRef, useState } from 'react';
9
9
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
10
10
  import { css, jsx } from '@emotion/react';
11
11
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
12
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
12
13
  import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
13
14
  import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
14
15
  import { layers } from '@atlaskit/theme/constants';
@@ -223,7 +224,7 @@ export var DropTarget = function DropTarget(props) {
223
224
  };
224
225
  var dynamicStyle = _defineProperty(_defineProperty(_defineProperty({
225
226
  width: isNestedDropTarget ? 'unset' : '100%'
226
- }, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH, isNestedDropTarget ? '100%' : "".concat(lineLength || DEFAULT_DROP_INDICATOR_WIDTH, "px")), EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN, isNestedDropTarget ? getNestedNodeLeftPaddingMargin(parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) : '0'), EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX, layers.navigation());
227
+ }, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH, isNestedDropTarget ? '100%' : "".concat(lineLength || DEFAULT_DROP_INDICATOR_WIDTH, "px")), EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN, isNestedDropTarget ? expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) && parentNode !== null && parentNode !== void 0 && parentNode.type ? getNestedNodeLeftPaddingMargin(getBaseNodeTypeName(parentNode.type)) : getNestedNodeLeftPaddingMargin(parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name) : '0'), EDITOR_BLOCK_CONTROLS_DROP_TARGET_ZINDEX, layers.navigation());
227
228
  var isShowInlineDropTarget = shouldAllowInlineDropTarget(isNestedDropTarget, nextNode, isSameLayout, activeNode, parentNode);
228
229
  return jsx(Fragment, null, jsx(HoverZone
229
230
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
@@ -1,6 +1,5 @@
1
1
  import type { MemoizedFn } from 'memoize-one';
2
- import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
3
- import type { NodeType, Node as PMNode, ResolvedPos } from '@atlaskit/editor-prosemirror/model';
2
+ import { Fragment, Slice, type Schema, type NodeType, type Node as PMNode, type ResolvedPos } from '@atlaskit/editor-prosemirror/model';
4
3
  export declare const isInsideTable: (nodeType: NodeType) => Boolean;
5
4
  export declare const isLayoutColumn: (nodeType: NodeType) => Boolean;
6
5
  export declare const isDoc: (nodeType: NodeType) => Boolean;
@@ -17,6 +16,15 @@ export declare const isInSameLayout: ($from: ResolvedPos, $to: ResolvedPos) => b
17
16
  */
18
17
  export declare const transformExpandToNestedExpand: (expandNode: PMNode) => PMNode | null;
19
18
  export declare const transformFragmentExpandToNestedExpand: (fragment: Fragment) => Fragment | null;
19
+ /**
20
+ * Generic fragment transformer — converts all nodes of `fromType` to `toType`,
21
+ * preserving attrs, content, and marks.
22
+ */
23
+ export declare const transformFragmentNodeType: (fragment: Fragment, schema: Schema, fromType: string, toType: string) => Fragment | null;
24
+ /**
25
+ * Generic slice transformer — converts all nodes of `fromType` to `toType`.
26
+ */
27
+ export declare const transformSliceNodeType: (slice: Slice, schema: Schema, fromType: string, toType: string) => Slice | null;
20
28
  export declare const transformSliceExpandToNestedExpand: (slice: Slice) => Slice | null;
21
29
  export declare const memoizedTransformExpandToNestedExpand: MemoizedFn<(node: PMNode) => PMNode | null>;
22
30
  export declare const canCreateNodeWithContentInsideAnotherNode: (nodeTypesToCreate: NodeType[], nodeWithTargetFragment: Fragment) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "13.0.4",
3
+ "version": "13.0.6",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -21,7 +21,7 @@
21
21
  "atlaskit:src": "src/index.ts",
22
22
  "dependencies": {
23
23
  "@atlaskit/browser-apis": "^1.0.0",
24
- "@atlaskit/button": "^24.0.0",
24
+ "@atlaskit/button": "^24.1.0",
25
25
  "@atlaskit/editor-plugin-accessibility-utils": "^12.0.0",
26
26
  "@atlaskit/editor-plugin-analytics": "^12.0.0",
27
27
  "@atlaskit/editor-plugin-editor-disabled": "^12.0.0",
@@ -48,7 +48,7 @@
48
48
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^4.0.0",
49
49
  "@atlaskit/primitives": "^20.0.0",
50
50
  "@atlaskit/theme": "^26.0.0",
51
- "@atlaskit/tmp-editor-statsig": "^108.0.0",
51
+ "@atlaskit/tmp-editor-statsig": "^109.1.0",
52
52
  "@atlaskit/tokens": "^14.0.0",
53
53
  "@atlaskit/tooltip": "^23.0.0",
54
54
  "@babel/runtime": "^7.0.0",
@@ -59,7 +59,7 @@
59
59
  "uuid": "^3.1.0"
60
60
  },
61
61
  "peerDependencies": {
62
- "@atlaskit/editor-common": "^116.3.0",
62
+ "@atlaskit/editor-common": "^116.8.0",
63
63
  "react": "^18.2.0",
64
64
  "react-dom": "^18.2.0",
65
65
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"