@atlaskit/editor-plugin-block-menu 6.0.10 → 6.0.12

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 (36) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +1 -12
  3. package/dist/cjs/editor-commands/transform-node-utils/utils.js +11 -33
  4. package/dist/cjs/ui/block-menu-components.js +12 -0
  5. package/dist/cjs/ui/block-menu-renderer/BlockMenuComponent.js +3 -3
  6. package/dist/cjs/ui/block-menu-renderer/utils.js +4 -7
  7. package/dist/cjs/ui/hooks/useSuggestedItems.js +4 -37
  8. package/dist/cjs/ui/utils/createMenuItemsMap.js +19 -0
  9. package/dist/cjs/ui/utils/getSuggestedItemsFromSelection.js +40 -0
  10. package/dist/es2019/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +2 -13
  11. package/dist/es2019/editor-commands/transform-node-utils/utils.js +10 -32
  12. package/dist/es2019/ui/block-menu-components.js +13 -1
  13. package/dist/es2019/ui/block-menu-renderer/BlockMenuComponent.js +3 -3
  14. package/dist/es2019/ui/block-menu-renderer/utils.js +4 -7
  15. package/dist/es2019/ui/hooks/useSuggestedItems.js +4 -28
  16. package/dist/es2019/ui/utils/createMenuItemsMap.js +9 -0
  17. package/dist/es2019/ui/utils/getSuggestedItemsFromSelection.js +30 -0
  18. package/dist/esm/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +2 -13
  19. package/dist/esm/editor-commands/transform-node-utils/utils.js +10 -32
  20. package/dist/esm/ui/block-menu-components.js +12 -0
  21. package/dist/esm/ui/block-menu-renderer/BlockMenuComponent.js +3 -3
  22. package/dist/esm/ui/block-menu-renderer/utils.js +4 -7
  23. package/dist/esm/ui/hooks/useSuggestedItems.js +4 -37
  24. package/dist/esm/ui/utils/createMenuItemsMap.js +13 -0
  25. package/dist/esm/ui/utils/getSuggestedItemsFromSelection.js +35 -0
  26. package/dist/types/blockMenuPluginType.d.ts +1 -0
  27. package/dist/types/editor-commands/transform-node-utils/utils.d.ts +5 -10
  28. package/dist/types/ui/block-menu-renderer/utils.d.ts +2 -3
  29. package/dist/types/ui/utils/createMenuItemsMap.d.ts +6 -0
  30. package/dist/types/ui/utils/getSuggestedItemsFromSelection.d.ts +6 -0
  31. package/dist/types-ts4.5/blockMenuPluginType.d.ts +1 -0
  32. package/dist/types-ts4.5/editor-commands/transform-node-utils/utils.d.ts +5 -10
  33. package/dist/types-ts4.5/ui/block-menu-renderer/utils.d.ts +2 -3
  34. package/dist/types-ts4.5/ui/utils/createMenuItemsMap.d.ts +6 -0
  35. package/dist/types-ts4.5/ui/utils/getSuggestedItemsFromSelection.d.ts +6 -0
  36. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-block-menu
2
2
 
3
+ ## 6.0.12
4
+
5
+ ### Patch Changes
6
+
7
+ - [`b909e5f47ea91`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b909e5f47ea91) -
8
+ EDITOR-4159 Make sure block-menu-item type component return null when tranform disabled
9
+ - Updated dependencies
10
+
11
+ ## 6.0.11
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
3
17
  ## 6.0.10
4
18
 
5
19
  ### Patch Changes
@@ -155,18 +155,7 @@ var wrapMixedContentStep = exports.wrapMixedContentStep = function wrapMixedCont
155
155
  (_currentContainerCont = currentContainerContent).push.apply(_currentContainerCont, (0, _toConsumableArray2.default)((0, _marks.removeDisallowedMarks)([node], validationType)));
156
156
  };
157
157
  var handleCodeblockTextNode = function handleCodeblockTextNode(node) {
158
- // Split the text node into text parts and incompatible inline nodes
159
- var parts = (0, _utils.splitTextNodeForCodeBlock)(node, schema);
160
- parts.forEach(function (part) {
161
- if (typeof part === 'string') {
162
- // Text content - add to current codeBlock
163
- currentContainerContent.push(part);
164
- } else {
165
- // Incompatible inline node wrapped in paragraph - break it out
166
- flushCurrentContainer();
167
- result.push(part);
168
- }
169
- });
158
+ currentContainerContent.push((0, _utils.createTextContent)(node));
170
159
  };
171
160
  var handleConvertibleTextNode = function handleConvertibleTextNode(node) {
172
161
  var paragraph = (0, _utils.convertTextNodeToParagraph)(node, schema);
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.splitTextNodeForCodeBlock = exports.isTextNode = exports.getTargetNodeTypeNameInContext = exports.getSelectedNode = exports.getBlockNodesInRange = exports.convertTextNodeToParagraph = exports.convertNestedExpandToExpand = exports.convertExpandToNestedExpand = void 0;
6
+ exports.isTextNode = exports.getTargetNodeTypeNameInContext = exports.getSelectedNode = exports.getBlockNodesInRange = exports.createTextContent = exports.convertTextNodeToParagraph = exports.convertNestedExpandToExpand = exports.convertExpandToNestedExpand = void 0;
7
7
  var _state = require("@atlaskit/editor-prosemirror/state");
8
8
  var _utils = require("@atlaskit/editor-prosemirror/utils");
9
9
  var _editorTables = require("@atlaskit/editor-tables");
@@ -131,42 +131,20 @@ var getBlockNodesInRange = exports.getBlockNodesInRange = function getBlockNodes
131
131
  };
132
132
 
133
133
  /**
134
- * Splits a text node (paragraph/heading) into parts for codeBlock conversion.
135
- * Returns an array of:
136
- * - strings (text content that can go into codeBlock)
137
- * - PMNodes (incompatible inline nodes wrapped in paragraphs that need to break out)
134
+ * Iterates over a nodes children and extracting text content, removing all other inline content and converting
135
+ * hardbreaks to newlines.
138
136
  *
139
- * This preserves inline nodes (like status, inlineExtension) that cannot be represented as plain text.
140
- *
141
- * @param node - The text node (paragraph or heading) to split
142
- * @param schema - The schema to use for creating paragraph nodes
143
- * @returns Array of strings (for codeBlock) and PMNodes (to break out)
137
+ * @param node - The node to create text content from (should be paragraph)
138
+ * @returns The text content string.
144
139
  */
145
- var splitTextNodeForCodeBlock = exports.splitTextNodeForCodeBlock = function splitTextNodeForCodeBlock(node, schema) {
146
- var result = [];
147
- var currentText = '';
148
- node.content.forEach(function (child) {
140
+ var createTextContent = exports.createTextContent = function createTextContent(node) {
141
+ var textContent = node.children.map(function (child) {
149
142
  if (child.isText) {
150
- currentText += child.text || '';
143
+ return child.text;
151
144
  } else if (child.type.name === 'hardBreak') {
152
- currentText += '\n';
153
- } else {
154
- // Incompatible inline node (status, inlineExtension, etc.)
155
- // Flush accumulated text if any
156
- if (currentText) {
157
- result.push(currentText);
158
- currentText = '';
159
- }
160
- // Wrap the inline node in a paragraph and add it to break out
161
- var paragraph = schema.nodes.paragraph.create({}, child);
162
- result.push(paragraph);
145
+ return '\n';
163
146
  }
147
+ return '';
164
148
  });
165
-
166
- // Don't forget remaining text (or empty string for empty nodes)
167
- // Always push at least an empty string so empty paragraphs create empty codeBlocks
168
- if (currentText || result.length === 0) {
169
- result.push(currentText);
170
- }
171
- return result;
149
+ return textContent.join('');
172
150
  };
@@ -19,6 +19,8 @@ var _moveDown = require("./move-down");
19
19
  var _moveUp = require("./move-up");
20
20
  var _suggestedItemsMenuSection = require("./suggested-items-menu-section");
21
21
  var _suggestedMenuItems = require("./suggested-menu-items");
22
+ var _createMenuItemsMap = require("./utils/createMenuItemsMap");
23
+ var _getSuggestedItemsFromSelection = require("./utils/getSuggestedItemsFromSelection");
22
24
  var getMoveUpMoveDownMenuComponents = function getMoveUpMoveDownMenuComponents(api) {
23
25
  return [{
24
26
  type: 'block-menu-item',
@@ -95,6 +97,16 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
95
97
  return /*#__PURE__*/_react.default.createElement(_suggestedMenuItems.SuggestedMenuItems, {
96
98
  api: api
97
99
  });
100
+ },
101
+ isHidden: function isHidden() {
102
+ var _api$blockMenu, _api$selection, _api$blockControls;
103
+ var blockMenuComponents = api === null || api === void 0 || (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
104
+ var menuItemsMap = (0, _createMenuItemsMap.createMenuItemsMap)(blockMenuComponents);
105
+ var selection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.sharedState.currentState()) === null || _api$selection === void 0 ? void 0 : _api$selection.selection;
106
+ var preservedSelection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
107
+ var currentSelection = preservedSelection || selection;
108
+ var suggestedItems = (0, _getSuggestedItemsFromSelection.getSuggestedItemsFromSelection)(menuItemsMap, currentSelection);
109
+ return suggestedItems.length === 0;
98
110
  }
99
111
  }, {
100
112
  type: 'block-menu-section',
@@ -15,15 +15,15 @@ var BlockMenuComponent = exports.BlockMenuComponent = function BlockMenuComponen
15
15
  var registeredComponent = _ref.registeredComponent,
16
16
  childrenMap = _ref.childrenMap,
17
17
  fallbacks = _ref.fallbacks;
18
+ if (!(0, _utils.willComponentRender)(registeredComponent, childrenMap)) {
19
+ return null;
20
+ }
18
21
  if (registeredComponent.type === 'block-menu-item') {
19
22
  var ItemComponent = registeredComponent.component || fallbacks['block-menu-item'];
20
23
  return /*#__PURE__*/_react.default.createElement(ItemComponent, {
21
24
  key: registeredComponent.key
22
25
  });
23
26
  }
24
- if (!(0, _utils.willComponentRender)(registeredComponent, childrenMap)) {
25
- return null;
26
- }
27
27
  var ParentComponent = registeredComponent.component || fallbacks[registeredComponent.type];
28
28
  var childrenMapKey = (0, _utils.getChildrenMapKey)(registeredComponent.key, registeredComponent.type);
29
29
  var registeredComponents = childrenMap.get(childrenMapKey);
@@ -106,21 +106,18 @@ var buildChildrenMap = exports.buildChildrenMap = function buildChildrenMap(comp
106
106
  * Determines whether a component will render based on its type and children
107
107
  *
108
108
  * Rules:
109
- * - An item will not render if has a component that returns null
110
- * - A nested menu will render if it has at least one registered child component
109
+ * - An item will not render if it has isHidden that returns true OR if its component returns null (fallback)
110
+ * - A nested menu will render if at least one section, that has at least one registered child
111
111
  * - A section will render if it has at least one registered child component that will render
112
112
  *
113
- * NOTE: This requires invoking each item's component function to check for null return
114
113
  */
115
114
  var _willComponentRender = exports.willComponentRender = function willComponentRender(registeredComponent, childrenMap) {
116
115
  if (registeredComponent.type === 'block-menu-item') {
117
- return registeredComponent.component ? registeredComponent.component() !== null : true;
116
+ var _registeredComponent$;
117
+ return !(registeredComponent !== null && registeredComponent !== void 0 && (_registeredComponent$ = registeredComponent.isHidden) !== null && _registeredComponent$ !== void 0 && _registeredComponent$.call(registeredComponent));
118
118
  }
119
119
  var childrenMapKey = getChildrenMapKey(registeredComponent.key, registeredComponent.type);
120
120
  var registeredComponents = childrenMap.get(childrenMapKey) || [];
121
- if (registeredComponent.type === 'block-menu-nested') {
122
- return registeredComponents.length > 0;
123
- }
124
121
  return registeredComponents.some(function (childComponent) {
125
122
  return _willComponentRender(childComponent, childrenMap);
126
123
  });
@@ -6,9 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.useSuggestedItems = void 0;
7
7
  var _react = require("react");
8
8
  var _hooks = require("@atlaskit/editor-common/hooks");
9
- var _selection = require("@atlaskit/editor-common/selection");
10
- var _utils = require("../../editor-commands/transform-node-utils/utils");
11
- var _suggestedItemsRank = require("../utils/suggested-items-rank");
9
+ var _createMenuItemsMap = require("../utils/createMenuItemsMap");
10
+ var _getSuggestedItemsFromSelection = require("../utils/getSuggestedItemsFromSelection");
12
11
  var useSuggestedItems = exports.useSuggestedItems = function useSuggestedItems(api) {
13
12
  var _api$blockMenu;
14
13
  var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls', 'selection'], function (states) {
@@ -22,43 +21,11 @@ var useSuggestedItems = exports.useSuggestedItems = function useSuggestedItems(a
22
21
  selection = _useSharedPluginState.selection;
23
22
  var blockMenuComponents = api === null || api === void 0 || (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
24
23
  var menuItemsMap = (0, _react.useMemo)(function () {
25
- if (!blockMenuComponents) {
26
- return new Map();
27
- }
28
- return new Map(blockMenuComponents.filter(function (c) {
29
- return c.type === 'block-menu-item';
30
- }).map(function (item) {
31
- return [item.key, item];
32
- }));
24
+ return (0, _createMenuItemsMap.createMenuItemsMap)(blockMenuComponents);
33
25
  }, [blockMenuComponents]);
34
26
  var suggestedItems = (0, _react.useMemo)(function () {
35
27
  var currentSelection = preservedSelection || selection;
36
- if (menuItemsMap.size === 0 || !currentSelection) {
37
- return [];
38
- }
39
- var _expandSelectionToBlo = (0, _selection.expandSelectionToBlockRange)(currentSelection),
40
- range = _expandSelectionToBlo.range;
41
- if (!range) {
42
- return [];
43
- }
44
- var blockNodes = (0, _utils.getBlockNodesInRange)(range);
45
- if (blockNodes.length === 0) {
46
- return [];
47
- }
48
- var firstNodeType = blockNodes[0].type.name;
49
- var allSameType = blockNodes.every(function (node) {
50
- return node.type.name === firstNodeType;
51
- });
52
- if (!allSameType) {
53
- return [];
54
- }
55
- var nodeTypeName = firstNodeType;
56
- var sortedKeys = (0, _suggestedItemsRank.getSortedSuggestedItems)(nodeTypeName);
57
- return sortedKeys.map(function (key) {
58
- return menuItemsMap.get(key);
59
- }).filter(function (item) {
60
- return item !== undefined;
61
- });
28
+ return (0, _getSuggestedItemsFromSelection.getSuggestedItemsFromSelection)(menuItemsMap, currentSelection);
62
29
  }, [menuItemsMap, preservedSelection, selection]);
63
30
  return suggestedItems;
64
31
  };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createMenuItemsMap = void 0;
7
+ /**
8
+ * Helper function to create menu items map from block menu components.
9
+ */
10
+ var createMenuItemsMap = exports.createMenuItemsMap = function createMenuItemsMap(blockMenuComponents) {
11
+ if (!blockMenuComponents) {
12
+ return new Map();
13
+ }
14
+ return new Map(blockMenuComponents.filter(function (c) {
15
+ return c.type === 'block-menu-item';
16
+ }).map(function (item) {
17
+ return [item.key, item];
18
+ }));
19
+ };
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getSuggestedItemsFromSelection = void 0;
7
+ var _selection = require("@atlaskit/editor-common/selection");
8
+ var _utils = require("../../editor-commands/transform-node-utils/utils");
9
+ var _suggestedItemsRank = require("../utils/suggested-items-rank");
10
+ /**
11
+ * Pure function to calculate suggested items based on selection and menu components.
12
+ */
13
+ var getSuggestedItemsFromSelection = exports.getSuggestedItemsFromSelection = function getSuggestedItemsFromSelection(menuItemsMap, currentSelection) {
14
+ if (menuItemsMap.size === 0 || !currentSelection) {
15
+ return [];
16
+ }
17
+ var _expandSelectionToBlo = (0, _selection.expandSelectionToBlockRange)(currentSelection),
18
+ range = _expandSelectionToBlo.range;
19
+ if (!range) {
20
+ return [];
21
+ }
22
+ var blockNodes = (0, _utils.getBlockNodesInRange)(range);
23
+ if (blockNodes.length === 0) {
24
+ return [];
25
+ }
26
+ var firstNodeType = blockNodes[0].type.name;
27
+ var allSameType = blockNodes.every(function (node) {
28
+ return node.type.name === firstNodeType;
29
+ });
30
+ if (!allSameType) {
31
+ return [];
32
+ }
33
+ var nodeTypeName = firstNodeType;
34
+ var sortedKeys = (0, _suggestedItemsRank.getSortedSuggestedItems)(nodeTypeName);
35
+ return sortedKeys.map(function (key) {
36
+ return menuItemsMap.get(key);
37
+ }).filter(function (item) {
38
+ return item !== undefined;
39
+ });
40
+ };
@@ -1,7 +1,7 @@
1
1
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
2
2
  import { removeDisallowedMarks } from '../marks';
3
3
  import { NODE_CATEGORY_BY_TYPE } from '../types';
4
- import { convertTextNodeToParagraph, isTextNode, splitTextNodeForCodeBlock } from '../utils';
4
+ import { convertTextNodeToParagraph, createTextContent, isTextNode } from '../utils';
5
5
 
6
6
  /**
7
7
  * Creates a layout section with two columns, where the first column contains the provided content.
@@ -150,18 +150,7 @@ export const wrapMixedContentStep = (nodes, context) => {
150
150
  currentContainerContent.push(...removeDisallowedMarks([node], validationType));
151
151
  };
152
152
  const handleCodeblockTextNode = node => {
153
- // Split the text node into text parts and incompatible inline nodes
154
- const parts = splitTextNodeForCodeBlock(node, schema);
155
- parts.forEach(part => {
156
- if (typeof part === 'string') {
157
- // Text content - add to current codeBlock
158
- currentContainerContent.push(part);
159
- } else {
160
- // Incompatible inline node wrapped in paragraph - break it out
161
- flushCurrentContainer();
162
- result.push(part);
163
- }
164
- });
153
+ currentContainerContent.push(createTextContent(node));
165
154
  };
166
155
  const handleConvertibleTextNode = node => {
167
156
  const paragraph = convertTextNodeToParagraph(node, schema);
@@ -127,42 +127,20 @@ export const getBlockNodesInRange = range => {
127
127
  };
128
128
 
129
129
  /**
130
- * Splits a text node (paragraph/heading) into parts for codeBlock conversion.
131
- * Returns an array of:
132
- * - strings (text content that can go into codeBlock)
133
- * - PMNodes (incompatible inline nodes wrapped in paragraphs that need to break out)
130
+ * Iterates over a nodes children and extracting text content, removing all other inline content and converting
131
+ * hardbreaks to newlines.
134
132
  *
135
- * This preserves inline nodes (like status, inlineExtension) that cannot be represented as plain text.
136
- *
137
- * @param node - The text node (paragraph or heading) to split
138
- * @param schema - The schema to use for creating paragraph nodes
139
- * @returns Array of strings (for codeBlock) and PMNodes (to break out)
133
+ * @param node - The node to create text content from (should be paragraph)
134
+ * @returns The text content string.
140
135
  */
141
- export const splitTextNodeForCodeBlock = (node, schema) => {
142
- const result = [];
143
- let currentText = '';
144
- node.content.forEach(child => {
136
+ export const createTextContent = node => {
137
+ const textContent = node.children.map(child => {
145
138
  if (child.isText) {
146
- currentText += child.text || '';
139
+ return child.text;
147
140
  } else if (child.type.name === 'hardBreak') {
148
- currentText += '\n';
149
- } else {
150
- // Incompatible inline node (status, inlineExtension, etc.)
151
- // Flush accumulated text if any
152
- if (currentText) {
153
- result.push(currentText);
154
- currentText = '';
155
- }
156
- // Wrap the inline node in a paragraph and add it to break out
157
- const paragraph = schema.nodes.paragraph.create({}, child);
158
- result.push(paragraph);
141
+ return '\n';
159
142
  }
143
+ return '';
160
144
  });
161
-
162
- // Don't forget remaining text (or empty string for empty nodes)
163
- // Always push at least an empty string so empty paragraphs create empty codeBlocks
164
- if (currentText || result.length === 0) {
165
- result.push(currentText);
166
- }
167
- return result;
145
+ return textContent.join('');
168
146
  };
@@ -11,6 +11,8 @@ import { MoveDownDropdownItem } from './move-down';
11
11
  import { MoveUpDropdownItem } from './move-up';
12
12
  import { SuggestedItemsMenuSection } from './suggested-items-menu-section';
13
13
  import { SuggestedMenuItems } from './suggested-menu-items';
14
+ import { createMenuItemsMap } from './utils/createMenuItemsMap';
15
+ import { getSuggestedItemsFromSelection } from './utils/getSuggestedItemsFromSelection';
14
16
  const getMoveUpMoveDownMenuComponents = api => {
15
17
  return [{
16
18
  type: 'block-menu-item',
@@ -79,7 +81,17 @@ const getTurnIntoMenuComponents = api => {
79
81
  },
80
82
  component: () => /*#__PURE__*/React.createElement(SuggestedMenuItems, {
81
83
  api: api
82
- })
84
+ }),
85
+ isHidden: () => {
86
+ var _api$blockMenu, _api$selection, _api$selection$shared, _api$blockControls, _api$blockControls$sh;
87
+ const blockMenuComponents = api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
88
+ const menuItemsMap = createMenuItemsMap(blockMenuComponents);
89
+ const selection = api === null || api === void 0 ? void 0 : (_api$selection = api.selection) === null || _api$selection === void 0 ? void 0 : (_api$selection$shared = _api$selection.sharedState.currentState()) === null || _api$selection$shared === void 0 ? void 0 : _api$selection$shared.selection;
90
+ const preservedSelection = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$sh = _api$blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.preservedSelection;
91
+ const currentSelection = preservedSelection || selection;
92
+ const suggestedItems = getSuggestedItemsFromSelection(menuItemsMap, currentSelection);
93
+ return suggestedItems.length === 0;
94
+ }
83
95
  }, {
84
96
  type: 'block-menu-section',
85
97
  key: TRANSFORM_CREATE_MENU_SECTION.key,
@@ -9,15 +9,15 @@ export const BlockMenuComponent = ({
9
9
  childrenMap,
10
10
  fallbacks
11
11
  }) => {
12
+ if (!willComponentRender(registeredComponent, childrenMap)) {
13
+ return null;
14
+ }
12
15
  if (registeredComponent.type === 'block-menu-item') {
13
16
  const ItemComponent = registeredComponent.component || fallbacks['block-menu-item'];
14
17
  return /*#__PURE__*/React.createElement(ItemComponent, {
15
18
  key: registeredComponent.key
16
19
  });
17
20
  }
18
- if (!willComponentRender(registeredComponent, childrenMap)) {
19
- return null;
20
- }
21
21
  const ParentComponent = registeredComponent.component || fallbacks[registeredComponent.type];
22
22
  const childrenMapKey = getChildrenMapKey(registeredComponent.key, registeredComponent.type);
23
23
  const registeredComponents = childrenMap.get(childrenMapKey);
@@ -74,20 +74,17 @@ export const buildChildrenMap = components => {
74
74
  * Determines whether a component will render based on its type and children
75
75
  *
76
76
  * Rules:
77
- * - An item will not render if has a component that returns null
78
- * - A nested menu will render if it has at least one registered child component
77
+ * - An item will not render if it has isHidden that returns true OR if its component returns null (fallback)
78
+ * - A nested menu will render if at least one section, that has at least one registered child
79
79
  * - A section will render if it has at least one registered child component that will render
80
80
  *
81
- * NOTE: This requires invoking each item's component function to check for null return
82
81
  */
83
82
  export const willComponentRender = (registeredComponent, childrenMap) => {
84
83
  if (registeredComponent.type === 'block-menu-item') {
85
- return registeredComponent.component ? registeredComponent.component() !== null : true;
84
+ var _registeredComponent$;
85
+ return !(registeredComponent !== null && registeredComponent !== void 0 && (_registeredComponent$ = registeredComponent.isHidden) !== null && _registeredComponent$ !== void 0 && _registeredComponent$.call(registeredComponent));
86
86
  }
87
87
  const childrenMapKey = getChildrenMapKey(registeredComponent.key, registeredComponent.type);
88
88
  const registeredComponents = childrenMap.get(childrenMapKey) || [];
89
- if (registeredComponent.type === 'block-menu-nested') {
90
- return registeredComponents.length > 0;
91
- }
92
89
  return registeredComponents.some(childComponent => willComponentRender(childComponent, childrenMap));
93
90
  };
@@ -1,8 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
- import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
4
- import { getBlockNodesInRange } from '../../editor-commands/transform-node-utils/utils';
5
- import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
3
+ import { createMenuItemsMap } from '../utils/createMenuItemsMap';
4
+ import { getSuggestedItemsFromSelection } from '../utils/getSuggestedItemsFromSelection';
6
5
  export const useSuggestedItems = api => {
7
6
  var _api$blockMenu;
8
7
  const {
@@ -17,34 +16,11 @@ export const useSuggestedItems = api => {
17
16
  });
18
17
  const blockMenuComponents = api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
19
18
  const menuItemsMap = useMemo(() => {
20
- if (!blockMenuComponents) {
21
- return new Map();
22
- }
23
- return new Map(blockMenuComponents.filter(c => c.type === 'block-menu-item').map(item => [item.key, item]));
19
+ return createMenuItemsMap(blockMenuComponents);
24
20
  }, [blockMenuComponents]);
25
21
  const suggestedItems = useMemo(() => {
26
22
  const currentSelection = preservedSelection || selection;
27
- if (menuItemsMap.size === 0 || !currentSelection) {
28
- return [];
29
- }
30
- const {
31
- range
32
- } = expandSelectionToBlockRange(currentSelection);
33
- if (!range) {
34
- return [];
35
- }
36
- const blockNodes = getBlockNodesInRange(range);
37
- if (blockNodes.length === 0) {
38
- return [];
39
- }
40
- const firstNodeType = blockNodes[0].type.name;
41
- const allSameType = blockNodes.every(node => node.type.name === firstNodeType);
42
- if (!allSameType) {
43
- return [];
44
- }
45
- const nodeTypeName = firstNodeType;
46
- const sortedKeys = getSortedSuggestedItems(nodeTypeName);
47
- return sortedKeys.map(key => menuItemsMap.get(key)).filter(item => item !== undefined);
23
+ return getSuggestedItemsFromSelection(menuItemsMap, currentSelection);
48
24
  }, [menuItemsMap, preservedSelection, selection]);
49
25
  return suggestedItems;
50
26
  };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Helper function to create menu items map from block menu components.
3
+ */
4
+ export const createMenuItemsMap = blockMenuComponents => {
5
+ if (!blockMenuComponents) {
6
+ return new Map();
7
+ }
8
+ return new Map(blockMenuComponents.filter(c => c.type === 'block-menu-item').map(item => [item.key, item]));
9
+ };
@@ -0,0 +1,30 @@
1
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
2
+ import { getBlockNodesInRange } from '../../editor-commands/transform-node-utils/utils';
3
+ import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
4
+
5
+ /**
6
+ * Pure function to calculate suggested items based on selection and menu components.
7
+ */
8
+ export const getSuggestedItemsFromSelection = (menuItemsMap, currentSelection) => {
9
+ if (menuItemsMap.size === 0 || !currentSelection) {
10
+ return [];
11
+ }
12
+ const {
13
+ range
14
+ } = expandSelectionToBlockRange(currentSelection);
15
+ if (!range) {
16
+ return [];
17
+ }
18
+ const blockNodes = getBlockNodesInRange(range);
19
+ if (blockNodes.length === 0) {
20
+ return [];
21
+ }
22
+ const firstNodeType = blockNodes[0].type.name;
23
+ const allSameType = blockNodes.every(node => node.type.name === firstNodeType);
24
+ if (!allSameType) {
25
+ return [];
26
+ }
27
+ const nodeTypeName = firstNodeType;
28
+ const sortedKeys = getSortedSuggestedItems(nodeTypeName);
29
+ return sortedKeys.map(key => menuItemsMap.get(key)).filter(item => item !== undefined);
30
+ };
@@ -2,7 +2,7 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
3
3
  import { removeDisallowedMarks } from '../marks';
4
4
  import { NODE_CATEGORY_BY_TYPE } from '../types';
5
- import { convertTextNodeToParagraph, isTextNode, splitTextNodeForCodeBlock } from '../utils';
5
+ import { convertTextNodeToParagraph, createTextContent, isTextNode } from '../utils';
6
6
 
7
7
  /**
8
8
  * Creates a layout section with two columns, where the first column contains the provided content.
@@ -149,18 +149,7 @@ export var wrapMixedContentStep = function wrapMixedContentStep(nodes, context)
149
149
  (_currentContainerCont = currentContainerContent).push.apply(_currentContainerCont, _toConsumableArray(removeDisallowedMarks([node], validationType)));
150
150
  };
151
151
  var handleCodeblockTextNode = function handleCodeblockTextNode(node) {
152
- // Split the text node into text parts and incompatible inline nodes
153
- var parts = splitTextNodeForCodeBlock(node, schema);
154
- parts.forEach(function (part) {
155
- if (typeof part === 'string') {
156
- // Text content - add to current codeBlock
157
- currentContainerContent.push(part);
158
- } else {
159
- // Incompatible inline node wrapped in paragraph - break it out
160
- flushCurrentContainer();
161
- result.push(part);
162
- }
163
- });
152
+ currentContainerContent.push(createTextContent(node));
164
153
  };
165
154
  var handleConvertibleTextNode = function handleConvertibleTextNode(node) {
166
155
  var paragraph = convertTextNodeToParagraph(node, schema);
@@ -126,42 +126,20 @@ export var getBlockNodesInRange = function getBlockNodesInRange(range) {
126
126
  };
127
127
 
128
128
  /**
129
- * Splits a text node (paragraph/heading) into parts for codeBlock conversion.
130
- * Returns an array of:
131
- * - strings (text content that can go into codeBlock)
132
- * - PMNodes (incompatible inline nodes wrapped in paragraphs that need to break out)
129
+ * Iterates over a nodes children and extracting text content, removing all other inline content and converting
130
+ * hardbreaks to newlines.
133
131
  *
134
- * This preserves inline nodes (like status, inlineExtension) that cannot be represented as plain text.
135
- *
136
- * @param node - The text node (paragraph or heading) to split
137
- * @param schema - The schema to use for creating paragraph nodes
138
- * @returns Array of strings (for codeBlock) and PMNodes (to break out)
132
+ * @param node - The node to create text content from (should be paragraph)
133
+ * @returns The text content string.
139
134
  */
140
- export var splitTextNodeForCodeBlock = function splitTextNodeForCodeBlock(node, schema) {
141
- var result = [];
142
- var currentText = '';
143
- node.content.forEach(function (child) {
135
+ export var createTextContent = function createTextContent(node) {
136
+ var textContent = node.children.map(function (child) {
144
137
  if (child.isText) {
145
- currentText += child.text || '';
138
+ return child.text;
146
139
  } else if (child.type.name === 'hardBreak') {
147
- currentText += '\n';
148
- } else {
149
- // Incompatible inline node (status, inlineExtension, etc.)
150
- // Flush accumulated text if any
151
- if (currentText) {
152
- result.push(currentText);
153
- currentText = '';
154
- }
155
- // Wrap the inline node in a paragraph and add it to break out
156
- var paragraph = schema.nodes.paragraph.create({}, child);
157
- result.push(paragraph);
140
+ return '\n';
158
141
  }
142
+ return '';
159
143
  });
160
-
161
- // Don't forget remaining text (or empty string for empty nodes)
162
- // Always push at least an empty string so empty paragraphs create empty codeBlocks
163
- if (currentText || result.length === 0) {
164
- result.push(currentText);
165
- }
166
- return result;
144
+ return textContent.join('');
167
145
  };
@@ -12,6 +12,8 @@ import { MoveDownDropdownItem } from './move-down';
12
12
  import { MoveUpDropdownItem } from './move-up';
13
13
  import { SuggestedItemsMenuSection } from './suggested-items-menu-section';
14
14
  import { SuggestedMenuItems } from './suggested-menu-items';
15
+ import { createMenuItemsMap } from './utils/createMenuItemsMap';
16
+ import { getSuggestedItemsFromSelection } from './utils/getSuggestedItemsFromSelection';
15
17
  var getMoveUpMoveDownMenuComponents = function getMoveUpMoveDownMenuComponents(api) {
16
18
  return [{
17
19
  type: 'block-menu-item',
@@ -88,6 +90,16 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
88
90
  return /*#__PURE__*/React.createElement(SuggestedMenuItems, {
89
91
  api: api
90
92
  });
93
+ },
94
+ isHidden: function isHidden() {
95
+ var _api$blockMenu, _api$selection, _api$blockControls;
96
+ var blockMenuComponents = api === null || api === void 0 || (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
97
+ var menuItemsMap = createMenuItemsMap(blockMenuComponents);
98
+ var selection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.sharedState.currentState()) === null || _api$selection === void 0 ? void 0 : _api$selection.selection;
99
+ var preservedSelection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
100
+ var currentSelection = preservedSelection || selection;
101
+ var suggestedItems = getSuggestedItemsFromSelection(menuItemsMap, currentSelection);
102
+ return suggestedItems.length === 0;
91
103
  }
92
104
  }, {
93
105
  type: 'block-menu-section',
@@ -8,15 +8,15 @@ export var BlockMenuComponent = function BlockMenuComponent(_ref) {
8
8
  var registeredComponent = _ref.registeredComponent,
9
9
  childrenMap = _ref.childrenMap,
10
10
  fallbacks = _ref.fallbacks;
11
+ if (!willComponentRender(registeredComponent, childrenMap)) {
12
+ return null;
13
+ }
11
14
  if (registeredComponent.type === 'block-menu-item') {
12
15
  var ItemComponent = registeredComponent.component || fallbacks['block-menu-item'];
13
16
  return /*#__PURE__*/React.createElement(ItemComponent, {
14
17
  key: registeredComponent.key
15
18
  });
16
19
  }
17
- if (!willComponentRender(registeredComponent, childrenMap)) {
18
- return null;
19
- }
20
20
  var ParentComponent = registeredComponent.component || fallbacks[registeredComponent.type];
21
21
  var childrenMapKey = getChildrenMapKey(registeredComponent.key, registeredComponent.type);
22
22
  var registeredComponents = childrenMap.get(childrenMapKey);
@@ -99,21 +99,18 @@ export var buildChildrenMap = function buildChildrenMap(components) {
99
99
  * Determines whether a component will render based on its type and children
100
100
  *
101
101
  * Rules:
102
- * - An item will not render if has a component that returns null
103
- * - A nested menu will render if it has at least one registered child component
102
+ * - An item will not render if it has isHidden that returns true OR if its component returns null (fallback)
103
+ * - A nested menu will render if at least one section, that has at least one registered child
104
104
  * - A section will render if it has at least one registered child component that will render
105
105
  *
106
- * NOTE: This requires invoking each item's component function to check for null return
107
106
  */
108
107
  var _willComponentRender = function willComponentRender(registeredComponent, childrenMap) {
109
108
  if (registeredComponent.type === 'block-menu-item') {
110
- return registeredComponent.component ? registeredComponent.component() !== null : true;
109
+ var _registeredComponent$;
110
+ return !(registeredComponent !== null && registeredComponent !== void 0 && (_registeredComponent$ = registeredComponent.isHidden) !== null && _registeredComponent$ !== void 0 && _registeredComponent$.call(registeredComponent));
111
111
  }
112
112
  var childrenMapKey = getChildrenMapKey(registeredComponent.key, registeredComponent.type);
113
113
  var registeredComponents = childrenMap.get(childrenMapKey) || [];
114
- if (registeredComponent.type === 'block-menu-nested') {
115
- return registeredComponents.length > 0;
116
- }
117
114
  return registeredComponents.some(function (childComponent) {
118
115
  return _willComponentRender(childComponent, childrenMap);
119
116
  });
@@ -1,8 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
- import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
4
- import { getBlockNodesInRange } from '../../editor-commands/transform-node-utils/utils';
5
- import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
3
+ import { createMenuItemsMap } from '../utils/createMenuItemsMap';
4
+ import { getSuggestedItemsFromSelection } from '../utils/getSuggestedItemsFromSelection';
6
5
  export var useSuggestedItems = function useSuggestedItems(api) {
7
6
  var _api$blockMenu;
8
7
  var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls', 'selection'], function (states) {
@@ -16,43 +15,11 @@ export var useSuggestedItems = function useSuggestedItems(api) {
16
15
  selection = _useSharedPluginState.selection;
17
16
  var blockMenuComponents = api === null || api === void 0 || (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
18
17
  var menuItemsMap = useMemo(function () {
19
- if (!blockMenuComponents) {
20
- return new Map();
21
- }
22
- return new Map(blockMenuComponents.filter(function (c) {
23
- return c.type === 'block-menu-item';
24
- }).map(function (item) {
25
- return [item.key, item];
26
- }));
18
+ return createMenuItemsMap(blockMenuComponents);
27
19
  }, [blockMenuComponents]);
28
20
  var suggestedItems = useMemo(function () {
29
21
  var currentSelection = preservedSelection || selection;
30
- if (menuItemsMap.size === 0 || !currentSelection) {
31
- return [];
32
- }
33
- var _expandSelectionToBlo = expandSelectionToBlockRange(currentSelection),
34
- range = _expandSelectionToBlo.range;
35
- if (!range) {
36
- return [];
37
- }
38
- var blockNodes = getBlockNodesInRange(range);
39
- if (blockNodes.length === 0) {
40
- return [];
41
- }
42
- var firstNodeType = blockNodes[0].type.name;
43
- var allSameType = blockNodes.every(function (node) {
44
- return node.type.name === firstNodeType;
45
- });
46
- if (!allSameType) {
47
- return [];
48
- }
49
- var nodeTypeName = firstNodeType;
50
- var sortedKeys = getSortedSuggestedItems(nodeTypeName);
51
- return sortedKeys.map(function (key) {
52
- return menuItemsMap.get(key);
53
- }).filter(function (item) {
54
- return item !== undefined;
55
- });
22
+ return getSuggestedItemsFromSelection(menuItemsMap, currentSelection);
56
23
  }, [menuItemsMap, preservedSelection, selection]);
57
24
  return suggestedItems;
58
25
  };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Helper function to create menu items map from block menu components.
3
+ */
4
+ export var createMenuItemsMap = function createMenuItemsMap(blockMenuComponents) {
5
+ if (!blockMenuComponents) {
6
+ return new Map();
7
+ }
8
+ return new Map(blockMenuComponents.filter(function (c) {
9
+ return c.type === 'block-menu-item';
10
+ }).map(function (item) {
11
+ return [item.key, item];
12
+ }));
13
+ };
@@ -0,0 +1,35 @@
1
+ import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
2
+ import { getBlockNodesInRange } from '../../editor-commands/transform-node-utils/utils';
3
+ import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
4
+
5
+ /**
6
+ * Pure function to calculate suggested items based on selection and menu components.
7
+ */
8
+ export var getSuggestedItemsFromSelection = function getSuggestedItemsFromSelection(menuItemsMap, currentSelection) {
9
+ if (menuItemsMap.size === 0 || !currentSelection) {
10
+ return [];
11
+ }
12
+ var _expandSelectionToBlo = expandSelectionToBlockRange(currentSelection),
13
+ range = _expandSelectionToBlo.range;
14
+ if (!range) {
15
+ return [];
16
+ }
17
+ var blockNodes = getBlockNodesInRange(range);
18
+ if (blockNodes.length === 0) {
19
+ return [];
20
+ }
21
+ var firstNodeType = blockNodes[0].type.name;
22
+ var allSameType = blockNodes.every(function (node) {
23
+ return node.type.name === firstNodeType;
24
+ });
25
+ if (!allSameType) {
26
+ return [];
27
+ }
28
+ var nodeTypeName = firstNodeType;
29
+ var sortedKeys = getSortedSuggestedItems(nodeTypeName);
30
+ return sortedKeys.map(function (key) {
31
+ return menuItemsMap.get(key);
32
+ }).filter(function (item) {
33
+ return item !== undefined;
34
+ });
35
+ };
@@ -106,6 +106,7 @@ export type RegisterBlockMenuSection = BlockMenuSection & {
106
106
  };
107
107
  export type RegisterBlockMenuItem = BlockMenuItem & {
108
108
  component?: BlockMenuItemComponent;
109
+ isHidden?: () => boolean;
109
110
  parent: Parent<BlockMenuSection>;
110
111
  };
111
112
  export type RegisterBlockMenuComponent = RegisterBlockMenuNested | RegisterBlockMenuSection | RegisterBlockMenuItem;
@@ -29,15 +29,10 @@ export declare const convertExpandToNestedExpand: (node: PMNode, schema: Schema)
29
29
  export declare const convertTextNodeToParagraph: (node: PMNode, schema: Schema) => PMNode | null;
30
30
  export declare const getBlockNodesInRange: (range: NodeRange) => PMNode[];
31
31
  /**
32
- * Splits a text node (paragraph/heading) into parts for codeBlock conversion.
33
- * Returns an array of:
34
- * - strings (text content that can go into codeBlock)
35
- * - PMNodes (incompatible inline nodes wrapped in paragraphs that need to break out)
32
+ * Iterates over a nodes children and extracting text content, removing all other inline content and converting
33
+ * hardbreaks to newlines.
36
34
  *
37
- * This preserves inline nodes (like status, inlineExtension) that cannot be represented as plain text.
38
- *
39
- * @param node - The text node (paragraph or heading) to split
40
- * @param schema - The schema to use for creating paragraph nodes
41
- * @returns Array of strings (for codeBlock) and PMNodes (to break out)
35
+ * @param node - The node to create text content from (should be paragraph)
36
+ * @returns The text content string.
42
37
  */
43
- export declare const splitTextNodeForCodeBlock: (node: PMNode, schema: Schema) => Array<string | PMNode>;
38
+ export declare const createTextContent: (node: PMNode) => string;
@@ -28,10 +28,9 @@ export declare const buildChildrenMap: (components: RegisterBlockMenuComponent[]
28
28
  * Determines whether a component will render based on its type and children
29
29
  *
30
30
  * Rules:
31
- * - An item will not render if has a component that returns null
32
- * - A nested menu will render if it has at least one registered child component
31
+ * - An item will not render if it has isHidden that returns true OR if its component returns null (fallback)
32
+ * - A nested menu will render if at least one section, that has at least one registered child
33
33
  * - A section will render if it has at least one registered child component that will render
34
34
  *
35
- * NOTE: This requires invoking each item's component function to check for null return
36
35
  */
37
36
  export declare const willComponentRender: (registeredComponent: RegisterBlockMenuComponent, childrenMap: ChildrenMap) => boolean;
@@ -0,0 +1,6 @@
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import type { BlockMenuPlugin, RegisterBlockMenuItem } from '../../blockMenuPluginType';
3
+ /**
4
+ * Helper function to create menu items map from block menu components.
5
+ */
6
+ export declare const createMenuItemsMap: (blockMenuComponents: ReturnType<ExtractInjectionAPI<BlockMenuPlugin>["blockMenu"]["actions"]["getBlockMenuComponents"]> | undefined) => Map<string, RegisterBlockMenuItem>;
@@ -0,0 +1,6 @@
1
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
2
+ import type { RegisterBlockMenuItem } from '../../blockMenuPluginType';
3
+ /**
4
+ * Pure function to calculate suggested items based on selection and menu components.
5
+ */
6
+ export declare const getSuggestedItemsFromSelection: (menuItemsMap: Map<string, RegisterBlockMenuItem>, currentSelection: Selection | null | undefined) => RegisterBlockMenuItem[];
@@ -106,6 +106,7 @@ export type RegisterBlockMenuSection = BlockMenuSection & {
106
106
  };
107
107
  export type RegisterBlockMenuItem = BlockMenuItem & {
108
108
  component?: BlockMenuItemComponent;
109
+ isHidden?: () => boolean;
109
110
  parent: Parent<BlockMenuSection>;
110
111
  };
111
112
  export type RegisterBlockMenuComponent = RegisterBlockMenuNested | RegisterBlockMenuSection | RegisterBlockMenuItem;
@@ -29,15 +29,10 @@ export declare const convertExpandToNestedExpand: (node: PMNode, schema: Schema)
29
29
  export declare const convertTextNodeToParagraph: (node: PMNode, schema: Schema) => PMNode | null;
30
30
  export declare const getBlockNodesInRange: (range: NodeRange) => PMNode[];
31
31
  /**
32
- * Splits a text node (paragraph/heading) into parts for codeBlock conversion.
33
- * Returns an array of:
34
- * - strings (text content that can go into codeBlock)
35
- * - PMNodes (incompatible inline nodes wrapped in paragraphs that need to break out)
32
+ * Iterates over a nodes children and extracting text content, removing all other inline content and converting
33
+ * hardbreaks to newlines.
36
34
  *
37
- * This preserves inline nodes (like status, inlineExtension) that cannot be represented as plain text.
38
- *
39
- * @param node - The text node (paragraph or heading) to split
40
- * @param schema - The schema to use for creating paragraph nodes
41
- * @returns Array of strings (for codeBlock) and PMNodes (to break out)
35
+ * @param node - The node to create text content from (should be paragraph)
36
+ * @returns The text content string.
42
37
  */
43
- export declare const splitTextNodeForCodeBlock: (node: PMNode, schema: Schema) => Array<string | PMNode>;
38
+ export declare const createTextContent: (node: PMNode) => string;
@@ -28,10 +28,9 @@ export declare const buildChildrenMap: (components: RegisterBlockMenuComponent[]
28
28
  * Determines whether a component will render based on its type and children
29
29
  *
30
30
  * Rules:
31
- * - An item will not render if has a component that returns null
32
- * - A nested menu will render if it has at least one registered child component
31
+ * - An item will not render if it has isHidden that returns true OR if its component returns null (fallback)
32
+ * - A nested menu will render if at least one section, that has at least one registered child
33
33
  * - A section will render if it has at least one registered child component that will render
34
34
  *
35
- * NOTE: This requires invoking each item's component function to check for null return
36
35
  */
37
36
  export declare const willComponentRender: (registeredComponent: RegisterBlockMenuComponent, childrenMap: ChildrenMap) => boolean;
@@ -0,0 +1,6 @@
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import type { BlockMenuPlugin, RegisterBlockMenuItem } from '../../blockMenuPluginType';
3
+ /**
4
+ * Helper function to create menu items map from block menu components.
5
+ */
6
+ export declare const createMenuItemsMap: (blockMenuComponents: ReturnType<ExtractInjectionAPI<BlockMenuPlugin>["blockMenu"]["actions"]["getBlockMenuComponents"]> | undefined) => Map<string, RegisterBlockMenuItem>;
@@ -0,0 +1,6 @@
1
+ import type { Selection } from '@atlaskit/editor-prosemirror/state';
2
+ import type { RegisterBlockMenuItem } from '../../blockMenuPluginType';
3
+ /**
4
+ * Pure function to calculate suggested items based on selection and menu components.
5
+ */
6
+ export declare const getSuggestedItemsFromSelection: (menuItemsMap: Map<string, RegisterBlockMenuItem>, currentSelection: Selection | null | undefined) => RegisterBlockMenuItem[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "6.0.10",
3
+ "version": "6.0.12",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -38,18 +38,18 @@
38
38
  "@atlaskit/editor-prosemirror": "^7.2.0",
39
39
  "@atlaskit/editor-shared-styles": "^3.10.0",
40
40
  "@atlaskit/editor-tables": "^2.9.0",
41
- "@atlaskit/editor-toolbar": "^0.18.0",
42
- "@atlaskit/flag": "^17.7.0",
41
+ "@atlaskit/editor-toolbar": "^0.19.0",
42
+ "@atlaskit/flag": "^17.8.0",
43
43
  "@atlaskit/icon": "^29.4.0",
44
44
  "@atlaskit/platform-feature-flags": "^1.1.0",
45
45
  "@atlaskit/platform-feature-flags-react": "^0.4.0",
46
46
  "@atlaskit/primitives": "^17.0.0",
47
- "@atlaskit/tmp-editor-statsig": "^16.8.0",
47
+ "@atlaskit/tmp-editor-statsig": "^16.11.0",
48
48
  "@atlaskit/tokens": "^9.1.0",
49
49
  "@babel/runtime": "^7.0.0"
50
50
  },
51
51
  "peerDependencies": {
52
- "@atlaskit/editor-common": "^111.6.0",
52
+ "@atlaskit/editor-common": "^111.7.0",
53
53
  "react": "^18.2.0",
54
54
  "react-intl-next": "npm:react-intl@^5.18.1"
55
55
  },