@atlaskit/editor-plugin-type-ahead 25.0.0 → 25.0.2

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 (27) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/ui/TypeAheadPopup.js +0 -4
  3. package/dist/cjs/ui/registered-menu/RegisteredTypeAheadMenu.js +63 -15
  4. package/dist/cjs/ui/registered-menu/TypeAheadItemRow.js +22 -3
  5. package/dist/cjs/ui/registered-menu/TypeAheadMenuRenderer.js +4 -0
  6. package/dist/cjs/ui/registered-menu/createTypeAheadRowRenderer.js +5 -0
  7. package/dist/cjs/ui/registered-menu/quick-insert/TypeAheadQuickInsertItem.js +4 -1
  8. package/dist/cjs/ui/registered-menu/quick-insert/TypeAheadQuickInsertProvider.js +6 -1
  9. package/dist/es2019/ui/TypeAheadPopup.js +0 -4
  10. package/dist/es2019/ui/registered-menu/RegisteredTypeAheadMenu.js +56 -15
  11. package/dist/es2019/ui/registered-menu/TypeAheadItemRow.js +18 -3
  12. package/dist/es2019/ui/registered-menu/TypeAheadMenuRenderer.js +4 -0
  13. package/dist/es2019/ui/registered-menu/createTypeAheadRowRenderer.js +5 -0
  14. package/dist/es2019/ui/registered-menu/quick-insert/TypeAheadQuickInsertItem.js +4 -1
  15. package/dist/es2019/ui/registered-menu/quick-insert/TypeAheadQuickInsertProvider.js +6 -1
  16. package/dist/esm/ui/TypeAheadPopup.js +0 -4
  17. package/dist/esm/ui/registered-menu/RegisteredTypeAheadMenu.js +63 -15
  18. package/dist/esm/ui/registered-menu/TypeAheadItemRow.js +23 -4
  19. package/dist/esm/ui/registered-menu/TypeAheadMenuRenderer.js +4 -0
  20. package/dist/esm/ui/registered-menu/createTypeAheadRowRenderer.js +5 -0
  21. package/dist/esm/ui/registered-menu/quick-insert/TypeAheadQuickInsertItem.js +4 -1
  22. package/dist/esm/ui/registered-menu/quick-insert/TypeAheadQuickInsertProvider.js +6 -1
  23. package/dist/types/ui/registered-menu/TypeAheadContext.d.ts +2 -0
  24. package/dist/types/ui/registered-menu/TypeAheadItemRow.d.ts +5 -2
  25. package/dist/types/ui/registered-menu/TypeAheadMenuRenderer.d.ts +4 -2
  26. package/dist/types/ui/registered-menu/createTypeAheadRowRenderer.d.ts +4 -2
  27. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-plugin-type-ahead
2
2
 
3
+ ## 25.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`395ccdc5786c2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/395ccdc5786c2) -
8
+ Clean up experiment `cc_fd_db_quick_insert_options`
9
+
10
+ ## 25.0.1
11
+
12
+ ### Patch Changes
13
+
14
+ - [`2f527121e0516`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2f527121e0516) -
15
+ Require deliberate pointer or keyboard activation before displaying registered slash-command
16
+ previews under `platform_editor_slash_command`. Avoid redundant menu renders when the pointer
17
+ moves within the active preview row.
18
+ - [`2f527121e0516`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2f527121e0516) -
19
+ Keep active slash-command previews positioned with custom popup hosts such as Whiteboards.
20
+ - Updated dependencies
21
+
3
22
  ## 25.0.0
4
23
 
5
24
  ### Patch Changes
@@ -15,7 +15,6 @@ var _hooks = require("@atlaskit/editor-common/hooks");
15
15
  var _typeAhead = require("@atlaskit/editor-common/type-ahead");
16
16
  var _ui = require("@atlaskit/editor-common/ui");
17
17
  var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
18
- var _featureGates = _interopRequireDefault(require("@atlaskit/feature-gate-js-client/feature-gates"));
19
18
  var _editorExperiment = require("@atlaskit/tmp-editor-statsig/editor-experiment");
20
19
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
21
20
  var _analytics2 = require("../pm-plugins/analytics");
@@ -116,9 +115,6 @@ var TypeAheadPopup = exports.TypeAheadPopup = /*#__PURE__*/_react.default.memo(f
116
115
  }
117
116
  var stopTime = performance.now();
118
117
  var time = stopTime - startTime;
119
-
120
- // eslint-disable-next-line @atlaskit/platform/use-recommended-utils
121
- _featureGates.default.getExperimentValue('cc_fd_db_quick_insert_options', 'isEnabled', false);
122
118
  api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.fireAnalyticsEvent({
123
119
  action: _analytics.ACTION.RENDERED,
124
120
  actionSubject: _analytics.ACTION_SUBJECT.TYPEAHEAD,
@@ -83,6 +83,7 @@ var RegisteredTypeAheadMenu = exports.RegisteredTypeAheadMenu = function Registe
83
83
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
84
84
  selectedItemIndex = _useState4[0],
85
85
  setSelectedItemIndex = _useState4[1];
86
+ var selectedItemIndexRef = (0, _react.useRef)(selectedItemIndex);
86
87
  var getComponents = (0, _react.useCallback)(function () {
87
88
  var _api$uiControlRegistr;
88
89
  var components = api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.getComponents(surface.root.key);
@@ -109,6 +110,11 @@ var RegisteredTypeAheadMenu = exports.RegisteredTypeAheadMenu = function Registe
109
110
  var _menuModel$fallbackIt;
110
111
  return [].concat((0, _toConsumableArray2.default)(menuModel.sections.flat()), (0, _toConsumableArray2.default)((_menuModel$fallbackIt = menuModel.fallbackItems) !== null && _menuModel$fallbackIt !== void 0 ? _menuModel$fallbackIt : []));
111
112
  }, [menuModel.fallbackItems, menuModel.sections]);
113
+ var _useState5 = (0, _react.useState)(),
114
+ _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
115
+ previewActivation = _useState6[0],
116
+ setPreviewActivation = _useState6[1];
117
+ var activePreviewItemKey = (previewActivation === null || previewActivation === void 0 ? void 0 : previewActivation.menuModel) === menuModel ? previewActivation.itemKey : undefined;
112
118
  var selectableRowIndexes = (0, _react.useMemo)(function () {
113
119
  return rows.flatMap(function (registration, rowIndex) {
114
120
  return registration.type === 'menu-item' ? [rowIndex] : [];
@@ -120,8 +126,13 @@ var RegisteredTypeAheadMenu = exports.RegisteredTypeAheadMenu = function Registe
120
126
  }).join(',');
121
127
  var selectableItemCount = selectableRowIndexes.length + (menuModel.footer ? 1 : 0);
122
128
  (0, _react.useLayoutEffect)(function () {
123
- setSelectedItemIndex(selectableItemCount > 0 ? 0 : -1);
129
+ var initialItemIndex = selectableItemCount > 0 ? 0 : -1;
130
+ selectedItemIndexRef.current = initialItemIndex;
131
+ setSelectedItemIndex(initialItemIndex);
124
132
  }, [query, selectableItemCount, selectableRowKeys]);
133
+ (0, _react.useLayoutEffect)(function () {
134
+ setPreviewActivation(undefined);
135
+ }, [menuModel, query]);
125
136
  var selectActiveItem = (0, _react.useCallback)(function (_mode) {
126
137
  var rowIndex = selectableRowIndexes[selectedItemIndex];
127
138
  var selectedId = rowIndex !== undefined ? (0, _getTypeAheadItemId.getTypeAheadItemId)(listId, rowIndex) : menuModel.footer && selectedItemIndex === selectableRowIndexes.length ? (0, _getTypeAheadGlobalViewMoreId.getTypeAheadGlobalViewMoreId)(listId) : undefined;
@@ -130,34 +141,69 @@ var RegisteredTypeAheadMenu = exports.RegisteredTypeAheadMenu = function Registe
130
141
  (_menuRef$current = menuRef.current) === null || _menuRef$current === void 0 || (_menuRef$current = _menuRef$current.ownerDocument.getElementById(selectedId)) === null || _menuRef$current === void 0 || _menuRef$current.click();
131
142
  }
132
143
  }, [listId, menuModel.footer, selectableRowIndexes, selectedItemIndex]);
144
+ var setKeyboardPreview = (0, _react.useCallback)(function (itemIndex) {
145
+ var rowIndex = selectableRowIndexes[itemIndex];
146
+ var registration = rowIndex === undefined ? undefined : rows[rowIndex];
147
+ setPreviewActivation((registration === null || registration === void 0 ? void 0 : registration.type) === 'menu-item' ? {
148
+ itemKey: registration.key,
149
+ menuModel: menuModel,
150
+ source: 'keyboard'
151
+ } : undefined);
152
+ }, [menuModel, rows, selectableRowIndexes]);
133
153
  var selectNextItem = (0, _react.useCallback)(function () {
134
- setSelectedItemIndex(function (currentIndex) {
135
- if (selectableItemCount === 0) {
136
- return -1;
137
- }
138
- return currentIndex < 0 || currentIndex === selectableItemCount - 1 ? 0 : currentIndex + 1;
139
- });
140
- }, [selectableItemCount]);
154
+ var currentIndex = selectedItemIndexRef.current;
155
+ var nextIndex = selectableItemCount === 0 ? -1 : currentIndex < 0 || currentIndex === selectableItemCount - 1 ? 0 : currentIndex + 1;
156
+ selectedItemIndexRef.current = nextIndex;
157
+ setSelectedItemIndex(nextIndex);
158
+ setKeyboardPreview(nextIndex);
159
+ }, [selectableItemCount, setKeyboardPreview]);
141
160
  var selectPreviousItem = (0, _react.useCallback)(function () {
142
- setSelectedItemIndex(function (currentIndex) {
143
- if (selectableItemCount === 0) {
144
- return -1;
161
+ var currentIndex = selectedItemIndexRef.current;
162
+ var previousIndex = selectableItemCount === 0 ? -1 : currentIndex <= 0 ? selectableItemCount - 1 : currentIndex - 1;
163
+ selectedItemIndexRef.current = previousIndex;
164
+ setSelectedItemIndex(previousIndex);
165
+ setKeyboardPreview(previousIndex);
166
+ }, [selectableItemCount, setKeyboardPreview]);
167
+ var onItemHover = (0, _react.useCallback)(function (itemIndex, itemKey) {
168
+ selectedItemIndexRef.current = itemIndex;
169
+ setSelectedItemIndex(itemIndex);
170
+ setPreviewActivation(function (current) {
171
+ if ((current === null || current === void 0 ? void 0 : current.itemKey) === itemKey && (current === null || current === void 0 ? void 0 : current.menuModel) === menuModel && (current === null || current === void 0 ? void 0 : current.source) === 'pointer') {
172
+ return current;
145
173
  }
146
- return currentIndex <= 0 ? selectableItemCount - 1 : currentIndex - 1;
174
+ return itemKey ? {
175
+ itemKey: itemKey,
176
+ menuModel: menuModel,
177
+ source: 'pointer'
178
+ } : undefined;
147
179
  });
148
- }, [selectableItemCount]);
180
+ }, [menuModel]);
181
+ var onItemLeave = (0, _react.useCallback)(function (itemKey) {
182
+ setPreviewActivation(function (current) {
183
+ return (current === null || current === void 0 ? void 0 : current.source) === 'pointer' && current.itemKey === itemKey ? undefined : current;
184
+ });
185
+ }, []);
186
+ var onItemVisibilityChange = (0, _react.useCallback)(function (itemKey, isVisible) {
187
+ if (!isVisible) {
188
+ setPreviewActivation(function (current) {
189
+ return (current === null || current === void 0 ? void 0 : current.source) === 'pointer' && current.itemKey === itemKey ? undefined : current;
190
+ });
191
+ }
192
+ }, []);
149
193
  var typeAheadContextValue = (0, _react.useMemo)(function () {
150
194
  return {
195
+ activePreviewItemKey: activePreviewItemKey,
151
196
  api: api,
152
197
  editorView: editorView,
153
198
  inputMethod: surface.inputMethod,
154
199
  menuOpenId: typeAheadSurfaceContext.menuOpenId,
155
200
  onClose: onClose,
201
+ popupsMountPoint: popupsMountPoint,
156
202
  query: query,
157
203
  surfaceContext: surfaceContext,
158
204
  triggerHandler: triggerHandler
159
205
  };
160
- }, [api, editorView, onClose, query, surface.inputMethod, surfaceContext, triggerHandler, typeAheadSurfaceContext]);
206
+ }, [activePreviewItemKey, api, editorView, onClose, popupsMountPoint, query, surface.inputMethod, surfaceContext, triggerHandler, typeAheadSurfaceContext]);
161
207
  var noOp = (0, _react.useCallback)(function () {}, []);
162
208
  var SurfaceProvider = surface.Provider;
163
209
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_InputQuery.InputQuery, {
@@ -201,7 +247,9 @@ var RegisteredTypeAheadMenu = exports.RegisteredTypeAheadMenu = function Registe
201
247
  listId: listId,
202
248
  maxHeight: Math.max(0, menuHeight - MENU_VERTICAL_PADDING),
203
249
  model: menuModel,
204
- onItemHover: setSelectedItemIndex,
250
+ onItemHover: onItemHover,
251
+ onItemLeave: onItemLeave,
252
+ onItemVisibilityChange: onItemVisibilityChange,
205
253
  selectedItemIndex: selectedItemIndex
206
254
  }))))));
207
255
  };
@@ -14,12 +14,31 @@ var TypeAheadItemRow = exports.TypeAheadItemRow = function TypeAheadItemRow(_ref
14
14
  Item = _ref.Item,
15
15
  listId = _ref.listId,
16
16
  onItemHover = _ref.onItemHover,
17
+ onItemLeave = _ref.onItemLeave,
18
+ onItemVisibilityChange = _ref.onItemVisibilityChange,
17
19
  registration = _ref.registration,
18
- rowIndex = _ref.rowIndex;
20
+ rowIndex = _ref.rowIndex,
21
+ isVisible = _ref.isVisible;
19
22
  var onMouseMove = (0, _react.useCallback)(function () {
20
- return onItemHover(itemIndex);
21
- }, [itemIndex, onItemHover]);
23
+ return onItemHover(itemIndex, registration.key);
24
+ }, [itemIndex, onItemHover, registration.key]);
25
+ var onMouseLeave = (0, _react.useCallback)(function () {
26
+ return onItemLeave(registration.key);
27
+ }, [onItemLeave, registration.key]);
28
+ var onBlur = (0, _react.useCallback)(function (event) {
29
+ if (!event.currentTarget.contains(event.relatedTarget)) {
30
+ onItemLeave(registration.key);
31
+ }
32
+ }, [onItemLeave, registration.key]);
33
+ (0, _react.useLayoutEffect)(function () {
34
+ onItemVisibilityChange(registration.key, isVisible);
35
+ return function () {
36
+ return onItemVisibilityChange(registration.key, false);
37
+ };
38
+ }, [isVisible, onItemVisibilityChange, registration.key]);
22
39
  return /*#__PURE__*/_react.default.createElement("div", {
40
+ onBlur: onBlur,
41
+ onMouseLeave: onMouseLeave,
23
42
  onMouseMove: onMouseMove
24
43
  }, /*#__PURE__*/_react.default.createElement(Item, {
25
44
  id: (0, _getTypeAheadItemId.getTypeAheadItemId)(listId, rowIndex),
@@ -35,6 +35,8 @@ var TypeAheadMenuRenderer = exports.TypeAheadMenuRenderer = function TypeAheadMe
35
35
  maxHeight = _ref.maxHeight,
36
36
  model = _ref.model,
37
37
  onItemHover = _ref.onItemHover,
38
+ onItemLeave = _ref.onItemLeave,
39
+ onItemVisibilityChange = _ref.onItemVisibilityChange,
38
40
  selectedItemIndex = _ref.selectedItemIndex;
39
41
  var intl = (0, _reactIntl.useIntl)();
40
42
  var listRef = (0, _react.useRef)(null);
@@ -106,6 +108,8 @@ var TypeAheadMenuRenderer = exports.TypeAheadMenuRenderer = function TypeAheadMe
106
108
  Item: Item,
107
109
  listId: listId,
108
110
  onItemHover: onItemHover,
111
+ onItemLeave: onItemLeave,
112
+ onItemVisibilityChange: onItemVisibilityChange,
109
113
  rows: rows,
110
114
  selectedItemIndex: selectedItemIndex
111
115
  });
@@ -18,6 +18,8 @@ var createTypeAheadRowRenderer = exports.createTypeAheadRowRenderer = function c
18
18
  Item = _ref.Item,
19
19
  listId = _ref.listId,
20
20
  onItemHover = _ref.onItemHover,
21
+ onItemLeave = _ref.onItemLeave,
22
+ onItemVisibilityChange = _ref.onItemVisibilityChange,
21
23
  rows = _ref.rows,
22
24
  selectedItemIndex = _ref.selectedItemIndex;
23
25
  return function (_ref2) {
@@ -56,6 +58,9 @@ var createTypeAheadRowRenderer = exports.createTypeAheadRowRenderer = function c
56
58
  itemIndex: itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0,
57
59
  listId: listId,
58
60
  onItemHover: onItemHover,
61
+ onItemLeave: onItemLeave,
62
+ onItemVisibilityChange: onItemVisibilityChange,
63
+ isVisible: isVisible,
59
64
  registration: registration,
60
65
  rowIndex: index
61
66
  }));
@@ -19,18 +19,21 @@ var TypeAheadQuickInsertItem = exports.TypeAheadQuickInsertItem = function TypeA
19
19
  var Component = (_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : _PassThrough.PassThrough;
20
20
  var contextValue = (0, _react.useMemo)(function () {
21
21
  return {
22
+ activePreviewItemKey: quickInsertContext.activePreviewItemKey,
22
23
  editorView: quickInsertContext.editorView,
23
24
  isOffline: quickInsertContext.isOffline,
24
25
  menuOpenId: quickInsertContext.menuOpenId,
26
+ popupsMountPoint: quickInsertContext.popupsMountPoint,
25
27
  surfaceContext: quickInsertContext.surfaceContext,
26
28
  surface: 'typeahead',
27
29
  item: {
28
30
  id: id,
31
+ isPreviewActive: quickInsertContext.activePreviewItemKey === registration.key,
29
32
  isSelected: isSelected
30
33
  },
31
34
  select: quickInsertContext.select
32
35
  };
33
- }, [id, isSelected, quickInsertContext]);
36
+ }, [id, isSelected, quickInsertContext, registration.key]);
34
37
  return /*#__PURE__*/_react.default.createElement(_provider.QuickInsertProvider, {
35
38
  value: contextValue
36
39
  }, /*#__PURE__*/_react.default.createElement(Component, null, null));
@@ -15,11 +15,13 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
15
15
  var TypeAheadQuickInsertProvider = exports.TypeAheadQuickInsertProvider = function TypeAheadQuickInsertProvider(_ref) {
16
16
  var children = _ref.children;
17
17
  var _useTypeAheadContext = (0, _useTypeAheadContext2.useTypeAheadContext)(),
18
+ activePreviewItemKey = _useTypeAheadContext.activePreviewItemKey,
18
19
  api = _useTypeAheadContext.api,
19
20
  editorView = _useTypeAheadContext.editorView,
20
21
  inputMethod = _useTypeAheadContext.inputMethod,
21
22
  menuOpenId = _useTypeAheadContext.menuOpenId,
22
23
  onClose = _useTypeAheadContext.onClose,
24
+ popupsMountPoint = _useTypeAheadContext.popupsMountPoint,
23
25
  query = _useTypeAheadContext.query,
24
26
  surfaceContext = _useTypeAheadContext.surfaceContext,
25
27
  triggerHandler = _useTypeAheadContext.triggerHandler;
@@ -43,18 +45,21 @@ var TypeAheadQuickInsertProvider = exports.TypeAheadQuickInsertProvider = functi
43
45
  }, [editorView, inputMethod, onClose, query, triggerHandler]);
44
46
  var contextValue = (0, _react.useMemo)(function () {
45
47
  return {
48
+ activePreviewItemKey: activePreviewItemKey,
46
49
  editorView: editorView,
47
50
  isOffline: isOffline,
48
51
  menuOpenId: menuOpenId,
52
+ popupsMountPoint: popupsMountPoint,
49
53
  item: {
50
54
  id: 'typeahead-quick-insert',
55
+ isPreviewActive: false,
51
56
  isSelected: false
52
57
  },
53
58
  surface: 'typeahead',
54
59
  select: select,
55
60
  surfaceContext: surfaceContext
56
61
  };
57
- }, [editorView, isOffline, menuOpenId, select, surfaceContext]);
62
+ }, [activePreviewItemKey, editorView, isOffline, menuOpenId, popupsMountPoint, select, surfaceContext]);
58
63
  return /*#__PURE__*/_react.default.createElement(_provider.QuickInsertProvider, {
59
64
  value: contextValue
60
65
  }, children);
@@ -12,7 +12,6 @@ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'
12
12
  import { TypeAheadAvailableNodes } from '@atlaskit/editor-common/type-ahead';
13
13
  import { findOverflowScrollParent, Popup } from '@atlaskit/editor-common/ui';
14
14
  import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
15
- import FeatureGates from '@atlaskit/feature-gate-js-client/feature-gates';
16
15
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
17
16
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
18
17
  import { fireTypeAheadClosedAnalyticsEvent } from '../pm-plugins/analytics';
@@ -104,9 +103,6 @@ export const TypeAheadPopup = /*#__PURE__*/React.memo(props => {
104
103
  }
105
104
  const stopTime = performance.now();
106
105
  const time = stopTime - startTime;
107
-
108
- // eslint-disable-next-line @atlaskit/platform/use-recommended-utils
109
- FeatureGates.getExperimentValue('cc_fd_db_quick_insert_options', 'isEnabled', false);
110
106
  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({
111
107
  action: ACTION.RENDERED,
112
108
  actionSubject: ACTION_SUBJECT.TYPEAHEAD,
@@ -62,6 +62,7 @@ export const RegisteredTypeAheadMenu = ({
62
62
  }));
63
63
  const surfaceContext = useMemo(() => createSurfaceContext(TYPE_AHEAD_SURFACE_CONTEXT, typeAheadSurfaceContext), [typeAheadSurfaceContext]);
64
64
  const [selectedItemIndex, setSelectedItemIndex] = useState(0);
65
+ const selectedItemIndexRef = useRef(selectedItemIndex);
65
66
  const getComponents = useCallback(() => {
66
67
  var _api$uiControlRegistr;
67
68
  const components = api === null || api === void 0 ? void 0 : (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.getComponents(surface.root.key);
@@ -83,6 +84,8 @@ export const RegisteredTypeAheadMenu = ({
83
84
  var _menuModel$fallbackIt;
84
85
  return [...menuModel.sections.flat(), ...((_menuModel$fallbackIt = menuModel.fallbackItems) !== null && _menuModel$fallbackIt !== void 0 ? _menuModel$fallbackIt : [])];
85
86
  }, [menuModel.fallbackItems, menuModel.sections]);
87
+ const [previewActivation, setPreviewActivation] = useState();
88
+ const activePreviewItemKey = (previewActivation === null || previewActivation === void 0 ? void 0 : previewActivation.menuModel) === menuModel ? previewActivation.itemKey : undefined;
86
89
  const selectableRowIndexes = useMemo(() => rows.flatMap((registration, rowIndex) => registration.type === 'menu-item' ? [rowIndex] : []), [rows]);
87
90
  const selectableRowKeys = selectableRowIndexes.map(index => {
88
91
  var _rows$index;
@@ -90,8 +93,13 @@ export const RegisteredTypeAheadMenu = ({
90
93
  }).join(',');
91
94
  const selectableItemCount = selectableRowIndexes.length + (menuModel.footer ? 1 : 0);
92
95
  useLayoutEffect(() => {
93
- setSelectedItemIndex(selectableItemCount > 0 ? 0 : -1);
96
+ const initialItemIndex = selectableItemCount > 0 ? 0 : -1;
97
+ selectedItemIndexRef.current = initialItemIndex;
98
+ setSelectedItemIndex(initialItemIndex);
94
99
  }, [query, selectableItemCount, selectableRowKeys]);
100
+ useLayoutEffect(() => {
101
+ setPreviewActivation(undefined);
102
+ }, [menuModel, query]);
95
103
  const selectActiveItem = useCallback(_mode => {
96
104
  const rowIndex = selectableRowIndexes[selectedItemIndex];
97
105
  const selectedId = rowIndex !== undefined ? getTypeAheadItemId(listId, rowIndex) : menuModel.footer && selectedItemIndex === selectableRowIndexes.length ? getTypeAheadGlobalViewMoreId(listId) : undefined;
@@ -100,32 +108,63 @@ export const RegisteredTypeAheadMenu = ({
100
108
  (_menuRef$current = menuRef.current) === null || _menuRef$current === void 0 ? void 0 : (_menuRef$current$owne = _menuRef$current.ownerDocument.getElementById(selectedId)) === null || _menuRef$current$owne === void 0 ? void 0 : _menuRef$current$owne.click();
101
109
  }
102
110
  }, [listId, menuModel.footer, selectableRowIndexes, selectedItemIndex]);
111
+ const setKeyboardPreview = useCallback(itemIndex => {
112
+ const rowIndex = selectableRowIndexes[itemIndex];
113
+ const registration = rowIndex === undefined ? undefined : rows[rowIndex];
114
+ setPreviewActivation((registration === null || registration === void 0 ? void 0 : registration.type) === 'menu-item' ? {
115
+ itemKey: registration.key,
116
+ menuModel,
117
+ source: 'keyboard'
118
+ } : undefined);
119
+ }, [menuModel, rows, selectableRowIndexes]);
103
120
  const selectNextItem = useCallback(() => {
104
- setSelectedItemIndex(currentIndex => {
105
- if (selectableItemCount === 0) {
106
- return -1;
107
- }
108
- return currentIndex < 0 || currentIndex === selectableItemCount - 1 ? 0 : currentIndex + 1;
109
- });
110
- }, [selectableItemCount]);
121
+ const currentIndex = selectedItemIndexRef.current;
122
+ const nextIndex = selectableItemCount === 0 ? -1 : currentIndex < 0 || currentIndex === selectableItemCount - 1 ? 0 : currentIndex + 1;
123
+ selectedItemIndexRef.current = nextIndex;
124
+ setSelectedItemIndex(nextIndex);
125
+ setKeyboardPreview(nextIndex);
126
+ }, [selectableItemCount, setKeyboardPreview]);
111
127
  const selectPreviousItem = useCallback(() => {
112
- setSelectedItemIndex(currentIndex => {
113
- if (selectableItemCount === 0) {
114
- return -1;
128
+ const currentIndex = selectedItemIndexRef.current;
129
+ const previousIndex = selectableItemCount === 0 ? -1 : currentIndex <= 0 ? selectableItemCount - 1 : currentIndex - 1;
130
+ selectedItemIndexRef.current = previousIndex;
131
+ setSelectedItemIndex(previousIndex);
132
+ setKeyboardPreview(previousIndex);
133
+ }, [selectableItemCount, setKeyboardPreview]);
134
+ const onItemHover = useCallback((itemIndex, itemKey) => {
135
+ selectedItemIndexRef.current = itemIndex;
136
+ setSelectedItemIndex(itemIndex);
137
+ setPreviewActivation(current => {
138
+ if ((current === null || current === void 0 ? void 0 : current.itemKey) === itemKey && (current === null || current === void 0 ? void 0 : current.menuModel) === menuModel && (current === null || current === void 0 ? void 0 : current.source) === 'pointer') {
139
+ return current;
115
140
  }
116
- return currentIndex <= 0 ? selectableItemCount - 1 : currentIndex - 1;
141
+ return itemKey ? {
142
+ itemKey,
143
+ menuModel,
144
+ source: 'pointer'
145
+ } : undefined;
117
146
  });
118
- }, [selectableItemCount]);
147
+ }, [menuModel]);
148
+ const onItemLeave = useCallback(itemKey => {
149
+ setPreviewActivation(current => (current === null || current === void 0 ? void 0 : current.source) === 'pointer' && current.itemKey === itemKey ? undefined : current);
150
+ }, []);
151
+ const onItemVisibilityChange = useCallback((itemKey, isVisible) => {
152
+ if (!isVisible) {
153
+ setPreviewActivation(current => (current === null || current === void 0 ? void 0 : current.source) === 'pointer' && current.itemKey === itemKey ? undefined : current);
154
+ }
155
+ }, []);
119
156
  const typeAheadContextValue = useMemo(() => ({
157
+ activePreviewItemKey,
120
158
  api,
121
159
  editorView,
122
160
  inputMethod: surface.inputMethod,
123
161
  menuOpenId: typeAheadSurfaceContext.menuOpenId,
124
162
  onClose,
163
+ popupsMountPoint,
125
164
  query,
126
165
  surfaceContext,
127
166
  triggerHandler
128
- }), [api, editorView, onClose, query, surface.inputMethod, surfaceContext, triggerHandler, typeAheadSurfaceContext]);
167
+ }), [activePreviewItemKey, api, editorView, onClose, popupsMountPoint, query, surface.inputMethod, surfaceContext, triggerHandler, typeAheadSurfaceContext]);
129
168
  const noOp = useCallback(() => {}, []);
130
169
  const SurfaceProvider = surface.Provider;
131
170
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(InputQuery, {
@@ -169,7 +208,9 @@ export const RegisteredTypeAheadMenu = ({
169
208
  listId: listId,
170
209
  maxHeight: Math.max(0, menuHeight - MENU_VERTICAL_PADDING),
171
210
  model: menuModel,
172
- onItemHover: setSelectedItemIndex,
211
+ onItemHover: onItemHover,
212
+ onItemLeave: onItemLeave,
213
+ onItemVisibilityChange: onItemVisibilityChange,
173
214
  selectedItemIndex: selectedItemIndex
174
215
  }))))));
175
216
  };
@@ -1,4 +1,4 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useLayoutEffect } from 'react';
2
2
  import { getTypeAheadItemId } from './getTypeAheadItemId';
3
3
  export const TypeAheadItemRow = ({
4
4
  isSelected,
@@ -6,11 +6,26 @@ export const TypeAheadItemRow = ({
6
6
  Item,
7
7
  listId,
8
8
  onItemHover,
9
+ onItemLeave,
10
+ onItemVisibilityChange,
9
11
  registration,
10
- rowIndex
12
+ rowIndex,
13
+ isVisible
11
14
  }) => {
12
- const onMouseMove = useCallback(() => onItemHover(itemIndex), [itemIndex, onItemHover]);
15
+ const onMouseMove = useCallback(() => onItemHover(itemIndex, registration.key), [itemIndex, onItemHover, registration.key]);
16
+ const onMouseLeave = useCallback(() => onItemLeave(registration.key), [onItemLeave, registration.key]);
17
+ const onBlur = useCallback(event => {
18
+ if (!event.currentTarget.contains(event.relatedTarget)) {
19
+ onItemLeave(registration.key);
20
+ }
21
+ }, [onItemLeave, registration.key]);
22
+ useLayoutEffect(() => {
23
+ onItemVisibilityChange(registration.key, isVisible);
24
+ return () => onItemVisibilityChange(registration.key, false);
25
+ }, [isVisible, onItemVisibilityChange, registration.key]);
13
26
  return /*#__PURE__*/React.createElement("div", {
27
+ onBlur: onBlur,
28
+ onMouseLeave: onMouseLeave,
14
29
  onMouseMove: onMouseMove
15
30
  }, /*#__PURE__*/React.createElement(Item, {
16
31
  id: getTypeAheadItemId(listId, rowIndex),
@@ -20,6 +20,8 @@ export const TypeAheadMenuRenderer = ({
20
20
  maxHeight,
21
21
  model,
22
22
  onItemHover,
23
+ onItemLeave,
24
+ onItemVisibilityChange,
23
25
  selectedItemIndex
24
26
  }) => {
25
27
  var _model$root$component;
@@ -78,6 +80,8 @@ export const TypeAheadMenuRenderer = ({
78
80
  Item,
79
81
  listId,
80
82
  onItemHover,
83
+ onItemLeave,
84
+ onItemVisibilityChange,
81
85
  rows,
82
86
  selectedItemIndex
83
87
  });
@@ -11,6 +11,8 @@ export const createTypeAheadRowRenderer = ({
11
11
  Item,
12
12
  listId,
13
13
  onItemHover,
14
+ onItemLeave,
15
+ onItemVisibilityChange,
14
16
  rows,
15
17
  selectedItemIndex
16
18
  }) => ({
@@ -50,6 +52,9 @@ export const createTypeAheadRowRenderer = ({
50
52
  itemIndex: itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0,
51
53
  listId: listId,
52
54
  onItemHover: onItemHover,
55
+ onItemLeave: onItemLeave,
56
+ onItemVisibilityChange: onItemVisibilityChange,
57
+ isVisible: isVisible,
53
58
  registration: registration,
54
59
  rowIndex: index
55
60
  })));
@@ -11,17 +11,20 @@ export const TypeAheadQuickInsertItem = ({
11
11
  const quickInsertContext = useQuickInsertContext();
12
12
  const Component = (_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : PassThrough;
13
13
  const contextValue = useMemo(() => ({
14
+ activePreviewItemKey: quickInsertContext.activePreviewItemKey,
14
15
  editorView: quickInsertContext.editorView,
15
16
  isOffline: quickInsertContext.isOffline,
16
17
  menuOpenId: quickInsertContext.menuOpenId,
18
+ popupsMountPoint: quickInsertContext.popupsMountPoint,
17
19
  surfaceContext: quickInsertContext.surfaceContext,
18
20
  surface: 'typeahead',
19
21
  item: {
20
22
  id,
23
+ isPreviewActive: quickInsertContext.activePreviewItemKey === registration.key,
21
24
  isSelected
22
25
  },
23
26
  select: quickInsertContext.select
24
- }), [id, isSelected, quickInsertContext]);
27
+ }), [id, isSelected, quickInsertContext, registration.key]);
25
28
  return /*#__PURE__*/React.createElement(QuickInsertProvider, {
26
29
  value: contextValue
27
30
  }, /*#__PURE__*/React.createElement(Component, null, null));
@@ -8,11 +8,13 @@ export const TypeAheadQuickInsertProvider = ({
8
8
  children
9
9
  }) => {
10
10
  const {
11
+ activePreviewItemKey,
11
12
  api,
12
13
  editorView,
13
14
  inputMethod,
14
15
  menuOpenId,
15
16
  onClose,
17
+ popupsMountPoint,
16
18
  query,
17
19
  surfaceContext,
18
20
  triggerHandler
@@ -36,17 +38,20 @@ export const TypeAheadQuickInsertProvider = ({
36
38
  });
37
39
  }, [editorView, inputMethod, onClose, query, triggerHandler]);
38
40
  const contextValue = useMemo(() => ({
41
+ activePreviewItemKey,
39
42
  editorView,
40
43
  isOffline,
41
44
  menuOpenId,
45
+ popupsMountPoint,
42
46
  item: {
43
47
  id: 'typeahead-quick-insert',
48
+ isPreviewActive: false,
44
49
  isSelected: false
45
50
  },
46
51
  surface: 'typeahead',
47
52
  select,
48
53
  surfaceContext
49
- }), [editorView, isOffline, menuOpenId, select, surfaceContext]);
54
+ }), [activePreviewItemKey, editorView, isOffline, menuOpenId, popupsMountPoint, select, surfaceContext]);
50
55
  return /*#__PURE__*/React.createElement(QuickInsertProvider, {
51
56
  value: contextValue
52
57
  }, children);
@@ -13,7 +13,6 @@ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'
13
13
  import { TypeAheadAvailableNodes } from '@atlaskit/editor-common/type-ahead';
14
14
  import { findOverflowScrollParent, Popup } from '@atlaskit/editor-common/ui';
15
15
  import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
16
- import FeatureGates from '@atlaskit/feature-gate-js-client/feature-gates';
17
16
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
18
17
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
19
18
  import { fireTypeAheadClosedAnalyticsEvent } from '../pm-plugins/analytics';
@@ -106,9 +105,6 @@ export var TypeAheadPopup = /*#__PURE__*/React.memo(function (props) {
106
105
  }
107
106
  var stopTime = performance.now();
108
107
  var time = stopTime - startTime;
109
-
110
- // eslint-disable-next-line @atlaskit/platform/use-recommended-utils
111
- FeatureGates.getExperimentValue('cc_fd_db_quick_insert_options', 'isEnabled', false);
112
108
  api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.fireAnalyticsEvent({
113
109
  action: ACTION.RENDERED,
114
110
  actionSubject: ACTION_SUBJECT.TYPEAHEAD,
@@ -74,6 +74,7 @@ export var RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
74
74
  _useState4 = _slicedToArray(_useState3, 2),
75
75
  selectedItemIndex = _useState4[0],
76
76
  setSelectedItemIndex = _useState4[1];
77
+ var selectedItemIndexRef = useRef(selectedItemIndex);
77
78
  var getComponents = useCallback(function () {
78
79
  var _api$uiControlRegistr;
79
80
  var components = api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.getComponents(surface.root.key);
@@ -100,6 +101,11 @@ export var RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
100
101
  var _menuModel$fallbackIt;
101
102
  return [].concat(_toConsumableArray(menuModel.sections.flat()), _toConsumableArray((_menuModel$fallbackIt = menuModel.fallbackItems) !== null && _menuModel$fallbackIt !== void 0 ? _menuModel$fallbackIt : []));
102
103
  }, [menuModel.fallbackItems, menuModel.sections]);
104
+ var _useState5 = useState(),
105
+ _useState6 = _slicedToArray(_useState5, 2),
106
+ previewActivation = _useState6[0],
107
+ setPreviewActivation = _useState6[1];
108
+ var activePreviewItemKey = (previewActivation === null || previewActivation === void 0 ? void 0 : previewActivation.menuModel) === menuModel ? previewActivation.itemKey : undefined;
103
109
  var selectableRowIndexes = useMemo(function () {
104
110
  return rows.flatMap(function (registration, rowIndex) {
105
111
  return registration.type === 'menu-item' ? [rowIndex] : [];
@@ -111,8 +117,13 @@ export var RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
111
117
  }).join(',');
112
118
  var selectableItemCount = selectableRowIndexes.length + (menuModel.footer ? 1 : 0);
113
119
  useLayoutEffect(function () {
114
- setSelectedItemIndex(selectableItemCount > 0 ? 0 : -1);
120
+ var initialItemIndex = selectableItemCount > 0 ? 0 : -1;
121
+ selectedItemIndexRef.current = initialItemIndex;
122
+ setSelectedItemIndex(initialItemIndex);
115
123
  }, [query, selectableItemCount, selectableRowKeys]);
124
+ useLayoutEffect(function () {
125
+ setPreviewActivation(undefined);
126
+ }, [menuModel, query]);
116
127
  var selectActiveItem = useCallback(function (_mode) {
117
128
  var rowIndex = selectableRowIndexes[selectedItemIndex];
118
129
  var selectedId = rowIndex !== undefined ? getTypeAheadItemId(listId, rowIndex) : menuModel.footer && selectedItemIndex === selectableRowIndexes.length ? getTypeAheadGlobalViewMoreId(listId) : undefined;
@@ -121,34 +132,69 @@ export var RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
121
132
  (_menuRef$current = menuRef.current) === null || _menuRef$current === void 0 || (_menuRef$current = _menuRef$current.ownerDocument.getElementById(selectedId)) === null || _menuRef$current === void 0 || _menuRef$current.click();
122
133
  }
123
134
  }, [listId, menuModel.footer, selectableRowIndexes, selectedItemIndex]);
135
+ var setKeyboardPreview = useCallback(function (itemIndex) {
136
+ var rowIndex = selectableRowIndexes[itemIndex];
137
+ var registration = rowIndex === undefined ? undefined : rows[rowIndex];
138
+ setPreviewActivation((registration === null || registration === void 0 ? void 0 : registration.type) === 'menu-item' ? {
139
+ itemKey: registration.key,
140
+ menuModel: menuModel,
141
+ source: 'keyboard'
142
+ } : undefined);
143
+ }, [menuModel, rows, selectableRowIndexes]);
124
144
  var selectNextItem = useCallback(function () {
125
- setSelectedItemIndex(function (currentIndex) {
126
- if (selectableItemCount === 0) {
127
- return -1;
128
- }
129
- return currentIndex < 0 || currentIndex === selectableItemCount - 1 ? 0 : currentIndex + 1;
130
- });
131
- }, [selectableItemCount]);
145
+ var currentIndex = selectedItemIndexRef.current;
146
+ var nextIndex = selectableItemCount === 0 ? -1 : currentIndex < 0 || currentIndex === selectableItemCount - 1 ? 0 : currentIndex + 1;
147
+ selectedItemIndexRef.current = nextIndex;
148
+ setSelectedItemIndex(nextIndex);
149
+ setKeyboardPreview(nextIndex);
150
+ }, [selectableItemCount, setKeyboardPreview]);
132
151
  var selectPreviousItem = useCallback(function () {
133
- setSelectedItemIndex(function (currentIndex) {
134
- if (selectableItemCount === 0) {
135
- return -1;
152
+ var currentIndex = selectedItemIndexRef.current;
153
+ var previousIndex = selectableItemCount === 0 ? -1 : currentIndex <= 0 ? selectableItemCount - 1 : currentIndex - 1;
154
+ selectedItemIndexRef.current = previousIndex;
155
+ setSelectedItemIndex(previousIndex);
156
+ setKeyboardPreview(previousIndex);
157
+ }, [selectableItemCount, setKeyboardPreview]);
158
+ var onItemHover = useCallback(function (itemIndex, itemKey) {
159
+ selectedItemIndexRef.current = itemIndex;
160
+ setSelectedItemIndex(itemIndex);
161
+ setPreviewActivation(function (current) {
162
+ if ((current === null || current === void 0 ? void 0 : current.itemKey) === itemKey && (current === null || current === void 0 ? void 0 : current.menuModel) === menuModel && (current === null || current === void 0 ? void 0 : current.source) === 'pointer') {
163
+ return current;
136
164
  }
137
- return currentIndex <= 0 ? selectableItemCount - 1 : currentIndex - 1;
165
+ return itemKey ? {
166
+ itemKey: itemKey,
167
+ menuModel: menuModel,
168
+ source: 'pointer'
169
+ } : undefined;
138
170
  });
139
- }, [selectableItemCount]);
171
+ }, [menuModel]);
172
+ var onItemLeave = useCallback(function (itemKey) {
173
+ setPreviewActivation(function (current) {
174
+ return (current === null || current === void 0 ? void 0 : current.source) === 'pointer' && current.itemKey === itemKey ? undefined : current;
175
+ });
176
+ }, []);
177
+ var onItemVisibilityChange = useCallback(function (itemKey, isVisible) {
178
+ if (!isVisible) {
179
+ setPreviewActivation(function (current) {
180
+ return (current === null || current === void 0 ? void 0 : current.source) === 'pointer' && current.itemKey === itemKey ? undefined : current;
181
+ });
182
+ }
183
+ }, []);
140
184
  var typeAheadContextValue = useMemo(function () {
141
185
  return {
186
+ activePreviewItemKey: activePreviewItemKey,
142
187
  api: api,
143
188
  editorView: editorView,
144
189
  inputMethod: surface.inputMethod,
145
190
  menuOpenId: typeAheadSurfaceContext.menuOpenId,
146
191
  onClose: onClose,
192
+ popupsMountPoint: popupsMountPoint,
147
193
  query: query,
148
194
  surfaceContext: surfaceContext,
149
195
  triggerHandler: triggerHandler
150
196
  };
151
- }, [api, editorView, onClose, query, surface.inputMethod, surfaceContext, triggerHandler, typeAheadSurfaceContext]);
197
+ }, [activePreviewItemKey, api, editorView, onClose, popupsMountPoint, query, surface.inputMethod, surfaceContext, triggerHandler, typeAheadSurfaceContext]);
152
198
  var noOp = useCallback(function () {}, []);
153
199
  var SurfaceProvider = surface.Provider;
154
200
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(InputQuery, {
@@ -192,7 +238,9 @@ export var RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
192
238
  listId: listId,
193
239
  maxHeight: Math.max(0, menuHeight - MENU_VERTICAL_PADDING),
194
240
  model: menuModel,
195
- onItemHover: setSelectedItemIndex,
241
+ onItemHover: onItemHover,
242
+ onItemLeave: onItemLeave,
243
+ onItemVisibilityChange: onItemVisibilityChange,
196
244
  selectedItemIndex: selectedItemIndex
197
245
  }))))));
198
246
  };
@@ -1,4 +1,4 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useLayoutEffect } from 'react';
2
2
  import { getTypeAheadItemId } from './getTypeAheadItemId';
3
3
  export var TypeAheadItemRow = function TypeAheadItemRow(_ref) {
4
4
  var isSelected = _ref.isSelected,
@@ -6,12 +6,31 @@ export var TypeAheadItemRow = function TypeAheadItemRow(_ref) {
6
6
  Item = _ref.Item,
7
7
  listId = _ref.listId,
8
8
  onItemHover = _ref.onItemHover,
9
+ onItemLeave = _ref.onItemLeave,
10
+ onItemVisibilityChange = _ref.onItemVisibilityChange,
9
11
  registration = _ref.registration,
10
- rowIndex = _ref.rowIndex;
12
+ rowIndex = _ref.rowIndex,
13
+ isVisible = _ref.isVisible;
11
14
  var onMouseMove = useCallback(function () {
12
- return onItemHover(itemIndex);
13
- }, [itemIndex, onItemHover]);
15
+ return onItemHover(itemIndex, registration.key);
16
+ }, [itemIndex, onItemHover, registration.key]);
17
+ var onMouseLeave = useCallback(function () {
18
+ return onItemLeave(registration.key);
19
+ }, [onItemLeave, registration.key]);
20
+ var onBlur = useCallback(function (event) {
21
+ if (!event.currentTarget.contains(event.relatedTarget)) {
22
+ onItemLeave(registration.key);
23
+ }
24
+ }, [onItemLeave, registration.key]);
25
+ useLayoutEffect(function () {
26
+ onItemVisibilityChange(registration.key, isVisible);
27
+ return function () {
28
+ return onItemVisibilityChange(registration.key, false);
29
+ };
30
+ }, [isVisible, onItemVisibilityChange, registration.key]);
14
31
  return /*#__PURE__*/React.createElement("div", {
32
+ onBlur: onBlur,
33
+ onMouseLeave: onMouseLeave,
15
34
  onMouseMove: onMouseMove
16
35
  }, /*#__PURE__*/React.createElement(Item, {
17
36
  id: getTypeAheadItemId(listId, rowIndex),
@@ -26,6 +26,8 @@ export var TypeAheadMenuRenderer = function TypeAheadMenuRenderer(_ref) {
26
26
  maxHeight = _ref.maxHeight,
27
27
  model = _ref.model,
28
28
  onItemHover = _ref.onItemHover,
29
+ onItemLeave = _ref.onItemLeave,
30
+ onItemVisibilityChange = _ref.onItemVisibilityChange,
29
31
  selectedItemIndex = _ref.selectedItemIndex;
30
32
  var intl = useIntl();
31
33
  var listRef = useRef(null);
@@ -97,6 +99,8 @@ export var TypeAheadMenuRenderer = function TypeAheadMenuRenderer(_ref) {
97
99
  Item: Item,
98
100
  listId: listId,
99
101
  onItemHover: onItemHover,
102
+ onItemLeave: onItemLeave,
103
+ onItemVisibilityChange: onItemVisibilityChange,
100
104
  rows: rows,
101
105
  selectedItemIndex: selectedItemIndex
102
106
  });
@@ -11,6 +11,8 @@ export var createTypeAheadRowRenderer = function createTypeAheadRowRenderer(_ref
11
11
  Item = _ref.Item,
12
12
  listId = _ref.listId,
13
13
  onItemHover = _ref.onItemHover,
14
+ onItemLeave = _ref.onItemLeave,
15
+ onItemVisibilityChange = _ref.onItemVisibilityChange,
14
16
  rows = _ref.rows,
15
17
  selectedItemIndex = _ref.selectedItemIndex;
16
18
  return function (_ref2) {
@@ -49,6 +51,9 @@ export var createTypeAheadRowRenderer = function createTypeAheadRowRenderer(_ref
49
51
  itemIndex: itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0,
50
52
  listId: listId,
51
53
  onItemHover: onItemHover,
54
+ onItemLeave: onItemLeave,
55
+ onItemVisibilityChange: onItemVisibilityChange,
56
+ isVisible: isVisible,
52
57
  registration: registration,
53
58
  rowIndex: index
54
59
  }));
@@ -11,18 +11,21 @@ export var TypeAheadQuickInsertItem = function TypeAheadQuickInsertItem(_ref) {
11
11
  var Component = (_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : PassThrough;
12
12
  var contextValue = useMemo(function () {
13
13
  return {
14
+ activePreviewItemKey: quickInsertContext.activePreviewItemKey,
14
15
  editorView: quickInsertContext.editorView,
15
16
  isOffline: quickInsertContext.isOffline,
16
17
  menuOpenId: quickInsertContext.menuOpenId,
18
+ popupsMountPoint: quickInsertContext.popupsMountPoint,
17
19
  surfaceContext: quickInsertContext.surfaceContext,
18
20
  surface: 'typeahead',
19
21
  item: {
20
22
  id: id,
23
+ isPreviewActive: quickInsertContext.activePreviewItemKey === registration.key,
21
24
  isSelected: isSelected
22
25
  },
23
26
  select: quickInsertContext.select
24
27
  };
25
- }, [id, isSelected, quickInsertContext]);
28
+ }, [id, isSelected, quickInsertContext, registration.key]);
26
29
  return /*#__PURE__*/React.createElement(QuickInsertProvider, {
27
30
  value: contextValue
28
31
  }, /*#__PURE__*/React.createElement(Component, null, null));
@@ -7,11 +7,13 @@ import { useTypeAheadContext } from '../useTypeAheadContext';
7
7
  export var TypeAheadQuickInsertProvider = function TypeAheadQuickInsertProvider(_ref) {
8
8
  var children = _ref.children;
9
9
  var _useTypeAheadContext = useTypeAheadContext(),
10
+ activePreviewItemKey = _useTypeAheadContext.activePreviewItemKey,
10
11
  api = _useTypeAheadContext.api,
11
12
  editorView = _useTypeAheadContext.editorView,
12
13
  inputMethod = _useTypeAheadContext.inputMethod,
13
14
  menuOpenId = _useTypeAheadContext.menuOpenId,
14
15
  onClose = _useTypeAheadContext.onClose,
16
+ popupsMountPoint = _useTypeAheadContext.popupsMountPoint,
15
17
  query = _useTypeAheadContext.query,
16
18
  surfaceContext = _useTypeAheadContext.surfaceContext,
17
19
  triggerHandler = _useTypeAheadContext.triggerHandler;
@@ -35,18 +37,21 @@ export var TypeAheadQuickInsertProvider = function TypeAheadQuickInsertProvider(
35
37
  }, [editorView, inputMethod, onClose, query, triggerHandler]);
36
38
  var contextValue = useMemo(function () {
37
39
  return {
40
+ activePreviewItemKey: activePreviewItemKey,
38
41
  editorView: editorView,
39
42
  isOffline: isOffline,
40
43
  menuOpenId: menuOpenId,
44
+ popupsMountPoint: popupsMountPoint,
41
45
  item: {
42
46
  id: 'typeahead-quick-insert',
47
+ isPreviewActive: false,
43
48
  isSelected: false
44
49
  },
45
50
  surface: 'typeahead',
46
51
  select: select,
47
52
  surfaceContext: surfaceContext
48
53
  };
49
- }, [editorView, isOffline, menuOpenId, select, surfaceContext]);
54
+ }, [activePreviewItemKey, editorView, isOffline, menuOpenId, popupsMountPoint, select, surfaceContext]);
50
55
  return /*#__PURE__*/React.createElement(QuickInsertProvider, {
51
56
  value: contextValue
52
57
  }, children);
@@ -5,11 +5,13 @@ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { SurfaceContext } from '@atlaskit/editor-ui-control-model/types';
6
6
  import type { TypeAheadPlugin } from '../../typeAheadPluginType';
7
7
  export type TypeAheadContextValue = {
8
+ activePreviewItemKey?: string;
8
9
  api: ExtractInjectionAPI<TypeAheadPlugin> | undefined;
9
10
  editorView: EditorView;
10
11
  inputMethod: INPUT_METHOD.QUICK_INSERT;
11
12
  menuOpenId: symbol;
12
13
  onClose: () => void;
14
+ popupsMountPoint?: HTMLElement;
13
15
  query: string;
14
16
  surfaceContext: SurfaceContext;
15
17
  triggerHandler: TypeAheadHandler;
@@ -1,12 +1,15 @@
1
1
  import React from 'react';
2
2
  import type { RegisterMenuItem } from '@atlaskit/editor-ui-control-model/types';
3
3
  import type { TypeAheadItemComponent } from './typeAheadMenuTypes';
4
- export declare const TypeAheadItemRow: ({ isSelected, itemIndex, Item, listId, onItemHover, registration, rowIndex, }: {
4
+ export declare const TypeAheadItemRow: ({ isSelected, itemIndex, Item, listId, onItemHover, onItemLeave, onItemVisibilityChange, registration, rowIndex, isVisible, }: {
5
5
  isSelected: boolean;
6
+ isVisible: boolean;
6
7
  Item: TypeAheadItemComponent;
7
8
  itemIndex: number;
8
9
  listId: string;
9
- onItemHover: (itemIndex: number) => void;
10
+ onItemHover: (itemIndex: number, itemKey: string) => void;
11
+ onItemLeave: (itemKey: string) => void;
12
+ onItemVisibilityChange: (itemKey: string, isVisible: boolean) => void;
10
13
  registration: RegisterMenuItem;
11
14
  rowIndex: number;
12
15
  }) => React.JSX.Element;
@@ -8,8 +8,10 @@ type Props = {
8
8
  listLabel: MessageDescriptor;
9
9
  maxHeight: number;
10
10
  model: TypeAheadMenuModel;
11
- onItemHover: (itemIndex: number) => void;
11
+ onItemHover: (itemIndex: number, itemKey?: string) => void;
12
+ onItemLeave: (itemKey: string) => void;
13
+ onItemVisibilityChange: (itemKey: string, isVisible: boolean) => void;
12
14
  selectedItemIndex: number;
13
15
  };
14
- export declare const TypeAheadMenuRenderer: ({ Item, listLabel, listId, maxHeight, model, onItemHover, selectedItemIndex, }: Props) => React.JSX.Element | null;
16
+ export declare const TypeAheadMenuRenderer: ({ Item, listLabel, listId, maxHeight, model, onItemHover, onItemLeave, onItemVisibilityChange, selectedItemIndex, }: Props) => React.JSX.Element | null;
15
17
  export {};
@@ -2,12 +2,14 @@ import type { CellMeasurerCache } from 'react-virtualized/dist/commonjs/CellMeas
2
2
  import type { ListRowRenderer } from 'react-virtualized/dist/commonjs/List';
3
3
  import type { RegisterMenuItem, RegisterMenuSection } from '@atlaskit/editor-ui-control-model/types';
4
4
  import type { TypeAheadItemComponent } from './typeAheadMenuTypes';
5
- export declare const createTypeAheadRowRenderer: ({ cache, onMeasured, itemIndexByRowIndex, Item, listId, onItemHover, rows, selectedItemIndex, }: {
5
+ export declare const createTypeAheadRowRenderer: ({ cache, onMeasured, itemIndexByRowIndex, Item, listId, onItemHover, onItemLeave, onItemVisibilityChange, rows, selectedItemIndex, }: {
6
6
  cache: CellMeasurerCache;
7
7
  Item: TypeAheadItemComponent;
8
8
  itemIndexByRowIndex: Map<number, number>;
9
9
  listId: string;
10
- onItemHover: (itemIndex: number) => void;
10
+ onItemHover: (itemIndex: number, itemKey: string) => void;
11
+ onItemLeave: (itemKey: string) => void;
12
+ onItemVisibilityChange: (itemKey: string, isVisible: boolean) => void;
11
13
  onMeasured: () => void;
12
14
  rows: Array<RegisterMenuItem | RegisterMenuSection>;
13
15
  selectedItemIndex: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-type-ahead",
3
- "version": "25.0.0",
3
+ "version": "25.0.2",
4
4
  "description": "Type-ahead plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -35,15 +35,15 @@
35
35
  "@atlaskit/heading": "^8.0.0",
36
36
  "@atlaskit/icon": "^38.0.0",
37
37
  "@atlaskit/insm": "^3.0.0",
38
- "@atlaskit/mention": "^30.0.0",
38
+ "@atlaskit/mention": "^30.1.0",
39
39
  "@atlaskit/menu": "^11.0.0",
40
40
  "@atlaskit/platform-feature-experiments": "^0.3.0",
41
41
  "@atlaskit/platform-feature-flags": "^2.2.0",
42
42
  "@atlaskit/primitives": "^22.5.0",
43
43
  "@atlaskit/prosemirror-history": "^1.3.0",
44
44
  "@atlaskit/prosemirror-input-rules": "^4.1.0",
45
- "@atlaskit/tmp-editor-statsig": "^220.0.0",
46
- "@atlaskit/tokens": "^20.1.0",
45
+ "@atlaskit/tmp-editor-statsig": "^221.0.0",
46
+ "@atlaskit/tokens": "^20.2.0",
47
47
  "@atlaskit/visually-hidden": "^4.4.0",
48
48
  "@babel/runtime": "^7.0.0",
49
49
  "@emotion/react": "^11.7.1",
@@ -54,7 +54,7 @@
54
54
  "w3c-keyname": "^2.1.8"
55
55
  },
56
56
  "peerDependencies": {
57
- "@atlaskit/editor-common": "^128.0.0",
57
+ "@atlaskit/editor-common": "^128.2.0",
58
58
  "react": "^18.2.0 || ^19.2.0",
59
59
  "react-dom": "^18.2.0 || ^19.2.0",
60
60
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"