@atlaskit/editor-plugin-paste-options-toolbar 9.1.5 → 9.1.7
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 +19 -0
- package/dist/cjs/pm-plugins/util/format-handlers.js +1 -1
- package/dist/cjs/ui/on-paste-actions-menu/PasteActionsMenu.js +133 -13
- package/dist/cjs/ui/on-paste-actions-menu/PasteActionsMenuContent.js +16 -13
- package/dist/cjs/ui/on-paste-actions-menu/PasteMenuComponents.js +45 -15
- package/dist/cjs/ui/on-paste-actions-menu/PasteOptionsDropdownButton.js +52 -0
- package/dist/es2019/pm-plugins/util/format-handlers.js +1 -1
- package/dist/es2019/ui/on-paste-actions-menu/PasteActionsMenu.js +131 -14
- package/dist/es2019/ui/on-paste-actions-menu/PasteActionsMenuContent.js +17 -14
- package/dist/es2019/ui/on-paste-actions-menu/PasteMenuComponents.js +45 -13
- package/dist/es2019/ui/on-paste-actions-menu/PasteOptionsDropdownButton.js +47 -0
- package/dist/esm/pm-plugins/util/format-handlers.js +1 -1
- package/dist/esm/ui/on-paste-actions-menu/PasteActionsMenu.js +132 -14
- package/dist/esm/ui/on-paste-actions-menu/PasteActionsMenuContent.js +17 -14
- package/dist/esm/ui/on-paste-actions-menu/PasteMenuComponents.js +45 -15
- package/dist/esm/ui/on-paste-actions-menu/PasteOptionsDropdownButton.js +46 -0
- package/dist/types/ui/on-paste-actions-menu/PasteActionsMenu.d.ts +38 -4
- package/dist/types/ui/on-paste-actions-menu/PasteActionsMenuContent.d.ts +2 -1
- package/dist/types/ui/on-paste-actions-menu/PasteOptionsDropdownButton.d.ts +19 -0
- package/dist/types-ts4.5/ui/on-paste-actions-menu/PasteActionsMenu.d.ts +38 -4
- package/dist/types-ts4.5/ui/on-paste-actions-menu/PasteActionsMenuContent.d.ts +2 -1
- package/dist/types-ts4.5/ui/on-paste-actions-menu/PasteOptionsDropdownButton.d.ts +19 -0
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-paste-options-toolbar
|
|
2
2
|
|
|
3
|
+
## 9.1.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`3b007c601e102`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3b007c601e102) -
|
|
8
|
+
EDITOR-6092 Remove 100 character limit on legacy paste actions for new editor AI paste actions
|
|
9
|
+
menu. Also redesigns the legacy paste actions to more closely resemble the legacy paste floating
|
|
10
|
+
toolbar when there are no AI actions present.
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
|
|
13
|
+
## 9.1.6
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [`fc5915138b437`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fc5915138b437) -
|
|
18
|
+
EDITOR-6110 Ensure that paste actions menu appears in the correct position when the first item of
|
|
19
|
+
the paste is an inline node or mark
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
3
22
|
## 9.1.5
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -157,7 +157,7 @@ function getMarkdownSlice(text, schema, selection) {
|
|
|
157
157
|
for (var i = 0; i < textSplitByCodeBlock.length; i++) {
|
|
158
158
|
if (i % 2 === 0) {
|
|
159
159
|
// Ignored via go/ees005
|
|
160
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
160
|
+
// eslint-disable-next-line require-unicode-regexp, @atlassian/perf-linting/no-expensive-split-replace -- Ignored via go/ees017 (to be fixed)
|
|
161
161
|
textSplitByCodeBlock[i] = textSplitByCodeBlock[i].replace(/\\/g, '\\\\');
|
|
162
162
|
}
|
|
163
163
|
}
|
|
@@ -6,8 +6,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
8
|
exports.PasteActionsMenu = void 0;
|
|
9
|
+
exports.findBlockAncestorDOM = findBlockAncestorDOM;
|
|
9
10
|
exports.getTargetElement = getTargetElement;
|
|
10
11
|
exports.getVisualEndBottom = getVisualEndBottom;
|
|
12
|
+
exports.onInlinePositionCalculated = onInlinePositionCalculated;
|
|
11
13
|
exports.onPositionCalculated = onPositionCalculated;
|
|
12
14
|
exports.resolveTableAfterPos = resolveTableAfterPos;
|
|
13
15
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
@@ -82,10 +84,76 @@ function getVisualEndBottom(editorView, pasteEndPos, tableAfterPos) {
|
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
87
|
+
* Finds the DOM element for the nearest block-level ProseMirror ancestor of
|
|
88
|
+
* the given document position. Uses ProseMirror's schema (`node.isBlock`)
|
|
89
|
+
* rather than CSS display properties, so the check is always in sync with the
|
|
90
|
+
* document model.
|
|
91
|
+
*
|
|
92
|
+
* Returns `null` if no block ancestor can be resolved to a DOM element.
|
|
93
|
+
*/
|
|
94
|
+
function findBlockAncestorDOM(editorView, pos) {
|
|
95
|
+
try {
|
|
96
|
+
var $pos = editorView.state.doc.resolve(pos);
|
|
97
|
+
// Walk up the document tree from the resolved position's innermost
|
|
98
|
+
// node towards the root. $pos.node(depth) gives the ancestor at each
|
|
99
|
+
// depth; $pos.start(depth) gives the position just inside that ancestor,
|
|
100
|
+
// so `$pos.start(depth) - 1` is the position of the ancestor node itself
|
|
101
|
+
// (which is what nodeDOM expects).
|
|
102
|
+
for (var depth = $pos.depth; depth >= 0; depth--) {
|
|
103
|
+
var node = $pos.node(depth);
|
|
104
|
+
if (node.isBlock) {
|
|
105
|
+
var domNode = editorView.nodeDOM($pos.start(depth) - 1);
|
|
106
|
+
if (domNode instanceof HTMLElement) {
|
|
107
|
+
return domNode;
|
|
108
|
+
}
|
|
109
|
+
// depth 0 is the doc node — nodeDOM(–1) won't work, so try
|
|
110
|
+
// the editor's own DOM element as a fallback.
|
|
111
|
+
if (depth === 0 && editorView.dom instanceof HTMLElement) {
|
|
112
|
+
return editorView.dom;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} catch (_unused2) {
|
|
117
|
+
// Position may be out of range after a concurrent edit — fall through.
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Positions the paste menu inline, immediately to the right of the cursor
|
|
124
|
+
* at the paste end position, vertically centered with the line.
|
|
125
|
+
* Used for short pastes without AI actions.
|
|
126
|
+
*/
|
|
127
|
+
function onInlinePositionCalculated(editorView, pasteEndPos, targetElement, popupContentRef) {
|
|
128
|
+
return function (position) {
|
|
129
|
+
var _popupContentRef$curr, _popupContentRef$curr2, _position$top, _position$left;
|
|
130
|
+
var endCoords = editorView.coordsAtPos(pasteEndPos);
|
|
131
|
+
var targetRect = targetElement.getBoundingClientRect();
|
|
132
|
+
|
|
133
|
+
// Vertical: center the menu with the line at the paste end position.
|
|
134
|
+
var lineHeight = endCoords.bottom - endCoords.top;
|
|
135
|
+
var lineMidpoint = endCoords.top + lineHeight / 2;
|
|
136
|
+
var menuHeight = (_popupContentRef$curr = (_popupContentRef$curr2 = popupContentRef.current) === null || _popupContentRef$curr2 === void 0 ? void 0 : _popupContentRef$curr2.getBoundingClientRect().height) !== null && _popupContentRef$curr !== void 0 ? _popupContentRef$curr : lineHeight;
|
|
137
|
+
var menuTop = lineMidpoint - menuHeight / 2;
|
|
138
|
+
var topDelta = menuTop - (targetRect.top + targetRect.height);
|
|
139
|
+
var adjustedTop = ((_position$top = position.top) !== null && _position$top !== void 0 ? _position$top : 0) + topDelta;
|
|
140
|
+
|
|
141
|
+
// Horizontal: position to the right of the cursor
|
|
142
|
+
var leftDelta = endCoords.right - targetRect.right;
|
|
143
|
+
var adjustedLeft = ((_position$left = position.left) !== null && _position$left !== void 0 ? _position$left : 0) + leftDelta;
|
|
144
|
+
return _objectSpread(_objectSpread({}, position), {}, {
|
|
145
|
+
top: adjustedTop,
|
|
146
|
+
left: adjustedLeft
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Adjusts the position of the paste menu so that:
|
|
153
|
+
*
|
|
154
|
+
* **Vertical:** The menu aligns with the top of the pasted content using the
|
|
155
|
+
* exact coordinates at the paste start position, and sticks to the top of the
|
|
156
|
+
* scroll container when the pasted content scrolls above the visible area.
|
|
89
157
|
*
|
|
90
158
|
* The Popup uses alignY="bottom", which positions the popup below the target
|
|
91
159
|
* element's bottom edge. This override:
|
|
@@ -96,21 +164,31 @@ function getVisualEndBottom(editorView, pasteEndPos, tableAfterPos) {
|
|
|
96
164
|
* to the scroll container's top edge (sticky-top).
|
|
97
165
|
* 3. Stops sticking once the entire pasted range (pasteEndPos) has scrolled
|
|
98
166
|
* above the visible area.
|
|
167
|
+
*
|
|
168
|
+
* **Horizontal:** When the target element is an inline element (e.g. a mark
|
|
169
|
+
* wrapper like `<strong>`, or an inline node like an emoji), the Popup's
|
|
170
|
+
* `alignX="end"` would place the menu at the right edge of that narrow
|
|
171
|
+
* element. This override resolves the nearest block-level ProseMirror
|
|
172
|
+
* ancestor (using `node.isBlock` from the document schema) and re-anchors
|
|
173
|
+
* the horizontal position to its right edge, so the menu consistently
|
|
174
|
+
* appears at the right side of the content area.
|
|
99
175
|
*/
|
|
100
176
|
function onPositionCalculated(editorView, pasteStartPos, pasteEndPos, targetElement, scrollableElement) {
|
|
101
177
|
// Pre-compute once per render to avoid doc.resolve() on every scroll frame.
|
|
102
178
|
var tableAfterPos = resolveTableAfterPos(editorView, pasteEndPos);
|
|
179
|
+
var blockAncestorDOM = findBlockAncestorDOM(editorView, pasteStartPos);
|
|
103
180
|
return function (position) {
|
|
104
|
-
var _position$
|
|
181
|
+
var _position$top2;
|
|
105
182
|
var startCoords = editorView.coordsAtPos(pasteStartPos);
|
|
106
183
|
var endBottom = getVisualEndBottom(editorView, pasteEndPos, tableAfterPos);
|
|
107
184
|
var targetRect = targetElement.getBoundingClientRect();
|
|
108
185
|
|
|
186
|
+
// ── Vertical adjustment ──────────────────────────────────────────
|
|
109
187
|
// The Popup places the menu at the target's bottom edge by default.
|
|
110
188
|
// We shift it up so it aligns with the paste start position.
|
|
111
189
|
// Both coordinates are in viewport space, so the delta is offset-parent agnostic.
|
|
112
190
|
var topDelta = startCoords.top - (targetRect.top + targetRect.height);
|
|
113
|
-
var adjustedTop = ((_position$
|
|
191
|
+
var adjustedTop = ((_position$top2 = position.top) !== null && _position$top2 !== void 0 ? _position$top2 : 0) + topDelta;
|
|
114
192
|
|
|
115
193
|
// Sticky-top: clamp to the scroll container's top edge when the paste
|
|
116
194
|
// start has scrolled above the visible area, but only while some pasted
|
|
@@ -121,8 +199,28 @@ function onPositionCalculated(editorView, pasteStartPos, pasteEndPos, targetElem
|
|
|
121
199
|
adjustedTop += scrollContainerTop - startCoords.top + _constants.PASTE_MENU_GAP_TOP;
|
|
122
200
|
}
|
|
123
201
|
}
|
|
202
|
+
|
|
203
|
+
// ── Horizontal adjustment ────────────────────────────────────────
|
|
204
|
+
// When pasted content starts with a mark (bold, italic, link …) or
|
|
205
|
+
// an inline node (emoji, smart link, inline image …),
|
|
206
|
+
// findDomRefAtPos returns the narrow inline wrapper element. The
|
|
207
|
+
// Popup's alignX="end" then places the menu at that element's right
|
|
208
|
+
// edge instead of the content area's right edge. We correct this by
|
|
209
|
+
// resolving the nearest block-level ProseMirror ancestor and
|
|
210
|
+
// re-anchoring to its right edge.
|
|
211
|
+
var adjustedLeft = position.left;
|
|
212
|
+
if (blockAncestorDOM && blockAncestorDOM !== targetElement) {
|
|
213
|
+
var _position$left2;
|
|
214
|
+
var blockRect = blockAncestorDOM.getBoundingClientRect();
|
|
215
|
+
// Shift left by the difference between the block's right edge and
|
|
216
|
+
// the inline target's right edge. This mirrors what alignX="end"
|
|
217
|
+
// would have computed if the target were the block element.
|
|
218
|
+
var leftDelta = blockRect.right - targetRect.right;
|
|
219
|
+
adjustedLeft = ((_position$left2 = position.left) !== null && _position$left2 !== void 0 ? _position$left2 : 0) + leftDelta;
|
|
220
|
+
}
|
|
124
221
|
return _objectSpread(_objectSpread({}, position), {}, {
|
|
125
|
-
top: adjustedTop
|
|
222
|
+
top: adjustedTop,
|
|
223
|
+
left: adjustedLeft
|
|
126
224
|
});
|
|
127
225
|
};
|
|
128
226
|
}
|
|
@@ -142,8 +240,8 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
142
240
|
}),
|
|
143
241
|
lastContentPasted = _useSharedPluginState.lastContentPasted;
|
|
144
242
|
var prevShowToolbarRef = (0, _react.useRef)(false);
|
|
243
|
+
var popupContentRef = (0, _react.useRef)(null);
|
|
145
244
|
(0, _react.useEffect)(function () {
|
|
146
|
-
var _lastContentPasted$te, _lastContentPasted$te2;
|
|
147
245
|
if (!lastContentPasted) {
|
|
148
246
|
(0, _commands.hideToolbar)()(editorView.state, editorView.dispatch);
|
|
149
247
|
return;
|
|
@@ -166,7 +264,7 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
166
264
|
pasteAncestorNodeNames.push($pos.node(depth).type.name);
|
|
167
265
|
}
|
|
168
266
|
}
|
|
169
|
-
var legacyVisible = (0, _toolbar2.isToolbarVisible)(editorView.state, lastContentPasted)
|
|
267
|
+
var legacyVisible = (0, _toolbar2.isToolbarVisible)(editorView.state, lastContentPasted);
|
|
170
268
|
(0, _commands.showToolbar)(lastContentPasted, selectedOption, legacyVisible, pasteAncestorNodeNames)(editorView.state, editorView.dispatch);
|
|
171
269
|
}, [lastContentPasted, editorView]);
|
|
172
270
|
var _useSharedPluginState2 = (0, _hooks.useSharedPluginStateWithSelector)(api, ['pasteOptionsToolbarPlugin'], function (states) {
|
|
@@ -230,16 +328,36 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
230
328
|
var effectiveScrollableElement = overflowScrollParent || scrollableElement;
|
|
231
329
|
var pasteMenuComponents = (_api$uiControlRegistr3 = api === null || api === void 0 || (_api$uiControlRegistr4 = api.uiControlRegistry) === null || _api$uiControlRegistr4 === void 0 ? void 0 : _api$uiControlRegistr4.actions.getComponents(_toolbar.PASTE_MENU.key)) !== null && _api$uiControlRegistr3 !== void 0 ? _api$uiControlRegistr3 : [];
|
|
232
330
|
var anyComponentVisible = (0, _hasVisibleButton.hasVisibleButton)(pasteMenuComponents);
|
|
331
|
+
|
|
332
|
+
// Two positioning modes:
|
|
333
|
+
// 1. Inline: no AI actions visible — menu appears to the right of the cursor,
|
|
334
|
+
// vertically centered with the text line.
|
|
335
|
+
// 2. Block-anchored: AI actions are visible — menu appears at the right edge
|
|
336
|
+
// of the content block, aligned with paste start.
|
|
337
|
+
var hasVisibleAiActions = (0, _hasVisibleButton.getVisibleKeys)(
|
|
338
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-computations-in-render -- pasteMenuComponents changes by reference each render; filter is small (< 10 items)
|
|
339
|
+
pasteMenuComponents.filter(function (c) {
|
|
340
|
+
var _c$parents;
|
|
341
|
+
return c.type === 'menu-item' && ((_c$parents = c.parents) === null || _c$parents === void 0 ? void 0 : _c$parents.some(function (p) {
|
|
342
|
+
return p.key === _toolbar.AI_PASTE_MENU_SECTION.key;
|
|
343
|
+
}));
|
|
344
|
+
}), ['menu-item']).length > 0;
|
|
345
|
+
var useInlinePosition = !hasVisibleAiActions;
|
|
233
346
|
if (!isToolbarShown) {
|
|
234
347
|
return null;
|
|
235
348
|
}
|
|
236
349
|
if (!anyComponentVisible) {
|
|
237
350
|
return null;
|
|
238
351
|
}
|
|
239
|
-
var target = getTargetElement(editorView, pasteStartPos);
|
|
352
|
+
var target = getTargetElement(editorView, useInlinePosition ? pasteEndPos : pasteStartPos);
|
|
240
353
|
if (!target) {
|
|
241
354
|
return null;
|
|
242
355
|
}
|
|
356
|
+
|
|
357
|
+
// Choose positioning strategy based on whether the menu appears inline
|
|
358
|
+
// (right of cursor for short pastes) or anchored to the block ancestor
|
|
359
|
+
// (right side of content area for longer pastes / AI actions).
|
|
360
|
+
var positionCalculator = useInlinePosition ? onInlinePositionCalculated(editorView, pasteEndPos, target, popupContentRef) : onPositionCalculated(editorView, pasteStartPos, pasteEndPos, target, effectiveScrollableElement);
|
|
243
361
|
return /*#__PURE__*/_react.default.createElement(PopupWithListeners, {
|
|
244
362
|
target: target,
|
|
245
363
|
mountTo: mountTo,
|
|
@@ -248,9 +366,10 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
248
366
|
minPopupMargin: _constants.PASTE_MENU_GAP_HORIZONTAL,
|
|
249
367
|
zIndex: _editorSharedStyles.akEditorFloatingPanelZIndex,
|
|
250
368
|
alignX: "end",
|
|
251
|
-
alignY:
|
|
369
|
+
alignY: useInlinePosition ? 'top' : 'bottom'
|
|
370
|
+
/* eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) */,
|
|
252
371
|
offset: [_constants.PASTE_MENU_GAP_HORIZONTAL, 0],
|
|
253
|
-
onPositionCalculated:
|
|
372
|
+
onPositionCalculated: positionCalculator,
|
|
254
373
|
handleClickOutside: handleClickOutside,
|
|
255
374
|
handleEscapeKeydown: handleDismiss
|
|
256
375
|
}, /*#__PURE__*/_react.default.createElement(_toolbar.EditorToolbarProvider, {
|
|
@@ -261,6 +380,7 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
261
380
|
}, /*#__PURE__*/_react.default.createElement(_PasteActionsMenuContent.PasteActionsMenuContent, {
|
|
262
381
|
onMouseDown: preventEditorFocusLoss,
|
|
263
382
|
onMouseEnter: handleMouseEnter,
|
|
264
|
-
components: pasteMenuComponents
|
|
383
|
+
components: pasteMenuComponents,
|
|
384
|
+
contentRef: popupContentRef
|
|
265
385
|
}))));
|
|
266
386
|
};
|
|
@@ -9,34 +9,37 @@ exports.PasteActionsMenuContent = void 0;
|
|
|
9
9
|
require("./PasteActionsMenuContent.compiled.css");
|
|
10
10
|
var _runtime = require("@compiled/react/runtime");
|
|
11
11
|
var _react = _interopRequireWildcard(require("react"));
|
|
12
|
-
var
|
|
13
|
-
var _messages = require("@atlaskit/editor-common/messages");
|
|
12
|
+
var _toolbar = require("@atlaskit/editor-common/toolbar");
|
|
14
13
|
var _uiReact = require("@atlaskit/editor-common/ui-react");
|
|
15
|
-
var _editorToolbar = require("@atlaskit/editor-toolbar");
|
|
16
14
|
var _editorUiControlModel = require("@atlaskit/editor-ui-control-model");
|
|
17
15
|
var _compiled = require("@atlaskit/primitives/compiled");
|
|
18
16
|
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); }
|
|
19
17
|
var styles = {
|
|
20
18
|
container: "_2rko12b0 _bfhk1bhr _16qs130s"
|
|
21
19
|
};
|
|
20
|
+
var pasteMenuSurface = {
|
|
21
|
+
type: _toolbar.PASTE_MENU.type,
|
|
22
|
+
key: _toolbar.PASTE_MENU.key
|
|
23
|
+
};
|
|
22
24
|
var PasteActionsMenuContent = exports.PasteActionsMenuContent = function PasteActionsMenuContent(_ref) {
|
|
23
25
|
var onMouseDown = _ref.onMouseDown,
|
|
24
26
|
onMouseEnter = _ref.onMouseEnter,
|
|
25
|
-
components = _ref.components
|
|
27
|
+
components = _ref.components,
|
|
28
|
+
contentRef = _ref.contentRef;
|
|
26
29
|
var setOutsideClickTargetRef = (0, _react.useContext)(_uiReact.OutsideClickTargetRefContext);
|
|
27
|
-
var
|
|
30
|
+
var mergedRef = (0, _react.useCallback)(function (node) {
|
|
31
|
+
setOutsideClickTargetRef === null || setOutsideClickTargetRef === void 0 || setOutsideClickTargetRef(node);
|
|
32
|
+
if (contentRef) {
|
|
33
|
+
contentRef.current = node;
|
|
34
|
+
}
|
|
35
|
+
}, [setOutsideClickTargetRef, contentRef]);
|
|
28
36
|
return /*#__PURE__*/_react.default.createElement(_compiled.Box, {
|
|
29
|
-
ref:
|
|
37
|
+
ref: mergedRef,
|
|
30
38
|
xcss: styles.container,
|
|
31
39
|
onMouseDown: onMouseDown,
|
|
32
40
|
onMouseEnter: onMouseEnter
|
|
33
|
-
}, /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItemSection, {
|
|
34
|
-
title: intl.formatMessage(_messages.pasteOptionsToolbarMessages.pasteMenuActionsTitle)
|
|
35
41
|
}, /*#__PURE__*/_react.default.createElement(_editorUiControlModel.SurfaceRenderer, {
|
|
36
|
-
surface:
|
|
37
|
-
type: 'menu',
|
|
38
|
-
key: 'paste-menu'
|
|
39
|
-
},
|
|
42
|
+
surface: pasteMenuSurface,
|
|
40
43
|
components: components
|
|
41
|
-
}))
|
|
44
|
+
}));
|
|
42
45
|
};
|
|
@@ -16,12 +16,14 @@ var _hooks = require("@atlaskit/editor-common/hooks");
|
|
|
16
16
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
17
17
|
var _toolbar = require("@atlaskit/editor-common/toolbar");
|
|
18
18
|
var _editorToolbar = require("@atlaskit/editor-toolbar");
|
|
19
|
+
var _chevronDown = _interopRequireDefault(require("@atlaskit/icon/core/chevron-down"));
|
|
19
20
|
var _chevronRight = _interopRequireDefault(require("@atlaskit/icon/core/chevron-right"));
|
|
20
21
|
var _clipboard = _interopRequireDefault(require("@atlaskit/icon/core/clipboard"));
|
|
21
22
|
var _compiled = require("@atlaskit/primitives/compiled");
|
|
22
23
|
var _commands = require("../../editor-commands/commands");
|
|
23
24
|
var _types = require("../../types/types");
|
|
24
25
|
var _hasVisibleButton = require("./hasVisibleButton");
|
|
26
|
+
var _PasteOptionsDropdownButton = require("./PasteOptionsDropdownButton");
|
|
25
27
|
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); }
|
|
26
28
|
var nestedMenuStyles = {
|
|
27
29
|
narrowSection: "_10gv1lit"
|
|
@@ -100,21 +102,49 @@ var PasteMenuItem = function PasteMenuItem(_ref) {
|
|
|
100
102
|
}, displayLabel);
|
|
101
103
|
};
|
|
102
104
|
var PasteOptionsNestedMenu = function PasteOptionsNestedMenu(_ref2) {
|
|
103
|
-
var children = _ref2.children
|
|
105
|
+
var children = _ref2.children,
|
|
106
|
+
hasVisibleAiActions = _ref2.hasVisibleAiActions;
|
|
104
107
|
var intl = (0, _reactIntlNext.useIntl)();
|
|
108
|
+
var label = intl.formatMessage(_messages.pasteOptionsToolbarMessages.pasteMenuActionsPasteAs);
|
|
109
|
+
if (!hasVisibleAiActions) {
|
|
110
|
+
return /*#__PURE__*/_react.default.createElement(_PasteOptionsDropdownButton.PasteOptionsDropdownButton, {
|
|
111
|
+
elemBefore: /*#__PURE__*/_react.default.createElement(_clipboard.default, {
|
|
112
|
+
size: "small",
|
|
113
|
+
label: ""
|
|
114
|
+
}),
|
|
115
|
+
elemAfter: /*#__PURE__*/_react.default.createElement(_chevronDown.default, {
|
|
116
|
+
size: "small",
|
|
117
|
+
label: ""
|
|
118
|
+
}),
|
|
119
|
+
label: label,
|
|
120
|
+
testId: "paste-options-nested-menu",
|
|
121
|
+
tooltipContent: label
|
|
122
|
+
}, children);
|
|
123
|
+
}
|
|
105
124
|
return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarNestedDropdownMenu, {
|
|
106
125
|
elemBefore: /*#__PURE__*/_react.default.createElement(_clipboard.default, {
|
|
107
126
|
size: "small",
|
|
108
|
-
label:
|
|
127
|
+
label: label
|
|
109
128
|
}),
|
|
110
129
|
elemAfter: /*#__PURE__*/_react.default.createElement(_chevronRight.default, {
|
|
111
130
|
size: "small",
|
|
112
|
-
label:
|
|
131
|
+
label: ""
|
|
113
132
|
}),
|
|
114
133
|
testId: "paste-options-nested-menu",
|
|
115
|
-
text:
|
|
134
|
+
text: label
|
|
116
135
|
}, children);
|
|
117
136
|
};
|
|
137
|
+
var getHasVisibleAiActions = function getHasVisibleAiActions(api) {
|
|
138
|
+
var _api$uiControlRegistr, _api$uiControlRegistr2;
|
|
139
|
+
var allComponents = (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(_toolbar.PASTE_MENU.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
|
|
140
|
+
var aiMenuItems = allComponents.filter(function (c) {
|
|
141
|
+
var _c$parents;
|
|
142
|
+
return c.type === 'menu-item' && ((_c$parents = c.parents) === null || _c$parents === void 0 ? void 0 : _c$parents.some(function (p) {
|
|
143
|
+
return p.key === _toolbar.AI_PASTE_MENU_SECTION.key;
|
|
144
|
+
}));
|
|
145
|
+
});
|
|
146
|
+
return (0, _hasVisibleButton.getVisibleKeys)(aiMenuItems, ['menu-item']).length > 0;
|
|
147
|
+
};
|
|
118
148
|
var getPasteMenuComponents = exports.getPasteMenuComponents = function getPasteMenuComponents(_ref3) {
|
|
119
149
|
var api = _ref3.api;
|
|
120
150
|
return [{
|
|
@@ -134,17 +164,14 @@ var getPasteMenuComponents = exports.getPasteMenuComponents = function getPasteM
|
|
|
134
164
|
return !((_pluginState$showLega = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLegacyOptions) !== null && _pluginState$showLega !== void 0 ? _pluginState$showLega : false);
|
|
135
165
|
},
|
|
136
166
|
component: function component(props) {
|
|
137
|
-
var
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}));
|
|
144
|
-
});
|
|
145
|
-
var hasVisibleAiActions = (0, _hasVisibleButton.getVisibleKeys)(aiMenuItems, ['menu-item']).length > 0;
|
|
167
|
+
var hasVisibleAiActions = getHasVisibleAiActions(api);
|
|
168
|
+
if (!hasVisibleAiActions) {
|
|
169
|
+
return /*#__PURE__*/_react.default.createElement(_compiled.Box, {
|
|
170
|
+
padding: "space.050"
|
|
171
|
+
}, props.children);
|
|
172
|
+
}
|
|
146
173
|
return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItemSection, {
|
|
147
|
-
hasSeparator:
|
|
174
|
+
hasSeparator: true
|
|
148
175
|
}, props.children);
|
|
149
176
|
}
|
|
150
177
|
}, {
|
|
@@ -156,7 +183,10 @@ var getPasteMenuComponents = exports.getPasteMenuComponents = function getPasteM
|
|
|
156
183
|
rank: _toolbar.PASTE_MENU_SECTION_RANK[_toolbar.PASTE_NESTED_MENU.key]
|
|
157
184
|
}],
|
|
158
185
|
component: function component(props) {
|
|
159
|
-
|
|
186
|
+
var hasVisibleAiActions = getHasVisibleAiActions(api);
|
|
187
|
+
return /*#__PURE__*/_react.default.createElement(PasteOptionsNestedMenu, {
|
|
188
|
+
hasVisibleAiActions: hasVisibleAiActions
|
|
189
|
+
}, props.children);
|
|
160
190
|
}
|
|
161
191
|
}, {
|
|
162
192
|
type: _toolbar.PASTE_MENU_NESTED_SECTION.type,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* PasteOptionsDropdownButton.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
5
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
6
|
+
Object.defineProperty(exports, "__esModule", {
|
|
7
|
+
value: true
|
|
8
|
+
});
|
|
9
|
+
exports.PasteOptionsDropdownButton = void 0;
|
|
10
|
+
var _runtime = require("@compiled/react/runtime");
|
|
11
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
12
|
+
var _dropdownMenu = _interopRequireDefault(require("@atlaskit/dropdown-menu"));
|
|
13
|
+
var _editorToolbar = require("@atlaskit/editor-toolbar");
|
|
14
|
+
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); }
|
|
15
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
16
|
+
/**
|
|
17
|
+
* A compact dropdown button for paste options, styled like floating toolbar buttons.
|
|
18
|
+
* Renders as a ToolbarButton with an icon and dropdown caret that opens a
|
|
19
|
+
* dropdown menu below. Used when AI actions are not visible and the paste
|
|
20
|
+
* options menu is the only content.
|
|
21
|
+
*/
|
|
22
|
+
var PasteOptionsDropdownButton = exports.PasteOptionsDropdownButton = function PasteOptionsDropdownButton(_ref) {
|
|
23
|
+
var children = _ref.children,
|
|
24
|
+
elemBefore = _ref.elemBefore,
|
|
25
|
+
elemAfter = _ref.elemAfter,
|
|
26
|
+
label = _ref.label,
|
|
27
|
+
testId = _ref.testId,
|
|
28
|
+
tooltipContent = _ref.tooltipContent;
|
|
29
|
+
var trigger = (0, _react.useCallback)(function (triggerProps) {
|
|
30
|
+
var button = /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarButton, {
|
|
31
|
+
ref: triggerProps.triggerRef,
|
|
32
|
+
isSelected: triggerProps.isSelected,
|
|
33
|
+
"aria-expanded": triggerProps['aria-expanded'],
|
|
34
|
+
"aria-haspopup": triggerProps['aria-haspopup'],
|
|
35
|
+
onClick: triggerProps.onClick,
|
|
36
|
+
testId: testId,
|
|
37
|
+
iconBefore: elemBefore,
|
|
38
|
+
label: label
|
|
39
|
+
}, elemAfter);
|
|
40
|
+
if (tooltipContent) {
|
|
41
|
+
return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarTooltip, {
|
|
42
|
+
content: tooltipContent,
|
|
43
|
+
position: "top"
|
|
44
|
+
}, button);
|
|
45
|
+
}
|
|
46
|
+
return button;
|
|
47
|
+
}, [testId, elemBefore, elemAfter, label, tooltipContent]);
|
|
48
|
+
return /*#__PURE__*/_react.default.createElement(_dropdownMenu.default, {
|
|
49
|
+
placement: "bottom-start",
|
|
50
|
+
trigger: trigger
|
|
51
|
+
}, children);
|
|
52
|
+
};
|
|
@@ -152,7 +152,7 @@ export function getMarkdownSlice(text, schema, selection) {
|
|
|
152
152
|
for (let i = 0; i < textSplitByCodeBlock.length; i++) {
|
|
153
153
|
if (i % 2 === 0) {
|
|
154
154
|
// Ignored via go/ees005
|
|
155
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
155
|
+
// eslint-disable-next-line require-unicode-regexp, @atlassian/perf-linting/no-expensive-split-replace -- Ignored via go/ees017 (to be fixed)
|
|
156
156
|
textSplitByCodeBlock[i] = textSplitByCodeBlock[i].replace(/\\/g, '\\\\');
|
|
157
157
|
}
|
|
158
158
|
}
|