@atlaskit/editor-plugin-block-controls 8.0.15 → 8.1.1

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,25 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 8.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`5acb6a79c09f2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5acb6a79c09f2) -
8
+ Pause the EOU active session counter when block menu is opened
9
+
10
+ ## 8.1.0
11
+
12
+ ### Minor Changes
13
+
14
+ - [`1d31a4729ab09`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1d31a4729ab09) -
15
+ [ux] Implement nested block menu icon (flagged)
16
+
17
+ ### Patch Changes
18
+
19
+ - [`e00b363b9fa30`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e00b363b9fa30) -
20
+ [ux] EDITOR-4481 Clean up platform_editor_toolbar_aifc_user_intent_fix
21
+ - Updated dependencies
22
+
3
23
  ## 8.0.15
4
24
 
5
25
  ### Patch Changes
@@ -87,13 +87,14 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
87
87
  },
88
88
  toggleBlockMenu: function toggleBlockMenu(options) {
89
89
  return function (_ref4) {
90
- var _api$userIntent, _options$anchorName, _api$blockControls;
90
+ var _api$userIntent, _api$blockControls, _options$anchorName, _api$blockControls2;
91
91
  var tr = _ref4.tr;
92
92
  if (!(0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true)) {
93
93
  return tr;
94
94
  }
95
95
  var currMeta = tr.getMeta(_main.key);
96
96
  var currentUserIntent = api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || (_api$userIntent = _api$userIntent.sharedState.currentState()) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.currentUserIntent;
97
+ var isMenuCurrentlyOpen = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.isMenuOpen;
97
98
  if (options !== null && options !== void 0 && options.closeMenu) {
98
99
  tr.setMeta(_main.key, _objectSpread(_objectSpread({}, currMeta), {}, {
99
100
  closeMenu: true
@@ -104,6 +105,14 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
104
105
  tr: tr
105
106
  });
106
107
  }
108
+
109
+ // When closing the menu, restart the active session timer
110
+ if (isMenuCurrentlyOpen && (0, _platformFeatureFlags.fg)('platform_editor_ease_of_use_metrics')) {
111
+ var _api$metrics;
112
+ api === null || api === void 0 || (_api$metrics = api.metrics) === null || _api$metrics === void 0 || _api$metrics.commands.startActiveSessionTimer()({
113
+ tr: tr
114
+ });
115
+ }
107
116
  return tr;
108
117
  }
109
118
 
@@ -118,13 +127,21 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
118
127
  tr.setMeta(_main.key, _objectSpread(_objectSpread({}, currMeta), {}, {
119
128
  closeMenu: true
120
129
  }));
130
+
131
+ // When closing the menu, restart the active session timer
132
+ if (isMenuCurrentlyOpen && (0, _platformFeatureFlags.fg)('platform_editor_ease_of_use_metrics')) {
133
+ var _api$metrics2;
134
+ api === null || api === void 0 || (_api$metrics2 = api.metrics) === null || _api$metrics2 === void 0 || _api$metrics2.commands.startActiveSessionTimer()({
135
+ tr: tr
136
+ });
137
+ }
121
138
  return tr;
122
139
  }
123
140
  var toggleMenuMeta = {
124
141
  anchorName: options === null || options === void 0 ? void 0 : options.anchorName,
125
142
  triggerByNode: options === null || options === void 0 ? void 0 : options.triggerByNode
126
143
  };
127
- var menuTriggerBy = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.menuTriggerBy;
144
+ var menuTriggerBy = api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.sharedState.currentState()) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.menuTriggerBy;
128
145
  if (options !== null && options !== void 0 && options.anchorName) {
129
146
  var _canMoveNodeUpOrDown = (0, _moveNodeUtils.canMoveNodeUpOrDown)(tr),
130
147
  moveUp = _canMoveNodeUpOrDown.moveUp,
@@ -140,7 +157,7 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
140
157
  }));
141
158
  if ((menuTriggerBy === undefined || !!menuTriggerBy && menuTriggerBy === (options === null || options === void 0 ? void 0 : options.anchorName)) && currentUserIntent === 'blockMenuOpen') {
142
159
  var state = api === null || api === void 0 ? void 0 : api.blockControls.sharedState.currentState();
143
- if (state !== null && state !== void 0 && state.isSelectedViaDragHandle && (0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_user_intent_fix')) {
160
+ if (state !== null && state !== void 0 && state.isSelectedViaDragHandle) {
144
161
  var _api$userIntent4;
145
162
  api === null || api === void 0 || (_api$userIntent4 = api.userIntent) === null || _api$userIntent4 === void 0 || _api$userIntent4.commands.setCurrentUserIntent('dragHandleSelected')({
146
163
  tr: tr
@@ -152,6 +169,25 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
152
169
  tr: tr
153
170
  });
154
171
  }
172
+
173
+ // When closing the menu, restart the active session timer
174
+ if ((0, _platformFeatureFlags.fg)('platform_editor_ease_of_use_metrics')) {
175
+ var _api$metrics3;
176
+ api === null || api === void 0 || (_api$metrics3 = api.metrics) === null || _api$metrics3 === void 0 || _api$metrics3.commands.startActiveSessionTimer()({
177
+ tr: tr
178
+ });
179
+ }
180
+ } else if (!isMenuCurrentlyOpen) {
181
+ // When opening the menu, pause the active session timer
182
+ if ((0, _platformFeatureFlags.fg)('platform_editor_ease_of_use_metrics')) {
183
+ var _api$metrics4;
184
+ api === null || api === void 0 || (_api$metrics4 = api.metrics) === null || _api$metrics4 === void 0 || _api$metrics4.commands.handleIntentToStartEdit({
185
+ shouldStartTimer: false,
186
+ shouldPersistActiveSession: true
187
+ })({
188
+ tr: tr
189
+ });
190
+ }
155
191
  }
156
192
  return tr;
157
193
  };
@@ -174,8 +210,8 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
174
210
  }
175
211
  }));
176
212
  if ((0, _platformFeatureFlags.fg)('platform_editor_ease_of_use_metrics')) {
177
- var _api$metrics;
178
- api === null || api === void 0 || (_api$metrics = api.metrics) === null || _api$metrics === void 0 || _api$metrics.commands.handleIntentToStartEdit({
213
+ var _api$metrics5;
214
+ api === null || api === void 0 || (_api$metrics5 = api.metrics) === null || _api$metrics5 === void 0 || _api$metrics5.commands.handleIntentToStartEdit({
179
215
  shouldStartTimer: false,
180
216
  shouldPersistActiveSession: true
181
217
  })({
@@ -92,7 +92,7 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
92
92
  var getPos = function getPos() {
93
93
  try {
94
94
  return getPosUnsafe();
95
- } catch (e) {
95
+ } catch (_unused) {
96
96
  // Ignore errors from getPosUnsafe
97
97
  return undefined;
98
98
  }
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.handleMouseDown = void 0;
7
7
  var _styles = require("@atlaskit/editor-common/styles");
8
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
9
8
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
10
9
  var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
11
10
  var handleMouseDown = exports.handleMouseDown = function handleMouseDown(api) {
@@ -45,21 +44,19 @@ var handleMouseDown = exports.handleMouseDown = function handleMouseDown(api) {
45
44
  * When block menu is enabled, reset intent back to 'default' as editor-plugin-block-menu sets the user intent to 'blockMenuOpen', and setting here
46
45
  * causes flickering as this runs before editor-plugin-block-menu.
47
46
  */
48
- if ((0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_user_intent_fix')) {
49
- if ((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true)) {
50
- // if target is drag handle, block menu will be opened
51
- if (!isDragHandle) {
52
- var _api$userIntent;
53
- api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || _api$userIntent.commands.setCurrentUserIntent('default')({
54
- tr: tr
55
- });
56
- }
57
- } else {
58
- var _api$userIntent2;
59
- (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || _api$userIntent2.commands.setCurrentUserIntent(isDragHandle ? 'dragHandleSelected' : 'default')({
47
+ if ((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true)) {
48
+ // if target is drag handle, block menu will be opened
49
+ if (!isDragHandle) {
50
+ var _api$userIntent;
51
+ api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || _api$userIntent.commands.setCurrentUserIntent('default')({
60
52
  tr: tr
61
53
  });
62
54
  }
55
+ } else {
56
+ var _api$userIntent2;
57
+ (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || _api$userIntent2.commands.setCurrentUserIntent(isDragHandle ? 'dragHandleSelected' : 'default')({
58
+ tr: tr
59
+ });
63
60
  }
64
61
  return tr;
65
62
  });
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DragHandleNestedIcon = void 0;
7
+ var _react = require("@emotion/react");
8
+ /** @jsxRuntime classic */
9
+ /**
10
+ * @jsxRuntime classic
11
+ * @jsx jsx
12
+ */
13
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
14
+
15
+ var spanStyles = (0, _react.css)({
16
+ display: 'inline-block',
17
+ boxSizing: 'border-box',
18
+ flexShrink: 0
19
+ });
20
+ var svgSizeStyles = (0, _react.css)({
21
+ width: '24px',
22
+ height: '24px'
23
+ });
24
+ var svgStyles = (0, _react.css)({
25
+ color: 'currentColor',
26
+ overflow: 'hidden',
27
+ pointerEvents: 'none',
28
+ verticalAlign: 'bottom'
29
+ });
30
+
31
+ /**
32
+ * Custom 3-dot vertical drag handle icon for nested nodes.
33
+ * Similar to DragHandleVerticalIcon but with only 3 dots instead of 6.
34
+ * Hardcoded to medium size with spacious spacing.
35
+ */
36
+ var DragHandleNestedIcon = exports.DragHandleNestedIcon = function DragHandleNestedIcon() {
37
+ return (0, _react.jsx)("span", {
38
+ "aria-hidden": true,
39
+ css: spanStyles
40
+ }, (0, _react.jsx)("svg", {
41
+ width: 24,
42
+ height: 24,
43
+ viewBox: "-4 -4 24 24",
44
+ fill: "none",
45
+ xmlns: "http://www.w3.org/2000/svg",
46
+ role: "presentation",
47
+ css: [svgStyles, svgSizeStyles]
48
+ }, (0, _react.jsx)("circle", {
49
+ cx: "8",
50
+ cy: "4",
51
+ r: "1.5",
52
+ fill: "currentColor"
53
+ }), (0, _react.jsx)("circle", {
54
+ cx: "8",
55
+ cy: "8",
56
+ r: "1.5",
57
+ fill: "currentColor"
58
+ }), (0, _react.jsx)("circle", {
59
+ cx: "8",
60
+ cy: "12",
61
+ r: "1.5",
62
+ fill: "currentColor"
63
+ })));
64
+ };
@@ -41,6 +41,7 @@ var _dragHandlePositions = require("../pm-plugins/utils/drag-handle-positions");
41
41
  var _getSelection = require("../pm-plugins/utils/getSelection");
42
42
  var _selection2 = require("../pm-plugins/utils/selection");
43
43
  var _consts2 = require("./consts");
44
+ var _dragHandleNestedIcon = require("./drag-handle-nested-icon");
44
45
  var _dragPreview = require("./drag-preview");
45
46
  var _anchorName = require("./utils/anchor-name");
46
47
  var _domAttrName = require("./utils/dom-attr-name");
@@ -447,6 +448,24 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
447
448
  var start = getPos();
448
449
  var isLayoutColumn = nodeType === 'layoutColumn';
449
450
  var isMultiSelect = (0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true);
451
+
452
+ // Dynamically calculate if node is top-level based on current position (gated by experiment)
453
+ var isTopLevelNodeDynamic = (0, _react.useMemo)(function () {
454
+ if (!(0, _expValEquals.expValEquals)('platform_editor_nested_drag_handle_icon', 'isEnabled', true)) {
455
+ return isTopLevelNode;
456
+ }
457
+ var pos = getPos();
458
+ if (typeof pos === 'number') {
459
+ var $pos = view.state.doc.resolve(pos);
460
+ return ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
461
+ }
462
+ return true;
463
+ }, [getPos, view.state.doc, isTopLevelNode]);
464
+
465
+ // Use the dynamic value when experiment is on, otherwise use the prop
466
+ // When cleaning up the experiment, you can safely remove the isTopLevelNode as an prop and
467
+ // just rely on the dynamic value (rename it to isTopLevelNode for simplicitiy)
468
+ var isTopLevelNodeValue = (0, _expValEquals.expValEquals)('platform_editor_nested_drag_handle_icon', 'isEnabled', true) ? isTopLevelNodeDynamic : isTopLevelNode;
450
469
  (0, _react.useEffect)(function () {
451
470
  if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true)) {
452
471
  return;
@@ -537,7 +556,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
537
556
  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;
538
557
  if (!isMultiSelect || tr.selection.empty || !e.shiftKey) {
539
558
  tr = (0, _getSelection.selectNode)(tr, startPos, nodeType, api);
540
- } else if (isTopLevelNode && $anchor.depth <= _consts2.DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH && e.shiftKey && (0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_shift_click_select')) {
559
+ } else if (isTopLevelNodeValue && $anchor.depth <= _consts2.DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH && e.shiftKey && (0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_shift_click_select')) {
541
560
  var _api$blockControls3;
542
561
  var alignAnchorHeadToSel = (0, _selection2.alignAnchorHeadInDirectionOfPos)(tr.selection, startPos);
543
562
  var selectionWithExpandedHead = (0, _selection2.expandSelectionHeadToNodeAtPos)(alignAnchorHeadToSel, startPos);
@@ -562,7 +581,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
562
581
  return tr;
563
582
  });
564
583
  view.focus();
565
- }, [isMultiSelect, api, view, dragHandleSelected, getPos, isTopLevelNode, nodeType]);
584
+ }, [isMultiSelect, api, view, dragHandleSelected, getPos, isTopLevelNodeValue, nodeType]);
566
585
  var handleKeyDown = (0, _react.useCallback)(function (e) {
567
586
  // allow user to use spacebar to select the node
568
587
  if (!e.repeat && e.key === ' ') {
@@ -862,18 +881,18 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
862
881
  var isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
863
882
  var isSticky = (0, _dragHandlePositions.shouldBeSticky)(nodeType);
864
883
  if (supportsAnchor) {
865
- var bottom = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName, isSticky, isTopLevelNode, isLayoutColumn) : {};
884
+ var bottom = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn) : {};
866
885
  return _objectSpread({
867
886
  left: isEdgeCase ? "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType), ")") : (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn ? "calc((anchor(".concat(safeAnchorName, " right) + anchor(").concat(safeAnchorName, " left))/2 - ").concat(_consts2.DRAG_HANDLE_HEIGHT / 2, "px)") : "calc(anchor(".concat(safeAnchorName, " start) - ").concat(_styles.DRAG_HANDLE_WIDTH, "px - ").concat((0, _consts2.dragHandleGap)(nodeType, parentNodeType), "px)"),
868
887
  top: (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn ? "calc(anchor(".concat(safeAnchorName, " top) - ").concat(_styles.DRAG_HANDLE_WIDTH, "px)") : "calc(anchor(".concat(safeAnchorName, " start)+ ").concat((0, _consts2.topPositionAdjustment)((0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? $pos && $pos.nodeAfter && (0, _decorationsCommon.getNodeTypeWithLevel)($pos.nodeAfter) || nodeType : nodeType), "px)")
869
888
  }, bottom);
870
889
  }
871
- var height = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlHeightCSSValue)((0, _dragHandlePositions.getNodeHeight)(dom, safeAnchorName, anchorRectCache) || 0, isSticky, isTopLevelNode, "".concat(_consts2.DRAG_HANDLE_HEIGHT), isLayoutColumn) : {};
890
+ var height = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlHeightCSSValue)((0, _dragHandlePositions.getNodeHeight)(dom, safeAnchorName, anchorRectCache) || 0, isSticky, isTopLevelNodeValue, "".concat(_consts2.DRAG_HANDLE_HEIGHT), isLayoutColumn) : {};
872
891
  return _objectSpread({
873
892
  left: isEdgeCase ? "calc(".concat((dom === null || dom === void 0 ? void 0 : dom.offsetLeft) || 0, "px + ").concat((0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType), ")") : (0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType),
874
893
  top: (0, _dragHandlePositions.getTopPosition)(dom, nodeType)
875
894
  }, height);
876
- }, [anchorName, getPos, view, nodeType, macroInteractionUpdates, anchorRectCache, isTopLevelNode, isLayoutColumn, recalculatePosition]);
895
+ }, [anchorName, getPos, view, nodeType, macroInteractionUpdates, anchorRectCache, isTopLevelNodeValue, isLayoutColumn, recalculatePosition]);
877
896
  var calculatePositionOld = (0, _react.useCallback)(function () {
878
897
  var pos = getPos();
879
898
  var $pos = (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? typeof pos === 'number' && view.state.doc.resolve(pos) : pos && view.state.doc.resolve(pos);
@@ -908,18 +927,18 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
908
927
  var isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
909
928
  var isSticky = (0, _dragHandlePositions.shouldBeSticky)(nodeType);
910
929
  if (supportsAnchor) {
911
- var bottom = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName, isSticky, isTopLevelNode, isLayoutColumn) : {};
930
+ var bottom = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn) : {};
912
931
  return _objectSpread({
913
932
  left: isEdgeCase ? "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType), ")") : (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn ? "calc((anchor(".concat(safeAnchorName, " right) + anchor(").concat(safeAnchorName, " left))/2 - ").concat(_consts2.DRAG_HANDLE_HEIGHT / 2, "px)") : "calc(anchor(".concat(safeAnchorName, " start) - ").concat(_styles.DRAG_HANDLE_WIDTH, "px - ").concat((0, _consts2.dragHandleGap)(nodeType, parentNodeType), "px)"),
914
933
  top: (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn ? "calc(anchor(".concat(safeAnchorName, " top) - ").concat(_styles.DRAG_HANDLE_WIDTH, "px)") : "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _consts2.topPositionAdjustment)((0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? $pos && $pos.nodeAfter && (0, _decorationsCommon.getNodeTypeWithLevel)($pos.nodeAfter) || nodeType : nodeType), "px)")
915
934
  }, bottom);
916
935
  }
917
- var height = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlHeightCSSValue)((0, _dragHandlePositions.getNodeHeight)(dom, safeAnchorName, anchorRectCache) || 0, isSticky, isTopLevelNode, "".concat(_consts2.DRAG_HANDLE_HEIGHT), isLayoutColumn) : {};
936
+ var height = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlHeightCSSValue)((0, _dragHandlePositions.getNodeHeight)(dom, safeAnchorName, anchorRectCache) || 0, isSticky, isTopLevelNodeValue, "".concat(_consts2.DRAG_HANDLE_HEIGHT), isLayoutColumn) : {};
918
937
  return _objectSpread({
919
938
  left: isEdgeCase ? "calc(".concat((dom === null || dom === void 0 ? void 0 : dom.offsetLeft) || 0, "px + ").concat((0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType), ")") : (0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType),
920
939
  top: (0, _dragHandlePositions.getTopPosition)(dom, nodeType)
921
940
  }, height);
922
- }, [anchorName, getPos, view, nodeType, blockCardWidth, macroInteractionUpdates, anchorRectCache, isTopLevelNode, isLayoutColumn]);
941
+ }, [anchorName, getPos, view, nodeType, blockCardWidth, macroInteractionUpdates, anchorRectCache, isTopLevelNodeValue, isLayoutColumn]);
923
942
  (0, _react.useEffect)(function () {
924
943
  if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true)) {
925
944
  return;
@@ -995,12 +1014,12 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
995
1014
  }
996
1015
  var mSelect = api === null || api === void 0 || (_api$blockControls$sh4 = api.blockControls.sharedState.currentState()) === null || _api$blockControls$sh4 === void 0 ? void 0 : _api$blockControls$sh4.multiSelectDnD;
997
1016
  var $anchor = (mSelect === null || mSelect === void 0 ? void 0 : mSelect.anchor) !== undefined ? view.state.doc.resolve(mSelect === null || mSelect === void 0 ? void 0 : mSelect.anchor) : view.state.selection.$anchor;
998
- if (isShiftDown && (!isTopLevelNode || isTopLevelNode && $anchor.depth > _consts2.DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH)) {
1017
+ if (isShiftDown && (!isTopLevelNodeValue || isTopLevelNodeValue && $anchor.depth > _consts2.DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH)) {
999
1018
  setDragHandleDisabled(true);
1000
1019
  } else {
1001
1020
  setDragHandleDisabled(false);
1002
1021
  }
1003
- }, [api === null || api === void 0 ? void 0 : api.blockControls.sharedState, isMultiSelect, isShiftDown, isTopLevelNode, view]);
1022
+ }, [api === null || api === void 0 ? void 0 : api.blockControls.sharedState, isMultiSelect, isShiftDown, isTopLevelNodeValue, view]);
1004
1023
  var dragHandleMessage = (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true) ? formatMessage(_messages.blockControlsMessages.dragToMoveClickToOpen, {
1005
1024
  br: (0, _react2.jsx)("br", null)
1006
1025
  }) : formatMessage(_messages.blockControlsMessages.dragToMove);
@@ -1009,7 +1028,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
1009
1028
  var dragHandleAriaLabel = (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true) ? formatMessage(_messages.blockControlsMessages.dragToMoveClickToOpen, {
1010
1029
  br: ' '
1011
1030
  }) : formatMessage(_messages.blockControlsMessages.dragToMove);
1012
- var helpDescriptors = isTopLevelNode ? [{
1031
+ var helpDescriptors = isTopLevelNodeValue ? [{
1013
1032
  description: dragHandleMessage
1014
1033
  }, {
1015
1034
  description: formatMessage(_messages.blockControlsMessages.moveUp),
@@ -1033,7 +1052,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
1033
1052
  keymap: _keymaps.dragToMoveDown
1034
1053
  }];
1035
1054
  var isParentNodeOfTypeLayout;
1036
- if (!isTopLevelNode) {
1055
+ if (!isTopLevelNodeValue) {
1037
1056
  var pos = getPos();
1038
1057
  if (typeof pos === 'number') {
1039
1058
  var _$pos$parent;
@@ -1113,7 +1132,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
1113
1132
  // eslint-disable-next-line @atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop
1114
1133
  ,
1115
1134
  onDragStart: handleIconDragStart
1116
- }, (0, _react2.jsx)(_dragHandleVertical.default, {
1135
+ }, (0, _expValEquals.expValEquals)('platform_editor_nested_drag_handle_icon', 'isEnabled', true) && !isTopLevelNodeValue ? (0, _react2.jsx)(_dragHandleNestedIcon.DragHandleNestedIcon, null) : (0, _react2.jsx)(_dragHandleVertical.default, {
1117
1136
  spacing: "spacious",
1118
1137
  label: "",
1119
1138
  size: "small"
@@ -1129,7 +1148,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
1129
1148
  as: "span",
1130
1149
  testId: "block-ctrl-drag-handle-container"
1131
1150
  }, (0, _react2.jsx)("span", {
1132
- css: [tooltipContainerStyles, (0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNode) && ((0, _expValEquals.expValEquals)('platform_editor_table_sticky_header_improvements', 'cohort', 'test_with_overflow') && (0, _platformFeatureFlags.fg)('platform_editor_table_sticky_header_patch_6') ? tooltipContainerStylesImprovedStickyHeaderWithMask : tooltipContainerStylesStickyHeaderWithMask), !(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNode) && tooltipContainerStylesStickyHeaderWithoutMask]
1151
+ css: [tooltipContainerStyles, (0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && ((0, _expValEquals.expValEquals)('platform_editor_table_sticky_header_improvements', 'cohort', 'test_with_overflow') && (0, _platformFeatureFlags.fg)('platform_editor_table_sticky_header_patch_6') ? tooltipContainerStylesImprovedStickyHeaderWithMask : tooltipContainerStylesStickyHeaderWithMask), !(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithoutMask]
1133
1152
  }, (0, _react2.jsx)(_tooltip.default, {
1134
1153
  content: (0, _react2.jsx)(_keymaps.TooltipContentWithMultipleShortcuts, {
1135
1154
  helpDescriptors: helpDescriptors
@@ -1143,7 +1162,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
1143
1162
  });
1144
1163
  }
1145
1164
  }, (0, _react2.jsx)("span", {
1146
- css: [(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNode) && buttonWrapperStyles, buttonWrapperStylesPatch]
1165
+ css: [(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && buttonWrapperStyles, buttonWrapperStylesPatch]
1147
1166
  }, renderButton()))));
1148
1167
  };
1149
1168
  var stickyWithoutTooltip = function stickyWithoutTooltip() {
@@ -1155,9 +1174,9 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref3) {
1155
1174
  as: "span",
1156
1175
  testId: "block-ctrl-drag-handle-container"
1157
1176
  }, (0, _react2.jsx)("span", {
1158
- css: [tooltipContainerStyles, (0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNode) && tooltipContainerStylesStickyHeaderWithMask, !(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNode) && tooltipContainerStylesStickyHeaderWithoutMask]
1177
+ css: [tooltipContainerStyles, (0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithMask, !(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && tooltipContainerStylesStickyHeaderWithoutMask]
1159
1178
  }, (0, _react2.jsx)("span", {
1160
- css: [(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNode) && buttonWrapperStyles, buttonWrapperStylesPatch]
1179
+ css: [(0, _dragHandlePositions.shouldMaskNodeControls)(nodeType, isTopLevelNodeValue) && buttonWrapperStyles, buttonWrapperStylesPatch]
1161
1180
  }, renderButton())));
1162
1181
  };
1163
1182
  var buttonWithTooltip = function buttonWithTooltip() {
@@ -1187,6 +1206,7 @@ var DragHandleWithVisibility = exports.DragHandleWithVisibility = function DragH
1187
1206
  anchorName = _ref10.anchorName,
1188
1207
  nodeType = _ref10.nodeType,
1189
1208
  handleOptions = _ref10.handleOptions,
1209
+ isTopLevelNode = _ref10.isTopLevelNode,
1190
1210
  anchorRectCache = _ref10.anchorRectCache;
1191
1211
  return (0, _react2.jsx)(_visibilityContainer.VisibilityContainer, {
1192
1212
  api: api
@@ -1198,6 +1218,7 @@ var DragHandleWithVisibility = exports.DragHandleWithVisibility = function DragH
1198
1218
  anchorName: anchorName,
1199
1219
  nodeType: nodeType,
1200
1220
  handleOptions: handleOptions,
1221
+ isTopLevelNode: isTopLevelNode,
1201
1222
  anchorRectCache: anchorRectCache
1202
1223
  }));
1203
1224
  };
@@ -77,12 +77,13 @@ export const blockControlsPlugin = ({
77
77
  toggleBlockMenu: options => ({
78
78
  tr
79
79
  }) => {
80
- var _api$userIntent, _api$userIntent$share, _options$anchorName, _api$blockControls, _api$blockControls$sh;
80
+ var _api$userIntent, _api$userIntent$share, _api$blockControls, _api$blockControls$sh, _options$anchorName, _api$blockControls2, _api$blockControls2$s;
81
81
  if (!expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true)) {
82
82
  return tr;
83
83
  }
84
84
  const currMeta = tr.getMeta(key);
85
85
  const currentUserIntent = api === null || api === void 0 ? void 0 : (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : (_api$userIntent$share = _api$userIntent.sharedState.currentState()) === null || _api$userIntent$share === void 0 ? void 0 : _api$userIntent$share.currentUserIntent;
86
+ const isMenuCurrentlyOpen = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$sh = _api$blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.isMenuOpen;
86
87
  if (options !== null && options !== void 0 && options.closeMenu) {
87
88
  tr.setMeta(key, {
88
89
  ...currMeta,
@@ -94,6 +95,14 @@ export const blockControlsPlugin = ({
94
95
  tr
95
96
  });
96
97
  }
98
+
99
+ // When closing the menu, restart the active session timer
100
+ if (isMenuCurrentlyOpen && fg('platform_editor_ease_of_use_metrics')) {
101
+ var _api$metrics;
102
+ api === null || api === void 0 ? void 0 : (_api$metrics = api.metrics) === null || _api$metrics === void 0 ? void 0 : _api$metrics.commands.startActiveSessionTimer()({
103
+ tr
104
+ });
105
+ }
97
106
  return tr;
98
107
  }
99
108
 
@@ -109,13 +118,21 @@ export const blockControlsPlugin = ({
109
118
  ...currMeta,
110
119
  closeMenu: true
111
120
  });
121
+
122
+ // When closing the menu, restart the active session timer
123
+ if (isMenuCurrentlyOpen && fg('platform_editor_ease_of_use_metrics')) {
124
+ var _api$metrics2;
125
+ api === null || api === void 0 ? void 0 : (_api$metrics2 = api.metrics) === null || _api$metrics2 === void 0 ? void 0 : _api$metrics2.commands.startActiveSessionTimer()({
126
+ tr
127
+ });
128
+ }
112
129
  return tr;
113
130
  }
114
131
  let toggleMenuMeta = {
115
132
  anchorName: options === null || options === void 0 ? void 0 : options.anchorName,
116
133
  triggerByNode: options === null || options === void 0 ? void 0 : options.triggerByNode
117
134
  };
118
- const menuTriggerBy = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$sh = _api$blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.menuTriggerBy;
135
+ const menuTriggerBy = api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$s = _api$blockControls2.sharedState.currentState()) === null || _api$blockControls2$s === void 0 ? void 0 : _api$blockControls2$s.menuTriggerBy;
119
136
  if (options !== null && options !== void 0 && options.anchorName) {
120
137
  const {
121
138
  moveUp,
@@ -134,7 +151,7 @@ export const blockControlsPlugin = ({
134
151
  });
135
152
  if ((menuTriggerBy === undefined || !!menuTriggerBy && menuTriggerBy === (options === null || options === void 0 ? void 0 : options.anchorName)) && currentUserIntent === 'blockMenuOpen') {
136
153
  const state = api === null || api === void 0 ? void 0 : api.blockControls.sharedState.currentState();
137
- if (state !== null && state !== void 0 && state.isSelectedViaDragHandle && fg('platform_editor_toolbar_aifc_user_intent_fix')) {
154
+ if (state !== null && state !== void 0 && state.isSelectedViaDragHandle) {
138
155
  var _api$userIntent4;
139
156
  api === null || api === void 0 ? void 0 : (_api$userIntent4 = api.userIntent) === null || _api$userIntent4 === void 0 ? void 0 : _api$userIntent4.commands.setCurrentUserIntent('dragHandleSelected')({
140
157
  tr
@@ -146,6 +163,25 @@ export const blockControlsPlugin = ({
146
163
  tr
147
164
  });
148
165
  }
166
+
167
+ // When closing the menu, restart the active session timer
168
+ if (fg('platform_editor_ease_of_use_metrics')) {
169
+ var _api$metrics3;
170
+ api === null || api === void 0 ? void 0 : (_api$metrics3 = api.metrics) === null || _api$metrics3 === void 0 ? void 0 : _api$metrics3.commands.startActiveSessionTimer()({
171
+ tr
172
+ });
173
+ }
174
+ } else if (!isMenuCurrentlyOpen) {
175
+ // When opening the menu, pause the active session timer
176
+ if (fg('platform_editor_ease_of_use_metrics')) {
177
+ var _api$metrics4;
178
+ api === null || api === void 0 ? void 0 : (_api$metrics4 = api.metrics) === null || _api$metrics4 === void 0 ? void 0 : _api$metrics4.commands.handleIntentToStartEdit({
179
+ shouldStartTimer: false,
180
+ shouldPersistActiveSession: true
181
+ })({
182
+ tr
183
+ });
184
+ }
149
185
  }
150
186
  return tr;
151
187
  },
@@ -168,8 +204,8 @@ export const blockControlsPlugin = ({
168
204
  }
169
205
  });
170
206
  if (fg('platform_editor_ease_of_use_metrics')) {
171
- var _api$metrics;
172
- api === null || api === void 0 ? void 0 : (_api$metrics = api.metrics) === null || _api$metrics === void 0 ? void 0 : _api$metrics.commands.handleIntentToStartEdit({
207
+ var _api$metrics5;
208
+ api === null || api === void 0 ? void 0 : (_api$metrics5 = api.metrics) === null || _api$metrics5 === void 0 ? void 0 : _api$metrics5.commands.handleIntentToStartEdit({
173
209
  shouldStartTimer: false,
174
210
  shouldPersistActiveSession: true
175
211
  })({
@@ -83,7 +83,7 @@ export const dragHandleDecoration = ({
83
83
  const getPos = () => {
84
84
  try {
85
85
  return getPosUnsafe();
86
- } catch (e) {
86
+ } catch {
87
87
  // Ignore errors from getPosUnsafe
88
88
  return undefined;
89
89
  }
@@ -1,5 +1,4 @@
1
1
  import { DRAG_HANDLE_SELECTOR } from '@atlaskit/editor-common/styles';
2
- import { fg } from '@atlaskit/platform-feature-flags';
3
2
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
3
  import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
5
4
  export const handleMouseDown = api => (view, event) => {
@@ -39,21 +38,19 @@ export const handleMouseDown = api => (view, event) => {
39
38
  * When block menu is enabled, reset intent back to 'default' as editor-plugin-block-menu sets the user intent to 'blockMenuOpen', and setting here
40
39
  * causes flickering as this runs before editor-plugin-block-menu.
41
40
  */
42
- if (fg('platform_editor_toolbar_aifc_user_intent_fix')) {
43
- if (expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true)) {
44
- // if target is drag handle, block menu will be opened
45
- if (!isDragHandle) {
46
- var _api$userIntent;
47
- api === null || api === void 0 ? void 0 : (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.commands.setCurrentUserIntent('default')({
48
- tr
49
- });
50
- }
51
- } else {
52
- var _api$userIntent2;
53
- (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.commands.setCurrentUserIntent(isDragHandle ? 'dragHandleSelected' : 'default')({
41
+ if (expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true)) {
42
+ // if target is drag handle, block menu will be opened
43
+ if (!isDragHandle) {
44
+ var _api$userIntent;
45
+ api === null || api === void 0 ? void 0 : (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.commands.setCurrentUserIntent('default')({
54
46
  tr
55
47
  });
56
48
  }
49
+ } else {
50
+ var _api$userIntent2;
51
+ (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.commands.setCurrentUserIntent(isDragHandle ? 'dragHandleSelected' : 'default')({
52
+ tr
53
+ });
57
54
  }
58
55
  return tr;
59
56
  });
@@ -0,0 +1,57 @@
1
+ /** @jsxRuntime classic */
2
+ /**
3
+ * @jsxRuntime classic
4
+ * @jsx jsx
5
+ */
6
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
7
+ import { css, jsx } from '@emotion/react';
8
+ const spanStyles = css({
9
+ display: 'inline-block',
10
+ boxSizing: 'border-box',
11
+ flexShrink: 0
12
+ });
13
+ const svgSizeStyles = css({
14
+ width: '24px',
15
+ height: '24px'
16
+ });
17
+ const svgStyles = css({
18
+ color: 'currentColor',
19
+ overflow: 'hidden',
20
+ pointerEvents: 'none',
21
+ verticalAlign: 'bottom'
22
+ });
23
+
24
+ /**
25
+ * Custom 3-dot vertical drag handle icon for nested nodes.
26
+ * Similar to DragHandleVerticalIcon but with only 3 dots instead of 6.
27
+ * Hardcoded to medium size with spacious spacing.
28
+ */
29
+ export const DragHandleNestedIcon = () => {
30
+ return jsx("span", {
31
+ "aria-hidden": true,
32
+ css: spanStyles
33
+ }, jsx("svg", {
34
+ width: 24,
35
+ height: 24,
36
+ viewBox: "-4 -4 24 24",
37
+ fill: "none",
38
+ xmlns: "http://www.w3.org/2000/svg",
39
+ role: "presentation",
40
+ css: [svgStyles, svgSizeStyles]
41
+ }, jsx("circle", {
42
+ cx: "8",
43
+ cy: "4",
44
+ r: "1.5",
45
+ fill: "currentColor"
46
+ }), jsx("circle", {
47
+ cx: "8",
48
+ cy: "8",
49
+ r: "1.5",
50
+ fill: "currentColor"
51
+ }), jsx("circle", {
52
+ cx: "8",
53
+ cy: "12",
54
+ r: "1.5",
55
+ fill: "currentColor"
56
+ })));
57
+ };