@atlaskit/editor-plugin-block-controls 3.1.2 → 3.1.3
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 +9 -0
- package/dist/cjs/blockControlsPlugin.js +15 -9
- package/dist/cjs/pm-plugins/decorations-quick-insert-button.js +40 -0
- package/dist/cjs/pm-plugins/handle-mouse-over.js +24 -5
- package/dist/cjs/pm-plugins/main.js +35 -6
- package/dist/cjs/pm-plugins/utils/widget-positions.js +25 -0
- package/dist/cjs/ui/block-menu.js +7 -4
- package/dist/cjs/ui/consts.js +18 -1
- package/dist/cjs/ui/drag-handle.js +5 -2
- package/dist/cjs/ui/quick-insert-button.js +164 -0
- package/dist/es2019/blockControlsPlugin.js +15 -9
- package/dist/es2019/pm-plugins/decorations-quick-insert-button.js +29 -0
- package/dist/es2019/pm-plugins/handle-mouse-over.js +24 -5
- package/dist/es2019/pm-plugins/main.js +35 -7
- package/dist/es2019/pm-plugins/utils/widget-positions.js +20 -0
- package/dist/es2019/ui/block-menu.js +7 -4
- package/dist/es2019/ui/consts.js +17 -0
- package/dist/es2019/ui/drag-handle.js +5 -2
- package/dist/es2019/ui/quick-insert-button.js +152 -0
- package/dist/esm/blockControlsPlugin.js +15 -9
- package/dist/esm/pm-plugins/decorations-quick-insert-button.js +33 -0
- package/dist/esm/pm-plugins/handle-mouse-over.js +24 -5
- package/dist/esm/pm-plugins/main.js +35 -6
- package/dist/esm/pm-plugins/utils/widget-positions.js +20 -0
- package/dist/esm/ui/block-menu.js +7 -4
- package/dist/esm/ui/consts.js +17 -0
- package/dist/esm/ui/drag-handle.js +5 -2
- package/dist/esm/ui/quick-insert-button.js +154 -0
- package/dist/types/blockControlsPluginType.d.ts +7 -1
- package/dist/types/pm-plugins/decorations-quick-insert-button.d.ts +7 -0
- package/dist/types/pm-plugins/main.d.ts +1 -0
- package/dist/types/pm-plugins/utils/widget-positions.d.ts +4 -0
- package/dist/types/ui/consts.d.ts +7 -0
- package/dist/types/ui/quick-insert-button.d.ts +17 -0
- package/dist/types-ts4.5/blockControlsPluginType.d.ts +7 -1
- package/dist/types-ts4.5/pm-plugins/decorations-quick-insert-button.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/utils/widget-positions.d.ts +4 -0
- package/dist/types-ts4.5/ui/consts.d.ts +7 -0
- package/dist/types-ts4.5/ui/quick-insert-button.d.ts +17 -0
- package/package.json +2 -2
|
@@ -21,6 +21,7 @@ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
|
21
21
|
import { findNodeDecs, nodeDecorations } from './decorations-anchor';
|
|
22
22
|
import { dragHandleDecoration, emptyParagraphNodeDecorations, findHandleDec } from './decorations-drag-handle';
|
|
23
23
|
import { dropTargetDecorations, findDropTargetDecs } from './decorations-drop-target';
|
|
24
|
+
import { findQuickInsertInsertButtonDecoration, quickInsertButtonDecoration } from './decorations-quick-insert-button';
|
|
24
25
|
import { handleMouseOver } from './handle-mouse-over';
|
|
25
26
|
import { boundKeydownHandler } from './keymap';
|
|
26
27
|
import { defaultActiveAnchorTracker } from './utils/active-anchor-tracker';
|
|
@@ -150,7 +151,7 @@ export var getDecorations = function getDecorations(state) {
|
|
|
150
151
|
return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
|
|
151
152
|
};
|
|
152
153
|
export var newApply = function newApply(api, formatMessage, tr, currentState, newState, flags, nodeViewPortalProviderAPI, anchorRectCache) {
|
|
153
|
-
var _meta$multiSelectDnD, _meta$activeNode, _activeNode, _activeNode2, _meta$activeNode$hand, _meta$isDragging, _meta$isDragging2, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging, _meta$isShiftDown;
|
|
154
|
+
var _meta$multiSelectDnD, _meta$activeNode, _activeNode, _activeNode2, _meta$activeNode$hand, _meta$isDragging, _meta$isDragging2, _meta$toggleMenu, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging, _meta$isShiftDown;
|
|
154
155
|
var activeNode = currentState.activeNode,
|
|
155
156
|
decorations = currentState.decorations,
|
|
156
157
|
isResizerResizing = currentState.isResizerResizing,
|
|
@@ -160,6 +161,7 @@ export var newApply = function newApply(api, formatMessage, tr, currentState, ne
|
|
|
160
161
|
editorWidthRight = currentState.editorWidthRight,
|
|
161
162
|
isDragging = currentState.isDragging,
|
|
162
163
|
isMenuOpen = currentState.isMenuOpen,
|
|
164
|
+
menuTriggerBy = currentState.menuTriggerBy,
|
|
163
165
|
isPMDragging = currentState.isPMDragging,
|
|
164
166
|
isShiftDown = currentState.isShiftDown;
|
|
165
167
|
var isActiveNodeDeleted = false;
|
|
@@ -173,7 +175,10 @@ export var newApply = function newApply(api, formatMessage, tr, currentState, ne
|
|
|
173
175
|
activeNode = {
|
|
174
176
|
pos: mappedPos.pos,
|
|
175
177
|
anchorName: activeNode.anchorName,
|
|
176
|
-
nodeType: activeNode.nodeType
|
|
178
|
+
nodeType: activeNode.nodeType,
|
|
179
|
+
rootPos: activeNode.rootPos,
|
|
180
|
+
rootAnchorName: activeNode.rootAnchorName,
|
|
181
|
+
rootNodeType: activeNode.rootNodeType
|
|
177
182
|
};
|
|
178
183
|
}
|
|
179
184
|
if (multiSelectDnD && flags.isMultiSelectEnabled) {
|
|
@@ -245,12 +250,25 @@ export var newApply = function newApply(api, formatMessage, tr, currentState, ne
|
|
|
245
250
|
var _activeNode3, _activeNode4;
|
|
246
251
|
var oldHandle = findHandleDec(decorations, (_activeNode3 = activeNode) === null || _activeNode3 === void 0 ? void 0 : _activeNode3.pos, (_activeNode4 = activeNode) === null || _activeNode4 === void 0 ? void 0 : _activeNode4.pos);
|
|
247
252
|
decorations = decorations.remove(oldHandle);
|
|
253
|
+
if (editorExperiment('platform_editor_controls', 'variant1')) {
|
|
254
|
+
var _activeNode5, _activeNode6;
|
|
255
|
+
var oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (_activeNode5 = activeNode) === null || _activeNode5 === void 0 ? void 0 : _activeNode5.rootPos, (_activeNode6 = activeNode) === null || _activeNode6 === void 0 ? void 0 : _activeNode6.rootPos);
|
|
256
|
+
decorations = decorations.remove(oldQuickInsertButton);
|
|
257
|
+
}
|
|
248
258
|
} else if (api && shouldRecreateHandle) {
|
|
249
|
-
var
|
|
250
|
-
var _oldHandle = findHandleDec(decorations, (
|
|
259
|
+
var _activeNode7, _activeNode8;
|
|
260
|
+
var _oldHandle = findHandleDec(decorations, (_activeNode7 = activeNode) === null || _activeNode7 === void 0 ? void 0 : _activeNode7.pos, (_activeNode8 = activeNode) === null || _activeNode8 === void 0 ? void 0 : _activeNode8.pos);
|
|
251
261
|
decorations = decorations.remove(_oldHandle);
|
|
252
262
|
var handleDec = dragHandleDecoration(api, formatMessage, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.anchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.nodeType, nodeViewPortalProviderAPI, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.handleOptions);
|
|
253
|
-
|
|
263
|
+
if (editorExperiment('platform_editor_controls', 'variant1')) {
|
|
264
|
+
var _activeNode9, _activeNode10;
|
|
265
|
+
var _oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (_activeNode9 = activeNode) === null || _activeNode9 === void 0 ? void 0 : _activeNode9.rootPos, (_activeNode10 = activeNode) === null || _activeNode10 === void 0 ? void 0 : _activeNode10.rootPos);
|
|
266
|
+
decorations = decorations.remove(_oldQuickInsertButton);
|
|
267
|
+
var quickInsertButton = quickInsertButtonDecoration(api, formatMessage, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootPos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.anchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.nodeType, nodeViewPortalProviderAPI, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootAnchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootNodeType);
|
|
268
|
+
decorations = decorations.add(newState.doc, [handleDec, quickInsertButton]);
|
|
269
|
+
} else {
|
|
270
|
+
decorations = decorations.add(newState.doc, [handleDec]);
|
|
271
|
+
}
|
|
254
272
|
}
|
|
255
273
|
|
|
256
274
|
// Drop targets may be missing when the node count is being changed during a drag
|
|
@@ -277,12 +295,23 @@ export var newApply = function newApply(api, formatMessage, tr, currentState, ne
|
|
|
277
295
|
}
|
|
278
296
|
}
|
|
279
297
|
var newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos).length === 0 ? null : latestActiveNode;
|
|
280
|
-
var isMenuOpenNew =
|
|
298
|
+
var isMenuOpenNew = isMenuOpen;
|
|
299
|
+
if (editorExperiment('platform_editor_controls', 'variant1')) {
|
|
300
|
+
if (meta !== null && meta !== void 0 && meta.closeMenu) {
|
|
301
|
+
isMenuOpenNew = false;
|
|
302
|
+
} else if (meta !== null && meta !== void 0 && meta.toggleMenu) {
|
|
303
|
+
var isSameAnchor = (meta === null || meta === void 0 ? void 0 : meta.toggleMenu.anchorName) === menuTriggerBy;
|
|
304
|
+
isMenuOpenNew = menuTriggerBy === undefined || isSameAnchor || !isMenuOpen && !isSameAnchor ? !isMenuOpen : isMenuOpen;
|
|
305
|
+
}
|
|
306
|
+
} else if (meta !== null && meta !== void 0 && meta.toggleMenu) {
|
|
307
|
+
isMenuOpenNew = !isMenuOpen;
|
|
308
|
+
}
|
|
281
309
|
return {
|
|
282
310
|
decorations: decorations,
|
|
283
311
|
activeNode: newActiveNode,
|
|
284
312
|
isDragging: (_meta$isDragging2 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging2 !== void 0 ? _meta$isDragging2 : isDragging,
|
|
285
313
|
isMenuOpen: isMenuOpenNew,
|
|
314
|
+
menuTriggerBy: editorExperiment('platform_editor_controls', 'variant1') ? (meta === null || meta === void 0 || (_meta$toggleMenu = meta.toggleMenu) === null || _meta$toggleMenu === void 0 ? void 0 : _meta$toggleMenu.anchorName) || menuTriggerBy : undefined,
|
|
286
315
|
editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : editorHeight,
|
|
287
316
|
editorWidthLeft: (_meta$editorWidthLeft = meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== null && _meta$editorWidthLeft !== void 0 ? _meta$editorWidthLeft : editorWidthLeft,
|
|
288
317
|
editorWidthRight: (_meta$editorWidthRigh = meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== null && _meta$editorWidthRigh !== void 0 ? _meta$editorWidthRigh : editorWidthRight,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { rootElementGap } from '../../ui/consts';
|
|
2
|
+
|
|
3
|
+
// Adapted from `src/pm-plugins/utils/drag-handle-positions.ts`
|
|
4
|
+
// CHANGES - removed parentNodeType, use only for positioning widgets for top level element
|
|
5
|
+
// CHANGES - removed layout
|
|
6
|
+
// CHANGES - added overrides for constants for widget dimensions
|
|
7
|
+
export var getLeftPositionForRootElement = function getLeftPositionForRootElement(dom, nodeType, widgetDimensions, innerContainer, macroInteractionUpdates) {
|
|
8
|
+
if (!dom) {
|
|
9
|
+
return 'auto';
|
|
10
|
+
}
|
|
11
|
+
if (!innerContainer) {
|
|
12
|
+
return "".concat(dom.offsetLeft - rootElementGap(nodeType) - widgetDimensions.width, "px");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// There is a showMacroInteractionDesignUpdates prop in extension node wrapper that can add a relative span under the top level div
|
|
16
|
+
// We need to adjust the left offset position of the drag handle to account for the relative span
|
|
17
|
+
var relativeSpan = macroInteractionUpdates ? dom.querySelector('span.relative') : null;
|
|
18
|
+
var leftAdjustment = relativeSpan ? relativeSpan.offsetLeft : 0;
|
|
19
|
+
return getComputedStyle(innerContainer).transform === 'none' ? "".concat(innerContainer.offsetLeft + leftAdjustment - rootElementGap(nodeType) - widgetDimensions.width, "px") : "".concat(innerContainer.offsetLeft + leftAdjustment - innerContainer.offsetWidth / 2 - rootElementGap(nodeType) - widgetDimensions.width, "px");
|
|
20
|
+
};
|
|
@@ -6,7 +6,6 @@ import { ArrowKeyNavigationType, DropdownMenu } from '@atlaskit/editor-common/ui
|
|
|
6
6
|
import { akEditorFloatingOverlapPanelZIndex } from '@atlaskit/editor-shared-styles';
|
|
7
7
|
import { getBlockMenuItems, menuItemsCallback } from './block-menu-items';
|
|
8
8
|
import { BLOCK_MENU_WIDTH } from './consts';
|
|
9
|
-
var dragHandleSelector = '[data-blocks-drag-handle-container="true"] button';
|
|
10
9
|
var BlockMenu = function BlockMenu(_ref) {
|
|
11
10
|
var editorView = _ref.editorView,
|
|
12
11
|
mountPoint = _ref.mountPoint,
|
|
@@ -19,7 +18,8 @@ var BlockMenu = function BlockMenu(_ref) {
|
|
|
19
18
|
if (!(blockControlsState !== null && blockControlsState !== void 0 && blockControlsState.isMenuOpen)) {
|
|
20
19
|
return null;
|
|
21
20
|
}
|
|
22
|
-
var
|
|
21
|
+
var activeNodeSelector = "[data-drag-handler-anchor-name=".concat(blockControlsState === null || blockControlsState === void 0 ? void 0 : blockControlsState.menuTriggerBy, "]");
|
|
22
|
+
var targetHandleRef = document.querySelector(activeNodeSelector);
|
|
23
23
|
var items = getBlockMenuItems(formatMessage);
|
|
24
24
|
var handleOpenChange = function handleOpenChange(payload) {
|
|
25
25
|
if (!(payload !== null && payload !== void 0 && payload.isOpen)) {
|
|
@@ -33,10 +33,13 @@ var BlockMenu = function BlockMenu(_ref) {
|
|
|
33
33
|
if (editorView) {
|
|
34
34
|
var _menuItemsCallback, _menuItemsCallback$ca;
|
|
35
35
|
(_menuItemsCallback = menuItemsCallback[item.value.name]) === null || _menuItemsCallback === void 0 || (_menuItemsCallback$ca = _menuItemsCallback.call(menuItemsCallback, api, formatMessage)) === null || _menuItemsCallback$ca === void 0 || _menuItemsCallback$ca(editorView.state, editorView.dispatch, editorView);
|
|
36
|
+
api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.toggleBlockMenu({
|
|
37
|
+
closeMenu: true
|
|
38
|
+
}));
|
|
36
39
|
}
|
|
37
40
|
};
|
|
38
41
|
return /*#__PURE__*/React.createElement(Popup, {
|
|
39
|
-
alignX: '
|
|
42
|
+
alignX: 'left',
|
|
40
43
|
alignY: 'start'
|
|
41
44
|
// Ignored via go/ees005
|
|
42
45
|
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
@@ -46,7 +49,7 @@ var BlockMenu = function BlockMenu(_ref) {
|
|
|
46
49
|
zIndex: akEditorFloatingOverlapPanelZIndex,
|
|
47
50
|
forcePlacement: true,
|
|
48
51
|
stick: true,
|
|
49
|
-
offset: [-
|
|
52
|
+
offset: [-6, 8]
|
|
50
53
|
}, /*#__PURE__*/React.createElement(DropdownMenu, {
|
|
51
54
|
mountTo: mountPoint,
|
|
52
55
|
boundariesElement: boundariesElement,
|
package/dist/esm/ui/consts.js
CHANGED
|
@@ -28,6 +28,12 @@ export var DRAG_HANDLE_PARAGRAPH_TOP_ADJUSTMENT = 2;
|
|
|
28
28
|
* so we allow for some leniency to capture them all. e.g. Table is depth 3.
|
|
29
29
|
*/
|
|
30
30
|
export var DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH = 3;
|
|
31
|
+
export var QUICK_INSERT_HEIGHT = 24;
|
|
32
|
+
export var QUICK_INSERT_WIDTH = 24;
|
|
33
|
+
export var QUICK_INSERT_DIMENSIONS = {
|
|
34
|
+
width: QUICK_INSERT_WIDTH,
|
|
35
|
+
height: QUICK_INSERT_HEIGHT
|
|
36
|
+
};
|
|
31
37
|
var nodeTypeExcludeList = ['embedCard', 'mediaSingle', 'table'];
|
|
32
38
|
export var dragHandleGap = function dragHandleGap(nodeType, parentNodeType) {
|
|
33
39
|
if (nodeType === 'layoutSection' && fg('platform_editor_advanced_layouts_post_fix_patch_2')) {
|
|
@@ -44,6 +50,17 @@ export var dragHandleGap = function dragHandleGap(nodeType, parentNodeType) {
|
|
|
44
50
|
}
|
|
45
51
|
return DRAG_HANDLE_DEFAULT_GAP;
|
|
46
52
|
};
|
|
53
|
+
|
|
54
|
+
// use for returning hap only for root level elements
|
|
55
|
+
export var rootElementGap = function rootElementGap(nodeType) {
|
|
56
|
+
if (nodeTypeExcludeList.includes(nodeType)) {
|
|
57
|
+
return DRAG_HANDLE_MAX_GAP;
|
|
58
|
+
}
|
|
59
|
+
if (nodeType === 'layoutSection') {
|
|
60
|
+
return DRAG_HANDLE_MAX_GAP + 12;
|
|
61
|
+
}
|
|
62
|
+
return DRAG_HANDLE_DEFAULT_GAP;
|
|
63
|
+
};
|
|
47
64
|
export var getNestedNodeLeftPaddingMargin = function getNestedNodeLeftPaddingMargin(nodeType) {
|
|
48
65
|
switch (nodeType) {
|
|
49
66
|
case 'bodiedExtension':
|
|
@@ -187,9 +187,12 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
187
187
|
tr = selectNode(tr, startPos, nodeType);
|
|
188
188
|
if (editorExperiment('platform_editor_controls', 'variant1')) {
|
|
189
189
|
var _api$blockControls;
|
|
190
|
-
api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || _api$blockControls.commands.toggleBlockMenu(
|
|
190
|
+
api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || _api$blockControls.commands.toggleBlockMenu({
|
|
191
|
+
anchorName: anchorName
|
|
192
|
+
})({
|
|
191
193
|
tr: tr
|
|
192
194
|
});
|
|
195
|
+
e.stopPropagation();
|
|
193
196
|
}
|
|
194
197
|
} else if (isTopLevelNode && $anchor.depth <= DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH && e.shiftKey) {
|
|
195
198
|
var _api$blockControls2;
|
|
@@ -216,7 +219,7 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
216
219
|
return tr;
|
|
217
220
|
});
|
|
218
221
|
view.focus();
|
|
219
|
-
}, [isMultiSelect, api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions, api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions, api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.commands, view, dragHandleSelected, getPos, multiSelectDnD === null || multiSelectDnD === void 0 ? void 0 : multiSelectDnD.anchor, isTopLevelNode, nodeType]);
|
|
222
|
+
}, [isMultiSelect, api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions, api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions, api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.commands, view, dragHandleSelected, getPos, multiSelectDnD === null || multiSelectDnD === void 0 ? void 0 : multiSelectDnD.anchor, isTopLevelNode, nodeType, anchorName]);
|
|
220
223
|
|
|
221
224
|
// TODO - This needs to be investigated further. Drag preview generation is not always working
|
|
222
225
|
// as expected with a node selection. This workaround sets the selection to the node on mouseDown,
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { bind } from 'bind-event-listener';
|
|
4
|
+
import { ToolTipContent } from '@atlaskit/editor-common/keymaps';
|
|
5
|
+
import { blockControlsMessages as messages } from '@atlaskit/editor-common/messages';
|
|
6
|
+
import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
|
|
7
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
8
|
+
import EditorAddIcon from '@atlaskit/icon/glyph/editor/add';
|
|
9
|
+
import { Box, Pressable, xcss } from '@atlaskit/primitives';
|
|
10
|
+
import Tooltip from '@atlaskit/tooltip';
|
|
11
|
+
import { getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
|
|
12
|
+
import { getLeftPositionForRootElement } from '../pm-plugins/utils/widget-positions';
|
|
13
|
+
import { QUICK_INSERT_DIMENSIONS, rootElementGap, topPositionAdjustment } from './consts';
|
|
14
|
+
var buttonStyles = xcss({
|
|
15
|
+
boxSizing: 'border-box',
|
|
16
|
+
display: 'flex',
|
|
17
|
+
flexDirection: 'column',
|
|
18
|
+
justifyContent: 'center',
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
height: "var(--ds-space-300, 24px)",
|
|
21
|
+
width: "var(--ds-space-300, 24px)",
|
|
22
|
+
border: 'none',
|
|
23
|
+
backgroundColor: 'color.background.neutral',
|
|
24
|
+
borderRadius: '50%',
|
|
25
|
+
color: 'color.text.accent.gray',
|
|
26
|
+
zIndex: 'card',
|
|
27
|
+
outline: 'none',
|
|
28
|
+
':hover': {
|
|
29
|
+
backgroundColor: 'color.background.neutral.hovered'
|
|
30
|
+
},
|
|
31
|
+
':active': {
|
|
32
|
+
backgroundColor: 'color.background.neutral.pressed'
|
|
33
|
+
},
|
|
34
|
+
':focus': {
|
|
35
|
+
outline: "2px solid ".concat("var(--ds-border-focused, #388BFF)")
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
var containerStaticStyles = xcss({
|
|
39
|
+
position: 'absolute',
|
|
40
|
+
zIndex: 'card'
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// TODO: Share prop types between DragHandle - generic enough to create a type for block control decoration
|
|
44
|
+
|
|
45
|
+
export var TypeAheadControl = function TypeAheadControl(_ref) {
|
|
46
|
+
var view = _ref.view,
|
|
47
|
+
api = _ref.api,
|
|
48
|
+
formatMessage = _ref.formatMessage,
|
|
49
|
+
getPos = _ref.getPos,
|
|
50
|
+
nodeType = _ref.nodeType,
|
|
51
|
+
anchorName = _ref.anchorName,
|
|
52
|
+
rootAnchorName = _ref.rootAnchorName,
|
|
53
|
+
rootNodeType = _ref.rootNodeType;
|
|
54
|
+
var macroInteractionUpdates = useSharedPluginStateSelector(api, 'featureFlags.macroInteractionUpdates');
|
|
55
|
+
var _useState = useState({}),
|
|
56
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
57
|
+
positionStyles = _useState2[0],
|
|
58
|
+
setPositionStyles = _useState2[1];
|
|
59
|
+
|
|
60
|
+
// Adapted from `src/ui/drag-handle.tsx` as positioning logic is similar
|
|
61
|
+
// CHANGES - added an offset so quick insert button can be positioned beside drag handle
|
|
62
|
+
// CHANGES - removed `editorExperiment('nested-dnd', true)` check and rootNodeType calculation
|
|
63
|
+
// CHANGES - replace anchorName with rootAnchorName
|
|
64
|
+
// CHANGES - `removed editorExperiment('advanced_layouts', true) && isLayoutColumn` checks as quick insert button will not be positioned for layout column
|
|
65
|
+
var calculatePosition = useCallback(function () {
|
|
66
|
+
var supportsAnchor = CSS.supports('top', "anchor(".concat(rootAnchorName, " start)")) && CSS.supports('left', "anchor(".concat(rootAnchorName, " start)"));
|
|
67
|
+
var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(rootAnchorName, "\"]"));
|
|
68
|
+
var hasResizer = rootNodeType === 'table' || rootNodeType === 'mediaSingle';
|
|
69
|
+
var isExtension = rootNodeType === 'extension' || rootNodeType === 'bodiedExtension';
|
|
70
|
+
var isBlockCard = rootNodeType === 'blockCard';
|
|
71
|
+
var isEmbedCard = rootNodeType === 'embedCard';
|
|
72
|
+
var isMacroInteractionUpdates = macroInteractionUpdates && isExtension;
|
|
73
|
+
var innerContainer = null;
|
|
74
|
+
if (dom) {
|
|
75
|
+
if (isEmbedCard) {
|
|
76
|
+
innerContainer = dom.querySelector('.rich-media-item');
|
|
77
|
+
} else if (hasResizer) {
|
|
78
|
+
innerContainer = dom.querySelector('.resizer-item');
|
|
79
|
+
} else if (isExtension) {
|
|
80
|
+
innerContainer = dom.querySelector('.extension-container[data-layout]');
|
|
81
|
+
} else if (isBlockCard) {
|
|
82
|
+
//specific to datasource blockCard
|
|
83
|
+
innerContainer = dom.querySelector('.datasourceView-content-inner-wrap');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
var isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
|
|
87
|
+
var neighboringWidthOffset = anchorName === rootAnchorName ? '-16px' : '0px';
|
|
88
|
+
if (supportsAnchor) {
|
|
89
|
+
return {
|
|
90
|
+
left: isEdgeCase ? "calc(anchor(".concat(rootAnchorName, " start) + ").concat(getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + ").concat(neighboringWidthOffset, ")") : "calc(anchor(".concat(rootAnchorName, " start) - ").concat(QUICK_INSERT_DIMENSIONS.width, "px - ").concat(rootElementGap(rootNodeType), "px + ").concat(neighboringWidthOffset, ")"),
|
|
91
|
+
top: "calc(anchor(".concat(rootAnchorName, " start) + ").concat(topPositionAdjustment(rootNodeType), "px)")
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
left: isEdgeCase ? "calc(".concat((dom === null || dom === void 0 ? void 0 : dom.offsetLeft) || 0, "px + ").concat(getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + ").concat(neighboringWidthOffset, ")") : "calc(".concat(getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + ").concat(neighboringWidthOffset, ")"),
|
|
96
|
+
top: getTopPosition(dom, rootNodeType)
|
|
97
|
+
};
|
|
98
|
+
}, [rootAnchorName, view.dom, rootNodeType, macroInteractionUpdates, anchorName]);
|
|
99
|
+
useEffect(function () {
|
|
100
|
+
var cleanUpTransitionListener;
|
|
101
|
+
if (rootNodeType === 'extension' || rootNodeType === 'embedCard') {
|
|
102
|
+
var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(rootAnchorName, "\"]"));
|
|
103
|
+
if (!dom) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
cleanUpTransitionListener = bind(dom, {
|
|
107
|
+
type: 'transitionend',
|
|
108
|
+
listener: function listener() {
|
|
109
|
+
setPositionStyles(calculatePosition());
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
var calcPos = requestAnimationFrame(function () {
|
|
114
|
+
setPositionStyles(calculatePosition());
|
|
115
|
+
});
|
|
116
|
+
return function () {
|
|
117
|
+
var _cleanUpTransitionLis;
|
|
118
|
+
cancelAnimationFrame(calcPos);
|
|
119
|
+
(_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 || _cleanUpTransitionLis();
|
|
120
|
+
};
|
|
121
|
+
}, [calculatePosition, view.dom, rootAnchorName, rootNodeType]);
|
|
122
|
+
return (
|
|
123
|
+
/*#__PURE__*/
|
|
124
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
125
|
+
React.createElement(Box, {
|
|
126
|
+
style: positionStyles,
|
|
127
|
+
xcss: [containerStaticStyles]
|
|
128
|
+
}, /*#__PURE__*/React.createElement(Tooltip, {
|
|
129
|
+
content: /*#__PURE__*/React.createElement(ToolTipContent, {
|
|
130
|
+
description: formatMessage(messages.insert),
|
|
131
|
+
shortcutOverride: "/"
|
|
132
|
+
})
|
|
133
|
+
}, /*#__PURE__*/React.createElement(Pressable, {
|
|
134
|
+
type: "button",
|
|
135
|
+
"aria-label": formatMessage(messages.insert),
|
|
136
|
+
xcss: [buttonStyles],
|
|
137
|
+
onClick: function onClick() {
|
|
138
|
+
var _api$core, _api$quickInsert;
|
|
139
|
+
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
|
|
140
|
+
var tr = _ref2.tr;
|
|
141
|
+
var start = getPos();
|
|
142
|
+
if (!start) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
return tr.setSelection(TextSelection.create(tr.doc, start));
|
|
146
|
+
});
|
|
147
|
+
api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || _api$quickInsert.actions.openTypeAhead('blockControl');
|
|
148
|
+
}
|
|
149
|
+
}, /*#__PURE__*/React.createElement(EditorAddIcon, {
|
|
150
|
+
label: "add",
|
|
151
|
+
size: "medium"
|
|
152
|
+
}))))
|
|
153
|
+
);
|
|
154
|
+
};
|
|
@@ -14,6 +14,9 @@ export type ActiveNode = {
|
|
|
14
14
|
anchorName: string;
|
|
15
15
|
nodeType: string;
|
|
16
16
|
handleOptions?: HandleOptions;
|
|
17
|
+
rootPos?: number;
|
|
18
|
+
rootAnchorName?: string;
|
|
19
|
+
rootNodeType?: string;
|
|
17
20
|
};
|
|
18
21
|
export type MultiSelectDnD = {
|
|
19
22
|
anchor: number;
|
|
@@ -27,6 +30,7 @@ export interface PluginState {
|
|
|
27
30
|
decorations: DecorationSet;
|
|
28
31
|
isDragging: boolean;
|
|
29
32
|
isMenuOpen?: boolean;
|
|
33
|
+
menuTriggerBy?: string;
|
|
30
34
|
editorHeight: number;
|
|
31
35
|
editorWidthLeft: number;
|
|
32
36
|
editorWidthRight: number;
|
|
@@ -47,6 +51,7 @@ export interface PluginState {
|
|
|
47
51
|
export type ReleaseHiddenDecoration = () => boolean | undefined;
|
|
48
52
|
export type BlockControlsSharedState = {
|
|
49
53
|
isMenuOpen: boolean;
|
|
54
|
+
menuTriggerBy?: string;
|
|
50
55
|
activeNode?: ActiveNode;
|
|
51
56
|
isDragging: boolean;
|
|
52
57
|
isPMDragging: boolean;
|
|
@@ -87,9 +92,10 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
|
|
|
87
92
|
moveNodeAtCursorPos?: boolean;
|
|
88
93
|
}) => EditorCommand;
|
|
89
94
|
moveNode: MoveNode;
|
|
90
|
-
showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
|
|
95
|
+
showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions, rootPos?: number, rootAnchorName?: string, rootNodeType?: string) => EditorCommand;
|
|
91
96
|
toggleBlockMenu: (options?: {
|
|
92
97
|
closeMenu?: boolean;
|
|
98
|
+
anchorName?: string;
|
|
93
99
|
}) => EditorCommand;
|
|
94
100
|
setNodeDragged: (getPos: () => number | undefined, anchorName: string, nodeType: string) => EditorCommand;
|
|
95
101
|
setMultiSelectPositions: (anchor?: number, head?: number) => EditorCommand;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IntlShape } from 'react-intl-next';
|
|
2
|
+
import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
|
|
3
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
4
|
+
import { Decoration, type DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import type { BlockControlsPlugin } from '../blockControlsPluginType';
|
|
6
|
+
export declare const findQuickInsertInsertButtonDecoration: (decorations: DecorationSet, from?: number, to?: number) => Decoration[];
|
|
7
|
+
export declare const quickInsertButtonDecoration: (api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], rootPos: number, anchorName: string, nodeType: string, nodeViewPortalProviderAPI: PortalProviderAPI, rootAnchorName?: string, rootNodeType?: string) => Decoration;
|
|
@@ -22,7 +22,14 @@ export declare const DRAG_HANDLE_PARAGRAPH_TOP_ADJUSTMENT = 2;
|
|
|
22
22
|
* so we allow for some leniency to capture them all. e.g. Table is depth 3.
|
|
23
23
|
*/
|
|
24
24
|
export declare const DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH = 3;
|
|
25
|
+
export declare const QUICK_INSERT_HEIGHT = 24;
|
|
26
|
+
export declare const QUICK_INSERT_WIDTH = 24;
|
|
27
|
+
export declare const QUICK_INSERT_DIMENSIONS: {
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
};
|
|
25
31
|
export declare const dragHandleGap: (nodeType: string, parentNodeType?: string) => number;
|
|
32
|
+
export declare const rootElementGap: (nodeType: string) => number;
|
|
26
33
|
export declare const getNestedNodeLeftPaddingMargin: (nodeType?: string) => "8px" | "16px" | "20px" | "24px" | "28px" | "40px";
|
|
27
34
|
export declare const topPositionAdjustment: (nodeType: string) => number;
|
|
28
35
|
export declare const dropTargetMarginMap: {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type IntlShape } from 'react-intl-next';
|
|
3
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
4
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import type { BlockControlsPlugin } from '../blockControlsPluginType';
|
|
6
|
+
type Props = {
|
|
7
|
+
view: EditorView;
|
|
8
|
+
api: ExtractInjectionAPI<BlockControlsPlugin>;
|
|
9
|
+
formatMessage: IntlShape['formatMessage'];
|
|
10
|
+
getPos: () => number | undefined;
|
|
11
|
+
nodeType: string;
|
|
12
|
+
anchorName: string;
|
|
13
|
+
rootAnchorName?: string;
|
|
14
|
+
rootNodeType: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const TypeAheadControl: ({ view, api, formatMessage, getPos, nodeType, anchorName, rootAnchorName, rootNodeType, }: Props) => React.JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -14,6 +14,9 @@ export type ActiveNode = {
|
|
|
14
14
|
anchorName: string;
|
|
15
15
|
nodeType: string;
|
|
16
16
|
handleOptions?: HandleOptions;
|
|
17
|
+
rootPos?: number;
|
|
18
|
+
rootAnchorName?: string;
|
|
19
|
+
rootNodeType?: string;
|
|
17
20
|
};
|
|
18
21
|
export type MultiSelectDnD = {
|
|
19
22
|
anchor: number;
|
|
@@ -27,6 +30,7 @@ export interface PluginState {
|
|
|
27
30
|
decorations: DecorationSet;
|
|
28
31
|
isDragging: boolean;
|
|
29
32
|
isMenuOpen?: boolean;
|
|
33
|
+
menuTriggerBy?: string;
|
|
30
34
|
editorHeight: number;
|
|
31
35
|
editorWidthLeft: number;
|
|
32
36
|
editorWidthRight: number;
|
|
@@ -47,6 +51,7 @@ export interface PluginState {
|
|
|
47
51
|
export type ReleaseHiddenDecoration = () => boolean | undefined;
|
|
48
52
|
export type BlockControlsSharedState = {
|
|
49
53
|
isMenuOpen: boolean;
|
|
54
|
+
menuTriggerBy?: string;
|
|
50
55
|
activeNode?: ActiveNode;
|
|
51
56
|
isDragging: boolean;
|
|
52
57
|
isPMDragging: boolean;
|
|
@@ -87,9 +92,10 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
|
|
|
87
92
|
moveNodeAtCursorPos?: boolean;
|
|
88
93
|
}) => EditorCommand;
|
|
89
94
|
moveNode: MoveNode;
|
|
90
|
-
showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
|
|
95
|
+
showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions, rootPos?: number, rootAnchorName?: string, rootNodeType?: string) => EditorCommand;
|
|
91
96
|
toggleBlockMenu: (options?: {
|
|
92
97
|
closeMenu?: boolean;
|
|
98
|
+
anchorName?: string;
|
|
93
99
|
}) => EditorCommand;
|
|
94
100
|
setNodeDragged: (getPos: () => number | undefined, anchorName: string, nodeType: string) => EditorCommand;
|
|
95
101
|
setMultiSelectPositions: (anchor?: number, head?: number) => EditorCommand;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IntlShape } from 'react-intl-next';
|
|
2
|
+
import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
|
|
3
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
4
|
+
import { Decoration, type DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import type { BlockControlsPlugin } from '../blockControlsPluginType';
|
|
6
|
+
export declare const findQuickInsertInsertButtonDecoration: (decorations: DecorationSet, from?: number, to?: number) => Decoration[];
|
|
7
|
+
export declare const quickInsertButtonDecoration: (api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], rootPos: number, anchorName: string, nodeType: string, nodeViewPortalProviderAPI: PortalProviderAPI, rootAnchorName?: string, rootNodeType?: string) => Decoration;
|
|
@@ -22,7 +22,14 @@ export declare const DRAG_HANDLE_PARAGRAPH_TOP_ADJUSTMENT = 2;
|
|
|
22
22
|
* so we allow for some leniency to capture them all. e.g. Table is depth 3.
|
|
23
23
|
*/
|
|
24
24
|
export declare const DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH = 3;
|
|
25
|
+
export declare const QUICK_INSERT_HEIGHT = 24;
|
|
26
|
+
export declare const QUICK_INSERT_WIDTH = 24;
|
|
27
|
+
export declare const QUICK_INSERT_DIMENSIONS: {
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
};
|
|
25
31
|
export declare const dragHandleGap: (nodeType: string, parentNodeType?: string) => number;
|
|
32
|
+
export declare const rootElementGap: (nodeType: string) => number;
|
|
26
33
|
export declare const getNestedNodeLeftPaddingMargin: (nodeType?: string) => "8px" | "16px" | "20px" | "24px" | "28px" | "40px";
|
|
27
34
|
export declare const topPositionAdjustment: (nodeType: string) => number;
|
|
28
35
|
export declare const dropTargetMarginMap: {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type IntlShape } from 'react-intl-next';
|
|
3
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
4
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import type { BlockControlsPlugin } from '../blockControlsPluginType';
|
|
6
|
+
type Props = {
|
|
7
|
+
view: EditorView;
|
|
8
|
+
api: ExtractInjectionAPI<BlockControlsPlugin>;
|
|
9
|
+
formatMessage: IntlShape['formatMessage'];
|
|
10
|
+
getPos: () => number | undefined;
|
|
11
|
+
nodeType: string;
|
|
12
|
+
anchorName: string;
|
|
13
|
+
rootAnchorName?: string;
|
|
14
|
+
rootNodeType: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const TypeAheadControl: ({ view, api, formatMessage, getPos, nodeType, anchorName, rootAnchorName, rootNodeType, }: Props) => React.JSX.Element;
|
|
17
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-controls",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.3",
|
|
4
4
|
"description": "Block controls plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@atlaskit/adf-schema": "^47.2.1",
|
|
34
|
-
"@atlaskit/editor-common": "^100.
|
|
34
|
+
"@atlaskit/editor-common": "^100.2.0",
|
|
35
35
|
"@atlaskit/editor-plugin-accessibility-utils": "^2.0.0",
|
|
36
36
|
"@atlaskit/editor-plugin-analytics": "^2.0.0",
|
|
37
37
|
"@atlaskit/editor-plugin-editor-disabled": "^2.0.0",
|