@atlaskit/editor-plugin-type-ahead 10.2.2 → 10.3.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 (56) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/commands/package.json +17 -0
  3. package/dist/cjs/entry-points/commands.js +18 -0
  4. package/dist/cjs/pm-plugins/commands/open-typeahead-at-cursor.js +7 -2
  5. package/dist/cjs/pm-plugins/commands/update-list-items.js +3 -1
  6. package/dist/cjs/pm-plugins/main.js +54 -0
  7. package/dist/cjs/pm-plugins/reducer.js +7 -1
  8. package/dist/cjs/typeAheadPlugin.js +3 -1
  9. package/dist/cjs/ui/ContentComponent.js +10 -7
  10. package/dist/cjs/ui/TypeAheadList.js +126 -52
  11. package/dist/cjs/ui/TypeAheadMenu.js +3 -0
  12. package/dist/cjs/ui/TypeAheadPopup.js +3 -0
  13. package/dist/cjs/ui/WrapperTypeAhead.js +3 -1
  14. package/dist/cjs/ui/hooks/build-sectioned-result.js +131 -0
  15. package/dist/cjs/ui/hooks/use-load-items.js +12 -4
  16. package/dist/es2019/entry-points/commands.js +2 -0
  17. package/dist/es2019/pm-plugins/commands/open-typeahead-at-cursor.js +7 -2
  18. package/dist/es2019/pm-plugins/commands/update-list-items.js +3 -2
  19. package/dist/es2019/pm-plugins/main.js +54 -0
  20. package/dist/es2019/pm-plugins/reducer.js +6 -1
  21. package/dist/es2019/typeAheadPlugin.js +3 -1
  22. package/dist/es2019/ui/ContentComponent.js +10 -7
  23. package/dist/es2019/ui/TypeAheadList.js +85 -23
  24. package/dist/es2019/ui/TypeAheadMenu.js +2 -0
  25. package/dist/es2019/ui/TypeAheadPopup.js +2 -0
  26. package/dist/es2019/ui/WrapperTypeAhead.js +3 -1
  27. package/dist/es2019/ui/hooks/build-sectioned-result.js +83 -0
  28. package/dist/es2019/ui/hooks/use-load-items.js +13 -4
  29. package/dist/esm/entry-points/commands.js +2 -0
  30. package/dist/esm/pm-plugins/commands/open-typeahead-at-cursor.js +7 -2
  31. package/dist/esm/pm-plugins/commands/update-list-items.js +3 -1
  32. package/dist/esm/pm-plugins/main.js +54 -0
  33. package/dist/esm/pm-plugins/reducer.js +7 -1
  34. package/dist/esm/typeAheadPlugin.js +3 -1
  35. package/dist/esm/ui/ContentComponent.js +10 -7
  36. package/dist/esm/ui/TypeAheadList.js +126 -52
  37. package/dist/esm/ui/TypeAheadMenu.js +3 -0
  38. package/dist/esm/ui/TypeAheadPopup.js +3 -0
  39. package/dist/esm/ui/WrapperTypeAhead.js +3 -1
  40. package/dist/esm/ui/hooks/build-sectioned-result.js +124 -0
  41. package/dist/esm/ui/hooks/use-load-items.js +12 -4
  42. package/dist/types/entry-points/commands.d.ts +1 -0
  43. package/dist/types/pm-plugins/commands/update-list-items.d.ts +2 -1
  44. package/dist/types/types/index.d.ts +8 -0
  45. package/dist/types/ui/TypeAheadList.d.ts +3 -1
  46. package/dist/types/ui/TypeAheadPopup.d.ts +3 -2
  47. package/dist/types/ui/hooks/build-sectioned-result.d.ts +11 -0
  48. package/dist/types/ui/hooks/use-load-items.d.ts +2 -1
  49. package/dist/types-ts4.5/entry-points/commands.d.ts +1 -0
  50. package/dist/types-ts4.5/pm-plugins/commands/update-list-items.d.ts +2 -1
  51. package/dist/types-ts4.5/types/index.d.ts +8 -0
  52. package/dist/types-ts4.5/ui/TypeAheadList.d.ts +3 -1
  53. package/dist/types-ts4.5/ui/TypeAheadPopup.d.ts +3 -2
  54. package/dist/types-ts4.5/ui/hooks/build-sectioned-result.d.ts +11 -0
  55. package/dist/types-ts4.5/ui/hooks/use-load-items.d.ts +2 -1
  56. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @atlaskit/editor-plugin-type-ahead
2
2
 
3
+ ## 10.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`cf6977530a136`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cf6977530a136) -
8
+ Support fullwidth slash / (U+FF0F) as a quick insert trigger for Japanese/CJK keyboard users.
9
+ Japanese keyboards produce the fullwidth slash when pressing the / key, which previously did not
10
+ open the quick insert menu. The fix adds a `customRegex` to the quick-insert typeahead handler
11
+ that matches both ASCII slash `/` and fullwidth slash `/`, and extends the trigger cleanup logic
12
+ in `openTypeAheadAtCursor` to handle `customRegex` alternatives.
13
+ - [`cf6977530a136`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cf6977530a136) -
14
+ Add ./commands entry point exposing openTypeAheadAtCursor for test consumption
15
+ - Updated dependencies
16
+
17
+ ## 10.3.0
18
+
19
+ ### Minor Changes
20
+
21
+ - [`beab4fffee103`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/beab4fffee103) -
22
+ EDITOR-7318: Add type-ahead sections support with getSections handler API.
23
+
24
+ Adds `TypeAheadSection` and `TypeAheadSectionUpdate` types and an optional `getSections()` method
25
+ to `TypeAheadHandler` in `editor-common`. Implements section grouping in
26
+ `editor-plugin-type-ahead` via `buildSectionedResult`. Adds People/Agents section split to
27
+ `editor-plugin-mentions`.
28
+
29
+ Removes the `updateSection` action and associated `sectionOverrides`/`sectionsRefreshKey`
30
+ pm-plugin state — section definitions are now derived directly from `getSections()` at load time
31
+ rather than being mutated at runtime.
32
+
33
+ ### Patch Changes
34
+
35
+ - Updated dependencies
36
+
3
37
  ## 10.2.2
4
38
 
5
39
  ### Patch Changes
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@atlaskit/editor-plugin-type-ahead/commands",
3
+ "main": "../dist/cjs/entry-points/commands.js",
4
+ "module": "../dist/esm/entry-points/commands.js",
5
+ "module:es2019": "../dist/es2019/entry-points/commands.js",
6
+ "sideEffects": [
7
+ "*.compiled.css"
8
+ ],
9
+ "types": "../dist/types/entry-points/commands.d.ts",
10
+ "typesVersions": {
11
+ ">=4.5 <5.9": {
12
+ "*": [
13
+ "../dist/types-ts4.5/entry-points/commands.d.ts"
14
+ ]
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "openTypeAhead", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _openTypeaheadAtCursor.openTypeAhead;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "openTypeAheadAtCursor", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _openTypeaheadAtCursor.openTypeAheadAtCursor;
16
+ }
17
+ });
18
+ var _openTypeaheadAtCursor = require("../pm-plugins/commands/open-typeahead-at-cursor");
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.openTypeAheadAtCursor = exports.openTypeAhead = void 0;
7
7
  var _selection = require("@atlaskit/editor-common/selection");
8
8
  var _state = require("@atlaskit/editor-prosemirror/state");
9
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
9
10
  var _actions = require("../actions");
10
11
  var _key = require("../key");
11
12
  var openTypeAhead = exports.openTypeAhead = function openTypeAhead(props) {
@@ -49,7 +50,7 @@ var openTypeAheadAtCursor = exports.openTypeAheadAtCursor = function openTypeAhe
49
50
  // delete 1 pos before wherever selection is now - that will delete the empty space
50
51
  tr.delete(tr.selection.from - 1, tr.selection.from);
51
52
  } else {
52
- var _selection$$head, _selection$$head$pare, _selection$$head$pare2;
53
+ var _selection$$head$pare, _selection$$head$pare2, _selection$$head;
53
54
  if (selection instanceof _state.NodeSelection) {
54
55
  if (isInline) {
55
56
  tr.deleteSelection();
@@ -78,7 +79,11 @@ var openTypeAheadAtCursor = exports.openTypeAheadAtCursor = function openTypeAhe
78
79
  // being inserted due to composition by checking if we have the trigger
79
80
  // directly before the typeahead. This should not happen unless it has
80
81
  // been eroneously added because we require whitespace/newline for typeahead.
81
- if (cursorPos >= 2 && !!(selection !== null && selection !== void 0 && (_selection$$head = selection.$head) !== null && _selection$$head !== void 0 && (_selection$$head = _selection$$head.parent) !== null && _selection$$head !== void 0 && _selection$$head.textContent) && (_selection$$head$pare = (_selection$$head$pare2 = selection.$head.parent.textContent).endsWith) !== null && _selection$$head$pare !== void 0 && _selection$$head$pare.call(_selection$$head$pare2, triggerHandler.trigger)) {
82
+ // Check if the text ends with the trigger character (or any character matched
83
+ // by customRegex, to support wide-char variants like fullwidth slash /)
84
+ var triggerPattern = (0, _expValEquals.expValEquals)('platform_editor_wide_slash_trigger', 'isEnabled', true) && triggerHandler.customRegex ? new RegExp("(".concat(triggerHandler.customRegex, ")$"), 'u') : null;
85
+ var endsWithTrigger = ((_selection$$head$pare = (_selection$$head$pare2 = selection.$head.parent.textContent).endsWith) === null || _selection$$head$pare === void 0 ? void 0 : _selection$$head$pare.call(_selection$$head$pare2, triggerHandler.trigger)) || triggerPattern && triggerPattern.test(selection.$head.parent.textContent);
86
+ if (cursorPos >= 2 && !!(selection !== null && selection !== void 0 && (_selection$$head = selection.$head) !== null && _selection$$head !== void 0 && (_selection$$head = _selection$$head.parent) !== null && _selection$$head !== void 0 && _selection$$head.textContent) && endsWithTrigger) {
82
87
  tr.delete(cursorPos - 1, cursorPos);
83
88
  }
84
89
  }
@@ -7,12 +7,14 @@ exports.updateListItem = void 0;
7
7
  var _actions = require("../actions");
8
8
  var _key = require("../key");
9
9
  var updateListItem = exports.updateListItem = function updateListItem(items) {
10
+ var sections = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
10
11
  return function (state, dispatch) {
11
12
  var tr = state.tr;
12
13
  tr.setMeta(_key.pluginKey, {
13
14
  action: _actions.ACTIONS.UPDATE_LIST_ITEMS,
14
15
  params: {
15
- items: items
16
+ items: items,
17
+ sections: sections
16
18
  }
17
19
  });
18
20
  if (dispatch) {
@@ -5,11 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createPlugin = createPlugin;
7
7
  var _steps = require("@atlaskit/adf-schema/steps");
8
+ var _analytics = require("@atlaskit/editor-common/analytics");
8
9
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
9
10
  var _utils = require("@atlaskit/editor-common/utils");
10
11
  var _view = require("@atlaskit/editor-prosemirror/view");
11
12
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
12
14
  var _actions = require("./actions");
15
+ var _openTypeaheadAtCursor = require("./commands/open-typeahead-at-cursor");
13
16
  var _constants = require("./constants");
14
17
  var _decorations = require("./decorations");
15
18
  var _isInsertionTransaction = require("./isInsertionTransaction");
@@ -49,6 +52,11 @@ function createPlugin(_ref) {
49
52
  typeAheadHandlers: typeAheadHandlers,
50
53
  popupMountRef: popupMountRef
51
54
  });
55
+
56
+ // Tracks a wide-char trigger handler detected during IME composition (e.g. /).
57
+ // Set by compositionupdate, cleared by compositionend. Used by handleKeyDown
58
+ // to intercept Enter that confirms the composition.
59
+ var pendingWideSlashHandler = null;
52
60
  return new _safePlugin.SafePlugin({
53
61
  key: _key.pluginKey,
54
62
  state: {
@@ -59,6 +67,7 @@ function createPlugin(_ref) {
59
67
  decorationSet: _view.DecorationSet.empty,
60
68
  decorationElement: null,
61
69
  items: [],
70
+ sections: [],
62
71
  errorInfo: null,
63
72
  selectedIndex: -1,
64
73
  stats: null,
@@ -100,8 +109,53 @@ function createPlugin(_ref) {
100
109
  var _pluginKey$getState;
101
110
  return (_pluginKey$getState = _key.pluginKey.getState(state)) === null || _pluginKey$getState === void 0 ? void 0 : _pluginKey$getState.decorationSet;
102
111
  },
112
+ handleKeyDown: function handleKeyDown(view, event) {
113
+ // When composing a wide-char trigger (e.g. /), intercept the Enter key
114
+ // that confirms the composition so we can open the typeahead instead.
115
+ if (pendingWideSlashHandler && event.isComposing && (event.key === 'Enter' || event.keyCode === 13)) {
116
+ var handler = pendingWideSlashHandler;
117
+ pendingWideSlashHandler = null;
118
+ // Defer until ProseMirror has flushed the composed text into its state.
119
+ setTimeout(function () {
120
+ var command = (0, _openTypeaheadAtCursor.openTypeAheadAtCursor)({
121
+ triggerHandler: handler,
122
+ inputMethod: _analytics.INPUT_METHOD.KEYBOARD
123
+ });
124
+ var tr = command({
125
+ tr: view.state.tr
126
+ });
127
+ if (tr) {
128
+ view.dispatch(tr);
129
+ }
130
+ }, 0);
131
+ return true;
132
+ }
133
+ return false;
134
+ },
103
135
  handleDOMEvents: {
136
+ compositionupdate: function compositionupdate(view, event) {
137
+ // When the experiment is on, track whether the current composition
138
+ // exactly matches a wide-char trigger (e.g. / from Japanese keyboard).
139
+ // We can't open the typeahead yet because composition is still active,
140
+ // but we record the matching handler so the next keydown (Enter) can use it.
141
+ if ((0, _expValEquals.expValEquals)('platform_editor_wide_slash_trigger', 'isEnabled', true)) {
142
+ var _event$data, _typeAheadHandlers$fi;
143
+ var pendingData = (_event$data = event.data) !== null && _event$data !== void 0 ? _event$data : '';
144
+ pendingWideSlashHandler = (_typeAheadHandlers$fi = typeAheadHandlers.find(function (handler) {
145
+ if (!handler.customRegex) {
146
+ return false;
147
+ }
148
+ // Only match if the entire composition is a trigger character
149
+ var pattern = new RegExp("^(".concat(handler.customRegex, ")$"), 'u');
150
+ return pattern.test(pendingData);
151
+ })) !== null && _typeAheadHandlers$fi !== void 0 ? _typeAheadHandlers$fi : null;
152
+ }
153
+ return false;
154
+ },
104
155
  compositionend: function compositionend(view, event) {
156
+ // Clear the pending handler when composition ends (cancelled or committed
157
+ // via a non-Enter key like Space, which we don't want to intercept).
158
+ pendingWideSlashHandler = null;
105
159
  return false;
106
160
  },
107
161
  click: function click(view, event) {
@@ -76,6 +76,7 @@ var createReducer = exports.createReducer = function createReducer(_ref) {
76
76
  inputMethod: inputMethod,
77
77
  selectedIndex: typeof selectedIndex === 'number' ? selectedIndex : -1,
78
78
  items: [],
79
+ sections: [],
79
80
  query: reopenQuery || '',
80
81
  removePrefixTriggerOnCancel: removePrefixTriggerOnCancel
81
82
  });
@@ -94,6 +95,7 @@ var createReducer = exports.createReducer = function createReducer(_ref) {
94
95
  stats: null,
95
96
  triggerHandler: undefined,
96
97
  items: [],
98
+ sections: [],
97
99
  removePrefixTriggerOnCancel: undefined
98
100
  });
99
101
  };
@@ -144,13 +146,17 @@ var createReducer = exports.createReducer = function createReducer(_ref) {
144
146
  return _objectSpread(_objectSpread({}, currentPluginState), {}, {
145
147
  errorInfo: errorInfo,
146
148
  items: [],
149
+ sections: [],
147
150
  selectedIndex: -1
148
151
  });
149
152
  } else if (shouldUpdateListItems) {
150
- var items = params.items;
153
+ var items = params.items,
154
+ _params$sections = params.sections,
155
+ sections = _params$sections === void 0 ? [] : _params$sections;
151
156
  var selectedIndex = currentPluginState.selectedIndex;
152
157
  return _objectSpread(_objectSpread({}, currentPluginState), {}, {
153
158
  items: items,
159
+ sections: sections,
154
160
  selectedIndex: Math.max(selectedIndex >= items.length ? items.length - 1 : selectedIndex, -1)
155
161
  });
156
162
  } else if (shouldUpdateSelectedIndex) {
@@ -214,7 +214,7 @@ var typeAheadPlugin = exports.typeAheadPlugin = function typeAheadPlugin(_ref) {
214
214
  }];
215
215
  },
216
216
  getSharedState: function getSharedState(editorState) {
217
- var _state$decorationSet, _state$decorationElem, _state$items, _state$errorInfo, _state$selectedIndex;
217
+ var _state$decorationSet, _state$decorationElem, _state$items, _state$sections, _state$errorInfo, _state$selectedIndex;
218
218
  if (!editorState) {
219
219
  return {
220
220
  query: '',
@@ -225,6 +225,7 @@ var typeAheadPlugin = exports.typeAheadPlugin = function typeAheadPlugin(_ref) {
225
225
  decorationElement: null,
226
226
  triggerHandler: undefined,
227
227
  items: [],
228
+ sections: [],
228
229
  errorInfo: null,
229
230
  selectedIndex: 0
230
231
  };
@@ -240,6 +241,7 @@ var typeAheadPlugin = exports.typeAheadPlugin = function typeAheadPlugin(_ref) {
240
241
  decorationElement: (_state$decorationElem = state === null || state === void 0 ? void 0 : state.decorationElement) !== null && _state$decorationElem !== void 0 ? _state$decorationElem : null,
241
242
  triggerHandler: state === null || state === void 0 ? void 0 : state.triggerHandler,
242
243
  items: (_state$items = state === null || state === void 0 ? void 0 : state.items) !== null && _state$items !== void 0 ? _state$items : [],
244
+ sections: (_state$sections = state === null || state === void 0 ? void 0 : state.sections) !== null && _state$sections !== void 0 ? _state$sections : [],
243
245
  errorInfo: (_state$errorInfo = state === null || state === void 0 ? void 0 : state.errorInfo) !== null && _state$errorInfo !== void 0 ? _state$errorInfo : null,
244
246
  selectedIndex: (_state$selectedIndex = state === null || state === void 0 ? void 0 : state.selectedIndex) !== null && _state$selectedIndex !== void 0 ? _state$selectedIndex : 0
245
247
  };
@@ -13,25 +13,27 @@ function ContentComponent(_ref) {
13
13
  editorView = _ref.editorView,
14
14
  popupMountRef = _ref.popupMountRef;
15
15
  var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['typeAhead'], function (states) {
16
- var _states$typeAheadStat, _states$typeAheadStat2, _states$typeAheadStat3, _states$typeAheadStat4, _states$typeAheadStat5, _states$typeAheadStat6, _states$typeAheadStat7;
16
+ var _states$typeAheadStat, _states$typeAheadStat2, _states$typeAheadStat3, _states$typeAheadStat4, _states$typeAheadStat5, _states$typeAheadStat6, _states$typeAheadStat7, _states$typeAheadStat8;
17
17
  return {
18
18
  triggerHandler: (_states$typeAheadStat = states.typeAheadState) === null || _states$typeAheadStat === void 0 ? void 0 : _states$typeAheadStat.triggerHandler,
19
19
  items: (_states$typeAheadStat2 = states.typeAheadState) === null || _states$typeAheadStat2 === void 0 ? void 0 : _states$typeAheadStat2.items,
20
- errorInfo: (_states$typeAheadStat3 = states.typeAheadState) === null || _states$typeAheadStat3 === void 0 ? void 0 : _states$typeAheadStat3.errorInfo,
21
- decorationElement: (_states$typeAheadStat4 = states.typeAheadState) === null || _states$typeAheadStat4 === void 0 ? void 0 : _states$typeAheadStat4.decorationElement,
22
- decorationSet: (_states$typeAheadStat5 = states.typeAheadState) === null || _states$typeAheadStat5 === void 0 ? void 0 : _states$typeAheadStat5.decorationSet,
23
- query: (_states$typeAheadStat6 = states.typeAheadState) === null || _states$typeAheadStat6 === void 0 ? void 0 : _states$typeAheadStat6.query,
24
- selectedIndex: (_states$typeAheadStat7 = states.typeAheadState) === null || _states$typeAheadStat7 === void 0 ? void 0 : _states$typeAheadStat7.selectedIndex
20
+ sections: (_states$typeAheadStat3 = states.typeAheadState) === null || _states$typeAheadStat3 === void 0 ? void 0 : _states$typeAheadStat3.sections,
21
+ errorInfo: (_states$typeAheadStat4 = states.typeAheadState) === null || _states$typeAheadStat4 === void 0 ? void 0 : _states$typeAheadStat4.errorInfo,
22
+ decorationElement: (_states$typeAheadStat5 = states.typeAheadState) === null || _states$typeAheadStat5 === void 0 ? void 0 : _states$typeAheadStat5.decorationElement,
23
+ decorationSet: (_states$typeAheadStat6 = states.typeAheadState) === null || _states$typeAheadStat6 === void 0 ? void 0 : _states$typeAheadStat6.decorationSet,
24
+ query: (_states$typeAheadStat7 = states.typeAheadState) === null || _states$typeAheadStat7 === void 0 ? void 0 : _states$typeAheadStat7.query,
25
+ selectedIndex: (_states$typeAheadStat8 = states.typeAheadState) === null || _states$typeAheadStat8 === void 0 ? void 0 : _states$typeAheadStat8.selectedIndex
25
26
  };
26
27
  }),
27
28
  triggerHandler = _useSharedPluginState.triggerHandler,
28
29
  items = _useSharedPluginState.items,
30
+ sections = _useSharedPluginState.sections,
29
31
  errorInfo = _useSharedPluginState.errorInfo,
30
32
  decorationElement = _useSharedPluginState.decorationElement,
31
33
  decorationSet = _useSharedPluginState.decorationSet,
32
34
  query = _useSharedPluginState.query,
33
35
  selectedIndex = _useSharedPluginState.selectedIndex;
34
- if (items === undefined || decorationSet === undefined || errorInfo === undefined || decorationElement === undefined || query === undefined || selectedIndex === undefined) {
36
+ if (items === undefined || sections === undefined || decorationSet === undefined || errorInfo === undefined || decorationElement === undefined || query === undefined || selectedIndex === undefined) {
35
37
  return null;
36
38
  }
37
39
  return /*#__PURE__*/_react.default.createElement(_TypeAheadMenu.TypeAheadMenu, {
@@ -42,6 +44,7 @@ function ContentComponent(_ref) {
42
44
  typeAheadState: {
43
45
  triggerHandler: triggerHandler,
44
46
  items: items,
47
+ sections: sections,
45
48
  errorInfo: errorInfo,
46
49
  decorationElement: decorationElement,
47
50
  decorationSet: decorationSet,
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.TypeAheadList = void 0;
9
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
11
  var _react = _interopRequireWildcard(require("react"));
11
12
  var _react2 = require("@emotion/react");
12
13
  var _reactIntl = require("react-intl");
@@ -19,6 +20,7 @@ var _ui = require("@atlaskit/editor-common/ui");
19
20
  var _menu = require("@atlaskit/menu");
20
21
  var _compiled = require("@atlaskit/primitives/compiled");
21
22
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
23
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
22
24
  var _closeTypeAhead = require("../pm-plugins/commands/close-type-ahead");
23
25
  var _updateSelectedIndex = require("../pm-plugins/commands/update-selected-index");
24
26
  var _constants = require("../pm-plugins/constants");
@@ -42,8 +44,43 @@ var list = (0, _react2.css)({
42
44
  padding: "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-150, 12px)")
43
45
  }
44
46
  });
45
- var TypeaheadAssistiveTextPureComponent = /*#__PURE__*/_react.default.memo(function (_ref) {
46
- var numberOfResults = _ref.numberOfResults;
47
+ var buildTypeAheadRows = function buildTypeAheadRows(_ref) {
48
+ var itemsLength = _ref.itemsLength,
49
+ sections = _ref.sections;
50
+ if (sections.length === 0) {
51
+ return Array.from({
52
+ length: itemsLength
53
+ }, function (_, itemIndex) {
54
+ return {
55
+ type: 'item',
56
+ itemIndex: itemIndex
57
+ };
58
+ });
59
+ }
60
+ var sortedSections = (0, _toConsumableArray2.default)(sections).sort(function (left, right) {
61
+ return left.startIndex - right.startIndex;
62
+ });
63
+ var sectionsByStartIndex = new Map(sortedSections.map(function (section) {
64
+ return [section.startIndex, section];
65
+ }));
66
+ var rows = [];
67
+ for (var itemIndex = 0; itemIndex < itemsLength; itemIndex++) {
68
+ var section = sectionsByStartIndex.get(itemIndex);
69
+ if (section) {
70
+ rows.push({
71
+ type: 'section',
72
+ section: section
73
+ });
74
+ }
75
+ rows.push({
76
+ type: 'item',
77
+ itemIndex: itemIndex
78
+ });
79
+ }
80
+ return rows;
81
+ };
82
+ var TypeaheadAssistiveTextPureComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
83
+ var numberOfResults = _ref2.numberOfResults;
47
84
  var intl = (0, _reactIntl.useIntl)();
48
85
  return (0, _react2.jsx)(_ui.AssistiveText, {
49
86
  assistiveText: intl.formatMessage(_typeAhead.typeAheadListMessages.searchResultsLabel, {
@@ -55,21 +92,22 @@ var TypeaheadAssistiveTextPureComponent = /*#__PURE__*/_react.default.memo(funct
55
92
  id: _constants.TYPE_AHEAD_DECORATION_ELEMENT_ID + '__popup'
56
93
  });
57
94
  });
58
- var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
59
- var _triggerHandler$getMo, _decorationElement$qu2;
60
- var items = _ref2.items,
61
- emptyItem = _ref2.emptyItem,
62
- selectedIndex = _ref2.selectedIndex,
63
- editorView = _ref2.editorView,
64
- onItemClick = _ref2.onItemClick,
65
- intl = _ref2.intl,
66
- fitHeight = _ref2.fitHeight,
67
- decorationElement = _ref2.decorationElement,
68
- triggerHandler = _ref2.triggerHandler,
69
- moreElementsInQuickInsertViewEnabled = _ref2.moreElementsInQuickInsertViewEnabled,
70
- api = _ref2.api,
71
- showMoreOptionsButton = _ref2.showMoreOptionsButton,
72
- onMoreOptionsClicked = _ref2.onMoreOptionsClicked;
95
+ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref3) {
96
+ var _itemRowIndexByItemIn, _triggerHandler$getMo, _decorationElement$qu2;
97
+ var items = _ref3.items,
98
+ sections = _ref3.sections,
99
+ emptyItem = _ref3.emptyItem,
100
+ selectedIndex = _ref3.selectedIndex,
101
+ editorView = _ref3.editorView,
102
+ onItemClick = _ref3.onItemClick,
103
+ intl = _ref3.intl,
104
+ fitHeight = _ref3.fitHeight,
105
+ decorationElement = _ref3.decorationElement,
106
+ triggerHandler = _ref3.triggerHandler,
107
+ moreElementsInQuickInsertViewEnabled = _ref3.moreElementsInQuickInsertViewEnabled,
108
+ api = _ref3.api,
109
+ showMoreOptionsButton = _ref3.showMoreOptionsButton,
110
+ onMoreOptionsClicked = _ref3.onMoreOptionsClicked;
73
111
  var listRef = (0, _react.useRef)();
74
112
  var listContainerRef = (0, _react.useRef)(null);
75
113
  var lastInputMethodRef = (0, _react.useRef)('keyboard');
@@ -96,6 +134,27 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
96
134
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
97
135
  cache = _useState4[0],
98
136
  setCache = _useState4[1];
137
+ var listRows = (0, _react.useMemo)(function () {
138
+ return buildTypeAheadRows({
139
+ itemsLength: itemsLength,
140
+ sections: sections || []
141
+ });
142
+ }, [itemsLength, sections]);
143
+ var itemRowIndexByItemIndex = (0, _react.useMemo)(function () {
144
+ var rowIndexByItemIndex = new Map();
145
+ listRows.forEach(function (row, rowIndex) {
146
+ if (row.type === 'item') {
147
+ rowIndexByItemIndex.set(row.itemIndex, rowIndex);
148
+ }
149
+ });
150
+ return rowIndexByItemIndex;
151
+ }, [listRows]);
152
+ var populatedSectionCount = (0, _react.useMemo)(function () {
153
+ return listRows.filter(function (row) {
154
+ return row.type === 'section';
155
+ }).length;
156
+ }, [listRows]);
157
+ var selectedItemRowIndex = selectedIndex >= 0 ? (_itemRowIndexByItemIn = itemRowIndexByItemIndex.get(selectedIndex)) !== null && _itemRowIndexByItemIn !== void 0 ? _itemRowIndexByItemIn : -1 : -1;
99
158
  var onItemsRendered = (0, _react.useCallback)(function (props) {
100
159
  lastVisibleIndexes.current = props;
101
160
  }, []);
@@ -132,8 +191,8 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
132
191
  var lastVisibleStopIndex = lastVisibleIndexes.current.stopIndex;
133
192
  var onScroll = (0, _react.useCallback)(
134
193
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
135
- function (_ref3) {
136
- var scrollUpdateWasRequested = _ref3.scrollUpdateWasRequested;
194
+ function (_ref4) {
195
+ var scrollUpdateWasRequested = _ref4.scrollUpdateWasRequested;
137
196
  if (!scrollUpdateWasRequested) {
138
197
  return;
139
198
  }
@@ -151,28 +210,32 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
151
210
  requestAnimationFrame(function () {
152
211
  requestAnimationFrame(function () {
153
212
  var isViewMoreSelected = showMoreOptionsButton && selectedIndex === itemsLength;
154
- var isSelectedItemVisible = selectedIndex >= lastVisibleStartIndex && selectedIndex <= lastVisibleStopIndex ||
213
+ var isSelectedItemVisible = selectedItemRowIndex >= lastVisibleStartIndex && selectedItemRowIndex <= lastVisibleStopIndex ||
155
214
  // view more is always visible, hence no scrolling
156
215
  isViewMoreSelected;
157
216
 
158
217
  //Should scroll to the list item only when the selectedIndex >= 0 and item is not visible
159
218
  if (!isSelectedItemVisible && selectedIndex !== -1) {
160
- listRef.current.scrollToRow(selectedIndex);
219
+ listRef.current.scrollToRow(selectedItemRowIndex);
161
220
  } else if (selectedIndex === -1) {
162
221
  listRef.current.scrollToRow(0);
163
222
  }
164
223
  });
165
224
  });
166
- }, [selectedIndex, lastVisibleStartIndex, lastVisibleStopIndex, itemsLength, showMoreOptionsButton]);
167
- var _onMouseMove = function onMouseMove(event, index) {
225
+ }, [selectedIndex, lastVisibleStartIndex, lastVisibleStopIndex, itemsLength, showMoreOptionsButton, selectedItemRowIndex]);
226
+ var _onMouseMove = function onMouseMove(event, row) {
227
+ if (row.type !== 'item') {
228
+ return;
229
+ }
230
+ var itemIndex = row.itemIndex;
168
231
  event.preventDefault();
169
232
  event.stopPropagation();
170
- if (selectedIndex === index) {
233
+ if (selectedIndex === itemIndex) {
171
234
  return;
172
235
  }
173
236
  mouseMovedRef.current = true;
174
237
  lastInputMethodRef.current = 'mouse';
175
- (0, _updateSelectedIndex.updateSelectedIndex)(index, api)(editorView.state, editorView.dispatch);
238
+ (0, _updateSelectedIndex.updateSelectedIndex)(itemIndex, api)(editorView.state, editorView.dispatch);
176
239
  };
177
240
  (0, _react.useLayoutEffect)(function () {
178
241
  if (mouseMovedRef.current) {
@@ -186,17 +249,17 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
186
249
  return;
187
250
  }
188
251
  var isViewMoreSelected = showMoreOptionsButton && selectedIndex === itemsLength;
189
- var isSelectedItemVisible = selectedIndex >= lastVisibleStartIndex && selectedIndex <= lastVisibleStopIndex ||
252
+ var isSelectedItemVisible = selectedItemRowIndex >= lastVisibleStartIndex && selectedItemRowIndex <= lastVisibleStopIndex ||
190
253
  // view more is always visible, hence no scrolling
191
254
  isViewMoreSelected;
192
255
 
193
256
  //Should scroll to the list item only when the selectedIndex >= 0 and item is not visible
194
257
  if (!isSelectedItemVisible && selectedIndex !== -1) {
195
- listRef.current.scrollToRow(selectedIndex);
258
+ listRef.current.scrollToRow(selectedItemRowIndex);
196
259
  } else if (selectedIndex === -1) {
197
260
  listRef.current.scrollToRow(0);
198
261
  }
199
- }, [selectedIndex, lastVisibleStartIndex, lastVisibleStopIndex, itemsLength, showMoreOptionsButton]);
262
+ }, [selectedIndex, lastVisibleStartIndex, lastVisibleStopIndex, itemsLength, showMoreOptionsButton, selectedItemRowIndex]);
200
263
  (0, _react.useLayoutEffect)(function () {
201
264
  setCache(new _CellMeasurer.CellMeasurerCache({
202
265
  fixedWidth: true,
@@ -212,10 +275,10 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
212
275
  listContainerRef.current.firstChild.scrollTo(0, 0);
213
276
  }
214
277
  });
215
- }, [items]);
278
+ }, [items, sections]);
216
279
  (0, _react.useLayoutEffect)(function () {
217
280
  // Exclude view more item from the count
218
- var itemsToRender = showMoreOptionsButton ? items.slice(0, -1) : items;
281
+ var itemsToRender = (0, _experiments.editorExperiment)('platform_editor_agent_mentions', true) ? listRows : showMoreOptionsButton ? items.slice(0, -1) : items;
219
282
  var height = Math.min(
220
283
  // eslint-disable-next-line @atlassian/perf-linting/no-expensive-computations-in-render -- Ignored via go/ees017 (to be fixed)
221
284
  itemsToRender.reduce(function (prevValue, currentValue, index) {
@@ -224,7 +287,7 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
224
287
  });
225
288
  }, 0), fitHeight);
226
289
  setHeight(height);
227
- }, [items, cache, fitHeight, showMoreOptionsButton]);
290
+ }, [listRows, items, cache, fitHeight, showMoreOptionsButton]);
228
291
  (0, _react.useLayoutEffect)(function () {
229
292
  if (!listContainerRef.current) {
230
293
  return;
@@ -287,8 +350,8 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
287
350
  if (onMoreOptionsClicked) {
288
351
  onMoreOptionsClicked();
289
352
  }
290
- api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
291
- var tr = _ref4.tr;
353
+ api === null || api === void 0 || api.core.actions.execute(function (_ref5) {
354
+ var tr = _ref5.tr;
292
355
  (0, _closeTypeAhead.closeTypeAhead)(tr);
293
356
  config === null || config === void 0 || config.onClick({
294
357
  tr: tr
@@ -296,22 +359,25 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
296
359
  return tr;
297
360
  });
298
361
  };
299
- var renderRow = function renderRow(_ref5) {
300
- var index = _ref5.index,
301
- key = _ref5.key,
302
- style = _ref5.style,
303
- parent = _ref5.parent,
304
- isScrolling = _ref5.isScrolling,
305
- isVisible = _ref5.isVisible;
306
- var currentItem = items[index];
362
+ var renderRow = function renderRow(_ref6) {
363
+ var index = _ref6.index,
364
+ key = _ref6.key,
365
+ style = _ref6.style,
366
+ parent = _ref6.parent,
367
+ isScrolling = _ref6.isScrolling,
368
+ isVisible = _ref6.isVisible;
369
+ var currentRow = listRows[index];
370
+ if (!currentRow) {
371
+ return null;
372
+ }
307
373
  return (0, _react2.jsx)(_CellMeasurer.CellMeasurer, {
308
374
  key: key,
309
375
  cache: cache,
310
376
  parent: parent,
311
377
  columnIndex: 0,
312
378
  rowIndex: index
313
- }, function (_ref6) {
314
- var measure = _ref6.measure;
379
+ }, function (_ref7) {
380
+ var measure = _ref7.measure;
315
381
  return (0, _react2.jsx)(_ListRow.ListRow, {
316
382
  measure: measure,
317
383
  index: index
@@ -323,21 +389,29 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
323
389
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
324
390
  ,
325
391
  onMouseMove: function onMouseMove(e) {
326
- return _onMouseMove(e, index);
392
+ return _onMouseMove(e, currentRow);
327
393
  }
328
- }, (0, _react2.jsx)(_TypeAheadListItem.TypeAheadListItem, {
329
- key: items[index].title,
330
- item: currentItem,
394
+ }, currentRow.type === 'section' ? populatedSectionCount === 1 ? null : (0, _react2.jsx)(_compiled.Box, {
395
+ paddingInline: "space.150",
396
+ paddingBlock: "space.050"
397
+ }, (0, _react2.jsx)(_compiled.Text, {
398
+ as: "span",
399
+ size: "small",
400
+ color: "color.text.subtle",
401
+ weight: "medium"
402
+ }, currentRow.section.title)) : (0, _react2.jsx)(_TypeAheadListItem.TypeAheadListItem, {
403
+ key: items[currentRow.itemIndex].title,
404
+ item: items[currentRow.itemIndex],
331
405
  firstOnlineSupportedIndex: firstOnlineSupportedRow,
332
406
  itemsLength: itemsLength,
333
- itemIndex: index,
407
+ itemIndex: currentRow.itemIndex,
334
408
  selectedIndex: selectedIndex
335
409
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
336
410
  ,
337
- onItemClick: function onItemClick(mode, index) {
338
- actions.onItemClick(mode, index, _analytics.INPUT_METHOD.MOUSE);
411
+ onItemClick: function onItemClick(mode, itemIndex) {
412
+ actions.onItemClick(mode, itemIndex, _analytics.INPUT_METHOD.MOUSE);
339
413
  },
340
- ariaLabel: (0, _utils.getTypeAheadListAriaLabels)(triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.trigger, intl, currentItem).listItemAriaLabel,
414
+ ariaLabel: (0, _utils.getTypeAheadListAriaLabels)(triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.trigger, intl, items[currentRow.itemIndex]).listItemAriaLabel,
341
415
  moreElementsInQuickInsertViewEnabled: moreElementsInQuickInsertViewEnabled,
342
416
  api: api,
343
417
  lastInputMethodRef: lastInputMethodRef
@@ -371,7 +445,7 @@ var TypeAheadListComponent = /*#__PURE__*/_react.default.memo(function (_ref2) {
371
445
  ref: listRef
372
446
  // Skip rendering the view more button in the list
373
447
  ,
374
- rowCount: itemsLength,
448
+ rowCount: listRows.length,
375
449
  rowHeight: cache.rowHeight,
376
450
  onRowsRendered: onItemsRendered,
377
451
  width: LIST_WIDTH,
@@ -23,6 +23,8 @@ var TypeAheadMenu = exports.TypeAheadMenu = /*#__PURE__*/_react.default.memo(fun
23
23
  var isOpen = typeAheadState.decorationSet.find().length > 0;
24
24
  var triggerHandler = typeAheadState.triggerHandler,
25
25
  items = typeAheadState.items,
26
+ _typeAheadState$secti = typeAheadState.sections,
27
+ sections = _typeAheadState$secti === void 0 ? [] : _typeAheadState$secti,
26
28
  errorInfo = typeAheadState.errorInfo,
27
29
  decorationElement = typeAheadState.decorationElement,
28
30
  decorationSet = typeAheadState.decorationSet,
@@ -103,6 +105,7 @@ var TypeAheadMenu = exports.TypeAheadMenu = /*#__PURE__*/_react.default.memo(fun
103
105
  anchorElement: decorationElement,
104
106
  triggerHandler: triggerHandler,
105
107
  items: items,
108
+ sections: sections,
106
109
  emptyItem: emptyItem,
107
110
  errorInfo: errorInfo,
108
111
  selectedIndex: selectedIndex,