emoji-picker-react 4.22.3 → 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 +331 -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 -480
  271. package/package.json +180 -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
@@ -0,0 +1,133 @@
1
+ import * as React from 'react';
2
+ import { createSheet } from 'shipstyles';
3
+
4
+ import { DedupedStyle } from '../Stylesheet/DedupedStyle';
5
+ import { finalizeCss } from '../Stylesheet/stylesheet';
6
+
7
+ import {
8
+ darkPickerTokens,
9
+ lightPickerTokens,
10
+ structuralPickerTokens,
11
+ } from './tokens';
12
+
13
+ // Library-owned structural CSS on its own stylesheet (docs/v5/STYLING.md
14
+ // §1–§2): the Root containing block, the managed panel layout, and the
15
+ // geometry tokens that measurement, virtualization and keyboard row math
16
+ // depend on. Opt-in color themes (variables only) live here too; the
17
+ // branded chrome (border, background, radius, motion, typography) stays in
18
+ // the default tree on the main sheet, so a primitives-only consumer never
19
+ // pulls it in. Values match the documented defaults so the default tree —
20
+ // which re-declares them — renders identically.
21
+ const structuralSheet = /* @__PURE__ */ createSheet('epr-structural', null);
22
+
23
+ // A fallback reset must yield to design-library classes. MUI inputs use
24
+ // content-box heights plus padding; a Root-class universal reset otherwise
25
+ // overrides that rule and clips their text. Managed cells own their sizing
26
+ // separately. Keep this inside the same nonce/layer boundary as the sheet.
27
+ const boxSizingReset =
28
+ ':where(.epr-structural-root *){box-sizing:border-box;}' +
29
+ // Honor the OS "reduce motion" setting for the library's own motion
30
+ // (expanding reactions, the tone fan, hover fades). Class-level and
31
+ // emitted after the main sheet, so it beats library transitions while
32
+ // a consumer's more specific rule still wins.
33
+ '@media (prefers-reduced-motion:reduce){.epr-structural-root,.epr-structural-root *{transition-duration:0s}}' +
34
+ // appearance="default" paints the token surface behind the built-in
35
+ // leaves, so colorScheme="dark" is not dark controls on a transparent
36
+ // root. Zero specificity: any consumer background wins.
37
+ ':where(.epr-appearance-default){background-color:var(--epr-bg-color)}' +
38
+ // `columns`: the picker hugs that many emoji columns (plus the stable
39
+ // scrollbar gutter) unless the consumer sizes it; any width rule wins.
40
+ // In layout the content box spans the row (columns spread evenly); a
41
+ // narrower container caps it, so fewer columns render.
42
+ ':where([data-epr-columns]){width:fit-content;max-width:100%}' +
43
+ // Only the column geometry sizes the picker. Hover/focus titles, the
44
+ // search row (whose input grows as the skin tone fan opens) and a
45
+ // horizontal tab bar fill the resulting row instead of widening it; a
46
+ // vertical tab rail still adds its own width beside the grid.
47
+ ':where([data-epr-columns] :is([data-epr-part=preview],[data-epr-part=search],[aria-orientation=horizontal])){contain:inline-size}' +
48
+ ':where([data-epr-columns] [data-epr-part=viewport]){scrollbar-gutter:stable}' +
49
+ ':where([data-epr-columns] [data-epr-part=category-content]){width:calc(var(--epr-columns)*var(--epr-emoji-fullsize));min-width:calc(100% - 2*var(--epr-horizontal-padding));max-width:calc(100% - 2*var(--epr-horizontal-padding))}';
50
+
51
+ export const structuralStyles = /* @__PURE__ */ (() =>
52
+ structuralSheet.create({
53
+ root: {
54
+ '.': 'epr-structural-root',
55
+ position: 'relative',
56
+ display: 'flex',
57
+ flexDirection: 'column',
58
+ // The root is never a scroll container (the Viewport owns scrolling):
59
+ // clip forbids focus-reveal and programmatic scrolling, which `hidden`
60
+ // still permits. Both axes must clip: per spec, clip on one axis
61
+ // computes to hidden when the other axis is hidden, which is how a
62
+ // transient overflow plus autofocus used to leave the whole panel
63
+ // shifted sideways. `hidden` is the fallback for browsers without clip.
64
+ overflow: 'hidden',
65
+ overflowX: 'clip',
66
+ overflowY: 'clip',
67
+ // Every geometry token, so a bare Root lays out and measures
68
+ // correctly with no appearance tokens at all.
69
+ '--': structuralPickerTokens,
70
+ },
71
+ // Opt-in color themes for primitives (`<Root theme>`). Variables only:
72
+ // no borders, backgrounds or typography on the Root itself.
73
+ themeLight: {
74
+ '.': 'epr-theme-light',
75
+ '--': lightPickerTokens,
76
+ },
77
+ themeDark: {
78
+ '.': 'epr-theme-dark',
79
+ '--': { ...lightPickerTokens, ...darkPickerTokens },
80
+ colorScheme: 'dark',
81
+ },
82
+ themeAuto: {
83
+ '.': 'epr-theme-auto',
84
+ '--': lightPickerTokens,
85
+ '@media (prefers-color-scheme: dark)': {
86
+ '--': darkPickerTokens,
87
+ colorScheme: 'dark',
88
+ },
89
+ },
90
+ panel: {
91
+ '.': 'epr-structural-panel',
92
+ display: 'flex',
93
+ flexDirection: 'column',
94
+ flex: '1 1 auto',
95
+ minHeight: '0',
96
+ minWidth: '0',
97
+ },
98
+ // Convenience composition owns compact geometry. Explicit composition
99
+ // retains the host's dimensions. Pill decoration is separately opt-in.
100
+ collapsed: {
101
+ '.': 'epr-structural-collapsed',
102
+ height: '50px',
103
+ width: 'fit-content',
104
+ },
105
+ collapsedAppearance: {
106
+ backgroundColor: 'var(--epr-reactions-bg-color, transparent)',
107
+ // @ts-ignore - backdropFilter is not recognized.
108
+ backdropFilter: 'blur(8px)',
109
+ '--': {
110
+ '--epr-picker-border-radius': '50px',
111
+ },
112
+ },
113
+ }))();
114
+
115
+ export const StructuralStyleTag = /* @__PURE__ */ React.memo(
116
+ function StructuralStyleTag({
117
+ nonce,
118
+ cssLayer,
119
+ }: {
120
+ nonce?: string;
121
+ cssLayer?: string;
122
+ }) {
123
+ return (
124
+ <DedupedStyle
125
+ nonce={nonce}
126
+ css={finalizeCss(
127
+ structuralSheet.getStyle() + '\n' + boxSizingReset,
128
+ cssLayer,
129
+ )}
130
+ />
131
+ );
132
+ },
133
+ );
@@ -0,0 +1,149 @@
1
+ import { DEFAULT_LABEL_HEIGHT } from '../components/main/labelHeight';
2
+
3
+ // Design tokens. The
4
+ // documented `--epr-*` variable defaults as plain data: no styles, no side
5
+ // effects.
6
+ //
7
+ // - structuralPickerTokens: geometry, always applied by every Root.
8
+ // - lightPickerTokens / darkPickerTokens: colors, applied by
9
+ // `<Root theme="light" | "dark" | "auto">`, or by hand.
10
+ // - defaultPickerTokens: geometry + light colors (the v4 defaults), shared
11
+ // with the default picker so the two cannot drift apart.
12
+ /**
13
+ * Geometry tokens: sizes, spacing and stacking that measurement,
14
+ * virtualization and layout depend on. Every Root applies these
15
+ * (structural stylesheet), so a bare composition is functional without
16
+ * any appearance tokens. Consumers may override them; measurement reads
17
+ * the resulting DOM.
18
+ */
19
+ export const structuralPickerTokens: Record<string, string> = {
20
+ '--epr-horizontal-padding': '10px',
21
+
22
+ /* Header */
23
+ '--epr-header-padding': '15px var(--epr-horizontal-padding)',
24
+
25
+ /* Search */
26
+ '--epr-search-input-padding': '0 30px',
27
+ '--epr-search-input-height': '40px',
28
+ '--epr-search-bar-inner-padding': 'var(--epr-horizontal-padding)',
29
+
30
+ /* Category Navigation */
31
+ '--epr-category-navigation-button-size': '30px',
32
+
33
+ '--epr-skin-tone-size': '15px',
34
+
35
+ /* Variation Picker */
36
+ '--epr-emoji-variation-picker-height': '45px',
37
+
38
+ /* Preview */
39
+ '--epr-preview-height': '70px',
40
+ '--epr-preview-emoji-size': '45px',
41
+ '--epr-preview-text-size': '14px',
42
+ '--epr-preview-text-padding': '0 var(--epr-horizontal-padding)',
43
+
44
+ /* Category */
45
+ '--epr-category-padding': '0 var(--epr-horizontal-padding)',
46
+
47
+ /* Category Label */
48
+ '--epr-category-label-padding': '0 var(--epr-horizontal-padding)',
49
+ '--epr-category-label-height': `${DEFAULT_LABEL_HEIGHT}px`,
50
+
51
+ /* Emoji */
52
+ '--epr-emoji-size': '30px',
53
+ '--epr-emoji-padding': '5px',
54
+ '--epr-emoji-fullsize':
55
+ 'calc(var(--epr-emoji-size) + var(--epr-emoji-padding) * 2)',
56
+
57
+ /* Z-Index */
58
+ '--epr-header-overlay-z-index': '3',
59
+ '--epr-emoji-variations-indictator-z-index': '1',
60
+ '--epr-category-label-z-index': '2',
61
+ '--epr-skin-variation-picker-z-index': '5',
62
+ '--epr-preview-z-index': '6',
63
+ };
64
+
65
+ /** Light color tokens (the v4 default palette). */
66
+ export const lightPickerTokens: Record<string, string> = {
67
+ '--epr-highlight-color': '#007aeb',
68
+ '--epr-hover-bg-color': '#e5f0fa',
69
+ '--epr-hover-bg-color-reduced-opacity': '#e5f0fa80',
70
+ '--epr-focus-bg-color': '#e0f0ff',
71
+ // WCAG AA: #858585 measured 3.4–3.7:1 on the light surfaces; #6b6b6b
72
+ // is ~5:1 on both the background and the search field.
73
+ '--epr-text-color': '#6b6b6b',
74
+ '--epr-search-input-bg-color': '#f6f6f6',
75
+ '--epr-picker-border-color': '#e7e7e7',
76
+ '--epr-bg-color': '#fff',
77
+ '--epr-reactions-bg-color': '#ffffff90',
78
+ '--epr-category-icon-active-color': '#3371B7',
79
+ '--epr-category-icon-inactive-color': '#868686',
80
+ '--epr-skin-tone-picker-menu-color': '#ffffff95',
81
+ '--epr-skin-tone-outer-border-color': '#555555',
82
+ '--epr-skin-tone-inner-border-color': 'var(--epr-bg-color)',
83
+
84
+ '--epr-picker-border-radius': '8px',
85
+
86
+ /* Skin Tone Picker */
87
+ '--epr-active-skin-tone-indicator-border-color': 'var(--epr-highlight-color)',
88
+ '--epr-active-skin-hover-color': 'var(--epr-hover-bg-color)',
89
+
90
+ /* Search */
91
+ '--epr-search-input-bg-color-active': 'var(--epr-search-input-bg-color)',
92
+ '--epr-search-input-border-radius': '8px',
93
+ '--epr-search-input-text-color': 'var(--epr-text-color)',
94
+ '--epr-search-input-placeholder-color': 'var(--epr-text-color)',
95
+ '--epr-search-border-color': 'var(--epr-search-input-bg-color)',
96
+ '--epr-search-border-color-active': 'var(--epr-highlight-color)',
97
+
98
+ /* Variation Picker */
99
+ '--epr-emoji-variation-picker-bg-color': 'var(--epr-bg-color)',
100
+
101
+ /* Preview */
102
+ '--epr-preview-border-color': 'var(--epr-picker-border-color)',
103
+ '--epr-preview-text-color': 'var(--epr-text-color)',
104
+
105
+ /* Category Label */
106
+ '--epr-category-label-bg-color': '#ffffffe6',
107
+ '--epr-category-label-text-color': 'var(--epr-text-color)',
108
+
109
+ /* Emoji */
110
+ '--epr-emoji-hover-color': 'var(--epr-hover-bg-color)',
111
+ '--epr-emoji-variation-indicator-color': 'var(--epr-picker-border-color)',
112
+ '--epr-emoji-variation-indicator-color-hover': 'var(--epr-text-color)',
113
+ };
114
+
115
+ /**
116
+ * Dark color overrides layered on top of the light tokens. Direct values:
117
+ * the default picker keeps its private `--epr-dark-*` indirection for v4
118
+ * compatibility, primitives do not need it.
119
+ */
120
+ export const darkPickerTokens: Record<string, string> = {
121
+ '--epr-emoji-variation-picker-bg-color': '#000',
122
+ '--epr-hover-bg-color-reduced-opacity': '#36363680',
123
+ '--epr-highlight-color': '#c0c0c0',
124
+ '--epr-text-color': 'var(--epr-highlight-color)',
125
+ '--epr-hover-bg-color': '#363636f6',
126
+ '--epr-focus-bg-color': '#474747',
127
+ '--epr-search-input-bg-color': '#333333',
128
+ '--epr-category-label-bg-color': '#222222e6',
129
+ '--epr-picker-border-color': '#151617',
130
+ '--epr-bg-color': '#222222',
131
+ '--epr-reactions-bg-color': '#22222290',
132
+ '--epr-search-input-bg-color-active': '#000',
133
+ '--epr-emoji-variation-indicator-color': '#444',
134
+ '--epr-category-icon-active-color': '#6AA9DD',
135
+ '--epr-category-icon-inactive-color': '#C0C0BF',
136
+ '--epr-skin-tone-picker-menu-color': '#22222295',
137
+ '--epr-skin-tone-outer-border-color': '#151617',
138
+ '--epr-skin-tone-inner-border-color': '#00000000',
139
+ };
140
+
141
+ /** Full light preset: geometry plus light colors (v4 defaults). */
142
+ export const defaultPickerTokens: Record<string, string> = {
143
+ ...lightPickerTokens,
144
+ ...structuralPickerTokens,
145
+ };
146
+
147
+ // NOTE: the `--epr-dark-*` indirection variables are deliberately NOT part
148
+ // of this module. They exist only in the default tree's DarkTheme overrides
149
+ // (v4 compatibility); primitives theme through `darkPickerTokens` instead.
@@ -0,0 +1,192 @@
1
+ import * as React from 'react';
2
+
3
+ import type { ListComponents } from '../components/body/listComponents';
4
+ import type { PickerConfig } from '../config/config';
5
+ import type { ThemeValue } from '../types/exposedTypes';
6
+
7
+ import type { PickerComponents } from './components';
8
+
9
+ // Public primitive prop contracts (docs/v5/PRIMITIVES.md).
10
+ // React-16.8-compatible types only (no React-18-only type helpers).
11
+
12
+ /**
13
+ * Appearance props owned by the default <EmojiPicker /> wrapper, plus the
14
+ * two that Root already accepts as native `aside` attributes. This list is
15
+ * short and stable; the behavior set is long and grows.
16
+ */
17
+ export type PickerAppearanceProps =
18
+ | 'theme'
19
+ | 'colorScheme'
20
+ | 'width'
21
+ | 'height'
22
+ | 'className'
23
+ | 'style'
24
+ | 'unstyled';
25
+
26
+ /** Presence and placement belong to the caller's JSX, not Root switches. */
27
+ export type PickerCompositionProps =
28
+ | 'open'
29
+ | 'searchDisabled'
30
+ | 'skinTonesDisabled'
31
+ | 'skinTonePickerLocation';
32
+
33
+ export type RootBehaviorProps = Omit<
34
+ PickerConfig,
35
+ PickerAppearanceProps | PickerCompositionProps | 'previewConfig'
36
+ > & {
37
+ previewConfig?: Omit<
38
+ NonNullable<PickerConfig['previewConfig']>,
39
+ 'showPreview'
40
+ >;
41
+ };
42
+
43
+ export type RootProps = Omit<
44
+ React.HTMLAttributes<HTMLElement>,
45
+ keyof RootBehaviorProps | 'children' | 'role' | 'dangerouslySetInnerHTML'
46
+ > &
47
+ RootBehaviorProps & {
48
+ children: React.ReactNode;
49
+ /** Built-in leaf appearance. Bare compositions default to 'none'. */
50
+ appearance?: 'none' | 'default';
51
+ /** Shared replacements for grid, variation, reaction and navigation controls. */
52
+ components?: PickerComponents;
53
+ /**
54
+ * Opt-in color scheme: applies the default light/dark color tokens as
55
+ * CSS variables on Root (no border, background or typography).
56
+ * Omit it to style a fully unbranded picker yourself. (Not `theme`:
57
+ * CSS-in-JS libraries reserve that prop on components they wrap.)
58
+ */
59
+ colorScheme?: ThemeValue;
60
+ };
61
+
62
+ /**
63
+ * Children are trailing controls, e.g. <SkinTone />; nothing is inserted
64
+ * automatically.
65
+ */
66
+ export type SearchProps = Omit<
67
+ React.HTMLAttributes<HTMLDivElement>,
68
+ 'role' | 'dangerouslySetInnerHTML'
69
+ > & {
70
+ /** Native attributes for the managed input; Root owns its value. */
71
+ inputProps?: Omit<
72
+ React.InputHTMLAttributes<HTMLInputElement>,
73
+ | 'type'
74
+ | 'value'
75
+ | 'defaultValue'
76
+ | 'onChange'
77
+ | 'autoFocus'
78
+ | 'placeholder'
79
+ | 'aria-controls'
80
+ | 'role'
81
+ | 'children'
82
+ | 'dangerouslySetInnerHTML'
83
+ >;
84
+ inputRef?: React.Ref<HTMLInputElement>;
85
+ };
86
+
87
+ export type SearchInputElement = 'input' | React.ComponentType<any>;
88
+
89
+ type ManagedInputProps = Omit<
90
+ React.InputHTMLAttributes<HTMLInputElement>,
91
+ | 'type'
92
+ | 'value'
93
+ | 'defaultValue'
94
+ | 'role'
95
+ | 'aria-controls'
96
+ | 'children'
97
+ | 'dangerouslySetInnerHTML'
98
+ >;
99
+
100
+ type ReservedInputProps =
101
+ | 'type'
102
+ | 'value'
103
+ | 'defaultValue'
104
+ | 'role'
105
+ | 'aria-controls'
106
+ | 'children'
107
+ | 'dangerouslySetInnerHTML'
108
+ | 'as';
109
+
110
+ type InputBehaviorHandlers =
111
+ | 'onChange'
112
+ | 'onFocus'
113
+ | 'onCompositionStart'
114
+ | 'onCompositionEnd';
115
+
116
+ /** Native input props plus the selected design-system input's own props. */
117
+ export type SearchInputProps<T extends SearchInputElement = 'input'> = Omit<
118
+ ManagedInputProps,
119
+ keyof React.ComponentPropsWithoutRef<T>
120
+ > &
121
+ Pick<ManagedInputProps, InputBehaviorHandlers> &
122
+ Omit<
123
+ React.ComponentPropsWithoutRef<T>,
124
+ ReservedInputProps | InputBehaviorHandlers
125
+ > & {
126
+ /** Must forward its ref and supplied props to an actual input element. */
127
+ as?: T;
128
+ };
129
+
130
+ export type SearchInputComponent = <T extends SearchInputElement = 'input'>(
131
+ props: SearchInputProps<T> & React.RefAttributes<HTMLInputElement>,
132
+ ) => React.ReactElement | null;
133
+
134
+ export type CategoryNavProps = Omit<
135
+ React.HTMLAttributes<HTMLDivElement>,
136
+ 'role' | 'children' | 'dangerouslySetInnerHTML'
137
+ > & {
138
+ /**
139
+ * Tab axis. `vertical` stacks the tabs (e.g. a side rail) and switches
140
+ * keyboard navigation to Up/Down between tabs and Left/Right to leave,
141
+ * announced through aria-orientation. Default: 'horizontal'.
142
+ */
143
+ orientation?: 'horizontal' | 'vertical';
144
+ };
145
+
146
+ export type PreviewProps = Omit<
147
+ React.HTMLAttributes<HTMLDivElement>,
148
+ 'role' | 'dangerouslySetInnerHTML'
149
+ >;
150
+
151
+ export type ListProps = Omit<
152
+ React.HTMLAttributes<HTMLUListElement>,
153
+ 'role' | 'children' | 'dangerouslySetInnerHTML'
154
+ > & {
155
+ /**
156
+ * Custom markup for emoji cells and category headers. Each receives the
157
+ * library-owned props to spread onto its element (see EmojiRenderProps /
158
+ * CategoryHeaderRenderProps).
159
+ */
160
+ components?: ListComponents;
161
+ };
162
+
163
+ export type EmptyProps = Omit<
164
+ React.HTMLAttributes<HTMLDivElement>,
165
+ 'role' | 'children' | 'dangerouslySetInnerHTML'
166
+ > & {
167
+ children?: React.ReactNode | ((state: { search: string }) => React.ReactNode);
168
+ };
169
+
170
+ export type SkinToneProps = Omit<
171
+ React.HTMLAttributes<HTMLDivElement>,
172
+ 'role' | 'children' | 'dangerouslySetInnerHTML'
173
+ > & {
174
+ /** Axis the tones fan out along. Default: 'horizontal'. */
175
+ orientation?: 'horizontal' | 'vertical';
176
+ };
177
+
178
+ export type LoadingProps = Omit<
179
+ React.HTMLAttributes<HTMLDivElement>,
180
+ 'role' | 'children' | 'dangerouslySetInnerHTML'
181
+ > & {
182
+ children?: React.ReactNode;
183
+ };
184
+
185
+ export type LoadErrorProps = Omit<
186
+ React.HTMLAttributes<HTMLDivElement>,
187
+ 'role' | 'children' | 'dangerouslySetInnerHTML'
188
+ > & {
189
+ children?:
190
+ | React.ReactNode
191
+ | ((state: { error: Error; retry: () => void }) => React.ReactNode);
192
+ };
@@ -0,0 +1,39 @@
1
+ import type { ActiveEmojiState } from '../components/context/PickerContext';
2
+
3
+ /** Instance-local subscriptions: changing hover updates only affected cells. */
4
+ export function createActiveEmojiStore() {
5
+ let value: ActiveEmojiState = null;
6
+ const readers = new Set<() => void>();
7
+ const cells = new Map<string, Set<() => void>>();
8
+ return {
9
+ get: () => value,
10
+ set(
11
+ next:
12
+ ActiveEmojiState | ((previous: ActiveEmojiState) => ActiveEmojiState),
13
+ ) {
14
+ const previous = value;
15
+ const resolved = typeof next === 'function' ? next(previous) : next;
16
+ if (
17
+ previous?.unified === resolved?.unified &&
18
+ previous?.originalUnified === resolved?.originalUnified
19
+ )
20
+ return;
21
+ value = resolved;
22
+ readers.forEach((read) => read());
23
+ new Set([previous?.unified, resolved?.unified]).forEach((key) => {
24
+ if (key) cells.get(key)?.forEach((read) => read());
25
+ });
26
+ },
27
+ subscribe(read: () => void, unified?: string) {
28
+ const group = unified
29
+ ? (cells.get(unified) ?? new Set<() => void>())
30
+ : readers;
31
+ if (unified) cells.set(unified, group);
32
+ group.add(read);
33
+ return () => {
34
+ group.delete(read);
35
+ if (unified && group.size === 0) cells.delete(unified);
36
+ };
37
+ },
38
+ };
39
+ }