@atlaskit/editor-common 110.18.4 → 110.18.6

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 (37) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/experiences/Experience.js +63 -23
  3. package/dist/cjs/experiences/ExperienceCheck.js +5 -1
  4. package/dist/cjs/experiences/ExperienceCheckDomMutation.js +6 -2
  5. package/dist/cjs/experiences/ExperienceCheckTimeout.js +24 -8
  6. package/dist/cjs/monitoring/error.js +1 -1
  7. package/dist/cjs/provider-factory/with-providers.js +1 -2
  8. package/dist/cjs/toolbar/EditorToolbarUIProvider.js +29 -9
  9. package/dist/cjs/ui/DropList/index.js +1 -1
  10. package/dist/es2019/experiences/Experience.js +63 -22
  11. package/dist/es2019/experiences/ExperienceCheck.js +1 -0
  12. package/dist/es2019/experiences/ExperienceCheckDomMutation.js +6 -2
  13. package/dist/es2019/experiences/ExperienceCheckTimeout.js +21 -8
  14. package/dist/es2019/monitoring/error.js +1 -1
  15. package/dist/es2019/provider-factory/with-providers.js +1 -2
  16. package/dist/es2019/toolbar/EditorToolbarUIProvider.js +26 -8
  17. package/dist/es2019/ui/DropList/index.js +1 -1
  18. package/dist/esm/experiences/Experience.js +63 -23
  19. package/dist/esm/experiences/ExperienceCheck.js +1 -0
  20. package/dist/esm/experiences/ExperienceCheckDomMutation.js +6 -2
  21. package/dist/esm/experiences/ExperienceCheckTimeout.js +24 -8
  22. package/dist/esm/monitoring/error.js +1 -1
  23. package/dist/esm/provider-factory/with-providers.js +1 -2
  24. package/dist/esm/toolbar/EditorToolbarUIProvider.js +29 -9
  25. package/dist/esm/ui/DropList/index.js +1 -1
  26. package/dist/types/experiences/Experience.d.ts +43 -12
  27. package/dist/types/experiences/ExperienceCheck.d.ts +5 -7
  28. package/dist/types/experiences/ExperienceCheckDomMutation.d.ts +16 -6
  29. package/dist/types/experiences/ExperienceCheckTimeout.d.ts +19 -4
  30. package/dist/types-ts4.5/experiences/Experience.d.ts +43 -12
  31. package/dist/types-ts4.5/experiences/ExperienceCheck.d.ts +5 -7
  32. package/dist/types-ts4.5/experiences/ExperienceCheckDomMutation.d.ts +16 -6
  33. package/dist/types-ts4.5/experiences/ExperienceCheckTimeout.d.ts +19 -4
  34. package/package.json +3 -3
  35. package/afm-dev-agents/tsconfig.json +0 -195
  36. package/afm-rovo-extension/tsconfig.json +0 -195
  37. package/afm-volt/tsconfig.json +0 -183
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 110.18.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [`bbd03bed5ca41`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bbd03bed5ca41) -
8
+ [ux] ED-29587 Keyboard shortcuts break when navigating to and from dropdown menus
9
+ - Updated dependencies
10
+
11
+ ## 110.18.5
12
+
13
+ ### Patch Changes
14
+
15
+ - [`822ed20eeca65`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/822ed20eeca65) -
16
+ Clean up platform_editor_fix_unsubscribe_of_provider
17
+ - [`7aff1e36b43e1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7aff1e36b43e1) -
18
+ Improve editor selection toolbar experience tracking
19
+ - [`3cbddf575e48e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3cbddf575e48e) -
20
+ platform_editor_ai_open_chat_general_ai_fg clean up
21
+
3
22
  ## 110.18.4
4
23
 
5
24
  ### Patch Changes
@@ -5,10 +5,13 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.Experience = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
8
9
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
10
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
11
  var _ufo = require("@atlaskit/ufo");
11
12
  var _ExperienceCheckComposite = require("./ExperienceCheckComposite");
13
+ 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; }
14
+ 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; }
12
15
  var PROGRESS_STATES = [_ufo.UFOExperienceState.STARTED.id, _ufo.UFOExperienceState.IN_PROGRESS.id];
13
16
  var Experience = exports.Experience = /*#__PURE__*/function () {
14
17
  function Experience(id) {
@@ -38,11 +41,18 @@ var Experience = exports.Experience = /*#__PURE__*/function () {
38
41
  var _this = this;
39
42
  this.stopCheck();
40
43
  this.check.start(function (result) {
44
+ var metadata = result.metadata;
41
45
  if (result.status === 'success') {
42
- _this.success();
43
- } else {
46
+ _this.success({
47
+ metadata: metadata
48
+ });
49
+ } else if (result.status === 'abort') {
50
+ _this.abort({
51
+ metadata: metadata
52
+ });
53
+ } else if (result.status === 'failure') {
44
54
  _this.failure({
45
- reason: result.reason
55
+ metadata: metadata
46
56
  });
47
57
  }
48
58
  });
@@ -57,13 +67,28 @@ var Experience = exports.Experience = /*#__PURE__*/function () {
57
67
  value: function isInProgress() {
58
68
  return PROGRESS_STATES.includes(this.ufoExperience.state.id);
59
69
  }
70
+ }, {
71
+ key: "getEndStateConfig",
72
+ value: function getEndStateConfig(options) {
73
+ var _this$startOptions, _this$startOptions2;
74
+ return {
75
+ metadata: options !== null && options !== void 0 && options.metadata || (_this$startOptions = this.startOptions) !== null && _this$startOptions !== void 0 && _this$startOptions.metadata ? _objectSpread(_objectSpread({}, (_this$startOptions2 = this.startOptions) === null || _this$startOptions2 === void 0 ? void 0 : _this$startOptions2.metadata), options === null || options === void 0 ? void 0 : options.metadata) : undefined
76
+ };
77
+ }
60
78
 
61
79
  /**
62
- * Starts UFO experience tracking and starts all checks which monitor for completion of the experience.
80
+ * Starts tracking the experience and all checks which monitor for completion.
81
+ *
82
+ * If the experience is already in progress, this will restart the checks.
83
+ * Metadata from options will be merged with any end state metadata.
84
+ *
85
+ * @param options - Configuration for starting the experience
86
+ * @param options.metadata - Optional metadata attached to all subsequent events for this started experience
63
87
  */
64
88
  }, {
65
89
  key: "start",
66
- value: function start() {
90
+ value: function start(options) {
91
+ this.startOptions = options === null || options === void 0 ? void 0 : options.metadata;
67
92
  this.ufoExperience.start();
68
93
  if (this.isInProgress()) {
69
94
  this.startCheck();
@@ -71,43 +96,58 @@ var Experience = exports.Experience = /*#__PURE__*/function () {
71
96
  }
72
97
 
73
98
  /**
74
- * Manually mark the experience as successful and stop any ongoing checks.
99
+ * Marks the experience as successful and stops any ongoing checks.
100
+ *
101
+ * Use this when the experience completes as expected.
102
+ *
103
+ * @param options - Configuration for the success event
104
+ * @param options.metadata - Optional metadata attached to the success event
75
105
  */
76
106
  }, {
77
107
  key: "success",
78
- value: function success() {
108
+ value: function success(options) {
79
109
  this.stopCheck();
80
- this.ufoExperience.success();
110
+ this.ufoExperience.success(this.getEndStateConfig(options));
111
+ this.startOptions = undefined;
81
112
  }
82
113
 
83
114
  /**
84
- * Manually abort the experience and stop any ongoing checks.
115
+ * Aborts the experience and stops any ongoing checks.
116
+ *
117
+ * Use this when a started experience terminates early due to user action or context change
118
+ * (e.g., component unmount, navigation). This is neither success nor failure.
85
119
  *
86
- * Typically used when the experience did not complete due to user action and should not be marked as success or failure,
87
- * for example on unmount or when navigating away from a page.
120
+ * @param options - Configuration for the abort event
121
+ * @param options.metadata - Optional metadata attached to the abort event
122
+ *
123
+ * @example
124
+ * // Abort on component unmount
125
+ * useEffect(() => {
126
+ * return () => experience.abort({ metadata: { reason: 'unmount' } });
127
+ * }, []);
88
128
  */
89
129
  }, {
90
130
  key: "abort",
91
- value: function abort() {
131
+ value: function abort(options) {
92
132
  this.stopCheck();
93
- this.ufoExperience.abort();
133
+ this.ufoExperience.abort(this.getEndStateConfig(options));
134
+ this.startOptions = undefined;
94
135
  }
95
136
 
96
137
  /**
97
- * Manually mark the experience as failed and stop any ongoing checks.
138
+ * Manually marks the experience as failed and stops any ongoing checks.
139
+ *
140
+ * Use this for actual failures in the experience flow (e.g., timeout, error conditions).
141
+ *
142
+ * @param options - Configuration for the failure event
143
+ * @param options.metadata - Optional metadata attached to the failure event
98
144
  */
99
145
  }, {
100
146
  key: "failure",
101
- value: function failure() {
102
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
103
- _ref$reason = _ref.reason,
104
- reason = _ref$reason === void 0 ? 'error' : _ref$reason;
147
+ value: function failure(options) {
105
148
  this.stopCheck();
106
- this.ufoExperience.failure({
107
- metadata: {
108
- reason: reason
109
- }
110
- });
149
+ this.ufoExperience.failure(this.getEndStateConfig(options));
150
+ this.startOptions = undefined;
111
151
  }
112
152
  }]);
113
153
  }();
@@ -1 +1,5 @@
1
- "use strict";
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -33,7 +33,9 @@ var ExperienceCheckDomMutation = exports.ExperienceCheckDomMutation = /*#__PURE_
33
33
  if (!(config !== null && config !== void 0 && config.target)) {
34
34
  callback({
35
35
  status: 'failure',
36
- reason: _consts.EXPERIENCE_FAILURE_REASON.DOM_MUTATION_TARGET_NOT_FOUND
36
+ metadata: {
37
+ reason: _consts.EXPERIENCE_FAILURE_REASON.DOM_MUTATION_TARGET_NOT_FOUND
38
+ }
37
39
  });
38
40
  return;
39
41
  }
@@ -48,7 +50,9 @@ var ExperienceCheckDomMutation = exports.ExperienceCheckDomMutation = /*#__PURE_
48
50
  } catch (error) {
49
51
  callback({
50
52
  status: 'failure',
51
- reason: _consts.EXPERIENCE_FAILURE_REASON.DOM_MUTATION_CHECK_ERROR
53
+ metadata: {
54
+ reason: _consts.EXPERIENCE_FAILURE_REASON.DOM_MUTATION_CHECK_ERROR
55
+ }
52
56
  });
53
57
  }
54
58
  });
@@ -7,27 +7,43 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.ExperienceCheckTimeout = void 0;
8
8
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
9
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
11
  var _consts = require("./consts");
12
+ var DEFAULT_FAILURE_RESULT = {
13
+ status: 'failure',
14
+ metadata: {
15
+ reason: _consts.EXPERIENCE_FAILURE_REASON.TIMEOUT
16
+ }
17
+ };
18
+
11
19
  /**
12
20
  * Check for the completion of an experience based on a timeout
13
21
  *
14
- * Will always result in failure after the timeout duration
22
+ * By default, will result in failure with reason 'timeout' after the specified duration.
23
+ *
24
+ * Can be customized for different results on timeout via the onTimeout callback.
15
25
  */
16
26
  var ExperienceCheckTimeout = exports.ExperienceCheckTimeout = /*#__PURE__*/function () {
17
- function ExperienceCheckTimeout(maxDurationMs) {
27
+ function ExperienceCheckTimeout(_ref) {
28
+ var durationMs = _ref.durationMs,
29
+ _ref$onTimeout = _ref.onTimeout,
30
+ onTimeout = _ref$onTimeout === void 0 ? function () {
31
+ return DEFAULT_FAILURE_RESULT;
32
+ } : _ref$onTimeout;
18
33
  (0, _classCallCheck2.default)(this, ExperienceCheckTimeout);
19
- this.maxDurationMs = maxDurationMs;
34
+ (0, _defineProperty2.default)(this, "durationMs", 0);
35
+ this.durationMs = durationMs;
36
+ this.onTimeout = onTimeout;
20
37
  }
21
38
  return (0, _createClass2.default)(ExperienceCheckTimeout, [{
22
39
  key: "start",
23
40
  value: function start(callback) {
41
+ var _this = this;
24
42
  this.stop();
25
43
  this.timeoutId = setTimeout(function () {
26
- callback({
27
- status: 'failure',
28
- reason: _consts.EXPERIENCE_FAILURE_REASON.TIMEOUT
29
- });
30
- }, this.maxDurationMs);
44
+ var result = _this.onTimeout() || DEFAULT_FAILURE_RESULT;
45
+ callback(result);
46
+ }, this.durationMs);
31
47
  }
32
48
  }, {
33
49
  key: "stop",
@@ -16,7 +16,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
16
16
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
17
17
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
18
18
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
19
- var packageVersion = "110.18.3";
19
+ var packageVersion = "110.18.5";
20
20
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
21
21
  // Remove URL as it has UGC
22
22
  // Ignored via go/ees007
@@ -12,7 +12,6 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
12
12
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
13
13
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
14
  var _react = require("react");
15
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
15
  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; }
17
16
  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; }
18
17
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
@@ -71,7 +70,7 @@ var WithProviders = exports.WithProviders = /*#__PURE__*/function (_PureComponen
71
70
  providers = _this$props.providers,
72
71
  providerFactory = _this$props.providerFactory;
73
72
  providers.forEach(function (name) {
74
- providerFactory.unsubscribe(name, (0, _platformFeatureFlags.fg)('platform_editor_fix_unsubscribe_of_provider') ? _this2.handleProviderIfMounted : _this2.handleProvider);
73
+ providerFactory.unsubscribe(name, _this2.handleProviderIfMounted);
75
74
  });
76
75
  }
77
76
  }, {
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.EditorToolbarUIProvider = void 0;
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
  var _editorToolbar = require("@atlaskit/editor-toolbar");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  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); }
11
12
  var EditorToolbarUIProvider = exports.EditorToolbarUIProvider = function EditorToolbarUIProvider(_ref) {
12
13
  var children = _ref.children,
@@ -18,17 +19,36 @@ var EditorToolbarUIProvider = exports.EditorToolbarUIProvider = function EditorT
18
19
  fireAnalyticsEvent = _ref.fireAnalyticsEvent,
19
20
  keyboardNavigation = _ref.keyboardNavigation;
20
21
  var onDropdownOpenChanged = (0, _react.useCallback)(function (_ref2) {
21
- var isOpen = _ref2.isOpen;
22
+ var isOpen = _ref2.isOpen,
23
+ event = _ref2.event;
22
24
  if (!isOpen) {
23
- // On Dropdown closed, focus is returned to trigger button by default in requestAnimationFrame
24
- // Hence, `.focus()` should also be called in requestAnimationFrame
25
- setTimeout(function () {
26
- return requestAnimationFrame(function () {
27
- api === null || api === void 0 || api.core.actions.focus({
28
- scrollIntoView: false
25
+ if ((0, _platformFeatureFlags.fg)('platform_editor_toolbar_aifc_patch_7')) {
26
+ // Only refocus the editor when the dropdown closes via mouse or programmatic close.
27
+ // When closed via keyboard Escape, keep focus on the trigger for better keyboard UX.
28
+ var isKeyboardEscape = event instanceof KeyboardEvent && event.key === 'Escape';
29
+ var shouldFocusEditor = !isKeyboardEscape;
30
+ if (shouldFocusEditor) {
31
+ // On Dropdown closed, focus is returned to trigger button by default in requestAnimationFrame
32
+ // Hence, `.focus()` should also be called in requestAnimationFrame
33
+ setTimeout(function () {
34
+ return requestAnimationFrame(function () {
35
+ api === null || api === void 0 || api.core.actions.focus({
36
+ scrollIntoView: false
37
+ });
38
+ });
39
+ }, 1);
40
+ }
41
+ } else {
42
+ // On Dropdown closed, focus is returned to trigger button by default in requestAnimationFrame
43
+ // Hence, `.focus()` should also be called in requestAnimationFrame
44
+ setTimeout(function () {
45
+ return requestAnimationFrame(function () {
46
+ api === null || api === void 0 || api.core.actions.focus({
47
+ scrollIntoView: false
48
+ });
29
49
  });
30
- });
31
- }, 1);
50
+ }, 1);
51
+ }
32
52
  }
33
53
  }, [api]);
34
54
  return /*#__PURE__*/_react.default.createElement(_editorToolbar.ToolbarUIProvider, {
@@ -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 = "110.18.3";
27
+ var packageVersion = "110.18.5";
28
28
  var halfFocusRing = 1;
29
29
  var dropOffset = '0, 8';
30
30
  var fadeIn = (0, _react2.keyframes)({
@@ -22,11 +22,20 @@ export class Experience {
22
22
  startCheck() {
23
23
  this.stopCheck();
24
24
  this.check.start(result => {
25
+ const {
26
+ metadata
27
+ } = result;
25
28
  if (result.status === 'success') {
26
- this.success();
27
- } else {
29
+ this.success({
30
+ metadata
31
+ });
32
+ } else if (result.status === 'abort') {
33
+ this.abort({
34
+ metadata
35
+ });
36
+ } else if (result.status === 'failure') {
28
37
  this.failure({
29
- reason: result.reason
38
+ metadata
30
39
  });
31
40
  }
32
41
  });
@@ -37,11 +46,27 @@ export class Experience {
37
46
  isInProgress() {
38
47
  return PROGRESS_STATES.includes(this.ufoExperience.state.id);
39
48
  }
49
+ getEndStateConfig(options) {
50
+ var _this$startOptions, _this$startOptions2;
51
+ return {
52
+ metadata: options !== null && options !== void 0 && options.metadata || (_this$startOptions = this.startOptions) !== null && _this$startOptions !== void 0 && _this$startOptions.metadata ? {
53
+ ...((_this$startOptions2 = this.startOptions) === null || _this$startOptions2 === void 0 ? void 0 : _this$startOptions2.metadata),
54
+ ...(options === null || options === void 0 ? void 0 : options.metadata)
55
+ } : undefined
56
+ };
57
+ }
40
58
 
41
59
  /**
42
- * Starts UFO experience tracking and starts all checks which monitor for completion of the experience.
60
+ * Starts tracking the experience and all checks which monitor for completion.
61
+ *
62
+ * If the experience is already in progress, this will restart the checks.
63
+ * Metadata from options will be merged with any end state metadata.
64
+ *
65
+ * @param options - Configuration for starting the experience
66
+ * @param options.metadata - Optional metadata attached to all subsequent events for this started experience
43
67
  */
44
- start() {
68
+ start(options) {
69
+ this.startOptions = options === null || options === void 0 ? void 0 : options.metadata;
45
70
  this.ufoExperience.start();
46
71
  if (this.isInProgress()) {
47
72
  this.startCheck();
@@ -49,35 +74,51 @@ export class Experience {
49
74
  }
50
75
 
51
76
  /**
52
- * Manually mark the experience as successful and stop any ongoing checks.
77
+ * Marks the experience as successful and stops any ongoing checks.
78
+ *
79
+ * Use this when the experience completes as expected.
80
+ *
81
+ * @param options - Configuration for the success event
82
+ * @param options.metadata - Optional metadata attached to the success event
53
83
  */
54
- success() {
84
+ success(options) {
55
85
  this.stopCheck();
56
- this.ufoExperience.success();
86
+ this.ufoExperience.success(this.getEndStateConfig(options));
87
+ this.startOptions = undefined;
57
88
  }
58
89
 
59
90
  /**
60
- * Manually abort the experience and stop any ongoing checks.
91
+ * Aborts the experience and stops any ongoing checks.
61
92
  *
62
- * Typically used when the experience did not complete due to user action and should not be marked as success or failure,
63
- * for example on unmount or when navigating away from a page.
93
+ * Use this when a started experience terminates early due to user action or context change
94
+ * (e.g., component unmount, navigation). This is neither success nor failure.
95
+ *
96
+ * @param options - Configuration for the abort event
97
+ * @param options.metadata - Optional metadata attached to the abort event
98
+ *
99
+ * @example
100
+ * // Abort on component unmount
101
+ * useEffect(() => {
102
+ * return () => experience.abort({ metadata: { reason: 'unmount' } });
103
+ * }, []);
64
104
  */
65
- abort() {
105
+ abort(options) {
66
106
  this.stopCheck();
67
- this.ufoExperience.abort();
107
+ this.ufoExperience.abort(this.getEndStateConfig(options));
108
+ this.startOptions = undefined;
68
109
  }
69
110
 
70
111
  /**
71
- * Manually mark the experience as failed and stop any ongoing checks.
112
+ * Manually marks the experience as failed and stops any ongoing checks.
113
+ *
114
+ * Use this for actual failures in the experience flow (e.g., timeout, error conditions).
115
+ *
116
+ * @param options - Configuration for the failure event
117
+ * @param options.metadata - Optional metadata attached to the failure event
72
118
  */
73
- failure({
74
- reason = 'error'
75
- } = {}) {
119
+ failure(options) {
76
120
  this.stopCheck();
77
- this.ufoExperience.failure({
78
- metadata: {
79
- reason
80
- }
81
- });
121
+ this.ufoExperience.failure(this.getEndStateConfig(options));
122
+ this.startOptions = undefined;
82
123
  }
83
124
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -21,7 +21,9 @@ export class ExperienceCheckDomMutation {
21
21
  if (!(config !== null && config !== void 0 && config.target)) {
22
22
  callback({
23
23
  status: 'failure',
24
- reason: EXPERIENCE_FAILURE_REASON.DOM_MUTATION_TARGET_NOT_FOUND
24
+ metadata: {
25
+ reason: EXPERIENCE_FAILURE_REASON.DOM_MUTATION_TARGET_NOT_FOUND
26
+ }
25
27
  });
26
28
  return;
27
29
  }
@@ -36,7 +38,9 @@ export class ExperienceCheckDomMutation {
36
38
  } catch (error) {
37
39
  callback({
38
40
  status: 'failure',
39
- reason: EXPERIENCE_FAILURE_REASON.DOM_MUTATION_CHECK_ERROR
41
+ metadata: {
42
+ reason: EXPERIENCE_FAILURE_REASON.DOM_MUTATION_CHECK_ERROR
43
+ }
40
44
  });
41
45
  }
42
46
  });
@@ -1,21 +1,34 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import { EXPERIENCE_FAILURE_REASON } from './consts';
3
+ const DEFAULT_FAILURE_RESULT = {
4
+ status: 'failure',
5
+ metadata: {
6
+ reason: EXPERIENCE_FAILURE_REASON.TIMEOUT
7
+ }
8
+ };
9
+
2
10
  /**
3
11
  * Check for the completion of an experience based on a timeout
4
12
  *
5
- * Will always result in failure after the timeout duration
13
+ * By default, will result in failure with reason 'timeout' after the specified duration.
14
+ *
15
+ * Can be customized for different results on timeout via the onTimeout callback.
6
16
  */
7
17
  export class ExperienceCheckTimeout {
8
- constructor(maxDurationMs) {
9
- this.maxDurationMs = maxDurationMs;
18
+ constructor({
19
+ durationMs,
20
+ onTimeout = () => DEFAULT_FAILURE_RESULT
21
+ }) {
22
+ _defineProperty(this, "durationMs", 0);
23
+ this.durationMs = durationMs;
24
+ this.onTimeout = onTimeout;
10
25
  }
11
26
  start(callback) {
12
27
  this.stop();
13
28
  this.timeoutId = setTimeout(() => {
14
- callback({
15
- status: 'failure',
16
- reason: EXPERIENCE_FAILURE_REASON.TIMEOUT
17
- });
18
- }, this.maxDurationMs);
29
+ const result = this.onTimeout() || DEFAULT_FAILURE_RESULT;
30
+ callback(result);
31
+ }, this.durationMs);
19
32
  }
20
33
  stop() {
21
34
  if (this.timeoutId) {
@@ -1,7 +1,7 @@
1
1
  import { isFedRamp } from './environment';
2
2
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
3
3
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
4
- const packageVersion = "110.18.3";
4
+ const packageVersion = "110.18.5";
5
5
  const sanitiseSentryEvents = (data, _hint) => {
6
6
  // Remove URL as it has UGC
7
7
  // Ignored via go/ees007
@@ -1,7 +1,6 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  /* eslint-disable @repo/internal/react/no-class-components */
3
3
  import { PureComponent } from 'react';
4
- import { fg } from '@atlaskit/platform-feature-flags';
5
4
  // Ignored via go/ees005
6
5
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
6
  export class WithProviders extends PureComponent {
@@ -52,7 +51,7 @@ export class WithProviders extends PureComponent {
52
51
  providerFactory
53
52
  } = this.props;
54
53
  providers.forEach(name => {
55
- providerFactory.unsubscribe(name, fg('platform_editor_fix_unsubscribe_of_provider') ? this.handleProviderIfMounted : this.handleProvider);
54
+ providerFactory.unsubscribe(name, this.handleProviderIfMounted);
56
55
  });
57
56
  }
58
57
  render() {
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { ToolbarUIProvider } from '@atlaskit/editor-toolbar';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
3
4
  export const EditorToolbarUIProvider = ({
4
5
  children,
5
6
  api,
@@ -11,16 +12,33 @@ export const EditorToolbarUIProvider = ({
11
12
  keyboardNavigation
12
13
  }) => {
13
14
  const onDropdownOpenChanged = useCallback(({
14
- isOpen
15
+ isOpen,
16
+ event
15
17
  }) => {
16
18
  if (!isOpen) {
17
- // On Dropdown closed, focus is returned to trigger button by default in requestAnimationFrame
18
- // Hence, `.focus()` should also be called in requestAnimationFrame
19
- setTimeout(() => requestAnimationFrame(() => {
20
- api === null || api === void 0 ? void 0 : api.core.actions.focus({
21
- scrollIntoView: false
22
- });
23
- }), 1);
19
+ if (fg('platform_editor_toolbar_aifc_patch_7')) {
20
+ // Only refocus the editor when the dropdown closes via mouse or programmatic close.
21
+ // When closed via keyboard Escape, keep focus on the trigger for better keyboard UX.
22
+ const isKeyboardEscape = event instanceof KeyboardEvent && event.key === 'Escape';
23
+ const shouldFocusEditor = !isKeyboardEscape;
24
+ if (shouldFocusEditor) {
25
+ // On Dropdown closed, focus is returned to trigger button by default in requestAnimationFrame
26
+ // Hence, `.focus()` should also be called in requestAnimationFrame
27
+ setTimeout(() => requestAnimationFrame(() => {
28
+ api === null || api === void 0 ? void 0 : api.core.actions.focus({
29
+ scrollIntoView: false
30
+ });
31
+ }), 1);
32
+ }
33
+ } else {
34
+ // On Dropdown closed, focus is returned to trigger button by default in requestAnimationFrame
35
+ // Hence, `.focus()` should also be called in requestAnimationFrame
36
+ setTimeout(() => requestAnimationFrame(() => {
37
+ api === null || api === void 0 ? void 0 : api.core.actions.focus({
38
+ scrollIntoView: false
39
+ });
40
+ }), 1);
41
+ }
24
42
  }
25
43
  }, [api]);
26
44
  return /*#__PURE__*/React.createElement(ToolbarUIProvider, {
@@ -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 = "110.18.3";
17
+ const packageVersion = "110.18.5";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({