@atlaskit/editor-core 172.3.2 → 173.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/cjs/index.js +0 -6
  3. package/dist/cjs/plugins/base/index.js +8 -0
  4. package/dist/cjs/plugins/base/pm-plugins/composition.js +60 -0
  5. package/dist/cjs/plugins/breakout/index.js +5 -4
  6. package/dist/cjs/plugins/breakout/ui/LayoutButton.js +1 -3
  7. package/dist/cjs/plugins/card/pm-plugins/doc.js +8 -1
  8. package/dist/cjs/plugins/code-block/pm-plugins/ide-ux.js +2 -36
  9. package/dist/cjs/plugins/collab-edit/plugin-state.js +16 -9
  10. package/dist/cjs/plugins/collab-edit/utils.js +16 -2
  11. package/dist/cjs/plugins/feature-flags-context/feature-flags-from-props.js +24 -22
  12. package/dist/cjs/plugins/floating-toolbar/ui/Dropdown.js +20 -15
  13. package/dist/cjs/plugins/floating-toolbar/ui/DropdownMenu.js +8 -5
  14. package/dist/cjs/plugins/floating-toolbar/ui/Toolbar.js +3 -3
  15. package/dist/cjs/plugins/paste/actions.js +13 -0
  16. package/dist/cjs/plugins/paste/commands.js +44 -0
  17. package/dist/cjs/plugins/paste/handlers.js +48 -7
  18. package/dist/cjs/plugins/paste/index.js +3 -2
  19. package/dist/cjs/plugins/paste/pm-plugins/main.js +34 -9
  20. package/dist/cjs/plugins/paste/pm-plugins/plugin-factory.js +62 -0
  21. package/dist/cjs/plugins/paste/reducer.js +47 -0
  22. package/dist/cjs/plugins/paste/types.js +5 -0
  23. package/dist/cjs/plugins/placeholder/index.js +3 -1
  24. package/dist/cjs/plugins/placeholder-text/index.js +9 -3
  25. package/dist/cjs/plugins/status/ui/statusPicker.js +4 -1
  26. package/dist/cjs/plugins/table/commands-with-analytics.js +59 -52
  27. package/dist/cjs/plugins/table/index.js +53 -36
  28. package/dist/cjs/plugins/table/toolbar.js +136 -20
  29. package/dist/cjs/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +3 -3
  30. package/dist/cjs/plugins/tasks-and-decisions/commands.js +1 -16
  31. package/dist/cjs/plugins/type-ahead/constants.js +3 -1
  32. package/dist/cjs/plugins/type-ahead/messages.js +16 -1
  33. package/dist/cjs/plugins/type-ahead/pm-plugins/main.js +1 -1
  34. package/dist/cjs/plugins/type-ahead/pm-plugins/reducer.js +2 -2
  35. package/dist/cjs/plugins/type-ahead/ui/AssistiveText.js +143 -0
  36. package/dist/cjs/plugins/type-ahead/ui/InputQuery.js +59 -11
  37. package/dist/cjs/plugins/type-ahead/ui/TypeAheadList.js +156 -31
  38. package/dist/cjs/plugins/type-ahead/ui/TypeAheadListItem.js +55 -29
  39. package/dist/cjs/plugins/type-ahead/ui/TypeAheadPopup.js +3 -3
  40. package/dist/cjs/plugins/type-ahead/ui/WrapperTypeAhead.js +5 -2
  41. package/dist/cjs/plugins/type-ahead/utils.js +1 -1
  42. package/dist/cjs/ui/MediaAndEmbedsToolbar/index.js +8 -0
  43. package/dist/cjs/ui/PortalProvider/PortalProviderThemesProvider.js +2 -6
  44. package/dist/cjs/ui/PortalProvider/index.js +26 -32
  45. package/dist/cjs/utils/index.js +8 -1
  46. package/dist/cjs/utils/selection.js +6 -8
  47. package/dist/cjs/version-wrapper.js +1 -1
  48. package/dist/cjs/version.json +1 -1
  49. package/dist/es2019/index.js +1 -1
  50. package/dist/es2019/plugins/base/index.js +5 -0
  51. package/dist/es2019/plugins/base/pm-plugins/composition.js +45 -0
  52. package/dist/es2019/plugins/breakout/index.js +5 -4
  53. package/dist/es2019/plugins/breakout/ui/LayoutButton.js +1 -3
  54. package/dist/es2019/plugins/card/pm-plugins/doc.js +10 -1
  55. package/dist/es2019/plugins/code-block/pm-plugins/ide-ux.js +3 -40
  56. package/dist/es2019/plugins/collab-edit/plugin-state.js +9 -3
  57. package/dist/es2019/plugins/collab-edit/utils.js +17 -3
  58. package/dist/es2019/plugins/feature-flags-context/feature-flags-from-props.js +24 -22
  59. package/dist/es2019/plugins/floating-toolbar/ui/Dropdown.js +15 -7
  60. package/dist/es2019/plugins/floating-toolbar/ui/DropdownMenu.js +9 -5
  61. package/dist/es2019/plugins/floating-toolbar/ui/Toolbar.js +3 -3
  62. package/dist/es2019/plugins/paste/actions.js +6 -0
  63. package/dist/es2019/plugins/paste/commands.js +27 -0
  64. package/dist/es2019/plugins/paste/handlers.js +50 -8
  65. package/dist/es2019/plugins/paste/index.js +3 -2
  66. package/dist/es2019/plugins/paste/pm-plugins/main.js +29 -6
  67. package/dist/es2019/plugins/paste/pm-plugins/plugin-factory.js +33 -0
  68. package/dist/es2019/plugins/paste/reducer.js +24 -0
  69. package/dist/es2019/plugins/paste/types.js +1 -0
  70. package/dist/es2019/plugins/placeholder/index.js +2 -1
  71. package/dist/es2019/plugins/placeholder-text/index.js +13 -3
  72. package/dist/es2019/plugins/status/ui/statusPicker.js +5 -1
  73. package/dist/es2019/plugins/table/commands-with-analytics.js +6 -3
  74. package/dist/es2019/plugins/table/index.js +22 -4
  75. package/dist/es2019/plugins/table/toolbar.js +118 -14
  76. package/dist/es2019/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +3 -3
  77. package/dist/es2019/plugins/tasks-and-decisions/commands.js +0 -9
  78. package/dist/es2019/plugins/type-ahead/constants.js +1 -0
  79. package/dist/es2019/plugins/type-ahead/messages.js +16 -1
  80. package/dist/es2019/plugins/type-ahead/pm-plugins/main.js +1 -1
  81. package/dist/es2019/plugins/type-ahead/pm-plugins/reducer.js +2 -2
  82. package/dist/es2019/plugins/type-ahead/ui/AssistiveText.js +95 -0
  83. package/dist/es2019/plugins/type-ahead/ui/InputQuery.js +49 -12
  84. package/dist/es2019/plugins/type-ahead/ui/TypeAheadList.js +143 -29
  85. package/dist/es2019/plugins/type-ahead/ui/TypeAheadListItem.js +64 -31
  86. package/dist/es2019/plugins/type-ahead/ui/TypeAheadPopup.js +3 -3
  87. package/dist/es2019/plugins/type-ahead/ui/WrapperTypeAhead.js +5 -2
  88. package/dist/es2019/plugins/type-ahead/utils.js +1 -1
  89. package/dist/es2019/ui/MediaAndEmbedsToolbar/index.js +17 -0
  90. package/dist/es2019/ui/PortalProvider/PortalProviderThemesProvider.js +2 -5
  91. package/dist/es2019/ui/PortalProvider/index.js +5 -8
  92. package/dist/es2019/utils/index.js +6 -0
  93. package/dist/es2019/utils/selection.js +1 -9
  94. package/dist/es2019/version-wrapper.js +1 -1
  95. package/dist/es2019/version.json +1 -1
  96. package/dist/esm/index.js +1 -1
  97. package/dist/esm/plugins/base/index.js +7 -0
  98. package/dist/esm/plugins/base/pm-plugins/composition.js +45 -0
  99. package/dist/esm/plugins/breakout/index.js +5 -4
  100. package/dist/esm/plugins/breakout/ui/LayoutButton.js +1 -3
  101. package/dist/esm/plugins/card/pm-plugins/doc.js +8 -1
  102. package/dist/esm/plugins/code-block/pm-plugins/ide-ux.js +3 -37
  103. package/dist/esm/plugins/collab-edit/plugin-state.js +9 -3
  104. package/dist/esm/plugins/collab-edit/utils.js +17 -3
  105. package/dist/esm/plugins/feature-flags-context/feature-flags-from-props.js +24 -22
  106. package/dist/esm/plugins/floating-toolbar/ui/Dropdown.js +20 -15
  107. package/dist/esm/plugins/floating-toolbar/ui/DropdownMenu.js +8 -5
  108. package/dist/esm/plugins/floating-toolbar/ui/Toolbar.js +3 -3
  109. package/dist/esm/plugins/paste/actions.js +6 -0
  110. package/dist/esm/plugins/paste/commands.js +31 -0
  111. package/dist/esm/plugins/paste/handlers.js +46 -8
  112. package/dist/esm/plugins/paste/index.js +3 -2
  113. package/dist/esm/plugins/paste/pm-plugins/main.js +27 -6
  114. package/dist/esm/plugins/paste/pm-plugins/plugin-factory.js +46 -0
  115. package/dist/esm/plugins/paste/reducer.js +34 -0
  116. package/dist/esm/plugins/paste/types.js +1 -0
  117. package/dist/esm/plugins/placeholder/index.js +2 -1
  118. package/dist/esm/plugins/placeholder-text/index.js +9 -3
  119. package/dist/esm/plugins/status/ui/statusPicker.js +4 -1
  120. package/dist/esm/plugins/table/commands-with-analytics.js +56 -49
  121. package/dist/esm/plugins/table/index.js +54 -37
  122. package/dist/esm/plugins/table/toolbar.js +124 -15
  123. package/dist/esm/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +3 -3
  124. package/dist/esm/plugins/tasks-and-decisions/commands.js +0 -12
  125. package/dist/esm/plugins/type-ahead/constants.js +1 -0
  126. package/dist/esm/plugins/type-ahead/messages.js +16 -1
  127. package/dist/esm/plugins/type-ahead/pm-plugins/main.js +1 -1
  128. package/dist/esm/plugins/type-ahead/pm-plugins/reducer.js +2 -2
  129. package/dist/esm/plugins/type-ahead/ui/AssistiveText.js +129 -0
  130. package/dist/esm/plugins/type-ahead/ui/InputQuery.js +56 -12
  131. package/dist/esm/plugins/type-ahead/ui/TypeAheadList.js +151 -32
  132. package/dist/esm/plugins/type-ahead/ui/TypeAheadListItem.js +54 -31
  133. package/dist/esm/plugins/type-ahead/ui/TypeAheadPopup.js +3 -3
  134. package/dist/esm/plugins/type-ahead/ui/WrapperTypeAhead.js +5 -2
  135. package/dist/esm/plugins/type-ahead/utils.js +1 -1
  136. package/dist/esm/ui/MediaAndEmbedsToolbar/index.js +7 -0
  137. package/dist/esm/ui/PortalProvider/PortalProviderThemesProvider.js +2 -5
  138. package/dist/esm/ui/PortalProvider/index.js +26 -35
  139. package/dist/esm/utils/index.js +4 -0
  140. package/dist/esm/utils/selection.js +1 -7
  141. package/dist/esm/version-wrapper.js +1 -1
  142. package/dist/esm/version.json +1 -1
  143. package/dist/types/index.d.ts +1 -1
  144. package/dist/types/plugins/base/pm-plugins/composition.d.ts +8 -0
  145. package/dist/types/plugins/code-block/pm-plugins/ide-ux.d.ts +1 -4
  146. package/dist/types/plugins/floating-toolbar/ui/Dropdown.d.ts +2 -0
  147. package/dist/types/plugins/floating-toolbar/ui/DropdownMenu.d.ts +1 -0
  148. package/dist/types/plugins/paste/actions.d.ts +15 -0
  149. package/dist/types/plugins/paste/commands.d.ts +16 -0
  150. package/dist/types/plugins/paste/handlers.d.ts +1 -1
  151. package/dist/types/plugins/paste/pm-plugins/main.d.ts +3 -3
  152. package/dist/types/plugins/paste/pm-plugins/plugin-factory.d.ts +3 -0
  153. package/dist/types/plugins/paste/reducer.d.ts +3 -0
  154. package/dist/types/plugins/paste/types.d.ts +6 -0
  155. package/dist/types/plugins/table/commands-with-analytics.d.ts +5 -5
  156. package/dist/types/plugins/tasks-and-decisions/commands.d.ts +0 -2
  157. package/dist/types/plugins/type-ahead/constants.d.ts +1 -0
  158. package/dist/types/plugins/type-ahead/messages.d.ts +15 -0
  159. package/dist/types/plugins/type-ahead/ui/AssistiveText.d.ts +33 -0
  160. package/dist/types/plugins/type-ahead/ui/InputQuery.d.ts +3 -0
  161. package/dist/types/plugins/type-ahead/ui/TypeAheadList.d.ts +6 -3
  162. package/dist/types/plugins/type-ahead/ui/TypeAheadListItem.d.ts +2 -2
  163. package/dist/types/plugins/type-ahead/ui/TypeAheadPopup.d.ts +1 -1
  164. package/dist/types/ui/Appearance/FullPage/StyledComponents.d.ts +2 -2
  165. package/dist/types/ui/ContentStyles/index.d.ts +2 -2
  166. package/dist/types/utils/index.d.ts +1 -0
  167. package/dist/types/utils/selection.d.ts +1 -2
  168. package/dist/types-ts4.0/index.d.ts +1 -1
  169. package/dist/types-ts4.0/plugins/base/pm-plugins/composition.d.ts +8 -0
  170. package/dist/types-ts4.0/plugins/code-block/pm-plugins/ide-ux.d.ts +1 -4
  171. package/dist/types-ts4.0/plugins/floating-toolbar/ui/Dropdown.d.ts +2 -0
  172. package/dist/types-ts4.0/plugins/floating-toolbar/ui/DropdownMenu.d.ts +1 -0
  173. package/dist/types-ts4.0/plugins/paste/actions.d.ts +15 -0
  174. package/dist/types-ts4.0/plugins/paste/commands.d.ts +16 -0
  175. package/dist/types-ts4.0/plugins/paste/handlers.d.ts +1 -1
  176. package/dist/types-ts4.0/plugins/paste/pm-plugins/main.d.ts +3 -3
  177. package/dist/types-ts4.0/plugins/paste/pm-plugins/plugin-factory.d.ts +3 -0
  178. package/dist/types-ts4.0/plugins/paste/reducer.d.ts +3 -0
  179. package/dist/types-ts4.0/plugins/paste/types.d.ts +6 -0
  180. package/dist/types-ts4.0/plugins/table/commands-with-analytics.d.ts +5 -5
  181. package/dist/types-ts4.0/plugins/tasks-and-decisions/commands.d.ts +0 -2
  182. package/dist/types-ts4.0/plugins/type-ahead/constants.d.ts +1 -0
  183. package/dist/types-ts4.0/plugins/type-ahead/messages.d.ts +15 -0
  184. package/dist/types-ts4.0/plugins/type-ahead/ui/AssistiveText.d.ts +33 -0
  185. package/dist/types-ts4.0/plugins/type-ahead/ui/InputQuery.d.ts +3 -0
  186. package/dist/types-ts4.0/plugins/type-ahead/ui/TypeAheadList.d.ts +6 -3
  187. package/dist/types-ts4.0/plugins/type-ahead/ui/TypeAheadListItem.d.ts +2 -2
  188. package/dist/types-ts4.0/plugins/type-ahead/ui/TypeAheadPopup.d.ts +1 -1
  189. package/dist/types-ts4.0/ui/Appearance/FullPage/StyledComponents.d.ts +2 -2
  190. package/dist/types-ts4.0/ui/ContentStyles/index.d.ts +2 -2
  191. package/dist/types-ts4.0/utils/index.d.ts +1 -0
  192. package/dist/types-ts4.0/utils/selection.d.ts +1 -2
  193. package/package.json +30 -31
  194. package/report.api.md +161 -49
@@ -2,22 +2,44 @@
2
2
  import React, { useMemo, useRef, useCallback, useLayoutEffect, useState } from 'react';
3
3
  import { jsx, css } from '@emotion/react';
4
4
  import { MenuGroup } from '@atlaskit/menu';
5
+ import { SelectItemMode } from '@atlaskit/editor-common/type-ahead';
5
6
  import { CellMeasurer, CellMeasurerCache } from 'react-virtualized/dist/commonjs/CellMeasurer';
6
7
  import { List } from 'react-virtualized/dist/commonjs/List';
7
8
  import { ICON_HEIGHT, ITEM_PADDING, TypeAheadListItem } from './TypeAheadListItem';
8
- import { injectIntl } from 'react-intl-next';
9
+ import { injectIntl, useIntl } from 'react-intl-next';
9
10
  import { typeAheadListMessages } from '../messages';
11
+ import { moveSelectedIndex } from '../utils';
12
+ import { updateSelectedIndex } from '../commands/update-selected-index';
13
+ import { AssistiveText } from './AssistiveText';
14
+ import { TYPE_AHEAD_DECORATION_ELEMENT_ID } from '../constants';
10
15
  const LIST_ITEM_ESTIMATED_HEIGHT = ICON_HEIGHT + ITEM_PADDING * 2;
11
16
  const LIST_WIDTH = 320;
17
+ const TypeaheadAssistiveTextPureComponent = /*#__PURE__*/React.memo(({
18
+ numberOfResults
19
+ }) => {
20
+ const intl = useIntl();
21
+ return jsx(AssistiveText, {
22
+ assistiveText: intl.formatMessage(typeAheadListMessages.searchResultsLabel, {
23
+ itemsLength: numberOfResults
24
+ }) // when the popup is open its always in focus
25
+ ,
26
+ isInFocus: true,
27
+ id: TYPE_AHEAD_DECORATION_ELEMENT_ID + '__popup'
28
+ });
29
+ });
12
30
  const TypeAheadListComponent = /*#__PURE__*/React.memo(({
13
31
  items,
14
32
  selectedIndex,
15
- onItemHover,
33
+ editorView,
16
34
  onItemClick,
17
35
  intl,
18
- fitHeight
36
+ fitHeight,
37
+ decorationElement
19
38
  }) => {
39
+ var _decorationElement$qu2;
40
+
20
41
  const listRef = useRef();
42
+ const listContainerRef = useRef(null);
21
43
  const lastVisibleIndexes = useRef({
22
44
  overscanStartIndex: 0,
23
45
  overscanStopIndex: 0,
@@ -34,9 +56,31 @@ const TypeAheadListComponent = /*#__PURE__*/React.memo(({
34
56
  lastVisibleIndexes.current = props;
35
57
  }, []);
36
58
  const actions = useMemo(() => ({
37
- onItemClick,
38
- onItemHover
39
- }), [onItemClick, onItemHover]);
59
+ onItemClick
60
+ }), [onItemClick]);
61
+
62
+ const isNavigationKey = event => {
63
+ return ['ArrowDown', 'ArrowUp', 'Tab', 'Enter'].includes(event.key);
64
+ };
65
+
66
+ const focusTargetElement = useCallback(() => {
67
+ var _decorationElement$qu;
68
+
69
+ //To reset the selected index
70
+ updateSelectedIndex(-1)(editorView.state, editorView.dispatch);
71
+ listRef.current.scrollToRow(0);
72
+ decorationElement === null || decorationElement === void 0 ? void 0 : (_decorationElement$qu = decorationElement.querySelector(`[role='combobox']`)) === null || _decorationElement$qu === void 0 ? void 0 : _decorationElement$qu.focus();
73
+ }, [editorView, listRef, decorationElement]);
74
+ const selectNextItem = useMemo(() => moveSelectedIndex({
75
+ editorView,
76
+ direction: 'next'
77
+ }), [editorView]);
78
+ const selectPreviousItem = useMemo(() => moveSelectedIndex({
79
+ editorView,
80
+ direction: 'previous'
81
+ }), [editorView]);
82
+ const lastVisibleStartIndex = lastVisibleIndexes.current.startIndex;
83
+ const lastVisibleStopIndex = lastVisibleIndexes.current.stopIndex;
40
84
  const onScroll = useCallback(({
41
85
  scrollUpdateWasRequested
42
86
  }) => {
@@ -56,31 +100,29 @@ const TypeAheadListComponent = /*#__PURE__*/React.memo(({
56
100
 
57
101
  requestAnimationFrame(() => {
58
102
  requestAnimationFrame(() => {
59
- const {
60
- current: indexes
61
- } = lastVisibleIndexes;
62
- const isSelectedItemVisible = selectedIndex >= indexes.startIndex && selectedIndex <= indexes.stopIndex;
103
+ const isSelectedItemVisible = selectedIndex >= lastVisibleStartIndex && selectedIndex <= lastVisibleStopIndex; //Should scroll to the list item only when the selectedIndex >= 0 and item is not visible
63
104
 
64
- if (!isSelectedItemVisible) {
105
+ if (!isSelectedItemVisible && selectedIndex !== -1) {
65
106
  listRef.current.scrollToRow(selectedIndex);
107
+ } else if (selectedIndex === -1) {
108
+ listRef.current.scrollToRow(0);
66
109
  }
67
110
  });
68
111
  });
69
- }, [selectedIndex, lastVisibleIndexes]);
112
+ }, [selectedIndex, lastVisibleStartIndex, lastVisibleStopIndex]);
70
113
  useLayoutEffect(() => {
71
114
  if (!listRef.current) {
72
115
  return;
73
116
  }
74
117
 
75
- const {
76
- current: indexes
77
- } = lastVisibleIndexes;
78
- const isSelectedItemVisible = selectedIndex >= indexes.startIndex && selectedIndex <= indexes.stopIndex;
118
+ const isSelectedItemVisible = selectedIndex >= lastVisibleStartIndex && selectedIndex <= lastVisibleStopIndex; //Should scroll to the list item only when the selectedIndex >= 0 and item is not visible
79
119
 
80
- if (!isSelectedItemVisible) {
120
+ if (!isSelectedItemVisible && selectedIndex !== -1) {
81
121
  listRef.current.scrollToRow(selectedIndex);
122
+ } else if (selectedIndex === -1) {
123
+ listRef.current.scrollToRow(0);
82
124
  }
83
- }, [selectedIndex, lastVisibleIndexes]);
125
+ }, [selectedIndex, lastVisibleStartIndex, lastVisibleStopIndex]);
84
126
  useLayoutEffect(() => {
85
127
  setCache(new CellMeasurerCache({
86
128
  fixedWidth: true,
@@ -95,6 +137,72 @@ const TypeAheadListComponent = /*#__PURE__*/React.memo(({
95
137
  }, 0), fitHeight);
96
138
  setHeight(height);
97
139
  }, [items, cache, fitHeight]);
140
+ useLayoutEffect(() => {
141
+ if (!listContainerRef.current) {
142
+ return;
143
+ }
144
+
145
+ const {
146
+ current: element
147
+ } = listContainerRef;
148
+ /**
149
+ * To handle the key events on the list
150
+ * @param event
151
+ */
152
+
153
+ const handleKeyDown = event => {
154
+ if (isNavigationKey(event)) {
155
+ switch (event.key) {
156
+ case 'ArrowDown':
157
+ if (selectedIndex === items.length - 1) {
158
+ event.stopPropagation();
159
+ } else {
160
+ selectNextItem();
161
+ }
162
+
163
+ event.preventDefault();
164
+ break;
165
+
166
+ case 'ArrowUp':
167
+ if (selectedIndex === 0) {
168
+ //To set focus on target element when up arrow is pressed on first option of list
169
+ focusTargetElement();
170
+ } else {
171
+ selectPreviousItem();
172
+ }
173
+
174
+ event.preventDefault();
175
+ break;
176
+
177
+ case 'Tab':
178
+ //Tab key quick inserts the selected item.
179
+ onItemClick(SelectItemMode.TAB, selectedIndex);
180
+ event.preventDefault();
181
+ break;
182
+
183
+ case 'Enter':
184
+ //Enter key quick inserts the selected item.
185
+ if (!event.isComposing || event.which !== 229 && event.keyCode !== 229) {
186
+ onItemClick(event.shiftKey ? SelectItemMode.SHIFT_ENTER : SelectItemMode.ENTER, selectedIndex);
187
+ event.preventDefault();
188
+ }
189
+
190
+ break;
191
+
192
+ default:
193
+ event.preventDefault();
194
+ }
195
+ } else {
196
+ //All the remaining keys sets focus on the typeahead query(inputQuery.tsx))
197
+ focusTargetElement();
198
+ }
199
+ };
200
+
201
+ element === null || element === void 0 ? void 0 : element.addEventListener('keydown', handleKeyDown);
202
+ return () => {
203
+ element === null || element === void 0 ? void 0 : element.removeEventListener('keydown', handleKeyDown);
204
+ };
205
+ }, [editorView.state, focusTargetElement, selectNextItem, selectPreviousItem, selectedIndex, onItemClick, items.length]);
98
206
 
99
207
  const renderRow = ({
100
208
  index,
@@ -116,10 +224,10 @@ const TypeAheadListComponent = /*#__PURE__*/React.memo(({
116
224
  }, jsx(TypeAheadListItem, {
117
225
  key: items[index].title,
118
226
  item: items[index],
227
+ itemsLength: items.length,
119
228
  itemIndex: index,
120
229
  selectedIndex: selectedIndex,
121
- onItemClick: actions.onItemClick,
122
- onItemHover: actions.onItemHover
230
+ onItemClick: actions.onItemClick
123
231
  }))));
124
232
  };
125
233
 
@@ -127,11 +235,13 @@ const TypeAheadListComponent = /*#__PURE__*/React.memo(({
127
235
  return null;
128
236
  }
129
237
 
238
+ const menuGroupId = ((_decorationElement$qu2 = decorationElement.querySelector(`[role='combobox']`)) === null || _decorationElement$qu2 === void 0 ? void 0 : _decorationElement$qu2.getAttribute('aria-controls')) || TYPE_AHEAD_DECORATION_ELEMENT_ID;
130
239
  return jsx(MenuGroup, {
131
- role: "listbox",
132
- "aria-live": "polite",
133
240
  "aria-label": intl.formatMessage(typeAheadListMessages.typeAheadResultLabel),
134
241
  "aria-relevant": "additions removals"
242
+ }, jsx("div", {
243
+ id: menuGroupId,
244
+ ref: listContainerRef
135
245
  }, jsx(List, {
136
246
  rowRenderer: renderRow,
137
247
  ref: listRef,
@@ -142,15 +252,19 @@ const TypeAheadListComponent = /*#__PURE__*/React.memo(({
142
252
  onScroll: onScroll,
143
253
  height: height,
144
254
  overscanRowCount: 3,
255
+ containerRole: "presentation",
256
+ role: "listbox",
145
257
  css: css`
146
- button {
147
- padding: 12px 12px 11px;
148
- span:last-child span:last-child {
149
- white-space: normal;
258
+ button {
259
+ padding: 12px 12px 11px;
260
+ span:last-child span:last-child {
261
+ white-space: normal;
262
+ }
150
263
  }
151
- }
152
- `
153
- }));
264
+ `
265
+ }), jsx(TypeaheadAssistiveTextPureComponent, {
266
+ numberOfResults: items.length.toString()
267
+ })));
154
268
  });
155
269
  export const TypeAheadList = injectIntl(TypeAheadListComponent);
156
270
  TypeAheadList.displayName = 'TypeAheadList';
@@ -1,7 +1,7 @@
1
1
  /** @jsx jsx */
2
- import React, { useCallback, useMemo, useRef, useLayoutEffect } from 'react';
2
+ import React, { useCallback, useMemo, useLayoutEffect } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
- import { DN600, N200, N800 } from '@atlaskit/theme/colors';
4
+ import { DN600, N200, N800, N30, B100 } from '@atlaskit/theme/colors';
5
5
  import { themed } from '@atlaskit/theme/components';
6
6
  import { borderRadius } from '@atlaskit/theme/constants';
7
7
  import { ButtonItem } from '@atlaskit/menu';
@@ -54,9 +54,34 @@ const itemText = theme => css`
54
54
  const itemAfter = css`
55
55
  flex: 0 0 auto;
56
56
  `;
57
- const hidden = {
58
- overflow: 'hidden'
57
+ const customRenderItemDivStyle = css`
58
+ overflow: hidden;
59
+ &:hover {
60
+ background-color: ${token('color.background.selected', N30)};
61
+ }
62
+ &:focus {
63
+ box-shadow: inset 0px 0px 0px 2px ${token('color.border.focused', B100)};
64
+ outline: none;
65
+ }
66
+ `;
67
+ /**
68
+ * This CSS emulates the desired behaviour with :focus-visible for firefox.
69
+ * Firefox unfortunately does not register keyboard focus if user mouseDown and drag a typeahead item
70
+ * resulting in focus-visible style not drawn.
71
+ */
72
+
73
+ const selectionFrame = {
74
+ '& > button:focus': {
75
+ boxShadow: `inset 0px 0px 0px 2px ${token('color.border.focused', B100)}`,
76
+ outline: 'none',
77
+ '&:active': {
78
+ boxShadow: 'none'
79
+ }
80
+ }
59
81
  };
82
+ const selectedStyle = css`
83
+ background-color: ${token('color.background.selected', N30)};
84
+ `;
60
85
  const FallbackIcon = /*#__PURE__*/React.memo(({
61
86
  label
62
87
  }) => {
@@ -67,32 +92,16 @@ const noop = () => {};
67
92
 
68
93
  export const TypeAheadListItem = ({
69
94
  item,
95
+ itemsLength,
70
96
  selectedIndex,
71
- onItemHover,
72
97
  onItemClick,
73
98
  itemIndex
74
99
  }) => {
75
- const isSelected = itemIndex === selectedIndex; // It's possible for onMouseMove to be called multiple times in quick
76
- // succession because the mousemove event can fire very rapidly. This
77
- // provides an additional safety net to prevent that.
78
-
79
- const mouseMoveCalled = useRef(false);
80
- const onMouseMove = useCallback(() => {
81
- if (isSelected || mouseMoveCalled.current) {
82
- return;
83
- }
84
-
85
- mouseMoveCalled.current = true;
86
- onItemHover({
87
- item,
88
- index: itemIndex
89
- });
90
- }, [item, itemIndex, onItemHover, isSelected]);
91
- useLayoutEffect(() => {
92
- if (!isSelected) {
93
- mouseMoveCalled.current = false;
94
- }
95
- }, [isSelected]);
100
+ /**
101
+ * To select and highlight the first Item when no item is selected
102
+ * However selectedIndex remains -1, So that user does not skip the first item when down arrow key is used from typeahead query(inputQuery.tsx)
103
+ */
104
+ const isSelected = itemIndex === selectedIndex || selectedIndex === -1 && itemIndex === 0;
96
105
  const {
97
106
  icon,
98
107
  title,
@@ -108,39 +117,63 @@ export const TypeAheadListItem = ({
108
117
  const insertSelectedItem = useCallback(() => {
109
118
  onItemClick(SelectItemMode.SELECTED, itemIndex);
110
119
  }, [onItemClick, itemIndex]);
120
+ const customItemRef = /*#__PURE__*/React.createRef();
121
+ const buttonItemRef = /*#__PURE__*/React.createRef();
122
+ const shouldUpdateFocus = selectedIndex === itemIndex;
123
+ useLayoutEffect(() => {
124
+ if (shouldUpdateFocus) {
125
+ var _customItemRef$curren;
126
+
127
+ customItemRef === null || customItemRef === void 0 ? void 0 : (_customItemRef$curren = customItemRef.current) === null || _customItemRef$curren === void 0 ? void 0 : _customItemRef$curren.focus();
128
+ }
129
+ }, [customItemRef, shouldUpdateFocus]);
130
+ useLayoutEffect(() => {
131
+ if (shouldUpdateFocus) {
132
+ var _buttonItemRef$curren;
133
+
134
+ buttonItemRef === null || buttonItemRef === void 0 ? void 0 : (_buttonItemRef$curren = buttonItemRef.current) === null || _buttonItemRef$curren === void 0 ? void 0 : _buttonItemRef$curren.focus();
135
+ }
136
+ }, [buttonItemRef, shouldUpdateFocus]);
111
137
  const customItem = useMemo(() => {
112
138
  if (!customRenderItem) {
113
139
  return null;
114
140
  }
115
141
 
116
142
  const Comp = customRenderItem;
143
+ const listItemClasses = [customRenderItemDivStyle, isSelected && selectedStyle];
117
144
  return jsx("div", {
118
145
  "aria-selected": isSelected,
119
146
  "aria-label": title,
120
147
  role: "option",
148
+ "aria-setsize": itemsLength,
121
149
  tabIndex: 0,
122
- style: hidden,
123
- onMouseMove: onMouseMove
150
+ css: listItemClasses,
151
+ className: `ak-typeahead-item ${isSelected ? 'typeahead-selected-item' : ''}` //CSS classes added for test cases purpose
152
+ ,
153
+ ref: customItemRef
124
154
  }, jsx(Comp, {
125
155
  onClick: insertSelectedItem,
126
- isSelected: isSelected,
156
+ isSelected: false //The selection styles are handled in the parent div instead. Hence isSelected is made false always.
157
+ ,
127
158
  onHover: noop
128
159
  }));
129
- }, [customRenderItem, insertSelectedItem, onMouseMove, isSelected, title]);
160
+ }, [customRenderItem, insertSelectedItem, isSelected, title, customItemRef, itemsLength]);
130
161
 
131
162
  if (customItem) {
132
163
  return customItem;
133
164
  }
134
165
 
135
166
  return jsx("span", {
136
- onMouseMove: onMouseMove
167
+ css: selectionFrame
137
168
  }, jsx(ButtonItem, {
138
169
  onClick: insertSelectedItem,
139
170
  iconBefore: elementIcon,
140
171
  isSelected: isSelected,
141
172
  "aria-selected": isSelected,
142
173
  "aria-label": item.title,
174
+ "aria-setsize": itemsLength,
143
175
  role: "option",
176
+ ref: buttonItemRef,
144
177
  description: item.description
145
178
  }, jsx("div", {
146
179
  css: itemBody
@@ -47,7 +47,6 @@ export const TypeAheadPopup = /*#__PURE__*/React.memo(props => {
47
47
  popupsScrollableElement,
48
48
  items,
49
49
  selectedIndex,
50
- setSelectedItem,
51
50
  onItemInsert,
52
51
  fireAnalyticsCallback,
53
52
  isEmptyQuery
@@ -173,9 +172,10 @@ export const TypeAheadPopup = /*#__PURE__*/React.memo(props => {
173
172
  }), jsx(TypeAheadList, {
174
173
  items: items,
175
174
  selectedIndex: selectedIndex,
176
- onItemHover: setSelectedItem,
177
175
  onItemClick: onItemInsert,
178
- fitHeight: fitHeight
176
+ fitHeight: fitHeight,
177
+ editorView: editorView,
178
+ decorationElement: anchorElement
179
179
  })));
180
180
  });
181
181
  TypeAheadPopup.displayName = 'TypeAheadPopup';
@@ -105,6 +105,9 @@ export const WrapperTypeAhead = /*#__PURE__*/React.memo(({
105
105
  cancel: cancel,
106
106
  forceFocus: shouldFocusCursorInsideQuery,
107
107
  onUndoRedo: onUndoRedo,
108
- reopenQuery: reopenQuery
108
+ reopenQuery: reopenQuery,
109
+ editorView: editorView,
110
+ items: items
109
111
  });
110
- });
112
+ });
113
+ WrapperTypeAhead.displayName = 'WrapperTypeAhead';
@@ -94,7 +94,7 @@ export const moveSelectedIndex = ({
94
94
  items
95
95
  } = typeAheadState;
96
96
  const stats = typeAheadState.stats instanceof StatsModifier ? typeAheadState.stats : new StatsModifier();
97
- let nextIndex = 0;
97
+ let nextIndex;
98
98
 
99
99
  if (direction === 'next') {
100
100
  stats.increaseArrowDown();
@@ -14,6 +14,7 @@ import { DEFAULT_EMBED_CARD_WIDTH } from '@atlaskit/editor-shared-styles';
14
14
  import { addAnalytics } from '../../plugins/analytics/utils';
15
15
  import { ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, ACTION } from '../../plugins/analytics';
16
16
  import { toolbarMessages } from './toolbar-messages';
17
+ import { insideTable, isInLayoutColumn } from '../../utils';
17
18
  const alignmentIcons = [{
18
19
  id: 'editor.media.alignLeft',
19
20
  value: 'align-start',
@@ -94,6 +95,22 @@ const makeAlign = (layout, nodeType) => {
94
95
  // setNodeMarkup is called
95
96
 
96
97
  tr.setSelection(NodeSelection.create(tr.doc, state.selection.from));
98
+ const {
99
+ doc: {
100
+ type: {
101
+ schema: {
102
+ nodes: {
103
+ paragraph
104
+ }
105
+ }
106
+ }
107
+ }
108
+ } = tr; // see https://product-fabric.atlassian.net/browse/ED-15518 insert a new paragraph when an embedded card is wrapped left or right
109
+
110
+ if (layout.startsWith('wrap') && paragraph && !tr.doc.nodeAt(state.selection.to) && (insideTable(state) || isInLayoutColumn(state))) {
111
+ tr.insert(state.selection.to, paragraph.createAndFill());
112
+ }
113
+
97
114
  dispatch(addAnalytics(state, tr, {
98
115
  eventType: EVENT_TYPE.TRACK,
99
116
  action: ACTION.SELECTED,
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import AtlaskitTheme from '@atlaskit/theme/components';
3
3
  import { CHANNEL } from '@atlaskit/theme/constants';
4
4
  import { ThemeProvider } from '@emotion/react';
5
- import { ThemeProvider as DeprectateStyledComponentsProvider } from 'styled-components';
6
5
  export function PortalProviderThemeProviders(props) {
7
6
  const {
8
7
  children,
@@ -29,11 +28,9 @@ export function PortalProviderThemeProviders(props) {
29
28
  const atlaskitTheme = React.useCallback(() => ({
30
29
  mode
31
30
  }), [mode]);
32
- return /*#__PURE__*/React.createElement(DeprectateStyledComponentsProvider, {
33
- theme: styledComponentsAndEmotionTheme
34
- }, /*#__PURE__*/React.createElement(ThemeProvider, {
31
+ return /*#__PURE__*/React.createElement(ThemeProvider, {
35
32
  theme: styledComponentsAndEmotionTheme
36
33
  }, /*#__PURE__*/React.createElement(AtlaskitTheme.Provider, {
37
34
  value: atlaskitTheme
38
- }, children)));
35
+ }, children));
39
36
  }
@@ -33,12 +33,10 @@ export class PortalProviderAPI extends EventDispatcher {
33
33
  hasAnalyticsContext,
34
34
  hasIntlContext
35
35
  });
36
-
37
- const childrenWithThemeProviders = () => /*#__PURE__*/React.createElement(PortalProviderThemeProviders, {
36
+ const childrenWithThemeProviders = /*#__PURE__*/React.createElement(PortalProviderThemeProviders, {
38
37
  mode: this.themeMode
39
38
  }, children());
40
-
41
- let wrappedChildren = this.useAnalyticsContext ? /*#__PURE__*/React.createElement(AnalyticsContextWrapper, null, childrenWithThemeProviders()) : childrenWithThemeProviders();
39
+ let wrappedChildren = this.useAnalyticsContext ? /*#__PURE__*/React.createElement(AnalyticsContextWrapper, null, childrenWithThemeProviders) : childrenWithThemeProviders;
42
40
 
43
41
  if (hasIntlContext) {
44
42
  wrappedChildren = /*#__PURE__*/React.createElement(RawIntlProvider, {
@@ -64,19 +62,18 @@ export class PortalProviderAPI extends EventDispatcher {
64
62
  }
65
63
 
66
64
  let wrappedChildren = portal.children();
67
-
68
- const childrenWithThemeProviders = () => /*#__PURE__*/React.createElement(PortalProviderThemeProviders, {
65
+ const childrenWithThemeProviders = /*#__PURE__*/React.createElement(PortalProviderThemeProviders, {
69
66
  mode: themeMode
70
67
  }, wrappedChildren);
71
68
 
72
69
  if (portal.hasAnalyticsContext && this.useAnalyticsContext) {
73
- wrappedChildren = /*#__PURE__*/React.createElement(AnalyticsContextWrapper, null, childrenWithThemeProviders());
70
+ wrappedChildren = /*#__PURE__*/React.createElement(AnalyticsContextWrapper, null, childrenWithThemeProviders);
74
71
  }
75
72
 
76
73
  if (portal.hasIntlContext) {
77
74
  wrappedChildren = /*#__PURE__*/React.createElement(RawIntlProvider, {
78
75
  value: this.intl
79
- }, childrenWithThemeProviders());
76
+ }, childrenWithThemeProviders);
80
77
  }
81
78
 
82
79
  unstable_renderSubtreeIntoContainer(this.context, wrappedChildren, container);
@@ -526,6 +526,12 @@ export const isInListItem = state => {
526
526
  export const hasOpenEnd = slice => {
527
527
  return slice.openStart > 0 || slice.openEnd > 0;
528
528
  };
529
+ export const isInsideBlockQuote = state => {
530
+ const {
531
+ blockquote
532
+ } = state.schema.nodes;
533
+ return hasParentNodeOfType(blockquote)(state.selection);
534
+ };
529
535
  export function filterChildrenBetween(doc, from, to, predicate) {
530
536
  const results = [];
531
537
  doc.nodesBetween(from, to, (node, pos, parent) => {
@@ -1,15 +1,7 @@
1
1
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
2
2
  import { NodeSelection, TextSelection, AllSelection } from 'prosemirror-state';
3
3
  import { GapCursorSelection } from '@atlaskit/editor-common/selection';
4
- export { setNodeSelection } from '@atlaskit/editor-common/utils';
5
- export function setTextSelection(view, anchor, head) {
6
- const {
7
- state,
8
- dispatch
9
- } = view;
10
- const tr = state.tr.setSelection(TextSelection.create(state.doc, anchor, head));
11
- dispatch(tr);
12
- }
4
+ export { setNodeSelection, setTextSelection } from '@atlaskit/editor-common/utils';
13
5
  export function setAllSelection(view) {
14
6
  const {
15
7
  state,
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/editor-core";
2
- export const version = "172.3.2";
2
+ export const version = "173.0.1";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-core",
3
- "version": "172.3.2",
3
+ "version": "173.0.1",
4
4
  "sideEffects": false
5
5
  }
package/dist/esm/index.js CHANGED
@@ -29,7 +29,7 @@ export { subscribeToToolbarAndPickerUpdates } from './plugins/view-update-subscr
29
29
  export { subscribeTypeAheadUpdates } from './plugins/view-update-subscription/subscribe/type-ahead-updates';
30
30
  export { insertBlockType, insertBlockTypesWithAnalytics, setBlockType, setBlockTypeWithAnalytics } from './plugins/block-type/commands';
31
31
  export { createTable } from './plugins/table/commands';
32
- export { insertTaskDecision, insertTaskDecisionCommand } from './plugins/tasks-and-decisions/commands';
32
+ export { insertTaskDecisionCommand } from './plugins/tasks-and-decisions/commands';
33
33
  export { EventDispatcher } from './event-dispatcher';
34
34
  export { pluginKey as statusPluginKey } from './plugins/status/plugin';
35
35
  export { insertDate, openDatePicker, deleteDate } from './plugins/date/actions';
@@ -21,6 +21,7 @@ import decorationPlugin from './pm-plugins/decoration';
21
21
  import scrollGutter from './pm-plugins/scroll-gutter';
22
22
  import { keymap } from '../../utils/keymap';
23
23
  import frozenEditor from './pm-plugins/frozen-editor';
24
+ import compositionPlugin from './pm-plugins/composition';
24
25
  // Chrome >= 88
25
26
  export var isChromeWithSelectionBug = browser.chrome && browser.chrome_version >= 88;
26
27
 
@@ -134,6 +135,12 @@ var basePlugin = function basePlugin(options) {
134
135
  return disableSpellcheckingPlugin();
135
136
  }
136
137
  });
138
+ plugins.push({
139
+ name: 'compositionPlugin',
140
+ plugin: function plugin() {
141
+ return compositionPlugin();
142
+ }
143
+ });
137
144
  return plugins;
138
145
  },
139
146
  nodes: function nodes() {
@@ -0,0 +1,45 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { PluginKey } from 'prosemirror-state';
3
+ var compositionPluginKey = new PluginKey('compositionPlugin');
4
+ export var isComposing = function isComposing(state) {
5
+ return compositionPluginKey.getState(state).isComposing;
6
+ };
7
+ export default (function () {
8
+ return new SafePlugin({
9
+ key: compositionPluginKey,
10
+ state: {
11
+ init: function init() {
12
+ return {
13
+ isComposing: false
14
+ };
15
+ },
16
+ apply: function apply(tr, value) {
17
+ var isComposing = tr.getMeta(compositionPluginKey);
18
+
19
+ if (typeof isComposing === 'undefined') {
20
+ return value;
21
+ }
22
+
23
+ return {
24
+ isComposing: isComposing
25
+ };
26
+ }
27
+ },
28
+ props: {
29
+ handleDOMEvents: {
30
+ compositionstart: function compositionstart(view, event) {
31
+ var tr = view.state.tr;
32
+ tr.setMeta(compositionPluginKey, true);
33
+ view.dispatch(tr);
34
+ return false;
35
+ },
36
+ compositionend: function compositionend(view, event) {
37
+ var tr = view.state.tr;
38
+ tr.setMeta(compositionPluginKey, false);
39
+ view.dispatch(tr);
40
+ return false;
41
+ }
42
+ }
43
+ }
44
+ });
45
+ });