@atlaskit/editor-plugin-paste-options-toolbar 9.0.1 → 9.0.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 +16 -0
- package/dist/cjs/pm-plugins/constants.js +5 -2
- package/dist/cjs/ui/on-paste-actions-menu/PasteActionsMenu.js +42 -15
- package/dist/cjs/ui/on-paste-actions-menu/PasteMenuComponents.js +3 -3
- package/dist/es2019/pm-plugins/constants.js +4 -1
- package/dist/es2019/ui/on-paste-actions-menu/PasteActionsMenu.js +38 -17
- package/dist/es2019/ui/on-paste-actions-menu/PasteMenuComponents.js +3 -3
- package/dist/esm/pm-plugins/constants.js +4 -1
- package/dist/esm/ui/on-paste-actions-menu/PasteActionsMenu.js +40 -15
- package/dist/esm/ui/on-paste-actions-menu/PasteMenuComponents.js +3 -3
- package/dist/types/pm-plugins/constants.d.ts +1 -0
- package/dist/types/ui/on-paste-actions-menu/PasteActionsMenu.d.ts +21 -0
- package/dist/types/ui/on-paste-actions-menu/PasteMenuComponents.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/constants.d.ts +1 -0
- package/dist/types-ts4.5/ui/on-paste-actions-menu/PasteActionsMenu.d.ts +21 -0
- package/dist/types-ts4.5/ui/on-paste-actions-menu/PasteMenuComponents.d.ts +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-paste-options-toolbar
|
|
2
2
|
|
|
3
|
+
## 9.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`bba4ad9eec00a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bba4ad9eec00a) -
|
|
8
|
+
Ensure `invokedFrom` is passed to on-paste actions legacy paste events
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 9.0.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`6ebc53b2b151d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6ebc53b2b151d) -
|
|
16
|
+
[ux] [EDITOR-5821] updated paste menu position so that its the same as the inline comment editor'
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 9.0.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.TEXT_HIGHLIGHT_CLASS = exports.PASTE_TOOLBAR_MENU_ID = exports.PASTE_TOOLBAR_ITEM_CLASS = exports.PASTE_TOOLBAR_CLASS = exports.PASTE_OPTIONS_TEST_ID = exports.PASTE_OPTIONS_META_ID = exports.PASTE_HIGHLIGHT_DECORATION_KEY = exports.EDITOR_WRAPPER_CLASS = void 0;
|
|
6
|
+
exports.TEXT_HIGHLIGHT_CLASS = exports.PASTE_TOOLBAR_MENU_ID = exports.PASTE_TOOLBAR_ITEM_CLASS = exports.PASTE_TOOLBAR_CLASS = exports.PASTE_OPTIONS_TEST_ID = exports.PASTE_OPTIONS_META_ID = exports.PASTE_MENU_GAP = exports.PASTE_HIGHLIGHT_DECORATION_KEY = exports.EDITOR_WRAPPER_CLASS = void 0;
|
|
7
7
|
var PASTE_TOOLBAR_CLASS = exports.PASTE_TOOLBAR_CLASS = 'ak-editor-paste-toolbar';
|
|
8
8
|
var PASTE_TOOLBAR_MENU_ID = exports.PASTE_TOOLBAR_MENU_ID = 'ak-editor-paste-toolbar-item-dropdownList';
|
|
9
9
|
var TEXT_HIGHLIGHT_CLASS = exports.TEXT_HIGHLIGHT_CLASS = 'text-highlight';
|
|
@@ -11,4 +11,7 @@ var PASTE_HIGHLIGHT_DECORATION_KEY = exports.PASTE_HIGHLIGHT_DECORATION_KEY = 'p
|
|
|
11
11
|
var PASTE_TOOLBAR_ITEM_CLASS = exports.PASTE_TOOLBAR_ITEM_CLASS = 'ak-editor-paste-toolbar-item';
|
|
12
12
|
var EDITOR_WRAPPER_CLASS = exports.EDITOR_WRAPPER_CLASS = 'akEditor';
|
|
13
13
|
var PASTE_OPTIONS_TEST_ID = exports.PASTE_OPTIONS_TEST_ID = 'paste-options-testid';
|
|
14
|
-
var PASTE_OPTIONS_META_ID = exports.PASTE_OPTIONS_META_ID = 'paste-options$';
|
|
14
|
+
var PASTE_OPTIONS_META_ID = exports.PASTE_OPTIONS_META_ID = 'paste-options$';
|
|
15
|
+
|
|
16
|
+
// Gap (in px) between the right edge of the pasted content and the left edge of the paste menu.
|
|
17
|
+
var PASTE_MENU_GAP = exports.PASTE_MENU_GAP = 12;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
6
7
|
});
|
|
7
8
|
exports.PasteActionsMenu = void 0;
|
|
9
|
+
exports.onPositionCalculated = onPositionCalculated;
|
|
10
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
8
11
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
12
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
10
13
|
var _hooks = require("@atlaskit/editor-common/hooks");
|
|
@@ -15,16 +18,18 @@ var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
|
15
18
|
var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
|
|
16
19
|
var _editorToolbar = require("@atlaskit/editor-toolbar");
|
|
17
20
|
var _commands = require("../../editor-commands/commands");
|
|
21
|
+
var _constants = require("../../pm-plugins/constants");
|
|
18
22
|
var _types = require("../../types/types");
|
|
19
23
|
var _toolbar2 = require("../toolbar");
|
|
20
24
|
var _hasVisibleButton = require("./hasVisibleButton");
|
|
21
25
|
var _PasteActionsMenuContent = require("./PasteActionsMenuContent");
|
|
22
26
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
27
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
28
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
23
29
|
var PopupWithListeners = (0, _uiReact.withReactEditorViewOuterListeners)(_ui.Popup);
|
|
24
|
-
function getTargetElement(editorView) {
|
|
25
|
-
var from = editorView.state.selection.from;
|
|
30
|
+
function getTargetElement(editorView, pos) {
|
|
26
31
|
try {
|
|
27
|
-
var domRef = (0, _utils.findDomRefAtPos)(
|
|
32
|
+
var domRef = (0, _utils.findDomRefAtPos)(pos, editorView.domAtPos.bind(editorView));
|
|
28
33
|
if (domRef instanceof HTMLElement) {
|
|
29
34
|
return domRef;
|
|
30
35
|
}
|
|
@@ -33,12 +38,31 @@ function getTargetElement(editorView) {
|
|
|
33
38
|
return null;
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Adjusts the vertical position of the paste menu to align with the top of the
|
|
44
|
+
* pasted content using the exact coordinates at the paste start position.
|
|
45
|
+
*
|
|
46
|
+
* The Popup's vertical placement may place the popup below the target element
|
|
47
|
+
* (alignY="bottom"). This override computes the correct top position using
|
|
48
|
+
* coordsAtPos for the paste start, then converts to the Popup's coordinate
|
|
49
|
+
* system by calculating the delta from the target element's bottom (where the
|
|
50
|
+
* Popup positions by default) to the paste start coordinates.
|
|
51
|
+
*/
|
|
52
|
+
function onPositionCalculated(editorView, pasteStartPos, targetElement) {
|
|
53
|
+
return function (position) {
|
|
54
|
+
var _position$top;
|
|
55
|
+
var startCoords = editorView.coordsAtPos(pasteStartPos);
|
|
56
|
+
var targetRect = targetElement.getBoundingClientRect();
|
|
57
|
+
|
|
58
|
+
// The Popup places the menu at the target's bottom edge by default.
|
|
59
|
+
// We need to shift it up so it aligns with the paste start position.
|
|
60
|
+
// Both coordinates are in viewport space, so the delta is offset-parent agnostic.
|
|
61
|
+
var topDelta = startCoords.top - (targetRect.top + targetRect.height);
|
|
62
|
+
return _objectSpread(_objectSpread({}, position), {}, {
|
|
63
|
+
top: ((_position$top = position.top) !== null && _position$top !== void 0 ? _position$top : 0) + topDelta
|
|
64
|
+
});
|
|
65
|
+
};
|
|
42
66
|
}
|
|
43
67
|
var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref) {
|
|
44
68
|
var _api$analytics, _api$uiControlRegistr, _api$uiControlRegistr2, _api$uiControlRegistr3, _api$uiControlRegistr4;
|
|
@@ -78,13 +102,15 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
78
102
|
(0, _commands.showToolbar)(lastContentPasted, selectedOption, legacyVisible, pasteAncestorNodeNames)(editorView.state, editorView.dispatch);
|
|
79
103
|
}, [lastContentPasted, editorView]);
|
|
80
104
|
var _useSharedPluginState2 = (0, _hooks.useSharedPluginStateWithSelector)(api, ['pasteOptionsToolbarPlugin'], function (states) {
|
|
81
|
-
var _pluginState$showTool;
|
|
105
|
+
var _pluginState$showTool, _pluginState$pasteSta;
|
|
82
106
|
var pluginState = states.pasteOptionsToolbarPluginState;
|
|
83
107
|
return {
|
|
84
|
-
showToolbar: (_pluginState$showTool = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showToolbar) !== null && _pluginState$showTool !== void 0 ? _pluginState$showTool : false
|
|
108
|
+
showToolbar: (_pluginState$showTool = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showToolbar) !== null && _pluginState$showTool !== void 0 ? _pluginState$showTool : false,
|
|
109
|
+
pasteStartPos: (_pluginState$pasteSta = pluginState === null || pluginState === void 0 ? void 0 : pluginState.pasteStartPos) !== null && _pluginState$pasteSta !== void 0 ? _pluginState$pasteSta : 0
|
|
85
110
|
};
|
|
86
111
|
}),
|
|
87
|
-
isToolbarShown = _useSharedPluginState2.showToolbar
|
|
112
|
+
isToolbarShown = _useSharedPluginState2.showToolbar,
|
|
113
|
+
pasteStartPos = _useSharedPluginState2.pasteStartPos;
|
|
88
114
|
var aiSurfaceComponents = (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents('ai-paste-menu')) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
|
|
89
115
|
var visibleAiActionKeys = (0, _hasVisibleButton.getVisibleKeys)(aiSurfaceComponents, ['button', 'menu-item']);
|
|
90
116
|
(0, _react.useEffect)(function () {
|
|
@@ -132,7 +158,7 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
132
158
|
if (!anyComponentVisible) {
|
|
133
159
|
return null;
|
|
134
160
|
}
|
|
135
|
-
var target = getTargetElement(editorView);
|
|
161
|
+
var target = getTargetElement(editorView, pasteStartPos);
|
|
136
162
|
if (!target) {
|
|
137
163
|
return null;
|
|
138
164
|
}
|
|
@@ -141,10 +167,11 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
141
167
|
mountTo: mountTo,
|
|
142
168
|
boundariesElement: boundariesElement,
|
|
143
169
|
scrollableElement: scrollableElement,
|
|
144
|
-
offset: getPopupOffset(target),
|
|
145
170
|
zIndex: _editorSharedStyles.akEditorFloatingPanelZIndex,
|
|
146
|
-
alignX: "
|
|
171
|
+
alignX: "end",
|
|
147
172
|
alignY: "bottom",
|
|
173
|
+
offset: [_constants.PASTE_MENU_GAP, 0],
|
|
174
|
+
onPositionCalculated: onPositionCalculated(editorView, pasteStartPos, target),
|
|
148
175
|
handleClickOutside: handleClickOutside,
|
|
149
176
|
handleEscapeKeydown: handleDismiss
|
|
150
177
|
}, /*#__PURE__*/_react.default.createElement(_toolbar.EditorToolbarProvider, {
|
|
@@ -77,13 +77,13 @@ var PasteMenuItem = function PasteMenuItem(_ref) {
|
|
|
77
77
|
}
|
|
78
78
|
switch (pasteType) {
|
|
79
79
|
case 'rich-text':
|
|
80
|
-
(0, _commands.changeToRichTextWithAnalytics)(editorAnalyticsAPI)()(editorView.state, editorView.dispatch);
|
|
80
|
+
(0, _commands.changeToRichTextWithAnalytics)(editorAnalyticsAPI, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
81
81
|
break;
|
|
82
82
|
case 'markdown':
|
|
83
|
-
(0, _commands.changeToMarkdownWithAnalytics)(editorAnalyticsAPI, plaintextLength)()(editorView.state, editorView.dispatch);
|
|
83
|
+
(0, _commands.changeToMarkdownWithAnalytics)(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
84
84
|
break;
|
|
85
85
|
case 'plain-text':
|
|
86
|
-
(0, _commands.changeToPlainTextWithAnalytics)(editorAnalyticsAPI, plaintextLength)()(editorView.state, editorView.dispatch);
|
|
86
|
+
(0, _commands.changeToPlainTextWithAnalytics)(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
87
87
|
break;
|
|
88
88
|
}
|
|
89
89
|
}, [editorView, editorAnalyticsAPI, plaintextLength, pasteType]);
|
|
@@ -5,4 +5,7 @@ export const PASTE_HIGHLIGHT_DECORATION_KEY = 'paste-highlight-decoration-key';
|
|
|
5
5
|
export const PASTE_TOOLBAR_ITEM_CLASS = 'ak-editor-paste-toolbar-item';
|
|
6
6
|
export const EDITOR_WRAPPER_CLASS = 'akEditor';
|
|
7
7
|
export const PASTE_OPTIONS_TEST_ID = 'paste-options-testid';
|
|
8
|
-
export const PASTE_OPTIONS_META_ID = 'paste-options$';
|
|
8
|
+
export const PASTE_OPTIONS_META_ID = 'paste-options$';
|
|
9
|
+
|
|
10
|
+
// Gap (in px) between the right edge of the pasted content and the left edge of the paste menu.
|
|
11
|
+
export const PASTE_MENU_GAP = 12;
|
|
@@ -8,17 +8,15 @@ import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
|
8
8
|
import { akEditorFloatingPanelZIndex } from '@atlaskit/editor-shared-styles';
|
|
9
9
|
import { ToolbarDropdownMenuProvider } from '@atlaskit/editor-toolbar';
|
|
10
10
|
import { hideToolbar, highlightContent, showToolbar } from '../../editor-commands/commands';
|
|
11
|
+
import { PASTE_MENU_GAP } from '../../pm-plugins/constants';
|
|
11
12
|
import { ToolbarDropdownOption } from '../../types/types';
|
|
12
13
|
import { isToolbarVisible } from '../toolbar';
|
|
13
14
|
import { getVisibleKeys, hasVisibleButton } from './hasVisibleButton';
|
|
14
15
|
import { PasteActionsMenuContent } from './PasteActionsMenuContent';
|
|
15
16
|
const PopupWithListeners = withReactEditorViewOuterListeners(Popup);
|
|
16
|
-
function getTargetElement(editorView) {
|
|
17
|
-
const {
|
|
18
|
-
from
|
|
19
|
-
} = editorView.state.selection;
|
|
17
|
+
function getTargetElement(editorView, pos) {
|
|
20
18
|
try {
|
|
21
|
-
const domRef = findDomRefAtPos(
|
|
19
|
+
const domRef = findDomRefAtPos(pos, editorView.domAtPos.bind(editorView));
|
|
22
20
|
if (domRef instanceof HTMLElement) {
|
|
23
21
|
return domRef;
|
|
24
22
|
}
|
|
@@ -27,12 +25,32 @@ function getTargetElement(editorView) {
|
|
|
27
25
|
return null;
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Adjusts the vertical position of the paste menu to align with the top of the
|
|
31
|
+
* pasted content using the exact coordinates at the paste start position.
|
|
32
|
+
*
|
|
33
|
+
* The Popup's vertical placement may place the popup below the target element
|
|
34
|
+
* (alignY="bottom"). This override computes the correct top position using
|
|
35
|
+
* coordsAtPos for the paste start, then converts to the Popup's coordinate
|
|
36
|
+
* system by calculating the delta from the target element's bottom (where the
|
|
37
|
+
* Popup positions by default) to the paste start coordinates.
|
|
38
|
+
*/
|
|
39
|
+
export function onPositionCalculated(editorView, pasteStartPos, targetElement) {
|
|
40
|
+
return position => {
|
|
41
|
+
var _position$top;
|
|
42
|
+
const startCoords = editorView.coordsAtPos(pasteStartPos);
|
|
43
|
+
const targetRect = targetElement.getBoundingClientRect();
|
|
44
|
+
|
|
45
|
+
// The Popup places the menu at the target's bottom edge by default.
|
|
46
|
+
// We need to shift it up so it aligns with the paste start position.
|
|
47
|
+
// Both coordinates are in viewport space, so the delta is offset-parent agnostic.
|
|
48
|
+
const topDelta = startCoords.top - (targetRect.top + targetRect.height);
|
|
49
|
+
return {
|
|
50
|
+
...position,
|
|
51
|
+
top: ((_position$top = position.top) !== null && _position$top !== void 0 ? _position$top : 0) + topDelta
|
|
52
|
+
};
|
|
53
|
+
};
|
|
36
54
|
}
|
|
37
55
|
export const PasteActionsMenu = ({
|
|
38
56
|
api,
|
|
@@ -74,12 +92,14 @@ export const PasteActionsMenu = ({
|
|
|
74
92
|
showToolbar(lastContentPasted, selectedOption, legacyVisible, pasteAncestorNodeNames)(editorView.state, editorView.dispatch);
|
|
75
93
|
}, [lastContentPasted, editorView]);
|
|
76
94
|
const {
|
|
77
|
-
showToolbar: isToolbarShown
|
|
95
|
+
showToolbar: isToolbarShown,
|
|
96
|
+
pasteStartPos
|
|
78
97
|
} = useSharedPluginStateWithSelector(api, ['pasteOptionsToolbarPlugin'], states => {
|
|
79
|
-
var _pluginState$showTool;
|
|
98
|
+
var _pluginState$showTool, _pluginState$pasteSta;
|
|
80
99
|
const pluginState = states.pasteOptionsToolbarPluginState;
|
|
81
100
|
return {
|
|
82
|
-
showToolbar: (_pluginState$showTool = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showToolbar) !== null && _pluginState$showTool !== void 0 ? _pluginState$showTool : false
|
|
101
|
+
showToolbar: (_pluginState$showTool = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showToolbar) !== null && _pluginState$showTool !== void 0 ? _pluginState$showTool : false,
|
|
102
|
+
pasteStartPos: (_pluginState$pasteSta = pluginState === null || pluginState === void 0 ? void 0 : pluginState.pasteStartPos) !== null && _pluginState$pasteSta !== void 0 ? _pluginState$pasteSta : 0
|
|
83
103
|
};
|
|
84
104
|
});
|
|
85
105
|
const aiSurfaceComponents = (_api$uiControlRegistr = api === null || api === void 0 ? void 0 : (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents('ai-paste-menu')) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
|
|
@@ -129,7 +149,7 @@ export const PasteActionsMenu = ({
|
|
|
129
149
|
if (!anyComponentVisible) {
|
|
130
150
|
return null;
|
|
131
151
|
}
|
|
132
|
-
const target = getTargetElement(editorView);
|
|
152
|
+
const target = getTargetElement(editorView, pasteStartPos);
|
|
133
153
|
if (!target) {
|
|
134
154
|
return null;
|
|
135
155
|
}
|
|
@@ -138,10 +158,11 @@ export const PasteActionsMenu = ({
|
|
|
138
158
|
mountTo: mountTo,
|
|
139
159
|
boundariesElement: boundariesElement,
|
|
140
160
|
scrollableElement: scrollableElement,
|
|
141
|
-
offset: getPopupOffset(target),
|
|
142
161
|
zIndex: akEditorFloatingPanelZIndex,
|
|
143
|
-
alignX: "
|
|
162
|
+
alignX: "end",
|
|
144
163
|
alignY: "bottom",
|
|
164
|
+
offset: [PASTE_MENU_GAP, 0],
|
|
165
|
+
onPositionCalculated: onPositionCalculated(editorView, pasteStartPos, target),
|
|
145
166
|
handleClickOutside: handleClickOutside,
|
|
146
167
|
handleEscapeKeydown: handleDismiss
|
|
147
168
|
}, /*#__PURE__*/React.createElement(EditorToolbarProvider, {
|
|
@@ -71,13 +71,13 @@ const PasteMenuItem = ({
|
|
|
71
71
|
}
|
|
72
72
|
switch (pasteType) {
|
|
73
73
|
case 'rich-text':
|
|
74
|
-
changeToRichTextWithAnalytics(editorAnalyticsAPI)()(editorView.state, editorView.dispatch);
|
|
74
|
+
changeToRichTextWithAnalytics(editorAnalyticsAPI, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
75
75
|
break;
|
|
76
76
|
case 'markdown':
|
|
77
|
-
changeToMarkdownWithAnalytics(editorAnalyticsAPI, plaintextLength)()(editorView.state, editorView.dispatch);
|
|
77
|
+
changeToMarkdownWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
78
78
|
break;
|
|
79
79
|
case 'plain-text':
|
|
80
|
-
changeToPlainTextWithAnalytics(editorAnalyticsAPI, plaintextLength)()(editorView.state, editorView.dispatch);
|
|
80
|
+
changeToPlainTextWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
81
81
|
break;
|
|
82
82
|
}
|
|
83
83
|
}, [editorView, editorAnalyticsAPI, plaintextLength, pasteType]);
|
|
@@ -5,4 +5,7 @@ export var PASTE_HIGHLIGHT_DECORATION_KEY = 'paste-highlight-decoration-key';
|
|
|
5
5
|
export var PASTE_TOOLBAR_ITEM_CLASS = 'ak-editor-paste-toolbar-item';
|
|
6
6
|
export var EDITOR_WRAPPER_CLASS = 'akEditor';
|
|
7
7
|
export var PASTE_OPTIONS_TEST_ID = 'paste-options-testid';
|
|
8
|
-
export var PASTE_OPTIONS_META_ID = 'paste-options$';
|
|
8
|
+
export var PASTE_OPTIONS_META_ID = 'paste-options$';
|
|
9
|
+
|
|
10
|
+
// Gap (in px) between the right edge of the pasted content and the left edge of the paste menu.
|
|
11
|
+
export var PASTE_MENU_GAP = 12;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
1
4
|
import React, { useCallback, useEffect, useRef } from 'react';
|
|
2
5
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
3
6
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
@@ -8,15 +11,15 @@ import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
|
8
11
|
import { akEditorFloatingPanelZIndex } from '@atlaskit/editor-shared-styles';
|
|
9
12
|
import { ToolbarDropdownMenuProvider } from '@atlaskit/editor-toolbar';
|
|
10
13
|
import { hideToolbar, highlightContent, showToolbar } from '../../editor-commands/commands';
|
|
14
|
+
import { PASTE_MENU_GAP } from '../../pm-plugins/constants';
|
|
11
15
|
import { ToolbarDropdownOption } from '../../types/types';
|
|
12
16
|
import { isToolbarVisible } from '../toolbar';
|
|
13
17
|
import { getVisibleKeys, hasVisibleButton } from './hasVisibleButton';
|
|
14
18
|
import { PasteActionsMenuContent } from './PasteActionsMenuContent';
|
|
15
19
|
var PopupWithListeners = withReactEditorViewOuterListeners(Popup);
|
|
16
|
-
function getTargetElement(editorView) {
|
|
17
|
-
var from = editorView.state.selection.from;
|
|
20
|
+
function getTargetElement(editorView, pos) {
|
|
18
21
|
try {
|
|
19
|
-
var domRef = findDomRefAtPos(
|
|
22
|
+
var domRef = findDomRefAtPos(pos, editorView.domAtPos.bind(editorView));
|
|
20
23
|
if (domRef instanceof HTMLElement) {
|
|
21
24
|
return domRef;
|
|
22
25
|
}
|
|
@@ -25,12 +28,31 @@ function getTargetElement(editorView) {
|
|
|
25
28
|
return null;
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Adjusts the vertical position of the paste menu to align with the top of the
|
|
34
|
+
* pasted content using the exact coordinates at the paste start position.
|
|
35
|
+
*
|
|
36
|
+
* The Popup's vertical placement may place the popup below the target element
|
|
37
|
+
* (alignY="bottom"). This override computes the correct top position using
|
|
38
|
+
* coordsAtPos for the paste start, then converts to the Popup's coordinate
|
|
39
|
+
* system by calculating the delta from the target element's bottom (where the
|
|
40
|
+
* Popup positions by default) to the paste start coordinates.
|
|
41
|
+
*/
|
|
42
|
+
export function onPositionCalculated(editorView, pasteStartPos, targetElement) {
|
|
43
|
+
return function (position) {
|
|
44
|
+
var _position$top;
|
|
45
|
+
var startCoords = editorView.coordsAtPos(pasteStartPos);
|
|
46
|
+
var targetRect = targetElement.getBoundingClientRect();
|
|
47
|
+
|
|
48
|
+
// The Popup places the menu at the target's bottom edge by default.
|
|
49
|
+
// We need to shift it up so it aligns with the paste start position.
|
|
50
|
+
// Both coordinates are in viewport space, so the delta is offset-parent agnostic.
|
|
51
|
+
var topDelta = startCoords.top - (targetRect.top + targetRect.height);
|
|
52
|
+
return _objectSpread(_objectSpread({}, position), {}, {
|
|
53
|
+
top: ((_position$top = position.top) !== null && _position$top !== void 0 ? _position$top : 0) + topDelta
|
|
54
|
+
});
|
|
55
|
+
};
|
|
34
56
|
}
|
|
35
57
|
export var PasteActionsMenu = function PasteActionsMenu(_ref) {
|
|
36
58
|
var _api$analytics, _api$uiControlRegistr, _api$uiControlRegistr2, _api$uiControlRegistr3, _api$uiControlRegistr4;
|
|
@@ -70,13 +92,15 @@ export var PasteActionsMenu = function PasteActionsMenu(_ref) {
|
|
|
70
92
|
showToolbar(lastContentPasted, selectedOption, legacyVisible, pasteAncestorNodeNames)(editorView.state, editorView.dispatch);
|
|
71
93
|
}, [lastContentPasted, editorView]);
|
|
72
94
|
var _useSharedPluginState2 = useSharedPluginStateWithSelector(api, ['pasteOptionsToolbarPlugin'], function (states) {
|
|
73
|
-
var _pluginState$showTool;
|
|
95
|
+
var _pluginState$showTool, _pluginState$pasteSta;
|
|
74
96
|
var pluginState = states.pasteOptionsToolbarPluginState;
|
|
75
97
|
return {
|
|
76
|
-
showToolbar: (_pluginState$showTool = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showToolbar) !== null && _pluginState$showTool !== void 0 ? _pluginState$showTool : false
|
|
98
|
+
showToolbar: (_pluginState$showTool = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showToolbar) !== null && _pluginState$showTool !== void 0 ? _pluginState$showTool : false,
|
|
99
|
+
pasteStartPos: (_pluginState$pasteSta = pluginState === null || pluginState === void 0 ? void 0 : pluginState.pasteStartPos) !== null && _pluginState$pasteSta !== void 0 ? _pluginState$pasteSta : 0
|
|
77
100
|
};
|
|
78
101
|
}),
|
|
79
|
-
isToolbarShown = _useSharedPluginState2.showToolbar
|
|
102
|
+
isToolbarShown = _useSharedPluginState2.showToolbar,
|
|
103
|
+
pasteStartPos = _useSharedPluginState2.pasteStartPos;
|
|
80
104
|
var aiSurfaceComponents = (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents('ai-paste-menu')) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
|
|
81
105
|
var visibleAiActionKeys = getVisibleKeys(aiSurfaceComponents, ['button', 'menu-item']);
|
|
82
106
|
useEffect(function () {
|
|
@@ -124,7 +148,7 @@ export var PasteActionsMenu = function PasteActionsMenu(_ref) {
|
|
|
124
148
|
if (!anyComponentVisible) {
|
|
125
149
|
return null;
|
|
126
150
|
}
|
|
127
|
-
var target = getTargetElement(editorView);
|
|
151
|
+
var target = getTargetElement(editorView, pasteStartPos);
|
|
128
152
|
if (!target) {
|
|
129
153
|
return null;
|
|
130
154
|
}
|
|
@@ -133,10 +157,11 @@ export var PasteActionsMenu = function PasteActionsMenu(_ref) {
|
|
|
133
157
|
mountTo: mountTo,
|
|
134
158
|
boundariesElement: boundariesElement,
|
|
135
159
|
scrollableElement: scrollableElement,
|
|
136
|
-
offset: getPopupOffset(target),
|
|
137
160
|
zIndex: akEditorFloatingPanelZIndex,
|
|
138
|
-
alignX: "
|
|
161
|
+
alignX: "end",
|
|
139
162
|
alignY: "bottom",
|
|
163
|
+
offset: [PASTE_MENU_GAP, 0],
|
|
164
|
+
onPositionCalculated: onPositionCalculated(editorView, pasteStartPos, target),
|
|
140
165
|
handleClickOutside: handleClickOutside,
|
|
141
166
|
handleEscapeKeydown: handleDismiss
|
|
142
167
|
}, /*#__PURE__*/React.createElement(EditorToolbarProvider, {
|
|
@@ -68,13 +68,13 @@ var PasteMenuItem = function PasteMenuItem(_ref) {
|
|
|
68
68
|
}
|
|
69
69
|
switch (pasteType) {
|
|
70
70
|
case 'rich-text':
|
|
71
|
-
changeToRichTextWithAnalytics(editorAnalyticsAPI)()(editorView.state, editorView.dispatch);
|
|
71
|
+
changeToRichTextWithAnalytics(editorAnalyticsAPI, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
72
72
|
break;
|
|
73
73
|
case 'markdown':
|
|
74
|
-
changeToMarkdownWithAnalytics(editorAnalyticsAPI, plaintextLength)()(editorView.state, editorView.dispatch);
|
|
74
|
+
changeToMarkdownWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
75
75
|
break;
|
|
76
76
|
case 'plain-text':
|
|
77
|
-
changeToPlainTextWithAnalytics(editorAnalyticsAPI, plaintextLength)()(editorView.state, editorView.dispatch);
|
|
77
|
+
changeToPlainTextWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
|
|
78
78
|
break;
|
|
79
79
|
}
|
|
80
80
|
}, [editorView, editorAnalyticsAPI, plaintextLength, pasteType]);
|
|
@@ -6,3 +6,4 @@ export declare const PASTE_TOOLBAR_ITEM_CLASS = "ak-editor-paste-toolbar-item";
|
|
|
6
6
|
export declare const EDITOR_WRAPPER_CLASS = "akEditor";
|
|
7
7
|
export declare const PASTE_OPTIONS_TEST_ID = "paste-options-testid";
|
|
8
8
|
export declare const PASTE_OPTIONS_META_ID = "paste-options$";
|
|
9
|
+
export declare const PASTE_MENU_GAP = 12;
|
|
@@ -9,5 +9,26 @@ interface PasteActionsMenuProps {
|
|
|
9
9
|
mountTo?: HTMLElement;
|
|
10
10
|
scrollableElement?: HTMLElement;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Adjusts the vertical position of the paste menu to align with the top of the
|
|
14
|
+
* pasted content using the exact coordinates at the paste start position.
|
|
15
|
+
*
|
|
16
|
+
* The Popup's vertical placement may place the popup below the target element
|
|
17
|
+
* (alignY="bottom"). This override computes the correct top position using
|
|
18
|
+
* coordsAtPos for the paste start, then converts to the Popup's coordinate
|
|
19
|
+
* system by calculating the delta from the target element's bottom (where the
|
|
20
|
+
* Popup positions by default) to the paste start coordinates.
|
|
21
|
+
*/
|
|
22
|
+
export declare function onPositionCalculated(editorView: EditorView, pasteStartPos: number, targetElement: HTMLElement): (position: {
|
|
23
|
+
bottom?: number;
|
|
24
|
+
left?: number;
|
|
25
|
+
right?: number;
|
|
26
|
+
top?: number;
|
|
27
|
+
}) => {
|
|
28
|
+
bottom?: number;
|
|
29
|
+
left?: number;
|
|
30
|
+
right?: number;
|
|
31
|
+
top: number;
|
|
32
|
+
};
|
|
12
33
|
export declare const PasteActionsMenu: ({ api, editorView, mountTo, boundariesElement, scrollableElement, }: PasteActionsMenuProps) => React.JSX.Element | null;
|
|
13
34
|
export {};
|
|
@@ -6,5 +6,5 @@ export declare const isPasteOptionSelected: (pasteType: PasteType, selectedOptio
|
|
|
6
6
|
interface PasteMenuComponentsConfig {
|
|
7
7
|
api: ExtractInjectionAPI<PasteOptionsToolbarPlugin> | undefined;
|
|
8
8
|
}
|
|
9
|
-
export declare const getPasteMenuComponents: ({ api
|
|
9
|
+
export declare const getPasteMenuComponents: ({ api }: PasteMenuComponentsConfig) => RegisterComponent[];
|
|
10
10
|
export {};
|
|
@@ -6,3 +6,4 @@ export declare const PASTE_TOOLBAR_ITEM_CLASS = "ak-editor-paste-toolbar-item";
|
|
|
6
6
|
export declare const EDITOR_WRAPPER_CLASS = "akEditor";
|
|
7
7
|
export declare const PASTE_OPTIONS_TEST_ID = "paste-options-testid";
|
|
8
8
|
export declare const PASTE_OPTIONS_META_ID = "paste-options$";
|
|
9
|
+
export declare const PASTE_MENU_GAP = 12;
|
|
@@ -9,5 +9,26 @@ interface PasteActionsMenuProps {
|
|
|
9
9
|
mountTo?: HTMLElement;
|
|
10
10
|
scrollableElement?: HTMLElement;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Adjusts the vertical position of the paste menu to align with the top of the
|
|
14
|
+
* pasted content using the exact coordinates at the paste start position.
|
|
15
|
+
*
|
|
16
|
+
* The Popup's vertical placement may place the popup below the target element
|
|
17
|
+
* (alignY="bottom"). This override computes the correct top position using
|
|
18
|
+
* coordsAtPos for the paste start, then converts to the Popup's coordinate
|
|
19
|
+
* system by calculating the delta from the target element's bottom (where the
|
|
20
|
+
* Popup positions by default) to the paste start coordinates.
|
|
21
|
+
*/
|
|
22
|
+
export declare function onPositionCalculated(editorView: EditorView, pasteStartPos: number, targetElement: HTMLElement): (position: {
|
|
23
|
+
bottom?: number;
|
|
24
|
+
left?: number;
|
|
25
|
+
right?: number;
|
|
26
|
+
top?: number;
|
|
27
|
+
}) => {
|
|
28
|
+
bottom?: number;
|
|
29
|
+
left?: number;
|
|
30
|
+
right?: number;
|
|
31
|
+
top: number;
|
|
32
|
+
};
|
|
12
33
|
export declare const PasteActionsMenu: ({ api, editorView, mountTo, boundariesElement, scrollableElement, }: PasteActionsMenuProps) => React.JSX.Element | null;
|
|
13
34
|
export {};
|
|
@@ -6,5 +6,5 @@ export declare const isPasteOptionSelected: (pasteType: PasteType, selectedOptio
|
|
|
6
6
|
interface PasteMenuComponentsConfig {
|
|
7
7
|
api: ExtractInjectionAPI<PasteOptionsToolbarPlugin> | undefined;
|
|
8
8
|
}
|
|
9
|
-
export declare const getPasteMenuComponents: ({ api
|
|
9
|
+
export declare const getPasteMenuComponents: ({ api }: PasteMenuComponentsConfig) => RegisterComponent[];
|
|
10
10
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-paste-options-toolbar",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.3",
|
|
4
4
|
"description": "Paste options toolbar for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@atlaskit/icon": "^32.0.0",
|
|
42
42
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
43
43
|
"@atlaskit/primitives": "^18.0.0",
|
|
44
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
44
|
+
"@atlaskit/tmp-editor-statsig": "^36.1.0",
|
|
45
45
|
"@atlaskit/tokens": "^11.1.0",
|
|
46
46
|
"@babel/runtime": "^7.0.0",
|
|
47
47
|
"@compiled/react": "^0.20.0",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@atlaskit/editor-common": "^112.
|
|
52
|
+
"@atlaskit/editor-common": "^112.2.0",
|
|
53
53
|
"react": "^18.2.0",
|
|
54
54
|
"react-dom": "^18.2.0"
|
|
55
55
|
},
|