emoji-picker-react 4.21.1 → 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.
- package/dist/components/context/PickerDataContext.d.ts +2 -1
- package/dist/config/categoryConfig.d.ts +19 -1
- package/dist/config/customEmojiConfig.d.ts +8 -0
- package/dist/emoji-picker-react.cjs.development.js +180 -42
- 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 +180 -42
- package/dist/emoji-picker-react.esm.js.map +1 -1
- package/dist/hooks/useActiveCategoryScrollDetection.d.ts +8 -1
- package/dist/types/exposedTypes.d.ts +6 -0
- package/llms.txt +38 -1
- package/package.json +1 -1
- package/src/components/body/EmojiCategory.tsx +2 -3
- package/src/components/body/EmojiList.tsx +16 -7
- package/src/components/body/MeasureEmoji.tsx +10 -4
- package/src/components/context/PickerConfigContext.tsx +5 -1
- package/src/components/context/PickerDataContext.tsx +38 -10
- package/src/components/navigation/CategoryNavigation.tsx +38 -10
- package/src/config/categoryConfig.ts +97 -5
- package/src/config/compareConfig.ts +31 -0
- package/src/config/config.ts +1 -0
- package/src/config/customEmojiConfig.ts +8 -0
- package/src/hooks/useActiveCategoryScrollDetection.ts +9 -1
- package/src/hooks/useScrollCategoryIntoView.ts +2 -1
- package/src/types/exposedTypes.ts +6 -0
|
@@ -6,6 +6,7 @@ export interface PickerDataContextValue {
|
|
|
6
6
|
allEmojis: DataEmojis;
|
|
7
7
|
allEmojisByUnified: Record<string, DataEmoji>;
|
|
8
8
|
searchIndex: Record<string, Record<string, DataEmoji>>;
|
|
9
|
+
customGroups: Record<string, DataEmojis>;
|
|
9
10
|
emojiByUnified: (unified?: string) => DataEmoji | undefined;
|
|
10
11
|
activeVariationFromUnified: (unified: string) => SkinTones | null;
|
|
11
12
|
}
|
|
@@ -13,4 +14,4 @@ export declare function PickerDataProvider({ children, }: {
|
|
|
13
14
|
children: React.ReactNode;
|
|
14
15
|
}): JSX.Element;
|
|
15
16
|
export declare function usePickerDataContext(): PickerDataContextValue;
|
|
16
|
-
export declare function useGetEmojisByCategory(): (category: Categories) => DataEmojis;
|
|
17
|
+
export declare function useGetEmojisByCategory(): (category: Categories, group?: string | undefined) => DataEmojis;
|
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
import { Categories, CategoryConfig, EmojiData, SuggestionMode } from '../types/exposedTypes';
|
|
2
|
+
import { CustomEmoji } from './customEmojiConfig';
|
|
2
3
|
export { Categories };
|
|
3
4
|
export declare const SuggestedRecent: CategoryConfig;
|
|
4
5
|
export declare type CustomCategoryConfig = {
|
|
5
6
|
category: Categories.CUSTOM;
|
|
6
7
|
name: string;
|
|
8
|
+
/**
|
|
9
|
+
* Selects the `CustomEmoji` group rendered in this section. Each entry
|
|
10
|
+
* may carry its own `name` and `icon`, so multiple custom sections can
|
|
11
|
+
* coexist — each placed wherever its entry sits in `categories`.
|
|
12
|
+
* Entries without a group share the ungrouped customs bucket.
|
|
13
|
+
*/
|
|
14
|
+
group?: string;
|
|
7
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Stable identity for a category entry. Custom groups are namespaced so
|
|
18
|
+
* duplicate `{ category: CUSTOM }` configs no longer collide in React
|
|
19
|
+
* keys, scroll targets, and active-tab detection.
|
|
20
|
+
*/
|
|
21
|
+
export declare function categoryIdFromCategoryConfig(categoryConfig: CategoryConfig): string;
|
|
22
|
+
/**
|
|
23
|
+
* The `CustomEmoji` group rendered by a category entry, if any.
|
|
24
|
+
*/
|
|
25
|
+
export declare function customGroupFromCategoryConfig(categoryConfig: CategoryConfig): string | undefined;
|
|
8
26
|
export declare function baseCategoriesConfig(modifiers?: Record<Categories, CategoryConfig>): CategoriesConfig;
|
|
9
27
|
export declare function categoryFromCategoryConfig(category: CategoryConfig): Categories;
|
|
10
28
|
export declare function categoryNameFromCategoryConfig(category: CategoryConfig): string;
|
|
11
29
|
export declare type CategoriesConfig = CategoryConfig[];
|
|
12
30
|
export declare type UserCategoryConfig = Array<Categories | CategoryConfig>;
|
|
13
|
-
export declare function mergeCategoriesConfig(userCategoriesConfig?: UserCategoryConfig, modifiers?: CategoryConfigModifiers, emojiData?: EmojiData): CategoriesConfig;
|
|
31
|
+
export declare function mergeCategoriesConfig(userCategoriesConfig?: UserCategoryConfig, modifiers?: CategoryConfigModifiers, emojiData?: EmojiData, customEmojis?: CustomEmoji[]): CategoriesConfig;
|
|
14
32
|
declare type CategoryConfigModifiers = {
|
|
15
33
|
suggestionMode?: SuggestionMode;
|
|
16
34
|
};
|
|
@@ -3,4 +3,12 @@ export declare type CustomEmoji = {
|
|
|
3
3
|
names: string[];
|
|
4
4
|
[EmojiProperties.imgUrl]: string;
|
|
5
5
|
id: string;
|
|
6
|
+
/**
|
|
7
|
+
* Optional group name. Customs sharing a group render as their own
|
|
8
|
+
* category section; ungrouped customs keep the single shared bucket.
|
|
9
|
+
* Reference the group from a `{ category: Categories.CUSTOM, group }`
|
|
10
|
+
* entry in the `categories` prop to place and name the section.
|
|
11
|
+
* https://github.com/ealush/emoji-picker-react/issues/510
|
|
12
|
+
*/
|
|
13
|
+
group?: string;
|
|
6
14
|
};
|
|
@@ -179,7 +179,27 @@ function compareConfig(prev, next) {
|
|
|
179
179
|
var _prev$customEmojis, _next$customEmojis;
|
|
180
180
|
var prevCustomEmojis = (_prev$customEmojis = prev.customEmojis) != null ? _prev$customEmojis : [];
|
|
181
181
|
var nextCustomEmojis = (_next$customEmojis = next.customEmojis) != null ? _next$customEmojis : [];
|
|
182
|
-
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;
|
|
182
|
+
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;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Content identity for custom emojis. Length alone misses regroups and
|
|
186
|
+
* swaps, which would leave merged categories, search, and sections stale.
|
|
187
|
+
*/
|
|
188
|
+
function customEmojisKey(customEmojis) {
|
|
189
|
+
return customEmojis.map(function (emoji) {
|
|
190
|
+
var _emoji$group;
|
|
191
|
+
return emoji.id + ":" + ((_emoji$group = emoji.group) != null ? _emoji$group : '') + ":" + emoji.names.join(',') + ":" + emoji.imgUrl;
|
|
192
|
+
}).join('|');
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Content identity for the categories input. Order, labels, icons, and
|
|
196
|
+
* group selection all flow into the merged configuration.
|
|
197
|
+
*/
|
|
198
|
+
function categoriesKey(categories) {
|
|
199
|
+
return (categories != null ? categories : []).map(function (entry) {
|
|
200
|
+
var _entry$group;
|
|
201
|
+
return typeof entry === 'string' ? entry : entry.category + ":" + entry.name + ":" + ((_entry$group = entry.group) != null ? _entry$group : '') + ":" + (entry.icon ? '1' : '');
|
|
202
|
+
}).join('|');
|
|
183
203
|
}
|
|
184
204
|
|
|
185
205
|
var DEFAULT_REACTIONS = ['1f44d', '2764-fe0f', '1f603', '1f622', '1f64f', '1f44e', '1f621'];
|
|
@@ -322,6 +342,34 @@ var SuggestedRecent = {
|
|
|
322
342
|
name: 'Recently Used',
|
|
323
343
|
category: exports.Categories.SUGGESTED
|
|
324
344
|
};
|
|
345
|
+
/**
|
|
346
|
+
* Stable identity for a category entry. Custom groups are namespaced so
|
|
347
|
+
* duplicate `{ category: CUSTOM }` configs no longer collide in React
|
|
348
|
+
* keys, scroll targets, and active-tab detection.
|
|
349
|
+
*/
|
|
350
|
+
function categoryIdFromCategoryConfig(categoryConfig) {
|
|
351
|
+
var category = categoryFromCategoryConfig(categoryConfig);
|
|
352
|
+
if (isCustomGroupConfig(categoryConfig)) {
|
|
353
|
+
return category + ":" + categoryConfig.group;
|
|
354
|
+
}
|
|
355
|
+
return category;
|
|
356
|
+
}
|
|
357
|
+
function isCustomGroupConfig(categoryConfig) {
|
|
358
|
+
if (categoryConfig.category !== exports.Categories.CUSTOM) {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
var group = categoryConfig.group;
|
|
362
|
+
return typeof group === 'string' && group.length > 0;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* The `CustomEmoji` group rendered by a category entry, if any.
|
|
366
|
+
*/
|
|
367
|
+
function customGroupFromCategoryConfig(categoryConfig) {
|
|
368
|
+
if (isCustomGroupConfig(categoryConfig)) {
|
|
369
|
+
return categoryConfig.group;
|
|
370
|
+
}
|
|
371
|
+
return undefined;
|
|
372
|
+
}
|
|
325
373
|
var configByCategory = (_configByCategory = {}, _configByCategory[exports.Categories.SUGGESTED] = {
|
|
326
374
|
category: exports.Categories.SUGGESTED,
|
|
327
375
|
name: 'Frequently Used'
|
|
@@ -364,14 +412,17 @@ function categoryFromCategoryConfig(category) {
|
|
|
364
412
|
function categoryNameFromCategoryConfig(category) {
|
|
365
413
|
return category.name;
|
|
366
414
|
}
|
|
367
|
-
function mergeCategoriesConfig(userCategoriesConfig, modifiers, emojiData) {
|
|
368
|
-
var _userCategoriesConfig;
|
|
415
|
+
function mergeCategoriesConfig(userCategoriesConfig, modifiers, emojiData, customEmojis) {
|
|
416
|
+
var _userCategoriesConfig, _userCategoriesConfig2;
|
|
369
417
|
if (userCategoriesConfig === void 0) {
|
|
370
418
|
userCategoriesConfig = [];
|
|
371
419
|
}
|
|
372
420
|
if (modifiers === void 0) {
|
|
373
421
|
modifiers = {};
|
|
374
422
|
}
|
|
423
|
+
if (customEmojis === void 0) {
|
|
424
|
+
customEmojis = [];
|
|
425
|
+
}
|
|
375
426
|
var extra = function () {
|
|
376
427
|
// 1. Start with localized categories from emojiData
|
|
377
428
|
var fromData = emojiData != null && emojiData.categories ? Object.fromEntries(Object.entries(emojiData.categories).filter(function (_ref) {
|
|
@@ -390,15 +441,50 @@ function mergeCategoriesConfig(userCategoriesConfig, modifiers, emojiData) {
|
|
|
390
441
|
return fromData;
|
|
391
442
|
}();
|
|
392
443
|
var base = baseCategoriesConfig(extra);
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
444
|
+
var explicit = (_userCategoriesConfig = userCategoriesConfig) != null && _userCategoriesConfig.length ? userCategoriesConfig.map(mapUserEntry) : base;
|
|
445
|
+
// Groups without a `categories` entry get an appended section so their
|
|
446
|
+
// emojis always render somewhere — unless the user opted out of customs
|
|
447
|
+
// entirely by listing `categories` without CUSTOM. `categories` remains
|
|
448
|
+
// the override for order, display name, and icon.
|
|
449
|
+
// https://github.com/ealush/emoji-picker-react/issues/510
|
|
450
|
+
var customInPlay = !((_userCategoriesConfig2 = userCategoriesConfig) != null && _userCategoriesConfig2.length) || userCategoriesConfig.some(function (entry) {
|
|
451
|
+
return entry === exports.Categories.CUSTOM || typeof entry !== 'string' && entry.category === exports.Categories.CUSTOM;
|
|
452
|
+
});
|
|
453
|
+
var listedGroups = new Set(explicit.map(function (entry) {
|
|
454
|
+
return customGroupFromCategoryConfig(entry);
|
|
455
|
+
}).filter(function (group) {
|
|
456
|
+
return !!group;
|
|
457
|
+
}));
|
|
458
|
+
var appended = !customInPlay ? [] : Array.from(new Set(customEmojis.map(function (emoji) {
|
|
459
|
+
return emoji.group;
|
|
460
|
+
}).filter(function (group) {
|
|
461
|
+
return !!group;
|
|
462
|
+
}))).filter(function (group) {
|
|
463
|
+
return !listedGroups.has(group);
|
|
464
|
+
}).map(function (group) {
|
|
465
|
+
return {
|
|
466
|
+
category: exports.Categories.CUSTOM,
|
|
467
|
+
name: group,
|
|
468
|
+
group: group
|
|
469
|
+
};
|
|
470
|
+
});
|
|
471
|
+
// Collapse duplicate entries (same identity twice renders the same
|
|
472
|
+
// section twice under one React key); first occurrence wins.
|
|
473
|
+
var seen = new Set();
|
|
474
|
+
return explicit.concat(appended).filter(function (entry) {
|
|
475
|
+
var id = categoryIdFromCategoryConfig(entry);
|
|
476
|
+
if (seen.has(id)) {
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
seen.add(id);
|
|
480
|
+
return true;
|
|
481
|
+
});
|
|
482
|
+
function mapUserEntry(category) {
|
|
397
483
|
if (typeof category === 'string') {
|
|
398
484
|
return getBaseConfigByCategory(category, extra[category]);
|
|
399
485
|
}
|
|
400
486
|
return _extends({}, getBaseConfigByCategory(category.category, extra[category.category]), category);
|
|
401
|
-
}
|
|
487
|
+
}
|
|
402
488
|
}
|
|
403
489
|
function getBaseConfigByCategory(category, modifier) {
|
|
404
490
|
if (modifier === void 0) {
|
|
@@ -429,7 +515,7 @@ function mergeConfig(userConfig) {
|
|
|
429
515
|
var config = Object.assign(base, userConfig);
|
|
430
516
|
var categories = mergeCategoriesConfig(userConfig.categories, {
|
|
431
517
|
suggestionMode: config.suggestedEmojisMode
|
|
432
|
-
}, userConfig.emojiData);
|
|
518
|
+
}, userConfig.emojiData, userConfig.customEmojis);
|
|
433
519
|
config.hiddenEmojis.forEach(function (emoji) {
|
|
434
520
|
config.unicodeToHide.add(emoji);
|
|
435
521
|
});
|
|
@@ -491,7 +577,6 @@ function PickerConfigProvider(_ref) {
|
|
|
491
577
|
}, children);
|
|
492
578
|
}
|
|
493
579
|
function useSetConfig(config) {
|
|
494
|
-
var _config$customEmojis;
|
|
495
580
|
var _React$useState = React.useState(function () {
|
|
496
581
|
return mergeConfig(config);
|
|
497
582
|
}),
|
|
@@ -504,7 +589,11 @@ function useSetConfig(config) {
|
|
|
504
589
|
setMergedConfig(mergeConfig(config));
|
|
505
590
|
// not gonna...
|
|
506
591
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
507
|
-
}, [
|
|
592
|
+
}, [
|
|
593
|
+
// New references rebuild merged categories and data even at equal
|
|
594
|
+
// length; compareConfig above still gates no-op updates so inline
|
|
595
|
+
// literals don't loop.
|
|
596
|
+
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]);
|
|
508
597
|
return mergedConfig;
|
|
509
598
|
}
|
|
510
599
|
function usePickerConfig() {
|
|
@@ -26861,8 +26950,9 @@ function useIsMounted() {
|
|
|
26861
26950
|
var PickerDataContext = /*#__PURE__*/React__default.createContext({
|
|
26862
26951
|
emojiData: {},
|
|
26863
26952
|
allEmojis: [],
|
|
26864
|
-
allEmojisByUnified:
|
|
26865
|
-
searchIndex:
|
|
26953
|
+
allEmojisByUnified: /*#__PURE__*/Object.create(null),
|
|
26954
|
+
searchIndex: /*#__PURE__*/Object.create(null),
|
|
26955
|
+
customGroups: /*#__PURE__*/Object.create(null),
|
|
26866
26956
|
emojiByUnified: emojiByUnified,
|
|
26867
26957
|
activeVariationFromUnified: function activeVariationFromUnified() {
|
|
26868
26958
|
return null;
|
|
@@ -26877,13 +26967,28 @@ function PickerDataProvider(_ref) {
|
|
|
26877
26967
|
var emojiData = genericEmojiData || defaultEmojiData;
|
|
26878
26968
|
// Clone to avoid mutation of shared source
|
|
26879
26969
|
var newData = JSON.parse(JSON.stringify(emojiData));
|
|
26970
|
+
// Group names and emoji ids are user-controlled strings: use
|
|
26971
|
+
// null-prototype dictionaries so names like `__proto__` behave as
|
|
26972
|
+
// ordinary data instead of resolving Object.prototype members.
|
|
26973
|
+
var customGroups = Object.create(null);
|
|
26880
26974
|
if (customEmojis && customEmojis.length > 0) {
|
|
26881
|
-
|
|
26975
|
+
for (var _iterator = _createForOfIteratorHelperLoose(customEmojis), _step; !(_step = _iterator()).done;) {
|
|
26976
|
+
var _customGroups$emoji$g;
|
|
26977
|
+
var emoji = _step.value;
|
|
26978
|
+
if (!emoji.group) {
|
|
26979
|
+
continue;
|
|
26980
|
+
}
|
|
26981
|
+
customGroups[emoji.group] = (_customGroups$emoji$g = customGroups[emoji.group]) != null ? _customGroups$emoji$g : [];
|
|
26982
|
+
customGroups[emoji.group].push(customToRegularEmoji(emoji));
|
|
26983
|
+
}
|
|
26984
|
+
newData.emojis[exports.Categories.CUSTOM] = customEmojis.filter(function (emoji) {
|
|
26985
|
+
return !emoji.group;
|
|
26986
|
+
}).map(customToRegularEmoji);
|
|
26882
26987
|
}
|
|
26883
26988
|
var emojis = newData.emojis || {};
|
|
26884
|
-
var allEmojis = Object.values(emojis).flat();
|
|
26885
|
-
var allEmojisByUnified =
|
|
26886
|
-
var searchIndex =
|
|
26989
|
+
var allEmojis = Object.values(emojis).concat(Object.values(customGroups)).flat();
|
|
26990
|
+
var allEmojisByUnified = Object.create(null);
|
|
26991
|
+
var searchIndex = Object.create(null);
|
|
26887
26992
|
allEmojis.forEach(function (emoji) {
|
|
26888
26993
|
var unified = emoji[EmojiProperties.unified];
|
|
26889
26994
|
allEmojisByUnified[unified] = emoji;
|
|
@@ -26898,7 +27003,7 @@ function PickerDataProvider(_ref) {
|
|
|
26898
27003
|
var joinedNameString = (emoji[EmojiProperties.name] || []).join('').toLowerCase().split('');
|
|
26899
27004
|
joinedNameString.forEach(function (_char) {
|
|
26900
27005
|
var _searchIndex$_char;
|
|
26901
|
-
searchIndex[_char] = (_searchIndex$_char = searchIndex[_char]) != null ? _searchIndex$_char :
|
|
27006
|
+
searchIndex[_char] = (_searchIndex$_char = searchIndex[_char]) != null ? _searchIndex$_char : Object.create(null);
|
|
26902
27007
|
searchIndex[_char][unified] = emoji;
|
|
26903
27008
|
});
|
|
26904
27009
|
});
|
|
@@ -26906,7 +27011,8 @@ function PickerDataProvider(_ref) {
|
|
|
26906
27011
|
emojiData: newData,
|
|
26907
27012
|
allEmojis: allEmojis,
|
|
26908
27013
|
allEmojisByUnified: allEmojisByUnified,
|
|
26909
|
-
searchIndex: searchIndex
|
|
27014
|
+
searchIndex: searchIndex,
|
|
27015
|
+
customGroups: customGroups
|
|
26910
27016
|
};
|
|
26911
27017
|
}, [genericEmojiData, customEmojis]);
|
|
26912
27018
|
var emojiByUnified = React__default.useCallback(function (unified) {
|
|
@@ -26928,7 +27034,8 @@ function usePickerDataContext() {
|
|
|
26928
27034
|
function useGetEmojisByCategory() {
|
|
26929
27035
|
var _usePickerDataContext = usePickerDataContext(),
|
|
26930
27036
|
emojiData = _usePickerDataContext.emojiData,
|
|
26931
|
-
emojiByUnified = _usePickerDataContext.emojiByUnified
|
|
27037
|
+
emojiByUnified = _usePickerDataContext.emojiByUnified,
|
|
27038
|
+
customGroups = _usePickerDataContext.customGroups;
|
|
26932
27039
|
var suggestedEmojisModeConfig = useSuggestedEmojisModeConfig();
|
|
26933
27040
|
var _useUpdateSuggested = useUpdateSuggested(),
|
|
26934
27041
|
suggestedUpdated = _useUpdateSuggested[0];
|
|
@@ -26949,11 +27056,15 @@ function useGetEmojisByCategory() {
|
|
|
26949
27056
|
}).filter(Boolean);
|
|
26950
27057
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
26951
27058
|
}, [isMounted, suggestedUpdated, suggestedEmojisModeConfig, emojiByUnified]);
|
|
26952
|
-
return function getEmojisByCategory(category) {
|
|
27059
|
+
return function getEmojisByCategory(category, group) {
|
|
26953
27060
|
var _emojiData$emojis$cat, _emojiData$emojis;
|
|
26954
27061
|
if (category === exports.Categories.SUGGESTED) {
|
|
26955
27062
|
return suggested;
|
|
26956
27063
|
}
|
|
27064
|
+
if (category === exports.Categories.CUSTOM && group) {
|
|
27065
|
+
var _customGroups$group;
|
|
27066
|
+
return (_customGroups$group = customGroups[group]) != null ? _customGroups$group : [];
|
|
27067
|
+
}
|
|
26957
27068
|
return (_emojiData$emojis$cat = (_emojiData$emojis = emojiData.emojis) == null ? void 0 : _emojiData$emojis[category]) != null ? _emojiData$emojis$cat : [];
|
|
26958
27069
|
};
|
|
26959
27070
|
}
|
|
@@ -29587,11 +29698,10 @@ function EmojiCategory(_ref) {
|
|
|
29587
29698
|
hiddenOnSearch = _ref.hiddenOnSearch,
|
|
29588
29699
|
height = _ref.height,
|
|
29589
29700
|
emojisPerRow = _ref.emojisPerRow;
|
|
29590
|
-
var category = categoryFromCategoryConfig(categoryConfig);
|
|
29591
29701
|
var categoryName = categoryNameFromCategoryConfig(categoryConfig);
|
|
29592
29702
|
return React.createElement("li", {
|
|
29593
29703
|
className: shipstyles.cx(styles$7.category, hidden && commonStyles.hidden, hiddenOnSearch && commonInteractionStyles.hiddenOnSearch),
|
|
29594
|
-
"data-name":
|
|
29704
|
+
"data-name": categoryIdFromCategoryConfig(categoryConfig),
|
|
29595
29705
|
role: "rowgroup",
|
|
29596
29706
|
"aria-label": categoryName
|
|
29597
29707
|
}, React.createElement("h2", {
|
|
@@ -29666,7 +29776,7 @@ function MeasureEmoji() {
|
|
|
29666
29776
|
return null;
|
|
29667
29777
|
}
|
|
29668
29778
|
var firstCategory = categories[0];
|
|
29669
|
-
var dummyEmoji = getEmojisByCategory(categoryFromCategoryConfig(firstCategory))[0];
|
|
29779
|
+
var dummyEmoji = firstCategory ? getEmojisByCategory(categoryFromCategoryConfig(firstCategory), customGroupFromCategoryConfig(firstCategory))[0] : undefined;
|
|
29670
29780
|
var unified = dummyEmoji ? emojiUnified(dummyEmoji, activeSkinTone) : '';
|
|
29671
29781
|
if (!dummyEmoji) {
|
|
29672
29782
|
return null;
|
|
@@ -29720,22 +29830,24 @@ function EmojiList(_ref) {
|
|
|
29720
29830
|
role: "grid"
|
|
29721
29831
|
}, React.createElement(MeasureEmoji, null), categories.map(function (categoryConfig, index) {
|
|
29722
29832
|
var category = categoryFromCategoryConfig(categoryConfig);
|
|
29833
|
+
var categoryId = categoryIdFromCategoryConfig(categoryConfig);
|
|
29834
|
+
var group = customGroupFromCategoryConfig(categoryConfig);
|
|
29723
29835
|
var currentOffset = topOffset;
|
|
29724
|
-
var categoryHeight = categoryHeights[
|
|
29836
|
+
var categoryHeight = categoryHeights[categoryId];
|
|
29725
29837
|
if (categoryHeight) {
|
|
29726
29838
|
topOffset += categoryHeight + labelHeight;
|
|
29727
29839
|
}
|
|
29728
29840
|
return React.createElement(RenderCategory, {
|
|
29729
|
-
key:
|
|
29730
|
-
categoryEmojis: getEmojisByCategory(category),
|
|
29841
|
+
key: categoryId,
|
|
29842
|
+
categoryEmojis: getEmojisByCategory(category, group),
|
|
29731
29843
|
categoryConfig: categoryConfig,
|
|
29732
29844
|
topOffset: currentOffset,
|
|
29733
29845
|
isFirstCategory: index === 0,
|
|
29734
29846
|
onHeightReady: function onHeightReady(height) {
|
|
29735
|
-
if (categoryHeights[
|
|
29847
|
+
if (categoryHeights[categoryId] !== height) {
|
|
29736
29848
|
setCategoryHeights(function (prev) {
|
|
29737
29849
|
var _extends2;
|
|
29738
|
-
return _extends({}, prev, (_extends2 = {}, _extends2[
|
|
29850
|
+
return _extends({}, prev, (_extends2 = {}, _extends2[categoryId] = height, _extends2));
|
|
29739
29851
|
});
|
|
29740
29852
|
}
|
|
29741
29853
|
},
|
|
@@ -29759,7 +29871,7 @@ function RenderCategory(_ref2) {
|
|
|
29759
29871
|
// the deadlock; the observer takes over from there.
|
|
29760
29872
|
// https://github.com/ealush/emoji-picker-react/issues/469
|
|
29761
29873
|
// https://github.com/ealush/emoji-picker-react/issues/475
|
|
29762
|
-
var isCategoryVisible = isFirstCategory || visibleCategories.includes(categoryConfig
|
|
29874
|
+
var isCategoryVisible = isFirstCategory || visibleCategories.includes(categoryIdFromCategoryConfig(categoryConfig));
|
|
29763
29875
|
var _useEmojiVirtualizati = useEmojiVirtualization({
|
|
29764
29876
|
categoryEmojis: categoryEmojis,
|
|
29765
29877
|
topOffset: topOffset,
|
|
@@ -30421,7 +30533,8 @@ function categoryNameFromDom($category) {
|
|
|
30421
30533
|
|
|
30422
30534
|
function useActiveCategoryScrollDetection(_ref) {
|
|
30423
30535
|
var setActiveCategory = _ref.setActiveCategory,
|
|
30424
|
-
setVisibleCategories = _ref.setVisibleCategories
|
|
30536
|
+
setVisibleCategories = _ref.setVisibleCategories,
|
|
30537
|
+
categoryIdentitiesKey = _ref.categoryIdentitiesKey;
|
|
30425
30538
|
var BodyRef = useBodyRef();
|
|
30426
30539
|
React.useEffect(function () {
|
|
30427
30540
|
var visibleCategories = new Map();
|
|
@@ -30473,7 +30586,7 @@ function useActiveCategoryScrollDetection(_ref) {
|
|
|
30473
30586
|
return function () {
|
|
30474
30587
|
observer.disconnect();
|
|
30475
30588
|
};
|
|
30476
|
-
}, [BodyRef, setActiveCategory, setVisibleCategories]);
|
|
30589
|
+
}, [BodyRef, categoryIdentitiesKey, setActiveCategory, setVisibleCategories]);
|
|
30477
30590
|
}
|
|
30478
30591
|
|
|
30479
30592
|
function useScrollCategoryIntoView() {
|
|
@@ -30484,7 +30597,8 @@ function useScrollCategoryIntoView() {
|
|
|
30484
30597
|
if (!BodyRef.current) {
|
|
30485
30598
|
return;
|
|
30486
30599
|
}
|
|
30487
|
-
|
|
30600
|
+
// Group names are user-controlled; escape for the attribute selector.
|
|
30601
|
+
var $category = (_BodyRef$current = BodyRef.current) == null ? void 0 : _BodyRef$current.querySelector("[data-name=\"" + CSS.escape(category) + "\"]");
|
|
30488
30602
|
if (!$category) {
|
|
30489
30603
|
return;
|
|
30490
30604
|
}
|
|
@@ -30858,17 +30972,40 @@ function CategoryNavigation() {
|
|
|
30858
30972
|
var _useVisibleCategories = useVisibleCategoriesState(),
|
|
30859
30973
|
setVisibleCategories = _useVisibleCategories[1];
|
|
30860
30974
|
var scrollCategoryIntoView = useScrollCategoryIntoView();
|
|
30861
|
-
useActiveCategoryScrollDetection({
|
|
30862
|
-
setActiveCategory: setActiveCategory,
|
|
30863
|
-
setVisibleCategories: setVisibleCategories
|
|
30864
|
-
});
|
|
30865
30975
|
var isSearchMode = useIsSearchMode();
|
|
30866
30976
|
var categoriesConfig = useCategoriesConfig();
|
|
30867
30977
|
var categoryIcons = useCategoryIconsConfig();
|
|
30868
30978
|
var CategoryNavigationRef = useCategoryNavigationRef();
|
|
30869
30979
|
var hideCustomCategory = useShouldHideCustomEmojis();
|
|
30980
|
+
var _usePickerDataContext = usePickerDataContext(),
|
|
30981
|
+
customGroups = _usePickerDataContext.customGroups,
|
|
30982
|
+
emojiData = _usePickerDataContext.emojiData;
|
|
30983
|
+
// Rendered section identities. Passed to the scroll-detection hook so
|
|
30984
|
+
// added/removed sections are (re-)subscribed; stable across renders
|
|
30985
|
+
// unless the effective category list changes.
|
|
30986
|
+
var categoryIdentitiesKey = categoriesConfig.map(function (entry) {
|
|
30987
|
+
return categoryIdFromCategoryConfig(entry);
|
|
30988
|
+
}).join('|');
|
|
30989
|
+
useActiveCategoryScrollDetection({
|
|
30990
|
+
setActiveCategory: setActiveCategory,
|
|
30991
|
+
setVisibleCategories: setVisibleCategories,
|
|
30992
|
+
categoryIdentitiesKey: categoryIdentitiesKey
|
|
30993
|
+
});
|
|
30870
30994
|
var visibleCategories = categoriesConfig.filter(function (categoryConfig) {
|
|
30871
|
-
|
|
30995
|
+
if (isCustomCategory(categoryConfig) && hideCustomCategory) {
|
|
30996
|
+
return false;
|
|
30997
|
+
}
|
|
30998
|
+
// Tabs navigating to an empty (hidden) section are dead weight.
|
|
30999
|
+
var group = customGroupFromCategoryConfig(categoryConfig);
|
|
31000
|
+
if (group) {
|
|
31001
|
+
var _customGroups$group$l, _customGroups$group;
|
|
31002
|
+
return ((_customGroups$group$l = (_customGroups$group = customGroups[group]) == null ? void 0 : _customGroups$group.length) != null ? _customGroups$group$l : 0) > 0;
|
|
31003
|
+
}
|
|
31004
|
+
if (isCustomCategory(categoryConfig)) {
|
|
31005
|
+
var _emojiData$emojis$Cat, _emojiData$emojis, _emojiData$emojis$Cat2;
|
|
31006
|
+
return ((_emojiData$emojis$Cat = (_emojiData$emojis = emojiData.emojis) == null ? void 0 : (_emojiData$emojis$Cat2 = _emojiData$emojis[exports.Categories.CUSTOM]) == null ? void 0 : _emojiData$emojis$Cat2.length) != null ? _emojiData$emojis$Cat : 0) > 0;
|
|
31007
|
+
}
|
|
31008
|
+
return true;
|
|
30872
31009
|
});
|
|
30873
31010
|
// A single tab navigates nowhere — hide the bar to reclaim its space.
|
|
30874
31011
|
// https://github.com/ealush/emoji-picker-react/issues/396
|
|
@@ -30883,19 +31020,20 @@ function CategoryNavigation() {
|
|
|
30883
31020
|
ref: CategoryNavigationRef
|
|
30884
31021
|
}, visibleCategories.map(function (categoryConfig) {
|
|
30885
31022
|
var category = categoryFromCategoryConfig(categoryConfig);
|
|
30886
|
-
var
|
|
31023
|
+
var categoryId = categoryIdFromCategoryConfig(categoryConfig);
|
|
31024
|
+
var isActiveCategory = categoryId === activeCategory;
|
|
30887
31025
|
var allowNavigation = !isSearchMode && !isActiveCategory;
|
|
30888
31026
|
return React.createElement(CategoryButton, {
|
|
30889
|
-
key:
|
|
31027
|
+
key: categoryId,
|
|
30890
31028
|
category: category,
|
|
30891
31029
|
isActiveCategory: isActiveCategory,
|
|
30892
31030
|
allowNavigation: allowNavigation,
|
|
30893
31031
|
categoryConfig: categoryConfig,
|
|
30894
31032
|
customIcon: categoryIcons[category],
|
|
30895
31033
|
onClick: function onClick() {
|
|
30896
|
-
scrollCategoryIntoView(
|
|
31034
|
+
scrollCategoryIntoView(categoryId);
|
|
30897
31035
|
setTimeout(function () {
|
|
30898
|
-
setActiveCategory(
|
|
31036
|
+
setActiveCategory(categoryId);
|
|
30899
31037
|
}, 10);
|
|
30900
31038
|
}
|
|
30901
31039
|
});
|