@atlaskit/editor-plugin-block-menu 5.2.17 → 5.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cjs/blockMenuPlugin.js +2 -2
  3. package/dist/cjs/editor-commands/transform-node-utils/flattenStep.js +18 -8
  4. package/dist/cjs/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.js +50 -0
  5. package/dist/cjs/editor-commands/transform-node-utils/steps/flattenListStep.js +12 -2
  6. package/dist/cjs/editor-commands/transform-node-utils/steps/unwrapListStep.js +10 -2
  7. package/dist/cjs/editor-commands/transform-node-utils/transform.js +14 -5
  8. package/dist/cjs/editor-commands/transformNode.js +3 -2
  9. package/dist/cjs/editor-commands/transforms/utils.js +3 -1
  10. package/dist/es2019/blockMenuPlugin.js +2 -2
  11. package/dist/es2019/editor-commands/transform-node-utils/flattenStep.js +16 -6
  12. package/dist/es2019/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.js +46 -0
  13. package/dist/es2019/editor-commands/transform-node-utils/steps/flattenListStep.js +12 -2
  14. package/dist/es2019/editor-commands/transform-node-utils/steps/unwrapListStep.js +10 -2
  15. package/dist/es2019/editor-commands/transform-node-utils/transform.js +14 -5
  16. package/dist/es2019/editor-commands/transformNode.js +3 -2
  17. package/dist/es2019/editor-commands/transforms/utils.js +3 -1
  18. package/dist/esm/blockMenuPlugin.js +2 -2
  19. package/dist/esm/editor-commands/transform-node-utils/flattenStep.js +18 -8
  20. package/dist/esm/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.js +44 -0
  21. package/dist/esm/editor-commands/transform-node-utils/steps/flattenListStep.js +12 -2
  22. package/dist/esm/editor-commands/transform-node-utils/steps/unwrapListStep.js +10 -2
  23. package/dist/esm/editor-commands/transform-node-utils/transform.js +14 -5
  24. package/dist/esm/editor-commands/transformNode.js +3 -2
  25. package/dist/esm/editor-commands/transforms/utils.js +3 -1
  26. package/dist/types/blockMenuPluginType.d.ts +2 -2
  27. package/dist/types/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.d.ts +20 -0
  28. package/dist/types/editor-commands/transform-node-utils/steps/unwrapListStep.d.ts +3 -0
  29. package/dist/types/editor-commands/transform-node-utils/transform.d.ts +2 -1
  30. package/dist/types/editor-commands/transform-node-utils/types.d.ts +1 -0
  31. package/dist/types/editor-commands/transformNode.d.ts +2 -2
  32. package/dist/types/editor-commands/transforms/types.d.ts +2 -1
  33. package/dist/types/index.d.ts +1 -0
  34. package/dist/types-ts4.5/blockMenuPluginType.d.ts +2 -2
  35. package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/applyTargetTextTypeStep.d.ts +20 -0
  36. package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/unwrapListStep.d.ts +3 -0
  37. package/dist/types-ts4.5/editor-commands/transform-node-utils/transform.d.ts +2 -1
  38. package/dist/types-ts4.5/editor-commands/transform-node-utils/types.d.ts +1 -0
  39. package/dist/types-ts4.5/editor-commands/transformNode.d.ts +2 -2
  40. package/dist/types-ts4.5/editor-commands/transforms/types.d.ts +2 -1
  41. package/dist/types-ts4.5/index.d.ts +1 -0
  42. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @atlaskit/editor-plugin-block-menu
2
2
 
3
+ ## 5.2.18
4
+
5
+ ### Patch Changes
6
+
7
+ - [`bfb0acc5f3d72`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bfb0acc5f3d72) -
8
+ [ux] Update list flattening steps to handle decision lists as well
9
+ - [`a528ea956ce65`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a528ea956ce65) -
10
+ [ux] EDITOR-3956 fix sync block resize handle padding and alignment
11
+ - Updated dependencies
12
+
3
13
  ## 5.2.17
4
14
 
5
15
  ### Patch Changes
@@ -42,8 +42,8 @@ var blockMenuPlugin = exports.blockMenuPlugin = function blockMenuPlugin(_ref) {
42
42
  formatNode: function formatNode(targetType, analyticsAttrs) {
43
43
  return (0, _formatNode2.formatNode)(api)(targetType, analyticsAttrs);
44
44
  },
45
- transformNode: function transformNode(targetType, analyticsAttrs) {
46
- return (0, _transformNode2.transformNode)(api)(targetType, analyticsAttrs);
45
+ transformNode: function transformNode(targetType, metadata) {
46
+ return (0, _transformNode2.transformNode)(api)(targetType, metadata);
47
47
  }
48
48
  },
49
49
  getSharedState: function getSharedState(editorState) {
@@ -7,15 +7,25 @@ exports.flattenStep = void 0;
7
7
  var flattenStep = exports.flattenStep = function flattenStep(nodes, context) {
8
8
  var schema = context.schema,
9
9
  targetNodeTypeName = context.targetNodeTypeName;
10
+ var targetNodeType = schema.nodes[targetNodeTypeName];
11
+ if (!targetNodeType) {
12
+ return nodes;
13
+ }
10
14
 
11
15
  // TODO: EDITOR-2920 - Implement flattening logic.
12
- // This is a simplified preliminary approach. We might want to use prosemirror-markdown functions.
13
- var codeBlockContent = nodes.map(function (node) {
14
- return node.content.textBetween(0, node.content.size, '\n');
15
- }).join('\n');
16
- var outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, schema.text(codeBlockContent));
17
- if (!outputNode) {
18
- return nodes;
16
+ var isTargetCodeBlock = targetNodeTypeName === 'codeBlock';
17
+ if (isTargetCodeBlock) {
18
+ // This strips explicitly text nodes
19
+ var codeBlockContent = nodes.map(function (node) {
20
+ return node.content.textBetween(0, node.content.size, '\n');
21
+ }).join('\n');
22
+ return [schema.nodes.codeBlock.create({}, schema.text(codeBlockContent))];
19
23
  }
20
- return [outputNode];
24
+ return nodes.map(function (node) {
25
+ var isValidWithin = targetNodeType.validContent(node.content);
26
+ if (!isValidWithin) {
27
+ return node;
28
+ }
29
+ return schema.nodes.paragraph.create({}, node.content);
30
+ });
21
31
  };
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.applyTargetTextTypeStep = void 0;
7
+ /**
8
+ * Applies target text type conversion. If the target type is a heading, converts textblock nodes
9
+ * (paragraphs, headings) to heading nodes with the specified level. Otherwise, leaves nodes unchanged.
10
+ * Non-textblock nodes are always left unchanged.
11
+ *
12
+ * @example
13
+ * Input:
14
+ * - paragraph "Heading 1"
15
+ * - paragraph "Heading 2"
16
+ *
17
+ * Output (with target: heading, level: 2):
18
+ * - heading (level: 2) "Heading 1"
19
+ * - heading (level: 2) "Heading 2"
20
+ *
21
+ * @param nodes
22
+ * @param context
23
+ * @returns
24
+ */
25
+ var applyTargetTextTypeStep = exports.applyTargetTextTypeStep = function applyTargetTextTypeStep(nodes, context) {
26
+ var schema = context.schema,
27
+ targetNodeTypeName = context.targetNodeTypeName,
28
+ targetAttrs = context.targetAttrs;
29
+ if (targetNodeTypeName !== 'heading') {
30
+ return nodes;
31
+ }
32
+ var headingType = schema.nodes.heading;
33
+ if (!headingType) {
34
+ return nodes;
35
+ }
36
+
37
+ // Default to level 1 if no level is specified
38
+ // The level should ideally come from targetAttrs, but if not available, use default
39
+ var headingLevel = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
40
+ return nodes.map(function (node) {
41
+ if (node.isTextblock) {
42
+ // Convert textblock nodes (paragraphs, headings) to heading with specified level
43
+ return headingType.create({
44
+ level: headingLevel
45
+ }, node.content);
46
+ }
47
+ // Non-textblock nodes are left unchanged
48
+ return node;
49
+ });
50
+ };
@@ -9,7 +9,7 @@ var _nodeChecks = require("../nodeChecks");
9
9
  var extractNestedLists = function extractNestedLists(node, schema) {
10
10
  var items = [];
11
11
  var paragraph = schema.nodes.paragraph;
12
- var itemTypes = [schema.nodes.listItem, schema.nodes.taskItem];
12
+ var itemTypes = [schema.nodes.listItem, schema.nodes.taskItem, schema.nodes.decisionItem];
13
13
  var _extract = function extract(currentNode) {
14
14
  currentNode.forEach(function (child) {
15
15
  if (itemTypes.some(function (type) {
@@ -17,11 +17,21 @@ var extractNestedLists = function extractNestedLists(node, schema) {
17
17
  })) {
18
18
  var contentWithoutNestedLists = [];
19
19
  var nestedLists = [];
20
+
21
+ // Check if this item type expects inline content (taskItem, decisionItem)
22
+ // vs block content (listItem) based on the schema definition
23
+ var isInlineItem = child.type.inlineContent;
20
24
  child.forEach(function (grandChild) {
21
25
  if ((0, _nodeChecks.isListWithIndentation)(grandChild.type.name, schema)) {
22
26
  nestedLists.push(grandChild);
23
27
  } else if (grandChild.isText) {
24
- contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
28
+ // For taskItem/decisionItem, keep text as-is (they support inline content)
29
+ // For listItem, wrap text in paragraph (they require block content)
30
+ if (isInlineItem) {
31
+ contentWithoutNestedLists.push(grandChild);
32
+ } else {
33
+ contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
34
+ }
25
35
  } else {
26
36
  contentWithoutNestedLists.push(grandChild);
27
37
  }
@@ -10,6 +10,9 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
10
10
  * Given an array of nodes, processes each list removing all parent list nodes and
11
11
  * just returning their child contents.
12
12
  *
13
+ * For lists with block content (bulletList, orderedList), it extracts the block nodes directly.
14
+ * For lists with inline content (taskList, decisionList), it wraps the content in paragraphs.
15
+ *
13
16
  * @example
14
17
  * Input:
15
18
  * - bulletList
@@ -27,14 +30,19 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
27
30
  * @returns
28
31
  */
29
32
  var unwrapListStep = exports.unwrapListStep = function unwrapListStep(nodes, context) {
30
- var listTypes = [context.schema.nodes.bulletList, context.schema.nodes.orderedList, context.schema.nodes.taskList];
33
+ var listTypes = [context.schema.nodes.bulletList, context.schema.nodes.orderedList, context.schema.nodes.taskList, context.schema.nodes.decisionList];
31
34
  return nodes.flatMap(function (node) {
32
35
  if (listTypes.some(function (type) {
33
36
  return node.type === type;
34
37
  })) {
35
38
  var listItems = [];
36
39
  node.forEach(function (listItem) {
37
- listItems.push.apply(listItems, (0, _toConsumableArray2.default)(listItem.children));
40
+ // if isTaskItem or isDecisionItem, convert to paragraph
41
+ if (listItem.type.name === 'taskItem' || listItem.type.name === 'decisionItem') {
42
+ listItems.push(context.schema.nodes.paragraph.create({}, listItem.content));
43
+ } else {
44
+ listItems.push.apply(listItems, (0, _toConsumableArray2.default)(listItem.children));
45
+ }
38
46
  });
39
47
  return listItems;
40
48
  }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getOutputNodes = void 0;
7
7
  var _utils = require("../transform-node-utils/utils");
8
8
  var _flattenStep = require("./flattenStep");
9
+ var _applyTargetTextTypeStep = require("./steps/applyTargetTextTypeStep");
9
10
  var _decisionListToListStep = require("./steps/decisionListToListStep");
10
11
  var _flattenListStep = require("./steps/flattenListStep");
11
12
  var _listToDecisionListStep = require("./steps/listToDecisionListStep");
@@ -34,19 +35,19 @@ var TRANSFORM_STEPS = {
34
35
  atomic: undefined,
35
36
  container: [_unwrapStep.unwrapStep, _wrapStep.wrapStep],
36
37
  list: undefined,
37
- text: [_unwrapStep.unwrapStep]
38
+ text: [_unwrapStep.unwrapStep, _applyTargetTextTypeStep.applyTargetTextTypeStep]
38
39
  },
39
40
  list: {
40
41
  atomic: undefined,
41
42
  container: [_wrapStep.wrapStep],
42
43
  list: [_listToListStep.listToListStep],
43
- text: [_flattenListStep.flattenListStep, _unwrapListStep.unwrapListStep]
44
+ text: [_flattenListStep.flattenListStep, _unwrapListStep.unwrapListStep, _applyTargetTextTypeStep.applyTargetTextTypeStep]
44
45
  },
45
46
  text: {
46
47
  atomic: undefined,
47
48
  container: [_wrapStep.wrapStep],
48
49
  list: [_wrapIntoListStep.wrapIntoListStep],
49
- text: [_stubStep.stubStep]
50
+ text: [_flattenStep.flattenStep, _applyTargetTextTypeStep.applyTargetTextTypeStep]
50
51
  }
51
52
  };
52
53
 
@@ -135,6 +136,12 @@ var TRANSFORM_STEPS_OVERRIDE = {
135
136
  },
136
137
  embedCard: {
137
138
  layoutSection: [_wrapIntoLayoutStep.wrapIntoLayoutStep]
139
+ },
140
+ extension: {
141
+ layoutSection: [_wrapIntoLayoutStep.wrapIntoLayoutStep]
142
+ },
143
+ bodiedExtension: {
144
+ layoutSection: [_wrapIntoLayoutStep.wrapIntoLayoutStep]
138
145
  }
139
146
  };
140
147
  var getTransformStepsForNodeTypes = function getTransformStepsForNodeTypes(selectedNodeTypeName, targetNodeTypeName) {
@@ -149,7 +156,8 @@ var getOutputNodes = exports.getOutputNodes = function getOutputNodes(_ref) {
149
156
  var sourceNode = _ref.sourceNode,
150
157
  targetNodeType = _ref.targetNodeType,
151
158
  schema = _ref.schema,
152
- isNested = _ref.isNested;
159
+ isNested = _ref.isNested,
160
+ targetAttrs = _ref.targetAttrs;
153
161
  var nodesToReplace = [sourceNode];
154
162
  var selectedNodeTypeName = (0, _types.toNodeTypeValue)(sourceNode.type.name);
155
163
  var initialTargetNodeTypeName = (0, _types.toNodeTypeValue)(targetNodeType.name);
@@ -162,7 +170,8 @@ var getOutputNodes = exports.getOutputNodes = function getOutputNodes(_ref) {
162
170
  var context = {
163
171
  fromNode: sourceNode,
164
172
  targetNodeTypeName: targetNodeTypeName,
165
- schema: schema
173
+ schema: schema,
174
+ targetAttrs: targetAttrs
166
175
  };
167
176
  if (!steps || steps.length === 0) {
168
177
  return;
@@ -13,7 +13,7 @@ var _utils = require("./transforms/utils");
13
13
  var transformNode = exports.transformNode = function transformNode(api) {
14
14
  return (
15
15
  // eslint-disable-next-line no-unused-vars
16
- function (targetType, analyticsAttrs) {
16
+ function (targetType, metadata) {
17
17
  return function (_ref) {
18
18
  var _api$blockControls;
19
19
  var tr = _ref.tr;
@@ -37,7 +37,8 @@ var transformNode = exports.transformNode = function transformNode(api) {
37
37
  sourceNode: node,
38
38
  targetNodeType: targetType,
39
39
  schema: tr.doc.type.schema,
40
- isNested: isNestedExceptLayout
40
+ isNested: isNestedExceptLayout,
41
+ targetAttrs: metadata === null || metadata === void 0 ? void 0 : metadata.targetAttrs
41
42
  });
42
43
  if (outputNode) {
43
44
  fragment = fragment.append(_model.Fragment.fromArray(outputNode));
@@ -6,7 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.isListNodeType = exports.isListNode = exports.isLayoutNodeType = exports.isLayoutNode = exports.isHeadingOrParagraphNode = exports.isContainerNodeType = exports.isContainerNode = exports.isBlockNodeType = exports.isBlockNodeForExtraction = exports.isBlockNode = exports.getTargetNodeInfo = exports.getMarksWithBreakout = exports.getConversionType = exports.getContentSupportChecker = exports.filterMarksForTargetNodeType = exports.convertNodeToInlineContent = exports.convertCodeBlockContentToParagraphs = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _utils = require("@atlaskit/editor-common/utils");
9
10
  var _model = require("@atlaskit/editor-prosemirror/model");
11
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
10
12
  var getTargetNodeInfo = exports.getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
11
13
  switch (targetType) {
12
14
  case 'heading1':
@@ -206,7 +208,7 @@ var convertCodeBlockContentToParagraphs = exports.convertCodeBlockContentToParag
206
208
  return paragraphNodes;
207
209
  };
208
210
  var isBreakoutMarkSupported = function isBreakoutMarkSupported(nodeType) {
209
- return ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
211
+ return (0, _experiments.editorExperiment)('platform_synced_block', true) ? _utils.breakoutResizableNodes.includes(nodeType.name) : ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
210
212
  };
211
213
  var getMarksWithBreakout = exports.getMarksWithBreakout = function getMarksWithBreakout(sourceNode, targetNodeType) {
212
214
  var allowedMarks = targetNodeType.allowedMarks(sourceNode.marks);
@@ -36,8 +36,8 @@ export const blockMenuPlugin = ({
36
36
  formatNode: (targetType, analyticsAttrs) => {
37
37
  return formatNode(api)(targetType, analyticsAttrs);
38
38
  },
39
- transformNode: (targetType, analyticsAttrs) => {
40
- return transformNode(api)(targetType, analyticsAttrs);
39
+ transformNode: (targetType, metadata) => {
40
+ return transformNode(api)(targetType, metadata);
41
41
  }
42
42
  },
43
43
  getSharedState(editorState) {
@@ -3,13 +3,23 @@ export const flattenStep = (nodes, context) => {
3
3
  schema,
4
4
  targetNodeTypeName
5
5
  } = context;
6
+ const targetNodeType = schema.nodes[targetNodeTypeName];
7
+ if (!targetNodeType) {
8
+ return nodes;
9
+ }
6
10
 
7
11
  // TODO: EDITOR-2920 - Implement flattening logic.
8
- // This is a simplified preliminary approach. We might want to use prosemirror-markdown functions.
9
- const codeBlockContent = nodes.map(node => node.content.textBetween(0, node.content.size, '\n')).join('\n');
10
- const outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, schema.text(codeBlockContent));
11
- if (!outputNode) {
12
- return nodes;
12
+ const isTargetCodeBlock = targetNodeTypeName === 'codeBlock';
13
+ if (isTargetCodeBlock) {
14
+ // This strips explicitly text nodes
15
+ const codeBlockContent = nodes.map(node => node.content.textBetween(0, node.content.size, '\n')).join('\n');
16
+ return [schema.nodes.codeBlock.create({}, schema.text(codeBlockContent))];
13
17
  }
14
- return [outputNode];
18
+ return nodes.map(node => {
19
+ const isValidWithin = targetNodeType.validContent(node.content);
20
+ if (!isValidWithin) {
21
+ return node;
22
+ }
23
+ return schema.nodes.paragraph.create({}, node.content);
24
+ });
15
25
  };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Applies target text type conversion. If the target type is a heading, converts textblock nodes
3
+ * (paragraphs, headings) to heading nodes with the specified level. Otherwise, leaves nodes unchanged.
4
+ * Non-textblock nodes are always left unchanged.
5
+ *
6
+ * @example
7
+ * Input:
8
+ * - paragraph "Heading 1"
9
+ * - paragraph "Heading 2"
10
+ *
11
+ * Output (with target: heading, level: 2):
12
+ * - heading (level: 2) "Heading 1"
13
+ * - heading (level: 2) "Heading 2"
14
+ *
15
+ * @param nodes
16
+ * @param context
17
+ * @returns
18
+ */
19
+ export const applyTargetTextTypeStep = (nodes, context) => {
20
+ const {
21
+ schema,
22
+ targetNodeTypeName,
23
+ targetAttrs
24
+ } = context;
25
+ if (targetNodeTypeName !== 'heading') {
26
+ return nodes;
27
+ }
28
+ const headingType = schema.nodes.heading;
29
+ if (!headingType) {
30
+ return nodes;
31
+ }
32
+
33
+ // Default to level 1 if no level is specified
34
+ // The level should ideally come from targetAttrs, but if not available, use default
35
+ const headingLevel = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
36
+ return nodes.map(node => {
37
+ if (node.isTextblock) {
38
+ // Convert textblock nodes (paragraphs, headings) to heading with specified level
39
+ return headingType.create({
40
+ level: headingLevel
41
+ }, node.content);
42
+ }
43
+ // Non-textblock nodes are left unchanged
44
+ return node;
45
+ });
46
+ };
@@ -3,17 +3,27 @@ import { isListWithIndentation } from '../nodeChecks';
3
3
  const extractNestedLists = (node, schema) => {
4
4
  const items = [];
5
5
  const paragraph = schema.nodes.paragraph;
6
- const itemTypes = [schema.nodes.listItem, schema.nodes.taskItem];
6
+ const itemTypes = [schema.nodes.listItem, schema.nodes.taskItem, schema.nodes.decisionItem];
7
7
  const extract = currentNode => {
8
8
  currentNode.forEach(child => {
9
9
  if (itemTypes.some(type => child.type === type)) {
10
10
  const contentWithoutNestedLists = [];
11
11
  const nestedLists = [];
12
+
13
+ // Check if this item type expects inline content (taskItem, decisionItem)
14
+ // vs block content (listItem) based on the schema definition
15
+ const isInlineItem = child.type.inlineContent;
12
16
  child.forEach(grandChild => {
13
17
  if (isListWithIndentation(grandChild.type.name, schema)) {
14
18
  nestedLists.push(grandChild);
15
19
  } else if (grandChild.isText) {
16
- contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
20
+ // For taskItem/decisionItem, keep text as-is (they support inline content)
21
+ // For listItem, wrap text in paragraph (they require block content)
22
+ if (isInlineItem) {
23
+ contentWithoutNestedLists.push(grandChild);
24
+ } else {
25
+ contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
26
+ }
17
27
  } else {
18
28
  contentWithoutNestedLists.push(grandChild);
19
29
  }
@@ -2,6 +2,9 @@
2
2
  * Given an array of nodes, processes each list removing all parent list nodes and
3
3
  * just returning their child contents.
4
4
  *
5
+ * For lists with block content (bulletList, orderedList), it extracts the block nodes directly.
6
+ * For lists with inline content (taskList, decisionList), it wraps the content in paragraphs.
7
+ *
5
8
  * @example
6
9
  * Input:
7
10
  * - bulletList
@@ -19,12 +22,17 @@
19
22
  * @returns
20
23
  */
21
24
  export const unwrapListStep = (nodes, context) => {
22
- const listTypes = [context.schema.nodes.bulletList, context.schema.nodes.orderedList, context.schema.nodes.taskList];
25
+ const listTypes = [context.schema.nodes.bulletList, context.schema.nodes.orderedList, context.schema.nodes.taskList, context.schema.nodes.decisionList];
23
26
  return nodes.flatMap(node => {
24
27
  if (listTypes.some(type => node.type === type)) {
25
28
  const listItems = [];
26
29
  node.forEach(listItem => {
27
- listItems.push(...listItem.children);
30
+ // if isTaskItem or isDecisionItem, convert to paragraph
31
+ if (listItem.type.name === 'taskItem' || listItem.type.name === 'decisionItem') {
32
+ listItems.push(context.schema.nodes.paragraph.create({}, listItem.content));
33
+ } else {
34
+ listItems.push(...listItem.children);
35
+ }
28
36
  });
29
37
  return listItems;
30
38
  }
@@ -1,5 +1,6 @@
1
1
  import { getTargetNodeTypeNameInContext } from '../transform-node-utils/utils';
2
2
  import { flattenStep } from './flattenStep';
3
+ import { applyTargetTextTypeStep } from './steps/applyTargetTextTypeStep';
3
4
  import { decisionListToListStep } from './steps/decisionListToListStep';
4
5
  import { flattenListStep } from './steps/flattenListStep';
5
6
  import { listToDecisionListStep } from './steps/listToDecisionListStep';
@@ -29,19 +30,19 @@ const TRANSFORM_STEPS = {
29
30
  atomic: undefined,
30
31
  container: [unwrapStep, wrapStep],
31
32
  list: undefined,
32
- text: [unwrapStep]
33
+ text: [unwrapStep, applyTargetTextTypeStep]
33
34
  },
34
35
  list: {
35
36
  atomic: undefined,
36
37
  container: [wrapStep],
37
38
  list: [listToListStep],
38
- text: [flattenListStep, unwrapListStep]
39
+ text: [flattenListStep, unwrapListStep, applyTargetTextTypeStep]
39
40
  },
40
41
  text: {
41
42
  atomic: undefined,
42
43
  container: [wrapStep],
43
44
  list: [wrapIntoListStep],
44
- text: [stubStep]
45
+ text: [flattenStep, applyTargetTextTypeStep]
45
46
  }
46
47
  };
47
48
 
@@ -130,6 +131,12 @@ const TRANSFORM_STEPS_OVERRIDE = {
130
131
  },
131
132
  embedCard: {
132
133
  layoutSection: [wrapIntoLayoutStep]
134
+ },
135
+ extension: {
136
+ layoutSection: [wrapIntoLayoutStep]
137
+ },
138
+ bodiedExtension: {
139
+ layoutSection: [wrapIntoLayoutStep]
133
140
  }
134
141
  };
135
142
  const getTransformStepsForNodeTypes = (selectedNodeTypeName, targetNodeTypeName) => {
@@ -144,7 +151,8 @@ export const getOutputNodes = ({
144
151
  sourceNode,
145
152
  targetNodeType,
146
153
  schema,
147
- isNested
154
+ isNested,
155
+ targetAttrs
148
156
  }) => {
149
157
  const nodesToReplace = [sourceNode];
150
158
  const selectedNodeTypeName = toNodeTypeValue(sourceNode.type.name);
@@ -158,7 +166,8 @@ export const getOutputNodes = ({
158
166
  const context = {
159
167
  fromNode: sourceNode,
160
168
  targetNodeTypeName,
161
- schema
169
+ schema,
170
+ targetAttrs
162
171
  };
163
172
  if (!steps || steps.length === 0) {
164
173
  return;
@@ -6,7 +6,7 @@ import { getOutputNodes } from './transform-node-utils/transform';
6
6
  import { isListNode } from './transforms/utils';
7
7
  export const transformNode = api =>
8
8
  // eslint-disable-next-line no-unused-vars
9
- (targetType, analyticsAttrs) => {
9
+ (targetType, metadata) => {
10
10
  return ({
11
11
  tr
12
12
  }) => {
@@ -34,7 +34,8 @@ export const transformNode = api =>
34
34
  sourceNode: node,
35
35
  targetNodeType: targetType,
36
36
  schema: tr.doc.type.schema,
37
- isNested: isNestedExceptLayout
37
+ isNested: isNestedExceptLayout,
38
+ targetAttrs: metadata === null || metadata === void 0 ? void 0 : metadata.targetAttrs
38
39
  });
39
40
  if (outputNode) {
40
41
  fragment = fragment.append(Fragment.fromArray(outputNode));
@@ -1,4 +1,6 @@
1
+ import { breakoutResizableNodes } from '@atlaskit/editor-common/utils';
1
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
3
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
2
4
  export const getTargetNodeInfo = (targetType, nodes) => {
3
5
  switch (targetType) {
4
6
  case 'heading1':
@@ -198,7 +200,7 @@ export const convertCodeBlockContentToParagraphs = (codeBlockNode, schema) => {
198
200
  return paragraphNodes;
199
201
  };
200
202
  const isBreakoutMarkSupported = nodeType => {
201
- return ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
203
+ return editorExperiment('platform_synced_block', true) ? breakoutResizableNodes.includes(nodeType.name) : ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
202
204
  };
203
205
  export const getMarksWithBreakout = (sourceNode, targetNodeType) => {
204
206
  const allowedMarks = targetNodeType.allowedMarks(sourceNode.marks);
@@ -35,8 +35,8 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
35
35
  formatNode: function formatNode(targetType, analyticsAttrs) {
36
36
  return _formatNode(api)(targetType, analyticsAttrs);
37
37
  },
38
- transformNode: function transformNode(targetType, analyticsAttrs) {
39
- return _transformNode(api)(targetType, analyticsAttrs);
38
+ transformNode: function transformNode(targetType, metadata) {
39
+ return _transformNode(api)(targetType, metadata);
40
40
  }
41
41
  },
42
42
  getSharedState: function getSharedState(editorState) {
@@ -1,15 +1,25 @@
1
1
  export var flattenStep = function flattenStep(nodes, context) {
2
2
  var schema = context.schema,
3
3
  targetNodeTypeName = context.targetNodeTypeName;
4
+ var targetNodeType = schema.nodes[targetNodeTypeName];
5
+ if (!targetNodeType) {
6
+ return nodes;
7
+ }
4
8
 
5
9
  // TODO: EDITOR-2920 - Implement flattening logic.
6
- // This is a simplified preliminary approach. We might want to use prosemirror-markdown functions.
7
- var codeBlockContent = nodes.map(function (node) {
8
- return node.content.textBetween(0, node.content.size, '\n');
9
- }).join('\n');
10
- var outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, schema.text(codeBlockContent));
11
- if (!outputNode) {
12
- return nodes;
10
+ var isTargetCodeBlock = targetNodeTypeName === 'codeBlock';
11
+ if (isTargetCodeBlock) {
12
+ // This strips explicitly text nodes
13
+ var codeBlockContent = nodes.map(function (node) {
14
+ return node.content.textBetween(0, node.content.size, '\n');
15
+ }).join('\n');
16
+ return [schema.nodes.codeBlock.create({}, schema.text(codeBlockContent))];
13
17
  }
14
- return [outputNode];
18
+ return nodes.map(function (node) {
19
+ var isValidWithin = targetNodeType.validContent(node.content);
20
+ if (!isValidWithin) {
21
+ return node;
22
+ }
23
+ return schema.nodes.paragraph.create({}, node.content);
24
+ });
15
25
  };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Applies target text type conversion. If the target type is a heading, converts textblock nodes
3
+ * (paragraphs, headings) to heading nodes with the specified level. Otherwise, leaves nodes unchanged.
4
+ * Non-textblock nodes are always left unchanged.
5
+ *
6
+ * @example
7
+ * Input:
8
+ * - paragraph "Heading 1"
9
+ * - paragraph "Heading 2"
10
+ *
11
+ * Output (with target: heading, level: 2):
12
+ * - heading (level: 2) "Heading 1"
13
+ * - heading (level: 2) "Heading 2"
14
+ *
15
+ * @param nodes
16
+ * @param context
17
+ * @returns
18
+ */
19
+ export var applyTargetTextTypeStep = function applyTargetTextTypeStep(nodes, context) {
20
+ var schema = context.schema,
21
+ targetNodeTypeName = context.targetNodeTypeName,
22
+ targetAttrs = context.targetAttrs;
23
+ if (targetNodeTypeName !== 'heading') {
24
+ return nodes;
25
+ }
26
+ var headingType = schema.nodes.heading;
27
+ if (!headingType) {
28
+ return nodes;
29
+ }
30
+
31
+ // Default to level 1 if no level is specified
32
+ // The level should ideally come from targetAttrs, but if not available, use default
33
+ var headingLevel = typeof (targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level) === 'number' ? targetAttrs.level : 1;
34
+ return nodes.map(function (node) {
35
+ if (node.isTextblock) {
36
+ // Convert textblock nodes (paragraphs, headings) to heading with specified level
37
+ return headingType.create({
38
+ level: headingLevel
39
+ }, node.content);
40
+ }
41
+ // Non-textblock nodes are left unchanged
42
+ return node;
43
+ });
44
+ };
@@ -3,7 +3,7 @@ import { isListWithIndentation } from '../nodeChecks';
3
3
  var extractNestedLists = function extractNestedLists(node, schema) {
4
4
  var items = [];
5
5
  var paragraph = schema.nodes.paragraph;
6
- var itemTypes = [schema.nodes.listItem, schema.nodes.taskItem];
6
+ var itemTypes = [schema.nodes.listItem, schema.nodes.taskItem, schema.nodes.decisionItem];
7
7
  var _extract = function extract(currentNode) {
8
8
  currentNode.forEach(function (child) {
9
9
  if (itemTypes.some(function (type) {
@@ -11,11 +11,21 @@ var extractNestedLists = function extractNestedLists(node, schema) {
11
11
  })) {
12
12
  var contentWithoutNestedLists = [];
13
13
  var nestedLists = [];
14
+
15
+ // Check if this item type expects inline content (taskItem, decisionItem)
16
+ // vs block content (listItem) based on the schema definition
17
+ var isInlineItem = child.type.inlineContent;
14
18
  child.forEach(function (grandChild) {
15
19
  if (isListWithIndentation(grandChild.type.name, schema)) {
16
20
  nestedLists.push(grandChild);
17
21
  } else if (grandChild.isText) {
18
- contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
22
+ // For taskItem/decisionItem, keep text as-is (they support inline content)
23
+ // For listItem, wrap text in paragraph (they require block content)
24
+ if (isInlineItem) {
25
+ contentWithoutNestedLists.push(grandChild);
26
+ } else {
27
+ contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
28
+ }
19
29
  } else {
20
30
  contentWithoutNestedLists.push(grandChild);
21
31
  }
@@ -3,6 +3,9 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
3
  * Given an array of nodes, processes each list removing all parent list nodes and
4
4
  * just returning their child contents.
5
5
  *
6
+ * For lists with block content (bulletList, orderedList), it extracts the block nodes directly.
7
+ * For lists with inline content (taskList, decisionList), it wraps the content in paragraphs.
8
+ *
6
9
  * @example
7
10
  * Input:
8
11
  * - bulletList
@@ -20,14 +23,19 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
20
23
  * @returns
21
24
  */
22
25
  export var unwrapListStep = function unwrapListStep(nodes, context) {
23
- var listTypes = [context.schema.nodes.bulletList, context.schema.nodes.orderedList, context.schema.nodes.taskList];
26
+ var listTypes = [context.schema.nodes.bulletList, context.schema.nodes.orderedList, context.schema.nodes.taskList, context.schema.nodes.decisionList];
24
27
  return nodes.flatMap(function (node) {
25
28
  if (listTypes.some(function (type) {
26
29
  return node.type === type;
27
30
  })) {
28
31
  var listItems = [];
29
32
  node.forEach(function (listItem) {
30
- listItems.push.apply(listItems, _toConsumableArray(listItem.children));
33
+ // if isTaskItem or isDecisionItem, convert to paragraph
34
+ if (listItem.type.name === 'taskItem' || listItem.type.name === 'decisionItem') {
35
+ listItems.push(context.schema.nodes.paragraph.create({}, listItem.content));
36
+ } else {
37
+ listItems.push.apply(listItems, _toConsumableArray(listItem.children));
38
+ }
31
39
  });
32
40
  return listItems;
33
41
  }
@@ -1,5 +1,6 @@
1
1
  import { getTargetNodeTypeNameInContext } from '../transform-node-utils/utils';
2
2
  import { flattenStep } from './flattenStep';
3
+ import { applyTargetTextTypeStep } from './steps/applyTargetTextTypeStep';
3
4
  import { decisionListToListStep } from './steps/decisionListToListStep';
4
5
  import { flattenListStep } from './steps/flattenListStep';
5
6
  import { listToDecisionListStep } from './steps/listToDecisionListStep';
@@ -29,19 +30,19 @@ var TRANSFORM_STEPS = {
29
30
  atomic: undefined,
30
31
  container: [unwrapStep, wrapStep],
31
32
  list: undefined,
32
- text: [unwrapStep]
33
+ text: [unwrapStep, applyTargetTextTypeStep]
33
34
  },
34
35
  list: {
35
36
  atomic: undefined,
36
37
  container: [wrapStep],
37
38
  list: [listToListStep],
38
- text: [flattenListStep, unwrapListStep]
39
+ text: [flattenListStep, unwrapListStep, applyTargetTextTypeStep]
39
40
  },
40
41
  text: {
41
42
  atomic: undefined,
42
43
  container: [wrapStep],
43
44
  list: [wrapIntoListStep],
44
- text: [stubStep]
45
+ text: [flattenStep, applyTargetTextTypeStep]
45
46
  }
46
47
  };
47
48
 
@@ -130,6 +131,12 @@ var TRANSFORM_STEPS_OVERRIDE = {
130
131
  },
131
132
  embedCard: {
132
133
  layoutSection: [wrapIntoLayoutStep]
134
+ },
135
+ extension: {
136
+ layoutSection: [wrapIntoLayoutStep]
137
+ },
138
+ bodiedExtension: {
139
+ layoutSection: [wrapIntoLayoutStep]
133
140
  }
134
141
  };
135
142
  var getTransformStepsForNodeTypes = function getTransformStepsForNodeTypes(selectedNodeTypeName, targetNodeTypeName) {
@@ -144,7 +151,8 @@ export var getOutputNodes = function getOutputNodes(_ref) {
144
151
  var sourceNode = _ref.sourceNode,
145
152
  targetNodeType = _ref.targetNodeType,
146
153
  schema = _ref.schema,
147
- isNested = _ref.isNested;
154
+ isNested = _ref.isNested,
155
+ targetAttrs = _ref.targetAttrs;
148
156
  var nodesToReplace = [sourceNode];
149
157
  var selectedNodeTypeName = toNodeTypeValue(sourceNode.type.name);
150
158
  var initialTargetNodeTypeName = toNodeTypeValue(targetNodeType.name);
@@ -157,7 +165,8 @@ export var getOutputNodes = function getOutputNodes(_ref) {
157
165
  var context = {
158
166
  fromNode: sourceNode,
159
167
  targetNodeTypeName: targetNodeTypeName,
160
- schema: schema
168
+ schema: schema,
169
+ targetAttrs: targetAttrs
161
170
  };
162
171
  if (!steps || steps.length === 0) {
163
172
  return;
@@ -7,7 +7,7 @@ import { isListNode } from './transforms/utils';
7
7
  export var transformNode = function transformNode(api) {
8
8
  return (
9
9
  // eslint-disable-next-line no-unused-vars
10
- function (targetType, analyticsAttrs) {
10
+ function (targetType, metadata) {
11
11
  return function (_ref) {
12
12
  var _api$blockControls;
13
13
  var tr = _ref.tr;
@@ -31,7 +31,8 @@ export var transformNode = function transformNode(api) {
31
31
  sourceNode: node,
32
32
  targetNodeType: targetType,
33
33
  schema: tr.doc.type.schema,
34
- isNested: isNestedExceptLayout
34
+ isNested: isNestedExceptLayout,
35
+ targetAttrs: metadata === null || metadata === void 0 ? void 0 : metadata.targetAttrs
35
36
  });
36
37
  if (outputNode) {
37
38
  fragment = fragment.append(Fragment.fromArray(outputNode));
@@ -1,5 +1,7 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import { breakoutResizableNodes } from '@atlaskit/editor-common/utils';
2
3
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
4
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
3
5
  export var getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
4
6
  switch (targetType) {
5
7
  case 'heading1':
@@ -199,7 +201,7 @@ export var convertCodeBlockContentToParagraphs = function convertCodeBlockConten
199
201
  return paragraphNodes;
200
202
  };
201
203
  var isBreakoutMarkSupported = function isBreakoutMarkSupported(nodeType) {
202
- return ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
204
+ return editorExperiment('platform_synced_block', true) ? breakoutResizableNodes.includes(nodeType.name) : ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
203
205
  };
204
206
  export var getMarksWithBreakout = function getMarksWithBreakout(sourceNode, targetNodeType) {
205
207
  var allowedMarks = targetNodeType.allowedMarks(sourceNode.marks);
@@ -5,12 +5,12 @@ import type { DecorationsPlugin } from '@atlaskit/editor-plugin-decorations';
5
5
  import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection';
6
6
  import type { UserIntentPlugin } from '@atlaskit/editor-plugin-user-intent';
7
7
  import type { NodeType } from '@atlaskit/editor-prosemirror/model';
8
- import type { FormatNodeAnalyticsAttrs, FormatNodeTargetType, TransformNodeAnalyticsAttrs } from './editor-commands/transforms/types';
8
+ import type { FormatNodeAnalyticsAttrs, FormatNodeTargetType, TransformNodeMetadata } from './editor-commands/transforms/types';
9
9
  export declare enum FLAG_ID {
10
10
  LINK_COPIED_TO_CLIPBOARD = "link-copied-to-clipboard"
11
11
  }
12
12
  type FormatNodeCommand = (targetType: FormatNodeTargetType, analyticsAttrs?: FormatNodeAnalyticsAttrs) => EditorCommand;
13
- type TransformNodeCommand = (targetType: NodeType, analyticsAttrs?: TransformNodeAnalyticsAttrs) => EditorCommand;
13
+ type TransformNodeCommand = (targetType: NodeType, metadata?: TransformNodeMetadata) => EditorCommand;
14
14
  export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', {
15
15
  actions: {
16
16
  getBlockMenuComponents: () => Array<RegisterBlockMenuComponent>;
@@ -0,0 +1,20 @@
1
+ import type { TransformStep } from '../types';
2
+ /**
3
+ * Applies target text type conversion. If the target type is a heading, converts textblock nodes
4
+ * (paragraphs, headings) to heading nodes with the specified level. Otherwise, leaves nodes unchanged.
5
+ * Non-textblock nodes are always left unchanged.
6
+ *
7
+ * @example
8
+ * Input:
9
+ * - paragraph "Heading 1"
10
+ * - paragraph "Heading 2"
11
+ *
12
+ * Output (with target: heading, level: 2):
13
+ * - heading (level: 2) "Heading 1"
14
+ * - heading (level: 2) "Heading 2"
15
+ *
16
+ * @param nodes
17
+ * @param context
18
+ * @returns
19
+ */
20
+ export declare const applyTargetTextTypeStep: TransformStep;
@@ -3,6 +3,9 @@ import type { TransformStep } from '../types';
3
3
  * Given an array of nodes, processes each list removing all parent list nodes and
4
4
  * just returning their child contents.
5
5
  *
6
+ * For lists with block content (bulletList, orderedList), it extracts the block nodes directly.
7
+ * For lists with inline content (taskList, decisionList), it wraps the content in paragraphs.
8
+ *
6
9
  * @example
7
10
  * Input:
8
11
  * - bulletList
@@ -3,7 +3,8 @@ interface GetOutputNodesArgs {
3
3
  isNested: boolean;
4
4
  schema: Schema;
5
5
  sourceNode: PMNode;
6
+ targetAttrs?: Record<string, unknown>;
6
7
  targetNodeType: NodeType;
7
8
  }
8
- export declare const getOutputNodes: ({ sourceNode, targetNodeType, schema, isNested, }: GetOutputNodesArgs) => PMNode[] | undefined;
9
+ export declare const getOutputNodes: ({ sourceNode, targetNodeType, schema, isNested, targetAttrs, }: GetOutputNodesArgs) => PMNode[] | undefined;
9
10
  export {};
@@ -8,5 +8,6 @@ export type TransformStep = (nodes: PMNode[], context: TransformStepContext) =>
8
8
  export interface TransformStepContext {
9
9
  fromNode: PMNode;
10
10
  schema: Schema;
11
+ targetAttrs?: Record<string, unknown>;
11
12
  targetNodeTypeName: NodeTypeName;
12
13
  }
@@ -1,5 +1,5 @@
1
1
  import type { EditorCommand, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
2
  import { type NodeType } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { BlockMenuPlugin } from '../blockMenuPluginType';
4
- import type { TransformNodeAnalyticsAttrs } from './transforms/types';
5
- export declare const transformNode: (api?: ExtractInjectionAPI<BlockMenuPlugin>) => (targetType: NodeType, analyticsAttrs?: TransformNodeAnalyticsAttrs) => EditorCommand;
4
+ import type { TransformNodeMetadata } from './transforms/types';
5
+ export declare const transformNode: (api?: ExtractInjectionAPI<BlockMenuPlugin>) => (targetType: NodeType, metadata?: TransformNodeMetadata) => EditorCommand;
@@ -7,7 +7,8 @@ export type FormatNodeAnalyticsAttrs = {
7
7
  inputMethod: INPUT_METHOD.BLOCK_MENU;
8
8
  triggeredFrom: INPUT_METHOD.MOUSE | INPUT_METHOD.KEYBOARD;
9
9
  };
10
- export type TransformNodeAnalyticsAttrs = FormatNodeAnalyticsAttrs & {
10
+ export type TransformNodeMetadata = FormatNodeAnalyticsAttrs & {
11
+ targetAttrs?: Record<string, unknown>;
11
12
  targetTypeName: TransfromNodeTargetType;
12
13
  };
13
14
  export type TransformFunction = (context: TransformContext) => Transaction | null;
@@ -1,2 +1,3 @@
1
1
  export { blockMenuPlugin } from './blockMenuPlugin';
2
2
  export type { BlockMenuPlugin, RegisterBlockMenuComponent, Parent, BlockMenuPluginOptions, BlockMenuSharedState, } from './blockMenuPluginType';
3
+ export type { TransformNodeMetadata } from './editor-commands/transforms/types';
@@ -5,12 +5,12 @@ import type { DecorationsPlugin } from '@atlaskit/editor-plugin-decorations';
5
5
  import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection';
6
6
  import type { UserIntentPlugin } from '@atlaskit/editor-plugin-user-intent';
7
7
  import type { NodeType } from '@atlaskit/editor-prosemirror/model';
8
- import type { FormatNodeAnalyticsAttrs, FormatNodeTargetType, TransformNodeAnalyticsAttrs } from './editor-commands/transforms/types';
8
+ import type { FormatNodeAnalyticsAttrs, FormatNodeTargetType, TransformNodeMetadata } from './editor-commands/transforms/types';
9
9
  export declare enum FLAG_ID {
10
10
  LINK_COPIED_TO_CLIPBOARD = "link-copied-to-clipboard"
11
11
  }
12
12
  type FormatNodeCommand = (targetType: FormatNodeTargetType, analyticsAttrs?: FormatNodeAnalyticsAttrs) => EditorCommand;
13
- type TransformNodeCommand = (targetType: NodeType, analyticsAttrs?: TransformNodeAnalyticsAttrs) => EditorCommand;
13
+ type TransformNodeCommand = (targetType: NodeType, metadata?: TransformNodeMetadata) => EditorCommand;
14
14
  export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', {
15
15
  actions: {
16
16
  getBlockMenuComponents: () => Array<RegisterBlockMenuComponent>;
@@ -0,0 +1,20 @@
1
+ import type { TransformStep } from '../types';
2
+ /**
3
+ * Applies target text type conversion. If the target type is a heading, converts textblock nodes
4
+ * (paragraphs, headings) to heading nodes with the specified level. Otherwise, leaves nodes unchanged.
5
+ * Non-textblock nodes are always left unchanged.
6
+ *
7
+ * @example
8
+ * Input:
9
+ * - paragraph "Heading 1"
10
+ * - paragraph "Heading 2"
11
+ *
12
+ * Output (with target: heading, level: 2):
13
+ * - heading (level: 2) "Heading 1"
14
+ * - heading (level: 2) "Heading 2"
15
+ *
16
+ * @param nodes
17
+ * @param context
18
+ * @returns
19
+ */
20
+ export declare const applyTargetTextTypeStep: TransformStep;
@@ -3,6 +3,9 @@ import type { TransformStep } from '../types';
3
3
  * Given an array of nodes, processes each list removing all parent list nodes and
4
4
  * just returning their child contents.
5
5
  *
6
+ * For lists with block content (bulletList, orderedList), it extracts the block nodes directly.
7
+ * For lists with inline content (taskList, decisionList), it wraps the content in paragraphs.
8
+ *
6
9
  * @example
7
10
  * Input:
8
11
  * - bulletList
@@ -3,7 +3,8 @@ interface GetOutputNodesArgs {
3
3
  isNested: boolean;
4
4
  schema: Schema;
5
5
  sourceNode: PMNode;
6
+ targetAttrs?: Record<string, unknown>;
6
7
  targetNodeType: NodeType;
7
8
  }
8
- export declare const getOutputNodes: ({ sourceNode, targetNodeType, schema, isNested, }: GetOutputNodesArgs) => PMNode[] | undefined;
9
+ export declare const getOutputNodes: ({ sourceNode, targetNodeType, schema, isNested, targetAttrs, }: GetOutputNodesArgs) => PMNode[] | undefined;
9
10
  export {};
@@ -8,5 +8,6 @@ export type TransformStep = (nodes: PMNode[], context: TransformStepContext) =>
8
8
  export interface TransformStepContext {
9
9
  fromNode: PMNode;
10
10
  schema: Schema;
11
+ targetAttrs?: Record<string, unknown>;
11
12
  targetNodeTypeName: NodeTypeName;
12
13
  }
@@ -1,5 +1,5 @@
1
1
  import type { EditorCommand, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
2
  import { type NodeType } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { BlockMenuPlugin } from '../blockMenuPluginType';
4
- import type { TransformNodeAnalyticsAttrs } from './transforms/types';
5
- export declare const transformNode: (api?: ExtractInjectionAPI<BlockMenuPlugin>) => (targetType: NodeType, analyticsAttrs?: TransformNodeAnalyticsAttrs) => EditorCommand;
4
+ import type { TransformNodeMetadata } from './transforms/types';
5
+ export declare const transformNode: (api?: ExtractInjectionAPI<BlockMenuPlugin>) => (targetType: NodeType, metadata?: TransformNodeMetadata) => EditorCommand;
@@ -7,7 +7,8 @@ export type FormatNodeAnalyticsAttrs = {
7
7
  inputMethod: INPUT_METHOD.BLOCK_MENU;
8
8
  triggeredFrom: INPUT_METHOD.MOUSE | INPUT_METHOD.KEYBOARD;
9
9
  };
10
- export type TransformNodeAnalyticsAttrs = FormatNodeAnalyticsAttrs & {
10
+ export type TransformNodeMetadata = FormatNodeAnalyticsAttrs & {
11
+ targetAttrs?: Record<string, unknown>;
11
12
  targetTypeName: TransfromNodeTargetType;
12
13
  };
13
14
  export type TransformFunction = (context: TransformContext) => Transaction | null;
@@ -1,2 +1,3 @@
1
1
  export { blockMenuPlugin } from './blockMenuPlugin';
2
2
  export type { BlockMenuPlugin, RegisterBlockMenuComponent, Parent, BlockMenuPluginOptions, BlockMenuSharedState, } from './blockMenuPluginType';
3
+ export type { TransformNodeMetadata } from './editor-commands/transforms/types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "5.2.17",
3
+ "version": "5.2.18",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -44,7 +44,7 @@
44
44
  "@atlaskit/platform-feature-flags": "^1.1.0",
45
45
  "@atlaskit/platform-feature-flags-react": "^0.4.0",
46
46
  "@atlaskit/primitives": "^16.4.0",
47
- "@atlaskit/tmp-editor-statsig": "^15.16.0",
47
+ "@atlaskit/tmp-editor-statsig": "^16.0.0",
48
48
  "@atlaskit/tokens": "^8.6.0",
49
49
  "@babel/runtime": "^7.0.0"
50
50
  },