@atlaskit/editor-plugin-block-controls 1.5.17 → 1.5.19
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 +24 -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 +9 -3
- 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 +100 -12
- package/dist/es2019/commands/show-drag-handle.js +16 -0
- package/dist/es2019/plugin.js +3 -2
- package/dist/es2019/pm-plugins/decorations.js +9 -3
- 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 +93 -8
- package/dist/esm/commands/show-drag-handle.js +18 -0
- package/dist/esm/plugin.js +3 -2
- package/dist/esm/pm-plugins/decorations.js +9 -3
- 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 +100 -13
- 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 +11 -2
|
@@ -11,6 +11,7 @@ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
|
|
11
11
|
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
12
12
|
import { dragHandleDecoration, dropTargetDecorations, emptyParagraphNodeDecorations, mouseMoveWrapperDecorations, nodeDecorations } from './decorations';
|
|
13
13
|
import { handleMouseOver } from './handle-mouse-over';
|
|
14
|
+
import { boundKeydownHandler } from './keymap';
|
|
14
15
|
export const key = new PluginKey('blockControls');
|
|
15
16
|
const destroyFn = api => {
|
|
16
17
|
const scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
|
|
@@ -86,7 +87,7 @@ export const createPlugin = (api, getIntl) => {
|
|
|
86
87
|
return initialState;
|
|
87
88
|
},
|
|
88
89
|
apply(tr, currentState, oldState, newState) {
|
|
89
|
-
var _meta$activeNode, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
|
|
90
|
+
var _meta$activeNode, _meta$activeNode$hand, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
|
|
90
91
|
if (initialState.isDocSizeLimitEnabled === null) {
|
|
91
92
|
if (fg('platform.editor.elements.drag-and-drop-doc-size-limit_7k4vq')) {
|
|
92
93
|
initialState.isDocSizeLimitEnabled = true;
|
|
@@ -119,9 +120,15 @@ export const createPlugin = (api, getIntl) => {
|
|
|
119
120
|
const resizerMeta = tr.getMeta('is-resizer-resizing');
|
|
120
121
|
isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
|
|
121
122
|
const nodeCountChanged = oldState.doc.childCount !== newState.doc.childCount;
|
|
123
|
+
let shouldRemoveHandle = true;
|
|
124
|
+
if (fg('platform_editor_elements_drag_and_drop_ed_24000')) {
|
|
125
|
+
shouldRemoveHandle = !tr.getMeta('isRemote');
|
|
126
|
+
}
|
|
122
127
|
|
|
123
|
-
// During resize, remove the drag handle widget
|
|
124
|
-
|
|
128
|
+
// During resize, remove the drag handle widget so its dom positioning doesn't need to be maintained
|
|
129
|
+
// Also remove the handle when the node is moved or the node count changes. This helps prevent incorrect positioning
|
|
130
|
+
// Don't remove the handle if remote changes are changing the node count, its prosemirror position can be mapped instead
|
|
131
|
+
if (isResizerResizing || nodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
|
|
125
132
|
const oldHandle = decorations.find().filter(({
|
|
126
133
|
spec
|
|
127
134
|
}) => spec.id === 'drag-handle');
|
|
@@ -154,7 +161,14 @@ export const createPlugin = (api, getIntl) => {
|
|
|
154
161
|
|
|
155
162
|
// Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
|
|
156
163
|
if (redrawDecorations && !isResizerResizing && api) {
|
|
157
|
-
|
|
164
|
+
if (fg('platform_editor_elements_drag_and_drop_ed_24000')) {
|
|
165
|
+
const oldNodeDecs = decorations.find().filter(({
|
|
166
|
+
spec
|
|
167
|
+
}) => spec.type !== 'drop-target-decoration');
|
|
168
|
+
decorations = decorations.remove(oldNodeDecs);
|
|
169
|
+
} else {
|
|
170
|
+
decorations = DecorationSet.create(newState.doc, []);
|
|
171
|
+
}
|
|
158
172
|
const nodeDecs = nodeDecorations(newState);
|
|
159
173
|
if (fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2')) {
|
|
160
174
|
decorations = decorations.add(newState.doc, [...nodeDecs]);
|
|
@@ -171,7 +185,9 @@ export const createPlugin = (api, getIntl) => {
|
|
|
171
185
|
|
|
172
186
|
// When a node type changed to be nested inside another node, the position of the active node is off by 1
|
|
173
187
|
// This is a workaround to fix the position of the active node when it is nested
|
|
174
|
-
|
|
188
|
+
|
|
189
|
+
const shouldUpdateNestedPosition = fg('platform_editor_element_drag_and_drop_ed_24049') ? tr.docChanged && !nodeCountChanged : true;
|
|
190
|
+
if (shouldUpdateNestedPosition && mappedPosisiton === prevMappedPos + 1) {
|
|
175
191
|
mappedPosisiton = prevMappedPos;
|
|
176
192
|
}
|
|
177
193
|
const newActiveNode = tr.doc.nodeAt(mappedPosisiton);
|
|
@@ -186,18 +202,18 @@ export const createPlugin = (api, getIntl) => {
|
|
|
186
202
|
anchorName
|
|
187
203
|
};
|
|
188
204
|
}
|
|
189
|
-
const draghandleDec = dragHandleDecoration(activeNode.pos, anchorName, nodeType
|
|
205
|
+
const draghandleDec = dragHandleDecoration(api, getIntl, activeNode.pos, anchorName, nodeType);
|
|
190
206
|
decorations = decorations.add(newState.doc, [draghandleDec]);
|
|
191
207
|
}
|
|
192
208
|
}
|
|
193
209
|
|
|
194
210
|
// Remove previous drag handle widget and draw new drag handle widget when activeNode changes
|
|
195
|
-
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) &&
|
|
211
|
+
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)) {
|
|
196
212
|
const oldHandle = decorations.find().filter(({
|
|
197
213
|
spec
|
|
198
214
|
}) => spec.id === 'drag-handle');
|
|
199
215
|
decorations = decorations.remove(oldHandle);
|
|
200
|
-
const decs = dragHandleDecoration(meta.activeNode.pos, meta.activeNode.anchorName, meta.activeNode.nodeType,
|
|
216
|
+
const decs = dragHandleDecoration(api, getIntl, meta.activeNode.pos, meta.activeNode.anchorName, meta.activeNode.nodeType, meta.activeNode.handleOptions);
|
|
201
217
|
decorations = decorations.add(newState.doc, [decs]);
|
|
202
218
|
}
|
|
203
219
|
if (fg('platform.editor.elements.drag-and-drop-ed-23816')) {
|
|
@@ -208,7 +224,7 @@ export const createPlugin = (api, getIntl) => {
|
|
|
208
224
|
spec
|
|
209
225
|
}) => spec.id === 'drag-handle');
|
|
210
226
|
decorations = decorations.remove(oldHandle);
|
|
211
|
-
const decs = dragHandleDecoration(activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType
|
|
227
|
+
const decs = dragHandleDecoration(api, getIntl, activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType);
|
|
212
228
|
decorations = decorations.add(newState.doc, [decs]);
|
|
213
229
|
}
|
|
214
230
|
}
|
|
@@ -373,6 +389,15 @@ export const createPlugin = (api, getIntl) => {
|
|
|
373
389
|
return true;
|
|
374
390
|
}
|
|
375
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
|
+
}
|
|
376
401
|
return false;
|
|
377
402
|
}
|
|
378
403
|
}
|
|
@@ -385,7 +410,8 @@ export const createPlugin = (api, getIntl) => {
|
|
|
385
410
|
if (!fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2')) {
|
|
386
411
|
// Use ResizeObserver to observe height changes
|
|
387
412
|
resizeObserverHeight = new ResizeObserver(rafSchedule(entries => {
|
|
388
|
-
|
|
413
|
+
var _entries$, _entries$$contentBoxS;
|
|
414
|
+
const editorHeight = (_entries$ = entries[0]) === null || _entries$ === void 0 ? void 0 : (_entries$$contentBoxS = _entries$.contentBoxSize[0]) === null || _entries$$contentBoxS === void 0 ? void 0 : _entries$$contentBoxS.blockSize;
|
|
389
415
|
|
|
390
416
|
// Update the plugin state when the height changes
|
|
391
417
|
const pluginState = key.getState(editorView.state);
|
|
@@ -395,7 +421,7 @@ export const createPlugin = (api, getIntl) => {
|
|
|
395
421
|
if ((pluginState === null || pluginState === void 0 ? void 0 : pluginState.isResizerResizing) !== isResizerResizing) {
|
|
396
422
|
transaction.setMeta('is-resizer-resizing', isResizerResizing);
|
|
397
423
|
}
|
|
398
|
-
if (!isResizerResizing) {
|
|
424
|
+
if (!isResizerResizing && editorHeight) {
|
|
399
425
|
transaction.setMeta(key, {
|
|
400
426
|
editorHeight
|
|
401
427
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
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';
|
|
5
|
+
import { bind } from 'bind-event-listener';
|
|
6
6
|
import { injectIntl } from 'react-intl-next';
|
|
7
7
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
8
8
|
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
@@ -39,11 +39,15 @@ const dragHandleButtonStyles = css({
|
|
|
39
39
|
cursor: 'grab',
|
|
40
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
|
|
41
41
|
zIndex: DRAG_HANDLE_ZINDEX,
|
|
42
|
+
outline: 'none',
|
|
42
43
|
'&:hover': {
|
|
43
44
|
backgroundColor: "var(--ds-background-neutral-subtle-hovered, #091E420F)"
|
|
44
45
|
},
|
|
45
46
|
'&:active': {
|
|
46
47
|
backgroundColor: "var(--ds-background-neutral-subtle-pressed, #091E4224)"
|
|
48
|
+
},
|
|
49
|
+
'&:focus': {
|
|
50
|
+
outline: `2px solid ${"var(--ds-border-focused, #388BFF)"}`
|
|
47
51
|
}
|
|
48
52
|
});
|
|
49
53
|
const selectedStyles = css({
|
|
@@ -58,7 +62,8 @@ const DragHandleInternal = ({
|
|
|
58
62
|
nodeType,
|
|
59
63
|
intl: {
|
|
60
64
|
formatMessage
|
|
61
|
-
}
|
|
65
|
+
},
|
|
66
|
+
handleOptions
|
|
62
67
|
}) => {
|
|
63
68
|
const start = getPos();
|
|
64
69
|
const buttonRef = useRef(null);
|
|
@@ -158,6 +163,35 @@ const DragHandleInternal = ({
|
|
|
158
163
|
return tr;
|
|
159
164
|
});
|
|
160
165
|
}, [start, api]);
|
|
166
|
+
const handleKeyDown = useCallback(e => {
|
|
167
|
+
if (fg('platform_editor_element_drag_and_drop_ed_23873')) {
|
|
168
|
+
// allow user to use spacebar to select the node
|
|
169
|
+
if (!e.repeat && e.key === ' ') {
|
|
170
|
+
var _api$core4;
|
|
171
|
+
api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
|
|
172
|
+
tr
|
|
173
|
+
}) => {
|
|
174
|
+
if (start === undefined) {
|
|
175
|
+
return tr;
|
|
176
|
+
}
|
|
177
|
+
const node = tr.doc.nodeAt(start);
|
|
178
|
+
if (!node) {
|
|
179
|
+
return tr;
|
|
180
|
+
}
|
|
181
|
+
const $startPos = tr.doc.resolve(start + node.nodeSize);
|
|
182
|
+
const 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]);
|
|
161
195
|
useEffect(() => {
|
|
162
196
|
const element = buttonRef.current;
|
|
163
197
|
if (!element) {
|
|
@@ -186,11 +220,11 @@ const DragHandleInternal = ({
|
|
|
186
220
|
});
|
|
187
221
|
},
|
|
188
222
|
onDragStart() {
|
|
189
|
-
var _api$
|
|
223
|
+
var _api$core5;
|
|
190
224
|
if (start === undefined) {
|
|
191
225
|
return;
|
|
192
226
|
}
|
|
193
|
-
api === null || api === void 0 ? void 0 : (_api$
|
|
227
|
+
api === null || api === void 0 ? void 0 : (_api$core5 = api.core) === null || _api$core5 === void 0 ? void 0 : _api$core5.actions.execute(({
|
|
194
228
|
tr
|
|
195
229
|
}) => {
|
|
196
230
|
var _api$blockControls, _api$analytics2;
|
|
@@ -217,7 +251,7 @@ const DragHandleInternal = ({
|
|
|
217
251
|
});
|
|
218
252
|
}, [anchorName, api, nodeType, view, start]);
|
|
219
253
|
const macroInteractionUpdates = featureFlagsState === null || featureFlagsState === void 0 ? void 0 : featureFlagsState.macroInteractionUpdates;
|
|
220
|
-
const
|
|
254
|
+
const calculatePosition = useCallback(() => {
|
|
221
255
|
const supportsAnchor = CSS.supports('top', `anchor(${anchorName} start)`) && CSS.supports('left', `anchor(${anchorName} start)`);
|
|
222
256
|
const dom = view.dom.querySelector(`[data-drag-handler-anchor-name="${anchorName}"]`);
|
|
223
257
|
const hasResizer = nodeType === 'table' || nodeType === 'mediaSingle';
|
|
@@ -239,18 +273,68 @@ const DragHandleInternal = ({
|
|
|
239
273
|
}
|
|
240
274
|
if (supportsAnchor) {
|
|
241
275
|
return fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2') ? {
|
|
242
|
-
left: hasResizer || isExtension || isEmbedCard ? `calc(anchor(${anchorName} start) + ${getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates)})` : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
|
|
276
|
+
left: hasResizer || isExtension || isEmbedCard || isBlockCard && innerContainer ? `calc(anchor(${anchorName} start) + ${getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates)})` : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
|
|
243
277
|
top: fg('platform_editor_elements_dnd_ed_23674') ? `calc(anchor(${anchorName} start) + ${topPositionAdjustment(nodeType)}px)` : anchorName.includes('table') ? `calc(anchor(${anchorName} start) + ${DRAG_HANDLE_HEIGHT}px)` : `anchor(${anchorName} start)`
|
|
244
278
|
} : {
|
|
245
279
|
left: hasResizer || isExtension || isBlockCard || isEmbedCard ? getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates) : `calc(anchor(${anchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType)}px)`,
|
|
246
280
|
top: fg('platform_editor_elements_dnd_ed_23674') ? `calc(anchor(${anchorName} start) + ${topPositionAdjustment(nodeType)}px)` : anchorName.includes('table') ? `calc(anchor(${anchorName} start) + ${DRAG_HANDLE_HEIGHT}px)` : `anchor(${anchorName} start)`
|
|
247
281
|
};
|
|
248
282
|
}
|
|
249
|
-
return {
|
|
283
|
+
return fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2') ? {
|
|
284
|
+
left: hasResizer || isExtension || isEmbedCard || isBlockCard && innerContainer ? `calc(${(dom === null || dom === void 0 ? void 0 : dom.offsetLeft) || 0}px + ${getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates)})` : getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates),
|
|
285
|
+
top: fg('platform_editor_elements_dnd_ed_23674') ? getTopPosition(dom, nodeType) : getTopPosition(dom)
|
|
286
|
+
} : {
|
|
250
287
|
left: getLeftPosition(dom, nodeType, innerContainer, macroInteractionUpdates),
|
|
251
288
|
top: fg('platform_editor_elements_dnd_ed_23674') ? getTopPosition(dom, nodeType) : getTopPosition(dom)
|
|
252
289
|
};
|
|
253
290
|
}, [anchorName, nodeType, view, blockCardWidth, macroInteractionUpdates]);
|
|
291
|
+
const [newPositionStyles, setNewPositionStyles] = useState({
|
|
292
|
+
display: 'none'
|
|
293
|
+
});
|
|
294
|
+
useEffect(() => {
|
|
295
|
+
if (!fg('platform_editor_element_drag_and_drop_ed_23896')) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
let cleanUpTransitionListener;
|
|
299
|
+
if (nodeType === 'extension' || nodeType === 'embedCard') {
|
|
300
|
+
const dom = view.dom.querySelector(`[data-drag-handler-anchor-name="${anchorName}"]`);
|
|
301
|
+
if (!dom) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
cleanUpTransitionListener = bind(dom, {
|
|
305
|
+
type: 'transitionend',
|
|
306
|
+
listener: () => {
|
|
307
|
+
setNewPositionStyles(calculatePosition());
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
const calcPos = requestAnimationFrame(() => {
|
|
312
|
+
setNewPositionStyles(calculatePosition());
|
|
313
|
+
});
|
|
314
|
+
return () => {
|
|
315
|
+
var _cleanUpTransitionLis;
|
|
316
|
+
cancelAnimationFrame(calcPos);
|
|
317
|
+
(_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 ? void 0 : _cleanUpTransitionLis();
|
|
318
|
+
};
|
|
319
|
+
}, [calculatePosition, view.dom, anchorName, nodeType]);
|
|
320
|
+
const positionStyles = useMemo(() => {
|
|
321
|
+
if (fg('platform_editor_element_drag_and_drop_ed_23896')) {
|
|
322
|
+
return newPositionStyles;
|
|
323
|
+
}
|
|
324
|
+
return calculatePosition();
|
|
325
|
+
}, [calculatePosition, newPositionStyles]);
|
|
326
|
+
useEffect(() => {
|
|
327
|
+
if (handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && buttonRef.current && fg('platform_editor_element_drag_and_drop_ed_23873')) {
|
|
328
|
+
const id = requestAnimationFrame(() => {
|
|
329
|
+
var _buttonRef$current;
|
|
330
|
+
(_buttonRef$current = buttonRef.current) === null || _buttonRef$current === void 0 ? void 0 : _buttonRef$current.focus();
|
|
331
|
+
});
|
|
332
|
+
return () => {
|
|
333
|
+
cancelAnimationFrame(id);
|
|
334
|
+
view.focus();
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
}, [buttonRef, handleOptions === null || handleOptions === void 0 ? void 0 : handleOptions.isFocused, view]);
|
|
254
338
|
const helpDescriptors = [{
|
|
255
339
|
description: formatMessage(blockControlsMessages.dragToMove)
|
|
256
340
|
}, {
|
|
@@ -266,9 +350,10 @@ const DragHandleInternal = ({
|
|
|
266
350
|
ref: buttonRef
|
|
267
351
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
268
352
|
,
|
|
269
|
-
style: positionStyles,
|
|
353
|
+
style: fg('platform_editor_element_drag_and_drop_ed_23896') ? newPositionStyles : positionStyles,
|
|
270
354
|
onClick: handleOnClick,
|
|
271
355
|
onMouseDown: fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2') ? handleMouseDownWrapperRemoved : handleMouseDown,
|
|
356
|
+
onKeyDown: handleKeyDown,
|
|
272
357
|
"data-testid": "block-ctrl-drag-handle"
|
|
273
358
|
}, jsx(DragHandlerIcon, {
|
|
274
359
|
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,13 +129,16 @@ 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
|
|
136
136
|
element.style.display = 'inline';
|
|
137
137
|
element.setAttribute('data-testid', 'block-ctrl-decorator-widget');
|
|
138
138
|
element.setAttribute('data-blocks-drag-handle-container', 'true');
|
|
139
|
+
if (fg('platform_editor_element_drag_and_drop_ed_23896')) {
|
|
140
|
+
unmountDecorations('data-blocks-drag-handle-container');
|
|
141
|
+
}
|
|
139
142
|
if (fg('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2')) {
|
|
140
143
|
// There are times when global clear: "both" styles are applied to this decoration causing jumpiness
|
|
141
144
|
// due to margins applied to other nodes eg. Headings
|
|
@@ -148,14 +151,17 @@ export var dragHandleDecoration = function dragHandleDecoration(pos, anchorName,
|
|
|
148
151
|
api: api,
|
|
149
152
|
getPos: getPos,
|
|
150
153
|
anchorName: anchorName,
|
|
151
|
-
nodeType: nodeType
|
|
154
|
+
nodeType: nodeType,
|
|
155
|
+
handleOptions: handleOptions
|
|
152
156
|
})), element);
|
|
153
157
|
return element;
|
|
154
158
|
}, {
|
|
155
159
|
side: -1,
|
|
156
160
|
id: 'drag-handle',
|
|
157
161
|
destroy: function destroy(node) {
|
|
158
|
-
|
|
162
|
+
if (!fg('platform_editor_element_drag_and_drop_ed_23896')) {
|
|
163
|
+
ReactDOM.unmountComponentAtNode(node);
|
|
164
|
+
}
|
|
159
165
|
}
|
|
160
166
|
});
|
|
161
167
|
};
|
|
@@ -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
|
});
|