@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.
- package/CHANGELOG.md +15 -0
- package/dist/cjs/commands/show-drag-handle.js +24 -0
- package/dist/cjs/plugin.js +3 -2
- package/dist/cjs/pm-plugins/decorations.js +3 -2
- package/dist/cjs/pm-plugins/keymap.js +24 -0
- package/dist/cjs/pm-plugins/main.js +49 -22
- package/dist/cjs/ui/drag-handle.js +54 -8
- package/dist/es2019/commands/show-drag-handle.js +16 -0
- package/dist/es2019/plugin.js +3 -2
- package/dist/es2019/pm-plugins/decorations.js +3 -2
- package/dist/es2019/pm-plugins/keymap.js +16 -0
- package/dist/es2019/pm-plugins/main.js +37 -11
- package/dist/es2019/ui/drag-handle.js +50 -4
- package/dist/esm/commands/show-drag-handle.js +18 -0
- package/dist/esm/plugin.js +3 -2
- package/dist/esm/pm-plugins/decorations.js +3 -2
- package/dist/esm/pm-plugins/keymap.js +18 -0
- package/dist/esm/pm-plugins/main.js +49 -22
- package/dist/esm/ui/drag-handle.js +54 -9
- package/dist/types/commands/show-drag-handle.d.ts +3 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/pm-plugins/decorations.d.ts +2 -2
- package/dist/types/pm-plugins/keymap.d.ts +3 -0
- package/dist/types/types.d.ts +4 -1
- package/dist/types/ui/drag-handle.d.ts +3 -1
- package/dist/types-ts4.5/commands/show-drag-handle.d.ts +3 -0
- package/dist/types-ts4.5/index.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/decorations.d.ts +2 -2
- package/dist/types-ts4.5/pm-plugins/keymap.d.ts +3 -0
- package/dist/types-ts4.5/types.d.ts +4 -1
- package/dist/types-ts4.5/ui/drag-handle.d.ts +3 -1
- package/package.json +8 -2
|
@@ -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$
|
|
222
|
+
var _api$core5;
|
|
190
223
|
if (start === undefined) {
|
|
191
224
|
return;
|
|
192
225
|
}
|
|
193
|
-
api === null || api === void 0 ? void 0 : (_api$
|
|
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
|
+
};
|
package/dist/esm/plugin.js
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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) &&
|
|
198
|
-
var _oldHandle = decorations.find().filter(function (
|
|
199
|
-
var 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,
|
|
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 (
|
|
211
|
-
var 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
|
|
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 (
|
|
232
|
-
var 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 (
|
|
241
|
-
var index =
|
|
242
|
-
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 (
|
|
256
|
-
var 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
|
|
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(
|
|
177
|
-
var nativeSetDragImage =
|
|
208
|
+
onGenerateDragPreview: function onGenerateDragPreview(_ref6) {
|
|
209
|
+
var nativeSetDragImage = _ref6.nativeSetDragImage;
|
|
178
210
|
setCustomNativeDragPreview({
|
|
179
|
-
render: function render(
|
|
180
|
-
var 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$
|
|
223
|
+
var _api$core5;
|
|
192
224
|
if (start === undefined) {
|
|
193
225
|
return;
|
|
194
226
|
}
|
|
195
|
-
api === null || api === void 0 || (_api$
|
|
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 =
|
|
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: "",
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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,
|
|
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;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -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
|
};
|
|
@@ -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,
|
|
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
|
};
|