@atlaskit/editor-plugin-block-menu 5.1.5 → 5.1.7

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 (39) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/editor-commands/transform-node-utils/flattenListStep.js +9 -32
  3. package/dist/cjs/editor-commands/transform-node-utils/steps/unwrapLayoutStep.js +38 -0
  4. package/dist/cjs/editor-commands/transform-node-utils/transform.js +24 -4
  5. package/dist/cjs/editor-commands/transform-node-utils/unwrapExpandStep.js +6 -7
  6. package/dist/cjs/editor-commands/transform-node-utils/unwrapListStep.js +16 -1
  7. package/dist/cjs/editor-commands/transform-node-utils/utils.js +30 -1
  8. package/dist/cjs/editor-commands/transform-node-utils/wrapStep.js +0 -1
  9. package/dist/cjs/editor-commands/transformNode.js +6 -6
  10. package/dist/cjs/ui/utils/suggested-items-rank.js +107 -0
  11. package/dist/es2019/editor-commands/transform-node-utils/flattenListStep.js +9 -32
  12. package/dist/es2019/editor-commands/transform-node-utils/steps/unwrapLayoutStep.js +30 -0
  13. package/dist/es2019/editor-commands/transform-node-utils/transform.js +24 -4
  14. package/dist/es2019/editor-commands/transform-node-utils/unwrapExpandStep.js +8 -7
  15. package/dist/es2019/editor-commands/transform-node-utils/unwrapListStep.js +16 -1
  16. package/dist/es2019/editor-commands/transform-node-utils/utils.js +29 -1
  17. package/dist/es2019/editor-commands/transform-node-utils/wrapStep.js +0 -1
  18. package/dist/es2019/editor-commands/transformNode.js +2 -2
  19. package/dist/es2019/ui/utils/suggested-items-rank.js +223 -0
  20. package/dist/esm/editor-commands/transform-node-utils/flattenListStep.js +9 -32
  21. package/dist/esm/editor-commands/transform-node-utils/steps/unwrapLayoutStep.js +31 -0
  22. package/dist/esm/editor-commands/transform-node-utils/transform.js +24 -4
  23. package/dist/esm/editor-commands/transform-node-utils/unwrapExpandStep.js +7 -7
  24. package/dist/esm/editor-commands/transform-node-utils/unwrapListStep.js +16 -1
  25. package/dist/esm/editor-commands/transform-node-utils/utils.js +30 -1
  26. package/dist/esm/editor-commands/transform-node-utils/wrapStep.js +0 -1
  27. package/dist/esm/editor-commands/transformNode.js +4 -4
  28. package/dist/esm/ui/utils/suggested-items-rank.js +101 -0
  29. package/dist/types/editor-commands/transform-node-utils/flattenListStep.d.ts +0 -18
  30. package/dist/types/editor-commands/transform-node-utils/steps/unwrapLayoutStep.d.ts +14 -0
  31. package/dist/types/editor-commands/transform-node-utils/unwrapListStep.d.ts +16 -1
  32. package/dist/types/editor-commands/transform-node-utils/utils.d.ts +12 -0
  33. package/dist/types/ui/utils/suggested-items-rank.d.ts +81 -0
  34. package/dist/types-ts4.5/editor-commands/transform-node-utils/flattenListStep.d.ts +0 -18
  35. package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/unwrapLayoutStep.d.ts +14 -0
  36. package/dist/types-ts4.5/editor-commands/transform-node-utils/unwrapListStep.d.ts +16 -1
  37. package/dist/types-ts4.5/editor-commands/transform-node-utils/utils.d.ts +12 -0
  38. package/dist/types-ts4.5/ui/utils/suggested-items-rank.d.ts +81 -0
  39. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/editor-plugin-block-menu
2
2
 
3
+ ## 5.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [`65ef204463ce4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/65ef204463ce4) -
8
+ Add predicate param to expandBlockRange, add logic to cater for selection being broken in lists
9
+ - Updated dependencies
10
+
11
+ ## 5.1.6
12
+
13
+ ### Patch Changes
14
+
15
+ - [`a202e97c73f3a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a202e97c73f3a) -
16
+ Adds base transform cases for codeBlock, layout, blockquote.
17
+
3
18
  ## 5.1.5
4
19
 
5
20
  ### Patch Changes
@@ -5,39 +5,34 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.flattenListStep = void 0;
7
7
  var _model = require("@atlaskit/editor-prosemirror/model");
8
- var extractNestedLists = function extractNestedLists(node, listTypes, itemTypes) {
8
+ var extractNestedLists = function extractNestedLists(node, listTypes, itemTypes, schema) {
9
9
  var items = [];
10
+ var paragraph = schema.nodes.paragraph;
10
11
  var _extract = function extract(currentNode) {
11
12
  currentNode.forEach(function (child) {
12
- // list item -> take content without nested lists, then recurse into nested lists
13
13
  if (itemTypes.some(function (type) {
14
14
  return child.type === type;
15
15
  })) {
16
- // Filter out nested list nodes from the list item's content
17
16
  var contentWithoutNestedLists = [];
18
17
  var nestedLists = [];
19
18
  child.forEach(function (grandChild) {
20
19
  if (listTypes.some(function (type) {
21
20
  return grandChild.type === type;
22
21
  })) {
23
- // This is a nested list - collect it for later processing
24
22
  nestedLists.push(grandChild);
25
23
  } else {
26
- // This is regular content (paragraph, etc.) - keep it
27
- contentWithoutNestedLists.push(grandChild);
24
+ if (grandChild.isText) {
25
+ contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
26
+ } else {
27
+ contentWithoutNestedLists.push(grandChild);
28
+ }
28
29
  }
29
30
  });
30
-
31
- // Add the list item with only its non-list content
32
31
  items.push(child.copy(_model.Fragment.from(contentWithoutNestedLists)));
33
-
34
- // Now process nested lists to maintain document order
35
32
  nestedLists.forEach(function (nestedList) {
36
33
  _extract(nestedList);
37
34
  });
38
- }
39
- // lists -> keep operating
40
- else if (listTypes.some(function (type) {
35
+ } else if (listTypes.some(function (type) {
41
36
  return child.type === type;
42
37
  })) {
43
38
  _extract(child);
@@ -53,24 +48,6 @@ var extractNestedLists = function extractNestedLists(node, listTypes, itemTypes)
53
48
  * to it's first ancestor list, maintaining document order.
54
49
  *
55
50
  * @example
56
- * Input:
57
- * - bulletList
58
- * - listItem "A"
59
- * - listItem "B"
60
- * - bulletList
61
- * - listItem "C"
62
- * - listItem "D"
63
- * - listItem "E"
64
- *
65
- * Output:
66
- * - bulletList
67
- * - listItem "A"
68
- * - listItem "B"
69
- * - listItem "C"
70
- * - listItem "D"
71
- * - listItem "E"
72
- *
73
- * @example
74
51
  * Input (deeply nested):
75
52
  * - bulletList
76
53
  * - listItem "1"
@@ -101,7 +78,7 @@ var flattenListStep = exports.flattenListStep = function flattenListStep(nodes,
101
78
  if (listTypes.some(function (type) {
102
79
  return node.type === type;
103
80
  })) {
104
- return node.copy(_model.Fragment.from(extractNestedLists(node, listTypes, [context.schema.nodes.listItem, context.schema.nodes.taskItem])));
81
+ return node.copy(_model.Fragment.from(extractNestedLists(node, listTypes, [context.schema.nodes.listItem, context.schema.nodes.taskItem], context.schema)));
105
82
  }
106
83
  return node;
107
84
  });
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.unwrapLayoutStep = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ /**
10
+ * Unwraps a layoutSection node, extracting content from all columns.
11
+ * Works with any number of columns (2, 3, etc.).
12
+ *
13
+ * Example:
14
+ * layoutSection(
15
+ * layoutColumn(p('a'), p('b')),
16
+ * layoutColumn(p('c')),
17
+ * layoutColumn(p('d'))
18
+ * )
19
+ * → [p('a'), p('b'), p('c'), p('d')]
20
+ */
21
+ var unwrapLayoutStep = exports.unwrapLayoutStep = function unwrapLayoutStep(nodes) {
22
+ var outputNodes = [];
23
+ nodes.forEach(function (node) {
24
+ var isLayoutSection = node.type.name === 'layoutSection';
25
+ if (isLayoutSection) {
26
+ node.children.forEach(function (column) {
27
+ var isLayoutColumn = column.type.name === 'layoutColumn';
28
+ if (isLayoutColumn) {
29
+ outputNodes.push.apply(outputNodes, (0, _toConsumableArray2.default)(column.children));
30
+ }
31
+ });
32
+ }
33
+ });
34
+ if (outputNodes.length === 0) {
35
+ return nodes;
36
+ }
37
+ return outputNodes;
38
+ };
@@ -7,6 +7,7 @@ exports.getOutputNodes = void 0;
7
7
  var _utils = require("../transform-node-utils/utils");
8
8
  var _flattenListStep = require("./flattenListStep");
9
9
  var _flattenStep = require("./flattenStep");
10
+ var _unwrapLayoutStep = require("./steps/unwrapLayoutStep");
10
11
  var _stubStep = require("./stubStep");
11
12
  var _types = require("./types");
12
13
  var _unwrapExpandStep = require("./unwrapExpandStep");
@@ -72,6 +73,26 @@ var TRANSFORM_STEPS_OVERRIDE = {
72
73
  blockquote: [_unwrapExpandStep.unwrapExpandStep, _wrapStep.wrapStep],
73
74
  paragraph: [_unwrapExpandStep.unwrapExpandStep],
74
75
  codeBlock: [_unwrapExpandStep.unwrapExpandStep, _flattenStep.flattenStep, _wrapStep.wrapStep]
76
+ },
77
+ blockquote: {
78
+ expand: [_wrapStep.wrapStep],
79
+ nestedExpand: [_wrapStep.wrapStep],
80
+ layoutSection: [_wrapIntoLayoutStep.wrapIntoLayoutStep],
81
+ codeBlock: [_unwrapStep.unwrapStep, _flattenStep.flattenStep, _wrapStep.wrapStep]
82
+ },
83
+ layoutSection: {
84
+ blockquote: [_unwrapLayoutStep.unwrapLayoutStep, _wrapStep.wrapStep],
85
+ expand: [_unwrapLayoutStep.unwrapLayoutStep, _wrapStep.wrapStep],
86
+ panel: [_unwrapLayoutStep.unwrapLayoutStep, _wrapStep.wrapStep],
87
+ codeBlock: [_unwrapLayoutStep.unwrapLayoutStep, _flattenStep.flattenStep, _wrapStep.wrapStep],
88
+ paragraph: [_unwrapLayoutStep.unwrapLayoutStep]
89
+ },
90
+ codeBlock: {
91
+ blockquote: [_wrapStep.wrapStep],
92
+ expand: [_wrapStep.wrapStep],
93
+ nestedExpand: [_wrapStep.wrapStep],
94
+ layoutSection: [_wrapIntoLayoutStep.wrapIntoLayoutStep],
95
+ panel: [_wrapStep.wrapStep]
75
96
  }
76
97
  };
77
98
  var getTransformStepsForNodeTypes = function getTransformStepsForNodeTypes(selectedNodeTypeName, targetNodeTypeName) {
@@ -89,8 +110,8 @@ var getOutputNodes = exports.getOutputNodes = function getOutputNodes(_ref) {
89
110
  isNested = _ref.isNested;
90
111
  var nodesToReplace = [sourceNode];
91
112
  var selectedNodeTypeName = (0, _types.toNodeTypeValue)(sourceNode.type.name);
92
- var targetNodeTypeName = (0, _types.toNodeTypeValue)(targetNodeType.name);
93
- targetNodeTypeName = (0, _utils.getTargetNodeTypeNameInContext)(targetNodeTypeName, isNested);
113
+ var initialTargetNodeTypeName = (0, _types.toNodeTypeValue)(targetNodeType.name);
114
+ var targetNodeTypeName = (0, _utils.getTargetNodeTypeNameInContext)(initialTargetNodeTypeName, isNested);
94
115
  if (!selectedNodeTypeName || !targetNodeTypeName) {
95
116
  // We may decide to return an empty array or undefined here
96
117
  return;
@@ -105,7 +126,6 @@ var getOutputNodes = exports.getOutputNodes = function getOutputNodes(_ref) {
105
126
  return;
106
127
  }
107
128
  return steps.reduce(function (nodes, step) {
108
- var result = step(nodes, context);
109
- return result;
129
+ return step(nodes, context);
110
130
  }, nodesToReplace);
111
131
  };
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.unwrapExpandStep = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _unwrapStep = require("./unwrapStep");
9
10
  /**
10
11
  * Unwraps an expand/nestedExpand node, converting its title attribute to a paragraph
11
12
  * and prepending it to the children.
@@ -15,8 +16,11 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
15
16
  var unwrapExpandStep = exports.unwrapExpandStep = function unwrapExpandStep(nodes, context) {
16
17
  var schema = context.schema;
17
18
  var outputNodes = [];
19
+ var _schema$nodes = schema.nodes,
20
+ expand = _schema$nodes.expand,
21
+ nestedExpand = _schema$nodes.nestedExpand;
18
22
  nodes.forEach(function (node) {
19
- var isExpand = node.type.name === 'expand' || node.type.name === 'nestedExpand';
23
+ var isExpand = node.type.name === expand.name || node.type.name === nestedExpand.name;
20
24
  if (isExpand) {
21
25
  var _node$attrs;
22
26
  var title = (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.title;
@@ -32,12 +36,7 @@ var unwrapExpandStep = exports.unwrapExpandStep = function unwrapExpandStep(node
32
36
  // Add the children
33
37
  outputNodes.push.apply(outputNodes, (0, _toConsumableArray2.default)(node.children));
34
38
  } else {
35
- // Fallback: behave like unwrapStep for non-expand nodes
36
- if (node.children.length === 0) {
37
- outputNodes.push(node);
38
- } else {
39
- outputNodes.push.apply(outputNodes, (0, _toConsumableArray2.default)(node.children));
40
- }
39
+ (0, _unwrapStep.unwrapStep)([node], context);
41
40
  }
42
41
  });
43
42
  return outputNodes;
@@ -7,8 +7,23 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.unwrapListStep = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
9
  /**
10
- * Given an array of nodes, returns an array with the flattened children of any list nodes.
10
+ * Given an array of nodes, processes each list removing all parent list nodes and
11
+ * just returning their child contents.
12
+ *
13
+ * @example
14
+ * Input:
15
+ * - bulletList
16
+ * - listItem "1"
17
+ * - paragraph "1"
18
+ * - listItem "2"
19
+ * - paragraph "2"
20
+ *
21
+ * Output:
22
+ * - paragraph "1"
23
+ * - paragraph "2"
24
+ *
11
25
  * @param nodes
26
+ * @param context
12
27
  * @returns
13
28
  */
14
29
  var unwrapListStep = exports.unwrapListStep = function unwrapListStep(nodes, context) {
@@ -3,7 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getTargetNodeTypeNameInContext = exports.getSelectedNode = void 0;
6
+ exports.getTargetNodeTypeNameInContext = exports.getSelectedNode = exports.expandSelectionToBlockRange = void 0;
7
+ var _selection = require("@atlaskit/editor-common/selection");
7
8
  var _state = require("@atlaskit/editor-prosemirror/state");
8
9
  var _utils = require("@atlaskit/editor-prosemirror/utils");
9
10
  var _editorTables = require("@atlaskit/editor-tables");
@@ -54,4 +55,32 @@ var getTargetNodeTypeNameInContext = exports.getTargetNodeTypeNameInContext = fu
54
55
  return 'nestedExpand';
55
56
  }
56
57
  return nodeTypeName;
58
+ };
59
+
60
+ /**
61
+ * Use common expandToBlockRange function, but account for edge cases with lists.
62
+ *
63
+ * @param selection
64
+ * @param schema
65
+ * @returns
66
+ */
67
+ var expandSelectionToBlockRange = exports.expandSelectionToBlockRange = function expandSelectionToBlockRange(selection, schema) {
68
+ var isListInSelection = (0, _utils.hasParentNode)(function (node) {
69
+ return node.type === schema.nodes.bulletList || node.type === schema.nodes.orderedList;
70
+ })(selection);
71
+ var _expandToBlockRange = (0, _selection.expandToBlockRange)(selection.$from, selection.$to, function (node) {
72
+ if (!isListInSelection) {
73
+ return true;
74
+ }
75
+ if (node.type === schema.nodes.bulletList || node.type === schema.nodes.orderedList) {
76
+ return true;
77
+ }
78
+ return false;
79
+ }),
80
+ $from = _expandToBlockRange.$from,
81
+ $to = _expandToBlockRange.$to;
82
+ return {
83
+ $from: $from,
84
+ $to: $to
85
+ };
57
86
  };
@@ -7,7 +7,6 @@ exports.wrapStep = void 0;
7
7
  var wrapStep = exports.wrapStep = function wrapStep(nodes, context) {
8
8
  var schema = context.schema,
9
9
  targetNodeTypeName = context.targetNodeTypeName;
10
- // edge case: nestedExpand
11
10
  var outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, nodes);
12
11
  if (outputNode) {
13
12
  return [outputNode];
@@ -4,11 +4,11 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.transformNode = void 0;
7
- var _selection = require("@atlaskit/editor-common/selection");
8
7
  var _model = require("@atlaskit/editor-prosemirror/model");
9
8
  var _isNestedNode = require("../ui/utils/isNestedNode");
10
9
  var _transform = require("./transform-node-utils/transform");
11
- var _utils = require("./transforms/utils");
10
+ var _utils = require("./transform-node-utils/utils");
11
+ var _utils2 = require("./transforms/utils");
12
12
  var transformNode = exports.transformNode = function transformNode(api) {
13
13
  return (
14
14
  // eslint-disable-next-line no-unused-vars
@@ -20,13 +20,13 @@ var transformNode = exports.transformNode = function transformNode(api) {
20
20
  if (!preservedSelection) {
21
21
  return tr;
22
22
  }
23
- var _expandToBlockRange = (0, _selection.expandToBlockRange)(preservedSelection.$from, preservedSelection.$to),
24
- $from = _expandToBlockRange.$from,
25
- $to = _expandToBlockRange.$to;
23
+ var _expandSelectionToBlo = (0, _utils.expandSelectionToBlockRange)(preservedSelection, tr.doc.type.schema),
24
+ $from = _expandSelectionToBlo.$from,
25
+ $to = _expandSelectionToBlo.$to;
26
26
  var isNested = (0, _isNestedNode.isNestedNode)(preservedSelection, '');
27
27
  var selectedParent = $from.parent;
28
28
  var fragment = _model.Fragment.empty;
29
- var isList = (0, _utils.isListNode)(selectedParent);
29
+ var isList = (0, _utils2.isListNode)(selectedParent);
30
30
  var slice = tr.doc.slice(isList ? $from.pos - 1 : $from.pos, isList ? $to.pos + 1 : $to.pos);
31
31
  slice.content.forEach(function (node) {
32
32
  var outputNode = (0, _transform.getOutputNodes)({
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getSuggestedItemsForNodeType = exports.getSortedSuggestedItems = exports.TRANSFORM_SUGGESTED_ITEMS_RANK = exports.BLOCK_MENU_NODE_TYPES = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _blockMenu = require("@atlaskit/editor-common/block-menu");
11
+ var _TRANSFORM_SUGGESTED_;
12
+ /**
13
+ * Suggested transformations mapping for each block type.
14
+ * Based on the Block Menu Compatibility Matrix:
15
+ * https://hello.atlassian.net/wiki/spaces/egcuc/pages/5868774224/Block+Menu+Compatibility+Matrix#Suggested-for-each-block-type
16
+ *
17
+ * This mapping defines which transform items should appear in the TRANSFORM_SUGGESTED_MENU_SECTION
18
+ * for each block type, ranked by priority (lower rank = higher priority).
19
+ *
20
+ * Structure:
21
+ * {
22
+ * [sourceNodeType]: {
23
+ * [targetMenuItemKey]: rank
24
+ * }
25
+ * }
26
+ */
27
+ /**
28
+ * Node type keys that map to ProseMirror node types from the ADF schema.
29
+ * These values must match the NodeTypeName type.
30
+ *
31
+ * TypeScript will enforce that all values are valid NodeTypeName values.
32
+ * If a new node type is added, it must be added to NodeTypeName first.
33
+ *
34
+ * Reference: packages/editor/editor-plugin-block-menu/src/editor-commands/transform-node-utils/types.ts
35
+ *
36
+ * Note: 'heading' represents all heading levels (1-6) as a single node type.
37
+ * The specific level is determined by the node's `attrs.level` property at runtime.
38
+ *
39
+ * @example
40
+ * // Usage:
41
+ * const nodeType = BLOCK_MENU_NODE_TYPES.PARAGRAPH; // Type: "paragraph"
42
+ */
43
+ var BLOCK_MENU_NODE_TYPES = exports.BLOCK_MENU_NODE_TYPES = {
44
+ PARAGRAPH: 'paragraph',
45
+ EXPAND: 'expand',
46
+ BLOCKQUOTE: 'blockquote',
47
+ LAYOUT_SECTION: 'layoutSection',
48
+ PANEL: 'panel',
49
+ CODE_BLOCK: 'codeBlock',
50
+ DECISION: 'decisionList',
51
+ BULLET_LIST: 'bulletList',
52
+ ORDERED_LIST: 'orderedList',
53
+ HEADING: 'heading',
54
+ TASK_LIST: 'taskList',
55
+ MEDIA_SINGLE: 'mediaSingle',
56
+ EXTENSION: 'extension',
57
+ BODIED_EXTENSION: 'bodiedExtension',
58
+ BLOCK_CARD: 'blockCard',
59
+ EMBED_CARD: 'embedCard',
60
+ TABLE: 'table'
61
+ };
62
+
63
+ /**
64
+ * Type for node type values extracted from BLOCK_MENU_NODE_TYPES
65
+ */
66
+
67
+ /**
68
+ * Type for the suggested items rank mapping
69
+ */
70
+
71
+ /**
72
+ * Mapping of source node types to suggested transformation menu items with their ranks.
73
+ * Lower rank number = higher priority in the suggested menu section.
74
+ */
75
+ var TRANSFORM_SUGGESTED_ITEMS_RANK = exports.TRANSFORM_SUGGESTED_ITEMS_RANK = (_TRANSFORM_SUGGESTED_ = {}, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.PARAGRAPH, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_HEADINGS_H2_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_HEADINGS_H3_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXPAND, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BLOCKQUOTE, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.LAYOUT_SECTION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_HEADINGS_H2_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.PANEL, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.CODE_BLOCK, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.DECISION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BULLET_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.ORDERED_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.HEADING, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_HEADINGS_H2_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 300)), (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_TRANSFORM_SUGGESTED_, BLOCK_MENU_NODE_TYPES.TASK_LIST, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.MEDIA_SINGLE, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.EXTENSION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BODIED_EXTENSION, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 200), _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 300)), BLOCK_MENU_NODE_TYPES.BLOCK_CARD, (0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 200)), BLOCK_MENU_NODE_TYPES.EMBED_CARD, (0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key, 200)), BLOCK_MENU_NODE_TYPES.TABLE, (0, _defineProperty2.default)((0, _defineProperty2.default)({}, _blockMenu.TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key, 100), _blockMenu.TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key, 200)));
76
+
77
+ /**
78
+ * Get suggested menu items for a given node type
79
+ * @param nodeType - The source node type (e.g., 'paragraph', 'heading')
80
+ * @returns Object mapping menu item keys to their ranks, or undefined if no suggestions
81
+ */
82
+ var getSuggestedItemsForNodeType = exports.getSuggestedItemsForNodeType = function getSuggestedItemsForNodeType(nodeType) {
83
+ return TRANSFORM_SUGGESTED_ITEMS_RANK[nodeType];
84
+ };
85
+
86
+ /**
87
+ * Get sorted suggested menu item keys for a given node type
88
+ * @param nodeType - The source node type
89
+ * @returns Array of menu item keys sorted by rank (highest priority first)
90
+ */
91
+ var getSortedSuggestedItems = exports.getSortedSuggestedItems = function getSortedSuggestedItems(nodeType) {
92
+ var suggestions = getSuggestedItemsForNodeType(nodeType);
93
+ if (!suggestions) {
94
+ return [];
95
+ }
96
+ return Object.entries(suggestions).sort(function (_ref, _ref2) {
97
+ var _ref3 = (0, _slicedToArray2.default)(_ref, 2),
98
+ rankA = _ref3[1];
99
+ var _ref4 = (0, _slicedToArray2.default)(_ref2, 2),
100
+ rankB = _ref4[1];
101
+ return rankA - rankB;
102
+ }).map(function (_ref5) {
103
+ var _ref6 = (0, _slicedToArray2.default)(_ref5, 1),
104
+ key = _ref6[0];
105
+ return key;
106
+ });
107
+ };
@@ -1,33 +1,28 @@
1
1
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
2
- const extractNestedLists = (node, listTypes, itemTypes) => {
2
+ const extractNestedLists = (node, listTypes, itemTypes, schema) => {
3
3
  const items = [];
4
+ const paragraph = schema.nodes.paragraph;
4
5
  const extract = currentNode => {
5
6
  currentNode.forEach(child => {
6
- // list item -> take content without nested lists, then recurse into nested lists
7
7
  if (itemTypes.some(type => child.type === type)) {
8
- // Filter out nested list nodes from the list item's content
9
8
  const contentWithoutNestedLists = [];
10
9
  const nestedLists = [];
11
10
  child.forEach(grandChild => {
12
11
  if (listTypes.some(type => grandChild.type === type)) {
13
- // This is a nested list - collect it for later processing
14
12
  nestedLists.push(grandChild);
15
13
  } else {
16
- // This is regular content (paragraph, etc.) - keep it
17
- contentWithoutNestedLists.push(grandChild);
14
+ if (grandChild.isText) {
15
+ contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
16
+ } else {
17
+ contentWithoutNestedLists.push(grandChild);
18
+ }
18
19
  }
19
20
  });
20
-
21
- // Add the list item with only its non-list content
22
21
  items.push(child.copy(Fragment.from(contentWithoutNestedLists)));
23
-
24
- // Now process nested lists to maintain document order
25
22
  nestedLists.forEach(nestedList => {
26
23
  extract(nestedList);
27
24
  });
28
- }
29
- // lists -> keep operating
30
- else if (listTypes.some(type => child.type === type)) {
25
+ } else if (listTypes.some(type => child.type === type)) {
31
26
  extract(child);
32
27
  }
33
28
  });
@@ -41,24 +36,6 @@ const extractNestedLists = (node, listTypes, itemTypes) => {
41
36
  * to it's first ancestor list, maintaining document order.
42
37
  *
43
38
  * @example
44
- * Input:
45
- * - bulletList
46
- * - listItem "A"
47
- * - listItem "B"
48
- * - bulletList
49
- * - listItem "C"
50
- * - listItem "D"
51
- * - listItem "E"
52
- *
53
- * Output:
54
- * - bulletList
55
- * - listItem "A"
56
- * - listItem "B"
57
- * - listItem "C"
58
- * - listItem "D"
59
- * - listItem "E"
60
- *
61
- * @example
62
39
  * Input (deeply nested):
63
40
  * - bulletList
64
41
  * - listItem "1"
@@ -87,7 +64,7 @@ export const flattenListStep = (nodes, context) => {
87
64
  const listTypes = [context.schema.nodes.bulletList, context.schema.nodes.orderedList, context.schema.nodes.taskList];
88
65
  return nodes.map(node => {
89
66
  if (listTypes.some(type => node.type === type)) {
90
- return node.copy(Fragment.from(extractNestedLists(node, listTypes, [context.schema.nodes.listItem, context.schema.nodes.taskItem])));
67
+ return node.copy(Fragment.from(extractNestedLists(node, listTypes, [context.schema.nodes.listItem, context.schema.nodes.taskItem], context.schema)));
91
68
  }
92
69
  return node;
93
70
  });
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Unwraps a layoutSection node, extracting content from all columns.
3
+ * Works with any number of columns (2, 3, etc.).
4
+ *
5
+ * Example:
6
+ * layoutSection(
7
+ * layoutColumn(p('a'), p('b')),
8
+ * layoutColumn(p('c')),
9
+ * layoutColumn(p('d'))
10
+ * )
11
+ * → [p('a'), p('b'), p('c'), p('d')]
12
+ */
13
+ export const unwrapLayoutStep = nodes => {
14
+ const outputNodes = [];
15
+ nodes.forEach(node => {
16
+ const isLayoutSection = node.type.name === 'layoutSection';
17
+ if (isLayoutSection) {
18
+ node.children.forEach(column => {
19
+ const isLayoutColumn = column.type.name === 'layoutColumn';
20
+ if (isLayoutColumn) {
21
+ outputNodes.push(...column.children);
22
+ }
23
+ });
24
+ }
25
+ });
26
+ if (outputNodes.length === 0) {
27
+ return nodes;
28
+ }
29
+ return outputNodes;
30
+ };
@@ -1,6 +1,7 @@
1
1
  import { getTargetNodeTypeNameInContext } from '../transform-node-utils/utils';
2
2
  import { flattenListStep } from './flattenListStep';
3
3
  import { flattenStep } from './flattenStep';
4
+ import { unwrapLayoutStep } from './steps/unwrapLayoutStep';
4
5
  import { stubStep } from './stubStep';
5
6
  import { NODE_CATEGORY_BY_TYPE, toNodeTypeValue } from './types';
6
7
  import { unwrapExpandStep } from './unwrapExpandStep';
@@ -67,6 +68,26 @@ const TRANSFORM_STEPS_OVERRIDE = {
67
68
  blockquote: [unwrapExpandStep, wrapStep],
68
69
  paragraph: [unwrapExpandStep],
69
70
  codeBlock: [unwrapExpandStep, flattenStep, wrapStep]
71
+ },
72
+ blockquote: {
73
+ expand: [wrapStep],
74
+ nestedExpand: [wrapStep],
75
+ layoutSection: [wrapIntoLayoutStep],
76
+ codeBlock: [unwrapStep, flattenStep, wrapStep]
77
+ },
78
+ layoutSection: {
79
+ blockquote: [unwrapLayoutStep, wrapStep],
80
+ expand: [unwrapLayoutStep, wrapStep],
81
+ panel: [unwrapLayoutStep, wrapStep],
82
+ codeBlock: [unwrapLayoutStep, flattenStep, wrapStep],
83
+ paragraph: [unwrapLayoutStep]
84
+ },
85
+ codeBlock: {
86
+ blockquote: [wrapStep],
87
+ expand: [wrapStep],
88
+ nestedExpand: [wrapStep],
89
+ layoutSection: [wrapIntoLayoutStep],
90
+ panel: [wrapStep]
70
91
  }
71
92
  };
72
93
  const getTransformStepsForNodeTypes = (selectedNodeTypeName, targetNodeTypeName) => {
@@ -85,8 +106,8 @@ export const getOutputNodes = ({
85
106
  }) => {
86
107
  const nodesToReplace = [sourceNode];
87
108
  const selectedNodeTypeName = toNodeTypeValue(sourceNode.type.name);
88
- let targetNodeTypeName = toNodeTypeValue(targetNodeType.name);
89
- targetNodeTypeName = getTargetNodeTypeNameInContext(targetNodeTypeName, isNested);
109
+ const initialTargetNodeTypeName = toNodeTypeValue(targetNodeType.name);
110
+ const targetNodeTypeName = getTargetNodeTypeNameInContext(initialTargetNodeTypeName, isNested);
90
111
  if (!selectedNodeTypeName || !targetNodeTypeName) {
91
112
  // We may decide to return an empty array or undefined here
92
113
  return;
@@ -101,7 +122,6 @@ export const getOutputNodes = ({
101
122
  return;
102
123
  }
103
124
  return steps.reduce((nodes, step) => {
104
- const result = step(nodes, context);
105
- return result;
125
+ return step(nodes, context);
106
126
  }, nodesToReplace);
107
127
  };
@@ -1,3 +1,5 @@
1
+ import { unwrapStep } from './unwrapStep';
2
+
1
3
  /**
2
4
  * Unwraps an expand/nestedExpand node, converting its title attribute to a paragraph
3
5
  * and prepending it to the children.
@@ -9,8 +11,12 @@ export const unwrapExpandStep = (nodes, context) => {
9
11
  schema
10
12
  } = context;
11
13
  const outputNodes = [];
14
+ const {
15
+ expand,
16
+ nestedExpand
17
+ } = schema.nodes;
12
18
  nodes.forEach(node => {
13
- const isExpand = node.type.name === 'expand' || node.type.name === 'nestedExpand';
19
+ const isExpand = node.type.name === expand.name || node.type.name === nestedExpand.name;
14
20
  if (isExpand) {
15
21
  var _node$attrs;
16
22
  const title = (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.title;
@@ -26,12 +32,7 @@ export const unwrapExpandStep = (nodes, context) => {
26
32
  // Add the children
27
33
  outputNodes.push(...node.children);
28
34
  } else {
29
- // Fallback: behave like unwrapStep for non-expand nodes
30
- if (node.children.length === 0) {
31
- outputNodes.push(node);
32
- } else {
33
- outputNodes.push(...node.children);
34
- }
35
+ unwrapStep([node], context);
35
36
  }
36
37
  });
37
38
  return outputNodes;