@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
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentType, ComponentPropsWithoutRef, ElementType, ReactNode, ComponentProps, FormEvent, RefAttributes, MouseEvent, PropsWithChildren } from 'react';
3
- import { CommentAttachment, AiKnowledgeSource, AiOpaqueToolDefinition, AiToolTypePack, JsonObject, ToolResultData, AiToolExecuteCallback, CommentBody, BaseMetadata, DM, CommentData, HistoryVersion, InboxNotificationData, InboxNotificationThreadData, InboxNotificationTextMentionData, InboxNotificationCustomData, KDAD, ThreadData } from '@liveblocks/core';
3
+ import { CommentAttachment, AiKnowledgeSource, AiOpaqueToolDefinition, AiToolTypePack, JsonObject, AiToolExecuteCallback, NoInfr, CommentBody, MentionData, BaseMetadata, DM, CommentData, HistoryVersion, InboxNotificationData, InboxNotificationThreadData, InboxNotificationTextMentionData, InboxNotificationCustomData, KDAD, ThreadData } from '@liveblocks/core';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
 
6
6
  interface GlobalComponents {
@@ -54,6 +54,7 @@ interface GlobalOverrides {
54
54
  EMOJI_PICKER_CHANGE_SKIN_TONE: string;
55
55
  ATTACHMENT_TOO_LARGE: (maxSize?: string) => string;
56
56
  ATTACHMENT_ERROR: (error: Error) => string;
57
+ COPY_TO_CLIPBOARD: string;
57
58
  }
58
59
  interface CommentOverrides {
59
60
  COMMENT_EDITED: ReactNode;
@@ -78,6 +79,10 @@ interface ComposerOverrides {
78
79
  COMPOSER_SEND: string;
79
80
  COMPOSER_TOGGLE_MARK: (mark: ComposerBodyMark) => string;
80
81
  }
82
+ interface AiToolConfirmationOverrides {
83
+ AI_TOOL_CONFIRMATION_CONFIRM: string;
84
+ AI_TOOL_CONFIRMATION_CANCEL: string;
85
+ }
81
86
  interface AiChatComposerOverrides {
82
87
  AI_CHAT_COMPOSER_PLACEHOLDER: string;
83
88
  AI_CHAT_COMPOSER_SEND: string;
@@ -86,6 +91,7 @@ interface AiChatComposerOverrides {
86
91
  interface AiChatMessageOverrides {
87
92
  AI_CHAT_MESSAGE_DELETED: string;
88
93
  AI_CHAT_MESSAGE_THINKING: string;
94
+ AI_CHAT_MESSAGE_REASONING: (isStreaming: boolean) => string;
89
95
  }
90
96
  interface AiChatOverrides {
91
97
  AI_CHAT_MESSAGES_ERROR: (error: Error) => ReactNode;
@@ -114,13 +120,28 @@ interface HistoryVersionPreviewOverrides {
114
120
  HISTORY_VERSION_PREVIEW_EMPTY: ReactNode;
115
121
  HISTORY_VERSION_PREVIEW_ERROR: (error: Error) => ReactNode;
116
122
  }
117
- type Overrides = LocalizationOverrides & GlobalOverrides & ComposerOverrides & CommentOverrides & ThreadOverrides & InboxNotificationOverrides & HistoryVersionPreviewOverrides & AiChatComposerOverrides & AiChatMessageOverrides & AiChatOverrides;
123
+ type Overrides = LocalizationOverrides & GlobalOverrides & ComposerOverrides & CommentOverrides & ThreadOverrides & InboxNotificationOverrides & HistoryVersionPreviewOverrides & AiChatComposerOverrides & AiChatMessageOverrides & AiChatOverrides & AiToolConfirmationOverrides;
118
124
  declare function useOverrides(overrides?: Partial<Overrides>): Overrides;
119
125
 
120
- type AiChatComponentsEmptyProps = Record<string, never>;
126
+ type AiChatComponentsEmptyProps = {
127
+ /**
128
+ * The chat id provided to the `AiChat` component.
129
+ */
130
+ chatId: string;
131
+ /**
132
+ * The copilot id provided to the `AiChat` component.
133
+ */
134
+ copilotId?: string;
135
+ };
121
136
  type AiChatComponentsLoadingProps = Record<string, never>;
122
137
  type AiChatComponents = {
138
+ /**
139
+ * The component used to render the empty state of the chat.
140
+ */
123
141
  Empty: ComponentType<AiChatComponentsEmptyProps>;
142
+ /**
143
+ * The component used to render the loading state of the chat.
144
+ */
124
145
  Loading: ComponentType<AiChatComponentsLoadingProps>;
125
146
  };
126
147
  interface AiChatProps extends ComponentProps<"div"> {
@@ -177,26 +198,210 @@ interface AiToolProps extends Omit<ComponentProps<"div">, "title" | "children">
177
198
  * The content shown in the tool.
178
199
  */
179
200
  children?: ReactNode;
201
+ /**
202
+ * Whether the content is currently collapsed.
203
+ * It is not a traditional controlled value, as in if you set it to `true` it would only stay expanded.
204
+ * Instead, it is "semi-controlled", meaning that setting it to `true` will expand it, but it
205
+ * can still be collapsed/expanded by clicking on it.
206
+ */
207
+ collapsed?: boolean;
208
+ /**
209
+ * The event handler called when the content is collapsed or expanded by clicking on it.
210
+ */
211
+ onCollapsedChange?: (collapsed: boolean) => void;
212
+ /**
213
+ * Whether the content can be collapsed/expanded.
214
+ * If set to `false`, clicking on it will have no effect.
215
+ * If there's no content, this prop has no effect.
216
+ */
217
+ collapsible?: boolean;
180
218
  }
181
219
  type AiToolIconProps = ComponentProps<"div">;
182
220
  type AiToolInspectorProps = ComponentProps<"div">;
183
- /**
184
- * @private This API will change, and is not considered stable. DO NOT RELY on it.
185
- *
186
- * This component can be used to build human-in-the-loop interfaces.
187
- */
188
- interface AiToolConfirmationProps<A extends JsonObject, R extends ToolResultData> extends ComponentProps<"div"> {
189
- args?: A;
221
+ interface AiToolConfirmationProps<A extends JsonObject, R extends JsonObject> extends ComponentProps<"div"> {
222
+ /**
223
+ * The callback invoked when the user clicks the confirm button.
224
+ */
190
225
  confirm: AiToolExecuteCallback<A, R>;
191
- cancel: AiToolExecuteCallback<A, R>;
226
+ /**
227
+ * The callback invoked when the user clicks the cancel button.
228
+ */
229
+ cancel?: AiToolExecuteCallback<A, R>;
230
+ /**
231
+ * The visual appearance.
232
+ */
192
233
  variant?: "default" | "destructive";
234
+ /**
235
+ * Override the component's strings.
236
+ */
237
+ overrides?: Partial<GlobalOverrides & AiToolConfirmationOverrides>;
238
+ /**
239
+ * The tool's result type, to be used with the `types` prop in the `render` method.
240
+ *
241
+ * @example
242
+ * defineAiTool<{ value: number }>()({
243
+ * // ...
244
+ * render: ({ types }) => (
245
+ * <AiTool.Confirmation
246
+ * types={types}
247
+ * confirm={() => {
248
+ * return {
249
+ * // Using `types` makes the result type-safe
250
+ * // based on the tool's definition
251
+ * data: { value: 123 },
252
+ * };
253
+ * }}
254
+ * />
255
+ * ),
256
+ * })
257
+ */
258
+ types?: NoInfr<AiToolTypePack<A, R>>;
193
259
  }
194
260
  declare function AiToolIcon({ className, ...props }: AiToolIconProps): react_jsx_runtime.JSX.Element;
195
261
  declare function AiToolInspector({ className, ...props }: AiToolInspectorProps): react_jsx_runtime.JSX.Element;
196
- declare function AiToolConfirmation<TPack extends AiToolTypePack, A extends JsonObject = TPack["A"], R extends ToolResultData = TPack["R"]>({ children, variant, confirm, cancel, className, ...props }: AiToolConfirmationProps<A, R>): react_jsx_runtime.JSX.Element | null;
262
+ declare function AiToolConfirmation<TPack extends AiToolTypePack, A extends JsonObject = TPack["A"], R extends JsonObject = TPack["R"]>({ children, variant, confirm, cancel, overrides, className, ...props }: AiToolConfirmationProps<A, R>): react_jsx_runtime.JSX.Element | null;
263
+ /**
264
+ * A pre-built component which displays a tool call.
265
+ *
266
+ * By default, a human-readable version of the tool's name is used as a title:
267
+ * - `"showTodo"` → "Show todo"
268
+ * - `"get_weather"` → "Get weather"
269
+ *
270
+ * @example
271
+ * defineAiTool()({
272
+ * // ...
273
+ * render: () => (
274
+ * <AiTool />
275
+ * ),
276
+ * })
277
+ *
278
+ * It can be customized in various ways:
279
+ * - adding an icon
280
+ * - customizing the title (even dynamically)
281
+ * - adding custom content inside it
282
+ * - collapsing it conditionally
283
+ * - etc.
284
+ *
285
+ * @example
286
+ * defineAiTool()({
287
+ * // ...
288
+ * render: ({ stage, result }) => (
289
+ * <AiTool
290
+ * icon="🔍"
291
+ *
292
+ * // Override the default title based on the tool's stage
293
+ * title={stage === "executing" ? "Searching…" : "Search results"}
294
+ *
295
+ * // Start open and automatically collapse after it is executed
296
+ * // The user can still expand/collapse it manually at any time
297
+ * collapsed={stage === "executed"}
298
+ * >
299
+ * <SearchResults data={result.data} />
300
+ * </AiTool>
301
+ * ),
302
+ * })
303
+ *
304
+ * It also comes with a few built-in sub-components:
305
+ * - `AiTool.Confirmation` to display a human-in-the-loop confirmation step
306
+ * which can be accepted or cancelled by the user.
307
+ * - `AiTool.Inspector` to display the tool's arguments and result which can
308
+ * be useful during development.
309
+ *
310
+ * @example
311
+ * defineAiTool()({
312
+ * // ...
313
+ * render: () => (
314
+ * <AiTool>
315
+ * <AiTool.Confirmation
316
+ * // Use a destructive visual appearance
317
+ * variant="destructive"
318
+ *
319
+ * // The tool's arguments can be directly accessed like in `execute`
320
+ * confirm={({ pageIds }) => {
321
+ * const deletedPageTitles = pages
322
+ * .filter((p) => pageIds.includes(p.id))
323
+ * .map((page) => page.title);
324
+ *
325
+ * deletePages(pageIds);
326
+ *
327
+ * // This result will be available as `result` in the tool's `render` props
328
+ * return { data: { deletedPageTitles } };
329
+ * }}
330
+ *
331
+ * // If needed, `cancel={() => ...}` would work similarly
332
+ * >
333
+ * Do you want to delete these pages?
334
+ * <PagesPreviews />
335
+ * </AiTool.Confirmation>
336
+ * </AiTool>
337
+ * ),
338
+ * })
339
+ *
340
+ * @example
341
+ * defineAiTool()({
342
+ * // ...
343
+ * render: () => (
344
+ * <AiTool>
345
+ * <AiTool.Inspector />
346
+ * </AiTool>
347
+ * ),
348
+ * })
349
+ */
197
350
  declare const AiTool: react.ForwardRefExoticComponent<Omit<AiToolProps, "ref"> & react.RefAttributes<HTMLDivElement>> & {
351
+ /**
352
+ * Display an icon in a container.
353
+ *
354
+ * @example
355
+ * <AiTool
356
+ * icon={
357
+ * <AiTool.Icon>🔍</AiTool.Icon>
358
+ * }
359
+ * />
360
+ */
198
361
  Icon: typeof AiToolIcon;
362
+ /**
363
+ * Display the tool's arguments and result, which can be useful during
364
+ * development.
365
+ *
366
+ * @example
367
+ * <AiTool>
368
+ * <AiTool.Inspector />
369
+ * </AiTool>
370
+ */
199
371
  Inspector: typeof AiToolInspector;
372
+ /**
373
+ * Display a human-in-the-loop confirmation step which can be accepted
374
+ * or cancelled by the user.
375
+ *
376
+ * The `confirm` and `cancel` callbacks work like `execute` in tool definitions: they can
377
+ * perform side-effects, be async if needed, and return a result. The tool call will stay
378
+ * pending until either `confirm` or `cancel` is called.
379
+ *
380
+ * @example
381
+ * <AiTool>
382
+ * <AiTool.Confirmation
383
+ * // Use a destructive visual appearance
384
+ * variant="destructive"
385
+ *
386
+ * // The tool's arguments can be directly accessed like in `execute`
387
+ * confirm={({ pageIds }) => {
388
+ * const deletedPageTitles = pages
389
+ * .filter((p) => pageIds.includes(p.id))
390
+ * .map((page) => page.title);
391
+ *
392
+ * deletePages(pageIds);
393
+ *
394
+ * // This result will be available as `result` in the tool's `render` props
395
+ * return { data: { deletedPageTitles } };
396
+ * }}
397
+ *
398
+ * // If needed, `cancel={() => ...}` would work similarly
399
+ * >
400
+ * Do you want to delete these pages?
401
+ * <PagesPreviews />
402
+ * </AiTool.Confirmation>
403
+ * </AiTool>
404
+ */
200
405
  Confirmation: typeof AiToolConfirmation;
201
406
  };
202
407
 
@@ -206,9 +411,9 @@ interface ComposerEditorMentionProps {
206
411
  */
207
412
  isSelected: boolean;
208
413
  /**
209
- * The mention's user ID.
414
+ * The mention to display.
210
415
  */
211
- userId: string;
416
+ mention: MentionData;
212
417
  }
213
418
  interface ComposerEditorLinkProps {
214
419
  /**
@@ -226,13 +431,13 @@ interface ComposerEditorLinkProps {
226
431
  }
227
432
  type ComposerEditorMentionSuggestionsProps = {
228
433
  /**
229
- * The list of suggested user IDs.
434
+ * The list of mention suggestions.
230
435
  */
231
- userIds: string[];
436
+ mentions: MentionData[];
232
437
  /**
233
- * The currently selected user ID.
438
+ * The currently selected mention's ID.
234
439
  */
235
- selectedUserId?: string;
440
+ selectedMentionId?: string;
236
441
  };
237
442
  type ComposerEditorFloatingToolbarProps = Record<string, never>;
238
443
  interface ComposerEditorComponents {
@@ -253,7 +458,7 @@ interface ComposerEditorComponents {
253
458
  */
254
459
  FloatingToolbar?: ComponentType<ComposerEditorFloatingToolbarProps>;
255
460
  }
256
- interface ComposerEditorProps extends Omit<ComponentPropsWithoutRef<"div">, "defaultValue"> {
461
+ interface ComposerEditorProps extends Omit<ComponentPropsWithoutRef<"div">, "defaultValue" | "children"> {
257
462
  /**
258
463
  * The reading direction of the editor and related elements.
259
464
  */
@@ -446,7 +651,7 @@ interface CommentProps extends ComponentPropsWithoutRef<"div"> {
446
651
  /**
447
652
  * The event handler called when clicking on a mention.
448
653
  */
449
- onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;
654
+ onMentionClick?: (mention: MentionData, event: MouseEvent<HTMLElement>) => void;
450
655
  /**
451
656
  * The event handler called when clicking on a comment's attachment.
452
657
  */
@@ -455,6 +660,10 @@ interface CommentProps extends ComponentPropsWithoutRef<"div"> {
455
660
  * Override the component's strings.
456
661
  */
457
662
  overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;
663
+ /**
664
+ * Override the component's components.
665
+ */
666
+ components?: Partial<GlobalComponents>;
458
667
  }
459
668
  /**
460
669
  * Displays a single comment.
@@ -712,6 +921,10 @@ interface ThreadProps<M extends BaseMetadata = DM> extends ComponentPropsWithout
712
921
  * Override the component's strings.
713
922
  */
714
923
  overrides?: Partial<GlobalOverrides & ThreadOverrides & CommentOverrides & ComposerOverrides>;
924
+ /**
925
+ * Override the component's components.
926
+ */
927
+ components?: Partial<GlobalComponents>;
715
928
  }
716
929
  /**
717
930
  * Displays a thread of comments, with a composer to reply
@@ -726,7 +939,7 @@ interface ThreadProps<M extends BaseMetadata = DM> extends ComponentPropsWithout
726
939
  */
727
940
  declare const Thread: <M extends BaseMetadata = DM>(props: ThreadProps<M> & RefAttributes<HTMLDivElement>) => JSX.Element;
728
941
 
729
- type LiveblocksUIConfigProps = PropsWithChildren<{
942
+ type LiveblocksUiConfigProps = PropsWithChildren<{
730
943
  /**
731
944
  * Override the components' strings.
732
945
  */
@@ -770,11 +983,11 @@ type LiveblocksUIConfigProps = PropsWithChildren<{
770
983
  * Set configuration options for all components.
771
984
  *
772
985
  * @example
773
- * <LiveblocksUIConfig overrides={{ locale: "fr", USER_UNKNOWN: "Anonyme", ... }}>
986
+ * <LiveblocksUiConfig overrides={{ locale: "fr", USER_UNKNOWN: "Anonyme", ... }}>
774
987
  * <App />
775
- * </LiveblocksUIConfig>
988
+ * </LiveblocksUiConfig>
776
989
  */
777
- declare function LiveblocksUIConfig({ overrides, components, portalContainer, preventUnsavedComposerChanges, emojibaseUrl, children, }: LiveblocksUIConfigProps): react_jsx_runtime.JSX.Element;
990
+ declare function LiveblocksUiConfig({ overrides, components, portalContainer, preventUnsavedComposerChanges, emojibaseUrl, children, }: LiveblocksUiConfigProps): react_jsx_runtime.JSX.Element;
778
991
 
779
992
  declare function ArrowCornerDownRightIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
780
993
 
@@ -916,4 +1129,4 @@ declare namespace icon {
916
1129
  };
917
1130
  }
918
1131
 
919
- export { AiChat, AiChatProps, AiTool, AiToolIconProps, AiToolProps, Comment, CommentAttachmentArgs, CommentOverrides, CommentProps, Composer, ComposerBodyMark, ComposerBodyMarks, ComposerOverrides, ComposerProps, ComposerSubmitComment, GlobalOverrides, HistoryVersionSummary, HistoryVersionSummaryList, HistoryVersionSummaryListProps, HistoryVersionSummaryProps, icon as Icon, InboxNotification, InboxNotificationAvatarProps, InboxNotificationCustomKindProps, InboxNotificationCustomProps, InboxNotificationIconProps, InboxNotificationList, InboxNotificationListProps, InboxNotificationOverrides, InboxNotificationProps, InboxNotificationTextMentionKindProps, InboxNotificationTextMentionProps, InboxNotificationThreadKindProps, InboxNotificationThreadProps, LiveblocksUIConfig, LocalizationOverrides, Overrides, Thread, ThreadOverrides, ThreadProps, useOverrides };
1132
+ export { AiChat, AiChatComponents, AiChatComponentsEmptyProps, AiChatComponentsLoadingProps, AiChatProps, AiTool, AiToolIconProps, AiToolProps, Comment, CommentAttachmentArgs, CommentOverrides, CommentProps, Composer, ComposerBodyMark, ComposerBodyMarks, ComposerOverrides, ComposerProps, ComposerSubmitComment, GlobalOverrides, HistoryVersionSummary, HistoryVersionSummaryList, HistoryVersionSummaryListProps, HistoryVersionSummaryProps, icon as Icon, InboxNotification, InboxNotificationAvatarProps, InboxNotificationCustomKindProps, InboxNotificationCustomProps, InboxNotificationIconProps, InboxNotificationList, InboxNotificationListProps, InboxNotificationOverrides, InboxNotificationProps, InboxNotificationTextMentionKindProps, InboxNotificationTextMentionProps, InboxNotificationThreadKindProps, InboxNotificationThreadProps, LiveblocksUiConfig, LocalizationOverrides, Overrides, Thread, ThreadOverrides, ThreadProps, useOverrides };
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ export { HistoryVersionSummaryList } from './components/HistoryVersionSummaryLis
9
9
  export { InboxNotification } from './components/InboxNotification.js';
10
10
  export { InboxNotificationList } from './components/InboxNotificationList.js';
11
11
  export { Thread } from './components/Thread.js';
12
- export { LiveblocksUIConfig } from './config.js';
12
+ export { LiveblocksUiConfig } from './config.js';
13
13
  import * as icon from './icon.js';
14
14
  export { icon as Icon };
15
15
  export { useOverrides } from './overrides.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AiChatProps } from \"./components/AiChat\";\nexport { AiChat } from \"./components/AiChat\";\nexport type { AiToolIconProps, AiToolProps } from \"./components/AiTool\";\nexport { AiTool } from \"./components/AiTool\";\nexport type { CommentProps } from \"./components/Comment\";\nexport { Comment } from \"./components/Comment\";\nexport type { ComposerProps } from \"./components/Composer\";\nexport { Composer } from \"./components/Composer\";\nexport type { HistoryVersionSummaryProps } from \"./components/HistoryVersionSummary\";\nexport { HistoryVersionSummary } from \"./components/HistoryVersionSummary\";\nexport type { HistoryVersionSummaryListProps } from \"./components/HistoryVersionSummaryList\";\nexport { HistoryVersionSummaryList } from \"./components/HistoryVersionSummaryList\";\nexport type {\n InboxNotificationAvatarProps,\n InboxNotificationCustomKindProps,\n InboxNotificationCustomProps,\n InboxNotificationIconProps,\n InboxNotificationProps,\n InboxNotificationTextMentionKindProps,\n InboxNotificationTextMentionProps,\n InboxNotificationThreadKindProps,\n InboxNotificationThreadProps,\n} from \"./components/InboxNotification\";\nexport { InboxNotification } from \"./components/InboxNotification\";\nexport type { InboxNotificationListProps } from \"./components/InboxNotificationList\";\nexport { InboxNotificationList } from \"./components/InboxNotificationList\";\nexport type { ThreadProps } from \"./components/Thread\";\nexport { Thread } from \"./components/Thread\";\nexport { LiveblocksUIConfig } from \"./config\";\nexport * as Icon from \"./icon\";\nexport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n LocalizationOverrides,\n Overrides,\n ThreadOverrides,\n} from \"./overrides\";\nexport { useOverrides } from \"./overrides\";\nexport type { ComposerSubmitComment } from \"./primitives\";\nexport type {\n CommentAttachmentArgs,\n ComposerBodyMark,\n ComposerBodyMarks,\n} from \"./types\";\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type {\n AiChatComponents,\n AiChatComponentsEmptyProps,\n AiChatComponentsLoadingProps,\n AiChatProps,\n} from \"./components/AiChat\";\nexport { AiChat } from \"./components/AiChat\";\nexport type { AiToolIconProps, AiToolProps } from \"./components/AiTool\";\nexport { AiTool } from \"./components/AiTool\";\nexport type { CommentProps } from \"./components/Comment\";\nexport { Comment } from \"./components/Comment\";\nexport type { ComposerProps } from \"./components/Composer\";\nexport { Composer } from \"./components/Composer\";\nexport type { HistoryVersionSummaryProps } from \"./components/HistoryVersionSummary\";\nexport { HistoryVersionSummary } from \"./components/HistoryVersionSummary\";\nexport type { HistoryVersionSummaryListProps } from \"./components/HistoryVersionSummaryList\";\nexport { HistoryVersionSummaryList } from \"./components/HistoryVersionSummaryList\";\nexport type {\n InboxNotificationAvatarProps,\n InboxNotificationCustomKindProps,\n InboxNotificationCustomProps,\n InboxNotificationIconProps,\n InboxNotificationProps,\n InboxNotificationTextMentionKindProps,\n InboxNotificationTextMentionProps,\n InboxNotificationThreadKindProps,\n InboxNotificationThreadProps,\n} from \"./components/InboxNotification\";\nexport { InboxNotification } from \"./components/InboxNotification\";\nexport type { InboxNotificationListProps } from \"./components/InboxNotificationList\";\nexport { InboxNotificationList } from \"./components/InboxNotificationList\";\nexport type { ThreadProps } from \"./components/Thread\";\nexport { Thread } from \"./components/Thread\";\nexport { LiveblocksUiConfig } from \"./config\";\nexport * as Icon from \"./icon\";\nexport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n LocalizationOverrides,\n Overrides,\n ThreadOverrides,\n} from \"./overrides\";\nexport { useOverrides } from \"./overrides\";\nexport type { ComposerSubmitComment } from \"./primitives\";\nexport type {\n CommentAttachmentArgs,\n ComposerBodyMark,\n ComposerBodyMarks,\n} from \"./types\";\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
@@ -13,6 +13,7 @@ const defaultOverrides = {
13
13
  dir: "ltr",
14
14
  USER_SELF: "you",
15
15
  USER_UNKNOWN: "Anonymous",
16
+ COPY_TO_CLIPBOARD: "Copy",
16
17
  LIST_REMAINING: (count) => `${count} more`,
17
18
  LIST_REMAINING_USERS: (count) => `${count} ${pluralize.pluralize(count, "other")}`,
18
19
  LIST_REMAINING_COMMENTS: (count) => `${count} more ${pluralize.pluralize(count, "comment")}`,
@@ -125,7 +126,10 @@ const defaultOverrides = {
125
126
  AI_CHAT_COMPOSER_ABORT: "Abort response",
126
127
  AI_CHAT_MESSAGE_DELETED: "This message has been deleted.",
127
128
  AI_CHAT_MESSAGE_THINKING: "Thinking\u2026",
128
- AI_CHAT_MESSAGES_ERROR: () => "There was an error while getting the messages."
129
+ AI_CHAT_MESSAGE_REASONING: (isStreaming) => isStreaming ? "Reasoning\u2026" : "Reasoning",
130
+ AI_CHAT_MESSAGES_ERROR: () => "There was an error while getting the messages.",
131
+ AI_TOOL_CONFIRMATION_CONFIRM: "Confirm",
132
+ AI_TOOL_CONFIRMATION_CANCEL: "Cancel"
129
133
  };
130
134
  const OverridesContext = react.createContext(void 0);
131
135
  function useOverrides(overrides) {
@@ -1 +1 @@
1
- {"version":3,"file":"overrides.cjs","sources":["../src/overrides.tsx"],"sourcesContent":["\"use client\";\n\nimport { assertNever } from \"@liveblocks/core\";\nimport type { PropsWithChildren, ReactNode } from \"react\";\nimport { createContext, useContext, useMemo } from \"react\";\n\nimport { Emoji } from \"./components/internal/Emoji\";\nimport type { ComposerBodyMark, Direction } from \"./types\";\nimport { pluralize } from \"./utils/pluralize\";\n\nexport interface LocalizationOverrides {\n locale: string;\n dir: Direction;\n}\n\nexport interface GlobalOverrides {\n USER_SELF: string;\n USER_UNKNOWN: string;\n LIST_REMAINING: (count: number) => string;\n LIST_REMAINING_USERS: (count: number) => string;\n LIST_REMAINING_COMMENTS: (count: number) => string;\n EMOJI_PICKER_SEARCH_PLACEHOLDER: string;\n EMOJI_PICKER_EMPTY: ReactNode;\n EMOJI_PICKER_ERROR: (error: Error) => ReactNode;\n EMOJI_PICKER_CHANGE_SKIN_TONE: string;\n ATTACHMENT_TOO_LARGE: (maxSize?: string) => string;\n ATTACHMENT_ERROR: (error: Error) => string;\n}\n\nexport interface CommentOverrides {\n COMMENT_EDITED: ReactNode;\n COMMENT_DELETED: ReactNode;\n COMMENT_MORE: string;\n COMMENT_EDIT: string;\n COMMENT_EDIT_COMPOSER_PLACEHOLDER: string;\n COMMENT_EDIT_COMPOSER_CANCEL: string;\n COMMENT_EDIT_COMPOSER_SAVE: string;\n COMMENT_DELETE: string;\n COMMENT_DELETE_ATTACHMENT: string;\n COMMENT_ADD_REACTION: string;\n COMMENT_REACTION_LIST: (\n list: ReactNode,\n emoji: string,\n count: number\n ) => ReactNode;\n COMMENT_REACTION_DESCRIPTION: (emoji: string, count: number) => string;\n}\n\nexport interface ComposerOverrides {\n COMPOSER_INSERT_MENTION: string;\n COMPOSER_INSERT_EMOJI: string;\n COMPOSER_ATTACH_FILES: string;\n COMPOSER_REMOVE_ATTACHMENT: string;\n COMPOSER_PLACEHOLDER: string;\n COMPOSER_SEND: string;\n COMPOSER_TOGGLE_MARK: (mark: ComposerBodyMark) => string;\n}\n\nexport interface AiChatComposerOverrides {\n AI_CHAT_COMPOSER_PLACEHOLDER: string;\n AI_CHAT_COMPOSER_SEND: string;\n AI_CHAT_COMPOSER_ABORT: string;\n}\n\nexport interface AiChatMessageOverrides {\n AI_CHAT_MESSAGE_DELETED: string;\n AI_CHAT_MESSAGE_THINKING: string;\n}\n\nexport interface AiChatOverrides {\n AI_CHAT_MESSAGES_ERROR: (error: Error) => ReactNode;\n}\n\nexport interface ThreadOverrides {\n THREAD_RESOLVE: string;\n THREAD_UNRESOLVE: string;\n THREAD_SUBSCRIBE: string;\n THREAD_UNSUBSCRIBE: string;\n THREAD_NEW_INDICATOR: string;\n THREAD_NEW_INDICATOR_DESCRIPTION: string;\n THREAD_COMPOSER_PLACEHOLDER: string;\n THREAD_COMPOSER_SEND: string;\n}\n\nexport interface InboxNotificationOverrides {\n INBOX_NOTIFICATION_MORE: string;\n INBOX_NOTIFICATION_MARK_AS_READ: string;\n INBOX_NOTIFICATION_DELETE: string;\n INBOX_NOTIFICATION_THREAD_COMMENTS_LIST: (\n list: ReactNode,\n room: ReactNode | undefined,\n count: number\n ) => ReactNode;\n INBOX_NOTIFICATION_THREAD_MENTION: (\n user: ReactNode,\n room: ReactNode | undefined\n ) => ReactNode;\n INBOX_NOTIFICATION_TEXT_MENTION: (\n user: ReactNode,\n room: ReactNode | undefined\n ) => ReactNode;\n}\n\nexport interface HistoryVersionPreviewOverrides {\n HISTORY_VERSION_PREVIEW_AUTHORS_LIST: (list: ReactNode) => ReactNode;\n HISTORY_VERSION_PREVIEW_RESTORE: string;\n HISTORY_VERSION_PREVIEW_EMPTY: ReactNode;\n HISTORY_VERSION_PREVIEW_ERROR: (error: Error) => ReactNode;\n}\n\nexport type Overrides = LocalizationOverrides &\n GlobalOverrides &\n ComposerOverrides &\n CommentOverrides &\n ThreadOverrides &\n InboxNotificationOverrides &\n HistoryVersionPreviewOverrides &\n AiChatComposerOverrides &\n AiChatMessageOverrides &\n AiChatOverrides;\n\ntype OverridesProviderProps = PropsWithChildren<{\n overrides?: Partial<Overrides>;\n}>;\n\nexport const defaultOverrides: Overrides = {\n locale: \"en\",\n dir: \"ltr\",\n USER_SELF: \"you\",\n USER_UNKNOWN: \"Anonymous\",\n LIST_REMAINING: (count) => `${count} more`,\n LIST_REMAINING_USERS: (count) => `${count} ${pluralize(count, \"other\")}`,\n LIST_REMAINING_COMMENTS: (count) =>\n `${count} more ${pluralize(count, \"comment\")}`,\n EMOJI_PICKER_SEARCH_PLACEHOLDER: \"Search…\",\n EMOJI_PICKER_EMPTY: \"No emoji found.\",\n EMOJI_PICKER_ERROR: () =>\n \"There was an error while getting the list of emoji.\",\n EMOJI_PICKER_CHANGE_SKIN_TONE: \"Change skin tone\",\n ATTACHMENT_TOO_LARGE: (maxSize) =>\n maxSize ? `The file is larger than ${maxSize}` : \"The file is too large\",\n ATTACHMENT_ERROR: () => \"The file couldn’t be uploaded.\",\n COMPOSER_INSERT_MENTION: \"Mention someone\",\n COMPOSER_INSERT_EMOJI: \"Add emoji\",\n COMPOSER_ATTACH_FILES: \"Attach files\",\n COMPOSER_REMOVE_ATTACHMENT: \"Remove attachment\",\n COMPOSER_PLACEHOLDER: \"Write a comment…\",\n COMPOSER_SEND: \"Send\",\n COMPOSER_TOGGLE_MARK: (format) => {\n switch (format) {\n case \"bold\":\n return \"Bold\";\n case \"italic\":\n return \"Italic\";\n case \"strikethrough\":\n return \"Strikethrough\";\n case \"code\":\n return \"Inline code\";\n default:\n return assertNever(format, \"Unexpected mark\");\n }\n },\n COMMENT_EDITED: \"(edited)\",\n COMMENT_DELETED: \"This comment has been deleted.\",\n COMMENT_MORE: \"More\",\n COMMENT_EDIT: \"Edit comment\",\n COMMENT_EDIT_COMPOSER_PLACEHOLDER: \"Edit comment…\",\n COMMENT_EDIT_COMPOSER_CANCEL: \"Cancel\",\n COMMENT_EDIT_COMPOSER_SAVE: \"Save\",\n COMMENT_DELETE: \"Delete comment\",\n COMMENT_DELETE_ATTACHMENT: \"Delete attachment\",\n COMMENT_ADD_REACTION: \"Add reaction\",\n COMMENT_REACTION_LIST: (list, emoji) => (\n <>\n {list} reacted with <Emoji emoji={emoji} />\n </>\n ),\n COMMENT_REACTION_DESCRIPTION: (emoji, count) =>\n `${count} ${pluralize(count, \"reaction\")}, react with ${emoji}`,\n THREAD_RESOLVE: \"Resolve thread\",\n THREAD_UNRESOLVE: \"Re-open thread\",\n THREAD_SUBSCRIBE: \"Subscribe to thread\",\n THREAD_UNSUBSCRIBE: \"Unsubscribe from thread\",\n THREAD_NEW_INDICATOR: \"New\",\n THREAD_NEW_INDICATOR_DESCRIPTION: \"New comments\",\n THREAD_COMPOSER_PLACEHOLDER: \"Reply to thread…\",\n THREAD_COMPOSER_SEND: \"Reply\",\n INBOX_NOTIFICATION_MORE: \"More\",\n INBOX_NOTIFICATION_MARK_AS_READ: \"Mark as read\",\n INBOX_NOTIFICATION_DELETE: \"Delete notification\",\n INBOX_NOTIFICATION_THREAD_COMMENTS_LIST: (\n list: ReactNode,\n room: ReactNode\n ) => (\n <>\n {list} commented\n {room ? <> in {room}</> : <> in a thread</>}\n </>\n ),\n INBOX_NOTIFICATION_THREAD_MENTION: (user: ReactNode, room: ReactNode) => (\n <>\n {user} mentioned you{room ? <> in {room}</> : null}\n </>\n ),\n INBOX_NOTIFICATION_TEXT_MENTION: (user: ReactNode, room: ReactNode) => (\n <>\n {user} mentioned you{room ? <> in {room}</> : null}\n </>\n ),\n HISTORY_VERSION_PREVIEW_AUTHORS_LIST: (list: ReactNode) => (\n <>Edits from {list}</>\n ),\n HISTORY_VERSION_PREVIEW_RESTORE: \"Restore\",\n HISTORY_VERSION_PREVIEW_EMPTY: \"No content.\",\n HISTORY_VERSION_PREVIEW_ERROR: () =>\n \"There was an error while getting this version.\",\n AI_CHAT_COMPOSER_PLACEHOLDER: \"Ask anything…\",\n AI_CHAT_COMPOSER_SEND: \"Send\",\n AI_CHAT_COMPOSER_ABORT: \"Abort response\",\n AI_CHAT_MESSAGE_DELETED: \"This message has been deleted.\",\n AI_CHAT_MESSAGE_THINKING: \"Thinking…\",\n AI_CHAT_MESSAGES_ERROR: () =>\n \"There was an error while getting the messages.\",\n};\n\nexport const OverridesContext = createContext<Overrides | undefined>(undefined);\n\nexport function useOverrides(overrides?: Partial<Overrides>): Overrides {\n const contextOverrides = useContext(OverridesContext);\n\n return useMemo(\n () => ({\n ...defaultOverrides,\n ...contextOverrides,\n ...overrides,\n }),\n [contextOverrides, overrides]\n );\n}\n\nexport function OverridesProvider({\n children,\n overrides: providerOverrides,\n}: OverridesProviderProps) {\n const contextOverrides = useContext(OverridesContext);\n const overrides = useMemo(\n () => ({\n ...defaultOverrides,\n ...contextOverrides,\n ...providerOverrides,\n }),\n [contextOverrides, providerOverrides]\n );\n\n return (\n <OverridesContext.Provider value={overrides}>\n {children}\n </OverridesContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AA6HO;AAAoC;AACjC;AACH;AACM;AACG;AACgB;AACuC;AAExB;AACZ;AACb;AAElB;AAC6B;AAEoB;AAC3B;AACC;AACF;AACA;AACK;AACN;AACP;AAEb;AAAgB;AAEZ;AAAO;AAEP;AAAO;AAEP;AAAO;AAEP;AAAO;AAEP;AAA4C;AAChD;AACF;AACgB;AACC;AACH;AACA;AACqB;AACL;AACF;AACZ;AACW;AACL;AAEpB;AACG;AAAA;AAAK;AAAe;AAAM;AAAc;AAAA;AAC3C;AAGwD;AAC1C;AACE;AACA;AACE;AACE;AACY;AACL;AACP;AACG;AACQ;AACN;AAKzB;AACG;AAAA;AAAK;AACE;AAAE;AAAA;AAAK;AAAA;AAAW;AAAE;AAAY;AAAA;AAC1C;AAGA;AACG;AAAA;AAAK;AAAsB;AAAE;AAAA;AAAK;AAAA;AAAW;AAAA;AAChD;AAGA;AACG;AAAA;AAAK;AAAsB;AAAE;AAAA;AAAK;AAAA;AAAW;AAAA;AAChD;AAGA;AAAE;AAAA;AAAY;AAAA;AAAK;AAEY;AACF;AAE7B;AAC4B;AACP;AACC;AACC;AACC;AAG5B;AAEa;AAEN;AACL;AAEA;AAAO;AACE;AACF;AACA;AACA;AACL;AAC4B;AAEhC;AAEO;AAA2B;AAChC;AAEF;AACE;AACA;AAAkB;AACT;AACF;AACA;AACA;AACL;AACoC;AAGtC;AACG;AAAiC;AAC/B;AAGP;;;;;"}
1
+ {"version":3,"file":"overrides.cjs","sources":["../src/overrides.tsx"],"sourcesContent":["\"use client\";\n\nimport { assertNever } from \"@liveblocks/core\";\nimport type { PropsWithChildren, ReactNode } from \"react\";\nimport { createContext, useContext, useMemo } from \"react\";\n\nimport { Emoji } from \"./components/internal/Emoji\";\nimport type { ComposerBodyMark, Direction } from \"./types\";\nimport { pluralize } from \"./utils/pluralize\";\n\nexport interface LocalizationOverrides {\n locale: string;\n dir: Direction;\n}\n\nexport interface GlobalOverrides {\n USER_SELF: string;\n USER_UNKNOWN: string;\n LIST_REMAINING: (count: number) => string;\n LIST_REMAINING_USERS: (count: number) => string;\n LIST_REMAINING_COMMENTS: (count: number) => string;\n EMOJI_PICKER_SEARCH_PLACEHOLDER: string;\n EMOJI_PICKER_EMPTY: ReactNode;\n EMOJI_PICKER_ERROR: (error: Error) => ReactNode;\n EMOJI_PICKER_CHANGE_SKIN_TONE: string;\n ATTACHMENT_TOO_LARGE: (maxSize?: string) => string;\n ATTACHMENT_ERROR: (error: Error) => string;\n COPY_TO_CLIPBOARD: string;\n}\n\nexport interface CommentOverrides {\n COMMENT_EDITED: ReactNode;\n COMMENT_DELETED: ReactNode;\n COMMENT_MORE: string;\n COMMENT_EDIT: string;\n COMMENT_EDIT_COMPOSER_PLACEHOLDER: string;\n COMMENT_EDIT_COMPOSER_CANCEL: string;\n COMMENT_EDIT_COMPOSER_SAVE: string;\n COMMENT_DELETE: string;\n COMMENT_DELETE_ATTACHMENT: string;\n COMMENT_ADD_REACTION: string;\n COMMENT_REACTION_LIST: (\n list: ReactNode,\n emoji: string,\n count: number\n ) => ReactNode;\n COMMENT_REACTION_DESCRIPTION: (emoji: string, count: number) => string;\n}\n\nexport interface ComposerOverrides {\n COMPOSER_INSERT_MENTION: string;\n COMPOSER_INSERT_EMOJI: string;\n COMPOSER_ATTACH_FILES: string;\n COMPOSER_REMOVE_ATTACHMENT: string;\n COMPOSER_PLACEHOLDER: string;\n COMPOSER_SEND: string;\n COMPOSER_TOGGLE_MARK: (mark: ComposerBodyMark) => string;\n}\n\nexport interface AiToolConfirmationOverrides {\n AI_TOOL_CONFIRMATION_CONFIRM: string;\n AI_TOOL_CONFIRMATION_CANCEL: string;\n}\n\nexport interface AiChatComposerOverrides {\n AI_CHAT_COMPOSER_PLACEHOLDER: string;\n AI_CHAT_COMPOSER_SEND: string;\n AI_CHAT_COMPOSER_ABORT: string;\n}\n\nexport interface AiChatMessageOverrides {\n AI_CHAT_MESSAGE_DELETED: string;\n AI_CHAT_MESSAGE_THINKING: string;\n AI_CHAT_MESSAGE_REASONING: (isStreaming: boolean) => string;\n}\n\nexport interface AiChatOverrides {\n AI_CHAT_MESSAGES_ERROR: (error: Error) => ReactNode;\n}\n\nexport interface ThreadOverrides {\n THREAD_RESOLVE: string;\n THREAD_UNRESOLVE: string;\n THREAD_SUBSCRIBE: string;\n THREAD_UNSUBSCRIBE: string;\n THREAD_NEW_INDICATOR: string;\n THREAD_NEW_INDICATOR_DESCRIPTION: string;\n THREAD_COMPOSER_PLACEHOLDER: string;\n THREAD_COMPOSER_SEND: string;\n}\n\nexport interface InboxNotificationOverrides {\n INBOX_NOTIFICATION_MORE: string;\n INBOX_NOTIFICATION_MARK_AS_READ: string;\n INBOX_NOTIFICATION_DELETE: string;\n INBOX_NOTIFICATION_THREAD_COMMENTS_LIST: (\n list: ReactNode,\n room: ReactNode | undefined,\n count: number\n ) => ReactNode;\n INBOX_NOTIFICATION_THREAD_MENTION: (\n user: ReactNode,\n room: ReactNode | undefined\n ) => ReactNode;\n INBOX_NOTIFICATION_TEXT_MENTION: (\n user: ReactNode,\n room: ReactNode | undefined\n ) => ReactNode;\n}\n\nexport interface HistoryVersionPreviewOverrides {\n HISTORY_VERSION_PREVIEW_AUTHORS_LIST: (list: ReactNode) => ReactNode;\n HISTORY_VERSION_PREVIEW_RESTORE: string;\n HISTORY_VERSION_PREVIEW_EMPTY: ReactNode;\n HISTORY_VERSION_PREVIEW_ERROR: (error: Error) => ReactNode;\n}\n\nexport type Overrides = LocalizationOverrides &\n GlobalOverrides &\n ComposerOverrides &\n CommentOverrides &\n ThreadOverrides &\n InboxNotificationOverrides &\n HistoryVersionPreviewOverrides &\n AiChatComposerOverrides &\n AiChatMessageOverrides &\n AiChatOverrides &\n AiToolConfirmationOverrides;\n\ntype OverridesProviderProps = PropsWithChildren<{\n overrides?: Partial<Overrides>;\n}>;\n\nexport const defaultOverrides: Overrides = {\n locale: \"en\",\n dir: \"ltr\",\n USER_SELF: \"you\",\n USER_UNKNOWN: \"Anonymous\",\n COPY_TO_CLIPBOARD: \"Copy\",\n LIST_REMAINING: (count) => `${count} more`,\n LIST_REMAINING_USERS: (count) => `${count} ${pluralize(count, \"other\")}`,\n LIST_REMAINING_COMMENTS: (count) =>\n `${count} more ${pluralize(count, \"comment\")}`,\n EMOJI_PICKER_SEARCH_PLACEHOLDER: \"Search…\",\n EMOJI_PICKER_EMPTY: \"No emoji found.\",\n EMOJI_PICKER_ERROR: () =>\n \"There was an error while getting the list of emoji.\",\n EMOJI_PICKER_CHANGE_SKIN_TONE: \"Change skin tone\",\n ATTACHMENT_TOO_LARGE: (maxSize) =>\n maxSize ? `The file is larger than ${maxSize}` : \"The file is too large\",\n ATTACHMENT_ERROR: () => \"The file couldn’t be uploaded.\",\n COMPOSER_INSERT_MENTION: \"Mention someone\",\n COMPOSER_INSERT_EMOJI: \"Add emoji\",\n COMPOSER_ATTACH_FILES: \"Attach files\",\n COMPOSER_REMOVE_ATTACHMENT: \"Remove attachment\",\n COMPOSER_PLACEHOLDER: \"Write a comment…\",\n COMPOSER_SEND: \"Send\",\n COMPOSER_TOGGLE_MARK: (format) => {\n switch (format) {\n case \"bold\":\n return \"Bold\";\n case \"italic\":\n return \"Italic\";\n case \"strikethrough\":\n return \"Strikethrough\";\n case \"code\":\n return \"Inline code\";\n default:\n return assertNever(format, \"Unexpected mark\");\n }\n },\n COMMENT_EDITED: \"(edited)\",\n COMMENT_DELETED: \"This comment has been deleted.\",\n COMMENT_MORE: \"More\",\n COMMENT_EDIT: \"Edit comment\",\n COMMENT_EDIT_COMPOSER_PLACEHOLDER: \"Edit comment…\",\n COMMENT_EDIT_COMPOSER_CANCEL: \"Cancel\",\n COMMENT_EDIT_COMPOSER_SAVE: \"Save\",\n COMMENT_DELETE: \"Delete comment\",\n COMMENT_DELETE_ATTACHMENT: \"Delete attachment\",\n COMMENT_ADD_REACTION: \"Add reaction\",\n COMMENT_REACTION_LIST: (list, emoji) => (\n <>\n {list} reacted with <Emoji emoji={emoji} />\n </>\n ),\n COMMENT_REACTION_DESCRIPTION: (emoji, count) =>\n `${count} ${pluralize(count, \"reaction\")}, react with ${emoji}`,\n THREAD_RESOLVE: \"Resolve thread\",\n THREAD_UNRESOLVE: \"Re-open thread\",\n THREAD_SUBSCRIBE: \"Subscribe to thread\",\n THREAD_UNSUBSCRIBE: \"Unsubscribe from thread\",\n THREAD_NEW_INDICATOR: \"New\",\n THREAD_NEW_INDICATOR_DESCRIPTION: \"New comments\",\n THREAD_COMPOSER_PLACEHOLDER: \"Reply to thread…\",\n THREAD_COMPOSER_SEND: \"Reply\",\n INBOX_NOTIFICATION_MORE: \"More\",\n INBOX_NOTIFICATION_MARK_AS_READ: \"Mark as read\",\n INBOX_NOTIFICATION_DELETE: \"Delete notification\",\n INBOX_NOTIFICATION_THREAD_COMMENTS_LIST: (\n list: ReactNode,\n room: ReactNode\n ) => (\n <>\n {list} commented\n {room ? <> in {room}</> : <> in a thread</>}\n </>\n ),\n INBOX_NOTIFICATION_THREAD_MENTION: (user: ReactNode, room: ReactNode) => (\n <>\n {user} mentioned you{room ? <> in {room}</> : null}\n </>\n ),\n INBOX_NOTIFICATION_TEXT_MENTION: (user: ReactNode, room: ReactNode) => (\n <>\n {user} mentioned you{room ? <> in {room}</> : null}\n </>\n ),\n HISTORY_VERSION_PREVIEW_AUTHORS_LIST: (list: ReactNode) => (\n <>Edits from {list}</>\n ),\n HISTORY_VERSION_PREVIEW_RESTORE: \"Restore\",\n HISTORY_VERSION_PREVIEW_EMPTY: \"No content.\",\n HISTORY_VERSION_PREVIEW_ERROR: () =>\n \"There was an error while getting this version.\",\n AI_CHAT_COMPOSER_PLACEHOLDER: \"Ask anything…\",\n AI_CHAT_COMPOSER_SEND: \"Send\",\n AI_CHAT_COMPOSER_ABORT: \"Abort response\",\n AI_CHAT_MESSAGE_DELETED: \"This message has been deleted.\",\n AI_CHAT_MESSAGE_THINKING: \"Thinking…\",\n AI_CHAT_MESSAGE_REASONING: (isStreaming) =>\n isStreaming ? \"Reasoning…\" : \"Reasoning\",\n AI_CHAT_MESSAGES_ERROR: () =>\n \"There was an error while getting the messages.\",\n AI_TOOL_CONFIRMATION_CONFIRM: \"Confirm\",\n AI_TOOL_CONFIRMATION_CANCEL: \"Cancel\",\n};\n\nexport const OverridesContext = createContext<Overrides | undefined>(undefined);\n\nexport function useOverrides(overrides?: Partial<Overrides>): Overrides {\n const contextOverrides = useContext(OverridesContext);\n\n return useMemo(\n () => ({\n ...defaultOverrides,\n ...contextOverrides,\n ...overrides,\n }),\n [contextOverrides, overrides]\n );\n}\n\nexport function OverridesProvider({\n children,\n overrides: providerOverrides,\n}: OverridesProviderProps) {\n const contextOverrides = useContext(OverridesContext);\n const overrides = useMemo(\n () => ({\n ...defaultOverrides,\n ...contextOverrides,\n ...providerOverrides,\n }),\n [contextOverrides, providerOverrides]\n );\n\n return (\n <OverridesContext.Provider value={overrides}>\n {children}\n </OverridesContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AAqIO;AAAoC;AACjC;AACH;AACM;AACG;AACK;AACW;AACuC;AAExB;AACZ;AACb;AAElB;AAC6B;AAEoB;AAC3B;AACC;AACF;AACA;AACK;AACN;AACP;AAEb;AAAgB;AAEZ;AAAO;AAEP;AAAO;AAEP;AAAO;AAEP;AAAO;AAEP;AAA4C;AAChD;AACF;AACgB;AACC;AACH;AACA;AACqB;AACL;AACF;AACZ;AACW;AACL;AAEpB;AACG;AAAA;AAAK;AAAe;AAAM;AAAc;AAAA;AAC3C;AAGwD;AAC1C;AACE;AACA;AACE;AACE;AACY;AACL;AACP;AACG;AACQ;AACN;AAKzB;AACG;AAAA;AAAK;AACE;AAAE;AAAA;AAAK;AAAA;AAAW;AAAE;AAAY;AAAA;AAC1C;AAGA;AACG;AAAA;AAAK;AAAsB;AAAE;AAAA;AAAK;AAAA;AAAW;AAAA;AAChD;AAGA;AACG;AAAA;AAAK;AAAsB;AAAE;AAAA;AAAK;AAAA;AAAW;AAAA;AAChD;AAGA;AAAE;AAAA;AAAY;AAAA;AAAK;AAEY;AACF;AAE7B;AAC4B;AACP;AACC;AACC;AACC;AAEK;AAE7B;AAC4B;AAEhC;AAEa;AAEN;AACL;AAEA;AAAO;AACE;AACF;AACA;AACA;AACL;AAC4B;AAEhC;AAEO;AAA2B;AAChC;AAEF;AACE;AACA;AAAkB;AACT;AACF;AACA;AACA;AACL;AACoC;AAGtC;AACG;AAAiC;AAC/B;AAGP;;;;;"}
package/dist/overrides.js CHANGED
@@ -11,6 +11,7 @@ const defaultOverrides = {
11
11
  dir: "ltr",
12
12
  USER_SELF: "you",
13
13
  USER_UNKNOWN: "Anonymous",
14
+ COPY_TO_CLIPBOARD: "Copy",
14
15
  LIST_REMAINING: (count) => `${count} more`,
15
16
  LIST_REMAINING_USERS: (count) => `${count} ${pluralize(count, "other")}`,
16
17
  LIST_REMAINING_COMMENTS: (count) => `${count} more ${pluralize(count, "comment")}`,
@@ -123,7 +124,10 @@ const defaultOverrides = {
123
124
  AI_CHAT_COMPOSER_ABORT: "Abort response",
124
125
  AI_CHAT_MESSAGE_DELETED: "This message has been deleted.",
125
126
  AI_CHAT_MESSAGE_THINKING: "Thinking\u2026",
126
- AI_CHAT_MESSAGES_ERROR: () => "There was an error while getting the messages."
127
+ AI_CHAT_MESSAGE_REASONING: (isStreaming) => isStreaming ? "Reasoning\u2026" : "Reasoning",
128
+ AI_CHAT_MESSAGES_ERROR: () => "There was an error while getting the messages.",
129
+ AI_TOOL_CONFIRMATION_CONFIRM: "Confirm",
130
+ AI_TOOL_CONFIRMATION_CANCEL: "Cancel"
127
131
  };
128
132
  const OverridesContext = createContext(void 0);
129
133
  function useOverrides(overrides) {
@@ -1 +1 @@
1
- {"version":3,"file":"overrides.js","sources":["../src/overrides.tsx"],"sourcesContent":["\"use client\";\n\nimport { assertNever } from \"@liveblocks/core\";\nimport type { PropsWithChildren, ReactNode } from \"react\";\nimport { createContext, useContext, useMemo } from \"react\";\n\nimport { Emoji } from \"./components/internal/Emoji\";\nimport type { ComposerBodyMark, Direction } from \"./types\";\nimport { pluralize } from \"./utils/pluralize\";\n\nexport interface LocalizationOverrides {\n locale: string;\n dir: Direction;\n}\n\nexport interface GlobalOverrides {\n USER_SELF: string;\n USER_UNKNOWN: string;\n LIST_REMAINING: (count: number) => string;\n LIST_REMAINING_USERS: (count: number) => string;\n LIST_REMAINING_COMMENTS: (count: number) => string;\n EMOJI_PICKER_SEARCH_PLACEHOLDER: string;\n EMOJI_PICKER_EMPTY: ReactNode;\n EMOJI_PICKER_ERROR: (error: Error) => ReactNode;\n EMOJI_PICKER_CHANGE_SKIN_TONE: string;\n ATTACHMENT_TOO_LARGE: (maxSize?: string) => string;\n ATTACHMENT_ERROR: (error: Error) => string;\n}\n\nexport interface CommentOverrides {\n COMMENT_EDITED: ReactNode;\n COMMENT_DELETED: ReactNode;\n COMMENT_MORE: string;\n COMMENT_EDIT: string;\n COMMENT_EDIT_COMPOSER_PLACEHOLDER: string;\n COMMENT_EDIT_COMPOSER_CANCEL: string;\n COMMENT_EDIT_COMPOSER_SAVE: string;\n COMMENT_DELETE: string;\n COMMENT_DELETE_ATTACHMENT: string;\n COMMENT_ADD_REACTION: string;\n COMMENT_REACTION_LIST: (\n list: ReactNode,\n emoji: string,\n count: number\n ) => ReactNode;\n COMMENT_REACTION_DESCRIPTION: (emoji: string, count: number) => string;\n}\n\nexport interface ComposerOverrides {\n COMPOSER_INSERT_MENTION: string;\n COMPOSER_INSERT_EMOJI: string;\n COMPOSER_ATTACH_FILES: string;\n COMPOSER_REMOVE_ATTACHMENT: string;\n COMPOSER_PLACEHOLDER: string;\n COMPOSER_SEND: string;\n COMPOSER_TOGGLE_MARK: (mark: ComposerBodyMark) => string;\n}\n\nexport interface AiChatComposerOverrides {\n AI_CHAT_COMPOSER_PLACEHOLDER: string;\n AI_CHAT_COMPOSER_SEND: string;\n AI_CHAT_COMPOSER_ABORT: string;\n}\n\nexport interface AiChatMessageOverrides {\n AI_CHAT_MESSAGE_DELETED: string;\n AI_CHAT_MESSAGE_THINKING: string;\n}\n\nexport interface AiChatOverrides {\n AI_CHAT_MESSAGES_ERROR: (error: Error) => ReactNode;\n}\n\nexport interface ThreadOverrides {\n THREAD_RESOLVE: string;\n THREAD_UNRESOLVE: string;\n THREAD_SUBSCRIBE: string;\n THREAD_UNSUBSCRIBE: string;\n THREAD_NEW_INDICATOR: string;\n THREAD_NEW_INDICATOR_DESCRIPTION: string;\n THREAD_COMPOSER_PLACEHOLDER: string;\n THREAD_COMPOSER_SEND: string;\n}\n\nexport interface InboxNotificationOverrides {\n INBOX_NOTIFICATION_MORE: string;\n INBOX_NOTIFICATION_MARK_AS_READ: string;\n INBOX_NOTIFICATION_DELETE: string;\n INBOX_NOTIFICATION_THREAD_COMMENTS_LIST: (\n list: ReactNode,\n room: ReactNode | undefined,\n count: number\n ) => ReactNode;\n INBOX_NOTIFICATION_THREAD_MENTION: (\n user: ReactNode,\n room: ReactNode | undefined\n ) => ReactNode;\n INBOX_NOTIFICATION_TEXT_MENTION: (\n user: ReactNode,\n room: ReactNode | undefined\n ) => ReactNode;\n}\n\nexport interface HistoryVersionPreviewOverrides {\n HISTORY_VERSION_PREVIEW_AUTHORS_LIST: (list: ReactNode) => ReactNode;\n HISTORY_VERSION_PREVIEW_RESTORE: string;\n HISTORY_VERSION_PREVIEW_EMPTY: ReactNode;\n HISTORY_VERSION_PREVIEW_ERROR: (error: Error) => ReactNode;\n}\n\nexport type Overrides = LocalizationOverrides &\n GlobalOverrides &\n ComposerOverrides &\n CommentOverrides &\n ThreadOverrides &\n InboxNotificationOverrides &\n HistoryVersionPreviewOverrides &\n AiChatComposerOverrides &\n AiChatMessageOverrides &\n AiChatOverrides;\n\ntype OverridesProviderProps = PropsWithChildren<{\n overrides?: Partial<Overrides>;\n}>;\n\nexport const defaultOverrides: Overrides = {\n locale: \"en\",\n dir: \"ltr\",\n USER_SELF: \"you\",\n USER_UNKNOWN: \"Anonymous\",\n LIST_REMAINING: (count) => `${count} more`,\n LIST_REMAINING_USERS: (count) => `${count} ${pluralize(count, \"other\")}`,\n LIST_REMAINING_COMMENTS: (count) =>\n `${count} more ${pluralize(count, \"comment\")}`,\n EMOJI_PICKER_SEARCH_PLACEHOLDER: \"Search…\",\n EMOJI_PICKER_EMPTY: \"No emoji found.\",\n EMOJI_PICKER_ERROR: () =>\n \"There was an error while getting the list of emoji.\",\n EMOJI_PICKER_CHANGE_SKIN_TONE: \"Change skin tone\",\n ATTACHMENT_TOO_LARGE: (maxSize) =>\n maxSize ? `The file is larger than ${maxSize}` : \"The file is too large\",\n ATTACHMENT_ERROR: () => \"The file couldn’t be uploaded.\",\n COMPOSER_INSERT_MENTION: \"Mention someone\",\n COMPOSER_INSERT_EMOJI: \"Add emoji\",\n COMPOSER_ATTACH_FILES: \"Attach files\",\n COMPOSER_REMOVE_ATTACHMENT: \"Remove attachment\",\n COMPOSER_PLACEHOLDER: \"Write a comment…\",\n COMPOSER_SEND: \"Send\",\n COMPOSER_TOGGLE_MARK: (format) => {\n switch (format) {\n case \"bold\":\n return \"Bold\";\n case \"italic\":\n return \"Italic\";\n case \"strikethrough\":\n return \"Strikethrough\";\n case \"code\":\n return \"Inline code\";\n default:\n return assertNever(format, \"Unexpected mark\");\n }\n },\n COMMENT_EDITED: \"(edited)\",\n COMMENT_DELETED: \"This comment has been deleted.\",\n COMMENT_MORE: \"More\",\n COMMENT_EDIT: \"Edit comment\",\n COMMENT_EDIT_COMPOSER_PLACEHOLDER: \"Edit comment…\",\n COMMENT_EDIT_COMPOSER_CANCEL: \"Cancel\",\n COMMENT_EDIT_COMPOSER_SAVE: \"Save\",\n COMMENT_DELETE: \"Delete comment\",\n COMMENT_DELETE_ATTACHMENT: \"Delete attachment\",\n COMMENT_ADD_REACTION: \"Add reaction\",\n COMMENT_REACTION_LIST: (list, emoji) => (\n <>\n {list} reacted with <Emoji emoji={emoji} />\n </>\n ),\n COMMENT_REACTION_DESCRIPTION: (emoji, count) =>\n `${count} ${pluralize(count, \"reaction\")}, react with ${emoji}`,\n THREAD_RESOLVE: \"Resolve thread\",\n THREAD_UNRESOLVE: \"Re-open thread\",\n THREAD_SUBSCRIBE: \"Subscribe to thread\",\n THREAD_UNSUBSCRIBE: \"Unsubscribe from thread\",\n THREAD_NEW_INDICATOR: \"New\",\n THREAD_NEW_INDICATOR_DESCRIPTION: \"New comments\",\n THREAD_COMPOSER_PLACEHOLDER: \"Reply to thread…\",\n THREAD_COMPOSER_SEND: \"Reply\",\n INBOX_NOTIFICATION_MORE: \"More\",\n INBOX_NOTIFICATION_MARK_AS_READ: \"Mark as read\",\n INBOX_NOTIFICATION_DELETE: \"Delete notification\",\n INBOX_NOTIFICATION_THREAD_COMMENTS_LIST: (\n list: ReactNode,\n room: ReactNode\n ) => (\n <>\n {list} commented\n {room ? <> in {room}</> : <> in a thread</>}\n </>\n ),\n INBOX_NOTIFICATION_THREAD_MENTION: (user: ReactNode, room: ReactNode) => (\n <>\n {user} mentioned you{room ? <> in {room}</> : null}\n </>\n ),\n INBOX_NOTIFICATION_TEXT_MENTION: (user: ReactNode, room: ReactNode) => (\n <>\n {user} mentioned you{room ? <> in {room}</> : null}\n </>\n ),\n HISTORY_VERSION_PREVIEW_AUTHORS_LIST: (list: ReactNode) => (\n <>Edits from {list}</>\n ),\n HISTORY_VERSION_PREVIEW_RESTORE: \"Restore\",\n HISTORY_VERSION_PREVIEW_EMPTY: \"No content.\",\n HISTORY_VERSION_PREVIEW_ERROR: () =>\n \"There was an error while getting this version.\",\n AI_CHAT_COMPOSER_PLACEHOLDER: \"Ask anything…\",\n AI_CHAT_COMPOSER_SEND: \"Send\",\n AI_CHAT_COMPOSER_ABORT: \"Abort response\",\n AI_CHAT_MESSAGE_DELETED: \"This message has been deleted.\",\n AI_CHAT_MESSAGE_THINKING: \"Thinking…\",\n AI_CHAT_MESSAGES_ERROR: () =>\n \"There was an error while getting the messages.\",\n};\n\nexport const OverridesContext = createContext<Overrides | undefined>(undefined);\n\nexport function useOverrides(overrides?: Partial<Overrides>): Overrides {\n const contextOverrides = useContext(OverridesContext);\n\n return useMemo(\n () => ({\n ...defaultOverrides,\n ...contextOverrides,\n ...overrides,\n }),\n [contextOverrides, overrides]\n );\n}\n\nexport function OverridesProvider({\n children,\n overrides: providerOverrides,\n}: OverridesProviderProps) {\n const contextOverrides = useContext(OverridesContext);\n const overrides = useMemo(\n () => ({\n ...defaultOverrides,\n ...contextOverrides,\n ...providerOverrides,\n }),\n [contextOverrides, providerOverrides]\n );\n\n return (\n <OverridesContext.Provider value={overrides}>\n {children}\n </OverridesContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AA6HO;AAAoC;AACjC;AACH;AACM;AACG;AACgB;AACuC;AAExB;AACZ;AACb;AAElB;AAC6B;AAEoB;AAC3B;AACC;AACF;AACA;AACK;AACN;AACP;AAEb;AAAgB;AAEZ;AAAO;AAEP;AAAO;AAEP;AAAO;AAEP;AAAO;AAEP;AAA4C;AAChD;AACF;AACgB;AACC;AACH;AACA;AACqB;AACL;AACF;AACZ;AACW;AACL;AAEpB;AACG;AAAA;AAAK;AAAe;AAAM;AAAc;AAAA;AAC3C;AAGwD;AAC1C;AACE;AACA;AACE;AACE;AACY;AACL;AACP;AACG;AACQ;AACN;AAKzB;AACG;AAAA;AAAK;AACE;AAAE;AAAA;AAAK;AAAA;AAAW;AAAE;AAAY;AAAA;AAC1C;AAGA;AACG;AAAA;AAAK;AAAsB;AAAE;AAAA;AAAK;AAAA;AAAW;AAAA;AAChD;AAGA;AACG;AAAA;AAAK;AAAsB;AAAE;AAAA;AAAK;AAAA;AAAW;AAAA;AAChD;AAGA;AAAE;AAAA;AAAY;AAAA;AAAK;AAEY;AACF;AAE7B;AAC4B;AACP;AACC;AACC;AACC;AAG5B;AAEa;AAEN;AACL;AAEA;AAAO;AACE;AACF;AACA;AACA;AACL;AAC4B;AAEhC;AAEO;AAA2B;AAChC;AAEF;AACE;AACA;AAAkB;AACT;AACF;AACA;AACA;AACL;AACoC;AAGtC;AACG;AAAiC;AAC/B;AAGP;;"}
1
+ {"version":3,"file":"overrides.js","sources":["../src/overrides.tsx"],"sourcesContent":["\"use client\";\n\nimport { assertNever } from \"@liveblocks/core\";\nimport type { PropsWithChildren, ReactNode } from \"react\";\nimport { createContext, useContext, useMemo } from \"react\";\n\nimport { Emoji } from \"./components/internal/Emoji\";\nimport type { ComposerBodyMark, Direction } from \"./types\";\nimport { pluralize } from \"./utils/pluralize\";\n\nexport interface LocalizationOverrides {\n locale: string;\n dir: Direction;\n}\n\nexport interface GlobalOverrides {\n USER_SELF: string;\n USER_UNKNOWN: string;\n LIST_REMAINING: (count: number) => string;\n LIST_REMAINING_USERS: (count: number) => string;\n LIST_REMAINING_COMMENTS: (count: number) => string;\n EMOJI_PICKER_SEARCH_PLACEHOLDER: string;\n EMOJI_PICKER_EMPTY: ReactNode;\n EMOJI_PICKER_ERROR: (error: Error) => ReactNode;\n EMOJI_PICKER_CHANGE_SKIN_TONE: string;\n ATTACHMENT_TOO_LARGE: (maxSize?: string) => string;\n ATTACHMENT_ERROR: (error: Error) => string;\n COPY_TO_CLIPBOARD: string;\n}\n\nexport interface CommentOverrides {\n COMMENT_EDITED: ReactNode;\n COMMENT_DELETED: ReactNode;\n COMMENT_MORE: string;\n COMMENT_EDIT: string;\n COMMENT_EDIT_COMPOSER_PLACEHOLDER: string;\n COMMENT_EDIT_COMPOSER_CANCEL: string;\n COMMENT_EDIT_COMPOSER_SAVE: string;\n COMMENT_DELETE: string;\n COMMENT_DELETE_ATTACHMENT: string;\n COMMENT_ADD_REACTION: string;\n COMMENT_REACTION_LIST: (\n list: ReactNode,\n emoji: string,\n count: number\n ) => ReactNode;\n COMMENT_REACTION_DESCRIPTION: (emoji: string, count: number) => string;\n}\n\nexport interface ComposerOverrides {\n COMPOSER_INSERT_MENTION: string;\n COMPOSER_INSERT_EMOJI: string;\n COMPOSER_ATTACH_FILES: string;\n COMPOSER_REMOVE_ATTACHMENT: string;\n COMPOSER_PLACEHOLDER: string;\n COMPOSER_SEND: string;\n COMPOSER_TOGGLE_MARK: (mark: ComposerBodyMark) => string;\n}\n\nexport interface AiToolConfirmationOverrides {\n AI_TOOL_CONFIRMATION_CONFIRM: string;\n AI_TOOL_CONFIRMATION_CANCEL: string;\n}\n\nexport interface AiChatComposerOverrides {\n AI_CHAT_COMPOSER_PLACEHOLDER: string;\n AI_CHAT_COMPOSER_SEND: string;\n AI_CHAT_COMPOSER_ABORT: string;\n}\n\nexport interface AiChatMessageOverrides {\n AI_CHAT_MESSAGE_DELETED: string;\n AI_CHAT_MESSAGE_THINKING: string;\n AI_CHAT_MESSAGE_REASONING: (isStreaming: boolean) => string;\n}\n\nexport interface AiChatOverrides {\n AI_CHAT_MESSAGES_ERROR: (error: Error) => ReactNode;\n}\n\nexport interface ThreadOverrides {\n THREAD_RESOLVE: string;\n THREAD_UNRESOLVE: string;\n THREAD_SUBSCRIBE: string;\n THREAD_UNSUBSCRIBE: string;\n THREAD_NEW_INDICATOR: string;\n THREAD_NEW_INDICATOR_DESCRIPTION: string;\n THREAD_COMPOSER_PLACEHOLDER: string;\n THREAD_COMPOSER_SEND: string;\n}\n\nexport interface InboxNotificationOverrides {\n INBOX_NOTIFICATION_MORE: string;\n INBOX_NOTIFICATION_MARK_AS_READ: string;\n INBOX_NOTIFICATION_DELETE: string;\n INBOX_NOTIFICATION_THREAD_COMMENTS_LIST: (\n list: ReactNode,\n room: ReactNode | undefined,\n count: number\n ) => ReactNode;\n INBOX_NOTIFICATION_THREAD_MENTION: (\n user: ReactNode,\n room: ReactNode | undefined\n ) => ReactNode;\n INBOX_NOTIFICATION_TEXT_MENTION: (\n user: ReactNode,\n room: ReactNode | undefined\n ) => ReactNode;\n}\n\nexport interface HistoryVersionPreviewOverrides {\n HISTORY_VERSION_PREVIEW_AUTHORS_LIST: (list: ReactNode) => ReactNode;\n HISTORY_VERSION_PREVIEW_RESTORE: string;\n HISTORY_VERSION_PREVIEW_EMPTY: ReactNode;\n HISTORY_VERSION_PREVIEW_ERROR: (error: Error) => ReactNode;\n}\n\nexport type Overrides = LocalizationOverrides &\n GlobalOverrides &\n ComposerOverrides &\n CommentOverrides &\n ThreadOverrides &\n InboxNotificationOverrides &\n HistoryVersionPreviewOverrides &\n AiChatComposerOverrides &\n AiChatMessageOverrides &\n AiChatOverrides &\n AiToolConfirmationOverrides;\n\ntype OverridesProviderProps = PropsWithChildren<{\n overrides?: Partial<Overrides>;\n}>;\n\nexport const defaultOverrides: Overrides = {\n locale: \"en\",\n dir: \"ltr\",\n USER_SELF: \"you\",\n USER_UNKNOWN: \"Anonymous\",\n COPY_TO_CLIPBOARD: \"Copy\",\n LIST_REMAINING: (count) => `${count} more`,\n LIST_REMAINING_USERS: (count) => `${count} ${pluralize(count, \"other\")}`,\n LIST_REMAINING_COMMENTS: (count) =>\n `${count} more ${pluralize(count, \"comment\")}`,\n EMOJI_PICKER_SEARCH_PLACEHOLDER: \"Search…\",\n EMOJI_PICKER_EMPTY: \"No emoji found.\",\n EMOJI_PICKER_ERROR: () =>\n \"There was an error while getting the list of emoji.\",\n EMOJI_PICKER_CHANGE_SKIN_TONE: \"Change skin tone\",\n ATTACHMENT_TOO_LARGE: (maxSize) =>\n maxSize ? `The file is larger than ${maxSize}` : \"The file is too large\",\n ATTACHMENT_ERROR: () => \"The file couldn’t be uploaded.\",\n COMPOSER_INSERT_MENTION: \"Mention someone\",\n COMPOSER_INSERT_EMOJI: \"Add emoji\",\n COMPOSER_ATTACH_FILES: \"Attach files\",\n COMPOSER_REMOVE_ATTACHMENT: \"Remove attachment\",\n COMPOSER_PLACEHOLDER: \"Write a comment…\",\n COMPOSER_SEND: \"Send\",\n COMPOSER_TOGGLE_MARK: (format) => {\n switch (format) {\n case \"bold\":\n return \"Bold\";\n case \"italic\":\n return \"Italic\";\n case \"strikethrough\":\n return \"Strikethrough\";\n case \"code\":\n return \"Inline code\";\n default:\n return assertNever(format, \"Unexpected mark\");\n }\n },\n COMMENT_EDITED: \"(edited)\",\n COMMENT_DELETED: \"This comment has been deleted.\",\n COMMENT_MORE: \"More\",\n COMMENT_EDIT: \"Edit comment\",\n COMMENT_EDIT_COMPOSER_PLACEHOLDER: \"Edit comment…\",\n COMMENT_EDIT_COMPOSER_CANCEL: \"Cancel\",\n COMMENT_EDIT_COMPOSER_SAVE: \"Save\",\n COMMENT_DELETE: \"Delete comment\",\n COMMENT_DELETE_ATTACHMENT: \"Delete attachment\",\n COMMENT_ADD_REACTION: \"Add reaction\",\n COMMENT_REACTION_LIST: (list, emoji) => (\n <>\n {list} reacted with <Emoji emoji={emoji} />\n </>\n ),\n COMMENT_REACTION_DESCRIPTION: (emoji, count) =>\n `${count} ${pluralize(count, \"reaction\")}, react with ${emoji}`,\n THREAD_RESOLVE: \"Resolve thread\",\n THREAD_UNRESOLVE: \"Re-open thread\",\n THREAD_SUBSCRIBE: \"Subscribe to thread\",\n THREAD_UNSUBSCRIBE: \"Unsubscribe from thread\",\n THREAD_NEW_INDICATOR: \"New\",\n THREAD_NEW_INDICATOR_DESCRIPTION: \"New comments\",\n THREAD_COMPOSER_PLACEHOLDER: \"Reply to thread…\",\n THREAD_COMPOSER_SEND: \"Reply\",\n INBOX_NOTIFICATION_MORE: \"More\",\n INBOX_NOTIFICATION_MARK_AS_READ: \"Mark as read\",\n INBOX_NOTIFICATION_DELETE: \"Delete notification\",\n INBOX_NOTIFICATION_THREAD_COMMENTS_LIST: (\n list: ReactNode,\n room: ReactNode\n ) => (\n <>\n {list} commented\n {room ? <> in {room}</> : <> in a thread</>}\n </>\n ),\n INBOX_NOTIFICATION_THREAD_MENTION: (user: ReactNode, room: ReactNode) => (\n <>\n {user} mentioned you{room ? <> in {room}</> : null}\n </>\n ),\n INBOX_NOTIFICATION_TEXT_MENTION: (user: ReactNode, room: ReactNode) => (\n <>\n {user} mentioned you{room ? <> in {room}</> : null}\n </>\n ),\n HISTORY_VERSION_PREVIEW_AUTHORS_LIST: (list: ReactNode) => (\n <>Edits from {list}</>\n ),\n HISTORY_VERSION_PREVIEW_RESTORE: \"Restore\",\n HISTORY_VERSION_PREVIEW_EMPTY: \"No content.\",\n HISTORY_VERSION_PREVIEW_ERROR: () =>\n \"There was an error while getting this version.\",\n AI_CHAT_COMPOSER_PLACEHOLDER: \"Ask anything…\",\n AI_CHAT_COMPOSER_SEND: \"Send\",\n AI_CHAT_COMPOSER_ABORT: \"Abort response\",\n AI_CHAT_MESSAGE_DELETED: \"This message has been deleted.\",\n AI_CHAT_MESSAGE_THINKING: \"Thinking…\",\n AI_CHAT_MESSAGE_REASONING: (isStreaming) =>\n isStreaming ? \"Reasoning…\" : \"Reasoning\",\n AI_CHAT_MESSAGES_ERROR: () =>\n \"There was an error while getting the messages.\",\n AI_TOOL_CONFIRMATION_CONFIRM: \"Confirm\",\n AI_TOOL_CONFIRMATION_CANCEL: \"Cancel\",\n};\n\nexport const OverridesContext = createContext<Overrides | undefined>(undefined);\n\nexport function useOverrides(overrides?: Partial<Overrides>): Overrides {\n const contextOverrides = useContext(OverridesContext);\n\n return useMemo(\n () => ({\n ...defaultOverrides,\n ...contextOverrides,\n ...overrides,\n }),\n [contextOverrides, overrides]\n );\n}\n\nexport function OverridesProvider({\n children,\n overrides: providerOverrides,\n}: OverridesProviderProps) {\n const contextOverrides = useContext(OverridesContext);\n const overrides = useMemo(\n () => ({\n ...defaultOverrides,\n ...contextOverrides,\n ...providerOverrides,\n }),\n [contextOverrides, providerOverrides]\n );\n\n return (\n <OverridesContext.Provider value={overrides}>\n {children}\n </OverridesContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAqIO;AAAoC;AACjC;AACH;AACM;AACG;AACK;AACW;AACuC;AAExB;AACZ;AACb;AAElB;AAC6B;AAEoB;AAC3B;AACC;AACF;AACA;AACK;AACN;AACP;AAEb;AAAgB;AAEZ;AAAO;AAEP;AAAO;AAEP;AAAO;AAEP;AAAO;AAEP;AAA4C;AAChD;AACF;AACgB;AACC;AACH;AACA;AACqB;AACL;AACF;AACZ;AACW;AACL;AAEpB;AACG;AAAA;AAAK;AAAe;AAAM;AAAc;AAAA;AAC3C;AAGwD;AAC1C;AACE;AACA;AACE;AACE;AACY;AACL;AACP;AACG;AACQ;AACN;AAKzB;AACG;AAAA;AAAK;AACE;AAAE;AAAA;AAAK;AAAA;AAAW;AAAE;AAAY;AAAA;AAC1C;AAGA;AACG;AAAA;AAAK;AAAsB;AAAE;AAAA;AAAK;AAAA;AAAW;AAAA;AAChD;AAGA;AACG;AAAA;AAAK;AAAsB;AAAE;AAAA;AAAK;AAAA;AAAW;AAAA;AAChD;AAGA;AAAE;AAAA;AAAY;AAAA;AAAK;AAEY;AACF;AAE7B;AAC4B;AACP;AACC;AACC;AACC;AAEK;AAE7B;AAC4B;AAEhC;AAEa;AAEN;AACL;AAEA;AAAO;AACE;AACF;AACA;AACA;AACL;AAC4B;AAEhC;AAEO;AAA2B;AAChC;AAEF;AACE;AACA;AAAkB;AACT;AACF;AACA;AACA;AACL;AACoC;AAGtC;AACG;AAAiC;AAC/B;AAGP;;"}
@@ -1,14 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var core = require('@liveblocks/core');
5
- var react$1 = require('@liveblocks/react');
6
- var _private = require('@liveblocks/react/_private');
7
4
  var reactSlot = require('@radix-ui/react-slot');
8
5
  var react = require('react');
9
6
  var ErrorBoundary = require('../../utils/ErrorBoundary.cjs');
10
7
  var Markdown = require('../Markdown.cjs');
11
- var contexts = require('./contexts.cjs');
8
+ var toolInvocation = require('./tool-invocation.cjs');
12
9
 
13
10
  const AI_MESSAGE_CONTENT_NAME = "AiMessageContent";
14
11
  const defaultMessageContentComponents = {
@@ -22,65 +19,16 @@ const defaultMessageContentComponents = {
22
19
  content: part.text
23
20
  });
24
21
  },
25
- ToolInvocationPart: react.Fragment
26
- };
27
- function ToolInvocation({
28
- chatId,
29
- messageId,
30
- part
31
- }) {
32
- const client = react$1.useClient();
33
- const ai = client[core.kInternal].ai;
34
- const tool = _private.useSignal(ai.signals.getToolDefinition\u03A3(chatId, part.toolName));
35
- const respond = react.useCallback(
36
- (result) => {
37
- if (part.status === "receiving") {
38
- console.log(
39
- `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) is still receiving`
40
- );
41
- } else if (part.status === "executed") {
42
- console.log(
43
- `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) has already executed`
44
- );
45
- } else {
46
- ai.setToolResult(
47
- chatId,
48
- messageId,
49
- part.toolCallId,
50
- result
51
- );
52
- }
53
- },
54
- [ai, chatId, messageId, part.status, part.toolName, part.toolCallId]
55
- );
56
- if (tool === void 0 || tool.render === void 0)
57
- return null;
58
- const { type: _, ...rest } = part;
59
- const props = {
60
- ...rest,
61
- respond,
62
- $types: void 0,
63
- [core.kInternal]: {
64
- execute: tool.execute
65
- }
66
- };
67
- return /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary.ErrorBoundary, {
68
- fallback: /* @__PURE__ */ jsxRuntime.jsxs("p", {
69
- style: { color: "red" },
70
- children: [
71
- "Failed to render tool call result for '",
72
- part.toolName,
73
- "'. See console for details."
74
- ]
75
- }),
76
- children: /* @__PURE__ */ jsxRuntime.jsx(contexts.AiToolInvocationContext.Provider, {
77
- value: props,
78
- children: /* @__PURE__ */ jsxRuntime.jsx(tool.render, {
79
- ...props
22
+ ToolInvocationPart: ({ part, message }) => {
23
+ return /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary.ErrorBoundary, {
24
+ fallback: null,
25
+ children: /* @__PURE__ */ jsxRuntime.jsx(toolInvocation.AiMessageToolInvocation, {
26
+ part,
27
+ message
80
28
  })
81
- })
82
- });
83
- }
29
+ });
30
+ }
31
+ };
84
32
  const AiMessageContent = react.forwardRef(
85
33
  ({ message, components, asChild, ...props }, forwardedRef) => {
86
34
  const Component = asChild ? reactSlot.Slot : "div";
@@ -112,11 +60,7 @@ const AiMessageContent = react.forwardRef(
112
60
  return /* @__PURE__ */ jsxRuntime.jsx(ToolInvocationPart, {
113
61
  part,
114
62
  ...extra,
115
- children: /* @__PURE__ */ jsxRuntime.jsx(ToolInvocation, {
116
- part,
117
- chatId: message.chatId,
118
- messageId: message.id
119
- }, index)
63
+ message
120
64
  }, index);
121
65
  default:
122
66
  return null;