@liveblocks/react-ui 2.5.2 → 2.7.0-beta2

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 (104) hide show
  1. package/dist/components/Comment.js +61 -3
  2. package/dist/components/Comment.js.map +1 -1
  3. package/dist/components/Comment.mjs +62 -5
  4. package/dist/components/Comment.mjs.map +1 -1
  5. package/dist/components/Composer.js +217 -101
  6. package/dist/components/Composer.js.map +1 -1
  7. package/dist/components/Composer.mjs +220 -104
  8. package/dist/components/Composer.mjs.map +1 -1
  9. package/dist/components/InboxNotification.js +20 -4
  10. package/dist/components/InboxNotification.js.map +1 -1
  11. package/dist/components/InboxNotification.mjs +20 -4
  12. package/dist/components/InboxNotification.mjs.map +1 -1
  13. package/dist/components/Thread.js +2 -0
  14. package/dist/components/Thread.js.map +1 -1
  15. package/dist/components/Thread.mjs +2 -0
  16. package/dist/components/Thread.mjs.map +1 -1
  17. package/dist/components/internal/Attachment.js +207 -0
  18. package/dist/components/internal/Attachment.js.map +1 -0
  19. package/dist/components/internal/Attachment.mjs +205 -0
  20. package/dist/components/internal/Attachment.mjs.map +1 -0
  21. package/dist/components/internal/InboxNotificationThread.js +10 -2
  22. package/dist/components/internal/InboxNotificationThread.js.map +1 -1
  23. package/dist/components/internal/InboxNotificationThread.mjs +11 -3
  24. package/dist/components/internal/InboxNotificationThread.mjs.map +1 -1
  25. package/dist/icons/Attachment.js +15 -0
  26. package/dist/icons/Attachment.js.map +1 -0
  27. package/dist/icons/Attachment.mjs +13 -0
  28. package/dist/icons/Attachment.mjs.map +1 -0
  29. package/dist/icons/Spinner.js +3 -9
  30. package/dist/icons/Spinner.js.map +1 -1
  31. package/dist/icons/Spinner.mjs +4 -10
  32. package/dist/icons/Spinner.mjs.map +1 -1
  33. package/dist/icons/{Missing.js → Warning.js} +3 -3
  34. package/dist/icons/{Missing.js.map → Warning.js.map} +1 -1
  35. package/dist/icons/{Missing.mjs → Warning.mjs} +3 -3
  36. package/dist/icons/{Missing.mjs.map → Warning.mjs.map} +1 -1
  37. package/dist/index.d.mts +70 -4
  38. package/dist/index.d.ts +70 -4
  39. package/dist/index.js.map +1 -1
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/overrides.js +5 -0
  42. package/dist/overrides.js.map +1 -1
  43. package/dist/overrides.mjs +5 -0
  44. package/dist/overrides.mjs.map +1 -1
  45. package/dist/primitives/Composer/contexts.js +17 -3
  46. package/dist/primitives/Composer/contexts.js.map +1 -1
  47. package/dist/primitives/Composer/contexts.mjs +15 -4
  48. package/dist/primitives/Composer/contexts.mjs.map +1 -1
  49. package/dist/primitives/Composer/index.js +185 -26
  50. package/dist/primitives/Composer/index.js.map +1 -1
  51. package/dist/primitives/Composer/index.mjs +188 -31
  52. package/dist/primitives/Composer/index.mjs.map +1 -1
  53. package/dist/primitives/Composer/utils.js +224 -0
  54. package/dist/primitives/Composer/utils.js.map +1 -1
  55. package/dist/primitives/Composer/utils.mjs +222 -1
  56. package/dist/primitives/Composer/utils.mjs.map +1 -1
  57. package/dist/primitives/EmojiPicker/utils.js +2 -2
  58. package/dist/primitives/EmojiPicker/utils.js.map +1 -1
  59. package/dist/primitives/EmojiPicker/utils.mjs +1 -1
  60. package/dist/primitives/EmojiPicker/utils.mjs.map +1 -1
  61. package/dist/primitives/FileSize.js +33 -0
  62. package/dist/primitives/FileSize.js.map +1 -0
  63. package/dist/primitives/FileSize.mjs +31 -0
  64. package/dist/primitives/FileSize.mjs.map +1 -0
  65. package/dist/primitives/index.d.mts +83 -3
  66. package/dist/primitives/index.d.ts +83 -3
  67. package/dist/primitives/index.js +4 -0
  68. package/dist/primitives/index.js.map +1 -1
  69. package/dist/primitives/index.mjs +2 -0
  70. package/dist/primitives/index.mjs.map +1 -1
  71. package/dist/utils/download.js +14 -0
  72. package/dist/utils/download.js.map +1 -0
  73. package/dist/utils/download.mjs +12 -0
  74. package/dist/utils/download.mjs.map +1 -0
  75. package/dist/utils/format-file-size.js +45 -0
  76. package/dist/utils/format-file-size.js.map +1 -0
  77. package/dist/utils/format-file-size.mjs +43 -0
  78. package/dist/utils/format-file-size.mjs.map +1 -0
  79. package/dist/utils/intl.js +6 -0
  80. package/dist/utils/intl.js.map +1 -1
  81. package/dist/utils/intl.mjs +6 -1
  82. package/dist/utils/intl.mjs.map +1 -1
  83. package/dist/utils/use-initial.js +2 -1
  84. package/dist/utils/use-initial.js.map +1 -1
  85. package/dist/utils/use-initial.mjs +3 -2
  86. package/dist/utils/use-initial.mjs.map +1 -1
  87. package/dist/version.js +1 -1
  88. package/dist/version.js.map +1 -1
  89. package/dist/version.mjs +1 -1
  90. package/dist/version.mjs.map +1 -1
  91. package/package.json +4 -4
  92. package/src/styles/dark/index.css +1 -0
  93. package/src/styles/index.css +296 -62
  94. package/src/styles/utils.css +44 -0
  95. package/styles/dark/attributes.css +1 -1
  96. package/styles/dark/attributes.css.map +1 -1
  97. package/styles/dark/media-query.css +1 -1
  98. package/styles/dark/media-query.css.map +1 -1
  99. package/styles.css +1 -1
  100. package/styles.css.map +1 -1
  101. package/dist/utils/chunk.js +0 -12
  102. package/dist/utils/chunk.js.map +0 -1
  103. package/dist/utils/chunk.mjs +0 -10
  104. package/dist/utils/chunk.mjs.map +0 -1
@@ -1,9 +1,15 @@
1
+ import { makeEventSource } from '@liveblocks/core';
2
+ import { useRoom } from '@liveblocks/react';
3
+ import { useState, useCallback, useEffect, useMemo } from 'react';
4
+ import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';
1
5
  import { isComposerBodyAutoLink } from '../../slate/plugins/auto-links.mjs';
2
6
  import { isComposerBodyCustomLink } from '../../slate/plugins/custom-links.mjs';
3
7
  import { isComposerBodyMention } from '../../slate/plugins/mentions.mjs';
4
8
  import { isText } from '../../slate/utils/is-text.mjs';
5
9
  import { exists } from '../../utils/exists.mjs';
10
+ import { useInitial } from '../../utils/use-initial.mjs';
6
11
  import { isCommentBodyMention, isCommentBodyLink, isCommentBodyText } from '../Comment/utils.mjs';
12
+ import { useComposer, useComposerAttachmentsContext } from './contexts.mjs';
7
13
 
8
14
  function composerBodyMentionToCommentBodyMention(mention) {
9
15
  return {
@@ -109,6 +115,221 @@ function getSideAndAlignFromPlacement(placement) {
109
115
  const [side, align = "center"] = placement.split("-");
110
116
  return [side, align];
111
117
  }
118
+ function useComposerAttachmentsDropArea({
119
+ onDragEnter,
120
+ onDragLeave,
121
+ onDragOver,
122
+ onDrop,
123
+ ignoreLeaveEvent,
124
+ disabled
125
+ }) {
126
+ const { isDisabled: isComposerDisabled } = useComposer();
127
+ const isDisabled = isComposerDisabled || disabled;
128
+ const { createAttachments } = useComposerAttachmentsContext();
129
+ const [isDraggingOver, setDraggingOver] = useState(false);
130
+ const handleDragEnter = useCallback(
131
+ (event) => {
132
+ onDragEnter?.(event);
133
+ if (isDisabled || event.isDefaultPrevented()) {
134
+ return;
135
+ }
136
+ const dataTransfer = event.dataTransfer;
137
+ if (dataTransfer.types.includes("Files")) {
138
+ event.preventDefault();
139
+ event.stopPropagation();
140
+ setDraggingOver(true);
141
+ }
142
+ },
143
+ [onDragEnter, isDisabled]
144
+ );
145
+ const handleDragLeave = useCallback(
146
+ (event) => {
147
+ onDragLeave?.(event);
148
+ if (isDisabled || event.isDefaultPrevented()) {
149
+ return;
150
+ }
151
+ if (ignoreLeaveEvent?.(event)) {
152
+ return;
153
+ }
154
+ event.preventDefault();
155
+ event.stopPropagation();
156
+ setDraggingOver(false);
157
+ },
158
+ [onDragLeave, ignoreLeaveEvent, isDisabled]
159
+ );
160
+ const handleDragOver = useCallback(
161
+ (event) => {
162
+ onDragOver?.(event);
163
+ if (isDisabled || !isDraggingOver || event.isDefaultPrevented()) {
164
+ return;
165
+ }
166
+ event.preventDefault();
167
+ event.stopPropagation();
168
+ },
169
+ [onDragOver, isDraggingOver, isDisabled]
170
+ );
171
+ const handleDrop = useCallback(
172
+ (event) => {
173
+ onDrop?.(event);
174
+ if (isDisabled || event.isDefaultPrevented()) {
175
+ return;
176
+ }
177
+ event.preventDefault();
178
+ event.stopPropagation();
179
+ setDraggingOver(false);
180
+ const files = Array.from(event.dataTransfer.items).map((item) => {
181
+ const entry = item.webkitGetAsEntry();
182
+ return entry && entry.isFile ? item.getAsFile() : null;
183
+ }).filter(exists);
184
+ createAttachments(files);
185
+ },
186
+ [onDrop, createAttachments, isDisabled]
187
+ );
188
+ return [
189
+ isDraggingOver,
190
+ {
191
+ onDragEnter: handleDragEnter,
192
+ onDragLeave: handleDragLeave,
193
+ onDragOver: handleDragOver,
194
+ onDrop: handleDrop,
195
+ "data-drop": isDraggingOver ? "" : void 0,
196
+ "data-disabled": isDisabled ? "" : void 0
197
+ }
198
+ ];
199
+ }
200
+ class AttachmentTooLargeError extends Error {
201
+ constructor() {
202
+ super(...arguments);
203
+ this.name = "AttachmentTooLargeError";
204
+ }
205
+ }
206
+ function createComposerAttachmentsManager(room, options) {
207
+ const attachments = /* @__PURE__ */ new Map();
208
+ const abortControllers = /* @__PURE__ */ new Map();
209
+ const eventSource = makeEventSource();
210
+ let cachedSnapshot = null;
211
+ function notifySubscribers() {
212
+ cachedSnapshot = null;
213
+ eventSource.notify();
214
+ }
215
+ function setAttachment(attachment) {
216
+ attachments.set(attachment.id, attachment);
217
+ notifySubscribers();
218
+ }
219
+ function addAttachment(attachment) {
220
+ if (attachments.has(attachment.id)) {
221
+ return;
222
+ }
223
+ if (attachment.type === "localAttachment") {
224
+ if (attachment.status !== "idle") {
225
+ return;
226
+ }
227
+ if (attachment.file.size > options.maxFileSize) {
228
+ setAttachment({
229
+ ...attachment,
230
+ status: "error",
231
+ error: new AttachmentTooLargeError("File is too large.")
232
+ });
233
+ return;
234
+ }
235
+ const abortController = new AbortController();
236
+ abortControllers.set(attachment.id, abortController);
237
+ setAttachment({
238
+ ...attachment,
239
+ status: "uploading"
240
+ });
241
+ room.uploadAttachment(attachment, {
242
+ signal: abortController.signal
243
+ }).then(() => {
244
+ setAttachment({
245
+ ...attachment,
246
+ status: "uploaded"
247
+ });
248
+ }).catch((error) => {
249
+ if (error instanceof Error && error.name !== "AbortError" && error.name !== "TimeoutError") {
250
+ setAttachment({
251
+ ...attachment,
252
+ status: "error",
253
+ error
254
+ });
255
+ }
256
+ });
257
+ } else {
258
+ setAttachment(attachment);
259
+ }
260
+ }
261
+ function removeAttachment(attachmentId) {
262
+ const abortController = abortControllers.get(attachmentId);
263
+ abortController?.abort();
264
+ attachments.delete(attachmentId);
265
+ abortControllers.delete(attachmentId);
266
+ notifySubscribers();
267
+ }
268
+ function getSnapshot() {
269
+ if (!cachedSnapshot) {
270
+ cachedSnapshot = Array.from(attachments.values());
271
+ }
272
+ return cachedSnapshot;
273
+ }
274
+ function clear() {
275
+ abortControllers.forEach((controller) => controller.abort());
276
+ abortControllers.clear();
277
+ eventSource.clear();
278
+ attachments.clear();
279
+ notifySubscribers();
280
+ }
281
+ return {
282
+ addAttachment,
283
+ removeAttachment,
284
+ getSnapshot,
285
+ subscribe: eventSource.subscribe,
286
+ clear
287
+ };
288
+ }
289
+ function preventBeforeUnloadDefault(event) {
290
+ event.preventDefault();
291
+ }
292
+ function useComposerAttachmentsManager(defaultAttachments, options) {
293
+ const room = useRoom();
294
+ const frozenDefaultAttachments = useInitial(defaultAttachments);
295
+ const attachmentsManager = useInitial(
296
+ () => createComposerAttachmentsManager(room, options)
297
+ );
298
+ useEffect(() => {
299
+ frozenDefaultAttachments.forEach((attachment) => {
300
+ attachmentsManager.addAttachment(attachment);
301
+ });
302
+ return () => {
303
+ attachmentsManager.clear();
304
+ };
305
+ }, [frozenDefaultAttachments, attachmentsManager]);
306
+ const attachments = useSyncExternalStore(
307
+ attachmentsManager.subscribe,
308
+ attachmentsManager.getSnapshot,
309
+ attachmentsManager.getSnapshot
310
+ );
311
+ const isUploadingAttachments = useMemo(() => {
312
+ return attachments.some(
313
+ (attachment) => attachment.type === "localAttachment" && attachment.status === "uploading"
314
+ );
315
+ }, [attachments]);
316
+ useEffect(() => {
317
+ if (!isUploadingAttachments) {
318
+ return;
319
+ }
320
+ window.addEventListener("beforeunload", preventBeforeUnloadDefault);
321
+ return () => {
322
+ window.removeEventListener("beforeunload", preventBeforeUnloadDefault);
323
+ };
324
+ }, [isUploadingAttachments]);
325
+ return {
326
+ attachments,
327
+ isUploadingAttachments,
328
+ addAttachment: attachmentsManager.addAttachment,
329
+ removeAttachment: attachmentsManager.removeAttachment,
330
+ clearAttachments: attachmentsManager.clear
331
+ };
332
+ }
112
333
 
113
- export { commentBodyLinkToComposerBodyLink, commentBodyMentionToComposerBodyMention, commentBodyToComposerBody, composerBodyAutoLinkToCommentBodyLink, composerBodyCustomLinkToCommentBodyLink, composerBodyMentionToCommentBodyMention, composerBodyToCommentBody, getPlacementFromPosition, getSideAndAlignFromPlacement };
334
+ export { AttachmentTooLargeError, commentBodyLinkToComposerBodyLink, commentBodyMentionToComposerBodyMention, commentBodyToComposerBody, composerBodyAutoLinkToCommentBodyLink, composerBodyCustomLinkToCommentBodyLink, composerBodyMentionToCommentBodyMention, composerBodyToCommentBody, getPlacementFromPosition, getSideAndAlignFromPlacement, useComposerAttachmentsDropArea, useComposerAttachmentsManager };
114
335
  //# sourceMappingURL=utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","sources":["../../../src/primitives/Composer/utils.ts"],"sourcesContent":["import type { Placement } from \"@floating-ui/react-dom\";\nimport type {\n CommentBody,\n CommentBodyLink,\n CommentBodyMention,\n} from \"@liveblocks/core\";\n\nimport { isComposerBodyAutoLink } from \"../../slate/plugins/auto-links\";\nimport { isComposerBodyCustomLink } from \"../../slate/plugins/custom-links\";\nimport { isComposerBodyMention } from \"../../slate/plugins/mentions\";\nimport { isText } from \"../../slate/utils/is-text\";\nimport type {\n ComposerBody,\n ComposerBodyAutoLink,\n ComposerBodyCustomLink,\n ComposerBodyMention,\n ComposerBodyText,\n Direction,\n} from \"../../types\";\nimport { exists } from \"../../utils/exists\";\nimport {\n isCommentBodyLink,\n isCommentBodyMention,\n isCommentBodyText,\n} from \"../Comment/utils\";\nimport type { SuggestionsPosition } from \"./types\";\n\nexport function composerBodyMentionToCommentBodyMention(\n mention: ComposerBodyMention\n): CommentBodyMention {\n return {\n type: \"mention\",\n id: mention.id,\n };\n}\n\nexport function composerBodyAutoLinkToCommentBodyLink(\n link: ComposerBodyAutoLink\n): CommentBodyLink {\n return {\n type: \"link\",\n url: link.url,\n };\n}\n\nexport function composerBodyCustomLinkToCommentBodyLink(\n link: ComposerBodyCustomLink\n): CommentBodyLink {\n return {\n type: \"link\",\n url: link.url,\n text: link.children.map((child) => child.text).join(\"\"),\n };\n}\n\nexport function commentBodyMentionToComposerBodyMention(\n mention: CommentBodyMention\n): ComposerBodyMention {\n return {\n type: \"mention\",\n id: mention.id,\n children: [{ text: \"\" }],\n };\n}\n\nexport function commentBodyLinkToComposerBodyLink(\n link: CommentBodyLink\n): ComposerBodyAutoLink | ComposerBodyCustomLink {\n if (link.text) {\n return {\n type: \"custom-link\",\n url: link.url,\n children: [{ text: link.text }],\n };\n } else {\n return {\n type: \"auto-link\",\n url: link.url,\n children: [{ text: link.url }],\n };\n }\n}\n\nexport function composerBodyToCommentBody(body: ComposerBody): CommentBody {\n return {\n version: 1,\n content: body\n .map((block) => {\n // All root blocks are paragraphs at the moment\n if (block.type !== \"paragraph\") {\n return null;\n }\n\n const children = block.children\n .map((inline) => {\n if (isComposerBodyMention(inline)) {\n return composerBodyMentionToCommentBodyMention(inline);\n }\n\n if (isComposerBodyAutoLink(inline)) {\n return composerBodyAutoLinkToCommentBodyLink(inline);\n }\n\n if (isComposerBodyCustomLink(inline)) {\n return composerBodyCustomLinkToCommentBodyLink(inline);\n }\n\n if (isText(inline)) {\n return inline;\n }\n\n return null;\n })\n .filter(exists);\n\n return {\n ...block,\n children,\n };\n })\n .filter(exists),\n };\n}\n\nconst emptyComposerBody: ComposerBody = [];\n\nexport function commentBodyToComposerBody(body: CommentBody): ComposerBody {\n if (!body || !body?.content) {\n return emptyComposerBody;\n }\n\n return body.content\n .map((block) => {\n // All root blocks are paragraphs at the moment\n if (block.type !== \"paragraph\") {\n return null;\n }\n\n const children = block.children\n .map((inline) => {\n if (isCommentBodyMention(inline)) {\n return commentBodyMentionToComposerBodyMention(inline);\n }\n\n if (isCommentBodyLink(inline)) {\n return commentBodyLinkToComposerBodyLink(inline);\n }\n\n if (isCommentBodyText(inline)) {\n return inline as ComposerBodyText;\n }\n\n return null;\n })\n .filter(exists);\n\n return {\n ...block,\n children,\n };\n })\n .filter(exists);\n}\n\nexport function getPlacementFromPosition(\n position: SuggestionsPosition,\n direction: Direction = \"ltr\"\n): Placement {\n return `${position}-${direction === \"rtl\" ? \"end\" : \"start\"}`;\n}\n\nexport function getSideAndAlignFromPlacement(placement: Placement) {\n const [side, align = \"center\"] = placement.split(\"-\");\n\n return [side, align] as const;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.mjs","sources":["../../../src/primitives/Composer/utils.ts"],"sourcesContent":["import type { Placement } from \"@floating-ui/react-dom\";\nimport {\n type CommentAttachment,\n type CommentBody,\n type CommentBodyLink,\n type CommentBodyMention,\n type CommentMixedAttachment,\n makeEventSource,\n type OpaqueRoom,\n} from \"@liveblocks/core\";\nimport { useRoom } from \"@liveblocks/react\";\nimport type { DragEvent } from \"react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport { isComposerBodyAutoLink } from \"../../slate/plugins/auto-links\";\nimport { isComposerBodyCustomLink } from \"../../slate/plugins/custom-links\";\nimport { isComposerBodyMention } from \"../../slate/plugins/mentions\";\nimport { isText } from \"../../slate/utils/is-text\";\nimport type {\n ComposerBody,\n ComposerBodyAutoLink,\n ComposerBodyCustomLink,\n ComposerBodyMention,\n ComposerBodyText,\n Direction,\n} from \"../../types\";\nimport { exists } from \"../../utils/exists\";\nimport { useInitial } from \"../../utils/use-initial\";\nimport {\n isCommentBodyLink,\n isCommentBodyMention,\n isCommentBodyText,\n} from \"../Comment/utils\";\nimport { useComposer, useComposerAttachmentsContext } from \"./contexts\";\nimport type { SuggestionsPosition } from \"./types\";\n\nexport function composerBodyMentionToCommentBodyMention(\n mention: ComposerBodyMention\n): CommentBodyMention {\n return {\n type: \"mention\",\n id: mention.id,\n };\n}\n\nexport function composerBodyAutoLinkToCommentBodyLink(\n link: ComposerBodyAutoLink\n): CommentBodyLink {\n return {\n type: \"link\",\n url: link.url,\n };\n}\n\nexport function composerBodyCustomLinkToCommentBodyLink(\n link: ComposerBodyCustomLink\n): CommentBodyLink {\n return {\n type: \"link\",\n url: link.url,\n text: link.children.map((child) => child.text).join(\"\"),\n };\n}\n\nexport function commentBodyMentionToComposerBodyMention(\n mention: CommentBodyMention\n): ComposerBodyMention {\n return {\n type: \"mention\",\n id: mention.id,\n children: [{ text: \"\" }],\n };\n}\n\nexport function commentBodyLinkToComposerBodyLink(\n link: CommentBodyLink\n): ComposerBodyAutoLink | ComposerBodyCustomLink {\n if (link.text) {\n return {\n type: \"custom-link\",\n url: link.url,\n children: [{ text: link.text }],\n };\n } else {\n return {\n type: \"auto-link\",\n url: link.url,\n children: [{ text: link.url }],\n };\n }\n}\n\nexport function composerBodyToCommentBody(body: ComposerBody): CommentBody {\n return {\n version: 1,\n content: body\n .map((block) => {\n // All root blocks are paragraphs at the moment\n if (block.type !== \"paragraph\") {\n return null;\n }\n\n const children = block.children\n .map((inline) => {\n if (isComposerBodyMention(inline)) {\n return composerBodyMentionToCommentBodyMention(inline);\n }\n\n if (isComposerBodyAutoLink(inline)) {\n return composerBodyAutoLinkToCommentBodyLink(inline);\n }\n\n if (isComposerBodyCustomLink(inline)) {\n return composerBodyCustomLinkToCommentBodyLink(inline);\n }\n\n if (isText(inline)) {\n return inline;\n }\n\n return null;\n })\n .filter(exists);\n\n return {\n ...block,\n children,\n };\n })\n .filter(exists),\n };\n}\n\nconst emptyComposerBody: ComposerBody = [];\n\nexport function commentBodyToComposerBody(body: CommentBody): ComposerBody {\n if (!body || !body?.content) {\n return emptyComposerBody;\n }\n\n return body.content\n .map((block) => {\n // All root blocks are paragraphs at the moment\n if (block.type !== \"paragraph\") {\n return null;\n }\n\n const children = block.children\n .map((inline) => {\n if (isCommentBodyMention(inline)) {\n return commentBodyMentionToComposerBodyMention(inline);\n }\n\n if (isCommentBodyLink(inline)) {\n return commentBodyLinkToComposerBodyLink(inline);\n }\n\n if (isCommentBodyText(inline)) {\n return inline as ComposerBodyText;\n }\n\n return null;\n })\n .filter(exists);\n\n return {\n ...block,\n children,\n };\n })\n .filter(exists);\n}\n\nexport function getPlacementFromPosition(\n position: SuggestionsPosition,\n direction: Direction = \"ltr\"\n): Placement {\n return `${position}-${direction === \"rtl\" ? \"end\" : \"start\"}`;\n}\n\nexport function getSideAndAlignFromPlacement(placement: Placement) {\n const [side, align = \"center\"] = placement.split(\"-\");\n\n return [side, align] as const;\n}\n\nexport function useComposerAttachmentsDropArea<\n T extends HTMLElement = HTMLElement,\n>({\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n ignoreLeaveEvent,\n disabled,\n}: {\n onDragEnter?: (event: DragEvent<T>) => void;\n onDragLeave?: (event: DragEvent<T>) => void;\n onDragOver?: (event: DragEvent<T>) => void;\n onDrop?: (event: DragEvent<T>) => void;\n ignoreLeaveEvent?: (event: DragEvent<T>) => boolean;\n disabled?: boolean;\n}) {\n const { isDisabled: isComposerDisabled } = useComposer();\n const isDisabled = isComposerDisabled || disabled;\n const { createAttachments } = useComposerAttachmentsContext();\n const [isDraggingOver, setDraggingOver] = useState(false);\n\n const handleDragEnter = useCallback(\n (event: DragEvent<T>) => {\n onDragEnter?.(event);\n\n if (isDisabled || event.isDefaultPrevented()) {\n return;\n }\n\n const dataTransfer = event.dataTransfer;\n\n if (dataTransfer.types.includes(\"Files\")) {\n event.preventDefault();\n event.stopPropagation();\n\n setDraggingOver(true);\n }\n },\n [onDragEnter, isDisabled]\n );\n\n const handleDragLeave = useCallback(\n (event: DragEvent<T>) => {\n onDragLeave?.(event);\n\n if (isDisabled || event.isDefaultPrevented()) {\n return;\n }\n\n if (ignoreLeaveEvent?.(event)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n setDraggingOver(false);\n },\n [onDragLeave, ignoreLeaveEvent, isDisabled]\n );\n\n const handleDragOver = useCallback(\n (event: DragEvent<T>) => {\n onDragOver?.(event);\n\n if (isDisabled || !isDraggingOver || event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n },\n [onDragOver, isDraggingOver, isDisabled]\n );\n\n const handleDrop = useCallback(\n (event: DragEvent<T>) => {\n onDrop?.(event);\n\n if (isDisabled || event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n setDraggingOver(false);\n\n const files = Array.from(event.dataTransfer.items)\n .map((item) => {\n const entry = item.webkitGetAsEntry();\n\n return entry && entry.isFile ? item.getAsFile() : null;\n })\n .filter(exists);\n\n createAttachments(files);\n },\n [onDrop, createAttachments, isDisabled]\n );\n\n return [\n isDraggingOver,\n {\n onDragEnter: handleDragEnter,\n onDragLeave: handleDragLeave,\n onDragOver: handleDragOver,\n onDrop: handleDrop,\n \"data-drop\": isDraggingOver ? \"\" : undefined,\n \"data-disabled\": isDisabled ? \"\" : undefined,\n } as const,\n ] as const;\n}\n\ninterface ComposerAttachmentsManagerOptions {\n maxFileSize: number;\n}\n\nexport class AttachmentTooLargeError extends Error {\n name = \"AttachmentTooLargeError\";\n}\n\nfunction createComposerAttachmentsManager(\n room: OpaqueRoom,\n options: ComposerAttachmentsManagerOptions\n) {\n const attachments: Map<string, CommentMixedAttachment> = new Map();\n const abortControllers: Map<string, AbortController> = new Map();\n const eventSource = makeEventSource<void>();\n let cachedSnapshot: CommentMixedAttachment[] | null = null;\n\n function notifySubscribers() {\n // Invalidate the cached snapshot\n cachedSnapshot = null;\n eventSource.notify();\n }\n\n function setAttachment(attachment: CommentMixedAttachment) {\n attachments.set(attachment.id, attachment);\n\n notifySubscribers();\n }\n\n function addAttachment(attachment: CommentMixedAttachment) {\n // The attachment already exists\n if (attachments.has(attachment.id)) {\n return;\n }\n\n if (attachment.type === \"localAttachment\") {\n if (attachment.status !== \"idle\") {\n return;\n }\n\n // The file is too large to be uploaded\n if (attachment.file.size > options.maxFileSize) {\n setAttachment({\n ...attachment,\n status: \"error\",\n error: new AttachmentTooLargeError(\"File is too large.\"),\n });\n\n return;\n }\n\n const abortController = new AbortController();\n abortControllers.set(attachment.id, abortController);\n\n setAttachment({\n ...attachment,\n status: \"uploading\",\n });\n\n // Start uploading the attachment immediately\n // TODO: Queue uploads and keep them in \"idle\" state until they actually start uploading?\n room\n .uploadAttachment(attachment, {\n signal: abortController.signal,\n })\n .then(() => {\n setAttachment({\n ...attachment,\n status: \"uploaded\",\n });\n })\n .catch((error) => {\n if (\n error instanceof Error &&\n error.name !== \"AbortError\" &&\n error.name !== \"TimeoutError\"\n ) {\n setAttachment({\n ...attachment,\n status: \"error\",\n error,\n });\n }\n });\n } else {\n // The attachment is already uploaded\n setAttachment(attachment);\n }\n }\n\n function removeAttachment(attachmentId: string) {\n const abortController = abortControllers.get(attachmentId);\n\n abortController?.abort();\n\n attachments.delete(attachmentId);\n abortControllers.delete(attachmentId);\n\n notifySubscribers();\n }\n\n function getSnapshot() {\n if (!cachedSnapshot) {\n cachedSnapshot = Array.from(attachments.values());\n }\n\n return cachedSnapshot;\n }\n\n function clear() {\n abortControllers.forEach((controller) => controller.abort());\n abortControllers.clear();\n eventSource.clear();\n attachments.clear();\n\n notifySubscribers();\n }\n\n return {\n addAttachment,\n removeAttachment,\n getSnapshot,\n subscribe: eventSource.subscribe,\n clear,\n };\n}\n\nfunction preventBeforeUnloadDefault(event: BeforeUnloadEvent) {\n event.preventDefault();\n}\n\nexport function useComposerAttachmentsManager(\n defaultAttachments: CommentAttachment[],\n options: ComposerAttachmentsManagerOptions\n) {\n const room = useRoom();\n const frozenDefaultAttachments = useInitial(defaultAttachments);\n const attachmentsManager = useInitial(() =>\n createComposerAttachmentsManager(room, options)\n );\n\n useEffect(() => {\n // Initialize default attachments\n frozenDefaultAttachments.forEach((attachment) => {\n attachmentsManager.addAttachment(attachment);\n });\n\n return () => {\n attachmentsManager.clear();\n };\n }, [frozenDefaultAttachments, attachmentsManager]);\n\n const attachments = useSyncExternalStore(\n attachmentsManager.subscribe,\n attachmentsManager.getSnapshot,\n attachmentsManager.getSnapshot\n );\n\n const isUploadingAttachments = useMemo(() => {\n return attachments.some(\n (attachment) =>\n attachment.type === \"localAttachment\" &&\n attachment.status === \"uploading\"\n );\n }, [attachments]);\n\n useEffect(() => {\n if (!isUploadingAttachments) {\n return;\n }\n\n window.addEventListener(\"beforeunload\", preventBeforeUnloadDefault);\n\n return () => {\n window.removeEventListener(\"beforeunload\", preventBeforeUnloadDefault);\n };\n }, [isUploadingAttachments]);\n\n return {\n attachments,\n isUploadingAttachments,\n addAttachment: attachmentsManager.addAttachment,\n removeAttachment: attachmentsManager.removeAttachment,\n clearAttachments: attachmentsManager.clear,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ var core = require('@liveblocks/core');
3
4
  var constants = require('../../constants.js');
4
5
  var capitalize = require('../../utils/capitalize.js');
5
- var chunk = require('../../utils/chunk.js');
6
6
 
7
7
  const EMOJIBASE_VERSION = "15.3.0";
8
8
  const EMOJIBASE_CDN_URL = `https://cdn.jsdelivr.net/npm/emojibase-data@${EMOJIBASE_VERSION}`;
@@ -304,7 +304,7 @@ function generateEmojiPickerData(emojis, categories, columns) {
304
304
  emojis: indexedEmojis.filter((emoji) => emoji.category === category.key)
305
305
  })).filter((category) => category.emojis.length > 0);
306
306
  for (const category of categorizedEmojis) {
307
- const categoryRows = chunk.chunk(category.emojis, columns);
307
+ const categoryRows = core.chunk(category.emojis, columns);
308
308
  const nextIndex = currentIndex + categoryRows.length;
309
309
  rows.push(...categoryRows);
310
310
  categoriesNames.push(category.name);
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/primitives/EmojiPicker/utils.ts"],"sourcesContent":["import type {\n Emoji as EmojibaseEmoji,\n Locale as EmojibaseLocale,\n MessagesDataset as EmojibaseMessagesDataset,\n} from \"emojibase\";\n\nimport { EMOJI_FONT_FAMILY } from \"../../constants\";\nimport { capitalize } from \"../../utils/capitalize\";\nimport { chunk } from \"../../utils/chunk\";\nimport type {\n Emoji,\n EmojiCategory,\n EmojiData,\n EmojiPickerData,\n EmojiPickerRow,\n} from \"./types\";\n\nconst EMOJIBASE_VERSION = \"15.3.0\";\nconst EMOJIBASE_CDN_URL = `https://cdn.jsdelivr.net/npm/emojibase-data@${EMOJIBASE_VERSION}`;\nconst EMOJIBASE_EMOJIS_URL = (locale: EmojibaseLocale) =>\n `${EMOJIBASE_CDN_URL}/${locale}/data.json`;\nconst EMOJIBASE_MESSAGES_URL = (locale: EmojibaseLocale) =>\n `${EMOJIBASE_CDN_URL}/${locale}/messages.json`;\nconst EMOJIBASE_LOCALES: EmojibaseLocale[] = [\n \"bn\",\n \"da\",\n \"de\",\n \"en\",\n \"en-gb\",\n \"es\",\n \"es-mx\",\n \"et\",\n \"fi\",\n \"fr\",\n \"hi\",\n \"hu\",\n \"it\",\n \"ja\",\n \"ko\",\n \"lt\",\n \"ms\",\n \"nb\",\n \"nl\",\n \"pl\",\n \"pt\",\n \"ru\",\n \"sv\",\n \"th\",\n \"uk\",\n \"zh\",\n \"zh-hant\",\n];\nconst EMOJIBASE_DEFAULT_LOCALE: EmojibaseLocale = \"en\";\n\nconst CACHE_EMOJI_DATA_KEY = (locale: string) => `lb-emoji-data-${locale}`;\nconst CACHE_EMOJI_METADATA_KEY = (locale: string) =>\n `lb-emoji-metadata-${locale}`;\nconst CACHE_EMOJI_SESSION_METADATA_KEY = \"lb-emoji-metadata\";\n\nconst EMOJI_DETECTION_CANVAS_WIDTH = 20;\nconst EMOJI_DETECTION_CANVAS_HEIGHT = 25;\nconst EMOJI_DETECTION_COUNTRY_FLAG = \"🇫🇷\";\n\ntype EmojiMetadata = {\n emojisEtag: string | null;\n messagesEtag: string | null;\n};\n\ntype EmojiSessionMetadata = {\n emojiVersion: number;\n countryFlags: boolean;\n};\n\nfunction generateRangeIndices(start: number, end: number) {\n const range: number[] = [];\n\n for (let i = start; i <= end; i++) {\n range.push(i);\n }\n\n return range;\n}\n\nfunction getStorageItem<T>(storage: Storage, key: string) {\n const item = storage.getItem(key);\n\n return item ? (JSON.parse(item) as T) : null;\n}\n\nfunction setStorageItem<T>(storage: Storage, key: string, value: T) {\n storage.setItem(key, JSON.stringify(value));\n}\n\nasync function fetchEtag(url: string) {\n try {\n const response = await fetch(url, { method: \"HEAD\" });\n\n return response.headers.get(\"etag\");\n } catch (error) {\n return null;\n }\n}\n\nfunction getEmojibaseSupportedLocale(locale: string): EmojibaseLocale {\n return EMOJIBASE_LOCALES.includes(locale as EmojibaseLocale)\n ? (locale as EmojibaseLocale)\n : EMOJIBASE_DEFAULT_LOCALE;\n}\n\nasync function fetchEmojibaseData(locale: EmojibaseLocale) {\n const [{ emojis, emojisEtag }, { messages, messagesEtag }] =\n await Promise.all([\n fetch(EMOJIBASE_EMOJIS_URL(locale)).then(async (response) => {\n return {\n emojis: (await response.json()) as EmojibaseEmoji[],\n emojisEtag: response.headers.get(\"etag\"),\n };\n }),\n fetch(EMOJIBASE_MESSAGES_URL(locale)).then(async (response) => {\n return {\n messages: (await response.json()) as EmojibaseMessagesDataset,\n messagesEtag: response.headers.get(\"etag\"),\n };\n }),\n ]);\n\n return {\n emojis,\n messages,\n emojisEtag,\n messagesEtag,\n };\n}\n\nasync function fetchEmojibaseEtags(locale: EmojibaseLocale) {\n const [emojisEtag, messagesEtag] = await Promise.all([\n fetchEtag(EMOJIBASE_EMOJIS_URL(locale)),\n fetchEtag(EMOJIBASE_MESSAGES_URL(locale)),\n ]);\n\n return {\n emojisEtag,\n messagesEtag,\n };\n}\n\nasync function fetchEmojiData(locale: EmojibaseLocale): Promise<EmojiData> {\n const { emojis, emojisEtag, messages, messagesEtag } =\n await fetchEmojibaseData(locale);\n const countryFlagsSubgroup = messages.subgroups.find(\n (subgroup) => subgroup.key === \"subdivision-flag\"\n );\n\n // Filter out component/modifier category and emojis\n const filteredGroups = messages.groups.filter(\n (group) => group.key !== \"component\"\n );\n const filteredEmojis = emojis.filter((emoji) => {\n return \"group\" in emoji;\n });\n\n // Pick and compact the data\n const categories = filteredGroups.map((group) => ({\n key: group.order,\n name: capitalize(group.message),\n }));\n const skinTones = messages.skinTones.map((skinTone) => ({\n key: skinTone.key,\n name: capitalize(skinTone.message),\n }));\n const compactEmojis = filteredEmojis.map((emoji) => {\n const compactEmoji: Emoji = {\n emoji: emoji.emoji,\n category: emoji.group!,\n version: emoji.version,\n name: capitalize(emoji.label),\n tags: emoji.tags,\n };\n\n if (countryFlagsSubgroup && emoji.subgroup === countryFlagsSubgroup.order) {\n compactEmoji.countryFlag = true;\n }\n\n return compactEmoji;\n });\n\n const emojiData = {\n emojis: compactEmojis,\n categories,\n skinTones,\n };\n\n // Cache the data and metadata\n setStorageItem<EmojiData>(\n localStorage,\n CACHE_EMOJI_DATA_KEY(locale),\n emojiData\n );\n setStorageItem<EmojiMetadata>(\n localStorage,\n CACHE_EMOJI_METADATA_KEY(locale),\n {\n emojisEtag,\n messagesEtag,\n }\n );\n\n return emojiData;\n}\n\n// Adapted from https://github.com/koala-interactive/is-emoji-supported/tree/master\nfunction detectEmojiSupport(\n canvasContext: CanvasRenderingContext2D,\n emoji: string\n): boolean {\n canvasContext.clearRect(\n 0,\n 0,\n EMOJI_DETECTION_CANVAS_WIDTH * 2,\n EMOJI_DETECTION_CANVAS_HEIGHT\n );\n\n // Draw in red on the left\n canvasContext.fillStyle = \"#f00\";\n canvasContext.fillText(emoji, 0, 22);\n\n // Draw in blue on right\n canvasContext.fillStyle = \"#00f\";\n canvasContext.fillText(emoji, EMOJI_DETECTION_CANVAS_WIDTH, 22);\n\n const pixels = canvasContext.getImageData(\n 0,\n 0,\n EMOJI_DETECTION_CANVAS_WIDTH,\n EMOJI_DETECTION_CANVAS_HEIGHT\n ).data;\n const pixelCount = pixels.length;\n let i = 0;\n\n // Search for the first visible pixel\n for (; i < pixelCount && !pixels[i + 3]; i += 4);\n\n // No visible pixel\n if (i >= pixelCount) {\n return false;\n }\n\n // Emojis have an immutable color, so we check the color of the emoji in two\n // different colors, the result should be the same\n const x =\n EMOJI_DETECTION_CANVAS_WIDTH + ((i / 4) % EMOJI_DETECTION_CANVAS_WIDTH);\n const y = Math.floor(i / 4 / EMOJI_DETECTION_CANVAS_WIDTH);\n const pixel = canvasContext.getImageData(x, y, 1, 1).data;\n\n if (pixels[i] !== pixel[0] || pixels[i + 2] !== pixel[2]) {\n return false;\n }\n\n // Unsupported ZWJ sequence emojis show up as separate emojis\n if (canvasContext.measureText(emoji).width >= EMOJI_DETECTION_CANVAS_WIDTH) {\n return false;\n }\n\n return true;\n}\n\nfunction getEmojiFontFamily() {\n try {\n const element = document.createElement(\"span\");\n element.style.display = \"none\";\n element.dataset.emoji = \"\";\n\n document.body.appendChild(element);\n\n const computedFontFamily = window.getComputedStyle(element).fontFamily;\n\n document.body.removeChild(element);\n\n return computedFontFamily;\n } catch {\n return EMOJI_FONT_FAMILY;\n }\n}\n\nfunction getEmojiSessionMetadata(emojis: Emoji[]): EmojiSessionMetadata {\n const versions = new Map<number, string>();\n\n for (const emoji of emojis) {\n if (!versions.has(emoji.version)) {\n versions.set(emoji.version, emoji.emoji);\n }\n }\n\n const descendingVersions = [...versions.keys()].sort((a, b) => b - a);\n\n const canvasContext = document\n .createElement(\"canvas\")\n .getContext(\"2d\", { willReadFrequently: true });\n\n if (!canvasContext) {\n return { emojiVersion: descendingVersions[0], countryFlags: true };\n }\n\n canvasContext.font = `${Math.floor(\n EMOJI_DETECTION_CANVAS_HEIGHT / 2\n )}px ${getEmojiFontFamily()}`;\n canvasContext.textBaseline = \"top\";\n canvasContext.canvas.width = EMOJI_DETECTION_CANVAS_WIDTH * 2;\n canvasContext.canvas.height = EMOJI_DETECTION_CANVAS_HEIGHT;\n\n const supportsCountryFlags = detectEmojiSupport(\n canvasContext,\n EMOJI_DETECTION_COUNTRY_FLAG\n );\n\n for (const version of descendingVersions) {\n const emoji = versions.get(version)!;\n const isSupported = detectEmojiSupport(canvasContext, emoji);\n\n if (isSupported) {\n return {\n emojiVersion: version,\n countryFlags: supportsCountryFlags,\n };\n }\n }\n\n return {\n emojiVersion: descendingVersions[0],\n countryFlags: supportsCountryFlags,\n };\n}\n\nexport async function getEmojiData(locale: string): Promise<EmojiData> {\n const emojibaseLocale = getEmojibaseSupportedLocale(locale);\n\n const sessionMetadata = getStorageItem<EmojiSessionMetadata>(\n sessionStorage,\n CACHE_EMOJI_SESSION_METADATA_KEY\n );\n const cachedData = getStorageItem<EmojiData>(\n localStorage,\n CACHE_EMOJI_DATA_KEY(emojibaseLocale)\n );\n let data: EmojiData;\n\n // If there is data already cached, check if the ETags are the same.\n // If they are, return the cached data, otherwise fetch it again.\n if (cachedData) {\n // ETags only need to be checked once per session\n if (sessionMetadata) {\n data = cachedData;\n } else {\n const { emojisEtag, messagesEtag } =\n await fetchEmojibaseEtags(emojibaseLocale);\n const cachedMetadata = getStorageItem<EmojiMetadata>(\n localStorage,\n CACHE_EMOJI_METADATA_KEY(emojibaseLocale)\n );\n\n if (\n cachedMetadata &&\n emojisEtag === cachedMetadata.emojisEtag &&\n messagesEtag === cachedMetadata.messagesEtag\n ) {\n data = cachedData;\n } else {\n data = await fetchEmojiData(emojibaseLocale);\n }\n }\n } else {\n data = await fetchEmojiData(emojibaseLocale);\n }\n\n const newSessionMetadata =\n sessionMetadata ?? getEmojiSessionMetadata(data.emojis);\n setStorageItem(\n sessionStorage,\n CACHE_EMOJI_SESSION_METADATA_KEY,\n newSessionMetadata\n );\n\n // Filter out unsupported emojis\n const filteredEmojis = data.emojis.filter((emoji) => {\n const isSupportedVersion = emoji.version <= newSessionMetadata.emojiVersion;\n\n return emoji.countryFlag\n ? isSupportedVersion && newSessionMetadata.countryFlags\n : isSupportedVersion;\n });\n\n return {\n emojis: filteredEmojis,\n categories: data.categories,\n skinTones: data.skinTones,\n };\n}\n\nexport function filterEmojis(emojis: Emoji[], search?: string) {\n if (!search) {\n return emojis;\n }\n\n const searchText = search.toLowerCase().trim();\n\n return emojis.filter(\n (emoji) =>\n emoji.name.toLowerCase().includes(searchText) ||\n emoji.tags?.some((tag) => tag.toLowerCase().includes(searchText))\n );\n}\n\nexport function generateEmojiPickerData(\n emojis: Emoji[],\n categories: EmojiCategory[],\n columns: number\n): EmojiPickerData {\n let currentIndex = 0;\n const rows: EmojiPickerRow[] = [];\n const indexedEmojis = emojis.map((emoji, index) => ({ ...emoji, index }));\n const categoriesRowCounts: number[] = [];\n const categoriesRowIndices: number[][] = [];\n const categoriesNames: string[] = [];\n const categorizedEmojis = categories\n .map((category) => ({\n ...category,\n emojis: indexedEmojis.filter((emoji) => emoji.category === category.key),\n }))\n .filter((category) => category.emojis.length > 0);\n\n for (const category of categorizedEmojis) {\n const categoryRows = chunk(category.emojis, columns);\n const nextIndex = currentIndex + categoryRows.length;\n\n rows.push(...categoryRows);\n categoriesNames.push(category.name);\n categoriesRowCounts.push(categoryRows.length);\n categoriesRowIndices.push(\n generateRangeIndices(currentIndex, nextIndex - 1)\n );\n currentIndex = nextIndex;\n }\n\n return {\n count: emojis.length,\n rows,\n categories: categoriesNames,\n categoriesRowCounts,\n categoriesRowIndices,\n };\n}\n"],"names":["capitalize","EMOJI_FONT_FAMILY","chunk"],"mappings":";;;;;;AAiBA,MAAM,iBAAoB,GAAA,QAAA,CAAA;AAC1B,MAAM,oBAAoB,CAA+C,4CAAA,EAAA,iBAAA,CAAA,CAAA,CAAA;AACzE,MAAM,oBAAuB,GAAA,CAAC,MAC5B,KAAA,CAAA,EAAG,iBAAqB,CAAA,CAAA,EAAA,MAAA,CAAA,UAAA,CAAA,CAAA;AAC1B,MAAM,sBAAyB,GAAA,CAAC,MAC9B,KAAA,CAAA,EAAG,iBAAqB,CAAA,CAAA,EAAA,MAAA,CAAA,cAAA,CAAA,CAAA;AAC1B,MAAM,iBAAuC,GAAA;AAAA,EAC3C,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,SAAA;AACF,CAAA,CAAA;AACA,MAAM,wBAA4C,GAAA,IAAA,CAAA;AAElD,MAAM,oBAAA,GAAuB,CAAC,MAAA,KAAmB,CAAiB,cAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AAClE,MAAM,wBAAA,GAA2B,CAAC,MAAA,KAChC,CAAqB,kBAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AACvB,MAAM,gCAAmC,GAAA,mBAAA,CAAA;AAEzC,MAAM,4BAA+B,GAAA,EAAA,CAAA;AACrC,MAAM,6BAAgC,GAAA,EAAA,CAAA;AACtC,MAAM,4BAA+B,GAAA,oBAAA,CAAA;AAYrC,SAAS,oBAAA,CAAqB,OAAe,GAAa,EAAA;AACxD,EAAA,MAAM,QAAkB,EAAC,CAAA;AAEzB,EAAA,KAAA,IAAS,CAAI,GAAA,KAAA,EAAO,CAAK,IAAA,GAAA,EAAK,CAAK,EAAA,EAAA;AACjC,IAAA,KAAA,CAAM,KAAK,CAAC,CAAA,CAAA;AAAA,GACd;AAEA,EAAO,OAAA,KAAA,CAAA;AACT,CAAA;AAEA,SAAS,cAAA,CAAkB,SAAkB,GAAa,EAAA;AACxD,EAAM,MAAA,IAAA,GAAO,OAAQ,CAAA,OAAA,CAAQ,GAAG,CAAA,CAAA;AAEhC,EAAA,OAAO,IAAQ,GAAA,IAAA,CAAK,KAAM,CAAA,IAAI,CAAU,GAAA,IAAA,CAAA;AAC1C,CAAA;AAEA,SAAS,cAAA,CAAkB,OAAkB,EAAA,GAAA,EAAa,KAAU,EAAA;AAClE,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,EAAK,IAAK,CAAA,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA;AAC5C,CAAA;AAEA,eAAe,UAAU,GAAa,EAAA;AACpC,EAAI,IAAA;AACF,IAAA,MAAM,WAAW,MAAM,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,QAAQ,CAAA,CAAA;AAEpD,IAAO,OAAA,QAAA,CAAS,OAAQ,CAAA,GAAA,CAAI,MAAM,CAAA,CAAA;AAAA,WAC3B,KAAP,EAAA;AACA,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AACF,CAAA;AAEA,SAAS,4BAA4B,MAAiC,EAAA;AACpE,EAAA,OAAO,iBAAkB,CAAA,QAAA,CAAS,MAAyB,CAAA,GACtD,MACD,GAAA,wBAAA,CAAA;AACN,CAAA;AAEA,eAAe,mBAAmB,MAAyB,EAAA;AACzD,EAAA,MAAM,CAAC,EAAE,MAAQ,EAAA,UAAA,EAAc,EAAA,EAAE,QAAU,EAAA,YAAA,EAAc,CAAA,GACvD,MAAM,OAAA,CAAQ,GAAI,CAAA;AAAA,IAChB,MAAM,oBAAqB,CAAA,MAAM,CAAC,CAAE,CAAA,IAAA,CAAK,OAAO,QAAa,KAAA;AAC3D,MAAO,OAAA;AAAA,QACL,MAAA,EAAS,MAAM,QAAA,CAAS,IAAK,EAAA;AAAA,QAC7B,UAAY,EAAA,QAAA,CAAS,OAAQ,CAAA,GAAA,CAAI,MAAM,CAAA;AAAA,OACzC,CAAA;AAAA,KACD,CAAA;AAAA,IACD,MAAM,sBAAuB,CAAA,MAAM,CAAC,CAAE,CAAA,IAAA,CAAK,OAAO,QAAa,KAAA;AAC7D,MAAO,OAAA;AAAA,QACL,QAAA,EAAW,MAAM,QAAA,CAAS,IAAK,EAAA;AAAA,QAC/B,YAAc,EAAA,QAAA,CAAS,OAAQ,CAAA,GAAA,CAAI,MAAM,CAAA;AAAA,OAC3C,CAAA;AAAA,KACD,CAAA;AAAA,GACF,CAAA,CAAA;AAEH,EAAO,OAAA;AAAA,IACL,MAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,GACF,CAAA;AACF,CAAA;AAEA,eAAe,oBAAoB,MAAyB,EAAA;AAC1D,EAAA,MAAM,CAAC,UAAY,EAAA,YAAY,CAAI,GAAA,MAAM,QAAQ,GAAI,CAAA;AAAA,IACnD,SAAA,CAAU,oBAAqB,CAAA,MAAM,CAAC,CAAA;AAAA,IACtC,SAAA,CAAU,sBAAuB,CAAA,MAAM,CAAC,CAAA;AAAA,GACzC,CAAA,CAAA;AAED,EAAO,OAAA;AAAA,IACL,UAAA;AAAA,IACA,YAAA;AAAA,GACF,CAAA;AACF,CAAA;AAEA,eAAe,eAAe,MAA6C,EAAA;AACzE,EAAM,MAAA,EAAE,QAAQ,UAAY,EAAA,QAAA,EAAU,cACpC,GAAA,MAAM,mBAAmB,MAAM,CAAA,CAAA;AACjC,EAAM,MAAA,oBAAA,GAAuB,SAAS,SAAU,CAAA,IAAA;AAAA,IAC9C,CAAC,QAAa,KAAA,QAAA,CAAS,GAAQ,KAAA,kBAAA;AAAA,GACjC,CAAA;AAGA,EAAM,MAAA,cAAA,GAAiB,SAAS,MAAO,CAAA,MAAA;AAAA,IACrC,CAAC,KAAU,KAAA,KAAA,CAAM,GAAQ,KAAA,WAAA;AAAA,GAC3B,CAAA;AACA,EAAA,MAAM,cAAiB,GAAA,MAAA,CAAO,MAAO,CAAA,CAAC,KAAU,KAAA;AAC9C,IAAA,OAAO,OAAW,IAAA,KAAA,CAAA;AAAA,GACnB,CAAA,CAAA;AAGD,EAAA,MAAM,UAAa,GAAA,cAAA,CAAe,GAAI,CAAA,CAAC,KAAW,MAAA;AAAA,IAChD,KAAK,KAAM,CAAA,KAAA;AAAA,IACX,IAAA,EAAMA,qBAAW,CAAA,KAAA,CAAM,OAAO,CAAA;AAAA,GAC9B,CAAA,CAAA,CAAA;AACF,EAAA,MAAM,SAAY,GAAA,QAAA,CAAS,SAAU,CAAA,GAAA,CAAI,CAAC,QAAc,MAAA;AAAA,IACtD,KAAK,QAAS,CAAA,GAAA;AAAA,IACd,IAAA,EAAMA,qBAAW,CAAA,QAAA,CAAS,OAAO,CAAA;AAAA,GACjC,CAAA,CAAA,CAAA;AACF,EAAA,MAAM,aAAgB,GAAA,cAAA,CAAe,GAAI,CAAA,CAAC,KAAU,KAAA;AAClD,IAAA,MAAM,YAAsB,GAAA;AAAA,MAC1B,OAAO,KAAM,CAAA,KAAA;AAAA,MACb,UAAU,KAAM,CAAA,KAAA;AAAA,MAChB,SAAS,KAAM,CAAA,OAAA;AAAA,MACf,IAAA,EAAMA,qBAAW,CAAA,KAAA,CAAM,KAAK,CAAA;AAAA,MAC5B,MAAM,KAAM,CAAA,IAAA;AAAA,KACd,CAAA;AAEA,IAAA,IAAI,oBAAwB,IAAA,KAAA,CAAM,QAAa,KAAA,oBAAA,CAAqB,KAAO,EAAA;AACzE,MAAA,YAAA,CAAa,WAAc,GAAA,IAAA,CAAA;AAAA,KAC7B;AAEA,IAAO,OAAA,YAAA,CAAA;AAAA,GACR,CAAA,CAAA;AAED,EAAA,MAAM,SAAY,GAAA;AAAA,IAChB,MAAQ,EAAA,aAAA;AAAA,IACR,UAAA;AAAA,IACA,SAAA;AAAA,GACF,CAAA;AAGA,EAAA,cAAA;AAAA,IACE,YAAA;AAAA,IACA,qBAAqB,MAAM,CAAA;AAAA,IAC3B,SAAA;AAAA,GACF,CAAA;AACA,EAAA,cAAA;AAAA,IACE,YAAA;AAAA,IACA,yBAAyB,MAAM,CAAA;AAAA,IAC/B;AAAA,MACE,UAAA;AAAA,MACA,YAAA;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAO,OAAA,SAAA,CAAA;AACT,CAAA;AAGA,SAAS,kBAAA,CACP,eACA,KACS,EAAA;AACT,EAAc,aAAA,CAAA,SAAA;AAAA,IACZ,CAAA;AAAA,IACA,CAAA;AAAA,IACA,4BAA+B,GAAA,CAAA;AAAA,IAC/B,6BAAA;AAAA,GACF,CAAA;AAGA,EAAA,aAAA,CAAc,SAAY,GAAA,MAAA,CAAA;AAC1B,EAAc,aAAA,CAAA,QAAA,CAAS,KAAO,EAAA,CAAA,EAAG,EAAE,CAAA,CAAA;AAGnC,EAAA,aAAA,CAAc,SAAY,GAAA,MAAA,CAAA;AAC1B,EAAc,aAAA,CAAA,QAAA,CAAS,KAAO,EAAA,4BAAA,EAA8B,EAAE,CAAA,CAAA;AAE9D,EAAA,MAAM,SAAS,aAAc,CAAA,YAAA;AAAA,IAC3B,CAAA;AAAA,IACA,CAAA;AAAA,IACA,4BAAA;AAAA,IACA,6BAAA;AAAA,GACA,CAAA,IAAA,CAAA;AACF,EAAA,MAAM,aAAa,MAAO,CAAA,MAAA,CAAA;AAC1B,EAAA,IAAI,CAAI,GAAA,CAAA,CAAA;AAGR,EAAA,OAAO,IAAI,UAAc,IAAA,CAAC,MAAO,CAAA,CAAA,GAAI,IAAI,CAAK,IAAA,CAAA;AAAE,IAAA,CAAA;AAGhD,EAAA,IAAI,KAAK,UAAY,EAAA;AACnB,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAIA,EAAM,MAAA,CAAA,GACJ,4BAAiC,GAAA,CAAA,GAAI,CAAK,GAAA,4BAAA,CAAA;AAC5C,EAAA,MAAM,CAAI,GAAA,IAAA,CAAK,KAAM,CAAA,CAAA,GAAI,IAAI,4BAA4B,CAAA,CAAA;AACzD,EAAA,MAAM,QAAQ,aAAc,CAAA,YAAA,CAAa,GAAG,CAAG,EAAA,CAAA,EAAG,CAAC,CAAE,CAAA,IAAA,CAAA;AAErD,EAAI,IAAA,MAAA,CAAO,OAAO,KAAM,CAAA,CAAA,CAAA,IAAM,OAAO,CAAI,GAAA,CAAA,CAAA,KAAO,MAAM,CAAI,CAAA,EAAA;AACxD,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAGA,EAAA,IAAI,aAAc,CAAA,WAAA,CAAY,KAAK,CAAA,CAAE,SAAS,4BAA8B,EAAA;AAC1E,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAO,OAAA,IAAA,CAAA;AACT,CAAA;AAEA,SAAS,kBAAqB,GAAA;AAC5B,EAAI,IAAA;AACF,IAAM,MAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AAC7C,IAAA,OAAA,CAAQ,MAAM,OAAU,GAAA,MAAA,CAAA;AACxB,IAAA,OAAA,CAAQ,QAAQ,KAAQ,GAAA,EAAA,CAAA;AAExB,IAAS,QAAA,CAAA,IAAA,CAAK,YAAY,OAAO,CAAA,CAAA;AAEjC,IAAA,MAAM,kBAAqB,GAAA,MAAA,CAAO,gBAAiB,CAAA,OAAO,CAAE,CAAA,UAAA,CAAA;AAE5D,IAAS,QAAA,CAAA,IAAA,CAAK,YAAY,OAAO,CAAA,CAAA;AAEjC,IAAO,OAAA,kBAAA,CAAA;AAAA,GACP,CAAA,MAAA;AACA,IAAO,OAAAC,2BAAA,CAAA;AAAA,GACT;AACF,CAAA;AAEA,SAAS,wBAAwB,MAAuC,EAAA;AACtE,EAAM,MAAA,QAAA,uBAAe,GAAoB,EAAA,CAAA;AAEzC,EAAA,KAAA,MAAW,SAAS,MAAQ,EAAA;AAC1B,IAAA,IAAI,CAAC,QAAA,CAAS,GAAI,CAAA,KAAA,CAAM,OAAO,CAAG,EAAA;AAChC,MAAA,QAAA,CAAS,GAAI,CAAA,KAAA,CAAM,OAAS,EAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AAAA,KACzC;AAAA,GACF;AAEA,EAAA,MAAM,kBAAqB,GAAA,CAAC,GAAG,QAAA,CAAS,IAAK,EAAC,CAAE,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAM,KAAA,CAAA,GAAI,CAAC,CAAA,CAAA;AAEpE,EAAM,MAAA,aAAA,GAAgB,QACnB,CAAA,aAAA,CAAc,QAAQ,CAAA,CACtB,WAAW,IAAM,EAAA,EAAE,kBAAoB,EAAA,IAAA,EAAM,CAAA,CAAA;AAEhD,EAAA,IAAI,CAAC,aAAe,EAAA;AAClB,IAAA,OAAO,EAAE,YAAA,EAAc,kBAAmB,CAAA,CAAA,CAAA,EAAI,cAAc,IAAK,EAAA,CAAA;AAAA,GACnE;AAEA,EAAc,aAAA,CAAA,IAAA,GAAO,GAAG,IAAK,CAAA,KAAA;AAAA,IAC3B,6BAAgC,GAAA,CAAA;AAAA,SAC3B,kBAAmB,EAAA,CAAA,CAAA,CAAA;AAC1B,EAAA,aAAA,CAAc,YAAe,GAAA,KAAA,CAAA;AAC7B,EAAc,aAAA,CAAA,MAAA,CAAO,QAAQ,4BAA+B,GAAA,CAAA,CAAA;AAC5D,EAAA,aAAA,CAAc,OAAO,MAAS,GAAA,6BAAA,CAAA;AAE9B,EAAA,MAAM,oBAAuB,GAAA,kBAAA;AAAA,IAC3B,aAAA;AAAA,IACA,4BAAA;AAAA,GACF,CAAA;AAEA,EAAA,KAAA,MAAW,WAAW,kBAAoB,EAAA;AACxC,IAAM,MAAA,KAAA,GAAQ,QAAS,CAAA,GAAA,CAAI,OAAO,CAAA,CAAA;AAClC,IAAM,MAAA,WAAA,GAAc,kBAAmB,CAAA,aAAA,EAAe,KAAK,CAAA,CAAA;AAE3D,IAAA,IAAI,WAAa,EAAA;AACf,MAAO,OAAA;AAAA,QACL,YAAc,EAAA,OAAA;AAAA,QACd,YAAc,EAAA,oBAAA;AAAA,OAChB,CAAA;AAAA,KACF;AAAA,GACF;AAEA,EAAO,OAAA;AAAA,IACL,cAAc,kBAAmB,CAAA,CAAA,CAAA;AAAA,IACjC,YAAc,EAAA,oBAAA;AAAA,GAChB,CAAA;AACF,CAAA;AAEA,eAAsB,aAAa,MAAoC,EAAA;AACrE,EAAM,MAAA,eAAA,GAAkB,4BAA4B,MAAM,CAAA,CAAA;AAE1D,EAAA,MAAM,eAAkB,GAAA,cAAA;AAAA,IACtB,cAAA;AAAA,IACA,gCAAA;AAAA,GACF,CAAA;AACA,EAAA,MAAM,UAAa,GAAA,cAAA;AAAA,IACjB,YAAA;AAAA,IACA,qBAAqB,eAAe,CAAA;AAAA,GACtC,CAAA;AACA,EAAI,IAAA,IAAA,CAAA;AAIJ,EAAA,IAAI,UAAY,EAAA;AAEd,IAAA,IAAI,eAAiB,EAAA;AACnB,MAAO,IAAA,GAAA,UAAA,CAAA;AAAA,KACF,MAAA;AACL,MAAA,MAAM,EAAE,UAAY,EAAA,YAAA,EAClB,GAAA,MAAM,oBAAoB,eAAe,CAAA,CAAA;AAC3C,MAAA,MAAM,cAAiB,GAAA,cAAA;AAAA,QACrB,YAAA;AAAA,QACA,yBAAyB,eAAe,CAAA;AAAA,OAC1C,CAAA;AAEA,MAAA,IACE,kBACA,UAAe,KAAA,cAAA,CAAe,UAC9B,IAAA,YAAA,KAAiB,eAAe,YAChC,EAAA;AACA,QAAO,IAAA,GAAA,UAAA,CAAA;AAAA,OACF,MAAA;AACL,QAAO,IAAA,GAAA,MAAM,eAAe,eAAe,CAAA,CAAA;AAAA,OAC7C;AAAA,KACF;AAAA,GACK,MAAA;AACL,IAAO,IAAA,GAAA,MAAM,eAAe,eAAe,CAAA,CAAA;AAAA,GAC7C;AAEA,EAAA,MAAM,kBACJ,GAAA,eAAA,IAAmB,uBAAwB,CAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AACxD,EAAA,cAAA;AAAA,IACE,cAAA;AAAA,IACA,gCAAA;AAAA,IACA,kBAAA;AAAA,GACF,CAAA;AAGA,EAAA,MAAM,cAAiB,GAAA,IAAA,CAAK,MAAO,CAAA,MAAA,CAAO,CAAC,KAAU,KAAA;AACnD,IAAM,MAAA,kBAAA,GAAqB,KAAM,CAAA,OAAA,IAAW,kBAAmB,CAAA,YAAA,CAAA;AAE/D,IAAA,OAAO,KAAM,CAAA,WAAA,GACT,kBAAsB,IAAA,kBAAA,CAAmB,YACzC,GAAA,kBAAA,CAAA;AAAA,GACL,CAAA,CAAA;AAED,EAAO,OAAA;AAAA,IACL,MAAQ,EAAA,cAAA;AAAA,IACR,YAAY,IAAK,CAAA,UAAA;AAAA,IACjB,WAAW,IAAK,CAAA,SAAA;AAAA,GAClB,CAAA;AACF,CAAA;AAEgB,SAAA,YAAA,CAAa,QAAiB,MAAiB,EAAA;AAC7D,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAO,OAAA,MAAA,CAAA;AAAA,GACT;AAEA,EAAA,MAAM,UAAa,GAAA,MAAA,CAAO,WAAY,EAAA,CAAE,IAAK,EAAA,CAAA;AAE7C,EAAA,OAAO,MAAO,CAAA,MAAA;AAAA,IACZ,CAAC,KACC,KAAA,KAAA,CAAM,KAAK,WAAY,EAAA,CAAE,SAAS,UAAU,CAAA,IAC5C,MAAM,IAAM,EAAA,IAAA,CAAK,CAAC,GAAQ,KAAA,GAAA,CAAI,aAAc,CAAA,QAAA,CAAS,UAAU,CAAC,CAAA;AAAA,GACpE,CAAA;AACF,CAAA;AAEgB,SAAA,uBAAA,CACd,MACA,EAAA,UAAA,EACA,OACiB,EAAA;AACjB,EAAA,IAAI,YAAe,GAAA,CAAA,CAAA;AACnB,EAAA,MAAM,OAAyB,EAAC,CAAA;AAChC,EAAM,MAAA,aAAA,GAAgB,MAAO,CAAA,GAAA,CAAI,CAAC,KAAA,EAAO,WAAW,EAAE,GAAG,KAAO,EAAA,KAAA,EAAQ,CAAA,CAAA,CAAA;AACxE,EAAA,MAAM,sBAAgC,EAAC,CAAA;AACvC,EAAA,MAAM,uBAAmC,EAAC,CAAA;AAC1C,EAAA,MAAM,kBAA4B,EAAC,CAAA;AACnC,EAAA,MAAM,iBAAoB,GAAA,UAAA,CACvB,GAAI,CAAA,CAAC,QAAc,MAAA;AAAA,IAClB,GAAG,QAAA;AAAA,IACH,MAAA,EAAQ,cAAc,MAAO,CAAA,CAAC,UAAU,KAAM,CAAA,QAAA,KAAa,SAAS,GAAG,CAAA;AAAA,GACzE,CAAE,EACD,MAAO,CAAA,CAAC,aAAa,QAAS,CAAA,MAAA,CAAO,SAAS,CAAC,CAAA,CAAA;AAElD,EAAA,KAAA,MAAW,YAAY,iBAAmB,EAAA;AACxC,IAAA,MAAM,YAAe,GAAAC,WAAA,CAAM,QAAS,CAAA,MAAA,EAAQ,OAAO,CAAA,CAAA;AACnD,IAAM,MAAA,SAAA,GAAY,eAAe,YAAa,CAAA,MAAA,CAAA;AAE9C,IAAK,IAAA,CAAA,IAAA,CAAK,GAAG,YAAY,CAAA,CAAA;AACzB,IAAgB,eAAA,CAAA,IAAA,CAAK,SAAS,IAAI,CAAA,CAAA;AAClC,IAAoB,mBAAA,CAAA,IAAA,CAAK,aAAa,MAAM,CAAA,CAAA;AAC5C,IAAqB,oBAAA,CAAA,IAAA;AAAA,MACnB,oBAAA,CAAqB,YAAc,EAAA,SAAA,GAAY,CAAC,CAAA;AAAA,KAClD,CAAA;AACA,IAAe,YAAA,GAAA,SAAA,CAAA;AAAA,GACjB;AAEA,EAAO,OAAA;AAAA,IACL,OAAO,MAAO,CAAA,MAAA;AAAA,IACd,IAAA;AAAA,IACA,UAAY,EAAA,eAAA;AAAA,IACZ,mBAAA;AAAA,IACA,oBAAA;AAAA,GACF,CAAA;AACF;;;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/primitives/EmojiPicker/utils.ts"],"sourcesContent":["import { chunk } from \"@liveblocks/core\";\nimport type {\n Emoji as EmojibaseEmoji,\n Locale as EmojibaseLocale,\n MessagesDataset as EmojibaseMessagesDataset,\n} from \"emojibase\";\n\nimport { EMOJI_FONT_FAMILY } from \"../../constants\";\nimport { capitalize } from \"../../utils/capitalize\";\nimport type {\n Emoji,\n EmojiCategory,\n EmojiData,\n EmojiPickerData,\n EmojiPickerRow,\n} from \"./types\";\n\nconst EMOJIBASE_VERSION = \"15.3.0\";\nconst EMOJIBASE_CDN_URL = `https://cdn.jsdelivr.net/npm/emojibase-data@${EMOJIBASE_VERSION}`;\nconst EMOJIBASE_EMOJIS_URL = (locale: EmojibaseLocale) =>\n `${EMOJIBASE_CDN_URL}/${locale}/data.json`;\nconst EMOJIBASE_MESSAGES_URL = (locale: EmojibaseLocale) =>\n `${EMOJIBASE_CDN_URL}/${locale}/messages.json`;\nconst EMOJIBASE_LOCALES: EmojibaseLocale[] = [\n \"bn\",\n \"da\",\n \"de\",\n \"en\",\n \"en-gb\",\n \"es\",\n \"es-mx\",\n \"et\",\n \"fi\",\n \"fr\",\n \"hi\",\n \"hu\",\n \"it\",\n \"ja\",\n \"ko\",\n \"lt\",\n \"ms\",\n \"nb\",\n \"nl\",\n \"pl\",\n \"pt\",\n \"ru\",\n \"sv\",\n \"th\",\n \"uk\",\n \"zh\",\n \"zh-hant\",\n];\nconst EMOJIBASE_DEFAULT_LOCALE: EmojibaseLocale = \"en\";\n\nconst CACHE_EMOJI_DATA_KEY = (locale: string) => `lb-emoji-data-${locale}`;\nconst CACHE_EMOJI_METADATA_KEY = (locale: string) =>\n `lb-emoji-metadata-${locale}`;\nconst CACHE_EMOJI_SESSION_METADATA_KEY = \"lb-emoji-metadata\";\n\nconst EMOJI_DETECTION_CANVAS_WIDTH = 20;\nconst EMOJI_DETECTION_CANVAS_HEIGHT = 25;\nconst EMOJI_DETECTION_COUNTRY_FLAG = \"🇫🇷\";\n\ntype EmojiMetadata = {\n emojisEtag: string | null;\n messagesEtag: string | null;\n};\n\ntype EmojiSessionMetadata = {\n emojiVersion: number;\n countryFlags: boolean;\n};\n\nfunction generateRangeIndices(start: number, end: number) {\n const range: number[] = [];\n\n for (let i = start; i <= end; i++) {\n range.push(i);\n }\n\n return range;\n}\n\nfunction getStorageItem<T>(storage: Storage, key: string) {\n const item = storage.getItem(key);\n\n return item ? (JSON.parse(item) as T) : null;\n}\n\nfunction setStorageItem<T>(storage: Storage, key: string, value: T) {\n storage.setItem(key, JSON.stringify(value));\n}\n\nasync function fetchEtag(url: string) {\n try {\n const response = await fetch(url, { method: \"HEAD\" });\n\n return response.headers.get(\"etag\");\n } catch (error) {\n return null;\n }\n}\n\nfunction getEmojibaseSupportedLocale(locale: string): EmojibaseLocale {\n return EMOJIBASE_LOCALES.includes(locale as EmojibaseLocale)\n ? (locale as EmojibaseLocale)\n : EMOJIBASE_DEFAULT_LOCALE;\n}\n\nasync function fetchEmojibaseData(locale: EmojibaseLocale) {\n const [{ emojis, emojisEtag }, { messages, messagesEtag }] =\n await Promise.all([\n fetch(EMOJIBASE_EMOJIS_URL(locale)).then(async (response) => {\n return {\n emojis: (await response.json()) as EmojibaseEmoji[],\n emojisEtag: response.headers.get(\"etag\"),\n };\n }),\n fetch(EMOJIBASE_MESSAGES_URL(locale)).then(async (response) => {\n return {\n messages: (await response.json()) as EmojibaseMessagesDataset,\n messagesEtag: response.headers.get(\"etag\"),\n };\n }),\n ]);\n\n return {\n emojis,\n messages,\n emojisEtag,\n messagesEtag,\n };\n}\n\nasync function fetchEmojibaseEtags(locale: EmojibaseLocale) {\n const [emojisEtag, messagesEtag] = await Promise.all([\n fetchEtag(EMOJIBASE_EMOJIS_URL(locale)),\n fetchEtag(EMOJIBASE_MESSAGES_URL(locale)),\n ]);\n\n return {\n emojisEtag,\n messagesEtag,\n };\n}\n\nasync function fetchEmojiData(locale: EmojibaseLocale): Promise<EmojiData> {\n const { emojis, emojisEtag, messages, messagesEtag } =\n await fetchEmojibaseData(locale);\n const countryFlagsSubgroup = messages.subgroups.find(\n (subgroup) => subgroup.key === \"subdivision-flag\"\n );\n\n // Filter out component/modifier category and emojis\n const filteredGroups = messages.groups.filter(\n (group) => group.key !== \"component\"\n );\n const filteredEmojis = emojis.filter((emoji) => {\n return \"group\" in emoji;\n });\n\n // Pick and compact the data\n const categories = filteredGroups.map((group) => ({\n key: group.order,\n name: capitalize(group.message),\n }));\n const skinTones = messages.skinTones.map((skinTone) => ({\n key: skinTone.key,\n name: capitalize(skinTone.message),\n }));\n const compactEmojis = filteredEmojis.map((emoji) => {\n const compactEmoji: Emoji = {\n emoji: emoji.emoji,\n category: emoji.group!,\n version: emoji.version,\n name: capitalize(emoji.label),\n tags: emoji.tags,\n };\n\n if (countryFlagsSubgroup && emoji.subgroup === countryFlagsSubgroup.order) {\n compactEmoji.countryFlag = true;\n }\n\n return compactEmoji;\n });\n\n const emojiData = {\n emojis: compactEmojis,\n categories,\n skinTones,\n };\n\n // Cache the data and metadata\n setStorageItem<EmojiData>(\n localStorage,\n CACHE_EMOJI_DATA_KEY(locale),\n emojiData\n );\n setStorageItem<EmojiMetadata>(\n localStorage,\n CACHE_EMOJI_METADATA_KEY(locale),\n {\n emojisEtag,\n messagesEtag,\n }\n );\n\n return emojiData;\n}\n\n// Adapted from https://github.com/koala-interactive/is-emoji-supported/tree/master\nfunction detectEmojiSupport(\n canvasContext: CanvasRenderingContext2D,\n emoji: string\n): boolean {\n canvasContext.clearRect(\n 0,\n 0,\n EMOJI_DETECTION_CANVAS_WIDTH * 2,\n EMOJI_DETECTION_CANVAS_HEIGHT\n );\n\n // Draw in red on the left\n canvasContext.fillStyle = \"#f00\";\n canvasContext.fillText(emoji, 0, 22);\n\n // Draw in blue on right\n canvasContext.fillStyle = \"#00f\";\n canvasContext.fillText(emoji, EMOJI_DETECTION_CANVAS_WIDTH, 22);\n\n const pixels = canvasContext.getImageData(\n 0,\n 0,\n EMOJI_DETECTION_CANVAS_WIDTH,\n EMOJI_DETECTION_CANVAS_HEIGHT\n ).data;\n const pixelCount = pixels.length;\n let i = 0;\n\n // Search for the first visible pixel\n for (; i < pixelCount && !pixels[i + 3]; i += 4);\n\n // No visible pixel\n if (i >= pixelCount) {\n return false;\n }\n\n // Emojis have an immutable color, so we check the color of the emoji in two\n // different colors, the result should be the same\n const x =\n EMOJI_DETECTION_CANVAS_WIDTH + ((i / 4) % EMOJI_DETECTION_CANVAS_WIDTH);\n const y = Math.floor(i / 4 / EMOJI_DETECTION_CANVAS_WIDTH);\n const pixel = canvasContext.getImageData(x, y, 1, 1).data;\n\n if (pixels[i] !== pixel[0] || pixels[i + 2] !== pixel[2]) {\n return false;\n }\n\n // Unsupported ZWJ sequence emojis show up as separate emojis\n if (canvasContext.measureText(emoji).width >= EMOJI_DETECTION_CANVAS_WIDTH) {\n return false;\n }\n\n return true;\n}\n\nfunction getEmojiFontFamily() {\n try {\n const element = document.createElement(\"span\");\n element.style.display = \"none\";\n element.dataset.emoji = \"\";\n\n document.body.appendChild(element);\n\n const computedFontFamily = window.getComputedStyle(element).fontFamily;\n\n document.body.removeChild(element);\n\n return computedFontFamily;\n } catch {\n return EMOJI_FONT_FAMILY;\n }\n}\n\nfunction getEmojiSessionMetadata(emojis: Emoji[]): EmojiSessionMetadata {\n const versions = new Map<number, string>();\n\n for (const emoji of emojis) {\n if (!versions.has(emoji.version)) {\n versions.set(emoji.version, emoji.emoji);\n }\n }\n\n const descendingVersions = [...versions.keys()].sort((a, b) => b - a);\n\n const canvasContext = document\n .createElement(\"canvas\")\n .getContext(\"2d\", { willReadFrequently: true });\n\n if (!canvasContext) {\n return { emojiVersion: descendingVersions[0], countryFlags: true };\n }\n\n canvasContext.font = `${Math.floor(\n EMOJI_DETECTION_CANVAS_HEIGHT / 2\n )}px ${getEmojiFontFamily()}`;\n canvasContext.textBaseline = \"top\";\n canvasContext.canvas.width = EMOJI_DETECTION_CANVAS_WIDTH * 2;\n canvasContext.canvas.height = EMOJI_DETECTION_CANVAS_HEIGHT;\n\n const supportsCountryFlags = detectEmojiSupport(\n canvasContext,\n EMOJI_DETECTION_COUNTRY_FLAG\n );\n\n for (const version of descendingVersions) {\n const emoji = versions.get(version)!;\n const isSupported = detectEmojiSupport(canvasContext, emoji);\n\n if (isSupported) {\n return {\n emojiVersion: version,\n countryFlags: supportsCountryFlags,\n };\n }\n }\n\n return {\n emojiVersion: descendingVersions[0],\n countryFlags: supportsCountryFlags,\n };\n}\n\nexport async function getEmojiData(locale: string): Promise<EmojiData> {\n const emojibaseLocale = getEmojibaseSupportedLocale(locale);\n\n const sessionMetadata = getStorageItem<EmojiSessionMetadata>(\n sessionStorage,\n CACHE_EMOJI_SESSION_METADATA_KEY\n );\n const cachedData = getStorageItem<EmojiData>(\n localStorage,\n CACHE_EMOJI_DATA_KEY(emojibaseLocale)\n );\n let data: EmojiData;\n\n // If there is data already cached, check if the ETags are the same.\n // If they are, return the cached data, otherwise fetch it again.\n if (cachedData) {\n // ETags only need to be checked once per session\n if (sessionMetadata) {\n data = cachedData;\n } else {\n const { emojisEtag, messagesEtag } =\n await fetchEmojibaseEtags(emojibaseLocale);\n const cachedMetadata = getStorageItem<EmojiMetadata>(\n localStorage,\n CACHE_EMOJI_METADATA_KEY(emojibaseLocale)\n );\n\n if (\n cachedMetadata &&\n emojisEtag === cachedMetadata.emojisEtag &&\n messagesEtag === cachedMetadata.messagesEtag\n ) {\n data = cachedData;\n } else {\n data = await fetchEmojiData(emojibaseLocale);\n }\n }\n } else {\n data = await fetchEmojiData(emojibaseLocale);\n }\n\n const newSessionMetadata =\n sessionMetadata ?? getEmojiSessionMetadata(data.emojis);\n setStorageItem(\n sessionStorage,\n CACHE_EMOJI_SESSION_METADATA_KEY,\n newSessionMetadata\n );\n\n // Filter out unsupported emojis\n const filteredEmojis = data.emojis.filter((emoji) => {\n const isSupportedVersion = emoji.version <= newSessionMetadata.emojiVersion;\n\n return emoji.countryFlag\n ? isSupportedVersion && newSessionMetadata.countryFlags\n : isSupportedVersion;\n });\n\n return {\n emojis: filteredEmojis,\n categories: data.categories,\n skinTones: data.skinTones,\n };\n}\n\nexport function filterEmojis(emojis: Emoji[], search?: string) {\n if (!search) {\n return emojis;\n }\n\n const searchText = search.toLowerCase().trim();\n\n return emojis.filter(\n (emoji) =>\n emoji.name.toLowerCase().includes(searchText) ||\n emoji.tags?.some((tag) => tag.toLowerCase().includes(searchText))\n );\n}\n\nexport function generateEmojiPickerData(\n emojis: Emoji[],\n categories: EmojiCategory[],\n columns: number\n): EmojiPickerData {\n let currentIndex = 0;\n const rows: EmojiPickerRow[] = [];\n const indexedEmojis = emojis.map((emoji, index) => ({ ...emoji, index }));\n const categoriesRowCounts: number[] = [];\n const categoriesRowIndices: number[][] = [];\n const categoriesNames: string[] = [];\n const categorizedEmojis = categories\n .map((category) => ({\n ...category,\n emojis: indexedEmojis.filter((emoji) => emoji.category === category.key),\n }))\n .filter((category) => category.emojis.length > 0);\n\n for (const category of categorizedEmojis) {\n const categoryRows = chunk(category.emojis, columns);\n const nextIndex = currentIndex + categoryRows.length;\n\n rows.push(...categoryRows);\n categoriesNames.push(category.name);\n categoriesRowCounts.push(categoryRows.length);\n categoriesRowIndices.push(\n generateRangeIndices(currentIndex, nextIndex - 1)\n );\n currentIndex = nextIndex;\n }\n\n return {\n count: emojis.length,\n rows,\n categories: categoriesNames,\n categoriesRowCounts,\n categoriesRowIndices,\n };\n}\n"],"names":["capitalize","EMOJI_FONT_FAMILY","chunk"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
+ import { chunk } from '@liveblocks/core';
1
2
  import { EMOJI_FONT_FAMILY } from '../../constants.mjs';
2
3
  import { capitalize } from '../../utils/capitalize.mjs';
3
- import { chunk } from '../../utils/chunk.mjs';
4
4
 
5
5
  const EMOJIBASE_VERSION = "15.3.0";
6
6
  const EMOJIBASE_CDN_URL = `https://cdn.jsdelivr.net/npm/emojibase-data@${EMOJIBASE_VERSION}`;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","sources":["../../../src/primitives/EmojiPicker/utils.ts"],"sourcesContent":["import type {\n Emoji as EmojibaseEmoji,\n Locale as EmojibaseLocale,\n MessagesDataset as EmojibaseMessagesDataset,\n} from \"emojibase\";\n\nimport { EMOJI_FONT_FAMILY } from \"../../constants\";\nimport { capitalize } from \"../../utils/capitalize\";\nimport { chunk } from \"../../utils/chunk\";\nimport type {\n Emoji,\n EmojiCategory,\n EmojiData,\n EmojiPickerData,\n EmojiPickerRow,\n} from \"./types\";\n\nconst EMOJIBASE_VERSION = \"15.3.0\";\nconst EMOJIBASE_CDN_URL = `https://cdn.jsdelivr.net/npm/emojibase-data@${EMOJIBASE_VERSION}`;\nconst EMOJIBASE_EMOJIS_URL = (locale: EmojibaseLocale) =>\n `${EMOJIBASE_CDN_URL}/${locale}/data.json`;\nconst EMOJIBASE_MESSAGES_URL = (locale: EmojibaseLocale) =>\n `${EMOJIBASE_CDN_URL}/${locale}/messages.json`;\nconst EMOJIBASE_LOCALES: EmojibaseLocale[] = [\n \"bn\",\n \"da\",\n \"de\",\n \"en\",\n \"en-gb\",\n \"es\",\n \"es-mx\",\n \"et\",\n \"fi\",\n \"fr\",\n \"hi\",\n \"hu\",\n \"it\",\n \"ja\",\n \"ko\",\n \"lt\",\n \"ms\",\n \"nb\",\n \"nl\",\n \"pl\",\n \"pt\",\n \"ru\",\n \"sv\",\n \"th\",\n \"uk\",\n \"zh\",\n \"zh-hant\",\n];\nconst EMOJIBASE_DEFAULT_LOCALE: EmojibaseLocale = \"en\";\n\nconst CACHE_EMOJI_DATA_KEY = (locale: string) => `lb-emoji-data-${locale}`;\nconst CACHE_EMOJI_METADATA_KEY = (locale: string) =>\n `lb-emoji-metadata-${locale}`;\nconst CACHE_EMOJI_SESSION_METADATA_KEY = \"lb-emoji-metadata\";\n\nconst EMOJI_DETECTION_CANVAS_WIDTH = 20;\nconst EMOJI_DETECTION_CANVAS_HEIGHT = 25;\nconst EMOJI_DETECTION_COUNTRY_FLAG = \"🇫🇷\";\n\ntype EmojiMetadata = {\n emojisEtag: string | null;\n messagesEtag: string | null;\n};\n\ntype EmojiSessionMetadata = {\n emojiVersion: number;\n countryFlags: boolean;\n};\n\nfunction generateRangeIndices(start: number, end: number) {\n const range: number[] = [];\n\n for (let i = start; i <= end; i++) {\n range.push(i);\n }\n\n return range;\n}\n\nfunction getStorageItem<T>(storage: Storage, key: string) {\n const item = storage.getItem(key);\n\n return item ? (JSON.parse(item) as T) : null;\n}\n\nfunction setStorageItem<T>(storage: Storage, key: string, value: T) {\n storage.setItem(key, JSON.stringify(value));\n}\n\nasync function fetchEtag(url: string) {\n try {\n const response = await fetch(url, { method: \"HEAD\" });\n\n return response.headers.get(\"etag\");\n } catch (error) {\n return null;\n }\n}\n\nfunction getEmojibaseSupportedLocale(locale: string): EmojibaseLocale {\n return EMOJIBASE_LOCALES.includes(locale as EmojibaseLocale)\n ? (locale as EmojibaseLocale)\n : EMOJIBASE_DEFAULT_LOCALE;\n}\n\nasync function fetchEmojibaseData(locale: EmojibaseLocale) {\n const [{ emojis, emojisEtag }, { messages, messagesEtag }] =\n await Promise.all([\n fetch(EMOJIBASE_EMOJIS_URL(locale)).then(async (response) => {\n return {\n emojis: (await response.json()) as EmojibaseEmoji[],\n emojisEtag: response.headers.get(\"etag\"),\n };\n }),\n fetch(EMOJIBASE_MESSAGES_URL(locale)).then(async (response) => {\n return {\n messages: (await response.json()) as EmojibaseMessagesDataset,\n messagesEtag: response.headers.get(\"etag\"),\n };\n }),\n ]);\n\n return {\n emojis,\n messages,\n emojisEtag,\n messagesEtag,\n };\n}\n\nasync function fetchEmojibaseEtags(locale: EmojibaseLocale) {\n const [emojisEtag, messagesEtag] = await Promise.all([\n fetchEtag(EMOJIBASE_EMOJIS_URL(locale)),\n fetchEtag(EMOJIBASE_MESSAGES_URL(locale)),\n ]);\n\n return {\n emojisEtag,\n messagesEtag,\n };\n}\n\nasync function fetchEmojiData(locale: EmojibaseLocale): Promise<EmojiData> {\n const { emojis, emojisEtag, messages, messagesEtag } =\n await fetchEmojibaseData(locale);\n const countryFlagsSubgroup = messages.subgroups.find(\n (subgroup) => subgroup.key === \"subdivision-flag\"\n );\n\n // Filter out component/modifier category and emojis\n const filteredGroups = messages.groups.filter(\n (group) => group.key !== \"component\"\n );\n const filteredEmojis = emojis.filter((emoji) => {\n return \"group\" in emoji;\n });\n\n // Pick and compact the data\n const categories = filteredGroups.map((group) => ({\n key: group.order,\n name: capitalize(group.message),\n }));\n const skinTones = messages.skinTones.map((skinTone) => ({\n key: skinTone.key,\n name: capitalize(skinTone.message),\n }));\n const compactEmojis = filteredEmojis.map((emoji) => {\n const compactEmoji: Emoji = {\n emoji: emoji.emoji,\n category: emoji.group!,\n version: emoji.version,\n name: capitalize(emoji.label),\n tags: emoji.tags,\n };\n\n if (countryFlagsSubgroup && emoji.subgroup === countryFlagsSubgroup.order) {\n compactEmoji.countryFlag = true;\n }\n\n return compactEmoji;\n });\n\n const emojiData = {\n emojis: compactEmojis,\n categories,\n skinTones,\n };\n\n // Cache the data and metadata\n setStorageItem<EmojiData>(\n localStorage,\n CACHE_EMOJI_DATA_KEY(locale),\n emojiData\n );\n setStorageItem<EmojiMetadata>(\n localStorage,\n CACHE_EMOJI_METADATA_KEY(locale),\n {\n emojisEtag,\n messagesEtag,\n }\n );\n\n return emojiData;\n}\n\n// Adapted from https://github.com/koala-interactive/is-emoji-supported/tree/master\nfunction detectEmojiSupport(\n canvasContext: CanvasRenderingContext2D,\n emoji: string\n): boolean {\n canvasContext.clearRect(\n 0,\n 0,\n EMOJI_DETECTION_CANVAS_WIDTH * 2,\n EMOJI_DETECTION_CANVAS_HEIGHT\n );\n\n // Draw in red on the left\n canvasContext.fillStyle = \"#f00\";\n canvasContext.fillText(emoji, 0, 22);\n\n // Draw in blue on right\n canvasContext.fillStyle = \"#00f\";\n canvasContext.fillText(emoji, EMOJI_DETECTION_CANVAS_WIDTH, 22);\n\n const pixels = canvasContext.getImageData(\n 0,\n 0,\n EMOJI_DETECTION_CANVAS_WIDTH,\n EMOJI_DETECTION_CANVAS_HEIGHT\n ).data;\n const pixelCount = pixels.length;\n let i = 0;\n\n // Search for the first visible pixel\n for (; i < pixelCount && !pixels[i + 3]; i += 4);\n\n // No visible pixel\n if (i >= pixelCount) {\n return false;\n }\n\n // Emojis have an immutable color, so we check the color of the emoji in two\n // different colors, the result should be the same\n const x =\n EMOJI_DETECTION_CANVAS_WIDTH + ((i / 4) % EMOJI_DETECTION_CANVAS_WIDTH);\n const y = Math.floor(i / 4 / EMOJI_DETECTION_CANVAS_WIDTH);\n const pixel = canvasContext.getImageData(x, y, 1, 1).data;\n\n if (pixels[i] !== pixel[0] || pixels[i + 2] !== pixel[2]) {\n return false;\n }\n\n // Unsupported ZWJ sequence emojis show up as separate emojis\n if (canvasContext.measureText(emoji).width >= EMOJI_DETECTION_CANVAS_WIDTH) {\n return false;\n }\n\n return true;\n}\n\nfunction getEmojiFontFamily() {\n try {\n const element = document.createElement(\"span\");\n element.style.display = \"none\";\n element.dataset.emoji = \"\";\n\n document.body.appendChild(element);\n\n const computedFontFamily = window.getComputedStyle(element).fontFamily;\n\n document.body.removeChild(element);\n\n return computedFontFamily;\n } catch {\n return EMOJI_FONT_FAMILY;\n }\n}\n\nfunction getEmojiSessionMetadata(emojis: Emoji[]): EmojiSessionMetadata {\n const versions = new Map<number, string>();\n\n for (const emoji of emojis) {\n if (!versions.has(emoji.version)) {\n versions.set(emoji.version, emoji.emoji);\n }\n }\n\n const descendingVersions = [...versions.keys()].sort((a, b) => b - a);\n\n const canvasContext = document\n .createElement(\"canvas\")\n .getContext(\"2d\", { willReadFrequently: true });\n\n if (!canvasContext) {\n return { emojiVersion: descendingVersions[0], countryFlags: true };\n }\n\n canvasContext.font = `${Math.floor(\n EMOJI_DETECTION_CANVAS_HEIGHT / 2\n )}px ${getEmojiFontFamily()}`;\n canvasContext.textBaseline = \"top\";\n canvasContext.canvas.width = EMOJI_DETECTION_CANVAS_WIDTH * 2;\n canvasContext.canvas.height = EMOJI_DETECTION_CANVAS_HEIGHT;\n\n const supportsCountryFlags = detectEmojiSupport(\n canvasContext,\n EMOJI_DETECTION_COUNTRY_FLAG\n );\n\n for (const version of descendingVersions) {\n const emoji = versions.get(version)!;\n const isSupported = detectEmojiSupport(canvasContext, emoji);\n\n if (isSupported) {\n return {\n emojiVersion: version,\n countryFlags: supportsCountryFlags,\n };\n }\n }\n\n return {\n emojiVersion: descendingVersions[0],\n countryFlags: supportsCountryFlags,\n };\n}\n\nexport async function getEmojiData(locale: string): Promise<EmojiData> {\n const emojibaseLocale = getEmojibaseSupportedLocale(locale);\n\n const sessionMetadata = getStorageItem<EmojiSessionMetadata>(\n sessionStorage,\n CACHE_EMOJI_SESSION_METADATA_KEY\n );\n const cachedData = getStorageItem<EmojiData>(\n localStorage,\n CACHE_EMOJI_DATA_KEY(emojibaseLocale)\n );\n let data: EmojiData;\n\n // If there is data already cached, check if the ETags are the same.\n // If they are, return the cached data, otherwise fetch it again.\n if (cachedData) {\n // ETags only need to be checked once per session\n if (sessionMetadata) {\n data = cachedData;\n } else {\n const { emojisEtag, messagesEtag } =\n await fetchEmojibaseEtags(emojibaseLocale);\n const cachedMetadata = getStorageItem<EmojiMetadata>(\n localStorage,\n CACHE_EMOJI_METADATA_KEY(emojibaseLocale)\n );\n\n if (\n cachedMetadata &&\n emojisEtag === cachedMetadata.emojisEtag &&\n messagesEtag === cachedMetadata.messagesEtag\n ) {\n data = cachedData;\n } else {\n data = await fetchEmojiData(emojibaseLocale);\n }\n }\n } else {\n data = await fetchEmojiData(emojibaseLocale);\n }\n\n const newSessionMetadata =\n sessionMetadata ?? getEmojiSessionMetadata(data.emojis);\n setStorageItem(\n sessionStorage,\n CACHE_EMOJI_SESSION_METADATA_KEY,\n newSessionMetadata\n );\n\n // Filter out unsupported emojis\n const filteredEmojis = data.emojis.filter((emoji) => {\n const isSupportedVersion = emoji.version <= newSessionMetadata.emojiVersion;\n\n return emoji.countryFlag\n ? isSupportedVersion && newSessionMetadata.countryFlags\n : isSupportedVersion;\n });\n\n return {\n emojis: filteredEmojis,\n categories: data.categories,\n skinTones: data.skinTones,\n };\n}\n\nexport function filterEmojis(emojis: Emoji[], search?: string) {\n if (!search) {\n return emojis;\n }\n\n const searchText = search.toLowerCase().trim();\n\n return emojis.filter(\n (emoji) =>\n emoji.name.toLowerCase().includes(searchText) ||\n emoji.tags?.some((tag) => tag.toLowerCase().includes(searchText))\n );\n}\n\nexport function generateEmojiPickerData(\n emojis: Emoji[],\n categories: EmojiCategory[],\n columns: number\n): EmojiPickerData {\n let currentIndex = 0;\n const rows: EmojiPickerRow[] = [];\n const indexedEmojis = emojis.map((emoji, index) => ({ ...emoji, index }));\n const categoriesRowCounts: number[] = [];\n const categoriesRowIndices: number[][] = [];\n const categoriesNames: string[] = [];\n const categorizedEmojis = categories\n .map((category) => ({\n ...category,\n emojis: indexedEmojis.filter((emoji) => emoji.category === category.key),\n }))\n .filter((category) => category.emojis.length > 0);\n\n for (const category of categorizedEmojis) {\n const categoryRows = chunk(category.emojis, columns);\n const nextIndex = currentIndex + categoryRows.length;\n\n rows.push(...categoryRows);\n categoriesNames.push(category.name);\n categoriesRowCounts.push(categoryRows.length);\n categoriesRowIndices.push(\n generateRangeIndices(currentIndex, nextIndex - 1)\n );\n currentIndex = nextIndex;\n }\n\n return {\n count: emojis.length,\n rows,\n categories: categoriesNames,\n categoriesRowCounts,\n categoriesRowIndices,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.mjs","sources":["../../../src/primitives/EmojiPicker/utils.ts"],"sourcesContent":["import { chunk } from \"@liveblocks/core\";\nimport type {\n Emoji as EmojibaseEmoji,\n Locale as EmojibaseLocale,\n MessagesDataset as EmojibaseMessagesDataset,\n} from \"emojibase\";\n\nimport { EMOJI_FONT_FAMILY } from \"../../constants\";\nimport { capitalize } from \"../../utils/capitalize\";\nimport type {\n Emoji,\n EmojiCategory,\n EmojiData,\n EmojiPickerData,\n EmojiPickerRow,\n} from \"./types\";\n\nconst EMOJIBASE_VERSION = \"15.3.0\";\nconst EMOJIBASE_CDN_URL = `https://cdn.jsdelivr.net/npm/emojibase-data@${EMOJIBASE_VERSION}`;\nconst EMOJIBASE_EMOJIS_URL = (locale: EmojibaseLocale) =>\n `${EMOJIBASE_CDN_URL}/${locale}/data.json`;\nconst EMOJIBASE_MESSAGES_URL = (locale: EmojibaseLocale) =>\n `${EMOJIBASE_CDN_URL}/${locale}/messages.json`;\nconst EMOJIBASE_LOCALES: EmojibaseLocale[] = [\n \"bn\",\n \"da\",\n \"de\",\n \"en\",\n \"en-gb\",\n \"es\",\n \"es-mx\",\n \"et\",\n \"fi\",\n \"fr\",\n \"hi\",\n \"hu\",\n \"it\",\n \"ja\",\n \"ko\",\n \"lt\",\n \"ms\",\n \"nb\",\n \"nl\",\n \"pl\",\n \"pt\",\n \"ru\",\n \"sv\",\n \"th\",\n \"uk\",\n \"zh\",\n \"zh-hant\",\n];\nconst EMOJIBASE_DEFAULT_LOCALE: EmojibaseLocale = \"en\";\n\nconst CACHE_EMOJI_DATA_KEY = (locale: string) => `lb-emoji-data-${locale}`;\nconst CACHE_EMOJI_METADATA_KEY = (locale: string) =>\n `lb-emoji-metadata-${locale}`;\nconst CACHE_EMOJI_SESSION_METADATA_KEY = \"lb-emoji-metadata\";\n\nconst EMOJI_DETECTION_CANVAS_WIDTH = 20;\nconst EMOJI_DETECTION_CANVAS_HEIGHT = 25;\nconst EMOJI_DETECTION_COUNTRY_FLAG = \"🇫🇷\";\n\ntype EmojiMetadata = {\n emojisEtag: string | null;\n messagesEtag: string | null;\n};\n\ntype EmojiSessionMetadata = {\n emojiVersion: number;\n countryFlags: boolean;\n};\n\nfunction generateRangeIndices(start: number, end: number) {\n const range: number[] = [];\n\n for (let i = start; i <= end; i++) {\n range.push(i);\n }\n\n return range;\n}\n\nfunction getStorageItem<T>(storage: Storage, key: string) {\n const item = storage.getItem(key);\n\n return item ? (JSON.parse(item) as T) : null;\n}\n\nfunction setStorageItem<T>(storage: Storage, key: string, value: T) {\n storage.setItem(key, JSON.stringify(value));\n}\n\nasync function fetchEtag(url: string) {\n try {\n const response = await fetch(url, { method: \"HEAD\" });\n\n return response.headers.get(\"etag\");\n } catch (error) {\n return null;\n }\n}\n\nfunction getEmojibaseSupportedLocale(locale: string): EmojibaseLocale {\n return EMOJIBASE_LOCALES.includes(locale as EmojibaseLocale)\n ? (locale as EmojibaseLocale)\n : EMOJIBASE_DEFAULT_LOCALE;\n}\n\nasync function fetchEmojibaseData(locale: EmojibaseLocale) {\n const [{ emojis, emojisEtag }, { messages, messagesEtag }] =\n await Promise.all([\n fetch(EMOJIBASE_EMOJIS_URL(locale)).then(async (response) => {\n return {\n emojis: (await response.json()) as EmojibaseEmoji[],\n emojisEtag: response.headers.get(\"etag\"),\n };\n }),\n fetch(EMOJIBASE_MESSAGES_URL(locale)).then(async (response) => {\n return {\n messages: (await response.json()) as EmojibaseMessagesDataset,\n messagesEtag: response.headers.get(\"etag\"),\n };\n }),\n ]);\n\n return {\n emojis,\n messages,\n emojisEtag,\n messagesEtag,\n };\n}\n\nasync function fetchEmojibaseEtags(locale: EmojibaseLocale) {\n const [emojisEtag, messagesEtag] = await Promise.all([\n fetchEtag(EMOJIBASE_EMOJIS_URL(locale)),\n fetchEtag(EMOJIBASE_MESSAGES_URL(locale)),\n ]);\n\n return {\n emojisEtag,\n messagesEtag,\n };\n}\n\nasync function fetchEmojiData(locale: EmojibaseLocale): Promise<EmojiData> {\n const { emojis, emojisEtag, messages, messagesEtag } =\n await fetchEmojibaseData(locale);\n const countryFlagsSubgroup = messages.subgroups.find(\n (subgroup) => subgroup.key === \"subdivision-flag\"\n );\n\n // Filter out component/modifier category and emojis\n const filteredGroups = messages.groups.filter(\n (group) => group.key !== \"component\"\n );\n const filteredEmojis = emojis.filter((emoji) => {\n return \"group\" in emoji;\n });\n\n // Pick and compact the data\n const categories = filteredGroups.map((group) => ({\n key: group.order,\n name: capitalize(group.message),\n }));\n const skinTones = messages.skinTones.map((skinTone) => ({\n key: skinTone.key,\n name: capitalize(skinTone.message),\n }));\n const compactEmojis = filteredEmojis.map((emoji) => {\n const compactEmoji: Emoji = {\n emoji: emoji.emoji,\n category: emoji.group!,\n version: emoji.version,\n name: capitalize(emoji.label),\n tags: emoji.tags,\n };\n\n if (countryFlagsSubgroup && emoji.subgroup === countryFlagsSubgroup.order) {\n compactEmoji.countryFlag = true;\n }\n\n return compactEmoji;\n });\n\n const emojiData = {\n emojis: compactEmojis,\n categories,\n skinTones,\n };\n\n // Cache the data and metadata\n setStorageItem<EmojiData>(\n localStorage,\n CACHE_EMOJI_DATA_KEY(locale),\n emojiData\n );\n setStorageItem<EmojiMetadata>(\n localStorage,\n CACHE_EMOJI_METADATA_KEY(locale),\n {\n emojisEtag,\n messagesEtag,\n }\n );\n\n return emojiData;\n}\n\n// Adapted from https://github.com/koala-interactive/is-emoji-supported/tree/master\nfunction detectEmojiSupport(\n canvasContext: CanvasRenderingContext2D,\n emoji: string\n): boolean {\n canvasContext.clearRect(\n 0,\n 0,\n EMOJI_DETECTION_CANVAS_WIDTH * 2,\n EMOJI_DETECTION_CANVAS_HEIGHT\n );\n\n // Draw in red on the left\n canvasContext.fillStyle = \"#f00\";\n canvasContext.fillText(emoji, 0, 22);\n\n // Draw in blue on right\n canvasContext.fillStyle = \"#00f\";\n canvasContext.fillText(emoji, EMOJI_DETECTION_CANVAS_WIDTH, 22);\n\n const pixels = canvasContext.getImageData(\n 0,\n 0,\n EMOJI_DETECTION_CANVAS_WIDTH,\n EMOJI_DETECTION_CANVAS_HEIGHT\n ).data;\n const pixelCount = pixels.length;\n let i = 0;\n\n // Search for the first visible pixel\n for (; i < pixelCount && !pixels[i + 3]; i += 4);\n\n // No visible pixel\n if (i >= pixelCount) {\n return false;\n }\n\n // Emojis have an immutable color, so we check the color of the emoji in two\n // different colors, the result should be the same\n const x =\n EMOJI_DETECTION_CANVAS_WIDTH + ((i / 4) % EMOJI_DETECTION_CANVAS_WIDTH);\n const y = Math.floor(i / 4 / EMOJI_DETECTION_CANVAS_WIDTH);\n const pixel = canvasContext.getImageData(x, y, 1, 1).data;\n\n if (pixels[i] !== pixel[0] || pixels[i + 2] !== pixel[2]) {\n return false;\n }\n\n // Unsupported ZWJ sequence emojis show up as separate emojis\n if (canvasContext.measureText(emoji).width >= EMOJI_DETECTION_CANVAS_WIDTH) {\n return false;\n }\n\n return true;\n}\n\nfunction getEmojiFontFamily() {\n try {\n const element = document.createElement(\"span\");\n element.style.display = \"none\";\n element.dataset.emoji = \"\";\n\n document.body.appendChild(element);\n\n const computedFontFamily = window.getComputedStyle(element).fontFamily;\n\n document.body.removeChild(element);\n\n return computedFontFamily;\n } catch {\n return EMOJI_FONT_FAMILY;\n }\n}\n\nfunction getEmojiSessionMetadata(emojis: Emoji[]): EmojiSessionMetadata {\n const versions = new Map<number, string>();\n\n for (const emoji of emojis) {\n if (!versions.has(emoji.version)) {\n versions.set(emoji.version, emoji.emoji);\n }\n }\n\n const descendingVersions = [...versions.keys()].sort((a, b) => b - a);\n\n const canvasContext = document\n .createElement(\"canvas\")\n .getContext(\"2d\", { willReadFrequently: true });\n\n if (!canvasContext) {\n return { emojiVersion: descendingVersions[0], countryFlags: true };\n }\n\n canvasContext.font = `${Math.floor(\n EMOJI_DETECTION_CANVAS_HEIGHT / 2\n )}px ${getEmojiFontFamily()}`;\n canvasContext.textBaseline = \"top\";\n canvasContext.canvas.width = EMOJI_DETECTION_CANVAS_WIDTH * 2;\n canvasContext.canvas.height = EMOJI_DETECTION_CANVAS_HEIGHT;\n\n const supportsCountryFlags = detectEmojiSupport(\n canvasContext,\n EMOJI_DETECTION_COUNTRY_FLAG\n );\n\n for (const version of descendingVersions) {\n const emoji = versions.get(version)!;\n const isSupported = detectEmojiSupport(canvasContext, emoji);\n\n if (isSupported) {\n return {\n emojiVersion: version,\n countryFlags: supportsCountryFlags,\n };\n }\n }\n\n return {\n emojiVersion: descendingVersions[0],\n countryFlags: supportsCountryFlags,\n };\n}\n\nexport async function getEmojiData(locale: string): Promise<EmojiData> {\n const emojibaseLocale = getEmojibaseSupportedLocale(locale);\n\n const sessionMetadata = getStorageItem<EmojiSessionMetadata>(\n sessionStorage,\n CACHE_EMOJI_SESSION_METADATA_KEY\n );\n const cachedData = getStorageItem<EmojiData>(\n localStorage,\n CACHE_EMOJI_DATA_KEY(emojibaseLocale)\n );\n let data: EmojiData;\n\n // If there is data already cached, check if the ETags are the same.\n // If they are, return the cached data, otherwise fetch it again.\n if (cachedData) {\n // ETags only need to be checked once per session\n if (sessionMetadata) {\n data = cachedData;\n } else {\n const { emojisEtag, messagesEtag } =\n await fetchEmojibaseEtags(emojibaseLocale);\n const cachedMetadata = getStorageItem<EmojiMetadata>(\n localStorage,\n CACHE_EMOJI_METADATA_KEY(emojibaseLocale)\n );\n\n if (\n cachedMetadata &&\n emojisEtag === cachedMetadata.emojisEtag &&\n messagesEtag === cachedMetadata.messagesEtag\n ) {\n data = cachedData;\n } else {\n data = await fetchEmojiData(emojibaseLocale);\n }\n }\n } else {\n data = await fetchEmojiData(emojibaseLocale);\n }\n\n const newSessionMetadata =\n sessionMetadata ?? getEmojiSessionMetadata(data.emojis);\n setStorageItem(\n sessionStorage,\n CACHE_EMOJI_SESSION_METADATA_KEY,\n newSessionMetadata\n );\n\n // Filter out unsupported emojis\n const filteredEmojis = data.emojis.filter((emoji) => {\n const isSupportedVersion = emoji.version <= newSessionMetadata.emojiVersion;\n\n return emoji.countryFlag\n ? isSupportedVersion && newSessionMetadata.countryFlags\n : isSupportedVersion;\n });\n\n return {\n emojis: filteredEmojis,\n categories: data.categories,\n skinTones: data.skinTones,\n };\n}\n\nexport function filterEmojis(emojis: Emoji[], search?: string) {\n if (!search) {\n return emojis;\n }\n\n const searchText = search.toLowerCase().trim();\n\n return emojis.filter(\n (emoji) =>\n emoji.name.toLowerCase().includes(searchText) ||\n emoji.tags?.some((tag) => tag.toLowerCase().includes(searchText))\n );\n}\n\nexport function generateEmojiPickerData(\n emojis: Emoji[],\n categories: EmojiCategory[],\n columns: number\n): EmojiPickerData {\n let currentIndex = 0;\n const rows: EmojiPickerRow[] = [];\n const indexedEmojis = emojis.map((emoji, index) => ({ ...emoji, index }));\n const categoriesRowCounts: number[] = [];\n const categoriesRowIndices: number[][] = [];\n const categoriesNames: string[] = [];\n const categorizedEmojis = categories\n .map((category) => ({\n ...category,\n emojis: indexedEmojis.filter((emoji) => emoji.category === category.key),\n }))\n .filter((category) => category.emojis.length > 0);\n\n for (const category of categorizedEmojis) {\n const categoryRows = chunk(category.emojis, columns);\n const nextIndex = currentIndex + categoryRows.length;\n\n rows.push(...categoryRows);\n categoriesNames.push(category.name);\n categoriesRowCounts.push(categoryRows.length);\n categoriesRowIndices.push(\n generateRangeIndices(currentIndex, nextIndex - 1)\n );\n currentIndex = nextIndex;\n }\n\n return {\n count: emojis.length,\n rows,\n categories: categoriesNames,\n categoriesRowCounts,\n categoriesRowIndices,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var reactSlot = require('@radix-ui/react-slot');
5
+ var React = require('react');
6
+ var formatFileSize = require('../utils/format-file-size.js');
7
+
8
+ const FILE_SIZE_NAME = "FileSize";
9
+ const FileSize = React.forwardRef(
10
+ ({
11
+ size,
12
+ locale,
13
+ children: renderChildren = formatFileSize.formatFileSize,
14
+ asChild,
15
+ ...props
16
+ }, forwardedRef) => {
17
+ const Component = asChild ? reactSlot.Slot : "span";
18
+ const children = React.useMemo(
19
+ () => typeof renderChildren === "function" ? renderChildren(size, locale) : renderChildren,
20
+ [renderChildren, size]
21
+ );
22
+ return /* @__PURE__ */ React.createElement(Component, {
23
+ ...props,
24
+ ref: forwardedRef
25
+ }, children);
26
+ }
27
+ );
28
+ if (process.env.NODE_ENV !== "production") {
29
+ FileSize.displayName = FILE_SIZE_NAME;
30
+ }
31
+
32
+ exports.FileSize = FileSize;
33
+ //# sourceMappingURL=FileSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileSize.js","sources":["../../src/primitives/FileSize.tsx"],"sourcesContent":["\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { ReactNode } from \"react\";\nimport React, { forwardRef, useMemo } from \"react\";\n\nimport type { ComponentPropsWithSlot } from \"../types\";\nimport { formatFileSize } from \"../utils/format-file-size\";\n\nconst FILE_SIZE_NAME = \"FileSize\";\n\nexport interface FileSizeProps\n extends Omit<ComponentPropsWithSlot<\"span\">, \"children\"> {\n /**\n * The file size to display.\n */\n size: number;\n\n /**\n * A function to format the displayed file size.\n */\n children?: (size: number, locale?: string) => ReactNode;\n\n /**\n * The locale used when formatting the file size.\n */\n locale?: string;\n}\n\n/**\n * Displays a formatted file size.\n *\n * @example\n * <FileSize size={100000} />\n */\nexport const FileSize = forwardRef<HTMLSpanElement, FileSizeProps>(\n (\n {\n size,\n locale,\n children: renderChildren = formatFileSize,\n asChild,\n ...props\n },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"span\";\n const children = useMemo(\n () =>\n typeof renderChildren === \"function\"\n ? renderChildren(size, locale)\n : renderChildren,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [renderChildren, size]\n );\n\n return (\n <Component {...props} ref={forwardedRef}>\n {children}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n FileSize.displayName = FILE_SIZE_NAME;\n}\n"],"names":[],"mappings":";;;;;;;AASA;AA0BO;AAAiB;AAEpB;AACE;AACA;AAC2B;AAC3B;AACG;AAIL;AACA;AAAiB;AAIT;AAEe;AAGvB;AACG;AAAc;AAAY;AAE3B;AAGN;AAEA;AACE;AACF;;"}
@@ -0,0 +1,31 @@
1
+ 'use client';
2
+ import { Slot } from '@radix-ui/react-slot';
3
+ import React__default, { forwardRef, useMemo } from 'react';
4
+ import { formatFileSize } from '../utils/format-file-size.mjs';
5
+
6
+ const FILE_SIZE_NAME = "FileSize";
7
+ const FileSize = forwardRef(
8
+ ({
9
+ size,
10
+ locale,
11
+ children: renderChildren = formatFileSize,
12
+ asChild,
13
+ ...props
14
+ }, forwardedRef) => {
15
+ const Component = asChild ? Slot : "span";
16
+ const children = useMemo(
17
+ () => typeof renderChildren === "function" ? renderChildren(size, locale) : renderChildren,
18
+ [renderChildren, size]
19
+ );
20
+ return /* @__PURE__ */ React__default.createElement(Component, {
21
+ ...props,
22
+ ref: forwardedRef
23
+ }, children);
24
+ }
25
+ );
26
+ if (process.env.NODE_ENV !== "production") {
27
+ FileSize.displayName = FILE_SIZE_NAME;
28
+ }
29
+
30
+ export { FileSize };
31
+ //# sourceMappingURL=FileSize.mjs.map