@liveblocks/react-ui 2.25.0-aiprivatebeta9 → 3.1.0-alpha1

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 (198) hide show
  1. package/_private/package.json +2 -2
  2. package/dist/_private/index.cjs +8 -0
  3. package/dist/_private/index.cjs.map +1 -1
  4. package/dist/_private/index.d.cts +22 -5
  5. package/dist/_private/index.d.ts +22 -5
  6. package/dist/_private/index.js +4 -0
  7. package/dist/_private/index.js.map +1 -1
  8. package/dist/components/AiChat.cjs +17 -21
  9. package/dist/components/AiChat.cjs.map +1 -1
  10. package/dist/components/AiChat.js +18 -22
  11. package/dist/components/AiChat.js.map +1 -1
  12. package/dist/components/AiTool.cjs +61 -35
  13. package/dist/components/AiTool.cjs.map +1 -1
  14. package/dist/components/AiTool.js +62 -36
  15. package/dist/components/AiTool.js.map +1 -1
  16. package/dist/components/Comment.cjs +261 -242
  17. package/dist/components/Comment.cjs.map +1 -1
  18. package/dist/components/Comment.js +262 -243
  19. package/dist/components/Comment.js.map +1 -1
  20. package/dist/components/Composer.cjs +49 -40
  21. package/dist/components/Composer.cjs.map +1 -1
  22. package/dist/components/Composer.js +51 -42
  23. package/dist/components/Composer.js.map +1 -1
  24. package/dist/components/HistoryVersionSummary.cjs +2 -2
  25. package/dist/components/HistoryVersionSummary.cjs.map +1 -1
  26. package/dist/components/HistoryVersionSummary.js +2 -2
  27. package/dist/components/HistoryVersionSummary.js.map +1 -1
  28. package/dist/components/HistoryVersionSummaryList.cjs +2 -5
  29. package/dist/components/HistoryVersionSummaryList.cjs.map +1 -1
  30. package/dist/components/HistoryVersionSummaryList.js +2 -5
  31. package/dist/components/HistoryVersionSummaryList.js.map +1 -1
  32. package/dist/components/InboxNotification.cjs +4 -4
  33. package/dist/components/InboxNotification.cjs.map +1 -1
  34. package/dist/components/InboxNotification.js +4 -4
  35. package/dist/components/InboxNotification.js.map +1 -1
  36. package/dist/components/InboxNotificationList.cjs +2 -2
  37. package/dist/components/InboxNotificationList.cjs.map +1 -1
  38. package/dist/components/InboxNotificationList.js +2 -2
  39. package/dist/components/InboxNotificationList.js.map +1 -1
  40. package/dist/components/Thread.cjs +9 -3
  41. package/dist/components/Thread.cjs.map +1 -1
  42. package/dist/components/Thread.js +10 -4
  43. package/dist/components/Thread.js.map +1 -1
  44. package/dist/components/internal/AiChatAssistantMessage.cjs +47 -10
  45. package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
  46. package/dist/components/internal/AiChatAssistantMessage.js +49 -12
  47. package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
  48. package/dist/components/internal/AiChatComposer.cjs +2 -2
  49. package/dist/components/internal/AiChatComposer.cjs.map +1 -1
  50. package/dist/components/internal/AiChatComposer.js +2 -2
  51. package/dist/components/internal/AiChatComposer.js.map +1 -1
  52. package/dist/components/internal/AiChatUserMessage.cjs +2 -2
  53. package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
  54. package/dist/components/internal/AiChatUserMessage.js +2 -2
  55. package/dist/components/internal/AiChatUserMessage.js.map +1 -1
  56. package/dist/components/internal/Attachment.cjs +3 -3
  57. package/dist/components/internal/Attachment.cjs.map +1 -1
  58. package/dist/components/internal/Attachment.js +3 -3
  59. package/dist/components/internal/Attachment.js.map +1 -1
  60. package/dist/components/internal/Attribution.cjs +2 -2
  61. package/dist/components/internal/Attribution.cjs.map +1 -1
  62. package/dist/components/internal/Attribution.js +2 -2
  63. package/dist/components/internal/Attribution.js.map +1 -1
  64. package/dist/components/internal/Avatar.cjs +2 -2
  65. package/dist/components/internal/Avatar.cjs.map +1 -1
  66. package/dist/components/internal/Avatar.js +2 -2
  67. package/dist/components/internal/Avatar.js.map +1 -1
  68. package/dist/components/internal/Button.cjs +3 -3
  69. package/dist/components/internal/Button.cjs.map +1 -1
  70. package/dist/components/internal/Button.js +3 -3
  71. package/dist/components/internal/Button.js.map +1 -1
  72. package/dist/components/internal/CodeBlock.cjs +6 -3
  73. package/dist/components/internal/CodeBlock.cjs.map +1 -1
  74. package/dist/components/internal/CodeBlock.js +6 -3
  75. package/dist/components/internal/CodeBlock.js.map +1 -1
  76. package/dist/components/internal/Dropdown.cjs +4 -4
  77. package/dist/components/internal/Dropdown.cjs.map +1 -1
  78. package/dist/components/internal/Dropdown.js +5 -5
  79. package/dist/components/internal/Dropdown.js.map +1 -1
  80. package/dist/components/internal/Emoji.cjs +2 -2
  81. package/dist/components/internal/Emoji.cjs.map +1 -1
  82. package/dist/components/internal/Emoji.js +2 -2
  83. package/dist/components/internal/Emoji.js.map +1 -1
  84. package/dist/components/internal/EmojiPicker.cjs +6 -6
  85. package/dist/components/internal/EmojiPicker.cjs.map +1 -1
  86. package/dist/components/internal/EmojiPicker.js +7 -7
  87. package/dist/components/internal/EmojiPicker.js.map +1 -1
  88. package/dist/components/internal/Icon.cjs +2 -2
  89. package/dist/components/internal/Icon.cjs.map +1 -1
  90. package/dist/components/internal/Icon.js +2 -2
  91. package/dist/components/internal/Icon.js.map +1 -1
  92. package/dist/components/internal/InboxNotificationThread.cjs +7 -4
  93. package/dist/components/internal/InboxNotificationThread.cjs.map +1 -1
  94. package/dist/components/internal/InboxNotificationThread.js +8 -5
  95. package/dist/components/internal/InboxNotificationThread.js.map +1 -1
  96. package/dist/components/internal/List.cjs +2 -2
  97. package/dist/components/internal/List.cjs.map +1 -1
  98. package/dist/components/internal/List.js +2 -2
  99. package/dist/components/internal/List.js.map +1 -1
  100. package/dist/components/internal/Prose.cjs +2 -2
  101. package/dist/components/internal/Prose.cjs.map +1 -1
  102. package/dist/components/internal/Prose.js +2 -2
  103. package/dist/components/internal/Prose.js.map +1 -1
  104. package/dist/components/internal/Room.cjs +2 -2
  105. package/dist/components/internal/Room.cjs.map +1 -1
  106. package/dist/components/internal/Room.js +2 -2
  107. package/dist/components/internal/Room.js.map +1 -1
  108. package/dist/components/internal/Tooltip.cjs +3 -3
  109. package/dist/components/internal/Tooltip.cjs.map +1 -1
  110. package/dist/components/internal/Tooltip.js +4 -4
  111. package/dist/components/internal/Tooltip.js.map +1 -1
  112. package/dist/components/internal/User.cjs +2 -2
  113. package/dist/components/internal/User.cjs.map +1 -1
  114. package/dist/components/internal/User.js +2 -2
  115. package/dist/components/internal/User.js.map +1 -1
  116. package/dist/config.cjs +9 -9
  117. package/dist/config.cjs.map +1 -1
  118. package/dist/config.js +8 -8
  119. package/dist/config.js.map +1 -1
  120. package/dist/icons/CrossCircleFill.cjs +25 -0
  121. package/dist/icons/CrossCircleFill.cjs.map +1 -0
  122. package/dist/icons/CrossCircleFill.js +23 -0
  123. package/dist/icons/CrossCircleFill.js.map +1 -0
  124. package/dist/icons/MinusCircle.cjs +23 -0
  125. package/dist/icons/MinusCircle.cjs.map +1 -0
  126. package/dist/icons/MinusCircle.js +21 -0
  127. package/dist/icons/MinusCircle.js.map +1 -0
  128. package/dist/icons/index.cjs +4 -0
  129. package/dist/icons/index.cjs.map +1 -1
  130. package/dist/icons/index.js +2 -0
  131. package/dist/icons/index.js.map +1 -1
  132. package/dist/index.cjs +1 -1
  133. package/dist/index.cjs.map +1 -1
  134. package/dist/index.d.cts +238 -25
  135. package/dist/index.d.ts +238 -25
  136. package/dist/index.js +1 -1
  137. package/dist/index.js.map +1 -1
  138. package/dist/overrides.cjs +5 -1
  139. package/dist/overrides.cjs.map +1 -1
  140. package/dist/overrides.js +5 -1
  141. package/dist/overrides.js.map +1 -1
  142. package/dist/primitives/AiMessage/index.cjs +11 -67
  143. package/dist/primitives/AiMessage/index.cjs.map +1 -1
  144. package/dist/primitives/AiMessage/index.js +13 -69
  145. package/dist/primitives/AiMessage/index.js.map +1 -1
  146. package/dist/primitives/AiMessage/tool-invocation.cjs +70 -0
  147. package/dist/primitives/AiMessage/tool-invocation.cjs.map +1 -0
  148. package/dist/primitives/AiMessage/tool-invocation.js +68 -0
  149. package/dist/primitives/AiMessage/tool-invocation.js.map +1 -0
  150. package/dist/primitives/Collapsible/index.cjs +3 -3
  151. package/dist/primitives/Collapsible/index.cjs.map +1 -1
  152. package/dist/primitives/Collapsible/index.js +3 -3
  153. package/dist/primitives/Collapsible/index.js.map +1 -1
  154. package/dist/primitives/Comment/index.cjs +5 -4
  155. package/dist/primitives/Comment/index.cjs.map +1 -1
  156. package/dist/primitives/Comment/index.js +5 -4
  157. package/dist/primitives/Comment/index.js.map +1 -1
  158. package/dist/primitives/Composer/index.cjs +49 -41
  159. package/dist/primitives/Composer/index.cjs.map +1 -1
  160. package/dist/primitives/Composer/index.js +50 -42
  161. package/dist/primitives/Composer/index.js.map +1 -1
  162. package/dist/primitives/Composer/slate/plugins/mentions.cjs +4 -4
  163. package/dist/primitives/Composer/slate/plugins/mentions.cjs.map +1 -1
  164. package/dist/primitives/Composer/slate/plugins/mentions.js +4 -4
  165. package/dist/primitives/Composer/slate/plugins/mentions.js.map +1 -1
  166. package/dist/primitives/Composer/utils.cjs +3 -6
  167. package/dist/primitives/Composer/utils.cjs.map +1 -1
  168. package/dist/primitives/Composer/utils.js +3 -6
  169. package/dist/primitives/Composer/utils.js.map +1 -1
  170. package/dist/primitives/Markdown.cjs +6 -2
  171. package/dist/primitives/Markdown.cjs.map +1 -1
  172. package/dist/primitives/Markdown.js +6 -2
  173. package/dist/primitives/Markdown.js.map +1 -1
  174. package/dist/primitives/index.d.cts +18 -18
  175. package/dist/primitives/index.d.ts +18 -18
  176. package/dist/utils/{class-names.cjs → cn.cjs} +3 -3
  177. package/dist/utils/cn.cjs.map +1 -0
  178. package/dist/utils/{class-names.js → cn.js} +3 -3
  179. package/dist/utils/cn.js.map +1 -0
  180. package/dist/utils/use-controllable-state.cjs +25 -2
  181. package/dist/utils/use-controllable-state.cjs.map +1 -1
  182. package/dist/utils/use-controllable-state.js +25 -3
  183. package/dist/utils/use-controllable-state.js.map +1 -1
  184. package/dist/utils/use-visible.cjs +3 -1
  185. package/dist/utils/use-visible.cjs.map +1 -1
  186. package/dist/utils/use-visible.js +3 -1
  187. package/dist/utils/use-visible.js.map +1 -1
  188. package/dist/version.cjs +1 -1
  189. package/dist/version.cjs.map +1 -1
  190. package/dist/version.js +1 -1
  191. package/dist/version.js.map +1 -1
  192. package/package.json +16 -5
  193. package/primitives/package.json +2 -2
  194. package/src/styles/index.css +26 -7
  195. package/styles.css +1 -1
  196. package/styles.css.map +1 -1
  197. package/dist/utils/class-names.cjs.map +0 -1
  198. package/dist/utils/class-names.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { Permission } from '@liveblocks/core';
3
+ import { assertNever, Permission } from '@liveblocks/core';
4
4
  import { useRoom } from '@liveblocks/react';
5
5
  import { useLayoutEffect, useCreateRoomThread, useCreateRoomComment, useEditRoomComment, useResolveMentionSuggestions, useRoomPermissions } from '@liveblocks/react/_private';
6
6
  import { useCallback, useMemo, createContext, forwardRef, useRef, useSyncExternalStore } from 'react';
7
- import { useLiveblocksUIConfig } from '../config.js';
7
+ import { useLiveblocksUiConfig } from '../config.js';
8
8
  import { MENTION_CHARACTER, FLOATING_ELEMENT_SIDE_OFFSET } from '../constants.js';
9
9
  import { AttachmentIcon } from '../icons/Attachment.js';
10
10
  import { BoldIcon } from '../icons/Bold.js';
@@ -18,7 +18,7 @@ import { useOverrides } from '../overrides.js';
18
18
  import { AttachFiles as ComposerAttachFiles, Mention as ComposerMention$1, Suggestions as ComposerSuggestions, SuggestionsList as ComposerSuggestionsList, SuggestionsListItem as ComposerSuggestionsListItem, MarkToggle as ComposerMarkToggle, FloatingToolbar as ComposerFloatingToolbar$1, Link as ComposerLink$1, Editor as ComposerEditor, Submit as ComposerSubmit, Form as ComposerForm } from '../primitives/Composer/index.js';
19
19
  import { useComposer, useComposerEditorContext, useComposerAttachmentsContext } from '../primitives/Composer/contexts.js';
20
20
  import { useComposerAttachmentsDropArea } from '../primitives/Composer/utils.js';
21
- import { classNames } from '../utils/class-names.js';
21
+ import { cn } from '../utils/cn.js';
22
22
  import { useControllableState } from '../utils/use-controllable-state.js';
23
23
  import { FileAttachment } from './internal/Attachment.js';
24
24
  import { Attribution } from './internal/Attribution.js';
@@ -55,7 +55,7 @@ function ComposerInsertMentionEditorAction({
55
55
  return /* @__PURE__ */ jsx(Tooltip, {
56
56
  content: tooltipLabel ?? label,
57
57
  children: /* @__PURE__ */ jsx(Button, {
58
- className: classNames("lb-composer-editor-action", className),
58
+ className: cn("lb-composer-editor-action", className),
59
59
  onPointerDown: preventDefault,
60
60
  onClick: handleClick,
61
61
  "aria-label": label,
@@ -86,7 +86,7 @@ function ComposerInsertEmojiEditorAction({
86
86
  children: /* @__PURE__ */ jsx(PopoverTrigger, {
87
87
  asChild: true,
88
88
  children: /* @__PURE__ */ jsx(Button, {
89
- className: classNames("lb-composer-editor-action", className),
89
+ className: cn("lb-composer-editor-action", className),
90
90
  onPointerDown: preventDefault,
91
91
  onClick: stopPropagation,
92
92
  "aria-label": label,
@@ -114,7 +114,7 @@ function ComposerAttachFilesEditorAction({
114
114
  children: /* @__PURE__ */ jsx(ComposerAttachFiles, {
115
115
  asChild: true,
116
116
  children: /* @__PURE__ */ jsx(Button, {
117
- className: classNames("lb-composer-editor-action", className),
117
+ className: cn("lb-composer-editor-action", className),
118
118
  onPointerDown: preventDefault,
119
119
  onClick: stopPropagation,
120
120
  "aria-label": label,
@@ -124,38 +124,50 @@ function ComposerAttachFilesEditorAction({
124
124
  })
125
125
  });
126
126
  }
127
- function ComposerMention({ userId }) {
128
- return /* @__PURE__ */ jsxs(ComposerMention$1, {
129
- className: "lb-composer-mention",
130
- children: [
131
- MENTION_CHARACTER,
132
- /* @__PURE__ */ jsx(User, {
133
- userId
134
- })
135
- ]
136
- });
127
+ function ComposerMention({ mention }) {
128
+ switch (mention.kind) {
129
+ case "user":
130
+ return /* @__PURE__ */ jsxs(ComposerMention$1, {
131
+ className: "lb-composer-mention",
132
+ children: [
133
+ MENTION_CHARACTER,
134
+ /* @__PURE__ */ jsx(User, {
135
+ userId: mention.id
136
+ })
137
+ ]
138
+ });
139
+ default:
140
+ return assertNever(mention.kind, "Unhandled mention kind");
141
+ }
137
142
  }
138
143
  function ComposerMentionSuggestions({
139
- userIds
144
+ mentions
140
145
  }) {
141
- return userIds.length > 0 ? /* @__PURE__ */ jsx(ComposerSuggestions, {
146
+ return mentions.length > 0 ? /* @__PURE__ */ jsx(ComposerSuggestions, {
142
147
  className: "lb-root lb-portal lb-elevation lb-composer-suggestions lb-composer-mention-suggestions",
143
148
  children: /* @__PURE__ */ jsx(ComposerSuggestionsList, {
144
149
  className: "lb-composer-suggestions-list lb-composer-mention-suggestions-list",
145
- children: userIds.map((userId) => /* @__PURE__ */ jsxs(ComposerSuggestionsListItem, {
146
- className: "lb-composer-suggestions-list-item lb-composer-mention-suggestion",
147
- value: userId,
148
- children: [
149
- /* @__PURE__ */ jsx(Avatar, {
150
- userId,
151
- className: "lb-composer-mention-suggestion-avatar"
152
- }),
153
- /* @__PURE__ */ jsx(User, {
154
- userId,
155
- className: "lb-composer-mention-suggestion-user"
156
- })
157
- ]
158
- }, userId))
150
+ children: mentions.map((mention) => {
151
+ switch (mention.kind) {
152
+ case "user":
153
+ return /* @__PURE__ */ jsxs(ComposerSuggestionsListItem, {
154
+ className: "lb-composer-suggestions-list-item lb-composer-mention-suggestion",
155
+ value: mention.id,
156
+ children: [
157
+ /* @__PURE__ */ jsx(Avatar, {
158
+ userId: mention.id,
159
+ className: "lb-composer-mention-suggestion-avatar"
160
+ }),
161
+ /* @__PURE__ */ jsx(User, {
162
+ userId: mention.id,
163
+ className: "lb-composer-mention-suggestion-user"
164
+ })
165
+ ]
166
+ }, mention.id);
167
+ default:
168
+ return assertNever(mention.kind, "Unhandled mention kind");
169
+ }
170
+ })
159
171
  })
160
172
  }) : null;
161
173
  }
@@ -235,7 +247,7 @@ function ComposerFileAttachment({
235
247
  removeAttachment(attachment.id);
236
248
  }, [attachment.id, removeAttachment]);
237
249
  return /* @__PURE__ */ jsx(FileAttachment, {
238
- className: classNames("lb-composer-attachment", className),
250
+ className: cn("lb-composer-attachment", className),
239
251
  ...props,
240
252
  attachment,
241
253
  onDeleteClick: handleDeleteClick,
@@ -254,7 +266,7 @@ function ComposerAttachments({
254
266
  return null;
255
267
  }
256
268
  return /* @__PURE__ */ jsx("div", {
257
- className: classNames("lb-composer-attachments", className),
269
+ className: cn("lb-composer-attachments", className),
258
270
  ...props,
259
271
  children: /* @__PURE__ */ jsx("div", {
260
272
  className: "lb-attachments",
@@ -417,15 +429,15 @@ const Composer = forwardRef(
417
429
  const createThread = useCreateRoomThread(roomId);
418
430
  const createComment = useCreateRoomComment(roomId);
419
431
  const editComment = useEditRoomComment(roomId);
420
- const { preventUnsavedComposerChanges } = useLiveblocksUIConfig();
432
+ const { preventUnsavedComposerChanges } = useLiveblocksUiConfig();
421
433
  const hasResolveMentionSuggestions = useResolveMentionSuggestions() !== void 0;
422
434
  const isEmptyRef = useRef(true);
423
435
  const isEmojiPickerOpenRef = useRef(false);
424
436
  const $ = useOverrides(overrides);
425
437
  const [isCollapsed, onCollapsedChange] = useControllableState(
426
- controlledCollapsed === void 0 && defaultCollapsed === void 0 ? false : controlledCollapsed,
427
- controlledOnCollapsedChange,
428
- defaultCollapsed
438
+ defaultCollapsed ?? false,
439
+ controlledCollapsed,
440
+ controlledOnCollapsedChange
429
441
  );
430
442
  const canCommentFallback = useSyncExternalStore(
431
443
  useCallback(
@@ -527,10 +539,7 @@ const Composer = forwardRef(
527
539
  return /* @__PURE__ */ jsx(TooltipProvider, {
528
540
  children: /* @__PURE__ */ jsx(ComposerForm, {
529
541
  onComposerSubmit: handleComposerSubmit,
530
- className: classNames(
531
- "lb-root lb-composer lb-composer-form",
532
- className
533
- ),
542
+ className: cn("lb-root lb-composer lb-composer-form", className),
534
543
  dir: $.dir,
535
544
  ...props,
536
545
  ref: forwardedRef,
@@ -1 +1 @@
1
- {"version":3,"file":"Composer.js","sources":["../../src/components/Composer.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n BaseMetadata,\n CommentAttachment,\n CommentMixedAttachment,\n DM,\n} from \"@liveblocks/core\";\nimport { Permission } from \"@liveblocks/core\";\nimport { useRoom } from \"@liveblocks/react\";\nimport {\n useCreateRoomComment,\n useCreateRoomThread,\n useEditRoomComment,\n useLayoutEffect,\n useResolveMentionSuggestions,\n useRoomPermissions,\n} from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n ComponentType,\n FocusEvent,\n FormEvent,\n ForwardedRef,\n MouseEvent,\n PropsWithChildren,\n ReactNode,\n RefAttributes,\n SyntheticEvent,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\n\nimport { useLiveblocksUIConfig } from \"../config\";\nimport { FLOATING_ELEMENT_SIDE_OFFSET, MENTION_CHARACTER } from \"../constants\";\nimport { AttachmentIcon } from \"../icons/Attachment\";\nimport { BoldIcon } from \"../icons/Bold\";\nimport { CodeIcon } from \"../icons/Code\";\nimport { EmojiIcon } from \"../icons/Emoji\";\nimport { ItalicIcon } from \"../icons/Italic\";\nimport { MentionIcon } from \"../icons/Mention\";\nimport { SendIcon } from \"../icons/Send\";\nimport { StrikethroughIcon } from \"../icons/Strikethrough\";\nimport type { ComposerOverrides, GlobalOverrides } from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport {\n useComposer,\n useComposerAttachmentsContext,\n useComposerEditorContext,\n} from \"../primitives/Composer/contexts\";\nimport type {\n ComposerEditorComponents,\n ComposerEditorLinkProps,\n ComposerEditorMentionProps,\n ComposerEditorMentionSuggestionsProps,\n ComposerEditorProps,\n ComposerFormProps,\n ComposerMarkToggleProps,\n ComposerSubmitComment,\n} from \"../primitives/Composer/types\";\nimport { useComposerAttachmentsDropArea } from \"../primitives/Composer/utils\";\nimport type { ComposerBodyMark } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport { FileAttachment } from \"./internal/Attachment\";\nimport { Attribution } from \"./internal/Attribution\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport type { EmojiPickerProps } from \"./internal/EmojiPicker\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { ShortcutTooltip, Tooltip, TooltipProvider } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\ninterface EditorActionProps extends ComponentPropsWithoutRef<\"button\"> {\n label: string;\n tooltipLabel?: string;\n}\n\ninterface EmojiEditorActionProps extends EditorActionProps {\n onPickerOpenChange?: EmojiPickerProps[\"onOpenChange\"];\n}\n\ninterface MarkToggleProps extends ComposerMarkToggleProps {\n icon?: ReactNode;\n shortcut?: string;\n}\n\ntype ComposerCreateThreadProps<M extends BaseMetadata> = {\n threadId?: never;\n commentId?: never;\n\n /**\n * The metadata of the thread to create.\n */\n metadata?: M;\n};\n\ntype ComposerCreateCommentProps = {\n /**\n * The ID of the thread to reply to.\n */\n threadId: string;\n commentId?: never;\n metadata?: never;\n};\n\ntype ComposerEditCommentProps = {\n /**\n * The ID of the thread to edit a comment in.\n */\n threadId: string;\n\n /**\n * The ID of the comment to edit.\n */\n commentId: string;\n metadata?: never;\n};\n\nexport type ComposerProps<M extends BaseMetadata = DM> = Omit<\n ComponentPropsWithoutRef<\"form\">,\n \"defaultValue\"\n> &\n (\n | ComposerCreateThreadProps<M>\n | ComposerCreateCommentProps\n | ComposerEditCommentProps\n ) & {\n /**\n * The event handler called when the composer is submitted.\n */\n onComposerSubmit?: (\n comment: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => Promise<void> | void;\n\n /**\n * The composer's initial value.\n */\n defaultValue?: ComposerEditorProps[\"defaultValue\"];\n\n /**\n * The composer's initial attachments.\n */\n defaultAttachments?: CommentAttachment[];\n\n /**\n * Whether the composer is collapsed. Setting a value will make the composer controlled.\n */\n collapsed?: boolean;\n\n /**\n * The event handler called when the collapsed state of the composer changes.\n */\n onCollapsedChange?: (collapsed: boolean) => void;\n\n /**\n * Whether the composer is initially collapsed. Setting a value will make the composer uncontrolled.\n */\n defaultCollapsed?: boolean;\n\n /**\n * Whether to show and allow adding attachments.\n */\n showAttachments?: boolean;\n\n /**\n * Whether to show formatting controls (e.g. a floating toolbar with formatting toggles when selecting text)\n */\n showFormattingControls?: boolean;\n\n /**\n * Whether the composer is disabled.\n */\n disabled?: ComposerFormProps[\"disabled\"];\n\n /**\n * Whether to focus the composer on mount.\n */\n autoFocus?: ComposerEditorProps[\"autoFocus\"];\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n actions?: ReactNode;\n\n /**\n * @internal\n */\n showAttribution?: boolean;\n\n /**\n * @internal\n */\n roomId?: string;\n };\n\ninterface ComposerEditorContainerProps\n extends Pick<\n ComposerProps,\n | \"defaultValue\"\n | \"showAttachments\"\n | \"showFormattingControls\"\n | \"showAttribution\"\n | \"overrides\"\n | \"actions\"\n | \"autoFocus\"\n | \"disabled\"\n > {\n isCollapsed: boolean | undefined;\n onEmptyChange: (isEmpty: boolean) => void;\n hasResolveMentionSuggestions: boolean;\n onEmojiPickerOpenChange: (isOpen: boolean) => void;\n onEditorClick: (event: MouseEvent<HTMLDivElement>) => void;\n}\n\nfunction ComposerInsertMentionEditorAction({\n label,\n tooltipLabel,\n className,\n onClick,\n ...props\n}: EditorActionProps) {\n const { createMention } = useComposer();\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (!event.isDefaultPrevented()) {\n event.stopPropagation();\n createMention();\n }\n },\n [createMention, onClick]\n );\n\n return (\n <Tooltip content={tooltipLabel ?? label}>\n <Button\n className={classNames(\"lb-composer-editor-action\", className)}\n onPointerDown={preventDefault}\n onClick={handleClick}\n aria-label={label}\n icon={<MentionIcon />}\n {...props}\n />\n </Tooltip>\n );\n}\n\nfunction ComposerInsertEmojiEditorAction({\n label,\n tooltipLabel,\n onPickerOpenChange,\n className,\n ...props\n}: EmojiEditorActionProps) {\n const { insertText } = useComposer();\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <EmojiPicker onEmojiSelect={insertText} onOpenChange={onPickerOpenChange}>\n <Tooltip content={tooltipLabel ?? label}>\n <EmojiPickerTrigger asChild>\n <Button\n className={classNames(\"lb-composer-editor-action\", className)}\n onPointerDown={preventDefault}\n onClick={stopPropagation}\n aria-label={label}\n icon={<EmojiIcon />}\n {...props}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n );\n}\n\nfunction ComposerAttachFilesEditorAction({\n label,\n tooltipLabel,\n className,\n ...props\n}: EditorActionProps) {\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <Tooltip content={tooltipLabel ?? label}>\n <ComposerPrimitive.AttachFiles asChild>\n <Button\n className={classNames(\"lb-composer-editor-action\", className)}\n onPointerDown={preventDefault}\n onClick={stopPropagation}\n aria-label={label}\n icon={<AttachmentIcon />}\n {...props}\n />\n </ComposerPrimitive.AttachFiles>\n </Tooltip>\n );\n}\n\nfunction ComposerMention({ userId }: ComposerEditorMentionProps) {\n return (\n <ComposerPrimitive.Mention className=\"lb-composer-mention\">\n {MENTION_CHARACTER}\n <User userId={userId} />\n </ComposerPrimitive.Mention>\n );\n}\n\nfunction ComposerMentionSuggestions({\n userIds,\n}: ComposerEditorMentionSuggestionsProps) {\n return userIds.length > 0 ? (\n <ComposerPrimitive.Suggestions className=\"lb-root lb-portal lb-elevation lb-composer-suggestions lb-composer-mention-suggestions\">\n <ComposerPrimitive.SuggestionsList className=\"lb-composer-suggestions-list lb-composer-mention-suggestions-list\">\n {userIds.map((userId) => (\n <ComposerPrimitive.SuggestionsListItem\n key={userId}\n className=\"lb-composer-suggestions-list-item lb-composer-mention-suggestion\"\n value={userId}\n >\n <Avatar\n userId={userId}\n className=\"lb-composer-mention-suggestion-avatar\"\n />\n <User\n userId={userId}\n className=\"lb-composer-mention-suggestion-user\"\n />\n </ComposerPrimitive.SuggestionsListItem>\n ))}\n </ComposerPrimitive.SuggestionsList>\n </ComposerPrimitive.Suggestions>\n ) : null;\n}\n\nfunction MarkToggle({\n mark,\n icon,\n shortcut,\n children,\n ...props\n}: MarkToggleProps) {\n const $ = useOverrides();\n const label = useMemo(() => {\n return $.COMPOSER_TOGGLE_MARK(mark);\n }, [$, mark]);\n\n return (\n <ShortcutTooltip\n content={label}\n shortcut={shortcut}\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET + 2}\n >\n <ComposerPrimitive.MarkToggle mark={mark} asChild {...props}>\n <Button aria-label={label} variant=\"toolbar\" icon={icon}>\n {children}\n </Button>\n </ComposerPrimitive.MarkToggle>\n </ShortcutTooltip>\n );\n}\n\ntype MarkToggles = {\n [K in ComposerBodyMark]: ComponentType<PropsWithChildren>;\n};\n\nconst markToggles: MarkToggles = {\n bold: () => <MarkToggle mark=\"bold\" shortcut=\"Mod-B\" icon={<BoldIcon />} />,\n italic: () => (\n <MarkToggle mark=\"italic\" shortcut=\"Mod-I\" icon={<ItalicIcon />} />\n ),\n strikethrough: () => (\n <MarkToggle\n mark=\"strikethrough\"\n shortcut=\"Mod-Shift-S\"\n icon={<StrikethroughIcon />}\n />\n ),\n code: () => <MarkToggle mark=\"code\" shortcut=\"Mod-E\" icon={<CodeIcon />} />,\n};\n\nconst markTogglesList = Object.entries(markToggles).map(([mark, Toggle]) => (\n <Toggle key={mark} />\n));\n\nfunction ComposerFloatingToolbar() {\n return (\n <ComposerPrimitive.FloatingToolbar className=\"lb-root lb-portal lb-elevation lb-composer-floating-toolbar\">\n {markTogglesList}\n </ComposerPrimitive.FloatingToolbar>\n );\n}\n\nfunction ComposerLink({ href, children }: ComposerEditorLinkProps) {\n return (\n <ComposerPrimitive.Link href={href} className=\"lb-composer-link\">\n {children}\n </ComposerPrimitive.Link>\n );\n}\n\ninterface ComposerAttachmentsProps extends ComponentPropsWithoutRef<\"div\"> {\n overrides?: Partial<GlobalOverrides & ComposerOverrides>;\n}\n\ninterface ComposerFileAttachmentProps extends ComponentPropsWithoutRef<\"div\"> {\n attachment: CommentMixedAttachment;\n overrides?: Partial<GlobalOverrides & ComposerOverrides>;\n}\n\nfunction ComposerFileAttachment({\n attachment,\n className,\n overrides,\n ...props\n}: ComposerFileAttachmentProps) {\n const { removeAttachment } = useComposer();\n const { roomId } = useComposerEditorContext();\n\n const handleDeleteClick = useCallback(() => {\n removeAttachment(attachment.id);\n }, [attachment.id, removeAttachment]);\n\n return (\n <FileAttachment\n className={classNames(\"lb-composer-attachment\", className)}\n {...props}\n attachment={attachment}\n onDeleteClick={handleDeleteClick}\n preventFocusOnDelete\n overrides={overrides}\n roomId={roomId}\n />\n );\n}\n\nfunction ComposerAttachments({\n overrides,\n className,\n ...props\n}: ComposerAttachmentsProps) {\n const { attachments } = useComposer();\n\n if (attachments.length === 0) {\n return null;\n }\n\n return (\n <div\n className={classNames(\"lb-composer-attachments\", className)}\n {...props}\n >\n <div className=\"lb-attachments\">\n {attachments.map((attachment) => {\n return (\n <ComposerFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n />\n );\n })}\n </div>\n </div>\n );\n}\n\nconst editorRequiredComponents: ComposerEditorComponents = {\n Mention: ComposerMention,\n MentionSuggestions: ComposerMentionSuggestions,\n Link: ComposerLink,\n};\n\nfunction ComposerEditorContainer({\n showAttachments = true,\n showFormattingControls = true,\n showAttribution,\n defaultValue,\n isCollapsed,\n overrides,\n actions,\n autoFocus,\n disabled,\n hasResolveMentionSuggestions,\n onEmojiPickerOpenChange,\n onEmptyChange,\n onEditorClick,\n}: ComposerEditorContainerProps) {\n const { isEmpty } = useComposer();\n const { hasMaxAttachments } = useComposerAttachmentsContext();\n const $ = useOverrides(overrides);\n const components = useMemo(() => {\n return {\n ...editorRequiredComponents,\n FloatingToolbar: showFormattingControls\n ? ComposerFloatingToolbar\n : undefined,\n };\n }, [showFormattingControls]);\n\n const [isDraggingOver, dropAreaProps] = useComposerAttachmentsDropArea({\n disabled: disabled || hasMaxAttachments,\n });\n\n useLayoutEffect(() => {\n onEmptyChange(isEmpty);\n }, [isEmpty, onEmptyChange]);\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <div className=\"lb-composer-editor-container\" {...dropAreaProps}>\n <ComposerPrimitive.Editor\n className=\"lb-composer-editor\"\n onClick={onEditorClick}\n placeholder={$.COMPOSER_PLACEHOLDER}\n defaultValue={defaultValue}\n autoFocus={autoFocus}\n components={components}\n disabled={disabled}\n dir={$.dir}\n />\n {showAttachments && <ComposerAttachments overrides={overrides} />}\n {(!isCollapsed || isDraggingOver) && (\n <div className=\"lb-composer-footer\">\n <div className=\"lb-composer-editor-actions\">\n {hasResolveMentionSuggestions && (\n <ComposerInsertMentionEditorAction\n label={$.COMPOSER_INSERT_MENTION}\n disabled={disabled}\n />\n )}\n <ComposerInsertEmojiEditorAction\n label={$.COMPOSER_INSERT_EMOJI}\n onPickerOpenChange={onEmojiPickerOpenChange}\n disabled={disabled}\n />\n {showAttachments && (\n <ComposerAttachFilesEditorAction\n label={$.COMPOSER_ATTACH_FILES}\n disabled={disabled}\n />\n )}\n </div>\n {showAttribution && <Attribution />}\n <div className=\"lb-composer-actions\">\n {actions ?? (\n <>\n <ShortcutTooltip content={$.COMPOSER_SEND} shortcut=\"Enter\">\n <ComposerPrimitive.Submit asChild>\n <Button\n onPointerDown={preventDefault}\n onClick={stopPropagation}\n className=\"lb-composer-action\"\n variant=\"primary\"\n aria-label={$.COMPOSER_SEND}\n icon={<SendIcon />}\n />\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n )}\n </div>\n </div>\n )}\n {showAttachments && isDraggingOver && (\n <div className=\"lb-composer-attachments-drop-area\">\n <div className=\"lb-composer-attachments-drop-area-label\">\n <AttachmentIcon />\n {$.COMPOSER_ATTACH_FILES}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport const ComposerRoomIdContext = createContext<string | null>(null);\n\n/**\n * Displays a composer to create comments.\n *\n * @example\n * <Composer />\n */\nexport const Composer = forwardRef(\n <M extends BaseMetadata = DM>(\n {\n threadId,\n commentId,\n metadata,\n defaultValue,\n defaultAttachments,\n onComposerSubmit,\n collapsed: controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange: controlledOnCollapsedChange,\n overrides,\n actions,\n onBlur,\n className,\n onFocus,\n autoFocus,\n disabled,\n showAttachments = true,\n showFormattingControls = true,\n showAttribution,\n roomId: _roomId,\n ...props\n }: ComposerProps<M>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const room = useRoom({ allowOutsideRoom: true });\n\n const roomId = _roomId !== undefined ? _roomId : room?.id;\n if (roomId === undefined) {\n throw new Error(\n \"Composer must be a descendant of RoomProvider component\"\n );\n }\n\n const createThread = useCreateRoomThread(roomId);\n const createComment = useCreateRoomComment(roomId);\n const editComment = useEditRoomComment(roomId);\n const { preventUnsavedComposerChanges } = useLiveblocksUIConfig();\n const hasResolveMentionSuggestions =\n useResolveMentionSuggestions() !== undefined;\n const isEmptyRef = useRef(true);\n const isEmojiPickerOpenRef = useRef(false);\n const $ = useOverrides(overrides);\n const [isCollapsed, onCollapsedChange] = useControllableState(\n // If the composer is neither controlled nor uncontrolled, it defaults to controlled as uncollapsed.\n controlledCollapsed === undefined && defaultCollapsed === undefined\n ? false\n : controlledCollapsed,\n controlledOnCollapsedChange,\n defaultCollapsed\n );\n\n const canCommentFallback = useSyncExternalStore(\n useCallback(\n (callback) => {\n if (room === null) return () => {};\n return room.events.self.subscribeOnce(callback);\n },\n [room]\n ),\n useCallback(() => {\n return room?.getSelf()?.canComment ?? true;\n }, [room]),\n useCallback(() => true, [])\n );\n\n const permissions = useRoomPermissions(roomId);\n const canComment =\n permissions.size > 0\n ? permissions.has(Permission.CommentsWrite) ||\n permissions.has(Permission.Write)\n : canCommentFallback;\n\n const setEmptyRef = useCallback((isEmpty: boolean) => {\n isEmptyRef.current = isEmpty;\n }, []);\n\n const setEmojiPickerOpenRef = useCallback((isEmojiPickerOpen: boolean) => {\n isEmojiPickerOpenRef.current = isEmojiPickerOpen;\n }, []);\n\n const handleFocus = useCallback(\n (event: FocusEvent<HTMLFormElement>) => {\n onFocus?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (isEmptyRef.current && canComment) {\n onCollapsedChange?.(false);\n }\n },\n [onCollapsedChange, onFocus, canComment]\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLFormElement>) => {\n onBlur?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n const isOutside = !event.currentTarget.contains(\n event.relatedTarget ?? document.activeElement\n );\n\n if (isOutside && isEmptyRef.current && !isEmojiPickerOpenRef.current) {\n onCollapsedChange?.(true);\n }\n },\n [onBlur, onCollapsedChange]\n );\n\n const handleEditorClick = useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n event.stopPropagation();\n\n if (isEmptyRef.current && canComment) {\n onCollapsedChange?.(false);\n }\n },\n [onCollapsedChange, canComment]\n );\n\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.stopPropagation();\n\n if (commentId && threadId) {\n editComment({\n commentId,\n threadId,\n body: comment.body,\n attachments: comment.attachments,\n });\n } else if (threadId) {\n createComment({\n threadId,\n body: comment.body,\n attachments: comment.attachments,\n });\n } else {\n createThread({\n body: comment.body,\n metadata: metadata ?? {},\n attachments: comment.attachments,\n });\n }\n },\n [\n commentId,\n createComment,\n createThread,\n editComment,\n metadata,\n onComposerSubmit,\n threadId,\n ]\n );\n\n return (\n <TooltipProvider>\n <ComposerPrimitive.Form\n onComposerSubmit={handleComposerSubmit}\n className={classNames(\n \"lb-root lb-composer lb-composer-form\",\n className\n )}\n dir={$.dir}\n {...props}\n ref={forwardedRef}\n data-collapsed={isCollapsed ? \"\" : undefined}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={disabled || !canComment}\n defaultAttachments={defaultAttachments}\n pasteFilesAsAttachments={showAttachments}\n preventUnsavedChanges={preventUnsavedComposerChanges}\n roomId={roomId}\n >\n <ComposerEditorContainer\n defaultValue={defaultValue}\n actions={actions}\n overrides={overrides}\n isCollapsed={isCollapsed}\n showAttachments={showAttachments}\n showAttribution={showAttribution}\n showFormattingControls={showFormattingControls}\n hasResolveMentionSuggestions={hasResolveMentionSuggestions}\n onEmptyChange={setEmptyRef}\n onEmojiPickerOpenChange={setEmojiPickerOpenRef}\n onEditorClick={handleEditorClick}\n autoFocus={autoFocus}\n disabled={disabled}\n />\n </ComposerPrimitive.Form>\n </TooltipProvider>\n );\n }\n) as <M extends BaseMetadata = DM>(\n props: ComposerProps<M> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoOA;AAA2C;AACzC;AACA;AACA;AACA;AAEF;AACE;AAEA;AACE;AAAqB;AAGvB;AAAoB;AAEhB;AAEA;AACE;AACA;AAAc;AAChB;AACF;AACuB;AAGzB;AACG;AAAiC;AAC/B;AAC6D;AAC7C;AACN;AACG;AACO;AACf;AACN;AAGN;AAEA;AAAyC;AACvC;AACA;AACA;AACA;AAEF;AACE;AAEA;AACE;AAAqB;AAGvB;AACE;AAAsB;AAGxB;AACG;AAA2B;AAA0B;AACnD;AAAiC;AAC/B;AAA0B;AACxB;AAC6D;AAC7C;AACN;AACG;AACK;AACb;AACN;AACF;AACF;AAGN;AAEA;AAAyC;AACvC;AACA;AACA;AAEF;AACE;AACE;AAAqB;AAGvB;AACE;AAAsB;AAGxB;AACG;AAAiC;AAC/B;AAAqC;AACnC;AAC6D;AAC7C;AACN;AACG;AACU;AAClB;AACN;AACF;AAGN;AAEA;AACE;AACG;AAAoC;AAClC;AAAA;AACA;AAAK;AAAgB;AAAA;AAG5B;AAEA;AAAoC;AAEpC;AACE;AACG;AAAwC;AACtC;AAA4C;AAExC;AAEW;AACH;AAEP;AAAC;AACC;AACU;AACZ;AACC;AACC;AACU;AACZ;AAAA;AAEH;AACH;AAGN;AAEA;AAAoB;AAClB;AACA;AACA;AACA;AAEF;AACE;AACA;AACE;AAAkC;AAGpC;AACG;AACU;AACT;AAC2C;AAE1C;AAA6B;AAAmB;AAAK;AACnD;AAAmB;AAAe;AAAU;AAC1C;AACH;AACF;AAGN;AAMA;AAAiC;AAClB;AAAgB;AAAgB;AAAwB;AAAI;AAEtE;AAAgB;AAAkB;AAA0B;AAAI;AAGhE;AACM;AACI;AACgB;AAC3B;AAEW;AAAgB;AAAgB;AAAwB;AACvE;AAEA;AAIA;AACE;AACG;AAA4C;AAC1C;AAGP;AAEA;AACE;AACG;AAAuB;AAAsB;AAC3C;AAGP;AAWA;AAAgC;AAC9B;AACA;AACA;AAEF;AACE;AACA;AAEA;AACE;AAA8B;AAGhC;AACG;AAC0D;AACrD;AACJ;AACe;AACK;AACpB;AACA;AAGN;AAEA;AAA6B;AAC3B;AACA;AAEF;AACE;AAEA;AACE;AAAO;AAGT;AACG;AAC2D;AACtD;AAEH;AAAc;AAEX;AACG;AAEC;AACA;AACF;AAEH;AACH;AAGN;AAEA;AAA2D;AAChD;AACW;AAEtB;AAEA;AAAiC;AACb;AACO;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AACA;AACA;AACA;AACE;AAAO;AACF;AAGC;AACN;AAGF;AAAuE;AAC/C;AAGxB;AACE;AAAqB;AAGvB;AACE;AAAqB;AAGvB;AACE;AAAsB;AAGxB;AACG;AAAc;AAAmC;AAChD;AAAC;AACW;AACD;AACM;AACf;AACA;AACA;AACA;AACO;AACT;AACqB;AAAoB;AAAsB;AAE5D;AAAc;AACb;AAAC;AAAc;AACZ;AACE;AACU;AACT;AACF;AAED;AACU;AACW;AACpB;AACF;AAEG;AACU;AACT;AACF;AAAA;AAEJ;AACiC;AAChC;AAAc;AAEX;AACG;AAA2B;AAAwB;AACjD;AAAgC;AAC9B;AACgB;AACN;AACC;AACF;AACM;AACE;AAClB;AACF;AACF;AACF;AAEJ;AAAA;AACF;AAGC;AAAc;AACZ;AAAc;AACb;AAAgB;AACb;AAAA;AACL;AACF;AAAA;AAIR;AAEa;AAQN;AAAiB;AAEpB;AACE;AACA;AACA;AACA;AACA;AACA;AACW;AACX;AACmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACkB;AACO;AACzB;AACQ;AACL;AAIL;AAEA;AACA;AACE;AAAU;AACR;AACF;AAGF;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAyC;AAInC;AACJ;AACA;AAGF;AAA2B;AACzB;AAEI;AAAmB;AAAa;AAChC;AAA8C;AAChD;AACK;AACP;AAEE;AAAsC;AAC/B;AACiB;AAG5B;AACA;AAMA;AACE;AAAqB;AAGvB;AACE;AAA+B;AAGjC;AAAoB;AAEhB;AAEA;AACE;AAAA;AAGF;AACE;AAAyB;AAC3B;AACF;AACuC;AAGzC;AAAmB;AAEf;AAEA;AACE;AAAA;AAGF;AAAuC;AACL;AAGlC;AACE;AAAwB;AAC1B;AACF;AAC0B;AAG5B;AAA0B;AAEtB;AAEA;AACE;AAAyB;AAC3B;AACF;AAC8B;AAGhC;AAA6B;AAEzB;AAEA;AACE;AAAA;AAGF;AAEA;AACE;AAAY;AACV;AACA;AACc;AACO;AACtB;AAED;AAAc;AACZ;AACc;AACO;AACtB;AAED;AAAa;AACG;AACS;AACF;AACtB;AACH;AACF;AACA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF;AAGF;AACG;AACE;AACmB;AACP;AACT;AACA;AACF;AACO;AACH;AACC;AAC8B;AAC1B;AACD;AACe;AACvB;AACyB;AACF;AACvB;AAEC;AACC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe;AACU;AACV;AACf;AACA;AACF;AACF;AACF;AAGN;;"}
1
+ {"version":3,"file":"Composer.js","sources":["../../src/components/Composer.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n BaseMetadata,\n CommentAttachment,\n CommentMixedAttachment,\n DM,\n} from \"@liveblocks/core\";\nimport { assertNever, Permission } from \"@liveblocks/core\";\nimport { useRoom } from \"@liveblocks/react\";\nimport {\n useCreateRoomComment,\n useCreateRoomThread,\n useEditRoomComment,\n useLayoutEffect,\n useResolveMentionSuggestions,\n useRoomPermissions,\n} from \"@liveblocks/react/_private\";\nimport type {\n ComponentPropsWithoutRef,\n ComponentType,\n FocusEvent,\n FormEvent,\n ForwardedRef,\n MouseEvent,\n PropsWithChildren,\n ReactNode,\n RefAttributes,\n SyntheticEvent,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\n\nimport { useLiveblocksUiConfig } from \"../config\";\nimport { FLOATING_ELEMENT_SIDE_OFFSET, MENTION_CHARACTER } from \"../constants\";\nimport { AttachmentIcon } from \"../icons/Attachment\";\nimport { BoldIcon } from \"../icons/Bold\";\nimport { CodeIcon } from \"../icons/Code\";\nimport { EmojiIcon } from \"../icons/Emoji\";\nimport { ItalicIcon } from \"../icons/Italic\";\nimport { MentionIcon } from \"../icons/Mention\";\nimport { SendIcon } from \"../icons/Send\";\nimport { StrikethroughIcon } from \"../icons/Strikethrough\";\nimport type { ComposerOverrides, GlobalOverrides } from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport {\n useComposer,\n useComposerAttachmentsContext,\n useComposerEditorContext,\n} from \"../primitives/Composer/contexts\";\nimport type {\n ComposerEditorComponents,\n ComposerEditorLinkProps,\n ComposerEditorMentionProps,\n ComposerEditorMentionSuggestionsProps,\n ComposerEditorProps,\n ComposerFormProps,\n ComposerMarkToggleProps,\n ComposerSubmitComment,\n} from \"../primitives/Composer/types\";\nimport { useComposerAttachmentsDropArea } from \"../primitives/Composer/utils\";\nimport type { ComposerBodyMark } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport { FileAttachment } from \"./internal/Attachment\";\nimport { Attribution } from \"./internal/Attribution\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport type { EmojiPickerProps } from \"./internal/EmojiPicker\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { ShortcutTooltip, Tooltip, TooltipProvider } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\ninterface EditorActionProps extends ComponentPropsWithoutRef<\"button\"> {\n label: string;\n tooltipLabel?: string;\n}\n\ninterface EmojiEditorActionProps extends EditorActionProps {\n onPickerOpenChange?: EmojiPickerProps[\"onOpenChange\"];\n}\n\ninterface MarkToggleProps extends ComposerMarkToggleProps {\n icon?: ReactNode;\n shortcut?: string;\n}\n\ntype ComposerCreateThreadProps<M extends BaseMetadata> = {\n threadId?: never;\n commentId?: never;\n\n /**\n * The metadata of the thread to create.\n */\n metadata?: M;\n};\n\ntype ComposerCreateCommentProps = {\n /**\n * The ID of the thread to reply to.\n */\n threadId: string;\n commentId?: never;\n metadata?: never;\n};\n\ntype ComposerEditCommentProps = {\n /**\n * The ID of the thread to edit a comment in.\n */\n threadId: string;\n\n /**\n * The ID of the comment to edit.\n */\n commentId: string;\n metadata?: never;\n};\n\nexport type ComposerProps<M extends BaseMetadata = DM> = Omit<\n ComponentPropsWithoutRef<\"form\">,\n \"defaultValue\"\n> &\n (\n | ComposerCreateThreadProps<M>\n | ComposerCreateCommentProps\n | ComposerEditCommentProps\n ) & {\n /**\n * The event handler called when the composer is submitted.\n */\n onComposerSubmit?: (\n comment: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => Promise<void> | void;\n\n /**\n * The composer's initial value.\n */\n defaultValue?: ComposerEditorProps[\"defaultValue\"];\n\n /**\n * The composer's initial attachments.\n */\n defaultAttachments?: CommentAttachment[];\n\n /**\n * Whether the composer is collapsed. Setting a value will make the composer controlled.\n */\n collapsed?: boolean;\n\n /**\n * The event handler called when the collapsed state of the composer changes.\n */\n onCollapsedChange?: (collapsed: boolean) => void;\n\n /**\n * Whether the composer is initially collapsed. Setting a value will make the composer uncontrolled.\n */\n defaultCollapsed?: boolean;\n\n /**\n * Whether to show and allow adding attachments.\n */\n showAttachments?: boolean;\n\n /**\n * Whether to show formatting controls (e.g. a floating toolbar with formatting toggles when selecting text)\n */\n showFormattingControls?: boolean;\n\n /**\n * Whether the composer is disabled.\n */\n disabled?: ComposerFormProps[\"disabled\"];\n\n /**\n * Whether to focus the composer on mount.\n */\n autoFocus?: ComposerEditorProps[\"autoFocus\"];\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n actions?: ReactNode;\n\n /**\n * @internal\n */\n showAttribution?: boolean;\n\n /**\n * @internal\n */\n roomId?: string;\n };\n\ninterface ComposerEditorContainerProps\n extends Pick<\n ComposerProps,\n | \"defaultValue\"\n | \"showAttachments\"\n | \"showFormattingControls\"\n | \"showAttribution\"\n | \"overrides\"\n | \"actions\"\n | \"autoFocus\"\n | \"disabled\"\n > {\n isCollapsed: boolean | undefined;\n onEmptyChange: (isEmpty: boolean) => void;\n hasResolveMentionSuggestions: boolean;\n onEmojiPickerOpenChange: (isOpen: boolean) => void;\n onEditorClick: (event: MouseEvent<HTMLDivElement>) => void;\n}\n\nfunction ComposerInsertMentionEditorAction({\n label,\n tooltipLabel,\n className,\n onClick,\n ...props\n}: EditorActionProps) {\n const { createMention } = useComposer();\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (!event.isDefaultPrevented()) {\n event.stopPropagation();\n createMention();\n }\n },\n [createMention, onClick]\n );\n\n return (\n <Tooltip content={tooltipLabel ?? label}>\n <Button\n className={cn(\"lb-composer-editor-action\", className)}\n onPointerDown={preventDefault}\n onClick={handleClick}\n aria-label={label}\n icon={<MentionIcon />}\n {...props}\n />\n </Tooltip>\n );\n}\n\nfunction ComposerInsertEmojiEditorAction({\n label,\n tooltipLabel,\n onPickerOpenChange,\n className,\n ...props\n}: EmojiEditorActionProps) {\n const { insertText } = useComposer();\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <EmojiPicker onEmojiSelect={insertText} onOpenChange={onPickerOpenChange}>\n <Tooltip content={tooltipLabel ?? label}>\n <EmojiPickerTrigger asChild>\n <Button\n className={cn(\"lb-composer-editor-action\", className)}\n onPointerDown={preventDefault}\n onClick={stopPropagation}\n aria-label={label}\n icon={<EmojiIcon />}\n {...props}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n );\n}\n\nfunction ComposerAttachFilesEditorAction({\n label,\n tooltipLabel,\n className,\n ...props\n}: EditorActionProps) {\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <Tooltip content={tooltipLabel ?? label}>\n <ComposerPrimitive.AttachFiles asChild>\n <Button\n className={cn(\"lb-composer-editor-action\", className)}\n onPointerDown={preventDefault}\n onClick={stopPropagation}\n aria-label={label}\n icon={<AttachmentIcon />}\n {...props}\n />\n </ComposerPrimitive.AttachFiles>\n </Tooltip>\n );\n}\n\nfunction ComposerMention({ mention }: ComposerEditorMentionProps) {\n switch (mention.kind) {\n case \"user\":\n return (\n <ComposerPrimitive.Mention className=\"lb-composer-mention\">\n {MENTION_CHARACTER}\n <User userId={mention.id} />\n </ComposerPrimitive.Mention>\n );\n\n default:\n return assertNever(mention.kind, \"Unhandled mention kind\");\n }\n}\n\nfunction ComposerMentionSuggestions({\n mentions,\n}: ComposerEditorMentionSuggestionsProps) {\n return mentions.length > 0 ? (\n <ComposerPrimitive.Suggestions className=\"lb-root lb-portal lb-elevation lb-composer-suggestions lb-composer-mention-suggestions\">\n <ComposerPrimitive.SuggestionsList className=\"lb-composer-suggestions-list lb-composer-mention-suggestions-list\">\n {mentions.map((mention) => {\n switch (mention.kind) {\n case \"user\":\n return (\n <ComposerPrimitive.SuggestionsListItem\n key={mention.id}\n className=\"lb-composer-suggestions-list-item lb-composer-mention-suggestion\"\n value={mention.id}\n >\n <Avatar\n userId={mention.id}\n className=\"lb-composer-mention-suggestion-avatar\"\n />\n <User\n userId={mention.id}\n className=\"lb-composer-mention-suggestion-user\"\n />\n </ComposerPrimitive.SuggestionsListItem>\n );\n\n default:\n return assertNever(mention.kind, \"Unhandled mention kind\");\n }\n })}\n </ComposerPrimitive.SuggestionsList>\n </ComposerPrimitive.Suggestions>\n ) : null;\n}\n\nfunction MarkToggle({\n mark,\n icon,\n shortcut,\n children,\n ...props\n}: MarkToggleProps) {\n const $ = useOverrides();\n const label = useMemo(() => {\n return $.COMPOSER_TOGGLE_MARK(mark);\n }, [$, mark]);\n\n return (\n <ShortcutTooltip\n content={label}\n shortcut={shortcut}\n sideOffset={FLOATING_ELEMENT_SIDE_OFFSET + 2}\n >\n <ComposerPrimitive.MarkToggle mark={mark} asChild {...props}>\n <Button aria-label={label} variant=\"toolbar\" icon={icon}>\n {children}\n </Button>\n </ComposerPrimitive.MarkToggle>\n </ShortcutTooltip>\n );\n}\n\ntype MarkToggles = {\n [K in ComposerBodyMark]: ComponentType<PropsWithChildren>;\n};\n\nconst markToggles: MarkToggles = {\n bold: () => <MarkToggle mark=\"bold\" shortcut=\"Mod-B\" icon={<BoldIcon />} />,\n italic: () => (\n <MarkToggle mark=\"italic\" shortcut=\"Mod-I\" icon={<ItalicIcon />} />\n ),\n strikethrough: () => (\n <MarkToggle\n mark=\"strikethrough\"\n shortcut=\"Mod-Shift-S\"\n icon={<StrikethroughIcon />}\n />\n ),\n code: () => <MarkToggle mark=\"code\" shortcut=\"Mod-E\" icon={<CodeIcon />} />,\n};\n\nconst markTogglesList = Object.entries(markToggles).map(([mark, Toggle]) => (\n <Toggle key={mark} />\n));\n\nfunction ComposerFloatingToolbar() {\n return (\n <ComposerPrimitive.FloatingToolbar className=\"lb-root lb-portal lb-elevation lb-composer-floating-toolbar\">\n {markTogglesList}\n </ComposerPrimitive.FloatingToolbar>\n );\n}\n\nfunction ComposerLink({ href, children }: ComposerEditorLinkProps) {\n return (\n <ComposerPrimitive.Link href={href} className=\"lb-composer-link\">\n {children}\n </ComposerPrimitive.Link>\n );\n}\n\ninterface ComposerAttachmentsProps extends ComponentPropsWithoutRef<\"div\"> {\n overrides?: Partial<GlobalOverrides & ComposerOverrides>;\n}\n\ninterface ComposerFileAttachmentProps extends ComponentPropsWithoutRef<\"div\"> {\n attachment: CommentMixedAttachment;\n overrides?: Partial<GlobalOverrides & ComposerOverrides>;\n}\n\nfunction ComposerFileAttachment({\n attachment,\n className,\n overrides,\n ...props\n}: ComposerFileAttachmentProps) {\n const { removeAttachment } = useComposer();\n const { roomId } = useComposerEditorContext();\n\n const handleDeleteClick = useCallback(() => {\n removeAttachment(attachment.id);\n }, [attachment.id, removeAttachment]);\n\n return (\n <FileAttachment\n className={cn(\"lb-composer-attachment\", className)}\n {...props}\n attachment={attachment}\n onDeleteClick={handleDeleteClick}\n preventFocusOnDelete\n overrides={overrides}\n roomId={roomId}\n />\n );\n}\n\nfunction ComposerAttachments({\n overrides,\n className,\n ...props\n}: ComposerAttachmentsProps) {\n const { attachments } = useComposer();\n\n if (attachments.length === 0) {\n return null;\n }\n\n return (\n <div className={cn(\"lb-composer-attachments\", className)} {...props}>\n <div className=\"lb-attachments\">\n {attachments.map((attachment) => {\n return (\n <ComposerFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n />\n );\n })}\n </div>\n </div>\n );\n}\n\nconst editorRequiredComponents: ComposerEditorComponents = {\n Mention: ComposerMention,\n MentionSuggestions: ComposerMentionSuggestions,\n Link: ComposerLink,\n};\n\nfunction ComposerEditorContainer({\n showAttachments = true,\n showFormattingControls = true,\n showAttribution,\n defaultValue,\n isCollapsed,\n overrides,\n actions,\n autoFocus,\n disabled,\n hasResolveMentionSuggestions,\n onEmojiPickerOpenChange,\n onEmptyChange,\n onEditorClick,\n}: ComposerEditorContainerProps) {\n const { isEmpty } = useComposer();\n const { hasMaxAttachments } = useComposerAttachmentsContext();\n const $ = useOverrides(overrides);\n const components = useMemo(() => {\n return {\n ...editorRequiredComponents,\n FloatingToolbar: showFormattingControls\n ? ComposerFloatingToolbar\n : undefined,\n };\n }, [showFormattingControls]);\n\n const [isDraggingOver, dropAreaProps] = useComposerAttachmentsDropArea({\n disabled: disabled || hasMaxAttachments,\n });\n\n useLayoutEffect(() => {\n onEmptyChange(isEmpty);\n }, [isEmpty, onEmptyChange]);\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n return (\n <div className=\"lb-composer-editor-container\" {...dropAreaProps}>\n <ComposerPrimitive.Editor\n className=\"lb-composer-editor\"\n onClick={onEditorClick}\n placeholder={$.COMPOSER_PLACEHOLDER}\n defaultValue={defaultValue}\n autoFocus={autoFocus}\n components={components}\n disabled={disabled}\n dir={$.dir}\n />\n {showAttachments && <ComposerAttachments overrides={overrides} />}\n {(!isCollapsed || isDraggingOver) && (\n <div className=\"lb-composer-footer\">\n <div className=\"lb-composer-editor-actions\">\n {hasResolveMentionSuggestions && (\n <ComposerInsertMentionEditorAction\n label={$.COMPOSER_INSERT_MENTION}\n disabled={disabled}\n />\n )}\n <ComposerInsertEmojiEditorAction\n label={$.COMPOSER_INSERT_EMOJI}\n onPickerOpenChange={onEmojiPickerOpenChange}\n disabled={disabled}\n />\n {showAttachments && (\n <ComposerAttachFilesEditorAction\n label={$.COMPOSER_ATTACH_FILES}\n disabled={disabled}\n />\n )}\n </div>\n {showAttribution && <Attribution />}\n <div className=\"lb-composer-actions\">\n {actions ?? (\n <>\n <ShortcutTooltip content={$.COMPOSER_SEND} shortcut=\"Enter\">\n <ComposerPrimitive.Submit asChild>\n <Button\n onPointerDown={preventDefault}\n onClick={stopPropagation}\n className=\"lb-composer-action\"\n variant=\"primary\"\n aria-label={$.COMPOSER_SEND}\n icon={<SendIcon />}\n />\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n )}\n </div>\n </div>\n )}\n {showAttachments && isDraggingOver && (\n <div className=\"lb-composer-attachments-drop-area\">\n <div className=\"lb-composer-attachments-drop-area-label\">\n <AttachmentIcon />\n {$.COMPOSER_ATTACH_FILES}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport const ComposerRoomIdContext = createContext<string | null>(null);\n\n/**\n * Displays a composer to create comments.\n *\n * @example\n * <Composer />\n */\nexport const Composer = forwardRef(\n <M extends BaseMetadata = DM>(\n {\n threadId,\n commentId,\n metadata,\n defaultValue,\n defaultAttachments,\n onComposerSubmit,\n collapsed: controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange: controlledOnCollapsedChange,\n overrides,\n actions,\n onBlur,\n className,\n onFocus,\n autoFocus,\n disabled,\n showAttachments = true,\n showFormattingControls = true,\n showAttribution,\n roomId: _roomId,\n ...props\n }: ComposerProps<M>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const room = useRoom({ allowOutsideRoom: true });\n\n const roomId = _roomId !== undefined ? _roomId : room?.id;\n if (roomId === undefined) {\n throw new Error(\n \"Composer must be a descendant of RoomProvider component\"\n );\n }\n\n const createThread = useCreateRoomThread(roomId);\n const createComment = useCreateRoomComment(roomId);\n const editComment = useEditRoomComment(roomId);\n const { preventUnsavedComposerChanges } = useLiveblocksUiConfig();\n const hasResolveMentionSuggestions =\n useResolveMentionSuggestions() !== undefined;\n const isEmptyRef = useRef(true);\n const isEmojiPickerOpenRef = useRef(false);\n const $ = useOverrides(overrides);\n const [isCollapsed, onCollapsedChange] = useControllableState(\n defaultCollapsed ?? false,\n controlledCollapsed,\n controlledOnCollapsedChange\n );\n\n const canCommentFallback = useSyncExternalStore(\n useCallback(\n (callback) => {\n if (room === null) return () => {};\n return room.events.self.subscribeOnce(callback);\n },\n [room]\n ),\n useCallback(() => {\n return room?.getSelf()?.canComment ?? true;\n }, [room]),\n useCallback(() => true, [])\n );\n\n const permissions = useRoomPermissions(roomId);\n const canComment =\n permissions.size > 0\n ? permissions.has(Permission.CommentsWrite) ||\n permissions.has(Permission.Write)\n : canCommentFallback;\n\n const setEmptyRef = useCallback((isEmpty: boolean) => {\n isEmptyRef.current = isEmpty;\n }, []);\n\n const setEmojiPickerOpenRef = useCallback((isEmojiPickerOpen: boolean) => {\n isEmojiPickerOpenRef.current = isEmojiPickerOpen;\n }, []);\n\n const handleFocus = useCallback(\n (event: FocusEvent<HTMLFormElement>) => {\n onFocus?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (isEmptyRef.current && canComment) {\n onCollapsedChange?.(false);\n }\n },\n [onCollapsedChange, onFocus, canComment]\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLFormElement>) => {\n onBlur?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n const isOutside = !event.currentTarget.contains(\n event.relatedTarget ?? document.activeElement\n );\n\n if (isOutside && isEmptyRef.current && !isEmojiPickerOpenRef.current) {\n onCollapsedChange?.(true);\n }\n },\n [onBlur, onCollapsedChange]\n );\n\n const handleEditorClick = useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n event.stopPropagation();\n\n if (isEmptyRef.current && canComment) {\n onCollapsedChange?.(false);\n }\n },\n [onCollapsedChange, canComment]\n );\n\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.stopPropagation();\n\n if (commentId && threadId) {\n editComment({\n commentId,\n threadId,\n body: comment.body,\n attachments: comment.attachments,\n });\n } else if (threadId) {\n createComment({\n threadId,\n body: comment.body,\n attachments: comment.attachments,\n });\n } else {\n createThread({\n body: comment.body,\n metadata: metadata ?? {},\n attachments: comment.attachments,\n });\n }\n },\n [\n commentId,\n createComment,\n createThread,\n editComment,\n metadata,\n onComposerSubmit,\n threadId,\n ]\n );\n\n return (\n <TooltipProvider>\n <ComposerPrimitive.Form\n onComposerSubmit={handleComposerSubmit}\n className={cn(\"lb-root lb-composer lb-composer-form\", className)}\n dir={$.dir}\n {...props}\n ref={forwardedRef}\n data-collapsed={isCollapsed ? \"\" : undefined}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={disabled || !canComment}\n defaultAttachments={defaultAttachments}\n pasteFilesAsAttachments={showAttachments}\n preventUnsavedChanges={preventUnsavedComposerChanges}\n roomId={roomId}\n >\n <ComposerEditorContainer\n defaultValue={defaultValue}\n actions={actions}\n overrides={overrides}\n isCollapsed={isCollapsed}\n showAttachments={showAttachments}\n showAttribution={showAttribution}\n showFormattingControls={showFormattingControls}\n hasResolveMentionSuggestions={hasResolveMentionSuggestions}\n onEmptyChange={setEmptyRef}\n onEmojiPickerOpenChange={setEmojiPickerOpenRef}\n onEditorClick={handleEditorClick}\n autoFocus={autoFocus}\n disabled={disabled}\n />\n </ComposerPrimitive.Form>\n </TooltipProvider>\n );\n }\n) as <M extends BaseMetadata = DM>(\n props: ComposerProps<M> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoOA;AAA2C;AACzC;AACA;AACA;AACA;AAEF;AACE;AAEA;AACE;AAAqB;AAGvB;AAAoB;AAEhB;AAEA;AACE;AACA;AAAc;AAChB;AACF;AACuB;AAGzB;AACG;AAAiC;AAC/B;AACqD;AACrC;AACN;AACG;AACO;AACf;AACN;AAGN;AAEA;AAAyC;AACvC;AACA;AACA;AACA;AAEF;AACE;AAEA;AACE;AAAqB;AAGvB;AACE;AAAsB;AAGxB;AACG;AAA2B;AAA0B;AACnD;AAAiC;AAC/B;AAA0B;AACxB;AACqD;AACrC;AACN;AACG;AACK;AACb;AACN;AACF;AACF;AAGN;AAEA;AAAyC;AACvC;AACA;AACA;AAEF;AACE;AACE;AAAqB;AAGvB;AACE;AAAsB;AAGxB;AACG;AAAiC;AAC/B;AAAqC;AACnC;AACqD;AACrC;AACN;AACG;AACU;AAClB;AACN;AACF;AAGN;AAEA;AACE;AAAsB;AAElB;AACG;AAAoC;AAClC;AAAA;AACA;AAAqB;AAAI;AAAA;AAC5B;AAIF;AAAyD;AAE/D;AAEA;AAAoC;AAEpC;AACE;AACG;AAAwC;AACtC;AAA4C;AAEzC;AAAsB;AAElB;AACG;AAEW;AACK;AAEf;AAAC;AACiB;AACN;AACZ;AACC;AACiB;AACN;AACZ;AAAA;AACF;AAIF;AAAyD;AAC7D;AACD;AACH;AAGN;AAEA;AAAoB;AAClB;AACA;AACA;AACA;AAEF;AACE;AACA;AACE;AAAkC;AAGpC;AACG;AACU;AACT;AAC2C;AAE1C;AAA6B;AAAmB;AAAK;AACnD;AAAmB;AAAe;AAAU;AAC1C;AACH;AACF;AAGN;AAMA;AAAiC;AAClB;AAAgB;AAAgB;AAAwB;AAAI;AAEtE;AAAgB;AAAkB;AAA0B;AAAI;AAGhE;AACM;AACI;AACgB;AAC3B;AAEW;AAAgB;AAAgB;AAAwB;AACvE;AAEA;AAIA;AACE;AACG;AAA4C;AAC1C;AAGP;AAEA;AACE;AACG;AAAuB;AAAsB;AAC3C;AAGP;AAWA;AAAgC;AAC9B;AACA;AACA;AAEF;AACE;AACA;AAEA;AACE;AAA8B;AAGhC;AACG;AACkD;AAC7C;AACJ;AACe;AACK;AACpB;AACA;AAGN;AAEA;AAA6B;AAC3B;AACA;AAEF;AACE;AAEA;AACE;AAAO;AAGT;AACG;AAAsD;AAAO;AAC3D;AAAc;AAEX;AACG;AAEC;AACA;AACF;AAEH;AACH;AAGN;AAEA;AAA2D;AAChD;AACW;AAEtB;AAEA;AAAiC;AACb;AACO;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEF;AACE;AACA;AACA;AACA;AACE;AAAO;AACF;AAGC;AACN;AAGF;AAAuE;AAC/C;AAGxB;AACE;AAAqB;AAGvB;AACE;AAAqB;AAGvB;AACE;AAAsB;AAGxB;AACG;AAAc;AAAmC;AAChD;AAAC;AACW;AACD;AACM;AACf;AACA;AACA;AACA;AACO;AACT;AACqB;AAAoB;AAAsB;AAE5D;AAAc;AACb;AAAC;AAAc;AACZ;AACE;AACU;AACT;AACF;AAED;AACU;AACW;AACpB;AACF;AAEG;AACU;AACT;AACF;AAAA;AAEJ;AACiC;AAChC;AAAc;AAEX;AACG;AAA2B;AAAwB;AACjD;AAAgC;AAC9B;AACgB;AACN;AACC;AACF;AACM;AACE;AAClB;AACF;AACF;AACF;AAEJ;AAAA;AACF;AAGC;AAAc;AACZ;AAAc;AACb;AAAgB;AACb;AAAA;AACL;AACF;AAAA;AAIR;AAEa;AAQN;AAAiB;AAEpB;AACE;AACA;AACA;AACA;AACA;AACA;AACW;AACX;AACmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACkB;AACO;AACzB;AACQ;AACL;AAIL;AAEA;AACA;AACE;AAAU;AACR;AACF;AAGF;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAyC;AACnB;AACpB;AACA;AAGF;AAA2B;AACzB;AAEI;AAAmB;AAAa;AAChC;AAA8C;AAChD;AACK;AACP;AAEE;AAAsC;AAC/B;AACiB;AAG5B;AACA;AAMA;AACE;AAAqB;AAGvB;AACE;AAA+B;AAGjC;AAAoB;AAEhB;AAEA;AACE;AAAA;AAGF;AACE;AAAyB;AAC3B;AACF;AACuC;AAGzC;AAAmB;AAEf;AAEA;AACE;AAAA;AAGF;AAAuC;AACL;AAGlC;AACE;AAAwB;AAC1B;AACF;AAC0B;AAG5B;AAA0B;AAEtB;AAEA;AACE;AAAyB;AAC3B;AACF;AAC8B;AAGhC;AAA6B;AAEzB;AAEA;AACE;AAAA;AAGF;AAEA;AACE;AAAY;AACV;AACA;AACc;AACO;AACtB;AAED;AAAc;AACZ;AACc;AACO;AACtB;AAED;AAAa;AACG;AACS;AACF;AACtB;AACH;AACF;AACA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF;AAGF;AACG;AACE;AACmB;AAC6C;AACxD;AACH;AACC;AAC8B;AAC1B;AACD;AACe;AACvB;AACyB;AACF;AACvB;AAEC;AACC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe;AACU;AACV;AACf;AACA;AACF;AACF;AACF;AAGN;;"}
@@ -5,7 +5,7 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
  var react = require('react');
6
6
  var overrides = require('../overrides.cjs');
7
7
  require('../primitives/index.cjs');
8
- var classNames = require('../utils/class-names.cjs');
8
+ var cn = require('../utils/cn.cjs');
9
9
  var List = require('./internal/List.cjs');
10
10
  var User = require('./internal/User.cjs');
11
11
  var Timestamp = require('../primitives/Timestamp.cjs');
@@ -16,7 +16,7 @@ const HistoryVersionSummary = react.forwardRef(({ version, selected, className,
16
16
  const $ = overrides.useOverrides();
17
17
  return /* @__PURE__ */ jsxRuntime.jsxs("button", {
18
18
  ...props,
19
- className: classNames.classNames("lb-root lb-history-version-summary", className),
19
+ className: cn.cn("lb-root lb-history-version-summary", className),
20
20
  ref: forwardedRef,
21
21
  "data-selected": selected ? "" : void 0,
22
22
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"HistoryVersionSummary.cjs","sources":["../../src/components/HistoryVersionSummary.tsx"],"sourcesContent":["\"use client\";\n\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { forwardRef } from \"react\";\n\nimport { useOverrides } from \"../overrides\";\nimport { Timestamp } from \"../primitives\";\nimport { classNames } from \"../utils/class-names\";\nimport { List } from \"./internal/List\";\nimport { User } from \"./internal/User\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionSummaryProps\n extends ComponentPropsWithoutRef<\"button\"> {\n version: HistoryVersion;\n selected?: boolean;\n}\n\n/**\n * Displays some information about a version.\n *\n * @example\n * <HistoryVersionSummary version={version} />\n */\nexport const HistoryVersionSummary = forwardRef<\n HTMLButtonElement,\n HistoryVersionSummaryProps\n>(({ version, selected, className, ...props }, forwardedRef) => {\n const $ = useOverrides();\n\n return (\n <button\n {...props}\n className={classNames(\"lb-root lb-history-version-summary\", className)}\n ref={forwardedRef}\n data-selected={selected ? \"\" : undefined}\n >\n <Timestamp\n locale={$.locale}\n date={version.createdAt}\n className=\"lb-date lb-history-version-summary-date\"\n />\n <span className=\"lb-history-version-summary-authors\">\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n </span>\n </button>\n );\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;AAYA;AAca;AAIX;AAEA;AACG;AACK;AACiE;AAChE;AAC0B;AAE/B;AAAC;AACW;AACI;AACJ;AACZ;AACC;AAAe;AACb;AAEI;AAAoC;AAAe;AACrD;AACkB;AACT;AACA;AACZ;AACF;AAAA;AAGN;;"}
1
+ {"version":3,"file":"HistoryVersionSummary.cjs","sources":["../../src/components/HistoryVersionSummary.tsx"],"sourcesContent":["\"use client\";\n\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { forwardRef } from \"react\";\n\nimport { useOverrides } from \"../overrides\";\nimport { Timestamp } from \"../primitives\";\nimport { cn } from \"../utils/cn\";\nimport { List } from \"./internal/List\";\nimport { User } from \"./internal/User\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionSummaryProps\n extends ComponentPropsWithoutRef<\"button\"> {\n version: HistoryVersion;\n selected?: boolean;\n}\n\n/**\n * Displays some information about a version.\n *\n * @example\n * <HistoryVersionSummary version={version} />\n */\nexport const HistoryVersionSummary = forwardRef<\n HTMLButtonElement,\n HistoryVersionSummaryProps\n>(({ version, selected, className, ...props }, forwardedRef) => {\n const $ = useOverrides();\n\n return (\n <button\n {...props}\n className={cn(\"lb-root lb-history-version-summary\", className)}\n ref={forwardedRef}\n data-selected={selected ? \"\" : undefined}\n >\n <Timestamp\n locale={$.locale}\n date={version.createdAt}\n className=\"lb-date lb-history-version-summary-date\"\n />\n <span className=\"lb-history-version-summary-authors\">\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n </span>\n </button>\n );\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;AAYA;AAca;AAIX;AAEA;AACG;AACK;AACyD;AACxD;AAC0B;AAE/B;AAAC;AACW;AACI;AACJ;AACZ;AACC;AAAe;AACb;AAEI;AAAoC;AAAe;AACrD;AACkB;AACT;AACA;AACZ;AACF;AAAA;AAGN;;"}
@@ -3,7 +3,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { forwardRef } from 'react';
4
4
  import { useOverrides } from '../overrides.js';
5
5
  import '../primitives/index.js';
6
- import { classNames } from '../utils/class-names.js';
6
+ import { cn } from '../utils/cn.js';
7
7
  import { List } from './internal/List.js';
8
8
  import { User } from './internal/User.js';
9
9
  import { Timestamp } from '../primitives/Timestamp.js';
@@ -14,7 +14,7 @@ const HistoryVersionSummary = forwardRef(({ version, selected, className, ...pro
14
14
  const $ = useOverrides();
15
15
  return /* @__PURE__ */ jsxs("button", {
16
16
  ...props,
17
- className: classNames("lb-root lb-history-version-summary", className),
17
+ className: cn("lb-root lb-history-version-summary", className),
18
18
  ref: forwardedRef,
19
19
  "data-selected": selected ? "" : void 0,
20
20
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"HistoryVersionSummary.js","sources":["../../src/components/HistoryVersionSummary.tsx"],"sourcesContent":["\"use client\";\n\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { forwardRef } from \"react\";\n\nimport { useOverrides } from \"../overrides\";\nimport { Timestamp } from \"../primitives\";\nimport { classNames } from \"../utils/class-names\";\nimport { List } from \"./internal/List\";\nimport { User } from \"./internal/User\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionSummaryProps\n extends ComponentPropsWithoutRef<\"button\"> {\n version: HistoryVersion;\n selected?: boolean;\n}\n\n/**\n * Displays some information about a version.\n *\n * @example\n * <HistoryVersionSummary version={version} />\n */\nexport const HistoryVersionSummary = forwardRef<\n HTMLButtonElement,\n HistoryVersionSummaryProps\n>(({ version, selected, className, ...props }, forwardedRef) => {\n const $ = useOverrides();\n\n return (\n <button\n {...props}\n className={classNames(\"lb-root lb-history-version-summary\", className)}\n ref={forwardedRef}\n data-selected={selected ? \"\" : undefined}\n >\n <Timestamp\n locale={$.locale}\n date={version.createdAt}\n className=\"lb-date lb-history-version-summary-date\"\n />\n <span className=\"lb-history-version-summary-authors\">\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n </span>\n </button>\n );\n});\n"],"names":[],"mappings":";;;;;;;;;;;AAYA;AAca;AAIX;AAEA;AACG;AACK;AACiE;AAChE;AAC0B;AAE/B;AAAC;AACW;AACI;AACJ;AACZ;AACC;AAAe;AACb;AAEI;AAAoC;AAAe;AACrD;AACkB;AACT;AACA;AACZ;AACF;AAAA;AAGN;;"}
1
+ {"version":3,"file":"HistoryVersionSummary.js","sources":["../../src/components/HistoryVersionSummary.tsx"],"sourcesContent":["\"use client\";\n\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { forwardRef } from \"react\";\n\nimport { useOverrides } from \"../overrides\";\nimport { Timestamp } from \"../primitives\";\nimport { cn } from \"../utils/cn\";\nimport { List } from \"./internal/List\";\nimport { User } from \"./internal/User\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionSummaryProps\n extends ComponentPropsWithoutRef<\"button\"> {\n version: HistoryVersion;\n selected?: boolean;\n}\n\n/**\n * Displays some information about a version.\n *\n * @example\n * <HistoryVersionSummary version={version} />\n */\nexport const HistoryVersionSummary = forwardRef<\n HTMLButtonElement,\n HistoryVersionSummaryProps\n>(({ version, selected, className, ...props }, forwardedRef) => {\n const $ = useOverrides();\n\n return (\n <button\n {...props}\n className={cn(\"lb-root lb-history-version-summary\", className)}\n ref={forwardedRef}\n data-selected={selected ? \"\" : undefined}\n >\n <Timestamp\n locale={$.locale}\n date={version.createdAt}\n className=\"lb-date lb-history-version-summary-date\"\n />\n <span className=\"lb-history-version-summary-authors\">\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n </span>\n </button>\n );\n});\n"],"names":[],"mappings":";;;;;;;;;;;AAYA;AAca;AAIX;AAEA;AACG;AACK;AACyD;AACxD;AAC0B;AAE/B;AAAC;AACW;AACI;AACJ;AACZ;AACC;AAAe;AACb;AAEI;AAAoC;AAAe;AACrD;AACkB;AACT;AACA;AACZ;AACF;AAAA;AAGN;;"}
@@ -3,15 +3,12 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var react = require('react');
6
- var classNames = require('../utils/class-names.cjs');
6
+ var cn = require('../utils/cn.cjs');
7
7
 
8
8
 
9
9
  const HistoryVersionSummaryList = react.forwardRef(({ children, className, ...props }, forwardedRef) => {
10
10
  return /* @__PURE__ */ jsxRuntime.jsx("ol", {
11
- className: classNames.classNames(
12
- "lb-root lb-history-version-summary-list",
13
- className
14
- ),
11
+ className: cn.cn("lb-root lb-history-version-summary-list", className),
15
12
  ...props,
16
13
  ref: forwardedRef,
17
14
  children: react.Children.map(children, (child, index) => /* @__PURE__ */ jsxRuntime.jsx("li", {
@@ -1 +1 @@
1
- {"version":3,"file":"HistoryVersionSummaryList.cjs","sources":["../../src/components/HistoryVersionSummaryList.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { Children, forwardRef } from \"react\";\n\nimport { classNames } from \"../utils/class-names\";\n\nexport type HistoryVersionSummaryListProps = ComponentPropsWithoutRef<\"ol\">;\n\n/**\n * Displays versions summaries as a list.\n *\n * @example\n * <HistoryVersionSummaryList>\n * {versions.map((version) => (\n * <HistoryVersionSummary key={version.id} version={version} />\n * ))}\n * </HistoryVersionSummaryList>\n */\nexport const HistoryVersionSummaryList = forwardRef<\n HTMLOListElement,\n HistoryVersionSummaryListProps\n>(({ children, className, ...props }, forwardedRef) => {\n return (\n <ol\n className={classNames(\n \"lb-root lb-history-version-summary-list\",\n className\n )}\n {...props}\n ref={forwardedRef}\n >\n {Children.map(children, (child, index) => (\n <li key={index} className=\"lb-history-version-summary-list-item\">\n {child}\n </li>\n ))}\n </ol>\n );\n});\n"],"names":[],"mappings":";;;;;;;;AAmBa;AAIX;AACG;AACY;AACT;AACA;AACF;AACI;AACC;AAGF;AAAyB;AACvB;AAEJ;AAGP;;"}
1
+ {"version":3,"file":"HistoryVersionSummaryList.cjs","sources":["../../src/components/HistoryVersionSummaryList.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { Children, forwardRef } from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nexport type HistoryVersionSummaryListProps = ComponentPropsWithoutRef<\"ol\">;\n\n/**\n * Displays versions summaries as a list.\n *\n * @example\n * <HistoryVersionSummaryList>\n * {versions.map((version) => (\n * <HistoryVersionSummary key={version.id} version={version} />\n * ))}\n * </HistoryVersionSummaryList>\n */\nexport const HistoryVersionSummaryList = forwardRef<\n HTMLOListElement,\n HistoryVersionSummaryListProps\n>(({ children, className, ...props }, forwardedRef) => {\n return (\n <ol\n className={cn(\"lb-root lb-history-version-summary-list\", className)}\n {...props}\n ref={forwardedRef}\n >\n {Children.map(children, (child, index) => (\n <li key={index} className=\"lb-history-version-summary-list-item\">\n {child}\n </li>\n ))}\n </ol>\n );\n});\n"],"names":[],"mappings":";;;;;;;;AAmBa;AAIX;AACG;AACmE;AAC9D;AACC;AAGF;AAAyB;AACvB;AAEJ;AAGP;;"}
@@ -1,15 +1,12 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
  import { forwardRef, Children } from 'react';
4
- import { classNames } from '../utils/class-names.js';
4
+ import { cn } from '../utils/cn.js';
5
5
 
6
6
 
7
7
  const HistoryVersionSummaryList = forwardRef(({ children, className, ...props }, forwardedRef) => {
8
8
  return /* @__PURE__ */ jsx("ol", {
9
- className: classNames(
10
- "lb-root lb-history-version-summary-list",
11
- className
12
- ),
9
+ className: cn("lb-root lb-history-version-summary-list", className),
13
10
  ...props,
14
11
  ref: forwardedRef,
15
12
  children: Children.map(children, (child, index) => /* @__PURE__ */ jsx("li", {
@@ -1 +1 @@
1
- {"version":3,"file":"HistoryVersionSummaryList.js","sources":["../../src/components/HistoryVersionSummaryList.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { Children, forwardRef } from \"react\";\n\nimport { classNames } from \"../utils/class-names\";\n\nexport type HistoryVersionSummaryListProps = ComponentPropsWithoutRef<\"ol\">;\n\n/**\n * Displays versions summaries as a list.\n *\n * @example\n * <HistoryVersionSummaryList>\n * {versions.map((version) => (\n * <HistoryVersionSummary key={version.id} version={version} />\n * ))}\n * </HistoryVersionSummaryList>\n */\nexport const HistoryVersionSummaryList = forwardRef<\n HTMLOListElement,\n HistoryVersionSummaryListProps\n>(({ children, className, ...props }, forwardedRef) => {\n return (\n <ol\n className={classNames(\n \"lb-root lb-history-version-summary-list\",\n className\n )}\n {...props}\n ref={forwardedRef}\n >\n {Children.map(children, (child, index) => (\n <li key={index} className=\"lb-history-version-summary-list-item\">\n {child}\n </li>\n ))}\n </ol>\n );\n});\n"],"names":[],"mappings":";;;;;;AAmBa;AAIX;AACG;AACY;AACT;AACA;AACF;AACI;AACC;AAGF;AAAyB;AACvB;AAEJ;AAGP;;"}
1
+ {"version":3,"file":"HistoryVersionSummaryList.js","sources":["../../src/components/HistoryVersionSummaryList.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { Children, forwardRef } from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nexport type HistoryVersionSummaryListProps = ComponentPropsWithoutRef<\"ol\">;\n\n/**\n * Displays versions summaries as a list.\n *\n * @example\n * <HistoryVersionSummaryList>\n * {versions.map((version) => (\n * <HistoryVersionSummary key={version.id} version={version} />\n * ))}\n * </HistoryVersionSummaryList>\n */\nexport const HistoryVersionSummaryList = forwardRef<\n HTMLOListElement,\n HistoryVersionSummaryListProps\n>(({ children, className, ...props }, forwardedRef) => {\n return (\n <ol\n className={cn(\"lb-root lb-history-version-summary-list\", className)}\n {...props}\n ref={forwardedRef}\n >\n {Children.map(children, (child, index) => (\n <li key={index} className=\"lb-history-version-summary-list-item\">\n {child}\n </li>\n ))}\n </ol>\n );\n});\n"],"names":[],"mappings":";;;;;;AAmBa;AAIX;AACG;AACmE;AAC9D;AACC;AAGF;AAAyB;AACvB;AAEJ;AAGP;;"}
@@ -18,7 +18,7 @@ var Warning = require('../icons/Warning.cjs');
18
18
  var overrides = require('../overrides.cjs');
19
19
  var Timestamp = require('../primitives/Timestamp.cjs');
20
20
  var shared = require('../shared.cjs');
21
- var classNames = require('../utils/class-names.cjs');
21
+ var cn = require('../utils/cn.cjs');
22
22
  var url = require('../utils/url.cjs');
23
23
  var Avatar = require('./internal/Avatar.cjs');
24
24
  var Button = require('./internal/Button.cjs');
@@ -97,7 +97,7 @@ const InboxNotificationLayout = react.forwardRef(
97
97
  }, [inboxNotification.id, deleteInboxNotification]);
98
98
  return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive.TooltipProvider, {
99
99
  children: /* @__PURE__ */ jsxRuntime.jsxs(Component, {
100
- className: classNames.classNames(
100
+ className: cn.cn(
101
101
  "lb-root lb-inbox-notification",
102
102
  showActions === "hover" && "lb-inbox-notification:show-actions-hover",
103
103
  isMoreActionOpen && "lb-inbox-notification:action-open",
@@ -200,7 +200,7 @@ function InboxNotificationIcon({
200
200
  ...props
201
201
  }) {
202
202
  return /* @__PURE__ */ jsxRuntime.jsx("div", {
203
- className: classNames.classNames("lb-inbox-notification-icon", className),
203
+ className: cn.cn("lb-inbox-notification-icon", className),
204
204
  ...props
205
205
  });
206
206
  }
@@ -209,7 +209,7 @@ function InboxNotificationAvatar({
209
209
  ...props
210
210
  }) {
211
211
  return /* @__PURE__ */ jsxRuntime.jsx(Avatar.Avatar, {
212
- className: classNames.classNames("lb-inbox-notification-avatar", className),
212
+ className: cn.cn("lb-inbox-notification-avatar", className),
213
213
  ...props
214
214
  });
215
215
  }