@atlaskit/editor-plugin-paste-options-toolbar 9.0.0 → 9.0.2

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/pm-plugins/constants.js +5 -2
  3. package/dist/cjs/pm-plugins/plugin-factory.js +33 -33
  4. package/dist/cjs/ui/on-paste-actions-menu/PasteActionsMenu.js +42 -15
  5. package/dist/cjs/ui/on-paste-actions-menu/PasteActionsMenuContent.compiled.css +1 -2
  6. package/dist/cjs/ui/on-paste-actions-menu/PasteActionsMenuContent.js +1 -1
  7. package/dist/cjs/ui/on-paste-actions-menu/PasteMenuComponents.js +11 -1
  8. package/dist/es2019/pm-plugins/constants.js +4 -1
  9. package/dist/es2019/pm-plugins/plugin-factory.js +4 -5
  10. package/dist/es2019/ui/on-paste-actions-menu/PasteActionsMenu.js +38 -17
  11. package/dist/es2019/ui/on-paste-actions-menu/PasteActionsMenuContent.compiled.css +1 -2
  12. package/dist/es2019/ui/on-paste-actions-menu/PasteActionsMenuContent.js +1 -1
  13. package/dist/es2019/ui/on-paste-actions-menu/PasteMenuComponents.js +14 -4
  14. package/dist/esm/pm-plugins/constants.js +4 -1
  15. package/dist/esm/pm-plugins/plugin-factory.js +33 -34
  16. package/dist/esm/ui/on-paste-actions-menu/PasteActionsMenu.js +40 -15
  17. package/dist/esm/ui/on-paste-actions-menu/PasteActionsMenuContent.compiled.css +1 -2
  18. package/dist/esm/ui/on-paste-actions-menu/PasteActionsMenuContent.js +1 -1
  19. package/dist/esm/ui/on-paste-actions-menu/PasteMenuComponents.js +12 -2
  20. package/dist/types/pm-plugins/constants.d.ts +1 -0
  21. package/dist/types/pm-plugins/main.d.ts +2 -1
  22. package/dist/types/pm-plugins/plugin-factory.d.ts +7 -1
  23. package/dist/types/types/types.d.ts +1 -1
  24. package/dist/types/ui/on-paste-actions-menu/PasteActionsMenu.d.ts +21 -0
  25. package/dist/types/ui/on-paste-actions-menu/PasteMenuComponents.d.ts +1 -1
  26. package/dist/types-ts4.5/pm-plugins/constants.d.ts +1 -0
  27. package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -1
  28. package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +7 -1
  29. package/dist/types-ts4.5/types/types.d.ts +1 -1
  30. package/dist/types-ts4.5/ui/on-paste-actions-menu/PasteActionsMenu.d.ts +21 -0
  31. package/dist/types-ts4.5/ui/on-paste-actions-menu/PasteMenuComponents.d.ts +1 -1
  32. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-plugin-paste-options-toolbar
2
2
 
3
+ ## 9.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`6ebc53b2b151d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6ebc53b2b151d) -
8
+ [ux] [EDITOR-5821] updated paste menu position so that its the same as the inline comment editor'
9
+ - Updated dependencies
10
+
11
+ ## 9.0.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [`52d4528d79431`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/52d4528d79431) -
16
+ [ux] EDITOR-5896 Minor paste menu cleanup. Reduce padding and remove separator from legacy paste
17
+ actions when there's no AI paste actions
18
+
3
19
  ## 9.0.0
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;
@@ -13,45 +13,45 @@ var _constants = require("./constants");
13
13
  var _reducer = require("./reducer");
14
14
  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; }
15
15
  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; }
16
- var _pluginFactory = (0, _utils.pluginFactory)(_types.pasteOptionsPluginKey, _reducer.reducer, {
17
- mapping: function mapping(tr, pluginState) {
18
- if (!tr.docChanged || !pluginState.showToolbar) {
19
- return pluginState;
20
- }
21
- var oldPasteStartPos = pluginState.pasteStartPos;
22
- var oldPasteEndPos = pluginState.pasteEndPos;
23
- var newPasteStartPos = tr.mapping.map(oldPasteStartPos);
24
- var newPasteEndPos = tr.mapping.map(oldPasteEndPos);
16
+ var dest = (0, _utils.pluginFactory)(_types.pasteOptionsPluginKey, _reducer.reducer, {
17
+ mapping: function mapping(tr, pluginState) {
18
+ if (!tr.docChanged || !pluginState.showToolbar) {
19
+ return pluginState;
20
+ }
21
+ var oldPasteStartPos = pluginState.pasteStartPos;
22
+ var oldPasteEndPos = pluginState.pasteEndPos;
23
+ var newPasteStartPos = tr.mapping.map(oldPasteStartPos);
24
+ var newPasteEndPos = tr.mapping.map(oldPasteEndPos);
25
25
 
26
- //this is true when user changes format from the toolbar.
27
- //only change pasteEndPos in this case
28
- if (changedFormatFromToolbar(tr)) {
29
- return _objectSpread(_objectSpread({}, pluginState), {}, {
30
- pasteEndPos: newPasteEndPos
31
- });
32
- }
33
- if (oldPasteStartPos === newPasteStartPos && oldPasteEndPos === newPasteEndPos) {
34
- return pluginState;
35
- }
26
+ //this is true when user changes format from the toolbar.
27
+ //only change pasteEndPos in this case
28
+ if (changedFormatFromToolbar(tr)) {
36
29
  return _objectSpread(_objectSpread({}, pluginState), {}, {
37
- pasteStartPos: newPasteStartPos,
38
30
  pasteEndPos: newPasteEndPos
39
31
  });
40
- },
41
- onSelectionChanged: function onSelectionChanged(tr, pluginState) {
42
- // Detect click outside the editor
43
- if (tr.getMeta('outsideProsemirrorEditorClicked')) {
44
- return _objectSpread(_objectSpread({}, pluginState), {}, {
45
- showToolbar: false,
46
- highlightContent: false
47
- });
48
- }
32
+ }
33
+ if (oldPasteStartPos === newPasteStartPos && oldPasteEndPos === newPasteEndPos) {
49
34
  return pluginState;
50
35
  }
51
- }),
52
- createPluginState = exports.createPluginState = _pluginFactory.createPluginState,
53
- createCommand = exports.createCommand = _pluginFactory.createCommand,
54
- getPluginState = exports.getPluginState = _pluginFactory.getPluginState;
36
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
37
+ pasteStartPos: newPasteStartPos,
38
+ pasteEndPos: newPasteEndPos
39
+ });
40
+ },
41
+ onSelectionChanged: function onSelectionChanged(tr, pluginState) {
42
+ // Detect click outside the editor
43
+ if (tr.getMeta('outsideProsemirrorEditorClicked')) {
44
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
45
+ showToolbar: false,
46
+ highlightContent: false
47
+ });
48
+ }
49
+ return pluginState;
50
+ }
51
+ });
52
+ var createPluginState = exports.createPluginState = dest.createPluginState;
53
+ var createCommand = exports.createCommand = dest.createCommand;
54
+ var getPluginState = exports.getPluginState = dest.getPluginState;
55
55
  var changedFormatFromToolbar = function changedFormatFromToolbar(tr) {
56
56
  var meta = tr.getMeta(_constants.PASTE_OPTIONS_META_ID);
57
57
  if (meta && meta.type === _actions.PastePluginActionTypes.CHANGE_FORMAT) {
@@ -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)(from, editorView.domAtPos.bind(editorView));
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
- function getPopupOffset(dom) {
37
- if (!dom) {
38
- return [0, 20];
39
- }
40
- var rightEdge = dom.getBoundingClientRect().right;
41
- return [-(window.innerWidth - rightEdge - 50), 20];
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: "right",
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, {
@@ -1,4 +1,3 @@
1
1
 
2
- ._2rko12b0{border-radius:var(--ds-radius-small,4px)}
3
- ._1rjc1b66{padding-block:var(--ds-space-050,4px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
2
+ ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
4
3
  ._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
@@ -17,7 +17,7 @@ var _editorUiControlModel = require("@atlaskit/editor-ui-control-model");
17
17
  var _compiled = require("@atlaskit/primitives/compiled");
18
18
  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
19
  var styles = {
20
- container: "_2rko12b0 _1rjc1b66 _bfhk1bhr _16qs130s"
20
+ container: "_2rko12b0 _bfhk1bhr _16qs130s"
21
21
  };
22
22
  var PasteActionsMenuContent = exports.PasteActionsMenuContent = function PasteActionsMenuContent(_ref) {
23
23
  var onMouseDown = _ref.onMouseDown,
@@ -21,6 +21,7 @@ var _clipboard = _interopRequireDefault(require("@atlaskit/icon/core/clipboard")
21
21
  var _compiled = require("@atlaskit/primitives/compiled");
22
22
  var _commands = require("../../editor-commands/commands");
23
23
  var _types = require("../../types/types");
24
+ var _hasVisibleButton = require("./hasVisibleButton");
24
25
  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); }
25
26
  var nestedMenuStyles = {
26
27
  narrowSection: "_10gv1lit"
@@ -133,8 +134,17 @@ var getPasteMenuComponents = exports.getPasteMenuComponents = function getPasteM
133
134
  return !((_pluginState$showLega = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLegacyOptions) !== null && _pluginState$showLega !== void 0 ? _pluginState$showLega : false);
134
135
  },
135
136
  component: function component(props) {
137
+ var _api$uiControlRegistr, _api$uiControlRegistr2;
138
+ 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 : [];
139
+ var aiMenuItems = allComponents.filter(function (c) {
140
+ var _c$parents;
141
+ return c.type === 'menu-item' && ((_c$parents = c.parents) === null || _c$parents === void 0 ? void 0 : _c$parents.some(function (p) {
142
+ return p.key === _toolbar.AI_PASTE_MENU_SECTION.key;
143
+ }));
144
+ });
145
+ var hasVisibleAiActions = (0, _hasVisibleButton.getVisibleKeys)(aiMenuItems, ['menu-item']).length > 0;
136
146
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarDropdownItemSection, {
137
- hasSeparator: true
147
+ hasSeparator: hasVisibleAiActions
138
148
  }, props.children);
139
149
  }
140
150
  }, {
@@ -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;
@@ -3,11 +3,7 @@ import { PastePluginActionTypes } from '../editor-actions/actions';
3
3
  import { pasteOptionsPluginKey } from '../types/types';
4
4
  import { PASTE_OPTIONS_META_ID } from './constants';
5
5
  import { reducer } from './reducer';
6
- export const {
7
- createPluginState,
8
- createCommand,
9
- getPluginState
10
- } = pluginFactory(pasteOptionsPluginKey, reducer, {
6
+ const dest = pluginFactory(pasteOptionsPluginKey, reducer, {
11
7
  mapping: (tr, pluginState) => {
12
8
  if (!tr.docChanged || !pluginState.showToolbar) {
13
9
  return pluginState;
@@ -46,6 +42,9 @@ export const {
46
42
  return pluginState;
47
43
  }
48
44
  });
45
+ export const createPluginState = dest.createPluginState;
46
+ export const createCommand = dest.createCommand;
47
+ export const getPluginState = dest.getPluginState;
49
48
  const changedFormatFromToolbar = tr => {
50
49
  const meta = tr.getMeta(PASTE_OPTIONS_META_ID);
51
50
  if (meta && meta.type === PastePluginActionTypes.CHANGE_FORMAT) {
@@ -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(from, editorView.domAtPos.bind(editorView));
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
- function getPopupOffset(dom) {
31
- if (!dom) {
32
- return [0, 20];
33
- }
34
- const rightEdge = dom.getBoundingClientRect().right;
35
- return [-(window.innerWidth - rightEdge - 50), 20];
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: "right",
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, {
@@ -1,4 +1,3 @@
1
1
 
2
- ._2rko12b0{border-radius:var(--ds-radius-small,4px)}
3
- ._1rjc1b66{padding-block:var(--ds-space-050,4px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
2
+ ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
4
3
  ._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
@@ -9,7 +9,7 @@ import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
9
9
  import { SurfaceRenderer } from '@atlaskit/editor-ui-control-model';
10
10
  import { Box } from '@atlaskit/primitives/compiled';
11
11
  const styles = {
12
- container: "_2rko12b0 _1rjc1b66 _bfhk1bhr _16qs130s"
12
+ container: "_2rko12b0 _bfhk1bhr _16qs130s"
13
13
  };
14
14
  export const PasteActionsMenuContent = ({
15
15
  onMouseDown,
@@ -6,13 +6,14 @@ import { cx } from '@compiled/react';
6
6
  import { useIntl } from 'react-intl-next';
7
7
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
8
8
  import { pasteOptionsToolbarMessages as messages } from '@atlaskit/editor-common/messages';
9
- import { useEditorToolbar, PASTE_MENU, PASTE_MENU_SECTION, PASTE_NESTED_MENU, PASTE_MENU_NESTED_SECTION, PASTE_RICH_TEXT_MENU_ITEM, PASTE_MARKDOWN_MENU_ITEM, PASTE_PLAIN_TEXT_MENU_ITEM, PASTE_MENU_RANK, PASTE_MENU_SECTION_RANK, PASTE_NESTED_MENU_RANK, PASTE_MENU_NESTED_SECTION_RANK } from '@atlaskit/editor-common/toolbar';
9
+ import { useEditorToolbar, PASTE_MENU, PASTE_MENU_SECTION, PASTE_NESTED_MENU, PASTE_MENU_NESTED_SECTION, PASTE_RICH_TEXT_MENU_ITEM, PASTE_MARKDOWN_MENU_ITEM, PASTE_PLAIN_TEXT_MENU_ITEM, PASTE_MENU_RANK, PASTE_MENU_SECTION_RANK, PASTE_NESTED_MENU_RANK, PASTE_MENU_NESTED_SECTION_RANK, AI_PASTE_MENU_SECTION } from '@atlaskit/editor-common/toolbar';
10
10
  import { ToolbarDropdownItem, ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
11
11
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
12
12
  import ClipboardIcon from '@atlaskit/icon/core/clipboard';
13
13
  import { Box } from '@atlaskit/primitives/compiled';
14
14
  import { changeToMarkdownWithAnalytics, changeToPlainTextWithAnalytics, changeToRichTextWithAnalytics } from '../../editor-commands/commands';
15
15
  import { ToolbarDropdownOption } from '../../types/types';
16
+ import { getVisibleKeys } from './hasVisibleButton';
16
17
  const nestedMenuStyles = {
17
18
  narrowSection: "_10gv1lit"
18
19
  };
@@ -127,9 +128,18 @@ export const getPasteMenuComponents = ({
127
128
  const pluginState = api === null || api === void 0 ? void 0 : (_api$pasteOptionsTool = api.pasteOptionsToolbarPlugin) === null || _api$pasteOptionsTool === void 0 ? void 0 : _api$pasteOptionsTool.sharedState.currentState();
128
129
  return !((_pluginState$showLega = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLegacyOptions) !== null && _pluginState$showLega !== void 0 ? _pluginState$showLega : false);
129
130
  },
130
- component: props => /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
131
- hasSeparator: true
132
- }, props.children)
131
+ component: props => {
132
+ var _api$uiControlRegistr, _api$uiControlRegistr2;
133
+ const allComponents = (_api$uiControlRegistr = api === null || api === void 0 ? void 0 : (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(PASTE_MENU.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
134
+ const aiMenuItems = allComponents.filter(c => {
135
+ var _c$parents;
136
+ return c.type === 'menu-item' && ((_c$parents = c.parents) === null || _c$parents === void 0 ? void 0 : _c$parents.some(p => p.key === AI_PASTE_MENU_SECTION.key));
137
+ });
138
+ const hasVisibleAiActions = getVisibleKeys(aiMenuItems, ['menu-item']).length > 0;
139
+ return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
140
+ hasSeparator: hasVisibleAiActions
141
+ }, props.children);
142
+ }
133
143
  }, {
134
144
  type: PASTE_NESTED_MENU.type,
135
145
  key: PASTE_NESTED_MENU.key,
@@ -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;
@@ -6,46 +6,45 @@ import { PastePluginActionTypes } from '../editor-actions/actions';
6
6
  import { pasteOptionsPluginKey } from '../types/types';
7
7
  import { PASTE_OPTIONS_META_ID } from './constants';
8
8
  import { reducer } from './reducer';
9
- var _pluginFactory = pluginFactory(pasteOptionsPluginKey, reducer, {
10
- mapping: function mapping(tr, pluginState) {
11
- if (!tr.docChanged || !pluginState.showToolbar) {
12
- return pluginState;
13
- }
14
- var oldPasteStartPos = pluginState.pasteStartPos;
15
- var oldPasteEndPos = pluginState.pasteEndPos;
16
- var newPasteStartPos = tr.mapping.map(oldPasteStartPos);
17
- var newPasteEndPos = tr.mapping.map(oldPasteEndPos);
9
+ var dest = pluginFactory(pasteOptionsPluginKey, reducer, {
10
+ mapping: function mapping(tr, pluginState) {
11
+ if (!tr.docChanged || !pluginState.showToolbar) {
12
+ return pluginState;
13
+ }
14
+ var oldPasteStartPos = pluginState.pasteStartPos;
15
+ var oldPasteEndPos = pluginState.pasteEndPos;
16
+ var newPasteStartPos = tr.mapping.map(oldPasteStartPos);
17
+ var newPasteEndPos = tr.mapping.map(oldPasteEndPos);
18
18
 
19
- //this is true when user changes format from the toolbar.
20
- //only change pasteEndPos in this case
21
- if (changedFormatFromToolbar(tr)) {
22
- return _objectSpread(_objectSpread({}, pluginState), {}, {
23
- pasteEndPos: newPasteEndPos
24
- });
25
- }
26
- if (oldPasteStartPos === newPasteStartPos && oldPasteEndPos === newPasteEndPos) {
27
- return pluginState;
28
- }
19
+ //this is true when user changes format from the toolbar.
20
+ //only change pasteEndPos in this case
21
+ if (changedFormatFromToolbar(tr)) {
29
22
  return _objectSpread(_objectSpread({}, pluginState), {}, {
30
- pasteStartPos: newPasteStartPos,
31
23
  pasteEndPos: newPasteEndPos
32
24
  });
33
- },
34
- onSelectionChanged: function onSelectionChanged(tr, pluginState) {
35
- // Detect click outside the editor
36
- if (tr.getMeta('outsideProsemirrorEditorClicked')) {
37
- return _objectSpread(_objectSpread({}, pluginState), {}, {
38
- showToolbar: false,
39
- highlightContent: false
40
- });
41
- }
25
+ }
26
+ if (oldPasteStartPos === newPasteStartPos && oldPasteEndPos === newPasteEndPos) {
42
27
  return pluginState;
43
28
  }
44
- }),
45
- createPluginState = _pluginFactory.createPluginState,
46
- createCommand = _pluginFactory.createCommand,
47
- getPluginState = _pluginFactory.getPluginState;
48
- export { createPluginState, createCommand, getPluginState };
29
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
30
+ pasteStartPos: newPasteStartPos,
31
+ pasteEndPos: newPasteEndPos
32
+ });
33
+ },
34
+ onSelectionChanged: function onSelectionChanged(tr, pluginState) {
35
+ // Detect click outside the editor
36
+ if (tr.getMeta('outsideProsemirrorEditorClicked')) {
37
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
38
+ showToolbar: false,
39
+ highlightContent: false
40
+ });
41
+ }
42
+ return pluginState;
43
+ }
44
+ });
45
+ export var createPluginState = dest.createPluginState;
46
+ export var createCommand = dest.createCommand;
47
+ export var getPluginState = dest.getPluginState;
49
48
  var changedFormatFromToolbar = function changedFormatFromToolbar(tr) {
50
49
  var meta = tr.getMeta(PASTE_OPTIONS_META_ID);
51
50
  if (meta && meta.type === PastePluginActionTypes.CHANGE_FORMAT) {
@@ -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(from, editorView.domAtPos.bind(editorView));
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
- function getPopupOffset(dom) {
29
- if (!dom) {
30
- return [0, 20];
31
- }
32
- var rightEdge = dom.getBoundingClientRect().right;
33
- return [-(window.innerWidth - rightEdge - 50), 20];
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: "right",
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, {
@@ -1,4 +1,3 @@
1
1
 
2
- ._2rko12b0{border-radius:var(--ds-radius-small,4px)}
3
- ._1rjc1b66{padding-block:var(--ds-space-050,4px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
2
+ ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
4
3
  ._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
@@ -9,7 +9,7 @@ import { ToolbarDropdownItemSection } from '@atlaskit/editor-toolbar';
9
9
  import { SurfaceRenderer } from '@atlaskit/editor-ui-control-model';
10
10
  import { Box } from '@atlaskit/primitives/compiled';
11
11
  var styles = {
12
- container: "_2rko12b0 _1rjc1b66 _bfhk1bhr _16qs130s"
12
+ container: "_2rko12b0 _bfhk1bhr _16qs130s"
13
13
  };
14
14
  export var PasteActionsMenuContent = function PasteActionsMenuContent(_ref) {
15
15
  var onMouseDown = _ref.onMouseDown,
@@ -6,13 +6,14 @@ import { cx } from '@compiled/react';
6
6
  import { useIntl } from 'react-intl-next';
7
7
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
8
8
  import { pasteOptionsToolbarMessages as messages } from '@atlaskit/editor-common/messages';
9
- import { useEditorToolbar, PASTE_MENU, PASTE_MENU_SECTION, PASTE_NESTED_MENU, PASTE_MENU_NESTED_SECTION, PASTE_RICH_TEXT_MENU_ITEM, PASTE_MARKDOWN_MENU_ITEM, PASTE_PLAIN_TEXT_MENU_ITEM, PASTE_MENU_RANK, PASTE_MENU_SECTION_RANK, PASTE_NESTED_MENU_RANK, PASTE_MENU_NESTED_SECTION_RANK } from '@atlaskit/editor-common/toolbar';
9
+ import { useEditorToolbar, PASTE_MENU, PASTE_MENU_SECTION, PASTE_NESTED_MENU, PASTE_MENU_NESTED_SECTION, PASTE_RICH_TEXT_MENU_ITEM, PASTE_MARKDOWN_MENU_ITEM, PASTE_PLAIN_TEXT_MENU_ITEM, PASTE_MENU_RANK, PASTE_MENU_SECTION_RANK, PASTE_NESTED_MENU_RANK, PASTE_MENU_NESTED_SECTION_RANK, AI_PASTE_MENU_SECTION } from '@atlaskit/editor-common/toolbar';
10
10
  import { ToolbarDropdownItem, ToolbarDropdownItemSection, ToolbarNestedDropdownMenu } from '@atlaskit/editor-toolbar';
11
11
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
12
12
  import ClipboardIcon from '@atlaskit/icon/core/clipboard';
13
13
  import { Box } from '@atlaskit/primitives/compiled';
14
14
  import { changeToMarkdownWithAnalytics, changeToPlainTextWithAnalytics, changeToRichTextWithAnalytics } from '../../editor-commands/commands';
15
15
  import { ToolbarDropdownOption } from '../../types/types';
16
+ import { getVisibleKeys } from './hasVisibleButton';
16
17
  var nestedMenuStyles = {
17
18
  narrowSection: "_10gv1lit"
18
19
  };
@@ -124,8 +125,17 @@ export var getPasteMenuComponents = function getPasteMenuComponents(_ref3) {
124
125
  return !((_pluginState$showLega = pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLegacyOptions) !== null && _pluginState$showLega !== void 0 ? _pluginState$showLega : false);
125
126
  },
126
127
  component: function component(props) {
128
+ var _api$uiControlRegistr, _api$uiControlRegistr2;
129
+ var allComponents = (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(PASTE_MENU.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
130
+ var aiMenuItems = allComponents.filter(function (c) {
131
+ var _c$parents;
132
+ return c.type === 'menu-item' && ((_c$parents = c.parents) === null || _c$parents === void 0 ? void 0 : _c$parents.some(function (p) {
133
+ return p.key === AI_PASTE_MENU_SECTION.key;
134
+ }));
135
+ });
136
+ var hasVisibleAiActions = getVisibleKeys(aiMenuItems, ['menu-item']).length > 0;
127
137
  return /*#__PURE__*/React.createElement(ToolbarDropdownItemSection, {
128
- hasSeparator: true
138
+ hasSeparator: hasVisibleAiActions
129
139
  }, props.children);
130
140
  }
131
141
  }, {
@@ -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;
@@ -1,5 +1,6 @@
1
1
  import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
2
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import { type PasteOptionsPluginState } from '../types/types';
3
4
  export declare function createPlugin(dispatch: Dispatch, options?: {
4
5
  useNewPasteMenu?: boolean;
5
- }): SafePlugin<import("../types/types").PasteOptionsPluginState>;
6
+ }): SafePlugin<PasteOptionsPluginState>;
@@ -1,2 +1,8 @@
1
+ import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
2
+ import type { Command } from '@atlaskit/editor-common/types';
3
+ import type { EditorState, SafeStateField, Transaction } from '@atlaskit/editor-prosemirror/state';
4
+ import { type PastePluginAction } from '../editor-actions/actions';
1
5
  import type { PasteOptionsPluginState } from '../types/types';
2
- export declare const createPluginState: (dispatch: import("@atlaskit/editor-common/event-dispatcher").Dispatch, initialState: PasteOptionsPluginState | ((state: import("prosemirror-state").EditorState) => PasteOptionsPluginState)) => import("prosemirror-state").SafeStateField<PasteOptionsPluginState>, createCommand: <A = import("../editor-actions/actions").PastePluginAction>(action: A | ((state: Readonly<import("prosemirror-state").EditorState>) => false | A), transform?: (tr: import("prosemirror-state").Transaction, state: import("prosemirror-state").EditorState) => import("prosemirror-state").Transaction) => import("@atlaskit/editor-common/types").Command, getPluginState: (state: import("prosemirror-state").EditorState) => PasteOptionsPluginState;
6
+ export declare const createPluginState: (dispatch: Dispatch, initialState: PasteOptionsPluginState | ((state: EditorState) => PasteOptionsPluginState)) => SafeStateField<PasteOptionsPluginState>;
7
+ export declare const createCommand: <A = PastePluginAction>(action: A | ((state: Readonly<EditorState>) => false | A), transform?: (tr: Transaction, state: EditorState) => Transaction) => Command;
8
+ export declare const getPluginState: (state: EditorState) => PasteOptionsPluginState;
@@ -1,7 +1,7 @@
1
1
  import type { Slice } from '@atlaskit/editor-prosemirror/model';
2
2
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
- export declare const pasteOptionsPluginKey: PluginKey<any>;
4
+ export declare const pasteOptionsPluginKey: PluginKey;
5
5
  export declare enum ToolbarDropdownOption {
6
6
  Markdown = 0,
7
7
  RichText = 1,
@@ -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, }: PasteMenuComponentsConfig) => RegisterComponent[];
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;
@@ -1,5 +1,6 @@
1
1
  import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
2
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import { type PasteOptionsPluginState } from '../types/types';
3
4
  export declare function createPlugin(dispatch: Dispatch, options?: {
4
5
  useNewPasteMenu?: boolean;
5
- }): SafePlugin<import("../types/types").PasteOptionsPluginState>;
6
+ }): SafePlugin<PasteOptionsPluginState>;
@@ -1,2 +1,8 @@
1
+ import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
2
+ import type { Command } from '@atlaskit/editor-common/types';
3
+ import type { EditorState, SafeStateField, Transaction } from '@atlaskit/editor-prosemirror/state';
4
+ import { type PastePluginAction } from '../editor-actions/actions';
1
5
  import type { PasteOptionsPluginState } from '../types/types';
2
- export declare const createPluginState: (dispatch: import("@atlaskit/editor-common/event-dispatcher").Dispatch, initialState: PasteOptionsPluginState | ((state: import("prosemirror-state").EditorState) => PasteOptionsPluginState)) => import("prosemirror-state").SafeStateField<PasteOptionsPluginState>, createCommand: <A = import("../editor-actions/actions").PastePluginAction>(action: A | ((state: Readonly<import("prosemirror-state").EditorState>) => false | A), transform?: (tr: import("prosemirror-state").Transaction, state: import("prosemirror-state").EditorState) => import("prosemirror-state").Transaction) => import("@atlaskit/editor-common/types").Command, getPluginState: (state: import("prosemirror-state").EditorState) => PasteOptionsPluginState;
6
+ export declare const createPluginState: (dispatch: Dispatch, initialState: PasteOptionsPluginState | ((state: EditorState) => PasteOptionsPluginState)) => SafeStateField<PasteOptionsPluginState>;
7
+ export declare const createCommand: <A = PastePluginAction>(action: A | ((state: Readonly<EditorState>) => false | A), transform?: (tr: Transaction, state: EditorState) => Transaction) => Command;
8
+ export declare const getPluginState: (state: EditorState) => PasteOptionsPluginState;
@@ -1,7 +1,7 @@
1
1
  import type { Slice } from '@atlaskit/editor-prosemirror/model';
2
2
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
- export declare const pasteOptionsPluginKey: PluginKey<any>;
4
+ export declare const pasteOptionsPluginKey: PluginKey;
5
5
  export declare enum ToolbarDropdownOption {
6
6
  Markdown = 0,
7
7
  RichText = 1,
@@ -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, }: PasteMenuComponentsConfig) => RegisterComponent[];
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.0",
3
+ "version": "9.0.2",
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": "^35.10.0",
44
+ "@atlaskit/tmp-editor-statsig": "^36.0.0",
45
45
  "@atlaskit/tokens": "^11.1.0",
46
46
  "@babel/runtime": "^7.0.0",
47
47
  "@compiled/react": "^0.20.0",