emoji-picker-react 4.22.2 → 5.0.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 (405) hide show
  1. package/README.md +335 -49
  2. package/dist/DomUtils/categoryNameFromDom.d.ts +1 -1
  3. package/dist/DomUtils/classNames.d.ts +24 -23
  4. package/dist/DomUtils/detectEmojyPartiallyBelowFold.d.ts +2 -2
  5. package/dist/DomUtils/elementPositionInRow.d.ts +5 -5
  6. package/dist/DomUtils/eventBelongsToPicker.d.ts +2 -0
  7. package/dist/DomUtils/focusElement.d.ts +5 -5
  8. package/dist/DomUtils/getActiveElement.d.ts +2 -2
  9. package/dist/DomUtils/isJsdom.d.ts +1 -0
  10. package/dist/DomUtils/isRtl.d.ts +1 -0
  11. package/dist/DomUtils/keyboardNavigation.d.ts +7 -8
  12. package/dist/DomUtils/scrollTo.d.ts +4 -5
  13. package/dist/DomUtils/selectors.d.ts +31 -35
  14. package/dist/EmojiPickerReact.d.ts +5 -5
  15. package/dist/Stylesheet/DedupedStyle.d.ts +13 -0
  16. package/dist/Stylesheet/stylesheet.d.ts +40 -37
  17. package/dist/components/ErrorBoundary.d.ts +15 -15
  18. package/dist/components/Layout/Absolute.d.ts +8 -8
  19. package/dist/components/Layout/Flex.d.ts +13 -13
  20. package/dist/components/Layout/Relative.d.ts +8 -8
  21. package/dist/components/Layout/Space.d.ts +7 -7
  22. package/dist/components/Reactions/BtnPlus.d.ts +2 -2
  23. package/dist/components/Reactions/DEFAULT_REACTIONS.d.ts +1 -1
  24. package/dist/components/Reactions/Reactions.d.ts +3 -2
  25. package/dist/components/atoms/Button.d.ts +11 -6
  26. package/dist/components/body/EmojiCategory.d.ts +13 -12
  27. package/dist/components/body/EmojiList.d.ts +7 -4
  28. package/dist/components/body/EmojiVariationPicker.d.ts +2 -2
  29. package/dist/components/body/MeasureEmoji.d.ts +2 -2
  30. package/dist/components/body/listComponents.d.ts +47 -0
  31. package/dist/components/context/ElementRefContext.d.ts +18 -16
  32. package/dist/components/context/PickerConfigContext.d.ts +14 -9
  33. package/dist/components/context/PickerContext.d.ts +57 -25
  34. package/dist/components/context/PickerDataContext.d.ts +23 -17
  35. package/dist/components/emoji/BaseEmojiProps.d.ts +14 -13
  36. package/dist/components/emoji/ClickableEmojiButton.d.ts +23 -15
  37. package/dist/components/emoji/Emoji.d.ts +18 -15
  38. package/dist/components/emoji/EmojiImg.d.ts +11 -11
  39. package/dist/components/emoji/ExportedEmoji.d.ts +11 -11
  40. package/dist/components/emoji/NativeEmoji.d.ts +6 -6
  41. package/dist/components/emoji/ViewOnlyEmoji.d.ts +3 -3
  42. package/dist/components/emoji/emojiStyles.d.ts +6 -1
  43. package/dist/components/footer/Preview.d.ts +7 -7
  44. package/dist/components/header/Header.d.ts +2 -2
  45. package/dist/components/header/Search/BtnClearSearch.d.ts +2 -2
  46. package/dist/components/header/Search/IcnSearch.d.ts +2 -2
  47. package/dist/components/header/Search/Search.d.ts +11 -3
  48. package/dist/components/header/SkinTonePicker/BtnSkinToneVariation.d.ts +12 -12
  49. package/dist/components/header/SkinTonePicker/SkinTonePicker.d.ts +11 -11
  50. package/dist/components/icons/svgIcons.d.ts +4 -0
  51. package/dist/components/main/PickerMainBehaviors.d.ts +4 -0
  52. package/dist/components/main/defaultAppearance.d.ts +12 -0
  53. package/dist/components/main/labelHeight.d.ts +1 -0
  54. package/dist/components/navigation/CategoryButton.d.ts +12 -12
  55. package/dist/components/navigation/CategoryNavIcon.d.ts +4 -4
  56. package/dist/components/navigation/CategoryNavigation.d.ts +19 -2
  57. package/dist/config/categoryConfig.d.ts +34 -34
  58. package/dist/config/cdnUrls.d.ts +2 -2
  59. package/dist/config/compareConfig.d.ts +10 -2
  60. package/dist/config/config.d.ts +166 -64
  61. package/dist/config/customEmojiConfig.d.ts +14 -14
  62. package/dist/config/defaultPickerConfiguration.d.ts +10 -0
  63. package/dist/config/mutableConfig.d.ts +32 -10
  64. package/dist/config/useConfig.d.ts +48 -36
  65. package/dist/data/defaultEmojiData.d.ts +9 -0
  66. package/dist/data/defaultEmojiData.js +40 -0
  67. package/dist/data/emojis-bn.d.mts +39 -0
  68. package/dist/data/emojis-bn.d.ts +38 -2
  69. package/dist/data/emojis-bn.js +25 -2
  70. package/dist/data/emojis-bn.mjs +2 -0
  71. package/dist/data/emojis-da.d.mts +39 -0
  72. package/dist/data/emojis-da.d.ts +38 -2
  73. package/dist/data/emojis-da.js +25 -2
  74. package/dist/data/emojis-da.mjs +2 -0
  75. package/dist/data/emojis-de.d.mts +39 -0
  76. package/dist/data/emojis-de.d.ts +38 -2
  77. package/dist/data/emojis-de.js +25 -2
  78. package/dist/data/emojis-de.mjs +2 -0
  79. package/dist/data/emojis-en-gb.d.mts +39 -0
  80. package/dist/data/emojis-en-gb.d.ts +38 -2
  81. package/dist/data/emojis-en-gb.js +25 -2
  82. package/dist/data/emojis-en-gb.mjs +2 -0
  83. package/dist/data/emojis-en.d.mts +39 -0
  84. package/dist/data/emojis-en.d.ts +38 -2
  85. package/dist/data/emojis-en.js +25 -2
  86. package/dist/data/emojis-en.mjs +2 -0
  87. package/dist/data/emojis-es-mx.d.mts +39 -0
  88. package/dist/data/emojis-es-mx.d.ts +38 -2
  89. package/dist/data/emojis-es-mx.js +25 -2
  90. package/dist/data/emojis-es-mx.mjs +2 -0
  91. package/dist/data/emojis-es.d.mts +39 -0
  92. package/dist/data/emojis-es.d.ts +38 -2
  93. package/dist/data/emojis-es.js +25 -2
  94. package/dist/data/emojis-es.mjs +2 -0
  95. package/dist/data/emojis-et.d.mts +39 -0
  96. package/dist/data/emojis-et.d.ts +38 -2
  97. package/dist/data/emojis-et.js +25 -2
  98. package/dist/data/emojis-et.mjs +2 -0
  99. package/dist/data/emojis-fi.d.mts +39 -0
  100. package/dist/data/emojis-fi.d.ts +38 -2
  101. package/dist/data/emojis-fi.js +25 -2
  102. package/dist/data/emojis-fi.mjs +2 -0
  103. package/dist/data/emojis-fr.d.mts +39 -0
  104. package/dist/data/emojis-fr.d.ts +38 -2
  105. package/dist/data/emojis-fr.js +25 -2
  106. package/dist/data/emojis-fr.mjs +2 -0
  107. package/dist/data/emojis-hi.d.mts +39 -0
  108. package/dist/data/emojis-hi.d.ts +38 -2
  109. package/dist/data/emojis-hi.js +25 -2
  110. package/dist/data/emojis-hi.mjs +2 -0
  111. package/dist/data/emojis-hu.d.mts +39 -0
  112. package/dist/data/emojis-hu.d.ts +38 -2
  113. package/dist/data/emojis-hu.js +25 -2
  114. package/dist/data/emojis-hu.mjs +2 -0
  115. package/dist/data/emojis-it.d.mts +39 -0
  116. package/dist/data/emojis-it.d.ts +38 -2
  117. package/dist/data/emojis-it.js +25 -2
  118. package/dist/data/emojis-it.mjs +2 -0
  119. package/dist/data/emojis-ja.d.mts +39 -0
  120. package/dist/data/emojis-ja.d.ts +38 -2
  121. package/dist/data/emojis-ja.js +25 -2
  122. package/dist/data/emojis-ja.mjs +2 -0
  123. package/dist/data/emojis-ko.d.mts +39 -0
  124. package/dist/data/emojis-ko.d.ts +38 -2
  125. package/dist/data/emojis-ko.js +25 -2
  126. package/dist/data/emojis-ko.mjs +2 -0
  127. package/dist/data/emojis-lt.d.mts +39 -0
  128. package/dist/data/emojis-lt.d.ts +38 -2
  129. package/dist/data/emojis-lt.js +25 -2
  130. package/dist/data/emojis-lt.mjs +2 -0
  131. package/dist/data/emojis-ms.d.mts +39 -0
  132. package/dist/data/emojis-ms.d.ts +38 -2
  133. package/dist/data/emojis-ms.js +25 -2
  134. package/dist/data/emojis-ms.mjs +2 -0
  135. package/dist/data/emojis-nb.d.mts +39 -0
  136. package/dist/data/emojis-nb.d.ts +38 -2
  137. package/dist/data/emojis-nb.js +25 -2
  138. package/dist/data/emojis-nb.mjs +2 -0
  139. package/dist/data/emojis-nl.d.mts +39 -0
  140. package/dist/data/emojis-nl.d.ts +38 -2
  141. package/dist/data/emojis-nl.js +25 -2
  142. package/dist/data/emojis-nl.mjs +2 -0
  143. package/dist/data/emojis-pl.d.mts +39 -0
  144. package/dist/data/emojis-pl.d.ts +38 -2
  145. package/dist/data/emojis-pl.js +25 -2
  146. package/dist/data/emojis-pl.mjs +2 -0
  147. package/dist/data/emojis-pt.d.mts +39 -0
  148. package/dist/data/emojis-pt.d.ts +38 -2
  149. package/dist/data/emojis-pt.js +25 -2
  150. package/dist/data/emojis-pt.mjs +2 -0
  151. package/dist/data/emojis-ru.d.mts +39 -0
  152. package/dist/data/emojis-ru.d.ts +38 -2
  153. package/dist/data/emojis-ru.js +25 -2
  154. package/dist/data/emojis-ru.mjs +2 -0
  155. package/dist/data/emojis-sv.d.mts +39 -0
  156. package/dist/data/emojis-sv.d.ts +38 -2
  157. package/dist/data/emojis-sv.js +25 -2
  158. package/dist/data/emojis-sv.mjs +2 -0
  159. package/dist/data/emojis-th.d.mts +39 -0
  160. package/dist/data/emojis-th.d.ts +38 -2
  161. package/dist/data/emojis-th.js +25 -2
  162. package/dist/data/emojis-th.mjs +2 -0
  163. package/dist/data/emojis-uk.d.mts +39 -0
  164. package/dist/data/emojis-uk.d.ts +38 -2
  165. package/dist/data/emojis-uk.js +25 -2
  166. package/dist/data/emojis-uk.mjs +2 -0
  167. package/dist/data/emojis-vi.d.mts +39 -0
  168. package/dist/data/emojis-vi.d.ts +38 -2
  169. package/dist/data/emojis-vi.js +25 -2
  170. package/dist/data/emojis-vi.mjs +2 -0
  171. package/dist/data/emojis-zh-hant.d.mts +39 -0
  172. package/dist/data/emojis-zh-hant.d.ts +38 -2
  173. package/dist/data/emojis-zh-hant.js +25 -2
  174. package/dist/data/emojis-zh-hant.mjs +2 -0
  175. package/dist/data/emojis-zh.d.mts +39 -0
  176. package/dist/data/emojis-zh.d.ts +38 -2
  177. package/dist/data/emojis-zh.js +25 -2
  178. package/dist/data/emojis-zh.mjs +2 -0
  179. package/dist/data/index.js +1 -0
  180. package/dist/data/registerDefaultEmojiData.d.ts +1 -0
  181. package/dist/data/registerDefaultEmojiData.js +3 -0
  182. package/dist/data-core/pickerData.d.ts +12 -0
  183. package/dist/data-core/prepare.d.ts +23 -0
  184. package/dist/data-core/search.d.ts +13 -0
  185. package/dist/data-core/types.d.ts +23 -0
  186. package/dist/data.d.mts +72 -0
  187. package/dist/data.d.ts +72 -0
  188. package/dist/dataUtils/DataTypes.d.ts +23 -19
  189. package/dist/dataUtils/emojiSelectors.d.ts +15 -16
  190. package/dist/dataUtils/emojiUtils.d.ts +1 -12
  191. package/dist/dataUtils/nativeEmojiSequenceSupport.d.ts +10 -0
  192. package/dist/dataUtils/nativeEmojiSupport.d.ts +40 -0
  193. package/dist/dataUtils/parseNativeEmoji.d.ts +1 -1
  194. package/dist/dataUtils/suggested.d.ts +11 -11
  195. package/dist/dataUtils/suggestedEmojis.d.ts +7 -0
  196. package/dist/esm/chunks/chunk-46BUDQLE.mjs +228 -0
  197. package/dist/esm/chunks/chunk-7ZGTUZFB.mjs +16 -0
  198. package/dist/esm/chunks/chunk-FQIJ4HBW.mjs +25 -0
  199. package/dist/esm/chunks/chunk-KQPOIRSC.mjs +9305 -0
  200. package/dist/esm/chunks/chunk-LO4TPPLH.mjs +43 -0
  201. package/dist/esm/chunks/emojis-6L3GRBAP.mjs +9 -0
  202. package/dist/esm/data.mjs +18 -0
  203. package/dist/esm/index.mjs +389 -0
  204. package/dist/esm/primitives/index.mjs +67 -0
  205. package/dist/hooks/preloadEmoji.d.ts +9 -9
  206. package/dist/hooks/useActiveCategoryScrollDetection.d.ts +11 -11
  207. package/dist/hooks/useCategoryHeight.d.ts +6 -5
  208. package/dist/hooks/useCloseAllOpenToggles.d.ts +2 -2
  209. package/dist/hooks/useDataIdentityStabilityWarning.d.ts +13 -0
  210. package/dist/hooks/useDebouncedState.d.ts +1 -1
  211. package/dist/hooks/useDisallowMouseMove.d.ts +4 -4
  212. package/dist/hooks/useDisallowedEmojis.d.ts +2 -3
  213. package/dist/hooks/useEmojiPreviewEvents.d.ts +3 -3
  214. package/dist/hooks/useEmojiVirtualization.d.ts +21 -17
  215. package/dist/hooks/useFilter.d.ts +10 -16
  216. package/dist/hooks/useFocus.d.ts +3 -3
  217. package/dist/hooks/useInitialLoad.d.ts +2 -2
  218. package/dist/hooks/useIsEmojiHidden.d.ts +8 -8
  219. package/dist/hooks/useIsMounted.d.ts +1 -1
  220. package/dist/hooks/useIsSearchMode.d.ts +1 -1
  221. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +2 -2
  222. package/dist/hooks/useKeyboardNavigation.d.ts +3 -1
  223. package/dist/hooks/useMouseDownHandlers.d.ts +8 -4
  224. package/dist/hooks/useOnFocus.d.ts +1 -1
  225. package/dist/hooks/useOnScroll.d.ts +2 -2
  226. package/dist/hooks/useReactionsFocus.d.ts +1 -0
  227. package/dist/hooks/useRegisterRegion.d.ts +24 -0
  228. package/dist/hooks/useResolvedEmojiData.d.ts +37 -0
  229. package/dist/hooks/useScrollCategoryIntoView.d.ts +1 -1
  230. package/dist/hooks/useSearchController.d.ts +17 -0
  231. package/dist/hooks/useSearchResults.d.ts +8 -0
  232. package/dist/hooks/useSetVariationPicker.d.ts +2 -2
  233. package/dist/hooks/useShouldHideCustomEmojis.d.ts +1 -1
  234. package/dist/hooks/useShouldShowSkinTonePicker.d.ts +4 -4
  235. package/dist/index.d.mts +376 -0
  236. package/dist/index.d.ts +376 -9
  237. package/dist/index.js +2 -8
  238. package/dist/primitives/CategoryNav.d.ts +4 -0
  239. package/dist/primitives/Empty.d.ts +6 -0
  240. package/dist/primitives/List.d.ts +4 -0
  241. package/dist/primitives/LoadError.d.ts +8 -0
  242. package/dist/primitives/Loading.d.ts +4 -0
  243. package/dist/primitives/Panel.d.ts +3 -0
  244. package/dist/primitives/Preview.d.ts +3 -0
  245. package/dist/primitives/Reactions.d.ts +2 -0
  246. package/dist/primitives/Root.d.ts +26 -0
  247. package/dist/primitives/Search.d.ts +5 -0
  248. package/dist/primitives/SearchInput.d.ts +3 -0
  249. package/dist/primitives/SkinTone.d.ts +4 -0
  250. package/dist/primitives/Viewport.d.ts +19 -0
  251. package/dist/primitives/appearance.d.ts +3 -0
  252. package/dist/primitives/components.d.ts +27 -0
  253. package/dist/primitives/hooks.d.ts +48 -0
  254. package/dist/primitives/index.d.mts +561 -0
  255. package/dist/primitives/index.d.ts +561 -0
  256. package/dist/primitives/index.js +2 -0
  257. package/dist/primitives/nativeProps.d.ts +15 -0
  258. package/dist/primitives/scope.d.ts +13 -0
  259. package/dist/primitives/structuralStyles.d.ts +16 -0
  260. package/dist/primitives/tokens.d.ts +18 -0
  261. package/dist/primitives/types.d.ts +85 -0
  262. package/dist/state/activeEmojiStore.d.ts +7 -0
  263. package/dist/state/navigationRegistry.d.ts +61 -0
  264. package/dist/state/regionTraversal.d.ts +20 -0
  265. package/dist/typeRefinements/typeRefinements.d.ts +6 -6
  266. package/dist/types/exposedTypes.d.ts +16 -6
  267. package/dist/types/exposedTypes.js +5 -0
  268. package/dist/virtualization/virtualizationHelpers.d.ts +20 -18
  269. package/llms-full.txt +3680 -0
  270. package/llms.txt +66 -476
  271. package/package.json +204 -66
  272. package/src/DomUtils/categoryNameFromDom.ts +1 -1
  273. package/src/DomUtils/classNames.ts +1 -0
  274. package/src/DomUtils/elementPositionInRow.ts +26 -4
  275. package/src/DomUtils/eventBelongsToPicker.ts +17 -0
  276. package/src/DomUtils/getActiveElement.ts +7 -1
  277. package/src/DomUtils/isJsdom.ts +12 -0
  278. package/src/DomUtils/isRtl.ts +5 -0
  279. package/src/DomUtils/keyboardNavigation.ts +105 -149
  280. package/src/DomUtils/scrollTo.ts +18 -16
  281. package/src/DomUtils/selectors.ts +20 -111
  282. package/src/EmojiPickerReact.tsx +155 -48
  283. package/src/Stylesheet/DedupedStyle.tsx +80 -0
  284. package/src/Stylesheet/stylesheet.tsx +128 -59
  285. package/src/components/Layout/Flex.tsx +12 -11
  286. package/src/components/Reactions/BtnPlus.tsx +61 -51
  287. package/src/components/Reactions/Reactions.tsx +113 -55
  288. package/src/components/atoms/Button.tsx +18 -15
  289. package/src/components/body/EmojiCategory.tsx +77 -40
  290. package/src/components/body/EmojiList.tsx +55 -23
  291. package/src/components/body/EmojiVariationPicker.tsx +113 -66
  292. package/src/components/body/MeasureEmoji.tsx +9 -2
  293. package/src/components/body/listComponents.tsx +79 -0
  294. package/src/components/context/ElementRefContext.tsx +46 -35
  295. package/src/components/context/PickerConfigContext.tsx +55 -40
  296. package/src/components/context/PickerContext.tsx +567 -92
  297. package/src/components/context/PickerDataContext.tsx +110 -99
  298. package/src/components/emoji/BaseEmojiProps.ts +5 -4
  299. package/src/components/emoji/ClickableEmojiButton.tsx +148 -63
  300. package/src/components/emoji/Emoji.tsx +24 -2
  301. package/src/components/emoji/EmojiImg.tsx +13 -12
  302. package/src/components/emoji/ExportedEmoji.tsx +5 -4
  303. package/src/components/emoji/NativeEmoji.tsx +19 -16
  304. package/src/components/emoji/ViewOnlyEmoji.tsx +55 -30
  305. package/src/components/emoji/emojiStyles.ts +12 -11
  306. package/src/components/footer/Preview.tsx +86 -91
  307. package/src/components/header/Header.tsx +21 -6
  308. package/src/components/header/Search/BtnClearSearch.tsx +69 -55
  309. package/src/components/header/Search/IcnSearch.tsx +21 -21
  310. package/src/components/header/Search/Search.tsx +77 -137
  311. package/src/components/header/SkinTonePicker/BtnSkinToneVariation.tsx +99 -62
  312. package/src/components/header/SkinTonePicker/SkinTonePicker.tsx +84 -46
  313. package/src/components/icons/svgIcons.ts +17 -0
  314. package/src/components/main/PickerMainBehaviors.tsx +163 -0
  315. package/src/components/main/defaultAppearance.tsx +188 -0
  316. package/src/components/main/labelHeight.ts +5 -0
  317. package/src/components/navigation/CategoryButton.tsx +83 -57
  318. package/src/components/navigation/CategoryNavIcon.tsx +73 -194
  319. package/src/components/navigation/CategoryNavigation.tsx +118 -46
  320. package/src/config/categoryConfig.ts +7 -3
  321. package/src/config/cdnUrls.ts +11 -21
  322. package/src/config/compareConfig.ts +128 -30
  323. package/src/config/config.ts +228 -24
  324. package/src/config/defaultPickerConfiguration.ts +7 -0
  325. package/src/config/mutableConfig.ts +44 -20
  326. package/src/config/useConfig.ts +130 -37
  327. package/src/data/defaultEmojiData.ts +49 -0
  328. package/src/data/registerDefaultEmojiData.ts +8 -0
  329. package/src/data-core/pickerData.ts +173 -0
  330. package/src/data-core/prepare.ts +178 -0
  331. package/src/data-core/search.ts +122 -0
  332. package/src/data-core/types.ts +36 -0
  333. package/src/data.ts +10 -0
  334. package/src/dataUtils/DataTypes.ts +4 -0
  335. package/src/dataUtils/emojiSelectors.ts +58 -63
  336. package/src/dataUtils/emojiUtils.ts +17 -74
  337. package/src/dataUtils/nativeEmojiSequenceSupport.ts +116 -0
  338. package/src/dataUtils/nativeEmojiSupport.ts +160 -0
  339. package/src/dataUtils/suggested.ts +8 -4
  340. package/src/dataUtils/suggestedEmojis.ts +92 -0
  341. package/src/env.d.ts +4 -0
  342. package/src/hooks/preloadEmoji.ts +3 -3
  343. package/src/hooks/useActiveCategoryScrollDetection.ts +10 -1
  344. package/src/hooks/useCategoryHeight.ts +82 -8
  345. package/src/hooks/useDataIdentityStabilityWarning.ts +86 -0
  346. package/src/hooks/useDebouncedState.ts +13 -1
  347. package/src/hooks/useDisallowedEmojis.ts +26 -42
  348. package/src/hooks/useEmojiPreviewEvents.ts +43 -10
  349. package/src/hooks/useEmojiVirtualization.tsx +38 -4
  350. package/src/hooks/useFilter.ts +85 -127
  351. package/src/hooks/useFocus.ts +14 -24
  352. package/src/hooks/useIsEmojiHidden.ts +10 -6
  353. package/src/hooks/useKeyboardNavigation.ts +322 -429
  354. package/src/hooks/useMouseDownHandlers.ts +91 -16
  355. package/src/hooks/useOnFocus.ts +12 -3
  356. package/src/hooks/useOnScroll.ts +18 -2
  357. package/src/hooks/useReactionsFocus.ts +118 -0
  358. package/src/hooks/useRegisterRegion.ts +92 -0
  359. package/src/hooks/useResolvedEmojiData.ts +200 -0
  360. package/src/hooks/useScrollCategoryIntoView.ts +74 -12
  361. package/src/hooks/useSearchController.ts +369 -0
  362. package/src/hooks/useSearchResults.ts +51 -0
  363. package/src/hooks/useSetVariationPicker.ts +4 -1
  364. package/src/index.tsx +67 -5
  365. package/src/primitives/CategoryNav.tsx +40 -0
  366. package/src/primitives/Empty.tsx +68 -0
  367. package/src/primitives/List.tsx +61 -0
  368. package/src/primitives/LoadError.tsx +38 -0
  369. package/src/primitives/Loading.tsx +60 -0
  370. package/src/primitives/Panel.tsx +47 -0
  371. package/src/primitives/Preview.tsx +38 -0
  372. package/src/primitives/Reactions.tsx +2 -0
  373. package/src/primitives/Root.tsx +398 -0
  374. package/src/primitives/Search.tsx +41 -0
  375. package/src/primitives/SearchInput.tsx +110 -0
  376. package/src/primitives/SkinTone.tsx +76 -0
  377. package/src/primitives/Viewport.tsx +204 -0
  378. package/src/primitives/appearance.tsx +7 -0
  379. package/src/primitives/components.tsx +30 -0
  380. package/src/primitives/hooks.ts +165 -0
  381. package/src/primitives/index.ts +94 -0
  382. package/src/primitives/nativeProps.ts +90 -0
  383. package/src/primitives/scope.tsx +109 -0
  384. package/src/primitives/structuralStyles.tsx +133 -0
  385. package/src/primitives/tokens.ts +149 -0
  386. package/src/primitives/types.ts +192 -0
  387. package/src/state/activeEmojiStore.ts +39 -0
  388. package/src/state/navigationRegistry.ts +209 -0
  389. package/src/state/regionTraversal.ts +116 -0
  390. package/src/svg.d.ts +2 -2
  391. package/src/types/exposedTypes.ts +28 -1
  392. package/src/virtualization/virtualizationHelpers.ts +20 -6
  393. package/dist/components/body/Body.d.ts +0 -2
  394. package/dist/components/main/PickerMain.d.ts +0 -7
  395. package/dist/dataUtils/alphaNumericEmojiIndex.d.ts +0 -5
  396. package/dist/emoji-picker-react.cjs.development.js +0 -31413
  397. package/dist/emoji-picker-react.cjs.development.js.map +0 -1
  398. package/dist/emoji-picker-react.cjs.production.min.js +0 -2
  399. package/dist/emoji-picker-react.cjs.production.min.js.map +0 -1
  400. package/dist/emoji-picker-react.esm.js +0 -31411
  401. package/dist/emoji-picker-react.esm.js.map +0 -1
  402. package/dist/hooks/useHideEmojisByUniocode.d.ts +0 -1
  403. package/src/components/body/Body.tsx +0 -43
  404. package/src/components/main/PickerMain.tsx +0 -249
  405. package/src/dataUtils/alphaNumericEmojiIndex.ts +0 -21
@@ -4,47 +4,145 @@ import { UserCategoryConfig } from './categoryConfig';
4
4
  import { PickerConfig } from './config';
5
5
  import { CustomEmoji } from './customEmojiConfig';
6
6
 
7
- // eslint-disable-next-line complexity
7
+ // Callbacks are read through the mutable config ref, so a new function
8
+ // identity must never rebuild configuration or rerender the memoized tree.
9
+ const CALLBACK_KEYS: ReadonlySet<string> = new Set([
10
+ 'onEmojiClick',
11
+ 'onReactionClick',
12
+ 'onSkinToneChange',
13
+ 'onSearchChange',
14
+ 'onReactionsModeChange',
15
+ ]);
16
+
17
+ /**
18
+ * Content equality over every config key. Iterating the union of keys
19
+ * (rather than a hand-maintained list) means a prop added later is
20
+ * compared by default instead of being silently ignored after mount —
21
+ * which is how `reactions`, `previewConfig`, `hiddenEmojis`,
22
+ * `allowExpandReactions`, `categoryIcons`, `getEmojiUrl` and `nonce`
23
+ * updates used to be dropped.
24
+ */
8
25
  export function compareConfig(prev: PickerConfig, next: PickerConfig) {
9
- const prevCustomEmojis = prev.customEmojis ?? [];
10
- const nextCustomEmojis = next.customEmojis ?? [];
26
+ const prevRecord = prev as Record<string, unknown>;
27
+ const nextRecord = next as Record<string, unknown>;
28
+ const keys = Object.keys(prevRecord).concat(
29
+ Object.keys(nextRecord).filter((key) => !(key in prevRecord)),
30
+ );
31
+
32
+ for (const key of keys) {
33
+ if (CALLBACK_KEYS.has(key)) {
34
+ continue;
35
+ }
36
+ if (!configValueEqual(key, prevRecord[key], nextRecord[key])) {
37
+ return false;
38
+ }
39
+ }
40
+ return true;
41
+ }
42
+
43
+ type ValueComparator = (prev: unknown, next: unknown) => boolean;
44
+
45
+ const identityOnly: ValueComparator = () => false;
46
+
47
+ // Keys with dedicated structural comparisons. `emojiData` and `style` are
48
+ // identity-only: datasets are large (identity is the contract, see
49
+ // useDataIdentityStabilityWarning) and style objects feed the DOM.
50
+ const KEY_COMPARATORS: Record<string, ValueComparator> = {
51
+ customEmojis: (prev, next) =>
52
+ customEmojisEqual(
53
+ (prev as CustomEmoji[] | undefined) ?? [],
54
+ (next as CustomEmoji[] | undefined) ?? [],
55
+ ),
56
+ categories: (prev, next) =>
57
+ categoriesEqual(
58
+ prev as UserCategoryConfig | undefined,
59
+ next as UserCategoryConfig | undefined,
60
+ ),
61
+ suggestedEmojis: (prev, next) =>
62
+ suggestedEmojisEqual(
63
+ prev as string[] | undefined,
64
+ next as string[] | undefined,
65
+ ),
66
+ emojiData: identityOnly,
67
+ style: identityOnly,
68
+ };
69
+
70
+ function configValueEqual(key: string, prev: unknown, next: unknown): boolean {
71
+ if (prev === next) {
72
+ return true;
73
+ }
74
+ const comparator = KEY_COMPARATORS[key];
75
+ if (comparator) {
76
+ return comparator(prev, next);
77
+ }
78
+ return genericValueEqual(prev, next);
79
+ }
80
+
81
+ function genericValueEqual(prev: unknown, next: unknown): boolean {
82
+ if (Array.isArray(prev) && Array.isArray(next)) {
83
+ return shallowArrayEqual(prev, next);
84
+ }
85
+ if (isPlainObject(prev) && isPlainObject(next)) {
86
+ return shallowObjectEqual(prev, next);
87
+ }
88
+ return false;
89
+ }
90
+
91
+ function shallowArrayEqual(prev: unknown[], next: unknown[]): boolean {
11
92
  return (
12
- prev.open === next.open &&
13
- prev.emojiVersion === next.emojiVersion &&
14
- prev.reactionsDefaultOpen === next.reactionsDefaultOpen &&
15
- prev.searchPlaceHolder === next.searchPlaceHolder &&
16
- prev.searchPlaceholder === next.searchPlaceholder &&
17
- prev.searchClearButtonLabel === next.searchClearButtonLabel &&
18
- prev.defaultSkinTone === next.defaultSkinTone &&
19
- prev.skinTonesDisabled === next.skinTonesDisabled &&
20
- prev.autoFocusSearch === next.autoFocusSearch &&
21
- prev.emojiStyle === next.emojiStyle &&
22
- prev.theme === next.theme &&
23
- prev.suggestedEmojisMode === next.suggestedEmojisMode &&
24
- prev.lazyLoadEmojis === next.lazyLoadEmojis &&
25
- prev.className === next.className &&
26
- prev.height === next.height &&
27
- prev.width === next.width &&
28
- prev.style === next.style &&
29
- prev.searchDisabled === next.searchDisabled &&
30
- prev.skinTonePickerLocation === next.skinTonePickerLocation &&
31
- prevCustomEmojis.length === nextCustomEmojis.length &&
32
- customEmojisEqual(prevCustomEmojis, nextCustomEmojis) &&
33
- categoriesEqual(prev.categories, next.categories) &&
34
- prev.emojiData === next.emojiData
93
+ prev.length === next.length &&
94
+ prev.every((entry, index) => entry === next[index])
95
+ );
96
+ }
97
+
98
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
99
+ if (value === null || typeof value !== 'object') {
100
+ return false;
101
+ }
102
+ const proto = Object.getPrototypeOf(value);
103
+ return proto === Object.prototype || proto === null;
104
+ }
105
+
106
+ function shallowObjectEqual(
107
+ prev: Record<string, unknown>,
108
+ next: Record<string, unknown>,
109
+ ): boolean {
110
+ const prevKeys = Object.keys(prev);
111
+ if (prevKeys.length !== Object.keys(next).length) {
112
+ return false;
113
+ }
114
+ return prevKeys.every(
115
+ (key) =>
116
+ Object.prototype.hasOwnProperty.call(next, key) &&
117
+ prev[key] === next[key],
35
118
  );
36
119
  }
37
120
 
121
+ /**
122
+ * Element-wise equality for caller-defined suggestions. Compared by value
123
+ * (not identity) so inline literals with equal contents don't rebuild the
124
+ * merged configuration on every parent render.
125
+ */
126
+ function suggestedEmojisEqual(
127
+ prev: string[] | undefined,
128
+ next: string[] | undefined,
129
+ ): boolean {
130
+ if (prev === next) {
131
+ return true;
132
+ }
133
+ if (!prev || !next || prev.length !== next.length) {
134
+ return false;
135
+ }
136
+ return prev.every((entry, index) => entry === next[index]);
137
+ }
138
+
38
139
  /**
39
140
  * Structural content equality for custom emojis. Length alone misses
40
141
  * regroups and swaps, which would leave merged categories, search, and
41
142
  * sections stale. Fields are compared element-wise (never serialized
42
143
  * with delimiters) so user-controlled values cannot collide.
43
144
  */
44
- function customEmojisEqual(
45
- prev: CustomEmoji[],
46
- next: CustomEmoji[],
47
- ): boolean {
145
+ function customEmojisEqual(prev: CustomEmoji[], next: CustomEmoji[]): boolean {
48
146
  if (prev.length !== next.length) {
49
147
  return false;
50
148
  }
@@ -3,19 +3,25 @@ import * as React from 'react';
3
3
  import { DEFAULT_REACTIONS } from '../components/Reactions/DEFAULT_REACTIONS';
4
4
  import { GetEmojiUrl } from '../components/emoji/BaseEmojiProps';
5
5
  import { emojiUrlByUnified } from '../dataUtils/emojiUtils';
6
+ import type { EmojiDataInput } from '../hooks/useResolvedEmojiData';
6
7
  import {
7
8
  CategoryIcons,
8
9
  EmojiClickData,
9
10
  EmojiData,
10
11
  EmojiStyle,
12
+ EmojiStyleValue,
11
13
  SkinTonePickerLocation,
12
14
  SkinTones,
15
+ SkinTonesValue,
13
16
  SuggestionMode,
17
+ SuggestionModeValue,
14
18
  Theme,
19
+ ThemeValue,
15
20
  } from '../types/exposedTypes';
16
21
 
17
22
  import {
18
23
  CategoriesConfig,
24
+ UserCategoryConfig,
19
25
  baseCategoriesConfig,
20
26
  mergeCategoriesConfig,
21
27
  } from './categoryConfig';
@@ -24,6 +30,9 @@ import { CustomEmoji } from './customEmojiConfig';
24
30
  const KNOWN_FAILING_EMOJIS = ['2640-fe0f', '2642-fe0f', '2695-fe0f'];
25
31
 
26
32
  export const DEFAULT_SEARCH_PLACEHOLDER = 'Search';
33
+ export const DEFAULT_PICKER_WIDTH = 350;
34
+ export const DEFAULT_PICKER_HEIGHT = 450;
35
+ export const DEFAULT_SEARCH_INPUT_LABEL = 'Type to search for an emoji';
27
36
  export const DEFAULT_SEARCH_CLEAR_BUTTON_LABEL = 'Clear';
28
37
  export const SEARCH_RESULTS_NO_RESULTS_FOUND = 'No results found';
29
38
  export const SEARCH_RESULTS_SUFFIX =
@@ -33,13 +42,78 @@ export const SEARCH_RESULTS_ONE_RESULT_FOUND =
33
42
  export const SEARCH_RESULTS_MULTIPLE_RESULTS_FOUND =
34
43
  '%n results' + SEARCH_RESULTS_SUFFIX;
35
44
 
36
- export function mergeConfig(
37
- userConfig: PickerConfig = {},
38
- ): PickerConfigInternal {
39
- const base = basePickerConfig();
45
+ /**
46
+ * Every user-facing string the picker renders or announces. All keys are
47
+ * optional on the `labels` prop; anything omitted keeps its English
48
+ * default. Category names come from `categories` / localized `emojiData`,
49
+ * and the preview caption from `previewConfig.defaultCaption`.
50
+ */
51
+ export type PickerLabels = {
52
+ searchPlaceholder: string;
53
+ /** Accessible name of the search input. */
54
+ searchLabel: string;
55
+ searchClear: string;
56
+ /** Live-region announcement and visible empty state. */
57
+ searchResultsNone: string;
58
+ searchResultsOne: string;
59
+ /** `%n` is replaced with the result count. */
60
+ searchResultsMany: string;
61
+ categoryNavigation: string;
62
+ reactions: string;
63
+ expandReactions: string;
64
+ /** Shown by the Loading part while the dataset loads. */
65
+ loading: string;
66
+ loadingError: string;
67
+ retryLoading: string;
68
+ skinToneNeutral: string;
69
+ skinToneLight: string;
70
+ skinToneMediumLight: string;
71
+ skinToneMedium: string;
72
+ skinToneMediumDark: string;
73
+ skinToneDark: string;
74
+ };
75
+
76
+ // English defaults, identical to the v4 strings so existing queries and
77
+ // snapshots keep matching.
78
+ export const DEFAULT_LABELS: PickerLabels = {
79
+ searchPlaceholder: DEFAULT_SEARCH_PLACEHOLDER,
80
+ searchLabel: DEFAULT_SEARCH_INPUT_LABEL,
81
+ searchClear: DEFAULT_SEARCH_CLEAR_BUTTON_LABEL,
82
+ searchResultsNone: SEARCH_RESULTS_NO_RESULTS_FOUND,
83
+ searchResultsOne: SEARCH_RESULTS_ONE_RESULT_FOUND,
84
+ searchResultsMany: SEARCH_RESULTS_MULTIPLE_RESULTS_FOUND,
85
+ categoryNavigation: 'Category navigation',
86
+ reactions: 'Reactions',
87
+ expandReactions: 'Show all Emojis',
88
+ loading: 'Loading…',
89
+ loadingError: 'Could not load emojis.',
90
+ retryLoading: 'Try again',
91
+ skinToneNeutral: 'Skin tone NEUTRAL',
92
+ skinToneLight: 'Skin tone LIGHT',
93
+ skinToneMediumLight: 'Skin tone MEDIUM_LIGHT',
94
+ skinToneMedium: 'Skin tone MEDIUM',
95
+ skinToneMediumDark: 'Skin tone MEDIUM_DARK',
96
+ skinToneDark: 'Skin tone DARK',
97
+ };
40
98
 
41
- // Get localized mood from emojiData, fallback to base default
42
- // Get localized mood from emojiData, fallback to base default
99
+ type ResolvedUserConfig = Omit<PickerConfig, 'emojiData'> & {
100
+ emojiData?: EmojiData;
101
+ };
102
+
103
+ function withResolvedEmojiData(config: PickerConfig): ResolvedUserConfig {
104
+ return (
105
+ typeof config.emojiData === 'function'
106
+ ? { ...config, emojiData: undefined }
107
+ : config
108
+ ) as ResolvedUserConfig;
109
+ }
110
+
111
+ // Localized mood caption from emojiData is the default; an explicit
112
+ // previewConfig.defaultCaption still wins.
113
+ function mergePreviewConfig(
114
+ base: PreviewConfig,
115
+ userConfig: ResolvedUserConfig,
116
+ ): PreviewConfig {
43
117
  const localizedMood = (
44
118
  userConfig.emojiData?.categories as Record<
45
119
  string,
@@ -47,16 +121,44 @@ export function mergeConfig(
47
121
  >
48
122
  )?.preview_mood?.name;
49
123
 
50
- const previewConfig = {
51
- ...base.previewConfig,
52
- // Localized mood is default, but user can override
124
+ return {
125
+ ...base,
53
126
  ...(localizedMood && !userConfig.previewConfig?.defaultCaption
54
127
  ? { defaultCaption: localizedMood }
55
128
  : {}),
56
129
  ...(userConfig.previewConfig ?? {}),
57
130
  };
131
+ }
132
+
133
+ /**
134
+ * The default style is native, but a caller-supplied image URL resolver is
135
+ * an explicit request for images: without an explicit `emojiStyle` it keeps
136
+ * v4's image default (Apple), so the resolver is actually used.
137
+ */
138
+ export function resolveEmojiStyle(
139
+ emojiStyle: EmojiStyleValue | undefined,
140
+ customImageSource: unknown,
141
+ ): EmojiStyleValue {
142
+ if (emojiStyle !== undefined) {
143
+ return emojiStyle;
144
+ }
145
+ return customImageSource ? EmojiStyle.APPLE : EmojiStyle.NATIVE;
146
+ }
147
+
148
+ export function mergeConfig(
149
+ rawUserConfig: PickerConfig = {},
150
+ ): PickerConfigInternal {
151
+ const base = basePickerConfig();
152
+ // Root resolves loaders before configuration is merged; a loader that
153
+ // reaches this point (direct internal use) is treated as "not loaded".
154
+ const userConfig = withResolvedEmojiData(rawUserConfig);
155
+ const previewConfig = mergePreviewConfig(base.previewConfig, userConfig);
58
156
 
59
- const config = Object.assign(base, userConfig);
157
+ const config = Object.assign(base, userConfig) as PickerConfigInternal;
158
+ config.emojiStyle = resolveEmojiStyle(
159
+ userConfig.emojiStyle,
160
+ userConfig.getEmojiUrl,
161
+ );
60
162
 
61
163
  const categories = mergeCategoriesConfig(
62
164
  userConfig.categories,
@@ -67,13 +169,23 @@ export function mergeConfig(
67
169
  userConfig.customEmojis,
68
170
  );
69
171
 
172
+ // Dataset ids are lowercase; accept the uppercase spelling consumers
173
+ // copy from docs and tools (and stray whitespace), like `reactions` and
174
+ // `suggestedEmojis` already do.
70
175
  config.hiddenEmojis.forEach((emoji) => {
71
- config.unicodeToHide.add(emoji);
176
+ const id = String(emoji).trim().toLowerCase();
177
+ if (id) config.unicodeToHide.add(id);
72
178
  });
73
179
 
74
- const skinTonePickerLocation = config.searchDisabled
75
- ? SkinTonePickerLocation.PREVIEW
76
- : config.skinTonePickerLocation;
180
+ // The built-in tone control needs a host region: without Search a
181
+ // search-located control moves to the preview, and without the preview
182
+ // a preview-located control moves to Search. With neither region it is
183
+ // off (NONE), the same as the explicit placement.
184
+ const skinTonePickerLocation = resolveSkinTonePickerLocation(
185
+ config.skinTonePickerLocation,
186
+ config.searchDisabled,
187
+ previewConfig.showPreview,
188
+ );
77
189
 
78
190
  return {
79
191
  ...config,
@@ -83,6 +195,24 @@ export function mergeConfig(
83
195
  };
84
196
  }
85
197
 
198
+ export function resolveSkinTonePickerLocation(
199
+ location: SkinTonePickerLocation,
200
+ searchDisabled: boolean,
201
+ showPreview: boolean,
202
+ ): SkinTonePickerLocation {
203
+ if (location === SkinTonePickerLocation.SEARCH && searchDisabled) {
204
+ return showPreview
205
+ ? SkinTonePickerLocation.PREVIEW
206
+ : SkinTonePickerLocation.NONE;
207
+ }
208
+ if (location === SkinTonePickerLocation.PREVIEW && !showPreview) {
209
+ return searchDisabled
210
+ ? SkinTonePickerLocation.NONE
211
+ : SkinTonePickerLocation.SEARCH;
212
+ }
213
+ return location;
214
+ }
215
+
86
216
  export function basePickerConfig(): PickerConfigInternal {
87
217
  return {
88
218
  autoFocusSearch: true,
@@ -90,10 +220,10 @@ export function basePickerConfig(): PickerConfigInternal {
90
220
  className: '',
91
221
  customEmojis: [],
92
222
  defaultSkinTone: SkinTones.NEUTRAL,
93
- emojiStyle: EmojiStyle.APPLE,
223
+ emojiStyle: EmojiStyle.NATIVE,
94
224
  emojiVersion: null,
95
225
  getEmojiUrl: emojiUrlByUnified,
96
- height: 450,
226
+ height: DEFAULT_PICKER_HEIGHT,
97
227
  lazyLoadEmojis: false,
98
228
  previewConfig: {
99
229
  ...basePreviewConfig,
@@ -108,7 +238,7 @@ export function basePickerConfig(): PickerConfigInternal {
108
238
  suggestedEmojisMode: SuggestionMode.FREQUENT,
109
239
  theme: Theme.LIGHT,
110
240
  unicodeToHide: new Set<string>(KNOWN_FAILING_EMOJIS),
111
- width: 350,
241
+ width: DEFAULT_PICKER_WIDTH,
112
242
  reactionsDefaultOpen: false,
113
243
  reactions: DEFAULT_REACTIONS,
114
244
  open: true,
@@ -117,6 +247,16 @@ export function basePickerConfig(): PickerConfigInternal {
117
247
  emojiData: undefined,
118
248
  categoryIcons: {},
119
249
  nonce: undefined,
250
+ searchValue: undefined,
251
+ defaultSearchValue: undefined,
252
+ onSearchChange: undefined,
253
+ searchLabel: undefined,
254
+ suggestedEmojis: undefined,
255
+ onReactionsModeChange: undefined,
256
+ labels: undefined,
257
+ skinTone: undefined,
258
+ cssLayer: undefined,
259
+ columns: undefined,
120
260
  };
121
261
  }
122
262
 
@@ -125,13 +265,13 @@ export type PickerConfigInternal = {
125
265
  searchPlaceHolder: string;
126
266
  searchPlaceholder: string;
127
267
  searchClearButtonLabel: string;
128
- defaultSkinTone: SkinTones;
268
+ defaultSkinTone: SkinTonesValue;
129
269
  skinTonesDisabled: boolean;
130
270
  autoFocusSearch: boolean;
131
- emojiStyle: EmojiStyle;
271
+ emojiStyle: EmojiStyleValue;
132
272
  categories: CategoriesConfig;
133
- theme: Theme;
134
- suggestedEmojisMode: SuggestionMode;
273
+ theme: ThemeValue;
274
+ suggestedEmojisMode: SuggestionModeValue;
135
275
  lazyLoadEmojis: boolean;
136
276
  previewConfig: PreviewConfig;
137
277
  className: string;
@@ -151,6 +291,48 @@ export type PickerConfigInternal = {
151
291
  emojiData?: EmojiData;
152
292
  categoryIcons: CategoryIcons;
153
293
  nonce?: string;
294
+ /**
295
+ * Controlled search value (raw user text). When present, it is the
296
+ * accepted visible source of truth; user edits emit `onSearchChange`
297
+ * proposals instead of committing locally.
298
+ */
299
+ searchValue?: string;
300
+ /** Uncontrolled initial search value, read once per mounted lifetime. */
301
+ defaultSearchValue?: string;
302
+ /** Emitted synchronously with each committed (uncontrolled) or proposed (controlled) user edit. */
303
+ onSearchChange?: (value: string) => void;
304
+ /** Accessible label for the search input. Defaults to English. */
305
+ searchLabel?: string;
306
+ /**
307
+ * Caller-defined Suggested category contents/order (unified or custom
308
+ * IDs). While present, `suggestedEmojisMode` is ignored for contents.
309
+ */
310
+ suggestedEmojis?: string[];
311
+ /** Observes compact-reactions vs full-picker transitions. */
312
+ onReactionsModeChange?: (reactionsOpen: boolean) => void;
313
+ /**
314
+ * Localized user-facing strings. Takes precedence over the individual
315
+ * `searchPlaceholder` / `searchLabel` / `searchClearButtonLabel` props.
316
+ */
317
+ labels?: Partial<PickerLabels>;
318
+ /**
319
+ * Controlled active skin tone. Pair with `onSkinToneChange`; while
320
+ * present, `defaultSkinTone` is ignored.
321
+ */
322
+ skinTone?: SkinTonesValue;
323
+ /**
324
+ * Emit the picker's CSS inside this cascade layer (e.g. "epr"), for
325
+ * layered CSS frameworks such as Tailwind v4 whose utilities cannot
326
+ * beat unlayered CSS. Declare the layer first in your CSS:
327
+ * `@layer epr, theme, base, components, utilities;`. Default: unlayered.
328
+ */
329
+ cssLayer?: string;
330
+ /**
331
+ * Emojis per row. The picker then sizes its width to fit those columns
332
+ * unless you set a width; a narrower container shows fewer columns.
333
+ * Default: as many as the width fits.
334
+ */
335
+ columns?: number;
154
336
  };
155
337
 
156
338
  export type PreviewConfig = {
@@ -170,7 +352,22 @@ type ConfigExternal = {
170
352
  onEmojiClick: MouseDownEvent;
171
353
  onReactionClick: MouseDownEvent;
172
354
  onSkinToneChange: OnSkinToneChange;
173
- } & Omit<PickerConfigInternal, 'previewConfig' | 'unicodeToHide'>;
355
+ /**
356
+ * User-supplied allowlist/order/merge input. Bare `Categories` members
357
+ * are accepted alongside full configs (as in v4 usage and this repo's
358
+ * own tests); the merged internal representation stays `CategoriesConfig`.
359
+ */
360
+ categories: UserCategoryConfig;
361
+ /**
362
+ * Dataset: an object (synchronous, SSR-safe), or a loader such as
363
+ * `() => import('emoji-picker-react/data/emojis-fr')` to code-split it.
364
+ * Omitted: the bundled English dataset.
365
+ */
366
+ emojiData: EmojiDataInput;
367
+ } & Omit<
368
+ PickerConfigInternal,
369
+ 'previewConfig' | 'unicodeToHide' | 'categories' | 'emojiData'
370
+ >;
174
371
 
175
372
  export type PickerConfig = Partial<ConfigExternal>;
176
373
 
@@ -181,8 +378,15 @@ export type MouseDownEvent = (
181
378
  event: MouseEvent,
182
379
  api?: OnEmojiClickApi,
183
380
  ) => void;
184
- export type OnSkinToneChange = (emoji: SkinTones) => void;
381
+ export type OnSkinToneChange = (skinTone: SkinTones) => void;
382
+
383
+ /** The `onEmojiClick` / `onReactionClick` callback signature. */
384
+ export type EmojiClickHandler = MouseDownEvent;
385
+ /** The `onSkinToneChange` callback signature. */
386
+ export type SkinToneChangeHandler = OnSkinToneChange;
185
387
 
186
- type OnEmojiClickApi = {
388
+ /** Third argument of `onEmojiClick` / `onReactionClick`. */
389
+ export type OnEmojiClickApi = {
390
+ /** Return to the compact reactions bar (no-op when reactions are off). */
187
391
  collapseToReactions: () => void;
188
392
  };
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+
3
+ import type { PickerConfig } from './config';
4
+
5
+ /** Private bridge: only the assembled picker translates legacy switches. */
6
+ export const DefaultPickerConfiguration =
7
+ React.createContext<PickerConfig | null>(null);
@@ -6,38 +6,62 @@ export type MutableConfig = {
6
6
  onEmojiClick?: MouseDownEvent;
7
7
  onReactionClick?: MouseDownEvent;
8
8
  onSkinToneChange?: OnSkinToneChange;
9
+ onSearchChange?: (value: string) => void;
10
+ onReactionsModeChange?: (reactionsOpen: boolean) => void;
9
11
  };
10
12
 
11
- export const MutableConfigContext = React.createContext<
12
- React.MutableRefObject<MutableConfig>
13
- >({} as React.MutableRefObject<MutableConfig>);
13
+ /**
14
+ * Sentinel default: marks the absence of a provider. Root adopts the
15
+ * wrapper-provided ref across the default picker memo boundary and
16
+ * owns one otherwise (including nested bare Roots). Callbacks stay fresh
17
+ * without depending on the memoized default tree rerendering.
18
+ */
19
+ export const NO_MUTABLE_PROVIDER = {} as React.MutableRefObject<MutableConfig>;
20
+
21
+ export const MutableConfigContext = /* @__PURE__ */ React.createContext({
22
+ ref: NO_MUTABLE_PROVIDER,
23
+ inheritToRoot: false,
24
+ });
25
+
26
+ export function MutableConfigProvider({
27
+ value,
28
+ inheritToRoot = false,
29
+ children,
30
+ }: {
31
+ value: React.MutableRefObject<MutableConfig>;
32
+ inheritToRoot?: boolean;
33
+ children: React.ReactNode;
34
+ }) {
35
+ const context = React.useMemo(
36
+ () => ({ ref: value, inheritToRoot }),
37
+ [value, inheritToRoot],
38
+ );
39
+ return React.createElement(
40
+ MutableConfigContext.Provider,
41
+ { value: context },
42
+ children,
43
+ );
44
+ }
14
45
 
15
46
  export function useMutableConfig(): React.MutableRefObject<MutableConfig> {
16
47
  const mutableConfig = React.useContext(MutableConfigContext);
17
- return mutableConfig;
48
+ return mutableConfig.ref;
49
+ }
50
+
51
+ /** Only the default wrapper crosses its own memo boundary into Root. */
52
+ export function useInheritedMutableConfig(): React.MutableRefObject<MutableConfig> {
53
+ const value = React.useContext(MutableConfigContext);
54
+ return value.inheritToRoot ? value.ref : NO_MUTABLE_PROVIDER;
18
55
  }
19
56
 
20
57
  export function useDefineMutableConfig(
21
58
  config: MutableConfig,
22
59
  ): React.MutableRefObject<MutableConfig> {
23
- const MutableConfigRef = React.useRef<MutableConfig>({
24
- onEmojiClick: config.onEmojiClick || emptyFunc,
25
- onReactionClick: config.onReactionClick || config.onEmojiClick,
26
- onSkinToneChange: config.onSkinToneChange || emptyFunc,
27
- });
28
-
29
- React.useEffect(() => {
30
- MutableConfigRef.current.onEmojiClick = config.onEmojiClick || emptyFunc;
31
- MutableConfigRef.current.onReactionClick =
32
- config.onReactionClick || config.onEmojiClick;
33
- }, [config.onEmojiClick, config.onReactionClick]);
60
+ const MutableConfigRef = React.useRef<MutableConfig>(config);
34
61
 
35
62
  React.useEffect(() => {
36
- MutableConfigRef.current.onSkinToneChange =
37
- config.onSkinToneChange || emptyFunc;
38
- }, [config.onSkinToneChange]);
63
+ Object.assign(MutableConfigRef.current, config);
64
+ });
39
65
 
40
66
  return MutableConfigRef;
41
67
  }
42
-
43
- function emptyFunc() {}