emoji-picker-react 4.0.0-rc.19 → 4.0.0-rc.21

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 (82) hide show
  1. package/README.md +44 -4
  2. package/dist/DomUtils/classNames.d.ts +6 -1
  3. package/dist/DomUtils/elementPositionInRow.d.ts +10 -0
  4. package/dist/DomUtils/emojiElementRef.d.ts +4 -3
  5. package/dist/DomUtils/focusElement.d.ts +5 -0
  6. package/dist/DomUtils/getActiveElement.d.ts +2 -0
  7. package/dist/DomUtils/keyboardNavigation.d.ts +8 -0
  8. package/dist/DomUtils/scrollCategoryIntoView.d.ts +2 -1
  9. package/dist/DomUtils/scrollTo.d.ts +3 -1
  10. package/dist/DomUtils/selectors.d.ts +23 -11
  11. package/dist/components/context/ElementRefContext.d.ts +9 -13
  12. package/dist/components/context/PickerContext.d.ts +1 -1
  13. package/dist/components/emoji/Emoji.d.ts +2 -2
  14. package/dist/components/footer/Preview.d.ts +1 -1
  15. package/dist/config/config.d.ts +12 -15
  16. package/dist/config/useConfig.d.ts +2 -1
  17. package/dist/dataUtils/emojiSelectors.d.ts +2 -2
  18. package/dist/emoji-picker-react.cjs.development.css +7 -7
  19. package/dist/emoji-picker-react.cjs.development.js +1119 -302
  20. package/dist/emoji-picker-react.cjs.development.js.map +1 -1
  21. package/dist/emoji-picker-react.cjs.production.min.js +1 -1
  22. package/dist/emoji-picker-react.cjs.production.min.js.map +1 -1
  23. package/dist/emoji-picker-react.esm.js +1129 -312
  24. package/dist/emoji-picker-react.esm.js.map +1 -1
  25. package/dist/hooks/useCloseAllOpenToggles.d.ts +1 -4
  26. package/dist/hooks/useDebouncedState.d.ts +1 -1
  27. package/dist/hooks/useEmojiPreviewEvents.d.ts +3 -0
  28. package/dist/hooks/useFilter.d.ts +3 -3
  29. package/dist/hooks/useFocus.d.ts +3 -0
  30. package/dist/hooks/useInitialLoad.d.ts +1 -1
  31. package/dist/hooks/useKeyboardNavigation.d.ts +1 -0
  32. package/dist/hooks/useMouseDownHandlers.d.ts +3 -2
  33. package/package.json +7 -4
  34. package/src/DomUtils/classNames.ts +9 -1
  35. package/src/DomUtils/elementPositionInRow.ts +169 -0
  36. package/src/DomUtils/emojiElementRef.ts +4 -3
  37. package/src/DomUtils/focusElement.ts +35 -0
  38. package/src/DomUtils/getActiveElement.ts +5 -0
  39. package/src/DomUtils/keyboardNavigation.ts +159 -0
  40. package/src/DomUtils/scrollCategoryIntoView.ts +2 -1
  41. package/src/DomUtils/scrollTo.ts +22 -1
  42. package/src/DomUtils/selectors.ts +157 -32
  43. package/src/EmojiPickerReact.css +57 -29
  44. package/src/components/ErrorBoundary.tsx +1 -0
  45. package/src/components/body/EmojiCategory.css +14 -20
  46. package/src/components/body/EmojiCategory.tsx +3 -3
  47. package/src/components/body/EmojiList.tsx +8 -7
  48. package/src/components/body/EmojiVariationPicker.tsx +3 -3
  49. package/src/components/body/Suggested.tsx +3 -1
  50. package/src/components/context/ElementRefContext.tsx +46 -19
  51. package/src/components/context/PickerContext.tsx +16 -14
  52. package/src/components/emoji/Emoji.css +7 -2
  53. package/src/components/emoji/Emoji.tsx +10 -10
  54. package/src/components/footer/Preview.css +1 -1
  55. package/src/components/footer/Preview.tsx +13 -16
  56. package/src/components/header/Search.css +7 -7
  57. package/src/components/header/Search.tsx +6 -4
  58. package/src/components/header/SkinTonePicker.css +12 -5
  59. package/src/components/header/SkinTonePicker.tsx +11 -3
  60. package/src/components/main/PickerMain.tsx +6 -2
  61. package/src/components/navigation/CategoryNavigation.css +11 -0
  62. package/src/components/navigation/CategoryNavigation.tsx +5 -2
  63. package/src/config/config.ts +39 -10
  64. package/src/config/useConfig.ts +6 -5
  65. package/src/dataUtils/emojiSelectors.ts +3 -2
  66. package/src/dataUtils/suggested.ts +1 -0
  67. package/src/hooks/preloadEmoji.ts +1 -1
  68. package/src/hooks/useActiveCategoryScrollDetection.ts +7 -4
  69. package/src/hooks/useCloseAllOpenToggles.ts +7 -5
  70. package/src/hooks/useDebouncedState.ts +10 -7
  71. package/src/hooks/useEmojiPreviewEvents.ts +90 -0
  72. package/src/hooks/useFilter.ts +41 -21
  73. package/src/hooks/useFocus.ts +40 -0
  74. package/src/hooks/useInitialLoad.ts +1 -0
  75. package/src/hooks/useKeyboardNavigation.ts +389 -0
  76. package/src/hooks/useMouseDownHandlers.ts +100 -74
  77. package/src/hooks/useOnScroll.ts +2 -2
  78. package/src/index.tsx +3 -1
  79. package/dist/hooks/useEmojiElements.d.ts +0 -1
  80. package/dist/hooks/useEmojiMouseEnter.d.ts +0 -3
  81. package/src/hooks/useEmojiElements.ts +0 -7
  82. package/src/hooks/useEmojiMouseEnter.ts +0 -59
@@ -98,6 +98,131 @@ function categoryNameFromDom($category) {
98
98
  return (_$category$getAttribu = $category == null ? void 0 : $category.getAttribute('data-name')) != null ? _$category$getAttribu : null;
99
99
  }
100
100
 
101
+ var ClassNames;
102
+
103
+ (function (ClassNames) {
104
+ ClassNames["hiddenOnSearch"] = "epr-hidden-on-search";
105
+ ClassNames["searchActive"] = "epr-search-active";
106
+ ClassNames["hidden"] = "epr-hidden";
107
+ ClassNames["visible"] = "epr-visible";
108
+ ClassNames["active"] = "epr-active";
109
+ ClassNames["emoji"] = "epr-emoji";
110
+ ClassNames["category"] = "epr-emoji-category";
111
+ ClassNames["label"] = "epr-emoji-category-label";
112
+ })(ClassNames || (ClassNames = {}));
113
+
114
+ function asSelectors() {
115
+ for (var _len = arguments.length, classNames = new Array(_len), _key = 0; _key < _len; _key++) {
116
+ classNames[_key] = arguments[_key];
117
+ }
118
+
119
+ return classNames.map(function (c) {
120
+ return "." + c;
121
+ }).join('');
122
+ }
123
+
124
+ function ElementRefContextProvider(_ref) {
125
+ var children = _ref.children;
126
+ var PickerMainRef = React.useRef(null);
127
+ var AnchoredEmojiRef = React.useRef(null);
128
+ var BodyRef = React.useRef(null);
129
+ var SearchInputRef = React.useRef(null);
130
+ var SkinTonePickerRef = React.useRef(null);
131
+ var CategoryNavigationRef = React.useRef(null);
132
+ return React.createElement(ElementRefContext.Provider, {
133
+ value: {
134
+ AnchoredEmojiRef: AnchoredEmojiRef,
135
+ BodyRef: BodyRef,
136
+ CategoryNavigationRef: CategoryNavigationRef,
137
+ PickerMainRef: PickerMainRef,
138
+ SearchInputRef: SearchInputRef,
139
+ SkinTonePickerRef: SkinTonePickerRef
140
+ }
141
+ }, children);
142
+ }
143
+ var ElementRefContext = /*#__PURE__*/React.createContext({
144
+ AnchoredEmojiRef: /*#__PURE__*/React.createRef(),
145
+ BodyRef: /*#__PURE__*/React.createRef(),
146
+ CategoryNavigationRef: /*#__PURE__*/React.createRef(),
147
+ PickerMainRef: /*#__PURE__*/React.createRef(),
148
+ SearchInputRef: /*#__PURE__*/React.createRef(),
149
+ SkinTonePickerRef: /*#__PURE__*/React.createRef()
150
+ });
151
+
152
+ function useElementRef() {
153
+ return React.useContext(ElementRefContext);
154
+ }
155
+
156
+ function usePickerMainRef() {
157
+ return useElementRef()['PickerMainRef'];
158
+ }
159
+ function useAnchoredEmojiRef() {
160
+ return useElementRef()['AnchoredEmojiRef'];
161
+ }
162
+ function useSetAnchoredEmojiRef() {
163
+ var AnchoredEmojiRef = useAnchoredEmojiRef();
164
+ return function (target) {
165
+ AnchoredEmojiRef.current = target;
166
+ };
167
+ }
168
+ function useBodyRef() {
169
+ return useElementRef()['BodyRef'];
170
+ }
171
+ function useSearchInputRef() {
172
+ return useElementRef()['SearchInputRef'];
173
+ }
174
+ function useSkinTonePickerRef() {
175
+ return useElementRef()['SkinTonePickerRef'];
176
+ }
177
+ function useCategoryNavigationRef() {
178
+ return useElementRef()['CategoryNavigationRef'];
179
+ }
180
+
181
+ function scrollTo(root, top) {
182
+ if (top === void 0) {
183
+ top = 0;
184
+ }
185
+
186
+ var $eprBody = root ? root.querySelector('.epr-body') : null;
187
+
188
+ if (!root || !$eprBody) {
189
+ return;
190
+ }
191
+
192
+ requestAnimationFrame(function () {
193
+ $eprBody.scrollTop = top + 1;
194
+ });
195
+ }
196
+ function useScrollTo() {
197
+ var BodyRef = useBodyRef();
198
+ return React.useCallback(function (top) {
199
+ requestAnimationFrame(function () {
200
+ if (BodyRef.current) {
201
+ BodyRef.current.scrollTop = top;
202
+ }
203
+ });
204
+ }, [BodyRef]);
205
+ }
206
+
207
+ function scrollCategoryIntoView(root, category) {
208
+ var $category = root == null ? void 0 : root.querySelector("[data-name=\"" + category + "\"]");
209
+
210
+ if (!$category) {
211
+ return;
212
+ }
213
+
214
+ var offsetTop = $category.offsetTop || 0;
215
+ scrollTo(root, offsetTop);
216
+ }
217
+
218
+ function isSystemDarkTheme() {
219
+ if (typeof window === 'undefined') {
220
+ return false;
221
+ }
222
+
223
+ return !!window.matchMedia('(prefers-color-scheme: dark)').matches;
224
+ }
225
+
101
226
  var SuggestionMode;
102
227
 
103
228
  (function (SuggestionMode) {
@@ -226,17 +351,21 @@ function getBaseConfigByCategory(category, modifier) {
226
351
  }
227
352
 
228
353
  function mergeConfig(userConfig) {
354
+ var _userConfig$previewCo;
355
+
229
356
  if (userConfig === void 0) {
230
357
  userConfig = {};
231
358
  }
232
359
 
233
- var config = _extends({}, basePickerConfig(), userConfig);
234
-
360
+ var base = basePickerConfig();
361
+ var previewConfig = Object.assign(base.previewConfig, (_userConfig$previewCo = userConfig.previewConfig) != null ? _userConfig$previewCo : {});
362
+ var config = Object.assign(base, userConfig);
235
363
  var categories = mergeCategoriesConfig(userConfig.categories, {
236
364
  suggestionMode: config.suggestedEmojisMode
237
365
  });
238
366
  return _extends({}, config, {
239
- categories: categories
367
+ categories: categories,
368
+ previewConfig: previewConfig
240
369
  });
241
370
  }
242
371
  function basePickerConfig() {
@@ -245,17 +374,24 @@ function basePickerConfig() {
245
374
  categories: baseCategoriesConfig(),
246
375
  defaultSkinTone: exports.SkinTones.NEUTRAL,
247
376
  emojiStyle: exports.EmojiStyle.APPLE,
377
+ lazyLoadEmojis: false,
248
378
  onEmojiClick: function defaultOnClickHandler( // @ts-ignore
379
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
249
380
  emoji, // @ts-ignore
381
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
250
382
  event) {},
383
+ previewConfig: _extends({}, basePreviewConfig),
251
384
  searchPlaceHolder: 'Search',
252
- showPreview: true,
253
385
  skinTonesDisabled: false,
254
- theme: exports.Theme.LIGHT,
255
386
  suggestedEmojisMode: SuggestionMode.FREQUENT,
256
- lazyLoadEmojis: false
387
+ theme: exports.Theme.LIGHT
257
388
  };
258
389
  }
390
+ var basePreviewConfig = {
391
+ defaultEmoji: '1f60a',
392
+ defaultCaption: "What's your mood?",
393
+ showPreview: true
394
+ };
259
395
 
260
396
  var _excluded = ["children"];
261
397
  var ConfigContext = /*#__PURE__*/React.createContext( /*#__PURE__*/basePickerConfig());
@@ -271,14 +407,6 @@ function usePickerConfig() {
271
407
  return React.useContext(ConfigContext);
272
408
  }
273
409
 
274
- function isSystemDarkTheme() {
275
- if (typeof window === 'undefined') {
276
- return false;
277
- }
278
-
279
- return !!window.matchMedia('(prefers-color-scheme: dark)').matches;
280
- }
281
-
282
410
  function useSearchPlaceHolderConfig() {
283
411
  var _usePickerConfig = usePickerConfig(),
284
412
  searchPlaceHolder = _usePickerConfig.searchPlaceHolder;
@@ -321,11 +449,11 @@ function useOnEmojiClickConfig() {
321
449
 
322
450
  return onEmojiClick;
323
451
  }
324
- function useShowPreviewConfig() {
452
+ function usePreviewConfig() {
325
453
  var _usePickerConfig8 = usePickerConfig(),
326
- showPreview = _usePickerConfig8.showPreview;
454
+ previewConfig = _usePickerConfig8.previewConfig;
327
455
 
328
- return showPreview;
456
+ return previewConfig;
329
457
  }
330
458
  function useThemeConfig() {
331
459
  var _usePickerConfig9 = usePickerConfig(),
@@ -14946,33 +15074,6 @@ setTimeout(function () {
14946
15074
  }, alphaNumericEmojiIndex);
14947
15075
  });
14948
15076
 
14949
- function scrollTo(root, top) {
14950
- if (top === void 0) {
14951
- top = 0;
14952
- }
14953
-
14954
- var $eprBody = root ? root.querySelector('.epr-body') : null;
14955
-
14956
- if (!root || !$eprBody) {
14957
- return;
14958
- }
14959
-
14960
- requestAnimationFrame(function () {
14961
- $eprBody.scrollTop = top + 1;
14962
- });
14963
- }
14964
-
14965
- function scrollCategoryIntoView(root, category) {
14966
- var $category = root == null ? void 0 : root.querySelector("[data-name=\"" + category + "\"]");
14967
-
14968
- if (!$category) {
14969
- return;
14970
- }
14971
-
14972
- var offsetTop = $category.offsetTop || 0;
14973
- scrollTo(root, offsetTop);
14974
- }
14975
-
14976
15077
  function useDebouncedState(initialValue, delay) {
14977
15078
  if (delay === void 0) {
14978
15079
  delay = 0;
@@ -14985,15 +15086,18 @@ function useDebouncedState(initialValue, delay) {
14985
15086
  var timer = React.useRef(null);
14986
15087
 
14987
15088
  function debouncedSetState(value) {
14988
- var _window;
15089
+ return new Promise(function (resolve) {
15090
+ var _window;
14989
15091
 
14990
- if (timer.current) {
14991
- clearTimeout(timer.current);
14992
- }
15092
+ if (timer.current) {
15093
+ clearTimeout(timer.current);
15094
+ }
14993
15095
 
14994
- timer.current = (_window = window) == null ? void 0 : _window.setTimeout(function () {
14995
- setState(value);
14996
- }, delay);
15096
+ timer.current = (_window = window) == null ? void 0 : _window.setTimeout(function () {
15097
+ setState(value);
15098
+ resolve(value);
15099
+ }, delay);
15100
+ });
14997
15101
  }
14998
15102
 
14999
15103
  return [state, debouncedSetState];
@@ -15005,53 +15109,13 @@ function useMarkInitialLoad(dispatch) {
15005
15109
  }, [dispatch]);
15006
15110
  }
15007
15111
 
15008
- function ElementRefContextProvider(_ref) {
15009
- var children = _ref.children;
15010
- var PickerMainRef = React.useRef(null);
15011
- var AnchoredEmojiRef = React.useRef(null);
15012
- var BodyRef = React.useRef(null);
15013
- return React.createElement(ElementRefContext.Provider, {
15014
- value: {
15015
- PickerMainRef: PickerMainRef,
15016
- AnchoredEmojiRef: AnchoredEmojiRef,
15017
- BodyRef: BodyRef
15018
- }
15019
- }, children);
15020
- }
15021
- var ElementRefContext = /*#__PURE__*/React.createContext({
15022
- PickerMainRef: /*#__PURE__*/React.createRef(),
15023
- AnchoredEmojiRef: /*#__PURE__*/React.createRef(),
15024
- BodyRef: /*#__PURE__*/React.createRef()
15025
- });
15026
- function useElementRef(key) {
15027
- var _React$useContext = React.useContext(ElementRefContext),
15028
- elementRef = _React$useContext[key];
15029
-
15030
- return elementRef;
15031
- }
15032
- function usePickerMainRef() {
15033
- return useElementRef('PickerMainRef');
15034
- }
15035
- function useAnchoredEmojiRef() {
15036
- return useElementRef('AnchoredEmojiRef');
15037
- }
15038
- function useSetAnchoredEmojiRef() {
15039
- var AnchoredEmojiRef = useAnchoredEmojiRef();
15040
- return function (target) {
15041
- AnchoredEmojiRef.current = target;
15042
- };
15043
- }
15044
- function useBodyRef() {
15045
- return useElementRef('BodyRef');
15046
- }
15047
-
15048
15112
  function PickerContextProvider(_ref) {
15049
15113
  var children = _ref.children;
15050
15114
  var defaultSkinTone = useDefaultSkinToneConfig(); // Initialize the filter with the inititial dictionary
15051
15115
 
15052
15116
  var filterRef = React.useRef(alphaNumericEmojiIndex);
15053
15117
  var disallowClickRef = React.useRef(false);
15054
- var suggestedUpdateState = useDebouncedState(Date.now(), 250);
15118
+ var suggestedUpdateState = useDebouncedState(Date.now(), 200);
15055
15119
  var searchTerm = useDebouncedState('', 100);
15056
15120
  var skinToneFanOpenState = React.useState(false);
15057
15121
  var activeSkinTone = React.useState(defaultSkinTone);
@@ -15066,34 +15130,38 @@ function PickerContextProvider(_ref) {
15066
15130
  useMarkInitialLoad(setIsPastInitialLoad);
15067
15131
  return React.createElement(PickerContext.Provider, {
15068
15132
  value: {
15069
- suggestedUpdateState: suggestedUpdateState,
15070
- filterRef: filterRef,
15071
- searchTerm: searchTerm,
15072
15133
  activeCategoryState: activeCategoryState,
15073
15134
  activeSkinTone: activeSkinTone,
15135
+ disallowClickRef: disallowClickRef,
15136
+ emojiVariationPickerState: emojiVariationPickerState,
15074
15137
  emojisThatFailedToLoadState: emojisThatFailedToLoadState,
15138
+ filterRef: filterRef,
15075
15139
  isPastInitialLoad: isPastInitialLoad,
15076
- emojiVariationPickerState: emojiVariationPickerState,
15140
+ searchTerm: searchTerm,
15077
15141
  skinToneFanOpenState: skinToneFanOpenState,
15078
- disallowClickRef: disallowClickRef
15142
+ suggestedUpdateState: suggestedUpdateState
15079
15143
  }
15080
15144
  }, children);
15081
15145
  }
15082
15146
  var PickerContext = /*#__PURE__*/React.createContext({
15083
- suggestedUpdateState: [/*#__PURE__*/Date.now(), function () {}],
15084
- searchTerm: ['', function () {}],
15085
15147
  activeCategoryState: [null, function () {}],
15086
15148
  activeSkinTone: [exports.SkinTones.NEUTRAL, function () {}],
15087
- emojisThatFailedToLoadState: [/*#__PURE__*/new Set(), function () {}],
15088
- isPastInitialLoad: true,
15149
+ disallowClickRef: {
15150
+ current: false
15151
+ },
15089
15152
  emojiVariationPickerState: [null, function () {}],
15090
- skinToneFanOpenState: [false, function () {}],
15153
+ emojisThatFailedToLoadState: [/*#__PURE__*/new Set(), function () {}],
15091
15154
  filterRef: {
15092
15155
  current: {}
15093
15156
  },
15094
- disallowClickRef: {
15095
- current: false
15096
- }
15157
+ isPastInitialLoad: true,
15158
+ searchTerm: ['', function () {
15159
+ return new Promise(function () {
15160
+ return undefined;
15161
+ });
15162
+ }],
15163
+ skinToneFanOpenState: [false, function () {}],
15164
+ suggestedUpdateState: [/*#__PURE__*/Date.now(), function () {}]
15097
15165
  });
15098
15166
  function useFilterRef() {
15099
15167
  var _React$useContext = React.useContext(PickerContext),
@@ -15215,16 +15283,113 @@ function useActiveCategoryScrollDetection(bodyRef) {
15215
15283
  }, {
15216
15284
  threshold: [0, 1]
15217
15285
  });
15218
- (_bodyRef$current = bodyRef.current) == null ? void 0 : _bodyRef$current.querySelectorAll('.epr-emoji-category').forEach(function (el) {
15286
+ (_bodyRef$current = bodyRef.current) == null ? void 0 : _bodyRef$current.querySelectorAll(asSelectors(ClassNames.category)).forEach(function (el) {
15219
15287
  observer.observe(el);
15220
15288
  });
15221
- }, [bodyRef]);
15289
+ }, [bodyRef, setActiveCategory]);
15290
+ }
15291
+
15292
+ function elementCountInRow(parent, element) {
15293
+ if (!parent || !element) {
15294
+ return 0;
15295
+ }
15296
+
15297
+ var parentWidth = parent.getBoundingClientRect().width;
15298
+ var elementWidth = element.getBoundingClientRect().width;
15299
+ return Math.floor(parentWidth / elementWidth);
15300
+ }
15301
+ function elementIndexInRow(parent, element) {
15302
+ if (!parent || !element) {
15303
+ return 0;
15304
+ }
15305
+
15306
+ var elementWidth = element.getBoundingClientRect().width;
15307
+ var elementLeft = element.getBoundingClientRect().left;
15308
+ var parentLeft = parent.getBoundingClientRect().left;
15309
+ return Math.floor((elementLeft - parentLeft) / elementWidth);
15310
+ }
15311
+ function rowNumber(parent, element) {
15312
+ if (!parent || !element) {
15313
+ return 0;
15314
+ }
15315
+
15316
+ var elementHeight = element.getBoundingClientRect().height;
15317
+ var elementTop = element.getBoundingClientRect().top;
15318
+ var parentTop = parent.getBoundingClientRect().top;
15319
+ return Math.floor((elementTop - parentTop) / elementHeight) - 1;
15320
+ }
15321
+ function hasNextRow(parent, element) {
15322
+ if (!parent || !element) {
15323
+ return false;
15324
+ }
15325
+
15326
+ var elementHeight = element.getBoundingClientRect().height;
15327
+ var elementTop = element.getBoundingClientRect().top;
15328
+ var parentTop = parent.getBoundingClientRect().top;
15329
+ var parentHeight = parent.getBoundingClientRect().height;
15330
+ return elementTop - parentTop + elementHeight < parentHeight;
15331
+ }
15332
+
15333
+ function getRowElements(elements, row, elementsInRow) {
15334
+ if (row === -1) {
15335
+ var lastRow = Math.floor(elements.length / elementsInRow);
15336
+ var firstElementIndex = lastRow * elementsInRow;
15337
+ var lastElementIndex = elements.length - 1;
15338
+ return elements.slice(firstElementIndex, lastElementIndex + 1);
15339
+ }
15340
+
15341
+ return elements.slice(row * elementsInRow, (row + 1) * elementsInRow);
15342
+ }
15343
+
15344
+ function getNextRowElements(allElements, currentRow, elementsInRow) {
15345
+ var nextRow = currentRow + 1;
15346
+
15347
+ if (nextRow * elementsInRow > allElements.length) {
15348
+ return [];
15349
+ }
15350
+
15351
+ return getRowElements(allElements, nextRow, elementsInRow);
15352
+ }
15353
+
15354
+ function getElementInRow(elements, row, elementsInRow, indexInRow) {
15355
+ var rowElements = getRowElements(elements, row, elementsInRow); // get element, default to last
15356
+
15357
+ return rowElements[indexInRow] || rowElements[rowElements.length - 1] || null;
15222
15358
  }
15359
+ function getElementInNextRow(allElements, currentRow, elementsInRow, index) {
15360
+ var nextRowElements = getNextRowElements(allElements, currentRow, elementsInRow); // return item in index, or last item in row
15223
15361
 
15224
- function buttonFromEmoji(emojiElement) {
15362
+ return nextRowElements[index] || nextRowElements[nextRowElements.length - 1] || null;
15363
+ }
15364
+ function getElementInPrevRow(allElements, currentRow, elementsInRow, index) {
15365
+ var prevRowElements = getRowElements(allElements, currentRow - 1, elementsInRow); // default to last
15366
+
15367
+ return prevRowElements[index] || prevRowElements[prevRowElements.length - 1] || null;
15368
+ }
15369
+ function firstVisibleElementInContainer(parent, elements) {
15370
+ if (!parent || !elements.length) {
15371
+ return null;
15372
+ }
15373
+
15374
+ var parentTop = parent.getBoundingClientRect().top;
15375
+ var parentBottom = parent.getBoundingClientRect().bottom;
15376
+ var visibleElements = elements.find(function (element) {
15377
+ var elementTop = element.getBoundingClientRect().top;
15378
+ var elementBottom = element.getBoundingClientRect().bottom;
15379
+ return elementTop >= parentTop && elementTop <= parentBottom || elementBottom >= parentTop && elementBottom <= parentBottom;
15380
+ });
15381
+ return visibleElements || null;
15382
+ }
15383
+ function hasNextElementSibling(element) {
15384
+ return !!element.nextElementSibling;
15385
+ }
15386
+
15387
+ var EmojiButtonSelector = "button" + /*#__PURE__*/asSelectors(ClassNames.emoji);
15388
+ var VisibleEmojiSelector = /*#__PURE__*/[EmojiButtonSelector, asSelectors(ClassNames.visible), ":not(" + asSelectors(ClassNames.hidden) + ")"].join('');
15389
+ function buttonFromTarget(emojiElement) {
15225
15390
  var _emojiElement$closest;
15226
15391
 
15227
- return (_emojiElement$closest = emojiElement == null ? void 0 : emojiElement.closest('button.epr-emoji')) != null ? _emojiElement$closest : null;
15392
+ return (_emojiElement$closest = emojiElement == null ? void 0 : emojiElement.closest(EmojiButtonSelector)) != null ? _emojiElement$closest : null;
15228
15393
  }
15229
15394
  function emojiFromElement(element) {
15230
15395
  var originalUnified = originalUnifiedFromEmojiElement(element);
@@ -15245,12 +15410,7 @@ function emojiFromElement(element) {
15245
15410
  function isEmojiElement(element) {
15246
15411
  var _element$parentElemen;
15247
15412
 
15248
- return Boolean((element == null ? void 0 : element.matches('button.epr-emoji')) || (element == null ? void 0 : (_element$parentElemen = element.parentElement) == null ? void 0 : _element$parentElemen.matches('button.epr-emoji')));
15249
- }
15250
- function closestCategory(element) {
15251
- var _element$closest;
15252
-
15253
- return (_element$closest = element == null ? void 0 : element.closest('.epr-emoji-category')) != null ? _element$closest : null;
15413
+ return Boolean((element == null ? void 0 : element.matches(EmojiButtonSelector)) || (element == null ? void 0 : (_element$parentElemen = element.parentElement) == null ? void 0 : _element$parentElemen.matches(EmojiButtonSelector)));
15254
15414
  }
15255
15415
  function elementHeight(element) {
15256
15416
  var _element$clientHeight;
@@ -15258,12 +15418,12 @@ function elementHeight(element) {
15258
15418
  return (_element$clientHeight = element == null ? void 0 : element.clientHeight) != null ? _element$clientHeight : 0;
15259
15419
  }
15260
15420
  function emojiTrueOffsetTop(element) {
15261
- var button = buttonFromEmoji(element);
15421
+ var button = buttonFromTarget(element);
15262
15422
  var category = closestCategory(button);
15263
15423
  return elementOffsetTop(button) + elementOffsetTop(category);
15264
15424
  }
15265
15425
  function emojiTruOffsetLeft(element) {
15266
- var button = buttonFromEmoji(element);
15426
+ var button = buttonFromTarget(element);
15267
15427
  var category = closestCategory(button);
15268
15428
  return elementOffsetLeft(button) + elementOffsetLeft(category);
15269
15429
  }
@@ -15283,7 +15443,7 @@ function elementOffsetLeft(element) {
15283
15443
  function unifiedFromEmojiElement(emoji) {
15284
15444
  var _elementDataSetKey;
15285
15445
 
15286
- return (_elementDataSetKey = elementDataSetKey(buttonFromEmoji(emoji), 'unified')) != null ? _elementDataSetKey : null;
15446
+ return (_elementDataSetKey = elementDataSetKey(buttonFromTarget(emoji), 'unified')) != null ? _elementDataSetKey : null;
15287
15447
  }
15288
15448
  function originalUnifiedFromEmojiElement(emoji) {
15289
15449
  var unified = unifiedFromEmojiElement(emoji);
@@ -15307,45 +15467,156 @@ function elementDataSet(element) {
15307
15467
  return (_element$dataset = element == null ? void 0 : element.dataset) != null ? _element$dataset : {};
15308
15468
  }
15309
15469
 
15310
- function parseNativeEmoji(unified) {
15311
- return unified.split('-').map(function (hex) {
15312
- return String.fromCodePoint(parseInt(hex, 16));
15313
- }).join('');
15470
+ function isVisibleEmoji(element) {
15471
+ return element.classList.contains(ClassNames.visible);
15314
15472
  }
15315
-
15316
- var SUGGESTED_LS_KEY = 'epr_suggested';
15317
- function getsuggested(mode) {
15318
- var _window;
15319
-
15320
- if (!((_window = window) != null && _window.localStorage)) {
15473
+ function isHidden(element) {
15474
+ if (!element) return true;
15475
+ return element.classList.contains(ClassNames.hidden);
15476
+ }
15477
+ function allVisibleEmojis(parent) {
15478
+ if (!parent) {
15321
15479
  return [];
15322
15480
  }
15323
15481
 
15324
- try {
15325
- var _window$localStorage$, _window2;
15482
+ return Array.from(parent.querySelectorAll(VisibleEmojiSelector));
15483
+ }
15484
+ function lastVisibleEmoji(element) {
15485
+ if (!element) return null;
15486
+ var allEmojis = allVisibleEmojis(element);
15326
15487
 
15327
- var recent = JSON.parse((_window$localStorage$ = (_window2 = window) == null ? void 0 : _window2.localStorage.getItem(SUGGESTED_LS_KEY)) != null ? _window$localStorage$ : '[]');
15488
+ var _allEmojis$slice = allEmojis.slice(-1),
15489
+ last = _allEmojis$slice[0];
15328
15490
 
15329
- if (mode === SuggestionMode.FREQUENT) {
15330
- return recent.sort(function (a, b) {
15331
- return b.count - a.count;
15332
- });
15333
- }
15491
+ if (!last) {
15492
+ return null;
15493
+ }
15334
15494
 
15335
- return recent;
15336
- } catch (_unused) {
15337
- return [];
15495
+ if (!isVisibleEmoji(last)) {
15496
+ return prevVisibleEmoji(last);
15338
15497
  }
15498
+
15499
+ return last;
15339
15500
  }
15340
- function setsuggested(emoji, skinTone) {
15341
- var recent = getsuggested();
15342
- var unified = emojiUnified(emoji, skinTone);
15343
- var originalUnified = emojiUnified(emoji);
15344
- var existing = recent.find(function (_ref) {
15345
- var u = _ref.unified;
15346
- return u === unified;
15347
- });
15348
- var nextList;
15501
+ function nextVisibleEmoji(element) {
15502
+ var next = element.nextElementSibling;
15503
+
15504
+ if (!next) {
15505
+ return firstVisibleEmoji(nextCategory(element));
15506
+ }
15507
+
15508
+ if (!isVisibleEmoji(next)) {
15509
+ return nextVisibleEmoji(next);
15510
+ }
15511
+
15512
+ return next;
15513
+ }
15514
+ function prevVisibleEmoji(element) {
15515
+ var prev = element.previousElementSibling;
15516
+
15517
+ if (!prev) {
15518
+ return lastVisibleEmoji(prevCategory(element));
15519
+ }
15520
+
15521
+ if (!isVisibleEmoji(prev)) {
15522
+ return prevVisibleEmoji(prev);
15523
+ }
15524
+
15525
+ return prev;
15526
+ }
15527
+ function firstVisibleEmoji(parent) {
15528
+ if (!parent) {
15529
+ return null;
15530
+ }
15531
+
15532
+ var allEmojis = allVisibleEmojis(parent);
15533
+ return firstVisibleElementInContainer(parent, allEmojis);
15534
+ }
15535
+ function prevCategory(element) {
15536
+ var category = closestCategory(element);
15537
+
15538
+ if (!category) {
15539
+ return null;
15540
+ }
15541
+
15542
+ var prev = category.previousElementSibling;
15543
+
15544
+ if (!prev) {
15545
+ return null;
15546
+ }
15547
+
15548
+ if (isHidden(prev)) {
15549
+ return prevCategory(prev);
15550
+ }
15551
+
15552
+ return prev;
15553
+ }
15554
+ function nextCategory(element) {
15555
+ var category = closestCategory(element);
15556
+
15557
+ if (!category) {
15558
+ return null;
15559
+ }
15560
+
15561
+ var next = category.nextElementSibling;
15562
+
15563
+ if (!next) {
15564
+ return null;
15565
+ }
15566
+
15567
+ if (isHidden(next)) {
15568
+ return nextCategory(next);
15569
+ }
15570
+
15571
+ return next;
15572
+ }
15573
+ function closestCategory(element) {
15574
+ if (!element) {
15575
+ return null;
15576
+ }
15577
+
15578
+ return element.closest(asSelectors(ClassNames.category));
15579
+ }
15580
+
15581
+ function parseNativeEmoji(unified) {
15582
+ return unified.split('-').map(function (hex) {
15583
+ return String.fromCodePoint(parseInt(hex, 16));
15584
+ }).join('');
15585
+ }
15586
+
15587
+ var SUGGESTED_LS_KEY = 'epr_suggested';
15588
+ function getsuggested(mode) {
15589
+ var _window;
15590
+
15591
+ if (!((_window = window) != null && _window.localStorage)) {
15592
+ return [];
15593
+ }
15594
+
15595
+ try {
15596
+ var _window$localStorage$, _window2;
15597
+
15598
+ var recent = JSON.parse((_window$localStorage$ = (_window2 = window) == null ? void 0 : _window2.localStorage.getItem(SUGGESTED_LS_KEY)) != null ? _window$localStorage$ : '[]');
15599
+
15600
+ if (mode === SuggestionMode.FREQUENT) {
15601
+ return recent.sort(function (a, b) {
15602
+ return b.count - a.count;
15603
+ });
15604
+ }
15605
+
15606
+ return recent;
15607
+ } catch (_unused) {
15608
+ return [];
15609
+ }
15610
+ }
15611
+ function setsuggested(emoji, skinTone) {
15612
+ var recent = getsuggested();
15613
+ var unified = emojiUnified(emoji, skinTone);
15614
+ var originalUnified = emojiUnified(emoji);
15615
+ var existing = recent.find(function (_ref) {
15616
+ var u = _ref.unified;
15617
+ return u === unified;
15618
+ });
15619
+ var nextList;
15349
15620
 
15350
15621
  if (existing) {
15351
15622
  nextList = [existing].concat(recent.filter(function (i) {
@@ -15371,30 +15642,6 @@ function setsuggested(emoji, skinTone) {
15371
15642
  }
15372
15643
  }
15373
15644
 
15374
- function useCloseAllOpenToggles() {
15375
- var _useEmojiVariationPic = useEmojiVariationPickerState(),
15376
- variationPicker = _useEmojiVariationPic[0],
15377
- setVariationPicker = _useEmojiVariationPic[1];
15378
-
15379
- var _useSkinToneFanOpenSt = useSkinToneFanOpenState(),
15380
- skinToneFanOpen = _useSkinToneFanOpenSt[0],
15381
- setSkinToneFanOpen = _useSkinToneFanOpenSt[1];
15382
-
15383
- var closeAllOpenToggles = React.useCallback(function () {
15384
- if (variationPicker) {
15385
- setVariationPicker(null);
15386
- }
15387
-
15388
- if (skinToneFanOpen) {
15389
- setSkinToneFanOpen(false);
15390
- }
15391
- }, [[variationPicker, skinToneFanOpen]]);
15392
- return {
15393
- closeAllOpenToggles: closeAllOpenToggles,
15394
- dependencyArray: [variationPicker, skinToneFanOpen]
15395
- };
15396
- }
15397
-
15398
15645
  function preloadEmoji(emoji, emojiStyle) {
15399
15646
  var unified = emojiUnified(emoji);
15400
15647
 
@@ -15415,6 +15662,27 @@ function preloadImage(url) {
15415
15662
  image.src = url;
15416
15663
  }
15417
15664
 
15665
+ function useCloseAllOpenToggles() {
15666
+ var _useEmojiVariationPic = useEmojiVariationPickerState(),
15667
+ variationPicker = _useEmojiVariationPic[0],
15668
+ setVariationPicker = _useEmojiVariationPic[1];
15669
+
15670
+ var _useSkinToneFanOpenSt = useSkinToneFanOpenState(),
15671
+ skinToneFanOpen = _useSkinToneFanOpenSt[0],
15672
+ setSkinToneFanOpen = _useSkinToneFanOpenSt[1];
15673
+
15674
+ var closeAllOpenToggles = React.useCallback(function () {
15675
+ if (variationPicker) {
15676
+ setVariationPicker(null);
15677
+ }
15678
+
15679
+ if (skinToneFanOpen) {
15680
+ setSkinToneFanOpen(false);
15681
+ }
15682
+ }, [variationPicker, skinToneFanOpen, setVariationPicker, setSkinToneFanOpen]);
15683
+ return closeAllOpenToggles;
15684
+ }
15685
+
15418
15686
  var mouseDownTimer;
15419
15687
  function useMouseDownHandlers(BodyRef) {
15420
15688
  var preloading = React.useRef(false);
@@ -15424,9 +15692,7 @@ function useMouseDownHandlers(BodyRef) {
15424
15692
  var _useEmojiVariationPic = useEmojiVariationPickerState(),
15425
15693
  setEmojiVariationPicker = _useEmojiVariationPic[1];
15426
15694
 
15427
- var _useCloseAllOpenToggl = useCloseAllOpenToggles(),
15428
- closeAllOpenToggles = _useCloseAllOpenToggl.closeAllOpenToggles,
15429
- dependencyArray = _useCloseAllOpenToggl.dependencyArray;
15695
+ var closeAllOpenToggles = useCloseAllOpenToggles();
15430
15696
 
15431
15697
  var _useActiveSkinToneSta = useActiveSkinToneState(),
15432
15698
  activeSkinTone = _useActiveSkinToneSta[0];
@@ -15437,29 +15703,7 @@ function useMouseDownHandlers(BodyRef) {
15437
15703
  var _useUpdateSuggested = useUpdateSuggested(),
15438
15704
  updateSuggested = _useUpdateSuggested[1];
15439
15705
 
15440
- React.useEffect(function () {
15441
- if (!BodyRef.current) {
15442
- return;
15443
- }
15444
-
15445
- var bodyRef = BodyRef.current;
15446
- bodyRef.addEventListener('click', onClick, {
15447
- passive: true
15448
- });
15449
- bodyRef.addEventListener('mousedown', onMouseDown, {
15450
- passive: true
15451
- });
15452
- bodyRef.addEventListener('mouseup', onMouseUp, {
15453
- passive: true
15454
- });
15455
- return function () {
15456
- bodyRef == null ? void 0 : bodyRef.removeEventListener('click', onClick);
15457
- bodyRef == null ? void 0 : bodyRef.removeEventListener('mousedown', onMouseDown);
15458
- bodyRef == null ? void 0 : bodyRef.removeEventListener('mouseup', onMouseUp);
15459
- };
15460
- }, [BodyRef].concat(dependencyArray));
15461
-
15462
- function onClick(event) {
15706
+ var onClick = React.useCallback(function onClick(event) {
15463
15707
  if (disallowClickRef.current) {
15464
15708
  return;
15465
15709
  }
@@ -15478,9 +15722,8 @@ function useMouseDownHandlers(BodyRef) {
15478
15722
  updateSuggested();
15479
15723
  setsuggested(emoji, skinToneToUse);
15480
15724
  onEmojiClick(emojiClickOutput(emoji, skinToneToUse), event);
15481
- }
15482
-
15483
- function onMouseDown(event) {
15725
+ }, [activeSkinTone, closeAllOpenToggles, disallowClickRef, onEmojiClick, updateSuggested]);
15726
+ var onMouseDown = React.useCallback(function onMouseDown(event) {
15484
15727
  var _window, _window2;
15485
15728
 
15486
15729
  if (mouseDownTimer) {
@@ -15508,9 +15751,8 @@ function useMouseDownHandlers(BodyRef) {
15508
15751
  setAnchoredEmojiRef(event.target);
15509
15752
  setEmojiVariationPicker(emoji);
15510
15753
  }, 500);
15511
- }
15512
-
15513
- function onMouseUp() {
15754
+ }, [disallowClickRef, closeAllOpenToggles, setAnchoredEmojiRef, emojiStyle, setEmojiVariationPicker]);
15755
+ var onMouseUp = React.useCallback(function onMouseUp() {
15514
15756
  preloading.current = false;
15515
15757
 
15516
15758
  if (mouseDownTimer) {
@@ -15526,7 +15768,28 @@ function useMouseDownHandlers(BodyRef) {
15526
15768
  disallowClickRef.current = false;
15527
15769
  });
15528
15770
  }
15529
- }
15771
+ }, [disallowClickRef]);
15772
+ React.useEffect(function () {
15773
+ if (!BodyRef.current) {
15774
+ return;
15775
+ }
15776
+
15777
+ var bodyRef = BodyRef.current;
15778
+ bodyRef.addEventListener('click', onClick, {
15779
+ passive: true
15780
+ });
15781
+ bodyRef.addEventListener('mousedown', onMouseDown, {
15782
+ passive: true
15783
+ });
15784
+ bodyRef.addEventListener('mouseup', onMouseUp, {
15785
+ passive: true
15786
+ });
15787
+ return function () {
15788
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('click', onClick);
15789
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('mousedown', onMouseDown);
15790
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('mouseup', onMouseUp);
15791
+ };
15792
+ }, [BodyRef, onClick, onMouseDown, onMouseUp]);
15530
15793
  }
15531
15794
 
15532
15795
  function emojiFromEvent(event) {
@@ -15554,10 +15817,7 @@ function emojiClickOutput(emoji, activeSkinTone) {
15554
15817
  }
15555
15818
 
15556
15819
  function useOnScroll(BodyRef) {
15557
- var _useCloseAllOpenToggl = useCloseAllOpenToggles(),
15558
- closeAllOpenToggles = _useCloseAllOpenToggl.closeAllOpenToggles,
15559
- dependencyArray = _useCloseAllOpenToggl.dependencyArray;
15560
-
15820
+ var closeAllOpenToggles = useCloseAllOpenToggles();
15561
15821
  React.useEffect(function () {
15562
15822
  var bodyRef = BodyRef.current;
15563
15823
 
@@ -15576,18 +15836,9 @@ function useOnScroll(BodyRef) {
15576
15836
  return function () {
15577
15837
  bodyRef == null ? void 0 : bodyRef.removeEventListener('scroll', onScroll);
15578
15838
  };
15579
- }, [].concat(dependencyArray, [BodyRef, closeAllOpenToggles]));
15839
+ }, [BodyRef, closeAllOpenToggles]);
15580
15840
  }
15581
15841
 
15582
- var ClassNames;
15583
-
15584
- (function (ClassNames) {
15585
- ClassNames["hiddenOnSearch"] = "epr-hidden-on-search";
15586
- ClassNames["searchActive"] = "epr-search-active";
15587
- ClassNames["hidden"] = "epr-hidden";
15588
- ClassNames["visible"] = "epr-visible";
15589
- })(ClassNames || (ClassNames = {}));
15590
-
15591
15842
  var emojiRef = {};
15592
15843
  function getEmojiRef(unified) {
15593
15844
  emojiRef[unified] = emojiRef[unified] || {
@@ -15629,33 +15880,52 @@ function useSetFilterRef() {
15629
15880
  };
15630
15881
  }
15631
15882
 
15883
+ function useClearSearch() {
15884
+ var SearchInputRef = useSearchInputRef();
15885
+
15886
+ var _useSearchTermState = useSearchTermState(),
15887
+ setSearchTerm = _useSearchTermState[1];
15888
+
15889
+ return function clearSearch() {
15890
+ if (SearchInputRef.current) {
15891
+ SearchInputRef.current.value = '';
15892
+ }
15893
+
15894
+ setSearchTerm('');
15895
+ };
15896
+ }
15897
+ function useAppendSearch() {
15898
+ var SearchInputRef = useSearchInputRef();
15899
+
15900
+ var _useSearchTermState2 = useSearchTermState(),
15901
+ setSearchTerm = _useSearchTermState2[1];
15902
+
15903
+ return function appendSearch(str) {
15904
+ if (SearchInputRef.current) {
15905
+ SearchInputRef.current.value = SearchInputRef.current.value + str;
15906
+ setSearchTerm(SearchInputRef.current.value);
15907
+ }
15908
+
15909
+ setSearchTerm(str);
15910
+ };
15911
+ }
15632
15912
  function useFilter() {
15633
- var SearchInputRef = React.useRef(null);
15913
+ var SearchInputRef = useSearchInputRef();
15634
15914
  var filterRef = useFilterRef();
15635
15915
  var setFilterRef = useSetFilterRef();
15636
15916
 
15637
- var _useSearchTermState = useSearchTermState(),
15638
- searchTerm = _useSearchTermState[0],
15639
- setSearchTerm = _useSearchTermState[1];
15917
+ var _useSearchTermState3 = useSearchTermState(),
15918
+ searchTerm = _useSearchTermState3[0],
15919
+ setSearchTerm = _useSearchTermState3[1];
15640
15920
 
15641
15921
  var PickerMainRef = usePickerMainRef();
15642
15922
  return {
15643
15923
  onChange: onChange,
15644
15924
  searchTerm: searchTerm,
15645
- clearSearch: clearSearch,
15646
15925
  SearchInputRef: SearchInputRef
15647
15926
  };
15648
15927
 
15649
- function clearSearch() {
15650
- if (SearchInputRef.current) {
15651
- SearchInputRef.current.value = '';
15652
- }
15653
-
15654
- onChange('');
15655
- }
15656
-
15657
15928
  function onChange(nextValue) {
15658
- scrollTo(PickerMainRef.current, 0);
15659
15929
  var filter = filterRef.current;
15660
15930
 
15661
15931
  if (filter != null && filter[nextValue] || nextValue.length <= 1) {
@@ -15696,7 +15966,9 @@ function useFilter() {
15696
15966
  showElement(element);
15697
15967
  });
15698
15968
  requestAnimationFrame(function () {
15699
- setSearchTerm(searchTerm);
15969
+ setSearchTerm(searchTerm).then(function () {
15970
+ scrollTo(PickerMainRef.current, 0);
15971
+ });
15700
15972
  });
15701
15973
  }
15702
15974
  }
@@ -15727,8 +15999,8 @@ function useIsEmojiFiltered() {
15727
15999
  var _useFilterRef = useFilterRef(),
15728
16000
  filter = _useFilterRef.current;
15729
16001
 
15730
- var _useSearchTermState2 = useSearchTermState(),
15731
- searchTerm = _useSearchTermState2[0];
16002
+ var _useSearchTermState4 = useSearchTermState(),
16003
+ searchTerm = _useSearchTermState4[0];
15732
16004
 
15733
16005
  return function (unified) {
15734
16006
  return isEmojiFilteredBySearchTerm(unified, filter, searchTerm);
@@ -15778,23 +16050,6 @@ function useIsEmojiHidden() {
15778
16050
  };
15779
16051
  }
15780
16052
 
15781
- function EmojiCategory(_ref) {
15782
- var _clsx;
15783
-
15784
- var categoryConfig = _ref.categoryConfig,
15785
- children = _ref.children,
15786
- hidden = _ref.hidden,
15787
- hiddenOnSearch = _ref.hiddenOnSearch;
15788
- var category = categoryFromCategoryConfig(categoryConfig);
15789
- var categoryName = categoryNameFromCategoryConfig(categoryConfig);
15790
- return React.createElement("li", {
15791
- className: clsx('epr-emoji-category', (_clsx = {}, _clsx[ClassNames.hidden] = hidden, _clsx[ClassNames.hiddenOnSearch] = hiddenOnSearch, _clsx)),
15792
- "data-name": category
15793
- }, React.createElement("div", {
15794
- className: "epr-emoji-category-label"
15795
- }, categoryName), children);
15796
- }
15797
-
15798
16053
  function Emoji(_ref) {
15799
16054
  var _clsx;
15800
16055
 
@@ -15819,7 +16074,7 @@ function Emoji(_ref) {
15819
16074
  unified: unified
15820
16075
  };
15821
16076
  return React.createElement("button", {
15822
- className: clsx('epr-emoji', (_clsx = {}, _clsx[ClassNames.hidden] = hidden, _clsx[ClassNames.visible] = !hidden, _clsx['epr-emoji-has-variations'] = hasVariations && showVariations, _clsx)),
16077
+ className: clsx(ClassNames.emoji, (_clsx = {}, _clsx[ClassNames.hidden] = hidden, _clsx[ClassNames.visible] = !hidden, _clsx['epr-emoji-has-variations'] = hasVariations && showVariations, _clsx)),
15823
16078
  "data-unified": unified,
15824
16079
  // @ts-ignore - let's ignore the fact this is not a real react ref, ok?
15825
16080
  ref: emojiRef
@@ -15867,6 +16122,25 @@ function EmojiImg(_ref3) {
15867
16122
  }
15868
16123
  }
15869
16124
 
16125
+ function EmojiCategory(_ref) {
16126
+ var _clsx;
16127
+
16128
+ var categoryConfig = _ref.categoryConfig,
16129
+ children = _ref.children,
16130
+ hidden = _ref.hidden,
16131
+ hiddenOnSearch = _ref.hiddenOnSearch;
16132
+ var category = categoryFromCategoryConfig(categoryConfig);
16133
+ var categoryName = categoryNameFromCategoryConfig(categoryConfig);
16134
+ return React.createElement("li", {
16135
+ className: clsx(ClassNames.category, (_clsx = {}, _clsx[ClassNames.hidden] = hidden, _clsx[ClassNames.hiddenOnSearch] = hiddenOnSearch, _clsx)),
16136
+ "data-name": category
16137
+ }, React.createElement("div", {
16138
+ className: "epr-emoji-category-label"
16139
+ }, categoryName), React.createElement("div", {
16140
+ className: "epr-emoji-category-content"
16141
+ }, children));
16142
+ }
16143
+
15870
16144
  function Suggested(_ref) {
15871
16145
  var categoryConfig = _ref.categoryConfig;
15872
16146
 
@@ -15881,7 +16155,8 @@ function Suggested(_ref) {
15881
16155
  var _getsuggested;
15882
16156
 
15883
16157
  return (_getsuggested = getsuggested(suggestedEmojisModeConfig)) != null ? _getsuggested : [];
15884
- }, [suggestedUpdated]);
16158
+ }, // eslint-disable-next-line react-hooks/exhaustive-deps
16159
+ [suggestedUpdated, suggestedEmojisModeConfig]);
15885
16160
  var emojiStyle = useEmojiStyleConfig();
15886
16161
  var hidden = !!(searchTerm || suggested.length === 0);
15887
16162
  return React.createElement(EmojiCategory, {
@@ -15900,7 +16175,8 @@ function Suggested(_ref) {
15900
16175
  unified: suggestedItem.unified,
15901
16176
  emojiStyle: emojiStyle,
15902
16177
  emoji: emoji,
15903
- key: suggestedItem.unified
16178
+ key: suggestedItem.unified,
16179
+ hidden: hidden
15904
16180
  });
15905
16181
  }));
15906
16182
  }
@@ -16041,7 +16317,7 @@ function usePointerStyle(VariationPickerRef) {
16041
16317
  }
16042
16318
 
16043
16319
  if (AnchoredEmojiRef.current) {
16044
- var button = buttonFromEmoji(AnchoredEmojiRef.current);
16320
+ var button = buttonFromTarget(AnchoredEmojiRef.current);
16045
16321
  var offsetLeft = emojiTruOffsetLeft(button);
16046
16322
 
16047
16323
  if (!button) {
@@ -16083,7 +16359,7 @@ function useVariationPickerTop(VariationPickerRef) {
16083
16359
  var _bodyRef$scrollTop;
16084
16360
 
16085
16361
  var bodyRef = BodyRef.current;
16086
- var button = buttonFromEmoji(AnchoredEmojiRef.current);
16362
+ var button = buttonFromTarget(AnchoredEmojiRef.current);
16087
16363
  var buttonHeight = elementHeight(button);
16088
16364
  emojiOffsetTop = emojiTrueOffsetTop(button);
16089
16365
  var scrollTop = (_bodyRef$scrollTop = bodyRef == null ? void 0 : bodyRef.scrollTop) != null ? _bodyRef$scrollTop : 0;
@@ -16109,7 +16385,32 @@ function Body() {
16109
16385
  }, React.createElement(EmojiVariationPicker, null), React.createElement(EmojiList, null));
16110
16386
  }
16111
16387
 
16112
- function useEmojiMouseEnter(allow, setHoveredEmoji) {
16388
+ function focusElement(element) {
16389
+ if (!element) {
16390
+ return;
16391
+ }
16392
+
16393
+ requestAnimationFrame(function () {
16394
+ element.focus();
16395
+ });
16396
+ }
16397
+ function focusPrevElementSibling(element) {
16398
+ if (!element) return;
16399
+ var prev = element.previousElementSibling;
16400
+ focusElement(prev);
16401
+ }
16402
+ function focusNextElementSibling(element) {
16403
+ if (!element) return;
16404
+ var next = element.nextElementSibling;
16405
+ focusElement(next);
16406
+ }
16407
+ function focusFirstElementChild(element) {
16408
+ if (!element) return;
16409
+ var first = element.firstElementChild;
16410
+ focusElement(first);
16411
+ }
16412
+
16413
+ function useEmojiPreviewEvents(allow, setPreviewEmoji) {
16113
16414
  var BodyRef = useBodyRef();
16114
16415
  React.useEffect(function () {
16115
16416
  if (!allow) {
@@ -16117,40 +16418,71 @@ function useEmojiMouseEnter(allow, setHoveredEmoji) {
16117
16418
  }
16118
16419
 
16119
16420
  var bodyRef = BodyRef.current;
16421
+ bodyRef == null ? void 0 : bodyRef.addEventListener('keydown', onEscape, {
16422
+ passive: true
16423
+ });
16120
16424
  bodyRef == null ? void 0 : bodyRef.addEventListener('mouseover', onMouseOver, {
16121
16425
  passive: true
16122
16426
  });
16123
- bodyRef == null ? void 0 : bodyRef.addEventListener('mouseout', onMouseOut, {
16427
+ bodyRef == null ? void 0 : bodyRef.addEventListener('focus', onEnter, true);
16428
+ bodyRef == null ? void 0 : bodyRef.addEventListener('mouseout', onLeave, {
16124
16429
  passive: true
16125
16430
  });
16126
- return function () {
16127
- bodyRef == null ? void 0 : bodyRef.removeEventListener('mouseover', onMouseOver);
16128
- bodyRef == null ? void 0 : bodyRef.removeEventListener('mouseout', onMouseOut);
16129
- };
16130
- }, [BodyRef.current]);
16431
+ bodyRef == null ? void 0 : bodyRef.addEventListener('blur', onLeave, true);
16131
16432
 
16132
- function onMouseOver(e) {
16133
- var button = buttonFromEmoji(e.target);
16433
+ function onEnter(e) {
16434
+ var button = buttonFromTarget(e.target);
16134
16435
 
16135
- if (!button) {
16136
- return onMouseOut();
16436
+ if (!button) {
16437
+ return onLeave();
16438
+ }
16439
+
16440
+ var unified = unifiedFromEmojiElement(button);
16441
+ var originalUnified = originalUnifiedFromEmojiElement(button);
16442
+
16443
+ if (!unified || !originalUnified) {
16444
+ return onLeave();
16445
+ }
16446
+
16447
+ setPreviewEmoji({
16448
+ unified: unified,
16449
+ originalUnified: originalUnified
16450
+ });
16137
16451
  }
16138
16452
 
16139
- var unified = unifiedFromEmojiElement(button);
16140
- var originalUnified = originalUnifiedFromEmojiElement(button);
16453
+ function onLeave(e) {
16454
+ if (e) {
16455
+ var button = buttonFromTarget(e.target);
16456
+
16457
+ if (button) {
16458
+ return;
16459
+ }
16460
+ }
16141
16461
 
16142
- if (!unified || !originalUnified) {
16143
- return onMouseOut();
16462
+ setPreviewEmoji(null);
16144
16463
  }
16145
16464
 
16146
- setHoveredEmoji({
16147
- unified: unified,
16148
- originalUnified: originalUnified
16149
- });
16150
- }
16465
+ function onEscape(e) {
16466
+ if (e.key === 'Escape') {
16467
+ setPreviewEmoji(null);
16468
+ }
16469
+ }
16151
16470
 
16152
- function onMouseOut() {
16153
- setHoveredEmoji(null);
16471
+ return function () {
16472
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('mouseover', onMouseOver);
16473
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('mouseout', onLeave);
16474
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('focus', onEnter, true);
16475
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('blur', onLeave, true);
16476
+ bodyRef == null ? void 0 : bodyRef.removeEventListener('keydown', onEscape);
16477
+ };
16478
+ }, [BodyRef, allow, setPreviewEmoji]);
16479
+
16480
+ function onMouseOver(e) {
16481
+ var button = buttonFromTarget(e.target);
16482
+
16483
+ if (button) {
16484
+ focusElement(button);
16485
+ }
16154
16486
  }
16155
16487
  }
16156
16488
 
@@ -16175,34 +16507,34 @@ function Flex(_ref) {
16175
16507
  }
16176
16508
 
16177
16509
  function Preview() {
16178
- var showPreview = useShowPreviewConfig();
16510
+ var previewConfig = usePreviewConfig();
16179
16511
 
16180
16512
  var _useState = React.useState(null),
16181
- hoveredEmoji = _useState[0],
16182
- setHoveredEmoji = _useState[1];
16513
+ previewEmoji = _useState[0],
16514
+ setPreviewEmoji = _useState[1];
16183
16515
 
16184
16516
  var emojiStyle = useEmojiStyleConfig();
16185
16517
 
16186
16518
  var _useEmojiVariationPic = useEmojiVariationPickerState(),
16187
16519
  variationPickerEmoji = _useEmojiVariationPic[0];
16188
16520
 
16189
- useEmojiMouseEnter(showPreview, setHoveredEmoji);
16521
+ useEmojiPreviewEvents(previewConfig.showPreview, setPreviewEmoji);
16190
16522
 
16191
- if (!showPreview) {
16523
+ if (!previewConfig.showPreview) {
16192
16524
  return null;
16193
16525
  }
16194
16526
 
16195
- var emoji = emojiByUnified(hoveredEmoji == null ? void 0 : hoveredEmoji.originalUnified);
16196
- var show = emoji != null && hoveredEmoji != null;
16527
+ var emoji = emojiByUnified(previewEmoji == null ? void 0 : previewEmoji.originalUnified);
16528
+ var show = emoji != null && previewEmoji != null;
16197
16529
  return React.createElement(Flex, {
16198
16530
  className: "epr-preview"
16199
16531
  }, React.createElement(PreviewContent, null));
16200
16532
 
16201
16533
  function PreviewContent() {
16202
- var defaultEmoji = asEmoji(variationPickerEmoji != null ? variationPickerEmoji : emojiByUnified('1f60a'));
16203
- var defaultText = variationPickerEmoji ? emojiName(variationPickerEmoji) : "What's your mood?";
16534
+ var defaultEmoji = asEmoji(variationPickerEmoji != null ? variationPickerEmoji : emojiByUnified(previewConfig.defaultEmoji));
16535
+ var defaultText = variationPickerEmoji ? emojiName(variationPickerEmoji) : previewConfig.defaultCaption;
16204
16536
  return React.createElement(React.Fragment, null, React.createElement("div", null, show ? React.createElement(Emoji, {
16205
- unified: hoveredEmoji == null ? void 0 : hoveredEmoji.unified,
16537
+ unified: previewEmoji == null ? void 0 : previewEmoji.unified,
16206
16538
  emoji: asEmoji(emoji),
16207
16539
  showVariations: false,
16208
16540
  emojiStyle: emojiStyle,
@@ -16236,19 +16568,21 @@ function Relative(_ref) {
16236
16568
 
16237
16569
  function CategoryNavigation() {
16238
16570
  var categoriesConfig = useCategoriesConfig();
16571
+ var CategoryNavigationRef = useCategoryNavigationRef();
16239
16572
 
16240
16573
  var _useActiveCategorySta = useActiveCategoryState(),
16241
16574
  activeCategory = _useActiveCategorySta[0],
16242
16575
  setActiveCategoryAndScroll = _useActiveCategorySta[2];
16243
16576
 
16244
16577
  return React.createElement("div", {
16245
- className: "epr-category-nav"
16578
+ className: "epr-category-nav",
16579
+ ref: CategoryNavigationRef
16246
16580
  }, categoriesConfig.map(function (categoryConfig) {
16247
16581
  var _clsx;
16248
16582
 
16249
16583
  var category = categoryFromCategoryConfig(categoryConfig);
16250
16584
  return React.createElement("button", {
16251
- className: clsx('epr-cat-btn', "epr-icn-" + category, (_clsx = {}, _clsx['epr-active'] = category === activeCategory, _clsx)),
16585
+ className: clsx('epr-cat-btn', "epr-icn-" + category, (_clsx = {}, _clsx[ClassNames.active] = category === activeCategory, _clsx)),
16252
16586
  key: category,
16253
16587
  onClick: function onClick() {
16254
16588
  return setActiveCategoryAndScroll(category);
@@ -16258,17 +16592,15 @@ function CategoryNavigation() {
16258
16592
  }
16259
16593
 
16260
16594
  function Search() {
16261
- var _useCloseAllOpenToggl = useCloseAllOpenToggles(),
16262
- closeAllOpenToggles = _useCloseAllOpenToggl.closeAllOpenToggles;
16263
-
16595
+ var closeAllOpenToggles = useCloseAllOpenToggles();
16596
+ var SearchInputRef = useSearchInputRef();
16597
+ var clearSearch = useClearSearch();
16264
16598
  var placeholder = useSearchPlaceHolderConfig();
16265
16599
  var autoFocus = useAutoFocusSearchConfig();
16266
16600
 
16267
16601
  var _useFilter = useFilter(),
16268
16602
  _onChange = _useFilter.onChange,
16269
- searchTerm = _useFilter.searchTerm,
16270
- clearSearch = _useFilter.clearSearch,
16271
- SearchInputRef = _useFilter.SearchInputRef;
16603
+ searchTerm = _useFilter.searchTerm;
16272
16604
 
16273
16605
  return React.createElement(Relative, {
16274
16606
  className: "epr-search-container"
@@ -16293,6 +16625,7 @@ function Search() {
16293
16625
  }
16294
16626
 
16295
16627
  function SkinTonePicker() {
16628
+ var SkinTonePickerRef = useSkinTonePickerRef();
16296
16629
  var isDisabled = useSkinTonesDisabledConfig();
16297
16630
 
16298
16631
  var _useSkinToneFanOpenSt = useSkinToneFanOpenState(),
@@ -16303,8 +16636,7 @@ function SkinTonePicker() {
16303
16636
  activeSkinTone = _useActiveSkinToneSta[0],
16304
16637
  setActiveSkinTone = _useActiveSkinToneSta[1];
16305
16638
 
16306
- var _useCloseAllOpenToggl = useCloseAllOpenToggles(),
16307
- closeAllOpenToggles = _useCloseAllOpenToggl.closeAllOpenToggles;
16639
+ var closeAllOpenToggles = useCloseAllOpenToggles();
16308
16640
 
16309
16641
  if (isDisabled) {
16310
16642
  return null;
@@ -16318,7 +16650,8 @@ function SkinTonePicker() {
16318
16650
  className: "epr-skin-tone-select",
16319
16651
  onClick: function onClick() {
16320
16652
  return setIsOpen(!isOpen);
16321
- }
16653
+ },
16654
+ ref: SkinTonePickerRef
16322
16655
  }, skinToneVariations.map(function (skinToneVariation, i) {
16323
16656
  var _clsx;
16324
16657
 
@@ -16332,7 +16665,8 @@ function SkinTonePicker() {
16332
16665
  closeAllOpenToggles();
16333
16666
  },
16334
16667
  key: skinToneVariation,
16335
- className: clsx("epr-tone-" + skinToneVariation, 'epr-tone', (_clsx = {}, _clsx['epr-active'] = active, _clsx))
16668
+ className: clsx("epr-tone-" + skinToneVariation, 'epr-tone', (_clsx = {}, _clsx[ClassNames.active] = active, _clsx)),
16669
+ tabIndex: isOpen ? 0 : -1
16336
16670
  });
16337
16671
  })));
16338
16672
  }
@@ -16352,6 +16686,487 @@ function useIsSearchMode() {
16352
16686
  return !!searchTerm;
16353
16687
  }
16354
16688
 
16689
+ function getActiveElement() {
16690
+ return document.activeElement;
16691
+ }
16692
+
16693
+ function focusFirstVisibleEmoji(parent) {
16694
+ focusElement(firstVisibleEmoji(parent));
16695
+ }
16696
+ function focusAndClickFirstVisibleEmoji(parent) {
16697
+ var firstEmoji = firstVisibleEmoji(parent);
16698
+ focusElement(firstEmoji);
16699
+ firstEmoji == null ? void 0 : firstEmoji.click();
16700
+ }
16701
+ function focusLastVisibleEmoji(parent) {
16702
+ focusElement(lastVisibleEmoji(parent));
16703
+ }
16704
+ function focusNextVisibleEmoji(element) {
16705
+ if (!element) {
16706
+ return;
16707
+ }
16708
+
16709
+ var next = nextVisibleEmoji(element);
16710
+
16711
+ if (!next) {
16712
+ return focusFirstVisibleEmoji(nextCategory(element));
16713
+ }
16714
+
16715
+ focusElement(next);
16716
+ }
16717
+ function focusPrevVisibleEmoji(element) {
16718
+ if (!element) {
16719
+ return;
16720
+ }
16721
+
16722
+ var prev = prevVisibleEmoji(element);
16723
+
16724
+ if (!prev) {
16725
+ return focusLastVisibleEmoji(prevCategory(element));
16726
+ }
16727
+
16728
+ focusElement(prev);
16729
+ }
16730
+ function focusVisibleEmojiOneRowUp(element, exitUp) {
16731
+ if (!element) {
16732
+ return;
16733
+ }
16734
+
16735
+ var prev = visibleEmojiOneRowUp(element);
16736
+
16737
+ if (!prev) {
16738
+ return exitUp();
16739
+ }
16740
+
16741
+ focusElement(prev);
16742
+ }
16743
+ function focusVisibleEmojiOneRowDown(element) {
16744
+ if (!element) {
16745
+ return;
16746
+ }
16747
+
16748
+ var next = visibleEmojiOneRowDown(element);
16749
+ return focusElement(next);
16750
+ }
16751
+
16752
+ function visibleEmojiOneRowUp(element) {
16753
+ if (!element) {
16754
+ return null;
16755
+ }
16756
+
16757
+ var category = closestCategory(element);
16758
+ var indexInRow = elementIndexInRow(category, element);
16759
+ var row = rowNumber(category, element);
16760
+ var countInRow = elementCountInRow(category, element);
16761
+
16762
+ if (row === 0) {
16763
+ var prevVisibleCategory = prevCategory(category);
16764
+
16765
+ if (!prevVisibleCategory) {
16766
+ return null;
16767
+ }
16768
+
16769
+ return getElementInRow(allVisibleEmojis(prevVisibleCategory), -1, // last row
16770
+ countInRow, indexInRow);
16771
+ }
16772
+
16773
+ return getElementInPrevRow(allVisibleEmojis(category), row, countInRow, indexInRow);
16774
+ }
16775
+
16776
+ function visibleEmojiOneRowDown(element) {
16777
+ if (!element) {
16778
+ return null;
16779
+ }
16780
+
16781
+ var category = closestCategory(element);
16782
+ var indexInRow = elementIndexInRow(category, element);
16783
+ var row = rowNumber(category, element);
16784
+ var countInRow = elementCountInRow(category, element);
16785
+
16786
+ if (!hasNextRow(category, element)) {
16787
+ var nextVisibleCategory = nextCategory(category);
16788
+
16789
+ if (!nextVisibleCategory) {
16790
+ return null;
16791
+ }
16792
+
16793
+ return getElementInRow(allVisibleEmojis(nextVisibleCategory), 0, countInRow, indexInRow);
16794
+ }
16795
+
16796
+ var itemInNextRow = getElementInNextRow(allVisibleEmojis(category), row, countInRow, indexInRow);
16797
+ return itemInNextRow;
16798
+ }
16799
+
16800
+ function useFocusSearchInput() {
16801
+ var SearchInputRef = useSearchInputRef();
16802
+ return React.useCallback(function () {
16803
+ focusElement(SearchInputRef.current);
16804
+ }, [SearchInputRef]);
16805
+ }
16806
+ function useFocusSkinTonePicker() {
16807
+ var SkinTonePickerRef = useSkinTonePickerRef();
16808
+ return React.useCallback(function () {
16809
+ if (!SkinTonePickerRef.current) {
16810
+ return;
16811
+ }
16812
+
16813
+ focusFirstElementChild(SkinTonePickerRef.current);
16814
+ }, [SkinTonePickerRef]);
16815
+ }
16816
+ function useFocusCategoryNavigation() {
16817
+ var CategoryNavigationRef = useCategoryNavigationRef();
16818
+ return React.useCallback(function () {
16819
+ if (!CategoryNavigationRef.current) {
16820
+ return;
16821
+ }
16822
+
16823
+ focusFirstElementChild(CategoryNavigationRef.current);
16824
+ }, [CategoryNavigationRef]);
16825
+ }
16826
+
16827
+ var KeyboardEvents;
16828
+
16829
+ (function (KeyboardEvents) {
16830
+ KeyboardEvents["ArrowDown"] = "ArrowDown";
16831
+ KeyboardEvents["ArrowUp"] = "ArrowUp";
16832
+ KeyboardEvents["ArrowLeft"] = "ArrowLeft";
16833
+ KeyboardEvents["ArrowRight"] = "ArrowRight";
16834
+ KeyboardEvents["Escape"] = "Escape";
16835
+ KeyboardEvents["Enter"] = "Enter";
16836
+ })(KeyboardEvents || (KeyboardEvents = {}));
16837
+
16838
+ function useKeyboardNavigation() {
16839
+ usePickerMainKeyboardEvents();
16840
+ useSearchInputKeyboardEvents();
16841
+ useSkinTonePickerKeyboardEvents();
16842
+ useCategoryNavigationKeyboardEvents();
16843
+ useBodyKeyboardEvents();
16844
+ }
16845
+
16846
+ function usePickerMainKeyboardEvents() {
16847
+ var PickerMainRef = usePickerMainRef();
16848
+ var clearSearch = useClearSearch();
16849
+ var scrollTo = useScrollTo();
16850
+ var SearchInputRef = useSearchInputRef();
16851
+ var focusSearchInput = useFocusSearchInput();
16852
+ var closeAllOpenToggles = useCloseAllOpenToggles();
16853
+ var onKeyDown = React.useMemo(function () {
16854
+ return function onKeyDown(event) {
16855
+ var key = event.key;
16856
+
16857
+ if (key === KeyboardEvents.Escape) {
16858
+ event.preventDefault();
16859
+ clearSearch();
16860
+ closeAllOpenToggles();
16861
+ scrollTo(0);
16862
+ focusSearchInput();
16863
+ }
16864
+ };
16865
+ }, [scrollTo, clearSearch, closeAllOpenToggles, focusSearchInput]);
16866
+ React.useEffect(function () {
16867
+ var current = PickerMainRef.current;
16868
+
16869
+ if (!current) {
16870
+ return;
16871
+ }
16872
+
16873
+ current.addEventListener('keydown', onKeyDown);
16874
+ return function () {
16875
+ current.removeEventListener('keydown', onKeyDown);
16876
+ };
16877
+ }, [PickerMainRef, SearchInputRef, scrollTo, onKeyDown]);
16878
+ }
16879
+
16880
+ function useSearchInputKeyboardEvents() {
16881
+ var focusSkinTonePicker = useFocusSkinTonePicker();
16882
+ var PickerMainRef = usePickerMainRef();
16883
+ var BodyRef = useBodyRef();
16884
+ var SearchInputRef = useSearchInputRef();
16885
+
16886
+ var _useSkinToneFanOpenSt = useSkinToneFanOpenState(),
16887
+ setSkinToneFanOpenState = _useSkinToneFanOpenSt[1];
16888
+
16889
+ var goDownFromSearchInput = useGoDownFromSearchInput();
16890
+ var onKeyDown = React.useMemo(function () {
16891
+ return function onKeyDown(event) {
16892
+ var key = event.key;
16893
+
16894
+ switch (key) {
16895
+ case KeyboardEvents.ArrowRight:
16896
+ event.preventDefault();
16897
+ setSkinToneFanOpenState(true);
16898
+ focusSkinTonePicker();
16899
+ break;
16900
+
16901
+ case KeyboardEvents.ArrowDown:
16902
+ event.preventDefault();
16903
+ goDownFromSearchInput();
16904
+ break;
16905
+
16906
+ case KeyboardEvents.Enter:
16907
+ event.preventDefault();
16908
+ focusAndClickFirstVisibleEmoji(BodyRef.current);
16909
+ break;
16910
+ }
16911
+ };
16912
+ }, [focusSkinTonePicker, goDownFromSearchInput, setSkinToneFanOpenState, BodyRef]);
16913
+ React.useEffect(function () {
16914
+ var current = SearchInputRef.current;
16915
+
16916
+ if (!current) {
16917
+ return;
16918
+ }
16919
+
16920
+ current.addEventListener('keydown', onKeyDown);
16921
+ return function () {
16922
+ current.removeEventListener('keydown', onKeyDown);
16923
+ };
16924
+ }, [PickerMainRef, SearchInputRef, onKeyDown]);
16925
+ }
16926
+
16927
+ function useSkinTonePickerKeyboardEvents() {
16928
+ var SkinTonePickerRef = useSkinTonePickerRef();
16929
+ var focusSearchInput = useFocusSearchInput();
16930
+ var SearchInputRef = useSearchInputRef();
16931
+ var goDownFromSearchInput = useGoDownFromSearchInput();
16932
+
16933
+ var _useSkinToneFanOpenSt2 = useSkinToneFanOpenState(),
16934
+ isOpen = _useSkinToneFanOpenSt2[0],
16935
+ setIsOpen = _useSkinToneFanOpenSt2[1];
16936
+
16937
+ var onType = useOnType();
16938
+ var onKeyDown = React.useMemo(function () {
16939
+ return function onKeyDown(event) {
16940
+ var key = event.key;
16941
+
16942
+ switch (key) {
16943
+ case KeyboardEvents.ArrowLeft:
16944
+ event.preventDefault();
16945
+
16946
+ if (!isOpen) {
16947
+ return focusSearchInput();
16948
+ }
16949
+
16950
+ focusNextSkinTone(focusSearchInput);
16951
+ break;
16952
+
16953
+ case KeyboardEvents.ArrowRight:
16954
+ event.preventDefault();
16955
+
16956
+ if (!isOpen) {
16957
+ return focusSearchInput();
16958
+ }
16959
+
16960
+ focusPrevSkinTone();
16961
+ break;
16962
+
16963
+ case KeyboardEvents.ArrowDown:
16964
+ event.preventDefault();
16965
+
16966
+ if (isOpen) {
16967
+ setIsOpen(false);
16968
+ }
16969
+
16970
+ goDownFromSearchInput();
16971
+ break;
16972
+
16973
+ default:
16974
+ onType(event);
16975
+ break;
16976
+ }
16977
+ };
16978
+ }, [isOpen, focusSearchInput, setIsOpen, goDownFromSearchInput, onType]);
16979
+ React.useEffect(function () {
16980
+ var current = SkinTonePickerRef.current;
16981
+
16982
+ if (!current) {
16983
+ return;
16984
+ }
16985
+
16986
+ current.addEventListener('keydown', onKeyDown);
16987
+ return function () {
16988
+ current.removeEventListener('keydown', onKeyDown);
16989
+ };
16990
+ }, [SkinTonePickerRef, SearchInputRef, isOpen, onKeyDown]);
16991
+ }
16992
+
16993
+ function useCategoryNavigationKeyboardEvents() {
16994
+ var focusSearchInput = useFocusSearchInput();
16995
+ var CategoryNavigationRef = useCategoryNavigationRef();
16996
+ var BodyRef = useBodyRef();
16997
+ var onType = useOnType();
16998
+ var onKeyDown = React.useMemo(function () {
16999
+ return function onKeyDown(event) {
17000
+ var key = event.key;
17001
+
17002
+ switch (key) {
17003
+ case KeyboardEvents.ArrowUp:
17004
+ event.preventDefault();
17005
+ focusSearchInput();
17006
+ break;
17007
+
17008
+ case KeyboardEvents.ArrowRight:
17009
+ event.preventDefault();
17010
+ focusNextElementSibling(getActiveElement());
17011
+ break;
17012
+
17013
+ case KeyboardEvents.ArrowLeft:
17014
+ event.preventDefault();
17015
+ focusPrevElementSibling(getActiveElement());
17016
+ break;
17017
+
17018
+ case KeyboardEvents.ArrowDown:
17019
+ event.preventDefault();
17020
+ focusFirstVisibleEmoji(BodyRef.current);
17021
+ break;
17022
+
17023
+ default:
17024
+ onType(event);
17025
+ break;
17026
+ }
17027
+ };
17028
+ }, [BodyRef, focusSearchInput, onType]);
17029
+ React.useEffect(function () {
17030
+ var current = CategoryNavigationRef.current;
17031
+
17032
+ if (!current) {
17033
+ return;
17034
+ }
17035
+
17036
+ current.addEventListener('keydown', onKeyDown);
17037
+ return function () {
17038
+ current.removeEventListener('keydown', onKeyDown);
17039
+ };
17040
+ }, [CategoryNavigationRef, BodyRef, onKeyDown]);
17041
+ }
17042
+
17043
+ function useBodyKeyboardEvents() {
17044
+ var BodyRef = useBodyRef();
17045
+ var goUpFromBody = useGoUpFromBody();
17046
+ var onType = useOnType();
17047
+ var onKeyDown = React.useMemo(function () {
17048
+ return function onKeyDown(event) {
17049
+ var key = event.key;
17050
+ var activeElement = buttonFromTarget(getActiveElement());
17051
+
17052
+ switch (key) {
17053
+ case KeyboardEvents.ArrowRight:
17054
+ event.preventDefault();
17055
+ focusNextVisibleEmoji(activeElement);
17056
+ break;
17057
+
17058
+ case KeyboardEvents.ArrowLeft:
17059
+ event.preventDefault();
17060
+ focusPrevVisibleEmoji(activeElement);
17061
+ break;
17062
+
17063
+ case KeyboardEvents.ArrowDown:
17064
+ event.preventDefault();
17065
+ focusVisibleEmojiOneRowDown(activeElement);
17066
+ break;
17067
+
17068
+ case KeyboardEvents.ArrowUp:
17069
+ event.preventDefault();
17070
+ focusVisibleEmojiOneRowUp(activeElement, goUpFromBody);
17071
+ break;
17072
+
17073
+ default:
17074
+ onType(event);
17075
+ break;
17076
+ }
17077
+ };
17078
+ }, [goUpFromBody, onType]);
17079
+ React.useEffect(function () {
17080
+ var current = BodyRef.current;
17081
+
17082
+ if (!current) {
17083
+ return;
17084
+ }
17085
+
17086
+ current.addEventListener('keydown', onKeyDown);
17087
+ return function () {
17088
+ current.removeEventListener('keydown', onKeyDown);
17089
+ };
17090
+ }, [BodyRef, onKeyDown]);
17091
+ }
17092
+
17093
+ function useGoDownFromSearchInput() {
17094
+ var focusCategoryNavigation = useFocusCategoryNavigation();
17095
+ var isSearchMode = useIsSearchMode();
17096
+ var BodyRef = useBodyRef();
17097
+ return React.useCallback(function goDownFromSearchInput() {
17098
+ if (isSearchMode) {
17099
+ return focusFirstVisibleEmoji(BodyRef.current);
17100
+ }
17101
+
17102
+ return focusCategoryNavigation();
17103
+ }, [BodyRef, focusCategoryNavigation, isSearchMode]);
17104
+ }
17105
+
17106
+ function useGoUpFromBody() {
17107
+ var focusSearchInput = useFocusSearchInput();
17108
+ var focusCategoryNavigation = useFocusCategoryNavigation();
17109
+ var isSearchMode = useIsSearchMode();
17110
+ return React.useCallback(function goUpFromEmoji() {
17111
+ if (isSearchMode) {
17112
+ return focusSearchInput();
17113
+ }
17114
+
17115
+ return focusCategoryNavigation();
17116
+ }, [focusSearchInput, isSearchMode, focusCategoryNavigation]);
17117
+ }
17118
+
17119
+ function focusNextSkinTone(exitLeft) {
17120
+ var currentSkinTone = getActiveElement();
17121
+
17122
+ if (!currentSkinTone) {
17123
+ return;
17124
+ }
17125
+
17126
+ if (!hasNextElementSibling(currentSkinTone)) {
17127
+ exitLeft();
17128
+ }
17129
+
17130
+ focusNextElementSibling(currentSkinTone);
17131
+ }
17132
+
17133
+ function focusPrevSkinTone() {
17134
+ var currentSkinTone = getActiveElement();
17135
+
17136
+ if (!currentSkinTone) {
17137
+ return;
17138
+ }
17139
+
17140
+ focusPrevElementSibling(currentSkinTone);
17141
+ }
17142
+
17143
+ function useOnType() {
17144
+ var appendSearch = useAppendSearch();
17145
+ var focusSearchInput = useFocusSearchInput();
17146
+ var closeAllOpenToggles = useCloseAllOpenToggles();
17147
+ return function onType(event) {
17148
+ var key = event.key;
17149
+
17150
+ if (hasModifier(event)) {
17151
+ return;
17152
+ }
17153
+
17154
+ if (key.match(/(^[a-zA-Z0-9]$){1}/)) {
17155
+ event.preventDefault();
17156
+ closeAllOpenToggles();
17157
+ focusSearchInput();
17158
+ appendSearch(key);
17159
+ }
17160
+ };
17161
+ }
17162
+
17163
+ function hasModifier(event) {
17164
+ var metaKey = event.metaKey,
17165
+ ctrlKey = event.ctrlKey,
17166
+ altKey = event.altKey;
17167
+ return metaKey || ctrlKey || altKey;
17168
+ }
17169
+
16355
17170
  function PickerMain(_ref) {
16356
17171
  var children = _ref.children;
16357
17172
  return React.createElement(PickerContextProvider, null, React.createElement(PickerRootElement, null, children));
@@ -16364,6 +17179,7 @@ function PickerRootElement(_ref2) {
16364
17179
  var theme = useThemeConfig();
16365
17180
  var searchModeActive = useIsSearchMode();
16366
17181
  var PickerMainRef = usePickerMainRef();
17182
+ useKeyboardNavigation();
16367
17183
  return React.createElement("aside", {
16368
17184
  className: clsx('EmojiPickerReact', 'epr-main', (_clsx = {}, _clsx[ClassNames.searchActive] = searchModeActive, _clsx['epr-dark-theme'] = theme === exports.Theme.DARK, _clsx)),
16369
17185
  ref: PickerMainRef
@@ -16396,6 +17212,7 @@ var ErrorBoundary = /*#__PURE__*/function (_React$Component) {
16396
17212
  var _proto = ErrorBoundary.prototype;
16397
17213
 
16398
17214
  _proto.componentDidCatch = function componentDidCatch(error, errorInfo) {
17215
+ // eslint-disable-next-line no-console
16399
17216
  console.error('Emoji Picker React failed to render:', error, errorInfo);
16400
17217
  };
16401
17218