@atlaskit/editor-plugin-quick-insert 29.0.4 → 30.0.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 (87) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cjs/quickInsertPlugin.js +10 -5
  3. package/dist/cjs/ui/QuickInsertRecommendedSlot.js +11 -8
  4. package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowser.js +31 -7
  5. package/dist/cjs/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.js +13 -7
  6. package/dist/cjs/ui/RegistryElementBrowser/model.js +31 -18
  7. package/dist/cjs/ui/getQuickInsertComponents.js +28 -16
  8. package/dist/cjs/ui/getRecommendedComponents.js +2 -2
  9. package/dist/cjs/ui/registered-menu/QuickInsertEmptyState.compiled.css +11 -0
  10. package/dist/cjs/ui/registered-menu/QuickInsertEmptyState.js +61 -0
  11. package/dist/cjs/ui/registered-menu/QuickInsertMenuRoot.js +220 -0
  12. package/dist/cjs/ui/registered-menu/QuickInsertMenuSection.js +23 -0
  13. package/dist/cjs/ui/registered-menu/QuickInsertSearchResultsSection.js +19 -0
  14. package/dist/cjs/ui/registered-menu/RegisteredQuickInsertMenuItem.js +42 -0
  15. package/dist/cjs/ui/registered-menu/ToolbarQuickInsertMenu.compiled.css +11 -0
  16. package/dist/cjs/ui/registered-menu/ToolbarQuickInsertMenu.js +128 -0
  17. package/dist/cjs/ui/registered-menu/TypeAheadQuickInsertMenu.compiled.css +3 -0
  18. package/dist/cjs/ui/registered-menu/TypeAheadQuickInsertMenu.js +90 -0
  19. package/dist/cjs/ui/registered-menu/assets/no-results.js +36 -0
  20. package/dist/cjs/ui/registered-menu/get-quick-insert-menu-model.js +254 -0
  21. package/dist/cjs/ui/registered-menu/getQuickInsertMenuItemId.js +9 -0
  22. package/dist/cjs/ui/registered-menu/selectQuickInsertCategoryItems.js +27 -0
  23. package/dist/cjs/ui/registered-menu/useQuickInsertSearchAnalytics.js +100 -0
  24. package/dist/es2019/quickInsertPlugin.js +10 -5
  25. package/dist/es2019/ui/QuickInsertRecommendedSlot.js +10 -5
  26. package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowser.js +19 -2
  27. package/dist/es2019/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.js +12 -7
  28. package/dist/es2019/ui/RegistryElementBrowser/model.js +27 -16
  29. package/dist/es2019/ui/getQuickInsertComponents.js +24 -10
  30. package/dist/es2019/ui/getRecommendedComponents.js +2 -2
  31. package/dist/es2019/ui/registered-menu/QuickInsertEmptyState.compiled.css +11 -0
  32. package/dist/es2019/ui/registered-menu/QuickInsertEmptyState.js +47 -0
  33. package/dist/es2019/ui/registered-menu/QuickInsertMenuRoot.js +191 -0
  34. package/dist/es2019/ui/registered-menu/QuickInsertMenuSection.js +15 -0
  35. package/dist/es2019/ui/registered-menu/QuickInsertSearchResultsSection.js +14 -0
  36. package/dist/es2019/ui/registered-menu/RegisteredQuickInsertMenuItem.js +34 -0
  37. package/dist/es2019/ui/registered-menu/ToolbarQuickInsertMenu.compiled.css +11 -0
  38. package/dist/es2019/ui/registered-menu/ToolbarQuickInsertMenu.js +116 -0
  39. package/dist/es2019/ui/registered-menu/TypeAheadQuickInsertMenu.compiled.css +3 -0
  40. package/dist/es2019/ui/registered-menu/TypeAheadQuickInsertMenu.js +78 -0
  41. package/dist/es2019/ui/registered-menu/assets/no-results.js +30 -0
  42. package/dist/es2019/ui/registered-menu/get-quick-insert-menu-model.js +191 -0
  43. package/dist/es2019/ui/registered-menu/getQuickInsertMenuItemId.js +1 -0
  44. package/dist/es2019/ui/registered-menu/selectQuickInsertCategoryItems.js +19 -0
  45. package/dist/es2019/ui/registered-menu/useQuickInsertSearchAnalytics.js +91 -0
  46. package/dist/esm/quickInsertPlugin.js +10 -5
  47. package/dist/esm/ui/QuickInsertRecommendedSlot.js +11 -8
  48. package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowser.js +30 -6
  49. package/dist/esm/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.js +12 -7
  50. package/dist/esm/ui/RegistryElementBrowser/model.js +31 -18
  51. package/dist/esm/ui/getQuickInsertComponents.js +27 -15
  52. package/dist/esm/ui/getRecommendedComponents.js +2 -2
  53. package/dist/esm/ui/registered-menu/QuickInsertEmptyState.compiled.css +11 -0
  54. package/dist/esm/ui/registered-menu/QuickInsertEmptyState.js +50 -0
  55. package/dist/esm/ui/registered-menu/QuickInsertMenuRoot.js +211 -0
  56. package/dist/esm/ui/registered-menu/QuickInsertMenuSection.js +16 -0
  57. package/dist/esm/ui/registered-menu/QuickInsertSearchResultsSection.js +12 -0
  58. package/dist/esm/ui/registered-menu/RegisteredQuickInsertMenuItem.js +34 -0
  59. package/dist/esm/ui/registered-menu/ToolbarQuickInsertMenu.compiled.css +11 -0
  60. package/dist/esm/ui/registered-menu/ToolbarQuickInsertMenu.js +120 -0
  61. package/dist/esm/ui/registered-menu/TypeAheadQuickInsertMenu.compiled.css +3 -0
  62. package/dist/esm/ui/registered-menu/TypeAheadQuickInsertMenu.js +82 -0
  63. package/dist/esm/ui/registered-menu/assets/no-results.js +29 -0
  64. package/dist/esm/ui/registered-menu/get-quick-insert-menu-model.js +247 -0
  65. package/dist/esm/ui/registered-menu/getQuickInsertMenuItemId.js +3 -0
  66. package/dist/esm/ui/registered-menu/selectQuickInsertCategoryItems.js +21 -0
  67. package/dist/esm/ui/registered-menu/useQuickInsertSearchAnalytics.js +93 -0
  68. package/dist/types/quickInsertPluginType.d.ts +1 -1
  69. package/dist/types/ui/QuickInsertRecommendedSlot.d.ts +3 -3
  70. package/dist/types/ui/RegistryElementBrowser/RegistryElementBrowserSearchResults.d.ts +5 -2
  71. package/dist/types/ui/RegistryElementBrowser/model.d.ts +3 -2
  72. package/dist/types/ui/getQuickInsertComponents.d.ts +8 -2
  73. package/dist/types/ui/registered-menu/QuickInsertEmptyState.d.ts +7 -0
  74. package/dist/types/ui/registered-menu/QuickInsertMenuRoot.d.ts +11 -0
  75. package/dist/types/ui/registered-menu/QuickInsertMenuSection.d.ts +4 -0
  76. package/dist/types/ui/registered-menu/QuickInsertSearchResultsSection.d.ts +2 -0
  77. package/dist/types/ui/registered-menu/RegisteredQuickInsertMenuItem.d.ts +3 -0
  78. package/dist/types/ui/registered-menu/ToolbarQuickInsertMenu.d.ts +28 -0
  79. package/dist/types/ui/registered-menu/TypeAheadQuickInsertMenu.d.ts +27 -0
  80. package/dist/types/ui/registered-menu/assets/no-results.d.ts +7 -0
  81. package/dist/types/ui/registered-menu/get-quick-insert-menu-model.d.ts +19 -0
  82. package/dist/types/ui/registered-menu/getQuickInsertMenuItemId.d.ts +1 -0
  83. package/dist/types/ui/registered-menu/selectQuickInsertCategoryItems.d.ts +7 -0
  84. package/dist/types/ui/registered-menu/useQuickInsertSearchAnalytics.d.ts +12 -0
  85. package/package.json +15 -12
  86. package/registered-menu/model/package.json +10 -0
  87. package/registered-menu/search-analytics/package.json +10 -0
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getQuickInsertMenuModel = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
+ var _keys = require("@atlaskit/editor-common/quick-insert/keys");
11
+ var _itemRank = require("@atlaskit/editor-common/registered-menu/item-rank");
12
+ var _typeAheadIsMenuFooterSectionKey = require("@atlaskit/editor-common/type-ahead-is-menu-footer-section-key");
13
+ var _typeAheadIsSectionOverflowItemKey = require("@atlaskit/editor-common/type-ahead-is-section-overflow-item-key");
14
+ var _surfaceRenderer = require("@atlaskit/editor-ui-control-model/surface-renderer");
15
+ var _QuickInsertSearchResultsSection = require("./QuickInsertSearchResultsSection");
16
+ 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
+ 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
+ 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; } } }; }
19
+ 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; } }
20
+ 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; }
21
+ var SEARCH_TOP_MATCH_LIMIT = 5;
22
+ var SEARCH_RESULTS_HEADING = {
23
+ key: _keys.SEARCH_RESULTS_SECTION.key,
24
+ type: _keys.SEARCH_RESULTS_SECTION.type,
25
+ component: _QuickInsertSearchResultsSection.QuickInsertSearchResultsSection,
26
+ parents: [{
27
+ key: _keys.MENU.key,
28
+ type: _keys.MENU.type,
29
+ rank: 0
30
+ }]
31
+ };
32
+ var getParentRank = function getParentRank(component, parentKey) {
33
+ var _component$parents$fi, _component$parents;
34
+ return (_component$parents$fi = (_component$parents = component.parents) === null || _component$parents === void 0 || (_component$parents = _component$parents.find(function (parent) {
35
+ return parent.key === parentKey;
36
+ })) === null || _component$parents === void 0 ? void 0 : _component$parents.rank) !== null && _component$parents$fi !== void 0 ? _component$parents$fi : Number.MAX_SAFE_INTEGER;
37
+ };
38
+ var compareMatchedItems = function compareMatchedItems(a, b) {
39
+ return a.sectionRank - b.sectionRank || a.score - b.score || a.itemRank - b.itemRank || a.sourceIndex - b.sourceIndex || a.identity.localeCompare(b.identity);
40
+ };
41
+ var compareSearchResults = function compareSearchResults(a, b) {
42
+ return a.score - b.score || a.sectionRank - b.sectionRank || a.itemRank - b.itemRank || a.sourceIndex - b.sourceIndex || a.identity.localeCompare(b.identity);
43
+ };
44
+ var comparePrioritizedSearchResults = function comparePrioritizedSearchResults(a, b) {
45
+ var _b$priorityGroup, _a$priorityGroup;
46
+ return ((_b$priorityGroup = b.priorityGroup) !== null && _b$priorityGroup !== void 0 ? _b$priorityGroup : 0) - ((_a$priorityGroup = a.priorityGroup) !== null && _a$priorityGroup !== void 0 ? _a$priorityGroup : 0) || compareSearchResults(a, b);
47
+ };
48
+ var getSearchResults = function getSearchResults(matches) {
49
+ var topMatches = Array.from(matches).sort(compareSearchResults).slice(0, SEARCH_TOP_MATCH_LIMIT);
50
+ var topMatchIdentities = new Set(topMatches.map(function (_ref) {
51
+ var identity = _ref.identity;
52
+ return identity;
53
+ }));
54
+ var tailMatches = matches.filter(function (_ref2) {
55
+ var identity = _ref2.identity;
56
+ return !topMatchIdentities.has(identity);
57
+ });
58
+ return [].concat((0, _toConsumableArray2.default)(topMatches), (0, _toConsumableArray2.default)(tailMatches)).map(function (_ref3) {
59
+ var item = _ref3.item;
60
+ return item;
61
+ });
62
+ };
63
+ var getRenderedMenuItems = function getRenderedMenuItems(section, childrenMap, surfaceContext) {
64
+ var _childrenMap$get;
65
+ return ((_childrenMap$get = childrenMap.get((0, _surfaceRenderer.getComponentIdentity)(section))) !== null && _childrenMap$get !== void 0 ? _childrenMap$get : []).filter(function (child) {
66
+ return child.type === 'menu-item' && (0, _surfaceRenderer.willComponentRender)(child, childrenMap, surfaceContext);
67
+ });
68
+ };
69
+ var buildBrowseSections = function buildBrowseSections(_ref4) {
70
+ var childrenMap = _ref4.childrenMap,
71
+ contentSections = _ref4.contentSections,
72
+ selectCategoryItems = _ref4.selectCategoryItems,
73
+ surfaceContext = _ref4.surfaceContext;
74
+ var sections = [];
75
+ var _iterator = _createForOfIteratorHelper(contentSections),
76
+ _step;
77
+ try {
78
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
79
+ var section = _step.value;
80
+ var children = getRenderedMenuItems(section, childrenMap, surfaceContext);
81
+ var overflowItems = children.filter(function (child) {
82
+ return (0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(child.key);
83
+ });
84
+ var viewMoreItem = overflowItems[overflowItems.length - 1];
85
+ var items = children.filter(function (child) {
86
+ return !(0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(child.key);
87
+ });
88
+ if (items.length === 0) {
89
+ continue;
90
+ }
91
+ var selectedItems = viewMoreItem !== undefined && selectCategoryItems !== undefined ? selectCategoryItems(items) : items;
92
+ if (selectedItems.length < items.length && viewMoreItem !== undefined) {
93
+ sections.push([section].concat((0, _toConsumableArray2.default)(selectedItems), [viewMoreItem]));
94
+ } else {
95
+ sections.push([section].concat((0, _toConsumableArray2.default)(selectedItems)));
96
+ }
97
+ }
98
+ } catch (err) {
99
+ _iterator.e(err);
100
+ } finally {
101
+ _iterator.f();
102
+ }
103
+ return {
104
+ fallbackItems: [],
105
+ sections: sections
106
+ };
107
+ };
108
+ var buildSearchSections = function buildSearchSections(_ref5) {
109
+ var childrenMap = _ref5.childrenMap,
110
+ components = _ref5.components,
111
+ contentSections = _ref5.contentSections,
112
+ formatMessage = _ref5.formatMessage,
113
+ query = _ref5.query,
114
+ root = _ref5.root,
115
+ surfaceContext = _ref5.surfaceContext;
116
+ var matches = new Map();
117
+ var sourceIndexByComponent = new Map(components.map(function (component, index) {
118
+ return [component, index];
119
+ }));
120
+ var _iterator2 = _createForOfIteratorHelper(contentSections),
121
+ _step2;
122
+ try {
123
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
124
+ var section = _step2.value;
125
+ var _iterator3 = _createForOfIteratorHelper(getRenderedMenuItems(section, childrenMap, surfaceContext)),
126
+ _step3;
127
+ try {
128
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
129
+ var _item$match, _match$score, _sourceIndexByCompone;
130
+ var item = _step3.value;
131
+ if ((0, _typeAheadIsSectionOverflowItemKey.isSectionOverflowItemKey)(item.key)) {
132
+ continue;
133
+ }
134
+ var match = (_item$match = item.match) === null || _item$match === void 0 ? void 0 : _item$match.call(item, {
135
+ formatMessage: formatMessage,
136
+ itemKey: item.key,
137
+ query: query
138
+ });
139
+ if (item.match && match === null) {
140
+ continue;
141
+ }
142
+ var candidate = {
143
+ identity: "".concat(item.type, ":").concat(item.key),
144
+ item: item,
145
+ itemRank: getParentRank(item, section.key),
146
+ priorityGroup: (match === null || match === void 0 ? void 0 : match.priorityGroup) !== undefined && Number.isFinite(match.priorityGroup) ? match.priorityGroup : undefined,
147
+ 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)),
148
+ sourceIndex: (_sourceIndexByCompone = sourceIndexByComponent.get(item)) !== null && _sourceIndexByCompone !== void 0 ? _sourceIndexByCompone : Number.MAX_SAFE_INTEGER,
149
+ sectionRank: getParentRank(section, root.key)
150
+ };
151
+ var existing = matches.get(candidate.identity);
152
+ if (!existing || compareMatchedItems(candidate, existing) < 0) {
153
+ matches.set(candidate.identity, candidate);
154
+ }
155
+ }
156
+ } catch (err) {
157
+ _iterator3.e(err);
158
+ } finally {
159
+ _iterator3.f();
160
+ }
161
+ }
162
+ } catch (err) {
163
+ _iterator2.e(err);
164
+ } finally {
165
+ _iterator2.f();
166
+ }
167
+ var uniqueMatches = Array.from(matches.values()).sort(compareMatchedItems);
168
+ var prioritizedMatches = uniqueMatches.filter(function (_ref6) {
169
+ var priorityGroup = _ref6.priorityGroup;
170
+ return priorityGroup !== undefined;
171
+ });
172
+ var unprioritizedMatches = uniqueMatches.filter(function (_ref7) {
173
+ var priorityGroup = _ref7.priorityGroup;
174
+ return priorityGroup === undefined;
175
+ });
176
+ var orderedSearchResults = [].concat((0, _toConsumableArray2.default)(prioritizedMatches.sort(comparePrioritizedSearchResults).map(function (_ref8) {
177
+ var item = _ref8.item;
178
+ return item;
179
+ })), (0, _toConsumableArray2.default)(getSearchResults(unprioritizedMatches)));
180
+ if (orderedSearchResults.length > 0) {
181
+ return {
182
+ fallbackItems: [],
183
+ sections: [[SEARCH_RESULTS_HEADING].concat((0, _toConsumableArray2.default)(orderedSearchResults))]
184
+ };
185
+ }
186
+ var fallbackItem = contentSections.flatMap(function (section) {
187
+ var _childrenMap$get2;
188
+ return (_childrenMap$get2 = childrenMap.get((0, _surfaceRenderer.getComponentIdentity)(section))) !== null && _childrenMap$get2 !== void 0 ? _childrenMap$get2 : [];
189
+ }).find(function (component) {
190
+ return component.type === _keys.ASK_ROVO_MENU_ITEM.type && component.key === _keys.ASK_ROVO_MENU_ITEM.key && (0, _surfaceRenderer.willComponentRender)(component, childrenMap, surfaceContext);
191
+ });
192
+ return {
193
+ fallbackItems: fallbackItem ? [fallbackItem] : [],
194
+ sections: []
195
+ };
196
+ };
197
+
198
+ /**
199
+ * Builds the registered quick-insert menu model. An empty query browses every
200
+ * category; a non-empty query returns ranked matches. The footer is shared by both.
201
+ */
202
+ var getQuickInsertMenuModel = exports.getQuickInsertMenuModel = function getQuickInsertMenuModel(_ref9) {
203
+ var components = _ref9.components,
204
+ formatMessage = _ref9.formatMessage,
205
+ getItemRank = _ref9.getItemRank,
206
+ query = _ref9.query,
207
+ rootComponent = _ref9.rootComponent,
208
+ selectCategoryItems = _ref9.selectCategoryItems,
209
+ surfaceContext = _ref9.surfaceContext;
210
+ var rankedComponents = (0, _itemRank.applyRegisteredItemRanks)(components, getItemRank);
211
+ var _resolveSurface = (0, _surfaceRenderer.resolveSurface)(rankedComponents, rootComponent),
212
+ childrenMap = _resolveSurface.childrenMap,
213
+ root = _resolveSurface.root,
214
+ _resolveSurface$topLe = _resolveSurface.topLevelChildren,
215
+ topLevelChildren = _resolveSurface$topLe === void 0 ? [] : _resolveSurface$topLe;
216
+ if (!root || !(0, _surfaceRenderer.willComponentRender)(root, childrenMap, surfaceContext)) {
217
+ return {
218
+ fallbackItems: [],
219
+ footer: undefined,
220
+ root: undefined,
221
+ sections: []
222
+ };
223
+ }
224
+ var renderedSections = topLevelChildren.filter(function (section) {
225
+ return section.type === 'menu-section' && (0, _surfaceRenderer.willComponentRender)(section, childrenMap, surfaceContext);
226
+ });
227
+ var footerSection = renderedSections.find(function (_ref0) {
228
+ var key = _ref0.key;
229
+ return (0, _typeAheadIsMenuFooterSectionKey.isMenuFooterSectionKey)(key);
230
+ });
231
+ var contentSections = renderedSections.filter(function (_ref1) {
232
+ var key = _ref1.key;
233
+ return !(0, _typeAheadIsMenuFooterSectionKey.isMenuFooterSectionKey)(key);
234
+ });
235
+ var content = query === '' ? buildBrowseSections({
236
+ childrenMap: childrenMap,
237
+ contentSections: contentSections,
238
+ selectCategoryItems: selectCategoryItems,
239
+ surfaceContext: surfaceContext
240
+ }) : buildSearchSections({
241
+ childrenMap: childrenMap,
242
+ components: rankedComponents,
243
+ contentSections: contentSections,
244
+ formatMessage: formatMessage,
245
+ query: query,
246
+ root: root,
247
+ surfaceContext: surfaceContext
248
+ });
249
+ var footer = footerSection ? getRenderedMenuItems(footerSection, childrenMap, surfaceContext)[0] : undefined;
250
+ return _objectSpread(_objectSpread({}, content), {}, {
251
+ footer: footer,
252
+ root: root
253
+ });
254
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getQuickInsertMenuItemId = void 0;
7
+ var getQuickInsertMenuItemId = exports.getQuickInsertMenuItemId = function getQuickInsertMenuItemId(listId, itemIndex) {
8
+ return "".concat(listId, "-").concat(itemIndex);
9
+ };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.selectQuickInsertCategoryItems = void 0;
7
+ var _getProviderMenuItemKey = require("@atlaskit/editor-common/quick-insert/get-provider-menu-item-key");
8
+ var DEFAULT_ITEM_LIMIT = 30;
9
+ var ECOSYSTEM_ITEM_LIMIT = 10;
10
+ var isEcosystemQuickInsertItem = function isEcosystemQuickInsertItem(item) {
11
+ return _getProviderMenuItemKey.quickInsertProviderMenuItemKey.isEcosystem(item.key);
12
+ };
13
+
14
+ /**
15
+ * Keeps the initial native and ecosystem results while ensuring ecosystem registrations
16
+ * remain discoverable beyond the default category item limit.
17
+ */
18
+ var selectQuickInsertCategoryItems = exports.selectQuickInsertCategoryItems = function selectQuickInsertCategoryItems(items) {
19
+ var ecosystemItemCount = 0;
20
+ return items.filter(function (item, index) {
21
+ var isEcosystemItem = isEcosystemQuickInsertItem(item);
22
+ if (isEcosystemItem) {
23
+ ecosystemItemCount++;
24
+ }
25
+ return index < DEFAULT_ITEM_LIMIT || isEcosystemItem && ecosystemItemCount <= ECOSYSTEM_ITEM_LIMIT;
26
+ });
27
+ };
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useQuickInsertSearchAnalytics = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _react = require("react");
10
+ var _enums = require("@atlaskit/editor-common/analytics/types/enums");
11
+ 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; }
12
+ 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; }
13
+ var SEARCH_DEBOUNCE_MS = 1000;
14
+ var useQuickInsertSearchAnalytics = exports.useQuickInsertSearchAnalytics = function useQuickInsertSearchAnalytics(_ref) {
15
+ var query = _ref.query,
16
+ resultCount = _ref.resultCount,
17
+ surface = _ref.surface,
18
+ category = _ref.category,
19
+ _ref$isOpen = _ref.isOpen,
20
+ isOpen = _ref$isOpen === void 0 ? true : _ref$isOpen,
21
+ fireAnalyticsEvent = _ref.fireAnalyticsEvent;
22
+ var latestOptions = (0, _react.useRef)({
23
+ query: query,
24
+ resultCount: resultCount,
25
+ surface: surface,
26
+ category: category,
27
+ fireAnalyticsEvent: fireAnalyticsEvent
28
+ });
29
+ latestOptions.current = {
30
+ query: query,
31
+ resultCount: resultCount,
32
+ surface: surface,
33
+ category: category,
34
+ fireAnalyticsEvent: fireAnalyticsEvent
35
+ };
36
+ var pendingSearch = (0, _react.useRef)(null);
37
+ var effectVersion = (0, _react.useRef)(0);
38
+ var flush = (0, _react.useCallback)(function () {
39
+ var pending = pendingSearch.current;
40
+ if (!pending) {
41
+ return;
42
+ }
43
+ clearTimeout(pending.timer);
44
+ pendingSearch.current = null;
45
+ var current = latestOptions.current;
46
+ if (current.query.trim() !== pending.query || !current.fireAnalyticsEvent) {
47
+ return;
48
+ }
49
+ var attributes = _objectSpread(_objectSpread({}, current.surface === 'element-browser' && current.category !== undefined ? {
50
+ category: current.category
51
+ } : {}), {}, {
52
+ isEmpty: current.resultCount === 0,
53
+ queryLength: current.query.trim().length,
54
+ resultCount: current.resultCount,
55
+ surface: current.surface
56
+ });
57
+ var payload = {
58
+ action: _enums.ACTION.SEARCHED,
59
+ actionSubject: _enums.ACTION_SUBJECT.QUICK_INSERT,
60
+ eventType: _enums.EVENT_TYPE.TRACK,
61
+ attributes: attributes
62
+ };
63
+ current.fireAnalyticsEvent(payload);
64
+ }, []);
65
+ (0, _react.useEffect)(function () {
66
+ var currentVersion = ++effectVersion.current;
67
+ if (!isOpen) {
68
+ flush();
69
+ return;
70
+ }
71
+ var trimmedQuery = query.trim();
72
+ if (!trimmedQuery) {
73
+ if (pendingSearch.current) {
74
+ clearTimeout(pendingSearch.current.timer);
75
+ pendingSearch.current = null;
76
+ }
77
+ return;
78
+ }
79
+ if (pendingSearch.current) {
80
+ clearTimeout(pendingSearch.current.timer);
81
+ }
82
+ var timer = setTimeout(flush, SEARCH_DEBOUNCE_MS);
83
+ pendingSearch.current = {
84
+ query: trimmedQuery,
85
+ timer: timer
86
+ };
87
+ return function () {
88
+ if (pendingSearch.current) {
89
+ clearTimeout(pendingSearch.current.timer);
90
+ }
91
+ Promise.resolve().then(function () {
92
+ // oxlint-disable-next-line react-hooks/exhaustive-deps -- The live effect version distinguishes dependency cleanup from a real unmount.
93
+ if (effectVersion.current === currentVersion) {
94
+ flush();
95
+ }
96
+ });
97
+ };
98
+ }, [query, surface, category, isOpen, flush]);
99
+ return flush;
100
+ };
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { useIntl } from 'react-intl';
3
3
  import { isSSR } from '@atlaskit/editor-common/is-ssr';
4
4
  import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages/insert-block';
5
+ import { MENU } from '@atlaskit/editor-common/quick-insert/keys';
5
6
  import { createQuickInsertRankResolver } from '@atlaskit/editor-common/quick-insert/quick-insert-rank';
6
7
  import { memoProcessQuickInsertItems } from '@atlaskit/editor-common/quick-insert/utils';
7
8
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
@@ -32,6 +33,7 @@ export const quickInsertPlugin = ({
32
33
  const getItemRank = createQuickInsertRankResolver(options === null || options === void 0 ? void 0 : options.getItemRank);
33
34
  const typeAhead = {
34
35
  id: TypeAheadAvailableNodes.QUICK_INSERT,
36
+ registeredMenuKey: isExperimentEnabled('platform_editor_slash_command') ? MENU.key : undefined,
35
37
  getRegisteredItemRank: getItemRank,
36
38
  trigger: '/',
37
39
  // Support fullwidth slash (U+FF0F) used by Japanese/CJK keyboards (e.g. typing / on a Japanese keyboard layout)
@@ -73,12 +75,15 @@ export const quickInsertPlugin = ({
73
75
  } : undefined
74
76
  };
75
77
  if (isExperimentEnabled('platform_editor_slash_command')) {
76
- var _api$uiControlRegistr;
78
+ var _api$uiControlRegistr, _api$analytics;
77
79
  api === null || api === void 0 ? void 0 : (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.register(getQuickInsertComponents({
78
80
  api,
79
- includeElementBrowserItems: (options === null || options === void 0 ? void 0 : options.enableElementBrowser) === true,
81
+ getItemRank,
80
82
  isRecommendedItem: options === null || options === void 0 ? void 0 : options.isRecommendedItem,
81
- maxRecommendedItems: options === null || options === void 0 ? void 0 : options.maxRecommendedItems
83
+ maxRecommendedItems: options === null || options === void 0 ? void 0 : options.maxRecommendedItems,
84
+ emptyStateHandler: options === null || options === void 0 ? void 0 : options.emptyStateHandler,
85
+ fireAnalyticsEvent: api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.fireAnalyticsEvent,
86
+ includeElementBrowserItems: (options === null || options === void 0 ? void 0 : options.enableElementBrowser) === true
82
87
  }));
83
88
  }
84
89
  if (isExperimentEnabled('platform_editor_block_control_migration') && (options === null || options === void 0 ? void 0 : options.blockControlButtonEnabled) !== false) {
@@ -130,8 +135,8 @@ export const quickInsertPlugin = ({
130
135
  plugin: () => getQuickInsertOpenExperiencePlugin({
131
136
  refs,
132
137
  dispatchAnalyticsEvent: payload => {
133
- var _api$analytics, _api$analytics$action;
134
- return api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.fireAnalyticsEvent(payload);
138
+ var _api$analytics2, _api$analytics2$actio;
139
+ return api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : (_api$analytics2$actio = _api$analytics2.actions) === null || _api$analytics2$actio === void 0 ? void 0 : _api$analytics2$actio.fireAnalyticsEvent(payload);
135
140
  }
136
141
  })
137
142
  }];
@@ -1,13 +1,18 @@
1
1
  import React from 'react';
2
2
  import { useQuickInsertContext } from '@atlaskit/editor-common/quick-insert/use-quick-insert-context';
3
3
  export const QuickInsertRecommendedSlot = ({
4
+ children,
5
+ parents,
6
+ surfaceContext,
4
7
  index,
5
- getSnapshot,
6
- ...props
8
+ getSnapshot
7
9
  }) => {
8
10
  const {
9
- surfaceContext
11
+ surfaceContext: menuSurfaceContext
10
12
  } = useQuickInsertContext();
11
- const item = getSnapshot(surfaceContext)[index];
12
- return item !== null && item !== void 0 && item.component ? /*#__PURE__*/React.createElement(item.component, props) : null;
13
+ const item = getSnapshot(menuSurfaceContext)[index];
14
+ return item !== null && item !== void 0 && item.component ? /*#__PURE__*/React.createElement(item.component, {
15
+ parents: parents,
16
+ surfaceContext: surfaceContext
17
+ }, children) : null;
13
18
  };
@@ -7,7 +7,7 @@ import IconButton from '@atlaskit/button/icon/button';
7
7
  // eslint-disable-next-line @atlaskit/platform/no-barrel-entry-imports
8
8
  import { messages } from '@atlaskit/editor-common/quick-insert';
9
9
  import { MENU, RECOMMENDED_SECTION } from '@atlaskit/editor-common/quick-insert/keys';
10
- import { useQuickInsertSearchAnalytics } from '@atlaskit/editor-common/quick-insert/use-search-analytics';
10
+ import { createRegisteredMenuSurfaceContext } from '@atlaskit/editor-common/registered-menu/surface-context';
11
11
  import { getMenuFooterSectionKey } from '@atlaskit/editor-common/type-ahead-get-menu-footer-section-key';
12
12
  import { getSectionOverflowItemKey } from '@atlaskit/editor-common/type-ahead-get-section-overflow-item-key';
13
13
  import Heading from '@atlaskit/heading/heading';
@@ -20,6 +20,7 @@ import ModalTitle from '@atlaskit/modal-dialog/modal-title';
20
20
  import ModalTransition from '@atlaskit/modal-dialog/modal-transition';
21
21
  import { fg } from '@atlaskit/platform-feature-flags/fg';
22
22
  import Textfield from '@atlaskit/textfield/text-field';
23
+ import { useQuickInsertSearchAnalytics } from '../registered-menu/useQuickInsertSearchAnalytics';
23
24
  import { createRegistryElementBrowserModel, getInitialRegistryElementBrowserSection, getRegistryElementBrowserItems } from './model';
24
25
  import { RegistryElementBrowserCategories } from './RegistryElementBrowserCategories';
25
26
  import { RegistryElementBrowserFooter } from './RegistryElementBrowserFooter';
@@ -58,6 +59,20 @@ export const RegistryElementBrowser = ({
58
59
  const {
59
60
  formatMessage
60
61
  } = useIntl();
62
+ const [session, setSession] = useState(() => ({
63
+ isOpen,
64
+ menuOpenId: Symbol('element-browser')
65
+ }));
66
+ if (session.isOpen !== isOpen) {
67
+ setSession({
68
+ isOpen,
69
+ menuOpenId: isOpen ? Symbol('element-browser') : session.menuOpenId
70
+ });
71
+ }
72
+ const surfaceContext = useMemo(() => createRegisteredMenuSurfaceContext({
73
+ menuOpenId: session.menuOpenId,
74
+ surface: 'element-browser'
75
+ }), [session.menuOpenId]);
61
76
  const [browserState, setBrowserState] = useState({
62
77
  query: '',
63
78
  section: defaultSection
@@ -71,6 +86,7 @@ export const RegistryElementBrowser = ({
71
86
  const browserModel = useMemo(() => {
72
87
  const model = createRegistryElementBrowserModel(components, {
73
88
  footerKey: getMenuFooterSectionKey(MENU.key),
89
+ surfaceContext,
74
90
  overflowKeys: new Set(components.filter(component => component.type === 'menu-section').map(component => getSectionOverflowItemKey(component.key))),
75
91
  recommendedSectionKey: RECOMMENDED_SECTION.key,
76
92
  rootKey: MENU.key
@@ -88,7 +104,7 @@ export const RegistryElementBrowser = ({
88
104
  section: effectiveSection
89
105
  })
90
106
  };
91
- }, [components, formatMessage, query, section]);
107
+ }, [components, formatMessage, query, section, surfaceContext]);
92
108
  const {
93
109
  model,
94
110
  effectiveSection,
@@ -338,6 +354,7 @@ export const RegistryElementBrowser = ({
338
354
  fallbackItems: model.fallbackItems,
339
355
  query: query,
340
356
  resultsId: resultsId,
357
+ surfaceContext: surfaceContext,
341
358
  section: effectiveSection,
342
359
  selectedKey: selectedKey,
343
360
  onKeyDown: onKeyDown,
@@ -3,9 +3,8 @@ import "./RegistryElementBrowserSearchResults.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import React, { useMemo } from 'react';
5
5
  import { useIntl } from 'react-intl';
6
- import { QuickInsertEmptyState } from '@atlaskit/editor-common/quick-insert/empty-state';
7
6
  import { QuickInsertProvider } from '@atlaskit/editor-common/quick-insert/provider';
8
-
7
+ import { QuickInsertEmptyState } from '../registered-menu/QuickInsertEmptyState';
9
8
  // oxlint-disable-next-line eslint/no-redeclare
10
9
 
11
10
  const resultsGridStyles = null;
@@ -18,7 +17,8 @@ const RegistryElementBrowserItem = ({
18
17
  isOffline,
19
18
  isSelected,
20
19
  item,
21
- onSelect
20
+ onSelect,
21
+ surfaceContext
22
22
  }) => {
23
23
  const {
24
24
  component: Component,
@@ -33,14 +33,17 @@ const RegistryElementBrowserItem = ({
33
33
  isSelected
34
34
  },
35
35
  select: handler => onSelect(key, handler),
36
- surface: 'element-browser'
37
- }), [editorView, isOffline, isSelected, item.description, key, onSelect]);
36
+ surfaceContext
37
+ }), [editorView, isOffline, isSelected, item.description, key, onSelect, surfaceContext]);
38
38
  if (!Component) {
39
39
  return null;
40
40
  }
41
41
  return /*#__PURE__*/React.createElement(QuickInsertProvider, {
42
42
  value: contextValue
43
- }, /*#__PURE__*/React.createElement(Component, undefined, null));
43
+ }, /*#__PURE__*/React.createElement(Component, {
44
+ parents: item.registration.parents,
45
+ surfaceContext: surfaceContext
46
+ }, null));
44
47
  };
45
48
  export const RegistryElementBrowserSearchResults = ({
46
49
  editorView,
@@ -53,6 +56,7 @@ export const RegistryElementBrowserSearchResults = ({
53
56
  resultsId,
54
57
  section,
55
58
  selectedKey,
59
+ surfaceContext,
56
60
  onKeyDown,
57
61
  onSelect
58
62
  }) => {
@@ -94,7 +98,8 @@ export const RegistryElementBrowserSearchResults = ({
94
98
  isSelected: selectedKey === item.registration.key,
95
99
  item: item,
96
100
  key: item.registration.key,
97
- onSelect: onSelect
101
+ onSelect: onSelect,
102
+ surfaceContext: surfaceContext
98
103
  }))), shouldRenderEmptyState && !hasFallbackItems && query.trim().length > 0 && /*#__PURE__*/React.createElement(QuickInsertEmptyState, {
99
104
  mode: "full"
100
105
  }), emptyState && /*#__PURE__*/React.createElement("div", {