@atlaskit/editor-plugin-quick-insert 30.0.2 → 30.0.3

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 (28) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cjs/quickInsertPlugin.js +6 -2
  3. package/dist/cjs/ui/getQuickInsertComponents.js +8 -53
  4. package/dist/cjs/ui/getRecommendedComponents.js +19 -38
  5. package/dist/cjs/ui/registered-menu/QuickInsertMenuRoot.js +4 -2
  6. package/dist/cjs/ui/registered-menu/RegisteredQuickInsertMenuItem.js +5 -3
  7. package/dist/cjs/ui/registered-menu/get-quick-insert-menu-model.js +175 -88
  8. package/dist/es2019/quickInsertPlugin.js +6 -2
  9. package/dist/es2019/ui/getQuickInsertComponents.js +6 -43
  10. package/dist/es2019/ui/getRecommendedComponents.js +17 -37
  11. package/dist/es2019/ui/registered-menu/QuickInsertMenuRoot.js +4 -2
  12. package/dist/es2019/ui/registered-menu/RegisteredQuickInsertMenuItem.js +5 -3
  13. package/dist/es2019/ui/registered-menu/get-quick-insert-menu-model.js +128 -55
  14. package/dist/esm/quickInsertPlugin.js +6 -2
  15. package/dist/esm/ui/getQuickInsertComponents.js +8 -53
  16. package/dist/esm/ui/getRecommendedComponents.js +18 -37
  17. package/dist/esm/ui/registered-menu/QuickInsertMenuRoot.js +4 -2
  18. package/dist/esm/ui/registered-menu/RegisteredQuickInsertMenuItem.js +5 -3
  19. package/dist/esm/ui/registered-menu/get-quick-insert-menu-model.js +176 -89
  20. package/dist/types/ui/getQuickInsertComponents.d.ts +3 -4
  21. package/dist/types/ui/getRecommendedComponents.d.ts +8 -13
  22. package/dist/types/ui/registered-menu/QuickInsertMenuRoot.d.ts +3 -1
  23. package/dist/types/ui/registered-menu/get-quick-insert-menu-model.d.ts +12 -2
  24. package/package.json +2 -2
  25. package/dist/cjs/ui/QuickInsertRecommendedSlot.js +0 -23
  26. package/dist/es2019/ui/QuickInsertRecommendedSlot.js +0 -18
  27. package/dist/esm/ui/QuickInsertRecommendedSlot.js +0 -16
  28. package/dist/types/ui/QuickInsertRecommendedSlot.d.ts +0 -8
@@ -1,28 +1,22 @@
1
1
  import { logException } from '@atlaskit/editor-common/monitoring/error';
2
2
  import { quickInsertProviderMenuItemKey } from '@atlaskit/editor-common/quick-insert/get-provider-menu-item-key';
3
3
  import { defaultIsRecommendedItem } from '@atlaskit/editor-common/quick-insert/is-recommended-item';
4
- import { MENU } from '@atlaskit/editor-common/quick-insert/keys';
5
- import { REGISTERED_MENU_SURFACE_CONTEXT } from '@atlaskit/editor-common/registered-menu/surface-context';
6
4
  import { isMenuFooterSectionKey } from '@atlaskit/editor-common/type-ahead-is-menu-footer-section-key';
7
5
  import { isSectionOverflowItemKey } from '@atlaskit/editor-common/type-ahead-is-section-overflow-item-key';
8
6
  export var MAX_RECOMMENDED_ITEMS = 5;
9
- export var RECOMMENDED_SLOT_KEY_PREFIX = 'quick-insert-recommended-slot-';
10
- export var isRecommendedSlotKey = function isRecommendedSlotKey(key) {
11
- return key.startsWith(RECOMMENDED_SLOT_KEY_PREFIX);
12
- };
13
7
  var isRecommendationCandidate = function isRecommendationCandidate(component) {
14
- return component.type === 'menu-item' && !isRecommendedSlotKey(component.key) && !isSectionOverflowItemKey(component.key) && !component.parents.some(function (parent) {
8
+ return component.type === 'menu-item' && !isSectionOverflowItemKey(component.key) && !component.parents.some(function (parent) {
15
9
  return isMenuFooterSectionKey(parent.key);
16
10
  });
17
11
  };
18
12
 
19
- /** Normalises a consumer-supplied limit to the number of available recommended slots. */
13
+ /** Normalises a consumer-supplied limit to the supported number of recommended items. */
20
14
  export var resolveMaxRecommendedItems = function resolveMaxRecommendedItems(maxRecommendedItems) {
21
15
  if (maxRecommendedItems === undefined || !Number.isFinite(maxRecommendedItems)) {
22
16
  return MAX_RECOMMENDED_ITEMS;
23
17
  }
24
18
  if (maxRecommendedItems > MAX_RECOMMENDED_ITEMS) {
25
- void logException(new Error('Quick Insert maxRecommendedItems exceeds the available slots'), {
19
+ void logException(new Error('Quick Insert maxRecommendedItems exceeds the supported maximum'), {
26
20
  location: 'editor-plugin-quick-insert/getRecommendedComponents'
27
21
  });
28
22
  }
@@ -67,34 +61,21 @@ export var getRecommendedComponents = function getRecommendedComponents(_ref) {
67
61
  });
68
62
  };
69
63
 
70
- /** Keeps only the current menu-open recommendation snapshot. */
71
-
72
- export var createRecommendedSnapshotCache = function createRecommendedSnapshotCache(_ref3) {
73
- var api = _ref3.api,
74
- isRecommendedItem = _ref3.isRecommendedItem,
64
+ /**
65
+ * Resolves the Recommended section for a browse-mode menu. Callers memoise per components array,
66
+ * so the resolver itself keeps no state.
67
+ */
68
+ export var createRecommendedItemsResolver = function createRecommendedItemsResolver(_ref3) {
69
+ var isRecommendedItem = _ref3.isRecommendedItem,
75
70
  maxRecommendedItems = _ref3.maxRecommendedItems;
76
- var snapshot;
77
- var getSnapshot = function getSnapshot(surfaceContext) {
78
- var _surfaceContext$get, _snapshot;
79
- var menuOpenId = surfaceContext === null || surfaceContext === void 0 || (_surfaceContext$get = surfaceContext.get(REGISTERED_MENU_SURFACE_CONTEXT)) === null || _surfaceContext$get === void 0 ? void 0 : _surfaceContext$get.menuOpenId;
80
- if (!surfaceContext || !menuOpenId) {
81
- return [];
82
- }
83
- if (((_snapshot = snapshot) === null || _snapshot === void 0 ? void 0 : _snapshot.id) !== menuOpenId) {
84
- var _api$uiControlRegistr, _api$uiControlRegistr2;
85
- snapshot = {
86
- id: menuOpenId,
87
- items: getRecommendedComponents({
88
- components: (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(MENU.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [],
89
- context: surfaceContext,
90
- isRecommendedItem: isRecommendedItem,
91
- maxRecommendedItems: maxRecommendedItems
92
- })
93
- };
94
- }
95
- return snapshot.items;
96
- };
97
- return {
98
- getSnapshot: getSnapshot
71
+ return function (_ref4) {
72
+ var components = _ref4.components,
73
+ surfaceContext = _ref4.surfaceContext;
74
+ return surfaceContext ? getRecommendedComponents({
75
+ components: components,
76
+ context: surfaceContext,
77
+ isRecommendedItem: isRecommendedItem,
78
+ maxRecommendedItems: maxRecommendedItems
79
+ }) : [];
99
80
  };
100
81
  };
@@ -29,7 +29,8 @@ var QuickInsertMenuRoot = function QuickInsertMenuRoot(_ref) {
29
29
  var _surfaceContext$get, _registeredMenu$maxHe;
30
30
  var emptyStateHandler = _ref.emptyStateHandler,
31
31
  fireAnalyticsEvent = _ref.fireAnalyticsEvent,
32
- getItemRank = _ref.getItemRank;
32
+ getItemRank = _ref.getItemRank,
33
+ getRecommendedItems = _ref.getRecommendedItems;
33
34
  var registeredMenu = useRegisteredMenuContext();
34
35
  var _registeredMenu$query = registeredMenu.query,
35
36
  query = _registeredMenu$query === void 0 ? '' : _registeredMenu$query,
@@ -49,6 +50,7 @@ var QuickInsertMenuRoot = function QuickInsertMenuRoot(_ref) {
49
50
  components: components,
50
51
  formatMessage: formatMessage,
51
52
  getItemRank: runtimeItemRank !== null && runtimeItemRank !== void 0 ? runtimeItemRank : getItemRank,
53
+ getRecommendedItems: getRecommendedItems,
52
54
  query: query,
53
55
  rootComponent: rootComponent,
54
56
  selectCategoryItems: components.some(function (_ref2) {
@@ -57,7 +59,7 @@ var QuickInsertMenuRoot = function QuickInsertMenuRoot(_ref) {
57
59
  }) ? selectQuickInsertCategoryItems : undefined,
58
60
  surfaceContext: surfaceContext
59
61
  });
60
- }, [components, formatMessage, getItemRank, query, rootComponent, runtimeItemRank, surfaceContext]);
62
+ }, [components, formatMessage, getItemRank, getRecommendedItems, query, rootComponent, runtimeItemRank, surfaceContext]);
61
63
  var resultCount = useMemo(function () {
62
64
  return model.sections.reduce(function (count, _ref3) {
63
65
  var _ref4 = _toArray(_ref3),
@@ -2,7 +2,6 @@ import React, { useMemo } from 'react';
2
2
  import { QuickInsertProvider } from '@atlaskit/editor-common/quick-insert/provider';
3
3
  import { useQuickInsertContext } from '@atlaskit/editor-common/quick-insert/use-quick-insert-context';
4
4
  export var RegisteredQuickInsertMenuItem = function RegisteredQuickInsertMenuItem(_ref) {
5
- var _registration$compone;
6
5
  var id = _ref.id,
7
6
  isSelected = _ref.isSelected,
8
7
  isActive = _ref.isActive,
@@ -27,8 +26,11 @@ export var RegisteredQuickInsertMenuItem = function RegisteredQuickInsertMenuIte
27
26
  surfaceContext: surfaceContext
28
27
  };
29
28
  }, [editorView, isOffline, popupsMountPoint, select, surfaceContext, isActive, id, isSelected]);
30
- var Component = (_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : React.Fragment;
29
+ var Component = registration.component;
31
30
  return /*#__PURE__*/React.createElement(QuickInsertProvider, {
32
31
  value: value
33
- }, /*#__PURE__*/React.createElement(Component, null, null));
32
+ }, Component ? /*#__PURE__*/React.createElement(Component, {
33
+ parents: registration.parents,
34
+ surfaceContext: surfaceContext
35
+ }, null) : null);
34
36
  };
@@ -5,7 +5,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
5
5
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
6
6
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
7
7
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
8
- import { ASK_ROVO_MENU_ITEM, MENU, SEARCH_RESULTS_SECTION } from '@atlaskit/editor-common/quick-insert/keys';
8
+ import { ASK_ROVO_MENU_ITEM, MENU, RECOMMENDED_SECTION, SEARCH_RESULTS_SECTION } from '@atlaskit/editor-common/quick-insert/keys';
9
9
  import { applyRegisteredItemRanks } from '@atlaskit/editor-common/registered-menu/item-rank';
10
10
  import { isMenuFooterSectionKey } from '@atlaskit/editor-common/type-ahead-is-menu-footer-section-key';
11
11
  import { isSectionOverflowItemKey } from '@atlaskit/editor-common/type-ahead-is-section-overflow-item-key';
@@ -44,48 +44,70 @@ var getSearchResults = function getSearchResults(matches) {
44
44
  var identity = _ref.identity;
45
45
  return identity;
46
46
  }));
47
- var tailMatches = matches.filter(function (_ref2) {
47
+ return [].concat(_toConsumableArray(topMatches), _toConsumableArray(matches.filter(function (_ref2) {
48
48
  var identity = _ref2.identity;
49
49
  return !topMatchIdentities.has(identity);
50
- });
51
- return [].concat(_toConsumableArray(topMatches), _toConsumableArray(tailMatches)).map(function (_ref3) {
52
- var item = _ref3.item;
53
- return item;
54
- });
55
- };
56
- var getRenderedMenuItems = function getRenderedMenuItems(section, childrenMap, surfaceContext) {
57
- var _childrenMap$get;
58
- return ((_childrenMap$get = childrenMap.get(getComponentIdentity(section))) !== null && _childrenMap$get !== void 0 ? _childrenMap$get : []).filter(function (child) {
59
- return child.type === 'menu-item' && willComponentRender(child, childrenMap, surfaceContext);
60
- });
50
+ })));
61
51
  };
62
- var buildBrowseSections = function buildBrowseSections(_ref4) {
63
- var childrenMap = _ref4.childrenMap,
64
- contentSections = _ref4.contentSections,
65
- selectCategoryItems = _ref4.selectCategoryItems,
66
- surfaceContext = _ref4.surfaceContext;
67
- var sections = [];
68
- var _iterator = _createForOfIteratorHelper(contentSections),
52
+
53
+ /** Recommended uses resolved items rather than registered children. */
54
+ var readMenuSections = function readMenuSections(_ref3) {
55
+ var childrenMap = _ref3.childrenMap,
56
+ _ref3$recommendedItem = _ref3.recommendedItems,
57
+ recommendedItems = _ref3$recommendedItem === void 0 ? [] : _ref3$recommendedItem,
58
+ sections = _ref3.sections,
59
+ surfaceContext = _ref3.surfaceContext;
60
+ var renderedSections = [];
61
+ var _iterator = _createForOfIteratorHelper(sections),
69
62
  _step;
70
63
  try {
71
64
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
65
+ var _section$isHidden, _section$isHidden2, _childrenMap$get;
72
66
  var section = _step.value;
73
- var children = getRenderedMenuItems(section, childrenMap, surfaceContext);
74
- var overflowItems = children.filter(function (child) {
75
- return isSectionOverflowItemKey(child.key);
76
- });
77
- var viewMoreItem = overflowItems[overflowItems.length - 1];
78
- var items = children.filter(function (child) {
79
- return !isSectionOverflowItemKey(child.key);
80
- });
81
- if (items.length === 0) {
67
+ if (section.type !== 'menu-section') {
82
68
  continue;
83
69
  }
84
- var selectedItems = viewMoreItem !== undefined && selectCategoryItems !== undefined ? selectCategoryItems(items) : items;
85
- if (selectedItems.length < items.length && viewMoreItem !== undefined) {
86
- sections.push([section].concat(_toConsumableArray(selectedItems), [viewMoreItem]));
87
- } else {
88
- sections.push([section].concat(_toConsumableArray(selectedItems)));
70
+ if (surfaceContext ? (_section$isHidden = section.isHidden) === null || _section$isHidden === void 0 ? void 0 : _section$isHidden.call(section, {
71
+ surfaceContext: surfaceContext
72
+ }) : (_section$isHidden2 = section.isHidden) === null || _section$isHidden2 === void 0 ? void 0 : _section$isHidden2.call(section)) {
73
+ continue;
74
+ }
75
+ if (section.key === RECOMMENDED_SECTION.key) {
76
+ renderedSections.push({
77
+ section: section,
78
+ items: recommendedItems
79
+ });
80
+ continue;
81
+ }
82
+ var children = (_childrenMap$get = childrenMap.get(getComponentIdentity(section))) !== null && _childrenMap$get !== void 0 ? _childrenMap$get : [];
83
+ var items = [];
84
+ var viewMoreItem = void 0;
85
+ var _iterator2 = _createForOfIteratorHelper(children),
86
+ _step2;
87
+ try {
88
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
89
+ var child = _step2.value;
90
+ if (child.type !== 'menu-item' || !willComponentRender(child, childrenMap, surfaceContext)) {
91
+ continue;
92
+ }
93
+ if (isSectionOverflowItemKey(child.key)) {
94
+ viewMoreItem !== null && viewMoreItem !== void 0 ? viewMoreItem : viewMoreItem = child;
95
+ } else {
96
+ items.push(child);
97
+ }
98
+ }
99
+ // Empty registrations are visible leaves; containers need a visible child.
100
+ } catch (err) {
101
+ _iterator2.e(err);
102
+ } finally {
103
+ _iterator2.f();
104
+ }
105
+ if (children.length === 0 || items.length > 0 || viewMoreItem) {
106
+ renderedSections.push({
107
+ section: section,
108
+ items: items,
109
+ viewMoreItem: viewMoreItem
110
+ });
89
111
  }
90
112
  }
91
113
  } catch (err) {
@@ -93,53 +115,92 @@ var buildBrowseSections = function buildBrowseSections(_ref4) {
93
115
  } finally {
94
116
  _iterator.f();
95
117
  }
118
+ return renderedSections;
119
+ };
120
+ var getOwnerSectionKey = function getOwnerSectionKey(item, isRecommendedItem) {
121
+ var _item$parents$;
122
+ return isRecommendedItem(item) ? RECOMMENDED_SECTION.key : (_item$parents$ = item.parents[0]) === null || _item$parents$ === void 0 ? void 0 : _item$parents$.key;
123
+ };
124
+ var buildBrowseSections = function buildBrowseSections(_ref4) {
125
+ var contentSections = _ref4.contentSections,
126
+ isRecommendedItem = _ref4.isRecommendedItem,
127
+ selectCategoryItems = _ref4.selectCategoryItems;
128
+ var sections = [];
129
+ var _iterator3 = _createForOfIteratorHelper(contentSections),
130
+ _step3;
131
+ try {
132
+ var _loop = function _loop() {
133
+ var _step3$value = _step3.value,
134
+ items = _step3$value.items,
135
+ section = _step3$value.section,
136
+ viewMoreItem = _step3$value.viewMoreItem;
137
+ var ownedItems = items.filter(function (item) {
138
+ return getOwnerSectionKey(item, isRecommendedItem) === section.key;
139
+ });
140
+ if (ownedItems.length === 0) {
141
+ return 1; // continue
142
+ }
143
+ var selectedItems = viewMoreItem && selectCategoryItems ? selectCategoryItems(ownedItems) : ownedItems;
144
+ sections.push([section].concat(_toConsumableArray(selectedItems), _toConsumableArray(viewMoreItem && selectedItems.length < ownedItems.length ? [viewMoreItem] : [])));
145
+ };
146
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
147
+ if (_loop()) continue;
148
+ }
149
+ } catch (err) {
150
+ _iterator3.e(err);
151
+ } finally {
152
+ _iterator3.f();
153
+ }
96
154
  return {
97
155
  fallbackItems: [],
98
156
  sections: sections
99
157
  };
100
158
  };
101
159
  var buildSearchSections = function buildSearchSections(_ref5) {
102
- var childrenMap = _ref5.childrenMap,
103
- components = _ref5.components,
160
+ var components = _ref5.components,
104
161
  contentSections = _ref5.contentSections,
105
162
  formatMessage = _ref5.formatMessage,
163
+ isRecommendedItem = _ref5.isRecommendedItem,
106
164
  query = _ref5.query,
107
- root = _ref5.root,
108
- surfaceContext = _ref5.surfaceContext;
109
- var matches = new Map();
165
+ root = _ref5.root;
110
166
  var sourceIndexByComponent = new Map(components.map(function (component, index) {
111
167
  return [component, index];
112
168
  }));
113
- var _iterator2 = _createForOfIteratorHelper(contentSections),
114
- _step2;
169
+ var matches = new Map();
170
+ var fallbackItem;
171
+ var _iterator4 = _createForOfIteratorHelper(contentSections),
172
+ _step4;
115
173
  try {
116
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
117
- var section = _step2.value;
118
- var _iterator3 = _createForOfIteratorHelper(getRenderedMenuItems(section, childrenMap, surfaceContext)),
119
- _step3;
174
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
175
+ var _step4$value = _step4.value,
176
+ items = _step4$value.items,
177
+ section = _step4$value.section;
178
+ var sectionRank = getParentRank(section, root.key);
179
+ var _iterator5 = _createForOfIteratorHelper(items),
180
+ _step5;
120
181
  try {
121
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
182
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
122
183
  var _item$match, _match$score, _sourceIndexByCompone;
123
- var item = _step3.value;
124
- if (isSectionOverflowItemKey(item.key)) {
125
- continue;
184
+ var item = _step5.value;
185
+ if (item.key === ASK_ROVO_MENU_ITEM.key) {
186
+ fallbackItem !== null && fallbackItem !== void 0 ? fallbackItem : fallbackItem = item;
126
187
  }
127
188
  var match = (_item$match = item.match) === null || _item$match === void 0 ? void 0 : _item$match.call(item, {
128
189
  formatMessage: formatMessage,
129
190
  itemKey: item.key,
130
191
  query: query
131
192
  });
132
- if (item.match && match === null) {
193
+ if (item.match && match === null || getOwnerSectionKey(item, isRecommendedItem) !== section.key) {
133
194
  continue;
134
195
  }
135
196
  var candidate = {
136
- identity: "".concat(item.type, ":").concat(item.key),
197
+ identity: getComponentIdentity(item),
137
198
  item: item,
138
199
  itemRank: getParentRank(item, section.key),
139
200
  priorityGroup: (match === null || match === void 0 ? void 0 : match.priorityGroup) !== undefined && Number.isFinite(match.priorityGroup) ? match.priorityGroup : undefined,
140
201
  score: Math.min(1, Math.max(0, (_match$score = match === null || match === void 0 ? void 0 : match.score) !== null && _match$score !== void 0 ? _match$score : 0)),
141
- sourceIndex: (_sourceIndexByCompone = sourceIndexByComponent.get(item)) !== null && _sourceIndexByCompone !== void 0 ? _sourceIndexByCompone : Number.MAX_SAFE_INTEGER,
142
- sectionRank: getParentRank(section, root.key)
202
+ sectionRank: sectionRank,
203
+ sourceIndex: (_sourceIndexByCompone = sourceIndexByComponent.get(item)) !== null && _sourceIndexByCompone !== void 0 ? _sourceIndexByCompone : Number.MAX_SAFE_INTEGER
143
204
  };
144
205
  var existing = matches.get(candidate.identity);
145
206
  if (!existing || compareMatchedItems(candidate, existing) < 0) {
@@ -147,15 +208,15 @@ var buildSearchSections = function buildSearchSections(_ref5) {
147
208
  }
148
209
  }
149
210
  } catch (err) {
150
- _iterator3.e(err);
211
+ _iterator5.e(err);
151
212
  } finally {
152
- _iterator3.f();
213
+ _iterator5.f();
153
214
  }
154
215
  }
155
216
  } catch (err) {
156
- _iterator2.e(err);
217
+ _iterator4.e(err);
157
218
  } finally {
158
- _iterator2.f();
219
+ _iterator4.f();
159
220
  }
160
221
  var uniqueMatches = Array.from(matches.values()).sort(compareMatchedItems);
161
222
  var prioritizedMatches = uniqueMatches.filter(function (_ref6) {
@@ -169,44 +230,50 @@ var buildSearchSections = function buildSearchSections(_ref5) {
169
230
  var orderedSearchResults = [].concat(_toConsumableArray(prioritizedMatches.sort(comparePrioritizedSearchResults).map(function (_ref8) {
170
231
  var item = _ref8.item;
171
232
  return item;
172
- })), _toConsumableArray(getSearchResults(unprioritizedMatches)));
233
+ })), _toConsumableArray(getSearchResults(unprioritizedMatches).map(function (_ref9) {
234
+ var item = _ref9.item;
235
+ return item;
236
+ })));
173
237
  if (orderedSearchResults.length > 0) {
174
238
  return {
175
239
  fallbackItems: [],
176
240
  sections: [[SEARCH_RESULTS_HEADING].concat(_toConsumableArray(orderedSearchResults))]
177
241
  };
178
242
  }
179
- var fallbackItem = contentSections.flatMap(function (section) {
180
- var _childrenMap$get2;
181
- return (_childrenMap$get2 = childrenMap.get(getComponentIdentity(section))) !== null && _childrenMap$get2 !== void 0 ? _childrenMap$get2 : [];
182
- }).find(function (component) {
183
- return component.type === ASK_ROVO_MENU_ITEM.type && component.key === ASK_ROVO_MENU_ITEM.key && willComponentRender(component, childrenMap, surfaceContext);
184
- });
185
243
  return {
186
244
  fallbackItems: fallbackItem ? [fallbackItem] : [],
187
245
  sections: []
188
246
  };
189
247
  };
190
248
 
249
+ /**
250
+ * Resolves the Recommended items for a browse. Receives the unranked components so a resolver
251
+ * can look recommendations up by their registered keys.
252
+ */
253
+
191
254
  /**
192
255
  * Builds the registered quick-insert menu model. An empty query browses every
193
256
  * category; a non-empty query returns ranked matches. The footer is shared by both.
194
257
  */
195
- export var getQuickInsertMenuModel = function getQuickInsertMenuModel(_ref9) {
196
- var components = _ref9.components,
197
- formatMessage = _ref9.formatMessage,
198
- getItemRank = _ref9.getItemRank,
199
- query = _ref9.query,
200
- rootComponent = _ref9.rootComponent,
201
- selectCategoryItems = _ref9.selectCategoryItems,
202
- surfaceContext = _ref9.surfaceContext;
258
+ export var getQuickInsertMenuModel = function getQuickInsertMenuModel(_ref0) {
259
+ var _root$isHidden, _root$isHidden2, _contentSections$find;
260
+ var components = _ref0.components,
261
+ formatMessage = _ref0.formatMessage,
262
+ getItemRank = _ref0.getItemRank,
263
+ getRecommendedItems = _ref0.getRecommendedItems,
264
+ query = _ref0.query,
265
+ rootComponent = _ref0.rootComponent,
266
+ selectCategoryItems = _ref0.selectCategoryItems,
267
+ surfaceContext = _ref0.surfaceContext;
203
268
  var rankedComponents = applyRegisteredItemRanks(components, getItemRank);
204
269
  var _resolveSurface = resolveSurface(rankedComponents, rootComponent),
205
270
  childrenMap = _resolveSurface.childrenMap,
206
271
  root = _resolveSurface.root,
207
272
  _resolveSurface$topLe = _resolveSurface.topLevelChildren,
208
273
  topLevelChildren = _resolveSurface$topLe === void 0 ? [] : _resolveSurface$topLe;
209
- if (!root || !willComponentRender(root, childrenMap, surfaceContext)) {
274
+ if (!root || (surfaceContext ? (_root$isHidden = root.isHidden) === null || _root$isHidden === void 0 ? void 0 : _root$isHidden.call(root, {
275
+ surfaceContext: surfaceContext
276
+ }) : (_root$isHidden2 = root.isHidden) === null || _root$isHidden2 === void 0 ? void 0 : _root$isHidden2.call(root))) {
210
277
  return {
211
278
  fallbackItems: [],
212
279
  footer: undefined,
@@ -214,32 +281,52 @@ export var getQuickInsertMenuModel = function getQuickInsertMenuModel(_ref9) {
214
281
  sections: []
215
282
  };
216
283
  }
217
- var renderedSections = topLevelChildren.filter(function (section) {
218
- return section.type === 'menu-section' && willComponentRender(section, childrenMap, surfaceContext);
284
+ var isBrowse = query === '';
285
+ var renderedSections = readMenuSections({
286
+ sections: topLevelChildren,
287
+ childrenMap: childrenMap,
288
+ surfaceContext: surfaceContext,
289
+ recommendedItems: isBrowse ? getRecommendedItems === null || getRecommendedItems === void 0 ? void 0 : getRecommendedItems({
290
+ components: components,
291
+ surfaceContext: surfaceContext
292
+ }) : undefined
219
293
  });
220
- var footerSection = renderedSections.find(function (_ref0) {
221
- var key = _ref0.key;
222
- return isMenuFooterSectionKey(key);
294
+ if (topLevelChildren.length > 0 && renderedSections.length === 0) {
295
+ return {
296
+ fallbackItems: [],
297
+ footer: undefined,
298
+ root: undefined,
299
+ sections: []
300
+ };
301
+ }
302
+ var footerSection = renderedSections.find(function (_ref1) {
303
+ var section = _ref1.section;
304
+ return isMenuFooterSectionKey(section.key);
223
305
  });
224
- var contentSections = renderedSections.filter(function (_ref1) {
225
- var key = _ref1.key;
226
- return !isMenuFooterSectionKey(key);
306
+ var contentSections = renderedSections.filter(function (_ref10) {
307
+ var section = _ref10.section;
308
+ return !isMenuFooterSectionKey(section.key) && (isBrowse || section.key !== RECOMMENDED_SECTION.key);
227
309
  });
228
- var content = query === '' ? buildBrowseSections({
229
- childrenMap: childrenMap,
310
+ var recommendedIdentities = new Set((_contentSections$find = contentSections.find(function (_ref11) {
311
+ var section = _ref11.section;
312
+ return section.key === RECOMMENDED_SECTION.key;
313
+ })) === null || _contentSections$find === void 0 ? void 0 : _contentSections$find.items.map(getComponentIdentity));
314
+ var isRecommendedItem = function isRecommendedItem(item) {
315
+ return recommendedIdentities.has(getComponentIdentity(item));
316
+ };
317
+ var content = isBrowse ? buildBrowseSections({
230
318
  contentSections: contentSections,
231
- selectCategoryItems: selectCategoryItems,
232
- surfaceContext: surfaceContext
319
+ isRecommendedItem: isRecommendedItem,
320
+ selectCategoryItems: selectCategoryItems
233
321
  }) : buildSearchSections({
234
- childrenMap: childrenMap,
235
322
  components: rankedComponents,
236
323
  contentSections: contentSections,
237
324
  formatMessage: formatMessage,
325
+ isRecommendedItem: isRecommendedItem,
238
326
  query: query,
239
- root: root,
240
- surfaceContext: surfaceContext
327
+ root: root
241
328
  });
242
- var footer = footerSection ? getRenderedMenuItems(footerSection, childrenMap, surfaceContext)[0] : undefined;
329
+ var footer = footerSection === null || footerSection === void 0 ? void 0 : footerSection.items[0];
243
330
  return _objectSpread(_objectSpread({}, content), {}, {
244
331
  footer: footer,
245
332
  root: root
@@ -1,18 +1,17 @@
1
1
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics/api';
2
- import type { IsRecommendedItem } from '@atlaskit/editor-common/quick-insert/is-recommended-item';
3
2
  import type { RegisteredItemRankResolver } from '@atlaskit/editor-common/registered-menu/item-rank';
4
3
  import type { EmptyStateHandler } from '@atlaskit/editor-common/types/empty-state-handler';
5
4
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types/next-editor-plugin';
6
5
  import type { RegisterComponent } from '@atlaskit/editor-ui-control-model/types';
7
6
  import type { QuickInsertPlugin } from '../quickInsertPluginType';
7
+ import type { RecommendedItemsResolver } from './registered-menu/get-quick-insert-menu-model';
8
8
  type Params = {
9
9
  api: ExtractInjectionAPI<QuickInsertPlugin> | undefined;
10
10
  emptyStateHandler?: EmptyStateHandler;
11
11
  fireAnalyticsEvent?: EditorAnalyticsAPI['fireAnalyticsEvent'];
12
12
  getItemRank?: RegisteredItemRankResolver;
13
+ getRecommendedItems?: RecommendedItemsResolver;
13
14
  includeElementBrowserItems: boolean;
14
- isRecommendedItem?: IsRecommendedItem;
15
- maxRecommendedItems?: number;
16
15
  };
17
- export declare const getQuickInsertComponents: ({ api, includeElementBrowserItems, isRecommendedItem, maxRecommendedItems, getItemRank, emptyStateHandler, fireAnalyticsEvent, }: Params) => RegisterComponent[];
16
+ export declare const getQuickInsertComponents: ({ api, includeElementBrowserItems, getItemRank, getRecommendedItems, emptyStateHandler, fireAnalyticsEvent, }: Params) => RegisterComponent[];
18
17
  export {};
@@ -1,11 +1,8 @@
1
1
  import { type IsRecommendedItem } from '@atlaskit/editor-common/quick-insert/is-recommended-item';
2
- import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types/next-editor-plugin';
3
2
  import type { RegisterComponent, RegisterMenuItem, SurfaceContext } from '@atlaskit/editor-ui-control-model/types';
4
- import type { QuickInsertPlugin } from '../quickInsertPluginType';
3
+ import type { RecommendedItemsResolver } from './registered-menu/get-quick-insert-menu-model';
5
4
  export declare const MAX_RECOMMENDED_ITEMS = 5;
6
- export declare const RECOMMENDED_SLOT_KEY_PREFIX = "quick-insert-recommended-slot-";
7
- export declare const isRecommendedSlotKey: (key: string) => boolean;
8
- /** Normalises a consumer-supplied limit to the number of available recommended slots. */
5
+ /** Normalises a consumer-supplied limit to the supported number of recommended items. */
9
6
  export declare const resolveMaxRecommendedItems: (maxRecommendedItems?: number) => number;
10
7
  export declare const getRecommendedComponents: ({ components, context, isRecommendedItem, maxRecommendedItems, }: {
11
8
  components: RegisterComponent[];
@@ -13,13 +10,11 @@ export declare const getRecommendedComponents: ({ components, context, isRecomme
13
10
  isRecommendedItem?: IsRecommendedItem;
14
11
  maxRecommendedItems?: number;
15
12
  }) => RegisterMenuItem[];
16
- /** Keeps only the current menu-open recommendation snapshot. */
17
- type RecommendedSnapshotCache = {
18
- getSnapshot: (surfaceContext?: SurfaceContext) => RegisterMenuItem[];
19
- };
20
- export declare const createRecommendedSnapshotCache: ({ api, isRecommendedItem, maxRecommendedItems, }: {
21
- api: ExtractInjectionAPI<QuickInsertPlugin> | undefined;
13
+ /**
14
+ * Resolves the Recommended section for a browse-mode menu. Callers memoise per components array,
15
+ * so the resolver itself keeps no state.
16
+ */
17
+ export declare const createRecommendedItemsResolver: ({ isRecommendedItem, maxRecommendedItems, }: {
22
18
  isRecommendedItem?: IsRecommendedItem;
23
19
  maxRecommendedItems?: number;
24
- }) => RecommendedSnapshotCache;
25
- export {};
20
+ }) => RecommendedItemsResolver;
@@ -2,10 +2,12 @@ import React from 'react';
2
2
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics/api';
3
3
  import type { RegisteredItemRankResolver } from '@atlaskit/editor-common/registered-menu/item-rank';
4
4
  import type { EmptyStateHandler } from '@atlaskit/editor-common/types/empty-state-handler';
5
+ import { type RecommendedItemsResolver } from './get-quick-insert-menu-model';
5
6
  type Props = {
6
7
  emptyStateHandler?: EmptyStateHandler;
7
8
  fireAnalyticsEvent?: EditorAnalyticsAPI['fireAnalyticsEvent'];
8
9
  getItemRank?: RegisteredItemRankResolver;
10
+ getRecommendedItems?: RecommendedItemsResolver;
9
11
  };
10
- declare const QuickInsertMenuRoot: ({ emptyStateHandler, fireAnalyticsEvent, getItemRank, }: React.PropsWithChildren<Props>) => React.JSX.Element | null;
12
+ declare const QuickInsertMenuRoot: ({ emptyStateHandler, fireAnalyticsEvent, getItemRank, getRecommendedItems, }: React.PropsWithChildren<Props>) => React.JSX.Element | null;
11
13
  export default QuickInsertMenuRoot;
@@ -2,16 +2,26 @@ import type { IntlShape } from 'react-intl';
2
2
  import type { RegisteredMenuModel } from '@atlaskit/editor-common/registered-menu';
3
3
  import { type RegisteredItemRankResolver } from '@atlaskit/editor-common/registered-menu/item-rank';
4
4
  import type { SurfaceIdentifier } from '@atlaskit/editor-ui-control-model/surface-renderer/types';
5
- import type { RegisterComponent, SurfaceContext } from '@atlaskit/editor-ui-control-model/types';
5
+ import type { RegisterComponent, RegisterMenuItem, SurfaceContext } from '@atlaskit/editor-ui-control-model/types';
6
6
  import type { QuickInsertCategoryItemSelectionPolicy } from './selectQuickInsertCategoryItems';
7
+ /**
8
+ * Resolves the Recommended items for a browse. Receives the unranked components so a resolver
9
+ * can look recommendations up by their registered keys.
10
+ */
11
+ export type RecommendedItemsResolver = (params: {
12
+ components: RegisterComponent[];
13
+ surfaceContext?: SurfaceContext;
14
+ }) => RegisterMenuItem[];
7
15
  /**
8
16
  * Builds the registered quick-insert menu model. An empty query browses every
9
17
  * category; a non-empty query returns ranked matches. The footer is shared by both.
10
18
  */
11
- export declare const getQuickInsertMenuModel: ({ components, formatMessage, getItemRank, query, rootComponent, selectCategoryItems, surfaceContext, }: {
19
+ export declare const getQuickInsertMenuModel: ({ components, formatMessage, getItemRank, getRecommendedItems, query, rootComponent, selectCategoryItems, surfaceContext, }: {
12
20
  components: RegisterComponent[];
13
21
  formatMessage: IntlShape['formatMessage'];
14
22
  getItemRank?: RegisteredItemRankResolver;
23
+ /** Fills Recommended when browsing. Search never shows Recommended. */
24
+ getRecommendedItems?: RecommendedItemsResolver;
15
25
  query: string;
16
26
  rootComponent: SurfaceIdentifier;
17
27
  selectCategoryItems?: QuickInsertCategoryItemSelectionPolicy;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-quick-insert",
3
- "version": "30.0.2",
3
+ "version": "30.0.3",
4
4
  "description": "Quick insert plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -46,7 +46,7 @@
46
46
  "@atlaskit/platform-feature-experiments": "^0.3.0",
47
47
  "@atlaskit/platform-feature-flags": "^2.2.0",
48
48
  "@atlaskit/primitives": "^22.6.0",
49
- "@atlaskit/textfield": "^10.2.0",
49
+ "@atlaskit/textfield": "^10.3.0",
50
50
  "@atlaskit/tmp-editor-statsig": "^248.0.0",
51
51
  "@atlaskit/tokens": "^20.8.0",
52
52
  "@atlaskit/tooltip": "^24.4.0",