emoji-picker-react 4.22.0 → 4.22.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.
@@ -172,7 +172,27 @@ function compareConfig(prev, next) {
172
172
  var _prev$customEmojis, _next$customEmojis;
173
173
  var prevCustomEmojis = (_prev$customEmojis = prev.customEmojis) != null ? _prev$customEmojis : [];
174
174
  var nextCustomEmojis = (_next$customEmojis = next.customEmojis) != null ? _next$customEmojis : [];
175
- return prev.open === next.open && prev.emojiVersion === next.emojiVersion && prev.reactionsDefaultOpen === next.reactionsDefaultOpen && prev.searchPlaceHolder === next.searchPlaceHolder && prev.searchPlaceholder === next.searchPlaceholder && prev.searchClearButtonLabel === next.searchClearButtonLabel && prev.defaultSkinTone === next.defaultSkinTone && prev.skinTonesDisabled === next.skinTonesDisabled && prev.autoFocusSearch === next.autoFocusSearch && prev.emojiStyle === next.emojiStyle && prev.theme === next.theme && prev.suggestedEmojisMode === next.suggestedEmojisMode && prev.lazyLoadEmojis === next.lazyLoadEmojis && prev.className === next.className && prev.height === next.height && prev.width === next.width && prev.style === next.style && prev.searchDisabled === next.searchDisabled && prev.skinTonePickerLocation === next.skinTonePickerLocation && prevCustomEmojis.length === nextCustomEmojis.length && prev.emojiData === next.emojiData;
175
+ return prev.open === next.open && prev.emojiVersion === next.emojiVersion && prev.reactionsDefaultOpen === next.reactionsDefaultOpen && prev.searchPlaceHolder === next.searchPlaceHolder && prev.searchPlaceholder === next.searchPlaceholder && prev.searchClearButtonLabel === next.searchClearButtonLabel && prev.defaultSkinTone === next.defaultSkinTone && prev.skinTonesDisabled === next.skinTonesDisabled && prev.autoFocusSearch === next.autoFocusSearch && prev.emojiStyle === next.emojiStyle && prev.theme === next.theme && prev.suggestedEmojisMode === next.suggestedEmojisMode && prev.lazyLoadEmojis === next.lazyLoadEmojis && prev.className === next.className && prev.height === next.height && prev.width === next.width && prev.style === next.style && prev.searchDisabled === next.searchDisabled && prev.skinTonePickerLocation === next.skinTonePickerLocation && prevCustomEmojis.length === nextCustomEmojis.length && customEmojisKey(prevCustomEmojis) === customEmojisKey(nextCustomEmojis) && categoriesKey(prev.categories) === categoriesKey(next.categories) && prev.emojiData === next.emojiData;
176
+ }
177
+ /**
178
+ * Content identity for custom emojis. Length alone misses regroups and
179
+ * swaps, which would leave merged categories, search, and sections stale.
180
+ */
181
+ function customEmojisKey(customEmojis) {
182
+ return customEmojis.map(function (emoji) {
183
+ var _emoji$group;
184
+ return emoji.id + ":" + ((_emoji$group = emoji.group) != null ? _emoji$group : '') + ":" + emoji.names.join(',') + ":" + emoji.imgUrl;
185
+ }).join('|');
186
+ }
187
+ /**
188
+ * Content identity for the categories input. Order, labels, icons, and
189
+ * group selection all flow into the merged configuration.
190
+ */
191
+ function categoriesKey(categories) {
192
+ return (categories != null ? categories : []).map(function (entry) {
193
+ var _entry$group;
194
+ return typeof entry === 'string' ? entry : entry.category + ":" + entry.name + ":" + ((_entry$group = entry.group) != null ? _entry$group : '') + ":" + (entry.icon ? '1' : '');
195
+ }).join('|');
176
196
  }
177
197
 
178
198
  var DEFAULT_REACTIONS = ['1f44d', '2764-fe0f', '1f603', '1f622', '1f64f', '1f44e', '1f621'];
@@ -556,7 +576,6 @@ function PickerConfigProvider(_ref) {
556
576
  }, children);
557
577
  }
558
578
  function useSetConfig(config) {
559
- var _config$customEmojis;
560
579
  var _React$useState = useState(function () {
561
580
  return mergeConfig(config);
562
581
  }),
@@ -569,7 +588,11 @@ function useSetConfig(config) {
569
588
  setMergedConfig(mergeConfig(config));
570
589
  // not gonna...
571
590
  // eslint-disable-next-line react-hooks/exhaustive-deps
572
- }, [(_config$customEmojis = config.customEmojis) == null ? void 0 : _config$customEmojis.length, config.open, config.emojiVersion, config.reactionsDefaultOpen, config.searchPlaceHolder, config.searchPlaceholder, config.searchClearButtonLabel, config.defaultSkinTone, config.skinTonesDisabled, config.autoFocusSearch, config.emojiStyle, config.theme, config.suggestedEmojisMode, config.lazyLoadEmojis, config.className, config.height, config.width, config.searchDisabled, config.skinTonePickerLocation, config.allowExpandReactions, config.emojiData]);
591
+ }, [
592
+ // New references rebuild merged categories and data even at equal
593
+ // length; compareConfig above still gates no-op updates so inline
594
+ // literals don't loop.
595
+ config.categories, config.customEmojis, config.open, config.emojiVersion, config.reactionsDefaultOpen, config.searchPlaceHolder, config.searchPlaceholder, config.searchClearButtonLabel, config.defaultSkinTone, config.skinTonesDisabled, config.autoFocusSearch, config.emojiStyle, config.theme, config.suggestedEmojisMode, config.lazyLoadEmojis, config.className, config.height, config.width, config.searchDisabled, config.skinTonePickerLocation, config.allowExpandReactions, config.emojiData]);
573
596
  return mergedConfig;
574
597
  }
575
598
  function usePickerConfig() {
@@ -26926,9 +26949,9 @@ function useIsMounted() {
26926
26949
  var PickerDataContext = /*#__PURE__*/React__default.createContext({
26927
26950
  emojiData: {},
26928
26951
  allEmojis: [],
26929
- allEmojisByUnified: {},
26930
- searchIndex: {},
26931
- customGroups: {},
26952
+ allEmojisByUnified: /*#__PURE__*/Object.create(null),
26953
+ searchIndex: /*#__PURE__*/Object.create(null),
26954
+ customGroups: /*#__PURE__*/Object.create(null),
26932
26955
  emojiByUnified: emojiByUnified,
26933
26956
  activeVariationFromUnified: function activeVariationFromUnified() {
26934
26957
  return null;
@@ -26943,7 +26966,10 @@ function PickerDataProvider(_ref) {
26943
26966
  var emojiData = genericEmojiData || defaultEmojiData;
26944
26967
  // Clone to avoid mutation of shared source
26945
26968
  var newData = JSON.parse(JSON.stringify(emojiData));
26946
- var customGroups = {};
26969
+ // Group names and emoji ids are user-controlled strings: use
26970
+ // null-prototype dictionaries so names like `__proto__` behave as
26971
+ // ordinary data instead of resolving Object.prototype members.
26972
+ var customGroups = Object.create(null);
26947
26973
  if (customEmojis && customEmojis.length > 0) {
26948
26974
  for (var _iterator = _createForOfIteratorHelperLoose(customEmojis), _step; !(_step = _iterator()).done;) {
26949
26975
  var _customGroups$emoji$g;
@@ -26960,8 +26986,8 @@ function PickerDataProvider(_ref) {
26960
26986
  }
26961
26987
  var emojis = newData.emojis || {};
26962
26988
  var allEmojis = Object.values(emojis).concat(Object.values(customGroups)).flat();
26963
- var allEmojisByUnified = {};
26964
- var searchIndex = {};
26989
+ var allEmojisByUnified = Object.create(null);
26990
+ var searchIndex = Object.create(null);
26965
26991
  allEmojis.forEach(function (emoji) {
26966
26992
  var unified = emoji[EmojiProperties.unified];
26967
26993
  allEmojisByUnified[unified] = emoji;
@@ -26976,7 +27002,7 @@ function PickerDataProvider(_ref) {
26976
27002
  var joinedNameString = (emoji[EmojiProperties.name] || []).join('').toLowerCase().split('');
26977
27003
  joinedNameString.forEach(function (_char) {
26978
27004
  var _searchIndex$_char;
26979
- searchIndex[_char] = (_searchIndex$_char = searchIndex[_char]) != null ? _searchIndex$_char : {};
27005
+ searchIndex[_char] = (_searchIndex$_char = searchIndex[_char]) != null ? _searchIndex$_char : Object.create(null);
26980
27006
  searchIndex[_char][unified] = emoji;
26981
27007
  });
26982
27008
  });
@@ -30506,7 +30532,8 @@ function categoryNameFromDom($category) {
30506
30532
 
30507
30533
  function useActiveCategoryScrollDetection(_ref) {
30508
30534
  var setActiveCategory = _ref.setActiveCategory,
30509
- setVisibleCategories = _ref.setVisibleCategories;
30535
+ setVisibleCategories = _ref.setVisibleCategories,
30536
+ categoryIdentitiesKey = _ref.categoryIdentitiesKey;
30510
30537
  var BodyRef = useBodyRef();
30511
30538
  useEffect(function () {
30512
30539
  var visibleCategories = new Map();
@@ -30558,7 +30585,7 @@ function useActiveCategoryScrollDetection(_ref) {
30558
30585
  return function () {
30559
30586
  observer.disconnect();
30560
30587
  };
30561
- }, [BodyRef, setActiveCategory, setVisibleCategories]);
30588
+ }, [BodyRef, categoryIdentitiesKey, setActiveCategory, setVisibleCategories]);
30562
30589
  }
30563
30590
 
30564
30591
  function useScrollCategoryIntoView() {
@@ -30944,10 +30971,6 @@ function CategoryNavigation() {
30944
30971
  var _useVisibleCategories = useVisibleCategoriesState(),
30945
30972
  setVisibleCategories = _useVisibleCategories[1];
30946
30973
  var scrollCategoryIntoView = useScrollCategoryIntoView();
30947
- useActiveCategoryScrollDetection({
30948
- setActiveCategory: setActiveCategory,
30949
- setVisibleCategories: setVisibleCategories
30950
- });
30951
30974
  var isSearchMode = useIsSearchMode();
30952
30975
  var categoriesConfig = useCategoriesConfig();
30953
30976
  var categoryIcons = useCategoryIconsConfig();
@@ -30956,6 +30979,17 @@ function CategoryNavigation() {
30956
30979
  var _usePickerDataContext = usePickerDataContext(),
30957
30980
  customGroups = _usePickerDataContext.customGroups,
30958
30981
  emojiData = _usePickerDataContext.emojiData;
30982
+ // Rendered section identities. Passed to the scroll-detection hook so
30983
+ // added/removed sections are (re-)subscribed; stable across renders
30984
+ // unless the effective category list changes.
30985
+ var categoryIdentitiesKey = categoriesConfig.map(function (entry) {
30986
+ return categoryIdFromCategoryConfig(entry);
30987
+ }).join('|');
30988
+ useActiveCategoryScrollDetection({
30989
+ setActiveCategory: setActiveCategory,
30990
+ setVisibleCategories: setVisibleCategories,
30991
+ categoryIdentitiesKey: categoryIdentitiesKey
30992
+ });
30959
30993
  var visibleCategories = categoriesConfig.filter(function (categoryConfig) {
30960
30994
  if (isCustomCategory(categoryConfig) && hideCustomCategory) {
30961
30995
  return false;