@atlaskit/editor-plugin-block-menu 0.0.12 → 0.0.14

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 (55) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/afm-cc/tsconfig.json +4 -1
  3. package/afm-dev-agents/tsconfig.json +3 -0
  4. package/afm-jira/tsconfig.json +3 -0
  5. package/afm-passionfruit/tsconfig.json +3 -0
  6. package/afm-post-office/tsconfig.json +3 -0
  7. package/afm-rovo-extension/tsconfig.json +3 -0
  8. package/afm-townsquare/tsconfig.json +3 -0
  9. package/dist/cjs/blockMenuPlugin.js +6 -0
  10. package/dist/cjs/editor-commands/formatNode.js +23 -0
  11. package/dist/cjs/editor-commands/transforms/block-transforms.js +37 -0
  12. package/dist/cjs/editor-commands/transforms/container-transforms.js +59 -0
  13. package/dist/cjs/editor-commands/transforms/list-transforms.js +53 -0
  14. package/dist/cjs/editor-commands/transforms/transformNodeToTargetType.js +50 -0
  15. package/dist/cjs/editor-commands/transforms/types.js +5 -0
  16. package/dist/cjs/editor-commands/transforms/utils.js +109 -0
  17. package/dist/cjs/ui/block-menu-components.js +55 -42
  18. package/dist/cjs/ui/block-menu-renderer.js +48 -11
  19. package/dist/es2019/blockMenuPlugin.js +6 -0
  20. package/dist/es2019/editor-commands/formatNode.js +20 -0
  21. package/dist/es2019/editor-commands/transforms/block-transforms.js +38 -0
  22. package/dist/es2019/editor-commands/transforms/container-transforms.js +55 -0
  23. package/dist/es2019/editor-commands/transforms/list-transforms.js +49 -0
  24. package/dist/es2019/editor-commands/transforms/transformNodeToTargetType.js +48 -0
  25. package/dist/es2019/editor-commands/transforms/types.js +1 -0
  26. package/dist/es2019/editor-commands/transforms/utils.js +103 -0
  27. package/dist/es2019/ui/block-menu-components.js +45 -32
  28. package/dist/es2019/ui/block-menu-renderer.js +46 -11
  29. package/dist/esm/blockMenuPlugin.js +6 -0
  30. package/dist/esm/editor-commands/formatNode.js +17 -0
  31. package/dist/esm/editor-commands/transforms/block-transforms.js +32 -0
  32. package/dist/esm/editor-commands/transforms/container-transforms.js +54 -0
  33. package/dist/esm/editor-commands/transforms/list-transforms.js +48 -0
  34. package/dist/esm/editor-commands/transforms/transformNodeToTargetType.js +44 -0
  35. package/dist/esm/editor-commands/transforms/types.js +1 -0
  36. package/dist/esm/editor-commands/transforms/utils.js +103 -0
  37. package/dist/esm/ui/block-menu-components.js +56 -43
  38. package/dist/esm/ui/block-menu-renderer.js +48 -11
  39. package/dist/types/blockMenuPluginType.d.ts +27 -3
  40. package/dist/types/editor-commands/formatNode.d.ts +9 -0
  41. package/dist/types/editor-commands/transforms/block-transforms.d.ts +5 -0
  42. package/dist/types/editor-commands/transforms/container-transforms.d.ts +17 -0
  43. package/dist/types/editor-commands/transforms/list-transforms.d.ts +17 -0
  44. package/dist/types/editor-commands/transforms/transformNodeToTargetType.d.ts +4 -0
  45. package/dist/types/editor-commands/transforms/types.d.ts +11 -0
  46. package/dist/types/editor-commands/transforms/utils.d.ts +12 -0
  47. package/dist/types-ts4.5/blockMenuPluginType.d.ts +27 -3
  48. package/dist/types-ts4.5/editor-commands/formatNode.d.ts +9 -0
  49. package/dist/types-ts4.5/editor-commands/transforms/block-transforms.d.ts +5 -0
  50. package/dist/types-ts4.5/editor-commands/transforms/container-transforms.d.ts +17 -0
  51. package/dist/types-ts4.5/editor-commands/transforms/list-transforms.d.ts +17 -0
  52. package/dist/types-ts4.5/editor-commands/transforms/transformNodeToTargetType.d.ts +4 -0
  53. package/dist/types-ts4.5/editor-commands/transforms/types.d.ts +11 -0
  54. package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +12 -0
  55. package/package.json +13 -10
@@ -0,0 +1,54 @@
1
+ import { isBlockNodeType, isListNodeType, isContainerNodeType } from './utils';
2
+
3
+ /**
4
+ * Transform selection to container type
5
+ */
6
+ export var transformToContainer = function transformToContainer() {
7
+ return null;
8
+ };
9
+
10
+ /**
11
+ * Transform container nodes (panel, expand, blockquote)
12
+ */
13
+ export var transformContainerNode = function transformContainerNode(_ref) {
14
+ var tr = _ref.tr,
15
+ sourcePos = _ref.sourcePos,
16
+ targetNodeType = _ref.targetNodeType,
17
+ targetAttrs = _ref.targetAttrs;
18
+ if (sourcePos === null) {
19
+ return null;
20
+ }
21
+
22
+ // Transform container to block type - unwrap and convert content
23
+ if (isBlockNodeType(targetNodeType)) {
24
+ return unwrapAndConvertToBlockType();
25
+ }
26
+
27
+ // Transform container to list type
28
+ if (isListNodeType(targetNodeType)) {
29
+ return unwrapAndConvertToList();
30
+ }
31
+
32
+ // Transform between container types
33
+ if (isContainerNodeType(targetNodeType)) {
34
+ tr.setNodeMarkup(sourcePos, targetNodeType, targetAttrs);
35
+ return tr;
36
+ }
37
+ return null;
38
+ };
39
+
40
+ /**
41
+ * Unwrap container node and convert content to block type
42
+ */
43
+ export var unwrapAndConvertToBlockType = function unwrapAndConvertToBlockType() {
44
+ // Convert to block type directly
45
+ return null;
46
+ };
47
+
48
+ /**
49
+ * Unwrap container node and convert content to list
50
+ */
51
+ export var unwrapAndConvertToList = function unwrapAndConvertToList() {
52
+ // Convert to list directly
53
+ return null;
54
+ };
@@ -0,0 +1,48 @@
1
+ import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
2
+
3
+ /**
4
+ * Transform selection to list type
5
+ */
6
+ export var transformToList = function transformToList() {
7
+ return null;
8
+ };
9
+
10
+ /**
11
+ * Transform list nodes
12
+ */
13
+ export var transformListNode = function transformListNode(_ref) {
14
+ var targetNodeType = _ref.targetNodeType;
15
+ // Transform list to block type
16
+ if (isBlockNodeType(targetNodeType)) {
17
+ // Lift list items out of the list and convert to target block type
18
+ return null;
19
+ }
20
+
21
+ // Transform list to container type
22
+ if (isContainerNodeType(targetNodeType)) {
23
+ // Lift list items out of the list and convert to container type
24
+ return null;
25
+ }
26
+
27
+ // Transform between list types
28
+ if (isListNodeType(targetNodeType)) {
29
+ // Lift list items out of the list and convert to the other list type
30
+ return null;
31
+ }
32
+ return null;
33
+ };
34
+
35
+ /**
36
+ * Lift list content and convert to block type
37
+ */
38
+ export var liftListToBlockType = function liftListToBlockType() {
39
+ // Convert to target block type directly
40
+ return null;
41
+ };
42
+
43
+ /**
44
+ * Transform between different list types
45
+ */
46
+ export var transformBetweenListTypes = function transformBetweenListTypes() {
47
+ return null;
48
+ };
@@ -0,0 +1,44 @@
1
+ import { transformBlockNode } from './block-transforms';
2
+ import { transformContainerNode } from './container-transforms';
3
+ import { transformListNode } from './list-transforms';
4
+ import { getTargetNodeInfo, isBlockNode, isListNode, isContainerNode } from './utils';
5
+ export function transformNodeToTargetType(tr, sourceNode, sourcePos, targetType) {
6
+ var nodes = tr.doc.type.schema.nodes;
7
+ var targetNodeInfo = getTargetNodeInfo(targetType, nodes);
8
+ if (!targetNodeInfo) {
9
+ return null;
10
+ }
11
+ var targetNodeType = targetNodeInfo.nodeType,
12
+ targetAttrs = targetNodeInfo.attrs;
13
+
14
+ // Early return if trying to transform to the same type
15
+ if (sourceNode.type === targetNodeType) {
16
+ return tr; // No transformation needed
17
+ }
18
+
19
+ // Prepare transformation context
20
+ var transformationContext = {
21
+ tr: tr,
22
+ sourceNode: sourceNode,
23
+ sourcePos: sourcePos,
24
+ targetNodeType: targetNodeType,
25
+ targetAttrs: targetAttrs
26
+ };
27
+
28
+ // Route to appropriate transformation strategy based on source node type
29
+ try {
30
+ if (isBlockNode(sourceNode)) {
31
+ return transformBlockNode(transformationContext);
32
+ }
33
+ if (isListNode(sourceNode)) {
34
+ return transformListNode(transformationContext);
35
+ }
36
+ if (isContainerNode(sourceNode)) {
37
+ return transformContainerNode(transformationContext);
38
+ }
39
+ return null;
40
+ } catch (e) {
41
+ // Node transformation failed
42
+ return null;
43
+ }
44
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,103 @@
1
+ export var getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
2
+ switch (targetType) {
3
+ case 'heading1':
4
+ return {
5
+ nodeType: nodes.heading,
6
+ attrs: {
7
+ level: 1
8
+ }
9
+ };
10
+ case 'heading2':
11
+ return {
12
+ nodeType: nodes.heading,
13
+ attrs: {
14
+ level: 2
15
+ }
16
+ };
17
+ case 'heading3':
18
+ return {
19
+ nodeType: nodes.heading,
20
+ attrs: {
21
+ level: 3
22
+ }
23
+ };
24
+ case 'heading4':
25
+ return {
26
+ nodeType: nodes.heading,
27
+ attrs: {
28
+ level: 4
29
+ }
30
+ };
31
+ case 'heading5':
32
+ return {
33
+ nodeType: nodes.heading,
34
+ attrs: {
35
+ level: 5
36
+ }
37
+ };
38
+ case 'heading6':
39
+ return {
40
+ nodeType: nodes.heading,
41
+ attrs: {
42
+ level: 6
43
+ }
44
+ };
45
+ case 'paragraph':
46
+ return {
47
+ nodeType: nodes.paragraph
48
+ };
49
+ case 'blockquote':
50
+ return {
51
+ nodeType: nodes.blockquote
52
+ };
53
+ case 'expand':
54
+ return {
55
+ nodeType: nodes.expand
56
+ };
57
+ case 'panel':
58
+ return {
59
+ nodeType: nodes.panel,
60
+ attrs: {
61
+ panelType: 'info'
62
+ }
63
+ };
64
+ case 'codeblock':
65
+ return {
66
+ nodeType: nodes.codeBlock
67
+ };
68
+ case 'bulletList':
69
+ return {
70
+ nodeType: nodes.bulletList
71
+ };
72
+ case 'orderedList':
73
+ return {
74
+ nodeType: nodes.orderedList
75
+ };
76
+ case 'taskList':
77
+ return {
78
+ nodeType: nodes.taskList
79
+ };
80
+ default:
81
+ return null;
82
+ }
83
+ };
84
+
85
+ // Helper functions to categorize node types
86
+ export var isBlockNode = function isBlockNode(node) {
87
+ return ['paragraph', 'heading', 'codeBlock'].includes(node.type.name);
88
+ };
89
+ export var isListNode = function isListNode(node) {
90
+ return ['bulletList', 'orderedList', 'taskList', 'listItem'].includes(node.type.name);
91
+ };
92
+ export var isContainerNode = function isContainerNode(node) {
93
+ return ['panel', 'expand', 'blockquote'].includes(node.type.name);
94
+ };
95
+ export var isBlockNodeType = function isBlockNodeType(nodeType) {
96
+ return ['paragraph', 'heading', 'codeBlock'].includes(nodeType.name);
97
+ };
98
+ export var isListNodeType = function isListNodeType(nodeType) {
99
+ return ['bulletList', 'orderedList', 'taskList'].includes(nodeType.name);
100
+ };
101
+ export var isContainerNodeType = function isContainerNodeType(nodeType) {
102
+ return ['panel', 'expand', 'blockquote'].includes(nodeType.name);
103
+ };
@@ -1,10 +1,9 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import React from 'react';
3
- import { ToolbarDropdownItem, ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
3
+ import { ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
4
4
  import ChangesIcon from '@atlaskit/icon/core/changes';
5
5
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
6
- import ListBulletedIcon from '@atlaskit/icon/core/list-bulleted';
7
- import TaskIcon from '@atlaskit/icon/core/task';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
8
7
  import CopyBlockMenuItem from './copy-block';
9
8
  import { CopyLinkDropdownItem } from './copy-link';
10
9
  import { DeleteDropdownItem } from './delete-button';
@@ -39,23 +38,64 @@ var getMoveUpMoveDownMenuComponents = function getMoveUpMoveDownMenuComponents(a
39
38
  }
40
39
  }];
41
40
  };
42
- export var getBlockMenuComponents = function getBlockMenuComponents(_ref) {
43
- var api = _ref.api,
44
- config = _ref.config;
41
+ var getFormatMenuComponents = function getFormatMenuComponents() {
45
42
  return [{
43
+ type: 'block-menu-nested',
44
+ key: 'nested-menu-format',
45
+ parent: {
46
+ type: 'block-menu-section',
47
+ key: 'block-menu-section-primary',
48
+ rank: 100
49
+ },
50
+ component: function component() {
51
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
52
+ children: null
53
+ },
54
+ children = _ref.children;
55
+ return /*#__PURE__*/React.createElement(ToolbarNestedDropdownMenu, {
56
+ text: "Format",
57
+ elemBefore: /*#__PURE__*/React.createElement(ChangesIcon, {
58
+ label: ""
59
+ }),
60
+ elemAfter: /*#__PURE__*/React.createElement(ChevronRightIcon, {
61
+ label: 'example nested menu'
62
+ })
63
+ }, children);
64
+ }
65
+ }, {
46
66
  type: 'block-menu-section',
47
- key: 'block-menu-section-format',
67
+ key: 'nested-menu-format-section-primary',
68
+ parent: {
69
+ type: 'block-menu-nested',
70
+ key: 'nested-menu-format',
71
+ rank: 100
72
+ },
73
+ component: function component() {
74
+ var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
75
+ children: null
76
+ },
77
+ children = _ref2.children;
78
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, null, children);
79
+ }
80
+ }];
81
+ };
82
+ export var getBlockMenuComponents = function getBlockMenuComponents(_ref3) {
83
+ var api = _ref3.api,
84
+ config = _ref3.config;
85
+ return [].concat(_toConsumableArray(fg('platform_editor_block_menu_format') ? getFormatMenuComponents() : []), [{
86
+ type: 'block-menu-section',
87
+ key: 'block-menu-section-primary',
48
88
  rank: 100,
49
- component: function component(_ref2) {
50
- var children = _ref2.children;
89
+ component: function component(_ref4) {
90
+ var children = _ref4.children;
51
91
  return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, null, children);
52
92
  }
53
93
  }, {
54
94
  type: 'block-menu-section',
55
95
  key: 'block-menu-section-copy',
56
96
  rank: 200,
57
- component: function component(_ref3) {
58
- var children = _ref3.children;
97
+ component: function component(_ref5) {
98
+ var children = _ref5.children;
59
99
  return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
60
100
  hasSeparator: true
61
101
  }, children);
@@ -91,8 +131,8 @@ export var getBlockMenuComponents = function getBlockMenuComponents(_ref) {
91
131
  type: 'block-menu-section',
92
132
  key: 'block-menu-section-move-up-down',
93
133
  rank: 300,
94
- component: function component(_ref4) {
95
- var children = _ref4.children;
134
+ component: function component(_ref6) {
135
+ var children = _ref6.children;
96
136
  return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
97
137
  hasSeparator: true
98
138
  }, children);
@@ -101,40 +141,13 @@ export var getBlockMenuComponents = function getBlockMenuComponents(_ref) {
101
141
  type: 'block-menu-section',
102
142
  key: 'block-menu-section-delete',
103
143
  rank: 400,
104
- component: function component(_ref5) {
105
- var children = _ref5.children;
144
+ component: function component(_ref7) {
145
+ var children = _ref7.children;
106
146
  return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
107
147
  hasSeparator: true
108
148
  }, children);
109
149
  }
110
- }, {
111
- type: 'block-menu-nested',
112
- key: 'nested-menu',
113
- parent: {
114
- type: 'block-menu-section',
115
- key: 'block-menu-section-format',
116
- rank: 100
117
- },
118
- component: function component() {
119
- return /*#__PURE__*/React.createElement(ToolbarNestedDropdownMenu, {
120
- text: "Format",
121
- elemBefore: /*#__PURE__*/React.createElement(ChangesIcon, {
122
- label: ""
123
- }),
124
- elemAfter: /*#__PURE__*/React.createElement(ChevronRightIcon, {
125
- label: 'example nested menu'
126
- })
127
- }, /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, null, /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
128
- elemBefore: /*#__PURE__*/React.createElement(TaskIcon, {
129
- label: ""
130
- })
131
- }, "Action item"), /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
132
- elemBefore: /*#__PURE__*/React.createElement(ListBulletedIcon, {
133
- label: ""
134
- })
135
- }, "Bullet list")));
136
- }
137
- }].concat(_toConsumableArray(getMoveUpMoveDownMenuComponents(api)), [{
150
+ }], _toConsumableArray(getMoveUpMoveDownMenuComponents(api)), [{
138
151
  type: 'block-menu-item',
139
152
  key: 'block-menu-item-delete',
140
153
  parent: {
@@ -3,8 +3,8 @@ import React, { Fragment } from 'react';
3
3
  var NoOp = function NoOp(props) {
4
4
  return null;
5
5
  };
6
- var isMenuSection = function isMenuSection(component) {
7
- return component.type === 'block-menu-section';
6
+ var isNonNestedMenuSection = function isNonNestedMenuSection(component) {
7
+ return component.type === 'block-menu-section' && !('parent' in component);
8
8
  };
9
9
  var isMenuItem = function isMenuItem(component) {
10
10
  return component.type === 'block-menu-item';
@@ -12,31 +12,68 @@ var isMenuItem = function isMenuItem(component) {
12
12
  var isNestedMenu = function isNestedMenu(component) {
13
13
  return component.type === 'block-menu-nested';
14
14
  };
15
+ var isNestedMenuSection = function isNestedMenuSection(component) {
16
+ return 'parent' in component && component.parent !== undefined && component.parent.type === 'block-menu-nested';
17
+ };
15
18
  var getSortedChildren = function getSortedChildren(components, parentKey) {
16
19
  return components.filter(function (component) {
17
- return component.parent.key === parentKey;
20
+ return 'parent' in component && component.parent !== undefined && component.parent.key === parentKey;
18
21
  }).sort(function (a, b) {
19
22
  return (a.parent.rank || 0) - (b.parent.rank || 0);
20
23
  });
21
24
  };
22
- var getSortedSections = function getSortedSections(components) {
23
- return components.filter(isMenuSection).sort(function (a, b) {
25
+ var getSortedNestedSections = function getSortedNestedSections(components, parentKey) {
26
+ var nestedMenuSections = components.filter(isNestedMenuSection);
27
+ var nestedMenuSectionsWithParent = nestedMenuSections.filter(function (section) {
28
+ return section.parent !== undefined;
29
+ });
30
+ return getSortedChildren(nestedMenuSectionsWithParent, parentKey);
31
+ };
32
+ var getSortedNonNestedSections = function getSortedNonNestedSections(components) {
33
+ return components.filter(isNonNestedMenuSection).sort(function (a, b) {
24
34
  return (a.rank || 0) - (b.rank || 0);
25
35
  });
26
36
  };
27
37
  export var BlockMenuRenderer = function BlockMenuRenderer(_ref) {
28
38
  var components = _ref.components,
29
39
  fallbacks = _ref.fallbacks;
30
- var menuSections = getSortedSections(components);
40
+ var menuSections = getSortedNonNestedSections(components);
31
41
  var menuItems = components.filter(isMenuItem);
32
42
  var nestedMenus = components.filter(isNestedMenu);
33
43
  return /*#__PURE__*/React.createElement(Fragment, null, menuSections.map(function (section) {
34
- var children = getSortedChildren([].concat(_toConsumableArray(menuItems), _toConsumableArray(nestedMenus)), section.key).map(function (item) {
35
- var ItemComponent = item.component || fallbacks.item || NoOp;
36
- return /*#__PURE__*/React.createElement(ItemComponent, {
37
- key: item.key
44
+ // Get all items for the current section, including nested menus, and sort them by rank
45
+ var currentSectionItemsSorted = getSortedChildren([].concat(_toConsumableArray(menuItems), _toConsumableArray(nestedMenus)), section.key);
46
+
47
+ // iterate over the current section items, if it is nested menu, get their children, sort them
48
+ // if they are menu items, just render as they are sorted above
49
+ var getChildrenWithNestedItems = function getChildrenWithNestedItems(items) {
50
+ return items.map(function (item) {
51
+ if (isNestedMenu(item)) {
52
+ var sortedNestedSections = getSortedNestedSections(components, item.key);
53
+ return sortedNestedSections.map(function (section) {
54
+ var sortedNestedMenuItems = getSortedChildren(menuItems, section.key);
55
+ var NestedMenuComponent = item.component || fallbacks.nestedMenu || NoOp;
56
+ var NestedSection = section.component || fallbacks.section || NoOp;
57
+ return /*#__PURE__*/React.createElement(NestedMenuComponent, {
58
+ key: item.key
59
+ }, /*#__PURE__*/React.createElement(NestedSection, {
60
+ key: section.key
61
+ }, sortedNestedMenuItems.map(function (nestedItem) {
62
+ var NestedMenuItemComponent = nestedItem.component || fallbacks.item || NoOp;
63
+ return /*#__PURE__*/React.createElement(NestedMenuItemComponent, {
64
+ key: nestedItem.key
65
+ });
66
+ })));
67
+ });
68
+ } else {
69
+ var ItemComponent = item.component || fallbacks.item || NoOp;
70
+ return /*#__PURE__*/React.createElement(ItemComponent, {
71
+ key: item.key
72
+ });
73
+ }
38
74
  });
39
- });
75
+ };
76
+ var children = getChildrenWithNestedItems(currentSectionItemsSorted);
40
77
  var SectionComponent = section.component || fallbacks.section || NoOp;
41
78
  return /*#__PURE__*/React.createElement(SectionComponent, {
42
79
  key: section.key
@@ -1,13 +1,18 @@
1
- import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
1
+ import type { NextEditorPlugin, OptionalPlugin, EditorCommand } from '@atlaskit/editor-common/types';
2
2
  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
+ import type { FormatNodeTargetType } from './editor-commands/transforms/types';
6
8
  export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', {
7
9
  actions: {
8
10
  getBlockMenuComponents: () => Array<RegisterBlockMenuComponent>;
9
11
  registerBlockMenuComponents: (blockMenuComponents: Array<RegisterBlockMenuComponent>) => void;
10
12
  };
13
+ commands: {
14
+ formatNode: (currentNode: PMNode, targetType: FormatNodeTargetType) => EditorCommand;
15
+ };
11
16
  dependencies: [
12
17
  OptionalPlugin<BlockControlsPlugin>,
13
18
  OptionalPlugin<UserIntentPlugin>,
@@ -33,6 +38,19 @@ type WithRank<T> = T & {
33
38
  export type Parent<T> = WithRank<T>;
34
39
  type ComponentType = BlockMenuSection | BlockMenuItem | BlockMenuNested;
35
40
  export type ComponentTypes = Array<ComponentType>;
41
+ /**
42
+ * The relationship between BlockMenuItem, BlockMenuSection, BlockMenuNested
43
+ * BlockMenuSection can have BlockMenuItem or BlockMenuNested as children
44
+ * BlockMenuNested can have BlockMenuSection as children,
45
+ * BlockMenuNested, with BlockMenuSection and BlockMenuItem, is a nested menu
46
+ * _______________________________________
47
+ * | Block menu (no typing)
48
+ * | |BlockMenuSection
49
+ * | | |BlockMenuItem
50
+ * | | |BlockMenuNested
51
+ * | | | |BlockMenuSection
52
+ * | | | | |BlockMenuItem
53
+ */
36
54
  type BlockMenuItem = {
37
55
  key: string;
38
56
  type: 'block-menu-item';
@@ -45,10 +63,15 @@ type BlockMenuNested = {
45
63
  key: string;
46
64
  type: 'block-menu-nested';
47
65
  };
48
- export type BlockMenuNestedComponent = () => React.ReactNode;
66
+ export type BlockMenuNestedComponent = (props?: {
67
+ children: React.ReactNode;
68
+ }) => React.ReactNode;
49
69
  export type BlockMenuSectionComponent = (props: {
50
70
  children: React.ReactNode;
51
71
  }) => React.ReactNode;
72
+ export type BlockMenuNestedSectionComponent = (props: {
73
+ children: React.ReactNode;
74
+ }) => React.ReactNode;
52
75
  export type BlockMenuItemComponent = () => React.ReactNode;
53
76
  export type RegisterBlockMenuNested = BlockMenuNested & {
54
77
  component?: BlockMenuNestedComponent;
@@ -56,7 +79,8 @@ export type RegisterBlockMenuNested = BlockMenuNested & {
56
79
  };
57
80
  export type RegisterBlockMenuSection = BlockMenuSection & {
58
81
  component?: BlockMenuSectionComponent;
59
- rank: number;
82
+ parent?: Parent<BlockMenuNested>;
83
+ rank?: number;
60
84
  };
61
85
  export type RegisterBlockMenuItem = BlockMenuItem & {
62
86
  component?: BlockMenuItemComponent;
@@ -0,0 +1,9 @@
1
+ import type { EditorCommand } from '@atlaskit/editor-common/types';
2
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
+ import type { FormatNodeTargetType } from './transforms/types';
4
+ /**
5
+ * Formats the current node or selection to the specified target type
6
+ * @param currentNode - The current node
7
+ * @param targetType - The target node type to convert to
8
+ */
9
+ export declare const formatNode: (currentNode: PMNode, targetType: FormatNodeTargetType) => EditorCommand;
@@ -0,0 +1,5 @@
1
+ import type { TransformFunction } from './types';
2
+ /**
3
+ * Transform block nodes (paragraph, heading, codeblock)
4
+ */
5
+ export declare const transformBlockNode: TransformFunction;
@@ -0,0 +1,17 @@
1
+ import type { TransformFunction } from './types';
2
+ /**
3
+ * Transform selection to container type
4
+ */
5
+ export declare const transformToContainer: () => null;
6
+ /**
7
+ * Transform container nodes (panel, expand, blockquote)
8
+ */
9
+ export declare const transformContainerNode: TransformFunction;
10
+ /**
11
+ * Unwrap container node and convert content to block type
12
+ */
13
+ export declare const unwrapAndConvertToBlockType: () => null;
14
+ /**
15
+ * Unwrap container node and convert content to list
16
+ */
17
+ export declare const unwrapAndConvertToList: () => null;
@@ -0,0 +1,17 @@
1
+ import type { TransformFunction } from './types';
2
+ /**
3
+ * Transform selection to list type
4
+ */
5
+ export declare const transformToList: () => null;
6
+ /**
7
+ * Transform list nodes
8
+ */
9
+ export declare const transformListNode: TransformFunction;
10
+ /**
11
+ * Lift list content and convert to block type
12
+ */
13
+ export declare const liftListToBlockType: () => null;
14
+ /**
15
+ * Transform between different list types
16
+ */
17
+ export declare const transformBetweenListTypes: () => null;
@@ -0,0 +1,4 @@
1
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ import type { FormatNodeTargetType } from './types';
4
+ export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number | null, targetType: FormatNodeTargetType): Transaction | null;
@@ -0,0 +1,11 @@
1
+ import type { Node as PMNode, NodeType } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ export type FormatNodeTargetType = 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6' | 'paragraph' | 'blockquote' | 'expand' | 'panel' | 'codeblock' | 'bulletList' | 'orderedList' | 'taskList';
4
+ export interface TransformContext {
5
+ tr: Transaction;
6
+ sourceNode: PMNode;
7
+ sourcePos: number | null;
8
+ targetNodeType: NodeType;
9
+ targetAttrs?: Record<string, unknown>;
10
+ }
11
+ export type TransformFunction = (context: TransformContext) => Transaction | null;
@@ -0,0 +1,12 @@
1
+ import type { Node as PMNode, NodeType } from '@atlaskit/editor-prosemirror/model';
2
+ import type { FormatNodeTargetType } from './types';
3
+ export declare const getTargetNodeInfo: (targetType: FormatNodeTargetType, nodes: Record<string, NodeType>) => {
4
+ nodeType: NodeType;
5
+ attrs?: Record<string, unknown>;
6
+ } | null;
7
+ export declare const isBlockNode: (node: PMNode) => boolean;
8
+ export declare const isListNode: (node: PMNode) => boolean;
9
+ export declare const isContainerNode: (node: PMNode) => boolean;
10
+ export declare const isBlockNodeType: (nodeType: NodeType) => boolean;
11
+ export declare const isListNodeType: (nodeType: NodeType) => boolean;
12
+ export declare const isContainerNodeType: (nodeType: NodeType) => boolean;