emoji-picker-react 4.16.0 → 4.17.0

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 (220) hide show
  1. package/README.md +101 -41
  2. package/dist/components/body/EmojiCategory.d.ts +1 -1
  3. package/dist/components/context/PickerDataContext.d.ts +16 -0
  4. package/dist/components/navigation/CategoryButton.d.ts +1 -1
  5. package/dist/config/categoryConfig.d.ts +2 -6
  6. package/dist/config/config.d.ts +4 -1
  7. package/dist/config/useConfig.d.ts +1 -0
  8. package/dist/data/emojis-bn.d.ts +3 -0
  9. package/dist/data/emojis-bn.js +2 -0
  10. package/dist/data/emojis-bn.json +1 -0
  11. package/dist/data/emojis-bn.ts +3 -0
  12. package/dist/data/emojis-da.d.ts +3 -0
  13. package/dist/data/emojis-da.js +2 -0
  14. package/dist/data/emojis-da.json +1 -0
  15. package/dist/data/emojis-da.ts +3 -0
  16. package/dist/data/emojis-de.d.ts +3 -0
  17. package/dist/data/emojis-de.js +2 -0
  18. package/dist/data/emojis-de.json +1 -0
  19. package/dist/data/emojis-de.ts +3 -0
  20. package/dist/data/emojis-en-gb.d.ts +3 -0
  21. package/dist/data/emojis-en-gb.js +2 -0
  22. package/dist/data/emojis-en-gb.json +1 -0
  23. package/dist/data/emojis-en-gb.ts +3 -0
  24. package/dist/data/emojis-en.d.ts +3 -0
  25. package/dist/data/emojis-en.js +2 -0
  26. package/dist/data/emojis-en.json +1 -0
  27. package/dist/data/emojis-en.ts +3 -0
  28. package/dist/data/emojis-es-mx.d.ts +3 -0
  29. package/dist/data/emojis-es-mx.js +2 -0
  30. package/dist/data/emojis-es-mx.json +1 -0
  31. package/dist/data/emojis-es-mx.ts +3 -0
  32. package/dist/data/emojis-es.d.ts +3 -0
  33. package/dist/data/emojis-es.js +2 -0
  34. package/dist/data/emojis-es.json +1 -0
  35. package/dist/data/emojis-es.ts +3 -0
  36. package/dist/data/emojis-et.d.ts +3 -0
  37. package/dist/data/emojis-et.js +2 -0
  38. package/dist/data/emojis-et.json +1 -0
  39. package/dist/data/emojis-et.ts +3 -0
  40. package/dist/data/emojis-fi.d.ts +3 -0
  41. package/dist/data/emojis-fi.js +2 -0
  42. package/dist/data/emojis-fi.json +1 -0
  43. package/dist/data/emojis-fi.ts +3 -0
  44. package/dist/data/emojis-fr.d.ts +3 -0
  45. package/dist/data/emojis-fr.js +2 -0
  46. package/dist/data/emojis-fr.json +1 -0
  47. package/dist/data/emojis-fr.ts +3 -0
  48. package/dist/data/emojis-hi.d.ts +3 -0
  49. package/dist/data/emojis-hi.js +2 -0
  50. package/dist/data/emojis-hi.json +1 -0
  51. package/dist/data/emojis-hi.ts +3 -0
  52. package/dist/data/emojis-hu.d.ts +3 -0
  53. package/dist/data/emojis-hu.js +2 -0
  54. package/dist/data/emojis-hu.json +1 -0
  55. package/dist/data/emojis-hu.ts +3 -0
  56. package/dist/data/emojis-it.d.ts +3 -0
  57. package/dist/data/emojis-it.js +2 -0
  58. package/dist/data/emojis-it.json +1 -0
  59. package/dist/data/emojis-it.ts +3 -0
  60. package/dist/data/emojis-ja.d.ts +3 -0
  61. package/dist/data/emojis-ja.js +2 -0
  62. package/dist/data/emojis-ja.json +1 -0
  63. package/dist/data/emojis-ja.ts +3 -0
  64. package/dist/data/emojis-ko.d.ts +3 -0
  65. package/dist/data/emojis-ko.js +2 -0
  66. package/dist/data/emojis-ko.json +1 -0
  67. package/dist/data/emojis-ko.ts +3 -0
  68. package/dist/data/emojis-lt.d.ts +3 -0
  69. package/dist/data/emojis-lt.js +2 -0
  70. package/dist/data/emojis-lt.json +1 -0
  71. package/dist/data/emojis-lt.ts +3 -0
  72. package/dist/data/emojis-ms.d.ts +3 -0
  73. package/dist/data/emojis-ms.js +2 -0
  74. package/dist/data/emojis-ms.json +1 -0
  75. package/dist/data/emojis-ms.ts +3 -0
  76. package/dist/data/emojis-nb.d.ts +3 -0
  77. package/dist/data/emojis-nb.js +2 -0
  78. package/dist/data/emojis-nb.json +1 -0
  79. package/dist/data/emojis-nb.ts +3 -0
  80. package/dist/data/emojis-nl.d.ts +3 -0
  81. package/dist/data/emojis-nl.js +2 -0
  82. package/dist/data/emojis-nl.json +1 -0
  83. package/dist/data/emojis-nl.ts +3 -0
  84. package/dist/data/emojis-pl.d.ts +3 -0
  85. package/dist/data/emojis-pl.js +2 -0
  86. package/dist/data/emojis-pl.json +1 -0
  87. package/dist/data/emojis-pl.ts +3 -0
  88. package/dist/data/emojis-pt.d.ts +3 -0
  89. package/dist/data/emojis-pt.js +2 -0
  90. package/dist/data/emojis-pt.json +1 -0
  91. package/dist/data/emojis-pt.ts +3 -0
  92. package/dist/data/emojis-ru.d.ts +3 -0
  93. package/dist/data/emojis-ru.js +2 -0
  94. package/dist/data/emojis-ru.json +1 -0
  95. package/dist/data/emojis-ru.ts +3 -0
  96. package/dist/data/emojis-sv.d.ts +3 -0
  97. package/dist/data/emojis-sv.js +2 -0
  98. package/dist/data/emojis-sv.json +1 -0
  99. package/dist/data/emojis-sv.ts +3 -0
  100. package/dist/data/emojis-th.d.ts +3 -0
  101. package/dist/data/emojis-th.js +2 -0
  102. package/dist/data/emojis-th.json +1 -0
  103. package/dist/data/emojis-th.ts +3 -0
  104. package/dist/data/emojis-uk.d.ts +3 -0
  105. package/dist/data/emojis-uk.js +2 -0
  106. package/dist/data/emojis-uk.json +1 -0
  107. package/dist/data/emojis-uk.ts +3 -0
  108. package/dist/data/emojis-zh-hant.d.ts +3 -0
  109. package/dist/data/emojis-zh-hant.js +2 -0
  110. package/dist/data/emojis-zh-hant.json +1 -0
  111. package/dist/data/emojis-zh-hant.ts +3 -0
  112. package/dist/data/emojis-zh.d.ts +3 -0
  113. package/dist/data/emojis-zh.js +2 -0
  114. package/dist/data/emojis-zh.json +1 -0
  115. package/dist/data/emojis-zh.ts +3 -0
  116. package/dist/data/emojis.d.ts +102 -50
  117. package/dist/data/emojis.js +1 -0
  118. package/dist/data/emojis.json +1 -0
  119. package/dist/data/emojis.ts +1 -0
  120. package/dist/data/groups.d.ts +2 -2
  121. package/dist/data/groups.js +11 -0
  122. package/dist/data/groups.ts +12 -0
  123. package/dist/data/skinToneVariations.d.ts +5 -5
  124. package/dist/data/skinToneVariations.js +17 -0
  125. package/dist/data/skinToneVariations.ts +31 -0
  126. package/dist/dataUtils/DataTypes.d.ts +2 -2
  127. package/dist/dataUtils/emojiUtils.d.ts +12 -0
  128. package/dist/emoji-picker-react.cjs.development.js +20142 -17373
  129. package/dist/emoji-picker-react.cjs.development.js.map +1 -1
  130. package/dist/emoji-picker-react.cjs.production.min.js +1 -1
  131. package/dist/emoji-picker-react.cjs.production.min.js.map +1 -1
  132. package/dist/emoji-picker-react.esm.js +20143 -17374
  133. package/dist/emoji-picker-react.esm.js.map +1 -1
  134. package/dist/typeRefinements/typeRefinements.d.ts +2 -1
  135. package/dist/types/exposedTypes.d.ts +64 -50
  136. package/dist/types/exposedTypes.js +46 -0
  137. package/package.json +9 -5
  138. package/src/EmojiPickerReact.tsx +4 -1
  139. package/src/components/Reactions/Reactions.tsx +28 -20
  140. package/src/components/body/EmojiCategory.tsx +1 -1
  141. package/src/components/body/EmojiList.tsx +3 -5
  142. package/src/components/context/PickerConfigContext.tsx +3 -1
  143. package/src/components/context/PickerContext.tsx +7 -2
  144. package/src/components/context/PickerDataContext.tsx +157 -0
  145. package/src/components/emoji/ClickableEmojiButton.tsx +1 -3
  146. package/src/components/emoji/ViewOnlyEmoji.tsx +4 -5
  147. package/src/components/footer/Preview.tsx +6 -6
  148. package/src/components/header/Search/BtnClearSearch.tsx +4 -2
  149. package/src/components/navigation/CategoryButton.tsx +2 -4
  150. package/src/config/categoryConfig.ts +47 -30
  151. package/src/config/compareConfig.ts +4 -2
  152. package/src/config/config.ts +34 -15
  153. package/src/config/useConfig.ts +6 -0
  154. package/src/data/emojis-bn.json +1 -0
  155. package/src/data/emojis-bn.ts +3 -0
  156. package/src/data/emojis-da.json +1 -0
  157. package/src/data/emojis-da.ts +3 -0
  158. package/src/data/emojis-de.json +1 -0
  159. package/src/data/emojis-de.ts +3 -0
  160. package/src/data/emojis-en-gb.json +1 -0
  161. package/src/data/emojis-en-gb.ts +3 -0
  162. package/src/data/emojis-en.json +1 -0
  163. package/src/data/emojis-en.ts +3 -0
  164. package/src/data/emojis-es-mx.json +1 -0
  165. package/src/data/emojis-es-mx.ts +3 -0
  166. package/src/data/emojis-es.json +1 -0
  167. package/src/data/emojis-es.ts +3 -0
  168. package/src/data/emojis-et.json +1 -0
  169. package/src/data/emojis-et.ts +3 -0
  170. package/src/data/emojis-fi.json +1 -0
  171. package/src/data/emojis-fi.ts +3 -0
  172. package/src/data/emojis-fr.json +1 -0
  173. package/src/data/emojis-fr.ts +3 -0
  174. package/src/data/emojis-hi.json +1 -0
  175. package/src/data/emojis-hi.ts +3 -0
  176. package/src/data/emojis-hu.json +1 -0
  177. package/src/data/emojis-hu.ts +3 -0
  178. package/src/data/emojis-it.json +1 -0
  179. package/src/data/emojis-it.ts +3 -0
  180. package/src/data/emojis-ja.json +1 -0
  181. package/src/data/emojis-ja.ts +3 -0
  182. package/src/data/emojis-ko.json +1 -0
  183. package/src/data/emojis-ko.ts +3 -0
  184. package/src/data/emojis-lt.json +1 -0
  185. package/src/data/emojis-lt.ts +3 -0
  186. package/src/data/emojis-ms.json +1 -0
  187. package/src/data/emojis-ms.ts +3 -0
  188. package/src/data/emojis-nb.json +1 -0
  189. package/src/data/emojis-nb.ts +3 -0
  190. package/src/data/emojis-nl.json +1 -0
  191. package/src/data/emojis-nl.ts +3 -0
  192. package/src/data/emojis-pl.json +1 -0
  193. package/src/data/emojis-pl.ts +3 -0
  194. package/src/data/emojis-pt.json +1 -0
  195. package/src/data/emojis-pt.ts +3 -0
  196. package/src/data/emojis-ru.json +1 -0
  197. package/src/data/emojis-ru.ts +3 -0
  198. package/src/data/emojis-sv.json +1 -0
  199. package/src/data/emojis-sv.ts +3 -0
  200. package/src/data/emojis-th.json +1 -0
  201. package/src/data/emojis-th.ts +3 -0
  202. package/src/data/emojis-uk.json +1 -0
  203. package/src/data/emojis-uk.ts +3 -0
  204. package/src/data/emojis-zh-hant.json +1 -0
  205. package/src/data/emojis-zh-hant.ts +3 -0
  206. package/src/data/emojis-zh.json +1 -0
  207. package/src/data/emojis-zh.ts +3 -0
  208. package/src/data/emojis.json +1 -1
  209. package/src/data/emojis.ts +1 -1
  210. package/src/dataUtils/DataTypes.ts +2 -2
  211. package/src/dataUtils/alphaNumericEmojiIndex.ts +1 -8
  212. package/src/dataUtils/emojiSelectors.ts +24 -25
  213. package/src/dataUtils/emojiUtils.ts +74 -0
  214. package/src/hooks/preloadEmoji.ts +1 -1
  215. package/src/hooks/useDisallowedEmojis.ts +4 -3
  216. package/src/hooks/useEmojiVirtualization.tsx +2 -3
  217. package/src/hooks/useFilter.ts +1 -1
  218. package/src/hooks/useIsEmojiHidden.ts +1 -1
  219. package/src/typeRefinements/typeRefinements.ts +2 -5
  220. package/src/types/exposedTypes.ts +17 -0
@@ -1,5 +1,6 @@
1
- import { CategoryConfig, CustomCategoryConfig } from '../config/categoryConfig';
1
+ import { CustomCategoryConfig } from '../config/categoryConfig';
2
2
  import { CustomEmoji } from '../config/customEmojiConfig';
3
+ import { CategoryConfig } from '../types/exposedTypes';
3
4
  import { DataEmoji } from '../dataUtils/DataTypes';
4
5
  export declare function isCustomCategory(category: CategoryConfig | CustomCategoryConfig): category is CustomCategoryConfig;
5
6
  export declare function isCustomEmoji(emoji: Partial<DataEmoji>): emoji is CustomEmoji;
@@ -1,50 +1,64 @@
1
- export declare type EmojiClickData = {
2
- activeSkinTone: SkinTones;
3
- unified: string;
4
- unifiedWithoutSkinTone: string;
5
- emoji: string;
6
- names: string[];
7
- imageUrl: string;
8
- getImageUrl: (emojiStyle?: EmojiStyle) => string;
9
- isCustom: boolean;
10
- };
11
- export declare enum SuggestionMode {
12
- RECENT = "recent",
13
- FREQUENT = "frequent"
14
- }
15
- export declare enum EmojiStyle {
16
- NATIVE = "native",
17
- APPLE = "apple",
18
- TWITTER = "twitter",
19
- GOOGLE = "google",
20
- FACEBOOK = "facebook"
21
- }
22
- export declare enum Theme {
23
- DARK = "dark",
24
- LIGHT = "light",
25
- AUTO = "auto"
26
- }
27
- export declare enum SkinTones {
28
- NEUTRAL = "neutral",
29
- LIGHT = "1f3fb",
30
- MEDIUM_LIGHT = "1f3fc",
31
- MEDIUM = "1f3fd",
32
- MEDIUM_DARK = "1f3fe",
33
- DARK = "1f3ff"
34
- }
35
- export declare enum Categories {
36
- SUGGESTED = "suggested",
37
- CUSTOM = "custom",
38
- SMILEYS_PEOPLE = "smileys_people",
39
- ANIMALS_NATURE = "animals_nature",
40
- FOOD_DRINK = "food_drink",
41
- TRAVEL_PLACES = "travel_places",
42
- ACTIVITIES = "activities",
43
- OBJECTS = "objects",
44
- SYMBOLS = "symbols",
45
- FLAGS = "flags"
46
- }
47
- export declare enum SkinTonePickerLocation {
48
- SEARCH = "SEARCH",
49
- PREVIEW = "PREVIEW"
50
- }
1
+ export declare type EmojiClickData = {
2
+ activeSkinTone: SkinTones;
3
+ unified: string;
4
+ unifiedWithoutSkinTone: string;
5
+ emoji: string;
6
+ names: string[];
7
+ imageUrl: string;
8
+ getImageUrl: (emojiStyle?: EmojiStyle) => string;
9
+ isCustom: boolean;
10
+ };
11
+ export declare type CategoryConfig = {
12
+ category: Categories;
13
+ name: string;
14
+ };
15
+ export declare type EmojiData = {
16
+ categories: Partial<Record<Categories, CategoryConfig>>;
17
+ emojis: Record<string, DataEmoji[]>;
18
+ };
19
+ export interface DataEmoji {
20
+ n: string[];
21
+ u: string;
22
+ v?: string[];
23
+ a: string;
24
+ }
25
+ export declare enum SuggestionMode {
26
+ RECENT = "recent",
27
+ FREQUENT = "frequent"
28
+ }
29
+ export declare enum EmojiStyle {
30
+ NATIVE = "native",
31
+ APPLE = "apple",
32
+ TWITTER = "twitter",
33
+ GOOGLE = "google",
34
+ FACEBOOK = "facebook"
35
+ }
36
+ export declare enum Theme {
37
+ DARK = "dark",
38
+ LIGHT = "light",
39
+ AUTO = "auto"
40
+ }
41
+ export declare enum SkinTones {
42
+ NEUTRAL = "neutral",
43
+ LIGHT = "1f3fb",
44
+ MEDIUM_LIGHT = "1f3fc",
45
+ MEDIUM = "1f3fd",
46
+ MEDIUM_DARK = "1f3fe",
47
+ DARK = "1f3ff"
48
+ }
49
+ export declare enum Categories {
50
+ SUGGESTED = "suggested",
51
+ CUSTOM = "custom",
52
+ SMILEYS_PEOPLE = "smileys_people",
53
+ ANIMALS_NATURE = "animals_nature",
54
+ FOOD_DRINK = "food_drink",
55
+ TRAVEL_PLACES = "travel_places",
56
+ ACTIVITIES = "activities",
57
+ OBJECTS = "objects",
58
+ SYMBOLS = "symbols",
59
+ FLAGS = "flags"
60
+ }
61
+ export declare enum SkinTonePickerLocation {
62
+ SEARCH = "SEARCH",
63
+ PREVIEW = "PREVIEW"
64
+ }
@@ -0,0 +1,46 @@
1
+ export var SuggestionMode;
2
+ (function (SuggestionMode) {
3
+ SuggestionMode["RECENT"] = "recent";
4
+ SuggestionMode["FREQUENT"] = "frequent";
5
+ })(SuggestionMode || (SuggestionMode = {}));
6
+ export var EmojiStyle;
7
+ (function (EmojiStyle) {
8
+ EmojiStyle["NATIVE"] = "native";
9
+ EmojiStyle["APPLE"] = "apple";
10
+ EmojiStyle["TWITTER"] = "twitter";
11
+ EmojiStyle["GOOGLE"] = "google";
12
+ EmojiStyle["FACEBOOK"] = "facebook";
13
+ })(EmojiStyle || (EmojiStyle = {}));
14
+ export var Theme;
15
+ (function (Theme) {
16
+ Theme["DARK"] = "dark";
17
+ Theme["LIGHT"] = "light";
18
+ Theme["AUTO"] = "auto";
19
+ })(Theme || (Theme = {}));
20
+ export var SkinTones;
21
+ (function (SkinTones) {
22
+ SkinTones["NEUTRAL"] = "neutral";
23
+ SkinTones["LIGHT"] = "1f3fb";
24
+ SkinTones["MEDIUM_LIGHT"] = "1f3fc";
25
+ SkinTones["MEDIUM"] = "1f3fd";
26
+ SkinTones["MEDIUM_DARK"] = "1f3fe";
27
+ SkinTones["DARK"] = "1f3ff";
28
+ })(SkinTones || (SkinTones = {}));
29
+ export var Categories;
30
+ (function (Categories) {
31
+ Categories["SUGGESTED"] = "suggested";
32
+ Categories["CUSTOM"] = "custom";
33
+ Categories["SMILEYS_PEOPLE"] = "smileys_people";
34
+ Categories["ANIMALS_NATURE"] = "animals_nature";
35
+ Categories["FOOD_DRINK"] = "food_drink";
36
+ Categories["TRAVEL_PLACES"] = "travel_places";
37
+ Categories["ACTIVITIES"] = "activities";
38
+ Categories["OBJECTS"] = "objects";
39
+ Categories["SYMBOLS"] = "symbols";
40
+ Categories["FLAGS"] = "flags";
41
+ })(Categories || (Categories = {}));
42
+ export var SkinTonePickerLocation;
43
+ (function (SkinTonePickerLocation) {
44
+ SkinTonePickerLocation["SEARCH"] = "SEARCH";
45
+ SkinTonePickerLocation["PREVIEW"] = "PREVIEW";
46
+ })(SkinTonePickerLocation || (SkinTonePickerLocation = {}));
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.16.0",
2
+ "version": "4.17.0",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -27,14 +27,17 @@
27
27
  },
28
28
  "scripts": {
29
29
  "start": "tsdx watch",
30
- "build": "node ./scripts/prepare.js && yarn type-check && tsdx build --transpileOnly && node ./scripts/copyData.js",
30
+ "build": "yarn build:data:src && yarn type-check && tsdx build --transpileOnly && yarn build:data:dist",
31
31
  "type-check": "tsc --noEmit --incremental --pretty --project tsconfig.json",
32
32
  "test": "tsdx test --passWithNoTests",
33
33
  "lint": "eslint ./src --ext .ts,.tsx",
34
- "prepare": "yarn type-check && tsdx build --transpileOnly",
34
+ "prepare": "yarn build",
35
35
  "size": "size-limit",
36
36
  "analyze": "size-limit --why",
37
- "storybook": "storybook dev -p 6006",
37
+ "build:data:src": "tsc --project ./scripts/tsconfig.build.json && node ./scripts/dist/prepare.js",
38
+ "build:data:dist": "tsc --project tsconfig.data.json && node ./scripts/copyData.js",
39
+ "build:data": "yarn build:data:src && yarn build:data:dist",
40
+ "storybook": "yarn build:data && storybook dev -p 6006",
38
41
  "build-storybook": "storybook build"
39
42
  },
40
43
  "peerDependencies": {
@@ -82,7 +85,8 @@
82
85
  "autoprefixer": "^10.4.8",
83
86
  "babel-loader": "^8.2.5",
84
87
  "cssnano": "^5.1.13",
85
- "emoji-datasource": "^15.1.2",
88
+ "emoji-datasource": "^16.0.0",
89
+ "emojibase-data": "^15.3.0",
86
90
  "eslint-import-resolver-typescript": "^3.3.0",
87
91
  "eslint-plugin-import": "^2.26.0",
88
92
  "eslint-plugin-jsx-a11y": "^6.6.1",
@@ -6,6 +6,7 @@ import { Body } from './components/body/Body';
6
6
  import { ElementRefContextProvider } from './components/context/ElementRefContext';
7
7
  import { PickerConfigProvider } from './components/context/PickerConfigContext';
8
8
  import { useReactionsModeState } from './components/context/PickerContext';
9
+ import { PickerDataProvider } from './components/context/PickerDataContext';
9
10
  import { Preview } from './components/footer/Preview';
10
11
  import { Header } from './components/header/Header';
11
12
  import PickerMain from './components/main/PickerMain';
@@ -19,7 +20,9 @@ function EmojiPicker(props: PickerProps) {
19
20
  <ElementRefContextProvider>
20
21
  <PickerStyleTag />
21
22
  <PickerConfigProvider {...props}>
22
- <ContentControl />
23
+ <PickerDataProvider>
24
+ <ContentControl />
25
+ </PickerDataProvider>
23
26
  </PickerConfigProvider>
24
27
  </ElementRefContextProvider>
25
28
  );
@@ -7,7 +7,7 @@ import {
7
7
  useEmojiStyleConfig,
8
8
  useReactionsConfig,
9
9
  useAllowExpandReactions,
10
- useGetEmojiUrlConfig
10
+ useGetEmojiUrlConfig,
11
11
  } from '../../config/useConfig';
12
12
  import { DataEmoji } from '../../dataUtils/DataTypes';
13
13
  import { emojiByUnified } from '../../dataUtils/emojiSelectors';
@@ -36,19 +36,27 @@ export function Reactions() {
36
36
  className={cx(styles.list, !reactionsOpen && commonStyles.hidden)}
37
37
  ref={ReactionsRef}
38
38
  >
39
- {reactions.map(reaction => (
40
- <li key={reaction}>
41
- <ClickableEmoji
42
- emoji={emojiByUnified(reaction) as DataEmoji}
43
- emojiStyle={emojiStyle}
44
- unified={reaction}
45
- showVariations={false}
46
- className={cx(styles.emojiButton)}
47
- noBackground
48
- getEmojiUrl={getEmojiUrl}
49
- />
50
- </li>
51
- ))}
39
+ {reactions.map((reaction) => {
40
+ const emoji = emojiByUnified(reaction);
41
+
42
+ if (!emoji) {
43
+ return null;
44
+ }
45
+
46
+ return (
47
+ <li key={reaction}>
48
+ <ClickableEmoji
49
+ emoji={emoji as DataEmoji}
50
+ emojiStyle={emojiStyle}
51
+ unified={reaction}
52
+ showVariations={false}
53
+ className={cx(styles.emojiButton)}
54
+ noBackground
55
+ getEmojiUrl={getEmojiUrl}
56
+ />
57
+ </li>
58
+ );
59
+ })}
52
60
  {allowExpandReactions ? (
53
61
  <li>
54
62
  <BtnPlus />
@@ -66,18 +74,18 @@ const styles = stylesheet.create({
66
74
  display: 'flex',
67
75
  justifyContent: 'space-between',
68
76
  alignItems: 'center',
69
- height: '100%'
77
+ height: '100%',
70
78
  },
71
79
  emojiButton: {
72
80
  ':hover': {
73
- transform: 'scale(1.2)'
81
+ transform: 'scale(1.2)',
74
82
  },
75
83
  ':focus': {
76
- transform: 'scale(1.2)'
84
+ transform: 'scale(1.2)',
77
85
  },
78
86
  ':active': {
79
- transform: 'scale(1.1)'
87
+ transform: 'scale(1.1)',
80
88
  },
81
- transition: 'transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.5)'
82
- }
89
+ transition: 'transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.5)',
90
+ },
83
91
  });
@@ -8,10 +8,10 @@ import {
8
8
  stylesheet
9
9
  } from '../../Stylesheet/stylesheet';
10
10
  import {
11
- CategoryConfig,
12
11
  categoryFromCategoryConfig,
13
12
  categoryNameFromCategoryConfig
14
13
  } from '../../config/categoryConfig';
14
+ import { CategoryConfig } from '../../types/exposedTypes';
15
15
 
16
16
  type Props = Readonly<{
17
17
  categoryConfig: CategoryConfig;
@@ -4,16 +4,14 @@ import * as React from 'react';
4
4
  import { ClassNames } from '../../DomUtils/classNames';
5
5
  import { getLabelHeight } from '../../DomUtils/elementPositionInRow';
6
6
  import { stylesheet } from '../../Stylesheet/stylesheet';
7
- import {
8
- CategoryConfig,
9
- categoryFromCategoryConfig
10
- } from '../../config/categoryConfig';
7
+ import { categoryFromCategoryConfig } from '../../config/categoryConfig';
8
+ import { CategoryConfig } from '../../types/exposedTypes';
11
9
  import { useCategoriesConfig } from '../../config/useConfig';
12
10
  import { DataEmojis } from '../../dataUtils/DataTypes';
13
- import { useGetEmojisByCategory } from '../../dataUtils/emojiSelectors';
14
11
  import { useEmojiVirtualization } from '../../hooks/useEmojiVirtualization';
15
12
  import { useEmojiListRef } from '../context/ElementRefContext';
16
13
  import { useVisibleCategoriesState } from '../context/PickerContext';
14
+ import { useGetEmojisByCategory } from '../context/PickerDataContext';
17
15
 
18
16
  import { EmojiCategory } from './EmojiCategory';
19
17
  import { MeasureEmoji } from './MeasureEmoji';
@@ -46,6 +46,7 @@ export function useSetConfig(config: PickerConfig) {
46
46
  config.reactionsDefaultOpen,
47
47
  config.searchPlaceHolder,
48
48
  config.searchPlaceholder,
49
+ config.searchClearButtonLabel,
49
50
  config.defaultSkinTone,
50
51
  config.skinTonesDisabled,
51
52
  config.autoFocusSearch,
@@ -58,7 +59,8 @@ export function useSetConfig(config: PickerConfig) {
58
59
  config.width,
59
60
  config.searchDisabled,
60
61
  config.skinTonePickerLocation,
61
- config.allowExpandReactions
62
+ config.allowExpandReactions,
63
+ config.emojiData
62
64
  ]);
63
65
 
64
66
  return mergedConfig;
@@ -6,20 +6,25 @@ import {
6
6
  useReactionsOpenConfig
7
7
  } from '../../config/useConfig';
8
8
  import { DataEmoji } from '../../dataUtils/DataTypes';
9
- import { alphaNumericEmojiIndex } from '../../dataUtils/alphaNumericEmojiIndex';
10
9
  import { useDebouncedState } from '../../hooks/useDebouncedState';
11
10
  import { useDisallowedEmojis } from '../../hooks/useDisallowedEmojis';
12
11
  import { FilterDict } from '../../hooks/useFilter';
13
12
  import { useMarkInitialLoad } from '../../hooks/useInitialLoad';
14
13
  import { SkinTones } from '../../types/exposedTypes';
14
+ import { usePickerDataContext } from './PickerDataContext';
15
15
 
16
16
  export function PickerContextProvider({ children }: Props) {
17
17
  const disallowedEmojis = useDisallowedEmojis();
18
18
  const defaultSkinTone = useDefaultSkinToneConfig();
19
19
  const reactionsDefaultOpen = useReactionsOpenConfig();
20
+ const { searchIndex } = usePickerDataContext();
20
21
 
21
22
  // Initialize the filter with the inititial dictionary
22
- const filterRef = React.useRef<FilterState>(alphaNumericEmojiIndex);
23
+ const filterRef = React.useRef<FilterState>(searchIndex);
24
+
25
+ React.useEffect(() => {
26
+ filterRef.current = searchIndex;
27
+ }, [searchIndex]);
23
28
  const disallowClickRef = React.useRef<boolean>(false);
24
29
  const disallowMouseRef = React.useRef<boolean>(false);
25
30
  const disallowedEmojisRef = React.useRef<Record<string, boolean>>(
@@ -0,0 +1,157 @@
1
+ import React from 'react';
2
+
3
+ import { CustomEmoji } from '../../config/customEmojiConfig';
4
+ import { useSuggestedEmojisModeConfig } from '../../config/useConfig';
5
+ import defaultEmojiData from '../../data/emojis';
6
+
7
+ import {
8
+ DataEmoji,
9
+ DataEmojis,
10
+ EmojiProperties,
11
+ EmojiProperties as Keys,
12
+ } from '../../dataUtils/DataTypes';
13
+ import {
14
+ activeVariationFromUnified,
15
+ unifiedWithoutSkinTone,
16
+ } from '../../dataUtils/emojiUtils';
17
+ import { getSuggested } from '../../dataUtils/suggested';
18
+ import { Categories, EmojiData, SkinTones } from '../../types/exposedTypes';
19
+
20
+ import { usePickerConfig } from './PickerConfigContext';
21
+ import { useUpdateSuggested } from './PickerContext';
22
+
23
+ export interface PickerDataContextValue {
24
+ emojiData: EmojiData;
25
+ allEmojis: DataEmojis;
26
+ allEmojisByUnified: Record<string, DataEmoji>;
27
+ searchIndex: Record<string, Record<string, DataEmoji>>;
28
+ emojiByUnified: (unified?: string) => DataEmoji | undefined;
29
+ activeVariationFromUnified: (unified: string) => SkinTones | null;
30
+ }
31
+
32
+ const PickerDataContext = React.createContext<PickerDataContextValue>({
33
+ emojiData: {} as EmojiData,
34
+ allEmojis: [],
35
+ allEmojisByUnified: {},
36
+ searchIndex: {},
37
+ emojiByUnified: () => undefined,
38
+ activeVariationFromUnified: () => null,
39
+ });
40
+
41
+ export function PickerDataProvider({
42
+ children,
43
+ }: {
44
+ children: React.ReactNode;
45
+ }) {
46
+ const { customEmojis, emojiData: genericEmojiData } = usePickerConfig();
47
+
48
+ const data = React.useMemo(() => {
49
+ const emojiData = genericEmojiData || (defaultEmojiData as EmojiData);
50
+
51
+ // Clone to avoid mutation of shared source
52
+ const newData: EmojiData = JSON.parse(JSON.stringify(emojiData));
53
+
54
+ if (customEmojis && customEmojis.length > 0) {
55
+ newData.emojis[Categories.CUSTOM] =
56
+ customEmojis.map(customToRegularEmoji);
57
+ }
58
+
59
+ const emojis = newData.emojis || {};
60
+
61
+ const allEmojis: DataEmojis = Object.values(emojis).flat();
62
+ const allEmojisByUnified: Record<string, DataEmoji> = {};
63
+ const searchIndex: Record<string, Record<string, DataEmoji>> = {};
64
+
65
+ allEmojis.forEach((emoji) => {
66
+ const unified = emoji[Keys.unified];
67
+ allEmojisByUnified[unified] = emoji;
68
+
69
+ if (emoji[Keys.variations]) {
70
+ emoji[Keys.variations]?.forEach((variation) => {
71
+ allEmojisByUnified[variation] = emoji;
72
+ });
73
+ }
74
+
75
+ // Index for search
76
+ // Re-implement indexEmoji logic here to be local
77
+ const joinedNameString = (emoji[Keys.name] || [])
78
+ .join('')
79
+ .toLowerCase()
80
+ .split('');
81
+
82
+ joinedNameString.forEach((char: string) => {
83
+ searchIndex[char] = searchIndex[char] ?? {};
84
+ searchIndex[char][unified] = emoji;
85
+ });
86
+ });
87
+
88
+ return {
89
+ emojiData: newData,
90
+ allEmojis,
91
+ allEmojisByUnified,
92
+ searchIndex,
93
+ };
94
+ }, [genericEmojiData, customEmojis]);
95
+
96
+ const emojiByUnified = React.useCallback(
97
+ (unified?: string): DataEmoji | undefined => {
98
+ if (!unified) return undefined;
99
+
100
+ const result =
101
+ data.allEmojisByUnified[unified] ??
102
+ data.allEmojisByUnified[unifiedWithoutSkinTone(unified)];
103
+ return result;
104
+ },
105
+ [data.allEmojisByUnified],
106
+ );
107
+
108
+ return (
109
+ <PickerDataContext.Provider
110
+ value={{
111
+ ...data,
112
+ emojiByUnified,
113
+ activeVariationFromUnified,
114
+ }}
115
+ >
116
+ {children}
117
+ </PickerDataContext.Provider>
118
+ );
119
+ }
120
+
121
+ export function usePickerDataContext() {
122
+ return React.useContext(PickerDataContext);
123
+ }
124
+
125
+ export function useGetEmojisByCategory() {
126
+ const { emojiData, emojiByUnified } = usePickerDataContext();
127
+ const suggestedEmojisModeConfig = useSuggestedEmojisModeConfig();
128
+ const [suggestedUpdated] = useUpdateSuggested();
129
+
130
+ const suggested = React.useMemo(() => {
131
+ const suggested = getSuggested(suggestedEmojisModeConfig) ?? [];
132
+
133
+ return suggested
134
+ .map((s) => emojiByUnified(s.unified))
135
+ .filter(Boolean) as DataEmojis;
136
+ // eslint-disable-next-line react-hooks/exhaustive-deps
137
+ }, [suggestedUpdated, suggestedEmojisModeConfig, emojiByUnified]);
138
+
139
+ return function getEmojisByCategory(category: Categories): DataEmojis {
140
+ if (category === Categories.SUGGESTED) {
141
+ return suggested;
142
+ }
143
+
144
+ return emojiData.emojis?.[category] ?? [];
145
+ };
146
+ }
147
+
148
+ function customToRegularEmoji(emoji: CustomEmoji): DataEmoji {
149
+ return {
150
+ [EmojiProperties.name]: emoji.names.map((name: string) =>
151
+ name.toLowerCase(),
152
+ ),
153
+ [EmojiProperties.unified]: emoji.id.toLowerCase(),
154
+ [EmojiProperties.added_in]: '0',
155
+ [EmojiProperties.imgUrl]: emoji.imgUrl,
156
+ };
157
+ }
@@ -58,9 +58,7 @@ export function ClickableEmojiButton({
58
58
  }
59
59
 
60
60
  function getAriaLabel(emojiNames: string[]) {
61
- return emojiNames[0].match('flag-')
62
- ? emojiNames[1] ?? emojiNames[0]
63
- : emojiNames[0];
61
+ return emojiNames[emojiNames.length - 1];
64
62
  }
65
63
 
66
64
  const styles = stylesheet.create({
@@ -1,14 +1,12 @@
1
1
  import * as React from 'react';
2
2
 
3
- import {
4
- emojiByUnified,
5
- emojiName,
6
- emojiUrlByUnified
7
- } from '../../dataUtils/emojiSelectors';
3
+ import { emojiName, emojiUrlByUnified } from '../../dataUtils/emojiUtils';
8
4
  import { isCustomEmoji } from '../../typeRefinements/typeRefinements';
9
5
  import { EmojiStyle } from '../../types/exposedTypes';
10
6
  import { useEmojisThatFailedToLoadState } from '../context/PickerContext';
11
7
 
8
+ import { usePickerDataContext } from '../context/PickerDataContext';
9
+
12
10
  import { BaseEmojiProps } from './BaseEmojiProps';
13
11
  import { EmojiImg } from './EmojiImg';
14
12
  import { NativeEmoji } from './NativeEmoji';
@@ -23,6 +21,7 @@ export function ViewOnlyEmoji({
23
21
  className
24
22
  }: BaseEmojiProps) {
25
23
  const [, setEmojisThatFailedToLoad] = useEmojisThatFailedToLoadState();
24
+ const { emojiByUnified } = usePickerDataContext();
26
25
 
27
26
  const style = {} as React.CSSProperties;
28
27
  if (size) {
@@ -11,11 +11,7 @@ import {
11
11
  useGetEmojiUrlConfig,
12
12
  usePreviewConfig
13
13
  } from '../../config/useConfig';
14
- import {
15
- emojiByUnified,
16
- emojiName,
17
- emojiUnified
18
- } from '../../dataUtils/emojiSelectors';
14
+ import { emojiName, emojiUnified } from '../../dataUtils/emojiSelectors';
19
15
  import { useEmojiPreviewEvents } from '../../hooks/useEmojiPreviewEvents';
20
16
  import { useIsSkinToneInPreview } from '../../hooks/useShouldShowSkinTonePicker';
21
17
  import Flex from '../Layout/Flex';
@@ -24,6 +20,7 @@ import {
24
20
  useEmojiVariationPickerState,
25
21
  useReactionsModeState
26
22
  } from '../context/PickerContext';
23
+ import { usePickerDataContext } from '../context/PickerDataContext';
27
24
  import { ViewOnlyEmoji } from '../emoji/ViewOnlyEmoji';
28
25
  import { SkinTonePickerMenu } from '../header/SkinTonePicker/SkinTonePicker';
29
26
 
@@ -57,11 +54,14 @@ export function PreviewBody() {
57
54
  const emojiStyle = useEmojiStyleConfig();
58
55
  const [variationPickerEmoji] = useEmojiVariationPickerState();
59
56
  const getEmojiUrl = useGetEmojiUrlConfig();
57
+ const { emojiByUnified } = usePickerDataContext();
60
58
 
61
59
  useEmojiPreviewEvents(previewConfig.showPreview, setPreviewEmoji);
62
60
 
63
61
  const emoji = emojiByUnified(
64
- previewEmoji?.unified ?? previewEmoji?.originalUnified
62
+ (previewEmoji?.unified ?? previewEmoji?.originalUnified) as
63
+ | string
64
+ | undefined
65
65
  );
66
66
 
67
67
  const show = emoji != null && previewEmoji != null;
@@ -6,6 +6,7 @@ import {
6
6
  darkMode,
7
7
  stylesheet
8
8
  } from '../../../Stylesheet/stylesheet';
9
+ import { useSearchClearButtonLabelConfig } from '../../../config/useConfig';
9
10
  import { useClearSearch } from '../../../hooks/useFilter';
10
11
  import { Button } from '../../atoms/Button';
11
12
 
@@ -13,6 +14,7 @@ import SVGTimes from './svg/times.svg';
13
14
 
14
15
  export function BtnClearSearch() {
15
16
  const clearSearch = useClearSearch();
17
+ const searchClearButtonLabel = useSearchClearButtonLabelConfig();
16
18
 
17
19
  return (
18
20
  <Button
@@ -21,8 +23,8 @@ export function BtnClearSearch() {
21
23
  commonInteractionStyles.visibleOnSearchOnly
22
24
  )}
23
25
  onClick={clearSearch}
24
- aria-label="Clear"
25
- title="Clear"
26
+ aria-label={searchClearButtonLabel}
27
+ title={searchClearButtonLabel}
26
28
  >
27
29
  <div className={cx(styles.icnClearnSearch)} />
28
30
  </Button>
@@ -7,10 +7,8 @@ import {
7
7
  darkMode,
8
8
  stylesheet
9
9
  } from '../../Stylesheet/stylesheet';
10
- import {
11
- CategoryConfig,
12
- categoryNameFromCategoryConfig
13
- } from '../../config/categoryConfig';
10
+ import { categoryNameFromCategoryConfig } from '../../config/categoryConfig';
11
+ import { CategoryConfig } from '../../types/exposedTypes';
14
12
  import { Button } from '../atoms/Button';
15
13
 
16
14
  import SVGNavigation from './svg/CategoryNav.svg';