@atlaskit/editor-plugin-block-menu 0.0.16 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/blockMenuPlugin.js +2 -2
  3. package/dist/cjs/editor-commands/formatNode.js +37 -4
  4. package/dist/cjs/editor-commands/transforms/block-transforms.js +1 -1
  5. package/dist/cjs/editor-commands/transforms/list-transforms.js +47 -12
  6. package/dist/cjs/editor-commands/transforms/transformNodeToTargetType.js +13 -3
  7. package/dist/cjs/ui/block-menu-renderer.js +3 -0
  8. package/dist/es2019/blockMenuPlugin.js +2 -2
  9. package/dist/es2019/editor-commands/formatNode.js +39 -4
  10. package/dist/es2019/editor-commands/transforms/block-transforms.js +1 -1
  11. package/dist/es2019/editor-commands/transforms/list-transforms.js +52 -9
  12. package/dist/es2019/editor-commands/transforms/transformNodeToTargetType.js +13 -3
  13. package/dist/es2019/ui/block-menu-renderer.js +3 -0
  14. package/dist/esm/blockMenuPlugin.js +2 -2
  15. package/dist/esm/editor-commands/formatNode.js +37 -4
  16. package/dist/esm/editor-commands/transforms/block-transforms.js +1 -1
  17. package/dist/esm/editor-commands/transforms/list-transforms.js +43 -8
  18. package/dist/esm/editor-commands/transforms/transformNodeToTargetType.js +13 -3
  19. package/dist/esm/ui/block-menu-renderer.js +3 -0
  20. package/dist/types/blockMenuPluginType.d.ts +1 -2
  21. package/dist/types/editor-commands/formatNode.d.ts +1 -3
  22. package/dist/types/editor-commands/transforms/list-transforms.d.ts +9 -3
  23. package/dist/types-ts4.5/blockMenuPluginType.d.ts +1 -2
  24. package/dist/types-ts4.5/editor-commands/formatNode.d.ts +1 -3
  25. package/dist/types-ts4.5/editor-commands/transforms/list-transforms.d.ts +9 -3
  26. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-block-menu
2
2
 
3
+ ## 0.0.18
4
+
5
+ ### Patch Changes
6
+
7
+ - [`942b7b9e97c21`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/942b7b9e97c21) -
8
+ Support nested block menu via selection extension config
9
+ - Updated dependencies
10
+
11
+ ## 0.0.17
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
3
17
  ## 0.0.16
4
18
 
5
19
  ### Patch Changes
@@ -36,8 +36,8 @@ var blockMenuPlugin = exports.blockMenuPlugin = function blockMenuPlugin(_ref) {
36
36
  }
37
37
  },
38
38
  commands: {
39
- formatNode: function formatNode(currentNode, targetType) {
40
- return (0, _formatNode2.formatNode)(currentNode, targetType);
39
+ formatNode: function formatNode(targetType) {
40
+ return (0, _formatNode2.formatNode)(targetType);
41
41
  }
42
42
  },
43
43
  contentComponent: function contentComponent(_ref2) {
@@ -4,19 +4,52 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.formatNode = void 0;
7
+ var _utils = require("@atlaskit/editor-prosemirror/utils");
7
8
  var _transformNodeToTargetType = require("./transforms/transformNodeToTargetType");
8
9
  /**
9
10
  * Formats the current node or selection to the specified target type
10
- * @param currentNode - The current node
11
11
  * @param targetType - The target node type to convert to
12
12
  */
13
- var formatNode = exports.formatNode = function formatNode(currentNode, targetType) {
13
+ var formatNode = exports.formatNode = function formatNode(targetType) {
14
14
  return function (_ref) {
15
15
  var tr = _ref.tr;
16
16
  var selection = tr.selection;
17
+ var nodes = tr.doc.type.schema.nodes;
18
+
19
+ // Find the node to format from the current selection
20
+ var nodeToFormat;
21
+ var nodePos = null;
22
+
23
+ // Try to find the current node from selection
24
+ var selectedNode = (0, _utils.findSelectedNodeOfType)([nodes.paragraph, nodes.heading, nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.layoutSection])(selection);
25
+ if (selectedNode) {
26
+ nodeToFormat = selectedNode.node;
27
+ nodePos = selectedNode.pos;
28
+ } else {
29
+ // Try to find parent node (including list parents)
30
+ var parentNode = (0, _utils.findParentNodeOfType)([nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.listItem, nodes.layoutSection])(selection);
31
+ if (parentNode) {
32
+ nodeToFormat = parentNode.node;
33
+ nodePos = parentNode.pos;
34
+
35
+ // Special case: if we found a listItem, check if we need the parent list instead
36
+ if (parentNode.node.type === nodes.listItem) {
37
+ var listParent = (0, _utils.findParentNodeOfType)([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
38
+ if (listParent) {
39
+ // For list transformations, we want the list parent, not the listItem
40
+ nodeToFormat = listParent.node;
41
+ nodePos = listParent.pos;
42
+ }
43
+ }
44
+ }
45
+ }
46
+ if (!nodeToFormat) {
47
+ nodeToFormat = selection.$from.node();
48
+ nodePos = selection.$from.pos;
49
+ }
17
50
  try {
18
- return (0, _transformNodeToTargetType.transformNodeToTargetType)(tr, currentNode, selection.from, targetType);
19
- } catch (e) {
51
+ return (0, _transformNodeToTargetType.transformNodeToTargetType)(tr, nodeToFormat, nodePos, targetType);
52
+ } catch (_unused) {
20
53
  return null;
21
54
  }
22
55
  };
@@ -20,7 +20,7 @@ var transformBlockNode = exports.transformBlockNode = function transformBlockNod
20
20
 
21
21
  // Handle transformation to list types
22
22
  if ((0, _utils.isListNodeType)(targetNodeType)) {
23
- return (0, _listTransforms.transformToList)();
23
+ return (0, _listTransforms.transformToList)(context);
24
24
  }
25
25
 
26
26
  // Handle transformation to container types (panel, expand, blockquote)
@@ -4,35 +4,54 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.transformToList = exports.transformListNode = exports.transformBetweenListTypes = exports.liftListToBlockType = void 0;
7
- var _utils = require("./utils");
7
+ var _transform = require("@atlaskit/editor-prosemirror/transform");
8
+ var _utils = require("@atlaskit/editor-prosemirror/utils");
9
+ var _utils2 = require("./utils");
8
10
  /**
9
11
  * Transform selection to list type
10
12
  */
11
- var transformToList = exports.transformToList = function transformToList() {
12
- return null;
13
+ var transformToList = exports.transformToList = function transformToList(_ref) {
14
+ var tr = _ref.tr,
15
+ targetNodeType = _ref.targetNodeType,
16
+ targetAttrs = _ref.targetAttrs;
17
+ // Wrap selection in list of target type
18
+ var _tr$selection = tr.selection,
19
+ $from = _tr$selection.$from,
20
+ $to = _tr$selection.$to;
21
+ var range = $from.blockRange($to);
22
+ if (!range) {
23
+ return null;
24
+ }
25
+
26
+ // Find if we can wrap the selection in the target list type
27
+ var wrapping = (0, _transform.findWrapping)(range, targetNodeType, targetAttrs);
28
+ if (!wrapping) {
29
+ return null;
30
+ }
31
+ tr.wrap(range, wrapping);
32
+ return tr;
13
33
  };
14
34
 
15
35
  /**
16
36
  * Transform list nodes
17
37
  */
18
- var transformListNode = exports.transformListNode = function transformListNode(_ref) {
19
- var targetNodeType = _ref.targetNodeType;
38
+ var transformListNode = exports.transformListNode = function transformListNode(context) {
39
+ var targetNodeType = context.targetNodeType;
20
40
  // Transform list to block type
21
- if ((0, _utils.isBlockNodeType)(targetNodeType)) {
41
+ if ((0, _utils2.isBlockNodeType)(targetNodeType)) {
22
42
  // Lift list items out of the list and convert to target block type
23
43
  return null;
24
44
  }
25
45
 
26
46
  // Transform list to container type
27
- if ((0, _utils.isContainerNodeType)(targetNodeType)) {
47
+ if ((0, _utils2.isContainerNodeType)(targetNodeType)) {
28
48
  // Lift list items out of the list and convert to container type
29
49
  return null;
30
50
  }
31
51
 
32
52
  // Transform between list types
33
- if ((0, _utils.isListNodeType)(targetNodeType)) {
34
- // Lift list items out of the list and convert to the other list type
35
- return null;
53
+ if ((0, _utils2.isListNodeType)(targetNodeType)) {
54
+ return transformBetweenListTypes(context);
36
55
  }
37
56
  return null;
38
57
  };
@@ -48,6 +67,22 @@ var liftListToBlockType = exports.liftListToBlockType = function liftListToBlock
48
67
  /**
49
68
  * Transform between different list types
50
69
  */
51
- var transformBetweenListTypes = exports.transformBetweenListTypes = function transformBetweenListTypes() {
52
- return null;
70
+ var transformBetweenListTypes = exports.transformBetweenListTypes = function transformBetweenListTypes(_ref2) {
71
+ var tr = _ref2.tr,
72
+ targetNodeType = _ref2.targetNodeType;
73
+ var selection = tr.selection;
74
+ var nodes = tr.doc.type.schema.nodes;
75
+
76
+ // Find the list node
77
+ var listNode = (0, _utils.findParentNodeOfType)([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
78
+ if (!listNode) {
79
+ return null;
80
+ }
81
+ try {
82
+ // Change the list type while preserving content
83
+ tr.setNodeMarkup(listNode.pos, targetNodeType);
84
+ return tr;
85
+ } catch (e) {
86
+ return null;
87
+ }
53
88
  };
@@ -18,8 +18,18 @@ function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType) {
18
18
  targetAttrs = targetNodeInfo.attrs;
19
19
 
20
20
  // Early return if trying to transform to the same type
21
- if (sourceNode.type === targetNodeType) {
22
- return tr; // No transformation needed
21
+ if (sourceNode.type.name === targetNodeType.name) {
22
+ // For headings, also check if the level matches
23
+ if (targetNodeType.name === 'heading') {
24
+ var _sourceNode$attrs;
25
+ var sourceLevel = (_sourceNode$attrs = sourceNode.attrs) === null || _sourceNode$attrs === void 0 ? void 0 : _sourceNode$attrs.level;
26
+ var targetLevel = targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level;
27
+ if (sourceLevel === targetLevel) {
28
+ return tr;
29
+ }
30
+ } else {
31
+ return tr;
32
+ }
23
33
  }
24
34
 
25
35
  // Prepare transformation context
@@ -43,7 +53,7 @@ function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType) {
43
53
  return (0, _containerTransforms.transformContainerNode)(transformationContext);
44
54
  }
45
55
  return null;
46
- } catch (e) {
56
+ } catch (_unused) {
47
57
  // Node transformation failed
48
58
  return null;
49
59
  }
@@ -52,6 +52,9 @@ var BlockMenuRenderer = exports.BlockMenuRenderer = function BlockMenuRenderer(_
52
52
  return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, menuSections.map(function (section) {
53
53
  // Get all items for the current section, including nested menus, and sort them by rank
54
54
  var currentSectionItemsSorted = getSortedChildren([].concat((0, _toConsumableArray2.default)(menuItems), (0, _toConsumableArray2.default)(nestedMenus)), section.key);
55
+ if (currentSectionItemsSorted.length === 0) {
56
+ return null;
57
+ }
55
58
 
56
59
  // iterate over the current section items, if it is nested menu, get their children, sort them
57
60
  // if they are menu items, just render as they are sorted above
@@ -30,8 +30,8 @@ export const blockMenuPlugin = ({
30
30
  }
31
31
  },
32
32
  commands: {
33
- formatNode: (currentNode, targetType) => {
34
- return formatNode(currentNode, targetType);
33
+ formatNode: targetType => {
34
+ return formatNode(targetType);
35
35
  }
36
36
  },
37
37
  contentComponent({
@@ -1,19 +1,54 @@
1
+ import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
1
2
  import { transformNodeToTargetType } from './transforms/transformNodeToTargetType';
2
3
  /**
3
4
  * Formats the current node or selection to the specified target type
4
- * @param currentNode - The current node
5
5
  * @param targetType - The target node type to convert to
6
6
  */
7
- export const formatNode = (currentNode, targetType) => {
7
+ export const formatNode = targetType => {
8
8
  return ({
9
9
  tr
10
10
  }) => {
11
11
  const {
12
12
  selection
13
13
  } = tr;
14
+ const {
15
+ nodes
16
+ } = tr.doc.type.schema;
17
+
18
+ // Find the node to format from the current selection
19
+ let nodeToFormat;
20
+ let nodePos = null;
21
+
22
+ // Try to find the current node from selection
23
+ const selectedNode = findSelectedNodeOfType([nodes.paragraph, nodes.heading, nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.layoutSection])(selection);
24
+ if (selectedNode) {
25
+ nodeToFormat = selectedNode.node;
26
+ nodePos = selectedNode.pos;
27
+ } else {
28
+ // Try to find parent node (including list parents)
29
+ const parentNode = findParentNodeOfType([nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.listItem, nodes.layoutSection])(selection);
30
+ if (parentNode) {
31
+ nodeToFormat = parentNode.node;
32
+ nodePos = parentNode.pos;
33
+
34
+ // Special case: if we found a listItem, check if we need the parent list instead
35
+ if (parentNode.node.type === nodes.listItem) {
36
+ const listParent = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
37
+ if (listParent) {
38
+ // For list transformations, we want the list parent, not the listItem
39
+ nodeToFormat = listParent.node;
40
+ nodePos = listParent.pos;
41
+ }
42
+ }
43
+ }
44
+ }
45
+ if (!nodeToFormat) {
46
+ nodeToFormat = selection.$from.node();
47
+ nodePos = selection.$from.pos;
48
+ }
14
49
  try {
15
- return transformNodeToTargetType(tr, currentNode, selection.from, targetType);
16
- } catch (e) {
50
+ return transformNodeToTargetType(tr, nodeToFormat, nodePos, targetType);
51
+ } catch {
17
52
  return null;
18
53
  }
19
54
  };
@@ -21,7 +21,7 @@ export const transformBlockNode = context => {
21
21
 
22
22
  // Handle transformation to list types
23
23
  if (isListNodeType(targetNodeType)) {
24
- return transformToList();
24
+ return transformToList(context);
25
25
  }
26
26
 
27
27
  // Handle transformation to container types (panel, expand, blockquote)
@@ -1,18 +1,41 @@
1
+ import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
2
+ import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
1
3
  import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
2
4
 
3
5
  /**
4
6
  * Transform selection to list type
5
7
  */
6
- export const transformToList = () => {
7
- return null;
8
+ export const transformToList = ({
9
+ tr,
10
+ targetNodeType,
11
+ targetAttrs
12
+ }) => {
13
+ // Wrap selection in list of target type
14
+ const {
15
+ $from,
16
+ $to
17
+ } = tr.selection;
18
+ const range = $from.blockRange($to);
19
+ if (!range) {
20
+ return null;
21
+ }
22
+
23
+ // Find if we can wrap the selection in the target list type
24
+ const wrapping = findWrapping(range, targetNodeType, targetAttrs);
25
+ if (!wrapping) {
26
+ return null;
27
+ }
28
+ tr.wrap(range, wrapping);
29
+ return tr;
8
30
  };
9
31
 
10
32
  /**
11
33
  * Transform list nodes
12
34
  */
13
- export const transformListNode = ({
14
- targetNodeType
15
- }) => {
35
+ export const transformListNode = context => {
36
+ const {
37
+ targetNodeType
38
+ } = context;
16
39
  // Transform list to block type
17
40
  if (isBlockNodeType(targetNodeType)) {
18
41
  // Lift list items out of the list and convert to target block type
@@ -27,8 +50,7 @@ export const transformListNode = ({
27
50
 
28
51
  // Transform between list types
29
52
  if (isListNodeType(targetNodeType)) {
30
- // Lift list items out of the list and convert to the other list type
31
- return null;
53
+ return transformBetweenListTypes(context);
32
54
  }
33
55
  return null;
34
56
  };
@@ -44,6 +66,27 @@ export const liftListToBlockType = () => {
44
66
  /**
45
67
  * Transform between different list types
46
68
  */
47
- export const transformBetweenListTypes = () => {
48
- return null;
69
+ export const transformBetweenListTypes = ({
70
+ tr,
71
+ targetNodeType
72
+ }) => {
73
+ const {
74
+ selection
75
+ } = tr;
76
+ const {
77
+ nodes
78
+ } = tr.doc.type.schema;
79
+
80
+ // Find the list node
81
+ const listNode = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
82
+ if (!listNode) {
83
+ return null;
84
+ }
85
+ try {
86
+ // Change the list type while preserving content
87
+ tr.setNodeMarkup(listNode.pos, targetNodeType);
88
+ return tr;
89
+ } catch (e) {
90
+ return null;
91
+ }
49
92
  };
@@ -16,8 +16,18 @@ export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType)
16
16
  } = targetNodeInfo;
17
17
 
18
18
  // Early return if trying to transform to the same type
19
- if (sourceNode.type === targetNodeType) {
20
- return tr; // No transformation needed
19
+ if (sourceNode.type.name === targetNodeType.name) {
20
+ // For headings, also check if the level matches
21
+ if (targetNodeType.name === 'heading') {
22
+ var _sourceNode$attrs;
23
+ const sourceLevel = (_sourceNode$attrs = sourceNode.attrs) === null || _sourceNode$attrs === void 0 ? void 0 : _sourceNode$attrs.level;
24
+ const targetLevel = targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level;
25
+ if (sourceLevel === targetLevel) {
26
+ return tr;
27
+ }
28
+ } else {
29
+ return tr;
30
+ }
21
31
  }
22
32
 
23
33
  // Prepare transformation context
@@ -41,7 +51,7 @@ export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType)
41
51
  return transformContainerNode(transformationContext);
42
52
  }
43
53
  return null;
44
- } catch (e) {
54
+ } catch {
45
55
  // Node transformation failed
46
56
  return null;
47
57
  }
@@ -31,6 +31,9 @@ export const BlockMenuRenderer = ({
31
31
  return /*#__PURE__*/React.createElement(Fragment, null, menuSections.map(section => {
32
32
  // Get all items for the current section, including nested menus, and sort them by rank
33
33
  const currentSectionItemsSorted = getSortedChildren([...menuItems, ...nestedMenus], section.key);
34
+ if (currentSectionItemsSorted.length === 0) {
35
+ return null;
36
+ }
34
37
 
35
38
  // iterate over the current section items, if it is nested menu, get their children, sort them
36
39
  // if they are menu items, just render as they are sorted above
@@ -29,8 +29,8 @@ export var blockMenuPlugin = function blockMenuPlugin(_ref) {
29
29
  }
30
30
  },
31
31
  commands: {
32
- formatNode: function formatNode(currentNode, targetType) {
33
- return _formatNode(currentNode, targetType);
32
+ formatNode: function formatNode(targetType) {
33
+ return _formatNode(targetType);
34
34
  }
35
35
  },
36
36
  contentComponent: function contentComponent(_ref2) {
@@ -1,16 +1,49 @@
1
+ import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
1
2
  import { transformNodeToTargetType } from './transforms/transformNodeToTargetType';
2
3
  /**
3
4
  * Formats the current node or selection to the specified target type
4
- * @param currentNode - The current node
5
5
  * @param targetType - The target node type to convert to
6
6
  */
7
- export var formatNode = function formatNode(currentNode, targetType) {
7
+ export var formatNode = function formatNode(targetType) {
8
8
  return function (_ref) {
9
9
  var tr = _ref.tr;
10
10
  var selection = tr.selection;
11
+ var nodes = tr.doc.type.schema.nodes;
12
+
13
+ // Find the node to format from the current selection
14
+ var nodeToFormat;
15
+ var nodePos = null;
16
+
17
+ // Try to find the current node from selection
18
+ var selectedNode = findSelectedNodeOfType([nodes.paragraph, nodes.heading, nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.layoutSection])(selection);
19
+ if (selectedNode) {
20
+ nodeToFormat = selectedNode.node;
21
+ nodePos = selectedNode.pos;
22
+ } else {
23
+ // Try to find parent node (including list parents)
24
+ var parentNode = findParentNodeOfType([nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.listItem, nodes.layoutSection])(selection);
25
+ if (parentNode) {
26
+ nodeToFormat = parentNode.node;
27
+ nodePos = parentNode.pos;
28
+
29
+ // Special case: if we found a listItem, check if we need the parent list instead
30
+ if (parentNode.node.type === nodes.listItem) {
31
+ var listParent = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
32
+ if (listParent) {
33
+ // For list transformations, we want the list parent, not the listItem
34
+ nodeToFormat = listParent.node;
35
+ nodePos = listParent.pos;
36
+ }
37
+ }
38
+ }
39
+ }
40
+ if (!nodeToFormat) {
41
+ nodeToFormat = selection.$from.node();
42
+ nodePos = selection.$from.pos;
43
+ }
11
44
  try {
12
- return transformNodeToTargetType(tr, currentNode, selection.from, targetType);
13
- } catch (e) {
45
+ return transformNodeToTargetType(tr, nodeToFormat, nodePos, targetType);
46
+ } catch (_unused) {
14
47
  return null;
15
48
  }
16
49
  };
@@ -15,7 +15,7 @@ export var transformBlockNode = function transformBlockNode(context) {
15
15
 
16
16
  // Handle transformation to list types
17
17
  if (isListNodeType(targetNodeType)) {
18
- return transformToList();
18
+ return transformToList(context);
19
19
  }
20
20
 
21
21
  // Handle transformation to container types (panel, expand, blockquote)
@@ -1,17 +1,37 @@
1
+ import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
2
+ import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
1
3
  import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
2
4
 
3
5
  /**
4
6
  * Transform selection to list type
5
7
  */
6
- export var transformToList = function transformToList() {
7
- return null;
8
+ export var transformToList = function transformToList(_ref) {
9
+ var tr = _ref.tr,
10
+ targetNodeType = _ref.targetNodeType,
11
+ targetAttrs = _ref.targetAttrs;
12
+ // Wrap selection in list of target type
13
+ var _tr$selection = tr.selection,
14
+ $from = _tr$selection.$from,
15
+ $to = _tr$selection.$to;
16
+ var range = $from.blockRange($to);
17
+ if (!range) {
18
+ return null;
19
+ }
20
+
21
+ // Find if we can wrap the selection in the target list type
22
+ var wrapping = findWrapping(range, targetNodeType, targetAttrs);
23
+ if (!wrapping) {
24
+ return null;
25
+ }
26
+ tr.wrap(range, wrapping);
27
+ return tr;
8
28
  };
9
29
 
10
30
  /**
11
31
  * Transform list nodes
12
32
  */
13
- export var transformListNode = function transformListNode(_ref) {
14
- var targetNodeType = _ref.targetNodeType;
33
+ export var transformListNode = function transformListNode(context) {
34
+ var targetNodeType = context.targetNodeType;
15
35
  // Transform list to block type
16
36
  if (isBlockNodeType(targetNodeType)) {
17
37
  // Lift list items out of the list and convert to target block type
@@ -26,8 +46,7 @@ export var transformListNode = function transformListNode(_ref) {
26
46
 
27
47
  // Transform between list types
28
48
  if (isListNodeType(targetNodeType)) {
29
- // Lift list items out of the list and convert to the other list type
30
- return null;
49
+ return transformBetweenListTypes(context);
31
50
  }
32
51
  return null;
33
52
  };
@@ -43,6 +62,22 @@ export var liftListToBlockType = function liftListToBlockType() {
43
62
  /**
44
63
  * Transform between different list types
45
64
  */
46
- export var transformBetweenListTypes = function transformBetweenListTypes() {
47
- return null;
65
+ export var transformBetweenListTypes = function transformBetweenListTypes(_ref2) {
66
+ var tr = _ref2.tr,
67
+ targetNodeType = _ref2.targetNodeType;
68
+ var selection = tr.selection;
69
+ var nodes = tr.doc.type.schema.nodes;
70
+
71
+ // Find the list node
72
+ var listNode = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
73
+ if (!listNode) {
74
+ return null;
75
+ }
76
+ try {
77
+ // Change the list type while preserving content
78
+ tr.setNodeMarkup(listNode.pos, targetNodeType);
79
+ return tr;
80
+ } catch (e) {
81
+ return null;
82
+ }
48
83
  };
@@ -12,8 +12,18 @@ export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType)
12
12
  targetAttrs = targetNodeInfo.attrs;
13
13
 
14
14
  // Early return if trying to transform to the same type
15
- if (sourceNode.type === targetNodeType) {
16
- return tr; // No transformation needed
15
+ if (sourceNode.type.name === targetNodeType.name) {
16
+ // For headings, also check if the level matches
17
+ if (targetNodeType.name === 'heading') {
18
+ var _sourceNode$attrs;
19
+ var sourceLevel = (_sourceNode$attrs = sourceNode.attrs) === null || _sourceNode$attrs === void 0 ? void 0 : _sourceNode$attrs.level;
20
+ var targetLevel = targetAttrs === null || targetAttrs === void 0 ? void 0 : targetAttrs.level;
21
+ if (sourceLevel === targetLevel) {
22
+ return tr;
23
+ }
24
+ } else {
25
+ return tr;
26
+ }
17
27
  }
18
28
 
19
29
  // Prepare transformation context
@@ -37,7 +47,7 @@ export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType)
37
47
  return transformContainerNode(transformationContext);
38
48
  }
39
49
  return null;
40
- } catch (e) {
50
+ } catch (_unused) {
41
51
  // Node transformation failed
42
52
  return null;
43
53
  }
@@ -43,6 +43,9 @@ export var BlockMenuRenderer = function BlockMenuRenderer(_ref) {
43
43
  return /*#__PURE__*/React.createElement(Fragment, null, menuSections.map(function (section) {
44
44
  // Get all items for the current section, including nested menus, and sort them by rank
45
45
  var currentSectionItemsSorted = getSortedChildren([].concat(_toConsumableArray(menuItems), _toConsumableArray(nestedMenus)), section.key);
46
+ if (currentSectionItemsSorted.length === 0) {
47
+ return null;
48
+ }
46
49
 
47
50
  // iterate over the current section items, if it is nested menu, get their children, sort them
48
51
  // if they are menu items, just render as they are sorted above
@@ -3,7 +3,6 @@ import type { BlockControlsPlugin } from '@atlaskit/editor-plugin-block-controls
3
3
  import type { DecorationsPlugin } from '@atlaskit/editor-plugin-decorations';
4
4
  import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection';
5
5
  import type { UserIntentPlugin } from '@atlaskit/editor-plugin-user-intent';
6
- import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
7
6
  import type { FormatNodeTargetType } from './editor-commands/transforms/types';
8
7
  export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', {
9
8
  actions: {
@@ -11,7 +10,7 @@ export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', {
11
10
  registerBlockMenuComponents: (blockMenuComponents: Array<RegisterBlockMenuComponent>) => void;
12
11
  };
13
12
  commands: {
14
- formatNode: (currentNode: PMNode, targetType: FormatNodeTargetType) => EditorCommand;
13
+ formatNode: (targetType: FormatNodeTargetType) => EditorCommand;
15
14
  };
16
15
  dependencies: [
17
16
  OptionalPlugin<BlockControlsPlugin>,
@@ -1,9 +1,7 @@
1
1
  import type { EditorCommand } from '@atlaskit/editor-common/types';
2
- import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
2
  import type { FormatNodeTargetType } from './transforms/types';
4
3
  /**
5
4
  * Formats the current node or selection to the specified target type
6
- * @param currentNode - The current node
7
5
  * @param targetType - The target node type to convert to
8
6
  */
9
- export declare const formatNode: (currentNode: PMNode, targetType: FormatNodeTargetType) => EditorCommand;
7
+ export declare const formatNode: (targetType: FormatNodeTargetType) => EditorCommand;
@@ -1,8 +1,14 @@
1
- import type { TransformFunction } from './types';
1
+ import type { NodeType } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ import type { TransformContext, TransformFunction } from './types';
2
4
  /**
3
5
  * Transform selection to list type
4
6
  */
5
- export declare const transformToList: () => null;
7
+ export declare const transformToList: ({ tr, targetNodeType, targetAttrs, }: {
8
+ targetAttrs?: Record<string, unknown>;
9
+ targetNodeType: NodeType;
10
+ tr: Transaction;
11
+ }) => Transaction | null;
6
12
  /**
7
13
  * Transform list nodes
8
14
  */
@@ -14,4 +20,4 @@ export declare const liftListToBlockType: () => null;
14
20
  /**
15
21
  * Transform between different list types
16
22
  */
17
- export declare const transformBetweenListTypes: () => null;
23
+ export declare const transformBetweenListTypes: ({ tr, targetNodeType }: TransformContext) => Transaction | null;
@@ -3,7 +3,6 @@ import type { BlockControlsPlugin } from '@atlaskit/editor-plugin-block-controls
3
3
  import type { DecorationsPlugin } from '@atlaskit/editor-plugin-decorations';
4
4
  import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection';
5
5
  import type { UserIntentPlugin } from '@atlaskit/editor-plugin-user-intent';
6
- import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
7
6
  import type { FormatNodeTargetType } from './editor-commands/transforms/types';
8
7
  export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', {
9
8
  actions: {
@@ -11,7 +10,7 @@ export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', {
11
10
  registerBlockMenuComponents: (blockMenuComponents: Array<RegisterBlockMenuComponent>) => void;
12
11
  };
13
12
  commands: {
14
- formatNode: (currentNode: PMNode, targetType: FormatNodeTargetType) => EditorCommand;
13
+ formatNode: (targetType: FormatNodeTargetType) => EditorCommand;
15
14
  };
16
15
  dependencies: [
17
16
  OptionalPlugin<BlockControlsPlugin>,
@@ -1,9 +1,7 @@
1
1
  import type { EditorCommand } from '@atlaskit/editor-common/types';
2
- import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
2
  import type { FormatNodeTargetType } from './transforms/types';
4
3
  /**
5
4
  * Formats the current node or selection to the specified target type
6
- * @param currentNode - The current node
7
5
  * @param targetType - The target node type to convert to
8
6
  */
9
- export declare const formatNode: (currentNode: PMNode, targetType: FormatNodeTargetType) => EditorCommand;
7
+ export declare const formatNode: (targetType: FormatNodeTargetType) => EditorCommand;
@@ -1,8 +1,14 @@
1
- import type { TransformFunction } from './types';
1
+ import type { NodeType } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ import type { TransformContext, TransformFunction } from './types';
2
4
  /**
3
5
  * Transform selection to list type
4
6
  */
5
- export declare const transformToList: () => null;
7
+ export declare const transformToList: ({ tr, targetNodeType, targetAttrs, }: {
8
+ targetAttrs?: Record<string, unknown>;
9
+ targetNodeType: NodeType;
10
+ tr: Transaction;
11
+ }) => Transaction | null;
6
12
  /**
7
13
  * Transform list nodes
8
14
  */
@@ -14,4 +20,4 @@ export declare const liftListToBlockType: () => null;
14
20
  /**
15
21
  * Transform between different list types
16
22
  */
17
- export declare const transformBetweenListTypes: () => null;
23
+ export declare const transformBetweenListTypes: ({ tr, targetNodeType }: TransformContext) => Transaction | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -37,7 +37,7 @@
37
37
  "@atlaskit/editor-prosemirror": "7.0.0",
38
38
  "@atlaskit/editor-shared-styles": "^3.6.0",
39
39
  "@atlaskit/editor-tables": "^2.9.0",
40
- "@atlaskit/editor-toolbar": "^0.5.0",
40
+ "@atlaskit/editor-toolbar": "^0.6.0",
41
41
  "@atlaskit/icon": "^28.1.0",
42
42
  "@atlaskit/icon-lab": "^5.7.0",
43
43
  "@atlaskit/platform-feature-flags": "^1.1.0",
@@ -46,7 +46,7 @@
46
46
  "@babel/runtime": "^7.0.0"
47
47
  },
48
48
  "peerDependencies": {
49
- "@atlaskit/editor-common": "^107.33.0",
49
+ "@atlaskit/editor-common": "^107.34.0",
50
50
  "react": "^18.2.0",
51
51
  "react-intl-next": "npm:react-intl@^5.18.1"
52
52
  },