@atlaskit/editor-plugin-block-menu 5.1.7 → 5.1.9
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 +18 -0
- package/dist/cjs/editor-commands/transform-node-utils/transform.js +5 -4
- package/dist/cjs/editor-commands/transform-node-utils/wrapMixedContentStep.js +141 -0
- package/dist/cjs/ui/block-menu-components.js +29 -24
- package/dist/cjs/ui/block-menu-provider.js +19 -2
- package/dist/cjs/ui/move-down.js +18 -7
- package/dist/cjs/ui/move-up.js +18 -7
- package/dist/cjs/ui/suggested-items-renderer.js +62 -0
- package/dist/cjs/ui/utils/suggested-items-rank.js +0 -41
- package/dist/es2019/editor-commands/transform-node-utils/transform.js +5 -4
- package/dist/es2019/editor-commands/transform-node-utils/wrapMixedContentStep.js +135 -0
- package/dist/es2019/ui/block-menu-components.js +12 -9
- package/dist/es2019/ui/block-menu-provider.js +20 -3
- package/dist/es2019/ui/move-down.js +17 -7
- package/dist/es2019/ui/move-up.js +17 -7
- package/dist/es2019/ui/suggested-items-renderer.js +48 -0
- package/dist/es2019/ui/utils/suggested-items-rank.js +17 -110
- package/dist/esm/editor-commands/transform-node-utils/transform.js +5 -4
- package/dist/esm/editor-commands/transform-node-utils/wrapMixedContentStep.js +135 -0
- package/dist/esm/ui/block-menu-components.js +30 -25
- package/dist/esm/ui/block-menu-provider.js +20 -3
- package/dist/esm/ui/move-down.js +16 -7
- package/dist/esm/ui/move-up.js +16 -7
- package/dist/esm/ui/suggested-items-renderer.js +54 -0
- package/dist/esm/ui/utils/suggested-items-rank.js +0 -41
- package/dist/types/editor-commands/transform-node-utils/wrapMixedContentStep.d.ts +20 -0
- package/dist/types/ui/block-menu-provider.d.ts +8 -0
- package/dist/types/ui/suggested-items-renderer.d.ts +8 -0
- package/dist/types/ui/utils/suggested-items-rank.d.ts +0 -36
- package/dist/types-ts4.5/editor-commands/transform-node-utils/wrapMixedContentStep.d.ts +20 -0
- package/dist/types-ts4.5/ui/block-menu-provider.d.ts +8 -0
- package/dist/types-ts4.5/ui/suggested-items-renderer.d.ts +8 -0
- package/dist/types-ts4.5/ui/utils/suggested-items-rank.d.ts +0 -36
- package/package.json +3 -3
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { NODE_CATEGORY_BY_TYPE } from './types';
|
|
3
|
+
import { unwrapStep } from './unwrapStep';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Determines if a node can be flattened (unwrapped and its contents merged).
|
|
7
|
+
*
|
|
8
|
+
* According to the text transformations list, flattenable nodes are:
|
|
9
|
+
* - Bulleted list, Numbered list, Task list
|
|
10
|
+
* - Text nodes (heading, paragraph)
|
|
11
|
+
*
|
|
12
|
+
* Containers (panels, expands, layouts, blockquotes) and atomic nodes (tables, media, macros) break out.
|
|
13
|
+
*/
|
|
14
|
+
const canFlatten = node => {
|
|
15
|
+
const category = NODE_CATEGORY_BY_TYPE[node.type.name];
|
|
16
|
+
// Text and list nodes can be flattened (converted to simpler forms)
|
|
17
|
+
return category === 'text' || category === 'list';
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Flattens a node by extracting its contents using the appropriate unwrap step.
|
|
22
|
+
* This is only called for text and list nodes that can be converted to simpler forms.
|
|
23
|
+
* Uses unwrapStep to extract children from list containers.
|
|
24
|
+
*/
|
|
25
|
+
const flattenNode = (node, context) => {
|
|
26
|
+
return unwrapStep([node], context);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Determines if a node can be wrapped in the target container type.
|
|
31
|
+
* Uses the schema's validContent to check if the target container can hold this node.
|
|
32
|
+
*
|
|
33
|
+
* Note: What can be wrapped depends on the target container type - for example:
|
|
34
|
+
* - Tables and media CAN go inside expand nodes
|
|
35
|
+
* - Tables CANNOT go inside panels or blockquotes
|
|
36
|
+
*/
|
|
37
|
+
const canWrapInTarget = (node, targetNodeType, targetNodeTypeName) => {
|
|
38
|
+
// Same-type containers should break out as separate containers
|
|
39
|
+
if (node.type.name === targetNodeTypeName) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Use the schema to determine if this node can be contained in the target
|
|
44
|
+
try {
|
|
45
|
+
return targetNodeType.validContent(Fragment.from(node));
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Converts a nestedExpand to a regular expand node.
|
|
53
|
+
* NestedExpands can only exist inside expands, so when breaking out they must be converted.
|
|
54
|
+
*/
|
|
55
|
+
const convertNestedExpandToExpand = (node, schema) => {
|
|
56
|
+
var _node$attrs;
|
|
57
|
+
const expandType = schema.nodes.expand;
|
|
58
|
+
if (!expandType) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return expandType.createAndFill({
|
|
62
|
+
title: ((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.title) || ''
|
|
63
|
+
}, node.content);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A wrap step that handles mixed content according to the Compatibility Matrix:
|
|
68
|
+
* - Wraps consecutive compatible nodes into the target container
|
|
69
|
+
* - Same-type containers break out as separate containers (preserved as-is)
|
|
70
|
+
* - NestedExpands break out as regular expands (converted since nestedExpand can't exist outside expand)
|
|
71
|
+
* - Container structures that can't be nested in target break out (not flattened)
|
|
72
|
+
* - Text/list nodes that can't be wrapped are flattened and merged into the container
|
|
73
|
+
* - Atomic nodes (tables, media, macros) break out
|
|
74
|
+
*
|
|
75
|
+
* What can be wrapped depends on the target container's schema:
|
|
76
|
+
* - expand → panel: tables break out, nestedExpands convert to expands and break out
|
|
77
|
+
* - expand → blockquote: tables/media break out, nestedExpands convert to expands and break out
|
|
78
|
+
* - expand → expand: tables/media stay inside (expands can contain them)
|
|
79
|
+
*
|
|
80
|
+
* Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
|
|
81
|
+
* Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
|
|
82
|
+
* Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
|
|
83
|
+
*/
|
|
84
|
+
export const wrapMixedContentStep = (nodes, context) => {
|
|
85
|
+
const {
|
|
86
|
+
schema,
|
|
87
|
+
targetNodeTypeName
|
|
88
|
+
} = context;
|
|
89
|
+
const targetNodeType = schema.nodes[targetNodeTypeName];
|
|
90
|
+
if (!targetNodeType) {
|
|
91
|
+
return nodes;
|
|
92
|
+
}
|
|
93
|
+
const result = [];
|
|
94
|
+
let currentContainerContent = [];
|
|
95
|
+
const flushCurrentContainer = () => {
|
|
96
|
+
if (currentContainerContent.length > 0) {
|
|
97
|
+
const containerNode = targetNodeType.createAndFill({}, Fragment.fromArray(currentContainerContent));
|
|
98
|
+
if (containerNode) {
|
|
99
|
+
result.push(containerNode);
|
|
100
|
+
}
|
|
101
|
+
currentContainerContent = [];
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
nodes.forEach(node => {
|
|
105
|
+
if (canWrapInTarget(node, targetNodeType, targetNodeTypeName)) {
|
|
106
|
+
// Node can be wrapped - add to current container content
|
|
107
|
+
currentContainerContent.push(node);
|
|
108
|
+
} else if (node.type.name === targetNodeTypeName) {
|
|
109
|
+
// Same-type container - breaks out as a separate container (preserved as-is)
|
|
110
|
+
// This handles: "If there's a panel in the expand, it breaks out into a separate panel"
|
|
111
|
+
flushCurrentContainer();
|
|
112
|
+
result.push(node);
|
|
113
|
+
} else if (node.type.name === 'nestedExpand') {
|
|
114
|
+
// NestedExpand can't be wrapped and can't exist outside an expand
|
|
115
|
+
// Convert to regular expand and break out
|
|
116
|
+
flushCurrentContainer();
|
|
117
|
+
const expandNode = convertNestedExpandToExpand(node, schema);
|
|
118
|
+
if (expandNode) {
|
|
119
|
+
result.push(expandNode);
|
|
120
|
+
}
|
|
121
|
+
} else if (canFlatten(node)) {
|
|
122
|
+
// Node cannot be wrapped but CAN be flattened - flatten and add to container
|
|
123
|
+
const flattenedNodes = flattenNode(node, context);
|
|
124
|
+
currentContainerContent.push(...flattenedNodes);
|
|
125
|
+
} else {
|
|
126
|
+
// Node cannot be wrapped AND cannot be flattened (containers, tables, media, macros) - break out
|
|
127
|
+
flushCurrentContainer();
|
|
128
|
+
result.push(node);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Flush any remaining content into a container
|
|
133
|
+
flushCurrentContainer();
|
|
134
|
+
return result.length > 0 ? result : nodes;
|
|
135
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { BLOCK_ACTIONS_COPY_LINK_TO_BLOCK_MENU_ITEM, BLOCK_ACTIONS_MENU_SECTION, BLOCK_ACTIONS_MENU_SECTION_RANK, DELETE_MENU_SECTION, DELETE_MENU_SECTION_RANK, DELETE_MENU_ITEM, POSITION_MENU_SECTION, POSITION_MENU_SECTION_RANK, POSITION_MOVE_DOWN_MENU_ITEM, POSITION_MOVE_UP_MENU_ITEM, TRANSFORM_MENU_ITEM, TRANSFORM_MENU_ITEM_RANK, TRANSFORM_MENU_SECTION, TRANSFORM_MENU_SECTION_RANK, TRANSFORM_CREATE_MENU_SECTION, TRANSFORM_SUGGESTED_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION, TRANSFORM_HEADINGS_MENU_SECTION, MAIN_BLOCK_MENU_SECTION_RANK } from '@atlaskit/editor-common/block-menu';
|
|
2
|
+
import { BLOCK_ACTIONS_COPY_LINK_TO_BLOCK_MENU_ITEM, BLOCK_ACTIONS_MENU_SECTION, BLOCK_ACTIONS_MENU_SECTION_RANK, DELETE_MENU_SECTION, DELETE_MENU_SECTION_RANK, DELETE_MENU_ITEM, POSITION_MENU_SECTION, POSITION_MENU_SECTION_RANK, POSITION_MOVE_DOWN_MENU_ITEM, POSITION_MOVE_UP_MENU_ITEM, TRANSFORM_MENU_ITEM, TRANSFORM_MENU_ITEM_RANK, TRANSFORM_MENU_SECTION, TRANSFORM_MENU_SECTION_RANK, TRANSFORM_CREATE_MENU_SECTION, TRANSFORM_SUGGESTED_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION, TRANSFORM_HEADINGS_MENU_SECTION, MAIN_BLOCK_MENU_SECTION_RANK, TRANSFORM_SUGGESTED_MENU_SECTION_RANK, TRANSFORM_SUGGESTED_MENU_ITEM } from '@atlaskit/editor-common/block-menu';
|
|
3
3
|
import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
|
|
4
4
|
import { CopyLinkDropdownItem } from './copy-link';
|
|
5
5
|
import { CopySection } from './copy-section';
|
|
@@ -9,6 +9,7 @@ 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 { SuggestedItemsRenderer } from './suggested-items-renderer';
|
|
12
13
|
const getMoveUpMoveDownMenuComponents = api => {
|
|
13
14
|
return [{
|
|
14
15
|
type: 'block-menu-item',
|
|
@@ -60,14 +61,16 @@ const getTurnIntoMenuComponents = api => {
|
|
|
60
61
|
key: TRANSFORM_MENU_ITEM.key,
|
|
61
62
|
rank: TRANSFORM_MENU_ITEM_RANK[TRANSFORM_SUGGESTED_MENU_SECTION.key]
|
|
62
63
|
},
|
|
63
|
-
component: ({
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
component: () => /*#__PURE__*/React.createElement(SuggestedItemsRenderer, {
|
|
65
|
+
api: api
|
|
66
|
+
})
|
|
67
|
+
}, {
|
|
68
|
+
type: 'block-menu-item',
|
|
69
|
+
key: TRANSFORM_SUGGESTED_MENU_ITEM.key,
|
|
70
|
+
parent: {
|
|
71
|
+
type: 'block-menu-section',
|
|
72
|
+
key: TRANSFORM_SUGGESTED_MENU_SECTION.key,
|
|
73
|
+
rank: TRANSFORM_SUGGESTED_MENU_SECTION_RANK[TRANSFORM_SUGGESTED_MENU_ITEM.key]
|
|
71
74
|
}
|
|
72
75
|
}, {
|
|
73
76
|
type: 'block-menu-section',
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import React, { useCallback, createContext, useContext } from 'react';
|
|
1
|
+
import React, { useCallback, createContext, useContext, useRef } from 'react';
|
|
2
2
|
const BlockMenuContext = /*#__PURE__*/createContext({
|
|
3
|
-
onDropdownOpenChanged: () => {}
|
|
3
|
+
onDropdownOpenChanged: () => {},
|
|
4
|
+
moveFocusTo: () => {},
|
|
5
|
+
moveDownRef: /*#__PURE__*/React.createRef(),
|
|
6
|
+
moveUpRef: /*#__PURE__*/React.createRef()
|
|
4
7
|
});
|
|
5
8
|
export const useBlockMenu = () => {
|
|
6
9
|
const context = useContext(BlockMenuContext);
|
|
@@ -13,6 +16,8 @@ export const BlockMenuProvider = ({
|
|
|
13
16
|
children,
|
|
14
17
|
api
|
|
15
18
|
}) => {
|
|
19
|
+
const moveUpRef = useRef(null);
|
|
20
|
+
const moveDownRef = useRef(null);
|
|
16
21
|
const onDropdownOpenChanged = useCallback(isOpen => {
|
|
17
22
|
if (!isOpen) {
|
|
18
23
|
// On Dropdown closed, return focus to editor
|
|
@@ -23,9 +28,21 @@ export const BlockMenuProvider = ({
|
|
|
23
28
|
}), 1);
|
|
24
29
|
}
|
|
25
30
|
}, [api]);
|
|
31
|
+
const moveFocusTo = useCallback(direction => {
|
|
32
|
+
if (direction === 'moveUp') {
|
|
33
|
+
var _moveUpRef$current;
|
|
34
|
+
(_moveUpRef$current = moveUpRef.current) === null || _moveUpRef$current === void 0 ? void 0 : _moveUpRef$current.focus();
|
|
35
|
+
} else if (direction === 'moveDown') {
|
|
36
|
+
var _moveDownRef$current;
|
|
37
|
+
(_moveDownRef$current = moveDownRef.current) === null || _moveDownRef$current === void 0 ? void 0 : _moveDownRef$current.focus();
|
|
38
|
+
}
|
|
39
|
+
}, []);
|
|
26
40
|
return /*#__PURE__*/React.createElement(BlockMenuContext.Provider, {
|
|
27
41
|
value: {
|
|
28
|
-
onDropdownOpenChanged
|
|
42
|
+
onDropdownOpenChanged,
|
|
43
|
+
moveFocusTo,
|
|
44
|
+
moveDownRef,
|
|
45
|
+
moveUpRef
|
|
29
46
|
}
|
|
30
47
|
}, children);
|
|
31
48
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import { useIntl, injectIntl } from 'react-intl-next';
|
|
3
3
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
@@ -6,6 +6,7 @@ import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages'
|
|
|
6
6
|
import { DIRECTION } from '@atlaskit/editor-common/types';
|
|
7
7
|
import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
|
|
8
8
|
import ArrowDownIcon from '@atlaskit/icon/core/arrow-down';
|
|
9
|
+
import { useBlockMenu } from './block-menu-provider';
|
|
9
10
|
import { BLOCK_MENU_ITEM_NAME } from './consts';
|
|
10
11
|
const MoveDownDropdownItemContent = ({
|
|
11
12
|
api
|
|
@@ -13,6 +14,10 @@ const MoveDownDropdownItemContent = ({
|
|
|
13
14
|
const {
|
|
14
15
|
formatMessage
|
|
15
16
|
} = useIntl();
|
|
17
|
+
const {
|
|
18
|
+
moveFocusTo,
|
|
19
|
+
moveDownRef
|
|
20
|
+
} = useBlockMenu();
|
|
16
21
|
const {
|
|
17
22
|
canMoveDown
|
|
18
23
|
} = useSharedPluginStateWithSelector(api, ['blockControls'], ({
|
|
@@ -23,11 +28,20 @@ const MoveDownDropdownItemContent = ({
|
|
|
23
28
|
canMoveDown: blockControlsState === null || blockControlsState === void 0 ? void 0 : (_blockControlsState$b = blockControlsState.blockMenuOptions) === null || _blockControlsState$b === void 0 ? void 0 : _blockControlsState$b.canMoveDown
|
|
24
29
|
};
|
|
25
30
|
});
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const moveDownElement = moveDownRef.current;
|
|
33
|
+
if (!moveDownElement) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!canMoveDown && moveDownElement === document.activeElement) {
|
|
37
|
+
moveFocusTo('moveUp');
|
|
38
|
+
}
|
|
39
|
+
}, [canMoveDown, moveFocusTo, moveDownRef]);
|
|
26
40
|
const handleClick = () => {
|
|
27
41
|
api === null || api === void 0 ? void 0 : api.core.actions.execute(({
|
|
28
42
|
tr
|
|
29
43
|
}) => {
|
|
30
|
-
var _api$analytics, _api$analytics$action, _api$blockControls, _api$blockControls$co
|
|
44
|
+
var _api$analytics, _api$analytics$action, _api$blockControls, _api$blockControls$co;
|
|
31
45
|
const payload = {
|
|
32
46
|
action: ACTION.CLICKED,
|
|
33
47
|
actionSubject: ACTION_SUBJECT.BLOCK_MENU_ITEM,
|
|
@@ -40,15 +54,11 @@ const MoveDownDropdownItemContent = ({
|
|
|
40
54
|
api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$co = _api$blockControls.commands) === null || _api$blockControls$co === void 0 ? void 0 : _api$blockControls$co.moveNodeWithBlockMenu(DIRECTION.DOWN)({
|
|
41
55
|
tr
|
|
42
56
|
});
|
|
43
|
-
api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.toggleBlockMenu({
|
|
44
|
-
closeMenu: true
|
|
45
|
-
})({
|
|
46
|
-
tr
|
|
47
|
-
});
|
|
48
57
|
return tr;
|
|
49
58
|
});
|
|
50
59
|
};
|
|
51
60
|
return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
|
|
61
|
+
triggerRef: moveDownRef,
|
|
52
62
|
onClick: handleClick,
|
|
53
63
|
elemBefore: /*#__PURE__*/React.createElement(ArrowDownIcon, {
|
|
54
64
|
label: ""
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import { useIntl, injectIntl } from 'react-intl-next';
|
|
3
3
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
@@ -6,6 +6,7 @@ import { blockMenuMessages as messages } from '@atlaskit/editor-common/messages'
|
|
|
6
6
|
import { DIRECTION } from '@atlaskit/editor-common/types';
|
|
7
7
|
import { ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
|
|
8
8
|
import ArrowUpIcon from '@atlaskit/icon/core/arrow-up';
|
|
9
|
+
import { useBlockMenu } from './block-menu-provider';
|
|
9
10
|
import { BLOCK_MENU_ITEM_NAME } from './consts';
|
|
10
11
|
const MoveUpDropdownItemContent = ({
|
|
11
12
|
api
|
|
@@ -13,6 +14,10 @@ const MoveUpDropdownItemContent = ({
|
|
|
13
14
|
const {
|
|
14
15
|
formatMessage
|
|
15
16
|
} = useIntl();
|
|
17
|
+
const {
|
|
18
|
+
moveFocusTo,
|
|
19
|
+
moveUpRef
|
|
20
|
+
} = useBlockMenu();
|
|
16
21
|
const {
|
|
17
22
|
canMoveUp
|
|
18
23
|
} = useSharedPluginStateWithSelector(api, ['blockControls'], ({
|
|
@@ -23,11 +28,20 @@ const MoveUpDropdownItemContent = ({
|
|
|
23
28
|
canMoveUp: blockControlsState === null || blockControlsState === void 0 ? void 0 : (_blockControlsState$b = blockControlsState.blockMenuOptions) === null || _blockControlsState$b === void 0 ? void 0 : _blockControlsState$b.canMoveUp
|
|
24
29
|
};
|
|
25
30
|
});
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const moveUpElement = moveUpRef.current;
|
|
33
|
+
if (!moveUpElement) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!canMoveUp && moveUpElement === document.activeElement) {
|
|
37
|
+
moveFocusTo('moveDown');
|
|
38
|
+
}
|
|
39
|
+
}, [canMoveUp, moveFocusTo, moveUpRef]);
|
|
26
40
|
const handleClick = () => {
|
|
27
41
|
api === null || api === void 0 ? void 0 : api.core.actions.execute(({
|
|
28
42
|
tr
|
|
29
43
|
}) => {
|
|
30
|
-
var _api$analytics, _api$analytics$action, _api$blockControls, _api$blockControls$co
|
|
44
|
+
var _api$analytics, _api$analytics$action, _api$blockControls, _api$blockControls$co;
|
|
31
45
|
const payload = {
|
|
32
46
|
action: ACTION.CLICKED,
|
|
33
47
|
actionSubject: ACTION_SUBJECT.BLOCK_MENU_ITEM,
|
|
@@ -40,15 +54,11 @@ const MoveUpDropdownItemContent = ({
|
|
|
40
54
|
api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$co = _api$blockControls.commands) === null || _api$blockControls$co === void 0 ? void 0 : _api$blockControls$co.moveNodeWithBlockMenu(DIRECTION.UP)({
|
|
41
55
|
tr
|
|
42
56
|
});
|
|
43
|
-
api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.toggleBlockMenu({
|
|
44
|
-
closeMenu: true
|
|
45
|
-
})({
|
|
46
|
-
tr
|
|
47
|
-
});
|
|
48
57
|
return tr;
|
|
49
58
|
});
|
|
50
59
|
};
|
|
51
60
|
return /*#__PURE__*/React.createElement(ToolbarDropdownItem, {
|
|
61
|
+
triggerRef: moveUpRef,
|
|
52
62
|
onClick: handleClick,
|
|
53
63
|
elemBefore: /*#__PURE__*/React.createElement(ArrowUpIcon, {
|
|
54
64
|
label: ""
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
3
|
+
import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
|
|
4
|
+
import { getSelectedNode } from '../editor-commands/transform-node-utils/utils';
|
|
5
|
+
import { getSortedSuggestedItems } from './utils/suggested-items-rank';
|
|
6
|
+
export const SuggestedItemsRenderer = /*#__PURE__*/React.memo(({
|
|
7
|
+
api
|
|
8
|
+
}) => {
|
|
9
|
+
var _api$blockMenu;
|
|
10
|
+
const {
|
|
11
|
+
preservedSelection
|
|
12
|
+
} = useSharedPluginStateWithSelector(api, ['blockControls'], states => {
|
|
13
|
+
var _states$blockControls;
|
|
14
|
+
return {
|
|
15
|
+
preservedSelection: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.preservedSelection
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
const blockMenuComponents = api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.getBlockMenuComponents();
|
|
19
|
+
const menuItemsMap = useMemo(() => {
|
|
20
|
+
if (!blockMenuComponents) {
|
|
21
|
+
return new Map();
|
|
22
|
+
}
|
|
23
|
+
return new Map(blockMenuComponents.filter(c => c.type === 'block-menu-item').map(item => [item.key, item]));
|
|
24
|
+
}, [blockMenuComponents]);
|
|
25
|
+
const suggestedItems = useMemo(() => {
|
|
26
|
+
if (!preservedSelection || menuItemsMap.size === 0) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const selectedNode = getSelectedNode(preservedSelection);
|
|
30
|
+
if (!selectedNode) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
const nodeTypeName = selectedNode.node.type.name;
|
|
34
|
+
const sortedKeys = getSortedSuggestedItems(nodeTypeName);
|
|
35
|
+
return sortedKeys.map(key => menuItemsMap.get(key)).filter(item => item !== undefined);
|
|
36
|
+
}, [menuItemsMap, preservedSelection]);
|
|
37
|
+
if (suggestedItems.length === 0) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
|
|
41
|
+
title: "Suggested"
|
|
42
|
+
}, suggestedItems.map(item => {
|
|
43
|
+
const ItemComponent = item.component;
|
|
44
|
+
return ItemComponent ? /*#__PURE__*/React.createElement(ItemComponent, {
|
|
45
|
+
key: item.key
|
|
46
|
+
}) : null;
|
|
47
|
+
}));
|
|
48
|
+
});
|
|
@@ -15,22 +15,6 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
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_H2_MENU_ITEM, TRANSFORM_HEADINGS_H3_MENU_ITEM, TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM } from '@atlaskit/editor-common/block-menu';
|
|
18
|
-
/**
|
|
19
|
-
* Node type keys that map to ProseMirror node types from the ADF schema.
|
|
20
|
-
* These values must match the NodeTypeName type.
|
|
21
|
-
*
|
|
22
|
-
* TypeScript will enforce that all values are valid NodeTypeName values.
|
|
23
|
-
* If a new node type is added, it must be added to NodeTypeName first.
|
|
24
|
-
*
|
|
25
|
-
* Reference: packages/editor/editor-plugin-block-menu/src/editor-commands/transform-node-utils/types.ts
|
|
26
|
-
*
|
|
27
|
-
* Note: 'heading' represents all heading levels (1-6) as a single node type.
|
|
28
|
-
* The specific level is determined by the node's `attrs.level` property at runtime.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* // Usage:
|
|
32
|
-
* const nodeType = BLOCK_MENU_NODE_TYPES.PARAGRAPH; // Type: "paragraph"
|
|
33
|
-
*/
|
|
34
18
|
export const BLOCK_MENU_NODE_TYPES = {
|
|
35
19
|
PARAGRAPH: 'paragraph',
|
|
36
20
|
EXPAND: 'expand',
|
|
@@ -50,170 +34,93 @@ export const BLOCK_MENU_NODE_TYPES = {
|
|
|
50
34
|
EMBED_CARD: 'embedCard',
|
|
51
35
|
TABLE: 'table'
|
|
52
36
|
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Type for node type values extracted from BLOCK_MENU_NODE_TYPES
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Type for the suggested items rank mapping
|
|
60
|
-
*/
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Mapping of source node types to suggested transformation menu items with their ranks.
|
|
64
|
-
* Lower rank number = higher priority in the suggested menu section.
|
|
65
|
-
*/
|
|
66
37
|
export const TRANSFORM_SUGGESTED_ITEMS_RANK = {
|
|
67
|
-
// Paragraph suggestions
|
|
68
38
|
[BLOCK_MENU_NODE_TYPES.PARAGRAPH]: {
|
|
69
39
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
70
|
-
// Turn into Panel
|
|
71
40
|
[TRANSFORM_HEADINGS_H2_MENU_ITEM.key]: 200,
|
|
72
|
-
|
|
73
|
-
[TRANSFORM_HEADINGS_H3_MENU_ITEM.key]: 300 // Turn into Heading 3
|
|
41
|
+
[TRANSFORM_HEADINGS_H3_MENU_ITEM.key]: 300
|
|
74
42
|
},
|
|
75
|
-
// Expand suggestions
|
|
76
43
|
[BLOCK_MENU_NODE_TYPES.EXPAND]: {
|
|
77
44
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
78
|
-
// Turn into Panel (wrap content)
|
|
79
45
|
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 200,
|
|
80
|
-
|
|
81
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300 // Turn into Paragraph
|
|
46
|
+
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300
|
|
82
47
|
},
|
|
83
|
-
// Quote block (blockquote) suggestions
|
|
84
48
|
[BLOCK_MENU_NODE_TYPES.BLOCKQUOTE]: {
|
|
85
49
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
86
|
-
// Turn into Panel
|
|
87
50
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200,
|
|
88
|
-
|
|
89
|
-
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 300 // Turn into Layout
|
|
51
|
+
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 300
|
|
90
52
|
},
|
|
91
|
-
// Layout suggestions
|
|
92
53
|
[BLOCK_MENU_NODE_TYPES.LAYOUT_SECTION]: {
|
|
93
54
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
94
|
-
// Wrap layout in panel
|
|
95
55
|
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 200,
|
|
96
|
-
|
|
97
|
-
[TRANSFORM_HEADINGS_H2_MENU_ITEM.key]: 300 // doesn't meet compatibility matrix, needs to be updated
|
|
56
|
+
[TRANSFORM_HEADINGS_H2_MENU_ITEM.key]: 300
|
|
98
57
|
},
|
|
99
|
-
// Panel suggestions
|
|
100
58
|
[BLOCK_MENU_NODE_TYPES.PANEL]: {
|
|
101
59
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 100,
|
|
102
|
-
// Turn into Paragraph
|
|
103
60
|
[TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key]: 200,
|
|
104
|
-
|
|
105
|
-
[TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key]: 300 // Turn into Code Block
|
|
61
|
+
[TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key]: 300
|
|
106
62
|
},
|
|
107
|
-
// Code block suggestions
|
|
108
63
|
[BLOCK_MENU_NODE_TYPES.CODE_BLOCK]: {
|
|
109
64
|
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 100,
|
|
110
|
-
// Turn into Expand
|
|
111
65
|
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 200,
|
|
112
|
-
|
|
113
|
-
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 300 // Turn into Panel
|
|
66
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 300
|
|
114
67
|
},
|
|
115
|
-
// Decision suggestions
|
|
116
68
|
[BLOCK_MENU_NODE_TYPES.DECISION]: {
|
|
117
69
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
118
|
-
// Wrap in Panel (Decision style)
|
|
119
70
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200,
|
|
120
|
-
|
|
121
|
-
[TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key]: 300 // Convert to Task List
|
|
71
|
+
[TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key]: 300
|
|
122
72
|
},
|
|
123
|
-
// Bulleted list suggestions
|
|
124
73
|
[BLOCK_MENU_NODE_TYPES.BULLET_LIST]: {
|
|
125
74
|
[TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key]: 100,
|
|
126
|
-
// Turn into Numbered list
|
|
127
75
|
[TRANSFORM_STRUCTURE_QUOTE_MENU_ITEM.key]: 200,
|
|
128
|
-
|
|
129
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300 // Turn into Paragraph
|
|
76
|
+
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300
|
|
130
77
|
},
|
|
131
|
-
// Numbered list (ordered list) suggestions
|
|
132
78
|
[BLOCK_MENU_NODE_TYPES.ORDERED_LIST]: {
|
|
133
79
|
[TRANSFORM_STRUCTURE_BULLETED_LIST_MENU_ITEM.key]: 100,
|
|
134
|
-
// Turn into Bulleted list
|
|
135
80
|
[TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key]: 200,
|
|
136
|
-
|
|
137
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300 // Turn into Paragraph
|
|
81
|
+
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300
|
|
138
82
|
},
|
|
139
|
-
// Heading suggestions
|
|
140
|
-
// Note: For headings, the specific heading level would need to be determined at runtime
|
|
141
|
-
// This provides a general mapping, but actual implementation should consider current heading level
|
|
142
83
|
[BLOCK_MENU_NODE_TYPES.HEADING]: {
|
|
143
84
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 100,
|
|
144
|
-
// Turn into Paragraph
|
|
145
85
|
[TRANSFORM_HEADINGS_H2_MENU_ITEM.key]: 200,
|
|
146
|
-
|
|
147
|
-
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 300 // Wrap in Panel
|
|
86
|
+
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 300
|
|
148
87
|
},
|
|
149
|
-
// Task list suggestions
|
|
150
88
|
[BLOCK_MENU_NODE_TYPES.TASK_LIST]: {
|
|
151
89
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 100,
|
|
152
|
-
// Turn into Paragraph
|
|
153
90
|
[TRANSFORM_STRUCTURE_NUMBERED_LIST_MENU_ITEM.key]: 200,
|
|
154
|
-
|
|
155
|
-
[TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key]: 300 // Turn into Code Block (for technical TODOs)
|
|
91
|
+
[TRANSFORM_STRUCTURE_CODE_BLOCK_MENU_ITEM.key]: 300
|
|
156
92
|
},
|
|
157
|
-
// Media (mediaSingle) suggestions
|
|
158
93
|
[BLOCK_MENU_NODE_TYPES.MEDIA_SINGLE]: {
|
|
159
94
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
160
|
-
// Wrap in Panel
|
|
161
95
|
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 200,
|
|
162
|
-
|
|
163
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300 // doesn't meet compatibility matrix, needs to be updated
|
|
96
|
+
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 300
|
|
164
97
|
},
|
|
165
|
-
// Extension (app/macro) suggestions
|
|
166
98
|
[BLOCK_MENU_NODE_TYPES.EXTENSION]: {
|
|
167
99
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
168
|
-
// Wrap in Panel
|
|
169
100
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200,
|
|
170
|
-
|
|
171
|
-
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 300 // Collapse in Expand
|
|
101
|
+
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 300
|
|
172
102
|
},
|
|
173
|
-
// Bodied Extension suggestions (same as Extension)
|
|
174
103
|
[BLOCK_MENU_NODE_TYPES.BODIED_EXTENSION]: {
|
|
175
104
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
176
|
-
// Wrap in Panel
|
|
177
105
|
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200,
|
|
178
|
-
|
|
179
|
-
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 300 // Collapse in Expand
|
|
106
|
+
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 300
|
|
180
107
|
},
|
|
181
|
-
// Smart link Card suggestions
|
|
182
108
|
[BLOCK_MENU_NODE_TYPES.BLOCK_CARD]: {
|
|
183
|
-
// Note: Smart link card conversion would be rank 100 (demote to card)
|
|
184
109
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
185
|
-
|
|
186
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200 // doesn't meet compatibility matrix, needs to be updated
|
|
110
|
+
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200
|
|
187
111
|
},
|
|
188
|
-
// Smart link Embed suggestions
|
|
189
112
|
[BLOCK_MENU_NODE_TYPES.EMBED_CARD]: {
|
|
190
|
-
// Note: Smart link embed conversion would be rank 100 (promote to embed)
|
|
191
113
|
[TRANSFORM_STRUCTURE_PANEL_MENU_ITEM.key]: 100,
|
|
192
|
-
|
|
193
|
-
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200 // doesn't meet compatibility matrix, needs to be updated
|
|
114
|
+
[TRANSFORM_STRUCTURE_PARAGRAPH_MENU_ITEM.key]: 200
|
|
194
115
|
},
|
|
195
|
-
// Table suggestions
|
|
196
116
|
[BLOCK_MENU_NODE_TYPES.TABLE]: {
|
|
197
117
|
[TRANSFORM_STRUCTURE_EXPAND_MENU_ITEM.key]: 100,
|
|
198
|
-
|
|
199
|
-
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 200 // Turn into Layout
|
|
118
|
+
[TRANSFORM_STRUCTURE_LAYOUT_MENU_ITEM.key]: 200
|
|
200
119
|
}
|
|
201
120
|
};
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Get suggested menu items for a given node type
|
|
205
|
-
* @param nodeType - The source node type (e.g., 'paragraph', 'heading')
|
|
206
|
-
* @returns Object mapping menu item keys to their ranks, or undefined if no suggestions
|
|
207
|
-
*/
|
|
208
121
|
export const getSuggestedItemsForNodeType = nodeType => {
|
|
209
122
|
return TRANSFORM_SUGGESTED_ITEMS_RANK[nodeType];
|
|
210
123
|
};
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Get sorted suggested menu item keys for a given node type
|
|
214
|
-
* @param nodeType - The source node type
|
|
215
|
-
* @returns Array of menu item keys sorted by rank (highest priority first)
|
|
216
|
-
*/
|
|
217
124
|
export const getSortedSuggestedItems = nodeType => {
|
|
218
125
|
const suggestions = getSuggestedItemsForNodeType(nodeType);
|
|
219
126
|
if (!suggestions) {
|
|
@@ -8,6 +8,7 @@ import { unwrapExpandStep } from './unwrapExpandStep';
|
|
|
8
8
|
import { unwrapListStep } from './unwrapListStep';
|
|
9
9
|
import { unwrapStep } from './unwrapStep';
|
|
10
10
|
import { wrapIntoLayoutStep } from './wrapIntoLayoutStep';
|
|
11
|
+
import { wrapMixedContentStep } from './wrapMixedContentStep';
|
|
11
12
|
import { wrapStep } from './wrapStep';
|
|
12
13
|
|
|
13
14
|
// Exampled step for overrides:
|
|
@@ -57,15 +58,15 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
57
58
|
codeBlock: [unwrapStep, flattenStep, wrapStep]
|
|
58
59
|
},
|
|
59
60
|
expand: {
|
|
60
|
-
panel: [unwrapExpandStep,
|
|
61
|
-
blockquote: [unwrapExpandStep,
|
|
61
|
+
panel: [unwrapExpandStep, wrapMixedContentStep],
|
|
62
|
+
blockquote: [unwrapExpandStep, wrapMixedContentStep],
|
|
62
63
|
layoutSection: [unwrapExpandStep, wrapIntoLayoutStep],
|
|
63
64
|
paragraph: [unwrapExpandStep],
|
|
64
65
|
codeBlock: [unwrapExpandStep, flattenStep, wrapStep]
|
|
65
66
|
},
|
|
66
67
|
nestedExpand: {
|
|
67
|
-
panel: [unwrapExpandStep,
|
|
68
|
-
blockquote: [unwrapExpandStep,
|
|
68
|
+
panel: [unwrapExpandStep, wrapMixedContentStep],
|
|
69
|
+
blockquote: [unwrapExpandStep, wrapMixedContentStep],
|
|
69
70
|
paragraph: [unwrapExpandStep],
|
|
70
71
|
codeBlock: [unwrapExpandStep, flattenStep, wrapStep]
|
|
71
72
|
},
|