@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.
- package/CHANGELOG.md +15 -0
- package/afm-cc/tsconfig.json +4 -1
- package/afm-dev-agents/tsconfig.json +3 -0
- package/afm-jira/tsconfig.json +3 -0
- package/afm-passionfruit/tsconfig.json +3 -0
- package/afm-post-office/tsconfig.json +3 -0
- package/afm-rovo-extension/tsconfig.json +3 -0
- package/afm-townsquare/tsconfig.json +3 -0
- package/dist/cjs/blockMenuPlugin.js +6 -0
- package/dist/cjs/editor-commands/formatNode.js +23 -0
- package/dist/cjs/editor-commands/transforms/block-transforms.js +37 -0
- package/dist/cjs/editor-commands/transforms/container-transforms.js +59 -0
- package/dist/cjs/editor-commands/transforms/list-transforms.js +53 -0
- package/dist/cjs/editor-commands/transforms/transformNodeToTargetType.js +50 -0
- package/dist/cjs/editor-commands/transforms/types.js +5 -0
- package/dist/cjs/editor-commands/transforms/utils.js +109 -0
- package/dist/cjs/ui/block-menu-components.js +55 -42
- package/dist/cjs/ui/block-menu-renderer.js +48 -11
- package/dist/es2019/blockMenuPlugin.js +6 -0
- package/dist/es2019/editor-commands/formatNode.js +20 -0
- package/dist/es2019/editor-commands/transforms/block-transforms.js +38 -0
- package/dist/es2019/editor-commands/transforms/container-transforms.js +55 -0
- package/dist/es2019/editor-commands/transforms/list-transforms.js +49 -0
- package/dist/es2019/editor-commands/transforms/transformNodeToTargetType.js +48 -0
- package/dist/es2019/editor-commands/transforms/types.js +1 -0
- package/dist/es2019/editor-commands/transforms/utils.js +103 -0
- package/dist/es2019/ui/block-menu-components.js +45 -32
- package/dist/es2019/ui/block-menu-renderer.js +46 -11
- package/dist/esm/blockMenuPlugin.js +6 -0
- package/dist/esm/editor-commands/formatNode.js +17 -0
- package/dist/esm/editor-commands/transforms/block-transforms.js +32 -0
- package/dist/esm/editor-commands/transforms/container-transforms.js +54 -0
- package/dist/esm/editor-commands/transforms/list-transforms.js +48 -0
- package/dist/esm/editor-commands/transforms/transformNodeToTargetType.js +44 -0
- package/dist/esm/editor-commands/transforms/types.js +1 -0
- package/dist/esm/editor-commands/transforms/utils.js +103 -0
- package/dist/esm/ui/block-menu-components.js +56 -43
- package/dist/esm/ui/block-menu-renderer.js +48 -11
- package/dist/types/blockMenuPluginType.d.ts +27 -3
- package/dist/types/editor-commands/formatNode.d.ts +9 -0
- package/dist/types/editor-commands/transforms/block-transforms.d.ts +5 -0
- package/dist/types/editor-commands/transforms/container-transforms.d.ts +17 -0
- package/dist/types/editor-commands/transforms/list-transforms.d.ts +17 -0
- package/dist/types/editor-commands/transforms/transformNodeToTargetType.d.ts +4 -0
- package/dist/types/editor-commands/transforms/types.d.ts +11 -0
- package/dist/types/editor-commands/transforms/utils.d.ts +12 -0
- package/dist/types-ts4.5/blockMenuPluginType.d.ts +27 -3
- package/dist/types-ts4.5/editor-commands/formatNode.d.ts +9 -0
- package/dist/types-ts4.5/editor-commands/transforms/block-transforms.d.ts +5 -0
- package/dist/types-ts4.5/editor-commands/transforms/container-transforms.d.ts +17 -0
- package/dist/types-ts4.5/editor-commands/transforms/list-transforms.d.ts +17 -0
- package/dist/types-ts4.5/editor-commands/transforms/transformNodeToTargetType.d.ts +4 -0
- package/dist/types-ts4.5/editor-commands/transforms/types.d.ts +11 -0
- package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +12 -0
- 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 {
|
|
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
|
|
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
|
-
|
|
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: '
|
|
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(
|
|
50
|
-
var 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(
|
|
58
|
-
var 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(
|
|
95
|
-
var 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(
|
|
105
|
-
var 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
|
|
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
|
|
23
|
-
|
|
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 =
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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 = (
|
|
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
|
-
|
|
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,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;
|