emoji-picker-react 4.14.0-rc.1 → 4.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,7 @@ export declare function useIsPastInitialLoad(): boolean;
18
18
  export declare function useEmojiVariationPickerState(): ReactState<DataEmoji | null>;
19
19
  export declare function useSkinToneFanOpenState(): ReactState<boolean>;
20
20
  export declare function useDisallowedEmojisRef(): React.MutableRefObject<Record<string, boolean>>;
21
+ export declare function useVisibleCategoriesState(): ReactState<string[]>;
21
22
  export declare function useUpdateSuggested(): [number, () => void];
22
23
  export declare type FilterState = Record<string, FilterDict>;
23
24
  export {};
@@ -339,6 +339,7 @@ function PickerContextProvider(_ref) {
339
339
  var _useState = React.useState(false),
340
340
  isPastInitialLoad = _useState[0],
341
341
  setIsPastInitialLoad = _useState[1];
342
+ var visibleCategoriesState = React.useState([]);
342
343
  useMarkInitialLoad(setIsPastInitialLoad);
343
344
  return React.createElement(PickerContext.Provider, {
344
345
  value: {
@@ -354,7 +355,8 @@ function PickerContextProvider(_ref) {
354
355
  searchTerm: searchTerm,
355
356
  skinToneFanOpenState: skinToneFanOpenState,
356
357
  suggestedUpdateState: suggestedUpdateState,
357
- reactionsModeState: reactionsModeState
358
+ reactionsModeState: reactionsModeState,
359
+ visibleCategoriesState: visibleCategoriesState
358
360
  }
359
361
  }, children);
360
362
  }
@@ -383,7 +385,10 @@ var PickerContext = /*#__PURE__*/React.createContext({
383
385
  }],
384
386
  skinToneFanOpenState: [false, function () {}],
385
387
  suggestedUpdateState: [/*#__PURE__*/Date.now(), function () {}],
386
- reactionsModeState: [false, function () {}]
388
+ reactionsModeState: [false, function () {}],
389
+ visibleCategoriesState: [[], function () {
390
+ return [];
391
+ }]
387
392
  });
388
393
  function useFilterRef() {
389
394
  var _React$useContext = React.useContext(PickerContext),
@@ -430,9 +435,14 @@ function useSkinToneFanOpenState() {
430
435
  skinToneFanOpenState = _React$useContext10.skinToneFanOpenState;
431
436
  return skinToneFanOpenState;
432
437
  }
433
- function useUpdateSuggested() {
438
+ function useVisibleCategoriesState() {
434
439
  var _React$useContext12 = React.useContext(PickerContext),
435
- suggestedUpdateState = _React$useContext12.suggestedUpdateState;
440
+ visibleCategoriesState = _React$useContext12.visibleCategoriesState;
441
+ return visibleCategoriesState;
442
+ }
443
+ function useUpdateSuggested() {
444
+ var _React$useContext13 = React.useContext(PickerContext),
445
+ suggestedUpdateState = _React$useContext13.suggestedUpdateState;
436
446
  var suggestedUpdated = suggestedUpdateState[0],
437
447
  setsuggestedUpdate = suggestedUpdateState[1];
438
448
  return [suggestedUpdated, function updateSuggested() {
@@ -18695,22 +18705,44 @@ function hasModifier(event) {
18695
18705
  return metaKey || ctrlKey || altKey;
18696
18706
  }
18697
18707
 
18698
- function preloadEmoji(getEmojiUrl, emoji, emojiStyle) {
18708
+ // eslint-disable-next-line max-params
18709
+ function preloadEmojiIfNeeded(emoji, emojiStyles, scrollTop, clientHeight, topOffset, style, dimensions, getEmojiUrl) {
18699
18710
  if (!emoji) {
18700
18711
  return;
18701
18712
  }
18702
- if (emojiStyle === exports.EmojiStyle.NATIVE) {
18713
+ if (emojiStyles === exports.EmojiStyle.NATIVE) {
18703
18714
  return;
18704
18715
  }
18705
18716
  var unified = emojiUnified(emoji);
18706
18717
  if (preloadedEmojs.has(unified)) {
18707
18718
  return;
18708
18719
  }
18709
- emojiVariations(emoji).forEach(function (variation) {
18720
+ // preload only if the emoji is a few rows below the viewport
18721
+ if (!style || !dimensions) {
18722
+ return;
18723
+ }
18724
+ setTimeout(function () {
18725
+ var emojiTop = topOffset + style.top;
18726
+ var viewportBottom = scrollTop + clientHeight;
18727
+ var isJustBelowViewport = emojiTop >= viewportBottom && emojiTop < viewportBottom + dimensions.emojiSize * 2;
18728
+ if (isJustBelowViewport) {
18729
+ preloadEmoji(getEmojiUrl, emoji, emojiStyles);
18730
+ }
18731
+ });
18732
+ }
18733
+ function preloadEmoji(getEmojiUrl, emoji, emojiStyle) {
18734
+ if (!emoji) {
18735
+ return;
18736
+ }
18737
+ var unified = emojiUnified(emoji);
18738
+ if (preloadedEmojs.has(unified)) {
18739
+ return;
18740
+ }
18741
+ preloadedEmojs.add(unified);
18742
+ emojiVariations(emoji).concat(unified).forEach(function (variation) {
18710
18743
  var emojiUrl = getEmojiUrl(variation, emojiStyle);
18711
18744
  preloadImage(emojiUrl);
18712
18745
  });
18713
- preloadedEmojs.add(unified);
18714
18746
  }
18715
18747
  var preloadedEmojs = /*#__PURE__*/new Set();
18716
18748
  function preloadImage(url) {
@@ -19706,6 +19738,27 @@ function useOnScroll(BodyRef) {
19706
19738
  return scrollTop;
19707
19739
  }
19708
19740
 
19741
+ function shouldVirtualize(_ref) {
19742
+ var scrollTop = _ref.scrollTop,
19743
+ clientHeight = _ref.clientHeight,
19744
+ topOffset = _ref.topOffset,
19745
+ style = _ref.style,
19746
+ dimensions = _ref.dimensions;
19747
+ if (!style || !dimensions) {
19748
+ return false;
19749
+ }
19750
+ var emojiTop = topOffset + style.top;
19751
+ var emojiBottom = emojiTop + dimensions.emojiSize;
19752
+ var isVisible = emojiBottom + dimensions.emojiSize * 2 >= scrollTop && emojiTop <= scrollTop + clientHeight + dimensions.emojiSize;
19753
+ return !isVisible;
19754
+ }
19755
+ function getEmojiPositionStyle(dimensions, index) {
19756
+ return dimensions ? {
19757
+ top: Math.floor(index / dimensions.emojisPerRow) * dimensions.emojiSize,
19758
+ left: index % dimensions.emojisPerRow * dimensions.emojiSize
19759
+ } : undefined;
19760
+ }
19761
+
19709
19762
  var EMOJI_SIZE_DEFAULT = 32;
19710
19763
  function useCategoryHeight(emojiCount) {
19711
19764
  var EmojiListRef = useEmojiListRef();
@@ -19713,6 +19766,8 @@ function useCategoryHeight(emojiCount) {
19713
19766
  isReactionsMode = _useReactionsModeStat[0];
19714
19767
  var PickerMainRef = usePickerMainRef();
19715
19768
  var emojiSizeRef = React.useRef();
19769
+ var _useVisibleCategories = useVisibleCategoriesState(),
19770
+ visibleCategories = _useVisibleCategories[0];
19716
19771
  var _React$useState = React.useState(),
19717
19772
  dimensions = _React$useState[0],
19718
19773
  setDimensions = _React$useState[1];
@@ -19739,7 +19794,7 @@ function useCategoryHeight(emojiCount) {
19739
19794
  // Recompute on data-count changes and when reactions mode toggles
19740
19795
  React.useEffect(function () {
19741
19796
  computeAndSetDimensions();
19742
- }, [emojiCount, isReactionsMode, computeAndSetDimensions]);
19797
+ }, [emojiCount, isReactionsMode, computeAndSetDimensions, visibleCategories.length]);
19743
19798
  // Listen to transitionend on the picker root (where height transition occurs)
19744
19799
  React.useEffect(function () {
19745
19800
  var rootEl = PickerMainRef.current;
@@ -19785,6 +19840,76 @@ function useIsEmojiHidden() {
19785
19840
  };
19786
19841
  }
19787
19842
 
19843
+ function useEmojiVirtualization(_ref) {
19844
+ var categoryEmojis = _ref.categoryEmojis,
19845
+ topOffset = _ref.topOffset,
19846
+ onHeightReady = _ref.onHeightReady,
19847
+ scrollTop = _ref.scrollTop,
19848
+ isCategoryVisible = _ref.isCategoryVisible;
19849
+ var isEmojiHidden = useIsEmojiHidden();
19850
+ var lazyLoadEmojis = useLazyLoadEmojisConfig();
19851
+ var emojiStyle = useEmojiStyleConfig();
19852
+ var _useActiveSkinToneSta = useActiveSkinToneState(),
19853
+ activeSkinTone = _useActiveSkinToneSta[0];
19854
+ var isEmojiDisallowed = useIsEmojiDisallowed();
19855
+ var getEmojiUrl = useGetEmojiUrlConfig();
19856
+ var showVariations = !useSkinTonesDisabledConfig();
19857
+ var BodyRef = useBodyRef();
19858
+ var virtualizedCounter = 0;
19859
+ var emojisToPush = categoryEmojis.filter(function (emoji) {
19860
+ var isDisallowed = isEmojiDisallowed(emoji);
19861
+ var _isEmojiHidden = isEmojiHidden(emoji),
19862
+ failedToLoad = _isEmojiHidden.failedToLoad,
19863
+ filteredOut = _isEmojiHidden.filteredOut,
19864
+ hidden = _isEmojiHidden.hidden;
19865
+ return !failedToLoad && !filteredOut && !hidden && !isDisallowed;
19866
+ });
19867
+ var dimensions = useCategoryHeight(emojisToPush.length);
19868
+ React.useEffect(function () {
19869
+ if (dimensions) {
19870
+ onHeightReady(dimensions.categoryHeight);
19871
+ }
19872
+ }, [dimensions, onHeightReady, emojisToPush.length]);
19873
+ var emojis = emojisToPush.reduce(function (accumulator, emoji, index) {
19874
+ var _BodyRef$current$clie, _BodyRef$current;
19875
+ var unified = emojiUnified(emoji, activeSkinTone);
19876
+ var style = getEmojiPositionStyle(dimensions, index);
19877
+ if (dimensions && BodyRef.current && shouldVirtualize({
19878
+ scrollTop: scrollTop,
19879
+ clientHeight: (_BodyRef$current$clie = (_BodyRef$current = BodyRef.current) == null ? void 0 : _BodyRef$current.clientHeight) != null ? _BodyRef$current$clie : 0,
19880
+ topOffset: topOffset,
19881
+ style: style,
19882
+ dimensions: dimensions
19883
+ })) {
19884
+ var _BodyRef$current$clie2, _BodyRef$current2;
19885
+ virtualizedCounter++;
19886
+ preloadEmojiIfNeeded(emoji, emojiStyle, scrollTop, (_BodyRef$current$clie2 = (_BodyRef$current2 = BodyRef.current) == null ? void 0 : _BodyRef$current2.clientHeight) != null ? _BodyRef$current$clie2 : 0, topOffset, style, dimensions, getEmojiUrl);
19887
+ return accumulator;
19888
+ }
19889
+ if (!isCategoryVisible) {
19890
+ return accumulator;
19891
+ }
19892
+ accumulator.push(React.createElement(ClickableEmoji, {
19893
+ showVariations: showVariations,
19894
+ key: unified,
19895
+ emoji: emoji,
19896
+ unified: unified,
19897
+ emojiStyle: emojiStyle,
19898
+ lazyLoad: lazyLoadEmojis,
19899
+ getEmojiUrl: getEmojiUrl,
19900
+ style: _extends({}, style, {
19901
+ position: 'absolute'
19902
+ })
19903
+ }));
19904
+ return accumulator;
19905
+ }, []);
19906
+ return {
19907
+ virtualizedCounter: virtualizedCounter,
19908
+ emojis: emojis,
19909
+ dimensions: dimensions
19910
+ };
19911
+ }
19912
+
19788
19913
  function EmojiCategory(_ref) {
19789
19914
  var categoryConfig = _ref.categoryConfig,
19790
19915
  children = _ref.children,
@@ -19885,77 +20010,24 @@ function RenderCategory(_ref2) {
19885
20010
  topOffset = _ref2.topOffset,
19886
20011
  onHeightReady = _ref2.onHeightReady,
19887
20012
  scrollTop = _ref2.scrollTop;
19888
- var isEmojiHidden = useIsEmojiHidden();
19889
- var lazyLoadEmojis = useLazyLoadEmojisConfig();
19890
- var emojiStyle = useEmojiStyleConfig();
19891
- var _useActiveSkinToneSta = useActiveSkinToneState(),
19892
- activeSkinTone = _useActiveSkinToneSta[0];
19893
- var isEmojiDisallowed = useIsEmojiDisallowed();
19894
- var getEmojiUrl = useGetEmojiUrlConfig();
19895
- var showVariations = !useSkinTonesDisabledConfig();
19896
- var BodyRef = useBodyRef();
19897
- var hiddenCounter = 0;
19898
- var virtualizedCounter = 0;
19899
- var emojisToPush = categoryEmojis.filter(function (emoji) {
19900
- var _isEmojiHidden = isEmojiHidden(emoji),
19901
- failedToLoad = _isEmojiHidden.failedToLoad,
19902
- filteredOut = _isEmojiHidden.filteredOut,
19903
- hidden = _isEmojiHidden.hidden;
19904
- return !failedToLoad && !filteredOut && !hidden;
19905
- });
19906
- var dimensions = useCategoryHeight(emojisToPush.length);
19907
- React.useEffect(function () {
19908
- if (dimensions) {
19909
- onHeightReady(dimensions.categoryHeight);
19910
- }
19911
- }, [dimensions, onHeightReady, emojisToPush.length]);
19912
- var emojis = emojisToPush.reduce(function (accumulator, emoji, index) {
19913
- var _BodyRef$current$clie, _BodyRef$current;
19914
- var unified = emojiUnified(emoji, activeSkinTone);
19915
- var _isEmojiHidden2 = isEmojiHidden(emoji),
19916
- failedToLoad = _isEmojiHidden2.failedToLoad,
19917
- filteredOut = _isEmojiHidden2.filteredOut,
19918
- hidden = _isEmojiHidden2.hidden;
19919
- var isDisallowed = isEmojiDisallowed(emoji);
19920
- if (hidden || isDisallowed) {
19921
- hiddenCounter++;
19922
- }
19923
- if (isDisallowed || failedToLoad || filteredOut) {
19924
- return accumulator;
19925
- }
19926
- var style = getEmojiPositionStyle(dimensions, index - hiddenCounter);
19927
- if (shouldVirtualize({
19928
- scrollTop: scrollTop,
19929
- clientHeight: (_BodyRef$current$clie = (_BodyRef$current = BodyRef.current) == null ? void 0 : _BodyRef$current.clientHeight) != null ? _BodyRef$current$clie : 0,
20013
+ var _useVisibleCategories = useVisibleCategoriesState(),
20014
+ visibleCategroies = _useVisibleCategories[0];
20015
+ var _useEmojiVirtualizati = useEmojiVirtualization({
20016
+ categoryEmojis: categoryEmojis,
19930
20017
  topOffset: topOffset,
19931
- style: style,
19932
- dimensions: dimensions
19933
- })) {
19934
- virtualizedCounter++;
19935
- return accumulator;
19936
- }
19937
- accumulator.push(React.createElement(ClickableEmoji, {
19938
- showVariations: showVariations,
19939
- key: unified,
19940
- emoji: emoji,
19941
- unified: unified,
19942
- hidden: failedToLoad,
19943
- hiddenOnSearch: filteredOut,
19944
- emojiStyle: emojiStyle,
19945
- lazyLoad: lazyLoadEmojis,
19946
- getEmojiUrl: getEmojiUrl,
19947
- style: _extends({}, style, {
19948
- position: 'absolute'
19949
- })
19950
- }));
19951
- return accumulator;
19952
- }, []);
20018
+ onHeightReady: onHeightReady,
20019
+ scrollTop: scrollTop,
20020
+ isCategoryVisible: visibleCategroies.includes(categoryConfig.category)
20021
+ }),
20022
+ virtualizedCounter = _useEmojiVirtualizati.virtualizedCounter,
20023
+ emojis = _useEmojiVirtualizati.emojis,
20024
+ dimensions = _useEmojiVirtualizati.dimensions;
19953
20025
  return React.createElement(EmojiCategory, {
19954
20026
  categoryConfig: categoryConfig,
19955
20027
  height: dimensions == null ? void 0 : dimensions.categoryHeight,
19956
20028
  // Indicates that there are no visible emojis
19957
20029
  // Hence, the category should be hidden
19958
- hidden: hiddenCounter === emojis.length && virtualizedCounter === 0
20030
+ hidden: !emojis.length && virtualizedCounter === 0
19959
20031
  }, emojis);
19960
20032
  }
19961
20033
  var styles$8 = /*#__PURE__*/stylesheet.create({
@@ -19966,26 +20038,6 @@ var styles$8 = /*#__PURE__*/stylesheet.create({
19966
20038
  padding: '0'
19967
20039
  }
19968
20040
  });
19969
- function getEmojiPositionStyle(dimensions, index) {
19970
- return dimensions ? {
19971
- top: Math.floor(index / dimensions.emojisPerRow) * dimensions.emojiSize,
19972
- left: index % dimensions.emojisPerRow * dimensions.emojiSize
19973
- } : undefined;
19974
- }
19975
- function shouldVirtualize(_ref3) {
19976
- var scrollTop = _ref3.scrollTop,
19977
- clientHeight = _ref3.clientHeight,
19978
- topOffset = _ref3.topOffset,
19979
- style = _ref3.style,
19980
- dimensions = _ref3.dimensions;
19981
- if (!style || !dimensions) {
19982
- return false;
19983
- }
19984
- var emojiTop = topOffset + style.top;
19985
- var emojiBottom = emojiTop + dimensions.emojiSize;
19986
- var isVisible = emojiBottom + dimensions.emojiSize * 2 >= scrollTop && emojiTop <= scrollTop + clientHeight + dimensions.emojiSize;
19987
- return !isVisible;
19988
- }
19989
20041
 
19990
20042
  var SVGTriangle = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI2LjMuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI1MHB4IgoJIGhlaWdodD0iMTVweCIgdmlld0JveD0iMCAwIDUwIDE1IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MCAxNSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnIGlkPSJMYXllcl8xIj4KPC9nPgo8ZyBpZD0iTGF5ZXJfMiI+Cgk8cGF0aCBmaWxsPSIjRkZGRkZGIiBzdHJva2U9IiNFOEU3RTciIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgZD0iTTEuODYtMC40M2w5LjgzLDExLjUzYzAuNTksMC42OSwxLjU2LDAuNjksMi4xNCwwbDkuODMtMTEuNTMiLz4KCTxwYXRoIGZpbGw9IiMwMTAyMDIiIHN0cm9rZT0iIzE1MTYxNyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBkPSJNMjYuODYtMC40M2w5LjgzLDExLjUzYzAuNTksMC42OSwxLjU2LDAuNjksMi4xNCwwbDkuODMtMTEuNTMiLz4KPC9nPgo8L3N2Zz4=';
19991
20043
 
@@ -20591,7 +20643,9 @@ function categoryNameFromDom($category) {
20591
20643
  return (_$category$getAttribu = $category == null ? void 0 : $category.getAttribute('data-name')) != null ? _$category$getAttribu : null;
20592
20644
  }
20593
20645
 
20594
- function useActiveCategoryScrollDetection(setActiveCategory) {
20646
+ function useActiveCategoryScrollDetection(_ref) {
20647
+ var setActiveCategory = _ref.setActiveCategory,
20648
+ setVisibleCategories = _ref.setVisibleCategories;
20595
20649
  var BodyRef = useBodyRef();
20596
20650
  React.useEffect(function () {
20597
20651
  var visibleCategories = new Map();
@@ -20603,9 +20657,19 @@ function useActiveCategoryScrollDetection(setActiveCategory) {
20603
20657
  for (var _iterator = _createForOfIteratorHelperLoose(entries), _step; !(_step = _iterator()).done;) {
20604
20658
  var entry = _step.value;
20605
20659
  var _id = categoryNameFromDom(entry.target);
20660
+ if (!_id) {
20661
+ continue;
20662
+ }
20606
20663
  visibleCategories.set(_id, entry.intersectionRatio);
20607
20664
  }
20608
20665
  var ratios = Array.from(visibleCategories);
20666
+ setVisibleCategories(ratios.filter(function (_ref2) {
20667
+ var ratio = _ref2[1];
20668
+ return ratio > 0;
20669
+ }).map(function (_ref3) {
20670
+ var id = _ref3[0];
20671
+ return id;
20672
+ }));
20609
20673
  var lastCategory = ratios[ratios.length - 1];
20610
20674
  if (lastCategory[1] == 1) {
20611
20675
  return setActiveCategory(lastCategory[0]);
@@ -20625,7 +20689,7 @@ function useActiveCategoryScrollDetection(setActiveCategory) {
20625
20689
  bodyRef == null ? void 0 : bodyRef.querySelectorAll(asSelectors(ClassNames.category)).forEach(function (el) {
20626
20690
  observer.observe(el);
20627
20691
  });
20628
- }, [BodyRef, setActiveCategory]);
20692
+ }, [BodyRef, setActiveCategory, setVisibleCategories]);
20629
20693
  }
20630
20694
 
20631
20695
  function useScrollCategoryIntoView() {
@@ -20748,8 +20812,13 @@ function CategoryNavigation() {
20748
20812
  var _useState = React.useState(null),
20749
20813
  activeCategory = _useState[0],
20750
20814
  setActiveCategory = _useState[1];
20815
+ var _useVisibleCategories = useVisibleCategoriesState(),
20816
+ setVisibleCategories = _useVisibleCategories[1];
20751
20817
  var scrollCategoryIntoView = useScrollCategoryIntoView();
20752
- useActiveCategoryScrollDetection(setActiveCategory);
20818
+ useActiveCategoryScrollDetection({
20819
+ setActiveCategory: setActiveCategory,
20820
+ setVisibleCategories: setVisibleCategories
20821
+ });
20753
20822
  var isSearchMode = useIsSearchMode();
20754
20823
  var categoriesConfig = useCategoriesConfig();
20755
20824
  var CategoryNavigationRef = useCategoryNavigationRef();