@atlaskit/editor-plugin-type-ahead 1.11.3 → 1.11.4

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 (65) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/pm-plugins/actions.js +1 -0
  3. package/dist/cjs/pm-plugins/commands/update-list-error.js +24 -0
  4. package/dist/cjs/pm-plugins/main.js +1 -0
  5. package/dist/cjs/pm-plugins/reducer.js +8 -0
  6. package/dist/cjs/pm-plugins/utils.js +49 -14
  7. package/dist/cjs/typeAheadPlugin.js +3 -1
  8. package/dist/cjs/ui/TypeAheadErrorFallback/EmptyState.js +38 -0
  9. package/dist/cjs/ui/TypeAheadErrorFallback/GenericErrorSVG.js +67 -0
  10. package/dist/cjs/ui/TypeAheadErrorFallback/MinHeightContainer.js +41 -0
  11. package/dist/cjs/ui/TypeAheadErrorFallback/index.js +38 -0
  12. package/dist/cjs/ui/TypeAheadListItem.js +1 -0
  13. package/dist/cjs/ui/TypeAheadMenu.js +3 -1
  14. package/dist/cjs/ui/TypeAheadPopup.js +4 -2
  15. package/dist/cjs/ui/WrapperTypeAhead.js +12 -4
  16. package/dist/cjs/ui/hooks/use-load-items.js +13 -0
  17. package/dist/es2019/pm-plugins/actions.js +1 -0
  18. package/dist/es2019/pm-plugins/commands/update-list-error.js +18 -0
  19. package/dist/es2019/pm-plugins/main.js +1 -0
  20. package/dist/es2019/pm-plugins/reducer.js +11 -0
  21. package/dist/es2019/pm-plugins/utils.js +44 -7
  22. package/dist/es2019/typeAheadPlugin.js +3 -1
  23. package/dist/es2019/ui/TypeAheadErrorFallback/EmptyState.js +32 -0
  24. package/dist/es2019/ui/TypeAheadErrorFallback/GenericErrorSVG.js +59 -0
  25. package/dist/es2019/ui/TypeAheadErrorFallback/MinHeightContainer.js +33 -0
  26. package/dist/es2019/ui/TypeAheadErrorFallback/index.js +29 -0
  27. package/dist/es2019/ui/TypeAheadListItem.js +1 -0
  28. package/dist/es2019/ui/TypeAheadMenu.js +3 -1
  29. package/dist/es2019/ui/TypeAheadPopup.js +4 -2
  30. package/dist/es2019/ui/WrapperTypeAhead.js +10 -2
  31. package/dist/es2019/ui/hooks/use-load-items.js +13 -0
  32. package/dist/esm/pm-plugins/actions.js +1 -0
  33. package/dist/esm/pm-plugins/commands/update-list-error.js +18 -0
  34. package/dist/esm/pm-plugins/main.js +1 -0
  35. package/dist/esm/pm-plugins/reducer.js +8 -0
  36. package/dist/esm/pm-plugins/utils.js +49 -14
  37. package/dist/esm/typeAheadPlugin.js +3 -1
  38. package/dist/esm/ui/TypeAheadErrorFallback/EmptyState.js +31 -0
  39. package/dist/esm/ui/TypeAheadErrorFallback/GenericErrorSVG.js +59 -0
  40. package/dist/esm/ui/TypeAheadErrorFallback/MinHeightContainer.js +33 -0
  41. package/dist/esm/ui/TypeAheadErrorFallback/index.js +31 -0
  42. package/dist/esm/ui/TypeAheadListItem.js +1 -0
  43. package/dist/esm/ui/TypeAheadMenu.js +3 -1
  44. package/dist/esm/ui/TypeAheadPopup.js +4 -2
  45. package/dist/esm/ui/WrapperTypeAhead.js +12 -4
  46. package/dist/esm/ui/hooks/use-load-items.js +13 -0
  47. package/dist/types/pm-plugins/actions.d.ts +1 -0
  48. package/dist/types/pm-plugins/commands/update-list-error.d.ts +2 -0
  49. package/dist/types/pm-plugins/utils.d.ts +12 -2
  50. package/dist/types/types/index.d.ts +6 -0
  51. package/dist/types/ui/TypeAheadErrorFallback/EmptyState.d.ts +9 -0
  52. package/dist/types/ui/TypeAheadErrorFallback/GenericErrorSVG.d.ts +6 -0
  53. package/dist/types/ui/TypeAheadErrorFallback/MinHeightContainer.d.ts +9 -0
  54. package/dist/types/ui/TypeAheadErrorFallback/index.d.ts +6 -0
  55. package/dist/types/ui/TypeAheadPopup.d.ts +2 -1
  56. package/dist/types-ts4.5/pm-plugins/actions.d.ts +1 -0
  57. package/dist/types-ts4.5/pm-plugins/commands/update-list-error.d.ts +2 -0
  58. package/dist/types-ts4.5/pm-plugins/utils.d.ts +12 -2
  59. package/dist/types-ts4.5/types/index.d.ts +6 -0
  60. package/dist/types-ts4.5/ui/TypeAheadErrorFallback/EmptyState.d.ts +9 -0
  61. package/dist/types-ts4.5/ui/TypeAheadErrorFallback/GenericErrorSVG.d.ts +6 -0
  62. package/dist/types-ts4.5/ui/TypeAheadErrorFallback/MinHeightContainer.d.ts +9 -0
  63. package/dist/types-ts4.5/ui/TypeAheadErrorFallback/index.d.ts +6 -0
  64. package/dist/types-ts4.5/ui/TypeAheadPopup.d.ts +2 -1
  65. package/package.json +7 -2
@@ -1,4 +1,5 @@
1
1
  import { TypeAheadAvailableNodes, typeAheadListMessages } from '@atlaskit/editor-common/type-ahead';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { updateSelectedIndex } from './commands/update-selected-index';
3
4
  import { itemIsDisabled } from './item-is-disabled';
4
5
  import { pluginKey as typeAheadPluginKey } from './key';
@@ -39,26 +40,52 @@ export const findHandler = (id, state) => {
39
40
  } = pluginState;
40
41
  return typeAheadHandlers.find(h => h.id === id) || null;
41
42
  };
42
- export const skipForwardToSafeItem = (currentIndex, nextIndex, listSize, itemIsDisabled
43
- // Ignored via go/ees005
44
- // eslint-disable-next-line @typescript-eslint/max-params
45
- ) => {
43
+ export const skipForwardToSafeItem = ({
44
+ currentIndex,
45
+ nextIndex,
46
+ listSize,
47
+ itemIsDisabled
48
+ }) => {
46
49
  // Use a loop to find the next selectable item
47
50
  for (let idx = nextIndex; idx < listSize; idx++) {
48
51
  if (!itemIsDisabled(idx)) {
49
52
  return idx;
50
53
  }
51
54
  }
55
+
56
+ // We got to the end of the list ^, now try from the start
57
+ if (fg('platform_editor_offline_editing_ga')) {
58
+ for (let idx = 0; idx < nextIndex; idx++) {
59
+ if (!itemIsDisabled(idx)) {
60
+ return idx;
61
+ }
62
+ }
63
+ }
64
+
52
65
  // If no selectable items are found, return currentIndex
53
66
  return currentIndex;
54
67
  };
55
- export const skipBackwardToSafeItem = (currentIndex, nextIndex, itemIsDisabled) => {
68
+ export const skipBackwardToSafeItem = ({
69
+ currentIndex,
70
+ nextIndex,
71
+ listSize,
72
+ itemIsDisabled
73
+ }) => {
56
74
  // Use a loop to find the next non-selectable item when going backwards
57
75
  for (let idx = nextIndex; idx >= 0; idx--) {
58
76
  if (!itemIsDisabled(idx)) {
59
77
  return idx;
60
78
  }
61
79
  }
80
+
81
+ // We got to the start of the list ^, now try from the end
82
+ if (fg('platform_editor_offline_editing_ga')) {
83
+ for (let idx = listSize; idx > nextIndex; idx--) {
84
+ if (!itemIsDisabled(idx)) {
85
+ return idx;
86
+ }
87
+ }
88
+ }
62
89
  // If no non-selectable items are found, return currentIndex
63
90
  return currentIndex;
64
91
  };
@@ -112,11 +139,21 @@ export const moveSelectedIndex = ({
112
139
  } else {
113
140
  nextIndex = selectedIndex >= items.length - 1 ? 0 : selectedIndex + 1;
114
141
  }
115
- nextIndex = skipForwardToSafeItem(selectedIndex, nextIndex, items.length, isDisabled);
142
+ nextIndex = skipForwardToSafeItem({
143
+ currentIndex: selectedIndex,
144
+ nextIndex,
145
+ listSize: items.length,
146
+ itemIsDisabled: isDisabled
147
+ });
116
148
  } else {
117
149
  stats.increaseArrowUp();
118
150
  nextIndex = selectedIndex <= 0 ? items.length - 1 : selectedIndex - 1;
119
- nextIndex = skipBackwardToSafeItem(selectedIndex, nextIndex, isDisabled);
151
+ nextIndex = skipBackwardToSafeItem({
152
+ currentIndex: selectedIndex,
153
+ nextIndex,
154
+ listSize: items.length,
155
+ itemIsDisabled: isDisabled
156
+ });
120
157
  }
121
158
  updateSelectedIndex(nextIndex, api)(editorView.state, editorView.dispatch);
122
159
  };
@@ -195,7 +195,7 @@ export const typeAheadPlugin = ({
195
195
  }];
196
196
  },
197
197
  getSharedState(editorState) {
198
- var _state$decorationSet, _state$decorationElem, _state$items, _state$selectedIndex;
198
+ var _state$decorationSet, _state$decorationElem, _state$items, _state$errorInfo, _state$selectedIndex;
199
199
  if (!editorState) {
200
200
  return {
201
201
  query: '',
@@ -206,6 +206,7 @@ export const typeAheadPlugin = ({
206
206
  decorationElement: null,
207
207
  triggerHandler: undefined,
208
208
  items: [],
209
+ errorInfo: null,
209
210
  selectedIndex: 0
210
211
  };
211
212
  }
@@ -220,6 +221,7 @@ export const typeAheadPlugin = ({
220
221
  decorationElement: (_state$decorationElem = state === null || state === void 0 ? void 0 : state.decorationElement) !== null && _state$decorationElem !== void 0 ? _state$decorationElem : null,
221
222
  triggerHandler: state === null || state === void 0 ? void 0 : state.triggerHandler,
222
223
  items: (_state$items = state === null || state === void 0 ? void 0 : state.items) !== null && _state$items !== void 0 ? _state$items : [],
224
+ errorInfo: (_state$errorInfo = state === null || state === void 0 ? void 0 : state.errorInfo) !== null && _state$errorInfo !== void 0 ? _state$errorInfo : null,
223
225
  selectedIndex: (_state$selectedIndex = state === null || state === void 0 ? void 0 : state.selectedIndex) !== null && _state$selectedIndex !== void 0 ? _state$selectedIndex : 0
224
226
  };
225
227
  },
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import Heading from '@atlaskit/heading';
3
+ import { Flex, Text, xcss } from '@atlaskit/primitives';
4
+ const containerStyles = xcss({
5
+ marginBlockStart: 'space.600',
6
+ marginBlockEnd: 'space.600',
7
+ textAlign: 'center'
8
+ });
9
+ export const EmptyState = ({
10
+ testId,
11
+ header,
12
+ description,
13
+ renderImage
14
+ }) => {
15
+ return /*#__PURE__*/React.createElement(Flex, {
16
+ xcss: containerStyles,
17
+ testId: testId,
18
+ direction: "column",
19
+ alignItems: "center",
20
+ gap: "space.300"
21
+ }, renderImage === null || renderImage === void 0 ? void 0 : renderImage(), /*#__PURE__*/React.createElement(Flex, {
22
+ direction: "column",
23
+ alignItems: "center",
24
+ gap: "space.200"
25
+ }, /*#__PURE__*/React.createElement(Heading, {
26
+ size: "medium",
27
+ as: "h2"
28
+ }, header), description && /*#__PURE__*/React.createElement(Text, {
29
+ as: "p",
30
+ color: "color.text"
31
+ }, description)));
32
+ };
@@ -0,0 +1,59 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ /**
3
+ * @jsxRuntime classic
4
+ * @jsx jsx
5
+ */
6
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
7
+ import { css, jsx } from '@emotion/react';
8
+ const HEIGHT = 90;
9
+ const genericErrorStyles = css({
10
+ height: `${HEIGHT}px`,
11
+ display: 'block'
12
+ });
13
+ export const GenericErrorSVG = props => {
14
+ const id = 'link-picker-ui-generic-error-svg';
15
+ return jsx("svg", _extends({
16
+ height: "90",
17
+ viewBox: "0 0 164 212",
18
+ fill: "none",
19
+ xmlns: "http://www.w3.org/2000/svg",
20
+ css: genericErrorStyles
21
+ // eslint-disable-next-line react/jsx-props-no-spreading
22
+ }, props), jsx("path", {
23
+ d: "m95.43 74.16 66.44 115.08c5.84 10.12-1.46 22.76-13.14 22.76H15.85c-11.68 0-18.98-12.65-13.14-22.76L69.15 74.16c5.84-10.12 20.44-10.12 26.28 0Zm-7.56 83.55 2.88-44.35c.34-5.29-3.86-9.78-9.16-9.78-5.31 0-9.51 4.48-9.16 9.78l2.88 44.35a6.3 6.3 0 0 0 6.28 5.89c3.31 0 6.06-2.58 6.28-5.89Zm-15.84 23.54c0 5.66 4.76 10.1 10.39 9.58 4.85-.45 8.73-4.5 8.83-9.37.11-5.45-4.31-9.94-9.73-9.94-5.23-.01-9.49 4.37-9.49 9.73Z",
24
+ fill: `url(#${id})`
25
+ }), jsx("path", {
26
+ opacity: ".6",
27
+ d: "M93.35 27.17 85.94.45c-.17-.62-1.07-.58-1.19.05l-4.66 25.1-5.8-1.08a.612.612 0 0 0-.7.76L81 52c.17.62 1.07.58 1.19-.05l4.66-25.1 5.8 1.08c.45.08.82-.33.7-.76ZM66.77 41.81 55.9 33.26c-.22-.18-.53.07-.41.33l5.53 11.43-2.66 1.29c-.18.09-.2.33-.05.45l10.87 8.55c.22.18.53-.07.41-.33l-5.53-11.43 2.66-1.29c.17-.08.2-.33.05-.45Z",
28
+ fill: "#C1C7D0"
29
+ }), jsx("path", {
30
+ opacity: ".6",
31
+ d: "M102.78 56.75a.993.993 0 0 1-.92-1.38c-.24-.77-2.29-2.85-3.54-4.11-2.97-3.01-4.93-5-3.84-6.49 1.09-1.48 3.58-.22 7.35 1.7 1.32.67 3.35 1.7 4.45 2.03-.64-.95-2.24-2.58-3.28-3.63-2.97-3.01-4.93-5-3.84-6.49 1.08-1.48 3.58-.22 7.34 1.7 1.32.67 3.34 1.7 4.45 2.03-.64-.95-2.24-2.57-3.28-3.62-2.97-3.01-4.93-5-3.84-6.49 1.08-1.48 3.57-.22 7.34 1.7 1.58.8 4.18 2.13 4.98 2.13a1.005 1.005 0 0 1 1.46 1.36c-1.09 1.48-3.57.22-7.34-1.7-1.32-.67-3.34-1.7-4.44-2.03.64.95 2.24 2.57 3.28 3.62 2.97 3.01 4.93 5 3.84 6.49-1.08 1.48-3.57.22-7.34-1.7-1.32-.67-3.35-1.7-4.45-2.03.64.95 2.24 2.57 3.28 3.63 2.97 3.01 4.93 5 3.84 6.49-1.09 1.48-3.58.22-7.35-1.7-1.32-.67-3.35-1.71-4.45-2.03.64.95 2.24 2.58 3.28 3.63 2.97 3.01 4.93 5 3.84 6.49-.21.26-.51.4-.82.4Zm5.56 14.32c-.35 0-.69-.19-.88-.52-1.04-1.88-2.22-4.02-.91-5.21 1.31-1.2 3.34.18 5.49 1.63.87.59 2.26 1.53 2.93 1.71-.12-.68-.93-2.15-1.45-3.07-1.26-2.27-2.45-4.41-1.14-5.61 1.31-1.2 3.34.18 5.49 1.63.96.65 2.54 1.72 3.1 1.74a1 1 0 0 1 1.27 1.54c-1.31 1.2-3.34-.17-5.49-1.63-.87-.59-2.26-1.53-2.93-1.71.12.68.93 2.15 1.45 3.07 1.26 2.27 2.45 4.41 1.14 5.61-1.31 1.2-3.34-.18-5.49-1.63-.87-.59-2.26-1.53-2.93-1.71.12.68.93 2.14 1.22 2.67.27.48.09 1.09-.39 1.36-.15.09-.32.13-.48.13Zm-54.32-2.89c-.22 0-.44-.04-.67-.14-1.64-.69-1.24-3.11-.81-5.67.17-1.04.45-2.7.33-3.38-.57.39-1.56 1.75-2.18 2.6-1.53 2.09-2.99 4.07-4.62 3.38a.991.991 0 0 1-.53-1.31c.2-.48.73-.72 1.21-.57.52-.21 1.65-1.75 2.34-2.68 1.53-2.09 2.98-4.08 4.62-3.38 1.64.69 1.24 3.11.81 5.67-.17 1.04-.45 2.7-.33 3.38.57-.39 1.56-1.75 2.18-2.6 1.53-2.09 2.98-4.08 4.62-3.38 1.63.69 1.24 3.09.89 5.21-.09.54-.6.91-1.15.83-.54-.09-.92-.6-.83-1.15.1-.59.37-2.24.26-2.92-.57.39-1.56 1.75-2.18 2.6-1.33 1.79-2.59 3.51-3.96 3.51Z",
32
+ fill: "#B3BAC5"
33
+ }), jsx("defs", null, jsx("linearGradient", {
34
+ id: id,
35
+ x1: "26.169",
36
+ y1: "228.621",
37
+ x2: "138.408",
38
+ y2: "116.382",
39
+ gradientUnits: "userSpaceOnUse"
40
+ }, jsx("stop", {
41
+ stopColor: "#C1C7D0"
42
+ }), jsx("stop", {
43
+ offset: ".297",
44
+ stopColor: "#C6CBD4",
45
+ stopOpacity: ".881"
46
+ }), jsx("stop", {
47
+ offset: ".63",
48
+ stopColor: "#D3D7DE",
49
+ stopOpacity: ".748"
50
+ }), jsx("stop", {
51
+ offset: ".98",
52
+ stopColor: "#E9EBEF",
53
+ stopOpacity: ".608"
54
+ }), jsx("stop", {
55
+ offset: "1",
56
+ stopColor: "#EBECF0",
57
+ stopOpacity: ".6"
58
+ }))));
59
+ };
@@ -0,0 +1,33 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ /**
3
+ * @jsxRuntime classic
4
+ * @jsx jsx
5
+ */
6
+ import React, { forwardRef } from 'react';
7
+
8
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
9
+ import { css, jsx } from '@emotion/react';
10
+
11
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
12
+ export const minHeightComponentStyles = css({
13
+ display: 'flex',
14
+ alignItems: 'stretch',
15
+ justifyContent: 'center',
16
+ minHeight: 'var(--link-picker-min-height)'
17
+ });
18
+ export const MinHeightContainer = /*#__PURE__*/forwardRef(({
19
+ minHeight,
20
+ ...props
21
+ }, ref) => {
22
+ return jsx("div", _extends({
23
+ ref: ref
24
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
25
+ ,
26
+ css: minHeightComponentStyles
27
+ // eslint-disable-next-line react/jsx-props-no-spreading
28
+ }, props, {
29
+ style: {
30
+ ['--link-picker-min-height']: minHeight
31
+ }
32
+ }));
33
+ });
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
6
+ import { css, jsx } from '@emotion/react';
7
+ import { useIntl } from 'react-intl-next';
8
+ import { typeAheadListMessages as messages } from '@atlaskit/editor-common/type-ahead';
9
+ import { EmptyState } from './EmptyState';
10
+ import { GenericErrorSVG } from './GenericErrorSVG';
11
+ const minHeightComponentStyles = css({
12
+ display: 'flex',
13
+ alignItems: 'stretch',
14
+ justifyContent: 'center',
15
+ minHeight: '290px'
16
+ });
17
+ export const TypeAheadErrorFallback = () => {
18
+ const intl = useIntl();
19
+ const header = intl.formatMessage(messages.offlineErrorFallbackHeading);
20
+ const description = intl.formatMessage(messages.offlineErrorFallbackDesc);
21
+ return jsx("div", {
22
+ "data-testid": "mentions-typeahead-error-boundary-ui",
23
+ css: minHeightComponentStyles
24
+ }, jsx(EmptyState, {
25
+ header: header,
26
+ renderImage: () => jsx(GenericErrorSVG, null),
27
+ description: description
28
+ }));
29
+ };
@@ -61,6 +61,7 @@ const itemText = css({
61
61
  color: `${`var(--ds-text, ${N800})`}`
62
62
  });
63
63
  const itemTitle = css({
64
+ // eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
64
65
  lineHeight: '1.4'
65
66
  });
66
67
  const itemTitleOverride = css({
@@ -14,6 +14,7 @@ export const TypeAheadMenu = /*#__PURE__*/React.memo(({
14
14
  const {
15
15
  triggerHandler,
16
16
  items,
17
+ errorInfo,
17
18
  selectedIndex,
18
19
  decorationElement,
19
20
  decorationSet,
@@ -67,7 +68,7 @@ export const TypeAheadMenu = /*#__PURE__*/React.memo(({
67
68
  return;
68
69
  }
69
70
  }, [isOpen, query, onItemMatch]);
70
- if (!isOpen || !triggerHandler || !(decorationElement instanceof HTMLElement) || items.length === 0) {
71
+ if (!isOpen || !triggerHandler || !(decorationElement instanceof HTMLElement) || items.length === 0 && !errorInfo) {
71
72
  return null;
72
73
  }
73
74
  return /*#__PURE__*/React.createElement(TypeAheadPopup, {
@@ -78,6 +79,7 @@ export const TypeAheadMenu = /*#__PURE__*/React.memo(({
78
79
  anchorElement: decorationElement,
79
80
  triggerHandler: triggerHandler,
80
81
  items: items,
82
+ errorInfo: errorInfo,
81
83
  selectedIndex: selectedIndex,
82
84
  setSelectedItem: setSelectedItem,
83
85
  onItemInsert: insertItem,
@@ -14,6 +14,7 @@ import { findOverflowScrollParent, Popup } from '@atlaskit/editor-common/ui';
14
14
  import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles';
15
15
  import { N0, N50A, N60A } from '@atlaskit/theme/colors';
16
16
  import { CloseSelectionOptions, TYPE_AHEAD_DECORATION_DATA_ATTRIBUTE, TYPE_AHEAD_POPUP_CONTENT_CLASS } from '../pm-plugins/constants';
17
+ import { TypeAheadErrorFallback } from './TypeAheadErrorFallback';
17
18
  import { TypeAheadList } from './TypeAheadList';
18
19
  const DEFAULT_TYPEAHEAD_MENU_HEIGHT = 380;
19
20
  const DEFAULT_TYPEAHEAD_MENU_HEIGHT_NEW = 480;
@@ -51,6 +52,7 @@ export const TypeAheadPopup = /*#__PURE__*/React.memo(props => {
51
52
  popupsBoundariesElement,
52
53
  popupsScrollableElement,
53
54
  items,
55
+ errorInfo,
54
56
  selectedIndex,
55
57
  onItemInsert,
56
58
  isEmptyQuery,
@@ -253,7 +255,7 @@ export const TypeAheadPopup = /*#__PURE__*/React.memo(props => {
253
255
  ,
254
256
  className: TYPE_AHEAD_POPUP_CONTENT_CLASS,
255
257
  ref: ref
256
- }, jsx(Highlight, {
258
+ }, errorInfo ? jsx(TypeAheadErrorFallback, null) : jsx(React.Fragment, null, jsx(Highlight, {
257
259
  state: editorView.state,
258
260
  triggerHandler: triggerHandler
259
261
  }), jsx(TypeAheadList, {
@@ -266,6 +268,6 @@ export const TypeAheadPopup = /*#__PURE__*/React.memo(props => {
266
268
  triggerHandler: triggerHandler,
267
269
  moreElementsInQuickInsertViewEnabled: moreElementsInQuickInsertViewEnabled,
268
270
  api: api
269
- })));
271
+ }))));
270
272
  });
271
273
  TypeAheadPopup.displayName = 'TypeAheadPopup';
@@ -64,7 +64,12 @@ export const WrapperTypeAhead = /*#__PURE__*/React.memo(({
64
64
  const {
65
65
  selectedIndex
66
66
  } = getPluginState(view.state);
67
- const safeSelectedIndex = skipForwardToSafeItem(selectedIndex, 1, items.length, idx => itemIsDisabled(items[idx], api));
67
+ const safeSelectedIndex = skipForwardToSafeItem({
68
+ currentIndex: selectedIndex,
69
+ nextIndex: 1,
70
+ listSize: items.length,
71
+ itemIsDisabled: idx => itemIsDisabled(items[idx], api)
72
+ });
68
73
  // If the only safe index is -1 then none are safe - do not insert item
69
74
  if (safeSelectedIndex === -1) {
70
75
  return;
@@ -102,8 +107,11 @@ export const WrapperTypeAhead = /*#__PURE__*/React.memo(({
102
107
  if (closed) {
103
108
  return null;
104
109
  }
110
+ if (!triggerHandler) {
111
+ return null;
112
+ }
105
113
  return /*#__PURE__*/React.createElement(InputQuery, {
106
- triggerQueryPrefix: triggerHandler.trigger,
114
+ triggerQueryPrefix: triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.trigger,
107
115
  onQueryChange: setQuery,
108
116
  onItemSelect: insertSelectedItem,
109
117
  selectNextItem: selectNextItem,
@@ -1,4 +1,6 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { updateListError } from '../../pm-plugins/commands/update-list-error';
2
4
  import { updateListItem } from '../../pm-plugins/commands/update-list-items';
3
5
  const EMPTY_LIST_ITEM = [];
4
6
  export const useLoadItems = (triggerHandler, editorView, query) => {
@@ -26,6 +28,17 @@ export const useLoadItems = (triggerHandler, editorView, query) => {
26
28
  queueMicrotask(() => {
27
29
  updateListItem(list)(view.state, view.dispatch);
28
30
  });
31
+ }).catch(e => {
32
+ if (fg('platform_editor_offline_editing_ga')) {
33
+ if (e) {
34
+ if (componentIsMounted.current) {
35
+ setItems(EMPTY_LIST_ITEM);
36
+ }
37
+ queueMicrotask(() => {
38
+ updateListError(e)(view.state, view.dispatch);
39
+ });
40
+ }
41
+ }
29
42
  });
30
43
 
31
44
  // ignore because EditorView is mutable but we don't want to
@@ -5,6 +5,7 @@ export var ACTIONS = /*#__PURE__*/function (ACTIONS) {
5
5
  ACTIONS["INSERT_ITEM"] = "INSERT_ITEM";
6
6
  ACTIONS["INSERT_RAW_QUERY"] = "INSERT_RAW_QUERY";
7
7
  ACTIONS["UPDATE_LIST_ITEMS"] = "UPDATE_LIST_ITEMS";
8
+ ACTIONS["UPDATE_LIST_ERROR"] = "UPDATE_LIST_ERROR";
8
9
  ACTIONS["UPDATE_SELECTED_INDEX"] = "UPDATE_SELECTED_INDEX";
9
10
  return ACTIONS;
10
11
  }({});
@@ -0,0 +1,18 @@
1
+ import { ACTIONS } from '../actions';
2
+ import { pluginKey as typeAheadPluginKey } from '../key';
3
+ export var updateListError = function updateListError(errorInfo) {
4
+ return function (state, dispatch) {
5
+ var tr = state.tr;
6
+ tr.setMeta(typeAheadPluginKey, {
7
+ action: ACTIONS.UPDATE_LIST_ERROR,
8
+ params: {
9
+ errorInfo: errorInfo,
10
+ items: []
11
+ }
12
+ });
13
+ if (dispatch) {
14
+ dispatch(tr);
15
+ }
16
+ return true;
17
+ };
18
+ };
@@ -52,6 +52,7 @@ export function createPlugin(_ref) {
52
52
  decorationSet: DecorationSet.empty,
53
53
  decorationElement: null,
54
54
  items: [],
55
+ errorInfo: null,
55
56
  selectedIndex: -1,
56
57
  stats: null,
57
58
  inputMethod: null
@@ -102,6 +102,7 @@ export var createReducer = function createReducer(_ref) {
102
102
  var shouldCloseMenu = [ACTIONS.CLOSE_TYPE_AHEAD, ACTIONS.INSERT_ITEM].includes(action) || selectionChanged;
103
103
  var shouldUpdateQuery = action === ACTIONS.CHANGE_QUERY;
104
104
  var shouldUpdateListItems = action === ACTIONS.UPDATE_LIST_ITEMS;
105
+ var shouldUpdateListError = action === ACTIONS.UPDATE_LIST_ERROR;
105
106
  var shouldUpdateSelectedIndex = action === ACTIONS.UPDATE_SELECTED_INDEX;
106
107
  if (shouldOpenMenu) {
107
108
  return openMenu(currentPluginState, {
@@ -116,6 +117,13 @@ export var createReducer = function createReducer(_ref) {
116
117
  return _objectSpread(_objectSpread({}, currentPluginState), {}, {
117
118
  query: params.query
118
119
  });
120
+ } else if (shouldUpdateListError) {
121
+ var errorInfo = params.errorInfo;
122
+ return _objectSpread(_objectSpread({}, currentPluginState), {}, {
123
+ errorInfo: errorInfo,
124
+ items: [],
125
+ selectedIndex: -1
126
+ });
119
127
  } else if (shouldUpdateListItems) {
120
128
  var items = params.items;
121
129
  var selectedIndex = currentPluginState.selectedIndex;
@@ -1,4 +1,5 @@
1
1
  import { TypeAheadAvailableNodes, typeAheadListMessages } from '@atlaskit/editor-common/type-ahead';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { updateSelectedIndex } from './commands/update-selected-index';
3
4
  import { itemIsDisabled } from './item-is-disabled';
4
5
  import { pluginKey as typeAheadPluginKey } from './key';
@@ -39,32 +40,56 @@ export var findHandler = function findHandler(id, state) {
39
40
  return h.id === id;
40
41
  }) || null;
41
42
  };
42
- export var skipForwardToSafeItem = function skipForwardToSafeItem(currentIndex, nextIndex, listSize, itemIsDisabled
43
- // Ignored via go/ees005
44
- // eslint-disable-next-line @typescript-eslint/max-params
45
- ) {
43
+ export var skipForwardToSafeItem = function skipForwardToSafeItem(_ref) {
44
+ var currentIndex = _ref.currentIndex,
45
+ nextIndex = _ref.nextIndex,
46
+ listSize = _ref.listSize,
47
+ itemIsDisabled = _ref.itemIsDisabled;
46
48
  // Use a loop to find the next selectable item
47
49
  for (var idx = nextIndex; idx < listSize; idx++) {
48
50
  if (!itemIsDisabled(idx)) {
49
51
  return idx;
50
52
  }
51
53
  }
54
+
55
+ // We got to the end of the list ^, now try from the start
56
+ if (fg('platform_editor_offline_editing_ga')) {
57
+ for (var _idx = 0; _idx < nextIndex; _idx++) {
58
+ if (!itemIsDisabled(_idx)) {
59
+ return _idx;
60
+ }
61
+ }
62
+ }
63
+
52
64
  // If no selectable items are found, return currentIndex
53
65
  return currentIndex;
54
66
  };
55
- export var skipBackwardToSafeItem = function skipBackwardToSafeItem(currentIndex, nextIndex, itemIsDisabled) {
67
+ export var skipBackwardToSafeItem = function skipBackwardToSafeItem(_ref2) {
68
+ var currentIndex = _ref2.currentIndex,
69
+ nextIndex = _ref2.nextIndex,
70
+ listSize = _ref2.listSize,
71
+ itemIsDisabled = _ref2.itemIsDisabled;
56
72
  // Use a loop to find the next non-selectable item when going backwards
57
73
  for (var idx = nextIndex; idx >= 0; idx--) {
58
74
  if (!itemIsDisabled(idx)) {
59
75
  return idx;
60
76
  }
61
77
  }
78
+
79
+ // We got to the start of the list ^, now try from the end
80
+ if (fg('platform_editor_offline_editing_ga')) {
81
+ for (var _idx2 = listSize; _idx2 > nextIndex; _idx2--) {
82
+ if (!itemIsDisabled(_idx2)) {
83
+ return _idx2;
84
+ }
85
+ }
86
+ }
62
87
  // If no non-selectable items are found, return currentIndex
63
88
  return currentIndex;
64
89
  };
65
- export var findHandlerByTrigger = function findHandlerByTrigger(_ref) {
66
- var trigger = _ref.trigger,
67
- editorState = _ref.editorState;
90
+ export var findHandlerByTrigger = function findHandlerByTrigger(_ref3) {
91
+ var trigger = _ref3.trigger,
92
+ editorState = _ref3.editorState;
68
93
  var pluginState = typeAheadPluginKey.getState(editorState);
69
94
  if (!pluginState || !pluginState.typeAheadHandlers || pluginState.typeAheadHandlers.length === 0) {
70
95
  return null;
@@ -74,10 +99,10 @@ export var findHandlerByTrigger = function findHandlerByTrigger(_ref) {
74
99
  return h.trigger === trigger;
75
100
  }) || null;
76
101
  };
77
- export var moveSelectedIndex = function moveSelectedIndex(_ref2) {
78
- var editorView = _ref2.editorView,
79
- direction = _ref2.direction,
80
- api = _ref2.api;
102
+ export var moveSelectedIndex = function moveSelectedIndex(_ref4) {
103
+ var editorView = _ref4.editorView,
104
+ direction = _ref4.direction,
105
+ api = _ref4.api;
81
106
  return function () {
82
107
  var typeAheadState = getPluginState(editorView.state);
83
108
  if (!typeAheadState) {
@@ -111,11 +136,21 @@ export var moveSelectedIndex = function moveSelectedIndex(_ref2) {
111
136
  } else {
112
137
  nextIndex = selectedIndex >= items.length - 1 ? 0 : selectedIndex + 1;
113
138
  }
114
- nextIndex = skipForwardToSafeItem(selectedIndex, nextIndex, items.length, isDisabled);
139
+ nextIndex = skipForwardToSafeItem({
140
+ currentIndex: selectedIndex,
141
+ nextIndex: nextIndex,
142
+ listSize: items.length,
143
+ itemIsDisabled: isDisabled
144
+ });
115
145
  } else {
116
146
  stats.increaseArrowUp();
117
147
  nextIndex = selectedIndex <= 0 ? items.length - 1 : selectedIndex - 1;
118
- nextIndex = skipBackwardToSafeItem(selectedIndex, nextIndex, isDisabled);
148
+ nextIndex = skipBackwardToSafeItem({
149
+ currentIndex: selectedIndex,
150
+ nextIndex: nextIndex,
151
+ listSize: items.length,
152
+ itemIsDisabled: isDisabled
153
+ });
119
154
  }
120
155
  updateSelectedIndex(nextIndex, api)(editorView.state, editorView.dispatch);
121
156
  };
@@ -193,7 +193,7 @@ export var typeAheadPlugin = function typeAheadPlugin(_ref) {
193
193
  }];
194
194
  },
195
195
  getSharedState: function getSharedState(editorState) {
196
- var _state$decorationSet, _state$decorationElem, _state$items, _state$selectedIndex;
196
+ var _state$decorationSet, _state$decorationElem, _state$items, _state$errorInfo, _state$selectedIndex;
197
197
  if (!editorState) {
198
198
  return {
199
199
  query: '',
@@ -204,6 +204,7 @@ export var typeAheadPlugin = function typeAheadPlugin(_ref) {
204
204
  decorationElement: null,
205
205
  triggerHandler: undefined,
206
206
  items: [],
207
+ errorInfo: null,
207
208
  selectedIndex: 0
208
209
  };
209
210
  }
@@ -218,6 +219,7 @@ export var typeAheadPlugin = function typeAheadPlugin(_ref) {
218
219
  decorationElement: (_state$decorationElem = state === null || state === void 0 ? void 0 : state.decorationElement) !== null && _state$decorationElem !== void 0 ? _state$decorationElem : null,
219
220
  triggerHandler: state === null || state === void 0 ? void 0 : state.triggerHandler,
220
221
  items: (_state$items = state === null || state === void 0 ? void 0 : state.items) !== null && _state$items !== void 0 ? _state$items : [],
222
+ errorInfo: (_state$errorInfo = state === null || state === void 0 ? void 0 : state.errorInfo) !== null && _state$errorInfo !== void 0 ? _state$errorInfo : null,
221
223
  selectedIndex: (_state$selectedIndex = state === null || state === void 0 ? void 0 : state.selectedIndex) !== null && _state$selectedIndex !== void 0 ? _state$selectedIndex : 0
222
224
  };
223
225
  },
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import Heading from '@atlaskit/heading';
3
+ import { Flex, Text, xcss } from '@atlaskit/primitives';
4
+ var containerStyles = xcss({
5
+ marginBlockStart: 'space.600',
6
+ marginBlockEnd: 'space.600',
7
+ textAlign: 'center'
8
+ });
9
+ export var EmptyState = function EmptyState(_ref) {
10
+ var testId = _ref.testId,
11
+ header = _ref.header,
12
+ description = _ref.description,
13
+ renderImage = _ref.renderImage;
14
+ return /*#__PURE__*/React.createElement(Flex, {
15
+ xcss: containerStyles,
16
+ testId: testId,
17
+ direction: "column",
18
+ alignItems: "center",
19
+ gap: "space.300"
20
+ }, renderImage === null || renderImage === void 0 ? void 0 : renderImage(), /*#__PURE__*/React.createElement(Flex, {
21
+ direction: "column",
22
+ alignItems: "center",
23
+ gap: "space.200"
24
+ }, /*#__PURE__*/React.createElement(Heading, {
25
+ size: "medium",
26
+ as: "h2"
27
+ }, header), description && /*#__PURE__*/React.createElement(Text, {
28
+ as: "p",
29
+ color: "color.text"
30
+ }, description)));
31
+ };