@atlaskit/editor-plugin-block-controls 1.5.17 → 1.5.18

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.
@@ -1,6 +1,5 @@
1
1
  /** @jsx jsx */
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
-
4
3
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
5
4
  import { css, jsx } from '@emotion/react';
6
5
  import { injectIntl } from 'react-intl-next';
@@ -39,11 +38,15 @@ const dragHandleButtonStyles = css({
39
38
  cursor: 'grab',
40
39
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
41
40
  zIndex: DRAG_HANDLE_ZINDEX,
41
+ outline: 'none',
42
42
  '&:hover': {
43
43
  backgroundColor: "var(--ds-background-neutral-subtle-hovered, #091E420F)"
44
44
  },
45
45
  '&:active': {
46
46
  backgroundColor: "var(--ds-background-neutral-subtle-pressed, #091E4224)"
47
+ },
48
+ '&:focus': {
49
+ outline: `2px solid ${"var(--ds-border-focused, #388BFF)"}`
47
50
  }
48
51
  });
49
52
  const selectedStyles = css({
@@ -58,7 +61,8 @@ const DragHandleInternal = ({
58
61
  nodeType,
59
62
  intl: {
60
63
  formatMessage
61
- }
64
+ },
65
+ handleOptions
62
66
  }) => {
63
67
  const start = getPos();
64
68
  const buttonRef = useRef(null);
@@ -158,6 +162,35 @@ const DragHandleInternal = ({
158
162
  return tr;
159
163
  });
160
164
  }, [start, api]);
165
+ const handleKeyDown = useCallback(e => {
166
+ if (fg('platform_editor_element_drag_and_drop_ed_23873')) {
167
+ // allow user to use spacebar to select the node
168
+ if (!e.repeat && e.key === ' ') {
169
+ var _api$core4;
170
+ api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
171
+ tr
172
+ }) => {
173
+ if (start === undefined) {
174
+ return tr;
175
+ }
176
+ const node = tr.doc.nodeAt(start);
177
+ if (!node) {
178
+ return tr;
179
+ }
180
+ const $startPos = tr.doc.resolve(start + node.nodeSize);
181
+ const selection = new TextSelection($startPos);
182
+ tr.setSelection(selection);
183
+ tr.setMeta(key, {
184
+ pos: start
185
+ });
186
+ return tr;
187
+ });
188
+ } else {
189
+ // return focus to editor to resume editing from caret positon
190
+ view.focus();
191
+ }
192
+ }
193
+ }, [start, api, view]);
161
194
  useEffect(() => {
162
195
  const element = buttonRef.current;
163
196
  if (!element) {
@@ -186,11 +219,11 @@ const DragHandleInternal = ({
186
219
  });
187
220
  },
188
221
  onDragStart() {
189
- var _api$core4;
222
+ var _api$core5;
190
223
  if (start === undefined) {
191
224
  return;
192
225
  }
193
- api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
226
+ api === null || api === void 0 ? void 0 : (_api$core5 = api.core) === null || _api$core5 === void 0 ? void 0 : _api$core5.actions.execute(({
194
227
  tr
195
228
  }) => {
196
229
  var _api$blockControls, _api$analytics2;
@@ -251,6 +284,18 @@ const DragHandleInternal = ({
251
284
  top: fg('platform_editor_elements_dnd_ed_23674') ? getTopPosition(dom, nodeType) : getTopPosition(dom)
252
285
  };
253
286
  }, [anchorName, nodeType, view, blockCardWidth, macroInteractionUpdates]);
287
+ useEffect(() => {
288
+ if (handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && buttonRef.current && fg('platform_editor_element_drag_and_drop_ed_23873')) {
289
+ const id = requestAnimationFrame(() => {
290
+ var _buttonRef$current;
291
+ (_buttonRef$current = buttonRef.current) === null || _buttonRef$current === void 0 ? void 0 : _buttonRef$current.focus();
292
+ });
293
+ return () => {
294
+ cancelAnimationFrame(id);
295
+ view.focus();
296
+ };
297
+ }
298
+ }, [buttonRef, handleOptions === null || handleOptions === void 0 ? void 0 : handleOptions.isFocused, view]);
254
299
  const helpDescriptors = [{
255
300
  description: formatMessage(blockControlsMessages.dragToMove)
256
301
  }, {
@@ -269,6 +314,7 @@ const DragHandleInternal = ({
269
314
  style: positionStyles,
270
315
  onClick: handleOnClick,
271
316
  onMouseDown: fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2') ? handleMouseDownWrapperRemoved : handleMouseDown,
317
+ onKeyDown: handleKeyDown,
272
318
  "data-testid": "block-ctrl-drag-handle"
273
319
  }, jsx(DragHandlerIcon, {
274
320
  label: "",
@@ -0,0 +1,18 @@
1
+ export var showDragHandleAtSelection = function showDragHandleAtSelection(api) {
2
+ return function (state, _, view) {
3
+ var rootPos = state.selection.$from.before(1);
4
+ var dom = view === null || view === void 0 ? void 0 : view.domAtPos(rootPos, 0);
5
+ var rootNode = dom === null || dom === void 0 ? void 0 : dom.node.childNodes[dom === null || dom === void 0 ? void 0 : dom.offset];
6
+ if (rootNode) {
7
+ var anchorName = rootNode.getAttribute('data-drag-handler-anchor-name');
8
+ var nodeType = rootNode.getAttribute('data-drag-handler-node-type');
9
+ if (api && anchorName && nodeType) {
10
+ api.core.actions.execute(api.blockControls.commands.showDragHandleAt(rootPos, anchorName, nodeType, {
11
+ isFocused: true
12
+ }));
13
+ return true;
14
+ }
15
+ }
16
+ return false;
17
+ };
18
+ };
@@ -51,14 +51,15 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
51
51
  return tr;
52
52
  };
53
53
  },
54
- showDragHandleAt: function showDragHandleAt(pos, anchorName, nodeType) {
54
+ showDragHandleAt: function showDragHandleAt(pos, anchorName, nodeType, handleOptions) {
55
55
  return function (_ref4) {
56
56
  var tr = _ref4.tr;
57
57
  tr.setMeta(key, {
58
58
  activeNode: {
59
59
  pos: pos,
60
60
  anchorName: anchorName,
61
- nodeType: nodeType
61
+ nodeType: nodeType,
62
+ handleOptions: handleOptions
62
63
  }
63
64
  });
64
65
  return tr;
@@ -129,7 +129,7 @@ export var mouseMoveWrapperDecorations = function mouseMoveWrapperDecorations(ne
129
129
  });
130
130
  return decs;
131
131
  };
132
- export var dragHandleDecoration = function dragHandleDecoration(pos, anchorName, nodeType, api, getIntl) {
132
+ export var dragHandleDecoration = function dragHandleDecoration(api, getIntl, pos, anchorName, nodeType, handleOptions) {
133
133
  return Decoration.widget(pos, function (view, getPos) {
134
134
  var element = document.createElement('div');
135
135
  // Need to set it to inline to avoid text being split when merging two paragraphs
@@ -148,7 +148,8 @@ export var dragHandleDecoration = function dragHandleDecoration(pos, anchorName,
148
148
  api: api,
149
149
  getPos: getPos,
150
150
  anchorName: anchorName,
151
- nodeType: nodeType
151
+ nodeType: nodeType,
152
+ handleOptions: handleOptions
152
153
  })), element);
153
154
  return element;
154
155
  }, {
@@ -0,0 +1,18 @@
1
+ import { bindKeymapWithCommand, showElementDragHandle } from '@atlaskit/editor-common/keymaps';
2
+ import { keydownHandler } from '@atlaskit/editor-prosemirror/keymap';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { showDragHandleAtSelection } from '../commands/show-drag-handle';
5
+ function keymapList(api) {
6
+ var keymapList = {};
7
+ if (api && fg('platform_editor_element_drag_and_drop_ed_23873')) {
8
+ bindKeymapWithCommand(showElementDragHandle.common, function (state, dispatch, view) {
9
+ showDragHandleAtSelection(api)(state, dispatch, view);
10
+ //we always want to handle this shortcut to prevent default browser special char insert when option + alphabetical key is used
11
+ return true;
12
+ }, keymapList);
13
+ }
14
+ return keymapList;
15
+ }
16
+ export var boundKeydownHandler = function boundKeydownHandler(api) {
17
+ return keydownHandler(keymapList(api));
18
+ };
@@ -12,6 +12,7 @@ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
12
12
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
13
13
  import { dragHandleDecoration, dropTargetDecorations, emptyParagraphNodeDecorations, mouseMoveWrapperDecorations, nodeDecorations } from './decorations';
14
14
  import { handleMouseOver } from './handle-mouse-over';
15
+ import { boundKeydownHandler } from './keymap';
15
16
  export var key = new PluginKey('blockControls');
16
17
  var destroyFn = function destroyFn(api) {
17
18
  var scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
@@ -85,7 +86,7 @@ export var createPlugin = function createPlugin(api, getIntl) {
85
86
  return initialState;
86
87
  },
87
88
  apply: function apply(tr, currentState, oldState, newState) {
88
- var _meta$activeNode, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
89
+ var _meta$activeNode, _meta$activeNode$hand, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
89
90
  if (initialState.isDocSizeLimitEnabled === null) {
90
91
  if (fg('platform.editor.elements.drag-and-drop-doc-size-limit_7k4vq')) {
91
92
  initialState.isDocSizeLimitEnabled = true;
@@ -118,9 +119,15 @@ export var createPlugin = function createPlugin(api, getIntl) {
118
119
  var resizerMeta = tr.getMeta('is-resizer-resizing');
119
120
  isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
120
121
  var nodeCountChanged = oldState.doc.childCount !== newState.doc.childCount;
122
+ var shouldRemoveHandle = true;
123
+ if (fg('platform_editor_elements_drag_and_drop_ed_24000')) {
124
+ shouldRemoveHandle = !tr.getMeta('isRemote');
125
+ }
121
126
 
122
- // During resize, remove the drag handle widget
123
- if (isResizerResizing || nodeCountChanged || meta !== null && meta !== void 0 && meta.nodeMoved) {
127
+ // During resize, remove the drag handle widget so its dom positioning doesn't need to be maintained
128
+ // Also remove the handle when the node is moved or the node count changes. This helps prevent incorrect positioning
129
+ // Don't remove the handle if remote changes are changing the node count, its prosemirror position can be mapped instead
130
+ if (isResizerResizing || nodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
124
131
  var oldHandle = decorations.find().filter(function (_ref5) {
125
132
  var spec = _ref5.spec;
126
133
  return spec.id === 'drag-handle';
@@ -156,7 +163,15 @@ export var createPlugin = function createPlugin(api, getIntl) {
156
163
 
157
164
  // Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
158
165
  if (redrawDecorations && !isResizerResizing && api) {
159
- decorations = DecorationSet.create(newState.doc, []);
166
+ if (fg('platform_editor_elements_drag_and_drop_ed_24000')) {
167
+ var oldNodeDecs = decorations.find().filter(function (_ref8) {
168
+ var spec = _ref8.spec;
169
+ return spec.type !== 'drop-target-decoration';
170
+ });
171
+ decorations = decorations.remove(oldNodeDecs);
172
+ } else {
173
+ decorations = DecorationSet.create(newState.doc, []);
174
+ }
160
175
  var nodeDecs = nodeDecorations(newState);
161
176
  if (fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2')) {
162
177
  decorations = decorations.add(newState.doc, _toConsumableArray(nodeDecs));
@@ -173,7 +188,9 @@ export var createPlugin = function createPlugin(api, getIntl) {
173
188
 
174
189
  // When a node type changed to be nested inside another node, the position of the active node is off by 1
175
190
  // This is a workaround to fix the position of the active node when it is nested
176
- if (mappedPosisiton === prevMappedPos + 1) {
191
+
192
+ var shouldUpdateNestedPosition = fg('platform_editor_element_drag_and_drop_ed_24049') ? tr.docChanged && !nodeCountChanged : true;
193
+ if (shouldUpdateNestedPosition && mappedPosisiton === prevMappedPos + 1) {
177
194
  mappedPosisiton = prevMappedPos;
178
195
  }
179
196
  var newActiveNode = tr.doc.nodeAt(mappedPosisiton);
@@ -188,31 +205,31 @@ export var createPlugin = function createPlugin(api, getIntl) {
188
205
  anchorName: anchorName
189
206
  };
190
207
  }
191
- var draghandleDec = dragHandleDecoration(activeNode.pos, anchorName, nodeType, api, getIntl);
208
+ var draghandleDec = dragHandleDecoration(api, getIntl, activeNode.pos, anchorName, nodeType);
192
209
  decorations = decorations.add(newState.doc, [draghandleDec]);
193
210
  }
194
211
  }
195
212
 
196
213
  // Remove previous drag handle widget and draw new drag handle widget when activeNode changes
197
- if (meta !== null && meta !== void 0 && meta.activeNode && (meta === null || meta === void 0 ? void 0 : meta.activeNode.pos) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) && (meta === null || meta === void 0 ? void 0 : meta.activeNode.anchorName) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName) && api) {
198
- var _oldHandle = decorations.find().filter(function (_ref8) {
199
- var spec = _ref8.spec;
214
+ if (api && meta !== null && meta !== void 0 && meta.activeNode && ((meta === null || meta === void 0 ? void 0 : meta.activeNode.pos) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) && (meta === null || meta === void 0 ? void 0 : meta.activeNode.anchorName) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName) || meta !== null && meta !== void 0 && (_meta$activeNode$hand = meta.activeNode.handleOptions) !== null && _meta$activeNode$hand !== void 0 && _meta$activeNode$hand.isFocused)) {
215
+ var _oldHandle = decorations.find().filter(function (_ref9) {
216
+ var spec = _ref9.spec;
200
217
  return spec.id === 'drag-handle';
201
218
  });
202
219
  decorations = decorations.remove(_oldHandle);
203
- var decs = dragHandleDecoration(meta.activeNode.pos, meta.activeNode.anchorName, meta.activeNode.nodeType, api, getIntl);
220
+ var decs = dragHandleDecoration(api, getIntl, meta.activeNode.pos, meta.activeNode.anchorName, meta.activeNode.nodeType, meta.activeNode.handleOptions);
204
221
  decorations = decorations.add(newState.doc, [decs]);
205
222
  }
206
223
  if (fg('platform.editor.elements.drag-and-drop-ed-23816')) {
207
224
  var _activeNodeWithNewNod;
208
225
  // Remove previous drag handle widget and draw new drag handle widget when node type changes
209
226
  if (activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
210
- var _oldHandle2 = decorations.find().filter(function (_ref9) {
211
- var spec = _ref9.spec;
227
+ var _oldHandle2 = decorations.find().filter(function (_ref10) {
228
+ var spec = _ref10.spec;
212
229
  return spec.id === 'drag-handle';
213
230
  });
214
231
  decorations = decorations.remove(_oldHandle2);
215
- var _decs = dragHandleDecoration(activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType, api, getIntl);
232
+ var _decs = dragHandleDecoration(api, getIntl, activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType);
216
233
  decorations = decorations.add(newState.doc, [_decs]);
217
234
  }
218
235
  }
@@ -228,8 +245,8 @@ export var createPlugin = function createPlugin(api, getIntl) {
228
245
 
229
246
  // Remove drop target decoration when dragging stops
230
247
  if ((meta === null || meta === void 0 ? void 0 : meta.isDragging) === false && !tr.docChanged) {
231
- var dropTargetDecs = decorations.find().filter(function (_ref10) {
232
- var spec = _ref10.spec;
248
+ var dropTargetDecs = decorations.find().filter(function (_ref11) {
249
+ var spec = _ref11.spec;
233
250
  return spec.type === 'drop-target-decoration';
234
251
  });
235
252
  decorations = decorations.remove(dropTargetDecs);
@@ -237,9 +254,9 @@ export var createPlugin = function createPlugin(api, getIntl) {
237
254
 
238
255
  // Map drop target decoration positions when the document changes
239
256
  if (tr.docChanged && isDragging) {
240
- decorationState = decorationState.map(function (_ref11) {
241
- var index = _ref11.index,
242
- pos = _ref11.pos;
257
+ decorationState = decorationState.map(function (_ref12) {
258
+ var index = _ref12.index,
259
+ pos = _ref12.pos;
243
260
  return {
244
261
  index: index,
245
262
  pos: tr.mapping.map(pos)
@@ -252,8 +269,8 @@ export var createPlugin = function createPlugin(api, getIntl) {
252
269
  decorations = decorations.map(tr.mapping, tr.doc);
253
270
  }
254
271
  var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
255
- var hasNodeDecoration = decorations.find().some(function (_ref12) {
256
- var spec = _ref12.spec;
272
+ var hasNodeDecoration = decorations.find().some(function (_ref13) {
273
+ var spec = _ref13.spec;
257
274
  return spec.type === 'node-decoration';
258
275
  });
259
276
  if (!hasNodeDecoration && isEmptyDoc) {
@@ -372,6 +389,15 @@ export var createPlugin = function createPlugin(api, getIntl) {
372
389
  return true;
373
390
  }
374
391
  }
392
+
393
+ //NOTE: altKey === 'option' on MacOS
394
+ if (event.altKey && event.shiftKey && event.ctrlKey && fg('platform_editor_element_drag_and_drop_ed_23873')) {
395
+ //prevent holding down key combo from firing repeatedly
396
+ if (!event.repeat && boundKeydownHandler(api)(view, event)) {
397
+ event.preventDefault();
398
+ return true;
399
+ }
400
+ }
375
401
  return false;
376
402
  }
377
403
  }
@@ -384,7 +410,8 @@ export var createPlugin = function createPlugin(api, getIntl) {
384
410
  if (!fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2')) {
385
411
  // Use ResizeObserver to observe height changes
386
412
  resizeObserverHeight = new ResizeObserver(rafSchedule(function (entries) {
387
- var editorHeight = entries[0].contentBoxSize[0].blockSize;
413
+ var _entries$;
414
+ var editorHeight = (_entries$ = entries[0]) === null || _entries$ === void 0 || (_entries$ = _entries$.contentBoxSize[0]) === null || _entries$ === void 0 ? void 0 : _entries$.blockSize;
388
415
 
389
416
  // Update the plugin state when the height changes
390
417
  var pluginState = key.getState(editorView.state);
@@ -394,7 +421,7 @@ export var createPlugin = function createPlugin(api, getIntl) {
394
421
  if ((pluginState === null || pluginState === void 0 ? void 0 : pluginState.isResizerResizing) !== isResizerResizing) {
395
422
  transaction.setMeta('is-resizer-resizing', isResizerResizing);
396
423
  }
397
- if (!isResizerResizing) {
424
+ if (!isResizerResizing && editorHeight) {
398
425
  transaction.setMeta(key, {
399
426
  editorHeight: editorHeight
400
427
  });
@@ -1,7 +1,6 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  /** @jsx jsx */
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
-
5
4
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
6
5
  import { css, jsx } from '@emotion/react';
7
6
  import { injectIntl } from 'react-intl-next';
@@ -40,11 +39,15 @@ var dragHandleButtonStyles = css({
40
39
  cursor: 'grab',
41
40
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
42
41
  zIndex: DRAG_HANDLE_ZINDEX,
42
+ outline: 'none',
43
43
  '&:hover': {
44
44
  backgroundColor: "var(--ds-background-neutral-subtle-hovered, #091E420F)"
45
45
  },
46
46
  '&:active': {
47
47
  backgroundColor: "var(--ds-background-neutral-subtle-pressed, #091E4224)"
48
+ },
49
+ '&:focus': {
50
+ outline: "2px solid ".concat("var(--ds-border-focused, #388BFF)")
48
51
  }
49
52
  });
50
53
  var selectedStyles = css({
@@ -57,7 +60,8 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
57
60
  getPos = _ref.getPos,
58
61
  anchorName = _ref.anchorName,
59
62
  nodeType = _ref.nodeType,
60
- formatMessage = _ref.intl.formatMessage;
63
+ formatMessage = _ref.intl.formatMessage,
64
+ handleOptions = _ref.handleOptions;
61
65
  var start = getPos();
62
66
  var buttonRef = useRef(null);
63
67
  var _useState = useState(768),
@@ -160,6 +164,34 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
160
164
  return tr;
161
165
  });
162
166
  }, [start, api]);
167
+ var handleKeyDown = useCallback(function (e) {
168
+ if (fg('platform_editor_element_drag_and_drop_ed_23873')) {
169
+ // allow user to use spacebar to select the node
170
+ if (!e.repeat && e.key === ' ') {
171
+ var _api$core4;
172
+ api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref5) {
173
+ var tr = _ref5.tr;
174
+ if (start === undefined) {
175
+ return tr;
176
+ }
177
+ var node = tr.doc.nodeAt(start);
178
+ if (!node) {
179
+ return tr;
180
+ }
181
+ var $startPos = tr.doc.resolve(start + node.nodeSize);
182
+ var selection = new TextSelection($startPos);
183
+ tr.setSelection(selection);
184
+ tr.setMeta(key, {
185
+ pos: start
186
+ });
187
+ return tr;
188
+ });
189
+ } else {
190
+ // return focus to editor to resume editing from caret positon
191
+ view.focus();
192
+ }
193
+ }
194
+ }, [start, api, view]);
163
195
  useEffect(function () {
164
196
  var element = buttonRef.current;
165
197
  if (!element) {
@@ -173,11 +205,11 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
173
205
  start: start
174
206
  };
175
207
  },
176
- onGenerateDragPreview: function onGenerateDragPreview(_ref5) {
177
- var nativeSetDragImage = _ref5.nativeSetDragImage;
208
+ onGenerateDragPreview: function onGenerateDragPreview(_ref6) {
209
+ var nativeSetDragImage = _ref6.nativeSetDragImage;
178
210
  setCustomNativeDragPreview({
179
- render: function render(_ref6) {
180
- var container = _ref6.container;
211
+ render: function render(_ref7) {
212
+ var container = _ref7.container;
181
213
  var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(anchorName, "\"]"));
182
214
  if (!dom) {
183
215
  return;
@@ -188,13 +220,13 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
188
220
  });
189
221
  },
190
222
  onDragStart: function onDragStart() {
191
- var _api$core4;
223
+ var _api$core5;
192
224
  if (start === undefined) {
193
225
  return;
194
226
  }
195
- api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref7) {
227
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(function (_ref8) {
196
228
  var _api$blockControls, _api$analytics2;
197
- var tr = _ref7.tr;
229
+ var tr = _ref8.tr;
198
230
  api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || _api$blockControls.commands.setNodeDragged(start, anchorName, nodeType)({
199
231
  tr: tr
200
232
  });
@@ -252,6 +284,18 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
252
284
  top: fg('platform_editor_elements_dnd_ed_23674') ? getTopPosition(dom, nodeType) : getTopPosition(dom)
253
285
  };
254
286
  }, [anchorName, nodeType, view, blockCardWidth, macroInteractionUpdates]);
287
+ useEffect(function () {
288
+ if (handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && buttonRef.current && fg('platform_editor_element_drag_and_drop_ed_23873')) {
289
+ var id = requestAnimationFrame(function () {
290
+ var _buttonRef$current;
291
+ (_buttonRef$current = buttonRef.current) === null || _buttonRef$current === void 0 || _buttonRef$current.focus();
292
+ });
293
+ return function () {
294
+ cancelAnimationFrame(id);
295
+ view.focus();
296
+ };
297
+ }
298
+ }, [buttonRef, handleOptions === null || handleOptions === void 0 ? void 0 : handleOptions.isFocused, view]);
255
299
  var helpDescriptors = [{
256
300
  description: formatMessage(blockControlsMessages.dragToMove)
257
301
  }, {
@@ -271,6 +315,7 @@ var DragHandleInternal = function DragHandleInternal(_ref) {
271
315
  style: positionStyles,
272
316
  onClick: handleOnClick,
273
317
  onMouseDown: fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2') ? handleMouseDownWrapperRemoved : handleMouseDown,
318
+ onKeyDown: handleKeyDown,
274
319
  "data-testid": "block-ctrl-drag-handle"
275
320
  }, jsx(DragHandlerIcon, {
276
321
  label: "",
@@ -0,0 +1,3 @@
1
+ import type { Command, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import type { BlockControlsPlugin } from '../types';
3
+ export declare const showDragHandleAtSelection: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => Command;
@@ -1,2 +1,2 @@
1
1
  export { blockControlsPlugin } from './plugin';
2
- export type { BlockControlsPlugin, DecorationState, BlockControlsSharedState } from './types';
2
+ export type { BlockControlsPlugin, DecorationState, BlockControlsSharedState, HandleOptions, } from './types';
@@ -2,7 +2,7 @@ import { type IntlShape } from 'react-intl-next';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
4
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
5
- import type { BlockControlsPlugin } from '../types';
5
+ import type { BlockControlsPlugin, HandleOptions } from '../types';
6
6
  export declare const dropTargetDecorations: (oldState: EditorState, newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>) => {
7
7
  decs: Decoration[];
8
8
  decorationState: {
@@ -18,4 +18,4 @@ export declare const nodeDecorations: (newState: EditorState) => Decoration[];
18
18
  * And show the drag handle
19
19
  */
20
20
  export declare const mouseMoveWrapperDecorations: (newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>) => Decoration[];
21
- export declare const dragHandleDecoration: (pos: number, anchorName: string, nodeType: string, api: ExtractInjectionAPI<BlockControlsPlugin>, getIntl: () => IntlShape) => Decoration;
21
+ export declare const dragHandleDecoration: (api: ExtractInjectionAPI<BlockControlsPlugin>, getIntl: () => IntlShape, pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => Decoration;
@@ -0,0 +1,3 @@
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import type { BlockControlsPlugin } from '../types';
3
+ export declare const boundKeydownHandler: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => (view: import("prosemirror-view").EditorView, event: KeyboardEvent) => boolean;
@@ -35,6 +35,9 @@ export type BlockControlsSharedState = {
35
35
  isDragging: boolean;
36
36
  isPMDragging: boolean;
37
37
  } | undefined;
38
+ export type HandleOptions = {
39
+ isFocused: boolean;
40
+ } | undefined;
38
41
  export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
39
42
  dependencies: [
40
43
  OptionalPlugin<EditorDisabledPlugin>,
@@ -45,7 +48,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
45
48
  sharedState: BlockControlsSharedState;
46
49
  commands: {
47
50
  moveNode: (start: number, to: number) => EditorCommand;
48
- showDragHandleAt: (pos: number, anchorName: string, nodeType: string) => EditorCommand;
51
+ showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
49
52
  setNodeDragged: (posNumber: number, anchorName: string, nodeType: string) => EditorCommand;
50
53
  };
51
54
  }>;
@@ -2,13 +2,14 @@
2
2
  import { type WrappedComponentProps } from 'react-intl-next';
3
3
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
- import type { BlockControlsPlugin } from '../types';
5
+ import type { BlockControlsPlugin, HandleOptions } from '../types';
6
6
  export declare const DragHandle: import("react").FC<import("react-intl-next").WithIntlProps<{
7
7
  view: EditorView;
8
8
  api: ExtractInjectionAPI<BlockControlsPlugin> | undefined;
9
9
  getPos: () => number | undefined;
10
10
  anchorName: string;
11
11
  nodeType: string;
12
+ handleOptions?: HandleOptions;
12
13
  } & WrappedComponentProps>> & {
13
14
  WrappedComponent: import("react").ComponentType<{
14
15
  view: EditorView;
@@ -16,5 +17,6 @@ export declare const DragHandle: import("react").FC<import("react-intl-next").Wi
16
17
  getPos: () => number | undefined;
17
18
  anchorName: string;
18
19
  nodeType: string;
20
+ handleOptions?: HandleOptions;
19
21
  } & WrappedComponentProps>;
20
22
  };
@@ -0,0 +1,3 @@
1
+ import type { Command, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import type { BlockControlsPlugin } from '../types';
3
+ export declare const showDragHandleAtSelection: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => Command;
@@ -1,2 +1,2 @@
1
1
  export { blockControlsPlugin } from './plugin';
2
- export type { BlockControlsPlugin, DecorationState, BlockControlsSharedState } from './types';
2
+ export type { BlockControlsPlugin, DecorationState, BlockControlsSharedState, HandleOptions, } from './types';
@@ -2,7 +2,7 @@ import { type IntlShape } from 'react-intl-next';
2
2
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
4
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
5
- import type { BlockControlsPlugin } from '../types';
5
+ import type { BlockControlsPlugin, HandleOptions } from '../types';
6
6
  export declare const dropTargetDecorations: (oldState: EditorState, newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>) => {
7
7
  decs: Decoration[];
8
8
  decorationState: {
@@ -18,4 +18,4 @@ export declare const nodeDecorations: (newState: EditorState) => Decoration[];
18
18
  * And show the drag handle
19
19
  */
20
20
  export declare const mouseMoveWrapperDecorations: (newState: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>) => Decoration[];
21
- export declare const dragHandleDecoration: (pos: number, anchorName: string, nodeType: string, api: ExtractInjectionAPI<BlockControlsPlugin>, getIntl: () => IntlShape) => Decoration;
21
+ export declare const dragHandleDecoration: (api: ExtractInjectionAPI<BlockControlsPlugin>, getIntl: () => IntlShape, pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => Decoration;
@@ -0,0 +1,3 @@
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import type { BlockControlsPlugin } from '../types';
3
+ export declare const boundKeydownHandler: (api?: ExtractInjectionAPI<BlockControlsPlugin>) => (view: import("prosemirror-view").EditorView, event: KeyboardEvent) => boolean;
@@ -35,6 +35,9 @@ export type BlockControlsSharedState = {
35
35
  isDragging: boolean;
36
36
  isPMDragging: boolean;
37
37
  } | undefined;
38
+ export type HandleOptions = {
39
+ isFocused: boolean;
40
+ } | undefined;
38
41
  export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
39
42
  dependencies: [
40
43
  OptionalPlugin<EditorDisabledPlugin>,
@@ -45,7 +48,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
45
48
  sharedState: BlockControlsSharedState;
46
49
  commands: {
47
50
  moveNode: (start: number, to: number) => EditorCommand;
48
- showDragHandleAt: (pos: number, anchorName: string, nodeType: string) => EditorCommand;
51
+ showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
49
52
  setNodeDragged: (posNumber: number, anchorName: string, nodeType: string) => EditorCommand;
50
53
  };
51
54
  }>;
@@ -2,13 +2,14 @@
2
2
  import { type WrappedComponentProps } from 'react-intl-next';
3
3
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
- import type { BlockControlsPlugin } from '../types';
5
+ import type { BlockControlsPlugin, HandleOptions } from '../types';
6
6
  export declare const DragHandle: import("react").FC<import("react-intl-next").WithIntlProps<{
7
7
  view: EditorView;
8
8
  api: ExtractInjectionAPI<BlockControlsPlugin> | undefined;
9
9
  getPos: () => number | undefined;
10
10
  anchorName: string;
11
11
  nodeType: string;
12
+ handleOptions?: HandleOptions;
12
13
  } & WrappedComponentProps>> & {
13
14
  WrappedComponent: import("react").ComponentType<{
14
15
  view: EditorView;
@@ -16,5 +17,6 @@ export declare const DragHandle: import("react").FC<import("react-intl-next").Wi
16
17
  getPos: () => number | undefined;
17
18
  anchorName: string;
18
19
  nodeType: string;
20
+ handleOptions?: HandleOptions;
19
21
  } & WrappedComponentProps>;
20
22
  };