@mieweb/ui 0.6.1-dev.148 → 0.6.1-dev.150
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/brands/index.cjs +22 -22
- package/dist/brands/index.js +5 -5
- package/dist/chunk-2T4JU5RH.cjs +1156 -0
- package/dist/chunk-2T4JU5RH.cjs.map +1 -0
- package/dist/chunk-3SSXDWD7.js +363 -0
- package/dist/chunk-3SSXDWD7.js.map +1 -0
- package/dist/{chunk-MARLXJQO.cjs → chunk-6R2ZPDN7.cjs} +7 -7
- package/dist/{chunk-MARLXJQO.cjs.map → chunk-6R2ZPDN7.cjs.map} +1 -1
- package/dist/{chunk-WHUD3XHR.cjs → chunk-7PA26KBF.cjs} +15 -3
- package/dist/chunk-7PA26KBF.cjs.map +1 -0
- package/dist/chunk-ASLZUFH4.js +1967 -0
- package/dist/chunk-ASLZUFH4.js.map +1 -0
- package/dist/chunk-FADQVM4M.cjs +2017 -0
- package/dist/chunk-FADQVM4M.cjs.map +1 -0
- package/dist/{chunk-DFT7TYKL.cjs → chunk-H4T5T65N.cjs} +6 -3
- package/dist/chunk-H4T5T65N.cjs.map +1 -0
- package/dist/chunk-I6CY5C6A.js +12 -0
- package/dist/chunk-I6CY5C6A.js.map +1 -0
- package/dist/chunk-JFLC7SHM.cjs +35 -0
- package/dist/chunk-JFLC7SHM.cjs.map +1 -0
- package/dist/chunk-LZPPH5BW.cjs +368 -0
- package/dist/chunk-LZPPH5BW.cjs.map +1 -0
- package/dist/{chunk-3OHVUXDG.js → chunk-M7BLVBL4.js} +6 -3
- package/dist/chunk-M7BLVBL4.js.map +1 -0
- package/dist/chunk-PM2I3QKM.cjs +1419 -0
- package/dist/chunk-PM2I3QKM.cjs.map +1 -0
- package/dist/{chunk-TW6DXMSD.js → chunk-R6PBBPU3.js} +2 -2
- package/dist/{chunk-TW6DXMSD.js.map → chunk-R6PBBPU3.js.map} +1 -1
- package/dist/{chunk-33PO3J4O.js → chunk-RXY5SD3O.js} +15 -3
- package/dist/chunk-RXY5SD3O.js.map +1 -0
- package/dist/{chunk-AEGYWRSL.js → chunk-TXYTMU3K.js} +3 -3
- package/dist/{chunk-AEGYWRSL.js.map → chunk-TXYTMU3K.js.map} +1 -1
- package/dist/chunk-UHPQYBXQ.js +1124 -0
- package/dist/chunk-UHPQYBXQ.js.map +1 -0
- package/dist/chunk-XQE26F3G.js +1383 -0
- package/dist/chunk-XQE26F3G.js.map +1 -0
- package/dist/{chunk-26YNFCOC.cjs → chunk-Z6NRP4Z5.cjs} +2 -2
- package/dist/{chunk-26YNFCOC.cjs.map → chunk-Z6NRP4Z5.cjs.map} +1 -1
- package/dist/components/Dropdown/index.cjs +7 -7
- package/dist/components/Dropdown/index.d.cts +1 -1
- package/dist/components/Dropdown/index.d.ts +1 -1
- package/dist/components/Dropdown/index.js +1 -1
- package/dist/components/RichTextEditor/index.cjs +5 -5
- package/dist/components/RichTextEditor/index.js +2 -2
- package/dist/components/SuperChat/index.cjs +1319 -0
- package/dist/components/SuperChat/index.cjs.map +1 -0
- package/dist/components/SuperChat/index.d.cts +189 -0
- package/dist/components/SuperChat/index.d.ts +189 -0
- package/dist/components/SuperChat/index.js +1282 -0
- package/dist/components/SuperChat/index.js.map +1 -0
- package/dist/components/SuperChat/plugins/index.cjs +1221 -0
- package/dist/components/SuperChat/plugins/index.cjs.map +1 -0
- package/dist/components/SuperChat/plugins/index.d.cts +253 -0
- package/dist/components/SuperChat/plugins/index.d.ts +253 -0
- package/dist/components/SuperChat/plugins/index.js +1181 -0
- package/dist/components/SuperChat/plugins/index.js.map +1 -0
- package/dist/datavis.cjs +18 -362
- package/dist/datavis.cjs.map +1 -1
- package/dist/datavis.js +1 -361
- package/dist/datavis.js.map +1 -1
- package/dist/index.cjs +1297 -5412
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -240
- package/dist/index.d.ts +44 -240
- package/dist/index.js +759 -5037
- package/dist/index.js.map +1 -1
- package/dist/nitroTableGrid-FWRCDE4N.js +22 -0
- package/dist/nitroTableGrid-FWRCDE4N.js.map +1 -0
- package/dist/nitroTableGrid-IY75TQJ2.cjs +44 -0
- package/dist/nitroTableGrid-IY75TQJ2.cjs.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/dist/types-BFFgW6qy.d.ts +240 -0
- package/dist/types-BzeY_kYO.d.cts +242 -0
- package/dist/types-BzeY_kYO.d.ts +242 -0
- package/dist/types-CRt5IPNL.d.cts +240 -0
- package/package.json +41 -4
- package/dist/chunk-33PO3J4O.js.map +0 -1
- package/dist/chunk-3OHVUXDG.js.map +0 -1
- package/dist/chunk-DFT7TYKL.cjs.map +0 -1
- package/dist/chunk-WHUD3XHR.cjs.map +0 -1
|
@@ -0,0 +1,1282 @@
|
|
|
1
|
+
import { TextRenderContext } from '../../chunk-I6CY5C6A.js';
|
|
2
|
+
export { TextRenderContext, useTextRenderContext } from '../../chunk-I6CY5C6A.js';
|
|
3
|
+
import { ChatBubble, MCPToolCallDisplay, AITypingIndicator, SparklesIcon, CloseIcon } from '../../chunk-XQE26F3G.js';
|
|
4
|
+
import { MessageComposer } from '../../chunk-UHPQYBXQ.js';
|
|
5
|
+
import { Dropdown, DropdownItem } from '../../chunk-M7BLVBL4.js';
|
|
6
|
+
import '../../chunk-PVUDXJAI.js';
|
|
7
|
+
import { Avatar } from '../../chunk-WO5CAOAN.js';
|
|
8
|
+
import { Badge } from '../../chunk-DCER2QQB.js';
|
|
9
|
+
import '../../chunk-T4ME7QCT.js';
|
|
10
|
+
import '../../chunk-OKBR6PX4.js';
|
|
11
|
+
import { cn } from '../../chunk-F3SOEIN2.js';
|
|
12
|
+
import * as React4 from 'react';
|
|
13
|
+
import Markdown, { defaultUrlTransform } from 'react-markdown';
|
|
14
|
+
import remarkGfm from 'remark-gfm';
|
|
15
|
+
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
|
16
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
17
|
+
import { cva } from 'class-variance-authority';
|
|
18
|
+
import { Pencil, Check, Clipboard } from 'lucide-react';
|
|
19
|
+
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
20
|
+
|
|
21
|
+
function remarkPreserveLineBreaks() {
|
|
22
|
+
const splitNode = (node) => {
|
|
23
|
+
if (!node.children) return;
|
|
24
|
+
const next = [];
|
|
25
|
+
for (const child of node.children) {
|
|
26
|
+
if (child.type === "text" && child.value && child.value.includes("\n")) {
|
|
27
|
+
const segments = child.value.split("\n");
|
|
28
|
+
segments.forEach((segment, i) => {
|
|
29
|
+
if (i > 0) next.push({ type: "break" });
|
|
30
|
+
if (segment) next.push({ type: "text", value: segment });
|
|
31
|
+
});
|
|
32
|
+
} else {
|
|
33
|
+
splitNode(child);
|
|
34
|
+
next.push(child);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
node.children = next;
|
|
38
|
+
};
|
|
39
|
+
return (tree) => splitNode(tree);
|
|
40
|
+
}
|
|
41
|
+
function baseSanitizeSchema() {
|
|
42
|
+
const schema = JSON.parse(JSON.stringify(defaultSchema));
|
|
43
|
+
const attributes = schema.attributes ?? {};
|
|
44
|
+
const allowClass = (tag) => {
|
|
45
|
+
const existing = attributes[tag] ?? [];
|
|
46
|
+
const withoutClass = existing.filter(
|
|
47
|
+
(a) => !(Array.isArray(a) && a[0] === "className")
|
|
48
|
+
);
|
|
49
|
+
attributes[tag] = [...withoutClass, "className"];
|
|
50
|
+
};
|
|
51
|
+
allowClass("code");
|
|
52
|
+
allowClass("pre");
|
|
53
|
+
allowClass("span");
|
|
54
|
+
allowClass("div");
|
|
55
|
+
schema.attributes = attributes;
|
|
56
|
+
return schema;
|
|
57
|
+
}
|
|
58
|
+
function mergeSanitizeSchema(base, extra) {
|
|
59
|
+
if (!extra) return base;
|
|
60
|
+
const out = { ...base };
|
|
61
|
+
if (Array.isArray(extra.tagNames)) {
|
|
62
|
+
const a = base.tagNames ?? [];
|
|
63
|
+
out.tagNames = Array.from(/* @__PURE__ */ new Set([...a, ...extra.tagNames]));
|
|
64
|
+
}
|
|
65
|
+
if (extra.attributes && typeof extra.attributes === "object") {
|
|
66
|
+
const baseAttrs = {
|
|
67
|
+
...base.attributes ?? {}
|
|
68
|
+
};
|
|
69
|
+
for (const [tag, attrs] of Object.entries(
|
|
70
|
+
extra.attributes
|
|
71
|
+
)) {
|
|
72
|
+
baseAttrs[tag] = [...baseAttrs[tag] ?? [], ...attrs];
|
|
73
|
+
}
|
|
74
|
+
out.attributes = baseAttrs;
|
|
75
|
+
}
|
|
76
|
+
if (extra.protocols && typeof extra.protocols === "object") {
|
|
77
|
+
const baseProtocols = {
|
|
78
|
+
...base.protocols ?? {}
|
|
79
|
+
};
|
|
80
|
+
for (const [attr, protocols] of Object.entries(
|
|
81
|
+
extra.protocols
|
|
82
|
+
)) {
|
|
83
|
+
baseProtocols[attr] = Array.from(
|
|
84
|
+
/* @__PURE__ */ new Set([...baseProtocols[attr] ?? [], ...protocols])
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
out.protocols = baseProtocols;
|
|
88
|
+
}
|
|
89
|
+
for (const [k, v] of Object.entries(extra)) {
|
|
90
|
+
if (k === "tagNames" || k === "attributes" || k === "protocols") continue;
|
|
91
|
+
out[k] = v;
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
function baseComponents() {
|
|
96
|
+
return {
|
|
97
|
+
a: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
98
|
+
"a",
|
|
99
|
+
{
|
|
100
|
+
...props,
|
|
101
|
+
className: cn(
|
|
102
|
+
"text-primary-700 hover:text-primary-800 dark:text-primary-300 underline underline-offset-2",
|
|
103
|
+
props.className
|
|
104
|
+
),
|
|
105
|
+
target: props.target ?? "_blank",
|
|
106
|
+
rel: props.rel ?? "noopener noreferrer",
|
|
107
|
+
children
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
pre: ({ node: _node, ...props }) => /* @__PURE__ */ jsx(
|
|
111
|
+
"pre",
|
|
112
|
+
{
|
|
113
|
+
...props,
|
|
114
|
+
className: cn(
|
|
115
|
+
"overflow-x-auto rounded-lg bg-neutral-900 p-3 text-sm text-neutral-100 dark:bg-neutral-950",
|
|
116
|
+
props.className
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
),
|
|
120
|
+
code: ({ node: _node, ...props }) => {
|
|
121
|
+
const isBlock = typeof props.className === "string" && props.className.includes("language-");
|
|
122
|
+
return /* @__PURE__ */ jsx(
|
|
123
|
+
"code",
|
|
124
|
+
{
|
|
125
|
+
...props,
|
|
126
|
+
className: cn(
|
|
127
|
+
!isBlock && "rounded bg-neutral-200 px-1 py-0.5 text-[0.85em] dark:bg-neutral-700",
|
|
128
|
+
props.className
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
},
|
|
133
|
+
table: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("div", { className: "my-2 overflow-x-auto", children: /* @__PURE__ */ jsx(
|
|
134
|
+
"table",
|
|
135
|
+
{
|
|
136
|
+
...props,
|
|
137
|
+
className: cn(
|
|
138
|
+
"w-full border-collapse text-sm [&_td]:border [&_td]:border-neutral-200 [&_td]:px-2 [&_td]:py-1 dark:[&_td]:border-neutral-700 [&_th]:border [&_th]:border-neutral-200 [&_th]:px-2 [&_th]:py-1 [&_th]:text-left dark:[&_th]:border-neutral-700",
|
|
139
|
+
props.className
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
) }),
|
|
143
|
+
// Tailwind's preflight resets list markers/padding; restore them explicitly
|
|
144
|
+
// so bullets/numbers show without depending on the typography plugin.
|
|
145
|
+
ul: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("ul", { ...props, className: cn("list-disc ps-5", props.className) }),
|
|
146
|
+
ol: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("ol", { ...props, className: cn("list-decimal ps-5", props.className) }),
|
|
147
|
+
li: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("li", { ...props, className: cn("ps-1", props.className) }),
|
|
148
|
+
// Preflight also flattens headings to body size/weight; restore a sensible
|
|
149
|
+
// hierarchy without depending on the typography plugin.
|
|
150
|
+
h1: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
151
|
+
"h1",
|
|
152
|
+
{
|
|
153
|
+
...props,
|
|
154
|
+
className: cn("mt-3 mb-1 text-xl font-semibold", props.className),
|
|
155
|
+
children
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
h2: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
159
|
+
"h2",
|
|
160
|
+
{
|
|
161
|
+
...props,
|
|
162
|
+
className: cn("mt-3 mb-1 text-lg font-semibold", props.className),
|
|
163
|
+
children
|
|
164
|
+
}
|
|
165
|
+
),
|
|
166
|
+
h3: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
167
|
+
"h3",
|
|
168
|
+
{
|
|
169
|
+
...props,
|
|
170
|
+
className: cn("mt-2 mb-1 text-base font-semibold", props.className),
|
|
171
|
+
children
|
|
172
|
+
}
|
|
173
|
+
),
|
|
174
|
+
h4: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
175
|
+
"h4",
|
|
176
|
+
{
|
|
177
|
+
...props,
|
|
178
|
+
className: cn("mt-2 mb-1 text-sm font-semibold", props.className),
|
|
179
|
+
children
|
|
180
|
+
}
|
|
181
|
+
),
|
|
182
|
+
h5: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
183
|
+
"h5",
|
|
184
|
+
{
|
|
185
|
+
...props,
|
|
186
|
+
className: cn("mt-2 mb-1 text-sm font-semibold", props.className),
|
|
187
|
+
children
|
|
188
|
+
}
|
|
189
|
+
),
|
|
190
|
+
h6: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
191
|
+
"h6",
|
|
192
|
+
{
|
|
193
|
+
...props,
|
|
194
|
+
className: cn(
|
|
195
|
+
"mt-2 mb-1 text-xs font-semibold tracking-wide uppercase",
|
|
196
|
+
props.className
|
|
197
|
+
),
|
|
198
|
+
children
|
|
199
|
+
}
|
|
200
|
+
),
|
|
201
|
+
hr: ({ node: _node, ...props }) => /* @__PURE__ */ jsx(
|
|
202
|
+
"hr",
|
|
203
|
+
{
|
|
204
|
+
...props,
|
|
205
|
+
className: cn(
|
|
206
|
+
"my-2 border-neutral-300 dark:border-neutral-600",
|
|
207
|
+
props.className
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
)
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function createMarkdownRenderer(options = {}) {
|
|
214
|
+
const { plugins = [], trusted = false } = options;
|
|
215
|
+
const remarkPlugins = [
|
|
216
|
+
remarkGfm,
|
|
217
|
+
remarkPreserveLineBreaks,
|
|
218
|
+
...plugins.flatMap((p) => p.remarkPlugins ?? [])
|
|
219
|
+
];
|
|
220
|
+
const pluginRehype = plugins.flatMap(
|
|
221
|
+
(p) => p.rehypePlugins ?? []
|
|
222
|
+
);
|
|
223
|
+
const sanitizeSchema = plugins.reduce(
|
|
224
|
+
(acc, p) => mergeSanitizeSchema(acc, p.sanitizeSchema),
|
|
225
|
+
baseSanitizeSchema()
|
|
226
|
+
);
|
|
227
|
+
const rehypePlugins = trusted ? pluginRehype : [...pluginRehype, [rehypeSanitize, sanitizeSchema]];
|
|
228
|
+
const components = plugins.reduce(
|
|
229
|
+
(acc, p) => ({ ...acc, ...p.components }),
|
|
230
|
+
baseComponents()
|
|
231
|
+
);
|
|
232
|
+
const MarkdownRenderer = (text, ctx) => /* @__PURE__ */ jsx(
|
|
233
|
+
MarkdownContent,
|
|
234
|
+
{
|
|
235
|
+
text,
|
|
236
|
+
messageId: ctx.messageId,
|
|
237
|
+
streaming: ctx.streaming,
|
|
238
|
+
remarkPlugins,
|
|
239
|
+
rehypePlugins,
|
|
240
|
+
components
|
|
241
|
+
},
|
|
242
|
+
ctx.messageId
|
|
243
|
+
);
|
|
244
|
+
return MarkdownRenderer;
|
|
245
|
+
}
|
|
246
|
+
var transformUrl = (url, key, node) => {
|
|
247
|
+
if (key === "src" && node.tagName === "img" && (/^data:image\//i.test(url) || /^blob:/i.test(url))) {
|
|
248
|
+
return url;
|
|
249
|
+
}
|
|
250
|
+
return defaultUrlTransform(url);
|
|
251
|
+
};
|
|
252
|
+
var MarkdownContent = React4.memo(function MarkdownContent2({
|
|
253
|
+
text,
|
|
254
|
+
messageId,
|
|
255
|
+
streaming,
|
|
256
|
+
remarkPlugins,
|
|
257
|
+
rehypePlugins,
|
|
258
|
+
components
|
|
259
|
+
}) {
|
|
260
|
+
return /* @__PURE__ */ jsx(TextRenderContext.Provider, { value: { messageId, streaming }, children: /* @__PURE__ */ jsx(
|
|
261
|
+
Markdown,
|
|
262
|
+
{
|
|
263
|
+
remarkPlugins,
|
|
264
|
+
rehypePlugins,
|
|
265
|
+
urlTransform: transformUrl,
|
|
266
|
+
components,
|
|
267
|
+
children: text
|
|
268
|
+
}
|
|
269
|
+
) });
|
|
270
|
+
});
|
|
271
|
+
function formatTime(time) {
|
|
272
|
+
return new Date(time).toLocaleTimeString(void 0, {
|
|
273
|
+
hour: "numeric",
|
|
274
|
+
minute: "2-digit"
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
function byTime(a, b) {
|
|
278
|
+
return new Date(a.time).getTime() - new Date(b.time).getTime();
|
|
279
|
+
}
|
|
280
|
+
function lastActivityOf(c) {
|
|
281
|
+
if (c.lastActivity) return new Date(c.lastActivity).getTime();
|
|
282
|
+
const last = lastMessageByTime(c.thread);
|
|
283
|
+
return last ? new Date(last.time).getTime() : 0;
|
|
284
|
+
}
|
|
285
|
+
function escapeRegExp(value) {
|
|
286
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
287
|
+
}
|
|
288
|
+
function detectMentions(text, participants) {
|
|
289
|
+
const ids = [];
|
|
290
|
+
for (const p of participants) {
|
|
291
|
+
if (p.kind === "system") continue;
|
|
292
|
+
const token = "@" + p.name.split(" ")[0];
|
|
293
|
+
const pattern = new RegExp(
|
|
294
|
+
`(?<![\\w@])${escapeRegExp(token)}(?![\\w])`,
|
|
295
|
+
"i"
|
|
296
|
+
);
|
|
297
|
+
if (pattern.test(text)) ids.push(p.id);
|
|
298
|
+
}
|
|
299
|
+
return ids;
|
|
300
|
+
}
|
|
301
|
+
function lastMessageByTime(thread) {
|
|
302
|
+
let latest;
|
|
303
|
+
let latestTime = -Infinity;
|
|
304
|
+
for (const message of thread) {
|
|
305
|
+
const t = new Date(message.time).getTime();
|
|
306
|
+
if (t >= latestTime) {
|
|
307
|
+
latest = message;
|
|
308
|
+
latestTime = t;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return latest;
|
|
312
|
+
}
|
|
313
|
+
function ParticipantAvatar({
|
|
314
|
+
participant
|
|
315
|
+
}) {
|
|
316
|
+
const isAgent = participant?.kind === "agent";
|
|
317
|
+
const backgroundColor = participant?.color ?? (isAgent ? "var(--mieweb-primary-700, #1f2937)" : "#64748b");
|
|
318
|
+
return /* @__PURE__ */ jsx(
|
|
319
|
+
Avatar,
|
|
320
|
+
{
|
|
321
|
+
size: "xs",
|
|
322
|
+
src: participant?.avatar,
|
|
323
|
+
alt: "",
|
|
324
|
+
name: participant?.name ?? "?",
|
|
325
|
+
fallback: isAgent ? /* @__PURE__ */ jsx(SparklesIcon, { size: "sm" }) : void 0,
|
|
326
|
+
style: { backgroundColor },
|
|
327
|
+
"aria-hidden": "true",
|
|
328
|
+
className: "shrink-0"
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
function ReferenceChip({
|
|
333
|
+
reference,
|
|
334
|
+
linkBuilder,
|
|
335
|
+
onReferenceClick
|
|
336
|
+
}) {
|
|
337
|
+
const href = linkBuilder?.(reference);
|
|
338
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
339
|
+
/* @__PURE__ */ jsx(
|
|
340
|
+
Badge,
|
|
341
|
+
{
|
|
342
|
+
variant: "default",
|
|
343
|
+
size: "sm",
|
|
344
|
+
className: "rounded px-1.5 text-[10px] font-semibold tracking-wide uppercase",
|
|
345
|
+
children: reference.refType
|
|
346
|
+
}
|
|
347
|
+
),
|
|
348
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: reference.title })
|
|
349
|
+
] });
|
|
350
|
+
const className = "inline-flex max-w-full items-center gap-2 rounded-lg border border-neutral-200 bg-white px-3 py-1.5 text-sm text-neutral-700 hover:border-primary-300 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-200";
|
|
351
|
+
if (href) {
|
|
352
|
+
return /* @__PURE__ */ jsx(
|
|
353
|
+
"a",
|
|
354
|
+
{
|
|
355
|
+
href,
|
|
356
|
+
className,
|
|
357
|
+
onClick: () => onReferenceClick?.(reference),
|
|
358
|
+
children: content
|
|
359
|
+
}
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
return /* @__PURE__ */ jsx(
|
|
363
|
+
"button",
|
|
364
|
+
{
|
|
365
|
+
type: "button",
|
|
366
|
+
className,
|
|
367
|
+
onClick: () => onReferenceClick?.(reference),
|
|
368
|
+
children: content
|
|
369
|
+
}
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
var ATTACHMENT_KIND_CONFIG = {
|
|
373
|
+
image: { accept: "image/*", match: (t) => t.startsWith("image/") },
|
|
374
|
+
video: { accept: "video/*", match: (t) => t.startsWith("video/") },
|
|
375
|
+
audio: { accept: "audio/*", match: (t) => t.startsWith("audio/") },
|
|
376
|
+
pdf: { accept: "application/pdf", match: (t) => t === "application/pdf" }
|
|
377
|
+
};
|
|
378
|
+
var DEFAULT_ACCEPTED_FILE_TYPES = [
|
|
379
|
+
"image",
|
|
380
|
+
"video",
|
|
381
|
+
"audio",
|
|
382
|
+
"pdf"
|
|
383
|
+
];
|
|
384
|
+
function acceptTokensFor(kinds = DEFAULT_ACCEPTED_FILE_TYPES) {
|
|
385
|
+
const source = kinds.length > 0 ? kinds : DEFAULT_ACCEPTED_FILE_TYPES;
|
|
386
|
+
return Array.from(
|
|
387
|
+
new Set(source.map((k) => ATTACHMENT_KIND_CONFIG[k].accept))
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
function filesToComposerAttachments(files) {
|
|
391
|
+
return Promise.all(
|
|
392
|
+
files.map(
|
|
393
|
+
(file, i) => new Promise((resolve, reject) => {
|
|
394
|
+
const reader = new window.FileReader();
|
|
395
|
+
reader.onload = () => {
|
|
396
|
+
const dataUrl = typeof reader.result === "string" ? reader.result : "";
|
|
397
|
+
resolve({
|
|
398
|
+
id: `att-${Date.now()}-${i}`,
|
|
399
|
+
name: file.name || `attachment-${i}`,
|
|
400
|
+
type: file.type || "application/octet-stream",
|
|
401
|
+
dataUrl
|
|
402
|
+
});
|
|
403
|
+
};
|
|
404
|
+
reader.onerror = () => reject(reader.error);
|
|
405
|
+
reader.readAsDataURL(file);
|
|
406
|
+
})
|
|
407
|
+
)
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
function CopyMenu({ isSelf, markdown, getHtml, getText }) {
|
|
411
|
+
const [open, setOpen] = React4.useState(false);
|
|
412
|
+
const [copied, setCopied] = React4.useState(false);
|
|
413
|
+
const copiedTimer = React4.useRef(
|
|
414
|
+
void 0
|
|
415
|
+
);
|
|
416
|
+
React4.useEffect(() => () => window.clearTimeout(copiedTimer.current), []);
|
|
417
|
+
const flash = () => {
|
|
418
|
+
setCopied(true);
|
|
419
|
+
window.clearTimeout(copiedTimer.current);
|
|
420
|
+
copiedTimer.current = setTimeout(() => setCopied(false), 1200);
|
|
421
|
+
};
|
|
422
|
+
const writeText = async (value) => {
|
|
423
|
+
if (!navigator.clipboard?.writeText) {
|
|
424
|
+
throw new Error("Clipboard API unavailable");
|
|
425
|
+
}
|
|
426
|
+
await navigator.clipboard.writeText(value);
|
|
427
|
+
};
|
|
428
|
+
const writeBoth = async () => {
|
|
429
|
+
const html = getHtml();
|
|
430
|
+
const text = markdown || getText();
|
|
431
|
+
try {
|
|
432
|
+
if (typeof window !== "undefined" && "ClipboardItem" in window && navigator.clipboard?.write) {
|
|
433
|
+
await navigator.clipboard.write([
|
|
434
|
+
new window.ClipboardItem({
|
|
435
|
+
"text/html": new Blob([html], { type: "text/html" }),
|
|
436
|
+
"text/plain": new Blob([text], { type: "text/plain" })
|
|
437
|
+
})
|
|
438
|
+
]);
|
|
439
|
+
} else {
|
|
440
|
+
await writeText(text);
|
|
441
|
+
}
|
|
442
|
+
} catch {
|
|
443
|
+
await writeText(text);
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
const run = (fn) => {
|
|
447
|
+
setOpen(false);
|
|
448
|
+
void fn().then(flash, () => {
|
|
449
|
+
});
|
|
450
|
+
};
|
|
451
|
+
return /* @__PURE__ */ jsx(
|
|
452
|
+
"div",
|
|
453
|
+
{
|
|
454
|
+
className: cn(
|
|
455
|
+
"sticky bottom-2 shrink-0 self-end",
|
|
456
|
+
// Rich content (e.g. NITRO tables) layers internals up to z-50, so the
|
|
457
|
+
// open menu's stacking context must clear that.
|
|
458
|
+
open ? "z-[60]" : "z-10"
|
|
459
|
+
),
|
|
460
|
+
children: /* @__PURE__ */ jsxs(
|
|
461
|
+
Dropdown,
|
|
462
|
+
{
|
|
463
|
+
open,
|
|
464
|
+
onOpenChange: setOpen,
|
|
465
|
+
placement: isSelf ? "top-end" : "top-start",
|
|
466
|
+
trigger: /* @__PURE__ */ jsx(
|
|
467
|
+
"button",
|
|
468
|
+
{
|
|
469
|
+
type: "button",
|
|
470
|
+
"data-slot": "superchat-copy-button",
|
|
471
|
+
"aria-label": "Copy message",
|
|
472
|
+
className: "rounded p-1 text-neutral-400 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100 hover:text-neutral-600 focus-visible:opacity-100 dark:hover:text-neutral-200",
|
|
473
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { size: 14, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Clipboard, { size: 14, "aria-hidden": "true" })
|
|
474
|
+
}
|
|
475
|
+
),
|
|
476
|
+
children: [
|
|
477
|
+
/* @__PURE__ */ jsx(DropdownItem, { onClick: () => run(writeBoth), children: /* @__PURE__ */ jsxs("span", { className: "flex flex-col items-start", children: [
|
|
478
|
+
/* @__PURE__ */ jsx("span", { children: "Copy" }),
|
|
479
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-normal text-neutral-400", children: "Rich text + Markdown" })
|
|
480
|
+
] }) }),
|
|
481
|
+
/* @__PURE__ */ jsx(
|
|
482
|
+
DropdownItem,
|
|
483
|
+
{
|
|
484
|
+
onClick: () => run(() => writeText(markdown || getText())),
|
|
485
|
+
children: "Copy as Markdown"
|
|
486
|
+
}
|
|
487
|
+
),
|
|
488
|
+
/* @__PURE__ */ jsx(DropdownItem, { onClick: () => run(() => writeText(getText())), children: "Copy as plain text" })
|
|
489
|
+
]
|
|
490
|
+
}
|
|
491
|
+
)
|
|
492
|
+
}
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
var MessageRow = React4.memo(function MessageRow2({
|
|
496
|
+
message,
|
|
497
|
+
participant,
|
|
498
|
+
isSelf,
|
|
499
|
+
renderText,
|
|
500
|
+
linkBuilder,
|
|
501
|
+
onReferenceClick,
|
|
502
|
+
editable,
|
|
503
|
+
onMessageEdited
|
|
504
|
+
}) {
|
|
505
|
+
const streaming = message.status === "streaming";
|
|
506
|
+
const hasBody = !!message.text || (message.content?.length ?? 0) > 0;
|
|
507
|
+
const [isEditing, setIsEditing] = React4.useState(false);
|
|
508
|
+
const [draft, setDraft] = React4.useState(message.text ?? "");
|
|
509
|
+
const editRef = React4.useRef(null);
|
|
510
|
+
const bubbleRef = React4.useRef(null);
|
|
511
|
+
const autosize = React4.useCallback(() => {
|
|
512
|
+
const el = editRef.current;
|
|
513
|
+
if (!el) return;
|
|
514
|
+
el.style.height = "auto";
|
|
515
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
516
|
+
}, []);
|
|
517
|
+
React4.useEffect(() => {
|
|
518
|
+
if (!isEditing) return;
|
|
519
|
+
const el = editRef.current;
|
|
520
|
+
if (!el) return;
|
|
521
|
+
el.focus();
|
|
522
|
+
el.setSelectionRange(el.value.length, el.value.length);
|
|
523
|
+
autosize();
|
|
524
|
+
}, [isEditing, autosize]);
|
|
525
|
+
if (message.type === "system") {
|
|
526
|
+
return /* @__PURE__ */ jsx(
|
|
527
|
+
"div",
|
|
528
|
+
{
|
|
529
|
+
"data-slot": "superchat-system-message",
|
|
530
|
+
role: "status",
|
|
531
|
+
className: "my-1 text-center text-xs text-neutral-500 dark:text-neutral-400",
|
|
532
|
+
children: message.text
|
|
533
|
+
}
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
if (message.type === "ref" && message.ref) {
|
|
537
|
+
return /* @__PURE__ */ jsx(
|
|
538
|
+
"div",
|
|
539
|
+
{
|
|
540
|
+
"data-slot": "superchat-reference",
|
|
541
|
+
className: cn("flex", isSelf && "justify-end"),
|
|
542
|
+
children: /* @__PURE__ */ jsx(
|
|
543
|
+
ReferenceChip,
|
|
544
|
+
{
|
|
545
|
+
reference: message.ref,
|
|
546
|
+
linkBuilder,
|
|
547
|
+
onReferenceClick
|
|
548
|
+
}
|
|
549
|
+
)
|
|
550
|
+
}
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
const accent = participant?.color;
|
|
554
|
+
const authorName = participant?.name ?? "Unknown";
|
|
555
|
+
const canEdit = !!editable && isSelf && !streaming && typeof message.text === "string" && !message.content?.length;
|
|
556
|
+
const startEdit = () => {
|
|
557
|
+
setDraft(message.text ?? "");
|
|
558
|
+
setIsEditing(true);
|
|
559
|
+
};
|
|
560
|
+
const cancelEdit = () => setIsEditing(false);
|
|
561
|
+
const saveEdit = () => {
|
|
562
|
+
const next = draft.trim();
|
|
563
|
+
if (next && next !== message.text) onMessageEdited?.(message.id, next);
|
|
564
|
+
setIsEditing(false);
|
|
565
|
+
};
|
|
566
|
+
const handleEditPaste = (e) => {
|
|
567
|
+
const files = Array.from(e.clipboardData.items).filter((item) => item.kind === "file" && item.type.startsWith("image/")).map((item) => item.getAsFile()).filter((f) => f !== null);
|
|
568
|
+
if (files.length === 0) return;
|
|
569
|
+
e.preventDefault();
|
|
570
|
+
const el = e.currentTarget;
|
|
571
|
+
const start = el.selectionStart ?? draft.length;
|
|
572
|
+
const end = el.selectionEnd ?? draft.length;
|
|
573
|
+
Promise.all(
|
|
574
|
+
files.map(
|
|
575
|
+
(file, i) => new Promise((resolve) => {
|
|
576
|
+
const reader = new window.FileReader();
|
|
577
|
+
reader.onload = () => {
|
|
578
|
+
const dataUrl = typeof reader.result === "string" ? reader.result : "";
|
|
579
|
+
const name = file.name || `pasted-image-${i + 1}.png`;
|
|
580
|
+
resolve(dataUrl ? `` : "");
|
|
581
|
+
};
|
|
582
|
+
reader.readAsDataURL(file);
|
|
583
|
+
})
|
|
584
|
+
)
|
|
585
|
+
).then((snippets) => {
|
|
586
|
+
const insert = snippets.filter(Boolean).join("\n");
|
|
587
|
+
if (!insert) return;
|
|
588
|
+
el.focus();
|
|
589
|
+
el.setSelectionRange(start, end);
|
|
590
|
+
const text = `${insert}
|
|
591
|
+
`;
|
|
592
|
+
const inserted = typeof document !== "undefined" && typeof document.execCommand === "function" && document.execCommand("insertText", false, text);
|
|
593
|
+
if (!inserted) {
|
|
594
|
+
setDraft((prev) => `${prev.slice(0, start)}${text}${prev.slice(end)}`);
|
|
595
|
+
}
|
|
596
|
+
requestAnimationFrame(autosize);
|
|
597
|
+
});
|
|
598
|
+
};
|
|
599
|
+
const markdownSource = typeof message.text === "string" && message.text ? message.text : message.content?.map((block) => {
|
|
600
|
+
if (block.type === "code" && block.text) {
|
|
601
|
+
return `\`\`\`${block.language ?? ""}
|
|
602
|
+
${block.text}
|
|
603
|
+
\`\`\``;
|
|
604
|
+
}
|
|
605
|
+
if ((block.type === "text" || block.type === "thinking") && block.text) {
|
|
606
|
+
return block.text;
|
|
607
|
+
}
|
|
608
|
+
return "";
|
|
609
|
+
}).filter(Boolean).join("\n\n") ?? "";
|
|
610
|
+
const canCopy = !isEditing && (!!message.content?.length || typeof message.text === "string" && message.text.length > 0);
|
|
611
|
+
return /* @__PURE__ */ jsxs(
|
|
612
|
+
"div",
|
|
613
|
+
{
|
|
614
|
+
"data-slot": "superchat-message",
|
|
615
|
+
role: "article",
|
|
616
|
+
"aria-label": `${authorName}, ${formatTime(message.time)}`,
|
|
617
|
+
className: cn(
|
|
618
|
+
"group flex gap-2",
|
|
619
|
+
isSelf ? "flex-row-reverse" : "flex-row"
|
|
620
|
+
),
|
|
621
|
+
children: [
|
|
622
|
+
/* @__PURE__ */ jsx(ParticipantAvatar, { participant }),
|
|
623
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 flex-col gap-1", isSelf && "items-end"), children: [
|
|
624
|
+
/* @__PURE__ */ jsxs(
|
|
625
|
+
"div",
|
|
626
|
+
{
|
|
627
|
+
"data-slot": "superchat-message-meta",
|
|
628
|
+
className: "flex items-baseline gap-2",
|
|
629
|
+
children: [
|
|
630
|
+
/* @__PURE__ */ jsx(
|
|
631
|
+
"span",
|
|
632
|
+
{
|
|
633
|
+
className: "text-xs font-medium",
|
|
634
|
+
style: accent ? { color: accent } : void 0,
|
|
635
|
+
children: authorName
|
|
636
|
+
}
|
|
637
|
+
),
|
|
638
|
+
participant?.role && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-neutral-400", children: participant.role }),
|
|
639
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-neutral-400", children: formatTime(message.time) }),
|
|
640
|
+
message.editedAt && /* @__PURE__ */ jsx(
|
|
641
|
+
"span",
|
|
642
|
+
{
|
|
643
|
+
"data-slot": "superchat-edited-indicator",
|
|
644
|
+
className: "text-[10px] text-neutral-400",
|
|
645
|
+
title: `Edited ${formatTime(message.editedAt)}`,
|
|
646
|
+
children: "(edited)"
|
|
647
|
+
}
|
|
648
|
+
),
|
|
649
|
+
canEdit && !isEditing && /* @__PURE__ */ jsx(
|
|
650
|
+
"button",
|
|
651
|
+
{
|
|
652
|
+
type: "button",
|
|
653
|
+
"data-slot": "superchat-edit-button",
|
|
654
|
+
onClick: startEdit,
|
|
655
|
+
"aria-label": "Edit message",
|
|
656
|
+
className: "rounded p-0.5 text-neutral-400 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100 hover:text-neutral-600 focus-visible:opacity-100 dark:hover:text-neutral-200",
|
|
657
|
+
children: /* @__PURE__ */ jsx(Pencil, { size: 14, "aria-hidden": "true" })
|
|
658
|
+
}
|
|
659
|
+
)
|
|
660
|
+
]
|
|
661
|
+
}
|
|
662
|
+
),
|
|
663
|
+
/* @__PURE__ */ jsxs(
|
|
664
|
+
"div",
|
|
665
|
+
{
|
|
666
|
+
className: cn(
|
|
667
|
+
"flex items-center gap-1",
|
|
668
|
+
isSelf ? "flex-row-reverse" : "flex-row"
|
|
669
|
+
),
|
|
670
|
+
children: [
|
|
671
|
+
canCopy && /* @__PURE__ */ jsx(
|
|
672
|
+
CopyMenu,
|
|
673
|
+
{
|
|
674
|
+
isSelf,
|
|
675
|
+
markdown: markdownSource,
|
|
676
|
+
getHtml: () => bubbleRef.current?.innerHTML ?? "",
|
|
677
|
+
getText: () => bubbleRef.current?.textContent ?? ""
|
|
678
|
+
}
|
|
679
|
+
),
|
|
680
|
+
/* @__PURE__ */ jsx(
|
|
681
|
+
ChatBubble,
|
|
682
|
+
{
|
|
683
|
+
ref: bubbleRef,
|
|
684
|
+
"data-slot": "superchat-bubble",
|
|
685
|
+
variant: isSelf ? "user" : "assistant",
|
|
686
|
+
hasError: message.status === "error",
|
|
687
|
+
className: "text-sm",
|
|
688
|
+
children: isEditing ? /* @__PURE__ */ jsxs(
|
|
689
|
+
"div",
|
|
690
|
+
{
|
|
691
|
+
"data-slot": "superchat-message-editor",
|
|
692
|
+
className: "flex w-80 max-w-full flex-col gap-2",
|
|
693
|
+
children: [
|
|
694
|
+
/* @__PURE__ */ jsx(
|
|
695
|
+
"textarea",
|
|
696
|
+
{
|
|
697
|
+
value: draft,
|
|
698
|
+
ref: editRef,
|
|
699
|
+
rows: 2,
|
|
700
|
+
onChange: (e) => {
|
|
701
|
+
setDraft(e.target.value);
|
|
702
|
+
autosize();
|
|
703
|
+
},
|
|
704
|
+
onPaste: handleEditPaste,
|
|
705
|
+
onKeyDown: (e) => {
|
|
706
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
707
|
+
e.preventDefault();
|
|
708
|
+
saveEdit();
|
|
709
|
+
} else if (e.key === "Escape") {
|
|
710
|
+
e.preventDefault();
|
|
711
|
+
cancelEdit();
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
"aria-label": "Edit message",
|
|
715
|
+
className: "focus:ring-primary-500 max-h-60 min-h-16 w-full resize-none rounded-lg border border-neutral-300 bg-white px-3 py-2 text-sm text-neutral-900 focus:ring-1 focus:outline-none dark:border-neutral-600 dark:bg-neutral-900 dark:text-white"
|
|
716
|
+
}
|
|
717
|
+
),
|
|
718
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
719
|
+
/* @__PURE__ */ jsx(
|
|
720
|
+
"button",
|
|
721
|
+
{
|
|
722
|
+
type: "button",
|
|
723
|
+
onClick: cancelEdit,
|
|
724
|
+
className: "rounded-md px-2.5 py-1 text-xs font-medium text-neutral-200 hover:bg-white/10",
|
|
725
|
+
children: "Cancel"
|
|
726
|
+
}
|
|
727
|
+
),
|
|
728
|
+
/* @__PURE__ */ jsx(
|
|
729
|
+
"button",
|
|
730
|
+
{
|
|
731
|
+
type: "button",
|
|
732
|
+
onClick: saveEdit,
|
|
733
|
+
disabled: !draft.trim() || draft.trim() === message.text,
|
|
734
|
+
className: "rounded-md bg-white px-2.5 py-1 text-xs font-medium text-neutral-900 hover:bg-neutral-100 disabled:opacity-40",
|
|
735
|
+
children: "Save"
|
|
736
|
+
}
|
|
737
|
+
)
|
|
738
|
+
] })
|
|
739
|
+
]
|
|
740
|
+
}
|
|
741
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
742
|
+
message.content?.map((block, i) => {
|
|
743
|
+
if (block.type === "tool_use" && block.toolCall) {
|
|
744
|
+
return /* @__PURE__ */ jsx(MCPToolCallDisplay, { toolCall: block.toolCall }, i);
|
|
745
|
+
}
|
|
746
|
+
if ((block.type === "text" || block.type === "thinking") && block.text) {
|
|
747
|
+
return /* @__PURE__ */ jsx(
|
|
748
|
+
"div",
|
|
749
|
+
{
|
|
750
|
+
className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word",
|
|
751
|
+
children: renderText(block.text, {
|
|
752
|
+
messageId: message.id,
|
|
753
|
+
streaming,
|
|
754
|
+
role: participant?.kind === "human" ? "user" : "assistant"
|
|
755
|
+
})
|
|
756
|
+
},
|
|
757
|
+
i
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
if (block.type === "code" && block.text) {
|
|
761
|
+
const fenced = `\`\`\`${block.language ?? ""}
|
|
762
|
+
${block.text}
|
|
763
|
+
\`\`\``;
|
|
764
|
+
return /* @__PURE__ */ jsx(
|
|
765
|
+
"div",
|
|
766
|
+
{
|
|
767
|
+
className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word",
|
|
768
|
+
children: renderText(fenced, {
|
|
769
|
+
messageId: message.id,
|
|
770
|
+
streaming,
|
|
771
|
+
role: participant?.kind === "human" ? "user" : "assistant"
|
|
772
|
+
})
|
|
773
|
+
},
|
|
774
|
+
i
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
return null;
|
|
778
|
+
}),
|
|
779
|
+
message.text && /* @__PURE__ */ jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word", children: renderText(message.text, {
|
|
780
|
+
messageId: message.id,
|
|
781
|
+
streaming,
|
|
782
|
+
role: participant?.kind === "human" ? "user" : "assistant"
|
|
783
|
+
}) }),
|
|
784
|
+
streaming && !hasBody && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(AITypingIndicator, {}) })
|
|
785
|
+
] })
|
|
786
|
+
}
|
|
787
|
+
)
|
|
788
|
+
]
|
|
789
|
+
}
|
|
790
|
+
)
|
|
791
|
+
] })
|
|
792
|
+
]
|
|
793
|
+
}
|
|
794
|
+
);
|
|
795
|
+
});
|
|
796
|
+
var sidebarItem = cva(
|
|
797
|
+
"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-sm transition-colors",
|
|
798
|
+
{
|
|
799
|
+
variants: {
|
|
800
|
+
active: {
|
|
801
|
+
true: "bg-primary-100 text-primary-900 dark:bg-primary-900/40 dark:text-primary-100",
|
|
802
|
+
false: "text-neutral-700 hover:bg-neutral-100 dark:text-neutral-200 dark:hover:bg-neutral-800"
|
|
803
|
+
}
|
|
804
|
+
},
|
|
805
|
+
defaultVariants: { active: false }
|
|
806
|
+
}
|
|
807
|
+
);
|
|
808
|
+
function VirtualThread({
|
|
809
|
+
items,
|
|
810
|
+
participantById,
|
|
811
|
+
currentParticipantId,
|
|
812
|
+
renderText,
|
|
813
|
+
linkBuilder,
|
|
814
|
+
onReferenceClick,
|
|
815
|
+
editable,
|
|
816
|
+
onMessageEdited,
|
|
817
|
+
order,
|
|
818
|
+
conversationId,
|
|
819
|
+
containerProps
|
|
820
|
+
}) {
|
|
821
|
+
const parentRef = React4.useRef(null);
|
|
822
|
+
const virtualizer = useVirtualizer({
|
|
823
|
+
count: items.length,
|
|
824
|
+
getScrollElement: () => parentRef.current,
|
|
825
|
+
// Rough first guess; real heights are measured via measureElement.
|
|
826
|
+
estimateSize: () => 88,
|
|
827
|
+
overscan: 10,
|
|
828
|
+
getItemKey: (index) => items[index]?.id ?? index
|
|
829
|
+
});
|
|
830
|
+
const count = items.length;
|
|
831
|
+
React4.useEffect(() => {
|
|
832
|
+
if (count === 0) return;
|
|
833
|
+
if (order === "desc") {
|
|
834
|
+
virtualizer.scrollToIndex(0, { align: "start" });
|
|
835
|
+
} else {
|
|
836
|
+
virtualizer.scrollToIndex(count - 1, { align: "end" });
|
|
837
|
+
}
|
|
838
|
+
}, [count, conversationId, order]);
|
|
839
|
+
const virtualItems = virtualizer.getVirtualItems();
|
|
840
|
+
return /* @__PURE__ */ jsx("div", { ...containerProps, ref: parentRef, children: /* @__PURE__ */ jsx(
|
|
841
|
+
"div",
|
|
842
|
+
{
|
|
843
|
+
style: {
|
|
844
|
+
height: virtualizer.getTotalSize(),
|
|
845
|
+
position: "relative",
|
|
846
|
+
width: "100%"
|
|
847
|
+
},
|
|
848
|
+
children: virtualItems.map((virtualRow) => {
|
|
849
|
+
const message = items[virtualRow.index];
|
|
850
|
+
if (!message) return null;
|
|
851
|
+
return /* @__PURE__ */ jsx(
|
|
852
|
+
"div",
|
|
853
|
+
{
|
|
854
|
+
"data-index": virtualRow.index,
|
|
855
|
+
ref: virtualizer.measureElement,
|
|
856
|
+
style: {
|
|
857
|
+
position: "absolute",
|
|
858
|
+
top: 0,
|
|
859
|
+
left: 0,
|
|
860
|
+
width: "100%",
|
|
861
|
+
transform: `translateY(${virtualRow.start}px)`
|
|
862
|
+
},
|
|
863
|
+
children: /* @__PURE__ */ jsx("div", { className: "pb-4", children: /* @__PURE__ */ jsx(
|
|
864
|
+
MessageRow,
|
|
865
|
+
{
|
|
866
|
+
message,
|
|
867
|
+
participant: participantById.get(message.participantId),
|
|
868
|
+
isSelf: !!currentParticipantId && message.participantId === currentParticipantId,
|
|
869
|
+
renderText,
|
|
870
|
+
linkBuilder,
|
|
871
|
+
onReferenceClick,
|
|
872
|
+
editable,
|
|
873
|
+
onMessageEdited
|
|
874
|
+
}
|
|
875
|
+
) })
|
|
876
|
+
},
|
|
877
|
+
virtualRow.key
|
|
878
|
+
);
|
|
879
|
+
})
|
|
880
|
+
}
|
|
881
|
+
) });
|
|
882
|
+
}
|
|
883
|
+
function SuperChat({
|
|
884
|
+
conversation,
|
|
885
|
+
currentParticipantId,
|
|
886
|
+
renderPlugins,
|
|
887
|
+
renderTextContent,
|
|
888
|
+
trustedContent,
|
|
889
|
+
readOnly,
|
|
890
|
+
acceptedFileTypes,
|
|
891
|
+
order = "asc",
|
|
892
|
+
virtualized = false,
|
|
893
|
+
linkBuilder,
|
|
894
|
+
className,
|
|
895
|
+
onMessageSent,
|
|
896
|
+
onMessageEdited,
|
|
897
|
+
onConversationClosed,
|
|
898
|
+
onReferenceClick,
|
|
899
|
+
onBack
|
|
900
|
+
}) {
|
|
901
|
+
const headingId = React4.useId();
|
|
902
|
+
const renderText = React4.useMemo(
|
|
903
|
+
() => renderTextContent ?? createMarkdownRenderer({
|
|
904
|
+
plugins: renderPlugins,
|
|
905
|
+
trusted: trustedContent
|
|
906
|
+
}),
|
|
907
|
+
[renderTextContent, renderPlugins, trustedContent]
|
|
908
|
+
);
|
|
909
|
+
const threadRef = React4.useRef(null);
|
|
910
|
+
React4.useEffect(() => {
|
|
911
|
+
if (virtualized) return;
|
|
912
|
+
const el = threadRef.current;
|
|
913
|
+
if (!el) return;
|
|
914
|
+
el.scrollTop = order === "desc" ? 0 : el.scrollHeight;
|
|
915
|
+
}, [conversation.thread.length, conversation.id, order, virtualized]);
|
|
916
|
+
const participantById = React4.useMemo(() => {
|
|
917
|
+
const map = /* @__PURE__ */ new Map();
|
|
918
|
+
conversation.participants.forEach((p) => map.set(p.id, p));
|
|
919
|
+
return map;
|
|
920
|
+
}, [conversation]);
|
|
921
|
+
const orderedThread = React4.useMemo(() => {
|
|
922
|
+
const sorted = [...conversation.thread].sort(byTime);
|
|
923
|
+
return order === "desc" ? sorted.reverse() : sorted;
|
|
924
|
+
}, [conversation, order]);
|
|
925
|
+
const onMessageEditedRef = React4.useRef(onMessageEdited);
|
|
926
|
+
onMessageEditedRef.current = onMessageEdited;
|
|
927
|
+
const conversationRef = React4.useRef(conversation);
|
|
928
|
+
conversationRef.current = conversation;
|
|
929
|
+
const handleMessageEdited = React4.useCallback(
|
|
930
|
+
(messageId, text) => {
|
|
931
|
+
onMessageEditedRef.current?.(messageId, text, {
|
|
932
|
+
conversation: conversationRef.current
|
|
933
|
+
});
|
|
934
|
+
},
|
|
935
|
+
[]
|
|
936
|
+
);
|
|
937
|
+
const editable = !readOnly && !!onMessageEdited;
|
|
938
|
+
const mentionOptions = React4.useMemo(
|
|
939
|
+
() => conversation.participants.filter((p) => p.kind !== "system").map((p) => ({
|
|
940
|
+
id: p.id,
|
|
941
|
+
label: p.name,
|
|
942
|
+
description: p.role,
|
|
943
|
+
meta: p.kind,
|
|
944
|
+
icon: /* @__PURE__ */ jsx(ParticipantAvatar, { participant: p })
|
|
945
|
+
})),
|
|
946
|
+
[conversation.participants]
|
|
947
|
+
);
|
|
948
|
+
const composerAccept = React4.useMemo(
|
|
949
|
+
() => acceptTokensFor(acceptedFileTypes),
|
|
950
|
+
[acceptedFileTypes]
|
|
951
|
+
);
|
|
952
|
+
const handleComposerSend = React4.useCallback(
|
|
953
|
+
async (message) => {
|
|
954
|
+
const text = message.content;
|
|
955
|
+
const mentions = detectMentions(text, conversation.participants);
|
|
956
|
+
const attachments = await filesToComposerAttachments(
|
|
957
|
+
message.attachments ?? []
|
|
958
|
+
);
|
|
959
|
+
onMessageSent?.(text, { conversation, mentions, attachments });
|
|
960
|
+
},
|
|
961
|
+
[conversation, onMessageSent]
|
|
962
|
+
);
|
|
963
|
+
return /* @__PURE__ */ jsxs(
|
|
964
|
+
"section",
|
|
965
|
+
{
|
|
966
|
+
"data-slot": "superchat",
|
|
967
|
+
role: "group",
|
|
968
|
+
"aria-labelledby": headingId,
|
|
969
|
+
className: cn(
|
|
970
|
+
"flex min-w-0 flex-1 flex-col bg-white dark:bg-neutral-900",
|
|
971
|
+
className
|
|
972
|
+
),
|
|
973
|
+
children: [
|
|
974
|
+
/* @__PURE__ */ jsxs(
|
|
975
|
+
"header",
|
|
976
|
+
{
|
|
977
|
+
"data-slot": "superchat-header",
|
|
978
|
+
className: "flex items-center justify-between gap-2 border-b border-neutral-200 p-3 dark:border-neutral-700",
|
|
979
|
+
children: [
|
|
980
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
981
|
+
onBack && /* @__PURE__ */ jsx(
|
|
982
|
+
"button",
|
|
983
|
+
{
|
|
984
|
+
type: "button",
|
|
985
|
+
onClick: onBack,
|
|
986
|
+
"aria-label": "Back to conversations",
|
|
987
|
+
className: "-ml-1 shrink-0 rounded-md p-1 text-neutral-500 hover:bg-neutral-100 sm:hidden dark:text-neutral-300 dark:hover:bg-neutral-800",
|
|
988
|
+
children: /* @__PURE__ */ jsx(
|
|
989
|
+
"svg",
|
|
990
|
+
{
|
|
991
|
+
viewBox: "0 0 24 24",
|
|
992
|
+
width: "20",
|
|
993
|
+
height: "20",
|
|
994
|
+
fill: "none",
|
|
995
|
+
stroke: "currentColor",
|
|
996
|
+
strokeWidth: "2",
|
|
997
|
+
strokeLinecap: "round",
|
|
998
|
+
strokeLinejoin: "round",
|
|
999
|
+
"aria-hidden": "true",
|
|
1000
|
+
children: /* @__PURE__ */ jsx("path", { d: "m15 18-6-6 6-6" })
|
|
1001
|
+
}
|
|
1002
|
+
)
|
|
1003
|
+
}
|
|
1004
|
+
),
|
|
1005
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1006
|
+
/* @__PURE__ */ jsx(
|
|
1007
|
+
"h2",
|
|
1008
|
+
{
|
|
1009
|
+
id: headingId,
|
|
1010
|
+
className: "truncate text-sm font-semibold text-neutral-800 dark:text-neutral-100",
|
|
1011
|
+
children: conversation.title
|
|
1012
|
+
}
|
|
1013
|
+
),
|
|
1014
|
+
/* @__PURE__ */ jsx(
|
|
1015
|
+
"div",
|
|
1016
|
+
{
|
|
1017
|
+
"data-slot": "superchat-participants",
|
|
1018
|
+
role: "group",
|
|
1019
|
+
"aria-label": "Participants",
|
|
1020
|
+
className: "mt-0.5 flex items-center gap-1",
|
|
1021
|
+
children: conversation.participants.slice(0, 6).map((p) => /* @__PURE__ */ jsx("span", { role: "img", "aria-label": p.name, children: /* @__PURE__ */ jsx(ParticipantAvatar, { participant: p }) }, p.id))
|
|
1022
|
+
}
|
|
1023
|
+
)
|
|
1024
|
+
] })
|
|
1025
|
+
] }),
|
|
1026
|
+
onConversationClosed && /* @__PURE__ */ jsx(
|
|
1027
|
+
"button",
|
|
1028
|
+
{
|
|
1029
|
+
type: "button",
|
|
1030
|
+
onClick: () => onConversationClosed(conversation),
|
|
1031
|
+
"aria-label": "Close conversation",
|
|
1032
|
+
className: "rounded-md p-1 text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800",
|
|
1033
|
+
children: /* @__PURE__ */ jsx(CloseIcon, {})
|
|
1034
|
+
}
|
|
1035
|
+
)
|
|
1036
|
+
]
|
|
1037
|
+
}
|
|
1038
|
+
),
|
|
1039
|
+
virtualized ? /* @__PURE__ */ jsx(
|
|
1040
|
+
VirtualThread,
|
|
1041
|
+
{
|
|
1042
|
+
items: orderedThread,
|
|
1043
|
+
participantById,
|
|
1044
|
+
currentParticipantId,
|
|
1045
|
+
renderText,
|
|
1046
|
+
linkBuilder,
|
|
1047
|
+
onReferenceClick,
|
|
1048
|
+
editable,
|
|
1049
|
+
onMessageEdited: handleMessageEdited,
|
|
1050
|
+
order,
|
|
1051
|
+
conversationId: conversation.id,
|
|
1052
|
+
containerProps: {
|
|
1053
|
+
"data-slot": "superchat-thread",
|
|
1054
|
+
role: "log",
|
|
1055
|
+
"aria-label": "Messages",
|
|
1056
|
+
"aria-live": "polite",
|
|
1057
|
+
// Focusable so keyboard-only users can scroll the message history.
|
|
1058
|
+
tabIndex: 0,
|
|
1059
|
+
className: "flex-1 overflow-y-auto p-4"
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
) : /* @__PURE__ */ jsx(
|
|
1063
|
+
"div",
|
|
1064
|
+
{
|
|
1065
|
+
"data-slot": "superchat-thread",
|
|
1066
|
+
ref: threadRef,
|
|
1067
|
+
role: "log",
|
|
1068
|
+
"aria-label": "Messages",
|
|
1069
|
+
"aria-live": "polite",
|
|
1070
|
+
tabIndex: 0,
|
|
1071
|
+
className: "flex-1 space-y-4 overflow-y-auto p-4",
|
|
1072
|
+
children: orderedThread.map((m) => /* @__PURE__ */ jsx(
|
|
1073
|
+
MessageRow,
|
|
1074
|
+
{
|
|
1075
|
+
message: m,
|
|
1076
|
+
participant: participantById.get(m.participantId),
|
|
1077
|
+
isSelf: !!currentParticipantId && m.participantId === currentParticipantId,
|
|
1078
|
+
renderText,
|
|
1079
|
+
linkBuilder,
|
|
1080
|
+
onReferenceClick,
|
|
1081
|
+
editable,
|
|
1082
|
+
onMessageEdited: handleMessageEdited
|
|
1083
|
+
},
|
|
1084
|
+
m.id
|
|
1085
|
+
))
|
|
1086
|
+
}
|
|
1087
|
+
),
|
|
1088
|
+
/* @__PURE__ */ jsx(
|
|
1089
|
+
MessageComposer,
|
|
1090
|
+
{
|
|
1091
|
+
onSend: handleComposerSend,
|
|
1092
|
+
disabled: readOnly,
|
|
1093
|
+
placeholder: readOnly ? "Read-only conversation" : "Type a message\u2026 use @ to address an agent",
|
|
1094
|
+
mentionOptions,
|
|
1095
|
+
showAttachmentPicker: !readOnly,
|
|
1096
|
+
showCameraButton: false,
|
|
1097
|
+
acceptedFileTypes: composerAccept,
|
|
1098
|
+
maxLength: 1e5
|
|
1099
|
+
}
|
|
1100
|
+
)
|
|
1101
|
+
]
|
|
1102
|
+
}
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
function SuperChatConversations({
|
|
1106
|
+
conversations,
|
|
1107
|
+
activeConversationId,
|
|
1108
|
+
defaultActiveConversationId,
|
|
1109
|
+
className,
|
|
1110
|
+
onConversationOpened,
|
|
1111
|
+
onNewConversation
|
|
1112
|
+
}) {
|
|
1113
|
+
const [internalActive, setInternalActive] = React4.useState(
|
|
1114
|
+
defaultActiveConversationId ?? conversations[0]?.id
|
|
1115
|
+
);
|
|
1116
|
+
const requestedId = activeConversationId ?? internalActive;
|
|
1117
|
+
const activeId = conversations.some((c) => c.id === requestedId) ? requestedId : conversations[0]?.id;
|
|
1118
|
+
const sortedConversations = React4.useMemo(
|
|
1119
|
+
() => [...conversations].sort((a, b) => lastActivityOf(b) - lastActivityOf(a)),
|
|
1120
|
+
[conversations]
|
|
1121
|
+
);
|
|
1122
|
+
const selectConversation = (c) => {
|
|
1123
|
+
if (activeConversationId === void 0) setInternalActive(c.id);
|
|
1124
|
+
onConversationOpened?.(c);
|
|
1125
|
+
};
|
|
1126
|
+
return /* @__PURE__ */ jsxs(
|
|
1127
|
+
"aside",
|
|
1128
|
+
{
|
|
1129
|
+
"data-slot": "superchat-conversations",
|
|
1130
|
+
"aria-label": "Conversations",
|
|
1131
|
+
className: cn(
|
|
1132
|
+
"flex w-64 shrink-0 flex-col border-r border-neutral-200 dark:border-neutral-700",
|
|
1133
|
+
className
|
|
1134
|
+
),
|
|
1135
|
+
children: [
|
|
1136
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-3", children: [
|
|
1137
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-neutral-700 dark:text-neutral-200", children: "Conversations" }),
|
|
1138
|
+
onNewConversation && /* @__PURE__ */ jsx(
|
|
1139
|
+
"button",
|
|
1140
|
+
{
|
|
1141
|
+
type: "button",
|
|
1142
|
+
onClick: onNewConversation,
|
|
1143
|
+
"aria-label": "New conversation",
|
|
1144
|
+
className: "rounded-md px-2 py-1 text-lg leading-none text-neutral-500 hover:bg-neutral-100 dark:hover:bg-neutral-800",
|
|
1145
|
+
children: "+"
|
|
1146
|
+
}
|
|
1147
|
+
)
|
|
1148
|
+
] }),
|
|
1149
|
+
/* @__PURE__ */ jsx(
|
|
1150
|
+
"div",
|
|
1151
|
+
{
|
|
1152
|
+
"data-slot": "superchat-conversation-list",
|
|
1153
|
+
role: "list",
|
|
1154
|
+
className: "flex-1 space-y-1 overflow-y-auto px-2 pb-2",
|
|
1155
|
+
children: sortedConversations.map((c) => {
|
|
1156
|
+
const last = lastMessageByTime(c.thread);
|
|
1157
|
+
const isActive = c.id === activeId;
|
|
1158
|
+
return /* @__PURE__ */ jsx("div", { role: "listitem", children: /* @__PURE__ */ jsxs(
|
|
1159
|
+
"button",
|
|
1160
|
+
{
|
|
1161
|
+
type: "button",
|
|
1162
|
+
"aria-current": isActive ? "true" : void 0,
|
|
1163
|
+
onClick: () => selectConversation(c),
|
|
1164
|
+
className: sidebarItem({ active: isActive }),
|
|
1165
|
+
children: [
|
|
1166
|
+
/* @__PURE__ */ jsxs("span", { className: "flex-1 truncate", children: [
|
|
1167
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate font-medium", children: c.title }),
|
|
1168
|
+
last?.text && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-neutral-400", children: last.text })
|
|
1169
|
+
] }),
|
|
1170
|
+
!!c.unread && /* @__PURE__ */ jsxs("span", { className: "bg-primary-600 ml-1 inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-[10px] font-semibold text-white", children: [
|
|
1171
|
+
c.unread,
|
|
1172
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: " unread messages" })
|
|
1173
|
+
] })
|
|
1174
|
+
]
|
|
1175
|
+
}
|
|
1176
|
+
) }, c.id);
|
|
1177
|
+
})
|
|
1178
|
+
}
|
|
1179
|
+
)
|
|
1180
|
+
]
|
|
1181
|
+
}
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1184
|
+
function SuperChatInbox({
|
|
1185
|
+
conversations,
|
|
1186
|
+
activeConversationId,
|
|
1187
|
+
defaultActiveConversationId,
|
|
1188
|
+
currentParticipantId,
|
|
1189
|
+
renderPlugins,
|
|
1190
|
+
renderTextContent,
|
|
1191
|
+
trustedContent,
|
|
1192
|
+
readOnly,
|
|
1193
|
+
acceptedFileTypes,
|
|
1194
|
+
order,
|
|
1195
|
+
virtualized,
|
|
1196
|
+
showSidebar = true,
|
|
1197
|
+
linkBuilder,
|
|
1198
|
+
className,
|
|
1199
|
+
onMessageSent,
|
|
1200
|
+
onMessageEdited,
|
|
1201
|
+
onConversationOpened,
|
|
1202
|
+
onConversationClosed,
|
|
1203
|
+
onNewConversation,
|
|
1204
|
+
onReferenceClick
|
|
1205
|
+
}) {
|
|
1206
|
+
const [internalActive, setInternalActive] = React4.useState(
|
|
1207
|
+
defaultActiveConversationId ?? conversations[0]?.id
|
|
1208
|
+
);
|
|
1209
|
+
const requestedId = activeConversationId ?? internalActive;
|
|
1210
|
+
const active = conversations.find((c) => c.id === requestedId) ?? conversations[0];
|
|
1211
|
+
const activeId = active?.id;
|
|
1212
|
+
const [mobileView, setMobileView] = React4.useState("list");
|
|
1213
|
+
const handleOpen = (c) => {
|
|
1214
|
+
if (activeConversationId === void 0) setInternalActive(c.id);
|
|
1215
|
+
setMobileView("chat");
|
|
1216
|
+
onConversationOpened?.(c);
|
|
1217
|
+
};
|
|
1218
|
+
return /* @__PURE__ */ jsxs(
|
|
1219
|
+
"div",
|
|
1220
|
+
{
|
|
1221
|
+
"data-slot": "superchat-inbox",
|
|
1222
|
+
role: "group",
|
|
1223
|
+
"aria-label": active ? `Chat: ${active.title}` : "Chat",
|
|
1224
|
+
className: cn(
|
|
1225
|
+
"flex h-full overflow-hidden rounded-xl border border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-900",
|
|
1226
|
+
className
|
|
1227
|
+
),
|
|
1228
|
+
children: [
|
|
1229
|
+
showSidebar && /* @__PURE__ */ jsx(
|
|
1230
|
+
SuperChatConversations,
|
|
1231
|
+
{
|
|
1232
|
+
conversations,
|
|
1233
|
+
activeConversationId: activeId,
|
|
1234
|
+
onConversationOpened: handleOpen,
|
|
1235
|
+
onNewConversation,
|
|
1236
|
+
className: cn(
|
|
1237
|
+
"w-full sm:w-64",
|
|
1238
|
+
mobileView === "chat" && "hidden sm:flex"
|
|
1239
|
+
)
|
|
1240
|
+
}
|
|
1241
|
+
),
|
|
1242
|
+
active ? /* @__PURE__ */ jsx(
|
|
1243
|
+
SuperChat,
|
|
1244
|
+
{
|
|
1245
|
+
conversation: active,
|
|
1246
|
+
currentParticipantId,
|
|
1247
|
+
renderPlugins,
|
|
1248
|
+
renderTextContent,
|
|
1249
|
+
trustedContent,
|
|
1250
|
+
readOnly,
|
|
1251
|
+
acceptedFileTypes,
|
|
1252
|
+
order,
|
|
1253
|
+
virtualized,
|
|
1254
|
+
linkBuilder,
|
|
1255
|
+
onMessageSent,
|
|
1256
|
+
onMessageEdited,
|
|
1257
|
+
onConversationClosed,
|
|
1258
|
+
onReferenceClick,
|
|
1259
|
+
onBack: showSidebar ? () => setMobileView("list") : void 0,
|
|
1260
|
+
className: cn(
|
|
1261
|
+
showSidebar && mobileView === "list" && "hidden sm:flex"
|
|
1262
|
+
)
|
|
1263
|
+
}
|
|
1264
|
+
) : /* @__PURE__ */ jsx(
|
|
1265
|
+
"section",
|
|
1266
|
+
{
|
|
1267
|
+
"data-slot": "superchat",
|
|
1268
|
+
className: cn(
|
|
1269
|
+
"min-w-0 flex-1 items-center justify-center text-sm text-neutral-400",
|
|
1270
|
+
showSidebar && mobileView === "list" ? "hidden sm:flex" : "flex"
|
|
1271
|
+
),
|
|
1272
|
+
children: "No conversation selected"
|
|
1273
|
+
}
|
|
1274
|
+
)
|
|
1275
|
+
]
|
|
1276
|
+
}
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
export { SuperChat, SuperChatConversations, SuperChatInbox, createMarkdownRenderer };
|
|
1281
|
+
//# sourceMappingURL=index.js.map
|
|
1282
|
+
//# sourceMappingURL=index.js.map
|