@atlaskit/editor-plugin-block-controls 3.3.6 → 3.3.8

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 3.3.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [#124180](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/124180)
8
+ [`f3f332175bf17`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f3f332175bf17) -
9
+ add case for quick insert button to handle block nodes which are leaf nodes, and handle media
10
+ - Updated dependencies
11
+
12
+ ## 3.3.7
13
+
14
+ ### Patch Changes
15
+
16
+ - [#124718](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/124718)
17
+ [`d923941c82bb4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d923941c82bb4) -
18
+ Disable block menu in Editor controls
19
+
3
20
  ## 3.3.6
4
21
 
5
22
  ### Patch Changes
@@ -21,6 +21,7 @@ var _element = require("@atlaskit/pragmatic-drag-and-drop-auto-scroll/element");
21
21
  var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine");
22
22
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
23
23
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
24
+ var _consts = require("../ui/consts");
24
25
  var _decorationsAnchor = require("./decorations-anchor");
25
26
  var _decorationsDragHandle = require("./decorations-drag-handle");
26
27
  var _decorationsDropTarget = require("./decorations-drop-target");
@@ -363,7 +364,7 @@ var newApply = exports.newApply = function newApply(api, formatMessage, tr, curr
363
364
  }
364
365
  var newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && (0, _decorationsDragHandle.findHandleDec)(decorations, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos).length === 0 ? null : latestActiveNode;
365
366
  var isMenuOpenNew = isMenuOpen;
366
- if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
367
+ if (_consts.BLOCK_MENU_ENABLED && (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
367
368
  if (meta !== null && meta !== void 0 && meta.closeMenu) {
368
369
  isMenuOpenNew = false;
369
370
  } else if (meta !== null && meta !== void 0 && meta.toggleMenu) {
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.topPositionAdjustment = exports.spacingBetweenNodesForPreview = exports.spaceLookupMap = exports.rootElementGap = exports.nodeMargins = exports.getNestedNodeLeftPaddingMargin = exports.dropTargetMarginMap = exports.dragHandleGap = exports.QUICK_INSERT_WIDTH = exports.QUICK_INSERT_HEIGHT = exports.QUICK_INSERT_DIMENSIONS = exports.DRAG_HANDLE_ZINDEX = exports.DRAG_HANDLE_WIDTH = exports.DRAG_HANDLE_PARAGRAPH_TOP_ADJUSTMENT = exports.DRAG_HANDLE_NARROW_GAP = exports.DRAG_HANDLE_MAX_WIDTH_PLUS_GAP = exports.DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH = exports.DRAG_HANDLE_MAX_GAP = exports.DRAG_HANDLE_LAYOUT_SECTION_TOP_ADJUSTMENT = exports.DRAG_HANDLE_HEIGHT = exports.DRAG_HANDLE_H6_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H5_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H4_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H3_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H2_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H1_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DEFAULT_GAP = exports.DRAG_HANDLE_BORDER_RADIUS = exports.DEFAULT_COLUMN_DISTRIBUTIONS = exports.BLOCK_MENU_WIDTH = void 0;
7
+ exports.topPositionAdjustment = exports.spacingBetweenNodesForPreview = exports.spaceLookupMap = exports.rootElementGap = exports.nodeMargins = exports.getNestedNodeLeftPaddingMargin = exports.dropTargetMarginMap = exports.dragHandleGap = exports.QUICK_INSERT_WIDTH = exports.QUICK_INSERT_HEIGHT = exports.QUICK_INSERT_DIMENSIONS = exports.DRAG_HANDLE_ZINDEX = exports.DRAG_HANDLE_WIDTH = exports.DRAG_HANDLE_PARAGRAPH_TOP_ADJUSTMENT = exports.DRAG_HANDLE_NARROW_GAP = exports.DRAG_HANDLE_MAX_WIDTH_PLUS_GAP = exports.DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH = exports.DRAG_HANDLE_MAX_GAP = exports.DRAG_HANDLE_LAYOUT_SECTION_TOP_ADJUSTMENT = exports.DRAG_HANDLE_HEIGHT = exports.DRAG_HANDLE_H6_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H5_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H4_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H3_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H2_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H1_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DEFAULT_GAP = exports.DRAG_HANDLE_BORDER_RADIUS = exports.DEFAULT_COLUMN_DISTRIBUTIONS = exports.BLOCK_MENU_WIDTH = exports.BLOCK_MENU_ENABLED = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
10
10
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
@@ -344,4 +344,8 @@ var DEFAULT_COLUMN_DISTRIBUTIONS = exports.DEFAULT_COLUMN_DISTRIBUTIONS = {
344
344
  4: 25,
345
345
  5: 20
346
346
  };
347
- var BLOCK_MENU_WIDTH = exports.BLOCK_MENU_WIDTH = 220;
347
+ var BLOCK_MENU_WIDTH = exports.BLOCK_MENU_WIDTH = 220;
348
+
349
+ // Temporarily disable BLOCK MENU feature until Q4 FY25.
350
+ // For more details, refer to ticket ED-26972 https://product-fabric.atlassian.net/browse/ED-26972
351
+ var BLOCK_MENU_ENABLED = exports.BLOCK_MENU_ENABLED = false;
@@ -200,7 +200,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
200
200
  var $anchor = (mSelect === null || mSelect === void 0 ? void 0 : mSelect.anchor) !== undefined ? tr.doc.resolve(mSelect === null || mSelect === void 0 ? void 0 : mSelect.anchor) : tr.selection.$anchor;
201
201
  if (!isMultiSelect || tr.selection.empty || !e.shiftKey) {
202
202
  tr = (0, _getSelection.selectNode)(tr, startPos, nodeType);
203
- if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
203
+ if (_consts.BLOCK_MENU_ENABLED && (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
204
204
  var _api$blockControls;
205
205
  api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || _api$blockControls.commands.toggleBlockMenu({
206
206
  anchorName: anchorName
@@ -19,6 +19,8 @@ var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
19
19
  var _dragHandlePositions = require("../pm-plugins/utils/drag-handle-positions");
20
20
  var _widgetPositions = require("../pm-plugins/utils/widget-positions");
21
21
  var _consts = require("./consts");
22
+ var _documentChecks = require("./utils/document-checks");
23
+ var _editorCommands = require("./utils/editor-commands");
22
24
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
23
25
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
24
26
  var buttonStyles = (0, _primitives.xcss)({
@@ -52,18 +54,6 @@ var containerStaticStyles = (0, _primitives.xcss)({
52
54
 
53
55
  // TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
54
56
 
55
- var isSelectionInNode = function isSelectionInNode(start, view) {
56
- var node = view.state.doc.nodeAt(start);
57
- if (node === null) {
58
- return false;
59
- }
60
- var endPos = start + node.nodeSize;
61
- var startPos = start;
62
- var _view$state$selection = view.state.selection,
63
- $from = _view$state$selection.$from,
64
- $to = _view$state$selection.$to;
65
- return $from.pos >= startPos && endPos >= $to.pos;
66
- };
67
57
  var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref) {
68
58
  var view = _ref.view,
69
59
  api = _ref.api,
@@ -143,6 +133,38 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
143
133
  (_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 || _cleanUpTransitionLis();
144
134
  };
145
135
  }, [calculatePosition, view.dom, rootAnchorName, rootNodeType]);
136
+ var handleQuickInsert = (0, _react.useCallback)(function () {
137
+ var _api$quickInsert;
138
+ // if the selection is not within the node this decoration is rendered at
139
+ // then insert a newline and trigger quick insert
140
+ var start = getPos();
141
+ if (start !== undefined) {
142
+ // if the selection is not within the node this decoration is rendered at
143
+ // or the node is non-editable, then insert a newline and trigger quick insert
144
+ if (!(0, _documentChecks.isSelectionInNode)(start, view) || (0, _documentChecks.isNonEditableBlock)(start, view)) {
145
+ api.core.actions.execute((0, _editorCommands.createNewLine)(start));
146
+ }
147
+ if ((0, _documentChecks.isSelectionInNode)(start, view) && (0, _documentChecks.isNestedNodeSelected)(view)) {
148
+ // if the nested selected node is non-editable, then insert a newline below the selected node
149
+ if ((0, _documentChecks.isNonEditableBlock)(view.state.selection.from, view)) {
150
+ api.core.actions.execute((0, _editorCommands.createNewLine)(view.state.selection.from));
151
+ } else {
152
+ // otherwise need to force the selection to be at the start of the node, because
153
+ // prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
154
+ // consistent NodeSelection for root level nodes.
155
+ api.core.actions.execute(function (_ref2) {
156
+ var tr = _ref2.tr;
157
+ (0, _editorCommands.createNewLine)(view.state.selection.from)({
158
+ tr: tr
159
+ });
160
+ tr.setSelection(_state.TextSelection.create(tr.doc, view.state.selection.from));
161
+ return tr;
162
+ });
163
+ }
164
+ }
165
+ }
166
+ api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
167
+ }, [api, getPos, view]);
146
168
  return (
147
169
  /*#__PURE__*/
148
170
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
@@ -157,26 +179,7 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
157
179
  type: "button",
158
180
  "aria-label": formatMessage(_messages.blockControlsMessages.insert),
159
181
  xcss: [buttonStyles],
160
- onClick: function onClick() {
161
- var _api$quickInsert;
162
- // if the selection is not within the node this decoration is rendered at
163
- // then insert a newline and trigger quick insert
164
- var start = getPos();
165
- if (start !== undefined && !isSelectionInNode(start, view)) {
166
- api.core.actions.execute(function (_ref2) {
167
- var _tr$doc$nodeAt;
168
- var tr = _ref2.tr;
169
- var nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
170
- if (nodeSize === undefined) {
171
- return tr;
172
- }
173
- var position = start + nodeSize;
174
- tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
175
- return tr.setSelection(_state.TextSelection.create(tr.doc, position));
176
- });
177
- }
178
- api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
179
- }
182
+ onClick: handleQuickInsert
180
183
  }, /*#__PURE__*/_react.default.createElement(_add.default, {
181
184
  label: "add"
182
185
  }))))
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isSelectionInNode = exports.isNonEditableBlock = exports.isNestedNodeSelected = void 0;
7
+ var _state = require("@atlaskit/editor-prosemirror/state");
8
+ var isNestedNodeSelected = exports.isNestedNodeSelected = function isNestedNodeSelected(view) {
9
+ var selection = view.state.selection;
10
+ return selection instanceof _state.NodeSelection && selection.$from.depth > 1;
11
+ };
12
+ var isSelectionInNode = exports.isSelectionInNode = function isSelectionInNode(start, view) {
13
+ var node = view.state.doc.nodeAt(start);
14
+ if (node === null) {
15
+ return false;
16
+ }
17
+ var endPos = start + node.nodeSize;
18
+ var startPos = start;
19
+ var _view$state$selection = view.state.selection,
20
+ $from = _view$state$selection.$from,
21
+ $to = _view$state$selection.$to;
22
+ return $from.pos >= startPos && endPos >= $to.pos;
23
+ };
24
+ var isNonEditableBlock = exports.isNonEditableBlock = function isNonEditableBlock(start, view) {
25
+ var node = view.state.doc.nodeAt(start);
26
+ if (node === null) {
27
+ return false;
28
+ }
29
+
30
+ // We want to treat some elements as if they are non-editable blocks for
31
+ // the purposes of quick insert.
32
+ switch (node.type.name) {
33
+ // mediaSingle and mediaGroup always contain a media child node, which is
34
+ // both a block and an atom. mediaSingle can also have a caption child node
35
+ // which is an editable block.
36
+ case 'mediaGroup':
37
+ case 'mediaSingle':
38
+ return true;
39
+ }
40
+ return node.isBlock && (node.isAtom || node.isLeaf);
41
+ };
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createNewLine = void 0;
7
+ var _state = require("@atlaskit/editor-prosemirror/state");
8
+ var createNewLine = exports.createNewLine = function createNewLine(start) {
9
+ return function (_ref) {
10
+ var _tr$doc$nodeAt;
11
+ var tr = _ref.tr;
12
+ var nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
13
+ if (nodeSize === undefined) {
14
+ return tr;
15
+ }
16
+ var position = start + nodeSize;
17
+ tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
18
+ return tr.setSelection(_state.TextSelection.create(tr.doc, position));
19
+ };
20
+ };
@@ -12,6 +12,7 @@ import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-sc
12
12
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
13
13
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
14
14
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
15
+ import { BLOCK_MENU_ENABLED } from '../ui/consts';
15
16
  import { findNodeDecs, nodeDecorations } from './decorations-anchor';
16
17
  import { dragHandleDecoration, emptyParagraphNodeDecorations, findHandleDec } from './decorations-drag-handle';
17
18
  import { dropTargetDecorations, findDropTargetDecs } from './decorations-drop-target';
@@ -360,7 +361,7 @@ export const newApply = (api, formatMessage, tr, currentState, newState, flags,
360
361
  }
361
362
  const newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos).length === 0 ? null : latestActiveNode;
362
363
  let isMenuOpenNew = isMenuOpen;
363
- if (editorExperiment('platform_editor_controls', 'variant1')) {
364
+ if (BLOCK_MENU_ENABLED && editorExperiment('platform_editor_controls', 'variant1')) {
364
365
  if (meta !== null && meta !== void 0 && meta.closeMenu) {
365
366
  isMenuOpenNew = false;
366
367
  } else if (meta !== null && meta !== void 0 && meta.toggleMenu) {
@@ -353,4 +353,8 @@ export const DEFAULT_COLUMN_DISTRIBUTIONS = {
353
353
  4: 25,
354
354
  5: 20
355
355
  };
356
- export const BLOCK_MENU_WIDTH = 220;
356
+ export const BLOCK_MENU_WIDTH = 220;
357
+
358
+ // Temporarily disable BLOCK MENU feature until Q4 FY25.
359
+ // For more details, refer to ticket ED-26972 https://product-fabric.atlassian.net/browse/ED-26972
360
+ export const BLOCK_MENU_ENABLED = false;
@@ -2,7 +2,9 @@
2
2
  * @jsxRuntime classic
3
3
  * @jsx jsx
4
4
  */
5
+
5
6
  import { useCallback, useEffect, useRef, useState } from 'react';
7
+
6
8
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
7
9
  import { css, jsx } from '@emotion/react';
8
10
  import { bind } from 'bind-event-listener';
@@ -26,7 +28,7 @@ import { getMultiSelectAnalyticsAttributes } from '../pm-plugins/utils/analytics
26
28
  import { getLeftPosition, getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
27
29
  import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
28
30
  import { alignAnchorHeadInDirectionOfPos, expandSelectionHeadToNodeAtPos } from '../pm-plugins/utils/selection';
29
- import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_WIDTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, topPositionAdjustment } from './consts';
31
+ import { BLOCK_MENU_ENABLED, DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_WIDTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, topPositionAdjustment } from './consts';
30
32
  import { dragPreview } from './drag-preview';
31
33
  const iconWrapperStyles = xcss({
32
34
  display: 'flex',
@@ -181,7 +183,7 @@ export const DragHandle = ({
181
183
  const $anchor = (mSelect === null || mSelect === void 0 ? void 0 : mSelect.anchor) !== undefined ? tr.doc.resolve(mSelect === null || mSelect === void 0 ? void 0 : mSelect.anchor) : tr.selection.$anchor;
182
184
  if (!isMultiSelect || tr.selection.empty || !e.shiftKey) {
183
185
  tr = selectNode(tr, startPos, nodeType);
184
- if (editorExperiment('platform_editor_controls', 'variant1')) {
186
+ if (BLOCK_MENU_ENABLED && editorExperiment('platform_editor_controls', 'variant1')) {
185
187
  var _api$blockControls;
186
188
  api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.commands.toggleBlockMenu({
187
189
  anchorName
@@ -10,6 +10,8 @@ import Tooltip from '@atlaskit/tooltip';
10
10
  import { getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
11
11
  import { getLeftPositionForRootElement } from '../pm-plugins/utils/widget-positions';
12
12
  import { QUICK_INSERT_DIMENSIONS, rootElementGap, topPositionAdjustment } from './consts';
13
+ import { isNestedNodeSelected, isNonEditableBlock, isSelectionInNode } from './utils/document-checks';
14
+ import { createNewLine } from './utils/editor-commands';
13
15
  const buttonStyles = xcss({
14
16
  boxSizing: 'border-box',
15
17
  display: 'flex',
@@ -41,19 +43,6 @@ const containerStaticStyles = xcss({
41
43
 
42
44
  // TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
43
45
 
44
- const isSelectionInNode = (start, view) => {
45
- const node = view.state.doc.nodeAt(start);
46
- if (node === null) {
47
- return false;
48
- }
49
- const endPos = start + node.nodeSize;
50
- const startPos = start;
51
- const {
52
- $from,
53
- $to
54
- } = view.state.selection;
55
- return $from.pos >= startPos && endPos >= $to.pos;
56
- };
57
46
  export const TypeAheadControl = ({
58
47
  view,
59
48
  api,
@@ -131,6 +120,39 @@ export const TypeAheadControl = ({
131
120
  (_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 ? void 0 : _cleanUpTransitionLis();
132
121
  };
133
122
  }, [calculatePosition, view.dom, rootAnchorName, rootNodeType]);
123
+ const handleQuickInsert = useCallback(() => {
124
+ var _api$quickInsert;
125
+ // if the selection is not within the node this decoration is rendered at
126
+ // then insert a newline and trigger quick insert
127
+ const start = getPos();
128
+ if (start !== undefined) {
129
+ // if the selection is not within the node this decoration is rendered at
130
+ // or the node is non-editable, then insert a newline and trigger quick insert
131
+ if (!isSelectionInNode(start, view) || isNonEditableBlock(start, view)) {
132
+ api.core.actions.execute(createNewLine(start));
133
+ }
134
+ if (isSelectionInNode(start, view) && isNestedNodeSelected(view)) {
135
+ // if the nested selected node is non-editable, then insert a newline below the selected node
136
+ if (isNonEditableBlock(view.state.selection.from, view)) {
137
+ api.core.actions.execute(createNewLine(view.state.selection.from));
138
+ } else {
139
+ // otherwise need to force the selection to be at the start of the node, because
140
+ // prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
141
+ // consistent NodeSelection for root level nodes.
142
+ api.core.actions.execute(({
143
+ tr
144
+ }) => {
145
+ createNewLine(view.state.selection.from)({
146
+ tr
147
+ });
148
+ tr.setSelection(TextSelection.create(tr.doc, view.state.selection.from));
149
+ return tr;
150
+ });
151
+ }
152
+ }
153
+ }
154
+ api === null || api === void 0 ? void 0 : (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.actions.openTypeAhead('blockControl');
155
+ }, [api, getPos, view]);
134
156
  return (
135
157
  /*#__PURE__*/
136
158
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
@@ -145,27 +167,7 @@ export const TypeAheadControl = ({
145
167
  type: "button",
146
168
  "aria-label": formatMessage(messages.insert),
147
169
  xcss: [buttonStyles],
148
- onClick: () => {
149
- var _api$quickInsert;
150
- // if the selection is not within the node this decoration is rendered at
151
- // then insert a newline and trigger quick insert
152
- const start = getPos();
153
- if (start !== undefined && !isSelectionInNode(start, view)) {
154
- api.core.actions.execute(({
155
- tr
156
- }) => {
157
- var _tr$doc$nodeAt;
158
- const nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
159
- if (nodeSize === undefined) {
160
- return tr;
161
- }
162
- const position = start + nodeSize;
163
- tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
164
- return tr.setSelection(TextSelection.create(tr.doc, position));
165
- });
166
- }
167
- api === null || api === void 0 ? void 0 : (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.actions.openTypeAhead('blockControl');
168
- }
170
+ onClick: handleQuickInsert
169
171
  }, /*#__PURE__*/React.createElement(AddIcon, {
170
172
  label: "add"
171
173
  }))))
@@ -0,0 +1,36 @@
1
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
2
+ export const isNestedNodeSelected = view => {
3
+ const selection = view.state.selection;
4
+ return selection instanceof NodeSelection && selection.$from.depth > 1;
5
+ };
6
+ export const isSelectionInNode = (start, view) => {
7
+ const node = view.state.doc.nodeAt(start);
8
+ if (node === null) {
9
+ return false;
10
+ }
11
+ const endPos = start + node.nodeSize;
12
+ const startPos = start;
13
+ const {
14
+ $from,
15
+ $to
16
+ } = view.state.selection;
17
+ return $from.pos >= startPos && endPos >= $to.pos;
18
+ };
19
+ export const isNonEditableBlock = (start, view) => {
20
+ const node = view.state.doc.nodeAt(start);
21
+ if (node === null) {
22
+ return false;
23
+ }
24
+
25
+ // We want to treat some elements as if they are non-editable blocks for
26
+ // the purposes of quick insert.
27
+ switch (node.type.name) {
28
+ // mediaSingle and mediaGroup always contain a media child node, which is
29
+ // both a block and an atom. mediaSingle can also have a caption child node
30
+ // which is an editable block.
31
+ case 'mediaGroup':
32
+ case 'mediaSingle':
33
+ return true;
34
+ }
35
+ return node.isBlock && (node.isAtom || node.isLeaf);
36
+ };
@@ -0,0 +1,13 @@
1
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
+ export const createNewLine = start => ({
3
+ tr
4
+ }) => {
5
+ var _tr$doc$nodeAt;
6
+ const nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
7
+ if (nodeSize === undefined) {
8
+ return tr;
9
+ }
10
+ const position = start + nodeSize;
11
+ tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
12
+ return tr.setSelection(TextSelection.create(tr.doc, position));
13
+ };
@@ -16,6 +16,7 @@ import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-sc
16
16
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
17
17
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
18
18
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
19
+ import { BLOCK_MENU_ENABLED } from '../ui/consts';
19
20
  import { findNodeDecs, nodeDecorations } from './decorations-anchor';
20
21
  import { dragHandleDecoration, emptyParagraphNodeDecorations, findHandleDec } from './decorations-drag-handle';
21
22
  import { dropTargetDecorations, findDropTargetDecs } from './decorations-drop-target';
@@ -356,7 +357,7 @@ export var newApply = function newApply(api, formatMessage, tr, currentState, ne
356
357
  }
357
358
  var newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos).length === 0 ? null : latestActiveNode;
358
359
  var isMenuOpenNew = isMenuOpen;
359
- if (editorExperiment('platform_editor_controls', 'variant1')) {
360
+ if (BLOCK_MENU_ENABLED && editorExperiment('platform_editor_controls', 'variant1')) {
360
361
  if (meta !== null && meta !== void 0 && meta.closeMenu) {
361
362
  isMenuOpenNew = false;
362
363
  } else if (meta !== null && meta !== void 0 && meta.toggleMenu) {
@@ -337,4 +337,8 @@ export var DEFAULT_COLUMN_DISTRIBUTIONS = {
337
337
  4: 25,
338
338
  5: 20
339
339
  };
340
- export var BLOCK_MENU_WIDTH = 220;
340
+ export var BLOCK_MENU_WIDTH = 220;
341
+
342
+ // Temporarily disable BLOCK MENU feature until Q4 FY25.
343
+ // For more details, refer to ticket ED-26972 https://product-fabric.atlassian.net/browse/ED-26972
344
+ export var BLOCK_MENU_ENABLED = false;
@@ -7,7 +7,9 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
7
7
  * @jsxRuntime classic
8
8
  * @jsx jsx
9
9
  */
10
+
10
11
  import { useCallback, useEffect, useRef, useState } from 'react';
12
+
11
13
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
12
14
  import { css, jsx } from '@emotion/react';
13
15
  import { bind } from 'bind-event-listener';
@@ -31,7 +33,7 @@ import { getMultiSelectAnalyticsAttributes } from '../pm-plugins/utils/analytics
31
33
  import { getLeftPosition, getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
32
34
  import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
33
35
  import { alignAnchorHeadInDirectionOfPos, expandSelectionHeadToNodeAtPos } from '../pm-plugins/utils/selection';
34
- import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_WIDTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, topPositionAdjustment } from './consts';
36
+ import { BLOCK_MENU_ENABLED, DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_WIDTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, topPositionAdjustment } from './consts';
35
37
  import { dragPreview } from './drag-preview';
36
38
  var iconWrapperStyles = xcss({
37
39
  display: 'flex',
@@ -195,7 +197,7 @@ export var DragHandle = function DragHandle(_ref) {
195
197
  var $anchor = (mSelect === null || mSelect === void 0 ? void 0 : mSelect.anchor) !== undefined ? tr.doc.resolve(mSelect === null || mSelect === void 0 ? void 0 : mSelect.anchor) : tr.selection.$anchor;
196
198
  if (!isMultiSelect || tr.selection.empty || !e.shiftKey) {
197
199
  tr = selectNode(tr, startPos, nodeType);
198
- if (editorExperiment('platform_editor_controls', 'variant1')) {
200
+ if (BLOCK_MENU_ENABLED && editorExperiment('platform_editor_controls', 'variant1')) {
199
201
  var _api$blockControls;
200
202
  api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || _api$blockControls.commands.toggleBlockMenu({
201
203
  anchorName: anchorName
@@ -11,6 +11,8 @@ import Tooltip from '@atlaskit/tooltip';
11
11
  import { getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
12
12
  import { getLeftPositionForRootElement } from '../pm-plugins/utils/widget-positions';
13
13
  import { QUICK_INSERT_DIMENSIONS, rootElementGap, topPositionAdjustment } from './consts';
14
+ import { isNestedNodeSelected, isNonEditableBlock, isSelectionInNode } from './utils/document-checks';
15
+ import { createNewLine } from './utils/editor-commands';
14
16
  var buttonStyles = xcss({
15
17
  boxSizing: 'border-box',
16
18
  display: 'flex',
@@ -42,18 +44,6 @@ var containerStaticStyles = xcss({
42
44
 
43
45
  // TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
44
46
 
45
- var isSelectionInNode = function isSelectionInNode(start, view) {
46
- var node = view.state.doc.nodeAt(start);
47
- if (node === null) {
48
- return false;
49
- }
50
- var endPos = start + node.nodeSize;
51
- var startPos = start;
52
- var _view$state$selection = view.state.selection,
53
- $from = _view$state$selection.$from,
54
- $to = _view$state$selection.$to;
55
- return $from.pos >= startPos && endPos >= $to.pos;
56
- };
57
47
  export var TypeAheadControl = function TypeAheadControl(_ref) {
58
48
  var view = _ref.view,
59
49
  api = _ref.api,
@@ -133,6 +123,38 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
133
123
  (_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 || _cleanUpTransitionLis();
134
124
  };
135
125
  }, [calculatePosition, view.dom, rootAnchorName, rootNodeType]);
126
+ var handleQuickInsert = useCallback(function () {
127
+ var _api$quickInsert;
128
+ // if the selection is not within the node this decoration is rendered at
129
+ // then insert a newline and trigger quick insert
130
+ var start = getPos();
131
+ if (start !== undefined) {
132
+ // if the selection is not within the node this decoration is rendered at
133
+ // or the node is non-editable, then insert a newline and trigger quick insert
134
+ if (!isSelectionInNode(start, view) || isNonEditableBlock(start, view)) {
135
+ api.core.actions.execute(createNewLine(start));
136
+ }
137
+ if (isSelectionInNode(start, view) && isNestedNodeSelected(view)) {
138
+ // if the nested selected node is non-editable, then insert a newline below the selected node
139
+ if (isNonEditableBlock(view.state.selection.from, view)) {
140
+ api.core.actions.execute(createNewLine(view.state.selection.from));
141
+ } else {
142
+ // otherwise need to force the selection to be at the start of the node, because
143
+ // prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
144
+ // consistent NodeSelection for root level nodes.
145
+ api.core.actions.execute(function (_ref2) {
146
+ var tr = _ref2.tr;
147
+ createNewLine(view.state.selection.from)({
148
+ tr: tr
149
+ });
150
+ tr.setSelection(TextSelection.create(tr.doc, view.state.selection.from));
151
+ return tr;
152
+ });
153
+ }
154
+ }
155
+ }
156
+ api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
157
+ }, [api, getPos, view]);
136
158
  return (
137
159
  /*#__PURE__*/
138
160
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
@@ -147,26 +169,7 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
147
169
  type: "button",
148
170
  "aria-label": formatMessage(messages.insert),
149
171
  xcss: [buttonStyles],
150
- onClick: function onClick() {
151
- var _api$quickInsert;
152
- // if the selection is not within the node this decoration is rendered at
153
- // then insert a newline and trigger quick insert
154
- var start = getPos();
155
- if (start !== undefined && !isSelectionInNode(start, view)) {
156
- api.core.actions.execute(function (_ref2) {
157
- var _tr$doc$nodeAt;
158
- var tr = _ref2.tr;
159
- var nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
160
- if (nodeSize === undefined) {
161
- return tr;
162
- }
163
- var position = start + nodeSize;
164
- tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
165
- return tr.setSelection(TextSelection.create(tr.doc, position));
166
- });
167
- }
168
- api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
169
- }
172
+ onClick: handleQuickInsert
170
173
  }, /*#__PURE__*/React.createElement(AddIcon, {
171
174
  label: "add"
172
175
  }))))
@@ -0,0 +1,35 @@
1
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
2
+ export var isNestedNodeSelected = function isNestedNodeSelected(view) {
3
+ var selection = view.state.selection;
4
+ return selection instanceof NodeSelection && selection.$from.depth > 1;
5
+ };
6
+ export var isSelectionInNode = function isSelectionInNode(start, view) {
7
+ var node = view.state.doc.nodeAt(start);
8
+ if (node === null) {
9
+ return false;
10
+ }
11
+ var endPos = start + node.nodeSize;
12
+ var startPos = start;
13
+ var _view$state$selection = view.state.selection,
14
+ $from = _view$state$selection.$from,
15
+ $to = _view$state$selection.$to;
16
+ return $from.pos >= startPos && endPos >= $to.pos;
17
+ };
18
+ export var isNonEditableBlock = function isNonEditableBlock(start, view) {
19
+ var node = view.state.doc.nodeAt(start);
20
+ if (node === null) {
21
+ return false;
22
+ }
23
+
24
+ // We want to treat some elements as if they are non-editable blocks for
25
+ // the purposes of quick insert.
26
+ switch (node.type.name) {
27
+ // mediaSingle and mediaGroup always contain a media child node, which is
28
+ // both a block and an atom. mediaSingle can also have a caption child node
29
+ // which is an editable block.
30
+ case 'mediaGroup':
31
+ case 'mediaSingle':
32
+ return true;
33
+ }
34
+ return node.isBlock && (node.isAtom || node.isLeaf);
35
+ };
@@ -0,0 +1,14 @@
1
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
+ export var createNewLine = function createNewLine(start) {
3
+ return function (_ref) {
4
+ var _tr$doc$nodeAt;
5
+ var tr = _ref.tr;
6
+ var nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize;
7
+ if (nodeSize === undefined) {
8
+ return tr;
9
+ }
10
+ var position = start + nodeSize;
11
+ tr.insert(position, tr.doc.type.schema.nodes.paragraph.create());
12
+ return tr.setSelection(TextSelection.create(tr.doc, position));
13
+ };
14
+ };
@@ -59,3 +59,4 @@ export declare const DEFAULT_COLUMN_DISTRIBUTIONS: {
59
59
  [key: number]: number;
60
60
  };
61
61
  export declare const BLOCK_MENU_WIDTH = 220;
62
+ export declare const BLOCK_MENU_ENABLED = false;
@@ -0,0 +1,4 @@
1
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ export declare const isNestedNodeSelected: (view: EditorView) => boolean;
3
+ export declare const isSelectionInNode: (start: number, view: EditorView) => boolean;
4
+ export declare const isNonEditableBlock: (start: number, view: EditorView) => boolean;
@@ -0,0 +1,2 @@
1
+ import type { EditorCommand } from '@atlaskit/editor-common/types';
2
+ export declare const createNewLine: (start: number) => EditorCommand;
@@ -59,3 +59,4 @@ export declare const DEFAULT_COLUMN_DISTRIBUTIONS: {
59
59
  [key: number]: number;
60
60
  };
61
61
  export declare const BLOCK_MENU_WIDTH = 220;
62
+ export declare const BLOCK_MENU_ENABLED = false;
@@ -0,0 +1,4 @@
1
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ export declare const isNestedNodeSelected: (view: EditorView) => boolean;
3
+ export declare const isSelectionInNode: (start: number, view: EditorView) => boolean;
4
+ export declare const isNonEditableBlock: (start: number, view: EditorView) => boolean;
@@ -0,0 +1,2 @@
1
+ import type { EditorCommand } from '@atlaskit/editor-common/types';
2
+ export declare const createNewLine: (start: number) => EditorCommand;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "3.3.6",
3
+ "version": "3.3.8",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -53,7 +53,7 @@
53
53
  "@atlaskit/primitives": "^14.1.0",
54
54
  "@atlaskit/theme": "^18.0.0",
55
55
  "@atlaskit/tmp-editor-statsig": "^3.5.0",
56
- "@atlaskit/tokens": "^4.3.0",
56
+ "@atlaskit/tokens": "^4.4.0",
57
57
  "@atlaskit/tooltip": "^20.0.0",
58
58
  "@babel/runtime": "^7.0.0",
59
59
  "@emotion/react": "^11.7.1",