emoji-picker-react 4.22.0 → 4.22.2
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.
- package/dist/emoji-picker-react.cjs.development.js +73 -16
- package/dist/emoji-picker-react.cjs.development.js.map +1 -1
- package/dist/emoji-picker-react.cjs.production.min.js +1 -1
- package/dist/emoji-picker-react.cjs.production.min.js.map +1 -1
- package/dist/emoji-picker-react.esm.js +73 -16
- package/dist/emoji-picker-react.esm.js.map +1 -1
- package/dist/hooks/useActiveCategoryScrollDetection.d.ts +8 -1
- package/llms.txt +7 -0
- package/package.json +1 -1
- package/src/components/context/PickerConfigContext.tsx +5 -1
- package/src/components/context/PickerDataContext.tsx +12 -7
- package/src/components/navigation/CategoryNavigation.tsx +8 -1
- package/src/config/compareConfig.ts +72 -0
- package/src/hooks/useActiveCategoryScrollDetection.ts +9 -1
|
@@ -172,7 +172,54 @@ 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 && customEmojisEqual(prevCustomEmojis, nextCustomEmojis) && categoriesEqual(prev.categories, next.categories) && prev.emojiData === next.emojiData;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Structural content equality for custom emojis. Length alone misses
|
|
179
|
+
* regroups and swaps, which would leave merged categories, search, and
|
|
180
|
+
* sections stale. Fields are compared element-wise (never serialized
|
|
181
|
+
* with delimiters) so user-controlled values cannot collide.
|
|
182
|
+
*/
|
|
183
|
+
function customEmojisEqual(prev, next) {
|
|
184
|
+
if (prev.length !== next.length) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
return prev.every(function (emoji, index) {
|
|
188
|
+
var _emoji$group, _other$group;
|
|
189
|
+
var other = next[index];
|
|
190
|
+
return emoji.id === other.id && ((_emoji$group = emoji.group) != null ? _emoji$group : '') === ((_other$group = other.group) != null ? _other$group : '') && emoji.imgUrl === other.imgUrl && emoji.names.length === other.names.length && emoji.names.every(function (name, nameIndex) {
|
|
191
|
+
return name === other.names[nameIndex];
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Structural content equality for the categories input. Order, labels,
|
|
197
|
+
* group selection, and icon identity all flow into the merged
|
|
198
|
+
* configuration. Icons compare by reference: swapping one icon element
|
|
199
|
+
* for another must rebuild, while a stable reference stays cheap.
|
|
200
|
+
*/
|
|
201
|
+
function categoriesEqual(prev, next) {
|
|
202
|
+
var prevEntries = prev != null ? prev : [];
|
|
203
|
+
var nextEntries = next != null ? next : [];
|
|
204
|
+
if (prevEntries.length !== nextEntries.length) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
return prevEntries.every(function (entry, index) {
|
|
208
|
+
return categoryEntriesEqual(entry, nextEntries[index]);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* One categories entry compared structurally. Icons compare by reference:
|
|
213
|
+
* swapping one icon element for another rebuilds, a stable reference stays
|
|
214
|
+
* cheap. Delimited serialization is avoided so user-controlled values
|
|
215
|
+
* cannot collide.
|
|
216
|
+
*/
|
|
217
|
+
function categoryEntriesEqual(entry, other) {
|
|
218
|
+
var _entry$group, _other$group2;
|
|
219
|
+
if (typeof entry === 'string' || typeof other === 'string') {
|
|
220
|
+
return entry === other;
|
|
221
|
+
}
|
|
222
|
+
return entry.category === other.category && entry.name === other.name && ((_entry$group = entry.group) != null ? _entry$group : '') === ((_other$group2 = other.group) != null ? _other$group2 : '') && entry.icon === other.icon;
|
|
176
223
|
}
|
|
177
224
|
|
|
178
225
|
var DEFAULT_REACTIONS = ['1f44d', '2764-fe0f', '1f603', '1f622', '1f64f', '1f44e', '1f621'];
|
|
@@ -556,7 +603,6 @@ function PickerConfigProvider(_ref) {
|
|
|
556
603
|
}, children);
|
|
557
604
|
}
|
|
558
605
|
function useSetConfig(config) {
|
|
559
|
-
var _config$customEmojis;
|
|
560
606
|
var _React$useState = useState(function () {
|
|
561
607
|
return mergeConfig(config);
|
|
562
608
|
}),
|
|
@@ -569,7 +615,11 @@ function useSetConfig(config) {
|
|
|
569
615
|
setMergedConfig(mergeConfig(config));
|
|
570
616
|
// not gonna...
|
|
571
617
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
572
|
-
}, [
|
|
618
|
+
}, [
|
|
619
|
+
// New references rebuild merged categories and data even at equal
|
|
620
|
+
// length; compareConfig above still gates no-op updates so inline
|
|
621
|
+
// literals don't loop.
|
|
622
|
+
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
623
|
return mergedConfig;
|
|
574
624
|
}
|
|
575
625
|
function usePickerConfig() {
|
|
@@ -26926,9 +26976,9 @@ function useIsMounted() {
|
|
|
26926
26976
|
var PickerDataContext = /*#__PURE__*/React__default.createContext({
|
|
26927
26977
|
emojiData: {},
|
|
26928
26978
|
allEmojis: [],
|
|
26929
|
-
allEmojisByUnified:
|
|
26930
|
-
searchIndex:
|
|
26931
|
-
customGroups:
|
|
26979
|
+
allEmojisByUnified: /*#__PURE__*/Object.create(null),
|
|
26980
|
+
searchIndex: /*#__PURE__*/Object.create(null),
|
|
26981
|
+
customGroups: /*#__PURE__*/Object.create(null),
|
|
26932
26982
|
emojiByUnified: emojiByUnified,
|
|
26933
26983
|
activeVariationFromUnified: function activeVariationFromUnified() {
|
|
26934
26984
|
return null;
|
|
@@ -26943,7 +26993,10 @@ function PickerDataProvider(_ref) {
|
|
|
26943
26993
|
var emojiData = genericEmojiData || defaultEmojiData;
|
|
26944
26994
|
// Clone to avoid mutation of shared source
|
|
26945
26995
|
var newData = JSON.parse(JSON.stringify(emojiData));
|
|
26946
|
-
|
|
26996
|
+
// Group names and emoji ids are user-controlled strings: use
|
|
26997
|
+
// null-prototype dictionaries so names like `__proto__` behave as
|
|
26998
|
+
// ordinary data instead of resolving Object.prototype members.
|
|
26999
|
+
var customGroups = Object.create(null);
|
|
26947
27000
|
if (customEmojis && customEmojis.length > 0) {
|
|
26948
27001
|
for (var _iterator = _createForOfIteratorHelperLoose(customEmojis), _step; !(_step = _iterator()).done;) {
|
|
26949
27002
|
var _customGroups$emoji$g;
|
|
@@ -26960,8 +27013,8 @@ function PickerDataProvider(_ref) {
|
|
|
26960
27013
|
}
|
|
26961
27014
|
var emojis = newData.emojis || {};
|
|
26962
27015
|
var allEmojis = Object.values(emojis).concat(Object.values(customGroups)).flat();
|
|
26963
|
-
var allEmojisByUnified =
|
|
26964
|
-
var searchIndex =
|
|
27016
|
+
var allEmojisByUnified = Object.create(null);
|
|
27017
|
+
var searchIndex = Object.create(null);
|
|
26965
27018
|
allEmojis.forEach(function (emoji) {
|
|
26966
27019
|
var unified = emoji[EmojiProperties.unified];
|
|
26967
27020
|
allEmojisByUnified[unified] = emoji;
|
|
@@ -26976,7 +27029,7 @@ function PickerDataProvider(_ref) {
|
|
|
26976
27029
|
var joinedNameString = (emoji[EmojiProperties.name] || []).join('').toLowerCase().split('');
|
|
26977
27030
|
joinedNameString.forEach(function (_char) {
|
|
26978
27031
|
var _searchIndex$_char;
|
|
26979
|
-
searchIndex[_char] = (_searchIndex$_char = searchIndex[_char]) != null ? _searchIndex$_char :
|
|
27032
|
+
searchIndex[_char] = (_searchIndex$_char = searchIndex[_char]) != null ? _searchIndex$_char : Object.create(null);
|
|
26980
27033
|
searchIndex[_char][unified] = emoji;
|
|
26981
27034
|
});
|
|
26982
27035
|
});
|
|
@@ -30506,7 +30559,8 @@ function categoryNameFromDom($category) {
|
|
|
30506
30559
|
|
|
30507
30560
|
function useActiveCategoryScrollDetection(_ref) {
|
|
30508
30561
|
var setActiveCategory = _ref.setActiveCategory,
|
|
30509
|
-
setVisibleCategories = _ref.setVisibleCategories
|
|
30562
|
+
setVisibleCategories = _ref.setVisibleCategories,
|
|
30563
|
+
categories = _ref.categories;
|
|
30510
30564
|
var BodyRef = useBodyRef();
|
|
30511
30565
|
useEffect(function () {
|
|
30512
30566
|
var visibleCategories = new Map();
|
|
@@ -30558,7 +30612,7 @@ function useActiveCategoryScrollDetection(_ref) {
|
|
|
30558
30612
|
return function () {
|
|
30559
30613
|
observer.disconnect();
|
|
30560
30614
|
};
|
|
30561
|
-
}, [BodyRef, setActiveCategory, setVisibleCategories]);
|
|
30615
|
+
}, [BodyRef, categories, setActiveCategory, setVisibleCategories]);
|
|
30562
30616
|
}
|
|
30563
30617
|
|
|
30564
30618
|
function useScrollCategoryIntoView() {
|
|
@@ -30944,10 +30998,6 @@ function CategoryNavigation() {
|
|
|
30944
30998
|
var _useVisibleCategories = useVisibleCategoriesState(),
|
|
30945
30999
|
setVisibleCategories = _useVisibleCategories[1];
|
|
30946
31000
|
var scrollCategoryIntoView = useScrollCategoryIntoView();
|
|
30947
|
-
useActiveCategoryScrollDetection({
|
|
30948
|
-
setActiveCategory: setActiveCategory,
|
|
30949
|
-
setVisibleCategories: setVisibleCategories
|
|
30950
|
-
});
|
|
30951
31001
|
var isSearchMode = useIsSearchMode();
|
|
30952
31002
|
var categoriesConfig = useCategoriesConfig();
|
|
30953
31003
|
var categoryIcons = useCategoryIconsConfig();
|
|
@@ -30956,6 +31006,13 @@ function CategoryNavigation() {
|
|
|
30956
31006
|
var _usePickerDataContext = usePickerDataContext(),
|
|
30957
31007
|
customGroups = _usePickerDataContext.customGroups,
|
|
30958
31008
|
emojiData = _usePickerDataContext.emojiData;
|
|
31009
|
+
// The observer re-subscribes when the merged categories reference
|
|
31010
|
+
// changes (sections added/removed); the reference is stable otherwise.
|
|
31011
|
+
useActiveCategoryScrollDetection({
|
|
31012
|
+
setActiveCategory: setActiveCategory,
|
|
31013
|
+
setVisibleCategories: setVisibleCategories,
|
|
31014
|
+
categories: categoriesConfig
|
|
31015
|
+
});
|
|
30959
31016
|
var visibleCategories = categoriesConfig.filter(function (categoryConfig) {
|
|
30960
31017
|
if (isCustomCategory(categoryConfig) && hideCustomCategory) {
|
|
30961
31018
|
return false;
|