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

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 (51) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/editor-commands/transform-node-utils/nodeChecks.js +33 -0
  3. package/dist/cjs/editor-commands/transform-node-utils/steps/flattenListStep.js +7 -12
  4. package/dist/cjs/editor-commands/transform-node-utils/steps/listToDecisionListStep.js +3 -3
  5. package/dist/cjs/editor-commands/transform-node-utils/steps/listToListStep.js +11 -11
  6. package/dist/cjs/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.js +21 -0
  7. package/dist/cjs/editor-commands/transform-node-utils/transform.js +11 -11
  8. package/dist/cjs/editor-commands/transform-node-utils/utils.js +20 -7
  9. package/dist/cjs/editor-commands/transform-node-utils/wrapIntoListStep.js +29 -7
  10. package/dist/cjs/editor-commands/transformNode.js +3 -2
  11. package/dist/cjs/ui/block-menu-components.js +1 -3
  12. package/dist/cjs/ui/block-menu.js +38 -33
  13. package/dist/cjs/ui/copy-link.js +2 -2
  14. package/dist/cjs/ui/delete-section.js +1 -8
  15. package/dist/es2019/editor-commands/transform-node-utils/nodeChecks.js +23 -0
  16. package/dist/es2019/editor-commands/transform-node-utils/steps/flattenListStep.js +7 -6
  17. package/dist/es2019/editor-commands/transform-node-utils/steps/listToDecisionListStep.js +3 -4
  18. package/dist/es2019/editor-commands/transform-node-utils/steps/listToListStep.js +11 -12
  19. package/dist/es2019/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.js +18 -0
  20. package/dist/es2019/editor-commands/transform-node-utils/transform.js +11 -11
  21. package/dist/es2019/editor-commands/transform-node-utils/utils.js +19 -4
  22. package/dist/es2019/editor-commands/transform-node-utils/wrapIntoListStep.js +29 -7
  23. package/dist/es2019/editor-commands/transformNode.js +3 -2
  24. package/dist/es2019/ui/block-menu-components.js +1 -3
  25. package/dist/es2019/ui/block-menu.js +38 -33
  26. package/dist/es2019/ui/copy-link.js +2 -2
  27. package/dist/es2019/ui/delete-section.js +0 -7
  28. package/dist/esm/editor-commands/transform-node-utils/nodeChecks.js +27 -0
  29. package/dist/esm/editor-commands/transform-node-utils/steps/flattenListStep.js +7 -12
  30. package/dist/esm/editor-commands/transform-node-utils/steps/listToDecisionListStep.js +3 -4
  31. package/dist/esm/editor-commands/transform-node-utils/steps/listToListStep.js +11 -12
  32. package/dist/esm/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.js +16 -0
  33. package/dist/esm/editor-commands/transform-node-utils/transform.js +11 -11
  34. package/dist/esm/editor-commands/transform-node-utils/utils.js +19 -6
  35. package/dist/esm/editor-commands/transform-node-utils/wrapIntoListStep.js +29 -7
  36. package/dist/esm/editor-commands/transformNode.js +3 -2
  37. package/dist/esm/ui/block-menu-components.js +1 -3
  38. package/dist/esm/ui/block-menu.js +38 -33
  39. package/dist/esm/ui/copy-link.js +2 -2
  40. package/dist/esm/ui/delete-section.js +1 -8
  41. package/dist/types/editor-commands/transform-node-utils/nodeChecks.d.ts +17 -0
  42. package/dist/types/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.d.ts +9 -0
  43. package/dist/types/editor-commands/transform-node-utils/utils.d.ts +8 -1
  44. package/dist/types/editor-commands/transform-node-utils/wrapIntoListStep.d.ts +7 -1
  45. package/dist/types/ui/delete-section.d.ts +1 -4
  46. package/dist/types-ts4.5/editor-commands/transform-node-utils/nodeChecks.d.ts +17 -0
  47. package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/wrapTextToCodeblock.d.ts +9 -0
  48. package/dist/types-ts4.5/editor-commands/transform-node-utils/utils.d.ts +8 -1
  49. package/dist/types-ts4.5/editor-commands/transform-node-utils/wrapIntoListStep.d.ts +7 -1
  50. package/dist/types-ts4.5/ui/delete-section.d.ts +1 -4
  51. package/package.json +4 -4
@@ -1,6 +1,5 @@
1
1
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
2
- import { isListType } from '../utils';
3
-
2
+ import { isListWithIndentation } from '../nodeChecks';
4
3
  /**
5
4
  * Recursively converts nested lists to the target list type.
6
5
  * This function handles the conversion of both the list container and its items,
@@ -14,13 +13,13 @@ const transformList = (node, targetListType, targetItemType, unsupportedContent)
14
13
  const schema = node.type.schema;
15
14
  const taskListType = schema.nodes.taskList;
16
15
  const isSourceTaskList = node.type === taskListType;
17
- const isTargetTaskList = targetListType === 'taskList';
16
+ const isTargetTaskList = targetListType === taskListType.name;
18
17
  const convertFromTaskListStructure = (node, targetListType, targetItemType) => {
19
18
  const schema = node.type.schema;
20
19
  const targetListNodeType = schema.nodes[targetListType];
21
20
  const transformedContent = [];
22
21
  node.forEach(child => {
23
- if (isListType(child, schema)) {
22
+ if (isListWithIndentation(child.type.name, schema)) {
24
23
  // This is a nested list - it should become a child of the previous item
25
24
  if (transformedContent.length > 0) {
26
25
  const previousItem = transformedContent[transformedContent.length - 1];
@@ -32,7 +31,7 @@ const transformList = (node, targetListType, targetItemType, unsupportedContent)
32
31
  }
33
32
  // If there's no previous item, skip this nested list (orphaned)
34
33
  } else {
35
- const transformedItem = transformListItem(child, targetItemType, targetListType);
34
+ const transformedItem = transformListItem(child, targetListType, targetItemType);
36
35
  if (transformedItem) {
37
36
  transformedContent.push(transformedItem);
38
37
  }
@@ -45,19 +44,19 @@ const transformList = (node, targetListType, targetItemType, unsupportedContent)
45
44
  const targetListNodeType = schema.nodes[targetListType];
46
45
  const transformedContent = [];
47
46
  node.forEach(itemNode => {
48
- const transformedItem = transformListItem(itemNode, targetItemType, targetListType, true);
47
+ const transformedItem = transformListItem(itemNode, targetListType, targetItemType, true);
49
48
  if (transformedItem) {
50
49
  transformedContent.push(transformedItem);
51
50
  }
52
51
  itemNode.forEach(child => {
53
- if (isListType(child, schema)) {
52
+ if (isListWithIndentation(child.type.name, schema)) {
54
53
  transformedContent.push(transformList(child, targetListType, targetItemType, unsupportedContent));
55
54
  }
56
55
  });
57
56
  });
58
57
  return targetListNodeType.create(node.attrs, transformedContent);
59
58
  };
60
- const transformListItem = (itemNode, targetItemType, targetListType, excludeNestedLists = false) => {
59
+ const transformListItem = (itemNode, targetListType, targetItemType, excludeNestedLists = false) => {
61
60
  const schema = itemNode.type.schema;
62
61
  const targetItemNodeType = schema.nodes[targetItemType];
63
62
  const isTargetTaskItem = targetItemType === 'taskItem';
@@ -71,7 +70,7 @@ const transformList = (node, targetListType, targetItemType, unsupportedContent)
71
70
  } else if (child.isText) {
72
71
  inlineContent.push(child);
73
72
  // Nested lists will be extracted and placed as siblings in the taskList
74
- } else if (!isListType(child, schema)) {
73
+ } else if (!isListWithIndentation(child.type.name, schema)) {
75
74
  unsupportedContent.push(child);
76
75
  }
77
76
  });
@@ -82,7 +81,7 @@ const transformList = (node, targetListType, targetItemType, unsupportedContent)
82
81
  transformedContent.push(paragraphType.create(null, itemNode.content));
83
82
  } else {
84
83
  itemNode.forEach(child => {
85
- if (isListType(child, schema)) {
84
+ if (isListWithIndentation(child.type.name, schema)) {
86
85
  if (excludeNestedLists) {
87
86
  // Skip nested lists - they will be handled separately as siblings
88
87
  return;
@@ -102,7 +101,7 @@ const transformList = (node, targetListType, targetItemType, unsupportedContent)
102
101
  const targetListNodeType = schema.nodes[targetListType];
103
102
  const transformedContent = [];
104
103
  node.forEach(childNode => {
105
- const transformedItem = isListType(childNode, schema) ? transformList(childNode, targetListType, targetItemType, unsupportedContent) : transformListItem(childNode, targetItemType, targetListType);
104
+ const transformedItem = isListWithIndentation(childNode.type.name, schema) ? transformList(childNode, targetListType, targetItemType, unsupportedContent) : transformListItem(childNode, targetListType, targetItemType);
106
105
  if (transformedItem) {
107
106
  transformedContent.push(transformedItem);
108
107
  }
@@ -187,7 +186,7 @@ export const listToListStep = (nodes, context) => {
187
186
  } = context;
188
187
  const unsupportedContent = [];
189
188
  const transformedNodes = nodes.map(node => {
190
- if (isListType(node, schema)) {
189
+ if (isListWithIndentation(node.type.name, schema)) {
191
190
  const targetItemType = targetNodeTypeName === 'taskList' ? 'taskItem' : 'listItem';
192
191
  return transformList(node, targetNodeTypeName, targetItemType, unsupportedContent);
193
192
  }
@@ -0,0 +1,18 @@
1
+ import { createTextContent } from '../utils';
2
+
3
+ /**
4
+ * Transforms a paragraph (or heading) into a codeBlock by extracting its text content.
5
+ * This step handles the conversion of inline content (including marks) to plain text,
6
+ * which is required because codeBlocks can only contain plain text nodes.
7
+ *
8
+ * Example: paragraph with bold/italic/status → codeBlock with plain text
9
+ */
10
+ export const wrapTextToCodeblockStep = (nodes, context) => {
11
+ const {
12
+ schema
13
+ } = context;
14
+ return nodes.map(node => {
15
+ const codeBlockNode = schema.nodes.codeBlock.createAndFill({}, schema.text(createTextContent(node)));
16
+ return codeBlockNode !== null && codeBlockNode !== void 0 ? codeBlockNode : node;
17
+ });
18
+ };
@@ -8,6 +8,7 @@ import { unwrapLayoutStep } from './steps/unwrapLayoutStep';
8
8
  import { unwrapListStep } from './steps/unwrapListStep';
9
9
  import { wrapBlockquoteToDecisionListStep } from './steps/wrapBlockquoteToDecisionListStep';
10
10
  import { wrapMixedContentStep } from './steps/wrapMixedContentStep';
11
+ import { wrapTextToCodeblockStep } from './steps/wrapTextToCodeblock';
11
12
  import { stubStep } from './stubStep';
12
13
  import { NODE_CATEGORY_BY_TYPE, toNodeTypeValue } from './types';
13
14
  import { unwrapExpandStep } from './unwrapExpandStep';
@@ -16,14 +17,6 @@ import { wrapIntoLayoutStep } from './wrapIntoLayoutStep';
16
17
  import { wrapIntoListStep } from './wrapIntoListStep';
17
18
  import { wrapStep } from './wrapStep';
18
19
 
19
- // Exampled step for overrides:
20
- // - open Block menu on a paragraph, click 'Panel' in the Turn into'
21
- // - expected to put paragraph into a panel
22
- const wrapIntoPanelStep = (nodes, context) => {
23
- const newNode = context.schema.nodes.panel.createAndFill({}, nodes);
24
- return newNode ? [newNode] : [];
25
- };
26
-
27
20
  // Transform steps for combinations of node categories (block/container/list/text)
28
21
  const TRANSFORM_STEPS = {
29
22
  atomic: {
@@ -46,8 +39,8 @@ const TRANSFORM_STEPS = {
46
39
  },
47
40
  text: {
48
41
  atomic: undefined,
49
- container: [stubStep],
50
- list: [stubStep],
42
+ container: [wrapStep],
43
+ list: [wrapIntoListStep],
51
44
  text: [stubStep]
52
45
  }
53
46
  };
@@ -56,7 +49,8 @@ const TRANSFORM_STEPS = {
56
49
  // using generic rules/steps from TRANSFORM_STEPS.
57
50
  const TRANSFORM_STEPS_OVERRIDE = {
58
51
  paragraph: {
59
- panel: [wrapIntoPanelStep]
52
+ codeBlock: [wrapTextToCodeblockStep],
53
+ layoutSection: [wrapIntoLayoutStep]
60
54
  },
61
55
  panel: {
62
56
  layoutSection: [unwrapStep, wrapIntoLayoutStep],
@@ -130,6 +124,12 @@ const TRANSFORM_STEPS_OVERRIDE = {
130
124
  orderedList: [decisionListToListStep],
131
125
  taskList: [decisionListToListStep],
132
126
  layoutSection: [wrapIntoLayoutStep]
127
+ },
128
+ blockCard: {
129
+ layoutSection: [wrapIntoLayoutStep]
130
+ },
131
+ embedCard: {
132
+ layoutSection: [wrapIntoLayoutStep]
133
133
  }
134
134
  };
135
135
  const getTransformStepsForNodeTypes = (selectedNodeTypeName, targetNodeTypeName) => {
@@ -50,10 +50,6 @@ export const getTargetNodeTypeNameInContext = (nodeTypeName, isNested) => {
50
50
  }
51
51
  return nodeTypeName;
52
52
  };
53
- export const isListType = (node, schema) => {
54
- const lists = [schema.nodes.taskList, schema.nodes.bulletList, schema.nodes.orderedList];
55
- return lists.some(list => list === node.type);
56
- };
57
53
 
58
54
  /**
59
55
  * Converts a nestedExpand to a regular expand node.
@@ -100,4 +96,23 @@ export const getBlockNodesInRange = range => {
100
96
  }
101
97
  }
102
98
  return blockNodes;
99
+ };
100
+
101
+ /**
102
+ * Iterates over a nodes children and extracting text content, removing all other inline content and converting
103
+ * hardbreaks to newlines.
104
+ *
105
+ * @param node - The node to create text content from (should be paragraph)
106
+ * @returns The text content string.
107
+ */
108
+ export const createTextContent = node => {
109
+ const textContent = node.children.map(child => {
110
+ if (child.isText) {
111
+ return child.text;
112
+ } else if (child.type.name === 'hardBreak') {
113
+ return '\n';
114
+ }
115
+ return '';
116
+ });
117
+ return textContent.join('');
103
118
  };
@@ -1,13 +1,35 @@
1
- /** wrap nodes into bullet list or numbered list, does not work for task list */
1
+ import { isListWithTextContentOnly } from './nodeChecks';
2
+ const wrapIntoTaskOrDecisionList = (nodes, targetNodeTypeName, schema) => {
3
+ const itemNodeType = targetNodeTypeName === 'taskList' ? schema.nodes.taskItem : schema.nodes.decisionItem;
4
+ const inlineContent = nodes.flatMap(node => {
5
+ if (node.isTextblock) {
6
+ return node.children;
7
+ } else if (node.isText) {
8
+ return [node];
9
+ }
10
+ return [];
11
+ });
12
+ const itemNode = itemNodeType.create({}, inlineContent);
13
+ const outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, itemNode);
14
+ return outputNode ? [outputNode] : nodes;
15
+ };
16
+ const wrapIntoBulletOrOrderedList = (nodes, targetNodeTypeName, schema) => {
17
+ const listItemNode = schema.nodes.listItem.createAndFill({}, nodes);
18
+ const outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, listItemNode);
19
+ return outputNode ? [outputNode] : nodes;
20
+ };
21
+
22
+ /**
23
+ * Wraps nodes into bullet list, numbered list, task list, or decision list.
24
+ *
25
+ * @param nodes - The nodes to wrap.
26
+ * @param context - The transformation context containing schema and target node type.
27
+ * @returns The wrapped nodes.
28
+ */
2
29
  export const wrapIntoListStep = (nodes, context) => {
3
30
  const {
4
31
  schema,
5
32
  targetNodeTypeName
6
33
  } = context;
7
- const listItemNode = schema.nodes.listItem.createAndFill({}, nodes);
8
- const outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, listItemNode);
9
- if (outputNode) {
10
- return [outputNode];
11
- }
12
- return nodes;
34
+ return isListWithTextContentOnly(targetNodeTypeName, schema) ? wrapIntoTaskOrDecisionList(nodes, targetNodeTypeName, schema) : wrapIntoBulletOrOrderedList(nodes, targetNodeTypeName, schema);
13
35
  };
@@ -23,8 +23,9 @@ export const transformNode = api =>
23
23
  $from,
24
24
  $to
25
25
  } = expandSelectionToBlockRange(preservedSelection);
26
- const isNested = isNestedNode(preservedSelection, '');
27
26
  const selectedParent = $from.parent;
27
+ const isParentLayout = selectedParent.type === nodes.layoutColumn;
28
+ const isNestedExceptLayout = isNestedNode(preservedSelection, '') && !isParentLayout;
28
29
  let fragment = Fragment.empty;
29
30
  const isList = isListNode(selectedParent);
30
31
  const slice = tr.doc.slice(isList ? $from.pos - 1 : $from.pos, isList ? $to.pos + 1 : $to.pos);
@@ -33,7 +34,7 @@ export const transformNode = api =>
33
34
  sourceNode: node,
34
35
  targetNodeType: targetType,
35
36
  schema: tr.doc.type.schema,
36
- isNested
37
+ isNested: isNestedExceptLayout
37
38
  });
38
39
  if (outputNode) {
39
40
  fragment = fragment.append(Fragment.fromArray(outputNode));
@@ -188,9 +188,7 @@ export const getBlockMenuComponents = ({
188
188
  component: ({
189
189
  children
190
190
  }) => {
191
- return /*#__PURE__*/React.createElement(DeleteSection, {
192
- api: api
193
- }, children);
191
+ return /*#__PURE__*/React.createElement(DeleteSection, null, children);
194
192
  }
195
193
  }, {
196
194
  type: 'block-menu-item',
@@ -124,7 +124,7 @@ const BlockMenu = ({
124
124
  boundariesElement,
125
125
  scrollableElement
126
126
  }) => {
127
- var _editorView$dom, _ref;
127
+ var _editorView$dom, _ref, _api$analytics3;
128
128
  const {
129
129
  menuTriggerBy,
130
130
  isSelectedViaDragHandle,
@@ -194,6 +194,13 @@ const BlockMenu = ({
194
194
  return tr;
195
195
  });
196
196
  };
197
+ const handleClickOutside = e => {
198
+ // check if the clicked element was another drag handle, if so don't close the menu
199
+ if (e.target instanceof HTMLElement && e.target.closest(DRAG_HANDLE_SELECTOR)) {
200
+ return;
201
+ }
202
+ closeMenu();
203
+ };
197
204
  const closeMenu = () => {
198
205
  api === null || api === void 0 ? void 0 : api.core.actions.execute(({
199
206
  tr
@@ -220,39 +227,37 @@ const BlockMenu = ({
220
227
  popupRef.current = el;
221
228
  }
222
229
  };
223
- if (targetHandleRef instanceof HTMLElement) {
224
- var _api$analytics3;
225
- return /*#__PURE__*/React.createElement(ErrorBoundary, {
226
- component: ACTION_SUBJECT.BLOCK_MENU,
227
- dispatchAnalyticsEvent: api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions.fireAnalyticsEvent,
228
- fallbackComponent: null
229
- }, /*#__PURE__*/React.createElement(PopupWithListeners, {
230
- alignX: 'right',
231
- alignY: 'start',
232
- handleClickOutside: closeMenu,
233
- handleEscapeKeydown: closeMenu,
234
- handleBackspaceDeleteKeydown: handleBackspaceDeleteKeydown,
235
- mountTo: mountTo,
236
- boundariesElement: boundariesElement,
237
- scrollableElement: scrollableElement,
238
- target: targetHandleRef,
239
- zIndex: akEditorFloatingOverlapPanelZIndex,
240
- fitWidth: DEFAULT_MENU_WIDTH,
241
- fitHeight: menuHeight,
242
- preventOverflow: true,
243
- stick: true,
244
- offset: [DRAG_HANDLE_WIDTH + DRAG_HANDLE_OFFSET_PADDING, targetHandleHeightOffset],
245
- focusTrap: openedViaKeyboard ?
246
- // Only enable focus trap when opened via keyboard to make sure the focus is on the first focusable menu item
247
- {
248
- initialFocus: undefined
249
- } : undefined
250
- }, /*#__PURE__*/React.createElement(BlockMenuContent, {
251
- api: api,
252
- setRef: setRef
253
- })));
254
- } else {
230
+ if (!(targetHandleRef instanceof HTMLElement)) {
255
231
  return null;
256
232
  }
233
+ return /*#__PURE__*/React.createElement(ErrorBoundary, {
234
+ component: ACTION_SUBJECT.BLOCK_MENU,
235
+ dispatchAnalyticsEvent: api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions.fireAnalyticsEvent,
236
+ fallbackComponent: null
237
+ }, /*#__PURE__*/React.createElement(PopupWithListeners, {
238
+ alignX: 'right',
239
+ alignY: 'start',
240
+ handleClickOutside: handleClickOutside,
241
+ handleEscapeKeydown: closeMenu,
242
+ handleBackspaceDeleteKeydown: handleBackspaceDeleteKeydown,
243
+ mountTo: mountTo,
244
+ boundariesElement: boundariesElement,
245
+ scrollableElement: scrollableElement,
246
+ target: targetHandleRef,
247
+ zIndex: akEditorFloatingOverlapPanelZIndex,
248
+ fitWidth: DEFAULT_MENU_WIDTH,
249
+ fitHeight: menuHeight,
250
+ preventOverflow: true,
251
+ stick: true,
252
+ offset: [DRAG_HANDLE_WIDTH + DRAG_HANDLE_OFFSET_PADDING, targetHandleHeightOffset],
253
+ focusTrap: openedViaKeyboard ?
254
+ // Only enable focus trap when opened via keyboard to make sure the focus is on the first focusable menu item
255
+ {
256
+ initialFocus: undefined
257
+ } : undefined
258
+ }, /*#__PURE__*/React.createElement(BlockMenuContent, {
259
+ api: api,
260
+ setRef: setRef
261
+ })));
257
262
  };
258
263
  export default injectIntl(BlockMenu);
@@ -84,8 +84,8 @@ const CopyLinkDropdownItemContent = ({
84
84
  });
85
85
  }, [api, blockLinkHashPrefix, getLinkPath, onDropdownOpenChanged, selection]);
86
86
 
87
- // Hide copy link when `platform_editor_adf_with_localid` feature flag is off or when the node is nested or on empty line
88
- if (!fg('platform_editor_adf_with_localid') || !!menuTriggerBy && isNestedNode(selection, menuTriggerBy) || selection !== null && selection !== void 0 && selection.empty) {
87
+ // Hide copy link when `platform_editor_adf_with_localid` feature flag is off or when the node is nested
88
+ if (!fg('platform_editor_adf_with_localid') || !!menuTriggerBy && isNestedNode(selection, menuTriggerBy)) {
89
89
  return null;
90
90
  }
91
91
  return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
@@ -1,15 +1,8 @@
1
1
  import React from 'react';
2
2
  import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
3
3
  export const DeleteSection = ({
4
- api,
5
4
  children
6
5
  }) => {
7
- var _api$selection, _api$selection$shared, _api$selection$shared2;
8
- 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) === null || _api$selection$shared === void 0 ? void 0 : (_api$selection$shared2 = _api$selection$shared.currentState()) === null || _api$selection$shared2 === void 0 ? void 0 : _api$selection$shared2.selection;
9
- const isEmptyLineSelected = !!(selection !== null && selection !== void 0 && selection.empty);
10
- if (isEmptyLineSelected) {
11
- return null;
12
- }
13
6
  return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
14
7
  hasSeparator: true
15
8
  }, children);
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Checks if a node is a list type that supports indentation (bulletList, orderedList, taskList).
3
+ *
4
+ * @param node - The node to check.
5
+ * @param schema - ProseMirror schema for check
6
+ * @returns True if the node is a list type, false otherwise.
7
+ */
8
+ export var isListWithIndentation = function isListWithIndentation(nodeTypeName, schema) {
9
+ var lists = [schema.nodes.taskList, schema.nodes.bulletList, schema.nodes.orderedList];
10
+ return lists.some(function (list) {
11
+ return list.name === nodeTypeName;
12
+ });
13
+ };
14
+
15
+ /**
16
+ * Checks if a node is a list where its list items only support text content (taskList or decisionList).
17
+ *
18
+ * @param nodeTypeName - The node type name to check.
19
+ * @param schema - ProseMirror schema for check
20
+ * @returns True if the node is a list text type, false otherwise.
21
+ */
22
+ export var isListWithTextContentOnly = function isListWithTextContentOnly(nodeTypeName, schema) {
23
+ var lists = [schema.nodes.taskList, schema.nodes.decisionList];
24
+ return lists.some(function (list) {
25
+ return list.name === nodeTypeName;
26
+ });
27
+ };
@@ -1,7 +1,9 @@
1
1
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
2
- var extractNestedLists = function extractNestedLists(node, listTypes, itemTypes, schema) {
2
+ import { isListWithIndentation } from '../nodeChecks';
3
+ var extractNestedLists = function extractNestedLists(node, schema) {
3
4
  var items = [];
4
5
  var paragraph = schema.nodes.paragraph;
6
+ var itemTypes = [schema.nodes.listItem, schema.nodes.taskItem];
5
7
  var _extract = function extract(currentNode) {
6
8
  currentNode.forEach(function (child) {
7
9
  if (itemTypes.some(function (type) {
@@ -10,9 +12,7 @@ var extractNestedLists = function extractNestedLists(node, listTypes, itemTypes,
10
12
  var contentWithoutNestedLists = [];
11
13
  var nestedLists = [];
12
14
  child.forEach(function (grandChild) {
13
- if (listTypes.some(function (type) {
14
- return grandChild.type === type;
15
- })) {
15
+ if (isListWithIndentation(grandChild.type.name, schema)) {
16
16
  nestedLists.push(grandChild);
17
17
  } else if (grandChild.isText) {
18
18
  contentWithoutNestedLists.push(paragraph.createAndFill({}, grandChild));
@@ -24,9 +24,7 @@ var extractNestedLists = function extractNestedLists(node, listTypes, itemTypes,
24
24
  nestedLists.forEach(function (nestedList) {
25
25
  _extract(nestedList);
26
26
  });
27
- } else if (listTypes.some(function (type) {
28
- return child.type === type;
29
- })) {
27
+ } else if (isListWithIndentation(child.type.name, schema)) {
30
28
  _extract(child);
31
29
  }
32
30
  });
@@ -65,12 +63,9 @@ var extractNestedLists = function extractNestedLists(node, listTypes, itemTypes,
65
63
  * TODO: Lists with mixed types (e.g. bulletList with a taskItem) doesn't full flatten
66
64
  */
67
65
  export var flattenListStep = function flattenListStep(nodes, context) {
68
- var listTypes = [context.schema.nodes.bulletList, context.schema.nodes.orderedList, context.schema.nodes.taskList];
69
66
  return nodes.map(function (node) {
70
- if (listTypes.some(function (type) {
71
- return node.type === type;
72
- })) {
73
- return node.copy(Fragment.from(extractNestedLists(node, listTypes, [context.schema.nodes.listItem, context.schema.nodes.taskItem], context.schema)));
67
+ if (isListWithIndentation(node.type.name, context.schema)) {
68
+ return node.copy(Fragment.from(extractNestedLists(node, context.schema)));
74
69
  }
75
70
  return node;
76
71
  });
@@ -1,6 +1,5 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
- import { isListType } from '../utils';
3
-
2
+ import { isListWithIndentation } from '../nodeChecks';
4
3
  /**
5
4
  * Transforms a bulletList, orderedList, or taskList into a decisionList.
6
5
  *
@@ -29,7 +28,7 @@ export var listToDecisionListStep = function listToDecisionListStep(nodes, conte
29
28
  var paragraphType = schema.nodes.paragraph;
30
29
  var unsupportedContent = [];
31
30
  var transformedNodes = nodes.map(function (node) {
32
- if (!isListType(node, schema)) {
31
+ if (!isListWithIndentation(node.type.name, schema)) {
33
32
  return node;
34
33
  }
35
34
  var decisionItems = [];
@@ -41,7 +40,7 @@ export var listToDecisionListStep = function listToDecisionListStep(nodes, conte
41
40
  itemContent.push.apply(itemContent, _toConsumableArray(child.children));
42
41
  } else if (child.isText) {
43
42
  itemContent.push(child);
44
- } else if (!isListType(child, schema)) {
43
+ } else if (!isListWithIndentation(child.type.name, schema)) {
45
44
  unsupportedContent.push(child);
46
45
  }
47
46
  });
@@ -1,7 +1,6 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
3
- import { isListType } from '../utils';
4
-
3
+ import { isListWithIndentation } from '../nodeChecks';
5
4
  /**
6
5
  * Recursively converts nested lists to the target list type.
7
6
  * This function handles the conversion of both the list container and its items,
@@ -15,13 +14,13 @@ var _transformList = function transformList(node, targetListType, targetItemType
15
14
  var schema = node.type.schema;
16
15
  var taskListType = schema.nodes.taskList;
17
16
  var isSourceTaskList = node.type === taskListType;
18
- var isTargetTaskList = targetListType === 'taskList';
17
+ var isTargetTaskList = targetListType === taskListType.name;
19
18
  var convertFromTaskListStructure = function convertFromTaskListStructure(node, targetListType, targetItemType) {
20
19
  var schema = node.type.schema;
21
20
  var targetListNodeType = schema.nodes[targetListType];
22
21
  var transformedContent = [];
23
22
  node.forEach(function (child) {
24
- if (isListType(child, schema)) {
23
+ if (isListWithIndentation(child.type.name, schema)) {
25
24
  // This is a nested list - it should become a child of the previous item
26
25
  if (transformedContent.length > 0) {
27
26
  var previousItem = transformedContent[transformedContent.length - 1];
@@ -33,7 +32,7 @@ var _transformList = function transformList(node, targetListType, targetItemType
33
32
  }
34
33
  // If there's no previous item, skip this nested list (orphaned)
35
34
  } else {
36
- var transformedItem = transformListItem(child, targetItemType, targetListType);
35
+ var transformedItem = transformListItem(child, targetListType, targetItemType);
37
36
  if (transformedItem) {
38
37
  transformedContent.push(transformedItem);
39
38
  }
@@ -46,19 +45,19 @@ var _transformList = function transformList(node, targetListType, targetItemType
46
45
  var targetListNodeType = schema.nodes[targetListType];
47
46
  var transformedContent = [];
48
47
  node.forEach(function (itemNode) {
49
- var transformedItem = transformListItem(itemNode, targetItemType, targetListType, true);
48
+ var transformedItem = transformListItem(itemNode, targetListType, targetItemType, true);
50
49
  if (transformedItem) {
51
50
  transformedContent.push(transformedItem);
52
51
  }
53
52
  itemNode.forEach(function (child) {
54
- if (isListType(child, schema)) {
53
+ if (isListWithIndentation(child.type.name, schema)) {
55
54
  transformedContent.push(_transformList(child, targetListType, targetItemType, unsupportedContent));
56
55
  }
57
56
  });
58
57
  });
59
58
  return targetListNodeType.create(node.attrs, transformedContent);
60
59
  };
61
- var transformListItem = function transformListItem(itemNode, targetItemType, targetListType) {
60
+ var transformListItem = function transformListItem(itemNode, targetListType, targetItemType) {
62
61
  var excludeNestedLists = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
63
62
  var schema = itemNode.type.schema;
64
63
  var targetItemNodeType = schema.nodes[targetItemType];
@@ -73,7 +72,7 @@ var _transformList = function transformList(node, targetListType, targetItemType
73
72
  } else if (child.isText) {
74
73
  inlineContent.push(child);
75
74
  // Nested lists will be extracted and placed as siblings in the taskList
76
- } else if (!isListType(child, schema)) {
75
+ } else if (!isListWithIndentation(child.type.name, schema)) {
77
76
  unsupportedContent.push(child);
78
77
  }
79
78
  });
@@ -84,7 +83,7 @@ var _transformList = function transformList(node, targetListType, targetItemType
84
83
  transformedContent.push(paragraphType.create(null, itemNode.content));
85
84
  } else {
86
85
  itemNode.forEach(function (child) {
87
- if (isListType(child, schema)) {
86
+ if (isListWithIndentation(child.type.name, schema)) {
88
87
  if (excludeNestedLists) {
89
88
  // Skip nested lists - they will be handled separately as siblings
90
89
  return;
@@ -104,7 +103,7 @@ var _transformList = function transformList(node, targetListType, targetItemType
104
103
  var targetListNodeType = schema.nodes[targetListType];
105
104
  var transformedContent = [];
106
105
  node.forEach(function (childNode) {
107
- var transformedItem = isListType(childNode, schema) ? _transformList(childNode, targetListType, targetItemType, unsupportedContent) : transformListItem(childNode, targetItemType, targetListType);
106
+ var transformedItem = isListWithIndentation(childNode.type.name, schema) ? _transformList(childNode, targetListType, targetItemType, unsupportedContent) : transformListItem(childNode, targetListType, targetItemType);
108
107
  if (transformedItem) {
109
108
  transformedContent.push(transformedItem);
110
109
  }
@@ -187,7 +186,7 @@ export var listToListStep = function listToListStep(nodes, context) {
187
186
  targetNodeTypeName = context.targetNodeTypeName;
188
187
  var unsupportedContent = [];
189
188
  var transformedNodes = nodes.map(function (node) {
190
- if (isListType(node, schema)) {
189
+ if (isListWithIndentation(node.type.name, schema)) {
191
190
  var targetItemType = targetNodeTypeName === 'taskList' ? 'taskItem' : 'listItem';
192
191
  return _transformList(node, targetNodeTypeName, targetItemType, unsupportedContent);
193
192
  }
@@ -0,0 +1,16 @@
1
+ import { createTextContent } from '../utils';
2
+
3
+ /**
4
+ * Transforms a paragraph (or heading) into a codeBlock by extracting its text content.
5
+ * This step handles the conversion of inline content (including marks) to plain text,
6
+ * which is required because codeBlocks can only contain plain text nodes.
7
+ *
8
+ * Example: paragraph with bold/italic/status → codeBlock with plain text
9
+ */
10
+ export var wrapTextToCodeblockStep = function wrapTextToCodeblockStep(nodes, context) {
11
+ var schema = context.schema;
12
+ return nodes.map(function (node) {
13
+ var codeBlockNode = schema.nodes.codeBlock.createAndFill({}, schema.text(createTextContent(node)));
14
+ return codeBlockNode !== null && codeBlockNode !== void 0 ? codeBlockNode : node;
15
+ });
16
+ };