@liveblocks/react-ui 2.25.0-aiprivatebeta7 → 2.25.0-aiprivatebeta9

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 (135) hide show
  1. package/dist/_private/index.cjs +14 -10
  2. package/dist/_private/index.cjs.map +1 -1
  3. package/dist/_private/index.d.cts +200 -105
  4. package/dist/_private/index.d.ts +200 -105
  5. package/dist/_private/index.js +10 -5
  6. package/dist/_private/index.js.map +1 -1
  7. package/dist/components/AiChat.cjs +85 -120
  8. package/dist/components/AiChat.cjs.map +1 -1
  9. package/dist/components/AiChat.js +87 -122
  10. package/dist/components/AiChat.js.map +1 -1
  11. package/dist/components/AiTool.cjs +164 -0
  12. package/dist/components/AiTool.cjs.map +1 -0
  13. package/dist/components/AiTool.js +162 -0
  14. package/dist/components/AiTool.js.map +1 -0
  15. package/dist/components/Comment.cjs +5 -3
  16. package/dist/components/Comment.cjs.map +1 -1
  17. package/dist/components/Comment.js +6 -4
  18. package/dist/components/Comment.js.map +1 -1
  19. package/dist/components/InboxNotificationList.cjs +11 -3
  20. package/dist/components/InboxNotificationList.cjs.map +1 -1
  21. package/dist/components/InboxNotificationList.js +12 -4
  22. package/dist/components/InboxNotificationList.js.map +1 -1
  23. package/dist/components/Thread.cjs +3 -3
  24. package/dist/components/Thread.cjs.map +1 -1
  25. package/dist/components/Thread.js +3 -3
  26. package/dist/components/Thread.js.map +1 -1
  27. package/dist/components/internal/AiChatAssistantMessage.cjs +53 -229
  28. package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
  29. package/dist/components/internal/AiChatAssistantMessage.js +55 -231
  30. package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
  31. package/dist/components/internal/AiChatComposer.cjs +29 -17
  32. package/dist/components/internal/AiChatComposer.cjs.map +1 -1
  33. package/dist/components/internal/AiChatComposer.js +29 -17
  34. package/dist/components/internal/AiChatComposer.js.map +1 -1
  35. package/dist/components/internal/AiChatUserMessage.cjs +17 -10
  36. package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
  37. package/dist/components/internal/AiChatUserMessage.js +17 -10
  38. package/dist/components/internal/AiChatUserMessage.js.map +1 -1
  39. package/dist/components/internal/Button.cjs.map +1 -1
  40. package/dist/components/internal/Button.js.map +1 -1
  41. package/dist/components/internal/CodeBlock.cjs +72 -0
  42. package/dist/components/internal/CodeBlock.cjs.map +1 -0
  43. package/dist/components/internal/CodeBlock.js +70 -0
  44. package/dist/components/internal/CodeBlock.js.map +1 -0
  45. package/dist/components/internal/Emoji.cjs +12 -4
  46. package/dist/components/internal/Emoji.cjs.map +1 -1
  47. package/dist/components/internal/Emoji.js +12 -4
  48. package/dist/components/internal/Emoji.js.map +1 -1
  49. package/dist/components/internal/Prose.cjs +37 -0
  50. package/dist/components/internal/Prose.cjs.map +1 -0
  51. package/dist/components/internal/Prose.js +35 -0
  52. package/dist/components/internal/Prose.js.map +1 -0
  53. package/dist/icon.cjs +2 -0
  54. package/dist/icon.cjs.map +1 -1
  55. package/dist/icon.js +1 -0
  56. package/dist/icon.js.map +1 -1
  57. package/dist/icons/{Resolve.cjs → CheckCircle.cjs} +3 -3
  58. package/dist/icons/CheckCircle.cjs.map +1 -0
  59. package/dist/icons/{Resolve.js → CheckCircle.js} +3 -3
  60. package/dist/icons/CheckCircle.js.map +1 -0
  61. package/dist/icons/{Resolved.cjs → CheckCircleFill.cjs} +3 -3
  62. package/dist/icons/CheckCircleFill.cjs.map +1 -0
  63. package/dist/icons/{Resolved.js → CheckCircleFill.js} +3 -3
  64. package/dist/icons/CheckCircleFill.js.map +1 -0
  65. package/dist/icons/index.cjs +4 -4
  66. package/dist/icons/index.js +2 -2
  67. package/dist/index.cjs +2 -0
  68. package/dist/index.cjs.map +1 -1
  69. package/dist/index.d.cts +68 -14
  70. package/dist/index.d.ts +68 -14
  71. package/dist/index.js +1 -0
  72. package/dist/index.js.map +1 -1
  73. package/dist/overrides.cjs +2 -8
  74. package/dist/overrides.cjs.map +1 -1
  75. package/dist/overrides.js +2 -8
  76. package/dist/overrides.js.map +1 -1
  77. package/dist/primitives/AiChatComposer/index.cjs +1 -2
  78. package/dist/primitives/AiChatComposer/index.cjs.map +1 -1
  79. package/dist/primitives/AiChatComposer/index.js +1 -2
  80. package/dist/primitives/AiChatComposer/index.js.map +1 -1
  81. package/dist/primitives/AiMessage/contexts.cjs +18 -0
  82. package/dist/primitives/AiMessage/contexts.cjs.map +1 -0
  83. package/dist/primitives/AiMessage/contexts.js +15 -0
  84. package/dist/primitives/AiMessage/contexts.js.map +1 -0
  85. package/dist/primitives/AiMessage/index.cjs +133 -0
  86. package/dist/primitives/AiMessage/index.cjs.map +1 -0
  87. package/dist/primitives/AiMessage/index.js +131 -0
  88. package/dist/primitives/AiMessage/index.js.map +1 -0
  89. package/dist/primitives/{internal/Collapsible → Collapsible}/index.cjs +39 -17
  90. package/dist/primitives/Collapsible/index.cjs.map +1 -0
  91. package/dist/primitives/{internal/Collapsible → Collapsible}/index.js +37 -15
  92. package/dist/primitives/Collapsible/index.js.map +1 -0
  93. package/dist/primitives/{internal/Markdown.cjs → Markdown.cjs} +150 -83
  94. package/dist/primitives/Markdown.cjs.map +1 -0
  95. package/dist/primitives/{internal/Markdown.js → Markdown.js} +151 -83
  96. package/dist/primitives/Markdown.js.map +1 -0
  97. package/dist/primitives/index.cjs +4 -6
  98. package/dist/primitives/index.cjs.map +1 -1
  99. package/dist/primitives/index.d.cts +2 -79
  100. package/dist/primitives/index.d.ts +2 -79
  101. package/dist/primitives/index.js +4 -6
  102. package/dist/primitives/index.js.map +1 -1
  103. package/dist/utils/ErrorBoundary.cjs +48 -0
  104. package/dist/utils/ErrorBoundary.cjs.map +1 -0
  105. package/dist/utils/ErrorBoundary.js +45 -0
  106. package/dist/utils/ErrorBoundary.js.map +1 -0
  107. package/dist/utils/use-visible.cjs +63 -45
  108. package/dist/utils/use-visible.cjs.map +1 -1
  109. package/dist/utils/use-visible.js +64 -46
  110. package/dist/utils/use-visible.js.map +1 -1
  111. package/dist/version.cjs +1 -1
  112. package/dist/version.js +1 -1
  113. package/package.json +5 -5
  114. package/src/styles/constants.css +1 -1
  115. package/src/styles/dark/index.css +7 -3
  116. package/src/styles/index.css +584 -238
  117. package/src/styles/utils.css +1 -1
  118. package/styles/dark/attributes.css +1 -1
  119. package/styles/dark/attributes.css.map +1 -1
  120. package/styles/dark/media-query.css +1 -1
  121. package/styles/dark/media-query.css.map +1 -1
  122. package/styles.css +1 -1
  123. package/styles.css.map +1 -1
  124. package/dist/icons/Resolve.cjs.map +0 -1
  125. package/dist/icons/Resolve.js.map +0 -1
  126. package/dist/icons/Resolved.cjs.map +0 -1
  127. package/dist/icons/Resolved.js.map +0 -1
  128. package/dist/primitives/internal/Collapsible/index.cjs.map +0 -1
  129. package/dist/primitives/internal/Collapsible/index.js.map +0 -1
  130. package/dist/primitives/internal/Emoji.cjs +0 -32
  131. package/dist/primitives/internal/Emoji.cjs.map +0 -1
  132. package/dist/primitives/internal/Emoji.js +0 -30
  133. package/dist/primitives/internal/Emoji.js.map +0 -1
  134. package/dist/primitives/internal/Markdown.cjs.map +0 -1
  135. package/dist/primitives/internal/Markdown.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { detectDupes } from '@liveblocks/core';
2
2
  import { PKG_NAME, PKG_VERSION, PKG_FORMAT } from './version.js';
3
3
  export { AiChat } from './components/AiChat.js';
4
+ export { AiTool } from './components/AiTool.js';
4
5
  export { Comment } from './components/Comment.js';
5
6
  export { Composer } from './components/Composer.js';
6
7
  export { HistoryVersionSummary } from './components/HistoryVersionSummary.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 { 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 { 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"}
@@ -122,16 +122,10 @@ const defaultOverrides = {
122
122
  HISTORY_VERSION_PREVIEW_ERROR: () => "There was an error while getting this version.",
123
123
  AI_CHAT_COMPOSER_PLACEHOLDER: "Ask anything\u2026",
124
124
  AI_CHAT_COMPOSER_SEND: "Send",
125
- AI_CHAT_COMPOSER_ATTACH_FILES: "Attach files",
126
- AI_CHAT_COMPOSER_REMOVE_ATTACHMENT: "Remove attachment",
127
- AI_CHAT_COMPOSER_ABORT: "Abort response.",
125
+ AI_CHAT_COMPOSER_ABORT: "Abort response",
128
126
  AI_CHAT_MESSAGE_DELETED: "This message has been deleted.",
129
127
  AI_CHAT_MESSAGE_THINKING: "Thinking\u2026",
130
- AI_CHAT_MESSAGE_COPY: "Copy",
131
- AI_CHAT_MESSAGE_TRY_AGAIN: "Try again",
132
- AI_CHAT_MESSAGES_ERROR: () => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {
133
- children: "There was an error while getting the messages"
134
- })
128
+ AI_CHAT_MESSAGES_ERROR: () => "There was an error while getting the messages."
135
129
  };
136
130
  const OverridesContext = react.createContext(void 0);
137
131
  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_ATTACH_FILES: string;\n AI_CHAT_COMPOSER_REMOVE_ATTACHMENT: 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_COPY: string;\n AI_CHAT_MESSAGE_TRY_AGAIN: 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_ATTACH_FILES: \"Attach files\",\n AI_CHAT_COMPOSER_REMOVE_ATTACHMENT: \"Remove attachment\",\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_COPY: \"Copy\",\n AI_CHAT_MESSAGE_TRY_AGAIN: \"Try again\",\n AI_CHAT_MESSAGES_ERROR: () => (\n <>There was an error while getting the messages</>\n ),\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":";;;;;;;;;;AAiIO;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;AACQ;AACK;AACZ;AACC;AACC;AACJ;AACK;AAEzB;AAAE;AAEN;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}\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;;;;;"}
package/dist/overrides.js CHANGED
@@ -120,16 +120,10 @@ const defaultOverrides = {
120
120
  HISTORY_VERSION_PREVIEW_ERROR: () => "There was an error while getting this version.",
121
121
  AI_CHAT_COMPOSER_PLACEHOLDER: "Ask anything\u2026",
122
122
  AI_CHAT_COMPOSER_SEND: "Send",
123
- AI_CHAT_COMPOSER_ATTACH_FILES: "Attach files",
124
- AI_CHAT_COMPOSER_REMOVE_ATTACHMENT: "Remove attachment",
125
- AI_CHAT_COMPOSER_ABORT: "Abort response.",
123
+ AI_CHAT_COMPOSER_ABORT: "Abort response",
126
124
  AI_CHAT_MESSAGE_DELETED: "This message has been deleted.",
127
125
  AI_CHAT_MESSAGE_THINKING: "Thinking\u2026",
128
- AI_CHAT_MESSAGE_COPY: "Copy",
129
- AI_CHAT_MESSAGE_TRY_AGAIN: "Try again",
130
- AI_CHAT_MESSAGES_ERROR: () => /* @__PURE__ */ jsx(Fragment, {
131
- children: "There was an error while getting the messages"
132
- })
126
+ AI_CHAT_MESSAGES_ERROR: () => "There was an error while getting the messages."
133
127
  };
134
128
  const OverridesContext = createContext(void 0);
135
129
  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_ATTACH_FILES: string;\n AI_CHAT_COMPOSER_REMOVE_ATTACHMENT: 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_COPY: string;\n AI_CHAT_MESSAGE_TRY_AGAIN: 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_ATTACH_FILES: \"Attach files\",\n AI_CHAT_COMPOSER_REMOVE_ATTACHMENT: \"Remove attachment\",\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_COPY: \"Copy\",\n AI_CHAT_MESSAGE_TRY_AGAIN: \"Try again\",\n AI_CHAT_MESSAGES_ERROR: () => (\n <>There was an error while getting the messages</>\n ),\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":";;;;;;;;AAiIO;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;AACQ;AACK;AACZ;AACC;AACC;AACJ;AACK;AAEzB;AAAE;AAEN;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}\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;;"}
@@ -15,7 +15,7 @@ const AI_CHAT_COMPOSER_EDITOR_NAME = "AiChatComposerEditor";
15
15
  const AI_CHAT_COMPOSER_FORM_NAME = "AiChatComposerForm";
16
16
  const AiChatComposerContext = react.createContext(null);
17
17
  const AiChatComposerForm = react.forwardRef(
18
- ({ onComposerSubmit, onSubmit, disabled, chatId, asChild, ...props }, forwardedRef) => {
18
+ ({ onComposerSubmit, onSubmit, disabled, asChild, ...props }, forwardedRef) => {
19
19
  const Component = asChild ? reactSlot.Slot : "form";
20
20
  const formRef = react.useRef(null);
21
21
  const editorRef = react.useRef(null);
@@ -88,7 +88,6 @@ const AiChatComposerForm = react.forwardRef(
88
88
  );
89
89
  return /* @__PURE__ */ jsxRuntime.jsx(AiChatComposerContext.Provider, {
90
90
  value: {
91
- chatId,
92
91
  editor,
93
92
  onEditorValueChange: handleEditorValueChange,
94
93
  isEditorEmpty,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiChatComposer/index.tsx"],"sourcesContent":["import { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FormEvent, KeyboardEvent } from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { Descendant as SlateDescendant } from \"slate\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, ReactEditor, Slate, withReact } from \"slate-react\";\n\nimport type { AiComposerEditor } from \"../../types\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport type {\n AiChatComposerEditorProps,\n AiChatComposerFormProps,\n AiChatComposerSubmitProps,\n} from \"./types\";\n\nconst AI_CHAT_COMPOSER_SUBMIT_NAME = \"AiChatComposerSubmit\";\nconst AI_CHAT_COMPOSER_EDITOR_NAME = \"AiChatComposerEditor\";\nconst AI_CHAT_COMPOSER_FORM_NAME = \"AiChatComposerForm\";\n\nconst AiChatComposerContext = createContext<{\n chatId: string;\n\n editor: SlateEditor;\n onEditorValueChange: (value: SlateDescendant[]) => void;\n isEditorEmpty: boolean;\n\n requestFormSubmit: () => void;\n disabled: boolean;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Surrounds the chat composer's content and handles submissions.\n *\n * @example\n * <AiChatComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiChatComposer.Editor />\n * <AiChatComposer.Submit />\n * </AiChatComposer.Form>\n */\nexport const AiChatComposerForm = forwardRef<\n HTMLFormElement,\n AiChatComposerFormProps\n>(\n (\n { onComposerSubmit, onSubmit, disabled, chatId, asChild, ...props },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const formRef = useRef<HTMLFormElement | null>(null);\n\n const editorRef = useRef<AiComposerEditor | null>(null);\n if (editorRef.current === null) {\n editorRef.current = withNormalize(withHistory(withReact(createEditor())));\n }\n const editor = editorRef.current;\n\n const [isEditorEmpty, setIsEditorEmpty] = useState(true);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled || isEmpty(editor, editor.children)) return;\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n onComposerSubmit({ text: content }, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n\n // Clear the editor after dispatching the message.\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n },\n [disabled, editor, onSubmit, onComposerSubmit]\n );\n\n useLayoutEffect(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const requestFormSubmit = useCallback(() => {\n if (isEmpty(editor, editor.children)) return;\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current === null) return;\n if (typeof formRef.current.requestSubmit === \"function\") {\n return formRef.current.requestSubmit();\n }\n const submitter = document.createElement(\"input\");\n submitter.type = \"submit\";\n submitter.hidden = true;\n formRef.current.appendChild(submitter);\n submitter.click();\n formRef.current.removeChild(submitter);\n });\n }, [editor]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiChatComposerContext.Provider\n value={{\n chatId,\n editor,\n onEditorValueChange: handleEditorValueChange,\n isEditorEmpty,\n requestFormSubmit,\n disabled: disabled || false,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiChatComposerContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Displays the chat composer's editor.\n *\n * @example\n * <AiChatComposer.Editor placeholder=\"Write a message…\" />\n */\nexport const AiChatComposerEditor = forwardRef<\n HTMLDivElement,\n AiChatComposerEditorProps\n>(\n (\n { defaultValue = \"\", onKeyDown, disabled, autoFocus, ...props },\n forwardedRef\n ) => {\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const {\n editor,\n onEditorValueChange,\n requestFormSubmit,\n disabled: isFormDisabled,\n } = context;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n requestFormSubmit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n }\n },\n [editor, onKeyDown, requestFormSubmit]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n useEffect(() => {\n if (!autoFocus) return;\n\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM node no longer exists. This action doesn't make sense on an unmounted editor so we can safely ignore it.\n }\n }, [editor, autoFocus]);\n\n const initialValue: { type: \"paragraph\"; children: { text: string }[] }[] =\n useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n onKeyDown={handleKeyDown}\n data-disabled={disabled || isFormDisabled || undefined}\n {...props}\n readOnly={disabled || isFormDisabled}\n disabled={disabled || isFormDisabled}\n renderPlaceholder={function ({ attributes, children }) {\n const { opacity: _opacity, ...style } = attributes.style;\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n }}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit a chat message.\n *\n * @example\n * <AiChatComposer.Submit>Send</AiChatComposer.Submit>\n */\nexport const AiChatComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiChatComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const { disabled: isFormDisabled, isEditorEmpty } = context;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || isFormDisabled || isEditorEmpty}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;\n AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;\n AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiChatComposer.*\nexport {\n AiChatComposerEditor as Editor,\n AiChatComposerForm as Form,\n AiChatComposerSubmit as Submit,\n};\n"],"names":["createContext","forwardRef","Slot","useRef","withNormalize","withHistory","withReact","createEditor","useState","useCallback","isEmpty","SlateTransforms","SlateEditor","useLayoutEffect","useImperativeHandle","jsx","useContext","ReactEditor","useEffect","useMemo","Slate","Editable"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiChatComposer/index.tsx"],"sourcesContent":["import { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FormEvent, KeyboardEvent } from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { Descendant as SlateDescendant } from \"slate\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, ReactEditor, Slate, withReact } from \"slate-react\";\n\nimport type { AiComposerEditor } from \"../../types\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport type {\n AiChatComposerEditorProps,\n AiChatComposerFormProps,\n AiChatComposerSubmitProps,\n} from \"./types\";\n\nconst AI_CHAT_COMPOSER_SUBMIT_NAME = \"AiChatComposerSubmit\";\nconst AI_CHAT_COMPOSER_EDITOR_NAME = \"AiChatComposerEditor\";\nconst AI_CHAT_COMPOSER_FORM_NAME = \"AiChatComposerForm\";\n\nconst AiChatComposerContext = createContext<{\n editor: SlateEditor;\n onEditorValueChange: (value: SlateDescendant[]) => void;\n isEditorEmpty: boolean;\n\n requestFormSubmit: () => void;\n disabled: boolean;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Surrounds the chat composer's content and handles submissions.\n *\n * @example\n * <AiChatComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiChatComposer.Editor />\n * <AiChatComposer.Submit />\n * </AiChatComposer.Form>\n */\nexport const AiChatComposerForm = forwardRef<\n HTMLFormElement,\n AiChatComposerFormProps\n>(\n (\n { onComposerSubmit, onSubmit, disabled, asChild, ...props },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const formRef = useRef<HTMLFormElement | null>(null);\n\n const editorRef = useRef<AiComposerEditor | null>(null);\n if (editorRef.current === null) {\n editorRef.current = withNormalize(withHistory(withReact(createEditor())));\n }\n const editor = editorRef.current;\n\n const [isEditorEmpty, setIsEditorEmpty] = useState(true);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled || isEmpty(editor, editor.children)) return;\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n onComposerSubmit({ text: content }, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n\n // Clear the editor after dispatching the message.\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n },\n [disabled, editor, onSubmit, onComposerSubmit]\n );\n\n useLayoutEffect(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const requestFormSubmit = useCallback(() => {\n if (isEmpty(editor, editor.children)) return;\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current === null) return;\n if (typeof formRef.current.requestSubmit === \"function\") {\n return formRef.current.requestSubmit();\n }\n const submitter = document.createElement(\"input\");\n submitter.type = \"submit\";\n submitter.hidden = true;\n formRef.current.appendChild(submitter);\n submitter.click();\n formRef.current.removeChild(submitter);\n });\n }, [editor]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiChatComposerContext.Provider\n value={{\n editor,\n onEditorValueChange: handleEditorValueChange,\n isEditorEmpty,\n requestFormSubmit,\n disabled: disabled || false,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiChatComposerContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Displays the chat composer's editor.\n *\n * @example\n * <AiChatComposer.Editor placeholder=\"Write a message…\" />\n */\nexport const AiChatComposerEditor = forwardRef<\n HTMLDivElement,\n AiChatComposerEditorProps\n>(\n (\n { defaultValue = \"\", onKeyDown, disabled, autoFocus, ...props },\n forwardedRef\n ) => {\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const {\n editor,\n onEditorValueChange,\n requestFormSubmit,\n disabled: isFormDisabled,\n } = context;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n requestFormSubmit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n }\n },\n [editor, onKeyDown, requestFormSubmit]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n useEffect(() => {\n if (!autoFocus) return;\n\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM node no longer exists. This action doesn't make sense on an unmounted editor so we can safely ignore it.\n }\n }, [editor, autoFocus]);\n\n const initialValue: { type: \"paragraph\"; children: { text: string }[] }[] =\n useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n onKeyDown={handleKeyDown}\n data-disabled={disabled || isFormDisabled || undefined}\n {...props}\n readOnly={disabled || isFormDisabled}\n disabled={disabled || isFormDisabled}\n renderPlaceholder={function ({ attributes, children }) {\n const { opacity: _opacity, ...style } = attributes.style;\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n }}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit a chat message.\n *\n * @example\n * <AiChatComposer.Submit>Send</AiChatComposer.Submit>\n */\nexport const AiChatComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiChatComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const { disabled: isFormDisabled, isEditorEmpty } = context;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || isFormDisabled || isEditorEmpty}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;\n AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;\n AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiChatComposer.*\nexport {\n AiChatComposerEditor as Editor,\n AiChatComposerForm as Form,\n AiChatComposerSubmit as Submit,\n};\n"],"names":["createContext","forwardRef","Slot","useRef","withNormalize","withHistory","withReact","createEditor","useState","useCallback","isEmpty","SlateTransforms","SlateEditor","useLayoutEffect","useImperativeHandle","jsx","useContext","ReactEditor","useEffect","useMemo","Slate","Editable"],"mappings":"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"}
@@ -13,7 +13,7 @@ const AI_CHAT_COMPOSER_EDITOR_NAME = "AiChatComposerEditor";
13
13
  const AI_CHAT_COMPOSER_FORM_NAME = "AiChatComposerForm";
14
14
  const AiChatComposerContext = createContext(null);
15
15
  const AiChatComposerForm = forwardRef(
16
- ({ onComposerSubmit, onSubmit, disabled, chatId, asChild, ...props }, forwardedRef) => {
16
+ ({ onComposerSubmit, onSubmit, disabled, asChild, ...props }, forwardedRef) => {
17
17
  const Component = asChild ? Slot : "form";
18
18
  const formRef = useRef(null);
19
19
  const editorRef = useRef(null);
@@ -86,7 +86,6 @@ const AiChatComposerForm = forwardRef(
86
86
  );
87
87
  return /* @__PURE__ */ jsx(AiChatComposerContext.Provider, {
88
88
  value: {
89
- chatId,
90
89
  editor,
91
90
  onEditorValueChange: handleEditorValueChange,
92
91
  isEditorEmpty,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/primitives/AiChatComposer/index.tsx"],"sourcesContent":["import { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FormEvent, KeyboardEvent } from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { Descendant as SlateDescendant } from \"slate\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, ReactEditor, Slate, withReact } from \"slate-react\";\n\nimport type { AiComposerEditor } from \"../../types\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport type {\n AiChatComposerEditorProps,\n AiChatComposerFormProps,\n AiChatComposerSubmitProps,\n} from \"./types\";\n\nconst AI_CHAT_COMPOSER_SUBMIT_NAME = \"AiChatComposerSubmit\";\nconst AI_CHAT_COMPOSER_EDITOR_NAME = \"AiChatComposerEditor\";\nconst AI_CHAT_COMPOSER_FORM_NAME = \"AiChatComposerForm\";\n\nconst AiChatComposerContext = createContext<{\n chatId: string;\n\n editor: SlateEditor;\n onEditorValueChange: (value: SlateDescendant[]) => void;\n isEditorEmpty: boolean;\n\n requestFormSubmit: () => void;\n disabled: boolean;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Surrounds the chat composer's content and handles submissions.\n *\n * @example\n * <AiChatComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiChatComposer.Editor />\n * <AiChatComposer.Submit />\n * </AiChatComposer.Form>\n */\nexport const AiChatComposerForm = forwardRef<\n HTMLFormElement,\n AiChatComposerFormProps\n>(\n (\n { onComposerSubmit, onSubmit, disabled, chatId, asChild, ...props },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const formRef = useRef<HTMLFormElement | null>(null);\n\n const editorRef = useRef<AiComposerEditor | null>(null);\n if (editorRef.current === null) {\n editorRef.current = withNormalize(withHistory(withReact(createEditor())));\n }\n const editor = editorRef.current;\n\n const [isEditorEmpty, setIsEditorEmpty] = useState(true);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled || isEmpty(editor, editor.children)) return;\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n onComposerSubmit({ text: content }, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n\n // Clear the editor after dispatching the message.\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n },\n [disabled, editor, onSubmit, onComposerSubmit]\n );\n\n useLayoutEffect(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const requestFormSubmit = useCallback(() => {\n if (isEmpty(editor, editor.children)) return;\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current === null) return;\n if (typeof formRef.current.requestSubmit === \"function\") {\n return formRef.current.requestSubmit();\n }\n const submitter = document.createElement(\"input\");\n submitter.type = \"submit\";\n submitter.hidden = true;\n formRef.current.appendChild(submitter);\n submitter.click();\n formRef.current.removeChild(submitter);\n });\n }, [editor]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiChatComposerContext.Provider\n value={{\n chatId,\n editor,\n onEditorValueChange: handleEditorValueChange,\n isEditorEmpty,\n requestFormSubmit,\n disabled: disabled || false,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiChatComposerContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Displays the chat composer's editor.\n *\n * @example\n * <AiChatComposer.Editor placeholder=\"Write a message…\" />\n */\nexport const AiChatComposerEditor = forwardRef<\n HTMLDivElement,\n AiChatComposerEditorProps\n>(\n (\n { defaultValue = \"\", onKeyDown, disabled, autoFocus, ...props },\n forwardedRef\n ) => {\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const {\n editor,\n onEditorValueChange,\n requestFormSubmit,\n disabled: isFormDisabled,\n } = context;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n requestFormSubmit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n }\n },\n [editor, onKeyDown, requestFormSubmit]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n useEffect(() => {\n if (!autoFocus) return;\n\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM node no longer exists. This action doesn't make sense on an unmounted editor so we can safely ignore it.\n }\n }, [editor, autoFocus]);\n\n const initialValue: { type: \"paragraph\"; children: { text: string }[] }[] =\n useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n onKeyDown={handleKeyDown}\n data-disabled={disabled || isFormDisabled || undefined}\n {...props}\n readOnly={disabled || isFormDisabled}\n disabled={disabled || isFormDisabled}\n renderPlaceholder={function ({ attributes, children }) {\n const { opacity: _opacity, ...style } = attributes.style;\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n }}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit a chat message.\n *\n * @example\n * <AiChatComposer.Submit>Send</AiChatComposer.Submit>\n */\nexport const AiChatComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiChatComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const { disabled: isFormDisabled, isEditorEmpty } = context;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || isFormDisabled || isEditorEmpty}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;\n AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;\n AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiChatComposer.*\nexport {\n AiChatComposerEditor as Editor,\n AiChatComposerForm as Form,\n AiChatComposerSubmit as Submit,\n};\n"],"names":["SlateTransforms","SlateEditor"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/primitives/AiChatComposer/index.tsx"],"sourcesContent":["import { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FormEvent, KeyboardEvent } from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { Descendant as SlateDescendant } from \"slate\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, ReactEditor, Slate, withReact } from \"slate-react\";\n\nimport type { AiComposerEditor } from \"../../types\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport type {\n AiChatComposerEditorProps,\n AiChatComposerFormProps,\n AiChatComposerSubmitProps,\n} from \"./types\";\n\nconst AI_CHAT_COMPOSER_SUBMIT_NAME = \"AiChatComposerSubmit\";\nconst AI_CHAT_COMPOSER_EDITOR_NAME = \"AiChatComposerEditor\";\nconst AI_CHAT_COMPOSER_FORM_NAME = \"AiChatComposerForm\";\n\nconst AiChatComposerContext = createContext<{\n editor: SlateEditor;\n onEditorValueChange: (value: SlateDescendant[]) => void;\n isEditorEmpty: boolean;\n\n requestFormSubmit: () => void;\n disabled: boolean;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Surrounds the chat composer's content and handles submissions.\n *\n * @example\n * <AiChatComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiChatComposer.Editor />\n * <AiChatComposer.Submit />\n * </AiChatComposer.Form>\n */\nexport const AiChatComposerForm = forwardRef<\n HTMLFormElement,\n AiChatComposerFormProps\n>(\n (\n { onComposerSubmit, onSubmit, disabled, asChild, ...props },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const formRef = useRef<HTMLFormElement | null>(null);\n\n const editorRef = useRef<AiComposerEditor | null>(null);\n if (editorRef.current === null) {\n editorRef.current = withNormalize(withHistory(withReact(createEditor())));\n }\n const editor = editorRef.current;\n\n const [isEditorEmpty, setIsEditorEmpty] = useState(true);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled || isEmpty(editor, editor.children)) return;\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n onComposerSubmit({ text: content }, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n\n // Clear the editor after dispatching the message.\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n },\n [disabled, editor, onSubmit, onComposerSubmit]\n );\n\n useLayoutEffect(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const requestFormSubmit = useCallback(() => {\n if (isEmpty(editor, editor.children)) return;\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current === null) return;\n if (typeof formRef.current.requestSubmit === \"function\") {\n return formRef.current.requestSubmit();\n }\n const submitter = document.createElement(\"input\");\n submitter.type = \"submit\";\n submitter.hidden = true;\n formRef.current.appendChild(submitter);\n submitter.click();\n formRef.current.removeChild(submitter);\n });\n }, [editor]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiChatComposerContext.Provider\n value={{\n editor,\n onEditorValueChange: handleEditorValueChange,\n isEditorEmpty,\n requestFormSubmit,\n disabled: disabled || false,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiChatComposerContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Displays the chat composer's editor.\n *\n * @example\n * <AiChatComposer.Editor placeholder=\"Write a message…\" />\n */\nexport const AiChatComposerEditor = forwardRef<\n HTMLDivElement,\n AiChatComposerEditorProps\n>(\n (\n { defaultValue = \"\", onKeyDown, disabled, autoFocus, ...props },\n forwardedRef\n ) => {\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const {\n editor,\n onEditorValueChange,\n requestFormSubmit,\n disabled: isFormDisabled,\n } = context;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n requestFormSubmit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n }\n },\n [editor, onKeyDown, requestFormSubmit]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n useEffect(() => {\n if (!autoFocus) return;\n\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM node no longer exists. This action doesn't make sense on an unmounted editor so we can safely ignore it.\n }\n }, [editor, autoFocus]);\n\n const initialValue: { type: \"paragraph\"; children: { text: string }[] }[] =\n useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n onKeyDown={handleKeyDown}\n data-disabled={disabled || isFormDisabled || undefined}\n {...props}\n readOnly={disabled || isFormDisabled}\n disabled={disabled || isFormDisabled}\n renderPlaceholder={function ({ attributes, children }) {\n const { opacity: _opacity, ...style } = attributes.style;\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n }}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit a chat message.\n *\n * @example\n * <AiChatComposer.Submit>Send</AiChatComposer.Submit>\n */\nexport const AiChatComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiChatComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const { disabled: isFormDisabled, isEditorEmpty } = context;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || isFormDisabled || isEditorEmpty}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;\n AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;\n AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiChatComposer.*\nexport {\n AiChatComposerEditor as Editor,\n AiChatComposerForm as Form,\n AiChatComposerSubmit as Submit,\n};\n"],"names":["SlateTransforms","SlateEditor"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ const AiToolInvocationContext = react.createContext(null);
6
+ function useAiToolInvocationContext() {
7
+ const context = react.useContext(AiToolInvocationContext);
8
+ if (context === null) {
9
+ throw new Error(
10
+ "This component must be used within a tool's render method."
11
+ );
12
+ }
13
+ return context;
14
+ }
15
+
16
+ exports.AiToolInvocationContext = AiToolInvocationContext;
17
+ exports.useAiToolInvocationContext = useAiToolInvocationContext;
18
+ //# sourceMappingURL=contexts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contexts.cjs","sources":["../../../src/primitives/AiMessage/contexts.ts"],"sourcesContent":["import type { AiOpaqueToolInvocationProps } from \"@liveblocks/core\";\nimport { createContext, useContext } from \"react\";\n\nexport const AiToolInvocationContext =\n createContext<AiOpaqueToolInvocationProps | null>(null);\n\nexport function useAiToolInvocationContext() {\n const context = useContext(AiToolInvocationContext);\n\n if (context === null) {\n throw new Error(\n \"This component must be used within a tool's render method.\"\n );\n }\n\n return context;\n}\n"],"names":["createContext","useContext"],"mappings":";;;;AAGa,MAAA,uBAAA,GACXA,oBAAkD,IAAI,EAAA;AAEjD,SAAS,0BAA6B,GAAA;AAC3C,EAAM,MAAA,OAAA,GAAUC,iBAAW,uBAAuB,CAAA,CAAA;AAElD,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,4DAAA;AAAA,KACF,CAAA;AAAA,GACF;AAEA,EAAO,OAAA,OAAA,CAAA;AACT;;;;;"}
@@ -0,0 +1,15 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ const AiToolInvocationContext = createContext(null);
4
+ function useAiToolInvocationContext() {
5
+ const context = useContext(AiToolInvocationContext);
6
+ if (context === null) {
7
+ throw new Error(
8
+ "This component must be used within a tool's render method."
9
+ );
10
+ }
11
+ return context;
12
+ }
13
+
14
+ export { AiToolInvocationContext, useAiToolInvocationContext };
15
+ //# sourceMappingURL=contexts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contexts.js","sources":["../../../src/primitives/AiMessage/contexts.ts"],"sourcesContent":["import type { AiOpaqueToolInvocationProps } from \"@liveblocks/core\";\nimport { createContext, useContext } from \"react\";\n\nexport const AiToolInvocationContext =\n createContext<AiOpaqueToolInvocationProps | null>(null);\n\nexport function useAiToolInvocationContext() {\n const context = useContext(AiToolInvocationContext);\n\n if (context === null) {\n throw new Error(\n \"This component must be used within a tool's render method.\"\n );\n }\n\n return context;\n}\n"],"names":[],"mappings":";;AAGa,MAAA,uBAAA,GACX,cAAkD,IAAI,EAAA;AAEjD,SAAS,0BAA6B,GAAA;AAC3C,EAAM,MAAA,OAAA,GAAU,WAAW,uBAAuB,CAAA,CAAA;AAElD,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,4DAAA;AAAA,KACF,CAAA;AAAA,GACF;AAEA,EAAO,OAAA,OAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,133 @@
1
+ 'use strict';
2
+
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
+ var reactSlot = require('@radix-ui/react-slot');
8
+ var react = require('react');
9
+ var ErrorBoundary = require('../../utils/ErrorBoundary.cjs');
10
+ var Markdown = require('../Markdown.cjs');
11
+ var contexts = require('./contexts.cjs');
12
+
13
+ const AI_MESSAGE_CONTENT_NAME = "AiMessageContent";
14
+ const defaultMessageContentComponents = {
15
+ TextPart: ({ part }) => {
16
+ return /* @__PURE__ */ jsxRuntime.jsx(Markdown.Markdown, {
17
+ content: part.text
18
+ });
19
+ },
20
+ ReasoningPart: ({ part }) => {
21
+ return /* @__PURE__ */ jsxRuntime.jsx(Markdown.Markdown, {
22
+ content: part.text
23
+ });
24
+ },
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
80
+ })
81
+ })
82
+ });
83
+ }
84
+ const AiMessageContent = react.forwardRef(
85
+ ({ message, components, asChild, ...props }, forwardedRef) => {
86
+ const Component = asChild ? reactSlot.Slot : "div";
87
+ const { TextPart, ReasoningPart, ToolInvocationPart } = react.useMemo(
88
+ () => ({ ...defaultMessageContentComponents, ...components }),
89
+ [components]
90
+ );
91
+ const content = message.content ?? message.contentSoFar;
92
+ const numParts = content.length;
93
+ const isGenerating = message.role === "assistant" && message.status === "generating";
94
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, {
95
+ ...props,
96
+ ref: forwardedRef,
97
+ children: content.map((part, index) => {
98
+ const isStreaming = isGenerating && index === numParts - 1;
99
+ const extra = { index, isStreaming };
100
+ switch (part.type) {
101
+ case "text":
102
+ return /* @__PURE__ */ jsxRuntime.jsx(TextPart, {
103
+ part,
104
+ ...extra
105
+ }, index);
106
+ case "reasoning":
107
+ return /* @__PURE__ */ jsxRuntime.jsx(ReasoningPart, {
108
+ part,
109
+ ...extra
110
+ }, index);
111
+ case "tool-invocation":
112
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolInvocationPart, {
113
+ part,
114
+ ...extra,
115
+ children: /* @__PURE__ */ jsxRuntime.jsx(ToolInvocation, {
116
+ part,
117
+ chatId: message.chatId,
118
+ messageId: message.id
119
+ }, index)
120
+ }, index);
121
+ default:
122
+ return null;
123
+ }
124
+ })
125
+ });
126
+ }
127
+ );
128
+ if (process.env.NODE_ENV !== "production") {
129
+ AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;
130
+ }
131
+
132
+ exports.Content = AiMessageContent;
133
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import type {\n AiToolInvocationPart,\n MessageId,\n ToolResultData,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, Fragment, useCallback, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiToolInvocationContext } from \"./contexts\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ToolInvocationPart: Fragment,\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ToolInvocationPart\n * -----------------------------------------------------------------------------------------------*/\n\nfunction ToolInvocation({\n chatId,\n messageId,\n part,\n}: {\n chatId: string;\n messageId: MessageId;\n part: AiToolInvocationPart;\n}) {\n const client = useClient();\n const ai = client[kInternal].ai;\n const tool = useSignal(ai.signals.getToolDefinitionΣ(chatId, part.toolName));\n\n const respond = useCallback(\n (result: ToolResultData) => {\n if (part.status === \"receiving\") {\n console.log(\n `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) is still receiving`\n );\n } else if (part.status === \"executed\") {\n console.log(\n `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) has already executed`\n );\n } else {\n ai.setToolResult(\n chatId,\n messageId,\n part.toolCallId,\n result\n // TODO Pass in AiGenerationOptions here?\n );\n }\n },\n [ai, chatId, messageId, part.status, part.toolName, part.toolCallId]\n );\n\n if (tool === undefined || tool.render === undefined) return null;\n\n const { type: _, ...rest } = part;\n const props = {\n ...rest,\n respond,\n $types: undefined as never,\n [kInternal]: {\n execute: tool.execute,\n },\n };\n return (\n <ErrorBoundary\n fallback={\n <p style={{ color: \"red\" }}>\n Failed to render tool call result for '{part.toolName}'. See console\n for details.\n </p>\n }\n >\n <AiToolInvocationContext.Provider value={props}>\n <tool.render {...props} />\n </AiToolInvocationContext.Provider>\n </ErrorBoundary>\n );\n}\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(\n () => ({ ...defaultMessageContentComponents, ...components }),\n [components]\n );\n\n const content = message.content ?? message.contentSoFar;\n const numParts = content.length;\n const isGenerating =\n message.role === \"assistant\" && message.status === \"generating\";\n return (\n <Component {...props} ref={forwardedRef}>\n {content.map((part, index) => {\n // A part is considered to be still \"streaming in\" if it's the last\n // part in the content array, and the message is in \"generating\"\n // state.\n const isStreaming = isGenerating && index === numParts - 1;\n const extra = { index, isStreaming };\n switch (part.type) {\n case \"text\":\n return <TextPart key={index} part={part} {...extra} />;\n case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n case \"tool-invocation\":\n // TODO: If the render() method doesn't exist, we should not render the ToolInvocationPart\n // or pass it no children so that it can decide to not render?\n return (\n <ToolInvocationPart key={index} part={part} {...extra}>\n <ToolInvocation\n key={index}\n part={part}\n chatId={message.chatId}\n messageId={message.id}\n />\n </ToolInvocationPart>\n );\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiMessage.*\nexport { AiMessageContent as Content };\n"],"names":["jsx","Markdown","Fragment","useClient","kInternal","useSignal","useCallback","ErrorBoundary","jsxs","AiToolInvocationContext","forwardRef","Slot","useMemo"],"mappings":"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"}