@atlaskit/editor-plugin-block-menu 5.2.9 → 5.2.11
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 +14 -0
- package/dist/cjs/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +0 -23
- package/dist/cjs/editor-commands/transform-node-utils/transform.js +2 -2
- package/dist/cjs/editor-commands/transform-node-utils/unwrapExpandStep.js +20 -4
- package/dist/cjs/editor-commands/transform-node-utils/utils.js +40 -4
- package/dist/cjs/editor-commands/transform-node-utils/wrapStep.js +20 -1
- package/dist/cjs/ui/block-menu-components.js +30 -20
- package/dist/cjs/ui/hooks/useSuggestedItems.js +57 -0
- package/dist/cjs/ui/suggested-items-menu-section.js +21 -0
- package/dist/cjs/ui/suggested-menu-items.js +19 -0
- package/dist/cjs/ui/utils/suggested-items-rank.js +1 -1
- package/dist/es2019/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +0 -23
- package/dist/es2019/editor-commands/transform-node-utils/transform.js +2 -2
- package/dist/es2019/editor-commands/transform-node-utils/unwrapExpandStep.js +20 -2
- package/dist/es2019/editor-commands/transform-node-utils/utils.js +39 -3
- package/dist/es2019/editor-commands/transform-node-utils/wrapStep.js +21 -1
- package/dist/es2019/ui/block-menu-components.js +12 -4
- package/dist/es2019/ui/hooks/useSuggestedItems.js +45 -0
- package/dist/es2019/ui/suggested-items-menu-section.js +15 -0
- package/dist/es2019/ui/suggested-menu-items.js +13 -0
- package/dist/es2019/ui/utils/suggested-items-rank.js +31 -43
- package/dist/esm/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +0 -23
- package/dist/esm/editor-commands/transform-node-utils/transform.js +2 -2
- package/dist/esm/editor-commands/transform-node-utils/unwrapExpandStep.js +20 -3
- package/dist/esm/editor-commands/transform-node-utils/utils.js +39 -3
- package/dist/esm/editor-commands/transform-node-utils/wrapStep.js +21 -1
- package/dist/esm/ui/block-menu-components.js +30 -20
- package/dist/esm/ui/hooks/useSuggestedItems.js +51 -0
- package/dist/esm/ui/suggested-items-menu-section.js +14 -0
- package/dist/esm/ui/suggested-menu-items.js +12 -0
- package/dist/esm/ui/utils/suggested-items-rank.js +2 -2
- package/dist/types/editor-commands/transform-node-utils/unwrapExpandStep.d.ts +5 -0
- package/dist/types/editor-commands/transform-node-utils/utils.d.ts +17 -0
- package/dist/types/editor-commands/transform-node-utils/wrapStep.d.ts +5 -0
- package/dist/types/ui/hooks/useSuggestedItems.d.ts +3 -0
- package/dist/types/ui/suggested-items-menu-section.d.ts +9 -0
- package/dist/{types-ts4.5/ui/suggested-items-renderer.d.ts → types/ui/suggested-menu-items.d.ts} +2 -2
- package/dist/types-ts4.5/editor-commands/transform-node-utils/unwrapExpandStep.d.ts +5 -0
- package/dist/types-ts4.5/editor-commands/transform-node-utils/utils.d.ts +17 -0
- package/dist/types-ts4.5/editor-commands/transform-node-utils/wrapStep.d.ts +5 -0
- package/dist/types-ts4.5/ui/hooks/useSuggestedItems.d.ts +3 -0
- package/dist/types-ts4.5/ui/suggested-items-menu-section.d.ts +9 -0
- package/dist/{types/ui/suggested-items-renderer.d.ts → types-ts4.5/ui/suggested-menu-items.d.ts} +2 -2
- package/package.json +4 -4
- package/dist/cjs/ui/suggested-items-renderer.js +0 -62
- package/dist/es2019/ui/suggested-items-renderer.js +0 -48
- package/dist/esm/ui/suggested-items-renderer.js +0 -54
|
@@ -1,9 +1,29 @@
|
|
|
1
|
+
import { convertExpandToNestedExpand } from './utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Wraps nodes into the target container type.
|
|
5
|
+
* When wrapping into expand, any expand children are converted to nestedExpand
|
|
6
|
+
* since expand cannot be a direct child of expand.
|
|
7
|
+
*/
|
|
1
8
|
export const wrapStep = (nodes, context) => {
|
|
2
9
|
const {
|
|
3
10
|
schema,
|
|
4
11
|
targetNodeTypeName
|
|
5
12
|
} = context;
|
|
6
|
-
|
|
13
|
+
|
|
14
|
+
// When wrapping into expand, convert any expand children to nestedExpand
|
|
15
|
+
// since expand cannot be a direct child of expand
|
|
16
|
+
let processedNodes = nodes;
|
|
17
|
+
if (targetNodeTypeName === 'expand') {
|
|
18
|
+
processedNodes = nodes.map(node => {
|
|
19
|
+
if (node.type.name === 'expand') {
|
|
20
|
+
const nestedExpandNode = convertExpandToNestedExpand(node, schema);
|
|
21
|
+
return nestedExpandNode !== null && nestedExpandNode !== void 0 ? nestedExpandNode : node;
|
|
22
|
+
}
|
|
23
|
+
return node;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, processedNodes);
|
|
7
27
|
if (outputNode) {
|
|
8
28
|
return [outputNode];
|
|
9
29
|
}
|
|
@@ -9,7 +9,8 @@ import { FormatMenuComponent } from './format-menu-nested';
|
|
|
9
9
|
import { FormatMenuSection } from './format-menu-section';
|
|
10
10
|
import { MoveDownDropdownItem } from './move-down';
|
|
11
11
|
import { MoveUpDropdownItem } from './move-up';
|
|
12
|
-
import {
|
|
12
|
+
import { SuggestedItemsMenuSection } from './suggested-items-menu-section';
|
|
13
|
+
import { SuggestedMenuItems } from './suggested-menu-items';
|
|
13
14
|
const getMoveUpMoveDownMenuComponents = api => {
|
|
14
15
|
return [{
|
|
15
16
|
type: 'block-menu-item',
|
|
@@ -61,9 +62,13 @@ const getTurnIntoMenuComponents = api => {
|
|
|
61
62
|
key: TRANSFORM_MENU_ITEM.key,
|
|
62
63
|
rank: TRANSFORM_MENU_ITEM_RANK[TRANSFORM_SUGGESTED_MENU_SECTION.key]
|
|
63
64
|
},
|
|
64
|
-
component: (
|
|
65
|
+
component: ({
|
|
66
|
+
children
|
|
67
|
+
} = {
|
|
68
|
+
children: null
|
|
69
|
+
}) => /*#__PURE__*/React.createElement(SuggestedItemsMenuSection, {
|
|
65
70
|
api: api
|
|
66
|
-
})
|
|
71
|
+
}, children)
|
|
67
72
|
}, {
|
|
68
73
|
type: 'block-menu-item',
|
|
69
74
|
key: TRANSFORM_SUGGESTED_MENU_ITEM.key,
|
|
@@ -71,7 +76,10 @@ const getTurnIntoMenuComponents = api => {
|
|
|
71
76
|
type: 'block-menu-section',
|
|
72
77
|
key: TRANSFORM_SUGGESTED_MENU_SECTION.key,
|
|
73
78
|
rank: TRANSFORM_SUGGESTED_MENU_SECTION_RANK[TRANSFORM_SUGGESTED_MENU_ITEM.key]
|
|
74
|
-
}
|
|
79
|
+
},
|
|
80
|
+
component: () => /*#__PURE__*/React.createElement(SuggestedMenuItems, {
|
|
81
|
+
api: api
|
|
82
|
+
})
|
|
75
83
|
}, {
|
|
76
84
|
type: 'block-menu-section',
|
|
77
85
|
key: TRANSFORM_CREATE_MENU_SECTION.key,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
3
|
+
import { getBlockNodesInRange, expandSelectionToBlockRange } from '../../editor-commands/transform-node-utils/utils';
|
|
4
|
+
import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
|
|
5
|
+
export const useSuggestedItems = api => {
|
|
6
|
+
var _api$blockMenu;
|
|
7
|
+
const {
|
|
8
|
+
preservedSelection,
|
|
9
|
+
selection
|
|
10
|
+
} = useSharedPluginStateWithSelector(api, ['blockControls', 'selection'], states => {
|
|
11
|
+
var _states$blockControls, _states$selectionStat;
|
|
12
|
+
return {
|
|
13
|
+
preservedSelection: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.preservedSelection,
|
|
14
|
+
selection: (_states$selectionStat = states.selectionState) === null || _states$selectionStat === void 0 ? void 0 : _states$selectionStat.selection
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
const blockMenuComponents = api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
|
|
18
|
+
const menuItemsMap = useMemo(() => {
|
|
19
|
+
if (!blockMenuComponents) {
|
|
20
|
+
return new Map();
|
|
21
|
+
}
|
|
22
|
+
return new Map(blockMenuComponents.filter(c => c.type === 'block-menu-item').map(item => [item.key, item]));
|
|
23
|
+
}, [blockMenuComponents]);
|
|
24
|
+
const suggestedItems = useMemo(() => {
|
|
25
|
+
const currentSelection = preservedSelection || selection;
|
|
26
|
+
if (menuItemsMap.size === 0 || !currentSelection) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const {
|
|
30
|
+
range
|
|
31
|
+
} = expandSelectionToBlockRange(currentSelection, currentSelection.$from.doc.type.schema);
|
|
32
|
+
if (!range) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
const blockNodes = getBlockNodesInRange(range);
|
|
36
|
+
const singleNode = blockNodes.length === 1 ? blockNodes[0] : undefined;
|
|
37
|
+
if (!singleNode) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const nodeTypeName = singleNode.type.name;
|
|
41
|
+
const sortedKeys = getSortedSuggestedItems(nodeTypeName);
|
|
42
|
+
return sortedKeys.map(key => menuItemsMap.get(key)).filter(item => item !== undefined);
|
|
43
|
+
}, [menuItemsMap, preservedSelection, selection]);
|
|
44
|
+
return suggestedItems;
|
|
45
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
|
|
3
|
+
import { useSuggestedItems } from './hooks/useSuggestedItems';
|
|
4
|
+
export const SuggestedItemsMenuSection = /*#__PURE__*/React.memo(({
|
|
5
|
+
api,
|
|
6
|
+
children
|
|
7
|
+
}) => {
|
|
8
|
+
const suggestedItems = useSuggestedItems(api);
|
|
9
|
+
if (suggestedItems.length === 0) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
|
|
13
|
+
title: "Suggested"
|
|
14
|
+
}, children);
|
|
15
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useSuggestedItems } from './hooks/useSuggestedItems';
|
|
3
|
+
export const SuggestedMenuItems = /*#__PURE__*/React.memo(({
|
|
4
|
+
api
|
|
5
|
+
}) => {
|
|
6
|
+
const suggestedItems = useSuggestedItems(api);
|
|
7
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, suggestedItems.map(item => {
|
|
8
|
+
const ItemComponent = item.component;
|
|
9
|
+
return ItemComponent ? /*#__PURE__*/React.createElement(ItemComponent, {
|
|
10
|
+
key: item.key
|
|
11
|
+
}) : null;
|
|
12
|
+
}));
|
|
13
|
+
});
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* }
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { TRANSFORM_STRUCTURE_PANEL_MENU_ITEM, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM, TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM, TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM, TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM, TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM, TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM, TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM,
|
|
17
|
+
import { TRANSFORM_STRUCTURE_PANEL_MENU_ITEM, TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM, TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM, TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM, TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM, TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM, TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM, TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM, TRANSFORM_HEADINGS_H1_MENU_ITEM, TRANSFORM_HEADINGS_H2_MENU_ITEM, TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM } from '@atlaskit/editor-common/block-menu';
|
|
18
18
|
export const BLOCK_MENU_NODE_TYPES = {
|
|
19
19
|
PARAGRAPH: 'paragraph',
|
|
20
20
|
EXPAND: 'expand',
|
|
@@ -37,85 +37,73 @@ export const BLOCK_MENU_NODE_TYPES = {
|
|
|
37
37
|
export const TRANSFORM_SUGGESTED_ITEMS_RANK = {
|
|
38
38
|
[BLOCK_MENU_NODE_TYPES.PARAGRAPH]: {
|
|
39
39
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
40
|
-
[
|
|
41
|
-
[
|
|
40
|
+
[TRANSFORM_HEADINGS_H1_MENU_ITEM.key]: 200,
|
|
41
|
+
[TRANSFORM_HEADINGS_H2_MENU_ITEM.key]: 300
|
|
42
42
|
},
|
|
43
43
|
[BLOCK_MENU_NODE_TYPES.EXPAND]: {
|
|
44
|
-
[
|
|
45
|
-
[
|
|
44
|
+
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 100,
|
|
45
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 200,
|
|
46
46
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300
|
|
47
47
|
},
|
|
48
48
|
[BLOCK_MENU_NODE_TYPES.BLOCKQUOTE]: {
|
|
49
|
-
[
|
|
50
|
-
[
|
|
51
|
-
[
|
|
49
|
+
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 100,
|
|
50
|
+
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 200,
|
|
51
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 300
|
|
52
52
|
},
|
|
53
53
|
[BLOCK_MENU_NODE_TYPES.LAYOUT_SECTION]: {
|
|
54
54
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
55
55
|
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 200,
|
|
56
|
-
[
|
|
56
|
+
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300
|
|
57
57
|
},
|
|
58
58
|
[BLOCK_MENU_NODE_TYPES.PANEL]: {
|
|
59
|
-
[
|
|
60
|
-
[
|
|
61
|
-
[
|
|
59
|
+
[TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key]: 100,
|
|
60
|
+
[TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key]: 200,
|
|
61
|
+
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 300
|
|
62
62
|
},
|
|
63
63
|
[BLOCK_MENU_NODE_TYPES.CODE_BLOCK]: {
|
|
64
64
|
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 100,
|
|
65
|
-
[
|
|
66
|
-
[
|
|
65
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 200,
|
|
66
|
+
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300
|
|
67
67
|
},
|
|
68
68
|
[BLOCK_MENU_NODE_TYPES.DECISION]: {
|
|
69
69
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
70
|
-
[
|
|
71
|
-
[
|
|
70
|
+
[TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key]: 200,
|
|
71
|
+
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 300
|
|
72
72
|
},
|
|
73
73
|
[BLOCK_MENU_NODE_TYPES.BULLET_LIST]: {
|
|
74
74
|
[TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key]: 100,
|
|
75
75
|
[TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key]: 200,
|
|
76
|
-
[
|
|
76
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 300
|
|
77
77
|
},
|
|
78
78
|
[BLOCK_MENU_NODE_TYPES.ORDERED_LIST]: {
|
|
79
|
-
[
|
|
80
|
-
[
|
|
81
|
-
[
|
|
79
|
+
[TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key]: 100,
|
|
80
|
+
[TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key]: 200,
|
|
81
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 300
|
|
82
82
|
},
|
|
83
83
|
[BLOCK_MENU_NODE_TYPES.HEADING]: {
|
|
84
84
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 100,
|
|
85
|
-
[
|
|
86
|
-
[
|
|
85
|
+
[TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key]: 200,
|
|
86
|
+
[TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key]: 300
|
|
87
87
|
},
|
|
88
88
|
[BLOCK_MENU_NODE_TYPES.TASK_LIST]: {
|
|
89
|
-
[
|
|
89
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
90
90
|
[TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key]: 200,
|
|
91
|
-
[
|
|
91
|
+
[TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key]: 300
|
|
92
92
|
},
|
|
93
93
|
[BLOCK_MENU_NODE_TYPES.MEDIA_SINGLE]: {
|
|
94
94
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
95
|
-
[
|
|
96
|
-
[
|
|
95
|
+
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 200,
|
|
96
|
+
[TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key]: 300
|
|
97
97
|
},
|
|
98
98
|
[BLOCK_MENU_NODE_TYPES.EXTENSION]: {
|
|
99
|
-
[
|
|
100
|
-
[
|
|
101
|
-
[
|
|
99
|
+
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 100,
|
|
100
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 200,
|
|
101
|
+
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 300
|
|
102
102
|
},
|
|
103
103
|
[BLOCK_MENU_NODE_TYPES.BODIED_EXTENSION]: {
|
|
104
|
-
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
105
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200,
|
|
106
|
-
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 300
|
|
107
|
-
},
|
|
108
|
-
[BLOCK_MENU_NODE_TYPES.BLOCK_CARD]: {
|
|
109
|
-
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
110
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200
|
|
111
|
-
},
|
|
112
|
-
[BLOCK_MENU_NODE_TYPES.EMBED_CARD]: {
|
|
113
|
-
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
114
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200
|
|
115
|
-
},
|
|
116
|
-
[BLOCK_MENU_NODE_TYPES.TABLE]: {
|
|
117
104
|
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 100,
|
|
118
|
-
[
|
|
105
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 200,
|
|
106
|
+
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 300
|
|
119
107
|
}
|
|
120
108
|
};
|
|
121
109
|
export const getSuggestedItemsForNodeType = nodeType => {
|
|
@@ -43,21 +43,6 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
|
|
|
43
43
|
return targetNodeType.validContent(Fragment.from(node));
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
/**
|
|
47
|
-
* Converts a nestedExpand to a regular expand node.
|
|
48
|
-
* NestedExpands can only exist inside expands, so when breaking out they must be converted.
|
|
49
|
-
*/
|
|
50
|
-
var convertNestedExpandToExpand = function convertNestedExpandToExpand(node, schema) {
|
|
51
|
-
var _node$attrs;
|
|
52
|
-
var expandType = schema.nodes.expand;
|
|
53
|
-
if (!expandType) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
return expandType.createAndFill({
|
|
57
|
-
title: ((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.title) || ''
|
|
58
|
-
}, node.content);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
46
|
/**
|
|
62
47
|
* A wrap step that handles mixed content according to the Compatibility Matrix:
|
|
63
48
|
* - Wraps consecutive compatible nodes into the target container
|
|
@@ -103,14 +88,6 @@ export var wrapMixedContentStep = function wrapMixedContentStep(nodes, context)
|
|
|
103
88
|
// This handles: "If there's a panel in the expand, it breaks out into a separate panel"
|
|
104
89
|
flushCurrentContainer();
|
|
105
90
|
result.push(node);
|
|
106
|
-
} else if (node.type.name === 'nestedExpand') {
|
|
107
|
-
// NestedExpand can't be wrapped and can't exist outside an expand
|
|
108
|
-
// Convert to regular expand and break out
|
|
109
|
-
flushCurrentContainer();
|
|
110
|
-
var expandNode = convertNestedExpandToExpand(node, schema);
|
|
111
|
-
if (expandNode) {
|
|
112
|
-
result.push(expandNode);
|
|
113
|
-
}
|
|
114
91
|
} else if (isTextNode(node)) {
|
|
115
92
|
// Text node (heading, paragraph) that can't be wrapped - convert to paragraph
|
|
116
93
|
// Example: heading can't go in blockquote, so convert to paragraph with same content
|
|
@@ -84,9 +84,9 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
84
84
|
decisionList: [unwrapStep, wrapBlockquoteToDecisionListStep]
|
|
85
85
|
},
|
|
86
86
|
layoutSection: {
|
|
87
|
-
blockquote: [unwrapLayoutStep,
|
|
87
|
+
blockquote: [unwrapLayoutStep, wrapMixedContentStep],
|
|
88
88
|
expand: [unwrapLayoutStep, wrapStep],
|
|
89
|
-
panel: [unwrapLayoutStep,
|
|
89
|
+
panel: [unwrapLayoutStep, wrapMixedContentStep],
|
|
90
90
|
codeBlock: [unwrapLayoutStep, flattenStep, wrapStep],
|
|
91
91
|
paragraph: [unwrapLayoutStep]
|
|
92
92
|
},
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
1
|
import { unwrapStep } from './unwrapStep';
|
|
2
|
+
import { convertNestedExpandToExpand } from './utils';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Unwraps an expand/nestedExpand node, converting its title attribute to a paragraph
|
|
6
6
|
* and prepending it to the children.
|
|
7
7
|
*
|
|
8
|
+
* Any nestedExpand children are converted to regular expands since nestedExpand
|
|
9
|
+
* can only exist inside an expand.
|
|
10
|
+
*
|
|
8
11
|
* Example: expand({ title: 'title' })(p('b')) → [p('title'), p('b')]
|
|
12
|
+
* Example: expand({ title: 'outer' })(nestedExpand({ title: 'inner' })(p('x')))
|
|
13
|
+
* → [p('outer'), expand({ title: 'inner' })(p('x'))]
|
|
9
14
|
*/
|
|
10
15
|
export var unwrapExpandStep = function unwrapExpandStep(nodes, context) {
|
|
11
16
|
var schema = context.schema;
|
|
@@ -27,8 +32,20 @@ export var unwrapExpandStep = function unwrapExpandStep(nodes, context) {
|
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
// Add the children
|
|
31
|
-
|
|
35
|
+
// Add the children, converting any nestedExpands to regular expands
|
|
36
|
+
// since nestedExpand can only exist inside an expand
|
|
37
|
+
node.children.forEach(function (child) {
|
|
38
|
+
if (child.type.name === nestedExpand.name) {
|
|
39
|
+
var expandNode = convertNestedExpandToExpand(child, schema);
|
|
40
|
+
if (expandNode) {
|
|
41
|
+
outputNodes.push(expandNode);
|
|
42
|
+
} else {
|
|
43
|
+
outputNodes.push(child);
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
outputNodes.push(child);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
32
49
|
} else {
|
|
33
50
|
unwrapStep([node], context);
|
|
34
51
|
}
|
|
@@ -61,7 +61,7 @@ export var getTargetNodeTypeNameInContext = function getTargetNodeTypeNameInCont
|
|
|
61
61
|
*/
|
|
62
62
|
export var expandSelectionToBlockRange = function expandSelectionToBlockRange(selection, schema) {
|
|
63
63
|
var nodes = schema.nodes;
|
|
64
|
-
var nodesNeedToExpandRange = [nodes.listItem, nodes.taskItem];
|
|
64
|
+
var nodesNeedToExpandRange = [nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.listItem, nodes.taskItem];
|
|
65
65
|
|
|
66
66
|
// when adding nodes.tableRow, tableHeader, tableCell in nodesNeedToExpandRang,
|
|
67
67
|
// expandToBlockRange does not return expected table start position, sometimes even freeze editor
|
|
@@ -70,10 +70,11 @@ export var expandSelectionToBlockRange = function expandSelectionToBlockRange(se
|
|
|
70
70
|
var table = findTable(selection);
|
|
71
71
|
if (table) {
|
|
72
72
|
var $from = selection.$from.doc.resolve(table.pos);
|
|
73
|
-
var $to = selection.$from.doc.resolve(table.pos + table.node.nodeSize);
|
|
73
|
+
var $to = selection.$from.doc.resolve(table.pos + table.node.nodeSize - 1);
|
|
74
74
|
return {
|
|
75
75
|
$from: $from,
|
|
76
|
-
$to: $to
|
|
76
|
+
$to: $to,
|
|
77
|
+
range: $from.blockRange($to)
|
|
77
78
|
};
|
|
78
79
|
}
|
|
79
80
|
}
|
|
@@ -106,7 +107,42 @@ export var isListType = function isListType(node, schema) {
|
|
|
106
107
|
return list === node.type;
|
|
107
108
|
});
|
|
108
109
|
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Converts a nestedExpand to a regular expand node.
|
|
113
|
+
* NestedExpands can only exist inside expands, so when breaking out or placing
|
|
114
|
+
* in containers that don't support nesting, they must be converted.
|
|
115
|
+
*/
|
|
116
|
+
export var convertNestedExpandToExpand = function convertNestedExpandToExpand(node, schema) {
|
|
117
|
+
var _node$attrs;
|
|
118
|
+
var expandType = schema.nodes.expand;
|
|
119
|
+
if (!expandType) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return expandType.createAndFill({
|
|
123
|
+
title: ((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.title) || ''
|
|
124
|
+
}, node.content);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Converts an expand to a nestedExpand node.
|
|
129
|
+
* When placing an expand inside another expand, it must become a nestedExpand
|
|
130
|
+
* since expand cannot be a direct child of expand.
|
|
131
|
+
*/
|
|
132
|
+
export var convertExpandToNestedExpand = function convertExpandToNestedExpand(node, schema) {
|
|
133
|
+
var _node$attrs2;
|
|
134
|
+
var nestedExpandType = schema.nodes.nestedExpand;
|
|
135
|
+
if (!nestedExpandType) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
return nestedExpandType.createAndFill({
|
|
139
|
+
title: ((_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.title) || ''
|
|
140
|
+
}, node.content);
|
|
141
|
+
};
|
|
109
142
|
export var getBlockNodesInRange = function getBlockNodesInRange(range) {
|
|
143
|
+
if (range.startIndex === range.endIndex) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
110
146
|
if (range.endIndex - range.startIndex <= 1) {
|
|
111
147
|
return [range.parent.child(range.startIndex)];
|
|
112
148
|
}
|
|
@@ -1,7 +1,27 @@
|
|
|
1
|
+
import { convertExpandToNestedExpand } from './utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Wraps nodes into the target container type.
|
|
5
|
+
* When wrapping into expand, any expand children are converted to nestedExpand
|
|
6
|
+
* since expand cannot be a direct child of expand.
|
|
7
|
+
*/
|
|
1
8
|
export var wrapStep = function wrapStep(nodes, context) {
|
|
2
9
|
var schema = context.schema,
|
|
3
10
|
targetNodeTypeName = context.targetNodeTypeName;
|
|
4
|
-
|
|
11
|
+
|
|
12
|
+
// When wrapping into expand, convert any expand children to nestedExpand
|
|
13
|
+
// since expand cannot be a direct child of expand
|
|
14
|
+
var processedNodes = nodes;
|
|
15
|
+
if (targetNodeTypeName === 'expand') {
|
|
16
|
+
processedNodes = nodes.map(function (node) {
|
|
17
|
+
if (node.type.name === 'expand') {
|
|
18
|
+
var nestedExpandNode = convertExpandToNestedExpand(node, schema);
|
|
19
|
+
return nestedExpandNode !== null && nestedExpandNode !== void 0 ? nestedExpandNode : node;
|
|
20
|
+
}
|
|
21
|
+
return node;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
var outputNode = schema.nodes[targetNodeTypeName].createAndFill({}, processedNodes);
|
|
5
25
|
if (outputNode) {
|
|
6
26
|
return [outputNode];
|
|
7
27
|
}
|
|
@@ -10,7 +10,8 @@ import { FormatMenuComponent } from './format-menu-nested';
|
|
|
10
10
|
import { FormatMenuSection } from './format-menu-section';
|
|
11
11
|
import { MoveDownDropdownItem } from './move-down';
|
|
12
12
|
import { MoveUpDropdownItem } from './move-up';
|
|
13
|
-
import {
|
|
13
|
+
import { SuggestedItemsMenuSection } from './suggested-items-menu-section';
|
|
14
|
+
import { SuggestedMenuItems } from './suggested-menu-items';
|
|
14
15
|
var getMoveUpMoveDownMenuComponents = function getMoveUpMoveDownMenuComponents(api) {
|
|
15
16
|
return [{
|
|
16
17
|
type: 'block-menu-item',
|
|
@@ -67,9 +68,13 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
|
|
|
67
68
|
rank: TRANSFORM_MENU_ITEM_RANK[TRANSFORM_SUGGESTED_MENU_SECTION.key]
|
|
68
69
|
},
|
|
69
70
|
component: function component() {
|
|
70
|
-
|
|
71
|
+
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
72
|
+
children: null
|
|
73
|
+
},
|
|
74
|
+
children = _ref2.children;
|
|
75
|
+
return /*#__PURE__*/React.createElement(SuggestedItemsMenuSection, {
|
|
71
76
|
api: api
|
|
72
|
-
});
|
|
77
|
+
}, children);
|
|
73
78
|
}
|
|
74
79
|
}, {
|
|
75
80
|
type: 'block-menu-item',
|
|
@@ -78,6 +83,11 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
|
|
|
78
83
|
type: 'block-menu-section',
|
|
79
84
|
key: TRANSFORM_SUGGESTED_MENU_SECTION.key,
|
|
80
85
|
rank: TRANSFORM_SUGGESTED_MENU_SECTION_RANK[TRANSFORM_SUGGESTED_MENU_ITEM.key]
|
|
86
|
+
},
|
|
87
|
+
component: function component() {
|
|
88
|
+
return /*#__PURE__*/React.createElement(SuggestedMenuItems, {
|
|
89
|
+
api: api
|
|
90
|
+
});
|
|
81
91
|
}
|
|
82
92
|
}, {
|
|
83
93
|
type: 'block-menu-section',
|
|
@@ -88,10 +98,10 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
|
|
|
88
98
|
rank: TRANSFORM_MENU_ITEM_RANK[TRANSFORM_CREATE_MENU_SECTION.key]
|
|
89
99
|
},
|
|
90
100
|
component: function component() {
|
|
91
|
-
var
|
|
101
|
+
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
92
102
|
children: null
|
|
93
103
|
},
|
|
94
|
-
children =
|
|
104
|
+
children = _ref3.children;
|
|
95
105
|
return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
|
|
96
106
|
title: "Create"
|
|
97
107
|
}, children);
|
|
@@ -105,10 +115,10 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
|
|
|
105
115
|
rank: TRANSFORM_MENU_ITEM_RANK[TRANSFORM_STRUCTURE_MENU_SECTION.key]
|
|
106
116
|
},
|
|
107
117
|
component: function component() {
|
|
108
|
-
var
|
|
118
|
+
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
109
119
|
children: null
|
|
110
120
|
},
|
|
111
|
-
children =
|
|
121
|
+
children = _ref4.children;
|
|
112
122
|
return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
|
|
113
123
|
title: "Structure"
|
|
114
124
|
}, children);
|
|
@@ -122,10 +132,10 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
|
|
|
122
132
|
rank: TRANSFORM_MENU_ITEM_RANK[TRANSFORM_HEADINGS_MENU_SECTION.key]
|
|
123
133
|
},
|
|
124
134
|
component: function component() {
|
|
125
|
-
var
|
|
135
|
+
var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
126
136
|
children: null
|
|
127
137
|
},
|
|
128
|
-
children =
|
|
138
|
+
children = _ref5.children;
|
|
129
139
|
return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
|
|
130
140
|
title: "Headings",
|
|
131
141
|
hasSeparator: true
|
|
@@ -135,23 +145,23 @@ var getTurnIntoMenuComponents = function getTurnIntoMenuComponents(api) {
|
|
|
135
145
|
type: 'block-menu-section',
|
|
136
146
|
key: TRANSFORM_MENU_SECTION.key,
|
|
137
147
|
rank: MAIN_BLOCK_MENU_SECTION_RANK[TRANSFORM_MENU_SECTION.key],
|
|
138
|
-
component: function component(
|
|
139
|
-
var children =
|
|
148
|
+
component: function component(_ref6) {
|
|
149
|
+
var children = _ref6.children;
|
|
140
150
|
return /*#__PURE__*/React.createElement(FormatMenuSection, {
|
|
141
151
|
api: api
|
|
142
152
|
}, children);
|
|
143
153
|
}
|
|
144
154
|
}];
|
|
145
155
|
};
|
|
146
|
-
export var getBlockMenuComponents = function getBlockMenuComponents(
|
|
147
|
-
var api =
|
|
148
|
-
config =
|
|
156
|
+
export var getBlockMenuComponents = function getBlockMenuComponents(_ref7) {
|
|
157
|
+
var api = _ref7.api,
|
|
158
|
+
config = _ref7.config;
|
|
149
159
|
return [].concat(_toConsumableArray(getTurnIntoMenuComponents(api)), [{
|
|
150
160
|
type: 'block-menu-section',
|
|
151
161
|
key: BLOCK_ACTIONS_MENU_SECTION.key,
|
|
152
162
|
rank: MAIN_BLOCK_MENU_SECTION_RANK[BLOCK_ACTIONS_MENU_SECTION.key],
|
|
153
|
-
component: function component(
|
|
154
|
-
var children =
|
|
163
|
+
component: function component(_ref8) {
|
|
164
|
+
var children = _ref8.children;
|
|
155
165
|
return /*#__PURE__*/React.createElement(CopySection, {
|
|
156
166
|
api: api
|
|
157
167
|
}, children);
|
|
@@ -174,8 +184,8 @@ export var getBlockMenuComponents = function getBlockMenuComponents(_ref6) {
|
|
|
174
184
|
type: 'block-menu-section',
|
|
175
185
|
key: POSITION_MENU_SECTION.key,
|
|
176
186
|
rank: MAIN_BLOCK_MENU_SECTION_RANK[POSITION_MENU_SECTION.key],
|
|
177
|
-
component: function component(
|
|
178
|
-
var children =
|
|
187
|
+
component: function component(_ref9) {
|
|
188
|
+
var children = _ref9.children;
|
|
179
189
|
return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
|
|
180
190
|
hasSeparator: true
|
|
181
191
|
}, children);
|
|
@@ -184,8 +194,8 @@ export var getBlockMenuComponents = function getBlockMenuComponents(_ref6) {
|
|
|
184
194
|
type: 'block-menu-section',
|
|
185
195
|
key: DELETE_MENU_SECTION.key,
|
|
186
196
|
rank: MAIN_BLOCK_MENU_SECTION_RANK[DELETE_MENU_SECTION.key],
|
|
187
|
-
component: function component(
|
|
188
|
-
var children =
|
|
197
|
+
component: function component(_ref0) {
|
|
198
|
+
var children = _ref0.children;
|
|
189
199
|
return /*#__PURE__*/React.createElement(DeleteSection, {
|
|
190
200
|
api: api
|
|
191
201
|
}, children);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
3
|
+
import { getBlockNodesInRange, expandSelectionToBlockRange } from '../../editor-commands/transform-node-utils/utils';
|
|
4
|
+
import { getSortedSuggestedItems } from '../utils/suggested-items-rank';
|
|
5
|
+
export var useSuggestedItems = function useSuggestedItems(api) {
|
|
6
|
+
var _api$blockMenu;
|
|
7
|
+
var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['blockControls', 'selection'], function (states) {
|
|
8
|
+
var _states$blockControls, _states$selectionStat;
|
|
9
|
+
return {
|
|
10
|
+
preservedSelection: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.preservedSelection,
|
|
11
|
+
selection: (_states$selectionStat = states.selectionState) === null || _states$selectionStat === void 0 ? void 0 : _states$selectionStat.selection
|
|
12
|
+
};
|
|
13
|
+
}),
|
|
14
|
+
preservedSelection = _useSharedPluginState.preservedSelection,
|
|
15
|
+
selection = _useSharedPluginState.selection;
|
|
16
|
+
var blockMenuComponents = api === null || api === void 0 || (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
|
|
17
|
+
var menuItemsMap = useMemo(function () {
|
|
18
|
+
if (!blockMenuComponents) {
|
|
19
|
+
return new Map();
|
|
20
|
+
}
|
|
21
|
+
return new Map(blockMenuComponents.filter(function (c) {
|
|
22
|
+
return c.type === 'block-menu-item';
|
|
23
|
+
}).map(function (item) {
|
|
24
|
+
return [item.key, item];
|
|
25
|
+
}));
|
|
26
|
+
}, [blockMenuComponents]);
|
|
27
|
+
var suggestedItems = useMemo(function () {
|
|
28
|
+
var currentSelection = preservedSelection || selection;
|
|
29
|
+
if (menuItemsMap.size === 0 || !currentSelection) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
var _expandSelectionToBlo = expandSelectionToBlockRange(currentSelection, currentSelection.$from.doc.type.schema),
|
|
33
|
+
range = _expandSelectionToBlo.range;
|
|
34
|
+
if (!range) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
var blockNodes = getBlockNodesInRange(range);
|
|
38
|
+
var singleNode = blockNodes.length === 1 ? blockNodes[0] : undefined;
|
|
39
|
+
if (!singleNode) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
var nodeTypeName = singleNode.type.name;
|
|
43
|
+
var sortedKeys = getSortedSuggestedItems(nodeTypeName);
|
|
44
|
+
return sortedKeys.map(function (key) {
|
|
45
|
+
return menuItemsMap.get(key);
|
|
46
|
+
}).filter(function (item) {
|
|
47
|
+
return item !== undefined;
|
|
48
|
+
});
|
|
49
|
+
}, [menuItemsMap, preservedSelection, selection]);
|
|
50
|
+
return suggestedItems;
|
|
51
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
|
|
3
|
+
import { useSuggestedItems } from './hooks/useSuggestedItems';
|
|
4
|
+
export var SuggestedItemsMenuSection = /*#__PURE__*/React.memo(function (_ref) {
|
|
5
|
+
var api = _ref.api,
|
|
6
|
+
children = _ref.children;
|
|
7
|
+
var suggestedItems = useSuggestedItems(api);
|
|
8
|
+
if (suggestedItems.length === 0) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
|
|
12
|
+
title: "Suggested"
|
|
13
|
+
}, children);
|
|
14
|
+
});
|