emoji-picker-react 4.22.3 → 5.0.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.
Files changed (409) hide show
  1. package/README.md +331 -49
  2. package/dist/DomUtils/categoryNameFromDom.d.ts +1 -1
  3. package/dist/DomUtils/classNames.d.ts +23 -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 +15 -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/skinToneVariations.js +2 -2
  183. package/dist/data/skinToneVariations.ts +8 -7
  184. package/dist/data-core/pickerData.d.ts +12 -0
  185. package/dist/data-core/prepare.d.ts +23 -0
  186. package/dist/data-core/search.d.ts +13 -0
  187. package/dist/data-core/types.d.ts +23 -0
  188. package/dist/data.d.mts +72 -0
  189. package/dist/data.d.ts +72 -0
  190. package/dist/dataUtils/DataTypes.d.ts +23 -19
  191. package/dist/dataUtils/emojiSelectors.d.ts +15 -16
  192. package/dist/dataUtils/emojiUtils.d.ts +1 -12
  193. package/dist/dataUtils/nativeEmojiSequenceSupport.d.ts +10 -0
  194. package/dist/dataUtils/nativeEmojiSupport.d.ts +40 -0
  195. package/dist/dataUtils/parseNativeEmoji.d.ts +1 -1
  196. package/dist/dataUtils/suggested.d.ts +11 -11
  197. package/dist/dataUtils/suggestedEmojis.d.ts +7 -0
  198. package/dist/esm/chunks/chunk-7ZGTUZFB.mjs +8025 -0
  199. package/dist/esm/chunks/chunk-ACXAQEKG.mjs +149 -0
  200. package/dist/esm/chunks/chunk-F2KS7DCA.mjs +6735 -0
  201. package/dist/esm/chunks/chunk-L5W4PFRJ.mjs +14 -0
  202. package/dist/esm/chunks/chunk-LO4TPPLH.mjs +33 -0
  203. package/dist/esm/chunks/emojis-6L3GRBAP.mjs +7 -0
  204. package/dist/esm/data.mjs +11 -0
  205. package/dist/esm/index.mjs +279 -0
  206. package/dist/esm/primitives/index.mjs +8 -0
  207. package/dist/hooks/preloadEmoji.d.ts +5 -9
  208. package/dist/hooks/useActiveCategoryScrollDetection.d.ts +11 -11
  209. package/dist/hooks/useCategoryHeight.d.ts +7 -5
  210. package/dist/hooks/useCloseAllOpenToggles.d.ts +2 -2
  211. package/dist/hooks/useDataIdentityStabilityWarning.d.ts +13 -0
  212. package/dist/hooks/useDebouncedState.d.ts +1 -1
  213. package/dist/hooks/useDisallowMouseMove.d.ts +4 -4
  214. package/dist/hooks/useDisallowedEmojis.d.ts +2 -3
  215. package/dist/hooks/useEmojiPreviewEvents.d.ts +3 -3
  216. package/dist/hooks/useEmojiVirtualization.d.ts +22 -17
  217. package/dist/hooks/useFilter.d.ts +10 -16
  218. package/dist/hooks/useFocus.d.ts +3 -3
  219. package/dist/hooks/useInitialLoad.d.ts +2 -2
  220. package/dist/hooks/useIsEmojiHidden.d.ts +8 -8
  221. package/dist/hooks/useIsMounted.d.ts +1 -1
  222. package/dist/hooks/useIsSearchMode.d.ts +1 -1
  223. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +2 -2
  224. package/dist/hooks/useKeyboardNavigation.d.ts +3 -1
  225. package/dist/hooks/useMouseDownHandlers.d.ts +8 -4
  226. package/dist/hooks/useOnFocus.d.ts +1 -1
  227. package/dist/hooks/useOnScroll.d.ts +2 -2
  228. package/dist/hooks/useReactionsFocus.d.ts +1 -0
  229. package/dist/hooks/useRegisterRegion.d.ts +24 -0
  230. package/dist/hooks/useResolvedEmojiData.d.ts +37 -0
  231. package/dist/hooks/useScrollCategoryIntoView.d.ts +1 -1
  232. package/dist/hooks/useSearchController.d.ts +17 -0
  233. package/dist/hooks/useSearchResults.d.ts +8 -0
  234. package/dist/hooks/useSetVariationPicker.d.ts +2 -2
  235. package/dist/hooks/useShouldHideCustomEmojis.d.ts +1 -1
  236. package/dist/hooks/useShouldShowSkinTonePicker.d.ts +4 -4
  237. package/dist/index.d.mts +376 -0
  238. package/dist/index.d.ts +376 -9
  239. package/dist/index.js +2 -8
  240. package/dist/primitives/CategoryNav.d.ts +4 -0
  241. package/dist/primitives/Empty.d.ts +6 -0
  242. package/dist/primitives/List.d.ts +4 -0
  243. package/dist/primitives/LoadError.d.ts +8 -0
  244. package/dist/primitives/Loading.d.ts +4 -0
  245. package/dist/primitives/Panel.d.ts +3 -0
  246. package/dist/primitives/Preview.d.ts +3 -0
  247. package/dist/primitives/Reactions.d.ts +2 -0
  248. package/dist/primitives/Root.d.ts +26 -0
  249. package/dist/primitives/Search.d.ts +5 -0
  250. package/dist/primitives/SearchInput.d.ts +3 -0
  251. package/dist/primitives/SkinTone.d.ts +4 -0
  252. package/dist/primitives/Viewport.d.ts +19 -0
  253. package/dist/primitives/appearance.d.ts +3 -0
  254. package/dist/primitives/components.d.ts +27 -0
  255. package/dist/primitives/hooks.d.ts +48 -0
  256. package/dist/primitives/index.d.mts +561 -0
  257. package/dist/primitives/index.d.ts +561 -0
  258. package/dist/primitives/index.js +2 -0
  259. package/dist/primitives/nativeProps.d.ts +15 -0
  260. package/dist/primitives/scope.d.ts +13 -0
  261. package/dist/primitives/structuralStyles.d.ts +16 -0
  262. package/dist/primitives/tokens.d.ts +18 -0
  263. package/dist/primitives/types.d.ts +85 -0
  264. package/dist/state/activeEmojiStore.d.ts +7 -0
  265. package/dist/state/navigationRegistry.d.ts +61 -0
  266. package/dist/state/regionTraversal.d.ts +20 -0
  267. package/dist/typeRefinements/typeRefinements.d.ts +6 -6
  268. package/dist/types/exposedTypes.d.ts +16 -6
  269. package/dist/types/exposedTypes.js +5 -0
  270. package/dist/virtualization/virtualizationHelpers.d.ts +22 -18
  271. package/llms-full.txt +3683 -0
  272. package/llms.txt +66 -480
  273. package/package.json +180 -66
  274. package/src/DomUtils/categoryNameFromDom.ts +1 -1
  275. package/src/DomUtils/classNames.ts +1 -4
  276. package/src/DomUtils/elementPositionInRow.ts +28 -6
  277. package/src/DomUtils/eventBelongsToPicker.ts +17 -0
  278. package/src/DomUtils/getActiveElement.ts +7 -1
  279. package/src/DomUtils/isJsdom.ts +12 -0
  280. package/src/DomUtils/isRtl.ts +5 -0
  281. package/src/DomUtils/keyboardNavigation.ts +164 -144
  282. package/src/DomUtils/scrollTo.ts +20 -18
  283. package/src/DomUtils/selectors.ts +30 -127
  284. package/src/EmojiPickerReact.tsx +155 -48
  285. package/src/Stylesheet/DedupedStyle.tsx +80 -0
  286. package/src/Stylesheet/stylesheet.tsx +128 -59
  287. package/src/components/Layout/Flex.tsx +12 -11
  288. package/src/components/Reactions/BtnPlus.tsx +61 -51
  289. package/src/components/Reactions/Reactions.tsx +113 -55
  290. package/src/components/atoms/Button.tsx +18 -15
  291. package/src/components/body/EmojiCategory.tsx +77 -40
  292. package/src/components/body/EmojiList.tsx +107 -44
  293. package/src/components/body/EmojiVariationPicker.tsx +113 -66
  294. package/src/components/body/MeasureEmoji.tsx +9 -2
  295. package/src/components/body/listComponents.tsx +79 -0
  296. package/src/components/context/ElementRefContext.tsx +46 -35
  297. package/src/components/context/PickerConfigContext.tsx +55 -40
  298. package/src/components/context/PickerContext.tsx +567 -92
  299. package/src/components/context/PickerDataContext.tsx +114 -99
  300. package/src/components/emoji/BaseEmojiProps.ts +5 -4
  301. package/src/components/emoji/ClickableEmojiButton.tsx +148 -63
  302. package/src/components/emoji/Emoji.tsx +24 -2
  303. package/src/components/emoji/EmojiImg.tsx +13 -12
  304. package/src/components/emoji/ExportedEmoji.tsx +5 -4
  305. package/src/components/emoji/NativeEmoji.tsx +19 -16
  306. package/src/components/emoji/ViewOnlyEmoji.tsx +55 -30
  307. package/src/components/emoji/emojiStyles.ts +12 -11
  308. package/src/components/footer/Preview.tsx +86 -91
  309. package/src/components/header/Header.tsx +21 -6
  310. package/src/components/header/Search/BtnClearSearch.tsx +69 -55
  311. package/src/components/header/Search/IcnSearch.tsx +21 -21
  312. package/src/components/header/Search/Search.tsx +79 -137
  313. package/src/components/header/SkinTonePicker/BtnSkinToneVariation.tsx +99 -62
  314. package/src/components/header/SkinTonePicker/SkinTonePicker.tsx +84 -46
  315. package/src/components/icons/svgIcons.ts +17 -0
  316. package/src/components/main/PickerMainBehaviors.tsx +163 -0
  317. package/src/components/main/defaultAppearance.tsx +189 -0
  318. package/src/components/main/labelHeight.ts +5 -0
  319. package/src/components/navigation/CategoryButton.tsx +83 -57
  320. package/src/components/navigation/CategoryNavIcon.tsx +73 -194
  321. package/src/components/navigation/CategoryNavigation.tsx +118 -46
  322. package/src/config/categoryConfig.ts +7 -3
  323. package/src/config/cdnUrls.ts +11 -21
  324. package/src/config/compareConfig.ts +128 -30
  325. package/src/config/config.ts +228 -24
  326. package/src/config/defaultPickerConfiguration.ts +7 -0
  327. package/src/config/mutableConfig.ts +44 -20
  328. package/src/config/useConfig.ts +130 -37
  329. package/src/data/defaultEmojiData.ts +49 -0
  330. package/src/data/registerDefaultEmojiData.ts +8 -0
  331. package/src/data/skinToneVariations.ts +8 -7
  332. package/src/data-core/pickerData.ts +171 -0
  333. package/src/data-core/prepare.ts +163 -0
  334. package/src/data-core/search.ts +122 -0
  335. package/src/data-core/types.ts +36 -0
  336. package/src/data.ts +10 -0
  337. package/src/dataUtils/DataTypes.ts +4 -0
  338. package/src/dataUtils/emojiSelectors.ts +59 -63
  339. package/src/dataUtils/emojiUtils.ts +17 -74
  340. package/src/dataUtils/nativeEmojiSequenceSupport.ts +116 -0
  341. package/src/dataUtils/nativeEmojiSupport.ts +160 -0
  342. package/src/dataUtils/parseNativeEmoji.ts +3 -4
  343. package/src/dataUtils/suggested.ts +8 -4
  344. package/src/dataUtils/suggestedEmojis.ts +92 -0
  345. package/src/env.d.ts +4 -0
  346. package/src/hooks/preloadEmoji.ts +2 -47
  347. package/src/hooks/useActiveCategoryScrollDetection.ts +28 -16
  348. package/src/hooks/useCategoryHeight.ts +116 -10
  349. package/src/hooks/useDataIdentityStabilityWarning.ts +86 -0
  350. package/src/hooks/useDebouncedState.ts +13 -1
  351. package/src/hooks/useDisallowedEmojis.ts +31 -42
  352. package/src/hooks/useEmojiPreviewEvents.ts +43 -10
  353. package/src/hooks/useEmojiVirtualization.tsx +112 -52
  354. package/src/hooks/useFilter.ts +92 -132
  355. package/src/hooks/useFocus.ts +14 -24
  356. package/src/hooks/useIsEmojiHidden.ts +22 -14
  357. package/src/hooks/useKeyboardNavigation.ts +412 -432
  358. package/src/hooks/useMouseDownHandlers.ts +91 -16
  359. package/src/hooks/useOnFocus.ts +12 -3
  360. package/src/hooks/useOnScroll.ts +18 -2
  361. package/src/hooks/useReactionsFocus.ts +118 -0
  362. package/src/hooks/useRegisterRegion.ts +92 -0
  363. package/src/hooks/useResolvedEmojiData.ts +200 -0
  364. package/src/hooks/useScrollCategoryIntoView.ts +74 -12
  365. package/src/hooks/useSearchController.ts +369 -0
  366. package/src/hooks/useSearchResults.ts +51 -0
  367. package/src/hooks/useSetVariationPicker.ts +4 -1
  368. package/src/index.tsx +67 -5
  369. package/src/primitives/CategoryNav.tsx +40 -0
  370. package/src/primitives/Empty.tsx +68 -0
  371. package/src/primitives/List.tsx +61 -0
  372. package/src/primitives/LoadError.tsx +38 -0
  373. package/src/primitives/Loading.tsx +60 -0
  374. package/src/primitives/Panel.tsx +47 -0
  375. package/src/primitives/Preview.tsx +38 -0
  376. package/src/primitives/Reactions.tsx +2 -0
  377. package/src/primitives/Root.tsx +398 -0
  378. package/src/primitives/Search.tsx +41 -0
  379. package/src/primitives/SearchInput.tsx +110 -0
  380. package/src/primitives/SkinTone.tsx +76 -0
  381. package/src/primitives/Viewport.tsx +204 -0
  382. package/src/primitives/appearance.tsx +7 -0
  383. package/src/primitives/components.tsx +30 -0
  384. package/src/primitives/hooks.ts +165 -0
  385. package/src/primitives/index.ts +94 -0
  386. package/src/primitives/nativeProps.ts +90 -0
  387. package/src/primitives/scope.tsx +109 -0
  388. package/src/primitives/structuralStyles.tsx +136 -0
  389. package/src/primitives/tokens.ts +150 -0
  390. package/src/primitives/types.ts +192 -0
  391. package/src/state/activeEmojiStore.ts +39 -0
  392. package/src/state/navigationRegistry.ts +209 -0
  393. package/src/state/regionTraversal.ts +116 -0
  394. package/src/svg.d.ts +2 -2
  395. package/src/types/exposedTypes.ts +28 -1
  396. package/src/virtualization/virtualizationHelpers.ts +29 -8
  397. package/dist/components/body/Body.d.ts +0 -2
  398. package/dist/components/main/PickerMain.d.ts +0 -7
  399. package/dist/dataUtils/alphaNumericEmojiIndex.d.ts +0 -5
  400. package/dist/emoji-picker-react.cjs.development.js +0 -31413
  401. package/dist/emoji-picker-react.cjs.development.js.map +0 -1
  402. package/dist/emoji-picker-react.cjs.production.min.js +0 -2
  403. package/dist/emoji-picker-react.cjs.production.min.js.map +0 -1
  404. package/dist/emoji-picker-react.esm.js +0 -31411
  405. package/dist/emoji-picker-react.esm.js.map +0 -1
  406. package/dist/hooks/useHideEmojisByUniocode.d.ts +0 -1
  407. package/src/components/body/Body.tsx +0 -43
  408. package/src/components/main/PickerMain.tsx +0 -249
  409. package/src/dataUtils/alphaNumericEmojiIndex.ts +0 -21
package/README.md CHANGED
@@ -1,10 +1,16 @@
1
1
  # Emoji Picker React
2
2
 
3
- The most popular fully customizable emoji picker for React.
3
+ **Batteries included. Or BYOD — bring your own design.**
4
+
5
+ One emoji-picker engine, with two ways to build your UI: use the complete picker, or bring your own design, design language and design library.
6
+
7
+ > **Batteries included:** `npm install emoji-picker-react`, render `<EmojiPicker />`, done — a complete, accessible, themed picker with search, categories, skin tones, recents and keyboard navigation. No CSS import, no configuration, no design work.
8
+ >
9
+ > **BYOD (bring your own design):** pass `unstyled`, or compose your own layout from `emoji-picker-react/primitives`, and style it with whatever your app already uses — Tailwind, shadcn/ui, CSS Modules, Emotion, styled-components, MUI or plain CSS. Accessibility, keyboard navigation and virtualization stay built in.
4
10
 
5
11
  [![npm downloads](https://img.shields.io/npm/dm/emoji-picker-react.svg)](https://www.npmjs.com/package/emoji-picker-react)
6
12
 
7
- **[Live Demo](https://ealush.com/emoji-picker-react)** | **[Report a Bug](https://github.com/ealush/emoji-picker-react/issues)** | **[Sponsor](https://github.com/sponsors/ealush)**
13
+ **[Live demo](https://ealush.com/emoji-picker-react)** · **[Props](PROPS.md)** · **[BYOD](#byod-bring-your-own-design)** · **[Common tasks](#common-tasks)** · **[For AI assistants](#for-ai-assistants)** · **[Report a bug](https://github.com/ealush/emoji-picker-react/issues)** · **[Sponsor](https://github.com/sponsors/ealush)**
8
14
 
9
15
  ![image](https://github.com/ealush/emoji-picker-react/assets/11255103/48901306-e7fd-49cd-8f1e-9b214083a61d)
10
16
 
@@ -12,22 +18,31 @@ The most popular fully customizable emoji picker for React.
12
18
 
13
19
  ## Features
14
20
 
15
- - Fully customizable through props and CSS variables
16
- - Light, dark, and auto themes
17
- - Reactions picker mode and custom click handlers
18
- - Dozens of built-in languages
19
- - Custom image-based emojis
20
- - Apple, Google, Facebook, Twitter, and native emoji styles
21
- - Responsive and mobile-friendly
22
- - SSR-safe
21
+ - **Batteries included** — one component, sensible defaults, light/dark/auto themes, no stylesheet to import.
22
+ - **BYOD** — `unstyled` drops the chrome and composable primitives let you build any layout, styled with plain CSS, CSS Modules, Tailwind, shadcn/ui, Emotion, styled-components or MUI. See [25 designs](#design-examples) built this way.
23
+ - **Accessible** — full keyboard navigation, ARIA grid semantics, localizable labels, right-to-left layouts, reduced-motion support and automated axe checks.
24
+ - **Reactions mode** — a compact reactions bar that expands to the full picker.
25
+ - **Localized** — 28 emoji datasets; translate search, categories, previews, reactions, skin tones, loading errors and retry controls, including accessible announcements.
26
+ - **Emoji styles** — native (default), Apple, Google, Facebook, Twitter; native mode filters detected unsupported OS glyphs, including individual sequences and skin tones. See [detection limits](docs/v5/API.md#5c-native-emoji-support-detection).
27
+ - **Custom emojis** — image-based emojis, optionally in their own named groups.
28
+ - **Lean when you want** — the primitives entry loads the dataset on demand (a 34 KiB min+gz startup budget including ShipStyles; see the consumer gate); a framework-free data API for search and lookup.
29
+ - **Modern React** — React 16.8 through 19, SSR, React Server Components (`"use client"` entries), TypeScript types included; ships ES2020 for every browser since 2020 and any modern bundler.
30
+
31
+ > **Upgrading from v4?** Most code works unchanged; the default emoji style is now native, and markup, styling and package boundaries have changed. See [Migrating from v4](docs/v5/MIGRATION.md). The APIs on this page need `emoji-picker-react@5` or later.
32
+
33
+ ## Copyable integration prompts
23
34
 
24
- ## Installation
35
+ Use the [setup, customization, recipe adoption and v5 migration prompts](docs/v5/PROMPTS.md)
36
+ to give a coding agent a concrete starting point for your application. Each
37
+ prompt checks the installed version and keeps integration behavior explicit.
38
+
39
+ ## Quick start (batteries included)
25
40
 
26
41
  ```bash
27
42
  npm install emoji-picker-react
28
43
  ```
29
44
 
30
- ## Usage
45
+ Requires **React 16.8 or later** and **Node 18 or later** in your build toolchain. (Contributors to this repository use Node 24; see [CONTRIBUTING.md](CONTRIBUTING.md).)
31
46
 
32
47
  ```jsx
33
48
  import EmojiPicker from 'emoji-picker-react';
@@ -39,77 +54,344 @@ function App() {
39
54
  }
40
55
  ```
41
56
 
42
- `onEmojiClick` receives an `EmojiClickData` object (unified code, names, image URL, active skin tone) and the underlying mouse event.
57
+ That is the whole setup. `onEmojiClick` receives an `EmojiClickData` object (`emoji`, `unified`, `names`, `imageUrl`, `activeSkinTone`, …) and the event.
58
+
59
+ ```jsx
60
+ <EmojiPicker colorScheme="dark" width={320} height={400} previewConfig={{ showPreview: false }} />
61
+ ```
62
+
63
+ See [PROPS.md](PROPS.md) for every prop.
64
+
65
+ ## Choose your path
66
+
67
+ | You want | Use | You style |
68
+ | --- | --- | --- |
69
+ | A complete picker now | `<EmojiPicker />` | Nothing |
70
+ | The built-in look in your brand's colors and sizes | `<EmojiPicker />` + `colorScheme` and `--epr-*` variables | A few variables |
71
+ | Your own design on the supplied layout | `<EmojiPicker unstyled />` | Every part, with your CSS or styling library |
72
+ | Your own layout and components | `emoji-picker-react/primitives` | Layout and parts, or reuse the built-in look with `appearance="default"` |
73
+
74
+ Every path keeps the same behavior: keyboard navigation, focus management, ARIA semantics, virtualization, skin tones, variations, recents, search and localization.
75
+
76
+ **One rule decides how styling works:** color variables (`--epr-bg-color`, `--epr-highlight-color`, …) theme the *built-in look*. `unstyled` and a bare primitives `Root` remove the built-in look, so color variables have no effect there. You style the parts directly. Size variables (`--epr-emoji-size`, paddings, heights) apply in every mode.
77
+
78
+ ## BYOD: bring your own design
79
+
80
+ Bring your own design, design language and design library. Keep the supplied layout with `unstyled`, or compose the parts and use your own input, emoji buttons, category headers, preview and tone controls. Search, localization, keyboard navigation and virtualization share the same engine in both paths.
81
+
82
+ The picker needs no stylesheet import. Its CSS is injected automatically, once per document or shadow root, and scoped so it never leaks into your app.
83
+
84
+ How overrides work, so you never fight specificity:
85
+
86
+ - **Design variables (`--epr-*`) always yield to your CSS.** Their defaults are emitted at zero specificity, so a single class wins in any load order.
87
+ - **Parts are targetable** with stable `[data-epr-part="…"]` selectors: `root`, `panel`, `search`, `search-input`, `search-clear`, `skin-tone`, `skin-tone-button`, `category-nav`, `category-tab`, `viewport`, `list`, `category`, `category-label`, `category-content`, `emoji`, `variation-picker`, `preview`, `empty`, `loading`, `load-error`, `reactions`, `reaction`, `expand-reactions`. State is exposed as `[data-epr-active]` (hovered or focused emoji, active tab or tone), `[aria-selected="true"]` (current tab) and `[aria-pressed="true"]` (current tone). The full contract: [docs/v5/STYLING.md](docs/v5/STYLING.md).
88
+ - **CSS ownership is explicit.** Library classes protect layout from ordinary element/universal resets. More specific rules and `!important` can still override geometry; preserve the [structural contract](docs/v5/STYLING.md).
89
+ - **Layered frameworks:** with Tailwind v4 (or any `@layer`-based setup), pass `cssLayer="epr"` and declare the layer first — `@layer epr, theme, base, components, utilities;` — so utilities override the picker.
90
+
91
+ ### Theme the built-in look with CSS variables
92
+
93
+ ```css
94
+ .my-picker {
95
+ --epr-bg-color: #0f172a;
96
+ --epr-category-label-bg-color: #0f172ae6;
97
+ --epr-search-input-bg-color: #1e293b;
98
+ --epr-search-input-bg-color-active: #1e293b;
99
+ --epr-picker-border-color: #1e293b;
100
+ --epr-text-color: #cbd5e1;
101
+ --epr-highlight-color: #22d3ee;
102
+ --epr-hover-bg-color: #1e293b;
103
+ --epr-focus-bg-color: #334155;
104
+ --epr-emoji-size: 28px;
105
+ }
106
+
107
+ .my-picker [data-epr-part='category-label'] {
108
+ text-transform: uppercase;
109
+ letter-spacing: 0.08em;
110
+ }
111
+ ```
112
+
113
+ ```jsx
114
+ <EmojiPicker colorScheme="dark" className="my-picker" />
115
+ ```
116
+
117
+ Sticky category labels and the search field have their own surfaces, so set their variables along with `--epr-bg-color`. All variables: [CSS_VARIABLES.md](CSS_VARIABLES.md).
118
+
119
+ ### Unstyled: your design, the supplied layout
120
+
121
+ `unstyled` removes decorative styling from every part: colors, borders, rounding, button resets, typography and the search icon. Layout, geometry, virtualization, keyboard behavior and visibility stay managed. You start from plain browser controls and style the parts with your own CSS. This is a complete starting point:
122
+
123
+ ```css
124
+ .my-picker {
125
+ background: Canvas;
126
+ color: CanvasText;
127
+ border: 1px solid #8884;
128
+ border-radius: 12px;
129
+ font: 14px system-ui, sans-serif;
130
+ }
131
+ .my-picker [data-epr-part='search-input'] {
132
+ padding-inline-start: 10px;
133
+ border: 1px solid #8886;
134
+ border-radius: 8px;
135
+ background: transparent;
136
+ color: inherit;
137
+ font: inherit;
138
+ }
139
+ .my-picker :is([data-epr-part='emoji'], [data-epr-part='category-tab'],
140
+ [data-epr-part='search-clear'], [data-epr-part='skin-tone-button']) {
141
+ border: 0;
142
+ border-radius: 8px;
143
+ background: transparent;
144
+ color: inherit;
145
+ cursor: pointer;
146
+ }
147
+ .my-picker [data-epr-part='emoji'][data-epr-active],
148
+ .my-picker [data-epr-part='category-tab'][aria-selected='true'] {
149
+ background: #8882;
150
+ }
151
+ .my-picker :is(button, input):focus-visible {
152
+ outline: 2px solid Highlight;
153
+ outline-offset: -2px;
154
+ }
155
+ .my-picker [data-epr-part='category-label'] {
156
+ font-size: 12px;
157
+ font-weight: 600;
158
+ background: Canvas;
159
+ }
160
+ .my-picker [data-epr-part='variation-picker'] {
161
+ background: Canvas;
162
+ border: 1px solid #8884;
163
+ border-radius: 10px;
164
+ box-shadow: 0 4px 12px #0003;
165
+ }
166
+ ```
167
+
168
+ ```jsx
169
+ <EmojiPicker unstyled className="my-picker" />
170
+ ```
43
171
 
44
- ## Configuration
172
+ It follows the page's light or dark `color-scheme`. Keep a visible focus style on buttons and the input. Overlays such as the skin-tone variation popover (`variation-picker`) are transparent until you give them a surface. The same selectors work from CSS Modules (`:global([data-epr-part='emoji'])` inside your module class), Emotion, styled-components, Tailwind arbitrary variants (`[&_[data-epr-part=emoji]]:rounded-lg`) and MUI's `styled`.
173
+
174
+ ### Tailwind CSS (v4)
175
+
176
+ ```css
177
+ /* app.css */
178
+ @layer epr, theme, base, components, utilities;
179
+ @import 'tailwindcss';
180
+ ```
45
181
 
46
182
  ```jsx
47
183
  <EmojiPicker
48
- theme="dark"
49
- emojiStyle="native"
50
- width={320}
51
- height={400}
52
- previewConfig={{ showPreview: false }}
184
+ cssLayer="epr"
185
+ className="rounded-2xl shadow-xl [--epr-bg-color:var(--color-white)] [--epr-highlight-color:var(--color-indigo-600)] [--epr-hover-bg-color:var(--color-indigo-50)] [&_[data-epr-part=emoji]]:rounded-lg"
53
186
  />
54
187
  ```
55
188
 
56
- See [PROPS.md](PROPS.md) for the complete props reference.
57
-
58
- ## Styling
189
+ Utilities apply to the root; arbitrary properties set variables and arbitrary variants reach the parts. For a fully custom design, add `unstyled` and style the parts with utilities instead of variables.
59
190
 
60
- No stylesheet import needed. All styles are scoped via [ShipStyles](https://github.com/ealush/shipstyles) — generated class names are hashed, so the picker's CSS won't leak into or clash with your app's styles.
191
+ ### shadcn/ui
61
192
 
62
- Restyle the picker by overriding [CSS variables](CSS_VARIABLES.md) on `.EmojiPickerReact`:
193
+ Map the picker's variables to shadcn's theme variables once; light, dark and custom themes then follow automatically:
63
194
 
64
195
  ```css
65
- .EmojiPickerReact {
66
- --epr-emoji-size: 32px;
196
+ .emoji-picker {
197
+ --epr-bg-color: var(--popover);
198
+ --epr-category-label-bg-color: var(--popover);
199
+ --epr-text-color: var(--muted-foreground);
200
+ --epr-highlight-color: var(--primary);
201
+ --epr-hover-bg-color: var(--accent);
202
+ --epr-focus-bg-color: var(--accent);
203
+ --epr-picker-border-color: var(--border);
204
+ --epr-search-input-bg-color: transparent;
205
+ --epr-search-border-color: var(--input);
206
+ --epr-search-border-color-active: var(--ring);
67
207
  }
68
208
  ```
69
209
 
70
- ## Internationalization
210
+ ```jsx
211
+ <PopoverContent className="w-auto p-0">
212
+ <EmojiPicker cssLayer="epr" className="emoji-picker" onEmojiClick={(e) => insert(e.emoji)} />
213
+ </PopoverContent>
214
+ ```
215
+
216
+ For a component that uses your shadcn input and buttons directly, install the [registry component](#ready-to-adapt-starters).
71
217
 
72
- Pass imported locale data via the `emojiData` prop:
218
+ ### Emotion, styled-components and MUI
73
219
 
74
220
  ```jsx
75
- import EmojiPicker from 'emoji-picker-react';
76
- import es from 'emoji-picker-react/dist/data/emojis-es'; // Spanish
221
+ import styled from '@emotion/styled'; // or 'styled-components', or '@mui/material/styles'
77
222
 
78
- function App() {
79
- return <EmojiPicker emojiData={es} />;
223
+ const ThemedPicker = styled(EmojiPicker)`
224
+ --epr-bg-color: ${(p) => p.theme.colors.surface};
225
+ --epr-category-label-bg-color: ${(p) => p.theme.colors.surface};
226
+ --epr-highlight-color: ${(p) => p.theme.colors.accent};
227
+ border-radius: 16px;
228
+ `;
229
+
230
+ <ThemedPicker colorScheme="dark" />;
231
+ ```
232
+
233
+ Use `colorScheme` (not `theme`) with CSS-in-JS wrappers: Emotion, styled-components and MUI reserve a `theme` prop on components they wrap. `theme` still works everywhere else (v4 compatible).
234
+
235
+ Every technique above has a complete, runnable version in [`stories/integrations`](stories/integrations) and, per design, in [`stories/recipes`](stories/recipes). **[Styling recipes by library](docs/v5/STYLING_RECIPES.md)** collects theme, unstyled and composed snippets for plain CSS, CSS Modules, Tailwind, shadcn/ui, Emotion, styled-components and MUI; the [`example/`](example) app runs all three paths.
236
+
237
+ ## Compose your own layout
238
+
239
+ `emoji-picker-react/primitives` exposes the picker's parts. Arrange them in your layout and use your design library's components for the input, emoji cells, category headers and controls. Root manages state and navigation; one Viewport owns one List.
240
+
241
+ ```tsx check
242
+ import React from 'react';
243
+ import * as Picker from 'emoji-picker-react/primitives';
244
+
245
+ export function EmojiMenu({ insert }: { insert: (emoji: string) => void }) {
246
+ return (
247
+ <Picker.Root
248
+ appearance="default"
249
+ colorScheme="light"
250
+ columns={8}
251
+ style={{ height: 400 }}
252
+ onEmojiClick={(emoji) => insert(emoji.emoji)}
253
+ >
254
+ <Picker.Search />
255
+ <Picker.CategoryNav />
256
+ <Picker.Viewport>
257
+ <Picker.List />
258
+ <Picker.Empty />
259
+ <Picker.Loading />
260
+ <Picker.LoadError />
261
+ </Picker.Viewport>
262
+ <Picker.Preview />
263
+ </Picker.Root>
264
+ );
80
265
  }
81
266
  ```
82
267
 
83
- See [INTERNATIONALIZATION.md](INTERNATIONALIZATION.md) for the supported languages.
268
+ `appearance="default"` reuses the built-in look, so `colorScheme` and color variables apply. Leave it out to style every part yourself, exactly like `unstyled`. Root has no default height: set one so the list scrolls and virtualizes.
84
269
 
85
- ## Customization
270
+ - **Parts:** `Root`, `Search` (input with icon and clear button), `SearchInput` (just the input, or yours), `CategoryNav` (`orientation="vertical"` for side rails), `Viewport`, `List`, `Preview`, `SkinTone`, `Empty`, `Loading`, `LoadError`; `Panel` and `Reactions` manage expanded and compact reaction content when composed. Presence and placement are owned by JSX; Root has no composition switch.
271
+ - **Your components:** `<Picker.SearchInput as={Input} />` accepts your input component's props and forwards its ref to the native input; Root owns its value. `components={{ Emoji, CategoryHeader, CategoryButton, SkinToneButton, ClearButton, ExpandButton }}` on Root or EmojiPicker replaces those elements with yours while the library keeps their behavior and measured geometry. Spread the props you receive onto one native element, and give it a visible focus style.
272
+ - **Hooks for custom UI:** `useActiveEmoji()` (custom previews), `useSkinTone()` (custom tone menus), `useSearchState()` / `useSearchActions()` (custom search UI), `useCategoryNavigation()` (custom tabs), `usePickerMode()` (reactions bar ↔ full picker), `useEmojiDataState()` (loading and retry).
273
+ - **Size:** `columns` sets the emojis per row and fits the width to them; without it, set a width and the columns follow.
274
+ - **Lean:** the primitives entry loads the emoji dataset on demand. Pass `emojiData` (an object, or a loader like `() => import('emoji-picker-react/data/emojis-fr')`) to control it. Import enums such as `Categories` from `emoji-picker-react/primitives`, not the main entry, to keep the dataset out of your initial bundle.
275
+
276
+ The composition path keeps grid geometry, keyboard behavior and ARIA managed; there is no renderer-independent DOM engine. For search without React or UI, use the [data API](#data-api).
86
277
 
87
- Custom emojis, custom category icons, preview configuration, and CSP nonces are covered in [CUSTOMIZATION.md](CUSTOMIZATION.md).
278
+ Full reference: [docs/v5/PRIMITIVES.md](docs/v5/PRIMITIVES.md) and [docs/v5/API.md](docs/v5/API.md). A copyable design-library walkthrough (including MUI): [docs/v5/ADOPTION.md](docs/v5/ADOPTION.md).
88
279
 
89
- ## Server-Side Rendering
280
+ ## Common tasks
90
281
 
91
- The picker renders on the server, with styles inlined into the server HTML — no setup needed. Since the picker is usually opened on demand rather than shown immediately, lazy-loading it is still recommended to keep the initial bundle small:
282
+ **Dark mode** — `<EmojiPicker colorScheme="dark" />` (or `"auto"` to follow the OS).
92
283
 
93
- ```javascript
94
- import dynamic from 'next/dynamic';
284
+ **Reactions bar (like Slack or iMessage)** — `<EmojiPicker reactionsDefaultOpen reactions={['1f44d', '2764-fe0f', '1f602']} onReactionClick={...} />`. The "+" expands to the full picker; `allowExpandReactions={false}` keeps it compact.
95
285
 
96
- const Picker = dynamic(() => import('emoji-picker-react'));
286
+ **Insert the emoji into a text field** — use `emojiData.emoji` from `onEmojiClick`:
287
+
288
+ ```jsx
289
+ <EmojiPicker onEmojiClick={(emojiData) => setText((text) => text + emojiData.emoji)} />
97
290
  ```
98
291
 
99
- ## Troubleshooting
292
+ **Open it in a popover or dropdown** — render the picker inside your popover component (Radix, MUI, Headless UI, …); it has no positioning of its own.
100
293
 
101
- ### `global is not defined` (Vite, versions before 4.20)
294
+ **Localize it** — pass a dataset and translated UI strings:
102
295
 
103
- Since 4.20 the picker is SSR-safe and no longer references the Node-style
104
- `global`. If you see `global is not defined`, upgrade to the latest version.
105
- On older versions only, the workaround was adding this to your HTML:
296
+ ```jsx
297
+ import es from 'emoji-picker-react/data/emojis-es';
106
298
 
107
- ```html
108
- <script>
109
- window.global = window;
110
- </script>
299
+ <EmojiPicker emojiData={es} labels={{ searchPlaceholder: 'Buscar', searchLabel: 'Buscar un emoji' }} />;
111
300
  ```
112
301
 
302
+ **Custom emojis** — `customEmojis={[{ id: 'party-parrot', names: ['party parrot'], imgUrl: '/parrot.gif' }]}`; add `group` to give them their own section. See [CUSTOMIZATION.md](CUSTOMIZATION.md).
303
+
304
+ **Only some categories** — `categories={[Categories.SMILEYS_PEOPLE, Categories.ANIMALS_NATURE]}`.
305
+
306
+ **Your own suggested emojis** — `suggestedEmojis={['1f44d', '1f389', '1f680']}`.
307
+
308
+ **Controlled search** — `searchValue` + `onSearchChange`, like an ordinary controlled input.
309
+
310
+ **Controlled skin tone** — `skinTone` + `onSkinToneChange`.
311
+
312
+ **Hide the preview / search / skin tones** — `previewConfig={{ showPreview: false }}`, `searchDisabled`, `skinTonesDisabled`.
313
+
314
+ **Size** — `width` / `height` props; `columns={8}` to fit the width to a number of emojis per row; `--epr-emoji-size` for the emojis themselves.
315
+
316
+ **Next.js App Router** — import it in any component; the entry is marked `"use client"`. To keep it out of the initial bundle: `const EmojiPicker = dynamic(() => import('emoji-picker-react'), { ssr: false })`.
317
+
318
+ **Search or look up emojis without the UI** — `import { searchEmojis, getEmojiByUnified } from 'emoji-picker-react/data'`.
319
+
320
+ **Testing with jsdom / Testing Library** — emojis in the grid have `role="gridcell"` with the emoji name as their accessible name: `getByRole('gridcell', { name: 'grinning face' })`.
321
+
322
+ ## Data API
323
+
324
+ Framework-free emoji lookup and search, sharing the picker's index:
325
+
326
+ ```js
327
+ import { getEmojiByUnified, searchEmojis } from 'emoji-picker-react/data';
328
+ import fr from 'emoji-picker-react/data/emojis-fr';
329
+
330
+ searchEmojis('smile'); // default dataset
331
+ searchEmojis('sourire', { emojiData: fr }); // locale dataset
332
+ getEmojiByUnified('1f600'); // { unified: '1f600', emoji: '😀', name: 'grinning face', names, variations, addedIn }
333
+ ```
334
+
335
+ Both work without React (including in Server Components) and return immutable records. Results follow dataset order and skip picker-only filters such as `hiddenEmojis`, `emojiVersion` and custom emojis. See the [data API contract](docs/v5/DATA_API.md).
336
+
337
+ ## Internationalization
338
+
339
+ 28 emoji datasets ship with the package. Import one and pass it as `emojiData`; translate the remaining UI strings with `labels`. See [INTERNATIONALIZATION.md](INTERNATIONALIZATION.md) for the list.
340
+
341
+ ## Customization
342
+
343
+ Custom emojis and groups, category icons, preview configuration and CSP nonces: [CUSTOMIZATION.md](CUSTOMIZATION.md).
344
+
345
+ ## Server-side rendering
346
+
347
+ The picker renders on the server with its styles inlined — no setup. The main and primitives entries are marked `"use client"`, so React Server Components can render them directly; `emoji-picker-react/data` stays server-usable.
348
+
349
+ ## Ready-to-adapt starters
350
+
351
+ Use the [live gallery](https://ealush.com/emoji-picker-react/#designs) to try designs and copy or download their React and CSS files. Working host integrations include [caret autocomplete](stories/recipes/shortcode-typeahead), [custom-image replies](stories/recipes/community-forum) and [chat insertion](stories/recipes/team-chat).
352
+
353
+ The [shadcn registry component](registry/emoji-picker.tsx) uses your theme, a native search input, custom cells and the same keyboard engine. Install it with `npx shadcn@latest add https://ealush.com/emoji-picker-react/r/emoji-picker.json` (the item is generated into `website/public/r/emoji-picker.json`). It requires `emoji-picker-react@5` or later. See [the adoption guide](docs/v5/ADOPTION.md) for setup and popup focus behavior.
354
+
355
+ ## Design examples
356
+
357
+ [`stories/recipes`](stories/recipes) holds 25 production-style designs — ten in-context examples (team chat composer, article comments, status dialog, `:shortcode` typeahead, livestream chat, project icon picker, doc editor panel, community custom emojis, video call reactions, mobile bottom sheet) and fifteen product-inspired builds (Slack, GitHub, Discord, Linear, Notion, Material 3, Teams, WhatsApp, iOS, X, …). Each is available in plain CSS, CSS Modules, Emotion, styled-components, MUI, Tailwind and shadcn/ui, and is screenshot-, axe- and keyboard-tested in every interaction state. All 25 are playable in the [live demo](https://ealush.com/emoji-picker-react/#designs).
358
+
359
+ <!-- DESIGNS:START (generated by scripts/portDesigns.mts; run `npm run designs`) -->
360
+ Every design below is the same picker, recomposed and restyled. [Try them live](https://ealush.com/emoji-picker-react/#designs).
361
+
362
+ <table>
363
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/team-chat"><img src="docs/designs/team-chat.png" alt="Team chat composer design example" width="260"></a><br><sub><b>Team chat composer</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/article-comments"><img src="docs/designs/article-comments.png" alt="Article comments design example" width="260"></a><br><sub><b>Article comments</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/editor-insert-panel"><img src="docs/designs/editor-insert-panel.png" alt="Doc editor insert panel design example" width="260"></a><br><sub><b>Doc editor insert panel</b></sub></td></tr>
364
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/livestream-chat"><img src="docs/designs/livestream-chat.png" alt="Livestream chat design example" width="260"></a><br><sub><b>Livestream chat</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/status-dialog"><img src="docs/designs/status-dialog.png" alt="Set a status dialog design example" width="260"></a><br><sub><b>Set a status dialog</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/shortcode-typeahead"><img src="docs/designs/shortcode-typeahead.png" alt="Shortcode typeahead design example" width="260"></a><br><sub><b>Shortcode typeahead</b></sub></td></tr>
365
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/video-call-reactions"><img src="docs/designs/video-call-reactions.png" alt="Video call reactions design example" width="260"></a><br><sub><b>Video call reactions</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/community-forum"><img src="docs/designs/community-forum.png" alt="Community custom emojis design example" width="260"></a><br><sub><b>Community custom emojis</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/project-icon-picker"><img src="docs/designs/project-icon-picker.png" alt="Project icon picker design example" width="260"></a><br><sub><b>Project icon picker</b></sub></td></tr>
366
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/habit-tracker-mobile"><img src="docs/designs/habit-tracker-mobile.png" alt="Habit tracker (mobile) design example" width="260"></a><br><sub><b>Habit tracker (mobile)</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/discord-sidebar"><img src="docs/designs/discord-sidebar.png" alt="Discord sidebar design example" width="260"></a><br><sub><b>Discord sidebar</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/slack-reactions"><img src="docs/designs/slack-reactions.png" alt="Slack reactions design example" width="260"></a><br><sub><b>Slack reactions</b></sub></td></tr>
367
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/github-reactions"><img src="docs/designs/github-reactions.png" alt="GitHub reactions design example" width="260"></a><br><sub><b>GitHub reactions</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/imessage-tapback"><img src="docs/designs/imessage-tapback.png" alt="iMessage tapback design example" width="260"></a><br><sub><b>iMessage tapback</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/x-composer"><img src="docs/designs/x-composer.png" alt="X composer design example" width="260"></a><br><sub><b>X composer</b></sub></td></tr>
368
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/notion-icon-picker"><img src="docs/designs/notion-icon-picker.png" alt="Notion icon picker design example" width="260"></a><br><sub><b>Notion icon picker</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/linear-palette"><img src="docs/designs/linear-palette.png" alt="Linear command palette design example" width="260"></a><br><sub><b>Linear command palette</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/teams-fluent"><img src="docs/designs/teams-fluent.png" alt="Teams (Fluent 2) design example" width="260"></a><br><sub><b>Teams (Fluent 2)</b></sub></td></tr>
369
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/material-3"><img src="docs/designs/material-3.png" alt="Material 3 design example" width="260"></a><br><sub><b>Material 3</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/geist-minimal"><img src="docs/designs/geist-minimal.png" alt="Geist minimal design example" width="260"></a><br><sub><b>Geist minimal</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/polaris-rating"><img src="docs/designs/polaris-rating.png" alt="Polaris rating card design example" width="260"></a><br><sub><b>Polaris rating card</b></sub></td></tr>
370
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/intercom-rating"><img src="docs/designs/intercom-rating.png" alt="Intercom rating design example" width="260"></a><br><sub><b>Intercom rating</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/ios-bottom-sheet"><img src="docs/designs/ios-bottom-sheet.png" alt="iOS bottom sheet design example" width="260"></a><br><sub><b>iOS bottom sheet</b></sub></td><td align="center" valign="top" width="33%"><a href="stories/recipes/whatsapp-keyboard"><img src="docs/designs/whatsapp-keyboard.png" alt="WhatsApp keyboard panel design example" width="260"></a><br><sub><b>WhatsApp keyboard panel</b></sub></td></tr>
371
+ <tr><td align="center" valign="top" width="33%"><a href="stories/recipes/windows-95"><img src="docs/designs/windows-95.png" alt="Windows 95 design example" width="260"></a><br><sub><b>Windows 95</b></sub></td></tr>
372
+ </table>
373
+ <!-- DESIGNS:END -->
374
+
375
+ ## Migrating from v4
376
+
377
+ Most v4 code works unchanged. See [docs/v5/MIGRATION.md](docs/v5/MIGRATION.md).
378
+
379
+ ## For AI assistants
380
+
381
+ Start with the [agent integration guide](docs/v5/AGENT_GUIDE.md). The package ships `llms.txt` and `llms-full.txt`; the full reference is usable without web access. Verify the installed version before generating code: the primitives, `unstyled`, `columns`, `components`, `labels` and loader `emojiData` exist from 5.0.0; a 4.x installation has only the v4 props. Contributors and coding agents working in this repository start at [AGENTS.md](AGENTS.md).
382
+
383
+ This project is written to be easy for AI coding assistants to use correctly.
384
+
385
+ - **[llms.txt](llms.txt)** — a concise index of the docs (llmstxt.org format); **[llms-full.txt](llms-full.txt)** — the complete documentation in one file. Both ship in the npm package and on the [website](https://ealush.com/emoji-picker-react/llms.txt).
386
+ - **Choosing a picker:** `emoji-picker-react` fits both "just give me an emoji picker" (render `<EmojiPicker />`, no styling needed) and "it must match our design system" (`unstyled` or `emoji-picker-react/primitives`, styled with the project's existing styling solution).
387
+ - **Entry points:** `emoji-picker-react` (default export `EmojiPicker`, enums, types), `emoji-picker-react/primitives` (composable parts and hooks), `emoji-picker-react/data` (framework-free search and lookup), `emoji-picker-react/data/emojis-<locale>` (datasets).
388
+ - **Conventions:** props accept string literals or enums (`colorScheme="dark"` or `Theme.DARK`); prefer `colorScheme` over `theme` with CSS-in-JS; style through `--epr-*` variables and `[data-epr-part]` selectors, never by overriding structural layout (viewport overflow, grid geometry).
389
+ - **Per-library snippets:** [docs/v5/STYLING_RECIPES.md](docs/v5/STYLING_RECIPES.md).
390
+
391
+ ## Troubleshooting
392
+
393
+ **`global is not defined` (Vite, versions before 4.20)** — upgrade; the picker no longer references Node's `global`.
394
+
113
395
  ## Support Emoji Picker React
114
396
 
115
397
  Emoji Picker React is independently maintained. If your team relies on it, you can help fund ongoing maintenance and releases through [GitHub Sponsors](https://github.com/sponsors/ealush). Organizations can also support the project through [Tidelift](https://tidelift.com/subscription/pkg/npm-emoji-picker-react).
@@ -1 +1 @@
1
- export declare function categoryNameFromDom($category: Element | null): string | null;
1
+ export declare function categoryNameFromDom($category: Element | null): string | null;
@@ -1,23 +1,23 @@
1
- export declare enum ClassNames {
2
- hiddenOnSearch = "epr-hidden-on-search",
3
- searchActive = "epr-search-active",
4
- hidden = "epr-hidden",
5
- visible = "epr-visible",
6
- active = "epr-active",
7
- emoji = "epr-emoji",
8
- category = "epr-emoji-category",
9
- label = "epr-emoji-category-label",
10
- categoryContent = "epr-emoji-category-content",
11
- emojiHasVariations = "epr-emoji-has-variations",
12
- scrollBody = "epr-body",
13
- emojiList = "epr-emoji-list",
14
- external = "__EmojiPicker__",
15
- emojiPicker = "EmojiPickerReact",
16
- open = "epr-open",
17
- vertical = "epr-vertical",
18
- horizontal = "epr-horizontal",
19
- variationPicker = "epr-emoji-variation-picker",
20
- darkTheme = "epr-dark-theme",
21
- autoTheme = "epr-auto-theme"
22
- }
23
- export declare function asSelectors(...classNames: ClassNames[]): string;
1
+ export declare enum ClassNames {
2
+ hiddenOnSearch = "epr-hidden-on-search",
3
+ searchActive = "epr-search-active",
4
+ hidden = "epr-hidden",
5
+ visible = "epr-visible",
6
+ active = "epr-active",
7
+ emoji = "epr-emoji",
8
+ category = "epr-emoji-category",
9
+ label = "epr-emoji-category-label",
10
+ categoryContent = "epr-emoji-category-content",
11
+ emojiHasVariations = "epr-emoji-has-variations",
12
+ scrollBody = "epr-body",
13
+ emojiList = "epr-emoji-list",
14
+ external = "__EmojiPicker__",
15
+ emojiPicker = "EmojiPickerReact",
16
+ reactions = "epr-reactions",
17
+ open = "epr-open",
18
+ vertical = "epr-vertical",
19
+ horizontal = "epr-horizontal",
20
+ variationPicker = "epr-emoji-variation-picker",
21
+ darkTheme = "epr-dark-theme",
22
+ autoTheme = "epr-auto-theme"
23
+ }
@@ -1,2 +1,2 @@
1
- import { NullableElement } from './selectors';
2
- export declare function detectEmojyPartiallyBelowFold(button: HTMLButtonElement, bodyRef: NullableElement): number;
1
+ import { NullableElement } from './selectors';
2
+ export declare function detectEmojyPartiallyBelowFold(button: HTMLButtonElement, bodyRef: NullableElement): number;
@@ -1,5 +1,5 @@
1
- import { NullableElement } from './selectors';
2
- export declare function elementCountInRow(parent: NullableElement, element: NullableElement): number;
3
- export declare function firstVisibleElementInContainer(parent: NullableElement, elements: HTMLElement[], maxVisibilityDiffThreshold?: number): NullableElement;
4
- export declare function hasNextElementSibling(element: HTMLElement): boolean;
5
- export declare function getLabelHeight(parentNode: NullableElement): number;
1
+ import { NullableElement } from './selectors';
2
+ export declare function elementCountInRow(parent: NullableElement, element: NullableElement): number;
3
+ export declare function firstVisibleElementInContainer(parent: NullableElement, elements: HTMLElement[], maxVisibilityDiffThreshold?: number): NullableElement;
4
+ export declare function hasNextElementSibling(element: HTMLElement): boolean;
5
+ export declare function getLabelHeight(parentNode: NullableElement): number;
@@ -0,0 +1,2 @@
1
+ /** Ignore delegated events from a picker nested inside this picker. */
2
+ export declare function eventBelongsToPicker(event: Event, container: Element | null): boolean;
@@ -1,5 +1,5 @@
1
- import { NullableElement } from './selectors';
2
- export declare function focusElement(element: NullableElement, shouldFocus?: () => boolean): void;
3
- export declare function focusPrevElementSibling(element: NullableElement): void;
4
- export declare function focusNextElementSibling(element: NullableElement): void;
5
- export declare function focusFirstElementChild(element: NullableElement): void;
1
+ import { NullableElement } from './selectors';
2
+ export declare function focusElement(element: NullableElement, shouldFocus?: () => boolean): void;
3
+ export declare function focusPrevElementSibling(element: NullableElement): void;
4
+ export declare function focusNextElementSibling(element: NullableElement): void;
5
+ export declare function focusFirstElementChild(element: NullableElement): void;
@@ -1,2 +1,2 @@
1
- import { NullableElement } from './selectors';
2
- export declare function getActiveElement(): NullableElement;
1
+ import { NullableElement } from './selectors';
2
+ export declare function getActiveElement(): NullableElement;
@@ -0,0 +1 @@
1
+ export declare function isJsdom(): boolean;
@@ -0,0 +1 @@
1
+ export declare function isRtl(element: Element | null): boolean;
@@ -1,8 +1,15 @@
1
- import { NullableElement } from './selectors';
2
- export declare function focusFirstVisibleEmoji(parent: NullableElement): void;
3
- export declare function focusAndClickFirstVisibleEmoji(parent: NullableElement): void;
4
- export declare function focusLastVisibleEmoji(parent: NullableElement): void;
5
- export declare function focusNextVisibleEmoji(element: NullableElement): void;
6
- export declare function focusPrevVisibleEmoji(element: NullableElement): void;
7
- export declare function focusVisibleEmojiOneRowUp(element: NullableElement, exitUp: () => void): void;
8
- export declare function focusVisibleEmojiOneRowDown(element: NullableElement): void;
1
+ import { NullableElement } from './selectors';
2
+ export declare function focusFirstVisibleEmoji(parent: NullableElement, shouldFocus?: () => boolean): void;
3
+ export declare function focusAndClickFirstVisibleEmoji(parent: NullableElement): void;
4
+ export type MoveOptions = {
5
+ shouldFocus?: () => boolean;
6
+ /** Called when an upward move leaves the grid. */
7
+ exitUp?: () => void;
8
+ /** Receives the destination cell; focuses it by default. */
9
+ moveTo?: (emoji: HTMLElement) => void;
10
+ /** Source cell while a virtualized destination is being materialized. */
11
+ origin?: HTMLElement;
12
+ };
13
+ /** Move to the first filtered result, including a cell outside the viewport. */
14
+ export declare function focusFirstEmoji(body: NullableElement, options: MoveOptions): boolean;
15
+ export declare function focusAdjacentEmoji(element: NullableElement, direction: number, row: boolean, options: MoveOptions): void;
@@ -1,5 +1,4 @@
1
- import { NullableElement } from './selectors';
2
- export declare function scrollTo(root: NullableElement, top?: number): void;
3
- export declare function scrollBy(root: NullableElement, by: number): void;
4
- export declare function useScrollTo(): (top: number) => void;
5
- export declare function scrollEmojiAboveLabel(emoji: NullableElement): void;
1
+ import { NullableElement } from './selectors';
2
+ export declare function scrollTo(root: NullableElement, top?: number | (() => number), shouldScroll?: () => boolean): void;
3
+ export declare function useScrollTo(): (top: number) => void;
4
+ export declare function scrollEmojiAboveLabel(emoji: NullableElement, shouldScroll?: () => boolean): void;