@atlaskit/editor-plugin-block-menu 3.2.1 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/editor-commands/transforms/container-transforms.js +15 -4
  3. package/dist/cjs/editor-commands/transforms/layout-transforms.js +7 -3
  4. package/dist/cjs/editor-commands/transforms/utils.js +20 -1
  5. package/dist/cjs/ui/block-menu-components.js +2 -12
  6. package/dist/cjs/ui/block-menu.js +6 -6
  7. package/dist/cjs/ui/format-menu-nested.js +28 -0
  8. package/dist/es2019/editor-commands/transforms/container-transforms.js +18 -5
  9. package/dist/es2019/editor-commands/transforms/layout-transforms.js +8 -4
  10. package/dist/es2019/editor-commands/transforms/utils.js +13 -0
  11. package/dist/es2019/ui/block-menu-components.js +3 -13
  12. package/dist/es2019/ui/block-menu.js +4 -4
  13. package/dist/es2019/ui/format-menu-nested.js +23 -0
  14. package/dist/esm/editor-commands/transforms/container-transforms.js +16 -5
  15. package/dist/esm/editor-commands/transforms/layout-transforms.js +8 -4
  16. package/dist/esm/editor-commands/transforms/utils.js +18 -0
  17. package/dist/esm/ui/block-menu-components.js +3 -13
  18. package/dist/esm/ui/block-menu.js +6 -6
  19. package/dist/esm/ui/format-menu-nested.js +21 -0
  20. package/dist/types/editor-commands/transforms/layout-transforms.d.ts +2 -2
  21. package/dist/types/editor-commands/transforms/utils.d.ts +2 -1
  22. package/dist/types/ui/block-menu-components.d.ts +1 -2
  23. package/dist/types/ui/format-menu-nested.d.ts +4 -0
  24. package/dist/types-ts4.5/editor-commands/transforms/layout-transforms.d.ts +2 -2
  25. package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +2 -1
  26. package/dist/types-ts4.5/ui/block-menu-components.d.ts +1 -2
  27. package/dist/types-ts4.5/ui/format-menu-nested.d.ts +4 -0
  28. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/editor-plugin-block-menu
2
2
 
3
+ ## 3.2.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`d5e5b25fe885a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d5e5b25fe885a) -
8
+ [ux] ED-29226 Open block menu when drag handle is focussed and space or enter key is pressed
9
+ - Updated dependencies
10
+
11
+ ## 3.2.2
12
+
13
+ ### Patch Changes
14
+
15
+ - [`0cde512c00691`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0cde512c00691) -
16
+ [ux] When resized node it transformed to another resized node, the width should be preserved.
17
+ - [`245e047a2f6e9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/245e047a2f6e9) -
18
+ [ux] Change `Format` option text to `Turn into` in block menu
19
+ - Updated dependencies
20
+
3
21
  ## 3.2.1
4
22
 
5
23
  ### Patch Changes
@@ -35,9 +35,11 @@ var transformToContainer = exports.transformToContainer = function transformToCo
35
35
  var schema = tr.doc.type.schema;
36
36
  var content = selection.content().content;
37
37
  var transformedContent = content;
38
+ var marks = [];
38
39
  if (sourceNode.type === schema.nodes.codeBlock) {
39
40
  var paragraphNodes = (0, _utils2.convertCodeBlockContentToParagraphs)(sourceNode, schema);
40
41
  transformedContent = _model.Fragment.fromArray(paragraphNodes);
42
+ marks = (0, _utils2.getMarksWithBreakout)(sourceNode, targetNodeType);
41
43
  }
42
44
  if (targetNodeType === schema.nodes.blockquote) {
43
45
  transformedContent = convertInvalidNodeToValidNodeType(transformedContent, schema.nodes.heading, schema.nodes.paragraph, true);
@@ -49,7 +51,7 @@ var transformToContainer = exports.transformToContainer = function transformToCo
49
51
  if (sourceNode.type === schema.nodes.paragraph || sourceNode.type === schema.nodes.heading) {
50
52
  transformedContent = (0, _utils2.filterMarksForTargetNodeType)(transformedContent, targetNodeType);
51
53
  }
52
- var newNode = targetNodeType.createAndFill(targetAttrs, transformedContent);
54
+ var newNode = targetNodeType.createAndFill(targetAttrs, transformedContent, marks);
53
55
  if (!newNode) {
54
56
  return null;
55
57
  }
@@ -175,7 +177,8 @@ var unwrapAndConvertToBlockType = exports.unwrapAndConvertToBlockType = function
175
177
  var codeBlockContent = sourceChildren.map(function (node) {
176
178
  return node.content.textBetween(0, node.content.size, '\n');
177
179
  }).join('\n');
178
- transformedContent = [codeBlock.createChecked({}, schema.text(codeBlockContent))];
180
+ var marks = (0, _utils2.getMarksWithBreakout)(sourceNode, targetNodeType);
181
+ transformedContent = [codeBlock.createChecked({}, schema.text(codeBlockContent), marks)];
179
182
  }
180
183
  var slice = new _model.Slice(_model.Fragment.fromArray(transformedContent), 0, 0);
181
184
  tr.replaceRange(rangeStart, rangeStart + sourceNode.nodeSize, slice);
@@ -272,6 +275,12 @@ var transformBetweenContainerTypes = exports.transformBetweenContainerTypes = fu
272
275
  // Special handling for codeBlock target
273
276
  if (targetNodeType.name === 'codeBlock') {
274
277
  var _contentSplits = splitContentForCodeBlock(sourceNode, targetNodeType, targetAttrs, tr.doc.type.schema);
278
+ if (_contentSplits.length === 0) {
279
+ var schema = tr.doc.type.schema;
280
+ var marks = (0, _utils2.getMarksWithBreakout)(sourceNode, targetNodeType);
281
+ var codeBlock = schema.nodes.codeBlock.create(targetAttrs, null, marks);
282
+ return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, codeBlock);
283
+ }
275
284
  return applySplitsToTransaction(tr, sourcePos, sourceNode.nodeSize, _contentSplits);
276
285
  }
277
286
 
@@ -319,7 +328,8 @@ var splitContentForCodeBlock = function splitContentForCodeBlock(sourceNode, tar
319
328
  var flushCurrentCodeBlock = function flushCurrentCodeBlock() {
320
329
  if (currentTextContent.length > 0) {
321
330
  var codeText = currentTextContent.join('\n');
322
- var codeBlockNode = targetNodeType.create(targetAttrs, schema.text(codeText));
331
+ var marks = (0, _utils2.getMarksWithBreakout)(sourceNode, targetNodeType);
332
+ var codeBlockNode = targetNodeType.create(targetAttrs, schema.text(codeText), marks);
323
333
  splits.push(codeBlockNode);
324
334
  currentTextContent = [];
325
335
  }
@@ -390,7 +400,8 @@ var splitContentAroundUnsupportedBlocks = function splitContentAroundUnsupported
390
400
  }
391
401
  var flushCurrentContainer = function flushCurrentContainer() {
392
402
  if (currentContainerContent.length > 0) {
393
- var containerNode = targetNodeType.create(targetAttrs, _model.Fragment.fromArray(currentContainerContent));
403
+ var marks = (0, _utils2.getMarksWithBreakout)(sourceNode, targetNodeType);
404
+ var containerNode = targetNodeType.create(targetAttrs, _model.Fragment.fromArray(currentContainerContent), marks);
394
405
  splits.push(containerNode);
395
406
  currentContainerContent = [];
396
407
  }
@@ -10,7 +10,7 @@ var _styles = require("@atlaskit/editor-common/styles");
10
10
  var _model = require("@atlaskit/editor-prosemirror/model");
11
11
  var _utils = require("./layout/utils");
12
12
  var _utils2 = require("./utils");
13
- var createDefaultLayoutSection = exports.createDefaultLayoutSection = function createDefaultLayoutSection(schema, content) {
13
+ var createDefaultLayoutSection = exports.createDefaultLayoutSection = function createDefaultLayoutSection(schema, content, marks) {
14
14
  var _schema$nodes = schema.nodes,
15
15
  layoutSection = _schema$nodes.layoutSection,
16
16
  layoutColumn = _schema$nodes.layoutColumn,
@@ -20,7 +20,7 @@ var createDefaultLayoutSection = exports.createDefaultLayoutSection = function c
20
20
  }, content), layoutColumn.create({
21
21
  width: _styles.DEFAULT_TWO_COLUMN_LAYOUT_COLUMN_WIDTH
22
22
  }, paragraph.createAndFill())]);
23
- return layoutSection.createChecked(undefined, layoutContent);
23
+ return layoutSection.createChecked(undefined, layoutContent, marks);
24
24
  };
25
25
  var convertToLayout = exports.convertToLayout = function convertToLayout(context) {
26
26
  var tr = context.tr,
@@ -29,7 +29,11 @@ var convertToLayout = exports.convertToLayout = function convertToLayout(context
29
29
  var content = sourceNode.mark(sourceNode.marks.filter(function (mark) {
30
30
  return mark.type.name !== 'breakout';
31
31
  }));
32
- var layoutSectionNode = createDefaultLayoutSection(tr.doc.type.schema, content);
32
+
33
+ // Layout supports breakout mark that can have width attribute
34
+ // When other nodes with breakout (codeBlock and expand) are converted to a layout, the layout should get width of original node
35
+ var marks = (0, _utils2.getMarksWithBreakout)(sourceNode, tr.doc.type.schema.nodes.layoutSection);
36
+ var layoutSectionNode = createDefaultLayoutSection(tr.doc.type.schema, content, marks);
33
37
  if ((0, _utils2.isHeadingOrParagraphNode)(sourceNode)) {
34
38
  // -1 to fix when sourceNode is the last node in the document, unable to convert to layout
35
39
  tr.replaceRangeWith(sourcePos > 0 ? sourcePos - 1 : sourcePos, sourcePos + sourceNode.nodeSize - 1, layoutSectionNode);
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
- exports.isListNodeType = exports.isListNode = exports.isLayoutNodeType = exports.isLayoutNode = exports.isHeadingOrParagraphNode = exports.isContainerNodeType = exports.isContainerNode = exports.isBlockNodeType = exports.isBlockNodeForExtraction = exports.isBlockNode = exports.getTargetNodeInfo = exports.getContentSupportChecker = exports.filterMarksForTargetNodeType = exports.convertNodeToInlineContent = exports.convertCodeBlockContentToParagraphs = void 0;
7
+ exports.isListNodeType = exports.isListNode = exports.isLayoutNodeType = exports.isLayoutNode = exports.isHeadingOrParagraphNode = exports.isContainerNodeType = exports.isContainerNode = exports.isBlockNodeType = exports.isBlockNodeForExtraction = exports.isBlockNode = exports.getTargetNodeInfo = exports.getMarksWithBreakout = exports.getContentSupportChecker = exports.filterMarksForTargetNodeType = exports.convertNodeToInlineContent = exports.convertCodeBlockContentToParagraphs = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
7
9
  var _model = require("@atlaskit/editor-prosemirror/model");
8
10
  var getTargetNodeInfo = exports.getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
9
11
  switch (targetType) {
@@ -202,4 +204,21 @@ var convertCodeBlockContentToParagraphs = exports.convertCodeBlockContentToParag
202
204
  paragraphNodes.push(paragraphNode);
203
205
  });
204
206
  return paragraphNodes;
207
+ };
208
+ var isBreakoutMarkSupported = function isBreakoutMarkSupported(nodeType) {
209
+ return ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
210
+ };
211
+ var getMarksWithBreakout = exports.getMarksWithBreakout = function getMarksWithBreakout(sourceNode, targetNodeType) {
212
+ var allowedMarks = targetNodeType.allowedMarks(sourceNode.marks);
213
+ var sourceBreakoutMark = sourceNode.marks.find(function (mark) {
214
+ return mark.type.name === 'breakout';
215
+ });
216
+ if (sourceBreakoutMark && isBreakoutMarkSupported(targetNodeType)) {
217
+ // Check if breakout mark is already in allowedMarks to avoid duplicates
218
+ var hasBreakoutMark = allowedMarks.some(function (mark) {
219
+ return mark.type.name === 'breakout';
220
+ });
221
+ return hasBreakoutMark ? allowedMarks : [].concat((0, _toConsumableArray2.default)(allowedMarks), [sourceBreakoutMark]);
222
+ }
223
+ return allowedMarks;
205
224
  };
@@ -9,13 +9,12 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
9
9
  var _react = _interopRequireDefault(require("react"));
10
10
  var _blockMenu = require("@atlaskit/editor-common/block-menu");
11
11
  var _editorToolbar = require("@atlaskit/editor-toolbar");
12
- var _changes = _interopRequireDefault(require("@atlaskit/icon/core/changes"));
13
- var _chevronRight = _interopRequireDefault(require("@atlaskit/icon/core/chevron-right"));
14
12
  var _copyBlock = _interopRequireDefault(require("./copy-block"));
15
13
  var _copyLink = require("./copy-link");
16
14
  var _copySection = require("./copy-section");
17
15
  var _deleteButton = require("./delete-button");
18
16
  var _deleteSection = require("./delete-section");
17
+ var _formatMenuNested = require("./format-menu-nested");
19
18
  var _formatMenuSection = require("./format-menu-section");
20
19
  var _moveDown = require("./move-down");
21
20
  var _moveUp = require("./move-up");
@@ -62,16 +61,7 @@ var getFormatMenuComponents = function getFormatMenuComponents(api) {
62
61
  children: null
63
62
  },
64
63
  children = _ref.children;
65
- return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarNestedDropdownMenu, {
66
- text: "Format",
67
- elemBefore: /*#__PURE__*/_react.default.createElement(_changes.default, {
68
- label: ""
69
- }),
70
- elemAfter: /*#__PURE__*/_react.default.createElement(_chevronRight.default, {
71
- label: 'example nested menu'
72
- }),
73
- enableMaxHeight: true
74
- }, children);
64
+ return /*#__PURE__*/_react.default.createElement(_formatMenuNested.FormatMenuComponent, null, children);
75
65
  }
76
66
  }, {
77
67
  type: 'block-menu-section',
@@ -1,4 +1,4 @@
1
- /* block-menu.tsx generated by @compiled/babel-plugin v0.36.1 */
1
+ /* block-menu.tsx generated by @compiled/babel-plugin v0.38.1 */
2
2
  "use strict";
3
3
 
4
4
  var _typeof = require("@babel/runtime/helpers/typeof");
@@ -56,7 +56,7 @@ var BlockMenuContent = function BlockMenuContent(_ref) {
56
56
  }));
57
57
  };
58
58
  var BlockMenu = function BlockMenu(_ref2) {
59
- var _editorView$hasFocus, _editorView$dom;
59
+ var _editorView$dom, _ref3, _editorView$hasFocus;
60
60
  var editorView = _ref2.editorView,
61
61
  api = _ref2.api,
62
62
  mountTo = _ref2.mountTo,
@@ -77,7 +77,8 @@ var BlockMenu = function BlockMenu(_ref2) {
77
77
  currentUserIntent = _useSharedPluginState.currentUserIntent;
78
78
  var _useBlockMenu = (0, _blockMenuProvider.useBlockMenu)(),
79
79
  onDropdownOpenChanged = _useBlockMenu.onDropdownOpenChanged;
80
- var hasFocus = (_editorView$hasFocus = editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) !== null && _editorView$hasFocus !== void 0 ? _editorView$hasFocus : false;
80
+ var targetHandleRef = editorView === null || editorView === void 0 || (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(_styles.DRAG_HANDLE_SELECTOR);
81
+ var hasFocus = (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu_keyboard_navigation', 'isEnabled', true) ? (_ref3 = (editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) || document.activeElement === targetHandleRef) !== null && _ref3 !== void 0 ? _ref3 : false : (_editorView$hasFocus = editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) !== null && _editorView$hasFocus !== void 0 ? _editorView$hasFocus : false;
81
82
  var hasSelection = !!editorView && !editorView.state.selection.empty;
82
83
  var emptyLineEnabled = (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu_empty_line', 'isEnabled', true);
83
84
 
@@ -95,9 +96,9 @@ var BlockMenu = function BlockMenu(_ref2) {
95
96
  return null;
96
97
  }
97
98
  var closeMenu = function closeMenu() {
98
- api === null || api === void 0 || api.core.actions.execute(function (_ref3) {
99
+ api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
99
100
  var _api$blockControls, _api$userIntent2;
100
- var tr = _ref3.tr;
101
+ var tr = _ref4.tr;
101
102
  api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || _api$blockControls.commands.toggleBlockMenu({
102
103
  closeMenu: true
103
104
  })({
@@ -114,7 +115,6 @@ var BlockMenu = function BlockMenu(_ref2) {
114
115
  closeMenu();
115
116
  return null;
116
117
  }
117
- var targetHandleRef = editorView === null || editorView === void 0 || (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(_styles.DRAG_HANDLE_SELECTOR);
118
118
  if (targetHandleRef instanceof HTMLElement) {
119
119
  return /*#__PURE__*/_react.default.createElement(PopupWithListeners, {
120
120
  alignX: 'right',
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.FormatMenuComponent = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _reactIntlNext = require("react-intl-next");
10
+ var _blockMenu = require("@atlaskit/editor-common/block-menu");
11
+ var _editorToolbar = require("@atlaskit/editor-toolbar");
12
+ var _changes = _interopRequireDefault(require("@atlaskit/icon/core/changes"));
13
+ var _chevronRight = _interopRequireDefault(require("@atlaskit/icon/core/chevron-right"));
14
+ var FormatMenuComponent = exports.FormatMenuComponent = function FormatMenuComponent(_ref) {
15
+ var children = _ref.children;
16
+ var _useIntl = (0, _reactIntlNext.useIntl)(),
17
+ formatMessage = _useIntl.formatMessage;
18
+ return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarNestedDropdownMenu, {
19
+ text: formatMessage(_blockMenu.messages.turnInto),
20
+ elemBefore: /*#__PURE__*/_react.default.createElement(_changes.default, {
21
+ label: ""
22
+ }),
23
+ elemAfter: /*#__PURE__*/_react.default.createElement(_chevronRight.default, {
24
+ label: ""
25
+ }),
26
+ enableMaxHeight: true
27
+ }, children);
28
+ };
@@ -1,7 +1,7 @@
1
1
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
2
2
  import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
3
3
  import { getInlineNodeTextContent } from './inline-node-transforms';
4
- import { isBlockNodeType, isListNodeType, isContainerNodeType, isBlockNodeForExtraction, convertNodeToInlineContent, getContentSupportChecker, convertCodeBlockContentToParagraphs, filterMarksForTargetNodeType } from './utils';
4
+ import { isBlockNodeType, isListNodeType, isContainerNodeType, isBlockNodeForExtraction, convertNodeToInlineContent, getContentSupportChecker, convertCodeBlockContentToParagraphs, filterMarksForTargetNodeType, getMarksWithBreakout } from './utils';
5
5
  const convertInvalidNodeToValidNodeType = (sourceContent, sourceNodeType, validNodeType, withMarks) => {
6
6
  const validTransformedContent = [];
7
7
  // Headings are not valid inside headings so convert heading nodes to paragraphs
@@ -28,9 +28,11 @@ export const transformToContainer = ({
28
28
  const schema = tr.doc.type.schema;
29
29
  const content = selection.content().content;
30
30
  let transformedContent = content;
31
+ let marks = [];
31
32
  if (sourceNode.type === schema.nodes.codeBlock) {
32
33
  const paragraphNodes = convertCodeBlockContentToParagraphs(sourceNode, schema);
33
34
  transformedContent = Fragment.fromArray(paragraphNodes);
35
+ marks = getMarksWithBreakout(sourceNode, targetNodeType);
34
36
  }
35
37
  if (targetNodeType === schema.nodes.blockquote) {
36
38
  transformedContent = convertInvalidNodeToValidNodeType(transformedContent, schema.nodes.heading, schema.nodes.paragraph, true);
@@ -42,7 +44,7 @@ export const transformToContainer = ({
42
44
  if (sourceNode.type === schema.nodes.paragraph || sourceNode.type === schema.nodes.heading) {
43
45
  transformedContent = filterMarksForTargetNodeType(transformedContent, targetNodeType);
44
46
  }
45
- const newNode = targetNodeType.createAndFill(targetAttrs, transformedContent);
47
+ const newNode = targetNodeType.createAndFill(targetAttrs, transformedContent, marks);
46
48
  if (!newNode) {
47
49
  return null;
48
50
  }
@@ -172,7 +174,8 @@ export const unwrapAndConvertToBlockType = context => {
172
174
  // if target node is code block, do unwrap and convert to code block
173
175
  if (targetNodeType === codeBlock) {
174
176
  const codeBlockContent = sourceChildren.map(node => node.content.textBetween(0, node.content.size, '\n')).join('\n');
175
- transformedContent = [codeBlock.createChecked({}, schema.text(codeBlockContent))];
177
+ const marks = getMarksWithBreakout(sourceNode, targetNodeType);
178
+ transformedContent = [codeBlock.createChecked({}, schema.text(codeBlockContent), marks)];
176
179
  }
177
180
  const slice = new Slice(Fragment.fromArray(transformedContent), 0, 0);
178
181
  tr.replaceRange(rangeStart, rangeStart + sourceNode.nodeSize, slice);
@@ -273,6 +276,14 @@ export const transformBetweenContainerTypes = context => {
273
276
  // Special handling for codeBlock target
274
277
  if (targetNodeType.name === 'codeBlock') {
275
278
  const contentSplits = splitContentForCodeBlock(sourceNode, targetNodeType, targetAttrs, tr.doc.type.schema);
279
+ if (contentSplits.length === 0) {
280
+ const {
281
+ schema
282
+ } = tr.doc.type;
283
+ const marks = getMarksWithBreakout(sourceNode, targetNodeType);
284
+ const codeBlock = schema.nodes.codeBlock.create(targetAttrs, null, marks);
285
+ return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, codeBlock);
286
+ }
276
287
  return applySplitsToTransaction(tr, sourcePos, sourceNode.nodeSize, contentSplits);
277
288
  }
278
289
 
@@ -320,7 +331,8 @@ const splitContentForCodeBlock = (sourceNode, targetNodeType, targetAttrs, schem
320
331
  const flushCurrentCodeBlock = () => {
321
332
  if (currentTextContent.length > 0) {
322
333
  const codeText = currentTextContent.join('\n');
323
- const codeBlockNode = targetNodeType.create(targetAttrs, schema.text(codeText));
334
+ const marks = getMarksWithBreakout(sourceNode, targetNodeType);
335
+ const codeBlockNode = targetNodeType.create(targetAttrs, schema.text(codeText), marks);
324
336
  splits.push(codeBlockNode);
325
337
  currentTextContent = [];
326
338
  }
@@ -391,7 +403,8 @@ const splitContentAroundUnsupportedBlocks = (sourceNode, isContentSupported, tar
391
403
  }
392
404
  const flushCurrentContainer = () => {
393
405
  if (currentContainerContent.length > 0) {
394
- const containerNode = targetNodeType.create(targetAttrs, Fragment.fromArray(currentContainerContent));
406
+ const marks = getMarksWithBreakout(sourceNode, targetNodeType);
407
+ const containerNode = targetNodeType.create(targetAttrs, Fragment.fromArray(currentContainerContent), marks);
395
408
  splits.push(containerNode);
396
409
  currentContainerContent = [];
397
410
  }
@@ -1,8 +1,8 @@
1
1
  import { DEFAULT_TWO_COLUMN_LAYOUT_COLUMN_WIDTH } from '@atlaskit/editor-common/styles';
2
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
3
3
  import { convertUnwrappedLayoutContent, unwrapLayoutNodesToTextNodes } from './layout/utils';
4
- import { isHeadingOrParagraphNode } from './utils';
5
- export const createDefaultLayoutSection = (schema, content) => {
4
+ import { getMarksWithBreakout, isHeadingOrParagraphNode } from './utils';
5
+ export const createDefaultLayoutSection = (schema, content, marks) => {
6
6
  const {
7
7
  layoutSection,
8
8
  layoutColumn,
@@ -13,7 +13,7 @@ export const createDefaultLayoutSection = (schema, content) => {
13
13
  }, content), layoutColumn.create({
14
14
  width: DEFAULT_TWO_COLUMN_LAYOUT_COLUMN_WIDTH
15
15
  }, paragraph.createAndFill())]);
16
- return layoutSection.createChecked(undefined, layoutContent);
16
+ return layoutSection.createChecked(undefined, layoutContent, marks);
17
17
  };
18
18
  export const convertToLayout = context => {
19
19
  const {
@@ -22,7 +22,11 @@ export const convertToLayout = context => {
22
22
  sourcePos
23
23
  } = context;
24
24
  const content = sourceNode.mark(sourceNode.marks.filter(mark => mark.type.name !== 'breakout'));
25
- const layoutSectionNode = createDefaultLayoutSection(tr.doc.type.schema, content);
25
+
26
+ // Layout supports breakout mark that can have width attribute
27
+ // When other nodes with breakout (codeBlock and expand) are converted to a layout, the layout should get width of original node
28
+ const marks = getMarksWithBreakout(sourceNode, tr.doc.type.schema.nodes.layoutSection);
29
+ const layoutSectionNode = createDefaultLayoutSection(tr.doc.type.schema, content, marks);
26
30
  if (isHeadingOrParagraphNode(sourceNode)) {
27
31
  // -1 to fix when sourceNode is the last node in the document, unable to convert to layout
28
32
  tr.replaceRangeWith(sourcePos > 0 ? sourcePos - 1 : sourcePos, sourcePos + sourceNode.nodeSize - 1, layoutSectionNode);
@@ -196,4 +196,17 @@ export const convertCodeBlockContentToParagraphs = (codeBlockNode, schema) => {
196
196
  paragraphNodes.push(paragraphNode);
197
197
  });
198
198
  return paragraphNodes;
199
+ };
200
+ const isBreakoutMarkSupported = nodeType => {
201
+ return ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
202
+ };
203
+ export const getMarksWithBreakout = (sourceNode, targetNodeType) => {
204
+ const allowedMarks = targetNodeType.allowedMarks(sourceNode.marks);
205
+ const sourceBreakoutMark = sourceNode.marks.find(mark => mark.type.name === 'breakout');
206
+ if (sourceBreakoutMark && isBreakoutMarkSupported(targetNodeType)) {
207
+ // Check if breakout mark is already in allowedMarks to avoid duplicates
208
+ const hasBreakoutMark = allowedMarks.some(mark => mark.type.name === 'breakout');
209
+ return hasBreakoutMark ? allowedMarks : [...allowedMarks, sourceBreakoutMark];
210
+ }
211
+ return allowedMarks;
199
212
  };
@@ -1,13 +1,12 @@
1
1
  import React from 'react';
2
2
  import { MOVE_UP_MENU_ITEM, MOVE_UP_DOWN_MENU_SECTION, MOVE_DOWN_MENU_ITEM, MOVE_BLOCK_SECTION_RANK, PRIMARY_MENU_SECTION, BLOCK_MENU_SECTION_RANK, COPY_MENU_SECTION, COPY_BLOCK_MENU_ITEM, COPY_MENU_SECTION_RANK, COPY_LINK_MENU_ITEM, DELETE_MENU_SECTION, DELETE_MENU_ITEM, DELETE_SECTION_RANK, NESTED_FORMAT_MENU_SECTION, NESTED_FORMAT_MENU } from '@atlaskit/editor-common/block-menu';
3
- import { ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
4
- import ChangesIcon from '@atlaskit/icon/core/changes';
5
- import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
3
+ import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
6
4
  import CopyBlockMenuItem from './copy-block';
7
5
  import { CopyLinkDropdownItem } from './copy-link';
8
6
  import { CopySection } from './copy-section';
9
7
  import { DeleteDropdownItem } from './delete-button';
10
8
  import { DeleteSection } from './delete-section';
9
+ import { FormatMenuComponent } from './format-menu-nested';
11
10
  import { FormatMenuSection } from './format-menu-section';
12
11
  import { MoveDownDropdownItem } from './move-down';
13
12
  import { MoveUpDropdownItem } from './move-up';
@@ -50,16 +49,7 @@ const getFormatMenuComponents = api => {
50
49
  } = {
51
50
  children: null
52
51
  }) => {
53
- return /*#__PURE__*/React.createElement(ToolbarNestedDropdownMenu, {
54
- text: "Format",
55
- elemBefore: /*#__PURE__*/React.createElement(ChangesIcon, {
56
- label: ""
57
- }),
58
- elemAfter: /*#__PURE__*/React.createElement(ChevronRightIcon, {
59
- label: 'example nested menu'
60
- }),
61
- enableMaxHeight: true
62
- }, children);
52
+ return /*#__PURE__*/React.createElement(FormatMenuComponent, null, children);
63
53
  }
64
54
  }, {
65
55
  type: 'block-menu-section',
@@ -1,4 +1,4 @@
1
- /* block-menu.tsx generated by @compiled/babel-plugin v0.36.1 */
1
+ /* block-menu.tsx generated by @compiled/babel-plugin v0.38.1 */
2
2
  import "./block-menu.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { useContext, useEffect } from 'react';
@@ -49,7 +49,7 @@ const BlockMenu = ({
49
49
  boundariesElement,
50
50
  scrollableElement
51
51
  }) => {
52
- var _editorView$hasFocus, _editorView$dom;
52
+ var _editorView$dom, _ref, _editorView$hasFocus;
53
53
  const {
54
54
  menuTriggerBy,
55
55
  isSelectedViaDragHandle,
@@ -67,7 +67,8 @@ const BlockMenu = ({
67
67
  const {
68
68
  onDropdownOpenChanged
69
69
  } = useBlockMenu();
70
- const hasFocus = (_editorView$hasFocus = editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) !== null && _editorView$hasFocus !== void 0 ? _editorView$hasFocus : false;
70
+ const targetHandleRef = editorView === null || editorView === void 0 ? void 0 : (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(DRAG_HANDLE_SELECTOR);
71
+ const hasFocus = expValEqualsNoExposure('platform_editor_block_menu_keyboard_navigation', 'isEnabled', true) ? (_ref = (editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) || document.activeElement === targetHandleRef) !== null && _ref !== void 0 ? _ref : false : (_editorView$hasFocus = editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) !== null && _editorView$hasFocus !== void 0 ? _editorView$hasFocus : false;
71
72
  const hasSelection = !!editorView && !editorView.state.selection.empty;
72
73
  const emptyLineEnabled = expValEqualsNoExposure('platform_editor_block_menu_empty_line', 'isEnabled', true);
73
74
 
@@ -105,7 +106,6 @@ const BlockMenu = ({
105
106
  closeMenu();
106
107
  return null;
107
108
  }
108
- const targetHandleRef = editorView === null || editorView === void 0 ? void 0 : (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(DRAG_HANDLE_SELECTOR);
109
109
  if (targetHandleRef instanceof HTMLElement) {
110
110
  return /*#__PURE__*/React.createElement(PopupWithListeners, {
111
111
  alignX: 'right',
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { messages } from '@atlaskit/editor-common/block-menu';
4
+ import { ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
5
+ import ChangesIcon from '@atlaskit/icon/core/changes';
6
+ import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
7
+ export const FormatMenuComponent = ({
8
+ children
9
+ }) => {
10
+ const {
11
+ formatMessage
12
+ } = useIntl();
13
+ return /*#__PURE__*/React.createElement(ToolbarNestedDropdownMenu, {
14
+ text: formatMessage(messages.turnInto),
15
+ elemBefore: /*#__PURE__*/React.createElement(ChangesIcon, {
16
+ label: ""
17
+ }),
18
+ elemAfter: /*#__PURE__*/React.createElement(ChevronRightIcon, {
19
+ label: ""
20
+ }),
21
+ enableMaxHeight: true
22
+ }, children);
23
+ };
@@ -2,7 +2,7 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
3
3
  import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
4
4
  import { getInlineNodeTextContent } from './inline-node-transforms';
5
- import { isBlockNodeType, isListNodeType, isContainerNodeType, isBlockNodeForExtraction, convertNodeToInlineContent, getContentSupportChecker, convertCodeBlockContentToParagraphs, filterMarksForTargetNodeType } from './utils';
5
+ import { isBlockNodeType, isListNodeType, isContainerNodeType, isBlockNodeForExtraction, convertNodeToInlineContent, getContentSupportChecker, convertCodeBlockContentToParagraphs, filterMarksForTargetNodeType, getMarksWithBreakout } from './utils';
6
6
  var convertInvalidNodeToValidNodeType = function convertInvalidNodeToValidNodeType(sourceContent, sourceNodeType, validNodeType, withMarks) {
7
7
  var validTransformedContent = [];
8
8
  // Headings are not valid inside headings so convert heading nodes to paragraphs
@@ -28,9 +28,11 @@ export var transformToContainer = function transformToContainer(_ref) {
28
28
  var schema = tr.doc.type.schema;
29
29
  var content = selection.content().content;
30
30
  var transformedContent = content;
31
+ var marks = [];
31
32
  if (sourceNode.type === schema.nodes.codeBlock) {
32
33
  var paragraphNodes = convertCodeBlockContentToParagraphs(sourceNode, schema);
33
34
  transformedContent = Fragment.fromArray(paragraphNodes);
35
+ marks = getMarksWithBreakout(sourceNode, targetNodeType);
34
36
  }
35
37
  if (targetNodeType === schema.nodes.blockquote) {
36
38
  transformedContent = convertInvalidNodeToValidNodeType(transformedContent, schema.nodes.heading, schema.nodes.paragraph, true);
@@ -42,7 +44,7 @@ export var transformToContainer = function transformToContainer(_ref) {
42
44
  if (sourceNode.type === schema.nodes.paragraph || sourceNode.type === schema.nodes.heading) {
43
45
  transformedContent = filterMarksForTargetNodeType(transformedContent, targetNodeType);
44
46
  }
45
- var newNode = targetNodeType.createAndFill(targetAttrs, transformedContent);
47
+ var newNode = targetNodeType.createAndFill(targetAttrs, transformedContent, marks);
46
48
  if (!newNode) {
47
49
  return null;
48
50
  }
@@ -168,7 +170,8 @@ export var unwrapAndConvertToBlockType = function unwrapAndConvertToBlockType(co
168
170
  var codeBlockContent = sourceChildren.map(function (node) {
169
171
  return node.content.textBetween(0, node.content.size, '\n');
170
172
  }).join('\n');
171
- transformedContent = [codeBlock.createChecked({}, schema.text(codeBlockContent))];
173
+ var marks = getMarksWithBreakout(sourceNode, targetNodeType);
174
+ transformedContent = [codeBlock.createChecked({}, schema.text(codeBlockContent), marks)];
172
175
  }
173
176
  var slice = new Slice(Fragment.fromArray(transformedContent), 0, 0);
174
177
  tr.replaceRange(rangeStart, rangeStart + sourceNode.nodeSize, slice);
@@ -265,6 +268,12 @@ export var transformBetweenContainerTypes = function transformBetweenContainerTy
265
268
  // Special handling for codeBlock target
266
269
  if (targetNodeType.name === 'codeBlock') {
267
270
  var _contentSplits = splitContentForCodeBlock(sourceNode, targetNodeType, targetAttrs, tr.doc.type.schema);
271
+ if (_contentSplits.length === 0) {
272
+ var schema = tr.doc.type.schema;
273
+ var marks = getMarksWithBreakout(sourceNode, targetNodeType);
274
+ var codeBlock = schema.nodes.codeBlock.create(targetAttrs, null, marks);
275
+ return tr.replaceWith(sourcePos, sourcePos + sourceNode.nodeSize, codeBlock);
276
+ }
268
277
  return applySplitsToTransaction(tr, sourcePos, sourceNode.nodeSize, _contentSplits);
269
278
  }
270
279
 
@@ -312,7 +321,8 @@ var splitContentForCodeBlock = function splitContentForCodeBlock(sourceNode, tar
312
321
  var flushCurrentCodeBlock = function flushCurrentCodeBlock() {
313
322
  if (currentTextContent.length > 0) {
314
323
  var codeText = currentTextContent.join('\n');
315
- var codeBlockNode = targetNodeType.create(targetAttrs, schema.text(codeText));
324
+ var marks = getMarksWithBreakout(sourceNode, targetNodeType);
325
+ var codeBlockNode = targetNodeType.create(targetAttrs, schema.text(codeText), marks);
316
326
  splits.push(codeBlockNode);
317
327
  currentTextContent = [];
318
328
  }
@@ -383,7 +393,8 @@ var splitContentAroundUnsupportedBlocks = function splitContentAroundUnsupported
383
393
  }
384
394
  var flushCurrentContainer = function flushCurrentContainer() {
385
395
  if (currentContainerContent.length > 0) {
386
- var containerNode = targetNodeType.create(targetAttrs, Fragment.fromArray(currentContainerContent));
396
+ var marks = getMarksWithBreakout(sourceNode, targetNodeType);
397
+ var containerNode = targetNodeType.create(targetAttrs, Fragment.fromArray(currentContainerContent), marks);
387
398
  splits.push(containerNode);
388
399
  currentContainerContent = [];
389
400
  }
@@ -2,8 +2,8 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import { DEFAULT_TWO_COLUMN_LAYOUT_COLUMN_WIDTH } from '@atlaskit/editor-common/styles';
3
3
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
4
4
  import { convertUnwrappedLayoutContent, unwrapLayoutNodesToTextNodes } from './layout/utils';
5
- import { isHeadingOrParagraphNode } from './utils';
6
- export var createDefaultLayoutSection = function createDefaultLayoutSection(schema, content) {
5
+ import { getMarksWithBreakout, isHeadingOrParagraphNode } from './utils';
6
+ export var createDefaultLayoutSection = function createDefaultLayoutSection(schema, content, marks) {
7
7
  var _schema$nodes = schema.nodes,
8
8
  layoutSection = _schema$nodes.layoutSection,
9
9
  layoutColumn = _schema$nodes.layoutColumn,
@@ -13,7 +13,7 @@ export var createDefaultLayoutSection = function createDefaultLayoutSection(sche
13
13
  }, content), layoutColumn.create({
14
14
  width: DEFAULT_TWO_COLUMN_LAYOUT_COLUMN_WIDTH
15
15
  }, paragraph.createAndFill())]);
16
- return layoutSection.createChecked(undefined, layoutContent);
16
+ return layoutSection.createChecked(undefined, layoutContent, marks);
17
17
  };
18
18
  export var convertToLayout = function convertToLayout(context) {
19
19
  var tr = context.tr,
@@ -22,7 +22,11 @@ export var convertToLayout = function convertToLayout(context) {
22
22
  var content = sourceNode.mark(sourceNode.marks.filter(function (mark) {
23
23
  return mark.type.name !== 'breakout';
24
24
  }));
25
- var layoutSectionNode = createDefaultLayoutSection(tr.doc.type.schema, content);
25
+
26
+ // Layout supports breakout mark that can have width attribute
27
+ // When other nodes with breakout (codeBlock and expand) are converted to a layout, the layout should get width of original node
28
+ var marks = getMarksWithBreakout(sourceNode, tr.doc.type.schema.nodes.layoutSection);
29
+ var layoutSectionNode = createDefaultLayoutSection(tr.doc.type.schema, content, marks);
26
30
  if (isHeadingOrParagraphNode(sourceNode)) {
27
31
  // -1 to fix when sourceNode is the last node in the document, unable to convert to layout
28
32
  tr.replaceRangeWith(sourcePos > 0 ? sourcePos - 1 : sourcePos, sourcePos + sourceNode.nodeSize - 1, layoutSectionNode);
@@ -1,3 +1,4 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
1
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
2
3
  export var getTargetNodeInfo = function getTargetNodeInfo(targetType, nodes) {
3
4
  switch (targetType) {
@@ -196,4 +197,21 @@ export var convertCodeBlockContentToParagraphs = function convertCodeBlockConten
196
197
  paragraphNodes.push(paragraphNode);
197
198
  });
198
199
  return paragraphNodes;
200
+ };
201
+ var isBreakoutMarkSupported = function isBreakoutMarkSupported(nodeType) {
202
+ return ['codeBlock', 'expand', 'layoutSection'].includes(nodeType.name);
203
+ };
204
+ export var getMarksWithBreakout = function getMarksWithBreakout(sourceNode, targetNodeType) {
205
+ var allowedMarks = targetNodeType.allowedMarks(sourceNode.marks);
206
+ var sourceBreakoutMark = sourceNode.marks.find(function (mark) {
207
+ return mark.type.name === 'breakout';
208
+ });
209
+ if (sourceBreakoutMark && isBreakoutMarkSupported(targetNodeType)) {
210
+ // Check if breakout mark is already in allowedMarks to avoid duplicates
211
+ var hasBreakoutMark = allowedMarks.some(function (mark) {
212
+ return mark.type.name === 'breakout';
213
+ });
214
+ return hasBreakoutMark ? allowedMarks : [].concat(_toConsumableArray(allowedMarks), [sourceBreakoutMark]);
215
+ }
216
+ return allowedMarks;
199
217
  };
@@ -1,14 +1,13 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  import React from 'react';
3
3
  import { MOVE_UP_MENU_ITEM, MOVE_UP_DOWN_MENU_SECTION, MOVE_DOWN_MENU_ITEM, MOVE_BLOCK_SECTION_RANK, PRIMARY_MENU_SECTION, BLOCK_MENU_SECTION_RANK, COPY_MENU_SECTION, COPY_BLOCK_MENU_ITEM, COPY_MENU_SECTION_RANK, COPY_LINK_MENU_ITEM, DELETE_MENU_SECTION, DELETE_MENU_ITEM, DELETE_SECTION_RANK, NESTED_FORMAT_MENU_SECTION, NESTED_FORMAT_MENU } from '@atlaskit/editor-common/block-menu';
4
- import { ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
5
- import ChangesIcon from '@atlaskit/icon/core/changes';
6
- import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
4
+ import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
7
5
  import CopyBlockMenuItem from './copy-block';
8
6
  import { CopyLinkDropdownItem } from './copy-link';
9
7
  import { CopySection } from './copy-section';
10
8
  import { DeleteDropdownItem } from './delete-button';
11
9
  import { DeleteSection } from './delete-section';
10
+ import { FormatMenuComponent } from './format-menu-nested';
12
11
  import { FormatMenuSection } from './format-menu-section';
13
12
  import { MoveDownDropdownItem } from './move-down';
14
13
  import { MoveUpDropdownItem } from './move-up';
@@ -55,16 +54,7 @@ var getFormatMenuComponents = function getFormatMenuComponents(api) {
55
54
  children: null
56
55
  },
57
56
  children = _ref.children;
58
- return /*#__PURE__*/React.createElement(ToolbarNestedDropdownMenu, {
59
- text: "Format",
60
- elemBefore: /*#__PURE__*/React.createElement(ChangesIcon, {
61
- label: ""
62
- }),
63
- elemAfter: /*#__PURE__*/React.createElement(ChevronRightIcon, {
64
- label: 'example nested menu'
65
- }),
66
- enableMaxHeight: true
67
- }, children);
57
+ return /*#__PURE__*/React.createElement(FormatMenuComponent, null, children);
68
58
  }
69
59
  }, {
70
60
  type: 'block-menu-section',
@@ -1,4 +1,4 @@
1
- /* block-menu.tsx generated by @compiled/babel-plugin v0.36.1 */
1
+ /* block-menu.tsx generated by @compiled/babel-plugin v0.38.1 */
2
2
  import "./block-menu.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { useContext, useEffect } from 'react';
@@ -48,7 +48,7 @@ var BlockMenuContent = function BlockMenuContent(_ref) {
48
48
  }));
49
49
  };
50
50
  var BlockMenu = function BlockMenu(_ref2) {
51
- var _editorView$hasFocus, _editorView$dom;
51
+ var _editorView$dom, _ref3, _editorView$hasFocus;
52
52
  var editorView = _ref2.editorView,
53
53
  api = _ref2.api,
54
54
  mountTo = _ref2.mountTo,
@@ -69,7 +69,8 @@ var BlockMenu = function BlockMenu(_ref2) {
69
69
  currentUserIntent = _useSharedPluginState.currentUserIntent;
70
70
  var _useBlockMenu = useBlockMenu(),
71
71
  onDropdownOpenChanged = _useBlockMenu.onDropdownOpenChanged;
72
- var hasFocus = (_editorView$hasFocus = editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) !== null && _editorView$hasFocus !== void 0 ? _editorView$hasFocus : false;
72
+ var targetHandleRef = editorView === null || editorView === void 0 || (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(DRAG_HANDLE_SELECTOR);
73
+ var hasFocus = expValEqualsNoExposure('platform_editor_block_menu_keyboard_navigation', 'isEnabled', true) ? (_ref3 = (editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) || document.activeElement === targetHandleRef) !== null && _ref3 !== void 0 ? _ref3 : false : (_editorView$hasFocus = editorView === null || editorView === void 0 ? void 0 : editorView.hasFocus()) !== null && _editorView$hasFocus !== void 0 ? _editorView$hasFocus : false;
73
74
  var hasSelection = !!editorView && !editorView.state.selection.empty;
74
75
  var emptyLineEnabled = expValEqualsNoExposure('platform_editor_block_menu_empty_line', 'isEnabled', true);
75
76
 
@@ -87,9 +88,9 @@ var BlockMenu = function BlockMenu(_ref2) {
87
88
  return null;
88
89
  }
89
90
  var closeMenu = function closeMenu() {
90
- api === null || api === void 0 || api.core.actions.execute(function (_ref3) {
91
+ api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
91
92
  var _api$blockControls, _api$userIntent2;
92
- var tr = _ref3.tr;
93
+ var tr = _ref4.tr;
93
94
  api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || _api$blockControls.commands.toggleBlockMenu({
94
95
  closeMenu: true
95
96
  })({
@@ -106,7 +107,6 @@ var BlockMenu = function BlockMenu(_ref2) {
106
107
  closeMenu();
107
108
  return null;
108
109
  }
109
- var targetHandleRef = editorView === null || editorView === void 0 || (_editorView$dom = editorView.dom) === null || _editorView$dom === void 0 ? void 0 : _editorView$dom.querySelector(DRAG_HANDLE_SELECTOR);
110
110
  if (targetHandleRef instanceof HTMLElement) {
111
111
  return /*#__PURE__*/React.createElement(PopupWithListeners, {
112
112
  alignX: 'right',
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl-next';
3
+ import { messages } from '@atlaskit/editor-common/block-menu';
4
+ import { ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
5
+ import ChangesIcon from '@atlaskit/icon/core/changes';
6
+ import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
7
+ export var FormatMenuComponent = function FormatMenuComponent(_ref) {
8
+ var children = _ref.children;
9
+ var _useIntl = useIntl(),
10
+ formatMessage = _useIntl.formatMessage;
11
+ return /*#__PURE__*/React.createElement(ToolbarNestedDropdownMenu, {
12
+ text: formatMessage(messages.turnInto),
13
+ elemBefore: /*#__PURE__*/React.createElement(ChangesIcon, {
14
+ label: ""
15
+ }),
16
+ elemAfter: /*#__PURE__*/React.createElement(ChevronRightIcon, {
17
+ label: ""
18
+ }),
19
+ enableMaxHeight: true
20
+ }, children);
21
+ };
@@ -1,6 +1,6 @@
1
1
  import type { TransformContext } from '@atlaskit/editor-common/transforms';
2
- import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Mark, Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
3
  import { type Schema } from '@atlaskit/editor-prosemirror/model';
4
- export declare const createDefaultLayoutSection: (schema: Schema, content: PMNode) => PMNode;
4
+ export declare const createDefaultLayoutSection: (schema: Schema, content: PMNode, marks?: readonly Mark[]) => PMNode;
5
5
  export declare const convertToLayout: (context: TransformContext) => import("prosemirror-state").Transaction;
6
6
  export declare const transformLayoutNode: (context: TransformContext) => import("prosemirror-state").Transaction;
@@ -1,4 +1,4 @@
1
- import type { Node as PMNode, NodeType, Schema } from '@atlaskit/editor-prosemirror/model';
1
+ import type { Mark, Node as PMNode, NodeType, Schema } from '@atlaskit/editor-prosemirror/model';
2
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { FormatNodeTargetType } from './types';
4
4
  export declare const getTargetNodeInfo: (targetType: FormatNodeTargetType, nodes: Record<string, NodeType>) => {
@@ -37,3 +37,4 @@ export declare const filterMarksForTargetNodeType: (content: Fragment, targetNod
37
37
  /** * Convert content from a code block node into multiple paragraph nodes
38
38
  */
39
39
  export declare const convertCodeBlockContentToParagraphs: (codeBlockNode: PMNode, schema: Schema) => PMNode[];
40
+ export declare const getMarksWithBreakout: (sourceNode: PMNode, targetNodeType: NodeType) => readonly Mark[];
@@ -1,6 +1,5 @@
1
1
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
- import type { BlockMenuPlugin, BlockMenuPluginOptions } from '../blockMenuPluginType';
3
- import { type RegisterBlockMenuComponent } from '../blockMenuPluginType';
2
+ import type { BlockMenuPlugin, BlockMenuPluginOptions, RegisterBlockMenuComponent } from '../blockMenuPluginType';
4
3
  export declare const getBlockMenuComponents: ({ api, config, }: {
5
4
  api: ExtractInjectionAPI<BlockMenuPlugin> | undefined;
6
5
  config: BlockMenuPluginOptions | undefined;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const FormatMenuComponent: ({ children }: {
3
+ children: React.ReactNode;
4
+ }) => React.JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import type { TransformContext } from '@atlaskit/editor-common/transforms';
2
- import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Mark, Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
3
  import { type Schema } from '@atlaskit/editor-prosemirror/model';
4
- export declare const createDefaultLayoutSection: (schema: Schema, content: PMNode) => PMNode;
4
+ export declare const createDefaultLayoutSection: (schema: Schema, content: PMNode, marks?: readonly Mark[]) => PMNode;
5
5
  export declare const convertToLayout: (context: TransformContext) => import("prosemirror-state").Transaction;
6
6
  export declare const transformLayoutNode: (context: TransformContext) => import("prosemirror-state").Transaction;
@@ -1,4 +1,4 @@
1
- import type { Node as PMNode, NodeType, Schema } from '@atlaskit/editor-prosemirror/model';
1
+ import type { Mark, Node as PMNode, NodeType, Schema } from '@atlaskit/editor-prosemirror/model';
2
2
  import { Fragment } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { FormatNodeTargetType } from './types';
4
4
  export declare const getTargetNodeInfo: (targetType: FormatNodeTargetType, nodes: Record<string, NodeType>) => {
@@ -37,3 +37,4 @@ export declare const filterMarksForTargetNodeType: (content: Fragment, targetNod
37
37
  /** * Convert content from a code block node into multiple paragraph nodes
38
38
  */
39
39
  export declare const convertCodeBlockContentToParagraphs: (codeBlockNode: PMNode, schema: Schema) => PMNode[];
40
+ export declare const getMarksWithBreakout: (sourceNode: PMNode, targetNodeType: NodeType) => readonly Mark[];
@@ -1,6 +1,5 @@
1
1
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
- import type { BlockMenuPlugin, BlockMenuPluginOptions } from '../blockMenuPluginType';
3
- import { type RegisterBlockMenuComponent } from '../blockMenuPluginType';
2
+ import type { BlockMenuPlugin, BlockMenuPluginOptions, RegisterBlockMenuComponent } from '../blockMenuPluginType';
4
3
  export declare const getBlockMenuComponents: ({ api, config, }: {
5
4
  api: ExtractInjectionAPI<BlockMenuPlugin> | undefined;
6
5
  config: BlockMenuPluginOptions | undefined;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const FormatMenuComponent: ({ children }: {
3
+ children: React.ReactNode;
4
+ }) => React.JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "3.2.1",
3
+ "version": "3.2.3",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -42,7 +42,7 @@
42
42
  "@atlaskit/icon-lab": "^5.7.0",
43
43
  "@atlaskit/platform-feature-flags": "^1.1.0",
44
44
  "@atlaskit/primitives": "^14.15.0",
45
- "@atlaskit/tmp-editor-statsig": "^12.26.0",
45
+ "@atlaskit/tmp-editor-statsig": "^12.27.0",
46
46
  "@atlaskit/tokens": "^6.3.0",
47
47
  "@babel/runtime": "^7.0.0"
48
48
  },