@liveblocks/react-ui 2.25.0-aiprivatebeta5 → 2.25.0-aiprivatebeta6
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 +4 -0
- package/dist/_private/index.cjs.map +1 -1
- package/dist/_private/index.d.cts +31 -94
- package/dist/_private/index.d.ts +31 -94
- package/dist/_private/index.js +2 -0
- package/dist/_private/index.js.map +1 -1
- package/dist/components/AiChat.cjs +217 -0
- package/dist/components/AiChat.cjs.map +1 -0
- package/dist/components/AiChat.js +215 -0
- package/dist/components/AiChat.js.map +1 -0
- package/dist/components/Comment.cjs +2 -2
- package/dist/components/Comment.cjs.map +1 -1
- package/dist/components/Comment.js +1 -1
- 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/internal/AiChatAssistantMessage.cjs +83 -124
- package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.js +81 -122
- package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
- package/dist/components/internal/AiChatComposer.cjs +30 -266
- package/dist/components/internal/AiChatComposer.cjs.map +1 -1
- package/dist/components/internal/AiChatComposer.js +35 -267
- package/dist/components/internal/AiChatComposer.js.map +1 -1
- package/dist/components/internal/AiChatUserMessage.cjs +18 -168
- package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatUserMessage.js +20 -170
- package/dist/components/internal/AiChatUserMessage.js.map +1 -1
- 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 +4 -0
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +2 -0
- package/dist/icon.js.map +1 -1
- 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 +4 -0
- package/dist/icons/index.cjs.map +1 -1
- package/dist/icons/index.js +2 -0
- package/dist/icons/index.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -43
- package/dist/index.d.ts +32 -43
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/overrides.cjs +10 -10
- package/dist/overrides.cjs.map +1 -1
- package/dist/overrides.js +10 -10
- package/dist/overrides.js.map +1 -1
- package/dist/primitives/AiChatComposer/index.cjs +203 -0
- package/dist/primitives/AiChatComposer/index.cjs.map +1 -0
- package/dist/primitives/AiChatComposer/index.js +196 -0
- package/dist/primitives/AiChatComposer/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/index.cjs +2 -5
- package/dist/primitives/index.cjs.map +1 -1
- package/dist/primitives/index.d.cts +33 -62
- package/dist/primitives/index.d.ts +33 -62
- package/dist/primitives/index.js +6 -5
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/internal/{Collapsible.cjs → Collapsible/index.cjs} +23 -17
- package/dist/primitives/internal/Collapsible/index.cjs.map +1 -0
- package/dist/primitives/internal/{Collapsible.js → Collapsible/index.js} +23 -17
- package/dist/primitives/internal/Collapsible/index.js.map +1 -0
- 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/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
- package/src/styles/index.css +119 -133
- package/src/styles/utils.css +7 -2
- 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/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.map +0 -1
- package/dist/primitives/internal/Collapsible.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
|
@@ -0,0 +1,203 @@
|
|
|
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, chatId, 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
|
+
chatId,
|
|
92
|
+
editor,
|
|
93
|
+
onEditorValueChange: handleEditorValueChange,
|
|
94
|
+
isEditorEmpty,
|
|
95
|
+
requestFormSubmit,
|
|
96
|
+
disabled: disabled || false
|
|
97
|
+
},
|
|
98
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
99
|
+
onSubmit: handleSubmit,
|
|
100
|
+
...props,
|
|
101
|
+
ref: formRef
|
|
102
|
+
})
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
const AiChatComposerEditor = react.forwardRef(
|
|
107
|
+
({ defaultValue = "", onKeyDown, disabled, autoFocus, ...props }, forwardedRef) => {
|
|
108
|
+
const context = react.useContext(AiChatComposerContext);
|
|
109
|
+
if (context === null) {
|
|
110
|
+
throw new Error("AiChatComposer.Form is missing from the React tree.");
|
|
111
|
+
}
|
|
112
|
+
const {
|
|
113
|
+
editor,
|
|
114
|
+
onEditorValueChange,
|
|
115
|
+
requestFormSubmit,
|
|
116
|
+
disabled: isFormDisabled
|
|
117
|
+
} = context;
|
|
118
|
+
const handleKeyDown = react.useCallback(
|
|
119
|
+
(event) => {
|
|
120
|
+
onKeyDown?.(event);
|
|
121
|
+
if (event.isDefaultPrevented())
|
|
122
|
+
return;
|
|
123
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
requestFormSubmit();
|
|
126
|
+
} else if (event.key === "Enter" && event.shiftKey) {
|
|
127
|
+
event.preventDefault();
|
|
128
|
+
editor.insertBreak();
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
[editor, onKeyDown, requestFormSubmit]
|
|
132
|
+
);
|
|
133
|
+
react.useImperativeHandle(
|
|
134
|
+
forwardedRef,
|
|
135
|
+
() => slateReact.ReactEditor.toDOMNode(editor, editor),
|
|
136
|
+
[editor]
|
|
137
|
+
);
|
|
138
|
+
react.useEffect(() => {
|
|
139
|
+
if (!autoFocus)
|
|
140
|
+
return;
|
|
141
|
+
try {
|
|
142
|
+
if (!slateReact.ReactEditor.isFocused(editor)) {
|
|
143
|
+
slate.Transforms.select(editor, slate.Editor.end(editor, []));
|
|
144
|
+
slateReact.ReactEditor.focus(editor);
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
}, [editor, autoFocus]);
|
|
149
|
+
const initialValue = react.useMemo(() => {
|
|
150
|
+
return defaultValue.split("\n").map((text) => ({ type: "paragraph", children: [{ text }] }));
|
|
151
|
+
}, [defaultValue]);
|
|
152
|
+
return /* @__PURE__ */ jsxRuntime.jsx(slateReact.Slate, {
|
|
153
|
+
editor,
|
|
154
|
+
initialValue,
|
|
155
|
+
onValueChange: onEditorValueChange,
|
|
156
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(slateReact.Editable, {
|
|
157
|
+
enterKeyHint: "send",
|
|
158
|
+
autoCapitalize: "sentences",
|
|
159
|
+
onKeyDown: handleKeyDown,
|
|
160
|
+
"data-disabled": disabled || isFormDisabled || void 0,
|
|
161
|
+
...props,
|
|
162
|
+
readOnly: disabled || isFormDisabled,
|
|
163
|
+
disabled: disabled || isFormDisabled,
|
|
164
|
+
renderPlaceholder: function({ attributes, children }) {
|
|
165
|
+
const { opacity: _opacity, ...style } = attributes.style;
|
|
166
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
167
|
+
...attributes,
|
|
168
|
+
style,
|
|
169
|
+
"data-placeholder": "",
|
|
170
|
+
children
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
const AiChatComposerSubmit = react.forwardRef(({ disabled, asChild, ...props }, forwardedRef) => {
|
|
178
|
+
const Component = asChild ? reactSlot.Slot : "button";
|
|
179
|
+
const context = react.useContext(AiChatComposerContext);
|
|
180
|
+
if (context === null) {
|
|
181
|
+
throw new Error("AiChatComposer.Form is missing from the React tree.");
|
|
182
|
+
}
|
|
183
|
+
const { disabled: isFormDisabled, isEditorEmpty } = context;
|
|
184
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
185
|
+
type: "submit",
|
|
186
|
+
...props,
|
|
187
|
+
ref: forwardedRef,
|
|
188
|
+
disabled: disabled || isFormDisabled || isEditorEmpty
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
if (process.env.NODE_ENV !== "production") {
|
|
192
|
+
AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;
|
|
193
|
+
AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;
|
|
194
|
+
AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
exports.AiChatComposerEditor = AiChatComposerEditor;
|
|
198
|
+
exports.AiChatComposerForm = AiChatComposerForm;
|
|
199
|
+
exports.AiChatComposerSubmit = AiChatComposerSubmit;
|
|
200
|
+
exports.Editor = AiChatComposerEditor;
|
|
201
|
+
exports.Form = AiChatComposerForm;
|
|
202
|
+
exports.Submit = AiChatComposerSubmit;
|
|
203
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiChatComposer/index.tsx"],"sourcesContent":["import { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FormEvent, KeyboardEvent } from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { Descendant as SlateDescendant } from \"slate\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, ReactEditor, Slate, withReact } from \"slate-react\";\n\nimport type { AiComposerEditor } from \"../../types\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport type {\n AiChatComposerEditorProps,\n AiChatComposerFormProps,\n AiChatComposerSubmitProps,\n} from \"./types\";\n\nconst AI_CHAT_COMPOSER_SUBMIT_NAME = \"AiChatComposerSubmit\";\nconst AI_CHAT_COMPOSER_EDITOR_NAME = \"AiChatComposerEditor\";\nconst AI_CHAT_COMPOSER_FORM_NAME = \"AiChatComposerForm\";\n\nconst AiChatComposerContext = createContext<{\n chatId: string;\n\n editor: SlateEditor;\n onEditorValueChange: (value: SlateDescendant[]) => void;\n isEditorEmpty: boolean;\n\n requestFormSubmit: () => void;\n disabled: boolean;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Surrounds the chat composer's content and handles submissions.\n *\n * @example\n * <AiChatComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiChatComposer.Editor />\n * <AiChatComposer.Submit />\n * </AiChatComposer.Form>\n */\nexport const AiChatComposerForm = forwardRef<\n HTMLFormElement,\n AiChatComposerFormProps\n>(\n (\n { onComposerSubmit, onSubmit, disabled, chatId, asChild, ...props },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const formRef = useRef<HTMLFormElement | null>(null);\n\n const editorRef = useRef<AiComposerEditor | null>(null);\n if (editorRef.current === null) {\n editorRef.current = withNormalize(withHistory(withReact(createEditor())));\n }\n const editor = editorRef.current;\n\n const [isEditorEmpty, setIsEditorEmpty] = useState(true);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled || isEmpty(editor, editor.children)) return;\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n onComposerSubmit({ text: content }, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n\n // Clear the editor after dispatching the message.\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n },\n [disabled, editor, onSubmit, onComposerSubmit]\n );\n\n useLayoutEffect(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const requestFormSubmit = useCallback(() => {\n if (isEmpty(editor, editor.children)) return;\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current === null) return;\n if (typeof formRef.current.requestSubmit === \"function\") {\n return formRef.current.requestSubmit();\n }\n const submitter = document.createElement(\"input\");\n submitter.type = \"submit\";\n submitter.hidden = true;\n formRef.current.appendChild(submitter);\n submitter.click();\n formRef.current.removeChild(submitter);\n });\n }, [editor]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiChatComposerContext.Provider\n value={{\n chatId,\n editor,\n onEditorValueChange: handleEditorValueChange,\n isEditorEmpty,\n requestFormSubmit,\n disabled: disabled || false,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiChatComposerContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Displays the chat composer's editor.\n *\n * @example\n * <AiChatComposer.Editor placeholder=\"Write a message…\" />\n */\nexport const AiChatComposerEditor = forwardRef<\n HTMLDivElement,\n AiChatComposerEditorProps\n>(\n (\n { defaultValue = \"\", onKeyDown, disabled, autoFocus, ...props },\n forwardedRef\n ) => {\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const {\n editor,\n onEditorValueChange,\n requestFormSubmit,\n disabled: isFormDisabled,\n } = context;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n requestFormSubmit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n }\n },\n [editor, onKeyDown, requestFormSubmit]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n useEffect(() => {\n if (!autoFocus) return;\n\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM node no longer exists. This action doesn't make sense on an unmounted editor so we can safely ignore it.\n }\n }, [editor, autoFocus]);\n\n const initialValue: { type: \"paragraph\"; children: { text: string }[] }[] =\n useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n onKeyDown={handleKeyDown}\n data-disabled={disabled || isFormDisabled || undefined}\n {...props}\n readOnly={disabled || isFormDisabled}\n disabled={disabled || isFormDisabled}\n renderPlaceholder={function ({ attributes, children }) {\n const { opacity: _opacity, ...style } = attributes.style;\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n }}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit a chat message.\n *\n * @example\n * <AiChatComposer.Submit>Send</AiChatComposer.Submit>\n */\nexport const AiChatComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiChatComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const { disabled: isFormDisabled, isEditorEmpty } = context;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || isFormDisabled || isEditorEmpty}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;\n AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;\n AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiChatComposer.*\nexport {\n AiChatComposerEditor as Editor,\n AiChatComposerForm as Form,\n AiChatComposerSubmit as Submit,\n};\n"],"names":["createContext","forwardRef","Slot","useRef","withNormalize","withHistory","withReact","createEditor","useState","useCallback","isEmpty","SlateTransforms","SlateEditor","useLayoutEffect","useImperativeHandle","jsx","useContext","ReactEditor","useEffect","useMemo","Slate","Editable"],"mappings":"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"}
|
|
@@ -0,0 +1,196 @@
|
|
|
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, chatId, 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
|
+
chatId,
|
|
90
|
+
editor,
|
|
91
|
+
onEditorValueChange: handleEditorValueChange,
|
|
92
|
+
isEditorEmpty,
|
|
93
|
+
requestFormSubmit,
|
|
94
|
+
disabled: disabled || false
|
|
95
|
+
},
|
|
96
|
+
children: /* @__PURE__ */ jsx(Component, {
|
|
97
|
+
onSubmit: handleSubmit,
|
|
98
|
+
...props,
|
|
99
|
+
ref: formRef
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
const AiChatComposerEditor = forwardRef(
|
|
105
|
+
({ defaultValue = "", onKeyDown, disabled, autoFocus, ...props }, forwardedRef) => {
|
|
106
|
+
const context = useContext(AiChatComposerContext);
|
|
107
|
+
if (context === null) {
|
|
108
|
+
throw new Error("AiChatComposer.Form is missing from the React tree.");
|
|
109
|
+
}
|
|
110
|
+
const {
|
|
111
|
+
editor,
|
|
112
|
+
onEditorValueChange,
|
|
113
|
+
requestFormSubmit,
|
|
114
|
+
disabled: isFormDisabled
|
|
115
|
+
} = context;
|
|
116
|
+
const handleKeyDown = useCallback(
|
|
117
|
+
(event) => {
|
|
118
|
+
onKeyDown?.(event);
|
|
119
|
+
if (event.isDefaultPrevented())
|
|
120
|
+
return;
|
|
121
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
requestFormSubmit();
|
|
124
|
+
} else if (event.key === "Enter" && event.shiftKey) {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
editor.insertBreak();
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
[editor, onKeyDown, requestFormSubmit]
|
|
130
|
+
);
|
|
131
|
+
useImperativeHandle(
|
|
132
|
+
forwardedRef,
|
|
133
|
+
() => ReactEditor.toDOMNode(editor, editor),
|
|
134
|
+
[editor]
|
|
135
|
+
);
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
if (!autoFocus)
|
|
138
|
+
return;
|
|
139
|
+
try {
|
|
140
|
+
if (!ReactEditor.isFocused(editor)) {
|
|
141
|
+
Transforms.select(editor, Editor.end(editor, []));
|
|
142
|
+
ReactEditor.focus(editor);
|
|
143
|
+
}
|
|
144
|
+
} catch {
|
|
145
|
+
}
|
|
146
|
+
}, [editor, autoFocus]);
|
|
147
|
+
const initialValue = useMemo(() => {
|
|
148
|
+
return defaultValue.split("\n").map((text) => ({ type: "paragraph", children: [{ text }] }));
|
|
149
|
+
}, [defaultValue]);
|
|
150
|
+
return /* @__PURE__ */ jsx(Slate, {
|
|
151
|
+
editor,
|
|
152
|
+
initialValue,
|
|
153
|
+
onValueChange: onEditorValueChange,
|
|
154
|
+
children: /* @__PURE__ */ jsx(Editable, {
|
|
155
|
+
enterKeyHint: "send",
|
|
156
|
+
autoCapitalize: "sentences",
|
|
157
|
+
onKeyDown: handleKeyDown,
|
|
158
|
+
"data-disabled": disabled || isFormDisabled || void 0,
|
|
159
|
+
...props,
|
|
160
|
+
readOnly: disabled || isFormDisabled,
|
|
161
|
+
disabled: disabled || isFormDisabled,
|
|
162
|
+
renderPlaceholder: function({ attributes, children }) {
|
|
163
|
+
const { opacity: _opacity, ...style } = attributes.style;
|
|
164
|
+
return /* @__PURE__ */ jsx("span", {
|
|
165
|
+
...attributes,
|
|
166
|
+
style,
|
|
167
|
+
"data-placeholder": "",
|
|
168
|
+
children
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
const AiChatComposerSubmit = forwardRef(({ disabled, asChild, ...props }, forwardedRef) => {
|
|
176
|
+
const Component = asChild ? Slot : "button";
|
|
177
|
+
const context = useContext(AiChatComposerContext);
|
|
178
|
+
if (context === null) {
|
|
179
|
+
throw new Error("AiChatComposer.Form is missing from the React tree.");
|
|
180
|
+
}
|
|
181
|
+
const { disabled: isFormDisabled, isEditorEmpty } = context;
|
|
182
|
+
return /* @__PURE__ */ jsx(Component, {
|
|
183
|
+
type: "submit",
|
|
184
|
+
...props,
|
|
185
|
+
ref: forwardedRef,
|
|
186
|
+
disabled: disabled || isFormDisabled || isEditorEmpty
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
if (process.env.NODE_ENV !== "production") {
|
|
190
|
+
AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;
|
|
191
|
+
AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;
|
|
192
|
+
AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export { AiChatComposerEditor, AiChatComposerForm, AiChatComposerSubmit, AiChatComposerEditor as Editor, AiChatComposerForm as Form, AiChatComposerSubmit as Submit };
|
|
196
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/AiChatComposer/index.tsx"],"sourcesContent":["import { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport type { FormEvent, KeyboardEvent } from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { Descendant as SlateDescendant } from \"slate\";\nimport {\n createEditor,\n Editor as SlateEditor,\n Transforms as SlateTransforms,\n} from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, ReactEditor, Slate, withReact } from \"slate-react\";\n\nimport type { AiComposerEditor } from \"../../types\";\nimport { withNormalize } from \"../slate/plugins/normalize\";\nimport { isEmpty } from \"../slate/utils/is-empty\";\nimport type {\n AiChatComposerEditorProps,\n AiChatComposerFormProps,\n AiChatComposerSubmitProps,\n} from \"./types\";\n\nconst AI_CHAT_COMPOSER_SUBMIT_NAME = \"AiChatComposerSubmit\";\nconst AI_CHAT_COMPOSER_EDITOR_NAME = \"AiChatComposerEditor\";\nconst AI_CHAT_COMPOSER_FORM_NAME = \"AiChatComposerForm\";\n\nconst AiChatComposerContext = createContext<{\n chatId: string;\n\n editor: SlateEditor;\n onEditorValueChange: (value: SlateDescendant[]) => void;\n isEditorEmpty: boolean;\n\n requestFormSubmit: () => void;\n disabled: boolean;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Form\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Surrounds the chat composer's content and handles submissions.\n *\n * @example\n * <AiChatComposer.Form onComposerSubmit={({ text }) => {}}>\n *\t <AiChatComposer.Editor />\n * <AiChatComposer.Submit />\n * </AiChatComposer.Form>\n */\nexport const AiChatComposerForm = forwardRef<\n HTMLFormElement,\n AiChatComposerFormProps\n>(\n (\n { onComposerSubmit, onSubmit, disabled, chatId, asChild, ...props },\n forwardedRef\n ) => {\n const Component = asChild ? Slot : \"form\";\n const formRef = useRef<HTMLFormElement | null>(null);\n\n const editorRef = useRef<AiComposerEditor | null>(null);\n if (editorRef.current === null) {\n editorRef.current = withNormalize(withHistory(withReact(createEditor())));\n }\n const editor = editorRef.current;\n\n const [isEditorEmpty, setIsEditorEmpty] = useState(true);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n if (disabled || isEmpty(editor, editor.children)) return;\n\n onSubmit?.(event);\n\n if (onComposerSubmit === undefined || event.isDefaultPrevented()) {\n event.preventDefault();\n return;\n }\n\n // Extract the text content from the editor.\n const content = editor.children\n .map((block) => {\n if (\"type\" in block && block.type === \"paragraph\") {\n return block.children\n .map((child) => {\n if (\"text\" in child) {\n return child.text;\n }\n return \"\";\n })\n .join(\"\");\n }\n return \"\";\n })\n .join(\"\\n\");\n\n onComposerSubmit({ text: content }, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n event.preventDefault();\n\n // Clear the editor after dispatching the message.\n SlateTransforms.delete(editor, {\n at: {\n anchor: SlateEditor.start(editor, []),\n focus: SlateEditor.end(editor, []),\n },\n });\n },\n [disabled, editor, onSubmit, onComposerSubmit]\n );\n\n useLayoutEffect(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const handleEditorValueChange = useCallback(() => {\n setIsEditorEmpty(isEmpty(editor, editor.children));\n }, [editor]);\n\n const requestFormSubmit = useCallback(() => {\n if (isEmpty(editor, editor.children)) return;\n\n // We need to wait for the next frame in some cases like when composing diacritics,\n // we want any native handling to be done first while still being handled on `keydown`.\n requestAnimationFrame(() => {\n if (formRef.current === null) return;\n if (typeof formRef.current.requestSubmit === \"function\") {\n return formRef.current.requestSubmit();\n }\n const submitter = document.createElement(\"input\");\n submitter.type = \"submit\";\n submitter.hidden = true;\n formRef.current.appendChild(submitter);\n submitter.click();\n formRef.current.removeChild(submitter);\n });\n }, [editor]);\n\n useImperativeHandle<HTMLFormElement | null, HTMLFormElement | null>(\n forwardedRef,\n () => formRef.current,\n []\n );\n\n return (\n <AiChatComposerContext.Provider\n value={{\n chatId,\n editor,\n onEditorValueChange: handleEditorValueChange,\n isEditorEmpty,\n requestFormSubmit,\n disabled: disabled || false,\n }}\n >\n <Component onSubmit={handleSubmit} {...props} ref={formRef} />\n </AiChatComposerContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Editor\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Displays the chat composer's editor.\n *\n * @example\n * <AiChatComposer.Editor placeholder=\"Write a message…\" />\n */\nexport const AiChatComposerEditor = forwardRef<\n HTMLDivElement,\n AiChatComposerEditorProps\n>(\n (\n { defaultValue = \"\", onKeyDown, disabled, autoFocus, ...props },\n forwardedRef\n ) => {\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const {\n editor,\n onEditorValueChange,\n requestFormSubmit,\n disabled: isFormDisabled,\n } = context;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n requestFormSubmit();\n } else if (event.key === \"Enter\" && event.shiftKey) {\n event.preventDefault();\n editor.insertBreak();\n }\n },\n [editor, onKeyDown, requestFormSubmit]\n );\n\n useImperativeHandle(\n forwardedRef,\n () => ReactEditor.toDOMNode(editor, editor) as HTMLDivElement,\n [editor]\n );\n\n useEffect(() => {\n if (!autoFocus) return;\n\n try {\n if (!ReactEditor.isFocused(editor)) {\n SlateTransforms.select(editor, SlateEditor.end(editor, []));\n ReactEditor.focus(editor);\n }\n } catch {\n // Slate's DOM-specific methods will throw if the editor's DOM node no longer exists. This action doesn't make sense on an unmounted editor so we can safely ignore it.\n }\n }, [editor, autoFocus]);\n\n const initialValue: { type: \"paragraph\"; children: { text: string }[] }[] =\n useMemo(() => {\n return defaultValue\n .split(\"\\n\")\n .map((text) => ({ type: \"paragraph\", children: [{ text }] }));\n }, [defaultValue]);\n\n return (\n <Slate\n editor={editor}\n initialValue={initialValue}\n onValueChange={onEditorValueChange}\n >\n <Editable\n enterKeyHint=\"send\"\n autoCapitalize=\"sentences\"\n onKeyDown={handleKeyDown}\n data-disabled={disabled || isFormDisabled || undefined}\n {...props}\n readOnly={disabled || isFormDisabled}\n disabled={disabled || isFormDisabled}\n renderPlaceholder={function ({ attributes, children }) {\n const { opacity: _opacity, ...style } = attributes.style;\n return (\n <span {...attributes} style={style} data-placeholder=\"\">\n {children}\n </span>\n );\n }}\n />\n </Slate>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Submit\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * A button to submit a chat message.\n *\n * @example\n * <AiChatComposer.Submit>Send</AiChatComposer.Submit>\n */\nexport const AiChatComposerSubmit = forwardRef<\n HTMLButtonElement,\n AiChatComposerSubmitProps\n>(({ disabled, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(AiChatComposerContext);\n if (context === null) {\n throw new Error(\"AiChatComposer.Form is missing from the React tree.\");\n }\n\n const { disabled: isFormDisabled, isEditorEmpty } = context;\n\n return (\n <Component\n type=\"submit\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || isFormDisabled || isEditorEmpty}\n />\n );\n});\n\nif (process.env.NODE_ENV !== \"production\") {\n AiChatComposerEditor.displayName = AI_CHAT_COMPOSER_EDITOR_NAME;\n AiChatComposerForm.displayName = AI_CHAT_COMPOSER_FORM_NAME;\n AiChatComposerSubmit.displayName = AI_CHAT_COMPOSER_SUBMIT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiChatComposer.*\nexport {\n AiChatComposerEditor as Editor,\n AiChatComposerForm as Form,\n AiChatComposerSubmit as Submit,\n};\n"],"names":["SlateTransforms","SlateEditor"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var reactSlot = require('@radix-ui/react-slot');
|
|
5
5
|
var react = require('react');
|
|
6
|
-
var
|
|
6
|
+
var constants = require('../../constants.cjs');
|
|
7
7
|
var utils = require('./utils.cjs');
|
|
8
8
|
|
|
9
9
|
const COMMENT_MENTION_NAME = "CommentMention";
|
|
@@ -35,7 +35,7 @@ const defaultBodyComponents = {
|
|
|
35
35
|
Mention: ({ userId }) => {
|
|
36
36
|
return /* @__PURE__ */ jsxRuntime.jsxs(CommentMention, {
|
|
37
37
|
children: [
|
|
38
|
-
|
|
38
|
+
constants.MENTION_CHARACTER,
|
|
39
39
|
userId
|
|
40
40
|
]
|
|
41
41
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/Comment/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport type { ReactNode } from \"react\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { MENTION_CHARACTER } from \"../../
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/Comment/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport type { ReactNode } from \"react\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { MENTION_CHARACTER } from \"../../constants\";\nimport type {\n CommentBodyComponents,\n CommentBodyProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"./types\";\nimport {\n isCommentBodyLink,\n isCommentBodyMention,\n toAbsoluteUrl,\n} from \"./utils\";\n\nconst COMMENT_MENTION_NAME = \"CommentMention\";\nconst COMMENT_BODY_NAME = \"CommentBody\";\nconst COMMENT_LINK_NAME = \"CommentLink\";\n\n/**\n * Displays mentions within `Comment.Body`.\n *\n * @example\n * <Comment.Mention>@{userId}</Comment.Mention>\n */\nconst CommentMention = forwardRef<HTMLSpanElement, CommentMentionProps>(\n ({ children, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"span\";\n\n return (\n <Component {...props} ref={forwardedRef}>\n {children}\n </Component>\n );\n }\n);\n\n/**\n * Displays links within `Comment.Body`.\n *\n * @example\n * <Comment.Link href={href}>{children}</Comment.Link>\n */\nconst CommentLink = forwardRef<HTMLAnchorElement, CommentLinkProps>(\n ({ children, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"a\";\n\n return (\n <Component\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n {...props}\n ref={forwardedRef}\n >\n {children}\n </Component>\n );\n }\n);\n\nconst defaultBodyComponents: CommentBodyComponents = {\n Mention: ({ userId }) => {\n return (\n <CommentMention>\n {MENTION_CHARACTER}\n {userId}\n </CommentMention>\n );\n },\n Link: ({ href, children }) => {\n return <CommentLink href={href}>{children}</CommentLink>;\n },\n};\n\n/**\n * Displays a comment body.\n *\n * @example\n * <Comment.Body body={comment.body} />\n */\nconst CommentBody = forwardRef<HTMLDivElement, CommentBodyProps>(\n ({ body, components, style, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const { Mention, Link } = useMemo(\n () => ({ ...defaultBodyComponents, ...components }),\n [components]\n );\n\n if (!body || !body?.content) {\n return null;\n }\n\n return (\n <Component\n {...props}\n style={{ whiteSpace: \"break-spaces\", ...style }}\n ref={forwardedRef}\n >\n {body.content.map((block, index) => {\n switch (block.type) {\n case \"paragraph\":\n return (\n <p key={index} style={{ minHeight: \"1lh\" }}>\n {block.children.map((inline, index) => {\n if (isCommentBodyMention(inline)) {\n return inline.id ? (\n <Mention userId={inline.id} key={index} />\n ) : null;\n }\n\n if (isCommentBodyLink(inline)) {\n const href = toAbsoluteUrl(inline.url) ?? inline.url;\n\n return (\n <Link href={href} key={index}>\n {inline.text ?? inline.url}\n </Link>\n );\n }\n\n // <code><s><em><strong>text</strong></s></em></code>\n let children: ReactNode = inline.text;\n\n if (inline.bold) {\n children = <strong key={index}>{children}</strong>;\n }\n\n if (inline.italic) {\n children = <em key={index}>{children}</em>;\n }\n\n if (inline.strikethrough) {\n children = <s key={index}>{children}</s>;\n }\n\n if (inline.code) {\n children = <code key={index}>{children}</code>;\n }\n\n return <span key={index}>{children}</span>;\n })}\n </p>\n );\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n CommentBody.displayName = COMMENT_BODY_NAME;\n CommentMention.displayName = COMMENT_MENTION_NAME;\n CommentLink.displayName = COMMENT_LINK_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as Comment.*\nexport { CommentBody as Body, CommentLink as Link, CommentMention as Mention };\n"],"names":["forwardRef","Slot","jsx","jsxs","MENTION_CHARACTER","useMemo","index","isCommentBodyMention","isCommentBodyLink","toAbsoluteUrl"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { Slot } from '@radix-ui/react-slot';
|
|
3
3
|
import { forwardRef, useMemo } from 'react';
|
|
4
|
-
import { MENTION_CHARACTER } from '../../
|
|
4
|
+
import { MENTION_CHARACTER } from '../../constants.js';
|
|
5
5
|
import { isCommentBodyMention, isCommentBodyLink, toAbsoluteUrl } from './utils.js';
|
|
6
6
|
|
|
7
7
|
const COMMENT_MENTION_NAME = "CommentMention";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/primitives/Comment/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport type { ReactNode } from \"react\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { MENTION_CHARACTER } from \"../../
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/Comment/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport type { ReactNode } from \"react\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { MENTION_CHARACTER } from \"../../constants\";\nimport type {\n CommentBodyComponents,\n CommentBodyProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"./types\";\nimport {\n isCommentBodyLink,\n isCommentBodyMention,\n toAbsoluteUrl,\n} from \"./utils\";\n\nconst COMMENT_MENTION_NAME = \"CommentMention\";\nconst COMMENT_BODY_NAME = \"CommentBody\";\nconst COMMENT_LINK_NAME = \"CommentLink\";\n\n/**\n * Displays mentions within `Comment.Body`.\n *\n * @example\n * <Comment.Mention>@{userId}</Comment.Mention>\n */\nconst CommentMention = forwardRef<HTMLSpanElement, CommentMentionProps>(\n ({ children, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"span\";\n\n return (\n <Component {...props} ref={forwardedRef}>\n {children}\n </Component>\n );\n }\n);\n\n/**\n * Displays links within `Comment.Body`.\n *\n * @example\n * <Comment.Link href={href}>{children}</Comment.Link>\n */\nconst CommentLink = forwardRef<HTMLAnchorElement, CommentLinkProps>(\n ({ children, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"a\";\n\n return (\n <Component\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\"\n {...props}\n ref={forwardedRef}\n >\n {children}\n </Component>\n );\n }\n);\n\nconst defaultBodyComponents: CommentBodyComponents = {\n Mention: ({ userId }) => {\n return (\n <CommentMention>\n {MENTION_CHARACTER}\n {userId}\n </CommentMention>\n );\n },\n Link: ({ href, children }) => {\n return <CommentLink href={href}>{children}</CommentLink>;\n },\n};\n\n/**\n * Displays a comment body.\n *\n * @example\n * <Comment.Body body={comment.body} />\n */\nconst CommentBody = forwardRef<HTMLDivElement, CommentBodyProps>(\n ({ body, components, style, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const { Mention, Link } = useMemo(\n () => ({ ...defaultBodyComponents, ...components }),\n [components]\n );\n\n if (!body || !body?.content) {\n return null;\n }\n\n return (\n <Component\n {...props}\n style={{ whiteSpace: \"break-spaces\", ...style }}\n ref={forwardedRef}\n >\n {body.content.map((block, index) => {\n switch (block.type) {\n case \"paragraph\":\n return (\n <p key={index} style={{ minHeight: \"1lh\" }}>\n {block.children.map((inline, index) => {\n if (isCommentBodyMention(inline)) {\n return inline.id ? (\n <Mention userId={inline.id} key={index} />\n ) : null;\n }\n\n if (isCommentBodyLink(inline)) {\n const href = toAbsoluteUrl(inline.url) ?? inline.url;\n\n return (\n <Link href={href} key={index}>\n {inline.text ?? inline.url}\n </Link>\n );\n }\n\n // <code><s><em><strong>text</strong></s></em></code>\n let children: ReactNode = inline.text;\n\n if (inline.bold) {\n children = <strong key={index}>{children}</strong>;\n }\n\n if (inline.italic) {\n children = <em key={index}>{children}</em>;\n }\n\n if (inline.strikethrough) {\n children = <s key={index}>{children}</s>;\n }\n\n if (inline.code) {\n children = <code key={index}>{children}</code>;\n }\n\n return <span key={index}>{children}</span>;\n })}\n </p>\n );\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n CommentBody.displayName = COMMENT_BODY_NAME;\n CommentMention.displayName = COMMENT_MENTION_NAME;\n CommentLink.displayName = COMMENT_LINK_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as Comment.*\nexport { CommentBody as Body, CommentLink as Link, CommentMention as Mention };\n"],"names":["index"],"mappings":"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"}
|