@liveblocks/react-ui 3.2.1 → 3.3.0

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 (52) hide show
  1. package/dist/_private/index.cjs +4 -2
  2. package/dist/_private/index.cjs.map +1 -1
  3. package/dist/_private/index.d.cts +100 -33
  4. package/dist/_private/index.d.ts +100 -33
  5. package/dist/_private/index.js +3 -2
  6. package/dist/_private/index.js.map +1 -1
  7. package/dist/components/AiChat.cjs +11 -9
  8. package/dist/components/AiChat.cjs.map +1 -1
  9. package/dist/components/AiChat.js +12 -10
  10. package/dist/components/AiChat.js.map +1 -1
  11. package/dist/components/Thread.cjs +58 -0
  12. package/dist/components/Thread.cjs.map +1 -1
  13. package/dist/components/Thread.js +59 -1
  14. package/dist/components/Thread.js.map +1 -1
  15. package/dist/components/internal/AiComposer.cjs +132 -0
  16. package/dist/components/internal/AiComposer.cjs.map +1 -0
  17. package/dist/components/internal/AiComposer.js +130 -0
  18. package/dist/components/internal/AiComposer.js.map +1 -0
  19. package/dist/components/internal/Button.cjs.map +1 -1
  20. package/dist/components/internal/Button.js.map +1 -1
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +113 -11
  23. package/dist/index.d.ts +113 -11
  24. package/dist/index.js.map +1 -1
  25. package/dist/overrides.cjs +4 -3
  26. package/dist/overrides.cjs.map +1 -1
  27. package/dist/overrides.js +4 -3
  28. package/dist/overrides.js.map +1 -1
  29. package/dist/primitives/AiComposer/contexts.cjs +24 -0
  30. package/dist/primitives/AiComposer/contexts.cjs.map +1 -0
  31. package/dist/primitives/AiComposer/contexts.js +19 -0
  32. package/dist/primitives/AiComposer/contexts.js.map +1 -0
  33. package/dist/primitives/AiComposer/index.cjs +348 -0
  34. package/dist/primitives/AiComposer/index.cjs.map +1 -0
  35. package/dist/primitives/AiComposer/index.js +340 -0
  36. package/dist/primitives/AiComposer/index.js.map +1 -0
  37. package/dist/primitives/index.d.cts +8 -1
  38. package/dist/primitives/index.d.ts +8 -1
  39. package/dist/version.cjs +1 -1
  40. package/dist/version.js +1 -1
  41. package/package.json +4 -4
  42. package/src/styles/index.css +36 -10
  43. package/styles.css +1 -1
  44. package/styles.css.map +1 -1
  45. package/dist/components/internal/AiChatComposer.cjs +0 -161
  46. package/dist/components/internal/AiChatComposer.cjs.map +0 -1
  47. package/dist/components/internal/AiChatComposer.js +0 -159
  48. package/dist/components/internal/AiChatComposer.js.map +0 -1
  49. package/dist/primitives/AiChatComposer/index.cjs +0 -202
  50. package/dist/primitives/AiChatComposer/index.cjs.map +0 -1
  51. package/dist/primitives/AiChatComposer/index.js +0 -195
  52. package/dist/primitives/AiChatComposer/index.js.map +0 -1
@@ -1,159 +0,0 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { kInternal } from '@liveblocks/core';
3
- import { useClient } from '@liveblocks/react';
4
- import { useSignal } from '@liveblocks/react/_private';
5
- import { forwardRef, useCallback } from 'react';
6
- import { SendIcon } from '../../icons/Send.js';
7
- import { StopIcon } from '../../icons/Stop.js';
8
- import { useOverrides } from '../../overrides.js';
9
- import { AiChatComposerForm, AiChatComposerEditor, AiChatComposerSubmit } from '../../primitives/AiChatComposer/index.js';
10
- import { cn } from '../../utils/cn.js';
11
- import { Button } from './Button.js';
12
- import { ShortcutTooltip } from './Tooltip.js';
13
- import { TooltipProvider } from '@radix-ui/react-tooltip';
14
-
15
- const AiChatComposer = forwardRef(
16
- ({
17
- defaultValue,
18
- onComposerSubmit,
19
- disabled,
20
- autoFocus,
21
- overrides,
22
- className,
23
- chatId,
24
- branchId,
25
- copilotId,
26
- stream = true,
27
- onUserMessageCreate,
28
- ...props
29
- }, forwardedRef) => {
30
- const $ = useOverrides(overrides);
31
- const client = useClient();
32
- const getLastMessageId = useCallback((messages) => {
33
- const lastMessage = messages[messages.length - 1];
34
- if (lastMessage === void 0)
35
- return null;
36
- return lastMessage.id;
37
- }, []);
38
- const getAbortableMessageId = useCallback((messages) => {
39
- return messages.find(
40
- (m) => m.role === "assistant" && (m.status === "generating" || m.status === "awaiting-tool")
41
- )?.id;
42
- }, []);
43
- const messages\u03A3 = client[kInternal].ai.signals.getChatMessagesForBranch\u03A3(
44
- chatId,
45
- branchId
46
- );
47
- const abortableMessageId = useSignal(messages\u03A3, getAbortableMessageId);
48
- const lastMessageId = useSignal(messages\u03A3, getLastMessageId);
49
- const handleComposerSubmit = useCallback(
50
- (message, event) => {
51
- if (abortableMessageId !== void 0) {
52
- event.preventDefault();
53
- return;
54
- }
55
- onComposerSubmit?.(message, event);
56
- if (event.isDefaultPrevented())
57
- return;
58
- const content = [{ type: "text", text: message.text }];
59
- const newMessageId = client[kInternal].ai[kInternal].context.messagesStore.createOptimistically(
60
- chatId,
61
- "user",
62
- lastMessageId,
63
- content
64
- );
65
- onUserMessageCreate?.({ id: newMessageId });
66
- const targetMessageId = client[kInternal].ai[kInternal].context.messagesStore.createOptimistically(
67
- chatId,
68
- "assistant",
69
- newMessageId
70
- );
71
- client[kInternal].ai.askUserMessageInChat(
72
- chatId,
73
- { id: newMessageId, parentMessageId: lastMessageId, content },
74
- targetMessageId,
75
- {
76
- stream,
77
- copilotId
78
- }
79
- );
80
- },
81
- [
82
- onComposerSubmit,
83
- onUserMessageCreate,
84
- client,
85
- chatId,
86
- lastMessageId,
87
- abortableMessageId,
88
- stream,
89
- copilotId
90
- ]
91
- );
92
- return /* @__PURE__ */ jsx(TooltipProvider, {
93
- children: /* @__PURE__ */ jsx(AiChatComposerForm, {
94
- className: cn(
95
- "lb-root lb-ai-chat-composer lb-ai-chat-composer-form",
96
- className
97
- ),
98
- dir: $.dir,
99
- ...props,
100
- disabled,
101
- ref: forwardedRef,
102
- onComposerSubmit: handleComposerSubmit,
103
- children: /* @__PURE__ */ jsxs("div", {
104
- className: "lb-ai-chat-composer-editor-container",
105
- children: [
106
- /* @__PURE__ */ jsx(AiChatComposerEditor, {
107
- autoFocus,
108
- className: "lb-ai-chat-composer-editor",
109
- placeholder: $.AI_CHAT_COMPOSER_PLACEHOLDER,
110
- defaultValue
111
- }),
112
- /* @__PURE__ */ jsxs("div", {
113
- className: "lb-ai-chat-composer-footer",
114
- children: [
115
- /* @__PURE__ */ jsx("div", {
116
- className: "lb-ai-chat-composer-editor-actions"
117
- }),
118
- /* @__PURE__ */ jsx("div", {
119
- className: "lb-ai-chat-composer-actions",
120
- children: abortableMessageId === void 0 ? /* @__PURE__ */ jsx(ShortcutTooltip, {
121
- content: $.AI_CHAT_COMPOSER_SEND,
122
- shortcut: "Enter",
123
- children: /* @__PURE__ */ jsx(AiChatComposerSubmit, {
124
- asChild: true,
125
- children: /* @__PURE__ */ jsx(Button, {
126
- onPointerDown: (event) => event.preventDefault(),
127
- onClick: (event) => event.stopPropagation(),
128
- className: "lb-ai-chat-composer-action",
129
- variant: "primary",
130
- "aria-label": $.AI_CHAT_COMPOSER_SEND,
131
- icon: /* @__PURE__ */ jsx(SendIcon, {})
132
- })
133
- })
134
- }) : /* @__PURE__ */ jsx(ShortcutTooltip, {
135
- content: $.AI_CHAT_COMPOSER_ABORT,
136
- children: /* @__PURE__ */ jsx(Button, {
137
- onPointerDown: (event) => event.preventDefault(),
138
- onClick: (event) => {
139
- event.stopPropagation();
140
- client[kInternal].ai.abort(abortableMessageId);
141
- },
142
- className: "lb-ai-chat-composer-action",
143
- variant: "secondary",
144
- "aria-label": $.AI_CHAT_COMPOSER_ABORT,
145
- icon: /* @__PURE__ */ jsx(StopIcon, {})
146
- })
147
- })
148
- })
149
- ]
150
- })
151
- ]
152
- })
153
- })
154
- });
155
- }
156
- );
157
-
158
- export { AiChatComposer };
159
- //# sourceMappingURL=AiChatComposer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AiChatComposer.js","sources":["../../../src/components/internal/AiChatComposer.tsx"],"sourcesContent":["import type {\n AiChatMessage,\n CopilotId,\n MessageId,\n WithNavigation,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport {\n type ComponentProps,\n type FormEvent,\n forwardRef,\n useCallback,\n} from \"react\";\n\nimport { SendIcon } from \"../../icons/Send\";\nimport { StopIcon } from \"../../icons/Stop\";\nimport {\n type AiChatComposerOverrides,\n type GlobalOverrides,\n useOverrides,\n} from \"../../overrides\";\nimport * as ComposerPrimitive from \"../../primitives/AiChatComposer\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"./Button\";\nimport { ShortcutTooltip, TooltipProvider } from \"./Tooltip\";\n\ntype UiChatMessage = WithNavigation<AiChatMessage>;\n\n/* -------------------------------------------------------------------------------------------------\n * AiChatComposer\n * -----------------------------------------------------------------------------------------------*/\nexport interface AiChatComposerProps extends ComponentProps<\"form\"> {\n /**\n * The composer's initial value.\n */\n defaultValue?: string;\n /**\n * The event handler called when a chat message is submitted.\n */\n onComposerSubmit?: (\n message: {\n /**\n * The submitted message text.\n */\n text: string;\n },\n event: FormEvent<HTMLFormElement>\n ) => void;\n\n /**\n * @internal\n * The event handler called when a user chat message is created optimistically.\n */\n onUserMessageCreate?: (message: {\n /**\n * The created user message id.\n */\n id: MessageId;\n }) => void;\n /**\n * Whether the composer is disabled.\n */\n disabled?: boolean;\n /**\n * Whether to focus the editor on mount.\n */\n autoFocus?: boolean;\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & AiChatComposerOverrides>;\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 * @internal\n */\n branchId?: MessageId;\n /**\n * @internal\n */\n stream?: boolean;\n}\n\nexport const AiChatComposer = forwardRef<HTMLFormElement, AiChatComposerProps>(\n (\n {\n defaultValue,\n onComposerSubmit,\n disabled,\n autoFocus,\n overrides,\n className,\n chatId,\n branchId,\n copilotId,\n stream = true,\n onUserMessageCreate,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const client = useClient();\n\n const getLastMessageId = useCallback((messages: UiChatMessage[]) => {\n const lastMessage = messages[messages.length - 1];\n if (lastMessage === undefined) return null;\n return lastMessage.id;\n }, []);\n\n const getAbortableMessageId = useCallback((messages: UiChatMessage[]) => {\n return messages.find(\n (m) =>\n m.role === \"assistant\" &&\n (m.status === \"generating\" || m.status === \"awaiting-tool\")\n )?.id;\n }, []);\n\n const messagesΣ = client[kInternal].ai.signals.getChatMessagesForBranchΣ(\n chatId,\n branchId\n );\n\n const abortableMessageId = useSignal(messagesΣ, getAbortableMessageId);\n const lastMessageId = useSignal(messagesΣ, getLastMessageId);\n\n const handleComposerSubmit = useCallback(\n (message: { text: string }, event: FormEvent<HTMLFormElement>) => {\n if (abortableMessageId !== undefined) {\n event.preventDefault();\n return;\n }\n\n onComposerSubmit?.(message, event);\n if (event.isDefaultPrevented()) return;\n\n const content = [{ type: \"text\" as const, text: message.text }];\n const newMessageId = client[kInternal].ai[\n kInternal\n ].context.messagesStore.createOptimistically(\n chatId,\n \"user\",\n lastMessageId,\n content\n );\n onUserMessageCreate?.({ id: newMessageId });\n\n const targetMessageId = client[kInternal].ai[\n kInternal\n ].context.messagesStore.createOptimistically(\n chatId,\n \"assistant\",\n newMessageId\n );\n\n client[kInternal].ai.askUserMessageInChat(\n chatId,\n { id: newMessageId, parentMessageId: lastMessageId, content },\n targetMessageId,\n {\n stream,\n copilotId,\n }\n );\n },\n [\n onComposerSubmit,\n onUserMessageCreate,\n client,\n chatId,\n lastMessageId,\n abortableMessageId,\n stream,\n copilotId,\n ]\n );\n\n return (\n <TooltipProvider>\n <ComposerPrimitive.Form\n className={cn(\n \"lb-root lb-ai-chat-composer lb-ai-chat-composer-form\",\n className\n )}\n dir={$.dir}\n {...props}\n disabled={disabled}\n ref={forwardedRef}\n onComposerSubmit={handleComposerSubmit}\n >\n <div className=\"lb-ai-chat-composer-editor-container\">\n <ComposerPrimitive.Editor\n autoFocus={autoFocus}\n className=\"lb-ai-chat-composer-editor\"\n placeholder={$.AI_CHAT_COMPOSER_PLACEHOLDER}\n defaultValue={defaultValue}\n />\n\n <div className=\"lb-ai-chat-composer-footer\">\n <div className=\"lb-ai-chat-composer-editor-actions\">\n {/* No actions for now but it makes sense to keep the DOM structure */}\n </div>\n\n <div className=\"lb-ai-chat-composer-actions\">\n {abortableMessageId === undefined ? (\n <ShortcutTooltip\n content={$.AI_CHAT_COMPOSER_SEND}\n shortcut=\"Enter\"\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n onPointerDown={(event) => event.preventDefault()}\n onClick={(event) => event.stopPropagation()}\n className=\"lb-ai-chat-composer-action\"\n variant=\"primary\"\n aria-label={$.AI_CHAT_COMPOSER_SEND}\n icon={<SendIcon />}\n />\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n ) : (\n <ShortcutTooltip content={$.AI_CHAT_COMPOSER_ABORT}>\n <Button\n onPointerDown={(event) => event.preventDefault()}\n onClick={(event) => {\n event.stopPropagation();\n client[kInternal].ai.abort(abortableMessageId);\n }}\n className=\"lb-ai-chat-composer-action\"\n variant=\"secondary\"\n aria-label={$.AI_CHAT_COMPOSER_ABORT}\n icon={<StopIcon />}\n />\n </ShortcutTooltip>\n )}\n </div>\n </div>\n </div>\n </ComposerPrimitive.Form>\n </TooltipProvider>\n );\n }\n);\n"],"names":["ComposerPrimitive.Form","ComposerPrimitive.Editor","ComposerPrimitive.Submit"],"mappings":"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"}
@@ -1,202 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var _private = require('@liveblocks/react/_private');
5
- var reactSlot = require('@radix-ui/react-slot');
6
- var react = require('react');
7
- var slate = require('slate');
8
- var slateHistory = require('slate-history');
9
- var slateReact = require('slate-react');
10
- var normalize = require('../slate/plugins/normalize.cjs');
11
- var isEmpty = require('../slate/utils/is-empty.cjs');
12
-
13
- const AI_CHAT_COMPOSER_SUBMIT_NAME = "AiChatComposerSubmit";
14
- const AI_CHAT_COMPOSER_EDITOR_NAME = "AiChatComposerEditor";
15
- const AI_CHAT_COMPOSER_FORM_NAME = "AiChatComposerForm";
16
- const AiChatComposerContext = react.createContext(null);
17
- const AiChatComposerForm = react.forwardRef(
18
- ({ onComposerSubmit, onSubmit, disabled, asChild, ...props }, forwardedRef) => {
19
- const Component = asChild ? reactSlot.Slot : "form";
20
- const formRef = react.useRef(null);
21
- const editorRef = react.useRef(null);
22
- if (editorRef.current === null) {
23
- editorRef.current = normalize.withNormalize(slateHistory.withHistory(slateReact.withReact(slate.createEditor())));
24
- }
25
- const editor = editorRef.current;
26
- const [isEditorEmpty, setIsEditorEmpty] = react.useState(true);
27
- const handleSubmit = react.useCallback(
28
- (event) => {
29
- if (disabled || isEmpty.isEmpty(editor, editor.children))
30
- return;
31
- onSubmit?.(event);
32
- if (onComposerSubmit === void 0 || event.isDefaultPrevented()) {
33
- event.preventDefault();
34
- return;
35
- }
36
- const content = editor.children.map((block) => {
37
- if ("type" in block && block.type === "paragraph") {
38
- return block.children.map((child) => {
39
- if ("text" in child) {
40
- return child.text;
41
- }
42
- return "";
43
- }).join("");
44
- }
45
- return "";
46
- }).join("\n");
47
- onComposerSubmit({ text: content }, event);
48
- if (event.isDefaultPrevented()) {
49
- return;
50
- }
51
- event.preventDefault();
52
- slate.Transforms.delete(editor, {
53
- at: {
54
- anchor: slate.Editor.start(editor, []),
55
- focus: slate.Editor.end(editor, [])
56
- }
57
- });
58
- },
59
- [disabled, editor, onSubmit, onComposerSubmit]
60
- );
61
- _private.useLayoutEffect(() => {
62
- setIsEditorEmpty(isEmpty.isEmpty(editor, editor.children));
63
- }, [editor]);
64
- const handleEditorValueChange = react.useCallback(() => {
65
- setIsEditorEmpty(isEmpty.isEmpty(editor, editor.children));
66
- }, [editor]);
67
- const requestFormSubmit = react.useCallback(() => {
68
- if (isEmpty.isEmpty(editor, editor.children))
69
- return;
70
- requestAnimationFrame(() => {
71
- if (formRef.current === null)
72
- return;
73
- if (typeof formRef.current.requestSubmit === "function") {
74
- return formRef.current.requestSubmit();
75
- }
76
- const submitter = document.createElement("input");
77
- submitter.type = "submit";
78
- submitter.hidden = true;
79
- formRef.current.appendChild(submitter);
80
- submitter.click();
81
- formRef.current.removeChild(submitter);
82
- });
83
- }, [editor]);
84
- react.useImperativeHandle(
85
- forwardedRef,
86
- () => formRef.current,
87
- []
88
- );
89
- return /* @__PURE__ */ jsxRuntime.jsx(AiChatComposerContext.Provider, {
90
- value: {
91
- editor,
92
- onEditorValueChange: handleEditorValueChange,
93
- isEditorEmpty,
94
- requestFormSubmit,
95
- disabled: disabled || false
96
- },
97
- children: /* @__PURE__ */ jsxRuntime.jsx(Component, {
98
- onSubmit: handleSubmit,
99
- ...props,
100
- ref: formRef
101
- })
102
- });
103
- }
104
- );
105
- const AiChatComposerEditor = react.forwardRef(
106
- ({ defaultValue = "", onKeyDown, disabled, autoFocus, ...props }, forwardedRef) => {
107
- const context = react.useContext(AiChatComposerContext);
108
- if (context === null) {
109
- throw new Error("AiChatComposer.Form is missing from the React tree.");
110
- }
111
- const {
112
- editor,
113
- onEditorValueChange,
114
- requestFormSubmit,
115
- disabled: isFormDisabled
116
- } = context;
117
- const handleKeyDown = react.useCallback(
118
- (event) => {
119
- onKeyDown?.(event);
120
- if (event.isDefaultPrevented())
121
- return;
122
- if (event.key === "Enter" && !event.shiftKey) {
123
- event.preventDefault();
124
- requestFormSubmit();
125
- } else if (event.key === "Enter" && event.shiftKey) {
126
- event.preventDefault();
127
- editor.insertBreak();
128
- }
129
- },
130
- [editor, onKeyDown, requestFormSubmit]
131
- );
132
- react.useImperativeHandle(
133
- forwardedRef,
134
- () => slateReact.ReactEditor.toDOMNode(editor, editor),
135
- [editor]
136
- );
137
- react.useEffect(() => {
138
- if (!autoFocus)
139
- return;
140
- try {
141
- if (!slateReact.ReactEditor.isFocused(editor)) {
142
- slate.Transforms.select(editor, slate.Editor.end(editor, []));
143
- slateReact.ReactEditor.focus(editor);
144
- }
145
- } catch {
146
- }
147
- }, [editor, autoFocus]);
148
- const initialValue = react.useMemo(() => {
149
- return defaultValue.split("\n").map((text) => ({ type: "paragraph", children: [{ text }] }));
150
- }, [defaultValue]);
151
- return /* @__PURE__ */ jsxRuntime.jsx(slateReact.Slate, {
152
- editor,
153
- initialValue,
154
- onValueChange: onEditorValueChange,
155
- children: /* @__PURE__ */ jsxRuntime.jsx(slateReact.Editable, {
156
- enterKeyHint: "send",
157
- autoCapitalize: "sentences",
158
- onKeyDown: handleKeyDown,
159
- "data-disabled": disabled || isFormDisabled || void 0,
160
- ...props,
161
- readOnly: disabled || isFormDisabled,
162
- disabled: disabled || isFormDisabled,
163
- renderPlaceholder: function({ attributes, children }) {
164
- const { opacity: _opacity, ...style } = attributes.style;
165
- return /* @__PURE__ */ jsxRuntime.jsx("span", {
166
- ...attributes,
167
- style,
168
- "data-placeholder": "",
169
- children
170
- });
171
- }
172
- })
173
- });
174
- }
175
- );
176
- const AiChatComposerSubmit = react.forwardRef(({ disabled, asChild, ...props }, forwardedRef) => {
177
- const Component = asChild ? reactSlot.Slot : "button";
178
- const context = react.useContext(AiChatComposerContext);
179
- if (context === null) {
180
- throw new Error("AiChatComposer.Form is missing from the React tree.");
181
- }
182
- const { disabled: isFormDisabled, isEditorEmpty } = context;
183
- return /* @__PURE__ */ jsxRuntime.jsx(Component, {
184
- type: "submit",
185
- ...props,
186
- ref: forwardedRef,
187
- disabled: disabled || isFormDisabled || isEditorEmpty
188
- });
189
- });
190
- if (process.env.NODE_ENV !== "production") {
191
- AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;
192
- AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;
193
- AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;
194
- }
195
-
196
- exports.AiChatComposerEditor = AiChatComposerEditor;
197
- exports.AiChatComposerForm = AiChatComposerForm;
198
- exports.AiChatComposerSubmit = AiChatComposerSubmit;
199
- exports.Editor = AiChatComposerEditor;
200
- exports.Form = AiChatComposerForm;
201
- exports.Submit = AiChatComposerSubmit;
202
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
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":";;;;;;;;;;;;AAgCA,MAAM,4BAA+B,GAAA,sBAAA,CAAA;AACrC,MAAM,4BAA+B,GAAA,sBAAA,CAAA;AACrC,MAAM,0BAA6B,GAAA,oBAAA,CAAA;AAEnC,MAAM,qBAAA,GAAwBA,oBAOpB,IAAI,CAAA,CAAA;AAeP,MAAM,kBAAqB,GAAAC,gBAAA;AAAA,EAIhC,CACE,EAAE,gBAAkB,EAAA,QAAA,EAAU,UAAU,OAAY,EAAA,GAAA,KAAA,IACpD,YACG,KAAA;AACH,IAAM,MAAA,SAAA,GAAY,UAAUC,cAAO,GAAA,MAAA,CAAA;AACnC,IAAM,MAAA,OAAA,GAAUC,aAA+B,IAAI,CAAA,CAAA;AAEnD,IAAM,MAAA,SAAA,GAAYA,aAAgC,IAAI,CAAA,CAAA;AACtD,IAAI,IAAA,SAAA,CAAU,YAAY,IAAM,EAAA;AAC9B,MAAA,SAAA,CAAU,UAAUC,uBAAc,CAAAC,wBAAA,CAAYC,qBAAUC,kBAAa,EAAC,CAAC,CAAC,CAAA,CAAA;AAAA,KAC1E;AACA,IAAA,MAAM,SAAS,SAAU,CAAA,OAAA,CAAA;AAEzB,IAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIC,eAAS,IAAI,CAAA,CAAA;AAEvD,IAAA,MAAM,YAAe,GAAAC,iBAAA;AAAA,MACnB,CAAC,KAAsC,KAAA;AACrC,QAAA,IAAI,QAAY,IAAAC,eAAA,CAAQ,MAAQ,EAAA,MAAA,CAAO,QAAQ,CAAA;AAAG,UAAA,OAAA;AAElD,QAAA,QAAA,GAAW,KAAK,CAAA,CAAA;AAEhB,QAAA,IAAI,gBAAqB,KAAA,KAAA,CAAA,IAAa,KAAM,CAAA,kBAAA,EAAsB,EAAA;AAChE,UAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,UAAA,OAAA;AAAA,SACF;AAGA,QAAA,MAAM,OAAU,GAAA,MAAA,CAAO,QACpB,CAAA,GAAA,CAAI,CAAC,KAAU,KAAA;AACd,UAAA,IAAI,MAAU,IAAA,KAAA,IAAS,KAAM,CAAA,IAAA,KAAS,WAAa,EAAA;AACjD,YAAA,OAAO,KAAM,CAAA,QAAA,CACV,GAAI,CAAA,CAAC,KAAU,KAAA;AACd,cAAA,IAAI,UAAU,KAAO,EAAA;AACnB,gBAAA,OAAO,KAAM,CAAA,IAAA,CAAA;AAAA,eACf;AACA,cAAO,OAAA,EAAA,CAAA;AAAA,aACR,CACA,CAAA,IAAA,CAAK,EAAE,CAAA,CAAA;AAAA,WACZ;AACA,UAAO,OAAA,EAAA,CAAA;AAAA,SACR,CACA,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAEZ,QAAA,gBAAA,CAAiB,EAAE,IAAA,EAAM,OAAQ,EAAA,EAAG,KAAK,CAAA,CAAA;AAEzC,QAAI,IAAA,KAAA,CAAM,oBAAsB,EAAA;AAC9B,UAAA,OAAA;AAAA,SACF;AAEA,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAGrB,QAAAC,gBAAA,CAAgB,OAAO,MAAQ,EAAA;AAAA,UAC7B,EAAI,EAAA;AAAA,YACF,MAAQ,EAAAC,YAAA,CAAY,KAAM,CAAA,MAAA,EAAQ,EAAE,CAAA;AAAA,YACpC,KAAO,EAAAA,YAAA,CAAY,GAAI,CAAA,MAAA,EAAQ,EAAE,CAAA;AAAA,WACnC;AAAA,SACD,CAAA,CAAA;AAAA,OACH;AAAA,MACA,CAAC,QAAA,EAAU,MAAQ,EAAA,QAAA,EAAU,gBAAgB,CAAA;AAAA,KAC/C,CAAA;AAEA,IAAAC,wBAAA,CAAgB,MAAM;AACpB,MAAA,gBAAA,CAAiBH,eAAQ,CAAA,MAAA,EAAQ,MAAO,CAAA,QAAQ,CAAC,CAAA,CAAA;AAAA,KACnD,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,IAAM,MAAA,uBAAA,GAA0BD,kBAAY,MAAM;AAChD,MAAA,gBAAA,CAAiBC,eAAQ,CAAA,MAAA,EAAQ,MAAO,CAAA,QAAQ,CAAC,CAAA,CAAA;AAAA,KACnD,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,IAAM,MAAA,iBAAA,GAAoBD,kBAAY,MAAM;AAC1C,MAAI,IAAAC,eAAA,CAAQ,MAAQ,EAAA,MAAA,CAAO,QAAQ,CAAA;AAAG,QAAA,OAAA;AAItC,MAAA,qBAAA,CAAsB,MAAM;AAC1B,QAAA,IAAI,QAAQ,OAAY,KAAA,IAAA;AAAM,UAAA,OAAA;AAC9B,QAAA,IAAI,OAAO,OAAA,CAAQ,OAAQ,CAAA,aAAA,KAAkB,UAAY,EAAA;AACvD,UAAO,OAAA,OAAA,CAAQ,QAAQ,aAAc,EAAA,CAAA;AAAA,SACvC;AACA,QAAM,MAAA,SAAA,GAAY,QAAS,CAAA,aAAA,CAAc,OAAO,CAAA,CAAA;AAChD,QAAA,SAAA,CAAU,IAAO,GAAA,QAAA,CAAA;AACjB,QAAA,SAAA,CAAU,MAAS,GAAA,IAAA,CAAA;AACnB,QAAQ,OAAA,CAAA,OAAA,CAAQ,YAAY,SAAS,CAAA,CAAA;AACrC,QAAA,SAAA,CAAU,KAAM,EAAA,CAAA;AAChB,QAAQ,OAAA,CAAA,OAAA,CAAQ,YAAY,SAAS,CAAA,CAAA;AAAA,OACtC,CAAA,CAAA;AAAA,KACH,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,IAAAI,yBAAA;AAAA,MACE,YAAA;AAAA,MACA,MAAM,OAAQ,CAAA,OAAA;AAAA,MACd,EAAC;AAAA,KACH,CAAA;AAEA,IACE,uBAAAC,cAAA,CAAC,sBAAsB,QAAtB,EAAA;AAAA,MACC,KAAO,EAAA;AAAA,QACL,MAAA;AAAA,QACA,mBAAqB,EAAA,uBAAA;AAAA,QACrB,aAAA;AAAA,QACA,iBAAA;AAAA,QACA,UAAU,QAAY,IAAA,KAAA;AAAA,OACxB;AAAA,MAEA,QAAC,kBAAAA,cAAA,CAAA,SAAA,EAAA;AAAA,QAAU,QAAU,EAAA,YAAA;AAAA,QAAe,GAAG,KAAA;AAAA,QAAO,GAAK,EAAA,OAAA;AAAA,OAAS,CAAA;AAAA,KAC9D,CAAA,CAAA;AAAA,GAEJ;AACF,EAAA;AAYO,MAAM,oBAAuB,GAAAd,gBAAA;AAAA,EAIlC,CACE,EAAE,YAAe,GAAA,EAAA,EAAI,WAAW,QAAU,EAAA,SAAA,EAAA,GAAc,KAAM,EAAA,EAC9D,YACG,KAAA;AACH,IAAM,MAAA,OAAA,GAAUe,iBAAW,qBAAqB,CAAA,CAAA;AAChD,IAAA,IAAI,YAAY,IAAM,EAAA;AACpB,MAAM,MAAA,IAAI,MAAM,qDAAqD,CAAA,CAAA;AAAA,KACvE;AAEA,IAAM,MAAA;AAAA,MACJ,MAAA;AAAA,MACA,mBAAA;AAAA,MACA,iBAAA;AAAA,MACA,QAAU,EAAA,cAAA;AAAA,KACR,GAAA,OAAA,CAAA;AAEJ,IAAA,MAAM,aAAgB,GAAAP,iBAAA;AAAA,MACpB,CAAC,KAAyC,KAAA;AACxC,QAAA,SAAA,GAAY,KAAK,CAAA,CAAA;AACjB,QAAA,IAAI,MAAM,kBAAmB,EAAA;AAAG,UAAA,OAAA;AAEhC,QAAA,IAAI,KAAM,CAAA,GAAA,KAAQ,OAAW,IAAA,CAAC,MAAM,QAAU,EAAA;AAC5C,UAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,UAAkB,iBAAA,EAAA,CAAA;AAAA,SACT,MAAA,IAAA,KAAA,CAAM,GAAQ,KAAA,OAAA,IAAW,MAAM,QAAU,EAAA;AAClD,UAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,UAAA,MAAA,CAAO,WAAY,EAAA,CAAA;AAAA,SACrB;AAAA,OACF;AAAA,MACA,CAAC,MAAQ,EAAA,SAAA,EAAW,iBAAiB,CAAA;AAAA,KACvC,CAAA;AAEA,IAAAK,yBAAA;AAAA,MACE,YAAA;AAAA,MACA,MAAMG,sBAAA,CAAY,SAAU,CAAA,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC1C,CAAC,MAAM,CAAA;AAAA,KACT,CAAA;AAEA,IAAAC,eAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,SAAA;AAAW,QAAA,OAAA;AAEhB,MAAI,IAAA;AACF,QAAA,IAAI,CAACD,sBAAA,CAAY,SAAU,CAAA,MAAM,CAAG,EAAA;AAClC,UAAAN,gBAAA,CAAgB,OAAO,MAAQ,EAAAC,YAAA,CAAY,IAAI,MAAQ,EAAA,EAAE,CAAC,CAAA,CAAA;AAC1D,UAAAK,sBAAA,CAAY,MAAM,MAAM,CAAA,CAAA;AAAA,SAC1B;AAAA,OACA,CAAA,MAAA;AAAA,OAEF;AAAA,KACC,EAAA,CAAC,MAAQ,EAAA,SAAS,CAAC,CAAA,CAAA;AAEtB,IAAM,MAAA,YAAA,GACJE,cAAQ,MAAM;AACZ,MAAA,OAAO,aACJ,KAAM,CAAA,IAAI,CACV,CAAA,GAAA,CAAI,CAAC,IAAU,MAAA,EAAE,IAAM,EAAA,WAAA,EAAa,UAAU,CAAC,EAAE,IAAK,EAAC,GAAI,CAAA,CAAA,CAAA;AAAA,KAChE,EAAG,CAAC,YAAY,CAAC,CAAA,CAAA;AAEnB,IAAA,uBACGJ,cAAA,CAAAK,gBAAA,EAAA;AAAA,MACC,MAAA;AAAA,MACA,YAAA;AAAA,MACA,aAAe,EAAA,mBAAA;AAAA,MAEf,QAAC,kBAAAL,cAAA,CAAAM,mBAAA,EAAA;AAAA,QACC,YAAa,EAAA,MAAA;AAAA,QACb,cAAe,EAAA,WAAA;AAAA,QACf,SAAW,EAAA,aAAA;AAAA,QACX,eAAA,EAAe,YAAY,cAAkB,IAAA,KAAA,CAAA;AAAA,QAC5C,GAAG,KAAA;AAAA,QACJ,UAAU,QAAY,IAAA,cAAA;AAAA,QACtB,UAAU,QAAY,IAAA,cAAA;AAAA,QACtB,iBAAmB,EAAA,SAAU,EAAE,UAAA,EAAY,UAAY,EAAA;AACrD,UAAA,MAAM,EAAE,OAAA,EAAS,QAAa,EAAA,GAAA,KAAA,KAAU,UAAW,CAAA,KAAA,CAAA;AACnD,UAAA,uBACGN,cAAA,CAAA,MAAA,EAAA;AAAA,YAAM,GAAG,UAAA;AAAA,YAAY,KAAA;AAAA,YAAc,kBAAiB,EAAA,EAAA;AAAA,YAClD,QAAA;AAAA,WACH,CAAA,CAAA;AAAA,SAEJ;AAAA,OACF,CAAA;AAAA,KACF,CAAA,CAAA;AAAA,GAEJ;AACF,EAAA;AAYa,MAAA,oBAAA,GAAuBd,iBAGlC,CAAC,EAAE,UAAU,OAAY,EAAA,GAAA,KAAA,IAAS,YAAiB,KAAA;AACnD,EAAM,MAAA,SAAA,GAAY,UAAUC,cAAO,GAAA,QAAA,CAAA;AACnC,EAAM,MAAA,OAAA,GAAUc,iBAAW,qBAAqB,CAAA,CAAA;AAChD,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAM,MAAA,IAAI,MAAM,qDAAqD,CAAA,CAAA;AAAA,GACvE;AAEA,EAAA,MAAM,EAAE,QAAA,EAAU,cAAgB,EAAA,aAAA,EAAkB,GAAA,OAAA,CAAA;AAEpD,EAAA,uBACGD,cAAA,CAAA,SAAA,EAAA;AAAA,IACC,IAAK,EAAA,QAAA;AAAA,IACJ,GAAG,KAAA;AAAA,IACJ,GAAK,EAAA,YAAA;AAAA,IACL,QAAA,EAAU,YAAY,cAAkB,IAAA,aAAA;AAAA,GAC1C,CAAA,CAAA;AAEJ,CAAC,EAAA;AAED,IAAI,OAAA,CAAQ,GAAI,CAAA,QAAA,KAAa,YAAc,EAAA;AACzC,EAAA,oBAAA,CAAqB,WAAc,GAAA,4BAAA,CAAA;AACnC,EAAA,kBAAA,CAAmB,WAAc,GAAA,0BAAA,CAAA;AACjC,EAAA,oBAAA,CAAqB,WAAc,GAAA,4BAAA,CAAA;AACrC;;;;;;;;;"}
@@ -1,195 +0,0 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import { useLayoutEffect } from '@liveblocks/react/_private';
3
- import { Slot } from '@radix-ui/react-slot';
4
- import { createContext, forwardRef, useRef, useState, useCallback, useImperativeHandle, useContext, useEffect, useMemo } from 'react';
5
- import { createEditor, Transforms, Editor } from 'slate';
6
- import { withHistory } from 'slate-history';
7
- import { withReact, ReactEditor, Slate, Editable } from 'slate-react';
8
- import { withNormalize } from '../slate/plugins/normalize.js';
9
- import { isEmpty } from '../slate/utils/is-empty.js';
10
-
11
- const AI_CHAT_COMPOSER_SUBMIT_NAME = "AiChatComposerSubmit";
12
- const AI_CHAT_COMPOSER_EDITOR_NAME = "AiChatComposerEditor";
13
- const AI_CHAT_COMPOSER_FORM_NAME = "AiChatComposerForm";
14
- const AiChatComposerContext = createContext(null);
15
- const AiChatComposerForm = forwardRef(
16
- ({ onComposerSubmit, onSubmit, disabled, asChild, ...props }, forwardedRef) => {
17
- const Component = asChild ? Slot : "form";
18
- const formRef = useRef(null);
19
- const editorRef = useRef(null);
20
- if (editorRef.current === null) {
21
- editorRef.current = withNormalize(withHistory(withReact(createEditor())));
22
- }
23
- const editor = editorRef.current;
24
- const [isEditorEmpty, setIsEditorEmpty] = useState(true);
25
- const handleSubmit = useCallback(
26
- (event) => {
27
- if (disabled || isEmpty(editor, editor.children))
28
- return;
29
- onSubmit?.(event);
30
- if (onComposerSubmit === void 0 || event.isDefaultPrevented()) {
31
- event.preventDefault();
32
- return;
33
- }
34
- const content = editor.children.map((block) => {
35
- if ("type" in block && block.type === "paragraph") {
36
- return block.children.map((child) => {
37
- if ("text" in child) {
38
- return child.text;
39
- }
40
- return "";
41
- }).join("");
42
- }
43
- return "";
44
- }).join("\n");
45
- onComposerSubmit({ text: content }, event);
46
- if (event.isDefaultPrevented()) {
47
- return;
48
- }
49
- event.preventDefault();
50
- Transforms.delete(editor, {
51
- at: {
52
- anchor: Editor.start(editor, []),
53
- focus: Editor.end(editor, [])
54
- }
55
- });
56
- },
57
- [disabled, editor, onSubmit, onComposerSubmit]
58
- );
59
- useLayoutEffect(() => {
60
- setIsEditorEmpty(isEmpty(editor, editor.children));
61
- }, [editor]);
62
- const handleEditorValueChange = useCallback(() => {
63
- setIsEditorEmpty(isEmpty(editor, editor.children));
64
- }, [editor]);
65
- const requestFormSubmit = useCallback(() => {
66
- if (isEmpty(editor, editor.children))
67
- return;
68
- requestAnimationFrame(() => {
69
- if (formRef.current === null)
70
- return;
71
- if (typeof formRef.current.requestSubmit === "function") {
72
- return formRef.current.requestSubmit();
73
- }
74
- const submitter = document.createElement("input");
75
- submitter.type = "submit";
76
- submitter.hidden = true;
77
- formRef.current.appendChild(submitter);
78
- submitter.click();
79
- formRef.current.removeChild(submitter);
80
- });
81
- }, [editor]);
82
- useImperativeHandle(
83
- forwardedRef,
84
- () => formRef.current,
85
- []
86
- );
87
- return /* @__PURE__ */ jsx(AiChatComposerContext.Provider, {
88
- value: {
89
- editor,
90
- onEditorValueChange: handleEditorValueChange,
91
- isEditorEmpty,
92
- requestFormSubmit,
93
- disabled: disabled || false
94
- },
95
- children: /* @__PURE__ */ jsx(Component, {
96
- onSubmit: handleSubmit,
97
- ...props,
98
- ref: formRef
99
- })
100
- });
101
- }
102
- );
103
- const AiChatComposerEditor = forwardRef(
104
- ({ defaultValue = "", onKeyDown, disabled, autoFocus, ...props }, forwardedRef) => {
105
- const context = useContext(AiChatComposerContext);
106
- if (context === null) {
107
- throw new Error("AiChatComposer.Form is missing from the React tree.");
108
- }
109
- const {
110
- editor,
111
- onEditorValueChange,
112
- requestFormSubmit,
113
- disabled: isFormDisabled
114
- } = context;
115
- const handleKeyDown = useCallback(
116
- (event) => {
117
- onKeyDown?.(event);
118
- if (event.isDefaultPrevented())
119
- return;
120
- if (event.key === "Enter" && !event.shiftKey) {
121
- event.preventDefault();
122
- requestFormSubmit();
123
- } else if (event.key === "Enter" && event.shiftKey) {
124
- event.preventDefault();
125
- editor.insertBreak();
126
- }
127
- },
128
- [editor, onKeyDown, requestFormSubmit]
129
- );
130
- useImperativeHandle(
131
- forwardedRef,
132
- () => ReactEditor.toDOMNode(editor, editor),
133
- [editor]
134
- );
135
- useEffect(() => {
136
- if (!autoFocus)
137
- return;
138
- try {
139
- if (!ReactEditor.isFocused(editor)) {
140
- Transforms.select(editor, Editor.end(editor, []));
141
- ReactEditor.focus(editor);
142
- }
143
- } catch {
144
- }
145
- }, [editor, autoFocus]);
146
- const initialValue = useMemo(() => {
147
- return defaultValue.split("\n").map((text) => ({ type: "paragraph", children: [{ text }] }));
148
- }, [defaultValue]);
149
- return /* @__PURE__ */ jsx(Slate, {
150
- editor,
151
- initialValue,
152
- onValueChange: onEditorValueChange,
153
- children: /* @__PURE__ */ jsx(Editable, {
154
- enterKeyHint: "send",
155
- autoCapitalize: "sentences",
156
- onKeyDown: handleKeyDown,
157
- "data-disabled": disabled || isFormDisabled || void 0,
158
- ...props,
159
- readOnly: disabled || isFormDisabled,
160
- disabled: disabled || isFormDisabled,
161
- renderPlaceholder: function({ attributes, children }) {
162
- const { opacity: _opacity, ...style } = attributes.style;
163
- return /* @__PURE__ */ jsx("span", {
164
- ...attributes,
165
- style,
166
- "data-placeholder": "",
167
- children
168
- });
169
- }
170
- })
171
- });
172
- }
173
- );
174
- const AiChatComposerSubmit = forwardRef(({ disabled, asChild, ...props }, forwardedRef) => {
175
- const Component = asChild ? Slot : "button";
176
- const context = useContext(AiChatComposerContext);
177
- if (context === null) {
178
- throw new Error("AiChatComposer.Form is missing from the React tree.");
179
- }
180
- const { disabled: isFormDisabled, isEditorEmpty } = context;
181
- return /* @__PURE__ */ jsx(Component, {
182
- type: "submit",
183
- ...props,
184
- ref: forwardedRef,
185
- disabled: disabled || isFormDisabled || isEditorEmpty
186
- });
187
- });
188
- if (process.env.NODE_ENV !== "production") {
189
- AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;
190
- AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;
191
- AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;
192
- }
193
-
194
- export { AiChatComposerEditor, AiChatComposerForm, AiChatComposerSubmit, AiChatComposerEditor as Editor, AiChatComposerForm as Form, AiChatComposerSubmit as Submit };
195
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
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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"}