@liveblocks/react-ui 2.25.0-aiprivatebeta1 → 2.25.0-aiprivatebeta11
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.
- package/dist/_private/index.cjs +18 -10
- package/dist/_private/index.cjs.map +1 -1
- package/dist/_private/index.d.cts +204 -172
- package/dist/_private/index.d.ts +204 -172
- package/dist/_private/index.js +12 -5
- package/dist/_private/index.js.map +1 -1
- package/dist/components/AiChat.cjs +179 -0
- package/dist/components/AiChat.cjs.map +1 -0
- package/dist/components/AiChat.js +177 -0
- package/dist/components/AiChat.js.map +1 -0
- package/dist/components/AiTool.cjs +164 -0
- package/dist/components/AiTool.cjs.map +1 -0
- package/dist/components/AiTool.js +162 -0
- package/dist/components/AiTool.js.map +1 -0
- package/dist/components/Comment.cjs +7 -5
- package/dist/components/Comment.cjs.map +1 -1
- package/dist/components/Comment.js +7 -5
- package/dist/components/Comment.js.map +1 -1
- package/dist/components/Composer.cjs +1 -2
- package/dist/components/Composer.cjs.map +1 -1
- package/dist/components/Composer.js +1 -2
- package/dist/components/Composer.js.map +1 -1
- package/dist/components/InboxNotificationList.cjs +11 -3
- package/dist/components/InboxNotificationList.cjs.map +1 -1
- package/dist/components/InboxNotificationList.js +12 -4
- package/dist/components/InboxNotificationList.js.map +1 -1
- package/dist/components/Thread.cjs +3 -3
- package/dist/components/Thread.cjs.map +1 -1
- package/dist/components/Thread.js +3 -3
- package/dist/components/Thread.js.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.cjs +74 -291
- package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.js +76 -293
- package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
- package/dist/components/internal/AiChatComposer.cjs +58 -282
- package/dist/components/internal/AiChatComposer.cjs.map +1 -1
- package/dist/components/internal/AiChatComposer.js +63 -283
- package/dist/components/internal/AiChatComposer.js.map +1 -1
- package/dist/components/internal/AiChatUserMessage.cjs +26 -169
- package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatUserMessage.js +28 -171
- package/dist/components/internal/AiChatUserMessage.js.map +1 -1
- package/dist/components/internal/Button.cjs.map +1 -1
- package/dist/components/internal/Button.js.map +1 -1
- package/dist/components/internal/CodeBlock.cjs +72 -0
- package/dist/components/internal/CodeBlock.cjs.map +1 -0
- package/dist/components/internal/CodeBlock.js +70 -0
- package/dist/components/internal/CodeBlock.js.map +1 -0
- package/dist/components/internal/Emoji.cjs +12 -4
- package/dist/components/internal/Emoji.cjs.map +1 -1
- package/dist/components/internal/Emoji.js +12 -4
- package/dist/components/internal/Emoji.js.map +1 -1
- package/dist/components/internal/Prose.cjs +37 -0
- package/dist/components/internal/Prose.cjs.map +1 -0
- package/dist/components/internal/Prose.js +35 -0
- package/dist/components/internal/Prose.js.map +1 -0
- package/dist/constants.cjs +2 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/icon.cjs +6 -0
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +3 -0
- package/dist/icon.js.map +1 -1
- package/dist/icons/{Resolve.cjs → CheckCircle.cjs} +3 -3
- package/dist/icons/CheckCircle.cjs.map +1 -0
- package/dist/icons/{Resolve.js → CheckCircle.js} +3 -3
- package/dist/icons/CheckCircle.js.map +1 -0
- package/dist/icons/{Resolved.cjs → CheckCircleFill.cjs} +3 -3
- package/dist/icons/CheckCircleFill.cjs.map +1 -0
- package/dist/icons/{Resolved.js → CheckCircleFill.js} +3 -3
- package/dist/icons/CheckCircleFill.js.map +1 -0
- package/dist/icons/Copy.cjs +8 -9
- package/dist/icons/Copy.cjs.map +1 -1
- package/dist/icons/Copy.js +8 -9
- package/dist/icons/Copy.js.map +1 -1
- package/dist/icons/Retry.cjs +21 -0
- package/dist/icons/Retry.cjs.map +1 -0
- package/dist/icons/Retry.js +19 -0
- package/dist/icons/Retry.js.map +1 -0
- package/dist/icons/index.cjs +8 -4
- package/dist/icons/index.cjs.map +1 -1
- package/dist/icons/index.js +4 -2
- package/dist/icons/index.js.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -43
- package/dist/index.d.ts +102 -43
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/overrides.cjs +6 -12
- package/dist/overrides.cjs.map +1 -1
- package/dist/overrides.js +6 -12
- package/dist/overrides.js.map +1 -1
- package/dist/primitives/AiChatComposer/index.cjs +202 -0
- package/dist/primitives/AiChatComposer/index.cjs.map +1 -0
- package/dist/primitives/AiChatComposer/index.js +195 -0
- package/dist/primitives/AiChatComposer/index.js.map +1 -0
- package/dist/primitives/AiMessage/contexts.cjs +18 -0
- package/dist/primitives/AiMessage/contexts.cjs.map +1 -0
- package/dist/primitives/AiMessage/contexts.js +15 -0
- package/dist/primitives/AiMessage/contexts.js.map +1 -0
- package/dist/primitives/AiMessage/index.cjs +134 -0
- package/dist/primitives/AiMessage/index.cjs.map +1 -0
- package/dist/primitives/AiMessage/index.js +132 -0
- package/dist/primitives/AiMessage/index.js.map +1 -0
- package/dist/primitives/Collapsible/index.cjs +127 -0
- package/dist/primitives/Collapsible/index.cjs.map +1 -0
- package/dist/primitives/Collapsible/index.js +123 -0
- package/dist/primitives/Collapsible/index.js.map +1 -0
- package/dist/primitives/Comment/index.cjs +2 -2
- package/dist/primitives/Comment/index.cjs.map +1 -1
- package/dist/primitives/Comment/index.js +1 -1
- package/dist/primitives/Comment/index.js.map +1 -1
- package/dist/primitives/Composer/index.cjs +19 -14
- package/dist/primitives/Composer/index.cjs.map +1 -1
- package/dist/primitives/Composer/index.js +18 -13
- package/dist/primitives/Composer/index.js.map +1 -1
- package/dist/{slate → primitives/Composer/slate}/plugins/auto-formatting.cjs +3 -3
- package/dist/primitives/Composer/slate/plugins/auto-formatting.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/auto-formatting.js +3 -3
- package/dist/primitives/Composer/slate/plugins/auto-formatting.js.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/auto-links.cjs +7 -2
- package/dist/primitives/Composer/slate/plugins/auto-links.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/auto-links.js +8 -3
- package/dist/primitives/Composer/slate/plugins/auto-links.js.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/custom-links.cjs +8 -3
- package/dist/primitives/Composer/slate/plugins/custom-links.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/custom-links.js +9 -4
- package/dist/primitives/Composer/slate/plugins/custom-links.js.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/mentions.cjs +9 -10
- package/dist/primitives/Composer/slate/plugins/mentions.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/mentions.js +6 -6
- package/dist/primitives/Composer/slate/plugins/mentions.js.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/paste.cjs +1 -1
- package/dist/primitives/Composer/slate/plugins/paste.cjs.map +1 -0
- package/dist/{slate → primitives/Composer/slate}/plugins/paste.js +1 -1
- package/dist/primitives/Composer/slate/plugins/paste.js.map +1 -0
- package/dist/primitives/Composer/utils.cjs +4 -4
- package/dist/primitives/Composer/utils.cjs.map +1 -1
- package/dist/primitives/Composer/utils.js +4 -4
- package/dist/primitives/Composer/utils.js.map +1 -1
- package/dist/primitives/{internal/Markdown.cjs → Markdown.cjs} +150 -83
- package/dist/primitives/Markdown.cjs.map +1 -0
- package/dist/primitives/{internal/Markdown.js → Markdown.js} +151 -83
- package/dist/primitives/Markdown.js.map +1 -0
- package/dist/primitives/index.cjs +4 -9
- package/dist/primitives/index.cjs.map +1 -1
- package/dist/primitives/index.d.cts +4 -110
- package/dist/primitives/index.d.ts +4 -110
- package/dist/primitives/index.js +0 -1
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/slate/plugins/empty-clear-formatting.cjs.map +1 -0
- package/dist/primitives/slate/plugins/empty-clear-formatting.js.map +1 -0
- package/dist/{slate → primitives/slate}/plugins/normalize.cjs +0 -5
- package/dist/primitives/slate/plugins/normalize.cjs.map +1 -0
- package/dist/{slate → primitives/slate}/plugins/normalize.js +0 -5
- package/dist/primitives/slate/plugins/normalize.js.map +1 -0
- package/dist/primitives/slate/utils/get-character.cjs.map +1 -0
- package/dist/primitives/slate/utils/get-character.js.map +1 -0
- package/dist/primitives/slate/utils/get-dom-range.cjs.map +1 -0
- package/dist/primitives/slate/utils/get-dom-range.js.map +1 -0
- package/dist/primitives/slate/utils/get-match-range.cjs.map +1 -0
- package/dist/primitives/slate/utils/get-match-range.js.map +1 -0
- package/dist/primitives/slate/utils/is-empty-string.cjs.map +1 -0
- package/dist/primitives/slate/utils/is-empty-string.js.map +1 -0
- package/dist/primitives/slate/utils/is-empty.cjs.map +1 -0
- package/dist/primitives/slate/utils/is-empty.js.map +1 -0
- package/dist/primitives/slate/utils/is-text.cjs.map +1 -0
- package/dist/primitives/slate/utils/is-text.js.map +1 -0
- package/dist/primitives/slate/utils/is-whitespace-character.cjs.map +1 -0
- package/dist/primitives/slate/utils/is-whitespace-character.js.map +1 -0
- package/dist/{slate → primitives/slate}/utils/marks.cjs +9 -9
- package/dist/primitives/slate/utils/marks.cjs.map +1 -0
- package/dist/{slate → primitives/slate}/utils/marks.js +9 -9
- package/dist/primitives/slate/utils/marks.js.map +1 -0
- package/dist/primitives/slate/utils/selection-contains-inlines.cjs.map +1 -0
- package/dist/primitives/slate/utils/selection-contains-inlines.js.map +1 -0
- package/dist/utils/ErrorBoundary.cjs +48 -0
- package/dist/utils/ErrorBoundary.cjs.map +1 -0
- package/dist/utils/ErrorBoundary.js +45 -0
- package/dist/utils/ErrorBoundary.js.map +1 -0
- package/dist/utils/use-visible.cjs +65 -45
- package/dist/utils/use-visible.cjs.map +1 -1
- package/dist/utils/use-visible.js +66 -46
- package/dist/utils/use-visible.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +18 -6
- package/src/styles/constants.css +1 -1
- package/src/styles/dark/index.css +7 -3
- package/src/styles/index.css +640 -307
- package/src/styles/utils.css +8 -3
- package/styles/dark/attributes.css +1 -1
- package/styles/dark/attributes.css.map +1 -1
- package/styles/dark/media-query.css +1 -1
- package/styles/dark/media-query.css.map +1 -1
- package/styles.css +1 -1
- package/styles.css.map +1 -1
- package/dist/components/AiChat/AiChat.cjs +0 -211
- package/dist/components/AiChat/AiChat.cjs.map +0 -1
- package/dist/components/AiChat/AiChat.js +0 -209
- package/dist/components/AiChat/AiChat.js.map +0 -1
- package/dist/icons/Resolve.cjs.map +0 -1
- package/dist/icons/Resolve.js.map +0 -1
- package/dist/icons/Resolved.cjs.map +0 -1
- package/dist/icons/Resolved.js.map +0 -1
- package/dist/primitives/Chat/Composer/index.cjs +0 -323
- package/dist/primitives/Chat/Composer/index.cjs.map +0 -1
- package/dist/primitives/Chat/Composer/index.js +0 -315
- package/dist/primitives/Chat/Composer/index.js.map +0 -1
- package/dist/primitives/internal/Collapsible.cjs +0 -99
- package/dist/primitives/internal/Collapsible.cjs.map +0 -1
- package/dist/primitives/internal/Collapsible.js +0 -95
- package/dist/primitives/internal/Collapsible.js.map +0 -1
- package/dist/primitives/internal/Emoji.cjs +0 -32
- package/dist/primitives/internal/Emoji.cjs.map +0 -1
- package/dist/primitives/internal/Emoji.js +0 -30
- package/dist/primitives/internal/Emoji.js.map +0 -1
- package/dist/primitives/internal/Markdown.cjs.map +0 -1
- package/dist/primitives/internal/Markdown.js.map +0 -1
- package/dist/slate/plugins/auto-formatting.cjs.map +0 -1
- package/dist/slate/plugins/auto-formatting.js.map +0 -1
- package/dist/slate/plugins/auto-links.cjs.map +0 -1
- package/dist/slate/plugins/auto-links.js.map +0 -1
- package/dist/slate/plugins/custom-links.cjs.map +0 -1
- package/dist/slate/plugins/custom-links.js.map +0 -1
- package/dist/slate/plugins/empty-clear-formatting.cjs.map +0 -1
- package/dist/slate/plugins/empty-clear-formatting.js.map +0 -1
- package/dist/slate/plugins/mentions.cjs.map +0 -1
- package/dist/slate/plugins/mentions.js.map +0 -1
- package/dist/slate/plugins/normalize.cjs.map +0 -1
- package/dist/slate/plugins/normalize.js.map +0 -1
- package/dist/slate/plugins/paste.cjs.map +0 -1
- package/dist/slate/plugins/paste.js.map +0 -1
- package/dist/slate/utils/get-character.cjs.map +0 -1
- package/dist/slate/utils/get-character.js.map +0 -1
- package/dist/slate/utils/get-dom-range.cjs.map +0 -1
- package/dist/slate/utils/get-dom-range.js.map +0 -1
- package/dist/slate/utils/get-match-range.cjs.map +0 -1
- package/dist/slate/utils/get-match-range.js.map +0 -1
- package/dist/slate/utils/is-empty-string.cjs.map +0 -1
- package/dist/slate/utils/is-empty-string.js.map +0 -1
- package/dist/slate/utils/is-empty.cjs.map +0 -1
- package/dist/slate/utils/is-empty.js.map +0 -1
- package/dist/slate/utils/is-text.cjs.map +0 -1
- package/dist/slate/utils/is-text.js.map +0 -1
- package/dist/slate/utils/is-whitespace-character.cjs.map +0 -1
- package/dist/slate/utils/is-whitespace-character.js.map +0 -1
- package/dist/slate/utils/marks.cjs.map +0 -1
- package/dist/slate/utils/marks.js.map +0 -1
- package/dist/slate/utils/selection-contains-inlines.cjs.map +0 -1
- package/dist/slate/utils/selection-contains-inlines.js.map +0 -1
- /package/dist/{slate → primitives/slate}/plugins/empty-clear-formatting.cjs +0 -0
- /package/dist/{slate → primitives/slate}/plugins/empty-clear-formatting.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-character.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-character.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-dom-range.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-dom-range.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-match-range.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/get-match-range.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-empty-string.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-empty-string.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-empty.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-empty.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-text.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-text.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-whitespace-character.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/is-whitespace-character.js +0 -0
- /package/dist/{slate → primitives/slate}/utils/selection-contains-inlines.cjs +0 -0
- /package/dist/{slate → primitives/slate}/utils/selection-contains-inlines.js +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AiChat.cjs","sources":["../../../src/components/AiChat/AiChat.tsx"],"sourcesContent":["import {\n type AiChatContext,\n type ClientToolDefinition,\n type CopilotId,\n kInternal,\n type UiChatMessage,\n} from \"@liveblocks/core\";\nimport { useAiChatMessages, useClient } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n forwardRef,\n type HTMLAttributes,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nimport { ChevronDownIcon } from \"../../icons/ChevronDown\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport {\n type ChatComposerOverrides,\n type ChatMessageOverrides,\n type ChatOverrides,\n type GlobalOverrides,\n useOverrides,\n} from \"../../overrides\";\nimport { classNames } from \"../../utils/class-names\";\nimport { AiChatAssistantMessage } from \"../internal/AiChatAssistantMessage\";\nimport { AiChatComposer } from \"../internal/AiChatComposer\";\nimport { AiChatUserMessage } from \"../internal/AiChatUserMessage\";\n\n/**\n * The number of pixels from the bottom of the messages list to trigger the scroll to bottom.\n */\nconst MIN_DISTANCE_TO_BOTTOM = 50;\n\nexport type AiChatProps = HTMLAttributes<HTMLDivElement> & {\n /**\n * The id of the chat the composer belongs to.\n */\n chatId: string;\n /**\n * The id of the copilot to use to send the message.\n */\n copilotId?: CopilotId;\n /**\n * The contextual information to include in the chat. Used by the assistant when generating responses.\n */\n contexts?: AiChatContext[];\n /**\n * The contextual information to include in the chat. Used by the assistant when generating responses.\n */\n tools?: Record<string, ClientToolDefinition>;\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides &\n ChatMessageOverrides &\n ChatComposerOverrides &\n ChatOverrides\n >;\n};\nexport const AiChat = forwardRef<HTMLDivElement, AiChatProps>(function (\n {\n chatId,\n copilotId,\n overrides,\n contexts = [],\n tools = {},\n className,\n ...props\n },\n forwardedRef\n) {\n const { messages, isLoading, error } = useAiChatMessages(chatId);\n const $ = useOverrides(overrides);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [distanceToBottom, setDistanceToBottom] = useState<number | null>(null);\n const client = useClient();\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => containerRef.current,\n []\n );\n\n // Add the provided contextual information to the chat on mount and remove on unmount\n // Note: 'contexts' will most likely be a new object on each render (unless user passes a stable object), but this won't be an issue as context addition and removal is a quick operation\n useEffect(() => {\n const unregister = contexts.map((context) =>\n client[kInternal].ai.registerChatContext(chatId, context)\n );\n return () => {\n unregister.forEach((unregister) => unregister());\n };\n }, [client, chatId, contexts]);\n\n // Register the provided tools to the chat on mount and unregister them on unmount\n useEffect(() => {\n Object.entries(tools).map(([key, value]) =>\n client[kInternal].ai.registerChatTool(chatId, key, value)\n );\n return () => {\n Object.entries(tools).map(([key]) =>\n client[kInternal].ai.unregisterChatTool(chatId, key)\n );\n };\n }, [client, chatId, tools]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n function handleScrollChange() {\n const container = containerRef.current;\n if (container === null) return;\n\n setDistanceToBottom(\n container.scrollHeight - container.clientHeight - container.scrollTop\n );\n }\n container.addEventListener(\"scroll\", handleScrollChange);\n return () => {\n container.removeEventListener(\"scroll\", handleScrollChange);\n };\n }, []);\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n\n setDistanceToBottom(\n container.scrollHeight - container.clientHeight - container.scrollTop\n );\n }, [messages]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n\n const distanceToBottom =\n container.scrollHeight - container.clientHeight - container.scrollTop;\n\n if (messages === undefined) return;\n const lastMessage = messages[messages.length - 1];\n if (lastMessage !== undefined && lastMessage.role === \"user\") {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"smooth\",\n });\n } else if (distanceToBottom <= MIN_DISTANCE_TO_BOTTOM) {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"smooth\",\n });\n }\n }, [messages]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n\n const observer = new ResizeObserver(() => {\n const container = containerRef.current;\n if (container === null) return;\n setDistanceToBottom(\n container.scrollHeight - container.clientHeight - container.scrollTop\n );\n });\n observer.observe(container);\n return () => {\n observer.disconnect();\n };\n }, []);\n\n const scrollToBottomCallbackRef = useRef<() => void>(undefined);\n if (scrollToBottomCallbackRef.current === undefined) {\n scrollToBottomCallbackRef.current = function () {\n const container = containerRef.current;\n if (container === null) return;\n\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"instant\",\n });\n };\n }\n\n return (\n <div\n ref={containerRef}\n {...props}\n className={classNames(\"lb-root lb-ai-chat\", className)}\n >\n {isLoading ? (\n <div className=\"lb-ai-chat-loading lb-loading\">\n <SpinnerIcon />\n </div>\n ) : error !== undefined ? (\n <div className=\"lb-ai-chat-error lb-error\">\n {$.GET_CHAT_MESSAGES_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-ai-chat-messages\">\n <Messages\n messages={messages}\n overrides={$}\n onDistanceToBottomChange={scrollToBottomCallbackRef.current}\n />\n </div>\n )}\n\n <div className=\"lb-ai-chat-footer\">\n <div className=\"lb-ai-chat-footer-actions\">\n <button\n className=\"lb-ai-chat-scroll-button lb-button\"\n data-visible={\n distanceToBottom !== null &&\n distanceToBottom > MIN_DISTANCE_TO_BOTTOM\n ? \"\"\n : undefined\n }\n data-variant=\"secondary\"\n onClick={() => {\n const container = containerRef.current;\n if (container === null) return;\n\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"smooth\",\n });\n }}\n >\n <span className=\"lb-icon-container\">\n <ChevronDownIcon />\n </span>\n </button>\n </div>\n <AiChatComposer\n key={chatId}\n chatId={chatId}\n copilotId={copilotId}\n className=\"lb-ai-chat-composer\"\n overrides={$}\n />\n </div>\n </div>\n );\n});\n\nfunction Messages({\n messages,\n overrides,\n onDistanceToBottomChange,\n}: {\n messages: readonly UiChatMessage[];\n overrides: Partial<GlobalOverrides & ChatMessageOverrides>;\n onDistanceToBottomChange: () => void;\n}) {\n const $ = useOverrides(overrides);\n\n useLayoutEffect(() => {\n onDistanceToBottomChange();\n }, [onDistanceToBottomChange]);\n\n return messages.map((message) => {\n if (message.role === \"user\") {\n return (\n <AiChatUserMessage\n key={message.id}\n message={message}\n overrides={$}\n className=\"lb-ai-chat-messages-user-message\"\n />\n );\n } else if (message.role === \"assistant\") {\n return (\n <AiChatAssistantMessage\n key={message.id}\n message={message}\n overrides={$}\n className=\"lb-ai-chat-messages-assistant-message\"\n />\n );\n } else {\n return null;\n }\n });\n}\n"],"names":["forwardRef","overrides","useAiChatMessages","useOverrides","useRef","useState","useClient","useImperativeHandle","useEffect","kInternal","unregister","container","distanceToBottom","jsxs","classNames","jsx","SpinnerIcon","ChevronDownIcon","AiChatComposer","useLayoutEffect","AiChatUserMessage","AiChatAssistantMessage"],"mappings":"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"}
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { kInternal } from '@liveblocks/core';
|
|
3
|
-
import { useAiChatMessages, useClient } from '@liveblocks/react';
|
|
4
|
-
import { useLayoutEffect } from '@liveblocks/react/_private';
|
|
5
|
-
import { forwardRef, useRef, useState, useImperativeHandle, useEffect } from 'react';
|
|
6
|
-
import { ChevronDownIcon } from '../../icons/ChevronDown.js';
|
|
7
|
-
import { SpinnerIcon } from '../../icons/Spinner.js';
|
|
8
|
-
import { useOverrides } from '../../overrides.js';
|
|
9
|
-
import { classNames } from '../../utils/class-names.js';
|
|
10
|
-
import { AiChatAssistantMessage } from '../internal/AiChatAssistantMessage.js';
|
|
11
|
-
import { AiChatComposer } from '../internal/AiChatComposer.js';
|
|
12
|
-
import { AiChatUserMessage } from '../internal/AiChatUserMessage.js';
|
|
13
|
-
|
|
14
|
-
const MIN_DISTANCE_TO_BOTTOM = 50;
|
|
15
|
-
const AiChat = forwardRef(function({
|
|
16
|
-
chatId,
|
|
17
|
-
copilotId,
|
|
18
|
-
overrides,
|
|
19
|
-
contexts = [],
|
|
20
|
-
tools = {},
|
|
21
|
-
className,
|
|
22
|
-
...props
|
|
23
|
-
}, forwardedRef) {
|
|
24
|
-
const { messages, isLoading, error } = useAiChatMessages(chatId);
|
|
25
|
-
const $ = useOverrides(overrides);
|
|
26
|
-
const containerRef = useRef(null);
|
|
27
|
-
const [distanceToBottom, setDistanceToBottom] = useState(null);
|
|
28
|
-
const client = useClient();
|
|
29
|
-
useImperativeHandle(
|
|
30
|
-
forwardedRef,
|
|
31
|
-
() => containerRef.current,
|
|
32
|
-
[]
|
|
33
|
-
);
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
const unregister = contexts.map(
|
|
36
|
-
(context) => client[kInternal].ai.registerChatContext(chatId, context)
|
|
37
|
-
);
|
|
38
|
-
return () => {
|
|
39
|
-
unregister.forEach((unregister2) => unregister2());
|
|
40
|
-
};
|
|
41
|
-
}, [client, chatId, contexts]);
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
Object.entries(tools).map(
|
|
44
|
-
([key, value]) => client[kInternal].ai.registerChatTool(chatId, key, value)
|
|
45
|
-
);
|
|
46
|
-
return () => {
|
|
47
|
-
Object.entries(tools).map(
|
|
48
|
-
([key]) => client[kInternal].ai.unregisterChatTool(chatId, key)
|
|
49
|
-
);
|
|
50
|
-
};
|
|
51
|
-
}, [client, chatId, tools]);
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
const container = containerRef.current;
|
|
54
|
-
if (container === null)
|
|
55
|
-
return;
|
|
56
|
-
function handleScrollChange() {
|
|
57
|
-
const container2 = containerRef.current;
|
|
58
|
-
if (container2 === null)
|
|
59
|
-
return;
|
|
60
|
-
setDistanceToBottom(
|
|
61
|
-
container2.scrollHeight - container2.clientHeight - container2.scrollTop
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
container.addEventListener("scroll", handleScrollChange);
|
|
65
|
-
return () => {
|
|
66
|
-
container.removeEventListener("scroll", handleScrollChange);
|
|
67
|
-
};
|
|
68
|
-
}, []);
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
const container = containerRef.current;
|
|
71
|
-
if (container === null)
|
|
72
|
-
return;
|
|
73
|
-
setDistanceToBottom(
|
|
74
|
-
container.scrollHeight - container.clientHeight - container.scrollTop
|
|
75
|
-
);
|
|
76
|
-
}, [messages]);
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
const container = containerRef.current;
|
|
79
|
-
if (container === null)
|
|
80
|
-
return;
|
|
81
|
-
const distanceToBottom2 = container.scrollHeight - container.clientHeight - container.scrollTop;
|
|
82
|
-
if (messages === void 0)
|
|
83
|
-
return;
|
|
84
|
-
const lastMessage = messages[messages.length - 1];
|
|
85
|
-
if (lastMessage !== void 0 && lastMessage.role === "user") {
|
|
86
|
-
container.scrollTo({
|
|
87
|
-
top: container.scrollHeight,
|
|
88
|
-
behavior: "smooth"
|
|
89
|
-
});
|
|
90
|
-
} else if (distanceToBottom2 <= MIN_DISTANCE_TO_BOTTOM) {
|
|
91
|
-
container.scrollTo({
|
|
92
|
-
top: container.scrollHeight,
|
|
93
|
-
behavior: "smooth"
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}, [messages]);
|
|
97
|
-
useEffect(() => {
|
|
98
|
-
const container = containerRef.current;
|
|
99
|
-
if (container === null)
|
|
100
|
-
return;
|
|
101
|
-
const observer = new ResizeObserver(() => {
|
|
102
|
-
const container2 = containerRef.current;
|
|
103
|
-
if (container2 === null)
|
|
104
|
-
return;
|
|
105
|
-
setDistanceToBottom(
|
|
106
|
-
container2.scrollHeight - container2.clientHeight - container2.scrollTop
|
|
107
|
-
);
|
|
108
|
-
});
|
|
109
|
-
observer.observe(container);
|
|
110
|
-
return () => {
|
|
111
|
-
observer.disconnect();
|
|
112
|
-
};
|
|
113
|
-
}, []);
|
|
114
|
-
const scrollToBottomCallbackRef = useRef(void 0);
|
|
115
|
-
if (scrollToBottomCallbackRef.current === void 0) {
|
|
116
|
-
scrollToBottomCallbackRef.current = function() {
|
|
117
|
-
const container = containerRef.current;
|
|
118
|
-
if (container === null)
|
|
119
|
-
return;
|
|
120
|
-
container.scrollTo({
|
|
121
|
-
top: container.scrollHeight,
|
|
122
|
-
behavior: "instant"
|
|
123
|
-
});
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
127
|
-
ref: containerRef,
|
|
128
|
-
...props,
|
|
129
|
-
className: classNames("lb-root lb-ai-chat", className),
|
|
130
|
-
children: [
|
|
131
|
-
isLoading ? /* @__PURE__ */ jsx("div", {
|
|
132
|
-
className: "lb-ai-chat-loading lb-loading",
|
|
133
|
-
children: /* @__PURE__ */ jsx(SpinnerIcon, {})
|
|
134
|
-
}) : error !== void 0 ? /* @__PURE__ */ jsx("div", {
|
|
135
|
-
className: "lb-ai-chat-error lb-error",
|
|
136
|
-
children: $.GET_CHAT_MESSAGES_ERROR(error)
|
|
137
|
-
}) : /* @__PURE__ */ jsx("div", {
|
|
138
|
-
className: "lb-ai-chat-messages",
|
|
139
|
-
children: /* @__PURE__ */ jsx(Messages, {
|
|
140
|
-
messages,
|
|
141
|
-
overrides: $,
|
|
142
|
-
onDistanceToBottomChange: scrollToBottomCallbackRef.current
|
|
143
|
-
})
|
|
144
|
-
}),
|
|
145
|
-
/* @__PURE__ */ jsxs("div", {
|
|
146
|
-
className: "lb-ai-chat-footer",
|
|
147
|
-
children: [
|
|
148
|
-
/* @__PURE__ */ jsx("div", {
|
|
149
|
-
className: "lb-ai-chat-footer-actions",
|
|
150
|
-
children: /* @__PURE__ */ jsx("button", {
|
|
151
|
-
className: "lb-ai-chat-scroll-button lb-button",
|
|
152
|
-
"data-visible": distanceToBottom !== null && distanceToBottom > MIN_DISTANCE_TO_BOTTOM ? "" : void 0,
|
|
153
|
-
"data-variant": "secondary",
|
|
154
|
-
onClick: () => {
|
|
155
|
-
const container = containerRef.current;
|
|
156
|
-
if (container === null)
|
|
157
|
-
return;
|
|
158
|
-
container.scrollTo({
|
|
159
|
-
top: container.scrollHeight,
|
|
160
|
-
behavior: "smooth"
|
|
161
|
-
});
|
|
162
|
-
},
|
|
163
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
164
|
-
className: "lb-icon-container",
|
|
165
|
-
children: /* @__PURE__ */ jsx(ChevronDownIcon, {})
|
|
166
|
-
})
|
|
167
|
-
})
|
|
168
|
-
}),
|
|
169
|
-
/* @__PURE__ */ jsx(AiChatComposer, {
|
|
170
|
-
chatId,
|
|
171
|
-
copilotId,
|
|
172
|
-
className: "lb-ai-chat-composer",
|
|
173
|
-
overrides: $
|
|
174
|
-
}, chatId)
|
|
175
|
-
]
|
|
176
|
-
})
|
|
177
|
-
]
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
function Messages({
|
|
181
|
-
messages,
|
|
182
|
-
overrides,
|
|
183
|
-
onDistanceToBottomChange
|
|
184
|
-
}) {
|
|
185
|
-
const $ = useOverrides(overrides);
|
|
186
|
-
useLayoutEffect(() => {
|
|
187
|
-
onDistanceToBottomChange();
|
|
188
|
-
}, [onDistanceToBottomChange]);
|
|
189
|
-
return messages.map((message) => {
|
|
190
|
-
if (message.role === "user") {
|
|
191
|
-
return /* @__PURE__ */ jsx(AiChatUserMessage, {
|
|
192
|
-
message,
|
|
193
|
-
overrides: $,
|
|
194
|
-
className: "lb-ai-chat-messages-user-message"
|
|
195
|
-
}, message.id);
|
|
196
|
-
} else if (message.role === "assistant") {
|
|
197
|
-
return /* @__PURE__ */ jsx(AiChatAssistantMessage, {
|
|
198
|
-
message,
|
|
199
|
-
overrides: $,
|
|
200
|
-
className: "lb-ai-chat-messages-assistant-message"
|
|
201
|
-
}, message.id);
|
|
202
|
-
} else {
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export { AiChat };
|
|
209
|
-
//# sourceMappingURL=AiChat.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AiChat.js","sources":["../../../src/components/AiChat/AiChat.tsx"],"sourcesContent":["import {\n type AiChatContext,\n type ClientToolDefinition,\n type CopilotId,\n kInternal,\n type UiChatMessage,\n} from \"@liveblocks/core\";\nimport { useAiChatMessages, useClient } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n forwardRef,\n type HTMLAttributes,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nimport { ChevronDownIcon } from \"../../icons/ChevronDown\";\nimport { SpinnerIcon } from \"../../icons/Spinner\";\nimport {\n type ChatComposerOverrides,\n type ChatMessageOverrides,\n type ChatOverrides,\n type GlobalOverrides,\n useOverrides,\n} from \"../../overrides\";\nimport { classNames } from \"../../utils/class-names\";\nimport { AiChatAssistantMessage } from \"../internal/AiChatAssistantMessage\";\nimport { AiChatComposer } from \"../internal/AiChatComposer\";\nimport { AiChatUserMessage } from \"../internal/AiChatUserMessage\";\n\n/**\n * The number of pixels from the bottom of the messages list to trigger the scroll to bottom.\n */\nconst MIN_DISTANCE_TO_BOTTOM = 50;\n\nexport type AiChatProps = HTMLAttributes<HTMLDivElement> & {\n /**\n * The id of the chat the composer belongs to.\n */\n chatId: string;\n /**\n * The id of the copilot to use to send the message.\n */\n copilotId?: CopilotId;\n /**\n * The contextual information to include in the chat. Used by the assistant when generating responses.\n */\n contexts?: AiChatContext[];\n /**\n * The contextual information to include in the chat. Used by the assistant when generating responses.\n */\n tools?: Record<string, ClientToolDefinition>;\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides &\n ChatMessageOverrides &\n ChatComposerOverrides &\n ChatOverrides\n >;\n};\nexport const AiChat = forwardRef<HTMLDivElement, AiChatProps>(function (\n {\n chatId,\n copilotId,\n overrides,\n contexts = [],\n tools = {},\n className,\n ...props\n },\n forwardedRef\n) {\n const { messages, isLoading, error } = useAiChatMessages(chatId);\n const $ = useOverrides(overrides);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [distanceToBottom, setDistanceToBottom] = useState<number | null>(null);\n const client = useClient();\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => containerRef.current,\n []\n );\n\n // Add the provided contextual information to the chat on mount and remove on unmount\n // Note: 'contexts' will most likely be a new object on each render (unless user passes a stable object), but this won't be an issue as context addition and removal is a quick operation\n useEffect(() => {\n const unregister = contexts.map((context) =>\n client[kInternal].ai.registerChatContext(chatId, context)\n );\n return () => {\n unregister.forEach((unregister) => unregister());\n };\n }, [client, chatId, contexts]);\n\n // Register the provided tools to the chat on mount and unregister them on unmount\n useEffect(() => {\n Object.entries(tools).map(([key, value]) =>\n client[kInternal].ai.registerChatTool(chatId, key, value)\n );\n return () => {\n Object.entries(tools).map(([key]) =>\n client[kInternal].ai.unregisterChatTool(chatId, key)\n );\n };\n }, [client, chatId, tools]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n function handleScrollChange() {\n const container = containerRef.current;\n if (container === null) return;\n\n setDistanceToBottom(\n container.scrollHeight - container.clientHeight - container.scrollTop\n );\n }\n container.addEventListener(\"scroll\", handleScrollChange);\n return () => {\n container.removeEventListener(\"scroll\", handleScrollChange);\n };\n }, []);\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n\n setDistanceToBottom(\n container.scrollHeight - container.clientHeight - container.scrollTop\n );\n }, [messages]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n\n const distanceToBottom =\n container.scrollHeight - container.clientHeight - container.scrollTop;\n\n if (messages === undefined) return;\n const lastMessage = messages[messages.length - 1];\n if (lastMessage !== undefined && lastMessage.role === \"user\") {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"smooth\",\n });\n } else if (distanceToBottom <= MIN_DISTANCE_TO_BOTTOM) {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"smooth\",\n });\n }\n }, [messages]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (container === null) return;\n\n const observer = new ResizeObserver(() => {\n const container = containerRef.current;\n if (container === null) return;\n setDistanceToBottom(\n container.scrollHeight - container.clientHeight - container.scrollTop\n );\n });\n observer.observe(container);\n return () => {\n observer.disconnect();\n };\n }, []);\n\n const scrollToBottomCallbackRef = useRef<() => void>(undefined);\n if (scrollToBottomCallbackRef.current === undefined) {\n scrollToBottomCallbackRef.current = function () {\n const container = containerRef.current;\n if (container === null) return;\n\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"instant\",\n });\n };\n }\n\n return (\n <div\n ref={containerRef}\n {...props}\n className={classNames(\"lb-root lb-ai-chat\", className)}\n >\n {isLoading ? (\n <div className=\"lb-ai-chat-loading lb-loading\">\n <SpinnerIcon />\n </div>\n ) : error !== undefined ? (\n <div className=\"lb-ai-chat-error lb-error\">\n {$.GET_CHAT_MESSAGES_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-ai-chat-messages\">\n <Messages\n messages={messages}\n overrides={$}\n onDistanceToBottomChange={scrollToBottomCallbackRef.current}\n />\n </div>\n )}\n\n <div className=\"lb-ai-chat-footer\">\n <div className=\"lb-ai-chat-footer-actions\">\n <button\n className=\"lb-ai-chat-scroll-button lb-button\"\n data-visible={\n distanceToBottom !== null &&\n distanceToBottom > MIN_DISTANCE_TO_BOTTOM\n ? \"\"\n : undefined\n }\n data-variant=\"secondary\"\n onClick={() => {\n const container = containerRef.current;\n if (container === null) return;\n\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"smooth\",\n });\n }}\n >\n <span className=\"lb-icon-container\">\n <ChevronDownIcon />\n </span>\n </button>\n </div>\n <AiChatComposer\n key={chatId}\n chatId={chatId}\n copilotId={copilotId}\n className=\"lb-ai-chat-composer\"\n overrides={$}\n />\n </div>\n </div>\n );\n});\n\nfunction Messages({\n messages,\n overrides,\n onDistanceToBottomChange,\n}: {\n messages: readonly UiChatMessage[];\n overrides: Partial<GlobalOverrides & ChatMessageOverrides>;\n onDistanceToBottomChange: () => void;\n}) {\n const $ = useOverrides(overrides);\n\n useLayoutEffect(() => {\n onDistanceToBottomChange();\n }, [onDistanceToBottomChange]);\n\n return messages.map((message) => {\n if (message.role === \"user\") {\n return (\n <AiChatUserMessage\n key={message.id}\n message={message}\n overrides={$}\n className=\"lb-ai-chat-messages-user-message\"\n />\n );\n } else if (message.role === \"assistant\") {\n return (\n <AiChatAssistantMessage\n key={message.id}\n message={message}\n overrides={$}\n className=\"lb-ai-chat-messages-assistant-message\"\n />\n );\n } else {\n return null;\n }\n });\n}\n"],"names":["unregister","container","distanceToBottom"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Resolve.cjs","sources":["../../src/icons/Resolve.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function ResolveIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <circle cx={10} cy={10} r={7} />\n <path d=\"m13 8-4 4-2-2\" />\n </Icon>\n );\n}\n"],"names":["jsxs","Icon","jsx"],"mappings":";;;;;AAIO,SAAS,YAAY,KAA8B,EAAA;AACxD,EAAA,uBACGA,eAAA,CAAAC,SAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,IACR,QAAA,EAAA;AAAA,sBAACC,cAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAI,EAAA,EAAA;AAAA,QAAI,EAAI,EAAA,EAAA;AAAA,QAAI,CAAG,EAAA,CAAA;AAAA,OAAG,CAAA;AAAA,sBAC7BA,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,eAAA;AAAA,OAAgB,CAAA;AAAA,KAAA;AAAA,GAC1B,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Resolve.js","sources":["../../src/icons/Resolve.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function ResolveIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <circle cx={10} cy={10} r={7} />\n <path d=\"m13 8-4 4-2-2\" />\n </Icon>\n );\n}\n"],"names":[],"mappings":";;;AAIO,SAAS,YAAY,KAA8B,EAAA;AACxD,EAAA,uBACG,IAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,IACR,QAAA,EAAA;AAAA,sBAAC,GAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAI,EAAA,EAAA;AAAA,QAAI,EAAI,EAAA,EAAA;AAAA,QAAI,CAAG,EAAA,CAAA;AAAA,OAAG,CAAA;AAAA,sBAC7B,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,eAAA;AAAA,OAAgB,CAAA;AAAA,KAAA;AAAA,GAC1B,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Resolved.cjs","sources":["../../src/icons/Resolved.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function ResolvedIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <circle cx={10} cy={10} r={7} fill=\"currentColor\" />\n <path d=\"m13 8-4 4-2-2\" stroke=\"var(--lb-icon-background)\" />\n </Icon>\n );\n}\n"],"names":["jsxs","Icon","jsx"],"mappings":";;;;;AAIO,SAAS,aAAa,KAA8B,EAAA;AACzD,EAAA,uBACGA,eAAA,CAAAC,SAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,IACR,QAAA,EAAA;AAAA,sBAACC,cAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAI,EAAA,EAAA;AAAA,QAAI,EAAI,EAAA,EAAA;AAAA,QAAI,CAAG,EAAA,CAAA;AAAA,QAAG,IAAK,EAAA,cAAA;AAAA,OAAe,CAAA;AAAA,sBACjDA,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,eAAA;AAAA,QAAgB,MAAO,EAAA,2BAAA;AAAA,OAA4B,CAAA;AAAA,KAAA;AAAA,GAC7D,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Resolved.js","sources":["../../src/icons/Resolved.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function ResolvedIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <circle cx={10} cy={10} r={7} fill=\"currentColor\" />\n <path d=\"m13 8-4 4-2-2\" stroke=\"var(--lb-icon-background)\" />\n </Icon>\n );\n}\n"],"names":[],"mappings":";;;AAIO,SAAS,aAAa,KAA8B,EAAA;AACzD,EAAA,uBACG,IAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,IACR,QAAA,EAAA;AAAA,sBAAC,GAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAI,EAAA,EAAA;AAAA,QAAI,EAAI,EAAA,EAAA;AAAA,QAAI,CAAG,EAAA,CAAA;AAAA,QAAG,IAAK,EAAA,cAAA;AAAA,OAAe,CAAA;AAAA,sBACjD,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,eAAA;AAAA,QAAgB,MAAO,EAAA,2BAAA;AAAA,OAA4B,CAAA;AAAA,KAAA;AAAA,GAC7D,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,323 +0,0 @@
|
|
|
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 react = require('react');
|
|
8
|
-
var slate = require('slate');
|
|
9
|
-
var slateHistory = require('slate-history');
|
|
10
|
-
var slateReact = require('slate-react');
|
|
11
|
-
var normalize = require('../../../slate/plugins/normalize.cjs');
|
|
12
|
-
var isEmpty = require('../../../slate/utils/is-empty.cjs');
|
|
13
|
-
var utils = require('../../Composer/utils.cjs');
|
|
14
|
-
|
|
15
|
-
const ComposerContext = react.createContext(null);
|
|
16
|
-
const MAX_ATTACHMENTS = 10;
|
|
17
|
-
const MAX_ATTACHMENT_SIZE = 1024 * 1024 * 1024;
|
|
18
|
-
const Form = react.forwardRef(
|
|
19
|
-
({ onComposerSubmit, onSubmit, disabled, chatId, ...props }, forwardedRef) => {
|
|
20
|
-
const formRef = react.useRef(null);
|
|
21
|
-
const fileInputRef = react.useRef(null);
|
|
22
|
-
const editorRef = react.useRef(
|
|
23
|
-
null
|
|
24
|
-
);
|
|
25
|
-
if (editorRef.current === null) {
|
|
26
|
-
editorRef.current = normalize.withNormalize(slateHistory.withHistory(slateReact.withReact(slate.createEditor())));
|
|
27
|
-
}
|
|
28
|
-
const editor = editorRef.current;
|
|
29
|
-
const [isEditorEmpty, setIsEditorEmpty] = react.useState(true);
|
|
30
|
-
const [attachments, setAttachments] = react.useState([]);
|
|
31
|
-
const handleSubmit = react.useCallback(
|
|
32
|
-
(event) => {
|
|
33
|
-
if (disabled || isEmpty.isEmpty(editor, editor.children))
|
|
34
|
-
return;
|
|
35
|
-
onSubmit?.(event);
|
|
36
|
-
if (onComposerSubmit === void 0 || event.isDefaultPrevented()) {
|
|
37
|
-
event.preventDefault();
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
const content = editor.children.map((block) => {
|
|
41
|
-
if ("type" in block && block.type === "paragraph") {
|
|
42
|
-
return block.children.map((child) => {
|
|
43
|
-
if ("text" in child) {
|
|
44
|
-
return child.text;
|
|
45
|
-
}
|
|
46
|
-
return "";
|
|
47
|
-
}).join("");
|
|
48
|
-
}
|
|
49
|
-
return "";
|
|
50
|
-
}).join("\n");
|
|
51
|
-
onComposerSubmit({ text: content }, event);
|
|
52
|
-
if (event.isDefaultPrevented()) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
event.preventDefault();
|
|
56
|
-
slate.Transforms.delete(editor, {
|
|
57
|
-
at: {
|
|
58
|
-
anchor: slate.Editor.start(editor, []),
|
|
59
|
-
focus: slate.Editor.end(editor, [])
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
},
|
|
63
|
-
[disabled, editor, onSubmit, onComposerSubmit]
|
|
64
|
-
);
|
|
65
|
-
_private.useLayoutEffect(() => {
|
|
66
|
-
setIsEditorEmpty(isEmpty.isEmpty(editor, editor.children));
|
|
67
|
-
}, [editor]);
|
|
68
|
-
const handleEditorValueChange = react.useCallback(() => {
|
|
69
|
-
setIsEditorEmpty(isEmpty.isEmpty(editor, editor.children));
|
|
70
|
-
}, [editor]);
|
|
71
|
-
const requestFormSubmit = react.useCallback(() => {
|
|
72
|
-
if (isEmpty.isEmpty(editor, editor.children))
|
|
73
|
-
return;
|
|
74
|
-
if (attachments.some((attachment) => attachment.status === "uploading")) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
requestAnimationFrame(() => {
|
|
78
|
-
if (formRef.current === null)
|
|
79
|
-
return;
|
|
80
|
-
if (typeof formRef.current.requestSubmit === "function") {
|
|
81
|
-
return formRef.current.requestSubmit();
|
|
82
|
-
}
|
|
83
|
-
const submitter = document.createElement("input");
|
|
84
|
-
submitter.type = "submit";
|
|
85
|
-
submitter.hidden = true;
|
|
86
|
-
formRef.current.appendChild(submitter);
|
|
87
|
-
submitter.click();
|
|
88
|
-
formRef.current.removeChild(submitter);
|
|
89
|
-
});
|
|
90
|
-
}, [editor, attachments]);
|
|
91
|
-
const handleAttachFiles = react.useCallback(() => {
|
|
92
|
-
if (disabled)
|
|
93
|
-
return;
|
|
94
|
-
fileInputRef.current?.click();
|
|
95
|
-
}, [disabled]);
|
|
96
|
-
const handleRemoveAttachment = react.useCallback((id) => {
|
|
97
|
-
setAttachments(
|
|
98
|
-
(attachments2) => attachments2.filter((attachment) => attachment.id !== id)
|
|
99
|
-
);
|
|
100
|
-
}, []);
|
|
101
|
-
react.useImperativeHandle(
|
|
102
|
-
forwardedRef,
|
|
103
|
-
() => formRef.current,
|
|
104
|
-
[]
|
|
105
|
-
);
|
|
106
|
-
const client = react$1.useClient();
|
|
107
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ComposerContext.Provider, {
|
|
108
|
-
value: {
|
|
109
|
-
chatId,
|
|
110
|
-
editor,
|
|
111
|
-
onEditorValueChange: handleEditorValueChange,
|
|
112
|
-
isEditorEmpty,
|
|
113
|
-
requestFormSubmit,
|
|
114
|
-
disabled: disabled || false,
|
|
115
|
-
attachments,
|
|
116
|
-
onAttachFiles: handleAttachFiles,
|
|
117
|
-
onRemoveAttachment: handleRemoveAttachment,
|
|
118
|
-
numOfAttachments: attachments.length
|
|
119
|
-
},
|
|
120
|
-
children: [
|
|
121
|
-
/* @__PURE__ */ jsxRuntime.jsx("form", {
|
|
122
|
-
onSubmit: handleSubmit,
|
|
123
|
-
...props,
|
|
124
|
-
ref: formRef
|
|
125
|
-
}),
|
|
126
|
-
/* @__PURE__ */ jsxRuntime.jsx("input", {
|
|
127
|
-
type: "file",
|
|
128
|
-
multiple: true,
|
|
129
|
-
accept: "image/png, image/jpeg",
|
|
130
|
-
ref: fileInputRef,
|
|
131
|
-
onClick: (event) => {
|
|
132
|
-
event.stopPropagation();
|
|
133
|
-
},
|
|
134
|
-
onChange: function(event) {
|
|
135
|
-
if (disabled)
|
|
136
|
-
return;
|
|
137
|
-
if (event.target.files === null)
|
|
138
|
-
return;
|
|
139
|
-
if (event.target.files.length === 0)
|
|
140
|
-
return;
|
|
141
|
-
for (const file of Array.from(event.target.files).slice(
|
|
142
|
-
0,
|
|
143
|
-
MAX_ATTACHMENTS - attachments.length
|
|
144
|
-
)) {
|
|
145
|
-
const id = `at_${core.nanoid()}`;
|
|
146
|
-
if (file.size > MAX_ATTACHMENT_SIZE) {
|
|
147
|
-
setAttachments((attachments2) => [
|
|
148
|
-
...attachments2,
|
|
149
|
-
{
|
|
150
|
-
id,
|
|
151
|
-
file,
|
|
152
|
-
status: "error",
|
|
153
|
-
error: new utils.AttachmentTooLargeError("File is too large.")
|
|
154
|
-
}
|
|
155
|
-
]);
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
setAttachments((attachments2) => [
|
|
159
|
-
...attachments2,
|
|
160
|
-
{
|
|
161
|
-
id,
|
|
162
|
-
file,
|
|
163
|
-
status: "uploading"
|
|
164
|
-
}
|
|
165
|
-
]);
|
|
166
|
-
client[core.kInternal].httpClient.uploadChatAttachment({
|
|
167
|
-
chatId,
|
|
168
|
-
attachment: {
|
|
169
|
-
id,
|
|
170
|
-
file
|
|
171
|
-
}
|
|
172
|
-
}).then(() => {
|
|
173
|
-
setAttachments(
|
|
174
|
-
(attachments2) => attachments2.map(
|
|
175
|
-
(attachment) => attachment.id === id ? { ...attachment, status: "uploaded" } : attachment
|
|
176
|
-
)
|
|
177
|
-
);
|
|
178
|
-
}).catch((error) => {
|
|
179
|
-
if (error instanceof Error) {
|
|
180
|
-
setAttachments(
|
|
181
|
-
(attachments2) => attachments2.map(
|
|
182
|
-
(attachment) => attachment.id === id ? {
|
|
183
|
-
...attachment,
|
|
184
|
-
status: "error",
|
|
185
|
-
error: error instanceof core.HttpError && error.status === 413 ? new utils.AttachmentTooLargeError(
|
|
186
|
-
"File is too large"
|
|
187
|
-
) : error
|
|
188
|
-
} : attachment
|
|
189
|
-
)
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
event.target.value = "";
|
|
195
|
-
},
|
|
196
|
-
tabIndex: -1,
|
|
197
|
-
style: { display: "none" }
|
|
198
|
-
})
|
|
199
|
-
]
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
);
|
|
203
|
-
const Editor = react.forwardRef(
|
|
204
|
-
({ defaultValue = "", onKeyDown, disabled, autoFocus, ...props }, forwardedRef) => {
|
|
205
|
-
const context = react.useContext(ComposerContext);
|
|
206
|
-
if (context === null) {
|
|
207
|
-
throw new Error("Editor must be a descendant of Form.");
|
|
208
|
-
}
|
|
209
|
-
const {
|
|
210
|
-
editor,
|
|
211
|
-
onEditorValueChange,
|
|
212
|
-
requestFormSubmit,
|
|
213
|
-
disabled: isFormDisabled
|
|
214
|
-
} = context;
|
|
215
|
-
const handleKeyDown = react.useCallback(
|
|
216
|
-
(event) => {
|
|
217
|
-
onKeyDown?.(event);
|
|
218
|
-
if (event.isDefaultPrevented())
|
|
219
|
-
return;
|
|
220
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
221
|
-
event.preventDefault();
|
|
222
|
-
requestFormSubmit();
|
|
223
|
-
} else if (event.key === "Enter" && event.shiftKey) {
|
|
224
|
-
event.preventDefault();
|
|
225
|
-
editor.insertBreak();
|
|
226
|
-
}
|
|
227
|
-
},
|
|
228
|
-
[editor, onKeyDown, requestFormSubmit]
|
|
229
|
-
);
|
|
230
|
-
react.useImperativeHandle(
|
|
231
|
-
forwardedRef,
|
|
232
|
-
() => slateReact.ReactEditor.toDOMNode(editor, editor),
|
|
233
|
-
[editor]
|
|
234
|
-
);
|
|
235
|
-
react.useEffect(() => {
|
|
236
|
-
if (!autoFocus)
|
|
237
|
-
return;
|
|
238
|
-
try {
|
|
239
|
-
if (!slateReact.ReactEditor.isFocused(editor)) {
|
|
240
|
-
slate.Transforms.select(editor, slate.Editor.end(editor, []));
|
|
241
|
-
slateReact.ReactEditor.focus(editor);
|
|
242
|
-
}
|
|
243
|
-
} catch {
|
|
244
|
-
}
|
|
245
|
-
}, [editor, autoFocus]);
|
|
246
|
-
const initialValue = react.useMemo(() => {
|
|
247
|
-
return defaultValue.split("\n").map((text) => ({ type: "paragraph", children: [{ text }] }));
|
|
248
|
-
}, [defaultValue]);
|
|
249
|
-
return /* @__PURE__ */ jsxRuntime.jsx(slateReact.Slate, {
|
|
250
|
-
editor,
|
|
251
|
-
initialValue,
|
|
252
|
-
onValueChange: onEditorValueChange,
|
|
253
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(slateReact.Editable, {
|
|
254
|
-
enterKeyHint: "send",
|
|
255
|
-
autoCapitalize: "sentences",
|
|
256
|
-
onKeyDown: handleKeyDown,
|
|
257
|
-
"data-disabled": disabled || isFormDisabled || void 0,
|
|
258
|
-
...props,
|
|
259
|
-
readOnly: disabled || isFormDisabled,
|
|
260
|
-
disabled: disabled || isFormDisabled,
|
|
261
|
-
renderPlaceholder: function({ attributes, children }) {
|
|
262
|
-
const { opacity: _opacity, ...style } = attributes.style;
|
|
263
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
264
|
-
...attributes,
|
|
265
|
-
style,
|
|
266
|
-
"data-placeholder": "",
|
|
267
|
-
children
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
})
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
);
|
|
274
|
-
const Submit = react.forwardRef(
|
|
275
|
-
({ disabled, ...props }, forwardedRef) => {
|
|
276
|
-
const context = react.useContext(ComposerContext);
|
|
277
|
-
if (context === null) {
|
|
278
|
-
throw new Error("Submit must be a descendant of Form.");
|
|
279
|
-
}
|
|
280
|
-
const { disabled: isFormDisabled, isEditorEmpty, attachments } = context;
|
|
281
|
-
return /* @__PURE__ */ jsxRuntime.jsx("button", {
|
|
282
|
-
type: "submit",
|
|
283
|
-
...props,
|
|
284
|
-
ref: forwardedRef,
|
|
285
|
-
disabled: disabled || isFormDisabled || isEditorEmpty || attachments.some((attachment) => attachment.status === "uploading")
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
);
|
|
289
|
-
const AttachFiles = react.forwardRef(
|
|
290
|
-
({ onClick, disabled, ...props }, forwardedRef) => {
|
|
291
|
-
const context = react.useContext(ComposerContext);
|
|
292
|
-
if (context === null) {
|
|
293
|
-
throw new Error("AttachFiles must be a descendant of Form.");
|
|
294
|
-
}
|
|
295
|
-
const {
|
|
296
|
-
disabled: isFormDisabled,
|
|
297
|
-
onAttachFiles,
|
|
298
|
-
numOfAttachments
|
|
299
|
-
} = context;
|
|
300
|
-
return /* @__PURE__ */ jsxRuntime.jsx("button", {
|
|
301
|
-
type: "button",
|
|
302
|
-
...props,
|
|
303
|
-
onClick: function(event) {
|
|
304
|
-
onClick?.(event);
|
|
305
|
-
if (event.isDefaultPrevented())
|
|
306
|
-
return;
|
|
307
|
-
onAttachFiles();
|
|
308
|
-
},
|
|
309
|
-
onPointerDown: (event) => event.preventDefault(),
|
|
310
|
-
ref: forwardedRef,
|
|
311
|
-
disabled: isFormDisabled || disabled || numOfAttachments >= MAX_ATTACHMENTS
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
);
|
|
315
|
-
|
|
316
|
-
exports.AttachFiles = AttachFiles;
|
|
317
|
-
exports.ComposerContext = ComposerContext;
|
|
318
|
-
exports.Editor = Editor;
|
|
319
|
-
exports.Form = Form;
|
|
320
|
-
exports.MAX_ATTACHMENTS = MAX_ATTACHMENTS;
|
|
321
|
-
exports.MAX_ATTACHMENT_SIZE = MAX_ATTACHMENT_SIZE;
|
|
322
|
-
exports.Submit = Submit;
|
|
323
|
-
//# sourceMappingURL=index.cjs.map
|