@atlaskit/editor-common 115.1.0 → 115.2.1

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 (36) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/ai-messages/ai-suggestions.js +5 -0
  3. package/dist/cjs/extensibility/MultiBodiedExtension/action-api.js +19 -9
  4. package/dist/cjs/extensibility/MultiBodiedExtension/index.js +7 -4
  5. package/dist/cjs/extensibility/MultiBodiedExtension/styles.js +59 -2
  6. package/dist/cjs/extensibility/extensionNodeView.js +19 -6
  7. package/dist/cjs/monitoring/error.js +1 -1
  8. package/dist/cjs/ui/DropList/index.js +1 -1
  9. package/dist/cjs/ui/MultiBodiedExtension/index.js +31 -1
  10. package/dist/es2019/ai-messages/ai-suggestions.js +5 -0
  11. package/dist/es2019/extensibility/MultiBodiedExtension/action-api.js +19 -9
  12. package/dist/es2019/extensibility/MultiBodiedExtension/index.js +8 -5
  13. package/dist/es2019/extensibility/MultiBodiedExtension/styles.js +58 -1
  14. package/dist/es2019/extensibility/extensionNodeView.js +19 -6
  15. package/dist/es2019/monitoring/error.js +1 -1
  16. package/dist/es2019/ui/DropList/index.js +1 -1
  17. package/dist/es2019/ui/MultiBodiedExtension/index.js +31 -1
  18. package/dist/esm/ai-messages/ai-suggestions.js +5 -0
  19. package/dist/esm/extensibility/MultiBodiedExtension/action-api.js +19 -9
  20. package/dist/esm/extensibility/MultiBodiedExtension/index.js +8 -5
  21. package/dist/esm/extensibility/MultiBodiedExtension/styles.js +58 -1
  22. package/dist/esm/extensibility/extensionNodeView.js +19 -6
  23. package/dist/esm/monitoring/error.js +1 -1
  24. package/dist/esm/ui/DropList/index.js +1 -1
  25. package/dist/esm/ui/MultiBodiedExtension/index.js +31 -1
  26. package/dist/types/ai-messages/ai-suggestions.d.ts +5 -0
  27. package/dist/types/extensibility/MultiBodiedExtension/styles.d.ts +2 -0
  28. package/dist/types/extensibility/extensionNodeView.d.ts +9 -6
  29. package/dist/types/extensions/types/extension-handler.d.ts +5 -1
  30. package/dist/types/ui/MultiBodiedExtension/index.d.ts +1 -1
  31. package/dist/types-ts4.5/ai-messages/ai-suggestions.d.ts +5 -0
  32. package/dist/types-ts4.5/extensibility/MultiBodiedExtension/styles.d.ts +2 -0
  33. package/dist/types-ts4.5/extensibility/extensionNodeView.d.ts +9 -6
  34. package/dist/types-ts4.5/extensions/types/extension-handler.d.ts +5 -1
  35. package/dist/types-ts4.5/ui/MultiBodiedExtension/index.d.ts +1 -1
  36. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 115.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`0d8f232a9fc98`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0d8f232a9fc98) -
8
+ Add selection options to MBE changeActive API and prevent unwanted node selection when clicking
9
+ extension UI elements
10
+ - [`f3f55d3ebf702`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f3f55d3ebf702) -
11
+ Gate MBE style and gap cursor changes behind confluence_frontend_native_tabs_extension feature
12
+ flag
13
+
14
+ ## 115.2.0
15
+
16
+ ### Minor Changes
17
+
18
+ - [`d0aecc7277414`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d0aecc7277414) -
19
+ EDITOR-7417: Link up the thinking components with Rovo chat state. Plugin now takes in a
20
+ ConversationAssistant provider that enables all the thinking actions to function, and will enable
21
+ showing thinking components too. onOpenRovoChatWithSkill has been removed as it is succeeded by
22
+ .startThinking.
23
+
3
24
  ## 115.1.0
4
25
 
5
26
  ### Minor Changes
@@ -11,6 +11,11 @@ var aiSuggestionsMessages = exports.aiSuggestionsMessages = (0, _reactIntl.defin
11
11
  defaultMessage: 'Review',
12
12
  description: 'Label for the Suggest edits button in the editor toolbar'
13
13
  },
14
+ suggestEditsPromptPrefix: {
15
+ id: 'fabric.editor.ai.suggestions.suggestEditsPromptPrefix.non-final',
16
+ defaultMessage: 'Review my content with ',
17
+ description: 'Localised text that precedes the suggest-edits skill tag in the prompt sent to the AI service. The trailing space is intentional — it separates this text from the skill tag that follows. Localise it in a way where the prompt ends with the skill tag. (With the skill tag it will look like e.g. "Review my content with /suggest-edits")'
18
+ },
14
19
  suggestionsToolbarButtonLabel: {
15
20
  id: 'fabric.editor.ai.suggestions.toolbarButton.label.non-final',
16
21
  defaultMessage: 'Suggestions',
@@ -23,35 +23,45 @@ var useMultiBodiedExtensionActions = exports.useMultiBodiedExtensionActions = fu
23
23
  childrenContainer = _ref.childrenContainer;
24
24
  var actions = _react.default.useMemo(function () {
25
25
  return {
26
- changeActive: function changeActive(index) {
27
- var _possiblyMbeNode$type;
26
+ changeActive: function changeActive(index, options) {
27
+ var _options$selection, _possiblyMbeNode$type;
28
28
  var state = editorView.state,
29
29
  dispatch = editorView.dispatch;
30
30
  var updateActiveChildResult = updateActiveChild(index);
31
31
  if (eventDispatcher) {
32
32
  (0, _utils.sendMBEAnalyticsEvent)(_analytics.ACTION.CHANGE_ACTIVE, node, eventDispatcher);
33
33
  }
34
- // On selection of a childFrame, we need to change the focus/selection to the end of the target child Frame
34
+ var selection = (_options$selection = options === null || options === void 0 ? void 0 : options.selection) !== null && _options$selection !== void 0 ? _options$selection : 'none';
35
+ if (selection === 'none') {
36
+ return updateActiveChildResult;
37
+ }
35
38
  var pos = getPos();
36
39
  if (typeof pos !== 'number') {
37
40
  return updateActiveChildResult;
38
41
  }
39
42
  var possiblyMbeNode = state.doc.nodeAt(pos);
40
- var desiredPos = pos;
41
43
  if (possiblyMbeNode && (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$type = possiblyMbeNode.type) === null || _possiblyMbeNode$type === void 0 ? void 0 : _possiblyMbeNode$type.name) === 'multiBodiedExtension' && possiblyMbeNode !== null && possiblyMbeNode !== void 0 && possiblyMbeNode.content) {
42
44
  var _possiblyMbeNode$cont;
43
45
  if (index < 0 || index >= (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont = possiblyMbeNode.content) === null || _possiblyMbeNode$cont === void 0 ? void 0 : _possiblyMbeNode$cont.childCount)) {
44
46
  var _possiblyMbeNode$cont2;
45
47
  throw new Error("Index out of bounds: valid range is 0-".concat((possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont2 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont2 === void 0 ? void 0 : _possiblyMbeNode$cont2.childCount) - 1, " inclusive"));
46
48
  }
47
- for (var i = 0; i <= index && i < (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont3 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont3 === void 0 ? void 0 : _possiblyMbeNode$cont3.childCount); i++) {
49
+ var desiredPos = pos;
50
+ for (var i = 0; i < index && i < (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont3 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont3 === void 0 ? void 0 : _possiblyMbeNode$cont3.childCount); i++) {
48
51
  var _possiblyMbeNode$cont3, _possiblyMbeNode$cont4;
49
52
  desiredPos += (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont4 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont4 === void 0 || (_possiblyMbeNode$cont4 = _possiblyMbeNode$cont4.child(i)) === null || _possiblyMbeNode$cont4 === void 0 ? void 0 : _possiblyMbeNode$cont4.nodeSize) || 0;
50
53
  }
51
- /* desiredPos gives the cursor at the end of last child of the current frame, in case of paragraph nodes, this will be the end of the paragraph
52
- * Performing -1 brings the cursor inside the paragraph, similar to a user click, so any pasted text will be inside the last paragraph rather than a new line
53
- */
54
- dispatch(state.tr.setSelection(new _state.TextSelection(state.doc.resolve(desiredPos - 1))));
54
+ var targetFrame = possiblyMbeNode.content.child(index);
55
+ if (selection === 'start') {
56
+ // +1 moves past the extensionFrame opening token; TextSelection.near() finds
57
+ // the nearest valid text cursor position from there.
58
+ dispatch(state.tr.setSelection(_state.TextSelection.near(state.doc.resolve(desiredPos + 1))));
59
+ } else {
60
+ // Place cursor at the end of the target frame's content.
61
+ // -1 bias searches backward from the frame's closing token.
62
+ dispatch(state.tr.setSelection(_state.TextSelection.near(state.doc.resolve(desiredPos + targetFrame.nodeSize), -1)));
63
+ }
64
+ editorView.focus();
55
65
  }
56
66
  return updateActiveChildResult;
57
67
  },
@@ -15,6 +15,7 @@ var _react = _interopRequireWildcard(require("react"));
15
15
  var _react2 = require("@emotion/react");
16
16
  var _classnames = _interopRequireDefault(require("classnames"));
17
17
  var _file = _interopRequireDefault(require("@atlaskit/icon/core/file"));
18
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
18
19
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
19
20
  var _hooks = require("../../hooks");
20
21
  var _MultiBodiedExtension = require("../../ui/MultiBodiedExtension");
@@ -58,6 +59,7 @@ var MultiBodiedExtensionFrames = function MultiBodiedExtensionFrames(_ref) {
58
59
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
59
60
  className: "multiBodiedExtension--frames",
60
61
  "data-testid": "multiBodiedExtension--frames",
62
+ "data-multibodiedextension-frames": true,
61
63
  ref: articleRef
62
64
  });
63
65
  };
@@ -209,9 +211,9 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
209
211
  }), (0, _react2.jsx)("div", {
210
212
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
211
213
  className: wrapperClassNames,
212
- css: [
213
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
214
- _styles.mbeExtensionWrapperCSSStyles, showMacroInteractionDesignUpdates && !isLivePageViewMode && (0, _expValEquals.expValEquals)('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles],
214
+ css: [/* eslint-disable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
215
+ (0, _platformFeatureFlags.fg)('confluence_frontend_native_tabs_extension') ? _styles.mbeExtensionWrapperCSSStyles : _styles.mbeExtensionWrapperCSSStylesOld, /* eslint-enable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage */
216
+ showMacroInteractionDesignUpdates && !isLivePageViewMode && (0, _expValEquals.expValEquals)('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles],
215
217
  "data-testid": "multiBodiedExtension--wrapper-editor",
216
218
  "data-layout": node.attrs.layout
217
219
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
@@ -230,7 +232,7 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
230
232
  onBlur: (0, _expValEquals.expValEquals)('editor_a11y__enghealth-46814_fy26', 'isEnabled', true) ? function () {} : undefined
231
233
  }, (0, _react2.jsx)("div", {
232
234
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
233
- css: _styles.overlayStyles
235
+ css: (0, _platformFeatureFlags.fg)('confluence_frontend_native_tabs_extension') ? _styles.overlayStyles : _styles.overlayStylesOld
234
236
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
235
237
  ,
236
238
  className: overlayClassNames,
@@ -242,6 +244,7 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
242
244
  ,
243
245
  css: getContainerCssExtendedStyles(activeChildIndex, showMacroInteractionDesignUpdates),
244
246
  "data-testid": "multiBodiedExtension--container",
247
+ "data-multiBodiedExtension-container": true,
245
248
  "data-active-child-index": activeChildIndex
246
249
  }, allowBodiedOverride ? (0, _react2.jsx)("div", {
247
250
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -3,15 +3,55 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.overlayStyles = exports.mbeExtensionWrapperCSSStyles = void 0;
6
+ exports.overlayStylesOld = exports.overlayStyles = exports.mbeExtensionWrapperCSSStylesOld = exports.mbeExtensionWrapperCSSStyles = void 0;
7
7
  var _react = require("@emotion/react");
8
8
  var _styles = require("../Extension/styles");
9
9
  /* eslint-disable @atlaskit/ui-styling-standard/use-compiled -- Pre-existing lint debt surfaced by this mechanical type-import-only PR. */
10
+ /* eslint-disable @atlaskit/design-system/use-tokens-typography -- Ignored via go/DSP-18766 */
10
11
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
11
12
 
12
13
  // Wrapper the extension title and extensionContainer
13
14
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
14
15
  var mbeExtensionWrapperCSSStyles = exports.mbeExtensionWrapperCSSStyles = (0, _react.css)(_styles.wrapperDefault, {
16
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
17
+ '&.with-margin-styles': {
18
+ marginTop: "var(--ds-space-300, 24px)",
19
+ marginLeft: "var(--ds-space-negative-250, -20px)",
20
+ marginRight: "var(--ds-space-negative-250, -20px)"
21
+ },
22
+ cursor: 'pointer',
23
+ marginTop: "var(--ds-space-250, 20px)",
24
+ marginBottom: "var(--ds-space-200, 16px)",
25
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
26
+ '.extension-title': {
27
+ display: 'flex',
28
+ alignItems: 'center',
29
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
30
+ lineHeight: '16px !important',
31
+ marginBottom: "var(--ds-space-100, 8px)",
32
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
33
+ marginLeft: "var(--ds-space-050, 4px)".concat(" !important"),
34
+ marginRight: "var(--ds-space-100, 8px)",
35
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
36
+ paddingTop: "var(--ds-space-100, 8px)".concat(" !important")
37
+ },
38
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
39
+ '&.with-border': {
40
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border, #0B120E24)")
41
+ },
42
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
43
+ '&.with-hover-border': {
44
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border-input, #8C8F97)")
45
+ },
46
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
47
+ '&.with-padding-background-styles': {
48
+ padding: "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-250, 20px)"),
49
+ background: 'transparent'
50
+ }
51
+ });
52
+
53
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
54
+ var mbeExtensionWrapperCSSStylesOld = exports.mbeExtensionWrapperCSSStylesOld = (0, _react.css)(_styles.wrapperDefault, {
15
55
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
16
56
  '&.with-margin-styles': {
17
57
  marginTop: 0,
@@ -25,7 +65,7 @@ var mbeExtensionWrapperCSSStyles = exports.mbeExtensionWrapperCSSStyles = (0, _r
25
65
  '.extension-title': {
26
66
  display: 'flex',
27
67
  alignItems: 'center',
28
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles, @atlaskit/design-system/use-tokens-typography -- Ignored via go/DSP-18766
68
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
29
69
  lineHeight: '16px !important',
30
70
  marginBottom: "var(--ds-space-100, 8px)",
31
71
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
@@ -51,6 +91,23 @@ var mbeExtensionWrapperCSSStyles = exports.mbeExtensionWrapperCSSStyles = (0, _r
51
91
 
52
92
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
53
93
  var overlayStyles = exports.overlayStyles = (0, _react.css)({
94
+ borderRadius: "var(--ds-radius-small, 3px)",
95
+ position: 'absolute',
96
+ width: '100%',
97
+ height: '100%',
98
+ opacity: 0,
99
+ pointerEvents: 'none',
100
+ transition: 'opacity 0.3s',
101
+ zIndex: 1,
102
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
103
+ '&.with-margin': {
104
+ marginTop: "var(--ds-space-negative-100, -8px)",
105
+ marginLeft: "var(--ds-space-negative-250, -20px)"
106
+ }
107
+ });
108
+
109
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
110
+ var overlayStylesOld = exports.overlayStylesOld = (0, _react.css)({
54
111
  borderRadius: "var(--ds-radius-small, 3px)",
55
112
  position: 'absolute',
56
113
  width: '100%',
@@ -236,16 +236,29 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
236
236
  }
237
237
 
238
238
  /**
239
- * When interacting with input elements inside an extension's body, the events
240
- * bubble up to the editor and get handled by it. This almost always gets in the way
241
- * of being able to actually interact with said input in the extension, i.e.
242
- * typing inside a text field (in an extension body) will print the text in the editor
243
- * content area instead. This change prevents the editor view from trying to handle these events,
244
- * when the target of the event is an input element, so the extension can.
239
+ * Prevents ProseMirror from handling events that belong to the extension's React UI.
240
+ *
241
+ * For multibodied extensions: the node consists of a React app (e.g. tab bar) that controls
242
+ * frames, and the editable frames themselves. Events inside frames must reach ProseMirror
243
+ * for normal editing; events in the surrounding React app (buttons, navigation) are stopped
244
+ * so ProseMirror doesn't create a NodeSelection on the entire node.
245
+ *
246
+ * For other extensions: input/textarea events are stopped so users can interact
247
+ * with form elements inside the extension body without the editor intercepting them.
245
248
  */
246
249
  }, {
247
250
  key: "stopEvent",
248
251
  value: function stopEvent(event) {
252
+ if (this.node.type.name === 'multiBodiedExtension') {
253
+ var target = event.target;
254
+ if (target instanceof Element) {
255
+ if (target.closest('[data-multibodiedextension-frames]')) {
256
+ return false;
257
+ }
258
+ return !!target.closest('[data-multiBodiedExtension-container]');
259
+ }
260
+ return false;
261
+ }
249
262
  if ((0, _platformFeatureFlags.fg)('forge-ui-extensionnodeview-stop-event-for-textarea')) {
250
263
  return event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement;
251
264
  }
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
19
19
  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 _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
20
20
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
21
21
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
22
- var packageVersion = "115.0.3";
22
+ var packageVersion = "115.2.0";
23
23
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
24
24
  // Remove URL as it has UGC
25
25
  // Ignored via go/ees007
@@ -24,7 +24,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
24
24
  * @jsx jsx
25
25
  */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
26
26
  var packageName = "@atlaskit/editor-common";
27
- var packageVersion = "115.0.3";
27
+ var packageVersion = "115.2.0";
28
28
  var halfFocusRing = 1;
29
29
  var dropOffset = '0, 8';
30
30
  var fadeIn = (0, _react2.keyframes)({
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.sharedMultiBodiedExtensionStyles = exports.removeMarginsAndBorder = void 0;
7
7
  var _react = require("@emotion/react");
8
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
8
9
  /* eslint-disable @atlaskit/ui-styling-standard/use-compiled -- Pre-existing lint debt surfaced by this mechanical type-import-only PR. */
9
10
  /**
10
11
  * @jsxRuntime classic
@@ -68,6 +69,33 @@ var mbeNavigation = (0, _react.css)({
68
69
  }
69
70
  });
70
71
  var extensionFrameContent = (0, _react.css)({
72
+ display: 'block',
73
+ minHeight: '100px',
74
+ background: 'transparent',
75
+ borderBottomLeftRadius: "var(--ds-radius-small, 3px)",
76
+ borderBottomRightRadius: "var(--ds-radius-small, 3px)",
77
+ marginLeft: "var(--ds-space-100, 8px)",
78
+ marginRight: "var(--ds-space-100, 8px)",
79
+ cursor: 'initial',
80
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
81
+ '.pm-table-with-controls': {
82
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
83
+ marginLeft: "var(--ds-space-150, 12px)".concat(" !important"),
84
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
85
+ paddingRight: "var(--ds-space-150, 12px)".concat(" !important")
86
+ },
87
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
88
+ '.bodiedExtensionView-content-wrap': {
89
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
90
+ marginTop: "var(--ds-space-150, 12px)".concat(" !important")
91
+ },
92
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
93
+ '.extensionView-content-wrap': {
94
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
95
+ marginTop: "var(--ds-space-100, 8px)".concat(" !important")
96
+ }
97
+ });
98
+ var extensionFrameContentOld = (0, _react.css)({
71
99
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
72
100
  padding: "var(--ds-space-100, 8px)".concat(" !important"),
73
101
  display: 'block',
@@ -108,5 +136,7 @@ var removeMarginsAndBorder = exports.removeMarginsAndBorder = (0, _react.css)({
108
136
  var sharedMultiBodiedExtensionStyles = exports.sharedMultiBodiedExtensionStyles = {
109
137
  mbeExtensionContainer: mbeExtensionContainer,
110
138
  mbeNavigation: mbeNavigation,
111
- extensionFrameContent: extensionFrameContent
139
+ get extensionFrameContent() {
140
+ return (0, _platformFeatureFlags.fg)('confluence_frontend_native_tabs_extension') ? extensionFrameContent : extensionFrameContentOld;
141
+ }
112
142
  };
@@ -5,6 +5,11 @@ export const aiSuggestionsMessages = defineMessages({
5
5
  defaultMessage: 'Review',
6
6
  description: 'Label for the Suggest edits button in the editor toolbar'
7
7
  },
8
+ suggestEditsPromptPrefix: {
9
+ id: 'fabric.editor.ai.suggestions.suggestEditsPromptPrefix.non-final',
10
+ defaultMessage: 'Review my content with ',
11
+ description: 'Localised text that precedes the suggest-edits skill tag in the prompt sent to the AI service. The trailing space is intentional — it separates this text from the skill tag that follows. Localise it in a way where the prompt ends with the skill tag. (With the skill tag it will look like e.g. "Review my content with /suggest-edits")'
12
+ },
8
13
  suggestionsToolbarButtonLabel: {
9
14
  id: 'fabric.editor.ai.suggestions.toolbarButton.label.non-final',
10
15
  defaultMessage: 'Suggestions',
@@ -14,8 +14,8 @@ export const useMultiBodiedExtensionActions = ({
14
14
  }) => {
15
15
  const actions = React.useMemo(() => {
16
16
  return {
17
- changeActive(index) {
18
- var _possiblyMbeNode$type;
17
+ changeActive(index, options) {
18
+ var _options$selection, _possiblyMbeNode$type;
19
19
  const {
20
20
  state,
21
21
  dispatch
@@ -24,27 +24,37 @@ export const useMultiBodiedExtensionActions = ({
24
24
  if (eventDispatcher) {
25
25
  sendMBEAnalyticsEvent(ACTION.CHANGE_ACTIVE, node, eventDispatcher);
26
26
  }
27
- // On selection of a childFrame, we need to change the focus/selection to the end of the target child Frame
27
+ const selection = (_options$selection = options === null || options === void 0 ? void 0 : options.selection) !== null && _options$selection !== void 0 ? _options$selection : 'none';
28
+ if (selection === 'none') {
29
+ return updateActiveChildResult;
30
+ }
28
31
  const pos = getPos();
29
32
  if (typeof pos !== 'number') {
30
33
  return updateActiveChildResult;
31
34
  }
32
35
  const possiblyMbeNode = state.doc.nodeAt(pos);
33
- let desiredPos = pos;
34
36
  if (possiblyMbeNode && (possiblyMbeNode === null || possiblyMbeNode === void 0 ? void 0 : (_possiblyMbeNode$type = possiblyMbeNode.type) === null || _possiblyMbeNode$type === void 0 ? void 0 : _possiblyMbeNode$type.name) === 'multiBodiedExtension' && possiblyMbeNode !== null && possiblyMbeNode !== void 0 && possiblyMbeNode.content) {
35
37
  var _possiblyMbeNode$cont;
36
38
  if (index < 0 || index >= (possiblyMbeNode === null || possiblyMbeNode === void 0 ? void 0 : (_possiblyMbeNode$cont = possiblyMbeNode.content) === null || _possiblyMbeNode$cont === void 0 ? void 0 : _possiblyMbeNode$cont.childCount)) {
37
39
  var _possiblyMbeNode$cont2;
38
40
  throw new Error(`Index out of bounds: valid range is 0-${(possiblyMbeNode === null || possiblyMbeNode === void 0 ? void 0 : (_possiblyMbeNode$cont2 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont2 === void 0 ? void 0 : _possiblyMbeNode$cont2.childCount) - 1} inclusive`);
39
41
  }
40
- for (let i = 0; i <= index && i < (possiblyMbeNode === null || possiblyMbeNode === void 0 ? void 0 : (_possiblyMbeNode$cont3 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont3 === void 0 ? void 0 : _possiblyMbeNode$cont3.childCount); i++) {
42
+ let desiredPos = pos;
43
+ for (let i = 0; i < index && i < (possiblyMbeNode === null || possiblyMbeNode === void 0 ? void 0 : (_possiblyMbeNode$cont3 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont3 === void 0 ? void 0 : _possiblyMbeNode$cont3.childCount); i++) {
41
44
  var _possiblyMbeNode$cont3, _possiblyMbeNode$cont4, _possiblyMbeNode$cont5;
42
45
  desiredPos += (possiblyMbeNode === null || possiblyMbeNode === void 0 ? void 0 : (_possiblyMbeNode$cont4 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont4 === void 0 ? void 0 : (_possiblyMbeNode$cont5 = _possiblyMbeNode$cont4.child(i)) === null || _possiblyMbeNode$cont5 === void 0 ? void 0 : _possiblyMbeNode$cont5.nodeSize) || 0;
43
46
  }
44
- /* desiredPos gives the cursor at the end of last child of the current frame, in case of paragraph nodes, this will be the end of the paragraph
45
- * Performing -1 brings the cursor inside the paragraph, similar to a user click, so any pasted text will be inside the last paragraph rather than a new line
46
- */
47
- dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(desiredPos - 1))));
47
+ const targetFrame = possiblyMbeNode.content.child(index);
48
+ if (selection === 'start') {
49
+ // +1 moves past the extensionFrame opening token; TextSelection.near() finds
50
+ // the nearest valid text cursor position from there.
51
+ dispatch(state.tr.setSelection(TextSelection.near(state.doc.resolve(desiredPos + 1))));
52
+ } else {
53
+ // Place cursor at the end of the target frame's content.
54
+ // -1 bias searches backward from the frame's closing token.
55
+ dispatch(state.tr.setSelection(TextSelection.near(state.doc.resolve(desiredPos + targetFrame.nodeSize), -1)));
56
+ }
57
+ editorView.focus();
48
58
  }
49
59
  return updateActiveChildResult;
50
60
  },
@@ -11,6 +11,7 @@ import React, { Fragment, useState } from 'react';
11
11
  import { css, jsx } from '@emotion/react';
12
12
  import classnames from 'classnames';
13
13
  import EditorFileIcon from '@atlaskit/icon/core/file';
14
+ import { fg } from '@atlaskit/platform-feature-flags';
14
15
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
16
  import { useSharedPluginStateWithSelector } from '../../hooks';
16
17
  import { removeMarginsAndBorder, sharedMultiBodiedExtensionStyles } from '../../ui/MultiBodiedExtension';
@@ -18,7 +19,7 @@ import { calculateBreakoutStyles, getExtensionLozengeData } from '../../utils';
18
19
  import ExtensionLozenge from '../Extension/Lozenge';
19
20
  import { shouldExtensionBreakout } from '../utils/should-extension-breakout';
20
21
  import { useMultiBodiedExtensionActions } from './action-api';
21
- import { mbeExtensionWrapperCSSStyles, overlayStyles } from './styles';
22
+ import { mbeExtensionWrapperCSSStyles, mbeExtensionWrapperCSSStylesOld, overlayStyles, overlayStylesOld } from './styles';
22
23
  const getContainerCssExtendedStyles = (activeChildIndex, showMacroInteractionDesignUpdates) =>
23
24
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
24
25
  css(sharedMultiBodiedExtensionStyles.mbeExtensionContainer, {
@@ -47,6 +48,7 @@ const MultiBodiedExtensionFrames = ({
47
48
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
48
49
  className: "multiBodiedExtension--frames",
49
50
  "data-testid": "multiBodiedExtension--frames",
51
+ "data-multibodiedextension-frames": true,
50
52
  ref: articleRef
51
53
  });
52
54
  };
@@ -200,9 +202,9 @@ const MultiBodiedExtensionWithWidth = ({
200
202
  }), jsx("div", {
201
203
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
202
204
  className: wrapperClassNames,
203
- css: [
204
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
205
- mbeExtensionWrapperCSSStyles, showMacroInteractionDesignUpdates && !isLivePageViewMode && expValEquals('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles],
205
+ css: [/* eslint-disable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
206
+ fg('confluence_frontend_native_tabs_extension') ? mbeExtensionWrapperCSSStyles : mbeExtensionWrapperCSSStylesOld, /* eslint-enable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage */
207
+ showMacroInteractionDesignUpdates && !isLivePageViewMode && expValEquals('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles],
206
208
  "data-testid": "multiBodiedExtension--wrapper-editor",
207
209
  "data-layout": node.attrs.layout
208
210
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
@@ -217,7 +219,7 @@ const MultiBodiedExtensionWithWidth = ({
217
219
  onBlur: expValEquals('editor_a11y__enghealth-46814_fy26', 'isEnabled', true) ? () => {} : undefined
218
220
  }, jsx("div", {
219
221
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
220
- css: overlayStyles
222
+ css: fg('confluence_frontend_native_tabs_extension') ? overlayStyles : overlayStylesOld
221
223
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
222
224
  ,
223
225
  className: overlayClassNames,
@@ -229,6 +231,7 @@ const MultiBodiedExtensionWithWidth = ({
229
231
  ,
230
232
  css: getContainerCssExtendedStyles(activeChildIndex, showMacroInteractionDesignUpdates),
231
233
  "data-testid": "multiBodiedExtension--container",
234
+ "data-multiBodiedExtension-container": true,
232
235
  "data-active-child-index": activeChildIndex
233
236
  }, allowBodiedOverride ? jsx("div", {
234
237
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable @atlaskit/ui-styling-standard/use-compiled -- Pre-existing lint debt surfaced by this mechanical type-import-only PR. */
2
+ /* eslint-disable @atlaskit/design-system/use-tokens-typography -- Ignored via go/DSP-18766 */
2
3
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
3
4
  import { css } from '@emotion/react';
4
5
  import { wrapperDefault } from '../Extension/styles';
@@ -6,6 +7,45 @@ import { wrapperDefault } from '../Extension/styles';
6
7
  // Wrapper the extension title and extensionContainer
7
8
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
8
9
  export const mbeExtensionWrapperCSSStyles = css(wrapperDefault, {
10
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
11
+ '&.with-margin-styles': {
12
+ marginTop: "var(--ds-space-300, 24px)",
13
+ marginLeft: "var(--ds-space-negative-250, -20px)",
14
+ marginRight: "var(--ds-space-negative-250, -20px)"
15
+ },
16
+ cursor: 'pointer',
17
+ marginTop: "var(--ds-space-250, 20px)",
18
+ marginBottom: "var(--ds-space-200, 16px)",
19
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
20
+ '.extension-title': {
21
+ display: 'flex',
22
+ alignItems: 'center',
23
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
24
+ lineHeight: '16px !important',
25
+ marginBottom: "var(--ds-space-100, 8px)",
26
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
27
+ marginLeft: `${"var(--ds-space-050, 4px)"} !important`,
28
+ marginRight: "var(--ds-space-100, 8px)",
29
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
30
+ paddingTop: `${"var(--ds-space-100, 8px)"} !important`
31
+ },
32
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
33
+ '&.with-border': {
34
+ boxShadow: `0 0 0 1px ${"var(--ds-border, #0B120E24)"}`
35
+ },
36
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
37
+ '&.with-hover-border': {
38
+ boxShadow: `0 0 0 1px ${"var(--ds-border-input, #8C8F97)"}`
39
+ },
40
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
41
+ '&.with-padding-background-styles': {
42
+ padding: `${"var(--ds-space-100, 8px)"} ${"var(--ds-space-250, 20px)"}`,
43
+ background: 'transparent'
44
+ }
45
+ });
46
+
47
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
48
+ export const mbeExtensionWrapperCSSStylesOld = css(wrapperDefault, {
9
49
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
10
50
  '&.with-margin-styles': {
11
51
  marginTop: 0,
@@ -19,7 +59,7 @@ export const mbeExtensionWrapperCSSStyles = css(wrapperDefault, {
19
59
  '.extension-title': {
20
60
  display: 'flex',
21
61
  alignItems: 'center',
22
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles, @atlaskit/design-system/use-tokens-typography -- Ignored via go/DSP-18766
62
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
23
63
  lineHeight: '16px !important',
24
64
  marginBottom: "var(--ds-space-100, 8px)",
25
65
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
@@ -45,6 +85,23 @@ export const mbeExtensionWrapperCSSStyles = css(wrapperDefault, {
45
85
 
46
86
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
47
87
  export const overlayStyles = css({
88
+ borderRadius: "var(--ds-radius-small, 3px)",
89
+ position: 'absolute',
90
+ width: '100%',
91
+ height: '100%',
92
+ opacity: 0,
93
+ pointerEvents: 'none',
94
+ transition: 'opacity 0.3s',
95
+ zIndex: 1,
96
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
97
+ '&.with-margin': {
98
+ marginTop: "var(--ds-space-negative-100, -8px)",
99
+ marginLeft: "var(--ds-space-negative-250, -20px)"
100
+ }
101
+ });
102
+
103
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
104
+ export const overlayStylesOld = css({
48
105
  borderRadius: "var(--ds-radius-small, 3px)",
49
106
  position: 'absolute',
50
107
  width: '100%',
@@ -196,14 +196,27 @@ export class ExtensionNode extends ReactNodeView {
196
196
  }
197
197
 
198
198
  /**
199
- * When interacting with input elements inside an extension's body, the events
200
- * bubble up to the editor and get handled by it. This almost always gets in the way
201
- * of being able to actually interact with said input in the extension, i.e.
202
- * typing inside a text field (in an extension body) will print the text in the editor
203
- * content area instead. This change prevents the editor view from trying to handle these events,
204
- * when the target of the event is an input element, so the extension can.
199
+ * Prevents ProseMirror from handling events that belong to the extension's React UI.
200
+ *
201
+ * For multibodied extensions: the node consists of a React app (e.g. tab bar) that controls
202
+ * frames, and the editable frames themselves. Events inside frames must reach ProseMirror
203
+ * for normal editing; events in the surrounding React app (buttons, navigation) are stopped
204
+ * so ProseMirror doesn't create a NodeSelection on the entire node.
205
+ *
206
+ * For other extensions: input/textarea events are stopped so users can interact
207
+ * with form elements inside the extension body without the editor intercepting them.
205
208
  */
206
209
  stopEvent(event) {
210
+ if (this.node.type.name === 'multiBodiedExtension') {
211
+ const target = event.target;
212
+ if (target instanceof Element) {
213
+ if (target.closest('[data-multibodiedextension-frames]')) {
214
+ return false;
215
+ }
216
+ return !!target.closest('[data-multiBodiedExtension-container]');
217
+ }
218
+ return false;
219
+ }
207
220
  if (fg('forge-ui-extensionnodeview-stop-event-for-textarea')) {
208
221
  return event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement;
209
222
  }
@@ -4,7 +4,7 @@ import { isFedRamp } from './environment';
4
4
  import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
5
5
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
6
6
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
7
- const packageVersion = "115.0.3";
7
+ const packageVersion = "115.2.0";
8
8
  const sanitiseSentryEvents = (data, _hint) => {
9
9
  // Remove URL as it has UGC
10
10
  // Ignored via go/ees007
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import { fg } from '@atlaskit/platform-feature-flags';
15
15
  import Layer from '../Layer';
16
16
  const packageName = "@atlaskit/editor-common";
17
- const packageVersion = "115.0.3";
17
+ const packageVersion = "115.2.0";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -6,6 +6,7 @@
6
6
 
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
8
8
  import { css } from '@emotion/react';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
9
10
  // Wraps the navigation bar and extensionFrames
10
11
  const mbeExtensionContainer = css({
11
12
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
@@ -61,6 +62,33 @@ const mbeNavigation = css({
61
62
  }
62
63
  });
63
64
  const extensionFrameContent = css({
65
+ display: 'block',
66
+ minHeight: '100px',
67
+ background: 'transparent',
68
+ borderBottomLeftRadius: "var(--ds-radius-small, 3px)",
69
+ borderBottomRightRadius: "var(--ds-radius-small, 3px)",
70
+ marginLeft: "var(--ds-space-100, 8px)",
71
+ marginRight: "var(--ds-space-100, 8px)",
72
+ cursor: 'initial',
73
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
74
+ '.pm-table-with-controls': {
75
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
76
+ marginLeft: `${"var(--ds-space-150, 12px)"} !important`,
77
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
78
+ paddingRight: `${"var(--ds-space-150, 12px)"} !important`
79
+ },
80
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
81
+ '.bodiedExtensionView-content-wrap': {
82
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
83
+ marginTop: `${"var(--ds-space-150, 12px)"} !important`
84
+ },
85
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
86
+ '.extensionView-content-wrap': {
87
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
88
+ marginTop: `${"var(--ds-space-100, 8px)"} !important`
89
+ }
90
+ });
91
+ const extensionFrameContentOld = css({
64
92
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
65
93
  padding: `${"var(--ds-space-100, 8px)"} !important`,
66
94
  display: 'block',
@@ -101,5 +129,7 @@ export const removeMarginsAndBorder = css({
101
129
  export const sharedMultiBodiedExtensionStyles = {
102
130
  mbeExtensionContainer,
103
131
  mbeNavigation,
104
- extensionFrameContent
132
+ get extensionFrameContent() {
133
+ return fg('confluence_frontend_native_tabs_extension') ? extensionFrameContent : extensionFrameContentOld;
134
+ }
105
135
  };
@@ -5,6 +5,11 @@ export var aiSuggestionsMessages = defineMessages({
5
5
  defaultMessage: 'Review',
6
6
  description: 'Label for the Suggest edits button in the editor toolbar'
7
7
  },
8
+ suggestEditsPromptPrefix: {
9
+ id: 'fabric.editor.ai.suggestions.suggestEditsPromptPrefix.non-final',
10
+ defaultMessage: 'Review my content with ',
11
+ description: 'Localised text that precedes the suggest-edits skill tag in the prompt sent to the AI service. The trailing space is intentional — it separates this text from the skill tag that follows. Localise it in a way where the prompt ends with the skill tag. (With the skill tag it will look like e.g. "Review my content with /suggest-edits")'
12
+ },
8
13
  suggestionsToolbarButtonLabel: {
9
14
  id: 'fabric.editor.ai.suggestions.toolbarButton.label.non-final',
10
15
  defaultMessage: 'Suggestions',
@@ -16,35 +16,45 @@ export var useMultiBodiedExtensionActions = function useMultiBodiedExtensionActi
16
16
  childrenContainer = _ref.childrenContainer;
17
17
  var actions = React.useMemo(function () {
18
18
  return {
19
- changeActive: function changeActive(index) {
20
- var _possiblyMbeNode$type;
19
+ changeActive: function changeActive(index, options) {
20
+ var _options$selection, _possiblyMbeNode$type;
21
21
  var state = editorView.state,
22
22
  dispatch = editorView.dispatch;
23
23
  var updateActiveChildResult = updateActiveChild(index);
24
24
  if (eventDispatcher) {
25
25
  sendMBEAnalyticsEvent(ACTION.CHANGE_ACTIVE, node, eventDispatcher);
26
26
  }
27
- // On selection of a childFrame, we need to change the focus/selection to the end of the target child Frame
27
+ var selection = (_options$selection = options === null || options === void 0 ? void 0 : options.selection) !== null && _options$selection !== void 0 ? _options$selection : 'none';
28
+ if (selection === 'none') {
29
+ return updateActiveChildResult;
30
+ }
28
31
  var pos = getPos();
29
32
  if (typeof pos !== 'number') {
30
33
  return updateActiveChildResult;
31
34
  }
32
35
  var possiblyMbeNode = state.doc.nodeAt(pos);
33
- var desiredPos = pos;
34
36
  if (possiblyMbeNode && (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$type = possiblyMbeNode.type) === null || _possiblyMbeNode$type === void 0 ? void 0 : _possiblyMbeNode$type.name) === 'multiBodiedExtension' && possiblyMbeNode !== null && possiblyMbeNode !== void 0 && possiblyMbeNode.content) {
35
37
  var _possiblyMbeNode$cont;
36
38
  if (index < 0 || index >= (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont = possiblyMbeNode.content) === null || _possiblyMbeNode$cont === void 0 ? void 0 : _possiblyMbeNode$cont.childCount)) {
37
39
  var _possiblyMbeNode$cont2;
38
40
  throw new Error("Index out of bounds: valid range is 0-".concat((possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont2 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont2 === void 0 ? void 0 : _possiblyMbeNode$cont2.childCount) - 1, " inclusive"));
39
41
  }
40
- for (var i = 0; i <= index && i < (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont3 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont3 === void 0 ? void 0 : _possiblyMbeNode$cont3.childCount); i++) {
42
+ var desiredPos = pos;
43
+ for (var i = 0; i < index && i < (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont3 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont3 === void 0 ? void 0 : _possiblyMbeNode$cont3.childCount); i++) {
41
44
  var _possiblyMbeNode$cont3, _possiblyMbeNode$cont4;
42
45
  desiredPos += (possiblyMbeNode === null || possiblyMbeNode === void 0 || (_possiblyMbeNode$cont4 = possiblyMbeNode.content) === null || _possiblyMbeNode$cont4 === void 0 || (_possiblyMbeNode$cont4 = _possiblyMbeNode$cont4.child(i)) === null || _possiblyMbeNode$cont4 === void 0 ? void 0 : _possiblyMbeNode$cont4.nodeSize) || 0;
43
46
  }
44
- /* desiredPos gives the cursor at the end of last child of the current frame, in case of paragraph nodes, this will be the end of the paragraph
45
- * Performing -1 brings the cursor inside the paragraph, similar to a user click, so any pasted text will be inside the last paragraph rather than a new line
46
- */
47
- dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(desiredPos - 1))));
47
+ var targetFrame = possiblyMbeNode.content.child(index);
48
+ if (selection === 'start') {
49
+ // +1 moves past the extensionFrame opening token; TextSelection.near() finds
50
+ // the nearest valid text cursor position from there.
51
+ dispatch(state.tr.setSelection(TextSelection.near(state.doc.resolve(desiredPos + 1))));
52
+ } else {
53
+ // Place cursor at the end of the target frame's content.
54
+ // -1 bias searches backward from the frame's closing token.
55
+ dispatch(state.tr.setSelection(TextSelection.near(state.doc.resolve(desiredPos + targetFrame.nodeSize), -1)));
56
+ }
57
+ editorView.focus();
48
58
  }
49
59
  return updateActiveChildResult;
50
60
  },
@@ -16,6 +16,7 @@ import React, { Fragment, useState } from 'react';
16
16
  import { css, jsx } from '@emotion/react';
17
17
  import classnames from 'classnames';
18
18
  import EditorFileIcon from '@atlaskit/icon/core/file';
19
+ import { fg } from '@atlaskit/platform-feature-flags';
19
20
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
20
21
  import { useSharedPluginStateWithSelector } from '../../hooks';
21
22
  import { removeMarginsAndBorder, sharedMultiBodiedExtensionStyles } from '../../ui/MultiBodiedExtension';
@@ -23,7 +24,7 @@ import { calculateBreakoutStyles, getExtensionLozengeData } from '../../utils';
23
24
  import ExtensionLozenge from '../Extension/Lozenge';
24
25
  import { shouldExtensionBreakout } from '../utils/should-extension-breakout';
25
26
  import { useMultiBodiedExtensionActions } from './action-api';
26
- import { mbeExtensionWrapperCSSStyles, overlayStyles } from './styles';
27
+ import { mbeExtensionWrapperCSSStyles, mbeExtensionWrapperCSSStylesOld, overlayStyles, overlayStylesOld } from './styles';
27
28
  var getContainerCssExtendedStyles = function getContainerCssExtendedStyles(activeChildIndex, showMacroInteractionDesignUpdates) {
28
29
  return (
29
30
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
@@ -51,6 +52,7 @@ var MultiBodiedExtensionFrames = function MultiBodiedExtensionFrames(_ref) {
51
52
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
52
53
  className: "multiBodiedExtension--frames",
53
54
  "data-testid": "multiBodiedExtension--frames",
55
+ "data-multibodiedextension-frames": true,
54
56
  ref: articleRef
55
57
  });
56
58
  };
@@ -202,9 +204,9 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
202
204
  }), jsx("div", {
203
205
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
204
206
  className: wrapperClassNames,
205
- css: [
206
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
207
- mbeExtensionWrapperCSSStyles, showMacroInteractionDesignUpdates && !isLivePageViewMode && expValEquals('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles],
207
+ css: [/* eslint-disable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
208
+ fg('confluence_frontend_native_tabs_extension') ? mbeExtensionWrapperCSSStyles : mbeExtensionWrapperCSSStylesOld, /* eslint-enable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage */
209
+ showMacroInteractionDesignUpdates && !isLivePageViewMode && expValEquals('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles],
208
210
  "data-testid": "multiBodiedExtension--wrapper-editor",
209
211
  "data-layout": node.attrs.layout
210
212
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
@@ -223,7 +225,7 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
223
225
  onBlur: expValEquals('editor_a11y__enghealth-46814_fy26', 'isEnabled', true) ? function () {} : undefined
224
226
  }, jsx("div", {
225
227
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
226
- css: overlayStyles
228
+ css: fg('confluence_frontend_native_tabs_extension') ? overlayStyles : overlayStylesOld
227
229
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
228
230
  ,
229
231
  className: overlayClassNames,
@@ -235,6 +237,7 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
235
237
  ,
236
238
  css: getContainerCssExtendedStyles(activeChildIndex, showMacroInteractionDesignUpdates),
237
239
  "data-testid": "multiBodiedExtension--container",
240
+ "data-multiBodiedExtension-container": true,
238
241
  "data-active-child-index": activeChildIndex
239
242
  }, allowBodiedOverride ? jsx("div", {
240
243
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable @atlaskit/ui-styling-standard/use-compiled -- Pre-existing lint debt surfaced by this mechanical type-import-only PR. */
2
+ /* eslint-disable @atlaskit/design-system/use-tokens-typography -- Ignored via go/DSP-18766 */
2
3
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
3
4
  import { css } from '@emotion/react';
4
5
  import { wrapperDefault } from '../Extension/styles';
@@ -6,6 +7,45 @@ import { wrapperDefault } from '../Extension/styles';
6
7
  // Wrapper the extension title and extensionContainer
7
8
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
8
9
  export var mbeExtensionWrapperCSSStyles = css(wrapperDefault, {
10
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
11
+ '&.with-margin-styles': {
12
+ marginTop: "var(--ds-space-300, 24px)",
13
+ marginLeft: "var(--ds-space-negative-250, -20px)",
14
+ marginRight: "var(--ds-space-negative-250, -20px)"
15
+ },
16
+ cursor: 'pointer',
17
+ marginTop: "var(--ds-space-250, 20px)",
18
+ marginBottom: "var(--ds-space-200, 16px)",
19
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
20
+ '.extension-title': {
21
+ display: 'flex',
22
+ alignItems: 'center',
23
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
24
+ lineHeight: '16px !important',
25
+ marginBottom: "var(--ds-space-100, 8px)",
26
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
27
+ marginLeft: "var(--ds-space-050, 4px)".concat(" !important"),
28
+ marginRight: "var(--ds-space-100, 8px)",
29
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
30
+ paddingTop: "var(--ds-space-100, 8px)".concat(" !important")
31
+ },
32
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
33
+ '&.with-border': {
34
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border, #0B120E24)")
35
+ },
36
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
37
+ '&.with-hover-border': {
38
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border-input, #8C8F97)")
39
+ },
40
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
41
+ '&.with-padding-background-styles': {
42
+ padding: "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-250, 20px)"),
43
+ background: 'transparent'
44
+ }
45
+ });
46
+
47
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
48
+ export var mbeExtensionWrapperCSSStylesOld = css(wrapperDefault, {
9
49
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
10
50
  '&.with-margin-styles': {
11
51
  marginTop: 0,
@@ -19,7 +59,7 @@ export var mbeExtensionWrapperCSSStyles = css(wrapperDefault, {
19
59
  '.extension-title': {
20
60
  display: 'flex',
21
61
  alignItems: 'center',
22
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles, @atlaskit/design-system/use-tokens-typography -- Ignored via go/DSP-18766
62
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
23
63
  lineHeight: '16px !important',
24
64
  marginBottom: "var(--ds-space-100, 8px)",
25
65
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
@@ -45,6 +85,23 @@ export var mbeExtensionWrapperCSSStyles = css(wrapperDefault, {
45
85
 
46
86
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
47
87
  export var overlayStyles = css({
88
+ borderRadius: "var(--ds-radius-small, 3px)",
89
+ position: 'absolute',
90
+ width: '100%',
91
+ height: '100%',
92
+ opacity: 0,
93
+ pointerEvents: 'none',
94
+ transition: 'opacity 0.3s',
95
+ zIndex: 1,
96
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
97
+ '&.with-margin': {
98
+ marginTop: "var(--ds-space-negative-100, -8px)",
99
+ marginLeft: "var(--ds-space-negative-250, -20px)"
100
+ }
101
+ });
102
+
103
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
104
+ export var overlayStylesOld = css({
48
105
  borderRadius: "var(--ds-radius-small, 3px)",
49
106
  position: 'absolute',
50
107
  width: '100%',
@@ -228,16 +228,29 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
228
228
  }
229
229
 
230
230
  /**
231
- * When interacting with input elements inside an extension's body, the events
232
- * bubble up to the editor and get handled by it. This almost always gets in the way
233
- * of being able to actually interact with said input in the extension, i.e.
234
- * typing inside a text field (in an extension body) will print the text in the editor
235
- * content area instead. This change prevents the editor view from trying to handle these events,
236
- * when the target of the event is an input element, so the extension can.
231
+ * Prevents ProseMirror from handling events that belong to the extension's React UI.
232
+ *
233
+ * For multibodied extensions: the node consists of a React app (e.g. tab bar) that controls
234
+ * frames, and the editable frames themselves. Events inside frames must reach ProseMirror
235
+ * for normal editing; events in the surrounding React app (buttons, navigation) are stopped
236
+ * so ProseMirror doesn't create a NodeSelection on the entire node.
237
+ *
238
+ * For other extensions: input/textarea events are stopped so users can interact
239
+ * with form elements inside the extension body without the editor intercepting them.
237
240
  */
238
241
  }, {
239
242
  key: "stopEvent",
240
243
  value: function stopEvent(event) {
244
+ if (this.node.type.name === 'multiBodiedExtension') {
245
+ var target = event.target;
246
+ if (target instanceof Element) {
247
+ if (target.closest('[data-multibodiedextension-frames]')) {
248
+ return false;
249
+ }
250
+ return !!target.closest('[data-multiBodiedExtension-container]');
251
+ }
252
+ return false;
253
+ }
241
254
  if (fg('forge-ui-extensionnodeview-stop-event-for-textarea')) {
242
255
  return event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement;
243
256
  }
@@ -10,7 +10,7 @@ import { isFedRamp } from './environment';
10
10
  import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
11
11
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
12
12
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
13
- var packageVersion = "115.0.3";
13
+ var packageVersion = "115.2.0";
14
14
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
15
15
  // Remove URL as it has UGC
16
16
  // Ignored via go/ees007
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
21
21
  import { fg } from '@atlaskit/platform-feature-flags';
22
22
  import Layer from '../Layer';
23
23
  var packageName = "@atlaskit/editor-common";
24
- var packageVersion = "115.0.3";
24
+ var packageVersion = "115.2.0";
25
25
  var halfFocusRing = 1;
26
26
  var dropOffset = '0, 8';
27
27
  var fadeIn = keyframes({
@@ -6,6 +6,7 @@
6
6
 
7
7
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
8
8
  import { css } from '@emotion/react';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
9
10
  // Wraps the navigation bar and extensionFrames
10
11
  var mbeExtensionContainer = css({
11
12
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
@@ -61,6 +62,33 @@ var mbeNavigation = css({
61
62
  }
62
63
  });
63
64
  var extensionFrameContent = css({
65
+ display: 'block',
66
+ minHeight: '100px',
67
+ background: 'transparent',
68
+ borderBottomLeftRadius: "var(--ds-radius-small, 3px)",
69
+ borderBottomRightRadius: "var(--ds-radius-small, 3px)",
70
+ marginLeft: "var(--ds-space-100, 8px)",
71
+ marginRight: "var(--ds-space-100, 8px)",
72
+ cursor: 'initial',
73
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
74
+ '.pm-table-with-controls': {
75
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
76
+ marginLeft: "var(--ds-space-150, 12px)".concat(" !important"),
77
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
78
+ paddingRight: "var(--ds-space-150, 12px)".concat(" !important")
79
+ },
80
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
81
+ '.bodiedExtensionView-content-wrap': {
82
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
83
+ marginTop: "var(--ds-space-150, 12px)".concat(" !important")
84
+ },
85
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
86
+ '.extensionView-content-wrap': {
87
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
88
+ marginTop: "var(--ds-space-100, 8px)".concat(" !important")
89
+ }
90
+ });
91
+ var extensionFrameContentOld = css({
64
92
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
65
93
  padding: "var(--ds-space-100, 8px)".concat(" !important"),
66
94
  display: 'block',
@@ -101,5 +129,7 @@ export var removeMarginsAndBorder = css({
101
129
  export var sharedMultiBodiedExtensionStyles = {
102
130
  mbeExtensionContainer: mbeExtensionContainer,
103
131
  mbeNavigation: mbeNavigation,
104
- extensionFrameContent: extensionFrameContent
132
+ get extensionFrameContent() {
133
+ return fg('confluence_frontend_native_tabs_extension') ? extensionFrameContent : extensionFrameContentOld;
134
+ }
105
135
  };
@@ -119,6 +119,11 @@ export declare const aiSuggestionsMessages: {
119
119
  description: string;
120
120
  id: string;
121
121
  };
122
+ suggestEditsPromptPrefix: {
123
+ defaultMessage: string;
124
+ description: string;
125
+ id: string;
126
+ };
122
127
  suggestedLabel: {
123
128
  defaultMessage: string;
124
129
  description: string;
@@ -1,3 +1,5 @@
1
1
  import type { SerializedStyles } from '@emotion/react';
2
2
  export declare const mbeExtensionWrapperCSSStyles: SerializedStyles;
3
+ export declare const mbeExtensionWrapperCSSStylesOld: SerializedStyles;
3
4
  export declare const overlayStyles: SerializedStyles;
5
+ export declare const overlayStylesOld: SerializedStyles;
@@ -55,12 +55,15 @@ export declare class ExtensionNode<AdditionalParams = unknown> extends ReactNode
55
55
  init(): this;
56
56
  update(node: PmNode, decorations: ReadonlyArray<Decoration>, _innerDecorations?: DecorationSource, validUpdate?: (currentNode: PmNode, newNode: PmNode) => boolean): boolean;
57
57
  /**
58
- * When interacting with input elements inside an extension's body, the events
59
- * bubble up to the editor and get handled by it. This almost always gets in the way
60
- * of being able to actually interact with said input in the extension, i.e.
61
- * typing inside a text field (in an extension body) will print the text in the editor
62
- * content area instead. This change prevents the editor view from trying to handle these events,
63
- * when the target of the event is an input element, so the extension can.
58
+ * Prevents ProseMirror from handling events that belong to the extension's React UI.
59
+ *
60
+ * For multibodied extensions: the node consists of a React app (e.g. tab bar) that controls
61
+ * frames, and the editable frames themselves. Events inside frames must reach ProseMirror
62
+ * for normal editing; events in the surrounding React app (buttons, navigation) are stopped
63
+ * so ProseMirror doesn't create a NodeSelection on the entire node.
64
+ *
65
+ * For other extensions: input/textarea events are stopped so users can interact
66
+ * with form elements inside the extension body without the editor intercepting them.
64
67
  */
65
68
  stopEvent(event: Event): boolean;
66
69
  getContentDOM(): {
@@ -43,9 +43,13 @@ export interface ExtensionHandlers<T extends Parameters = any> {
43
43
  export type ReferenceEntity = {
44
44
  [prop: string]: ADFEntity | Object;
45
45
  };
46
+ export type ChangeActiveOptions = {
47
+ /** Controls cursor placement after switching frames. Defaults to 'none'. */
48
+ selection?: 'none' | 'start' | 'end';
49
+ };
46
50
  export type MultiBodiedExtensionActions = {
47
51
  addChild: () => boolean;
48
- changeActive: (index: number) => boolean;
52
+ changeActive: (index: number, options?: ChangeActiveOptions) => boolean;
49
53
  getChildren: () => Array<ADFEntity>;
50
54
  getChildrenContainer: () => React.ReactNode;
51
55
  getChildrenCount: () => number;
@@ -5,7 +5,7 @@
5
5
  import type { SerializedStyles } from '@emotion/react';
6
6
  export declare const removeMarginsAndBorder: SerializedStyles;
7
7
  export declare const sharedMultiBodiedExtensionStyles: {
8
+ extensionFrameContent: SerializedStyles;
8
9
  mbeExtensionContainer: SerializedStyles;
9
10
  mbeNavigation: SerializedStyles;
10
- extensionFrameContent: SerializedStyles;
11
11
  };
@@ -119,6 +119,11 @@ export declare const aiSuggestionsMessages: {
119
119
  description: string;
120
120
  id: string;
121
121
  };
122
+ suggestEditsPromptPrefix: {
123
+ defaultMessage: string;
124
+ description: string;
125
+ id: string;
126
+ };
122
127
  suggestedLabel: {
123
128
  defaultMessage: string;
124
129
  description: string;
@@ -1,3 +1,5 @@
1
1
  import type { SerializedStyles } from '@emotion/react';
2
2
  export declare const mbeExtensionWrapperCSSStyles: SerializedStyles;
3
+ export declare const mbeExtensionWrapperCSSStylesOld: SerializedStyles;
3
4
  export declare const overlayStyles: SerializedStyles;
5
+ export declare const overlayStylesOld: SerializedStyles;
@@ -55,12 +55,15 @@ export declare class ExtensionNode<AdditionalParams = unknown> extends ReactNode
55
55
  init(): this;
56
56
  update(node: PmNode, decorations: ReadonlyArray<Decoration>, _innerDecorations?: DecorationSource, validUpdate?: (currentNode: PmNode, newNode: PmNode) => boolean): boolean;
57
57
  /**
58
- * When interacting with input elements inside an extension's body, the events
59
- * bubble up to the editor and get handled by it. This almost always gets in the way
60
- * of being able to actually interact with said input in the extension, i.e.
61
- * typing inside a text field (in an extension body) will print the text in the editor
62
- * content area instead. This change prevents the editor view from trying to handle these events,
63
- * when the target of the event is an input element, so the extension can.
58
+ * Prevents ProseMirror from handling events that belong to the extension's React UI.
59
+ *
60
+ * For multibodied extensions: the node consists of a React app (e.g. tab bar) that controls
61
+ * frames, and the editable frames themselves. Events inside frames must reach ProseMirror
62
+ * for normal editing; events in the surrounding React app (buttons, navigation) are stopped
63
+ * so ProseMirror doesn't create a NodeSelection on the entire node.
64
+ *
65
+ * For other extensions: input/textarea events are stopped so users can interact
66
+ * with form elements inside the extension body without the editor intercepting them.
64
67
  */
65
68
  stopEvent(event: Event): boolean;
66
69
  getContentDOM(): {
@@ -43,9 +43,13 @@ export interface ExtensionHandlers<T extends Parameters = any> {
43
43
  export type ReferenceEntity = {
44
44
  [prop: string]: ADFEntity | Object;
45
45
  };
46
+ export type ChangeActiveOptions = {
47
+ /** Controls cursor placement after switching frames. Defaults to 'none'. */
48
+ selection?: 'none' | 'start' | 'end';
49
+ };
46
50
  export type MultiBodiedExtensionActions = {
47
51
  addChild: () => boolean;
48
- changeActive: (index: number) => boolean;
52
+ changeActive: (index: number, options?: ChangeActiveOptions) => boolean;
49
53
  getChildren: () => Array<ADFEntity>;
50
54
  getChildrenContainer: () => React.ReactNode;
51
55
  getChildrenCount: () => number;
@@ -5,7 +5,7 @@
5
5
  import type { SerializedStyles } from '@emotion/react';
6
6
  export declare const removeMarginsAndBorder: SerializedStyles;
7
7
  export declare const sharedMultiBodiedExtensionStyles: {
8
+ extensionFrameContent: SerializedStyles;
8
9
  mbeExtensionContainer: SerializedStyles;
9
10
  mbeNavigation: SerializedStyles;
10
- extensionFrameContent: SerializedStyles;
11
11
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "115.1.0",
3
+ "version": "115.2.1",
4
4
  "description": "A package that contains common classes and components for editor and renderer",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -81,13 +81,13 @@
81
81
  "@atlaskit/prosemirror-history": "^0.2.0",
82
82
  "@atlaskit/react-ufo": "^6.6.0",
83
83
  "@atlaskit/section-message": "^8.13.0",
84
- "@atlaskit/smart-card": "^44.20.0",
84
+ "@atlaskit/smart-card": "^44.21.0",
85
85
  "@atlaskit/smart-user-picker": "^10.2.0",
86
86
  "@atlaskit/spinner": "^19.1.0",
87
87
  "@atlaskit/task-decision": "^20.1.0",
88
88
  "@atlaskit/teams-app-config": "^1.12.0",
89
89
  "@atlaskit/textfield": "^8.3.0",
90
- "@atlaskit/tmp-editor-statsig": "^88.4.0",
90
+ "@atlaskit/tmp-editor-statsig": "^88.5.0",
91
91
  "@atlaskit/tokens": "^13.1.0",
92
92
  "@atlaskit/tooltip": "^22.6.0",
93
93
  "@atlaskit/width-detector": "^5.1.0",