@liveblocks/react-ui 2.14.0 → 2.15.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 (272) hide show
  1. package/dist/_private/index.d.mts +24 -22
  2. package/dist/_private/index.d.ts +24 -22
  3. package/dist/_private/index.js +1 -0
  4. package/dist/_private/index.js.map +1 -1
  5. package/dist/_private/index.mjs +1 -0
  6. package/dist/_private/index.mjs.map +1 -1
  7. package/dist/components/Comment.js +358 -256
  8. package/dist/components/Comment.js.map +1 -1
  9. package/dist/components/Comment.mjs +334 -232
  10. package/dist/components/Comment.mjs.map +1 -1
  11. package/dist/components/Composer.js +308 -225
  12. package/dist/components/Composer.js.map +1 -1
  13. package/dist/components/Composer.mjs +288 -206
  14. package/dist/components/Composer.mjs.map +1 -1
  15. package/dist/components/HistoryVersionSummary.js +28 -32
  16. package/dist/components/HistoryVersionSummary.js.map +1 -1
  17. package/dist/components/HistoryVersionSummary.mjs +27 -31
  18. package/dist/components/HistoryVersionSummary.mjs.map +1 -1
  19. package/dist/components/HistoryVersionSummaryList.js +11 -9
  20. package/dist/components/HistoryVersionSummaryList.js.map +1 -1
  21. package/dist/components/HistoryVersionSummaryList.mjs +10 -8
  22. package/dist/components/HistoryVersionSummaryList.mjs.map +1 -1
  23. package/dist/components/InboxNotification.js +202 -143
  24. package/dist/components/InboxNotification.js.map +1 -1
  25. package/dist/components/InboxNotification.mjs +180 -121
  26. package/dist/components/InboxNotification.mjs.map +1 -1
  27. package/dist/components/InboxNotificationList.js +19 -14
  28. package/dist/components/InboxNotificationList.js.map +1 -1
  29. package/dist/components/InboxNotificationList.mjs +17 -12
  30. package/dist/components/InboxNotificationList.mjs.map +1 -1
  31. package/dist/components/Thread.js +104 -86
  32. package/dist/components/Thread.js.map +1 -1
  33. package/dist/components/Thread.mjs +93 -75
  34. package/dist/components/Thread.mjs.map +1 -1
  35. package/dist/components/internal/Attachment.js +161 -113
  36. package/dist/components/internal/Attachment.js.map +1 -1
  37. package/dist/components/internal/Attachment.mjs +150 -102
  38. package/dist/components/internal/Attachment.mjs.map +1 -1
  39. package/dist/components/internal/Attribution.js +15 -13
  40. package/dist/components/internal/Attribution.js.map +1 -1
  41. package/dist/components/internal/Attribution.mjs +15 -13
  42. package/dist/components/internal/Attribution.mjs.map +1 -1
  43. package/dist/components/internal/Avatar.js +27 -20
  44. package/dist/components/internal/Avatar.js.map +1 -1
  45. package/dist/components/internal/Avatar.mjs +23 -16
  46. package/dist/components/internal/Avatar.mjs.map +1 -1
  47. package/dist/components/internal/Button.js +5 -4
  48. package/dist/components/internal/Button.js.map +1 -1
  49. package/dist/components/internal/Button.mjs +4 -3
  50. package/dist/components/internal/Button.mjs.map +1 -1
  51. package/dist/components/internal/Dropdown.js +27 -19
  52. package/dist/components/internal/Dropdown.js.map +1 -1
  53. package/dist/components/internal/Dropdown.mjs +26 -18
  54. package/dist/components/internal/Dropdown.mjs.map +1 -1
  55. package/dist/components/internal/Emoji.js +4 -3
  56. package/dist/components/internal/Emoji.js.map +1 -1
  57. package/dist/components/internal/Emoji.mjs +3 -2
  58. package/dist/components/internal/Emoji.mjs.map +1 -1
  59. package/dist/components/internal/EmojiPicker.js +96 -72
  60. package/dist/components/internal/EmojiPicker.js.map +1 -1
  61. package/dist/components/internal/EmojiPicker.mjs +90 -66
  62. package/dist/components/internal/EmojiPicker.mjs.map +1 -1
  63. package/dist/components/internal/Icon.js +5 -4
  64. package/dist/components/internal/Icon.js.map +1 -1
  65. package/dist/components/internal/Icon.mjs +5 -4
  66. package/dist/components/internal/Icon.mjs.map +1 -1
  67. package/dist/components/internal/InboxNotificationThread.js +53 -38
  68. package/dist/components/internal/InboxNotificationThread.js.map +1 -1
  69. package/dist/components/internal/InboxNotificationThread.mjs +53 -38
  70. package/dist/components/internal/InboxNotificationThread.mjs.map +1 -1
  71. package/dist/components/internal/List.js +8 -6
  72. package/dist/components/internal/List.js.map +1 -1
  73. package/dist/components/internal/List.mjs +6 -4
  74. package/dist/components/internal/List.mjs.map +1 -1
  75. package/dist/components/internal/Room.js +8 -6
  76. package/dist/components/internal/Room.js.map +1 -1
  77. package/dist/components/internal/Room.mjs +7 -5
  78. package/dist/components/internal/Room.mjs.map +1 -1
  79. package/dist/components/internal/Tooltip.js +49 -33
  80. package/dist/components/internal/Tooltip.js.map +1 -1
  81. package/dist/components/internal/Tooltip.mjs +46 -30
  82. package/dist/components/internal/Tooltip.mjs.map +1 -1
  83. package/dist/components/internal/User.js +8 -6
  84. package/dist/components/internal/User.js.map +1 -1
  85. package/dist/components/internal/User.mjs +7 -5
  86. package/dist/components/internal/User.mjs.map +1 -1
  87. package/dist/components.js +12 -29
  88. package/dist/components.js.map +1 -1
  89. package/dist/components.mjs +6 -5
  90. package/dist/components.mjs.map +1 -1
  91. package/dist/config.js +16 -12
  92. package/dist/config.js.map +1 -1
  93. package/dist/config.mjs +13 -9
  94. package/dist/config.mjs.map +1 -1
  95. package/dist/icons/ArrowDown.js +7 -6
  96. package/dist/icons/ArrowDown.js.map +1 -1
  97. package/dist/icons/ArrowDown.mjs +7 -6
  98. package/dist/icons/ArrowDown.mjs.map +1 -1
  99. package/dist/icons/ArrowUp.js +7 -6
  100. package/dist/icons/ArrowUp.js.map +1 -1
  101. package/dist/icons/ArrowUp.mjs +7 -6
  102. package/dist/icons/ArrowUp.mjs.map +1 -1
  103. package/dist/icons/Attachment.js +7 -6
  104. package/dist/icons/Attachment.js.map +1 -1
  105. package/dist/icons/Attachment.mjs +7 -6
  106. package/dist/icons/Attachment.mjs.map +1 -1
  107. package/dist/icons/Bold.js +7 -6
  108. package/dist/icons/Bold.js.map +1 -1
  109. package/dist/icons/Bold.mjs +7 -6
  110. package/dist/icons/Bold.mjs.map +1 -1
  111. package/dist/icons/Check.js +7 -6
  112. package/dist/icons/Check.js.map +1 -1
  113. package/dist/icons/Check.mjs +7 -6
  114. package/dist/icons/Check.mjs.map +1 -1
  115. package/dist/icons/Code.js +7 -6
  116. package/dist/icons/Code.js.map +1 -1
  117. package/dist/icons/Code.mjs +7 -6
  118. package/dist/icons/Code.mjs.map +1 -1
  119. package/dist/icons/Cross.js +12 -8
  120. package/dist/icons/Cross.js.map +1 -1
  121. package/dist/icons/Cross.mjs +12 -8
  122. package/dist/icons/Cross.mjs.map +1 -1
  123. package/dist/icons/Delete.js +7 -6
  124. package/dist/icons/Delete.js.map +1 -1
  125. package/dist/icons/Delete.mjs +7 -6
  126. package/dist/icons/Delete.mjs.map +1 -1
  127. package/dist/icons/Edit.js +7 -6
  128. package/dist/icons/Edit.js.map +1 -1
  129. package/dist/icons/Edit.mjs +7 -6
  130. package/dist/icons/Edit.mjs.map +1 -1
  131. package/dist/icons/Ellipsis.js +21 -16
  132. package/dist/icons/Ellipsis.js.map +1 -1
  133. package/dist/icons/Ellipsis.mjs +21 -16
  134. package/dist/icons/Ellipsis.mjs.map +1 -1
  135. package/dist/icons/Emoji.js +25 -18
  136. package/dist/icons/Emoji.js.map +1 -1
  137. package/dist/icons/Emoji.mjs +25 -18
  138. package/dist/icons/Emoji.mjs.map +1 -1
  139. package/dist/icons/EmojiAdd.js +28 -20
  140. package/dist/icons/EmojiAdd.js.map +1 -1
  141. package/dist/icons/EmojiAdd.mjs +28 -20
  142. package/dist/icons/EmojiAdd.mjs.map +1 -1
  143. package/dist/icons/Italic.js +7 -6
  144. package/dist/icons/Italic.js.map +1 -1
  145. package/dist/icons/Italic.mjs +7 -6
  146. package/dist/icons/Italic.mjs.map +1 -1
  147. package/dist/icons/Mention.js +12 -8
  148. package/dist/icons/Mention.js.map +1 -1
  149. package/dist/icons/Mention.mjs +12 -8
  150. package/dist/icons/Mention.mjs.map +1 -1
  151. package/dist/icons/Resolve.js +14 -10
  152. package/dist/icons/Resolve.js.map +1 -1
  153. package/dist/icons/Resolve.mjs +14 -10
  154. package/dist/icons/Resolve.mjs.map +1 -1
  155. package/dist/icons/Resolved.js +16 -12
  156. package/dist/icons/Resolved.js.map +1 -1
  157. package/dist/icons/Resolved.mjs +16 -12
  158. package/dist/icons/Resolved.mjs.map +1 -1
  159. package/dist/icons/Restore.js +12 -8
  160. package/dist/icons/Restore.js.map +1 -1
  161. package/dist/icons/Restore.mjs +12 -8
  162. package/dist/icons/Restore.mjs.map +1 -1
  163. package/dist/icons/Search.js +7 -6
  164. package/dist/icons/Search.js.map +1 -1
  165. package/dist/icons/Search.mjs +7 -6
  166. package/dist/icons/Search.mjs.map +1 -1
  167. package/dist/icons/Send.js +7 -6
  168. package/dist/icons/Send.js.map +1 -1
  169. package/dist/icons/Send.mjs +7 -6
  170. package/dist/icons/Send.mjs.map +1 -1
  171. package/dist/icons/Spinner.js +8 -7
  172. package/dist/icons/Spinner.js.map +1 -1
  173. package/dist/icons/Spinner.mjs +8 -7
  174. package/dist/icons/Spinner.mjs.map +1 -1
  175. package/dist/icons/Strikethrough.js +7 -6
  176. package/dist/icons/Strikethrough.js.map +1 -1
  177. package/dist/icons/Strikethrough.mjs +7 -6
  178. package/dist/icons/Strikethrough.mjs.map +1 -1
  179. package/dist/icons/Warning.js +14 -10
  180. package/dist/icons/Warning.js.map +1 -1
  181. package/dist/icons/Warning.mjs +14 -10
  182. package/dist/icons/Warning.mjs.map +1 -1
  183. package/dist/icons/index.js +42 -0
  184. package/dist/icons/index.js.map +1 -0
  185. package/dist/icons/index.mjs +19 -0
  186. package/dist/icons/index.mjs.map +1 -0
  187. package/dist/index.d.mts +14 -12
  188. package/dist/index.d.ts +14 -12
  189. package/dist/overrides.js +65 -36
  190. package/dist/overrides.js.map +1 -1
  191. package/dist/overrides.mjs +59 -12
  192. package/dist/overrides.mjs.map +1 -1
  193. package/dist/primitives/Comment/index.js +75 -66
  194. package/dist/primitives/Comment/index.js.map +1 -1
  195. package/dist/primitives/Comment/index.mjs +71 -62
  196. package/dist/primitives/Comment/index.mjs.map +1 -1
  197. package/dist/primitives/Composer/contexts.js +11 -11
  198. package/dist/primitives/Composer/index.js +343 -284
  199. package/dist/primitives/Composer/index.js.map +1 -1
  200. package/dist/primitives/Composer/index.mjs +262 -203
  201. package/dist/primitives/Composer/index.mjs.map +1 -1
  202. package/dist/primitives/Composer/utils.js +20 -21
  203. package/dist/primitives/Composer/utils.js.map +1 -1
  204. package/dist/primitives/Composer/utils.mjs +4 -5
  205. package/dist/primitives/Composer/utils.mjs.map +1 -1
  206. package/dist/primitives/EmojiPicker/contexts.js +3 -3
  207. package/dist/primitives/EmojiPicker/index.js +160 -142
  208. package/dist/primitives/EmojiPicker/index.js.map +1 -1
  209. package/dist/primitives/EmojiPicker/index.mjs +122 -104
  210. package/dist/primitives/EmojiPicker/index.mjs.map +1 -1
  211. package/dist/primitives/FileSize.js +9 -7
  212. package/dist/primitives/FileSize.js.map +1 -1
  213. package/dist/primitives/FileSize.mjs +7 -5
  214. package/dist/primitives/FileSize.mjs.map +1 -1
  215. package/dist/primitives/Timestamp.js +12 -10
  216. package/dist/primitives/Timestamp.js.map +1 -1
  217. package/dist/primitives/Timestamp.mjs +7 -5
  218. package/dist/primitives/Timestamp.mjs.map +1 -1
  219. package/dist/primitives/index.d.mts +24 -23
  220. package/dist/primitives/index.d.ts +24 -23
  221. package/dist/primitives/internal/Emoji.js +7 -5
  222. package/dist/primitives/internal/Emoji.js.map +1 -1
  223. package/dist/primitives/internal/Emoji.mjs +6 -4
  224. package/dist/primitives/internal/Emoji.mjs.map +1 -1
  225. package/dist/shared.js +2 -7
  226. package/dist/shared.js.map +1 -1
  227. package/dist/shared.mjs +2 -7
  228. package/dist/shared.mjs.map +1 -1
  229. package/dist/slate/plugins/auto-links.mjs +1 -1
  230. package/dist/slate/plugins/custom-links.mjs +1 -1
  231. package/dist/slate/plugins/mentions.mjs +1 -1
  232. package/dist/utils/Persist.js +19 -18
  233. package/dist/utils/Persist.js.map +1 -1
  234. package/dist/utils/Persist.mjs +7 -6
  235. package/dist/utils/Persist.mjs.map +1 -1
  236. package/dist/utils/Portal.js +5 -4
  237. package/dist/utils/Portal.js.map +1 -1
  238. package/dist/utils/Portal.mjs +4 -3
  239. package/dist/utils/Portal.mjs.map +1 -1
  240. package/dist/utils/use-controllable-state.js +5 -5
  241. package/dist/utils/use-index.js +7 -7
  242. package/dist/utils/use-initial.js +2 -2
  243. package/dist/utils/use-interval.js +4 -4
  244. package/dist/utils/use-latest.js +3 -3
  245. package/dist/utils/use-observable.js +2 -2
  246. package/dist/utils/use-refs.js +2 -2
  247. package/dist/utils/use-rerender.js +2 -2
  248. package/dist/utils/use-visible.js +24 -2
  249. package/dist/utils/use-visible.js.map +1 -1
  250. package/dist/utils/use-visible.mjs +23 -2
  251. package/dist/utils/use-visible.mjs.map +1 -1
  252. package/dist/utils/use-window-focus.js +2 -2
  253. package/dist/utils/use-window-focus.js.map +1 -1
  254. package/dist/utils/use-window-focus.mjs +1 -1
  255. package/dist/utils/use-window-focus.mjs.map +1 -1
  256. package/dist/version.js +2 -2
  257. package/dist/version.js.map +1 -1
  258. package/dist/version.mjs +2 -2
  259. package/dist/version.mjs.map +1 -1
  260. package/package.json +10 -25
  261. package/dist/utils/use-id.js +0 -29
  262. package/dist/utils/use-id.js.map +0 -1
  263. package/dist/utils/use-id.mjs +0 -27
  264. package/dist/utils/use-id.mjs.map +0 -1
  265. package/dist/utils/use-layout-effect.js +0 -8
  266. package/dist/utils/use-layout-effect.js.map +0 -1
  267. package/dist/utils/use-layout-effect.mjs +0 -6
  268. package/dist/utils/use-layout-effect.mjs.map +0 -1
  269. package/dist/utils/use-transition.js +0 -16
  270. package/dist/utils/use-transition.js.map +0 -1
  271. package/dist/utils/use-transition.mjs +0 -14
  272. package/dist/utils/use-transition.mjs.map +0 -1
@@ -1,18 +1,17 @@
1
- 'use client';
2
1
  'use strict';
3
2
 
3
+ var jsxRuntime = require('react/jsx-runtime');
4
4
  var reactSlot = require('@radix-ui/react-slot');
5
- var React = require('react');
5
+ var react = require('react');
6
6
  var reactVirtuoso = require('react-virtuoso');
7
7
  var isKey = require('../../utils/is-key.js');
8
8
  var requestIdleCallback = require('../../utils/request-idle-callback.js');
9
- var useLayoutEffect = require('../../utils/use-layout-effect.js');
10
- var useTransition = require('../../utils/use-transition.js');
11
9
  var visuallyHidden = require('../../utils/visually-hidden.js');
12
10
  var Emoji = require('../internal/Emoji.js');
13
11
  var contexts = require('./contexts.js');
14
12
  var utils = require('./utils.js');
15
13
 
14
+ "use client";
16
15
  const DEFAULT_COLUMNS = 10;
17
16
  const DEFAULT_LOCALE = "en";
18
17
  const LOADING_MINIMUM_TIMEOUT = 100;
@@ -25,15 +24,15 @@ function EmojiPickerRoot({
25
24
  onEmojiSelect,
26
25
  children
27
26
  }) {
28
- const emojiData = React.useRef();
29
- const search = React.useRef("");
30
- const [, startEmojisTransition] = useTransition.useTransition();
31
- const [data, setData] = React.useState();
32
- const [error, setError] = React.useState();
33
- const [selectedColumnIndex, setSelectedColumnIndex] = React.useState(0);
34
- const [selectedRowIndex, setSelectedRowIndex] = React.useState(0);
35
- const [interaction, setInteraction] = React.useState("none");
36
- const selectCurrentEmoji = React.useCallback(() => {
27
+ const emojiData = react.useRef();
28
+ const search = react.useRef("");
29
+ const [, startEmojisTransition] = react.useTransition();
30
+ const [data, setData] = react.useState();
31
+ const [error, setError] = react.useState();
32
+ const [selectedColumnIndex, setSelectedColumnIndex] = react.useState(0);
33
+ const [selectedRowIndex, setSelectedRowIndex] = react.useState(0);
34
+ const [interaction, setInteraction] = react.useState("none");
35
+ const selectCurrentEmoji = react.useCallback(() => {
37
36
  if (onEmojiSelect) {
38
37
  const emoji = data?.rows[selectedRowIndex]?.[selectedColumnIndex];
39
38
  if (emoji) {
@@ -41,11 +40,11 @@ function EmojiPickerRoot({
41
40
  }
42
41
  }
43
42
  }, [data?.rows, onEmojiSelect, selectedColumnIndex, selectedRowIndex]);
44
- const resetSelection = React.useCallback(() => {
43
+ const resetSelection = react.useCallback(() => {
45
44
  setSelectedColumnIndex(0);
46
45
  setSelectedRowIndex(0);
47
46
  }, []);
48
- const setPointerSelection = React.useCallback(
47
+ const setPointerSelection = react.useCallback(
49
48
  (columnIndex, rowIndex) => {
50
49
  setInteraction("pointer");
51
50
  setSelectedColumnIndex(columnIndex);
@@ -53,7 +52,7 @@ function EmojiPickerRoot({
53
52
  },
54
53
  []
55
54
  );
56
- const moveSelection = React.useCallback(
55
+ const moveSelection = react.useCallback(
57
56
  (direction, event) => {
58
57
  if (!data) {
59
58
  return;
@@ -119,7 +118,7 @@ function EmojiPickerRoot({
119
118
  },
120
119
  [data, interaction, selectedColumnIndex, selectedRowIndex]
121
120
  );
122
- const updateEmojis = React.useCallback(() => {
121
+ const updateEmojis = react.useCallback(() => {
123
122
  if (!emojiData.current) {
124
123
  return;
125
124
  }
@@ -141,14 +140,14 @@ function EmojiPickerRoot({
141
140
  resetSelection();
142
141
  });
143
142
  }, [columns, resetSelection]);
144
- const handleSearch = React.useCallback(
143
+ const handleSearch = react.useCallback(
145
144
  (value) => {
146
145
  search.current = value;
147
146
  updateEmojis();
148
147
  },
149
148
  [updateEmojis]
150
149
  );
151
- const initializeEmojiData = React.useCallback(
150
+ const initializeEmojiData = react.useCallback(
152
151
  async (locale2) => {
153
152
  try {
154
153
  emojiData.current = await utils.getEmojiData(locale2);
@@ -159,7 +158,7 @@ function EmojiPickerRoot({
159
158
  },
160
159
  [updateEmojis]
161
160
  );
162
- React.useEffect(() => {
161
+ react.useEffect(() => {
163
162
  let idleCallbackId;
164
163
  const timeoutId = setTimeout(() => {
165
164
  idleCallbackId = requestIdleCallback.requestIdleCallback(() => {
@@ -171,12 +170,12 @@ function EmojiPickerRoot({
171
170
  requestIdleCallback.cancelIdleCallback(idleCallbackId);
172
171
  };
173
172
  }, [locale]);
174
- React.useEffect(() => {
173
+ react.useEffect(() => {
175
174
  if (interaction === "none") {
176
175
  resetSelection();
177
176
  }
178
177
  }, [interaction]);
179
- return /* @__PURE__ */ React.createElement(contexts.EmojiPickerContext.Provider, {
178
+ return /* @__PURE__ */ jsxRuntime.jsx(contexts.EmojiPickerContext.Provider, {
180
179
  value: {
181
180
  data,
182
181
  error,
@@ -191,10 +190,11 @@ function EmojiPickerRoot({
191
190
  setPointerSelection,
192
191
  interaction,
193
192
  setInteraction
194
- }
195
- }, children);
193
+ },
194
+ children
195
+ });
196
196
  }
197
- const EmojiPickerSearch = React.forwardRef(
197
+ const EmojiPickerSearch = react.forwardRef(
198
198
  ({ asChild, value, defaultValue, onChange, ...props }, forwardedRef) => {
199
199
  const Component = asChild ? reactSlot.Slot : "input";
200
200
  const {
@@ -204,7 +204,7 @@ const EmojiPickerSearch = React.forwardRef(
204
204
  interaction,
205
205
  setInteraction
206
206
  } = contexts.useEmojiPicker();
207
- const handleChange = React.useCallback(
207
+ const handleChange = react.useCallback(
208
208
  (event) => {
209
209
  onChange?.(event);
210
210
  if (event.isDefaultPrevented()) {
@@ -216,7 +216,7 @@ const EmojiPickerSearch = React.forwardRef(
216
216
  },
217
217
  [onChange, onSearch, setInteraction]
218
218
  );
219
- const handleKeyDown = React.useCallback(
219
+ const handleKeyDown = react.useCallback(
220
220
  (event) => {
221
221
  if (event.isDefaultPrevented()) {
222
222
  return;
@@ -238,12 +238,12 @@ const EmojiPickerSearch = React.forwardRef(
238
238
  },
239
239
  [interaction, moveSelection, selectCurrentEmoji]
240
240
  );
241
- React.useEffect(() => {
241
+ react.useEffect(() => {
242
242
  onSearch(
243
243
  value ? String(value) : defaultValue ? String(defaultValue) : ""
244
244
  );
245
245
  }, []);
246
- return /* @__PURE__ */ React.createElement(Component, {
246
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, {
247
247
  type: "search",
248
248
  value,
249
249
  defaultValue,
@@ -255,27 +255,30 @@ const EmojiPickerSearch = React.forwardRef(
255
255
  }
256
256
  );
257
257
  const defaultContentComponents = {
258
- CategoryHeader: ({ category, ...props }) => /* @__PURE__ */ React.createElement("div", {
259
- ...props
260
- }, category),
261
- Row: ({ children, attributes, ...props }) => /* @__PURE__ */ React.createElement("div", {
262
- ...props
263
- }, children),
264
- Emoji: ({ emoji, ...props }) => /* @__PURE__ */ React.createElement("button", {
265
- ...props
266
- }, /* @__PURE__ */ React.createElement(Emoji.Emoji, {
267
- emoji
268
- })),
269
- Loading: (props) => /* @__PURE__ */ React.createElement("div", {
258
+ CategoryHeader: ({ category, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", {
259
+ ...props,
260
+ children: category
261
+ }),
262
+ Row: ({ children, attributes, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", {
263
+ ...props,
264
+ children
265
+ }),
266
+ Emoji: ({ emoji, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("button", {
267
+ ...props,
268
+ children: /* @__PURE__ */ jsxRuntime.jsx(Emoji.Emoji, {
269
+ emoji
270
+ })
271
+ }),
272
+ Loading: (props) => /* @__PURE__ */ jsxRuntime.jsx("div", {
270
273
  ...props
271
274
  }),
272
- Empty: (props) => /* @__PURE__ */ React.createElement("div", {
275
+ Empty: (props) => /* @__PURE__ */ jsxRuntime.jsx("div", {
273
276
  ...props
274
277
  }),
275
- Grid: (props) => /* @__PURE__ */ React.createElement("div", {
278
+ Grid: (props) => /* @__PURE__ */ jsxRuntime.jsx("div", {
276
279
  ...props
277
280
  }),
278
- Error: ({ error, ...props }) => /* @__PURE__ */ React.createElement("div", {
281
+ Error: ({ error, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", {
279
282
  ...props
280
283
  })
281
284
  };
@@ -284,33 +287,35 @@ const placeholderRowAttributes = {
284
287
  categoryRowIndex: -1,
285
288
  categoryRowsCount: 0
286
289
  };
287
- const VirtuosoScroller = React.forwardRef(
290
+ const VirtuosoScroller = react.forwardRef(
288
291
  ({ children, ...props }, forwardedRef) => {
289
- return /* @__PURE__ */ React.createElement("div", {
292
+ return /* @__PURE__ */ jsxRuntime.jsx("div", {
290
293
  ...props,
291
294
  tabIndex: -1,
292
295
  "data-testid": void 0,
293
- ref: forwardedRef
294
- }, children);
296
+ ref: forwardedRef,
297
+ children
298
+ });
295
299
  }
296
300
  );
297
- const VirtuosoTopList = React.forwardRef(
301
+ const VirtuosoTopList = react.forwardRef(
298
302
  ({ children, ...props }, forwardedRef) => {
299
- return /* @__PURE__ */ React.createElement("div", {
303
+ return /* @__PURE__ */ jsxRuntime.jsx("div", {
300
304
  ...props,
301
305
  "data-testid": void 0,
302
- ref: forwardedRef
303
- }, children);
306
+ ref: forwardedRef,
307
+ children
308
+ });
304
309
  }
305
310
  );
306
- const EmojiPickerContent = React.forwardRef(
311
+ const EmojiPickerContent = react.forwardRef(
307
312
  ({ components, asChild, ...props }, forwardedRef) => {
308
313
  const Component = asChild ? reactSlot.Slot : "div";
309
- const virtuosoRef = React.useRef(null);
310
- const placeholderContainerRef = React.useRef(null);
311
- const rowScrollMarginTopRef = React.useRef(0);
312
- const rowScrollMarginBottomRef = React.useRef(0);
313
- const categoryHeaderHeightRef = React.useRef(0);
314
+ const virtuosoRef = react.useRef(null);
315
+ const placeholderContainerRef = react.useRef(null);
316
+ const rowScrollMarginTopRef = react.useRef(0);
317
+ const rowScrollMarginBottomRef = react.useRef(0);
318
+ const categoryHeaderHeightRef = react.useRef(0);
314
319
  const {
315
320
  data,
316
321
  error,
@@ -323,41 +328,42 @@ const EmojiPickerContent = React.forwardRef(
323
328
  interaction,
324
329
  setInteraction
325
330
  } = contexts.useEmojiPicker();
326
- const selectedEmoji = React.useMemo(
331
+ const selectedEmoji = react.useMemo(
327
332
  () => data?.rows[selectedRowIndex]?.[selectedColumnIndex],
328
333
  [data?.rows, selectedColumnIndex, selectedRowIndex]
329
334
  );
330
- const { Loading, Empty, Error, CategoryHeader, Grid, Row, Emoji } = React.useMemo(
335
+ const { Loading, Empty, Error, CategoryHeader, Grid, Row, Emoji } = react.useMemo(
331
336
  () => ({ ...defaultContentComponents, ...components }),
332
337
  [components]
333
338
  );
334
- const VirtuosoList = React.useMemo(
335
- () => React.forwardRef(
339
+ const VirtuosoList = react.useMemo(
340
+ () => react.forwardRef(
336
341
  ({ children, ...props2 }, forwardedRef2) => {
337
- return /* @__PURE__ */ React.createElement("div", {
342
+ return /* @__PURE__ */ jsxRuntime.jsx("div", {
338
343
  role: "grid",
339
344
  "aria-colcount": columns,
340
345
  ...props2,
341
346
  "data-testid": void 0,
342
- ref: forwardedRef2
343
- }, children);
347
+ ref: forwardedRef2,
348
+ children
349
+ });
344
350
  }
345
351
  ),
346
352
  [columns]
347
353
  );
348
- const placeholderColumns = React.useMemo(
354
+ const placeholderColumns = react.useMemo(
349
355
  () => Array(columns).fill("\u{1F32B}\uFE0F"),
350
356
  [columns]
351
357
  );
352
- const preventDefault = React.useCallback((event) => {
358
+ const preventDefault = react.useCallback((event) => {
353
359
  event.preventDefault();
354
360
  }, []);
355
- const handleEmojiPointerLeave = React.useCallback(() => {
361
+ const handleEmojiPointerLeave = react.useCallback(() => {
356
362
  if (interaction === "pointer") {
357
363
  setInteraction("none");
358
364
  }
359
365
  }, [interaction, setInteraction]);
360
- useLayoutEffect.useLayoutEffect(() => {
366
+ react.useLayoutEffect(() => {
361
367
  if (!placeholderContainerRef.current) {
362
368
  return;
363
369
  }
@@ -372,7 +378,7 @@ const EmojiPickerContent = React.forwardRef(
372
378
  categoryHeaderHeightRef.current = categoryHeader.offsetHeight;
373
379
  }
374
380
  }, []);
375
- const calculateViewLocation = React.useCallback(
381
+ const calculateViewLocation = react.useCallback(
376
382
  ({
377
383
  itemTop,
378
384
  itemBottom,
@@ -399,7 +405,7 @@ const EmojiPickerContent = React.forwardRef(
399
405
  },
400
406
  []
401
407
  );
402
- React.useEffect(() => {
408
+ react.useEffect(() => {
403
409
  if (interaction === "keyboard") {
404
410
  virtuosoRef.current?.scrollIntoView({
405
411
  index: selectedRowIndex,
@@ -408,80 +414,92 @@ const EmojiPickerContent = React.forwardRef(
408
414
  });
409
415
  }
410
416
  }, [interaction, selectedRowIndex, calculateViewLocation]);
411
- return /* @__PURE__ */ React.createElement(Component, {
417
+ return /* @__PURE__ */ jsxRuntime.jsxs(Component, {
412
418
  ...props,
413
- ref: forwardedRef
414
- }, /* @__PURE__ */ React.createElement("div", {
415
- style: {
416
- visibility: "hidden",
417
- height: 0
418
- },
419
- ref: placeholderContainerRef
420
- }, /* @__PURE__ */ React.createElement(Row, {
421
- attributes: placeholderRowAttributes
422
- }, placeholderColumns.map((placeholder, index) => /* @__PURE__ */ React.createElement(Emoji, {
423
- emoji: placeholder,
424
- key: index
425
- }))), /* @__PURE__ */ React.createElement(CategoryHeader, {
426
- category: "Category"
427
- })), isLoading ? /* @__PURE__ */ React.createElement(Loading, null) : error ? /* @__PURE__ */ React.createElement(Error, {
428
- error
429
- }) : data.count === 0 ? /* @__PURE__ */ React.createElement(Empty, null) : /* @__PURE__ */ React.createElement(Grid, null, /* @__PURE__ */ React.createElement(reactVirtuoso.GroupedVirtuoso, {
430
- ref: virtuosoRef,
431
- components: {
432
- Scroller: VirtuosoScroller,
433
- List: VirtuosoList,
434
- TopItemList: VirtuosoTopList
435
- },
436
- groupCounts: data.categoriesRowCounts,
437
- groupContent: (groupIndex) => {
438
- const category = data.categories[groupIndex];
439
- if (!category) {
440
- return null;
441
- }
442
- return /* @__PURE__ */ React.createElement(CategoryHeader, {
443
- category
444
- });
445
- },
446
- itemContent: (rowIndex, groupIndex) => {
447
- const categoryRow = data.rows[rowIndex];
448
- const categoryRowIndex = data.categoriesRowIndices[groupIndex]?.indexOf(rowIndex);
449
- const categoryRowsCount = data.categoriesRowCounts[groupIndex];
450
- if (categoryRow === void 0 || categoryRowIndex === void 0 || categoryRowsCount === void 0) {
451
- return null;
452
- }
453
- return /* @__PURE__ */ React.createElement(Row, {
454
- attributes: {
455
- rowIndex,
456
- categoryRowIndex,
457
- categoryRowsCount
458
- }
459
- }, categoryRow.map((emoji, columnIndex) => {
460
- const isSelected = interaction !== "none" && selectedColumnIndex === columnIndex && selectedRowIndex === rowIndex;
461
- return /* @__PURE__ */ React.createElement(Emoji, {
462
- key: emoji.emoji,
463
- role: "gridcell",
464
- "aria-colindex": columnIndex,
465
- "aria-selected": isSelected || void 0,
466
- "data-selected": isSelected || void 0,
467
- onMouseDown: preventDefault,
468
- tabIndex: -1,
469
- onPointerEnter: () => {
470
- setPointerSelection(columnIndex, rowIndex);
419
+ ref: forwardedRef,
420
+ children: [
421
+ /* @__PURE__ */ jsxRuntime.jsxs("div", {
422
+ style: {
423
+ visibility: "hidden",
424
+ height: 0
425
+ },
426
+ ref: placeholderContainerRef,
427
+ children: [
428
+ /* @__PURE__ */ jsxRuntime.jsx(Row, {
429
+ attributes: placeholderRowAttributes,
430
+ children: placeholderColumns.map((placeholder, index) => /* @__PURE__ */ jsxRuntime.jsx(Emoji, {
431
+ emoji: placeholder
432
+ }, index))
433
+ }),
434
+ /* @__PURE__ */ jsxRuntime.jsx(CategoryHeader, {
435
+ category: "Category"
436
+ })
437
+ ]
438
+ }),
439
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx(Loading, {}) : error ? /* @__PURE__ */ jsxRuntime.jsx(Error, {
440
+ error
441
+ }) : data.count === 0 ? /* @__PURE__ */ jsxRuntime.jsx(Empty, {}) : /* @__PURE__ */ jsxRuntime.jsx(Grid, {
442
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactVirtuoso.GroupedVirtuoso, {
443
+ ref: virtuosoRef,
444
+ components: {
445
+ Scroller: VirtuosoScroller,
446
+ List: VirtuosoList,
447
+ TopItemList: VirtuosoTopList
471
448
  },
472
- onPointerLeave: handleEmojiPointerLeave,
473
- onClick: (event) => {
474
- onEmojiSelect?.(emoji.emoji);
475
- event.stopPropagation();
449
+ groupCounts: data.categoriesRowCounts,
450
+ groupContent: (groupIndex) => {
451
+ const category = data.categories[groupIndex];
452
+ if (!category) {
453
+ return null;
454
+ }
455
+ return /* @__PURE__ */ jsxRuntime.jsx(CategoryHeader, {
456
+ category
457
+ });
476
458
  },
477
- emoji: emoji.emoji
478
- });
479
- }));
480
- }
481
- })), selectedEmoji && interaction !== "none" && /* @__PURE__ */ React.createElement("div", {
482
- "aria-live": "polite",
483
- style: visuallyHidden.visuallyHidden
484
- }, selectedEmoji.name));
459
+ itemContent: (rowIndex, groupIndex) => {
460
+ const categoryRow = data.rows[rowIndex];
461
+ const categoryRowIndex = data.categoriesRowIndices[groupIndex]?.indexOf(rowIndex);
462
+ const categoryRowsCount = data.categoriesRowCounts[groupIndex];
463
+ if (categoryRow === void 0 || categoryRowIndex === void 0 || categoryRowsCount === void 0) {
464
+ return null;
465
+ }
466
+ return /* @__PURE__ */ jsxRuntime.jsx(Row, {
467
+ attributes: {
468
+ rowIndex,
469
+ categoryRowIndex,
470
+ categoryRowsCount
471
+ },
472
+ children: categoryRow.map((emoji, columnIndex) => {
473
+ const isSelected = interaction !== "none" && selectedColumnIndex === columnIndex && selectedRowIndex === rowIndex;
474
+ return /* @__PURE__ */ jsxRuntime.jsx(Emoji, {
475
+ role: "gridcell",
476
+ "aria-colindex": columnIndex,
477
+ "aria-selected": isSelected || void 0,
478
+ "data-selected": isSelected || void 0,
479
+ onMouseDown: preventDefault,
480
+ tabIndex: -1,
481
+ onPointerEnter: () => {
482
+ setPointerSelection(columnIndex, rowIndex);
483
+ },
484
+ onPointerLeave: handleEmojiPointerLeave,
485
+ onClick: (event) => {
486
+ onEmojiSelect?.(emoji.emoji);
487
+ event.stopPropagation();
488
+ },
489
+ emoji: emoji.emoji
490
+ }, emoji.emoji);
491
+ })
492
+ });
493
+ }
494
+ })
495
+ }),
496
+ selectedEmoji && interaction !== "none" && /* @__PURE__ */ jsxRuntime.jsx("div", {
497
+ "aria-live": "polite",
498
+ style: visuallyHidden.visuallyHidden,
499
+ children: selectedEmoji.name
500
+ })
501
+ ]
502
+ });
485
503
  }
486
504
  );
487
505
  if (process.env.NODE_ENV !== "production") {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/primitives/EmojiPicker/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { ChangeEvent, KeyboardEvent, SyntheticEvent } from \"react\";\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n CalculateViewLocationParams,\n GroupedVirtuosoHandle,\n ListProps as VirtuosoListProps,\n ScrollerProps,\n TopItemListProps,\n} from \"react-virtuoso\";\nimport { GroupedVirtuoso } from \"react-virtuoso\";\n\nimport { isKey } from \"../../utils/is-key\";\nimport {\n cancelIdleCallback,\n requestIdleCallback,\n} from \"../../utils/request-idle-callback\";\nimport { useLayoutEffect } from \"../../utils/use-layout-effect\";\nimport { useTransition } from \"../../utils/use-transition\";\nimport { visuallyHidden } from \"../../utils/visually-hidden\";\nimport { Emoji as EmojiPrimitive } from \"../internal/Emoji\";\nimport { EmojiPickerContext, useEmojiPicker } from \"./contexts\";\nimport type {\n EmojiData,\n EmojiPickerContentComponents,\n EmojiPickerContentEmojiRowAttributes,\n EmojiPickerContentProps,\n EmojiPickerData,\n EmojiPickerRootProps,\n EmojiPickerSearchProps,\n EmojiPickerSelectionDirection,\n} from \"./types\";\nimport { filterEmojis, generateEmojiPickerData, getEmojiData } from \"./utils\";\n\nconst DEFAULT_COLUMNS = 10;\nconst DEFAULT_LOCALE = \"en\";\nconst LOADING_MINIMUM_TIMEOUT = 100;\n\nconst EMOJIPICKER_ROOT_NAME = \"EmojiPickerRoot\";\nconst EMOJIPICKER_CONTENT_NAME = \"EmojiPickerContent\";\nconst EMOJIPICKER_SEARCH_NAME = \"EmojiPickerSearch\";\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * Surrounds the emoji picker, it handles emoji data and coordinates\n * `EmojiPicker.Search` and `EmojiPicker.Content`.\n *\n * @example\n * <EmojiPicker.Root>\n * <EmojiPicker.Search />\n * <EmojiPicker.Content />\n * </EmojiPicker.Root>\n */\nfunction EmojiPickerRoot({\n columns = DEFAULT_COLUMNS,\n locale = DEFAULT_LOCALE,\n onEmojiSelect,\n children,\n}: EmojiPickerRootProps) {\n const emojiData = useRef<EmojiData>();\n const search = useRef(\"\");\n const [, startEmojisTransition] = useTransition();\n const [data, setData] = useState<EmojiPickerData>();\n const [error, setError] = useState<Error>();\n const [selectedColumnIndex, setSelectedColumnIndex] = useState(0);\n const [selectedRowIndex, setSelectedRowIndex] = useState(0);\n const [interaction, setInteraction] = useState<\n \"keyboard\" | \"pointer\" | \"none\"\n >(\"none\");\n\n const selectCurrentEmoji = useCallback(() => {\n if (onEmojiSelect) {\n const emoji = data?.rows[selectedRowIndex]?.[selectedColumnIndex];\n\n if (emoji) {\n onEmojiSelect(emoji.emoji);\n }\n }\n }, [data?.rows, onEmojiSelect, selectedColumnIndex, selectedRowIndex]);\n\n const resetSelection = useCallback(() => {\n setSelectedColumnIndex(0);\n setSelectedRowIndex(0);\n }, []);\n\n const setPointerSelection = useCallback(\n (columnIndex: number, rowIndex: number) => {\n setInteraction(\"pointer\");\n setSelectedColumnIndex(columnIndex);\n setSelectedRowIndex(rowIndex);\n },\n []\n );\n\n const moveSelection = useCallback(\n (\n direction: EmojiPickerSelectionDirection,\n event: KeyboardEvent<HTMLInputElement>\n ) => {\n if (!data) {\n return;\n }\n\n event.preventDefault();\n\n if (interaction === \"none\") {\n setInteraction(\"keyboard\");\n return;\n }\n\n setInteraction(\"keyboard\");\n\n switch (direction) {\n // If first column, move to last column of previous row (if available)\n // Otherwise, move to previous column\n case \"left\": {\n if (selectedColumnIndex === 0) {\n const previousRowIndex = selectedRowIndex - 1;\n const previousRow = data.rows[previousRowIndex];\n\n if (previousRow) {\n setSelectedRowIndex(previousRowIndex);\n setSelectedColumnIndex(previousRow.length - 1);\n }\n } else {\n setSelectedColumnIndex(selectedColumnIndex - 1);\n }\n\n break;\n }\n\n // If last column, move to first column of next row (if available)\n // Otherwise, move to next column\n case \"right\": {\n const currentRow = data.rows[selectedRowIndex];\n\n if (!currentRow) {\n return;\n }\n\n if (selectedColumnIndex === currentRow.length - 1) {\n const nextRowIndex = selectedRowIndex + 1;\n const nextRow = data.rows[nextRowIndex];\n\n if (nextRow) {\n setSelectedRowIndex(nextRowIndex);\n setSelectedColumnIndex(0);\n }\n } else {\n setSelectedColumnIndex(selectedColumnIndex + 1);\n }\n\n break;\n }\n\n // Move to same column of previous row\n // If same column is not available, move to last column of previous row\n case \"up\": {\n const previousRow = data.rows[selectedRowIndex - 1];\n\n if (previousRow) {\n setSelectedRowIndex(selectedRowIndex - 1);\n\n if (!previousRow[selectedColumnIndex]) {\n setSelectedColumnIndex(previousRow.length - 1);\n }\n }\n\n break;\n }\n\n // Move to same column of next row\n // If same column is not available, move to last column of next row\n case \"down\": {\n const nextRow = data.rows[selectedRowIndex + 1];\n\n if (nextRow) {\n setSelectedRowIndex(selectedRowIndex + 1);\n\n if (!nextRow[selectedColumnIndex]) {\n setSelectedColumnIndex(nextRow.length - 1);\n }\n }\n\n break;\n }\n }\n },\n [data, interaction, selectedColumnIndex, selectedRowIndex]\n );\n\n const updateEmojis = useCallback(() => {\n if (!emojiData.current) {\n return;\n }\n\n startEmojisTransition(() => {\n setData(() => {\n if (!emojiData.current) {\n return;\n }\n\n const filteredEmojis = filterEmojis(\n emojiData.current.emojis,\n search.current\n );\n\n return generateEmojiPickerData(\n filteredEmojis,\n emojiData.current.categories,\n columns\n );\n });\n resetSelection();\n });\n }, [columns, resetSelection]);\n\n const handleSearch = useCallback(\n (value: string) => {\n search.current = value;\n updateEmojis();\n },\n [updateEmojis]\n );\n\n const initializeEmojiData = useCallback(\n async (locale: string) => {\n try {\n emojiData.current = await getEmojiData(locale);\n updateEmojis();\n } catch (error) {\n setError(error as Error);\n }\n },\n [updateEmojis]\n );\n\n useEffect(() => {\n let idleCallbackId: number;\n const timeoutId = setTimeout(() => {\n idleCallbackId = requestIdleCallback(() => {\n initializeEmojiData(locale);\n });\n }, LOADING_MINIMUM_TIMEOUT);\n\n return () => {\n clearTimeout(timeoutId);\n cancelIdleCallback(idleCallbackId);\n };\n }, [locale]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n if (interaction === \"none\") {\n resetSelection();\n }\n }, [interaction]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <EmojiPickerContext.Provider\n value={{\n data: data as EmojiPickerData,\n error: error as undefined,\n isLoading: (!data && !error) as false,\n columns,\n onSearch: handleSearch,\n onEmojiSelect,\n selectCurrentEmoji,\n selectedRowIndex,\n selectedColumnIndex,\n moveSelection,\n setPointerSelection,\n interaction,\n setInteraction,\n }}\n >\n {children}\n </EmojiPickerContext.Provider>\n );\n}\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * The search input of the emoji picker. It also affects the focus and selection\n * within `EmojiPicker.Content`.\n *\n * @example\n * <EmojiPicker.Search />\n */\nconst EmojiPickerSearch = forwardRef<HTMLInputElement, EmojiPickerSearchProps>(\n ({ asChild, value, defaultValue, onChange, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"input\";\n const {\n onSearch,\n selectCurrentEmoji,\n moveSelection,\n interaction,\n setInteraction,\n } = useEmojiPicker();\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n onChange?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n const value = event.target.value;\n setInteraction(value ? \"keyboard\" : \"none\");\n onSearch(value);\n },\n [onChange, onSearch, setInteraction]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (isKey(event, \"ArrowLeft\")) {\n moveSelection(\"left\", event);\n } else if (isKey(event, \"ArrowRight\")) {\n moveSelection(\"right\", event);\n } else if (isKey(event, \"ArrowUp\")) {\n moveSelection(\"up\", event);\n } else if (isKey(event, \"ArrowDown\")) {\n moveSelection(\"down\", event);\n } else if (isKey(event, \"Enter\")) {\n if (interaction !== \"none\") {\n event.preventDefault();\n selectCurrentEmoji();\n }\n }\n },\n [interaction, moveSelection, selectCurrentEmoji]\n );\n\n useEffect(() => {\n onSearch(\n value ? String(value) : defaultValue ? String(defaultValue) : \"\"\n );\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <Component\n type=\"search\"\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n);\n\nconst defaultContentComponents: EmojiPickerContentComponents = {\n CategoryHeader: ({ category, ...props }) => <div {...props}>{category}</div>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Row: ({ children, attributes, ...props }) => <div {...props}>{children}</div>,\n Emoji: ({ emoji, ...props }) => (\n <button {...props}>\n <EmojiPrimitive emoji={emoji} />\n </button>\n ),\n Loading: (props) => <div {...props} />,\n Empty: (props) => <div {...props} />,\n Grid: (props) => <div {...props} />,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Error: ({ error, ...props }) => <div {...props} />,\n};\n\nconst placeholderRowAttributes: EmojiPickerContentEmojiRowAttributes = {\n rowIndex: -1,\n categoryRowIndex: -1,\n categoryRowsCount: 0,\n};\n\n// About `data-testid={undefined}`: Virtuoso bakes test IDs into the components we pass\n// to it, so we manually remove them.\n\nconst VirtuosoScroller = forwardRef<HTMLDivElement, ScrollerProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div {...props} tabIndex={-1} data-testid={undefined} ref={forwardedRef}>\n {children}\n </div>\n );\n }\n);\n\nconst VirtuosoTopList = forwardRef<HTMLDivElement, TopItemListProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div {...props} data-testid={undefined} ref={forwardedRef}>\n {children}\n </div>\n );\n }\n);\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * The main content of the emoji picker, either displaying the emoji grid or various\n * alternative states (loading, empty, and error).\n *\n * @example\n * <EmojiPicker.Content\n * components={{\n * Loading: EmojiPickerLoading,\n * Empty: EmojiPickerEmpty,\n * Error: EmojiPickerError,\n * CategoryHeader: EmojiPickerCategoryHeader,\n * Grid: EmojiPickerGrid,\n * Row: EmojiPickerRow,\n * Emoji: EmojiPickerEmoji,\n * }}\n * />\n */\nconst EmojiPickerContent = forwardRef<HTMLDivElement, EmojiPickerContentProps>(\n ({ components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const virtuosoRef = useRef<GroupedVirtuosoHandle>(null);\n const placeholderContainerRef = useRef<HTMLDivElement>(null);\n const rowScrollMarginTopRef = useRef<number>(0);\n const rowScrollMarginBottomRef = useRef<number>(0);\n const categoryHeaderHeightRef = useRef<number>(0);\n const {\n data,\n error,\n isLoading,\n columns,\n onEmojiSelect,\n selectedColumnIndex,\n selectedRowIndex,\n setPointerSelection,\n interaction,\n setInteraction,\n } = useEmojiPicker();\n const selectedEmoji = useMemo(\n () => data?.rows[selectedRowIndex]?.[selectedColumnIndex],\n [data?.rows, selectedColumnIndex, selectedRowIndex]\n );\n const { Loading, Empty, Error, CategoryHeader, Grid, Row, Emoji } = useMemo(\n () => ({ ...defaultContentComponents, ...components }),\n [components]\n );\n const VirtuosoList = useMemo(\n () =>\n forwardRef<HTMLDivElement, VirtuosoListProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div\n role=\"grid\"\n aria-colcount={columns}\n {...props}\n data-testid={undefined}\n ref={forwardedRef}\n >\n {children}\n </div>\n );\n }\n ),\n [columns]\n );\n const placeholderColumns = useMemo(\n () => Array<string>(columns).fill(\"🌫️\"),\n [columns]\n );\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const handleEmojiPointerLeave = useCallback(() => {\n if (interaction === \"pointer\") {\n setInteraction(\"none\");\n }\n }, [interaction, setInteraction]);\n\n useLayoutEffect(() => {\n if (!placeholderContainerRef.current) {\n return;\n }\n\n const row = placeholderContainerRef.current.childNodes[0];\n const categoryHeader = placeholderContainerRef.current.childNodes[1];\n\n if (row instanceof HTMLElement) {\n const style = window.getComputedStyle(row);\n\n rowScrollMarginTopRef.current = parseFloat(style.scrollMarginTop);\n rowScrollMarginBottomRef.current = parseFloat(style.scrollMarginBottom);\n }\n\n if (categoryHeader instanceof HTMLElement) {\n categoryHeaderHeightRef.current = categoryHeader.offsetHeight;\n }\n }, []);\n\n // Customize `scrollIntoView` behavior to take into account category headers and margins\n const calculateViewLocation = useCallback(\n ({\n itemTop,\n itemBottom,\n viewportTop,\n viewportBottom,\n locationParams: { behavior, align, ...params },\n }: CalculateViewLocationParams) => {\n if (\n itemTop -\n (categoryHeaderHeightRef.current + rowScrollMarginTopRef.current) <\n viewportTop\n ) {\n return {\n ...params,\n behavior,\n align: align ?? \"start\",\n };\n }\n\n if (itemBottom > viewportBottom) {\n return {\n ...params,\n behavior,\n align: align ?? \"end\",\n offset: rowScrollMarginBottomRef.current,\n };\n }\n\n return null;\n },\n []\n );\n\n useEffect(() => {\n if (interaction === \"keyboard\") {\n virtuosoRef.current?.scrollIntoView({\n index: selectedRowIndex,\n behavior: \"auto\",\n calculateViewLocation,\n });\n }\n }, [interaction, selectedRowIndex, calculateViewLocation]);\n\n return (\n <Component {...props} ref={forwardedRef}>\n <div\n style={{\n visibility: \"hidden\",\n height: 0,\n }}\n ref={placeholderContainerRef}\n >\n {/* Virtualized rows are absolutely positioned so they won't make\n the container automatically pick up their width. To achieve\n an automatic width, we add a relative (but hidden) full row. */}\n <Row attributes={placeholderRowAttributes}>\n {placeholderColumns.map((placeholder, index) => (\n <Emoji emoji={placeholder} key={index} />\n ))}\n </Row>\n {/* We also add a hidden category header to get its computed height. */}\n <CategoryHeader category=\"Category\" />\n </div>\n {isLoading ? (\n <Loading />\n ) : error ? (\n <Error error={error} />\n ) : data.count === 0 ? (\n <Empty />\n ) : (\n <Grid>\n <GroupedVirtuoso\n ref={virtuosoRef}\n components={{\n Scroller: VirtuosoScroller,\n List: VirtuosoList,\n TopItemList: VirtuosoTopList,\n }}\n groupCounts={data.categoriesRowCounts}\n groupContent={(groupIndex) => {\n const category = data.categories[groupIndex];\n\n if (!category) {\n return null;\n }\n\n return <CategoryHeader category={category} />;\n }}\n itemContent={(rowIndex, groupIndex) => {\n const categoryRow = data.rows[rowIndex];\n const categoryRowIndex =\n data.categoriesRowIndices[groupIndex]?.indexOf(rowIndex);\n const categoryRowsCount = data.categoriesRowCounts[groupIndex];\n\n if (\n categoryRow === undefined ||\n categoryRowIndex === undefined ||\n categoryRowsCount === undefined\n ) {\n return null;\n }\n\n return (\n <Row\n attributes={{\n rowIndex,\n categoryRowIndex,\n categoryRowsCount,\n }}\n >\n {categoryRow.map((emoji, columnIndex) => {\n const isSelected =\n interaction !== \"none\" &&\n selectedColumnIndex === columnIndex &&\n selectedRowIndex === rowIndex;\n\n return (\n <Emoji\n key={emoji.emoji}\n role=\"gridcell\"\n aria-colindex={columnIndex}\n aria-selected={isSelected || undefined}\n data-selected={isSelected || undefined}\n onMouseDown={preventDefault}\n tabIndex={-1}\n onPointerEnter={() => {\n setPointerSelection(columnIndex, rowIndex);\n }}\n onPointerLeave={handleEmojiPointerLeave}\n onClick={(event) => {\n onEmojiSelect?.(emoji.emoji);\n event.stopPropagation();\n }}\n emoji={emoji.emoji}\n />\n );\n })}\n </Row>\n );\n }}\n />\n </Grid>\n )}\n {selectedEmoji && interaction !== \"none\" && (\n <div aria-live=\"polite\" style={visuallyHidden}>\n {selectedEmoji.name}\n </div>\n )}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n EmojiPickerRoot.displayName = EMOJIPICKER_ROOT_NAME;\n EmojiPickerContent.displayName = EMOJIPICKER_CONTENT_NAME;\n EmojiPickerSearch.displayName = EMOJIPICKER_SEARCH_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as EmojiPicker.*\nexport {\n EmojiPickerContent as Content,\n EmojiPickerRoot as Root,\n EmojiPickerSearch as Search,\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA2CA;AACA;AACA;AAEA;AACA;AACA;AAkBA;AAAyB;AACb;AACD;AACT;AAEF;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACE;AACE;AAEA;AACE;AAAyB;AAC3B;AACF;AAGF;AACE;AACA;AAAqB;AAGvB;AAA4B;AAExB;AACA;AACA;AAA4B;AAC9B;AACC;AAGH;AAAsB;AAKlB;AACE;AAAA;AAGF;AAEA;AACE;AACA;AAAA;AAGF;AAEA;AAAmB;AAIf;AACE;AACA;AAEA;AACE;AACA;AAA6C;AAC/C;AAEA;AAA8C;AAGhD;AAAA;AACF;AAKE;AAEA;AACE;AAAA;AAGF;AACE;AACA;AAEA;AACE;AACA;AAAwB;AAC1B;AAEA;AAA8C;AAGhD;AAAA;AACF;AAKE;AAEA;AACE;AAEA;AACE;AAA6C;AAC/C;AAGF;AAAA;AACF;AAKE;AAEA;AACE;AAEA;AACE;AAAyC;AAC3C;AAGF;AAAA;AACF;AACF;AACF;AACyD;AAG3D;AACE;AACE;AAAA;AAGF;AACE;AACE;AACE;AAAA;AAGF;AAAuB;AACH;AACX;AAGT;AAAO;AACL;AACkB;AAClB;AACF;AAEF;AAAe;AAChB;AAGH;AAAqB;AAEjB;AACA;AAAa;AACf;AACa;AAGf;AAA4B;AAExB;AACE;AACA;AAAa;AAEb;AAAuB;AACzB;AACF;AACa;AAGf;AACE;AACA;AACE;AACE;AAA0B;AAC3B;AAGH;AACE;AACA;AAAiC;AACnC;AAGF;AACE;AACE;AAAe;AACjB;AAGF;AACG;AACQ;AACL;AACA;AACsB;AACtB;AACU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF;AAKN;AAeA;AAA0B;AAEtB;AACA;AAAM;AACJ;AACA;AACA;AACA;AACA;AAGF;AAAqB;AAEjB;AAEA;AACE;AAAA;AAGF;AACA;AACA;AAAc;AAChB;AACmC;AAGrC;AAAsB;AAElB;AACE;AAAA;AAGF;AACE;AAA2B;AAE3B;AAA4B;AAE5B;AAAyB;AAEzB;AAA2B;AAE3B;AACE;AACA;AAAmB;AACrB;AACF;AACF;AAC+C;AAGjD;AACE;AAAA;AACgE;AAChE;AAGF;AACG;AACM;AACL;AACA;AACU;AACC;AACP;AACC;AACP;AAGN;AAEA;AAA+D;AAChB;AAAQ;AAAiB;AAExB;AAAQ;AAAiB;AAEpE;AAAW;AACT;AAAe;AAClB;AAEmB;AAAQ;AAAO;AACjB;AAAQ;AAAO;AAChB;AAAQ;AAAO;AAEA;AAAQ;AAC3C;AAEA;AAAuE;AAC3D;AACQ;AAEpB;AAKA;AAAyB;AAErB;AACG;AAAQ;AAAiB;AAAiB;AAAgB;AAE3D;AAGN;AAEA;AAAwB;AAEpB;AACG;AAAQ;AAAoB;AAAgB;AAE7C;AAGN;AAyBA;AAA2B;AAEvB;AACA;AACA;AACA;AACA;AACA;AACA;AAAM;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEF;AAAsB;AACiB;AACa;AAEpD;AAAoE;AACd;AACzC;AAEb;AAAqB;AAEjB;AAEI;AACG;AACM;AACU;AACX;AACS;AACR;AAGP;AAEJ;AACF;AACM;AAEV;AAA2B;AACc;AAC/B;AAGV;AACE;AAAqB;AAGvB;AACE;AACE;AAAqB;AACvB;AAGF;AACE;AACE;AAAA;AAGF;AACA;AAEA;AACE;AAEA;AACA;AAAsE;AAGxE;AACE;AAAiD;AACnD;AAIF;AAA8B;AAC3B;AACC;AACA;AACA;AACA;AAC6C;AAE7C;AAKE;AAAO;AACF;AACH;AACgB;AAClB;AAGF;AACE;AAAO;AACF;AACH;AACgB;AACiB;AACnC;AAGF;AAAO;AACT;AACC;AAGH;AACE;AACE;AAAoC;AAC3B;AACG;AACV;AACD;AACH;AAGF;AACG;AAAc;AAAY;AACxB;AACQ;AACO;AACJ;AACV;AACK;AAKJ;AAAgB;AAEZ;AAAa;AAAkB;AAInC;AAAwB;AAKxB;AAAM;AAKJ;AACM;AACO;AACA;AACJ;AACO;AACf;AACkB;AAEhB;AAEA;AACE;AAAO;AAGT;AAAQ;AAAe;AAAoB;AAC7C;AAEE;AACA;AAEA;AAEA;AAKE;AAAO;AAGT;AACG;AACa;AACV;AACA;AACA;AACF;AAGE;AAKA;AACG;AACY;AACN;AACU;AACc;AACA;AAChB;AACH;AAER;AAAyC;AAC3C;AACgB;AAEd;AACA;AAAsB;AACxB;AACa;AACf;AAGN;AAEJ;AAKH;AAAc;AAAgB;AAInC;AAGN;AAEA;AACE;AACA;AACA;AACF;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/primitives/EmojiPicker/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { ChangeEvent, KeyboardEvent, SyntheticEvent } from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useTransition,\n} from \"react\";\nimport type {\n CalculateViewLocationParams,\n GroupedVirtuosoHandle,\n ListProps as VirtuosoListProps,\n ScrollerProps,\n TopItemListProps,\n} from \"react-virtuoso\";\nimport { GroupedVirtuoso } from \"react-virtuoso\";\n\nimport { isKey } from \"../../utils/is-key\";\nimport {\n cancelIdleCallback,\n requestIdleCallback,\n} from \"../../utils/request-idle-callback\";\nimport { visuallyHidden } from \"../../utils/visually-hidden\";\nimport { Emoji as EmojiPrimitive } from \"../internal/Emoji\";\nimport { EmojiPickerContext, useEmojiPicker } from \"./contexts\";\nimport type {\n EmojiData,\n EmojiPickerContentComponents,\n EmojiPickerContentEmojiRowAttributes,\n EmojiPickerContentProps,\n EmojiPickerData,\n EmojiPickerRootProps,\n EmojiPickerSearchProps,\n EmojiPickerSelectionDirection,\n} from \"./types\";\nimport { filterEmojis, generateEmojiPickerData, getEmojiData } from \"./utils\";\n\nconst DEFAULT_COLUMNS = 10;\nconst DEFAULT_LOCALE = \"en\";\nconst LOADING_MINIMUM_TIMEOUT = 100;\n\nconst EMOJIPICKER_ROOT_NAME = \"EmojiPickerRoot\";\nconst EMOJIPICKER_CONTENT_NAME = \"EmojiPickerContent\";\nconst EMOJIPICKER_SEARCH_NAME = \"EmojiPickerSearch\";\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * Surrounds the emoji picker, it handles emoji data and coordinates\n * `EmojiPicker.Search` and `EmojiPicker.Content`.\n *\n * @example\n * <EmojiPicker.Root>\n * <EmojiPicker.Search />\n * <EmojiPicker.Content />\n * </EmojiPicker.Root>\n */\nfunction EmojiPickerRoot({\n columns = DEFAULT_COLUMNS,\n locale = DEFAULT_LOCALE,\n onEmojiSelect,\n children,\n}: EmojiPickerRootProps) {\n const emojiData = useRef<EmojiData>();\n const search = useRef(\"\");\n const [, startEmojisTransition] = useTransition();\n const [data, setData] = useState<EmojiPickerData>();\n const [error, setError] = useState<Error>();\n const [selectedColumnIndex, setSelectedColumnIndex] = useState(0);\n const [selectedRowIndex, setSelectedRowIndex] = useState(0);\n const [interaction, setInteraction] = useState<\n \"keyboard\" | \"pointer\" | \"none\"\n >(\"none\");\n\n const selectCurrentEmoji = useCallback(() => {\n if (onEmojiSelect) {\n const emoji = data?.rows[selectedRowIndex]?.[selectedColumnIndex];\n\n if (emoji) {\n onEmojiSelect(emoji.emoji);\n }\n }\n }, [data?.rows, onEmojiSelect, selectedColumnIndex, selectedRowIndex]);\n\n const resetSelection = useCallback(() => {\n setSelectedColumnIndex(0);\n setSelectedRowIndex(0);\n }, []);\n\n const setPointerSelection = useCallback(\n (columnIndex: number, rowIndex: number) => {\n setInteraction(\"pointer\");\n setSelectedColumnIndex(columnIndex);\n setSelectedRowIndex(rowIndex);\n },\n []\n );\n\n const moveSelection = useCallback(\n (\n direction: EmojiPickerSelectionDirection,\n event: KeyboardEvent<HTMLInputElement>\n ) => {\n if (!data) {\n return;\n }\n\n event.preventDefault();\n\n if (interaction === \"none\") {\n setInteraction(\"keyboard\");\n return;\n }\n\n setInteraction(\"keyboard\");\n\n switch (direction) {\n // If first column, move to last column of previous row (if available)\n // Otherwise, move to previous column\n case \"left\": {\n if (selectedColumnIndex === 0) {\n const previousRowIndex = selectedRowIndex - 1;\n const previousRow = data.rows[previousRowIndex];\n\n if (previousRow) {\n setSelectedRowIndex(previousRowIndex);\n setSelectedColumnIndex(previousRow.length - 1);\n }\n } else {\n setSelectedColumnIndex(selectedColumnIndex - 1);\n }\n\n break;\n }\n\n // If last column, move to first column of next row (if available)\n // Otherwise, move to next column\n case \"right\": {\n const currentRow = data.rows[selectedRowIndex];\n\n if (!currentRow) {\n return;\n }\n\n if (selectedColumnIndex === currentRow.length - 1) {\n const nextRowIndex = selectedRowIndex + 1;\n const nextRow = data.rows[nextRowIndex];\n\n if (nextRow) {\n setSelectedRowIndex(nextRowIndex);\n setSelectedColumnIndex(0);\n }\n } else {\n setSelectedColumnIndex(selectedColumnIndex + 1);\n }\n\n break;\n }\n\n // Move to same column of previous row\n // If same column is not available, move to last column of previous row\n case \"up\": {\n const previousRow = data.rows[selectedRowIndex - 1];\n\n if (previousRow) {\n setSelectedRowIndex(selectedRowIndex - 1);\n\n if (!previousRow[selectedColumnIndex]) {\n setSelectedColumnIndex(previousRow.length - 1);\n }\n }\n\n break;\n }\n\n // Move to same column of next row\n // If same column is not available, move to last column of next row\n case \"down\": {\n const nextRow = data.rows[selectedRowIndex + 1];\n\n if (nextRow) {\n setSelectedRowIndex(selectedRowIndex + 1);\n\n if (!nextRow[selectedColumnIndex]) {\n setSelectedColumnIndex(nextRow.length - 1);\n }\n }\n\n break;\n }\n }\n },\n [data, interaction, selectedColumnIndex, selectedRowIndex]\n );\n\n const updateEmojis = useCallback(() => {\n if (!emojiData.current) {\n return;\n }\n\n startEmojisTransition(() => {\n setData(() => {\n if (!emojiData.current) {\n return;\n }\n\n const filteredEmojis = filterEmojis(\n emojiData.current.emojis,\n search.current\n );\n\n return generateEmojiPickerData(\n filteredEmojis,\n emojiData.current.categories,\n columns\n );\n });\n resetSelection();\n });\n }, [columns, resetSelection]);\n\n const handleSearch = useCallback(\n (value: string) => {\n search.current = value;\n updateEmojis();\n },\n [updateEmojis]\n );\n\n const initializeEmojiData = useCallback(\n async (locale: string) => {\n try {\n emojiData.current = await getEmojiData(locale);\n updateEmojis();\n } catch (error) {\n setError(error as Error);\n }\n },\n [updateEmojis]\n );\n\n useEffect(() => {\n let idleCallbackId: number;\n const timeoutId = setTimeout(() => {\n idleCallbackId = requestIdleCallback(() => {\n initializeEmojiData(locale);\n });\n }, LOADING_MINIMUM_TIMEOUT);\n\n return () => {\n clearTimeout(timeoutId);\n cancelIdleCallback(idleCallbackId);\n };\n }, [locale]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n if (interaction === \"none\") {\n resetSelection();\n }\n }, [interaction]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <EmojiPickerContext.Provider\n value={{\n data: data as EmojiPickerData,\n error: error as undefined,\n isLoading: (!data && !error) as false,\n columns,\n onSearch: handleSearch,\n onEmojiSelect,\n selectCurrentEmoji,\n selectedRowIndex,\n selectedColumnIndex,\n moveSelection,\n setPointerSelection,\n interaction,\n setInteraction,\n }}\n >\n {children}\n </EmojiPickerContext.Provider>\n );\n}\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * The search input of the emoji picker. It also affects the focus and selection\n * within `EmojiPicker.Content`.\n *\n * @example\n * <EmojiPicker.Search />\n */\nconst EmojiPickerSearch = forwardRef<HTMLInputElement, EmojiPickerSearchProps>(\n ({ asChild, value, defaultValue, onChange, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"input\";\n const {\n onSearch,\n selectCurrentEmoji,\n moveSelection,\n interaction,\n setInteraction,\n } = useEmojiPicker();\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n onChange?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n const value = event.target.value;\n setInteraction(value ? \"keyboard\" : \"none\");\n onSearch(value);\n },\n [onChange, onSearch, setInteraction]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (isKey(event, \"ArrowLeft\")) {\n moveSelection(\"left\", event);\n } else if (isKey(event, \"ArrowRight\")) {\n moveSelection(\"right\", event);\n } else if (isKey(event, \"ArrowUp\")) {\n moveSelection(\"up\", event);\n } else if (isKey(event, \"ArrowDown\")) {\n moveSelection(\"down\", event);\n } else if (isKey(event, \"Enter\")) {\n if (interaction !== \"none\") {\n event.preventDefault();\n selectCurrentEmoji();\n }\n }\n },\n [interaction, moveSelection, selectCurrentEmoji]\n );\n\n useEffect(() => {\n onSearch(\n value ? String(value) : defaultValue ? String(defaultValue) : \"\"\n );\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <Component\n type=\"search\"\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n);\n\nconst defaultContentComponents: EmojiPickerContentComponents = {\n CategoryHeader: ({ category, ...props }) => <div {...props}>{category}</div>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Row: ({ children, attributes, ...props }) => <div {...props}>{children}</div>,\n Emoji: ({ emoji, ...props }) => (\n <button {...props}>\n <EmojiPrimitive emoji={emoji} />\n </button>\n ),\n Loading: (props) => <div {...props} />,\n Empty: (props) => <div {...props} />,\n Grid: (props) => <div {...props} />,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Error: ({ error, ...props }) => <div {...props} />,\n};\n\nconst placeholderRowAttributes: EmojiPickerContentEmojiRowAttributes = {\n rowIndex: -1,\n categoryRowIndex: -1,\n categoryRowsCount: 0,\n};\n\n// About `data-testid={undefined}`: Virtuoso bakes test IDs into the components we pass\n// to it, so we manually remove them.\n\nconst VirtuosoScroller = forwardRef<HTMLDivElement, ScrollerProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div {...props} tabIndex={-1} data-testid={undefined} ref={forwardedRef}>\n {children}\n </div>\n );\n }\n);\n\nconst VirtuosoTopList = forwardRef<HTMLDivElement, TopItemListProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div {...props} data-testid={undefined} ref={forwardedRef}>\n {children}\n </div>\n );\n }\n);\n\n/**\n * @private\n * The EmojiPicker primitive is undocumented for now and subject to change,\n * use at your own risk. If you have any feedback on it, please let us know!\n * See how we use it in the default components to learn how to use it:\n * https://github.com/liveblocks/liveblocks/blob/main/packages/liveblocks-react-ui/src/components/internal/EmojiPicker.tsx.\n *\n * The main content of the emoji picker, either displaying the emoji grid or various\n * alternative states (loading, empty, and error).\n *\n * @example\n * <EmojiPicker.Content\n * components={{\n * Loading: EmojiPickerLoading,\n * Empty: EmojiPickerEmpty,\n * Error: EmojiPickerError,\n * CategoryHeader: EmojiPickerCategoryHeader,\n * Grid: EmojiPickerGrid,\n * Row: EmojiPickerRow,\n * Emoji: EmojiPickerEmoji,\n * }}\n * />\n */\nconst EmojiPickerContent = forwardRef<HTMLDivElement, EmojiPickerContentProps>(\n ({ components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const virtuosoRef = useRef<GroupedVirtuosoHandle>(null);\n const placeholderContainerRef = useRef<HTMLDivElement>(null);\n const rowScrollMarginTopRef = useRef<number>(0);\n const rowScrollMarginBottomRef = useRef<number>(0);\n const categoryHeaderHeightRef = useRef<number>(0);\n const {\n data,\n error,\n isLoading,\n columns,\n onEmojiSelect,\n selectedColumnIndex,\n selectedRowIndex,\n setPointerSelection,\n interaction,\n setInteraction,\n } = useEmojiPicker();\n const selectedEmoji = useMemo(\n () => data?.rows[selectedRowIndex]?.[selectedColumnIndex],\n [data?.rows, selectedColumnIndex, selectedRowIndex]\n );\n const { Loading, Empty, Error, CategoryHeader, Grid, Row, Emoji } = useMemo(\n () => ({ ...defaultContentComponents, ...components }),\n [components]\n );\n const VirtuosoList = useMemo(\n () =>\n forwardRef<HTMLDivElement, VirtuosoListProps>(\n ({ children, ...props }, forwardedRef) => {\n return (\n <div\n role=\"grid\"\n aria-colcount={columns}\n {...props}\n data-testid={undefined}\n ref={forwardedRef}\n >\n {children}\n </div>\n );\n }\n ),\n [columns]\n );\n const placeholderColumns = useMemo(\n () => Array<string>(columns).fill(\"🌫️\"),\n [columns]\n );\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const handleEmojiPointerLeave = useCallback(() => {\n if (interaction === \"pointer\") {\n setInteraction(\"none\");\n }\n }, [interaction, setInteraction]);\n\n useLayoutEffect(() => {\n if (!placeholderContainerRef.current) {\n return;\n }\n\n const row = placeholderContainerRef.current.childNodes[0];\n const categoryHeader = placeholderContainerRef.current.childNodes[1];\n\n if (row instanceof HTMLElement) {\n const style = window.getComputedStyle(row);\n\n rowScrollMarginTopRef.current = parseFloat(style.scrollMarginTop);\n rowScrollMarginBottomRef.current = parseFloat(style.scrollMarginBottom);\n }\n\n if (categoryHeader instanceof HTMLElement) {\n categoryHeaderHeightRef.current = categoryHeader.offsetHeight;\n }\n }, []);\n\n // Customize `scrollIntoView` behavior to take into account category headers and margins\n const calculateViewLocation = useCallback(\n ({\n itemTop,\n itemBottom,\n viewportTop,\n viewportBottom,\n locationParams: { behavior, align, ...params },\n }: CalculateViewLocationParams) => {\n if (\n itemTop -\n (categoryHeaderHeightRef.current + rowScrollMarginTopRef.current) <\n viewportTop\n ) {\n return {\n ...params,\n behavior,\n align: align ?? \"start\",\n };\n }\n\n if (itemBottom > viewportBottom) {\n return {\n ...params,\n behavior,\n align: align ?? \"end\",\n offset: rowScrollMarginBottomRef.current,\n };\n }\n\n return null;\n },\n []\n );\n\n useEffect(() => {\n if (interaction === \"keyboard\") {\n virtuosoRef.current?.scrollIntoView({\n index: selectedRowIndex,\n behavior: \"auto\",\n calculateViewLocation,\n });\n }\n }, [interaction, selectedRowIndex, calculateViewLocation]);\n\n return (\n <Component {...props} ref={forwardedRef}>\n <div\n style={{\n visibility: \"hidden\",\n height: 0,\n }}\n ref={placeholderContainerRef}\n >\n {/* Virtualized rows are absolutely positioned so they won't make\n the container automatically pick up their width. To achieve\n an automatic width, we add a relative (but hidden) full row. */}\n <Row attributes={placeholderRowAttributes}>\n {placeholderColumns.map((placeholder, index) => (\n <Emoji emoji={placeholder} key={index} />\n ))}\n </Row>\n {/* We also add a hidden category header to get its computed height. */}\n <CategoryHeader category=\"Category\" />\n </div>\n {isLoading ? (\n <Loading />\n ) : error ? (\n <Error error={error} />\n ) : data.count === 0 ? (\n <Empty />\n ) : (\n <Grid>\n <GroupedVirtuoso\n ref={virtuosoRef}\n components={{\n Scroller: VirtuosoScroller,\n List: VirtuosoList,\n TopItemList: VirtuosoTopList,\n }}\n groupCounts={data.categoriesRowCounts}\n groupContent={(groupIndex) => {\n const category = data.categories[groupIndex];\n\n if (!category) {\n return null;\n }\n\n return <CategoryHeader category={category} />;\n }}\n itemContent={(rowIndex, groupIndex) => {\n const categoryRow = data.rows[rowIndex];\n const categoryRowIndex =\n data.categoriesRowIndices[groupIndex]?.indexOf(rowIndex);\n const categoryRowsCount = data.categoriesRowCounts[groupIndex];\n\n if (\n categoryRow === undefined ||\n categoryRowIndex === undefined ||\n categoryRowsCount === undefined\n ) {\n return null;\n }\n\n return (\n <Row\n attributes={{\n rowIndex,\n categoryRowIndex,\n categoryRowsCount,\n }}\n >\n {categoryRow.map((emoji, columnIndex) => {\n const isSelected =\n interaction !== \"none\" &&\n selectedColumnIndex === columnIndex &&\n selectedRowIndex === rowIndex;\n\n return (\n <Emoji\n key={emoji.emoji}\n role=\"gridcell\"\n aria-colindex={columnIndex}\n aria-selected={isSelected || undefined}\n data-selected={isSelected || undefined}\n onMouseDown={preventDefault}\n tabIndex={-1}\n onPointerEnter={() => {\n setPointerSelection(columnIndex, rowIndex);\n }}\n onPointerLeave={handleEmojiPointerLeave}\n onClick={(event) => {\n onEmojiSelect?.(emoji.emoji);\n event.stopPropagation();\n }}\n emoji={emoji.emoji}\n />\n );\n })}\n </Row>\n );\n }}\n />\n </Grid>\n )}\n {selectedEmoji && interaction !== \"none\" && (\n <div aria-live=\"polite\" style={visuallyHidden}>\n {selectedEmoji.name}\n </div>\n )}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n EmojiPickerRoot.displayName = EMOJIPICKER_ROOT_NAME;\n EmojiPickerContent.displayName = EMOJIPICKER_CONTENT_NAME;\n EmojiPickerSearch.displayName = EMOJIPICKER_SEARCH_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as EmojiPicker.*\nexport {\n EmojiPickerContent as Content,\n EmojiPickerRoot as Root,\n EmojiPickerSearch as Search,\n};\n"],"names":["useRef","useTransition","useState","useCallback","filterEmojis","generateEmojiPickerData","locale","getEmojiData","error","useEffect","requestIdleCallback","cancelIdleCallback","jsx","EmojiPickerContext","forwardRef","Slot","useEmojiPicker","value","isKey","EmojiPrimitive","useMemo","props","forwardedRef","useLayoutEffect","jsxs","GroupedVirtuoso","visuallyHidden"],"mappings":"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"}