@atlaskit/editor-plugin-insert-block 20.0.3 → 20.0.5

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @atlaskit/editor-plugin-insert-block
2
2
 
3
+ ## 20.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 20.0.4
10
+
11
+ ### Patch Changes
12
+
13
+ - [`a1df9dd2d8f02`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a1df9dd2d8f02) -
14
+ Add the optional `showNoResultsMessage` empty-state handler parameter and
15
+ `platform_editor_slash_command`-gated Ask Rovo and View more recovery for registered quick insert
16
+ searches with no matches. Respect registry visibility and keep Marketplace content separate from
17
+ listbox navigation while preserving its native keyboard controls.
18
+
19
+ Show the registered Ask Rovo action alongside Marketplace suggestions in the element browser's
20
+ no-match state, with a divider separating the fallback action from Marketplace content. Keep the
21
+ toolbar's View more footer visible while Marketplace content scrolls and preserve native Tab
22
+ navigation.
23
+
24
+ Respect `data-keyboard-navigation-independent` containers in both toolbar keyboard navigation
25
+ providers. Apply the attribute to the registered insert menu, whose rendering is gated by
26
+ `platform_editor_slash_command`, so its controls retain their own key handling and native tab
27
+ stops.
28
+
29
+ - Updated dependencies
30
+
3
31
  ## 20.0.3
4
32
 
5
33
  ### Patch Changes
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", {
9
9
  exports.RegisteredInsertMenu = void 0;
10
10
  require("./RegisteredInsertMenu.compiled.css");
11
11
  var _runtime = require("@compiled/react/runtime");
12
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
12
13
  var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
13
14
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
15
  var _react = _interopRequireWildcard(require("react"));
@@ -32,6 +33,7 @@ var styles = {
32
33
  };
33
34
  var RegisteredInsertMenu = exports.RegisteredInsertMenu = function RegisteredInsertMenu(_ref) {
34
35
  var components = _ref.components,
36
+ emptyStateHandler = _ref.emptyStateHandler,
35
37
  editorView = _ref.editorView,
36
38
  isOffline = _ref.isOffline,
37
39
  onClose = _ref.onClose,
@@ -59,6 +61,7 @@ var RegisteredInsertMenu = exports.RegisteredInsertMenu = function RegisteredIns
59
61
  _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
60
62
  renderedItems = _useState8[0],
61
63
  setRenderedItems = _useState8[1];
64
+ var searchRef = (0, _react.useRef)(null);
62
65
  var surfaceContext = (0, _react.useMemo)(function () {
63
66
  return (0, _createSurfaceContext.createSurfaceContext)(_typeAheadSurfaceContext.TYPE_AHEAD_SURFACE_CONTEXT, {
64
67
  menuOpenId: menuOpenId
@@ -80,12 +83,29 @@ var RegisteredInsertMenu = exports.RegisteredInsertMenu = function RegisteredIns
80
83
  });
81
84
  }, [components, formatMessage, hasSectionOverflowItems, query, surfaceContext]);
82
85
  var itemCount = (0, _react.useMemo)(function () {
86
+ var _model$fallbackItems$, _model$fallbackItems;
83
87
  return model.sections.reduce(function (count, _ref3) {
84
88
  var _ref4 = (0, _toArray2.default)(_ref3),
85
89
  items = _arrayLikeToArray(_ref4).slice(1);
86
90
  return count + items.length;
87
- }, 0) + (model.footer ? 1 : 0);
88
- }, [model.footer, model.sections]);
91
+ }, 0) + ((_model$fallbackItems$ = (_model$fallbackItems = model.fallbackItems) === null || _model$fallbackItems === void 0 ? void 0 : _model$fallbackItems.length) !== null && _model$fallbackItems$ !== void 0 ? _model$fallbackItems$ : 0) + (model.footer ? 1 : 0);
92
+ }, [model.fallbackItems, model.footer, model.sections]);
93
+ var selectableItemKeys = (0, _react.useMemo)(function () {
94
+ var _model$fallbackItems2;
95
+ return [].concat((0, _toConsumableArray2.default)(model.sections.flatMap(function (_ref5) {
96
+ var _ref6 = (0, _toArray2.default)(_ref5),
97
+ items = _arrayLikeToArray(_ref6).slice(1);
98
+ return items;
99
+ })), (0, _toConsumableArray2.default)((_model$fallbackItems2 = model.fallbackItems) !== null && _model$fallbackItems2 !== void 0 ? _model$fallbackItems2 : []), [model.footer]).filter(function (item) {
100
+ return Boolean(item);
101
+ }).map(function (_ref7) {
102
+ var key = _ref7.key;
103
+ return key;
104
+ }).join(',');
105
+ }, [model.fallbackItems, model.footer, model.sections]);
106
+ (0, _react.useLayoutEffect)(function () {
107
+ setSelectedItemIndex(itemCount > 0 ? 0 : -1);
108
+ }, [itemCount, query, selectableItemKeys]);
89
109
  var isActiveItemMounted = selectedItemIndex >= 0 && selectedItemIndex < itemCount && (selectedItemIndex >= renderedItems.startIndex && selectedItemIndex <= renderedItems.stopIndex || Boolean(model.footer) && selectedItemIndex === itemCount - 1);
90
110
  var activeItemId = "".concat(listId, "-").concat(selectedItemIndex);
91
111
  var selectNextItem = (0, _react.useCallback)(function () {
@@ -109,6 +129,18 @@ var RegisteredInsertMenu = exports.RegisteredInsertMenu = function RegisteredIns
109
129
  setSelectedItemIndex(0);
110
130
  }, []);
111
131
  var onKeyDown = (0, _react.useCallback)(function (event) {
132
+ if (event.key === 'Escape') {
133
+ event.preventDefault();
134
+ onClose();
135
+ return;
136
+ }
137
+
138
+ // The search field owns the composite's arrow-key and Enter behaviour. Other
139
+ // focusable controls, including consumer-provided empty-state content, need
140
+ // to retain their native keyboard behaviour.
141
+ if (event.target !== searchRef.current) {
142
+ return;
143
+ }
112
144
  switch (event.key) {
113
145
  case 'ArrowDown':
114
146
  event.preventDefault();
@@ -122,14 +154,10 @@ var RegisteredInsertMenu = exports.RegisteredInsertMenu = function RegisteredIns
122
154
  event.preventDefault();
123
155
  selectActiveItem();
124
156
  break;
125
- case 'Escape':
126
- event.preventDefault();
127
- onClose();
128
- break;
129
157
  }
130
158
  }, [onClose, selectActiveItem, selectNextItem, selectPreviousItem]);
131
159
  return /*#__PURE__*/_react.default.createElement(_compiled.Box, {
132
- "data-registered-insert-menu": "",
160
+ "data-keyboard-navigation-independent": "",
133
161
  testId: "registered-insert-menu",
134
162
  onKeyDownCapture: onKeyDown,
135
163
  xcss: styles.menu
@@ -141,11 +169,13 @@ var RegisteredInsertMenu = exports.RegisteredInsertMenu = function RegisteredIns
141
169
  "aria-expanded": "true",
142
170
  autoFocus: true,
143
171
  placeholder: "Search",
172
+ ref: searchRef,
144
173
  role: "combobox",
145
174
  value: query,
146
175
  onChange: onQueryChange
147
176
  })), /*#__PURE__*/_react.default.createElement(_RegisteredInsertMenuList.RegisteredInsertMenuList, {
148
177
  editorView: editorView,
178
+ emptyStateHandler: emptyStateHandler,
149
179
  isOffline: isOffline,
150
180
  listId: listId,
151
181
  listLabel: formatMessage(_messages.toolbarInsertBlockMessages.insertMenu),
@@ -155,6 +185,7 @@ var RegisteredInsertMenu = exports.RegisteredInsertMenu = function RegisteredIns
155
185
  onClose: onSelect,
156
186
  onItemHover: setSelectedItemIndex,
157
187
  onRenderedItemsChange: setRenderedItems,
188
+ query: query,
158
189
  selectedItemIndex: selectedItemIndex,
159
190
  surfaceContext: surfaceContext
160
191
  }));
@@ -21,6 +21,7 @@ var RegisteredInsertMenuContainer = function RegisteredInsertMenuContainer(_ref)
21
21
  };
22
22
  var RegisteredInsertMenuWithListeners = (0, _ui.withOuterListeners)(RegisteredInsertMenuContainer);
23
23
  var RegisteredInsertMenuContent = exports.RegisteredInsertMenuContent = function RegisteredInsertMenuContent(_ref2) {
24
+ var _api$quickInsert;
24
25
  var api = _ref2.api,
25
26
  editorView = _ref2.editorView,
26
27
  isOffline = _ref2.isOffline,
@@ -46,6 +47,7 @@ var RegisteredInsertMenuContent = exports.RegisteredInsertMenuContent = function
46
47
  }, /*#__PURE__*/_react.default.createElement(_RegisteredInsertMenu.RegisteredInsertMenu, {
47
48
  components: components,
48
49
  editorView: editorView,
50
+ emptyStateHandler: api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || (_api$quickInsert = _api$quickInsert.sharedState.currentState()) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.emptyStateHandler,
49
51
  isOffline: isOffline,
50
52
  onClose: onClose,
51
53
  onSelect: onSelect
@@ -1,4 +1,9 @@
1
1
  ._1rjc1b66{padding-block:var(--ds-space-050,4px)}._15a5nqa1{border-top-style:solid}
2
+ ._16jlkb7n{flex-grow:1}
3
+ ._18m91wug{overflow-y:auto}
4
+ ._1e0c1txw{display:flex}
2
5
  ._1i531l7x{border-top-color:var(--ds-border,#0b120e24)}
3
6
  ._1o9zidpf{flex-shrink:0}
7
+ ._1tkeidpf{min-height:0}
8
+ ._2lx21bp4{flex-direction:column}
4
9
  ._uwhke4h9{border-top-width:var(--ds-border-width,1px)}
@@ -10,8 +10,8 @@ exports.RegisteredInsertMenuList = void 0;
10
10
  require("./RegisteredInsertMenuList.compiled.css");
11
11
  var _runtime = require("@compiled/react/runtime");
12
12
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
13
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
14
13
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
15
15
  var _react = _interopRequireWildcard(require("react"));
16
16
  var _CellMeasurer = require("react-virtualized/dist/commonjs/CellMeasurer");
17
17
  var _List = require("react-virtualized/dist/commonjs/List");
@@ -30,11 +30,14 @@ var listAriaProps = {
30
30
  'aria-readonly': null
31
31
  };
32
32
  var styles = {
33
+ content: "_1e0c1txw _2lx21bp4 _1tkeidpf",
34
+ scrollable: "_16jlkb7n _1tkeidpf _18m91wug",
33
35
  footer: "_1rjc1b66 _1i531l7x _15a5nqa1 _uwhke4h9 _1o9zidpf"
34
36
  };
35
37
  var RegisteredInsertMenuList = exports.RegisteredInsertMenuList = function RegisteredInsertMenuList(_ref) {
36
38
  var _model$root$component, _model$root;
37
39
  var editorView = _ref.editorView,
40
+ emptyStateHandler = _ref.emptyStateHandler,
38
41
  isOffline = _ref.isOffline,
39
42
  listId = _ref.listId,
40
43
  listLabel = _ref.listLabel,
@@ -42,15 +45,20 @@ var RegisteredInsertMenuList = exports.RegisteredInsertMenuList = function Regis
42
45
  menuOpenId = _ref.menuOpenId,
43
46
  model = _ref.model,
44
47
  onClose = _ref.onClose,
48
+ query = _ref.query,
45
49
  onItemHover = _ref.onItemHover,
46
50
  onRenderedItemsChange = _ref.onRenderedItemsChange,
47
51
  selectedItemIndex = _ref.selectedItemIndex,
48
52
  surfaceContext = _ref.surfaceContext;
49
53
  var Root = (_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 : _react.default.Fragment;
50
54
  var listRef = (0, _react.useRef)(null);
55
+ var setListRef = (0, _react.useCallback)(function (list) {
56
+ listRef.current = list;
57
+ }, []);
51
58
  var rows = (0, _react.useMemo)(function () {
52
- return model.sections.flat();
53
- }, [model.sections]);
59
+ var _model$fallbackItems;
60
+ return [].concat((0, _toConsumableArray2.default)(model.sections.flat()), (0, _toConsumableArray2.default)((_model$fallbackItems = model.fallbackItems) !== null && _model$fallbackItems !== void 0 ? _model$fallbackItems : []));
61
+ }, [model.fallbackItems, model.sections]);
54
62
  var cache = (0, _react.useMemo)(function () {
55
63
  return new _CellMeasurer.CellMeasurerCache({
56
64
  defaultHeight: ESTIMATED_ROW_HEIGHT,
@@ -129,6 +137,9 @@ var RegisteredInsertMenuList = exports.RegisteredInsertMenuList = function Regis
129
137
  }
130
138
  var itemIndex = itemIndexByRowIndex.get(index);
131
139
  var rowContent = registration.type === 'menu-section' ? ( /*#__PURE__*/_react.default.createElement((_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : _react.default.Fragment, null, null)) : /*#__PURE__*/_react.default.createElement("div", {
140
+ onFocus: function onFocus() {
141
+ return onItemHover(itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0);
142
+ },
132
143
  onMouseMove: function onMouseMove() {
133
144
  return onItemHover(itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0);
134
145
  }
@@ -153,8 +164,7 @@ var RegisteredInsertMenuList = exports.RegisteredInsertMenuList = function Regis
153
164
  return /*#__PURE__*/_react.default.createElement("div", {
154
165
  ref: function ref(element) {
155
166
  return registerChild === null || registerChild === void 0 ? void 0 : registerChild(element !== null && element !== void 0 ? element : undefined);
156
- },
157
- "data-index": index
167
+ }
158
168
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
159
169
  ,
160
170
  style: style
@@ -162,15 +172,40 @@ var RegisteredInsertMenuList = exports.RegisteredInsertMenuList = function Regis
162
172
  });
163
173
  }, [cache, editorView, isOffline, itemIndexByRowIndex, listId, menuOpenId, onClose, onItemHover, rows, selectedItemIndex, surfaceContext]);
164
174
  var footerItemIndex = itemIndexByRowIndex.size;
175
+ var footerItemId = "".concat(listId, "-").concat(footerItemIndex);
176
+ var hasExternalControls = model.fallbackItems !== undefined && emptyStateHandler !== undefined;
165
177
  var listMaxHeight = Math.max(0, maxHeight - MENU_SEARCH_HEIGHT - (model.footer ? MENU_FOOTER_HEIGHT : 0));
178
+ var contentStyle = {
179
+ maxHeight: Math.max(0, maxHeight - MENU_SEARCH_HEIGHT)
180
+ };
166
181
  var onFooterItemHover = (0, _react.useCallback)(function () {
167
182
  return onItemHover(footerItemIndex);
168
183
  }, [footerItemIndex, onItemHover]);
184
+ var footer = model.footer ? /*#__PURE__*/_react.default.createElement(_compiled.Box, {
185
+ xcss: styles.footer,
186
+ onFocus: onFooterItemHover,
187
+ onMouseMove: onFooterItemHover
188
+ }, /*#__PURE__*/_react.default.createElement(_RegisteredInsertMenuItem.RegisteredInsertMenuItem, {
189
+ editorView: editorView,
190
+ id: footerItemId,
191
+ isOffline: isOffline,
192
+ isSelected: footerItemIndex === selectedItemIndex,
193
+ menuOpenId: menuOpenId,
194
+ onClose: onClose,
195
+ registration: model.footer,
196
+ surfaceContext: surfaceContext
197
+ })) : null;
169
198
  if (!model.root) {
170
199
  return null;
171
200
  }
172
201
  return /*#__PURE__*/_react.default.createElement(Root, null, /*#__PURE__*/_react.default.createElement(_compiled.Box, {
202
+ xcss: styles.content,
203
+ style: contentStyle
204
+ }, /*#__PURE__*/_react.default.createElement(_compiled.Box, {
205
+ xcss: styles.scrollable
206
+ }, /*#__PURE__*/_react.default.createElement(_compiled.Box, {
173
207
  "aria-label": listLabel,
208
+ "aria-owns": model.footer ? footerItemId : undefined,
174
209
  id: listId,
175
210
  role: "listbox"
176
211
  }, rows.length > 0 && /*#__PURE__*/_react.default.createElement(_List.List
@@ -181,7 +216,7 @@ var RegisteredInsertMenuList = exports.RegisteredInsertMenuList = function Regis
181
216
  height: Math.min(rows.length * ESTIMATED_ROW_HEIGHT, listMaxHeight),
182
217
  overscanRowCount: 3,
183
218
  onRowsRendered: onRowsRendered,
184
- ref: listRef,
219
+ ref: setListRef,
185
220
  role: "group",
186
221
  rowCount: rows.length,
187
222
  rowHeight: cache.rowHeight,
@@ -189,17 +224,9 @@ var RegisteredInsertMenuList = exports.RegisteredInsertMenuList = function Regis
189
224
  scrollToAlignment: "auto",
190
225
  scrollToIndex: selectedRowIndex,
191
226
  width: LIST_WIDTH
192
- })), model.footer && /*#__PURE__*/_react.default.createElement(_compiled.Box, {
193
- xcss: styles.footer,
194
- onMouseMove: onFooterItemHover
195
- }, /*#__PURE__*/_react.default.createElement(_RegisteredInsertMenuItem.RegisteredInsertMenuItem, {
196
- editorView: editorView,
197
- id: "".concat(listId, "-").concat(footerItemIndex),
198
- isOffline: isOffline,
199
- isSelected: footerItemIndex === selectedItemIndex,
200
- menuOpenId: menuOpenId,
201
- onClose: onClose,
202
- registration: model.footer,
203
- surfaceContext: surfaceContext
204
- }))));
227
+ }))), hasExternalControls && /*#__PURE__*/_react.default.createElement(_compiled.Box, null, emptyStateHandler({
228
+ mode: 'inline',
229
+ searchTerm: query,
230
+ showNoResultsMessage: false
231
+ }))), footer));
205
232
  };
@@ -1,7 +1,7 @@
1
1
  /* RegisteredInsertMenu.tsx generated by @compiled/babel-plugin v3.0.2 */
2
2
  import "./RegisteredInsertMenu.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
- import React, { useCallback, useId, useMemo, useState } from 'react';
4
+ import React, { useCallback, useId, useLayoutEffect, useMemo, useRef, useState } from 'react';
5
5
  import { useIntl } from 'react-intl';
6
6
  import { getDocument } from '@atlaskit/browser-apis';
7
7
  import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
@@ -20,6 +20,7 @@ const styles = {
20
20
  };
21
21
  export const RegisteredInsertMenu = ({
22
22
  components,
23
+ emptyStateHandler,
23
24
  editorView,
24
25
  isOffline,
25
26
  onClose,
@@ -36,6 +37,7 @@ export const RegisteredInsertMenu = ({
36
37
  startIndex: -1,
37
38
  stopIndex: -1
38
39
  });
40
+ const searchRef = useRef(null);
39
41
  const surfaceContext = useMemo(() => createSurfaceContext(TYPE_AHEAD_SURFACE_CONTEXT, {
40
42
  menuOpenId
41
43
  }), [menuOpenId]);
@@ -49,7 +51,19 @@ export const RegisteredInsertMenu = ({
49
51
  rootComponent: MENU,
50
52
  surfaceContext
51
53
  }), [components, formatMessage, hasSectionOverflowItems, query, surfaceContext]);
52
- const itemCount = useMemo(() => model.sections.reduce((count, [, ...items]) => count + items.length, 0) + (model.footer ? 1 : 0), [model.footer, model.sections]);
54
+ const itemCount = useMemo(() => {
55
+ var _model$fallbackItems$, _model$fallbackItems;
56
+ return model.sections.reduce((count, [, ...items]) => count + items.length, 0) + ((_model$fallbackItems$ = (_model$fallbackItems = model.fallbackItems) === null || _model$fallbackItems === void 0 ? void 0 : _model$fallbackItems.length) !== null && _model$fallbackItems$ !== void 0 ? _model$fallbackItems$ : 0) + (model.footer ? 1 : 0);
57
+ }, [model.fallbackItems, model.footer, model.sections]);
58
+ const selectableItemKeys = useMemo(() => {
59
+ var _model$fallbackItems2;
60
+ return [...model.sections.flatMap(([, ...items]) => items), ...((_model$fallbackItems2 = model.fallbackItems) !== null && _model$fallbackItems2 !== void 0 ? _model$fallbackItems2 : []), model.footer].filter(item => Boolean(item)).map(({
61
+ key
62
+ }) => key).join(',');
63
+ }, [model.fallbackItems, model.footer, model.sections]);
64
+ useLayoutEffect(() => {
65
+ setSelectedItemIndex(itemCount > 0 ? 0 : -1);
66
+ }, [itemCount, query, selectableItemKeys]);
53
67
  const isActiveItemMounted = selectedItemIndex >= 0 && selectedItemIndex < itemCount && (selectedItemIndex >= renderedItems.startIndex && selectedItemIndex <= renderedItems.stopIndex || Boolean(model.footer) && selectedItemIndex === itemCount - 1);
54
68
  const activeItemId = `${listId}-${selectedItemIndex}`;
55
69
  const selectNextItem = useCallback(() => {
@@ -69,6 +83,18 @@ export const RegisteredInsertMenu = ({
69
83
  setSelectedItemIndex(0);
70
84
  }, []);
71
85
  const onKeyDown = useCallback(event => {
86
+ if (event.key === 'Escape') {
87
+ event.preventDefault();
88
+ onClose();
89
+ return;
90
+ }
91
+
92
+ // The search field owns the composite's arrow-key and Enter behaviour. Other
93
+ // focusable controls, including consumer-provided empty-state content, need
94
+ // to retain their native keyboard behaviour.
95
+ if (event.target !== searchRef.current) {
96
+ return;
97
+ }
72
98
  switch (event.key) {
73
99
  case 'ArrowDown':
74
100
  event.preventDefault();
@@ -82,14 +108,10 @@ export const RegisteredInsertMenu = ({
82
108
  event.preventDefault();
83
109
  selectActiveItem();
84
110
  break;
85
- case 'Escape':
86
- event.preventDefault();
87
- onClose();
88
- break;
89
111
  }
90
112
  }, [onClose, selectActiveItem, selectNextItem, selectPreviousItem]);
91
113
  return /*#__PURE__*/React.createElement(Box, {
92
- "data-registered-insert-menu": "",
114
+ "data-keyboard-navigation-independent": "",
93
115
  testId: "registered-insert-menu",
94
116
  onKeyDownCapture: onKeyDown,
95
117
  xcss: styles.menu
@@ -101,11 +123,13 @@ export const RegisteredInsertMenu = ({
101
123
  "aria-expanded": "true",
102
124
  autoFocus: true,
103
125
  placeholder: "Search",
126
+ ref: searchRef,
104
127
  role: "combobox",
105
128
  value: query,
106
129
  onChange: onQueryChange
107
130
  })), /*#__PURE__*/React.createElement(RegisteredInsertMenuList, {
108
131
  editorView: editorView,
132
+ emptyStateHandler: emptyStateHandler,
109
133
  isOffline: isOffline,
110
134
  listId: listId,
111
135
  listLabel: formatMessage(messages.insertMenu),
@@ -115,6 +139,7 @@ export const RegisteredInsertMenu = ({
115
139
  onClose: onSelect,
116
140
  onItemHover: setSelectedItemIndex,
117
141
  onRenderedItemsChange: setRenderedItems,
142
+ query: query,
118
143
  selectedItemIndex: selectedItemIndex,
119
144
  surfaceContext: surfaceContext
120
145
  }));
@@ -20,6 +20,7 @@ export const RegisteredInsertMenuContent = ({
20
20
  onSelect,
21
21
  target
22
22
  }) => {
23
+ var _api$quickInsert, _api$quickInsert$shar;
23
24
  // Keep registrations stable while the open menu is searched or navigated.
24
25
  const [components] = useState(() => {
25
26
  var _api$uiControlRegistr, _api$uiControlRegistr2;
@@ -36,6 +37,7 @@ export const RegisteredInsertMenuContent = ({
36
37
  }, /*#__PURE__*/React.createElement(RegisteredInsertMenu, {
37
38
  components: components,
38
39
  editorView: editorView,
40
+ emptyStateHandler: api === null || api === void 0 ? void 0 : (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 ? void 0 : (_api$quickInsert$shar = _api$quickInsert.sharedState.currentState()) === null || _api$quickInsert$shar === void 0 ? void 0 : _api$quickInsert$shar.emptyStateHandler,
39
41
  isOffline: isOffline,
40
42
  onClose: onClose,
41
43
  onSelect: onSelect
@@ -1,4 +1,9 @@
1
1
  ._1rjc1b66{padding-block:var(--ds-space-050,4px)}._15a5nqa1{border-top-style:solid}
2
+ ._16jlkb7n{flex-grow:1}
3
+ ._18m91wug{overflow-y:auto}
4
+ ._1e0c1txw{display:flex}
2
5
  ._1i531l7x{border-top-color:var(--ds-border,#0b120e24)}
3
6
  ._1o9zidpf{flex-shrink:0}
7
+ ._1tkeidpf{min-height:0}
8
+ ._2lx21bp4{flex-direction:column}
4
9
  ._uwhke4h9{border-top-width:var(--ds-border-width,1px)}
@@ -16,10 +16,13 @@ const listAriaProps = {
16
16
  'aria-readonly': null
17
17
  };
18
18
  const styles = {
19
+ content: "_1e0c1txw _2lx21bp4 _1tkeidpf",
20
+ scrollable: "_16jlkb7n _1tkeidpf _18m91wug",
19
21
  footer: "_1rjc1b66 _1i531l7x _15a5nqa1 _uwhke4h9 _1o9zidpf"
20
22
  };
21
23
  export const RegisteredInsertMenuList = ({
22
24
  editorView,
25
+ emptyStateHandler,
23
26
  isOffline,
24
27
  listId,
25
28
  listLabel,
@@ -27,6 +30,7 @@ export const RegisteredInsertMenuList = ({
27
30
  menuOpenId,
28
31
  model,
29
32
  onClose,
33
+ query,
30
34
  onItemHover,
31
35
  onRenderedItemsChange,
32
36
  selectedItemIndex,
@@ -35,7 +39,13 @@ export const RegisteredInsertMenuList = ({
35
39
  var _model$root$component, _model$root;
36
40
  const Root = (_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 : React.Fragment;
37
41
  const listRef = useRef(null);
38
- const rows = useMemo(() => model.sections.flat(), [model.sections]);
42
+ const setListRef = useCallback(list => {
43
+ listRef.current = list;
44
+ }, []);
45
+ const rows = useMemo(() => {
46
+ var _model$fallbackItems;
47
+ return [...model.sections.flat(), ...((_model$fallbackItems = model.fallbackItems) !== null && _model$fallbackItems !== void 0 ? _model$fallbackItems : [])];
48
+ }, [model.fallbackItems, model.sections]);
39
49
  const cache = useMemo(() => new CellMeasurerCache({
40
50
  defaultHeight: ESTIMATED_ROW_HEIGHT,
41
51
  fixedWidth: true
@@ -92,6 +102,7 @@ export const RegisteredInsertMenuList = ({
92
102
  }
93
103
  const itemIndex = itemIndexByRowIndex.get(index);
94
104
  const rowContent = registration.type === 'menu-section' ? ( /*#__PURE__*/React.createElement((_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : React.Fragment, null, null)) : /*#__PURE__*/React.createElement("div", {
105
+ onFocus: () => onItemHover(itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0),
95
106
  onMouseMove: () => onItemHover(itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0)
96
107
  }, /*#__PURE__*/React.createElement(RegisteredInsertMenuItem, {
97
108
  editorView: editorView,
@@ -112,21 +123,45 @@ export const RegisteredInsertMenuList = ({
112
123
  }, ({
113
124
  registerChild
114
125
  }) => /*#__PURE__*/React.createElement("div", {
115
- ref: element => registerChild === null || registerChild === void 0 ? void 0 : registerChild(element !== null && element !== void 0 ? element : undefined),
116
- "data-index": index
126
+ ref: element => registerChild === null || registerChild === void 0 ? void 0 : registerChild(element !== null && element !== void 0 ? element : undefined)
117
127
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
118
128
  ,
119
129
  style: style
120
130
  }, rowContent));
121
131
  }, [cache, editorView, isOffline, itemIndexByRowIndex, listId, menuOpenId, onClose, onItemHover, rows, selectedItemIndex, surfaceContext]);
122
132
  const footerItemIndex = itemIndexByRowIndex.size;
133
+ const footerItemId = `${listId}-${footerItemIndex}`;
134
+ const hasExternalControls = model.fallbackItems !== undefined && emptyStateHandler !== undefined;
123
135
  const listMaxHeight = Math.max(0, maxHeight - MENU_SEARCH_HEIGHT - (model.footer ? MENU_FOOTER_HEIGHT : 0));
136
+ const contentStyle = {
137
+ maxHeight: Math.max(0, maxHeight - MENU_SEARCH_HEIGHT)
138
+ };
124
139
  const onFooterItemHover = useCallback(() => onItemHover(footerItemIndex), [footerItemIndex, onItemHover]);
140
+ const footer = model.footer ? /*#__PURE__*/React.createElement(Box, {
141
+ xcss: styles.footer,
142
+ onFocus: onFooterItemHover,
143
+ onMouseMove: onFooterItemHover
144
+ }, /*#__PURE__*/React.createElement(RegisteredInsertMenuItem, {
145
+ editorView: editorView,
146
+ id: footerItemId,
147
+ isOffline: isOffline,
148
+ isSelected: footerItemIndex === selectedItemIndex,
149
+ menuOpenId: menuOpenId,
150
+ onClose: onClose,
151
+ registration: model.footer,
152
+ surfaceContext: surfaceContext
153
+ })) : null;
125
154
  if (!model.root) {
126
155
  return null;
127
156
  }
128
157
  return /*#__PURE__*/React.createElement(Root, null, /*#__PURE__*/React.createElement(Box, {
158
+ xcss: styles.content,
159
+ style: contentStyle
160
+ }, /*#__PURE__*/React.createElement(Box, {
161
+ xcss: styles.scrollable
162
+ }, /*#__PURE__*/React.createElement(Box, {
129
163
  "aria-label": listLabel,
164
+ "aria-owns": model.footer ? footerItemId : undefined,
130
165
  id: listId,
131
166
  role: "listbox"
132
167
  }, rows.length > 0 && /*#__PURE__*/React.createElement(List
@@ -137,7 +172,7 @@ export const RegisteredInsertMenuList = ({
137
172
  height: Math.min(rows.length * ESTIMATED_ROW_HEIGHT, listMaxHeight),
138
173
  overscanRowCount: 3,
139
174
  onRowsRendered: onRowsRendered,
140
- ref: listRef,
175
+ ref: setListRef,
141
176
  role: "group",
142
177
  rowCount: rows.length,
143
178
  rowHeight: cache.rowHeight,
@@ -145,17 +180,9 @@ export const RegisteredInsertMenuList = ({
145
180
  scrollToAlignment: "auto",
146
181
  scrollToIndex: selectedRowIndex,
147
182
  width: LIST_WIDTH
148
- })), model.footer && /*#__PURE__*/React.createElement(Box, {
149
- xcss: styles.footer,
150
- onMouseMove: onFooterItemHover
151
- }, /*#__PURE__*/React.createElement(RegisteredInsertMenuItem, {
152
- editorView: editorView,
153
- id: `${listId}-${footerItemIndex}`,
154
- isOffline: isOffline,
155
- isSelected: footerItemIndex === selectedItemIndex,
156
- menuOpenId: menuOpenId,
157
- onClose: onClose,
158
- registration: model.footer,
159
- surfaceContext: surfaceContext
160
- }))));
183
+ }))), hasExternalControls && /*#__PURE__*/React.createElement(Box, null, emptyStateHandler({
184
+ mode: 'inline',
185
+ searchTerm: query,
186
+ showNoResultsMessage: false
187
+ }))), footer));
161
188
  };
@@ -1,10 +1,11 @@
1
1
  /* RegisteredInsertMenu.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
3
  import _toArray from "@babel/runtime/helpers/toArray";
3
4
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
5
  import "./RegisteredInsertMenu.compiled.css";
5
6
  import { ax, ix } from "@compiled/react/runtime";
6
7
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
- import React, { useCallback, useId, useMemo, useState } from 'react';
8
+ import React, { useCallback, useId, useLayoutEffect, useMemo, useRef, useState } from 'react';
8
9
  import { useIntl } from 'react-intl';
9
10
  import { getDocument } from '@atlaskit/browser-apis';
10
11
  import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
@@ -23,6 +24,7 @@ var styles = {
23
24
  };
24
25
  export var RegisteredInsertMenu = function RegisteredInsertMenu(_ref) {
25
26
  var components = _ref.components,
27
+ emptyStateHandler = _ref.emptyStateHandler,
26
28
  editorView = _ref.editorView,
27
29
  isOffline = _ref.isOffline,
28
30
  onClose = _ref.onClose,
@@ -50,6 +52,7 @@ export var RegisteredInsertMenu = function RegisteredInsertMenu(_ref) {
50
52
  _useState8 = _slicedToArray(_useState7, 2),
51
53
  renderedItems = _useState8[0],
52
54
  setRenderedItems = _useState8[1];
55
+ var searchRef = useRef(null);
53
56
  var surfaceContext = useMemo(function () {
54
57
  return createSurfaceContext(TYPE_AHEAD_SURFACE_CONTEXT, {
55
58
  menuOpenId: menuOpenId
@@ -71,12 +74,29 @@ export var RegisteredInsertMenu = function RegisteredInsertMenu(_ref) {
71
74
  });
72
75
  }, [components, formatMessage, hasSectionOverflowItems, query, surfaceContext]);
73
76
  var itemCount = useMemo(function () {
77
+ var _model$fallbackItems$, _model$fallbackItems;
74
78
  return model.sections.reduce(function (count, _ref3) {
75
79
  var _ref4 = _toArray(_ref3),
76
80
  items = _arrayLikeToArray(_ref4).slice(1);
77
81
  return count + items.length;
78
- }, 0) + (model.footer ? 1 : 0);
79
- }, [model.footer, model.sections]);
82
+ }, 0) + ((_model$fallbackItems$ = (_model$fallbackItems = model.fallbackItems) === null || _model$fallbackItems === void 0 ? void 0 : _model$fallbackItems.length) !== null && _model$fallbackItems$ !== void 0 ? _model$fallbackItems$ : 0) + (model.footer ? 1 : 0);
83
+ }, [model.fallbackItems, model.footer, model.sections]);
84
+ var selectableItemKeys = useMemo(function () {
85
+ var _model$fallbackItems2;
86
+ return [].concat(_toConsumableArray(model.sections.flatMap(function (_ref5) {
87
+ var _ref6 = _toArray(_ref5),
88
+ items = _arrayLikeToArray(_ref6).slice(1);
89
+ return items;
90
+ })), _toConsumableArray((_model$fallbackItems2 = model.fallbackItems) !== null && _model$fallbackItems2 !== void 0 ? _model$fallbackItems2 : []), [model.footer]).filter(function (item) {
91
+ return Boolean(item);
92
+ }).map(function (_ref7) {
93
+ var key = _ref7.key;
94
+ return key;
95
+ }).join(',');
96
+ }, [model.fallbackItems, model.footer, model.sections]);
97
+ useLayoutEffect(function () {
98
+ setSelectedItemIndex(itemCount > 0 ? 0 : -1);
99
+ }, [itemCount, query, selectableItemKeys]);
80
100
  var isActiveItemMounted = selectedItemIndex >= 0 && selectedItemIndex < itemCount && (selectedItemIndex >= renderedItems.startIndex && selectedItemIndex <= renderedItems.stopIndex || Boolean(model.footer) && selectedItemIndex === itemCount - 1);
81
101
  var activeItemId = "".concat(listId, "-").concat(selectedItemIndex);
82
102
  var selectNextItem = useCallback(function () {
@@ -100,6 +120,18 @@ export var RegisteredInsertMenu = function RegisteredInsertMenu(_ref) {
100
120
  setSelectedItemIndex(0);
101
121
  }, []);
102
122
  var onKeyDown = useCallback(function (event) {
123
+ if (event.key === 'Escape') {
124
+ event.preventDefault();
125
+ onClose();
126
+ return;
127
+ }
128
+
129
+ // The search field owns the composite's arrow-key and Enter behaviour. Other
130
+ // focusable controls, including consumer-provided empty-state content, need
131
+ // to retain their native keyboard behaviour.
132
+ if (event.target !== searchRef.current) {
133
+ return;
134
+ }
103
135
  switch (event.key) {
104
136
  case 'ArrowDown':
105
137
  event.preventDefault();
@@ -113,14 +145,10 @@ export var RegisteredInsertMenu = function RegisteredInsertMenu(_ref) {
113
145
  event.preventDefault();
114
146
  selectActiveItem();
115
147
  break;
116
- case 'Escape':
117
- event.preventDefault();
118
- onClose();
119
- break;
120
148
  }
121
149
  }, [onClose, selectActiveItem, selectNextItem, selectPreviousItem]);
122
150
  return /*#__PURE__*/React.createElement(Box, {
123
- "data-registered-insert-menu": "",
151
+ "data-keyboard-navigation-independent": "",
124
152
  testId: "registered-insert-menu",
125
153
  onKeyDownCapture: onKeyDown,
126
154
  xcss: styles.menu
@@ -132,11 +160,13 @@ export var RegisteredInsertMenu = function RegisteredInsertMenu(_ref) {
132
160
  "aria-expanded": "true",
133
161
  autoFocus: true,
134
162
  placeholder: "Search",
163
+ ref: searchRef,
135
164
  role: "combobox",
136
165
  value: query,
137
166
  onChange: onQueryChange
138
167
  })), /*#__PURE__*/React.createElement(RegisteredInsertMenuList, {
139
168
  editorView: editorView,
169
+ emptyStateHandler: emptyStateHandler,
140
170
  isOffline: isOffline,
141
171
  listId: listId,
142
172
  listLabel: formatMessage(messages.insertMenu),
@@ -146,6 +176,7 @@ export var RegisteredInsertMenu = function RegisteredInsertMenu(_ref) {
146
176
  onClose: onSelect,
147
177
  onItemHover: setSelectedItemIndex,
148
178
  onRenderedItemsChange: setRenderedItems,
179
+ query: query,
149
180
  selectedItemIndex: selectedItemIndex,
150
181
  surfaceContext: surfaceContext
151
182
  }));
@@ -12,6 +12,7 @@ var RegisteredInsertMenuContainer = function RegisteredInsertMenuContainer(_ref)
12
12
  };
13
13
  var RegisteredInsertMenuWithListeners = withOuterListeners(RegisteredInsertMenuContainer);
14
14
  export var RegisteredInsertMenuContent = function RegisteredInsertMenuContent(_ref2) {
15
+ var _api$quickInsert;
15
16
  var api = _ref2.api,
16
17
  editorView = _ref2.editorView,
17
18
  isOffline = _ref2.isOffline,
@@ -37,6 +38,7 @@ export var RegisteredInsertMenuContent = function RegisteredInsertMenuContent(_r
37
38
  }, /*#__PURE__*/React.createElement(RegisteredInsertMenu, {
38
39
  components: components,
39
40
  editorView: editorView,
41
+ emptyStateHandler: api === null || api === void 0 || (_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 || (_api$quickInsert = _api$quickInsert.sharedState.currentState()) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.emptyStateHandler,
40
42
  isOffline: isOffline,
41
43
  onClose: onClose,
42
44
  onSelect: onSelect
@@ -1,4 +1,9 @@
1
1
  ._1rjc1b66{padding-block:var(--ds-space-050,4px)}._15a5nqa1{border-top-style:solid}
2
+ ._16jlkb7n{flex-grow:1}
3
+ ._18m91wug{overflow-y:auto}
4
+ ._1e0c1txw{display:flex}
2
5
  ._1i531l7x{border-top-color:var(--ds-border,#0b120e24)}
3
6
  ._1o9zidpf{flex-shrink:0}
7
+ ._1tkeidpf{min-height:0}
8
+ ._2lx21bp4{flex-direction:column}
4
9
  ._uwhke4h9{border-top-width:var(--ds-border-width,1px)}
@@ -1,7 +1,7 @@
1
1
  /* RegisteredInsertMenuList.tsx generated by @compiled/babel-plugin v3.0.2 */
2
2
  import _extends from "@babel/runtime/helpers/extends";
3
- import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
5
5
  import "./RegisteredInsertMenuList.compiled.css";
6
6
  import { ax, ix } from "@compiled/react/runtime";
7
7
  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; } } }; }
@@ -21,11 +21,14 @@ var listAriaProps = {
21
21
  'aria-readonly': null
22
22
  };
23
23
  var styles = {
24
+ content: "_1e0c1txw _2lx21bp4 _1tkeidpf",
25
+ scrollable: "_16jlkb7n _1tkeidpf _18m91wug",
24
26
  footer: "_1rjc1b66 _1i531l7x _15a5nqa1 _uwhke4h9 _1o9zidpf"
25
27
  };
26
28
  export var RegisteredInsertMenuList = function RegisteredInsertMenuList(_ref) {
27
29
  var _model$root$component, _model$root;
28
30
  var editorView = _ref.editorView,
31
+ emptyStateHandler = _ref.emptyStateHandler,
29
32
  isOffline = _ref.isOffline,
30
33
  listId = _ref.listId,
31
34
  listLabel = _ref.listLabel,
@@ -33,15 +36,20 @@ export var RegisteredInsertMenuList = function RegisteredInsertMenuList(_ref) {
33
36
  menuOpenId = _ref.menuOpenId,
34
37
  model = _ref.model,
35
38
  onClose = _ref.onClose,
39
+ query = _ref.query,
36
40
  onItemHover = _ref.onItemHover,
37
41
  onRenderedItemsChange = _ref.onRenderedItemsChange,
38
42
  selectedItemIndex = _ref.selectedItemIndex,
39
43
  surfaceContext = _ref.surfaceContext;
40
44
  var Root = (_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 : React.Fragment;
41
45
  var listRef = useRef(null);
46
+ var setListRef = useCallback(function (list) {
47
+ listRef.current = list;
48
+ }, []);
42
49
  var rows = useMemo(function () {
43
- return model.sections.flat();
44
- }, [model.sections]);
50
+ var _model$fallbackItems;
51
+ return [].concat(_toConsumableArray(model.sections.flat()), _toConsumableArray((_model$fallbackItems = model.fallbackItems) !== null && _model$fallbackItems !== void 0 ? _model$fallbackItems : []));
52
+ }, [model.fallbackItems, model.sections]);
45
53
  var cache = useMemo(function () {
46
54
  return new CellMeasurerCache({
47
55
  defaultHeight: ESTIMATED_ROW_HEIGHT,
@@ -120,6 +128,9 @@ export var RegisteredInsertMenuList = function RegisteredInsertMenuList(_ref) {
120
128
  }
121
129
  var itemIndex = itemIndexByRowIndex.get(index);
122
130
  var rowContent = registration.type === 'menu-section' ? ( /*#__PURE__*/React.createElement((_registration$compone = registration.component) !== null && _registration$compone !== void 0 ? _registration$compone : React.Fragment, null, null)) : /*#__PURE__*/React.createElement("div", {
131
+ onFocus: function onFocus() {
132
+ return onItemHover(itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0);
133
+ },
123
134
  onMouseMove: function onMouseMove() {
124
135
  return onItemHover(itemIndex !== null && itemIndex !== void 0 ? itemIndex : 0);
125
136
  }
@@ -144,8 +155,7 @@ export var RegisteredInsertMenuList = function RegisteredInsertMenuList(_ref) {
144
155
  return /*#__PURE__*/React.createElement("div", {
145
156
  ref: function ref(element) {
146
157
  return registerChild === null || registerChild === void 0 ? void 0 : registerChild(element !== null && element !== void 0 ? element : undefined);
147
- },
148
- "data-index": index
158
+ }
149
159
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
150
160
  ,
151
161
  style: style
@@ -153,15 +163,40 @@ export var RegisteredInsertMenuList = function RegisteredInsertMenuList(_ref) {
153
163
  });
154
164
  }, [cache, editorView, isOffline, itemIndexByRowIndex, listId, menuOpenId, onClose, onItemHover, rows, selectedItemIndex, surfaceContext]);
155
165
  var footerItemIndex = itemIndexByRowIndex.size;
166
+ var footerItemId = "".concat(listId, "-").concat(footerItemIndex);
167
+ var hasExternalControls = model.fallbackItems !== undefined && emptyStateHandler !== undefined;
156
168
  var listMaxHeight = Math.max(0, maxHeight - MENU_SEARCH_HEIGHT - (model.footer ? MENU_FOOTER_HEIGHT : 0));
169
+ var contentStyle = {
170
+ maxHeight: Math.max(0, maxHeight - MENU_SEARCH_HEIGHT)
171
+ };
157
172
  var onFooterItemHover = useCallback(function () {
158
173
  return onItemHover(footerItemIndex);
159
174
  }, [footerItemIndex, onItemHover]);
175
+ var footer = model.footer ? /*#__PURE__*/React.createElement(Box, {
176
+ xcss: styles.footer,
177
+ onFocus: onFooterItemHover,
178
+ onMouseMove: onFooterItemHover
179
+ }, /*#__PURE__*/React.createElement(RegisteredInsertMenuItem, {
180
+ editorView: editorView,
181
+ id: footerItemId,
182
+ isOffline: isOffline,
183
+ isSelected: footerItemIndex === selectedItemIndex,
184
+ menuOpenId: menuOpenId,
185
+ onClose: onClose,
186
+ registration: model.footer,
187
+ surfaceContext: surfaceContext
188
+ })) : null;
160
189
  if (!model.root) {
161
190
  return null;
162
191
  }
163
192
  return /*#__PURE__*/React.createElement(Root, null, /*#__PURE__*/React.createElement(Box, {
193
+ xcss: styles.content,
194
+ style: contentStyle
195
+ }, /*#__PURE__*/React.createElement(Box, {
196
+ xcss: styles.scrollable
197
+ }, /*#__PURE__*/React.createElement(Box, {
164
198
  "aria-label": listLabel,
199
+ "aria-owns": model.footer ? footerItemId : undefined,
165
200
  id: listId,
166
201
  role: "listbox"
167
202
  }, rows.length > 0 && /*#__PURE__*/React.createElement(List
@@ -172,7 +207,7 @@ export var RegisteredInsertMenuList = function RegisteredInsertMenuList(_ref) {
172
207
  height: Math.min(rows.length * ESTIMATED_ROW_HEIGHT, listMaxHeight),
173
208
  overscanRowCount: 3,
174
209
  onRowsRendered: onRowsRendered,
175
- ref: listRef,
210
+ ref: setListRef,
176
211
  role: "group",
177
212
  rowCount: rows.length,
178
213
  rowHeight: cache.rowHeight,
@@ -180,17 +215,9 @@ export var RegisteredInsertMenuList = function RegisteredInsertMenuList(_ref) {
180
215
  scrollToAlignment: "auto",
181
216
  scrollToIndex: selectedRowIndex,
182
217
  width: LIST_WIDTH
183
- })), model.footer && /*#__PURE__*/React.createElement(Box, {
184
- xcss: styles.footer,
185
- onMouseMove: onFooterItemHover
186
- }, /*#__PURE__*/React.createElement(RegisteredInsertMenuItem, {
187
- editorView: editorView,
188
- id: "".concat(listId, "-").concat(footerItemIndex),
189
- isOffline: isOffline,
190
- isSelected: footerItemIndex === selectedItemIndex,
191
- menuOpenId: menuOpenId,
192
- onClose: onClose,
193
- registration: model.footer,
194
- surfaceContext: surfaceContext
195
- }))));
218
+ }))), hasExternalControls && /*#__PURE__*/React.createElement(Box, null, emptyStateHandler({
219
+ mode: 'inline',
220
+ searchTerm: query,
221
+ showNoResultsMessage: false
222
+ }))), footer));
196
223
  };
@@ -1,12 +1,14 @@
1
1
  import React from 'react';
2
+ import type { EmptyStateHandler } from '@atlaskit/editor-common/types';
2
3
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
3
4
  import type { RegisterComponent } from '@atlaskit/editor-ui-control-model/types';
4
5
  type Props = {
5
6
  components: RegisterComponent[];
6
7
  editorView: EditorView;
8
+ emptyStateHandler?: EmptyStateHandler;
7
9
  isOffline: boolean;
8
10
  onClose: () => void;
9
11
  onSelect: () => void;
10
12
  };
11
- export declare const RegisteredInsertMenu: ({ components, editorView, isOffline, onClose, onSelect, }: Props) => React.JSX.Element;
13
+ export declare const RegisteredInsertMenu: ({ components, emptyStateHandler, editorView, isOffline, onClose, onSelect, }: Props) => React.JSX.Element;
12
14
  export {};
@@ -1,9 +1,11 @@
1
1
  import React from 'react';
2
2
  import type { QuickInsertMenuModel } from '@atlaskit/editor-common/quick-insert/registered-menu-model';
3
+ import type { EmptyStateHandler } from '@atlaskit/editor-common/types';
3
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
5
  import type { SurfaceContext } from '@atlaskit/editor-ui-control-model/types';
5
6
  type Props = {
6
7
  editorView: EditorView;
8
+ emptyStateHandler?: EmptyStateHandler;
7
9
  isOffline: boolean;
8
10
  listId: string;
9
11
  listLabel: string;
@@ -16,8 +18,9 @@ type Props = {
16
18
  startIndex: number;
17
19
  stopIndex: number;
18
20
  }) => void;
21
+ query: string;
19
22
  selectedItemIndex: number;
20
23
  surfaceContext: SurfaceContext;
21
24
  };
22
- export declare const RegisteredInsertMenuList: ({ editorView, isOffline, listId, listLabel, maxHeight, menuOpenId, model, onClose, onItemHover, onRenderedItemsChange, selectedItemIndex, surfaceContext, }: Props) => React.JSX.Element | null;
25
+ export declare const RegisteredInsertMenuList: ({ editorView, emptyStateHandler, isOffline, listId, listLabel, maxHeight, menuOpenId, model, onClose, query, onItemHover, onRenderedItemsChange, selectedItemIndex, surfaceContext, }: Props) => React.JSX.Element | null;
23
26
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-insert-block",
3
- "version": "20.0.3",
3
+ "version": "20.0.5",
4
4
  "description": "Insert block plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -36,7 +36,7 @@
36
36
  "@atlaskit/editor-plugin-image-upload": "^19.0.0",
37
37
  "@atlaskit/editor-plugin-layout": "^20.0.0",
38
38
  "@atlaskit/editor-plugin-media": "^21.0.0",
39
- "@atlaskit/editor-plugin-media-insert": "^36.0.0",
39
+ "@atlaskit/editor-plugin-media-insert": "^37.0.0",
40
40
  "@atlaskit/editor-plugin-mentions": "^21.1.0",
41
41
  "@atlaskit/editor-plugin-metrics": "^20.0.0",
42
42
  "@atlaskit/editor-plugin-panel": "^21.0.0",
@@ -63,7 +63,7 @@
63
63
  "@atlaskit/primitives": "^22.5.0",
64
64
  "@atlaskit/textfield": "^10.2.0",
65
65
  "@atlaskit/tmp-editor-statsig": "^202.0.0",
66
- "@atlaskit/tokens": "^18.2.0",
66
+ "@atlaskit/tokens": "^19.0.0",
67
67
  "@babel/runtime": "^7.0.0",
68
68
  "@emotion/react": "^11.7.1",
69
69
  "bind-event-listener": "^3.0.0",
@@ -72,7 +72,7 @@
72
72
  "react-virtualized": "^9.22.6"
73
73
  },
74
74
  "peerDependencies": {
75
- "@atlaskit/editor-common": "^123.5.0",
75
+ "@atlaskit/editor-common": "^123.7.0",
76
76
  "react": "^18.2.0 || ^19.2.0",
77
77
  "react-dom": "^18.2.0 || ^19.2.0",
78
78
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"