@liveblocks/react-ui
Version:
A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.
160 lines (157 loc) • 5.72 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import { kInternal } from '@liveblocks/core';
import { useClient } from '@liveblocks/react';
import { useSignal } from '@liveblocks/react/_private';
import { forwardRef, useCallback } from 'react';
import { SendIcon } from '../../icons/Send.js';
import { StopIcon } from '../../icons/Stop.js';
import { useOverrides } from '../../overrides.js';
import { AiChatComposerForm, AiChatComposerEditor, AiChatComposerSubmit } from '../../primitives/AiChatComposer/index.js';
import { cn } from '../../utils/cn.js';
import { Button } from './Button.js';
import { ShortcutTooltip } from './Tooltip.js';
import { TooltipProvider } from '@radix-ui/react-tooltip';
const AiChatComposer = forwardRef(
({
defaultValue,
onComposerSubmit,
disabled,
autoFocus,
overrides,
className,
chatId,
branchId,
copilotId,
stream = true,
onUserMessageCreate,
...props
}, forwardedRef) => {
const $ = useOverrides(overrides);
const client = useClient();
const getLastMessageId = useCallback((messages) => {
const lastMessage = messages[messages.length - 1];
if (lastMessage === void 0)
return null;
return lastMessage.id;
}, []);
const getAbortableMessageId = useCallback((messages) => {
return messages.find(
(m) => m.role === "assistant" && (m.status === "generating" || m.status === "awaiting-tool")
)?.id;
}, []);
const messages\u03A3 = client[kInternal].ai.signals.getChatMessagesForBranch\u03A3(
chatId,
branchId
);
const abortableMessageId = useSignal(messages\u03A3, getAbortableMessageId);
const lastMessageId = useSignal(messages\u03A3, getLastMessageId);
const handleComposerSubmit = useCallback(
(message, event) => {
if (abortableMessageId !== void 0) {
event.preventDefault();
return;
}
onComposerSubmit?.(message, event);
if (event.isDefaultPrevented())
return;
const content = [{ type: "text", text: message.text }];
const newMessageId = client[kInternal].ai[kInternal].context.messagesStore.createOptimistically(
chatId,
"user",
lastMessageId,
content
);
onUserMessageCreate?.({ id: newMessageId });
const targetMessageId = client[kInternal].ai[kInternal].context.messagesStore.createOptimistically(
chatId,
"assistant",
newMessageId
);
client[kInternal].ai.askUserMessageInChat(
chatId,
{ id: newMessageId, parentMessageId: lastMessageId, content },
targetMessageId,
{
stream,
copilotId
}
);
},
[
onComposerSubmit,
onUserMessageCreate,
client,
chatId,
lastMessageId,
abortableMessageId,
stream,
copilotId
]
);
return /* @__PURE__ */ jsx(TooltipProvider, {
children: /* @__PURE__ */ jsx(AiChatComposerForm, {
className: cn(
"lb-root lb-ai-chat-composer lb-ai-chat-composer-form",
className
),
dir: $.dir,
...props,
disabled,
ref: forwardedRef,
onComposerSubmit: handleComposerSubmit,
children: /* @__PURE__ */ jsxs("div", {
className: "lb-ai-chat-composer-editor-container",
children: [
/* @__PURE__ */ jsx(AiChatComposerEditor, {
autoFocus,
className: "lb-ai-chat-composer-editor",
placeholder: $.AI_CHAT_COMPOSER_PLACEHOLDER,
defaultValue
}),
/* @__PURE__ */ jsxs("div", {
className: "lb-ai-chat-composer-footer",
children: [
/* @__PURE__ */ jsx("div", {
className: "lb-ai-chat-composer-editor-actions"
}),
/* @__PURE__ */ jsx("div", {
className: "lb-ai-chat-composer-actions",
children: abortableMessageId === void 0 ? /* @__PURE__ */ jsx(ShortcutTooltip, {
content: $.AI_CHAT_COMPOSER_SEND,
shortcut: "Enter",
children: /* @__PURE__ */ jsx(AiChatComposerSubmit, {
asChild: true,
children: /* @__PURE__ */ jsx(Button, {
onPointerDown: (event) => event.preventDefault(),
onClick: (event) => event.stopPropagation(),
className: "lb-ai-chat-composer-action",
variant: "primary",
"aria-label": $.AI_CHAT_COMPOSER_SEND,
icon: /* @__PURE__ */ jsx(SendIcon, {})
})
})
}) : /* @__PURE__ */ jsx(ShortcutTooltip, {
content: $.AI_CHAT_COMPOSER_ABORT,
children: /* @__PURE__ */ jsx(Button, {
onPointerDown: (event) => event.preventDefault(),
onClick: (event) => {
event.stopPropagation();
client[kInternal].ai.abort(abortableMessageId);
},
className: "lb-ai-chat-composer-action",
variant: "secondary",
"aria-label": $.AI_CHAT_COMPOSER_ABORT,
icon: /* @__PURE__ */ jsx(StopIcon, {})
})
})
})
]
})
]
})
})
});
}
);
export { AiChatComposer };
//# sourceMappingURL=AiChatComposer.js.map