@atlaskit/emoji 67.0.7 → 67.2.0

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 (238) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/cjs/api/EmojiResource.js +41 -25
  3. package/dist/cjs/api/media/TokenManager.js +4 -4
  4. package/dist/cjs/components/common/CachingEmoji.js +14 -6
  5. package/dist/cjs/components/common/Emoji.js +48 -12
  6. package/dist/cjs/components/common/EmojiActions.js +62 -26
  7. package/dist/cjs/components/common/EmojiErrorMessage.js +12 -7
  8. package/dist/cjs/components/common/EmojiPlaceholder.js +1 -0
  9. package/dist/cjs/components/common/{EmojiButton.js → EmojiRadioButton.js} +28 -19
  10. package/dist/cjs/components/common/EmojiUploadPicker.js +80 -37
  11. package/dist/cjs/components/common/EmojiUploadPreview.js +11 -2
  12. package/dist/cjs/components/common/FileChooser.js +2 -2
  13. package/dist/cjs/components/common/ResourcedEmojiComponent.js +4 -0
  14. package/dist/cjs/components/common/RetryableButton.js +7 -3
  15. package/dist/cjs/components/common/TonePreviewButton.js +44 -0
  16. package/dist/cjs/components/common/ToneSelector.js +53 -25
  17. package/dist/cjs/components/common/styles.js +45 -16
  18. package/dist/cjs/components/i18n.js +44 -4
  19. package/dist/cjs/components/picker/CategorySelector.js +112 -90
  20. package/dist/cjs/components/picker/CategoryTracker.js +0 -28
  21. package/dist/cjs/components/picker/EmojiPickerCategoryHeading.js +2 -1
  22. package/dist/cjs/components/picker/EmojiPickerComponent.js +33 -44
  23. package/dist/cjs/components/picker/EmojiPickerEmojiRow.js +32 -4
  24. package/dist/cjs/components/picker/EmojiPickerList.js +154 -88
  25. package/dist/cjs/components/picker/EmojiPickerListSearch.js +66 -117
  26. package/dist/cjs/components/picker/EmojiPickerVirtualItems.js +5 -2
  27. package/dist/cjs/components/picker/VirtualList.js +273 -171
  28. package/dist/cjs/components/picker/styles.js +43 -51
  29. package/dist/cjs/components/typeahead/EmojiTypeAheadComponent.js +0 -10
  30. package/dist/cjs/context/EmojiPickerListContext.js +33 -0
  31. package/dist/cjs/hooks/useEmojiPickerListContext.js +12 -0
  32. package/dist/cjs/hooks/useIsMounted.js +17 -0
  33. package/dist/cjs/i18n/cs.js +35 -34
  34. package/dist/cjs/i18n/da.js +35 -34
  35. package/dist/cjs/i18n/de.js +35 -34
  36. package/dist/cjs/i18n/en.js +35 -34
  37. package/dist/cjs/i18n/en_GB.js +35 -34
  38. package/dist/cjs/i18n/es.js +35 -34
  39. package/dist/cjs/i18n/fi.js +35 -34
  40. package/dist/cjs/i18n/fr.js +35 -34
  41. package/dist/cjs/i18n/hu.js +35 -34
  42. package/dist/cjs/i18n/it.js +35 -34
  43. package/dist/cjs/i18n/ja.js +35 -34
  44. package/dist/cjs/i18n/ko.js +35 -34
  45. package/dist/cjs/i18n/nb.js +35 -34
  46. package/dist/cjs/i18n/nl.js +35 -34
  47. package/dist/cjs/i18n/pl.js +35 -34
  48. package/dist/cjs/i18n/pt_BR.js +35 -34
  49. package/dist/cjs/i18n/ru.js +35 -34
  50. package/dist/cjs/i18n/sv.js +35 -34
  51. package/dist/cjs/i18n/th.js +35 -34
  52. package/dist/cjs/i18n/tr.js +35 -34
  53. package/dist/cjs/i18n/uk.js +35 -34
  54. package/dist/cjs/i18n/vi.js +35 -34
  55. package/dist/cjs/i18n/zh.js +35 -34
  56. package/dist/cjs/i18n/zh_TW.js +35 -34
  57. package/dist/cjs/types.js +7 -1
  58. package/dist/cjs/util/constants.js +43 -2
  59. package/dist/cjs/util/shared-styles.js +3 -4
  60. package/dist/cjs/version.json +1 -1
  61. package/dist/es2019/api/EmojiResource.js +42 -26
  62. package/dist/es2019/api/media/TokenManager.js +4 -4
  63. package/dist/es2019/components/common/CachingEmoji.js +10 -3
  64. package/dist/es2019/components/common/Emoji.js +44 -11
  65. package/dist/es2019/components/common/EmojiActions.js +55 -24
  66. package/dist/es2019/components/common/EmojiErrorMessage.js +7 -3
  67. package/dist/es2019/components/common/EmojiPlaceholder.js +1 -0
  68. package/dist/es2019/components/common/EmojiRadioButton.js +54 -0
  69. package/dist/es2019/components/common/EmojiUploadPicker.js +75 -36
  70. package/dist/es2019/components/common/EmojiUploadPreview.js +11 -2
  71. package/dist/es2019/components/common/FileChooser.js +1 -1
  72. package/dist/es2019/components/common/ResourcedEmojiComponent.js +4 -0
  73. package/dist/es2019/components/common/RetryableButton.js +7 -3
  74. package/dist/es2019/components/common/TonePreviewButton.js +34 -0
  75. package/dist/es2019/components/common/ToneSelector.js +55 -21
  76. package/dist/es2019/components/common/styles.js +41 -10
  77. package/dist/es2019/components/i18n.js +44 -4
  78. package/dist/es2019/components/picker/CategorySelector.js +114 -89
  79. package/dist/es2019/components/picker/CategoryTracker.js +0 -24
  80. package/dist/es2019/components/picker/EmojiPickerCategoryHeading.js +2 -2
  81. package/dist/es2019/components/picker/EmojiPickerComponent.js +36 -46
  82. package/dist/es2019/components/picker/EmojiPickerEmojiRow.js +51 -21
  83. package/dist/es2019/components/picker/EmojiPickerList.js +113 -55
  84. package/dist/es2019/components/picker/EmojiPickerListSearch.js +61 -98
  85. package/dist/es2019/components/picker/EmojiPickerVirtualItems.js +4 -1
  86. package/dist/es2019/components/picker/VirtualList.js +247 -108
  87. package/dist/es2019/components/picker/styles.js +20 -28
  88. package/dist/es2019/components/typeahead/EmojiTypeAheadComponent.js +0 -10
  89. package/dist/es2019/context/EmojiPickerListContext.js +17 -0
  90. package/dist/es2019/hooks/useEmojiPickerListContext.js +3 -0
  91. package/dist/es2019/hooks/useIsMounted.js +11 -0
  92. package/dist/es2019/i18n/cs.js +35 -34
  93. package/dist/es2019/i18n/da.js +35 -34
  94. package/dist/es2019/i18n/de.js +35 -34
  95. package/dist/es2019/i18n/en.js +35 -34
  96. package/dist/es2019/i18n/en_GB.js +35 -34
  97. package/dist/es2019/i18n/es.js +35 -34
  98. package/dist/es2019/i18n/fi.js +35 -34
  99. package/dist/es2019/i18n/fr.js +35 -34
  100. package/dist/es2019/i18n/hu.js +35 -34
  101. package/dist/es2019/i18n/it.js +35 -34
  102. package/dist/es2019/i18n/ja.js +35 -34
  103. package/dist/es2019/i18n/ko.js +35 -34
  104. package/dist/es2019/i18n/nb.js +35 -34
  105. package/dist/es2019/i18n/nl.js +35 -34
  106. package/dist/es2019/i18n/pl.js +35 -34
  107. package/dist/es2019/i18n/pt_BR.js +35 -34
  108. package/dist/es2019/i18n/ru.js +35 -34
  109. package/dist/es2019/i18n/sv.js +35 -34
  110. package/dist/es2019/i18n/th.js +35 -34
  111. package/dist/es2019/i18n/tr.js +35 -34
  112. package/dist/es2019/i18n/uk.js +35 -34
  113. package/dist/es2019/i18n/vi.js +35 -34
  114. package/dist/es2019/i18n/zh.js +35 -34
  115. package/dist/es2019/i18n/zh_TW.js +35 -34
  116. package/dist/es2019/types.js +5 -0
  117. package/dist/es2019/util/constants.js +32 -0
  118. package/dist/es2019/util/shared-styles.js +1 -2
  119. package/dist/es2019/version.json +1 -1
  120. package/dist/esm/api/EmojiResource.js +42 -26
  121. package/dist/esm/api/media/TokenManager.js +4 -4
  122. package/dist/esm/components/common/CachingEmoji.js +14 -6
  123. package/dist/esm/components/common/Emoji.js +48 -12
  124. package/dist/esm/components/common/EmojiActions.js +62 -26
  125. package/dist/esm/components/common/EmojiErrorMessage.js +7 -3
  126. package/dist/esm/components/common/EmojiPlaceholder.js +1 -0
  127. package/dist/esm/components/common/EmojiRadioButton.js +52 -0
  128. package/dist/esm/components/common/EmojiUploadPicker.js +77 -36
  129. package/dist/esm/components/common/EmojiUploadPreview.js +11 -2
  130. package/dist/esm/components/common/FileChooser.js +1 -1
  131. package/dist/esm/components/common/ResourcedEmojiComponent.js +4 -0
  132. package/dist/esm/components/common/RetryableButton.js +7 -3
  133. package/dist/esm/components/common/TonePreviewButton.js +33 -0
  134. package/dist/esm/components/common/ToneSelector.js +49 -18
  135. package/dist/esm/components/common/styles.js +40 -12
  136. package/dist/esm/components/i18n.js +44 -4
  137. package/dist/esm/components/picker/CategorySelector.js +114 -95
  138. package/dist/esm/components/picker/CategoryTracker.js +0 -28
  139. package/dist/esm/components/picker/EmojiPickerCategoryHeading.js +2 -2
  140. package/dist/esm/components/picker/EmojiPickerComponent.js +35 -46
  141. package/dist/esm/components/picker/EmojiPickerEmojiRow.js +32 -4
  142. package/dist/esm/components/picker/EmojiPickerList.js +156 -86
  143. package/dist/esm/components/picker/EmojiPickerListSearch.js +64 -117
  144. package/dist/esm/components/picker/EmojiPickerVirtualItems.js +5 -2
  145. package/dist/esm/components/picker/VirtualList.js +274 -172
  146. package/dist/esm/components/picker/styles.js +37 -45
  147. package/dist/esm/components/typeahead/EmojiTypeAheadComponent.js +0 -10
  148. package/dist/esm/context/EmojiPickerListContext.js +21 -0
  149. package/dist/esm/hooks/useEmojiPickerListContext.js +5 -0
  150. package/dist/esm/hooks/useIsMounted.js +11 -0
  151. package/dist/esm/i18n/cs.js +35 -34
  152. package/dist/esm/i18n/da.js +35 -34
  153. package/dist/esm/i18n/de.js +35 -34
  154. package/dist/esm/i18n/en.js +35 -34
  155. package/dist/esm/i18n/en_GB.js +35 -34
  156. package/dist/esm/i18n/es.js +35 -34
  157. package/dist/esm/i18n/fi.js +35 -34
  158. package/dist/esm/i18n/fr.js +35 -34
  159. package/dist/esm/i18n/hu.js +35 -34
  160. package/dist/esm/i18n/it.js +35 -34
  161. package/dist/esm/i18n/ja.js +35 -34
  162. package/dist/esm/i18n/ko.js +35 -34
  163. package/dist/esm/i18n/nb.js +35 -34
  164. package/dist/esm/i18n/nl.js +35 -34
  165. package/dist/esm/i18n/pl.js +35 -34
  166. package/dist/esm/i18n/pt_BR.js +35 -34
  167. package/dist/esm/i18n/ru.js +35 -34
  168. package/dist/esm/i18n/sv.js +35 -34
  169. package/dist/esm/i18n/th.js +35 -34
  170. package/dist/esm/i18n/tr.js +35 -34
  171. package/dist/esm/i18n/uk.js +35 -34
  172. package/dist/esm/i18n/vi.js +35 -34
  173. package/dist/esm/i18n/zh.js +35 -34
  174. package/dist/esm/i18n/zh_TW.js +35 -34
  175. package/dist/esm/types.js +5 -0
  176. package/dist/esm/util/constants.js +32 -0
  177. package/dist/esm/util/shared-styles.js +1 -2
  178. package/dist/esm/version.json +1 -1
  179. package/dist/types/api/EmojiResource.d.ts +2 -0
  180. package/dist/types/components/common/Emoji.d.ts +7 -1
  181. package/dist/types/components/common/EmojiActions.d.ts +4 -3
  182. package/dist/types/components/common/{EmojiButton.d.ts → EmojiRadioButton.d.ts} +3 -4
  183. package/dist/types/components/common/EmojiUploadPicker.d.ts +6 -4
  184. package/dist/types/components/common/RetryableButton.d.ts +1 -0
  185. package/dist/types/components/common/TonePreviewButton.d.ts +14 -0
  186. package/dist/types/components/common/ToneSelector.d.ts +8 -5
  187. package/dist/types/components/common/internal-types.d.ts +9 -0
  188. package/dist/types/components/common/styles.d.ts +2 -1
  189. package/dist/types/components/i18n.d.ts +40 -0
  190. package/dist/types/components/picker/CategorySelector.d.ts +3 -10
  191. package/dist/types/components/picker/CategoryTracker.d.ts +0 -2
  192. package/dist/types/components/picker/EmojiPickerCategoryHeading.d.ts +2 -1
  193. package/dist/types/components/picker/EmojiPickerEmojiRow.d.ts +5 -0
  194. package/dist/types/components/picker/EmojiPickerList.d.ts +14 -7
  195. package/dist/types/components/picker/EmojiPickerListSearch.d.ts +4 -8
  196. package/dist/types/components/picker/EmojiPickerVirtualItems.d.ts +1 -1
  197. package/dist/types/components/picker/VirtualList.d.ts +7 -24
  198. package/dist/types/components/picker/styles.d.ts +1 -1
  199. package/dist/types/context/EmojiPickerListContext.d.ts +10 -0
  200. package/dist/types/hooks/useEmojiPickerListContext.d.ts +1 -0
  201. package/dist/types/hooks/useIsMounted.d.ts +1 -0
  202. package/dist/types/i18n/cs.d.ts +34 -34
  203. package/dist/types/i18n/da.d.ts +34 -34
  204. package/dist/types/i18n/de.d.ts +34 -34
  205. package/dist/types/i18n/en.d.ts +34 -34
  206. package/dist/types/i18n/en_GB.d.ts +34 -34
  207. package/dist/types/i18n/es.d.ts +34 -34
  208. package/dist/types/i18n/fi.d.ts +34 -34
  209. package/dist/types/i18n/fr.d.ts +34 -34
  210. package/dist/types/i18n/hu.d.ts +34 -34
  211. package/dist/types/i18n/it.d.ts +34 -34
  212. package/dist/types/i18n/ja.d.ts +34 -34
  213. package/dist/types/i18n/ko.d.ts +34 -34
  214. package/dist/types/i18n/nb.d.ts +34 -34
  215. package/dist/types/i18n/nl.d.ts +34 -34
  216. package/dist/types/i18n/pl.d.ts +34 -34
  217. package/dist/types/i18n/pt_BR.d.ts +34 -34
  218. package/dist/types/i18n/ru.d.ts +34 -34
  219. package/dist/types/i18n/sv.d.ts +34 -34
  220. package/dist/types/i18n/th.d.ts +34 -34
  221. package/dist/types/i18n/tr.d.ts +34 -34
  222. package/dist/types/i18n/uk.d.ts +34 -34
  223. package/dist/types/i18n/vi.d.ts +34 -34
  224. package/dist/types/i18n/zh.d.ts +34 -34
  225. package/dist/types/i18n/zh_TW.d.ts +34 -34
  226. package/dist/types/types.d.ts +5 -0
  227. package/dist/types/util/constants.d.ts +28 -0
  228. package/dist/types/util/shared-styles.d.ts +1 -1
  229. package/dist/types/util/type-helpers.d.ts +1 -1
  230. package/package.json +12 -8
  231. package/report.api.md +62 -1
  232. package/README.md +0 -3
  233. package/dist/cjs/components/hooks.js +0 -14
  234. package/dist/es2019/components/common/EmojiButton.js +0 -49
  235. package/dist/es2019/components/hooks.js +0 -8
  236. package/dist/esm/components/common/EmojiButton.js +0 -43
  237. package/dist/esm/components/hooks.js +0 -8
  238. package/dist/types/components/hooks.d.ts +0 -1
@@ -6,198 +6,300 @@ Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.virtualListScrollContainerTestId = exports.VirtualList = void 0;
9
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
- var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
12
- var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
13
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
14
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
15
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
16
10
  var _react = require("@emotion/react");
17
- var _reactVirtual = require("@tanstack/react-virtual");
18
11
  var _react2 = _interopRequireWildcard(require("react"));
19
12
  var _styles = require("./styles");
13
+ var _reactVirtual = require("@tanstack/react-virtual");
14
+ var _useEmojiPickerListContext = require("../../hooks/useEmojiPickerListContext");
15
+ var _constants = require("../../util/constants");
20
16
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
17
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
22
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
23
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
18
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
19
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
24
20
  var virtualListScrollContainerTestId = 'virtual-list-scroll-container';
25
21
  exports.virtualListScrollContainerTestId = virtualListScrollContainerTestId;
26
- var VirtualList = /*#__PURE__*/function (_PureComponent) {
27
- (0, _inherits2.default)(VirtualList, _PureComponent);
28
- var _super = _createSuper(VirtualList);
22
+ var VirtualList = /*#__PURE__*/_react2.default.forwardRef(function (props, ref) {
23
+ var parentRef = _react2.default.useRef(null);
24
+ var virtualistItemsRef = _react2.default.useRef(null);
25
+ var rowRenderer = props.rowRenderer,
26
+ onRowsRendered = props.onRowsRendered,
27
+ scrollToAlignment = props.scrollToAlignment,
28
+ width = props.width,
29
+ height = props.height,
30
+ rowCount = props.rowCount;
31
+ var _useEmojiPickerListCo = (0, _useEmojiPickerListContext.useEmojiPickerListContext)(),
32
+ currentEmojisFocus = _useEmojiPickerListCo.currentEmojisFocus,
33
+ setEmojisFocus = _useEmojiPickerListCo.setEmojisFocus;
34
+ var getVirtualizerOptions = function getVirtualizerOptions() {
35
+ var rowCount = props.rowCount,
36
+ rowHeight = props.rowHeight,
37
+ overscanRowCount = props.overscanRowCount;
38
+ return {
39
+ count: rowCount,
40
+ getScrollElement: function getScrollElement() {
41
+ return parentRef.current;
42
+ },
43
+ estimateSize: rowHeight,
44
+ overscan: overscanRowCount,
45
+ onChange: function onChange() {
46
+ var startIndex = getFirstVisibleListElementIndex();
47
+ onRowsRendered({
48
+ startIndex: startIndex
49
+ });
50
+ },
51
+ scrollPaddingStart: 28,
52
+ scrollPaddingEnd: 28
53
+ };
54
+ };
55
+ var rowVirtualizer = (0, _reactVirtual.useVirtualizer)(getVirtualizerOptions());
56
+ var isElementVisible = function isElementVisible(element) {
57
+ var parent = parentRef.current;
58
+ var elementRect = element.getBoundingClientRect();
59
+ var parentRect = parent.getBoundingClientRect();
60
+ var elemTop = elementRect.top;
61
+ var elemBottom = elementRect.bottom;
62
+ var parentTop = parentRect.top;
63
+ var parentBottom = parentRect.bottom;
64
+
65
+ // Only completely visible elements return true:
66
+ var isVisible = elemTop >= parentTop && elemBottom <= parentBottom;
67
+ return isVisible;
68
+ };
69
+ var getFirstVisibleListElementIndex = (0, _react2.useCallback)(function () {
70
+ var _parentRef$current, _parentRef$current$fi;
71
+ var virtualList = rowVirtualizer.getVirtualItems();
72
+ var renderedElements = (_parentRef$current = parentRef.current) === null || _parentRef$current === void 0 ? void 0 : (_parentRef$current$fi = _parentRef$current.firstChild) === null || _parentRef$current$fi === void 0 ? void 0 : _parentRef$current$fi.childNodes;
73
+ if (virtualList.length === 0 || !renderedElements || renderedElements.length === 0) {
74
+ return 0;
75
+ }
76
+ // Convert NodeListOf<ChildNodes> to ChildNodes[]
77
+ var renderedElementsToArray = Array.from(renderedElements);
78
+ var firstVisibleIndex = renderedElementsToArray.findIndex(function (elem) {
79
+ return isElementVisible(elem);
80
+ });
81
+ if (firstVisibleIndex !== -1) {
82
+ var _virtualList$firstVis;
83
+ return ((_virtualList$firstVis = virtualList[firstVisibleIndex]) === null || _virtualList$firstVis === void 0 ? void 0 : _virtualList$firstVis.index) || 0;
84
+ }
85
+ return 0;
86
+ }, [rowVirtualizer]);
87
+
29
88
  /**
30
- * Determine if the component is mounted to the DOM or not
89
+ * Recurisive function to find next available emoji and it's focus indexes in the grid
90
+ *
91
+ * current focus element is at rowIndex.columnIndex
92
+ * if found element then return the element and focus indexes
93
+ * otherwise change row/column till find the element
94
+ * if can't find the element till reach the edge of grid, we keep current focus states
95
+ *
96
+ * @param rowIndex search from row index (0 based)
97
+ * @param columnIndex search from column index (0 based)
98
+ * @param direction search direction
31
99
  */
32
-
33
- function VirtualList(props) {
34
- var _this;
35
- (0, _classCallCheck2.default)(this, VirtualList);
36
- _this = _super.call(this, props);
37
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_isMounted", false);
38
- _this.parentRef = /*#__PURE__*/(0, _react2.createRef)();
39
- _this.rowVirtualizer = new _reactVirtual.Virtualizer(_this.getVirtualizerOptions(props));
40
- return _this;
41
- }
42
- (0, _createClass2.default)(VirtualList, [{
43
- key: "getVirtualizerOptions",
44
- value: function getVirtualizerOptions(props) {
45
- var _this2 = this;
46
- var rowCount = props.rowCount,
47
- rowHeight = props.rowHeight,
48
- overscanRowCount = props.overscanRowCount;
100
+ var findNextEmoji = (0, _react2.useCallback)(function (rowIndex, columnIndex, direction) {
101
+ var _virtualistItemsRef$c;
102
+ var emojiToFocus = (_virtualistItemsRef$c = virtualistItemsRef.current) === null || _virtualistItemsRef$c === void 0 ? void 0 : _virtualistItemsRef$c.querySelector("[data-focus-index=\"".concat(rowIndex, "-").concat(columnIndex, "\"]"));
103
+ var lastRowIndex = rowCount - 1;
104
+ var lastColumnIndex = _constants.EMOJI_LIST_COLUMNS - 1;
105
+ if (emojiToFocus) {
49
106
  return {
50
- observeElementRect: _reactVirtual.observeElementRect,
51
- observeElementOffset: _reactVirtual.observeElementOffset,
52
- scrollToFn: _reactVirtual.elementScroll,
53
- count: rowCount,
54
- getScrollElement: function getScrollElement() {
55
- return _this2.parentRef.current;
56
- },
57
- estimateSize: rowHeight,
58
- overscan: overscanRowCount,
59
- onChange: function onChange() {
60
- _this2.forceUpdateGrid();
61
- }
107
+ element: emojiToFocus,
108
+ rowIndex: rowIndex,
109
+ columnIndex: columnIndex
62
110
  };
63
111
  }
64
- }, {
65
- key: "isElementVisible",
66
- value: function isElementVisible(element) {
67
- var parent = this.parentRef.current;
68
- var elementRect = element.getBoundingClientRect();
69
- var parentRect = parent.getBoundingClientRect();
70
- var elemTop = elementRect.top;
71
- var elemBottom = elementRect.bottom;
72
- var parentTop = parentRect.top;
73
- var parentBottom = parentRect.bottom;
74
-
75
- // Only completely visible elements return true:
76
- var isVisible = elemTop >= parentTop && elemBottom <= parentBottom;
77
- return isVisible;
112
+ switch (direction) {
113
+ case _constants.KeyboardNavigationDirection.Down:
114
+ if (rowIndex >= lastRowIndex) {
115
+ return null;
116
+ }
117
+ // find emoji in same column but lower row
118
+ return findNextEmoji(rowIndex + 1, columnIndex, _constants.KeyboardNavigationDirection.Down);
119
+ case _constants.KeyboardNavigationDirection.Up:
120
+ if (rowIndex <= 0) {
121
+ return null;
122
+ }
123
+ // find emoji in same column but upper row
124
+ return findNextEmoji(rowIndex - 1, columnIndex, _constants.KeyboardNavigationDirection.Up);
125
+ case _constants.KeyboardNavigationDirection.Left:
126
+ if (rowIndex <= 0) {
127
+ return null;
128
+ }
129
+ if (columnIndex < 0) {
130
+ // find emoji in upper row
131
+ return findNextEmoji(rowIndex - 1, lastColumnIndex, _constants.KeyboardNavigationDirection.Left);
132
+ }
133
+ // find emoji on left in the current row
134
+ return findNextEmoji(rowIndex, columnIndex - 1, _constants.KeyboardNavigationDirection.Left);
135
+ case _constants.KeyboardNavigationDirection.Right:
136
+ if (rowIndex >= lastRowIndex) {
137
+ return null;
138
+ }
139
+ // if no emoji on right, we try first emoji in next row
140
+ return findNextEmoji(rowIndex + 1, 0, _constants.KeyboardNavigationDirection.Right);
141
+ default:
142
+ return null;
78
143
  }
79
- }, {
80
- key: "getFirstVisibleListElementIndex",
81
- value: function getFirstVisibleListElementIndex() {
82
- var _this$parentRef$curre,
83
- _this$parentRef$curre2,
84
- _this3 = this;
85
- var virtualList = this.rowVirtualizer.getVirtualItems();
86
- var renderedElements = (_this$parentRef$curre = this.parentRef.current) === null || _this$parentRef$curre === void 0 ? void 0 : (_this$parentRef$curre2 = _this$parentRef$curre.firstChild) === null || _this$parentRef$curre2 === void 0 ? void 0 : _this$parentRef$curre2.childNodes;
87
- if (virtualList.length === 0 || !renderedElements || renderedElements.length === 0) {
88
- return 0;
89
- }
144
+ }, [rowCount]);
90
145
 
91
- // Convert NodeListOf<ChildNodes> to ChildNodes[]
92
- var renderedElementsToArray = Array.from(renderedElements);
93
- var firstVisibleIndex = renderedElementsToArray.findIndex(function (elem) {
94
- return _this3.isElementVisible(elem);
146
+ /**
147
+ * Find the valid emoji to scroll and focus
148
+ */
149
+ var scrollToRowAndFocusEmoji = (0, _react2.useCallback)(function (emojiToFocus) {
150
+ if (emojiToFocus) {
151
+ var _emojiToFocus$element;
152
+ rowVirtualizer.scrollToIndex(emojiToFocus.rowIndex, {
153
+ align: 'auto',
154
+ smoothScroll: false
95
155
  });
96
- if (firstVisibleIndex !== -1) {
97
- var _virtualList$firstVis;
98
- return ((_virtualList$firstVis = virtualList[firstVisibleIndex]) === null || _virtualList$firstVis === void 0 ? void 0 : _virtualList$firstVis.index) || 0;
99
- }
100
- return 0;
101
- }
102
- }, {
103
- key: "onRendered",
104
- value: function onRendered() {
105
- var onRowsRendered = this.props.onRowsRendered;
106
- this.rowVirtualizer.setOptions(this.getVirtualizerOptions(this.props));
107
- var startIndex = this.getFirstVisibleListElementIndex();
108
- onRowsRendered({
109
- startIndex: startIndex
156
+ (_emojiToFocus$element = emojiToFocus.element) === null || _emojiToFocus$element === void 0 ? void 0 : _emojiToFocus$element.focus({
157
+ preventScroll: true
158
+ });
159
+ setEmojisFocus({
160
+ rowIndex: emojiToFocus.rowIndex,
161
+ columnIndex: emojiToFocus.columnIndex
110
162
  });
111
163
  }
112
- }, {
113
- key: "componentDidUpdate",
114
- value: function componentDidUpdate() {
115
- this.onRendered();
116
- }
117
- }, {
118
- key: "componentDidMount",
119
- value: function componentDidMount() {
120
- if (this.rowVirtualizer) {
121
- this.rowVirtualizer._didMount();
122
- this.rowVirtualizer._willUpdate();
123
- this._isMounted = true;
124
- }
125
- }
126
- }, {
127
- key: "componentWillUnmount",
128
- value: function componentWillUnmount() {
129
- this._isMounted = false;
130
- }
131
- }, {
132
- key: "scrollToRow",
133
- value: function scrollToRow(index) {
134
- var scrollToAlignment = this.props.scrollToAlignment;
135
- if (index !== undefined) {
136
- var _this$rowVirtualizer;
137
- (_this$rowVirtualizer = this.rowVirtualizer) === null || _this$rowVirtualizer === void 0 ? void 0 : _this$rowVirtualizer.scrollToIndex(index, {
138
- align: scrollToAlignment,
139
- smoothScroll: false
140
- });
141
- this.forceUpdateGrid();
142
- }
164
+ }, [rowVirtualizer, setEmojisFocus]);
165
+ var focusEmoji = (0, _react2.useCallback)(function (rIndex, cIndex, direction) {
166
+ var waitForScrollFinish = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
167
+ if (waitForScrollFinish) {
168
+ // scroll to target rowIndex first to ensure the row is rendered in list.
169
+ // used in page up/down, ctrl+Home, ctrl+End
170
+ rowVirtualizer.scrollToIndex(rIndex, {
171
+ align: 'auto',
172
+ smoothScroll: false
173
+ });
174
+ setTimeout(function () {
175
+ var emojiToFocus = findNextEmoji(rIndex, cIndex, direction);
176
+ scrollToRowAndFocusEmoji(emojiToFocus);
177
+ }, 100); // 100ms is virtual list scrolling time
178
+ } else {
179
+ var emojiToFocus = findNextEmoji(rIndex, cIndex, direction);
180
+ scrollToRowAndFocusEmoji(emojiToFocus);
143
181
  }
144
- }, {
145
- key: "forceUpdateGrid",
146
- value: function forceUpdateGrid() {
147
- if (this._isMounted) {
148
- this.forceUpdate();
149
- }
182
+ }, [scrollToRowAndFocusEmoji, findNextEmoji, rowVirtualizer]);
183
+
184
+ // following the guide from https://www.w3.org/WAI/ARIA/apg/patterns/grid/
185
+ var handleKeyDown = function handleKeyDown(e) {
186
+ if (!_constants.EMOJIPICKERLIST_KEYBOARD_KEYS_SUPPORTED.includes(e.key)) {
187
+ return;
150
188
  }
151
- }, {
152
- key: "recomputeRowHeights",
153
- value: function recomputeRowHeights() {
154
- var _this$rowVirtualizer2;
155
- (_this$rowVirtualizer2 = this.rowVirtualizer) === null || _this$rowVirtualizer2 === void 0 ? void 0 : _this$rowVirtualizer2.measure();
189
+ e.preventDefault();
190
+ var lastRowIndex = rowCount - 1;
191
+ var lastColumnIndex = _constants.EMOJI_LIST_COLUMNS - 1;
192
+
193
+ // focus first emoji on first row
194
+ if (e.key === _constants.KeyboardKeys.Home && e.ctrlKey) {
195
+ focusEmoji(1, 0, _constants.KeyboardNavigationDirection.Up, true);
196
+ return;
197
+ } else if (e.key === _constants.KeyboardKeys.End && e.ctrlKey) {
198
+ // focus last available emoji on last row
199
+ focusEmoji(lastRowIndex, lastColumnIndex, _constants.KeyboardNavigationDirection.Left, true);
200
+ return;
156
201
  }
157
- }, {
158
- key: "handleScroll",
159
- value: function handleScroll(e) {
160
- e.preventDefault();
202
+ switch (e.key) {
203
+ // navigate to the right column
204
+ case _constants.KeyboardKeys.ArrowRight:
205
+ focusEmoji(currentEmojisFocus.rowIndex, currentEmojisFocus.columnIndex + 1, _constants.KeyboardNavigationDirection.Right);
206
+ break;
207
+ // navigate to the left column
208
+ case _constants.KeyboardKeys.ArrowLeft:
209
+ focusEmoji(currentEmojisFocus.rowIndex, currentEmojisFocus.columnIndex - 1, _constants.KeyboardNavigationDirection.Left);
210
+ break;
211
+ // navigate to the down row
212
+ case _constants.KeyboardKeys.ArrowDown:
213
+ focusEmoji(currentEmojisFocus.rowIndex === lastRowIndex ? lastRowIndex : currentEmojisFocus.rowIndex + 1, currentEmojisFocus.columnIndex, _constants.KeyboardNavigationDirection.Down);
214
+ break;
215
+ // navigate to the row after {EMOJI_LIST_PAGE_COUNT} rows
216
+ case _constants.KeyboardKeys.PageDown:
217
+ focusEmoji(currentEmojisFocus.rowIndex + _constants.EMOJI_LIST_PAGE_COUNT, currentEmojisFocus.columnIndex, _constants.KeyboardNavigationDirection.Down, true);
218
+ break;
219
+ // navigate to the up row
220
+ case _constants.KeyboardKeys.ArrowUp:
221
+ focusEmoji(currentEmojisFocus.rowIndex <= 1 ? 1 : currentEmojisFocus.rowIndex - 1, currentEmojisFocus.columnIndex, _constants.KeyboardNavigationDirection.Up);
222
+ break;
223
+ // navigate to the row before {EMOJI_LIST_PAGE_COUNT} rows
224
+ case _constants.KeyboardKeys.PageUp:
225
+ focusEmoji(currentEmojisFocus.rowIndex - _constants.EMOJI_LIST_PAGE_COUNT, currentEmojisFocus.columnIndex, _constants.KeyboardNavigationDirection.Up, true);
226
+ break;
227
+ // navigate to the first cell of current row
228
+ case _constants.KeyboardKeys.Home:
229
+ focusEmoji(currentEmojisFocus.rowIndex, 0, _constants.KeyboardNavigationDirection.Left);
230
+ break;
231
+ // navigate to the last cell of current row
232
+ case _constants.KeyboardKeys.End:
233
+ focusEmoji(currentEmojisFocus.rowIndex, lastColumnIndex, _constants.KeyboardNavigationDirection.Left);
234
+ break;
161
235
  }
162
- }, {
163
- key: "render",
164
- value: function render() {
165
- var _this$rowVirtualizer3, _this$rowVirtualizer4;
166
- var _this$props = this.props,
167
- rowRenderer = _this$props.rowRenderer,
168
- width = _this$props.width,
169
- height = _this$props.height;
170
- return (0, _react.jsx)("div", {
171
- ref: this.parentRef,
172
- role: "grid",
173
- style: {
174
- height: "".concat(height, "px"),
175
- width: "".concat(width, "px")
176
- },
177
- css: _styles.virtualList,
178
- "data-testid": virtualListScrollContainerTestId,
179
- onScroll: this.handleScroll
180
- }, (0, _react.jsx)("div", {
181
- style: {
182
- height: "".concat((_this$rowVirtualizer3 = this.rowVirtualizer) === null || _this$rowVirtualizer3 === void 0 ? void 0 : _this$rowVirtualizer3.getTotalSize(), "px"),
183
- width: '100%',
184
- position: 'relative'
236
+ };
237
+
238
+ // Exposing a custom ref handle to the parent component EmojiPickerList to trigger scrollToRow via the listRef
239
+ // https://beta.reactjs.org/reference/react/useImperativeHandle
240
+ (0, _react2.useImperativeHandle)(ref, function () {
241
+ return {
242
+ scrollToRow: function scrollToRow(index) {
243
+ if (index !== undefined) {
244
+ rowVirtualizer.setOptions(_objectSpread(_objectSpread({}, rowVirtualizer.options), {}, {
245
+ scrollPaddingStart: 0
246
+ }));
247
+ rowVirtualizer.scrollToIndex(index, {
248
+ align: scrollToAlignment,
249
+ smoothScroll: false
250
+ });
185
251
  }
186
- }, (_this$rowVirtualizer4 = this.rowVirtualizer) === null || _this$rowVirtualizer4 === void 0 ? void 0 : _this$rowVirtualizer4.getVirtualItems().map(function (virtualRow) {
187
- return (0, _react.jsx)("div", {
188
- key: virtualRow.key,
189
- style: {
190
- position: 'absolute',
191
- top: 0,
192
- left: 0,
193
- width: '100%',
194
- height: "".concat(virtualRow.size, "px"),
195
- transform: "translateY(".concat(virtualRow.start, "px)")
196
- }
197
- }, rowRenderer(virtualRow));
198
- })));
199
- }
200
- }]);
201
- return VirtualList;
202
- }(_react2.PureComponent);
252
+ },
253
+ scrollToRowAndFocusLastEmoji: function scrollToRowAndFocusLastEmoji(index) {
254
+ if (index !== undefined) {
255
+ focusEmoji(index, _constants.EMOJI_LIST_COLUMNS, _constants.KeyboardNavigationDirection.Left, true);
256
+ }
257
+ },
258
+ updateFocusIndex: function updateFocusIndex(index) {
259
+ var _virtualistItemsRef$c2;
260
+ // row could be removed from virtual list after scrolling, we'll update emoji cell tabIndex after losing focus
261
+ if (!((_virtualistItemsRef$c2 = virtualistItemsRef.current) !== null && _virtualistItemsRef$c2 !== void 0 && _virtualistItemsRef$c2.contains(document.activeElement))) {
262
+ setEmojisFocus({
263
+ rowIndex: index,
264
+ columnIndex: 0
265
+ });
266
+ }
267
+ }
268
+ };
269
+ }, [setEmojisFocus, focusEmoji, rowVirtualizer, scrollToAlignment]);
270
+ return (0, _react.jsx)("div", {
271
+ ref: parentRef,
272
+ style: {
273
+ height: "".concat(height, "px"),
274
+ width: "".concat(width, "px")
275
+ },
276
+ css: _styles.virtualList,
277
+ "data-testid": virtualListScrollContainerTestId,
278
+ "aria-labelledby": "emoji-picker-table-description",
279
+ role: "grid"
280
+ }, (0, _react.jsx)("div", {
281
+ style: {
282
+ height: "".concat(rowVirtualizer.getTotalSize(), "px"),
283
+ width: '100%',
284
+ position: 'relative'
285
+ },
286
+ ref: virtualistItemsRef,
287
+ onKeyDown: handleKeyDown,
288
+ role: "presentation"
289
+ }, rowVirtualizer.getVirtualItems().map(function (virtualRow, index) {
290
+ return (0, _react.jsx)("div", {
291
+ key: virtualRow.key,
292
+ style: {
293
+ position: 'absolute',
294
+ top: 0,
295
+ left: 0,
296
+ width: '100%',
297
+ height: "".concat(virtualRow.size, "px"),
298
+ transform: "translateY(".concat(virtualRow.start, "px)")
299
+ },
300
+ role: "row",
301
+ "aria-rowindex": index + 1
302
+ }, rowRenderer(virtualRow));
303
+ })));
304
+ });
203
305
  exports.VirtualList = VirtualList;