@atlaskit/editor-plugin-type-ahead 13.2.1 → 13.2.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 (69) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/pm-plugins/commands/insert-type-ahead-item.js +96 -1
  3. package/dist/cjs/ui/ContentComponent.js +4 -0
  4. package/dist/cjs/ui/InputQuery.js +21 -14
  5. package/dist/cjs/ui/WrapperTypeAhead.js +23 -1
  6. package/dist/cjs/ui/hooks/use-load-items.js +6 -1
  7. package/dist/cjs/ui/registered-menu/PassThrough.js +10 -0
  8. package/dist/cjs/ui/registered-menu/RegisteredTypeAheadMenu.js +146 -0
  9. package/dist/cjs/ui/registered-menu/TypeAheadContext.js +8 -0
  10. package/dist/cjs/ui/registered-menu/TypeAheadItemRow.js +27 -0
  11. package/dist/cjs/ui/registered-menu/TypeAheadProvider.js +8 -0
  12. package/dist/cjs/ui/registered-menu/buildTypeAheadMenuModel.js +50 -0
  13. package/dist/cjs/ui/registered-menu/getTypeAheadItemId.js +9 -0
  14. package/dist/cjs/ui/registered-menu/quick-insert/TypeAheadQuickInsertItem.js +37 -0
  15. package/dist/cjs/ui/registered-menu/quick-insert/TypeAheadQuickInsertProvider.js +41 -0
  16. package/dist/cjs/ui/registered-menu/typeAheadMenuTypes.js +5 -0
  17. package/dist/cjs/ui/registered-menu/typeAheadSurfaces.js +26 -0
  18. package/dist/cjs/ui/registered-menu/useTypeAheadContext.js +15 -0
  19. package/dist/es2019/pm-plugins/commands/insert-type-ahead-item.js +97 -0
  20. package/dist/es2019/ui/ContentComponent.js +4 -0
  21. package/dist/es2019/ui/InputQuery.js +15 -8
  22. package/dist/es2019/ui/WrapperTypeAhead.js +23 -1
  23. package/dist/es2019/ui/hooks/use-load-items.js +6 -2
  24. package/dist/es2019/ui/registered-menu/PassThrough.js +3 -0
  25. package/dist/es2019/ui/registered-menu/RegisteredTypeAheadMenu.js +127 -0
  26. package/dist/es2019/ui/registered-menu/TypeAheadContext.js +2 -0
  27. package/dist/es2019/ui/registered-menu/TypeAheadItemRow.js +18 -0
  28. package/dist/es2019/ui/registered-menu/TypeAheadProvider.js +2 -0
  29. package/dist/es2019/ui/registered-menu/buildTypeAheadMenuModel.js +24 -0
  30. package/dist/es2019/ui/registered-menu/getTypeAheadItemId.js +1 -0
  31. package/dist/es2019/ui/registered-menu/quick-insert/TypeAheadQuickInsertItem.js +25 -0
  32. package/dist/es2019/ui/registered-menu/quick-insert/TypeAheadQuickInsertProvider.js +33 -0
  33. package/dist/es2019/ui/registered-menu/typeAheadMenuTypes.js +1 -0
  34. package/dist/es2019/ui/registered-menu/typeAheadSurfaces.js +20 -0
  35. package/dist/es2019/ui/registered-menu/useTypeAheadContext.js +9 -0
  36. package/dist/esm/pm-plugins/commands/insert-type-ahead-item.js +95 -0
  37. package/dist/esm/ui/ContentComponent.js +4 -0
  38. package/dist/esm/ui/InputQuery.js +21 -14
  39. package/dist/esm/ui/WrapperTypeAhead.js +23 -1
  40. package/dist/esm/ui/hooks/use-load-items.js +6 -1
  41. package/dist/esm/ui/registered-menu/PassThrough.js +4 -0
  42. package/dist/esm/ui/registered-menu/RegisteredTypeAheadMenu.js +137 -0
  43. package/dist/esm/ui/registered-menu/TypeAheadContext.js +2 -0
  44. package/dist/esm/ui/registered-menu/TypeAheadItemRow.js +19 -0
  45. package/dist/esm/ui/registered-menu/TypeAheadProvider.js +2 -0
  46. package/dist/esm/ui/registered-menu/buildTypeAheadMenuModel.js +44 -0
  47. package/dist/esm/ui/registered-menu/getTypeAheadItemId.js +3 -0
  48. package/dist/esm/ui/registered-menu/quick-insert/TypeAheadQuickInsertItem.js +28 -0
  49. package/dist/esm/ui/registered-menu/quick-insert/TypeAheadQuickInsertProvider.js +33 -0
  50. package/dist/esm/ui/registered-menu/typeAheadMenuTypes.js +1 -0
  51. package/dist/esm/ui/registered-menu/typeAheadSurfaces.js +20 -0
  52. package/dist/esm/ui/registered-menu/useTypeAheadContext.js +9 -0
  53. package/dist/types/pm-plugins/commands/insert-type-ahead-item.d.ts +7 -0
  54. package/dist/types/typeAheadPluginType.d.ts +3 -1
  55. package/dist/types/ui/InputQuery.d.ts +10 -2
  56. package/dist/types/ui/hooks/use-load-items.d.ts +1 -1
  57. package/dist/types/ui/registered-menu/PassThrough.d.ts +2 -0
  58. package/dist/types/ui/registered-menu/RegisteredTypeAheadMenu.d.ts +30 -0
  59. package/dist/types/ui/registered-menu/TypeAheadContext.d.ts +14 -0
  60. package/dist/types/ui/registered-menu/TypeAheadItemRow.d.ts +11 -0
  61. package/dist/types/ui/registered-menu/TypeAheadProvider.d.ts +3 -0
  62. package/dist/types/ui/registered-menu/buildTypeAheadMenuModel.d.ts +7 -0
  63. package/dist/types/ui/registered-menu/getTypeAheadItemId.d.ts +1 -0
  64. package/dist/types/ui/registered-menu/quick-insert/TypeAheadQuickInsertItem.d.ts +3 -0
  65. package/dist/types/ui/registered-menu/quick-insert/TypeAheadQuickInsertProvider.d.ts +2 -0
  66. package/dist/types/ui/registered-menu/typeAheadMenuTypes.d.ts +9 -0
  67. package/dist/types/ui/registered-menu/typeAheadSurfaces.d.ts +17 -0
  68. package/dist/types/ui/registered-menu/useTypeAheadContext.d.ts +2 -0
  69. package/package.json +8 -4
@@ -195,4 +195,99 @@ export var insertTypeAheadItem = function insertTypeAheadItem(view) {
195
195
  view.dispatch(tr);
196
196
  view.focus();
197
197
  };
198
+ };
199
+ var executeTypeAheadSelection = function executeTypeAheadSelection(view) {
200
+ return function (_ref5) {
201
+ var selectItem = _ref5.selectItem,
202
+ handler = _ref5.handler,
203
+ mode = _ref5.mode,
204
+ query = _ref5.query,
205
+ sourceListItem = _ref5.sourceListItem;
206
+ var pluginState = getPluginState(view.state);
207
+ if (!pluginState) {
208
+ return;
209
+ }
210
+ var stats = (pluginState.stats || new StatsModifier()).serialize();
211
+ var meta = {
212
+ mode: mode,
213
+ query: query,
214
+ stats: stats,
215
+ sourceListItem: sourceListItem
216
+ };
217
+ var tr = view.state.tr;
218
+ var trigger = handler.trigger;
219
+ var text = "".concat(trigger).concat(query);
220
+ if (mode === SelectItemMode.SPACE) {
221
+ text = text.trim().concat(' ');
222
+ }
223
+ var selectedIndex = -1;
224
+ var wasInsertedBySpace = mode === SelectItemMode.SPACE;
225
+ var textStartPosition = tr.selection.from;
226
+ var insertItem = function insertItem(newEditorState) {
227
+ var insertCallback = createInsertCallback({
228
+ editorState: newEditorState,
229
+ query: query,
230
+ mode: mode,
231
+ handler: handler,
232
+ wasInsertedBySpace: wasInsertedBySpace,
233
+ selectedIndex: selectedIndex,
234
+ textInserted: text,
235
+ textStartPosition: textStartPosition
236
+ });
237
+ var wasInsertCallbackCalled = false;
238
+ var insertCallbackProxy = new Proxy(insertCallback, {
239
+ apply: function apply(target, _thisContext, argumentsList) {
240
+ wasInsertCallbackCalled = true;
241
+ return target.apply(void 0, _toConsumableArray(argumentsList));
242
+ }
243
+ });
244
+ var nextTr = selectItem(newEditorState, insertCallbackProxy, meta);
245
+ if (!wasInsertCallbackCalled && nextTr) {
246
+ closeHistory(nextTr);
247
+ if (!nextTr.getMeta(pluginKey)) {
248
+ closeTypeAhead(nextTr);
249
+ }
250
+ }
251
+ return nextTr || false;
252
+ };
253
+ var position = {
254
+ start: tr.selection.from,
255
+ end: tr.selection.from + text.length
256
+ };
257
+ tr.setMeta(pluginKey, {
258
+ action: ACTIONS.INSERT_RAW_QUERY,
259
+ params: createDeleteRawTextCallback({
260
+ wasInsertedBySpace: wasInsertedBySpace,
261
+ selectedIndex: selectedIndex,
262
+ insertItem: insertItem,
263
+ position: position,
264
+ query: query,
265
+ trigger: trigger
266
+ })
267
+ });
268
+ tr.insertText(text);
269
+ closeHistory(tr);
270
+ view.dispatch(tr);
271
+ view.focus();
272
+ };
273
+ };
274
+ export var performTypeAheadSelection = function performTypeAheadSelection(view) {
275
+ return function (_ref6) {
276
+ var inputMethod = _ref6.inputMethod,
277
+ selectionHandler = _ref6.selectionHandler,
278
+ handler = _ref6.handler,
279
+ query = _ref6.query;
280
+ executeTypeAheadSelection(view)({
281
+ handler: handler,
282
+ mode: SelectItemMode.SELECTED,
283
+ query: query,
284
+ sourceListItem: [],
285
+ selectItem: function selectItem(_state, insert) {
286
+ return selectionHandler({
287
+ insert: insert,
288
+ source: inputMethod
289
+ });
290
+ }
291
+ });
292
+ };
198
293
  };
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
3
+ import { getTypeAheadSurface } from './registered-menu/typeAheadSurfaces';
3
4
  import { TypeAheadMenu } from './TypeAheadMenu';
4
5
  export function ContentComponent(_ref) {
5
6
  var api = _ref.api,
@@ -29,6 +30,9 @@ export function ContentComponent(_ref) {
29
30
  if (items === undefined || sections === undefined || decorationSet === undefined || errorInfo === undefined || decorationElement === undefined || query === undefined || selectedIndex === undefined) {
30
31
  return null;
31
32
  }
33
+ if (getTypeAheadSurface(triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.id)) {
34
+ return null;
35
+ }
32
36
  return /*#__PURE__*/React.createElement(TypeAheadMenu, {
33
37
  editorView: editorView,
34
38
  popupMountRef: popupMountRef
@@ -82,7 +82,9 @@ var getAriaLabel = function getAriaLabel(triggerPrefix, _intl) {
82
82
  }
83
83
  };
84
84
  export var InputQuery = /*#__PURE__*/React.memo(function (_ref) {
85
- var triggerQueryPrefix = _ref.triggerQueryPrefix,
85
+ var _ref2;
86
+ var activeDescendantId = _ref.activeDescendantId,
87
+ triggerQueryPrefix = _ref.triggerQueryPrefix,
86
88
  cancel = _ref.cancel,
87
89
  onQueryChange = _ref.onQueryChange,
88
90
  onItemSelect = _ref.onItemSelect,
@@ -93,7 +95,11 @@ export var InputQuery = /*#__PURE__*/React.memo(function (_ref) {
93
95
  onQueryFocus = _ref.onQueryFocus,
94
96
  onUndoRedo = _ref.onUndoRedo,
95
97
  editorView = _ref.editorView,
96
- items = _ref.items;
98
+ items = _ref.items,
99
+ listId = _ref.listId,
100
+ optionCount = _ref.optionCount,
101
+ shouldKeepOpenOnRegisteredMenu = _ref.shouldKeepOpenOnRegisteredMenu;
102
+ var resolvedOptionCount = (_ref2 = optionCount !== null && optionCount !== void 0 ? optionCount : items === null || items === void 0 ? void 0 : items.length) !== null && _ref2 !== void 0 ? _ref2 : 0;
97
103
  var ref = useRef(document.createElement('span'));
98
104
  var inputRef = useRef(null);
99
105
  var _useState = useState(null),
@@ -136,9 +142,9 @@ export var InputQuery = /*#__PURE__*/React.memo(function (_ref) {
136
142
  var raw = ((_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.textContent) || '';
137
143
  var text = cleanedInputContent();
138
144
  var stopDefault = false;
139
- var _ref2 = getPluginState(editorView.state) || {},
140
- selectedIndex = _ref2.selectedIndex,
141
- removePrefixTriggerOnCancel = _ref2.removePrefixTriggerOnCancel;
145
+ var _ref3 = getPluginState(editorView.state) || {},
146
+ selectedIndex = _ref3.selectedIndex,
147
+ removePrefixTriggerOnCancel = _ref3.removePrefixTriggerOnCancel;
142
148
  setInFocus(true);
143
149
  switch (key) {
144
150
  case ' ':
@@ -225,8 +231,8 @@ export var InputQuery = /*#__PURE__*/React.memo(function (_ref) {
225
231
  }
226
232
  var browser = getBrowserInfo();
227
233
  var element = ref.current;
228
- var _ref3 = getPluginState(editorView.state) || {},
229
- removePrefixTriggerOnCancel = _ref3.removePrefixTriggerOnCancel;
234
+ var _ref4 = getPluginState(editorView.state) || {},
235
+ removePrefixTriggerOnCancel = _ref4.removePrefixTriggerOnCancel;
230
236
  var onFocusIn = function onFocusIn(_event) {
231
237
  onQueryFocus();
232
238
  };
@@ -279,7 +285,7 @@ export var InputQuery = /*#__PURE__*/React.memo(function (_ref) {
279
285
  // Given the user is changing the focus
280
286
  // When the target is inside the TypeAhead Popup
281
287
  // Then the popup should stay open
282
- if (relatedTarget instanceof HTMLElement && relatedTarget.closest && relatedTarget.closest(".".concat(TYPE_AHEAD_POPUP_CONTENT_CLASS))) {
288
+ if (relatedTarget instanceof HTMLElement && relatedTarget.closest && (relatedTarget.closest(".".concat(TYPE_AHEAD_POPUP_CONTENT_CLASS)) || shouldKeepOpenOnRegisteredMenu && relatedTarget.closest('[data-registered-type-ahead-menu]'))) {
283
289
  return;
284
290
  }
285
291
 
@@ -398,7 +404,7 @@ export var InputQuery = /*#__PURE__*/React.memo(function (_ref) {
398
404
  element.removeEventListener('input', onInput);
399
405
  }
400
406
  };
401
- }, [triggerQueryPrefix, cleanedInputContent, onQueryFocus, cancel, checkKeyEvent, editorView.state, isEditorControlsEnabled]);
407
+ }, [triggerQueryPrefix, cleanedInputContent, onQueryFocus, cancel, checkKeyEvent, editorView.state, isEditorControlsEnabled, shouldKeepOpenOnRegisteredMenu]);
402
408
  useLayoutEffect(function () {
403
409
  var hasReopenQuery = typeof reopenQuery === 'string' && reopenQuery.trim().length > 0;
404
410
  if (ref.current && forceFocus) {
@@ -447,9 +453,10 @@ export var InputQuery = /*#__PURE__*/React.memo(function (_ref) {
447
453
  tabIndex: -1,
448
454
  onInput: isSearchPlaceholderEnabled ? onInput : undefined,
449
455
  role: "combobox",
450
- "aria-controls": TYPE_AHEAD_DECORATION_ELEMENT_ID,
456
+ "aria-activedescendant": activeDescendantId,
457
+ "aria-controls": listId !== null && listId !== void 0 ? listId : TYPE_AHEAD_DECORATION_ELEMENT_ID,
451
458
  "aria-autocomplete": "list",
452
- "aria-expanded": items.length !== 0,
459
+ "aria-expanded": resolvedOptionCount !== 0,
453
460
  "aria-labelledby": assistiveHintID,
454
461
  suppressContentEditableWarning: true,
455
462
  "data-query-prefix": triggerQueryPrefix
@@ -467,10 +474,10 @@ export var InputQuery = /*#__PURE__*/React.memo(function (_ref) {
467
474
  display: 'none'
468
475
  }
469
476
  }, intl.formatMessage(typeAheadListMessages.inputQueryAssistiveLabel)), jsx(AssistiveText, {
470
- assistiveText: items.length === 0 ? intl.formatMessage(typeAheadListMessages.noSearchResultsLabel, {
471
- itemsLength: items.length
477
+ assistiveText: resolvedOptionCount === 0 ? intl.formatMessage(typeAheadListMessages.noSearchResultsLabel, {
478
+ itemsLength: resolvedOptionCount
472
479
  }) : '',
473
- isInFocus: items.length === 0 || isInFocus,
480
+ isInFocus: resolvedOptionCount === 0 || isInFocus,
474
481
  id: TYPE_AHEAD_DECORATION_ELEMENT_ID
475
482
  }));
476
483
  });
@@ -14,6 +14,8 @@ import { useItemInsert } from './hooks/use-item-insert';
14
14
  import { useLoadItems } from './hooks/use-load-items';
15
15
  import { useOnForceSelect } from './hooks/use-on-force-select';
16
16
  import { InputQuery } from './InputQuery';
17
+ import { RegisteredTypeAheadMenu } from './registered-menu/RegisteredTypeAheadMenu';
18
+ import { getTypeAheadSurface } from './registered-menu/typeAheadSurfaces';
17
19
  export var WrapperTypeAhead = /*#__PURE__*/React.memo(function (_ref) {
18
20
  var triggerHandler = _ref.triggerHandler,
19
21
  editorView = _ref.editorView,
@@ -44,7 +46,8 @@ export var WrapperTypeAhead = /*#__PURE__*/React.memo(function (_ref) {
44
46
  setQuery = _useState4[1];
45
47
  var queryRef = useRef(query);
46
48
  var editorViewRef = useRef(editorView);
47
- var items = useLoadItems(triggerHandler, editorView, query, showMoreOptionsButton, api, intl);
49
+ var registeredSurface = getTypeAheadSurface(triggerHandler.id);
50
+ var items = useLoadItems(triggerHandler, editorView, query, showMoreOptionsButton, api, intl, !registeredSurface);
48
51
  useEffect(function () {
49
52
  if (!closed && fg('platform_editor_ease_of_use_metrics')) {
50
53
  var _api$metrics;
@@ -151,6 +154,25 @@ export var WrapperTypeAhead = /*#__PURE__*/React.memo(function (_ref) {
151
154
  if (!triggerHandler) {
152
155
  return null;
153
156
  }
157
+ if (registeredSurface) {
158
+ return /*#__PURE__*/React.createElement(RegisteredTypeAheadMenu, {
159
+ anchorElement: anchorElement,
160
+ api: api,
161
+ cancel: cancel,
162
+ editorView: editorView,
163
+ forceFocus: shouldFocusCursorInsideQuery,
164
+ onClose: closePopup,
165
+ onUndoRedo: onUndoRedo,
166
+ popupsBoundariesElement: popupsBoundariesElement,
167
+ popupsMountPoint: popupsMountPoint,
168
+ popupsScrollableElement: popupsScrollableElement,
169
+ query: query,
170
+ reopenQuery: reopenQuery,
171
+ setQuery: setQuery,
172
+ surface: registeredSurface,
173
+ triggerHandler: triggerHandler
174
+ });
175
+ }
154
176
  return /*#__PURE__*/React.createElement(InputQuery, {
155
177
  triggerQueryPrefix: triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.trigger,
156
178
  onQueryChange: setQuery,
@@ -8,6 +8,7 @@ import { updateListItem } from '../../pm-plugins/commands/update-list-items';
8
8
  import { buildSectionedResult } from './build-sectioned-result';
9
9
  var EMPTY_LIST_ITEM = [];
10
10
  export var useLoadItems = function useLoadItems(triggerHandler, editorView, query, showViewMore, api, intl) {
11
+ var enabled = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : true;
11
12
  var _useState = useState(EMPTY_LIST_ITEM),
12
13
  _useState2 = _slicedToArray(_useState, 2),
13
14
  items = _useState2[0],
@@ -17,6 +18,10 @@ export var useLoadItems = function useLoadItems(triggerHandler, editorView, quer
17
18
  var latestQueryRef = useRef(query);
18
19
  latestQueryRef.current = query;
19
20
  useEffect(function () {
21
+ if (!enabled) {
22
+ setItems(EMPTY_LIST_ITEM);
23
+ return;
24
+ }
20
25
  var requestQuery = query;
21
26
  var isStaleRequest = function isStaleRequest() {
22
27
  return latestQueryRef.current !== requestQuery;
@@ -121,7 +126,7 @@ export var useLoadItems = function useLoadItems(triggerHandler, editorView, quer
121
126
  // ignore because EditorView is mutable but we don't want to
122
127
  // call loadItems when it changes, only when the query changes
123
128
  // eslint-disable-next-line react-hooks/exhaustive-deps
124
- }, [triggerHandler, query, intl]);
129
+ }, [triggerHandler, query, intl, enabled]);
125
130
  useEffect(function () {
126
131
  return function () {
127
132
  componentIsMounted.current = false;
@@ -0,0 +1,4 @@
1
+ export var PassThrough = function PassThrough(_ref) {
2
+ var children = _ref.children;
3
+ return children;
4
+ };
@@ -0,0 +1,137 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import React, { useCallback, useId, useLayoutEffect, useMemo, useRef, useState } from 'react';
3
+ import { useIntl } from 'react-intl';
4
+ import { Popup } from '@atlaskit/editor-common/ui';
5
+ import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles/constants';
6
+ import { Box } from '@atlaskit/primitives/compiled';
7
+ import { InputQuery } from '../InputQuery';
8
+ import { buildTypeAheadMenuModel } from './buildTypeAheadMenuModel';
9
+ import { getTypeAheadItemId } from './getTypeAheadItemId';
10
+ import { PassThrough } from './PassThrough';
11
+ import { TypeAheadItemRow } from './TypeAheadItemRow';
12
+ import { TypeAheadProvider } from './TypeAheadProvider';
13
+ var POPUP_OFFSET = [0, 8];
14
+ export var RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
15
+ var _model$root$component, _model$root;
16
+ var anchorElement = _ref.anchorElement,
17
+ api = _ref.api,
18
+ cancel = _ref.cancel,
19
+ editorView = _ref.editorView,
20
+ forceFocus = _ref.forceFocus,
21
+ onClose = _ref.onClose,
22
+ onUndoRedo = _ref.onUndoRedo,
23
+ popupsBoundariesElement = _ref.popupsBoundariesElement,
24
+ popupsMountPoint = _ref.popupsMountPoint,
25
+ popupsScrollableElement = _ref.popupsScrollableElement,
26
+ query = _ref.query,
27
+ reopenQuery = _ref.reopenQuery,
28
+ setQuery = _ref.setQuery,
29
+ surface = _ref.surface,
30
+ triggerHandler = _ref.triggerHandler;
31
+ var intl = useIntl();
32
+ var generatedId = useId();
33
+ var listId = "".concat(surface.listIdPrefix, "-").concat(generatedId);
34
+ var menuRef = useRef(null);
35
+ var _useState = useState(0),
36
+ _useState2 = _slicedToArray(_useState, 2),
37
+ selectedItemIndex = _useState2[0],
38
+ setSelectedItemIndex = _useState2[1];
39
+ var components = useMemo(function () {
40
+ var _api$uiControlRegistr, _api$uiControlRegistr2;
41
+ return (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(surface.root.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
42
+ }, [api, surface.root.key]);
43
+ var model = useMemo(function () {
44
+ return buildTypeAheadMenuModel(components, surface.root);
45
+ }, [components, surface.root]);
46
+ var itemKeySignature = model.items.map(function (_ref2) {
47
+ var key = _ref2.key;
48
+ return key;
49
+ }).join(',');
50
+ useLayoutEffect(function () {
51
+ setSelectedItemIndex(model.items.length > 0 ? 0 : -1);
52
+ }, [itemKeySignature, model.items.length, query]);
53
+ var selectActiveItem = useCallback(function (_mode) {
54
+ var _menuRef$current;
55
+ if (selectedItemIndex < 0) {
56
+ return;
57
+ }
58
+ (_menuRef$current = menuRef.current) === null || _menuRef$current === void 0 || (_menuRef$current = _menuRef$current.ownerDocument.getElementById(getTypeAheadItemId(listId, selectedItemIndex))) === null || _menuRef$current === void 0 || _menuRef$current.click();
59
+ }, [listId, selectedItemIndex]);
60
+ var selectNextItem = useCallback(function () {
61
+ setSelectedItemIndex(function (currentIndex) {
62
+ if (model.items.length === 0) {
63
+ return -1;
64
+ }
65
+ return currentIndex < 0 || currentIndex === model.items.length - 1 ? 0 : currentIndex + 1;
66
+ });
67
+ }, [model.items.length]);
68
+ var selectPreviousItem = useCallback(function () {
69
+ setSelectedItemIndex(function (currentIndex) {
70
+ if (model.items.length === 0) {
71
+ return -1;
72
+ }
73
+ return currentIndex <= 0 ? model.items.length - 1 : currentIndex - 1;
74
+ });
75
+ }, [model.items.length]);
76
+ var typeAheadContextValue = useMemo(function () {
77
+ return {
78
+ api: api,
79
+ editorView: editorView,
80
+ inputMethod: surface.inputMethod,
81
+ onClose: onClose,
82
+ query: query,
83
+ triggerHandler: triggerHandler
84
+ };
85
+ }, [api, editorView, onClose, query, surface.inputMethod, triggerHandler]);
86
+ var noOp = useCallback(function () {}, []);
87
+ var RootComponent = (_model$root$component = (_model$root = model.root) === null || _model$root === void 0 ? void 0 : _model$root.component) !== null && _model$root$component !== void 0 ? _model$root$component : PassThrough;
88
+ var SurfaceProvider = surface.Provider;
89
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(InputQuery, {
90
+ activeDescendantId: selectedItemIndex >= 0 ? getTypeAheadItemId(listId, selectedItemIndex) : undefined,
91
+ cancel: cancel,
92
+ editorView: editorView,
93
+ forceFocus: forceFocus,
94
+ listId: listId,
95
+ onItemSelect: selectActiveItem,
96
+ onQueryChange: setQuery,
97
+ onQueryFocus: noOp,
98
+ onUndoRedo: onUndoRedo,
99
+ optionCount: model.items.length,
100
+ reopenQuery: reopenQuery,
101
+ selectNextItem: selectNextItem,
102
+ selectPreviousItem: selectPreviousItem,
103
+ shouldKeepOpenOnRegisteredMenu: true,
104
+ triggerQueryPrefix: triggerHandler.trigger
105
+ }), /*#__PURE__*/React.createElement(Popup, {
106
+ ariaLabel: null,
107
+ boundariesElement: popupsBoundariesElement,
108
+ fitWidth: 320,
109
+ mountTo: popupsMountPoint,
110
+ offset: POPUP_OFFSET,
111
+ preventOverflow: true,
112
+ scrollableElement: popupsScrollableElement,
113
+ target: anchorElement,
114
+ zIndex: akEditorFloatingDialogZIndex
115
+ }, /*#__PURE__*/React.createElement(Box, {
116
+ ref: menuRef,
117
+ backgroundColor: "elevation.surface.overlay",
118
+ "data-registered-type-ahead-menu": "",
119
+ padding: "space.050"
120
+ }, /*#__PURE__*/React.createElement(TypeAheadProvider, {
121
+ value: typeAheadContextValue
122
+ }, /*#__PURE__*/React.createElement(SurfaceProvider, null, /*#__PURE__*/React.createElement(RootComponent, null, /*#__PURE__*/React.createElement(Box, {
123
+ "aria-label": intl.formatMessage(surface.listLabel),
124
+ id: listId,
125
+ role: "listbox"
126
+ }, model.items.map(function (registration, itemIndex) {
127
+ return /*#__PURE__*/React.createElement(TypeAheadItemRow, {
128
+ isSelected: selectedItemIndex === itemIndex,
129
+ itemIndex: itemIndex,
130
+ Item: surface.Item,
131
+ key: "".concat(registration.type, ":").concat(registration.key),
132
+ listId: listId,
133
+ onItemHover: setSelectedItemIndex,
134
+ registration: registration
135
+ });
136
+ }))))))));
137
+ };
@@ -0,0 +1,2 @@
1
+ import { createContext } from 'react';
2
+ export var TypeAheadContext = /*#__PURE__*/createContext(null);
@@ -0,0 +1,19 @@
1
+ import React, { useCallback } from 'react';
2
+ import { getTypeAheadItemId } from './getTypeAheadItemId';
3
+ export var TypeAheadItemRow = function TypeAheadItemRow(_ref) {
4
+ var isSelected = _ref.isSelected,
5
+ itemIndex = _ref.itemIndex,
6
+ Item = _ref.Item,
7
+ listId = _ref.listId,
8
+ onItemHover = _ref.onItemHover,
9
+ registration = _ref.registration;
10
+ var onMouseMove = useCallback(function () {
11
+ return onItemHover(itemIndex);
12
+ }, [itemIndex, onItemHover]);
13
+ return /*#__PURE__*/React.createElement(Item, {
14
+ id: getTypeAheadItemId(listId, itemIndex),
15
+ isSelected: isSelected,
16
+ onMouseMove: onMouseMove,
17
+ registration: registration
18
+ });
19
+ };
@@ -0,0 +1,2 @@
1
+ import { TypeAheadContext } from './TypeAheadContext';
2
+ export var TypeAheadProvider = TypeAheadContext.Provider;
@@ -0,0 +1,44 @@
1
+ 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; } } }; }
2
+ 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; } }
3
+ 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; }
4
+ import { resolveSurface, willComponentRender } from '@atlaskit/editor-ui-control-model/surface-renderer';
5
+ export var buildTypeAheadMenuModel = function buildTypeAheadMenuModel(components, rootComponent) {
6
+ var _resolveSurface = resolveSurface(components, rootComponent),
7
+ root = _resolveSurface.root,
8
+ childrenMap = _resolveSurface.childrenMap,
9
+ topLevelChildren = _resolveSurface.topLevelChildren;
10
+ var items = [];
11
+ var _iterator = _createForOfIteratorHelper(topLevelChildren !== null && topLevelChildren !== void 0 ? topLevelChildren : []),
12
+ _step;
13
+ try {
14
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
15
+ var _childrenMap$get;
16
+ var section = _step.value;
17
+ if (section.type !== 'menu-section' || !willComponentRender(section, childrenMap)) {
18
+ continue;
19
+ }
20
+ var _iterator2 = _createForOfIteratorHelper((_childrenMap$get = childrenMap.get(section.key)) !== null && _childrenMap$get !== void 0 ? _childrenMap$get : []),
21
+ _step2;
22
+ try {
23
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
24
+ var child = _step2.value;
25
+ if (child.type === 'menu-item' && willComponentRender(child, childrenMap)) {
26
+ items.push(child);
27
+ }
28
+ }
29
+ } catch (err) {
30
+ _iterator2.e(err);
31
+ } finally {
32
+ _iterator2.f();
33
+ }
34
+ }
35
+ } catch (err) {
36
+ _iterator.e(err);
37
+ } finally {
38
+ _iterator.f();
39
+ }
40
+ return {
41
+ items: items,
42
+ root: root
43
+ };
44
+ };
@@ -0,0 +1,3 @@
1
+ export var getTypeAheadItemId = function getTypeAheadItemId(listId, itemIndex) {
2
+ return "".concat(listId, "--").concat(itemIndex);
3
+ };
@@ -0,0 +1,28 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ 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; }
3
+ 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) { _defineProperty(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; }
4
+ import React, { useMemo } from 'react';
5
+ import { QuickInsertProvider } from '@atlaskit/editor-common/quick-insert/provider';
6
+ import { useQuickInsertContext } from '@atlaskit/editor-common/quick-insert/use-quick-insert-context';
7
+ import { PassThrough } from '../PassThrough';
8
+ export var TypeAheadQuickInsertItem = function TypeAheadQuickInsertItem(_ref) {
9
+ var _registration$compone;
10
+ var id = _ref.id,
11
+ isSelected = _ref.isSelected,
12
+ onMouseMove = _ref.onMouseMove,
13
+ registration = _ref.registration;
14
+ var quickInsertContext = useQuickInsertContext();
15
+ var Component = (_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : PassThrough;
16
+ var contextValue = useMemo(function () {
17
+ return _objectSpread(_objectSpread({}, quickInsertContext), {}, {
18
+ item: {
19
+ id: id,
20
+ isSelected: isSelected,
21
+ onMouseMove: onMouseMove
22
+ }
23
+ });
24
+ }, [id, isSelected, onMouseMove, quickInsertContext]);
25
+ return /*#__PURE__*/React.createElement(QuickInsertProvider, {
26
+ value: contextValue
27
+ }, /*#__PURE__*/React.createElement(Component, null, null));
28
+ };
@@ -0,0 +1,33 @@
1
+ import React, { useCallback, useMemo } from 'react';
2
+ import { QuickInsertProvider } from '@atlaskit/editor-common/quick-insert/provider';
3
+ import { performTypeAheadSelection } from '../../../pm-plugins/commands/insert-type-ahead-item';
4
+ import { useTypeAheadContext } from '../useTypeAheadContext';
5
+ export var TypeAheadQuickInsertProvider = function TypeAheadQuickInsertProvider(_ref) {
6
+ var children = _ref.children;
7
+ var _useTypeAheadContext = useTypeAheadContext(),
8
+ editorView = _useTypeAheadContext.editorView,
9
+ inputMethod = _useTypeAheadContext.inputMethod,
10
+ onClose = _useTypeAheadContext.onClose,
11
+ query = _useTypeAheadContext.query,
12
+ triggerHandler = _useTypeAheadContext.triggerHandler;
13
+ var select = useCallback(function (selectionHandler) {
14
+ onClose();
15
+ queueMicrotask(function () {
16
+ performTypeAheadSelection(editorView)({
17
+ handler: triggerHandler,
18
+ inputMethod: inputMethod,
19
+ query: query,
20
+ selectionHandler: selectionHandler
21
+ });
22
+ });
23
+ }, [editorView, inputMethod, onClose, query, triggerHandler]);
24
+ var contextValue = useMemo(function () {
25
+ return {
26
+ editorView: editorView,
27
+ select: select
28
+ };
29
+ }, [editorView, select]);
30
+ return /*#__PURE__*/React.createElement(QuickInsertProvider, {
31
+ value: contextValue
32
+ }, children);
33
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
2
+ import { MENU } from '@atlaskit/editor-common/quick-insert/keys';
3
+ import { TypeAheadAvailableNodes, typeAheadListMessages } from '@atlaskit/editor-common/type-ahead';
4
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
5
+ import { TypeAheadQuickInsertItem } from './quick-insert/TypeAheadQuickInsertItem';
6
+ import { TypeAheadQuickInsertProvider } from './quick-insert/TypeAheadQuickInsertProvider';
7
+ var quickInsertSurface = {
8
+ inputMethod: INPUT_METHOD.QUICK_INSERT,
9
+ Item: TypeAheadQuickInsertItem,
10
+ listIdPrefix: 'quick-insert-menu',
11
+ listLabel: typeAheadListMessages.quickInsertInputLabel,
12
+ Provider: TypeAheadQuickInsertProvider,
13
+ root: MENU
14
+ };
15
+ export var getTypeAheadSurface = function getTypeAheadSurface(id) {
16
+ if (id === TypeAheadAvailableNodes.QUICK_INSERT && isExperimentEnabled('platform_editor_slash_command')) {
17
+ return quickInsertSurface;
18
+ }
19
+ return undefined;
20
+ };
@@ -0,0 +1,9 @@
1
+ import { useContext } from 'react';
2
+ import { TypeAheadContext } from './TypeAheadContext';
3
+ export var useTypeAheadContext = function useTypeAheadContext() {
4
+ var value = useContext(TypeAheadContext);
5
+ if (!value) {
6
+ throw new Error('useTypeAheadContext must be used within TypeAheadProvider');
7
+ }
8
+ return value;
9
+ };
@@ -1,3 +1,4 @@
1
+ import type { QuickInsertSelectionHandler } from '@atlaskit/editor-common/quick-insert/context';
1
2
  import { SelectItemMode } from '@atlaskit/editor-common/type-ahead';
2
3
  import type { TypeAheadHandler, TypeAheadItem } from '@atlaskit/editor-common/types';
3
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
@@ -9,4 +10,10 @@ type Props = {
9
10
  sourceListItem: Array<TypeAheadItem>;
10
11
  };
11
12
  export declare const insertTypeAheadItem: (view: EditorView) => ({ item, handler, mode, query, sourceListItem }: Props) => void;
13
+ export declare const performTypeAheadSelection: (view: EditorView) => ({ inputMethod, selectionHandler, handler, query, }: {
14
+ handler: TypeAheadHandler;
15
+ inputMethod: Parameters<QuickInsertSelectionHandler>[0]['source'];
16
+ query: string;
17
+ selectionHandler: QuickInsertSelectionHandler;
18
+ }) => void;
12
19
  export {};
@@ -5,6 +5,7 @@ import type { ConnectivityPlugin } from '@atlaskit/editor-plugin-connectivity';
5
5
  import type { ContextPanelPlugin } from '@atlaskit/editor-plugin-context-panel';
6
6
  import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
7
7
  import type { MetricsPlugin } from '@atlaskit/editor-plugin-metrics';
8
+ import type { UiControlRegistryPlugin } from '@atlaskit/editor-plugin-ui-control-registry/ui-control-registry-plugin-type';
8
9
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
9
10
  import type { TypeAheadPluginOptions, TypeAheadPluginSharedState, OpenTypeAheadProps } from './types';
10
11
  type InsertTypeAheadItemProps = {
@@ -44,7 +45,8 @@ export type TypeAheadPlugin = NextEditorPlugin<'typeAhead', {
44
45
  OptionalPlugin<FeatureFlagsPlugin>,
45
46
  OptionalPlugin<ConnectivityPlugin>,
46
47
  OptionalPlugin<ContextPanelPlugin>,
47
- OptionalPlugin<MetricsPlugin>
48
+ OptionalPlugin<MetricsPlugin>,
49
+ OptionalPlugin<UiControlRegistryPlugin>
48
50
  ];
49
51
  pluginConfiguration: TypeAheadPluginOptions | undefined;
50
52
  sharedState: TypeAheadPluginSharedState;