@pactor-app/ui 1.21.0 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7WB4TS55.js → chunk-44DAGWXZ.js} +2 -0
- package/dist/{chunk-2A5MHANX.js → chunk-QQBAMERO.js} +1 -1
- package/dist/{chunk-XXOY57SN.js → chunk-VTCNWVKQ.js} +1074 -263
- package/dist/components/index.cjs +1063 -261
- package/dist/components/index.d.cts +181 -55
- package/dist/components/index.d.ts +181 -55
- package/dist/components/index.js +2 -2
- package/dist/index.cjs +1213 -411
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/layout/index.cjs +1 -0
- package/dist/layout/index.js +2 -2
- package/package.json +6 -6
- package/styles.css +66 -0
|
@@ -486,6 +486,7 @@ var ICONS = {
|
|
|
486
486
|
"file-text": import_lucide_react2.FileText,
|
|
487
487
|
"panel-left": import_lucide_react2.PanelLeft,
|
|
488
488
|
"panel-right-open": import_lucide_react2.PanelRightOpen,
|
|
489
|
+
"panel-right-close": import_lucide_react2.PanelRightClose,
|
|
489
490
|
square: import_lucide_react2.Square,
|
|
490
491
|
history: import_lucide_react2.History,
|
|
491
492
|
"rotate-ccw": import_lucide_react2.RotateCcw,
|
|
@@ -3053,6 +3054,7 @@ function ChatInput({
|
|
|
3053
3054
|
toolbarEnd,
|
|
3054
3055
|
header,
|
|
3055
3056
|
footer,
|
|
3057
|
+
field,
|
|
3056
3058
|
onChange,
|
|
3057
3059
|
onSubmit,
|
|
3058
3060
|
className,
|
|
@@ -3063,6 +3065,8 @@ function ChatInput({
|
|
|
3063
3065
|
const [draft, setDraft] = (0, import_react14.useState)("");
|
|
3064
3066
|
const text = controlled ? value : draft;
|
|
3065
3067
|
const canSubmit = !disabled && text.trim() !== "";
|
|
3068
|
+
const customField = field !== void 0 && field !== null;
|
|
3069
|
+
const renderSlot = (slot) => (0, import_react14.isValidElement)(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
3066
3070
|
const composingRef = (0, import_react14.useRef)(false);
|
|
3067
3071
|
const handleChange = (next) => {
|
|
3068
3072
|
if (!controlled) {
|
|
@@ -3098,8 +3102,8 @@ function ChatInput({
|
|
|
3098
3102
|
),
|
|
3099
3103
|
style,
|
|
3100
3104
|
children: [
|
|
3101
|
-
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "px-3 pt-3", children:
|
|
3102
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
3105
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "px-3 pt-3", children: renderSlot(header) }) : null,
|
|
3106
|
+
customField ? field : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
3103
3107
|
Textarea,
|
|
3104
3108
|
{
|
|
3105
3109
|
value: text,
|
|
@@ -3114,9 +3118,9 @@ function ChatInput({
|
|
|
3114
3118
|
}
|
|
3115
3119
|
),
|
|
3116
3120
|
toolbarStart || toolbarEnd || !hideSend ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1 px-2 pb-2", children: [
|
|
3117
|
-
toolbarStart ?
|
|
3121
|
+
toolbarStart ? renderSlot(toolbarStart) : null,
|
|
3118
3122
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1" }),
|
|
3119
|
-
toolbarEnd ?
|
|
3123
|
+
toolbarEnd ? renderSlot(toolbarEnd) : null,
|
|
3120
3124
|
hideSend ? null : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
3121
3125
|
Button,
|
|
3122
3126
|
{
|
|
@@ -3130,7 +3134,7 @@ function ChatInput({
|
|
|
3130
3134
|
}
|
|
3131
3135
|
)
|
|
3132
3136
|
] }) : null,
|
|
3133
|
-
footer ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-t border-border px-3 py-2", children:
|
|
3137
|
+
footer ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-t border-border px-3 py-2", children: renderSlot(footer) }) : null
|
|
3134
3138
|
]
|
|
3135
3139
|
}
|
|
3136
3140
|
);
|
|
@@ -3682,7 +3686,8 @@ function DatePicker(props) {
|
|
|
3682
3686
|
onSelect: handleRangeDaySelect,
|
|
3683
3687
|
modifiers: rangeModifiers,
|
|
3684
3688
|
modifiersClassNames: rangeModifierClassNames,
|
|
3685
|
-
locale: dfLocale
|
|
3689
|
+
locale: dfLocale,
|
|
3690
|
+
showOutsideDays: false
|
|
3686
3691
|
}
|
|
3687
3692
|
)
|
|
3688
3693
|
}
|
|
@@ -3696,7 +3701,8 @@ function DatePicker(props) {
|
|
|
3696
3701
|
onSelect: handleRangeDaySelect,
|
|
3697
3702
|
modifiers: rangeModifiers,
|
|
3698
3703
|
modifiersClassNames: rangeModifierClassNames,
|
|
3699
|
-
locale: dfLocale
|
|
3704
|
+
locale: dfLocale,
|
|
3705
|
+
showOutsideDays: false
|
|
3700
3706
|
}
|
|
3701
3707
|
) })
|
|
3702
3708
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
@@ -11735,7 +11741,14 @@ function ArtifactTreeRow({
|
|
|
11735
11741
|
className: "flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-accent",
|
|
11736
11742
|
onClick: () => setOpen((value) => !value),
|
|
11737
11743
|
children: [
|
|
11738
|
-
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
|
|
11744
|
+
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
|
|
11745
|
+
"span",
|
|
11746
|
+
{
|
|
11747
|
+
className: "inline-flex transition-transform data-[open=true]:rotate-90",
|
|
11748
|
+
"data-open": open,
|
|
11749
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(Icon, { name: "chevron-right", size: 12 })
|
|
11750
|
+
}
|
|
11751
|
+
),
|
|
11739
11752
|
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)(Icon, { name: "folder", size: 13 }),
|
|
11740
11753
|
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)("span", { className: "min-w-0 flex-1 truncate", children: node.name })
|
|
11741
11754
|
]
|
|
@@ -11867,6 +11880,7 @@ function ArtifactPanel({
|
|
|
11867
11880
|
icon: "download",
|
|
11868
11881
|
variant: "text",
|
|
11869
11882
|
tooltip: "\u4E0B\u8F7D\u4EA7\u7269",
|
|
11883
|
+
className: "px-2",
|
|
11870
11884
|
onClick: () => onDownload ? onDownload(artifact) : void downloadArtifact(artifact)
|
|
11871
11885
|
}
|
|
11872
11886
|
) : null,
|
|
@@ -11876,11 +11890,12 @@ function ArtifactPanel({
|
|
|
11876
11890
|
icon: "x",
|
|
11877
11891
|
variant: "text",
|
|
11878
11892
|
tooltip: "\u6536\u8D77\u4EA7\u7269\u533A",
|
|
11893
|
+
className: "px-2",
|
|
11879
11894
|
onClick: () => onClose?.()
|
|
11880
11895
|
}
|
|
11881
11896
|
)
|
|
11882
11897
|
] }),
|
|
11883
|
-
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)("div", { className: "min-h-0 flex-1 overflow-auto p-4", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
|
|
11898
|
+
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)("div", { className: "scrollbar-subtle min-h-0 flex-1 overflow-auto p-4", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
|
|
11884
11899
|
ArtifactListView,
|
|
11885
11900
|
{
|
|
11886
11901
|
nodes: buildArtifactTree(artifacts),
|
|
@@ -12138,7 +12153,7 @@ function Thinking({
|
|
|
12138
12153
|
{
|
|
12139
12154
|
"data-slot": "thinking",
|
|
12140
12155
|
"data-status": status,
|
|
12141
|
-
className: cn("w-full
|
|
12156
|
+
className: cn("w-full", className),
|
|
12142
12157
|
style,
|
|
12143
12158
|
children: [
|
|
12144
12159
|
/* @__PURE__ */ (0, import_jsx_runtime176.jsxs)(
|
|
@@ -12147,12 +12162,12 @@ function Thinking({
|
|
|
12147
12162
|
type: "button",
|
|
12148
12163
|
"data-slot": "thinking-trigger",
|
|
12149
12164
|
"aria-expanded": isExpanded,
|
|
12150
|
-
className: "flex w-full items-center gap-2
|
|
12165
|
+
className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
|
|
12151
12166
|
onClick: toggle,
|
|
12152
12167
|
children: [
|
|
12153
12168
|
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { className: cn("text-muted-foreground", status === "thinking" && "animate-pulse motion-reduce:animate-none"), children: /* @__PURE__ */ (0, import_jsx_runtime176.jsx)(Icon, { name: "brain", size: "sm" }) }),
|
|
12154
|
-
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { "data-slot": "thinking-title", className: "
|
|
12155
|
-
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" })
|
|
12169
|
+
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { "data-slot": "thinking-title", className: "text-muted-foreground", children: resolvedTitle }),
|
|
12170
|
+
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { className: "text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime176.jsx)(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" }) })
|
|
12156
12171
|
]
|
|
12157
12172
|
}
|
|
12158
12173
|
),
|
|
@@ -12160,7 +12175,7 @@ function Thinking({
|
|
|
12160
12175
|
"div",
|
|
12161
12176
|
{
|
|
12162
12177
|
"data-slot": "thinking-content",
|
|
12163
|
-
className: "
|
|
12178
|
+
className: "py-1 pl-6 text-sm whitespace-pre-wrap text-muted-foreground",
|
|
12164
12179
|
children: content
|
|
12165
12180
|
}
|
|
12166
12181
|
) : null
|
|
@@ -12190,42 +12205,51 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
|
|
|
12190
12205
|
const [expanded, setExpanded] = (0, import_react62.useState)(defaultExpanded ?? status === "running");
|
|
12191
12206
|
const meta = statusIcon3[status];
|
|
12192
12207
|
const paramsText = renderValue(params);
|
|
12208
|
+
const hasDetail = Boolean(paramsText) || Boolean(result);
|
|
12209
|
+
const headerInner = /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)(import_jsx_runtime177.Fragment, { children: [
|
|
12210
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: "terminal", size: "sm" }) }),
|
|
12211
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("span", { "data-slot": "tool-call-name", className: "min-w-0 truncate font-medium", children: name ?? "\u5DE5\u5177\u8C03\u7528" }),
|
|
12212
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("span", { className: cn("shrink-0", meta.className, meta.spin && "animate-spin motion-reduce:animate-none"), children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: meta.icon, size: "sm" }) }),
|
|
12213
|
+
durationMs !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
12214
|
+
(durationMs / 1e3).toFixed(1),
|
|
12215
|
+
"s"
|
|
12216
|
+
] }) : null,
|
|
12217
|
+
hasDetail ? /* @__PURE__ */ (0, import_jsx_runtime177.jsx)("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" }) }) : null
|
|
12218
|
+
] });
|
|
12193
12219
|
return /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)(
|
|
12194
12220
|
"div",
|
|
12195
12221
|
{
|
|
12196
12222
|
"data-slot": "tool-call",
|
|
12197
12223
|
"data-status": status,
|
|
12198
|
-
className: cn("w-full
|
|
12224
|
+
className: cn("w-full", className),
|
|
12199
12225
|
style,
|
|
12200
12226
|
children: [
|
|
12201
|
-
/* @__PURE__ */ (0, import_jsx_runtime177.
|
|
12227
|
+
hasDetail ? /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(
|
|
12202
12228
|
"button",
|
|
12203
12229
|
{
|
|
12204
12230
|
type: "button",
|
|
12205
12231
|
"data-slot": "tool-call-trigger",
|
|
12206
12232
|
"aria-expanded": expanded,
|
|
12207
|
-
className: "flex w-full items-center gap-2
|
|
12233
|
+
className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
|
|
12208
12234
|
onClick: () => setExpanded((value) => !value),
|
|
12209
|
-
children:
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
|
|
12213
|
-
|
|
12214
|
-
|
|
12215
|
-
|
|
12216
|
-
|
|
12217
|
-
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" })
|
|
12218
|
-
]
|
|
12235
|
+
children: headerInner
|
|
12236
|
+
}
|
|
12237
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(
|
|
12238
|
+
"div",
|
|
12239
|
+
{
|
|
12240
|
+
"data-slot": "tool-call-trigger",
|
|
12241
|
+
className: "flex w-full items-center gap-2 py-1 text-left text-sm",
|
|
12242
|
+
children: headerInner
|
|
12219
12243
|
}
|
|
12220
12244
|
),
|
|
12221
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { "data-slot": "tool-call-body", className: "flex flex-col gap-2
|
|
12245
|
+
hasDetail && expanded ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { "data-slot": "tool-call-body", className: "flex flex-col gap-2 py-1 pl-6", children: [
|
|
12222
12246
|
paramsText ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { children: [
|
|
12223
12247
|
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("div", { className: "text-xs font-medium text-muted-foreground", children: "\u53C2\u6570" }),
|
|
12224
|
-
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("pre", { "data-slot": "tool-call-params", className: "mt-1 overflow-x-auto
|
|
12248
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("pre", { "data-slot": "tool-call-params", className: "mt-1 overflow-x-auto text-xs whitespace-pre-wrap text-muted-foreground", children: paramsText })
|
|
12225
12249
|
] }) : null,
|
|
12226
12250
|
result ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { children: [
|
|
12227
12251
|
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("div", { className: "text-xs font-medium text-muted-foreground", children: "\u7ED3\u679C" }),
|
|
12228
|
-
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("pre", { "data-slot": "tool-call-result", className: "mt-1 overflow-x-auto
|
|
12252
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("pre", { "data-slot": "tool-call-result", className: "mt-1 overflow-x-auto text-xs whitespace-pre-wrap text-muted-foreground", children: result })
|
|
12229
12253
|
] }) : null
|
|
12230
12254
|
] }) : null
|
|
12231
12255
|
]
|
|
@@ -12235,12 +12259,26 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
|
|
|
12235
12259
|
|
|
12236
12260
|
// src/components/chat/ChatMessage/index.tsx
|
|
12237
12261
|
var import_jsx_runtime178 = require("react/jsx-runtime");
|
|
12238
|
-
function PartView({
|
|
12262
|
+
function PartView({
|
|
12263
|
+
part,
|
|
12264
|
+
role,
|
|
12265
|
+
onOpenArtifacts
|
|
12266
|
+
}) {
|
|
12267
|
+
if (role === "system" && (part.type === "text" || part.type === "markdown")) {
|
|
12268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
|
|
12269
|
+
"div",
|
|
12270
|
+
{
|
|
12271
|
+
"data-slot": "chat-message-system-part",
|
|
12272
|
+
className: "w-full text-center text-xs text-muted-foreground",
|
|
12273
|
+
children: part.type === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(import_markdown2.MarkdownDslComponent, { content: part.content }) : part.content
|
|
12274
|
+
}
|
|
12275
|
+
);
|
|
12276
|
+
}
|
|
12239
12277
|
switch (part.type) {
|
|
12240
12278
|
case "text":
|
|
12241
12279
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "muted", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)("span", { className: "text-sm whitespace-pre-wrap", children: part.content }) });
|
|
12242
12280
|
case "markdown":
|
|
12243
|
-
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "ghost", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(import_markdown2.MarkdownDslComponent, { content: part.content
|
|
12281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "ghost", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(import_markdown2.MarkdownDslComponent, { content: part.content }) });
|
|
12244
12282
|
case "thinking":
|
|
12245
12283
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Thinking, { content: part.content, status: part.status ?? "done" });
|
|
12246
12284
|
case "tool-call":
|
|
@@ -12248,10 +12286,31 @@ function PartView({ part, role }) {
|
|
|
12248
12286
|
case "tool-result":
|
|
12249
12287
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)("pre", { "data-slot": "chat-message-tool-result", className: "overflow-x-auto rounded-md bg-muted p-2 text-xs whitespace-pre-wrap", children: part.content });
|
|
12250
12288
|
case "status":
|
|
12251
|
-
return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-status", className: "flex items-center gap-1.5 text-
|
|
12289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-status", className: "flex w-fit items-center gap-1.5 text-muted-foreground", children: [
|
|
12252
12290
|
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "clock", size: "sm" }),
|
|
12253
12291
|
part.text
|
|
12254
12292
|
] });
|
|
12293
|
+
case "artifacts": {
|
|
12294
|
+
const artifactsClass = "flex w-fit items-center gap-1.5 text-muted-foreground";
|
|
12295
|
+
const label = `\u5DF2\u751F\u6210 ${part.count} \u4E2A\u4EA7\u7269`;
|
|
12296
|
+
return onOpenArtifacts ? /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)(
|
|
12297
|
+
"button",
|
|
12298
|
+
{
|
|
12299
|
+
type: "button",
|
|
12300
|
+
"data-slot": "chat-message-artifacts",
|
|
12301
|
+
className: cn(artifactsClass, "cursor-pointer hover:text-foreground"),
|
|
12302
|
+
onClick: onOpenArtifacts,
|
|
12303
|
+
children: [
|
|
12304
|
+
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "package", size: "sm" }),
|
|
12305
|
+
label,
|
|
12306
|
+
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "chevron-right", size: 12 })
|
|
12307
|
+
]
|
|
12308
|
+
}
|
|
12309
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-artifacts", className: artifactsClass, children: [
|
|
12310
|
+
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "package", size: "sm" }),
|
|
12311
|
+
label
|
|
12312
|
+
] });
|
|
12313
|
+
}
|
|
12255
12314
|
case "error":
|
|
12256
12315
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-error", className: "flex items-center gap-1.5 text-sm text-destructive", children: [
|
|
12257
12316
|
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "circle-alert", size: "sm" }),
|
|
@@ -12261,19 +12320,31 @@ function PartView({ part, role }) {
|
|
|
12261
12320
|
return null;
|
|
12262
12321
|
}
|
|
12263
12322
|
}
|
|
12323
|
+
var ACTION_ICON_BY_NAME = {
|
|
12324
|
+
copy: "copy",
|
|
12325
|
+
retry: "rotate-ccw",
|
|
12326
|
+
regenerate: "refresh-ccw",
|
|
12327
|
+
edit: "pencil",
|
|
12328
|
+
like: "thumbs-up",
|
|
12329
|
+
dislike: "thumbs-down",
|
|
12330
|
+
share: "share",
|
|
12331
|
+
delete: "trash"
|
|
12332
|
+
};
|
|
12264
12333
|
function ChatMessage({
|
|
12265
12334
|
role = "assistant",
|
|
12266
12335
|
parts = [],
|
|
12267
12336
|
status = "completed",
|
|
12268
12337
|
agent,
|
|
12269
12338
|
time,
|
|
12270
|
-
showSender =
|
|
12339
|
+
showSender = false,
|
|
12271
12340
|
actions = [],
|
|
12272
12341
|
onAction,
|
|
12342
|
+
onOpenArtifacts,
|
|
12273
12343
|
className,
|
|
12274
12344
|
style
|
|
12275
12345
|
}) {
|
|
12276
12346
|
const isUser = role === "user";
|
|
12347
|
+
const isSystem = role === "system";
|
|
12277
12348
|
const senderName = isUser ? "\u6211" : agent?.name ?? "\u52A9\u624B";
|
|
12278
12349
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)(
|
|
12279
12350
|
"div",
|
|
@@ -12281,10 +12352,16 @@ function ChatMessage({
|
|
|
12281
12352
|
"data-slot": "chat-message",
|
|
12282
12353
|
"data-role": role,
|
|
12283
12354
|
"data-status": status,
|
|
12284
|
-
className: cn(
|
|
12355
|
+
className: cn(
|
|
12356
|
+
"flex w-full flex-col gap-1.5",
|
|
12357
|
+
isUser && "items-end",
|
|
12358
|
+
// system 居中弱提示(参考 @pactor-app/chat MessageBubble)
|
|
12359
|
+
isSystem && "items-center text-muted-foreground",
|
|
12360
|
+
className
|
|
12361
|
+
),
|
|
12285
12362
|
style,
|
|
12286
12363
|
children: [
|
|
12287
|
-
showSender
|
|
12364
|
+
showSender ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
|
|
12288
12365
|
Sender,
|
|
12289
12366
|
{
|
|
12290
12367
|
name: senderName,
|
|
@@ -12293,35 +12370,445 @@ function ChatMessage({
|
|
|
12293
12370
|
align: isUser ? "end" : "start"
|
|
12294
12371
|
}
|
|
12295
12372
|
) : null,
|
|
12296
|
-
/* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { className: cn("flex min-w-0 w-full max-w-full flex-col gap-2", isUser && "items-end"), children: [
|
|
12297
|
-
parts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(PartView, { part, role }, index)),
|
|
12373
|
+
/* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { className: cn("flex min-w-0 w-full max-w-full flex-col gap-2", isUser && "items-end", isSystem && "items-center"), children: [
|
|
12374
|
+
parts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(PartView, { part, role, onOpenArtifacts }, index)),
|
|
12298
12375
|
status === "streaming" ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(StreamingText, { content: "", streaming: true }) : null
|
|
12299
12376
|
] }),
|
|
12300
|
-
actions.length > 0 && (status === "completed" || status === "error") ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)("div", { "data-slot": "chat-message-actions", className: "flex items-center gap-1", children: actions.map((action) =>
|
|
12301
|
-
|
|
12302
|
-
|
|
12303
|
-
|
|
12304
|
-
|
|
12305
|
-
|
|
12306
|
-
|
|
12307
|
-
|
|
12308
|
-
|
|
12309
|
-
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12377
|
+
actions.length > 0 && (status === "completed" || status === "error") ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)("div", { "data-slot": "chat-message-actions", className: "flex items-center gap-1 mt-2", children: actions.map((action) => {
|
|
12378
|
+
const label = action.label ?? action.name;
|
|
12379
|
+
const iconName = action.icon ?? ACTION_ICON_BY_NAME[action.name];
|
|
12380
|
+
if (iconName) {
|
|
12381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Tooltip2, { content: label, side: "top", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
|
|
12382
|
+
"button",
|
|
12383
|
+
{
|
|
12384
|
+
type: "button",
|
|
12385
|
+
"data-slot": "chat-message-action",
|
|
12386
|
+
"data-action": action.name,
|
|
12387
|
+
"aria-label": label,
|
|
12388
|
+
className: "flex cursor-pointer items-center rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
12389
|
+
onClick: () => onAction?.(action.name),
|
|
12390
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: iconName, size: "sm" })
|
|
12391
|
+
}
|
|
12392
|
+
) }, action.name);
|
|
12393
|
+
}
|
|
12394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
|
|
12395
|
+
"button",
|
|
12396
|
+
{
|
|
12397
|
+
type: "button",
|
|
12398
|
+
"data-slot": "chat-message-action",
|
|
12399
|
+
"data-action": action.name,
|
|
12400
|
+
className: "flex items-center cursor-pointer gap-1 rounded-sm px-1.5 py-0.5 text-xs text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
12401
|
+
onClick: () => onAction?.(action.name),
|
|
12402
|
+
children: label
|
|
12403
|
+
},
|
|
12404
|
+
action.name
|
|
12405
|
+
);
|
|
12406
|
+
}) }) : null
|
|
12315
12407
|
]
|
|
12316
12408
|
}
|
|
12317
12409
|
);
|
|
12318
12410
|
}
|
|
12319
12411
|
|
|
12320
12412
|
// src/components/chat/ChatPage/index.tsx
|
|
12321
|
-
var
|
|
12413
|
+
var import_runtime26 = require("@pactor-app/runtime");
|
|
12414
|
+
var import_react67 = require("react");
|
|
12322
12415
|
|
|
12323
12416
|
// src/components/chat/Composer/index.tsx
|
|
12417
|
+
var import_react64 = require("react");
|
|
12418
|
+
|
|
12419
|
+
// src/components/chat/Composer/mention-input.tsx
|
|
12420
|
+
var import_react63 = require("react");
|
|
12421
|
+
var import_server = require("react-dom/server");
|
|
12324
12422
|
var import_jsx_runtime179 = require("react/jsx-runtime");
|
|
12423
|
+
var NBSP = "\xA0";
|
|
12424
|
+
var CHIP_ATTR = "data-mention-chip";
|
|
12425
|
+
function escapeRegExp(text) {
|
|
12426
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12427
|
+
}
|
|
12428
|
+
function isChipElement(node) {
|
|
12429
|
+
return node instanceof HTMLElement && node.hasAttribute(CHIP_ATTR);
|
|
12430
|
+
}
|
|
12431
|
+
function serializeNode(node) {
|
|
12432
|
+
let out = "";
|
|
12433
|
+
node.childNodes.forEach((child) => {
|
|
12434
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
12435
|
+
out += (child.textContent ?? "").replace(/\u00A0/g, " ");
|
|
12436
|
+
} else if (isChipElement(child)) {
|
|
12437
|
+
out += `${child.dataset["trigger"] ?? ""}${child.dataset["label"] ?? ""}`;
|
|
12438
|
+
} else if (child instanceof HTMLBRElement) {
|
|
12439
|
+
out += "\n";
|
|
12440
|
+
} else if (child instanceof HTMLElement) {
|
|
12441
|
+
const inner = serializeNode(child).replace(/\n$/, "");
|
|
12442
|
+
out += (out === "" || out.endsWith("\n") ? "" : "\n") + inner + "\n";
|
|
12443
|
+
}
|
|
12444
|
+
});
|
|
12445
|
+
return out;
|
|
12446
|
+
}
|
|
12447
|
+
function collectChips(field) {
|
|
12448
|
+
return Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).map((el) => ({
|
|
12449
|
+
id: el.dataset["id"] ?? "",
|
|
12450
|
+
label: el.dataset["label"] ?? "",
|
|
12451
|
+
trigger: el.dataset["trigger"] ?? ""
|
|
12452
|
+
}));
|
|
12453
|
+
}
|
|
12454
|
+
function detectActiveMention(field, sources) {
|
|
12455
|
+
const selection = window.getSelection();
|
|
12456
|
+
if (!selection || selection.rangeCount === 0 || !selection.isCollapsed) {
|
|
12457
|
+
return null;
|
|
12458
|
+
}
|
|
12459
|
+
const anchor = selection.anchorNode;
|
|
12460
|
+
if (!anchor || anchor.nodeType !== Node.TEXT_NODE || !field.contains(anchor)) {
|
|
12461
|
+
return null;
|
|
12462
|
+
}
|
|
12463
|
+
const caretOffset = selection.anchorOffset;
|
|
12464
|
+
const beforeCaret = (anchor.textContent ?? "").slice(0, caretOffset);
|
|
12465
|
+
for (const source of sources) {
|
|
12466
|
+
const trigger = source.trigger;
|
|
12467
|
+
const match = new RegExp(
|
|
12468
|
+
`(?:^|\\s)${escapeRegExp(trigger)}([^\\s${escapeRegExp(trigger)}]*)$`
|
|
12469
|
+
).exec(beforeCaret);
|
|
12470
|
+
if (match) {
|
|
12471
|
+
const query = match[1] ?? "";
|
|
12472
|
+
return {
|
|
12473
|
+
source,
|
|
12474
|
+
query,
|
|
12475
|
+
node: anchor,
|
|
12476
|
+
triggerStart: caretOffset - query.length - trigger.length,
|
|
12477
|
+
caretOffset
|
|
12478
|
+
};
|
|
12479
|
+
}
|
|
12480
|
+
}
|
|
12481
|
+
return null;
|
|
12482
|
+
}
|
|
12483
|
+
function chipIcon(item, source) {
|
|
12484
|
+
return item.icon ?? source.icon ?? (source.trigger === "@" ? "user" : "file-text");
|
|
12485
|
+
}
|
|
12486
|
+
var MentionInput = (0, import_react63.forwardRef)(
|
|
12487
|
+
function MentionInput2({
|
|
12488
|
+
value,
|
|
12489
|
+
placeholder,
|
|
12490
|
+
disabled,
|
|
12491
|
+
sources,
|
|
12492
|
+
chips,
|
|
12493
|
+
onChipsChange,
|
|
12494
|
+
onChange,
|
|
12495
|
+
onSubmit,
|
|
12496
|
+
className,
|
|
12497
|
+
style
|
|
12498
|
+
}, ref) {
|
|
12499
|
+
const fieldRef = (0, import_react63.useRef)(null);
|
|
12500
|
+
const [menu, setMenu] = (0, import_react63.useState)(null);
|
|
12501
|
+
const [empty, setEmpty] = (0, import_react63.useState)(true);
|
|
12502
|
+
const suppressSyncRef = (0, import_react63.useRef)(false);
|
|
12503
|
+
const composingRef = (0, import_react63.useRef)(false);
|
|
12504
|
+
const emitChips = () => {
|
|
12505
|
+
if (suppressSyncRef.current || !fieldRef.current) {
|
|
12506
|
+
return;
|
|
12507
|
+
}
|
|
12508
|
+
onChipsChange?.(collectChips(fieldRef.current));
|
|
12509
|
+
};
|
|
12510
|
+
const serialize = () => fieldRef.current ? serializeNode(fieldRef.current).replace(/\n$/, "") : "";
|
|
12511
|
+
const buildChipElement = (item, source) => {
|
|
12512
|
+
const chip = document.createElement("span");
|
|
12513
|
+
chip.setAttribute(CHIP_ATTR, "");
|
|
12514
|
+
chip.dataset["id"] = item.id;
|
|
12515
|
+
chip.dataset["label"] = item.label;
|
|
12516
|
+
chip.dataset["trigger"] = item.trigger ?? source.trigger;
|
|
12517
|
+
chip.contentEditable = "false";
|
|
12518
|
+
chip.className = "mx-0.5 inline-flex items-center gap-1 rounded-md bg-muted px-1.5 py-0.5 align-middle text-xs text-foreground";
|
|
12519
|
+
const iconMarkup = (0, import_server.renderToStaticMarkup)(
|
|
12520
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)(Icon, { name: chipIcon(item, source), size: 12 })
|
|
12521
|
+
);
|
|
12522
|
+
const label = document.createElement("span");
|
|
12523
|
+
label.textContent = item.label;
|
|
12524
|
+
chip.innerHTML = iconMarkup;
|
|
12525
|
+
chip.appendChild(label);
|
|
12526
|
+
return chip;
|
|
12527
|
+
};
|
|
12528
|
+
const insertChipElement = (item, source, replace) => {
|
|
12529
|
+
const field = fieldRef.current;
|
|
12530
|
+
if (!field) {
|
|
12531
|
+
return;
|
|
12532
|
+
}
|
|
12533
|
+
const chip = buildChipElement(item, source);
|
|
12534
|
+
let caretNode;
|
|
12535
|
+
if (replace) {
|
|
12536
|
+
const { node, start, end } = replace;
|
|
12537
|
+
const text = node.textContent ?? "";
|
|
12538
|
+
node.textContent = text.slice(0, start);
|
|
12539
|
+
caretNode = document.createTextNode(`${NBSP}${text.slice(end)}`);
|
|
12540
|
+
node.after(chip, caretNode);
|
|
12541
|
+
} else {
|
|
12542
|
+
caretNode = document.createTextNode(NBSP);
|
|
12543
|
+
const selection2 = window.getSelection();
|
|
12544
|
+
if (selection2 && selection2.rangeCount > 0 && selection2.anchorNode !== null && field.contains(selection2.anchorNode)) {
|
|
12545
|
+
const range = selection2.getRangeAt(0);
|
|
12546
|
+
range.deleteContents();
|
|
12547
|
+
range.insertNode(caretNode);
|
|
12548
|
+
range.insertNode(chip);
|
|
12549
|
+
} else {
|
|
12550
|
+
field.append(chip, caretNode);
|
|
12551
|
+
}
|
|
12552
|
+
}
|
|
12553
|
+
const selection = window.getSelection();
|
|
12554
|
+
if (selection) {
|
|
12555
|
+
const range = document.createRange();
|
|
12556
|
+
range.setStart(caretNode, 1);
|
|
12557
|
+
range.collapse(true);
|
|
12558
|
+
selection.removeAllRanges();
|
|
12559
|
+
selection.addRange(range);
|
|
12560
|
+
}
|
|
12561
|
+
setEmpty(false);
|
|
12562
|
+
onChange?.(serialize());
|
|
12563
|
+
emitChips();
|
|
12564
|
+
};
|
|
12565
|
+
(0, import_react63.useImperativeHandle)(ref, () => ({
|
|
12566
|
+
insertChip: (item, source) => {
|
|
12567
|
+
fieldRef.current?.focus();
|
|
12568
|
+
insertChipElement(item, source);
|
|
12569
|
+
},
|
|
12570
|
+
focus: () => fieldRef.current?.focus()
|
|
12571
|
+
}));
|
|
12572
|
+
(0, import_react63.useEffect)(() => {
|
|
12573
|
+
const field = fieldRef.current;
|
|
12574
|
+
if (field && value === "" && serializeNode(field).trim() !== "") {
|
|
12575
|
+
suppressSyncRef.current = true;
|
|
12576
|
+
field.innerHTML = "";
|
|
12577
|
+
setEmpty(true);
|
|
12578
|
+
setMenu(null);
|
|
12579
|
+
suppressSyncRef.current = false;
|
|
12580
|
+
}
|
|
12581
|
+
}, [value]);
|
|
12582
|
+
(0, import_react63.useEffect)(() => {
|
|
12583
|
+
const field = fieldRef.current;
|
|
12584
|
+
if (!field) {
|
|
12585
|
+
return;
|
|
12586
|
+
}
|
|
12587
|
+
const keep = new Set(chips.map((chip) => `${chip.trigger}:${chip.id}`));
|
|
12588
|
+
const stale = Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).filter(
|
|
12589
|
+
(el) => !keep.has(
|
|
12590
|
+
`${el.dataset["trigger"]}:${el.dataset["id"]}`
|
|
12591
|
+
)
|
|
12592
|
+
);
|
|
12593
|
+
if (stale.length > 0) {
|
|
12594
|
+
suppressSyncRef.current = true;
|
|
12595
|
+
stale.forEach((el) => el.remove());
|
|
12596
|
+
suppressSyncRef.current = false;
|
|
12597
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
12598
|
+
}
|
|
12599
|
+
}, [chips]);
|
|
12600
|
+
const closeMenu = () => setMenu(null);
|
|
12601
|
+
const filteredItems = (state) => state.query ? state.source.items.filter((item) => item.label.includes(state.query)) : state.source.items;
|
|
12602
|
+
const refreshMenu = () => {
|
|
12603
|
+
const field = fieldRef.current;
|
|
12604
|
+
if (!field) {
|
|
12605
|
+
return;
|
|
12606
|
+
}
|
|
12607
|
+
const active = detectActiveMention(field, sources);
|
|
12608
|
+
if (!active) {
|
|
12609
|
+
setMenu(null);
|
|
12610
|
+
return;
|
|
12611
|
+
}
|
|
12612
|
+
const range = document.createRange();
|
|
12613
|
+
range.setStart(active.node, active.triggerStart);
|
|
12614
|
+
range.setEnd(active.node, active.caretOffset);
|
|
12615
|
+
const rect = typeof range.getBoundingClientRect === "function" ? range.getBoundingClientRect() : field.getBoundingClientRect();
|
|
12616
|
+
setMenu((prev) => ({
|
|
12617
|
+
source: active.source,
|
|
12618
|
+
query: active.query,
|
|
12619
|
+
left: rect.left,
|
|
12620
|
+
top: rect.top,
|
|
12621
|
+
// 过滤结果变化后候选下标钳制在有效范围内(DSL 每次渲染产出新
|
|
12622
|
+
// props 对象,source 按 trigger 比较而非引用)
|
|
12623
|
+
activeIndex: Math.min(
|
|
12624
|
+
prev?.source.trigger === active.source.trigger ? prev.activeIndex : 0,
|
|
12625
|
+
Math.max(filteredItems({ source: active.source, query: active.query, left: 0, top: 0, activeIndex: 0 }).length - 1, 0)
|
|
12626
|
+
)
|
|
12627
|
+
}));
|
|
12628
|
+
};
|
|
12629
|
+
const selectMenuItem = (item) => {
|
|
12630
|
+
const field = fieldRef.current;
|
|
12631
|
+
if (!field || !menu) {
|
|
12632
|
+
return;
|
|
12633
|
+
}
|
|
12634
|
+
const active = detectActiveMention(field, sources);
|
|
12635
|
+
insertChipElement(
|
|
12636
|
+
{ ...item, trigger: item.trigger ?? menu.source.trigger },
|
|
12637
|
+
menu.source,
|
|
12638
|
+
active && active.source.trigger === menu.source.trigger ? { node: active.node, start: active.triggerStart, end: active.caretOffset } : void 0
|
|
12639
|
+
);
|
|
12640
|
+
setMenu(null);
|
|
12641
|
+
};
|
|
12642
|
+
const handleInput = () => {
|
|
12643
|
+
const field = fieldRef.current;
|
|
12644
|
+
if (!field) {
|
|
12645
|
+
return;
|
|
12646
|
+
}
|
|
12647
|
+
if ((field.textContent ?? "") === "" && field.querySelector(`[${CHIP_ATTR}]`) === null) {
|
|
12648
|
+
field.innerHTML = "";
|
|
12649
|
+
}
|
|
12650
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
12651
|
+
onChange?.(serialize());
|
|
12652
|
+
refreshMenu();
|
|
12653
|
+
};
|
|
12654
|
+
const handleKeyDown = (event) => {
|
|
12655
|
+
if (menu) {
|
|
12656
|
+
const items = filteredItems(menu);
|
|
12657
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
12658
|
+
event.preventDefault();
|
|
12659
|
+
if (items.length > 0) {
|
|
12660
|
+
const delta = event.key === "ArrowDown" ? 1 : -1;
|
|
12661
|
+
setMenu({
|
|
12662
|
+
...menu,
|
|
12663
|
+
activeIndex: (menu.activeIndex + delta + items.length) % items.length
|
|
12664
|
+
});
|
|
12665
|
+
}
|
|
12666
|
+
return;
|
|
12667
|
+
}
|
|
12668
|
+
if (event.key === "Enter" && !composingRef.current && !event.nativeEvent.isComposing) {
|
|
12669
|
+
event.preventDefault();
|
|
12670
|
+
const item = items[Math.min(menu.activeIndex, items.length - 1)];
|
|
12671
|
+
if (item) {
|
|
12672
|
+
selectMenuItem(item);
|
|
12673
|
+
} else {
|
|
12674
|
+
closeMenu();
|
|
12675
|
+
}
|
|
12676
|
+
return;
|
|
12677
|
+
}
|
|
12678
|
+
if (event.key === "Escape") {
|
|
12679
|
+
event.preventDefault();
|
|
12680
|
+
closeMenu();
|
|
12681
|
+
return;
|
|
12682
|
+
}
|
|
12683
|
+
}
|
|
12684
|
+
if (event.key === "Enter" && !event.shiftKey && !composingRef.current && !event.nativeEvent.isComposing) {
|
|
12685
|
+
event.preventDefault();
|
|
12686
|
+
const text = serialize();
|
|
12687
|
+
if (text.trim() !== "" && !disabled) {
|
|
12688
|
+
onSubmit?.(text);
|
|
12689
|
+
}
|
|
12690
|
+
return;
|
|
12691
|
+
}
|
|
12692
|
+
if (event.key === "Backspace") {
|
|
12693
|
+
const selection = window.getSelection();
|
|
12694
|
+
const field = fieldRef.current;
|
|
12695
|
+
if (!selection || !selection.isCollapsed || !field) {
|
|
12696
|
+
return;
|
|
12697
|
+
}
|
|
12698
|
+
let chip = null;
|
|
12699
|
+
const anchor = selection.anchorNode;
|
|
12700
|
+
if (anchor === field && selection.anchorOffset > 0) {
|
|
12701
|
+
const before = field.childNodes[selection.anchorOffset - 1];
|
|
12702
|
+
if (isChipElement(before)) {
|
|
12703
|
+
chip = before;
|
|
12704
|
+
}
|
|
12705
|
+
} else if (anchor?.nodeType === Node.TEXT_NODE && selection.anchorOffset === 0) {
|
|
12706
|
+
if (isChipElement(anchor.previousSibling)) {
|
|
12707
|
+
chip = anchor.previousSibling;
|
|
12708
|
+
}
|
|
12709
|
+
}
|
|
12710
|
+
if (chip) {
|
|
12711
|
+
event.preventDefault();
|
|
12712
|
+
chip.remove();
|
|
12713
|
+
onChange?.(serialize());
|
|
12714
|
+
emitChips();
|
|
12715
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
12716
|
+
}
|
|
12717
|
+
}
|
|
12718
|
+
};
|
|
12719
|
+
const menuItems = menu ? filteredItems(menu) : [];
|
|
12720
|
+
const activeIndex = Math.min(menu?.activeIndex ?? 0, Math.max(menuItems.length - 1, 0));
|
|
12721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)("div", { className: "relative", children: [
|
|
12722
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)(
|
|
12723
|
+
"div",
|
|
12724
|
+
{
|
|
12725
|
+
ref: fieldRef,
|
|
12726
|
+
"data-slot": "mention-input",
|
|
12727
|
+
role: "textbox",
|
|
12728
|
+
"aria-multiline": "true",
|
|
12729
|
+
"aria-placeholder": placeholder,
|
|
12730
|
+
contentEditable: !disabled,
|
|
12731
|
+
suppressContentEditableWarning: true,
|
|
12732
|
+
className: cn(
|
|
12733
|
+
"min-h-[60px] w-full px-4 pt-3 pb-1 text-sm whitespace-pre-wrap break-words outline-none",
|
|
12734
|
+
className
|
|
12735
|
+
),
|
|
12736
|
+
style,
|
|
12737
|
+
onInput: handleInput,
|
|
12738
|
+
onKeyDown: handleKeyDown,
|
|
12739
|
+
onCompositionStart: () => {
|
|
12740
|
+
composingRef.current = true;
|
|
12741
|
+
},
|
|
12742
|
+
onCompositionEnd: () => {
|
|
12743
|
+
composingRef.current = false;
|
|
12744
|
+
},
|
|
12745
|
+
onPaste: (event) => {
|
|
12746
|
+
event.preventDefault();
|
|
12747
|
+
const text = event.clipboardData?.getData("text/plain") ?? "";
|
|
12748
|
+
if (text) {
|
|
12749
|
+
document.execCommand("insertText", false, text);
|
|
12750
|
+
}
|
|
12751
|
+
}
|
|
12752
|
+
}
|
|
12753
|
+
),
|
|
12754
|
+
empty && placeholder !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime179.jsx)("span", { className: "pointer-events-none absolute top-3 left-4 text-sm text-muted-foreground", children: placeholder }) : null,
|
|
12755
|
+
menu ? /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)(import_jsx_runtime179.Fragment, { children: [
|
|
12756
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)(
|
|
12757
|
+
"div",
|
|
12758
|
+
{
|
|
12759
|
+
className: "fixed inset-0 z-40",
|
|
12760
|
+
onMouseDown: (event) => {
|
|
12761
|
+
event.preventDefault();
|
|
12762
|
+
closeMenu();
|
|
12763
|
+
}
|
|
12764
|
+
}
|
|
12765
|
+
),
|
|
12766
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsxs)(
|
|
12767
|
+
"div",
|
|
12768
|
+
{
|
|
12769
|
+
"data-slot": "mention-menu",
|
|
12770
|
+
role: "listbox",
|
|
12771
|
+
className: "scrollbar-subtle fixed z-50 max-h-72 w-64 overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md",
|
|
12772
|
+
style: {
|
|
12773
|
+
left: menu.left,
|
|
12774
|
+
bottom: typeof window === "undefined" ? void 0 : window.innerHeight - menu.top + 6
|
|
12775
|
+
},
|
|
12776
|
+
children: [
|
|
12777
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: menu.source.label }),
|
|
12778
|
+
menuItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime179.jsx)("div", { className: "px-2 py-2 text-xs text-muted-foreground", children: "\u65E0\u5339\u914D\u9879" }) : menuItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)(
|
|
12779
|
+
"button",
|
|
12780
|
+
{
|
|
12781
|
+
type: "button",
|
|
12782
|
+
role: "option",
|
|
12783
|
+
"aria-selected": index === activeIndex,
|
|
12784
|
+
className: cn(
|
|
12785
|
+
"flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm",
|
|
12786
|
+
index === activeIndex ? "bg-accent" : "hover:bg-accent"
|
|
12787
|
+
),
|
|
12788
|
+
onMouseDown: (event) => {
|
|
12789
|
+
event.preventDefault();
|
|
12790
|
+
selectMenuItem(item);
|
|
12791
|
+
},
|
|
12792
|
+
children: [
|
|
12793
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)(Icon, { name: chipIcon(item, menu.source), size: "sm" }),
|
|
12794
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
12795
|
+
]
|
|
12796
|
+
},
|
|
12797
|
+
item.id
|
|
12798
|
+
))
|
|
12799
|
+
]
|
|
12800
|
+
}
|
|
12801
|
+
)
|
|
12802
|
+
] }) : null
|
|
12803
|
+
] });
|
|
12804
|
+
}
|
|
12805
|
+
);
|
|
12806
|
+
|
|
12807
|
+
// src/components/chat/Composer/index.tsx
|
|
12808
|
+
var import_jsx_runtime180 = require("react/jsx-runtime");
|
|
12809
|
+
var toolButtonClass3 = "flex cursor-pointer items-center rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground";
|
|
12810
|
+
var popoverPanelClass = "absolute bottom-full left-0 z-50 mb-2 max-h-72 w-64 overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md";
|
|
12811
|
+
var popoverItemClass = "flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent";
|
|
12325
12812
|
function Composer({
|
|
12326
12813
|
value,
|
|
12327
12814
|
placeholder,
|
|
@@ -12331,35 +12818,238 @@ function Composer({
|
|
|
12331
12818
|
attachments = [],
|
|
12332
12819
|
onRemoveAttachment,
|
|
12333
12820
|
onRetryAttachment,
|
|
12821
|
+
onAttachFiles,
|
|
12334
12822
|
onChange,
|
|
12335
12823
|
onSubmit,
|
|
12824
|
+
models,
|
|
12825
|
+
model,
|
|
12826
|
+
onModelChange,
|
|
12827
|
+
contexts,
|
|
12828
|
+
contextItems,
|
|
12829
|
+
onContextItemsChange,
|
|
12830
|
+
footer,
|
|
12336
12831
|
className,
|
|
12337
12832
|
style
|
|
12338
12833
|
}) {
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12834
|
+
const textControlled = value !== void 0;
|
|
12835
|
+
const [innerText, setInnerText] = (0, import_react64.useState)("");
|
|
12836
|
+
const text = textControlled ? value : innerText;
|
|
12837
|
+
const [dragOver, setDragOver] = (0, import_react64.useState)(false);
|
|
12838
|
+
const [plusOpen, setPlusOpen] = (0, import_react64.useState)(false);
|
|
12839
|
+
const [modelOpen, setModelOpen] = (0, import_react64.useState)(false);
|
|
12840
|
+
const fileInputRef = (0, import_react64.useRef)(null);
|
|
12841
|
+
const mentionRef = (0, import_react64.useRef)(null);
|
|
12842
|
+
const sources = contexts ?? [];
|
|
12843
|
+
const rich = sources.length > 0;
|
|
12844
|
+
const plusSources = sources.filter((s) => s.trigger === "+");
|
|
12845
|
+
const plusEnabled = plusSources.length > 0;
|
|
12846
|
+
const modelEnabled = models !== void 0 && models.length > 0;
|
|
12847
|
+
const currentModel = models?.find((m) => m.value === model) ?? models?.[0];
|
|
12848
|
+
const chips = contextItems ?? [];
|
|
12849
|
+
const closePopovers = () => {
|
|
12850
|
+
setPlusOpen(false);
|
|
12851
|
+
setModelOpen(false);
|
|
12852
|
+
};
|
|
12853
|
+
const handleChange = (next) => {
|
|
12854
|
+
if (!textControlled) {
|
|
12855
|
+
setInnerText(next);
|
|
12856
|
+
}
|
|
12857
|
+
onChange?.(next);
|
|
12858
|
+
};
|
|
12859
|
+
const handleSubmit = (submitted) => {
|
|
12860
|
+
onSubmit?.(submitted);
|
|
12861
|
+
if (!textControlled) {
|
|
12862
|
+
setInnerText("");
|
|
12863
|
+
}
|
|
12864
|
+
closePopovers();
|
|
12865
|
+
};
|
|
12866
|
+
const selectContext = (item, source) => {
|
|
12867
|
+
if (rich) {
|
|
12868
|
+
mentionRef.current?.insertChip(item, source);
|
|
12869
|
+
} else {
|
|
12870
|
+
const chip = { ...item, trigger: item.trigger ?? source.trigger };
|
|
12871
|
+
const duplicated = chips.some(
|
|
12872
|
+
(existing) => existing.id === chip.id && existing.trigger === chip.trigger
|
|
12873
|
+
);
|
|
12874
|
+
if (!duplicated) {
|
|
12875
|
+
onContextItemsChange?.([...chips, chip]);
|
|
12876
|
+
}
|
|
12877
|
+
}
|
|
12878
|
+
closePopovers();
|
|
12879
|
+
};
|
|
12880
|
+
const emitFiles = (files) => {
|
|
12881
|
+
if (files.length > 0 && onAttachFiles) {
|
|
12882
|
+
onAttachFiles(files);
|
|
12883
|
+
}
|
|
12884
|
+
};
|
|
12885
|
+
const handleDrop = (event) => {
|
|
12886
|
+
if (!onAttachFiles) {
|
|
12887
|
+
return;
|
|
12888
|
+
}
|
|
12889
|
+
event.preventDefault();
|
|
12890
|
+
setDragOver(false);
|
|
12891
|
+
emitFiles(Array.from(event.dataTransfer?.files ?? []));
|
|
12892
|
+
};
|
|
12893
|
+
const toolbarStart = plusEnabled || onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(import_jsx_runtime180.Fragment, { children: [
|
|
12894
|
+
plusEnabled ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12895
|
+
"button",
|
|
12896
|
+
{
|
|
12897
|
+
type: "button",
|
|
12898
|
+
"aria-label": "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
12899
|
+
title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
12900
|
+
className: toolButtonClass3,
|
|
12901
|
+
onClick: () => {
|
|
12902
|
+
setPlusOpen((prev) => !prev);
|
|
12903
|
+
setModelOpen(false);
|
|
12904
|
+
},
|
|
12905
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "plus", size: "sm" })
|
|
12906
|
+
}
|
|
12907
|
+
) : null,
|
|
12908
|
+
onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12909
|
+
"button",
|
|
12343
12910
|
{
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12911
|
+
type: "button",
|
|
12912
|
+
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
12913
|
+
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
12914
|
+
className: toolButtonClass3,
|
|
12915
|
+
onClick: () => fileInputRef.current?.click(),
|
|
12916
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "paperclip", size: "sm" })
|
|
12350
12917
|
}
|
|
12351
|
-
)
|
|
12352
|
-
] });
|
|
12918
|
+
) : null
|
|
12919
|
+
] }) : void 0;
|
|
12920
|
+
const toolbarEnd = modelEnabled ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
|
|
12921
|
+
"button",
|
|
12922
|
+
{
|
|
12923
|
+
type: "button",
|
|
12924
|
+
"aria-label": "\u9009\u62E9\u6A21\u578B",
|
|
12925
|
+
title: "\u9009\u62E9\u6A21\u578B",
|
|
12926
|
+
className: "flex cursor-pointer items-center gap-1 rounded-md px-2 py-1 text-xs text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
12927
|
+
onClick: () => {
|
|
12928
|
+
setModelOpen((prev) => !prev);
|
|
12929
|
+
setPlusOpen(false);
|
|
12930
|
+
},
|
|
12931
|
+
children: [
|
|
12932
|
+
currentModel?.label,
|
|
12933
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "chevrons-up-down", size: 12 })
|
|
12934
|
+
]
|
|
12935
|
+
}
|
|
12936
|
+
) : void 0;
|
|
12937
|
+
const activePopover = plusOpen ? "plus" : modelOpen ? "model" : null;
|
|
12938
|
+
return /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
|
|
12939
|
+
"div",
|
|
12940
|
+
{
|
|
12941
|
+
"data-slot": "composer",
|
|
12942
|
+
className: cn("relative flex w-full flex-col gap-2", className),
|
|
12943
|
+
style,
|
|
12944
|
+
onDragOver: (event) => {
|
|
12945
|
+
if (onAttachFiles) {
|
|
12946
|
+
event.preventDefault();
|
|
12947
|
+
setDragOver(true);
|
|
12948
|
+
}
|
|
12949
|
+
},
|
|
12950
|
+
onDragLeave: () => setDragOver(false),
|
|
12951
|
+
onDrop: handleDrop,
|
|
12952
|
+
onPaste: (event) => {
|
|
12953
|
+
const files = Array.from(event.clipboardData?.files ?? []);
|
|
12954
|
+
if (files.length > 0 && onAttachFiles) {
|
|
12955
|
+
event.preventDefault();
|
|
12956
|
+
emitFiles(files);
|
|
12957
|
+
}
|
|
12958
|
+
},
|
|
12959
|
+
children: [
|
|
12960
|
+
attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Attachment, { items: attachments, onRemove: onRemoveAttachment, onRetry: onRetryAttachment }) : null,
|
|
12961
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: cn(dragOver && "rounded-xl ring-2 ring-ring/50"), children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12962
|
+
ChatInput,
|
|
12963
|
+
{
|
|
12964
|
+
value: text,
|
|
12965
|
+
placeholder,
|
|
12966
|
+
disabled: disabled || loading,
|
|
12967
|
+
rows,
|
|
12968
|
+
toolbarStart,
|
|
12969
|
+
toolbarEnd,
|
|
12970
|
+
footer,
|
|
12971
|
+
field: rich ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12972
|
+
MentionInput,
|
|
12973
|
+
{
|
|
12974
|
+
ref: mentionRef,
|
|
12975
|
+
value: text,
|
|
12976
|
+
placeholder,
|
|
12977
|
+
disabled: disabled || loading,
|
|
12978
|
+
sources,
|
|
12979
|
+
chips,
|
|
12980
|
+
onChipsChange: onContextItemsChange,
|
|
12981
|
+
onChange: handleChange,
|
|
12982
|
+
onSubmit: handleSubmit
|
|
12983
|
+
}
|
|
12984
|
+
) : void 0,
|
|
12985
|
+
onChange: handleChange,
|
|
12986
|
+
onSubmit: handleSubmit
|
|
12987
|
+
}
|
|
12988
|
+
) }),
|
|
12989
|
+
onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12990
|
+
"input",
|
|
12991
|
+
{
|
|
12992
|
+
ref: fileInputRef,
|
|
12993
|
+
type: "file",
|
|
12994
|
+
multiple: true,
|
|
12995
|
+
hidden: true,
|
|
12996
|
+
onChange: (event) => {
|
|
12997
|
+
emitFiles(Array.from(event.target.files ?? []));
|
|
12998
|
+
event.target.value = "";
|
|
12999
|
+
}
|
|
13000
|
+
}
|
|
13001
|
+
) : null,
|
|
13002
|
+
activePopover !== null ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(import_jsx_runtime180.Fragment, { children: [
|
|
13003
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: "fixed inset-0 z-40", onClick: closePopovers }),
|
|
13004
|
+
activePopover === "model" ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { "data-slot": "composer-model-popover", className: cn(popoverPanelClass, "right-0 left-auto w-48"), role: "listbox", children: models.map((option) => /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
|
|
13005
|
+
"button",
|
|
13006
|
+
{
|
|
13007
|
+
type: "button",
|
|
13008
|
+
role: "option",
|
|
13009
|
+
"aria-selected": option.value === currentModel?.value,
|
|
13010
|
+
className: popoverItemClass,
|
|
13011
|
+
onClick: () => {
|
|
13012
|
+
onModelChange?.(option.value);
|
|
13013
|
+
closePopovers();
|
|
13014
|
+
},
|
|
13015
|
+
children: [
|
|
13016
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("span", { className: "min-w-0 flex-1 truncate", children: option.label }),
|
|
13017
|
+
option.value === currentModel?.value ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "check", size: 14 }) : null
|
|
13018
|
+
]
|
|
13019
|
+
},
|
|
13020
|
+
option.value
|
|
13021
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { "data-slot": "composer-context-popover", className: popoverPanelClass, role: "listbox", children: plusSources.map(
|
|
13022
|
+
(source) => source.items.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)("div", { children: [
|
|
13023
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: source.label }),
|
|
13024
|
+
source.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
|
|
13025
|
+
"button",
|
|
13026
|
+
{
|
|
13027
|
+
type: "button",
|
|
13028
|
+
className: popoverItemClass,
|
|
13029
|
+
onClick: () => selectContext(item, source),
|
|
13030
|
+
children: [
|
|
13031
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: item.icon ?? source.icon ?? "file-text", size: "sm" }),
|
|
13032
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
13033
|
+
]
|
|
13034
|
+
},
|
|
13035
|
+
item.id
|
|
13036
|
+
))
|
|
13037
|
+
] }, source.trigger)
|
|
13038
|
+
) })
|
|
13039
|
+
] }) : null
|
|
13040
|
+
]
|
|
13041
|
+
}
|
|
13042
|
+
);
|
|
12353
13043
|
}
|
|
12354
13044
|
|
|
12355
13045
|
// src/components/chat/ConversationList/index.tsx
|
|
12356
|
-
var
|
|
12357
|
-
var
|
|
13046
|
+
var import_react65 = require("react");
|
|
13047
|
+
var import_jsx_runtime181 = require("react/jsx-runtime");
|
|
12358
13048
|
function ConversationList({ items = [], activeId, searchable, onSelect, onDelete, className, style }) {
|
|
12359
|
-
const [innerActive, setInnerActive] = (0,
|
|
12360
|
-
const [keyword, setKeyword] = (0,
|
|
13049
|
+
const [innerActive, setInnerActive] = (0, import_react65.useState)();
|
|
13050
|
+
const [keyword, setKeyword] = (0, import_react65.useState)("");
|
|
12361
13051
|
const active = activeId ?? innerActive;
|
|
12362
|
-
const filtered = (0,
|
|
13052
|
+
const filtered = (0, import_react65.useMemo)(() => {
|
|
12363
13053
|
const query = keyword.trim().toLowerCase();
|
|
12364
13054
|
if (!query) return items;
|
|
12365
13055
|
return items.filter(
|
|
@@ -12372,10 +13062,10 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
12372
13062
|
}
|
|
12373
13063
|
onSelect?.(id);
|
|
12374
13064
|
};
|
|
12375
|
-
return /* @__PURE__ */ (0,
|
|
12376
|
-
searchable ? /* @__PURE__ */ (0,
|
|
12377
|
-
/* @__PURE__ */ (0,
|
|
12378
|
-
/* @__PURE__ */ (0,
|
|
13065
|
+
return /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { "data-slot": "conversation-list", className: cn("flex w-full flex-col gap-1", className), style, children: [
|
|
13066
|
+
searchable ? /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { className: "relative mb-1", children: [
|
|
13067
|
+
/* @__PURE__ */ (0, import_jsx_runtime181.jsx)("span", { className: "absolute top-1/2 left-2 -translate-y-1/2 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(Icon, { name: "search", size: "sm" }) }),
|
|
13068
|
+
/* @__PURE__ */ (0, import_jsx_runtime181.jsx)(
|
|
12379
13069
|
"input",
|
|
12380
13070
|
{
|
|
12381
13071
|
"data-slot": "conversation-list-search",
|
|
@@ -12386,7 +13076,7 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
12386
13076
|
}
|
|
12387
13077
|
)
|
|
12388
13078
|
] }) : null,
|
|
12389
|
-
filtered.map((item) => /* @__PURE__ */ (0,
|
|
13079
|
+
filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)(
|
|
12390
13080
|
"div",
|
|
12391
13081
|
{
|
|
12392
13082
|
"data-slot": "conversation-list-item",
|
|
@@ -12397,12 +13087,12 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
12397
13087
|
),
|
|
12398
13088
|
onClick: () => select(item.id),
|
|
12399
13089
|
children: [
|
|
12400
|
-
/* @__PURE__ */ (0,
|
|
12401
|
-
/* @__PURE__ */ (0,
|
|
12402
|
-
item.description ? /* @__PURE__ */ (0,
|
|
13090
|
+
/* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
13091
|
+
/* @__PURE__ */ (0, import_jsx_runtime181.jsx)("div", { className: cn("truncate text-sm", item.id === active && "font-medium"), children: item.title }),
|
|
13092
|
+
item.description ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
|
|
12403
13093
|
] }),
|
|
12404
|
-
item.time ? /* @__PURE__ */ (0,
|
|
12405
|
-
onDelete ? /* @__PURE__ */ (0,
|
|
13094
|
+
item.time ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.time }) : null,
|
|
13095
|
+
onDelete ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(
|
|
12406
13096
|
"button",
|
|
12407
13097
|
{
|
|
12408
13098
|
type: "button",
|
|
@@ -12413,41 +13103,42 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
12413
13103
|
event.stopPropagation();
|
|
12414
13104
|
onDelete(item.id);
|
|
12415
13105
|
},
|
|
12416
|
-
children: /* @__PURE__ */ (0,
|
|
13106
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(Icon, { name: "trash-2", size: "sm" })
|
|
12417
13107
|
}
|
|
12418
13108
|
) : null
|
|
12419
13109
|
]
|
|
12420
13110
|
},
|
|
12421
13111
|
item.id
|
|
12422
13112
|
)),
|
|
12423
|
-
filtered.length === 0 ? /* @__PURE__ */ (0,
|
|
13113
|
+
filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("div", { className: "px-2 py-4 text-center text-sm text-muted-foreground", children: "\u65E0\u5339\u914D\u4F1A\u8BDD" }) : null
|
|
12424
13114
|
] });
|
|
12425
13115
|
}
|
|
12426
13116
|
|
|
12427
13117
|
// src/components/chat/MessageList/index.tsx
|
|
12428
|
-
var
|
|
12429
|
-
var
|
|
12430
|
-
function MessageList({ messages = [], autoScroll = true, onAction, className, style }) {
|
|
12431
|
-
const listRef = (0,
|
|
12432
|
-
(0,
|
|
13118
|
+
var import_react66 = require("react");
|
|
13119
|
+
var import_jsx_runtime182 = require("react/jsx-runtime");
|
|
13120
|
+
function MessageList({ messages = [], autoScroll = true, onAction, onOpenArtifacts, className, style }) {
|
|
13121
|
+
const listRef = (0, import_react66.useRef)(null);
|
|
13122
|
+
(0, import_react66.useEffect)(() => {
|
|
12433
13123
|
if (!autoScroll) return;
|
|
12434
13124
|
const el = listRef.current;
|
|
12435
13125
|
if (el) {
|
|
12436
13126
|
el.scrollTop = el.scrollHeight;
|
|
12437
13127
|
}
|
|
12438
13128
|
}, [messages, autoScroll]);
|
|
12439
|
-
return /* @__PURE__ */ (0,
|
|
13129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime182.jsx)(
|
|
12440
13130
|
"div",
|
|
12441
13131
|
{
|
|
12442
13132
|
ref: listRef,
|
|
12443
13133
|
"data-slot": "message-list",
|
|
12444
13134
|
className: cn("flex w-full flex-col gap-4 overflow-y-auto", className),
|
|
12445
13135
|
style,
|
|
12446
|
-
children: messages.map((message, index) => /* @__PURE__ */ (0,
|
|
13136
|
+
children: messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime182.jsx)(
|
|
12447
13137
|
ChatMessage,
|
|
12448
13138
|
{
|
|
12449
13139
|
...message,
|
|
12450
|
-
onAction: (action) => onAction?.({ id: message.id, action })
|
|
13140
|
+
onAction: (action) => onAction?.({ id: message.id, action }),
|
|
13141
|
+
onOpenArtifacts: onOpenArtifacts ? () => onOpenArtifacts({ id: message.id }) : void 0
|
|
12451
13142
|
},
|
|
12452
13143
|
message.id ?? index
|
|
12453
13144
|
))
|
|
@@ -12456,9 +13147,9 @@ function MessageList({ messages = [], autoScroll = true, onAction, className, st
|
|
|
12456
13147
|
}
|
|
12457
13148
|
|
|
12458
13149
|
// src/components/chat/Prompt/index.tsx
|
|
12459
|
-
var
|
|
13150
|
+
var import_jsx_runtime183 = require("react/jsx-runtime");
|
|
12460
13151
|
function Prompt({ title, description, icon, value, disabled, onSelect, className, style }) {
|
|
12461
|
-
return /* @__PURE__ */ (0,
|
|
13152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime183.jsxs)(
|
|
12462
13153
|
"button",
|
|
12463
13154
|
{
|
|
12464
13155
|
type: "button",
|
|
@@ -12471,10 +13162,10 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
|
|
|
12471
13162
|
style,
|
|
12472
13163
|
onClick: () => onSelect?.(value ?? title ?? ""),
|
|
12473
13164
|
children: [
|
|
12474
|
-
icon ? /* @__PURE__ */ (0,
|
|
12475
|
-
/* @__PURE__ */ (0,
|
|
12476
|
-
/* @__PURE__ */ (0,
|
|
12477
|
-
description ? /* @__PURE__ */ (0,
|
|
13165
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("span", { className: "mt-0.5 shrink-0 text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime183.jsx)(Icon, { name: icon, size: "sm" }) }) : null,
|
|
13166
|
+
/* @__PURE__ */ (0, import_jsx_runtime183.jsxs)("span", { className: "min-w-0", children: [
|
|
13167
|
+
/* @__PURE__ */ (0, import_jsx_runtime183.jsx)("span", { "data-slot": "prompt-title", className: "block text-sm font-medium", children: title }),
|
|
13168
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("span", { "data-slot": "prompt-description", className: "mt-0.5 block text-xs text-muted-foreground", children: description }) : null
|
|
12478
13169
|
] })
|
|
12479
13170
|
]
|
|
12480
13171
|
}
|
|
@@ -12482,7 +13173,7 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
|
|
|
12482
13173
|
}
|
|
12483
13174
|
|
|
12484
13175
|
// src/components/chat/Welcome/index.tsx
|
|
12485
|
-
var
|
|
13176
|
+
var import_jsx_runtime184 = require("react/jsx-runtime");
|
|
12486
13177
|
function Welcome({
|
|
12487
13178
|
title = "\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F",
|
|
12488
13179
|
description,
|
|
@@ -12492,19 +13183,19 @@ function Welcome({
|
|
|
12492
13183
|
className,
|
|
12493
13184
|
style
|
|
12494
13185
|
}) {
|
|
12495
|
-
return /* @__PURE__ */ (0,
|
|
13186
|
+
return /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
|
|
12496
13187
|
"div",
|
|
12497
13188
|
{
|
|
12498
13189
|
"data-slot": "welcome",
|
|
12499
13190
|
className: cn("flex w-full flex-col items-center gap-4 py-10 text-center", className),
|
|
12500
13191
|
style,
|
|
12501
13192
|
children: [
|
|
12502
|
-
/* @__PURE__ */ (0,
|
|
12503
|
-
/* @__PURE__ */ (0,
|
|
12504
|
-
/* @__PURE__ */ (0,
|
|
12505
|
-
description ? /* @__PURE__ */ (0,
|
|
13193
|
+
/* @__PURE__ */ (0, import_jsx_runtime184.jsx)("span", { "data-slot": "welcome-icon", className: "text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Icon, { name: icon, size: "lg" }) }),
|
|
13194
|
+
/* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("div", { children: [
|
|
13195
|
+
/* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { "data-slot": "welcome-title", className: "text-xl font-semibold", children: title }),
|
|
13196
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { "data-slot": "welcome-description", className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
12506
13197
|
] }),
|
|
12507
|
-
prompts.length > 0 ? /* @__PURE__ */ (0,
|
|
13198
|
+
prompts.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { "data-slot": "welcome-prompts", className: "grid w-full max-w-xl grid-cols-1 gap-3 text-left sm:grid-cols-2", children: prompts.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
|
|
12508
13199
|
Prompt,
|
|
12509
13200
|
{
|
|
12510
13201
|
title: item.title,
|
|
@@ -12521,7 +13212,7 @@ function Welcome({
|
|
|
12521
13212
|
}
|
|
12522
13213
|
|
|
12523
13214
|
// src/components/chat/ChatPage/index.tsx
|
|
12524
|
-
var
|
|
13215
|
+
var import_jsx_runtime185 = require("react/jsx-runtime");
|
|
12525
13216
|
function ChatPage({
|
|
12526
13217
|
brand,
|
|
12527
13218
|
menuItems = [],
|
|
@@ -12547,12 +13238,26 @@ function ChatPage({
|
|
|
12547
13238
|
defaultFooterSectionCollapsed = false,
|
|
12548
13239
|
onFooterSectionToggle,
|
|
12549
13240
|
conversationTitle,
|
|
13241
|
+
conversationHeaderAction,
|
|
13242
|
+
onConversationHeaderAction,
|
|
12550
13243
|
messages = [],
|
|
12551
13244
|
sending,
|
|
12552
13245
|
composerPlaceholder,
|
|
12553
13246
|
welcome,
|
|
12554
13247
|
onSend,
|
|
12555
13248
|
onMessageAction,
|
|
13249
|
+
models,
|
|
13250
|
+
model,
|
|
13251
|
+
onModelChange,
|
|
13252
|
+
contexts,
|
|
13253
|
+
contextItems,
|
|
13254
|
+
onContextItemsChange,
|
|
13255
|
+
attachments,
|
|
13256
|
+
onAttachFiles,
|
|
13257
|
+
onRemoveAttachment,
|
|
13258
|
+
onRetryAttachment,
|
|
13259
|
+
composerFooter,
|
|
13260
|
+
composerBottom,
|
|
12556
13261
|
artifactTitle = "\u4EA7\u7269",
|
|
12557
13262
|
artifacts = [],
|
|
12558
13263
|
activeArtifactId,
|
|
@@ -12563,20 +13268,22 @@ function ChatPage({
|
|
|
12563
13268
|
artifactViewers,
|
|
12564
13269
|
onDownloadArtifact,
|
|
12565
13270
|
artifactOpen,
|
|
12566
|
-
defaultArtifactOpen =
|
|
13271
|
+
defaultArtifactOpen = false,
|
|
12567
13272
|
onArtifactOpenChange,
|
|
12568
13273
|
className,
|
|
12569
13274
|
style
|
|
12570
13275
|
}) {
|
|
12571
13276
|
const controlled = artifactOpen !== void 0;
|
|
12572
|
-
const [innerOpen, setInnerOpen] = (0,
|
|
13277
|
+
const [innerOpen, setInnerOpen] = (0, import_react67.useState)(defaultArtifactOpen);
|
|
12573
13278
|
const open = controlled ? artifactOpen === true : innerOpen;
|
|
12574
13279
|
const setOpen = (next) => {
|
|
12575
13280
|
if (!controlled) setInnerOpen(next);
|
|
12576
13281
|
onArtifactOpenChange?.(next);
|
|
12577
13282
|
};
|
|
13283
|
+
const { renderChildren } = (0, import_runtime26.useRenderer)();
|
|
13284
|
+
const renderSlot = (slot) => (0, import_react67.isValidElement)(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
12578
13285
|
const convCollControlled = conversationSectionCollapsed !== void 0;
|
|
12579
|
-
const [convCollapsedInner, setConvCollapsedInner] = (0,
|
|
13286
|
+
const [convCollapsedInner, setConvCollapsedInner] = (0, import_react67.useState)(
|
|
12580
13287
|
defaultConversationSectionCollapsed
|
|
12581
13288
|
);
|
|
12582
13289
|
const convCollapsed = convCollControlled ? conversationSectionCollapsed === true : convCollapsedInner;
|
|
@@ -12586,7 +13293,7 @@ function ChatPage({
|
|
|
12586
13293
|
onConversationSectionToggle?.(next);
|
|
12587
13294
|
};
|
|
12588
13295
|
const footerCollControlled = footerSectionCollapsed !== void 0;
|
|
12589
|
-
const [footerCollapsedInner, setFooterCollapsedInner] = (0,
|
|
13296
|
+
const [footerCollapsedInner, setFooterCollapsedInner] = (0, import_react67.useState)(
|
|
12590
13297
|
defaultFooterSectionCollapsed
|
|
12591
13298
|
);
|
|
12592
13299
|
const footerCollapsed = footerCollControlled ? footerSectionCollapsed === true : footerCollapsedInner;
|
|
@@ -12596,7 +13303,7 @@ function ChatPage({
|
|
|
12596
13303
|
onFooterSectionToggle?.(next);
|
|
12597
13304
|
};
|
|
12598
13305
|
const railVisible = railItems.length > 0 || railFooterItems.length > 0;
|
|
12599
|
-
const railButton = (item) => /* @__PURE__ */ (0,
|
|
13306
|
+
const railButton = (item) => /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: item.label, side: "right", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12600
13307
|
Button2,
|
|
12601
13308
|
{
|
|
12602
13309
|
icon: item.icon,
|
|
@@ -12604,17 +13311,25 @@ function ChatPage({
|
|
|
12604
13311
|
onClick: () => onMenuSelect?.(item.key)
|
|
12605
13312
|
}
|
|
12606
13313
|
) }, item.key);
|
|
12607
|
-
const chatArea = /* @__PURE__ */ (0,
|
|
12608
|
-
/* @__PURE__ */ (0,
|
|
13314
|
+
const chatArea = /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { "data-slot": "chat-page-conversation", className: "flex h-full min-w-0 flex-1 flex-col", children: [
|
|
13315
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12609
13316
|
"div",
|
|
12610
13317
|
{
|
|
12611
13318
|
className: "flex shrink-0 items-center justify-between border-b border-border px-4 py-2.5",
|
|
12612
13319
|
children: [
|
|
12613
|
-
/* @__PURE__ */ (0,
|
|
12614
|
-
/* @__PURE__ */ (0,
|
|
13320
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: conversationTitle, strong: true }),
|
|
13321
|
+
conversationHeaderAction ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: conversationHeaderAction.tooltip ?? conversationHeaderAction.label, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13322
|
+
Button2,
|
|
13323
|
+
{
|
|
13324
|
+
text: conversationHeaderAction.label,
|
|
13325
|
+
icon: conversationHeaderAction.icon,
|
|
13326
|
+
variant: "text",
|
|
13327
|
+
onClick: () => onConversationHeaderAction?.()
|
|
13328
|
+
}
|
|
13329
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: open ? "\u6536\u8D77\u4EA7\u7269\u533A" : artifactTitle, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12615
13330
|
Button2,
|
|
12616
13331
|
{
|
|
12617
|
-
icon: "panel-right-open",
|
|
13332
|
+
icon: open ? "panel-right-close" : "panel-right-open",
|
|
12618
13333
|
variant: "text",
|
|
12619
13334
|
onClick: () => setOpen(!open)
|
|
12620
13335
|
}
|
|
@@ -12622,40 +13337,63 @@ function ChatPage({
|
|
|
12622
13337
|
]
|
|
12623
13338
|
}
|
|
12624
13339
|
),
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
{
|
|
12628
|
-
title: welcome?.title,
|
|
12629
|
-
description: welcome?.description,
|
|
12630
|
-
prompts: welcome?.prompts,
|
|
12631
|
-
style: { flex: 1 },
|
|
12632
|
-
onSelect: (value) => onSend?.(value)
|
|
12633
|
-
}
|
|
12634
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
|
|
12635
|
-
MessageList,
|
|
12636
|
-
{
|
|
12637
|
-
messages,
|
|
12638
|
-
style: { flex: 1, minHeight: 0, padding: 16 },
|
|
12639
|
-
onAction: onMessageAction
|
|
12640
|
-
}
|
|
12641
|
-
),
|
|
12642
|
-
/* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
|
|
12643
|
-
Composer,
|
|
13340
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
13341
|
+
"div",
|
|
12644
13342
|
{
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
13343
|
+
"data-slot": "chat-page-conversation-body",
|
|
13344
|
+
className: "mx-auto flex min-h-0 w-[61.8cqw] max-w-full flex-1 flex-col",
|
|
13345
|
+
children: [
|
|
13346
|
+
messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13347
|
+
Welcome,
|
|
13348
|
+
{
|
|
13349
|
+
title: welcome?.title,
|
|
13350
|
+
description: welcome?.description,
|
|
13351
|
+
prompts: welcome?.prompts,
|
|
13352
|
+
style: { flex: 1 },
|
|
13353
|
+
onSelect: (value) => onSend?.(value)
|
|
13354
|
+
}
|
|
13355
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13356
|
+
MessageList,
|
|
13357
|
+
{
|
|
13358
|
+
messages,
|
|
13359
|
+
className: "scrollbar-subtle",
|
|
13360
|
+
style: { flex: 1, minHeight: 0, padding: 16 },
|
|
13361
|
+
onAction: onMessageAction,
|
|
13362
|
+
onOpenArtifacts: () => setOpen(true)
|
|
13363
|
+
}
|
|
13364
|
+
),
|
|
13365
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13366
|
+
Composer,
|
|
13367
|
+
{
|
|
13368
|
+
placeholder: composerPlaceholder,
|
|
13369
|
+
loading: sending,
|
|
13370
|
+
models,
|
|
13371
|
+
model,
|
|
13372
|
+
contexts,
|
|
13373
|
+
contextItems,
|
|
13374
|
+
attachments,
|
|
13375
|
+
footer: composerFooter,
|
|
13376
|
+
style: { padding: 16, paddingBottom: composerBottom ? 8 : 16, flexShrink: 0 },
|
|
13377
|
+
onModelChange,
|
|
13378
|
+
onContextItemsChange,
|
|
13379
|
+
onAttachFiles,
|
|
13380
|
+
onRemoveAttachment,
|
|
13381
|
+
onRetryAttachment,
|
|
13382
|
+
onSubmit: (text) => onSend?.(text)
|
|
13383
|
+
}
|
|
13384
|
+
),
|
|
13385
|
+
composerBottom ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { "data-slot": "chat-page-composer-bottom", className: "shrink-0 px-4 pb-2 text-center", children: renderSlot(composerBottom) }) : null
|
|
13386
|
+
]
|
|
12649
13387
|
}
|
|
12650
13388
|
)
|
|
12651
13389
|
] });
|
|
12652
13390
|
const activeArtifact = artifacts.find((item) => item.id === activeArtifactId) ?? (activeArtifactId === void 0 || activeArtifactId === "" ? artifacts[artifacts.length - 1] : void 0);
|
|
12653
|
-
const artifactPanel = /* @__PURE__ */ (0,
|
|
13391
|
+
const artifactPanel = /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12654
13392
|
"div",
|
|
12655
13393
|
{
|
|
12656
13394
|
"data-slot": "chat-page-artifact",
|
|
12657
13395
|
className: "flex h-full min-w-0 flex-col border-l border-border bg-muted",
|
|
12658
|
-
children: /* @__PURE__ */ (0,
|
|
13396
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12659
13397
|
ArtifactPanel,
|
|
12660
13398
|
{
|
|
12661
13399
|
artifact: activeArtifact,
|
|
@@ -12673,37 +13411,37 @@ function ChatPage({
|
|
|
12673
13411
|
)
|
|
12674
13412
|
}
|
|
12675
13413
|
);
|
|
12676
|
-
return /* @__PURE__ */ (0,
|
|
13414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12677
13415
|
"div",
|
|
12678
13416
|
{
|
|
12679
13417
|
"data-slot": "chat-page",
|
|
12680
13418
|
className: cn("flex w-full overflow-hidden", className),
|
|
12681
13419
|
style: { height: "100vh", ...style },
|
|
12682
13420
|
children: [
|
|
12683
|
-
railVisible ? /* @__PURE__ */ (0,
|
|
13421
|
+
railVisible ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12684
13422
|
"div",
|
|
12685
13423
|
{
|
|
12686
13424
|
"data-slot": "chat-page-rail",
|
|
12687
13425
|
className: "flex h-full w-[52px] shrink-0 flex-col items-center gap-1 border-r border-border py-2.5",
|
|
12688
13426
|
children: [
|
|
12689
13427
|
railItems.map(railButton),
|
|
12690
|
-
/* @__PURE__ */ (0,
|
|
13428
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "flex-1" }),
|
|
12691
13429
|
railFooterItems.map(railButton)
|
|
12692
13430
|
]
|
|
12693
13431
|
}
|
|
12694
13432
|
) : null,
|
|
12695
|
-
/* @__PURE__ */ (0,
|
|
13433
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12696
13434
|
"div",
|
|
12697
13435
|
{
|
|
12698
13436
|
"data-slot": "chat-page-menu",
|
|
12699
|
-
className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-
|
|
13437
|
+
className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-hidden border-r border-border px-2 py-3",
|
|
12700
13438
|
children: [
|
|
12701
|
-
brand ? /* @__PURE__ */ (0,
|
|
12702
|
-
/* @__PURE__ */ (0,
|
|
12703
|
-
/* @__PURE__ */ (0,
|
|
12704
|
-
brand.version !== void 0 ? /* @__PURE__ */ (0,
|
|
13439
|
+
brand ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { className: "flex shrink-0 items-center justify-between px-2", children: [
|
|
13440
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
|
|
13441
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: brand.title, strong: true, size: "large" }),
|
|
13442
|
+
brand.version !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: brand.version, type: "secondary", size: "small" }) : null
|
|
12705
13443
|
] }),
|
|
12706
|
-
menuAction ? /* @__PURE__ */ (0,
|
|
13444
|
+
menuAction ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12707
13445
|
Button2,
|
|
12708
13446
|
{
|
|
12709
13447
|
text: menuAction.label,
|
|
@@ -12713,24 +13451,24 @@ function ChatPage({
|
|
|
12713
13451
|
}
|
|
12714
13452
|
) : null
|
|
12715
13453
|
] }) : null,
|
|
12716
|
-
/* @__PURE__ */ (0,
|
|
13454
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "scrollbar-subtle max-h-[40%] min-h-0 shrink-0 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12717
13455
|
Menu2,
|
|
12718
13456
|
{
|
|
12719
13457
|
items: menuItems,
|
|
12720
13458
|
selectedKey: activeMenuKey,
|
|
12721
13459
|
onSelect: (key) => onMenuSelect?.(key)
|
|
12722
13460
|
}
|
|
12723
|
-
),
|
|
12724
|
-
conversationSectionTitle !== void 0 ? /* @__PURE__ */ (0,
|
|
13461
|
+
) }),
|
|
13462
|
+
conversationSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12725
13463
|
"button",
|
|
12726
13464
|
{
|
|
12727
13465
|
type: "button",
|
|
12728
13466
|
"data-slot": "chat-page-section-toggle",
|
|
12729
13467
|
"aria-expanded": !convCollapsed,
|
|
12730
|
-
className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
|
|
13468
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
|
|
12731
13469
|
onClick: toggleConvSection,
|
|
12732
13470
|
children: [
|
|
12733
|
-
/* @__PURE__ */ (0,
|
|
13471
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12734
13472
|
Text,
|
|
12735
13473
|
{
|
|
12736
13474
|
text: `${conversationSectionTitle} (${conversations.length})`,
|
|
@@ -12739,48 +13477,50 @@ function ChatPage({
|
|
|
12739
13477
|
strong: true
|
|
12740
13478
|
}
|
|
12741
13479
|
),
|
|
12742
|
-
/* @__PURE__ */ (0,
|
|
13480
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Icon, { name: convCollapsed ? "chevron-right" : "chevron-down", size: 14 })
|
|
12743
13481
|
]
|
|
12744
13482
|
}
|
|
12745
13483
|
) : null,
|
|
12746
|
-
!convCollapsed ? /* @__PURE__ */ (0,
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
13484
|
+
!convCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { "data-slot": "chat-page-section-body", className: "scrollbar-subtle flex min-h-0 flex-1 flex-col overflow-y-auto", children: [
|
|
13485
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13486
|
+
ConversationList,
|
|
13487
|
+
{
|
|
13488
|
+
items: conversations,
|
|
13489
|
+
activeId: activeConversationId,
|
|
13490
|
+
onSelect: (id) => onSelectConversation?.(id),
|
|
13491
|
+
onDelete: (id) => onDeleteConversation?.(id)
|
|
13492
|
+
}
|
|
13493
|
+
),
|
|
13494
|
+
moreLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Button2, { text: `${moreLabel} >>`, variant: "link", size: "small", onClick: () => onMore?.() }) }) : null
|
|
13495
|
+
] }) : null,
|
|
13496
|
+
footerSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12757
13497
|
"button",
|
|
12758
13498
|
{
|
|
12759
13499
|
type: "button",
|
|
12760
13500
|
"data-slot": "chat-page-section-toggle",
|
|
12761
13501
|
"aria-expanded": !footerCollapsed,
|
|
12762
|
-
className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
|
|
13502
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
|
|
12763
13503
|
onClick: toggleFooterSection,
|
|
12764
13504
|
children: [
|
|
12765
|
-
/* @__PURE__ */ (0,
|
|
12766
|
-
/* @__PURE__ */ (0,
|
|
13505
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: footerSectionTitle, type: "secondary", className: "text-sm", strong: true }),
|
|
13506
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Icon, { name: footerCollapsed ? "chevron-right" : "chevron-down", size: 14 })
|
|
12767
13507
|
]
|
|
12768
13508
|
}
|
|
12769
13509
|
) : null,
|
|
12770
|
-
!footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */ (0,
|
|
13510
|
+
!footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { "data-slot": "chat-page-section-body", className: "scrollbar-subtle min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12771
13511
|
Menu2,
|
|
12772
13512
|
{
|
|
12773
13513
|
items: footerItems,
|
|
12774
13514
|
onSelect: (key) => onMenuSelect?.(key)
|
|
12775
13515
|
}
|
|
12776
|
-
) : null
|
|
13516
|
+
) }) : null
|
|
12777
13517
|
]
|
|
12778
13518
|
}
|
|
12779
13519
|
),
|
|
12780
|
-
/* @__PURE__ */ (0,
|
|
12781
|
-
/* @__PURE__ */ (0,
|
|
12782
|
-
/* @__PURE__ */ (0,
|
|
12783
|
-
/* @__PURE__ */ (0,
|
|
13520
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "@container h-full min-w-0 flex-1", children: open ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(PanelGroup, { orientation: "horizontal", style: { width: "100%", height: "100%" }, children: [
|
|
13521
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Panel, { defaultSize: "62%", children: chatArea }),
|
|
13522
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(ResizableHandle, { withHandle: true }),
|
|
13523
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Panel, { defaultSize: "38%", minSize: "380px", maxSize: "760px", children: artifactPanel })
|
|
12784
13524
|
] }) : chatArea })
|
|
12785
13525
|
]
|
|
12786
13526
|
}
|
|
@@ -12788,10 +13528,10 @@ function ChatPage({
|
|
|
12788
13528
|
}
|
|
12789
13529
|
|
|
12790
13530
|
// src/components/chat/Citation/index.tsx
|
|
12791
|
-
var
|
|
13531
|
+
var import_jsx_runtime186 = require("react/jsx-runtime");
|
|
12792
13532
|
function Citation({ items = [], start = 1, className, style }) {
|
|
12793
|
-
return /* @__PURE__ */ (0,
|
|
12794
|
-
/* @__PURE__ */ (0,
|
|
13533
|
+
return /* @__PURE__ */ (0, import_jsx_runtime186.jsx)("span", { "data-slot": "citation", className: cn("inline-flex gap-1 align-super", className), style, children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(HoverCard, { children: [
|
|
13534
|
+
/* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(
|
|
12795
13535
|
HoverCardTrigger,
|
|
12796
13536
|
{
|
|
12797
13537
|
"data-slot": "citation-marker",
|
|
@@ -12803,10 +13543,10 @@ function Citation({ items = [], start = 1, className, style }) {
|
|
|
12803
13543
|
]
|
|
12804
13544
|
}
|
|
12805
13545
|
),
|
|
12806
|
-
/* @__PURE__ */ (0,
|
|
12807
|
-
/* @__PURE__ */ (0,
|
|
12808
|
-
item.snippet ? /* @__PURE__ */ (0,
|
|
12809
|
-
item.url ? /* @__PURE__ */ (0,
|
|
13546
|
+
/* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(HoverCardContent, { "data-slot": "citation-card", className: "w-72", children: [
|
|
13547
|
+
/* @__PURE__ */ (0, import_jsx_runtime186.jsx)("div", { className: "text-sm font-medium", children: item.title }),
|
|
13548
|
+
item.snippet ? /* @__PURE__ */ (0, import_jsx_runtime186.jsx)("div", { className: "mt-1 line-clamp-3 text-xs text-muted-foreground", children: item.snippet }) : null,
|
|
13549
|
+
item.url ? /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
|
|
12810
13550
|
"a",
|
|
12811
13551
|
{
|
|
12812
13552
|
href: item.url,
|
|
@@ -12821,13 +13561,13 @@ function Citation({ items = [], start = 1, className, style }) {
|
|
|
12821
13561
|
}
|
|
12822
13562
|
|
|
12823
13563
|
// src/components/chat/Suggestion/index.tsx
|
|
12824
|
-
var
|
|
13564
|
+
var import_jsx_runtime187 = require("react/jsx-runtime");
|
|
12825
13565
|
function normalize(item) {
|
|
12826
13566
|
if (typeof item === "string") return { label: item, value: item };
|
|
12827
13567
|
return { label: item.label, value: item.value ?? item.label, icon: item.icon };
|
|
12828
13568
|
}
|
|
12829
13569
|
function Suggestion({ items = [], justify = "start", onSelect, className, style }) {
|
|
12830
|
-
return /* @__PURE__ */ (0,
|
|
13570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime187.jsx)(
|
|
12831
13571
|
"div",
|
|
12832
13572
|
{
|
|
12833
13573
|
"data-slot": "suggestion",
|
|
@@ -12835,7 +13575,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
12835
13575
|
style,
|
|
12836
13576
|
children: items.map((item, index) => {
|
|
12837
13577
|
const { label, value, icon } = normalize(item);
|
|
12838
|
-
return /* @__PURE__ */ (0,
|
|
13578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime187.jsxs)(
|
|
12839
13579
|
"button",
|
|
12840
13580
|
{
|
|
12841
13581
|
type: "button",
|
|
@@ -12844,7 +13584,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
12844
13584
|
className: "flex items-center gap-1.5 rounded-full border border-border px-3 py-1 text-sm transition-colors hover:bg-accent",
|
|
12845
13585
|
onClick: () => onSelect?.(value),
|
|
12846
13586
|
children: [
|
|
12847
|
-
icon ? /* @__PURE__ */ (0,
|
|
13587
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime187.jsx)(Icon, { name: icon, size: "sm" }) : null,
|
|
12848
13588
|
label
|
|
12849
13589
|
]
|
|
12850
13590
|
},
|
|
@@ -12856,7 +13596,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
12856
13596
|
}
|
|
12857
13597
|
|
|
12858
13598
|
// src/components/chart/EChartBase/index.tsx
|
|
12859
|
-
var
|
|
13599
|
+
var import_react68 = require("react");
|
|
12860
13600
|
|
|
12861
13601
|
// src/components/chart/echarts-modules.ts
|
|
12862
13602
|
var echarts = __toESM(require("echarts/core"), 1);
|
|
@@ -12887,7 +13627,7 @@ echarts.use([
|
|
|
12887
13627
|
]);
|
|
12888
13628
|
|
|
12889
13629
|
// src/components/chart/EChartBase/index.tsx
|
|
12890
|
-
var
|
|
13630
|
+
var import_jsx_runtime188 = require("react/jsx-runtime");
|
|
12891
13631
|
function EChartBase({
|
|
12892
13632
|
option,
|
|
12893
13633
|
height = 256,
|
|
@@ -12896,12 +13636,12 @@ function EChartBase({
|
|
|
12896
13636
|
style,
|
|
12897
13637
|
slot
|
|
12898
13638
|
}) {
|
|
12899
|
-
const hostRef = (0,
|
|
12900
|
-
const chartRef = (0,
|
|
12901
|
-
const onSelectRef = (0,
|
|
13639
|
+
const hostRef = (0, import_react68.useRef)(null);
|
|
13640
|
+
const chartRef = (0, import_react68.useRef)(null);
|
|
13641
|
+
const onSelectRef = (0, import_react68.useRef)(onSelect);
|
|
12902
13642
|
onSelectRef.current = onSelect;
|
|
12903
|
-
const [failed, setFailed] = (0,
|
|
12904
|
-
(0,
|
|
13643
|
+
const [failed, setFailed] = (0, import_react68.useState)(false);
|
|
13644
|
+
(0, import_react68.useEffect)(() => {
|
|
12905
13645
|
const host = hostRef.current;
|
|
12906
13646
|
if (!host) return;
|
|
12907
13647
|
let chart = null;
|
|
@@ -12920,22 +13660,22 @@ function EChartBase({
|
|
|
12920
13660
|
dataIndex: params.dataIndex
|
|
12921
13661
|
});
|
|
12922
13662
|
});
|
|
12923
|
-
const
|
|
12924
|
-
|
|
13663
|
+
const observer2 = new ResizeObserver(() => chart?.resize());
|
|
13664
|
+
observer2.observe(host);
|
|
12925
13665
|
return () => {
|
|
12926
|
-
|
|
13666
|
+
observer2.disconnect();
|
|
12927
13667
|
chart?.dispose();
|
|
12928
13668
|
chartRef.current = null;
|
|
12929
13669
|
};
|
|
12930
13670
|
}, []);
|
|
12931
|
-
(0,
|
|
13671
|
+
(0, import_react68.useEffect)(() => {
|
|
12932
13672
|
try {
|
|
12933
13673
|
chartRef.current?.setOption(option, { notMerge: true });
|
|
12934
13674
|
} catch {
|
|
12935
13675
|
}
|
|
12936
13676
|
}, [option]);
|
|
12937
13677
|
if (failed) {
|
|
12938
|
-
return /* @__PURE__ */ (0,
|
|
13678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
|
|
12939
13679
|
"div",
|
|
12940
13680
|
{
|
|
12941
13681
|
"data-slot": "chart-fallback",
|
|
@@ -12948,7 +13688,7 @@ function EChartBase({
|
|
|
12948
13688
|
}
|
|
12949
13689
|
);
|
|
12950
13690
|
}
|
|
12951
|
-
return /* @__PURE__ */ (0,
|
|
13691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
|
|
12952
13692
|
"div",
|
|
12953
13693
|
{
|
|
12954
13694
|
ref: hostRef,
|
|
@@ -13384,6 +14124,9 @@ function buildComposedOption(input, theme) {
|
|
|
13384
14124
|
};
|
|
13385
14125
|
}
|
|
13386
14126
|
|
|
14127
|
+
// src/components/chart/lib/use-chart-theme.ts
|
|
14128
|
+
var import_react69 = require("react");
|
|
14129
|
+
|
|
13387
14130
|
// src/components/chart/lib/color.ts
|
|
13388
14131
|
var LPAREN = String.fromCharCode(40);
|
|
13389
14132
|
var RPAREN = String.fromCharCode(41);
|
|
@@ -13480,9 +14223,67 @@ function getChartTheme() {
|
|
|
13480
14223
|
return FALLBACK_THEME;
|
|
13481
14224
|
}
|
|
13482
14225
|
}
|
|
14226
|
+
function resetChartTheme() {
|
|
14227
|
+
cached = null;
|
|
14228
|
+
}
|
|
14229
|
+
var CHART_SKIN_CHANGE_EVENT = "pactor:skin-change";
|
|
14230
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
14231
|
+
var observer = null;
|
|
14232
|
+
var scheduled = false;
|
|
14233
|
+
function scheduleNotify() {
|
|
14234
|
+
if (scheduled) return;
|
|
14235
|
+
scheduled = true;
|
|
14236
|
+
const enqueue = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
14237
|
+
enqueue(() => {
|
|
14238
|
+
scheduled = false;
|
|
14239
|
+
resetChartTheme();
|
|
14240
|
+
for (const listener of [...listeners]) {
|
|
14241
|
+
listener();
|
|
14242
|
+
}
|
|
14243
|
+
});
|
|
14244
|
+
}
|
|
14245
|
+
function handleResourceLoad(event) {
|
|
14246
|
+
const target = event.target;
|
|
14247
|
+
if (target instanceof HTMLLinkElement || target instanceof HTMLStyleElement) {
|
|
14248
|
+
scheduleNotify();
|
|
14249
|
+
}
|
|
14250
|
+
}
|
|
14251
|
+
function subscribeChartTheme(listener) {
|
|
14252
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") {
|
|
14253
|
+
return () => {
|
|
14254
|
+
};
|
|
14255
|
+
}
|
|
14256
|
+
listeners.add(listener);
|
|
14257
|
+
if (!observer) {
|
|
14258
|
+
observer = new MutationObserver(scheduleNotify);
|
|
14259
|
+
observer.observe(document.documentElement, { attributes: true });
|
|
14260
|
+
observer.observe(document.head, {
|
|
14261
|
+
attributes: true,
|
|
14262
|
+
childList: true,
|
|
14263
|
+
characterData: true,
|
|
14264
|
+
subtree: true
|
|
14265
|
+
});
|
|
14266
|
+
document.addEventListener("load", handleResourceLoad, true);
|
|
14267
|
+
window.addEventListener(CHART_SKIN_CHANGE_EVENT, scheduleNotify);
|
|
14268
|
+
}
|
|
14269
|
+
return () => {
|
|
14270
|
+
listeners.delete(listener);
|
|
14271
|
+
if (listeners.size === 0 && observer) {
|
|
14272
|
+
observer.disconnect();
|
|
14273
|
+
observer = null;
|
|
14274
|
+
document.removeEventListener("load", handleResourceLoad, true);
|
|
14275
|
+
window.removeEventListener(CHART_SKIN_CHANGE_EVENT, scheduleNotify);
|
|
14276
|
+
}
|
|
14277
|
+
};
|
|
14278
|
+
}
|
|
14279
|
+
|
|
14280
|
+
// src/components/chart/lib/use-chart-theme.ts
|
|
14281
|
+
function useChartTheme() {
|
|
14282
|
+
return (0, import_react69.useSyncExternalStore)(subscribeChartTheme, getChartTheme, getChartTheme);
|
|
14283
|
+
}
|
|
13483
14284
|
|
|
13484
14285
|
// src/components/chart/AreaChart/index.tsx
|
|
13485
|
-
var
|
|
14286
|
+
var import_jsx_runtime189 = require("react/jsx-runtime");
|
|
13486
14287
|
function AreaChart({
|
|
13487
14288
|
data = [],
|
|
13488
14289
|
xKey,
|
|
@@ -13498,9 +14299,9 @@ function AreaChart({
|
|
|
13498
14299
|
}) {
|
|
13499
14300
|
const option = buildAreaOption(
|
|
13500
14301
|
{ data, xKey, yKeys, stacked, fillOpacity, colors, title },
|
|
13501
|
-
|
|
14302
|
+
useChartTheme()
|
|
13502
14303
|
);
|
|
13503
|
-
return /* @__PURE__ */ (0,
|
|
14304
|
+
return /* @__PURE__ */ (0, import_jsx_runtime189.jsx)(
|
|
13504
14305
|
EChartBase,
|
|
13505
14306
|
{
|
|
13506
14307
|
slot: "area-chart",
|
|
@@ -13514,7 +14315,7 @@ function AreaChart({
|
|
|
13514
14315
|
}
|
|
13515
14316
|
|
|
13516
14317
|
// src/components/chart/BarChart/index.tsx
|
|
13517
|
-
var
|
|
14318
|
+
var import_jsx_runtime190 = require("react/jsx-runtime");
|
|
13518
14319
|
function BarChart2({
|
|
13519
14320
|
data = [],
|
|
13520
14321
|
yKey,
|
|
@@ -13529,9 +14330,9 @@ function BarChart2({
|
|
|
13529
14330
|
}) {
|
|
13530
14331
|
const option = buildBarOption(
|
|
13531
14332
|
{ data, yKey, yKeys: xKeys, stacked, colors, title },
|
|
13532
|
-
|
|
14333
|
+
useChartTheme()
|
|
13533
14334
|
);
|
|
13534
|
-
return /* @__PURE__ */ (0,
|
|
14335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime190.jsx)(
|
|
13535
14336
|
EChartBase,
|
|
13536
14337
|
{
|
|
13537
14338
|
slot: "bar-chart",
|
|
@@ -13545,7 +14346,7 @@ function BarChart2({
|
|
|
13545
14346
|
}
|
|
13546
14347
|
|
|
13547
14348
|
// src/components/chart/BubbleChart/index.tsx
|
|
13548
|
-
var
|
|
14349
|
+
var import_jsx_runtime191 = require("react/jsx-runtime");
|
|
13549
14350
|
function BubbleChart({
|
|
13550
14351
|
data = [],
|
|
13551
14352
|
xKey,
|
|
@@ -13561,9 +14362,9 @@ function BubbleChart({
|
|
|
13561
14362
|
}) {
|
|
13562
14363
|
const option = buildBubbleOption(
|
|
13563
14364
|
{ data, xKey, yKey, sizeKey, seriesKey, colors, title },
|
|
13564
|
-
|
|
14365
|
+
useChartTheme()
|
|
13565
14366
|
);
|
|
13566
|
-
return /* @__PURE__ */ (0,
|
|
14367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
|
|
13567
14368
|
EChartBase,
|
|
13568
14369
|
{
|
|
13569
14370
|
slot: "bubble-chart",
|
|
@@ -13577,7 +14378,7 @@ function BubbleChart({
|
|
|
13577
14378
|
}
|
|
13578
14379
|
|
|
13579
14380
|
// src/components/chart/ColumnChart/index.tsx
|
|
13580
|
-
var
|
|
14381
|
+
var import_jsx_runtime192 = require("react/jsx-runtime");
|
|
13581
14382
|
function ColumnChart({
|
|
13582
14383
|
data = [],
|
|
13583
14384
|
xKey,
|
|
@@ -13592,9 +14393,9 @@ function ColumnChart({
|
|
|
13592
14393
|
}) {
|
|
13593
14394
|
const option = buildColumnOption(
|
|
13594
14395
|
{ data, xKey, yKeys, stacked, colors, title },
|
|
13595
|
-
|
|
14396
|
+
useChartTheme()
|
|
13596
14397
|
);
|
|
13597
|
-
return /* @__PURE__ */ (0,
|
|
14398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(
|
|
13598
14399
|
EChartBase,
|
|
13599
14400
|
{
|
|
13600
14401
|
slot: "column-chart",
|
|
@@ -13608,7 +14409,7 @@ function ColumnChart({
|
|
|
13608
14409
|
}
|
|
13609
14410
|
|
|
13610
14411
|
// src/components/chart/ComposedChart/index.tsx
|
|
13611
|
-
var
|
|
14412
|
+
var import_jsx_runtime193 = require("react/jsx-runtime");
|
|
13612
14413
|
function ComposedChart({
|
|
13613
14414
|
data = [],
|
|
13614
14415
|
xKey,
|
|
@@ -13622,9 +14423,9 @@ function ComposedChart({
|
|
|
13622
14423
|
}) {
|
|
13623
14424
|
const option = buildComposedOption(
|
|
13624
14425
|
{ data, xKey, series, colors, title },
|
|
13625
|
-
|
|
14426
|
+
useChartTheme()
|
|
13626
14427
|
);
|
|
13627
|
-
return /* @__PURE__ */ (0,
|
|
14428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(
|
|
13628
14429
|
EChartBase,
|
|
13629
14430
|
{
|
|
13630
14431
|
slot: "composed-chart",
|
|
@@ -13638,7 +14439,7 @@ function ComposedChart({
|
|
|
13638
14439
|
}
|
|
13639
14440
|
|
|
13640
14441
|
// src/components/chart/DonutChart/index.tsx
|
|
13641
|
-
var
|
|
14442
|
+
var import_jsx_runtime194 = require("react/jsx-runtime");
|
|
13642
14443
|
function DonutChart({
|
|
13643
14444
|
data = [],
|
|
13644
14445
|
nameKey,
|
|
@@ -13668,9 +14469,9 @@ function DonutChart({
|
|
|
13668
14469
|
colors,
|
|
13669
14470
|
title
|
|
13670
14471
|
},
|
|
13671
|
-
|
|
14472
|
+
useChartTheme()
|
|
13672
14473
|
);
|
|
13673
|
-
return /* @__PURE__ */ (0,
|
|
14474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(
|
|
13674
14475
|
EChartBase,
|
|
13675
14476
|
{
|
|
13676
14477
|
slot: "donut-chart",
|
|
@@ -13684,7 +14485,7 @@ function DonutChart({
|
|
|
13684
14485
|
}
|
|
13685
14486
|
|
|
13686
14487
|
// src/components/chart/FunnelChart/index.tsx
|
|
13687
|
-
var
|
|
14488
|
+
var import_jsx_runtime195 = require("react/jsx-runtime");
|
|
13688
14489
|
function FunnelChart2({
|
|
13689
14490
|
data = [],
|
|
13690
14491
|
nameKey,
|
|
@@ -13699,9 +14500,9 @@ function FunnelChart2({
|
|
|
13699
14500
|
}) {
|
|
13700
14501
|
const option = buildFunnelOption(
|
|
13701
14502
|
{ data, nameKey, valueKey, sort, colors, title },
|
|
13702
|
-
|
|
14503
|
+
useChartTheme()
|
|
13703
14504
|
);
|
|
13704
|
-
return /* @__PURE__ */ (0,
|
|
14505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(
|
|
13705
14506
|
EChartBase,
|
|
13706
14507
|
{
|
|
13707
14508
|
slot: "funnel-chart",
|
|
@@ -13715,7 +14516,7 @@ function FunnelChart2({
|
|
|
13715
14516
|
}
|
|
13716
14517
|
|
|
13717
14518
|
// src/components/chart/GaugeChart/index.tsx
|
|
13718
|
-
var
|
|
14519
|
+
var import_jsx_runtime196 = require("react/jsx-runtime");
|
|
13719
14520
|
function GaugeChart2({
|
|
13720
14521
|
value = 0,
|
|
13721
14522
|
min,
|
|
@@ -13730,9 +14531,9 @@ function GaugeChart2({
|
|
|
13730
14531
|
}) {
|
|
13731
14532
|
const option = buildGaugeOption(
|
|
13732
14533
|
{ value, min, max, thresholds, unit, title },
|
|
13733
|
-
|
|
14534
|
+
useChartTheme()
|
|
13734
14535
|
);
|
|
13735
|
-
return /* @__PURE__ */ (0,
|
|
14536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
|
|
13736
14537
|
EChartBase,
|
|
13737
14538
|
{
|
|
13738
14539
|
slot: "gauge-chart",
|
|
@@ -13746,7 +14547,7 @@ function GaugeChart2({
|
|
|
13746
14547
|
}
|
|
13747
14548
|
|
|
13748
14549
|
// src/components/chart/Heatmap/index.tsx
|
|
13749
|
-
var
|
|
14550
|
+
var import_jsx_runtime197 = require("react/jsx-runtime");
|
|
13750
14551
|
function Heatmap({
|
|
13751
14552
|
data = [],
|
|
13752
14553
|
xKey,
|
|
@@ -13760,9 +14561,9 @@ function Heatmap({
|
|
|
13760
14561
|
}) {
|
|
13761
14562
|
const option = buildHeatmapOption(
|
|
13762
14563
|
{ data, xKey, yKey, valueKey, title },
|
|
13763
|
-
|
|
14564
|
+
useChartTheme()
|
|
13764
14565
|
);
|
|
13765
|
-
return /* @__PURE__ */ (0,
|
|
14566
|
+
return /* @__PURE__ */ (0, import_jsx_runtime197.jsx)(
|
|
13766
14567
|
EChartBase,
|
|
13767
14568
|
{
|
|
13768
14569
|
slot: "heatmap",
|
|
@@ -13776,7 +14577,7 @@ function Heatmap({
|
|
|
13776
14577
|
}
|
|
13777
14578
|
|
|
13778
14579
|
// src/components/chart/LineChart/index.tsx
|
|
13779
|
-
var
|
|
14580
|
+
var import_jsx_runtime198 = require("react/jsx-runtime");
|
|
13780
14581
|
function LineChart2({
|
|
13781
14582
|
data = [],
|
|
13782
14583
|
xKey,
|
|
@@ -13793,9 +14594,9 @@ function LineChart2({
|
|
|
13793
14594
|
}) {
|
|
13794
14595
|
const option = buildLineOption(
|
|
13795
14596
|
{ data, xKey, yKeys, smooth, showArea, stacked, colors, title },
|
|
13796
|
-
|
|
14597
|
+
useChartTheme()
|
|
13797
14598
|
);
|
|
13798
|
-
return /* @__PURE__ */ (0,
|
|
14599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
|
|
13799
14600
|
EChartBase,
|
|
13800
14601
|
{
|
|
13801
14602
|
slot: "line-chart",
|
|
@@ -13809,8 +14610,8 @@ function LineChart2({
|
|
|
13809
14610
|
}
|
|
13810
14611
|
|
|
13811
14612
|
// src/components/chart/MapChart/index.tsx
|
|
13812
|
-
var
|
|
13813
|
-
var
|
|
14613
|
+
var import_react70 = require("react");
|
|
14614
|
+
var import_jsx_runtime199 = require("react/jsx-runtime");
|
|
13814
14615
|
var fetchedMaps = /* @__PURE__ */ new Set();
|
|
13815
14616
|
function hasRegisteredMap(mapName) {
|
|
13816
14617
|
try {
|
|
@@ -13832,7 +14633,8 @@ function MapChart2({
|
|
|
13832
14633
|
className,
|
|
13833
14634
|
style
|
|
13834
14635
|
}) {
|
|
13835
|
-
const
|
|
14636
|
+
const theme = useChartTheme();
|
|
14637
|
+
const [loadState, setLoadState] = (0, import_react70.useState)(
|
|
13836
14638
|
() => geoJson || !geoJsonUrl || hasRegisteredMap(mapName) ? "idle" : "loading"
|
|
13837
14639
|
);
|
|
13838
14640
|
if (geoJson) {
|
|
@@ -13841,7 +14643,7 @@ function MapChart2({
|
|
|
13841
14643
|
} catch {
|
|
13842
14644
|
}
|
|
13843
14645
|
}
|
|
13844
|
-
(0,
|
|
14646
|
+
(0, import_react70.useEffect)(() => {
|
|
13845
14647
|
if (geoJson || !geoJsonUrl || hasRegisteredMap(mapName) || fetchedMaps.has(mapName)) {
|
|
13846
14648
|
setLoadState("idle");
|
|
13847
14649
|
return;
|
|
@@ -13866,7 +14668,7 @@ function MapChart2({
|
|
|
13866
14668
|
};
|
|
13867
14669
|
}, [geoJson, geoJsonUrl, mapName]);
|
|
13868
14670
|
if (geoJsonUrl && !geoJson && loadState === "loading") {
|
|
13869
|
-
return /* @__PURE__ */ (0,
|
|
14671
|
+
return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
|
|
13870
14672
|
"div",
|
|
13871
14673
|
{
|
|
13872
14674
|
"data-slot": "map-chart-loading",
|
|
@@ -13876,7 +14678,7 @@ function MapChart2({
|
|
|
13876
14678
|
);
|
|
13877
14679
|
}
|
|
13878
14680
|
if (!geoJson && loadState === "error") {
|
|
13879
|
-
return /* @__PURE__ */ (0,
|
|
14681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
|
|
13880
14682
|
Empty2,
|
|
13881
14683
|
{
|
|
13882
14684
|
title: "\u5730\u56FE\u52A0\u8F7D\u5931\u8D25",
|
|
@@ -13888,7 +14690,7 @@ function MapChart2({
|
|
|
13888
14690
|
}
|
|
13889
14691
|
if (!geoJson && !hasRegisteredMap(mapName)) {
|
|
13890
14692
|
console.warn(`[MapChart] \u5730\u56FE "${mapName}" \u672A\u6CE8\u518C\uFF1A\u8BF7\u4F20\u5165 geoJson / geoJsonUrl\uFF0C\u6216\u5728\u5E94\u7528\u542F\u52A8\u65F6 echarts.registerMap`);
|
|
13891
|
-
return /* @__PURE__ */ (0,
|
|
14693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
|
|
13892
14694
|
Empty2,
|
|
13893
14695
|
{
|
|
13894
14696
|
title: "\u5730\u56FE\u672A\u6CE8\u518C",
|
|
@@ -13898,8 +14700,8 @@ function MapChart2({
|
|
|
13898
14700
|
}
|
|
13899
14701
|
);
|
|
13900
14702
|
}
|
|
13901
|
-
const option = buildMapOption({ mapName, data, nameKey, valueKey, title },
|
|
13902
|
-
return /* @__PURE__ */ (0,
|
|
14703
|
+
const option = buildMapOption({ mapName, data, nameKey, valueKey, title }, theme);
|
|
14704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
|
|
13903
14705
|
EChartBase,
|
|
13904
14706
|
{
|
|
13905
14707
|
slot: "map-chart",
|
|
@@ -13914,7 +14716,7 @@ function MapChart2({
|
|
|
13914
14716
|
|
|
13915
14717
|
// src/components/chart/MetricCard/index.tsx
|
|
13916
14718
|
var import_lucide_react37 = require("lucide-react");
|
|
13917
|
-
var
|
|
14719
|
+
var import_jsx_runtime200 = require("react/jsx-runtime");
|
|
13918
14720
|
function MetricCard({
|
|
13919
14721
|
title,
|
|
13920
14722
|
value,
|
|
@@ -13927,15 +14729,15 @@ function MetricCard({
|
|
|
13927
14729
|
}) {
|
|
13928
14730
|
const showTrend = typeof trend === "number" && trend !== 0;
|
|
13929
14731
|
const rising = (trend ?? 0) > 0;
|
|
13930
|
-
return /* @__PURE__ */ (0,
|
|
14732
|
+
return /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
|
|
13931
14733
|
"div",
|
|
13932
14734
|
{
|
|
13933
14735
|
"data-slot": "metric-card",
|
|
13934
14736
|
className: cn("rounded-lg border bg-card p-4 text-card-foreground shadow-sm", className),
|
|
13935
14737
|
style,
|
|
13936
14738
|
children: [
|
|
13937
|
-
title ? /* @__PURE__ */ (0,
|
|
13938
|
-
/* @__PURE__ */ (0,
|
|
14739
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
|
|
14740
|
+
/* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
|
|
13939
14741
|
"div",
|
|
13940
14742
|
{
|
|
13941
14743
|
"data-slot": "metric-card-value",
|
|
@@ -13947,7 +14749,7 @@ function MetricCard({
|
|
|
13947
14749
|
]
|
|
13948
14750
|
}
|
|
13949
14751
|
),
|
|
13950
|
-
showTrend ? /* @__PURE__ */ (0,
|
|
14752
|
+
showTrend ? /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
|
|
13951
14753
|
"div",
|
|
13952
14754
|
{
|
|
13953
14755
|
"data-slot": "metric-card-trend",
|
|
@@ -13957,10 +14759,10 @@ function MetricCard({
|
|
|
13957
14759
|
rising ? "text-success" : "text-destructive"
|
|
13958
14760
|
),
|
|
13959
14761
|
children: [
|
|
13960
|
-
rising ? /* @__PURE__ */ (0,
|
|
14762
|
+
rising ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)(import_lucide_react37.ArrowUpRight, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime200.jsx)(import_lucide_react37.ArrowDownRight, { className: "size-4" }),
|
|
13961
14763
|
Math.abs(trend ?? 0),
|
|
13962
14764
|
"%",
|
|
13963
|
-
trendLabel ? /* @__PURE__ */ (0,
|
|
14765
|
+
trendLabel ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
|
|
13964
14766
|
]
|
|
13965
14767
|
}
|
|
13966
14768
|
) : null
|
|
@@ -13970,7 +14772,7 @@ function MetricCard({
|
|
|
13970
14772
|
}
|
|
13971
14773
|
|
|
13972
14774
|
// src/components/chart/PieChart/index.tsx
|
|
13973
|
-
var
|
|
14775
|
+
var import_jsx_runtime201 = require("react/jsx-runtime");
|
|
13974
14776
|
function PieChart2({
|
|
13975
14777
|
data = [],
|
|
13976
14778
|
nameKey,
|
|
@@ -13985,9 +14787,9 @@ function PieChart2({
|
|
|
13985
14787
|
}) {
|
|
13986
14788
|
const option = buildPieOption(
|
|
13987
14789
|
{ data, nameKey, valueKey, showLabel, colors, title },
|
|
13988
|
-
|
|
14790
|
+
useChartTheme()
|
|
13989
14791
|
);
|
|
13990
|
-
return /* @__PURE__ */ (0,
|
|
14792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime201.jsx)(
|
|
13991
14793
|
EChartBase,
|
|
13992
14794
|
{
|
|
13993
14795
|
slot: "pie-chart",
|
|
@@ -14001,7 +14803,7 @@ function PieChart2({
|
|
|
14001
14803
|
}
|
|
14002
14804
|
|
|
14003
14805
|
// src/components/chart/RadarChart/index.tsx
|
|
14004
|
-
var
|
|
14806
|
+
var import_jsx_runtime202 = require("react/jsx-runtime");
|
|
14005
14807
|
function RadarChart2({
|
|
14006
14808
|
data = [],
|
|
14007
14809
|
indicatorKey,
|
|
@@ -14015,9 +14817,9 @@ function RadarChart2({
|
|
|
14015
14817
|
}) {
|
|
14016
14818
|
const option = buildRadarOption(
|
|
14017
14819
|
{ data, indicatorKey, yKeys, colors, title },
|
|
14018
|
-
|
|
14820
|
+
useChartTheme()
|
|
14019
14821
|
);
|
|
14020
|
-
return /* @__PURE__ */ (0,
|
|
14822
|
+
return /* @__PURE__ */ (0, import_jsx_runtime202.jsx)(
|
|
14021
14823
|
EChartBase,
|
|
14022
14824
|
{
|
|
14023
14825
|
slot: "radar-chart",
|
|
@@ -14031,7 +14833,7 @@ function RadarChart2({
|
|
|
14031
14833
|
}
|
|
14032
14834
|
|
|
14033
14835
|
// src/components/chart/SankeyChart/index.tsx
|
|
14034
|
-
var
|
|
14836
|
+
var import_jsx_runtime203 = require("react/jsx-runtime");
|
|
14035
14837
|
function SankeyChart2({
|
|
14036
14838
|
nodes = [],
|
|
14037
14839
|
links = [],
|
|
@@ -14041,8 +14843,8 @@ function SankeyChart2({
|
|
|
14041
14843
|
className,
|
|
14042
14844
|
style
|
|
14043
14845
|
}) {
|
|
14044
|
-
const option = buildSankeyOption({ nodes, links, title },
|
|
14045
|
-
return /* @__PURE__ */ (0,
|
|
14846
|
+
const option = buildSankeyOption({ nodes, links, title }, useChartTheme());
|
|
14847
|
+
return /* @__PURE__ */ (0, import_jsx_runtime203.jsx)(
|
|
14046
14848
|
EChartBase,
|
|
14047
14849
|
{
|
|
14048
14850
|
slot: "sankey-chart",
|
|
@@ -14056,7 +14858,7 @@ function SankeyChart2({
|
|
|
14056
14858
|
}
|
|
14057
14859
|
|
|
14058
14860
|
// src/components/chart/ScatterChart/index.tsx
|
|
14059
|
-
var
|
|
14861
|
+
var import_jsx_runtime204 = require("react/jsx-runtime");
|
|
14060
14862
|
function ScatterChart2({
|
|
14061
14863
|
data = [],
|
|
14062
14864
|
xKey,
|
|
@@ -14071,9 +14873,9 @@ function ScatterChart2({
|
|
|
14071
14873
|
}) {
|
|
14072
14874
|
const option = buildScatterOption(
|
|
14073
14875
|
{ data, xKey, yKey, seriesKey, colors, title },
|
|
14074
|
-
|
|
14876
|
+
useChartTheme()
|
|
14075
14877
|
);
|
|
14076
|
-
return /* @__PURE__ */ (0,
|
|
14878
|
+
return /* @__PURE__ */ (0, import_jsx_runtime204.jsx)(
|
|
14077
14879
|
EChartBase,
|
|
14078
14880
|
{
|
|
14079
14881
|
slot: "scatter-chart",
|
|
@@ -14087,7 +14889,7 @@ function ScatterChart2({
|
|
|
14087
14889
|
}
|
|
14088
14890
|
|
|
14089
14891
|
// src/components/chart/TreeChart/index.tsx
|
|
14090
|
-
var
|
|
14892
|
+
var import_jsx_runtime205 = require("react/jsx-runtime");
|
|
14091
14893
|
function TreeChart2({
|
|
14092
14894
|
data = [],
|
|
14093
14895
|
title,
|
|
@@ -14101,9 +14903,9 @@ function TreeChart2({
|
|
|
14101
14903
|
}) {
|
|
14102
14904
|
const option = buildTreeOption(
|
|
14103
14905
|
{ data, title, orient, edgeShape, initialTreeDepth },
|
|
14104
|
-
|
|
14906
|
+
useChartTheme()
|
|
14105
14907
|
);
|
|
14106
|
-
return /* @__PURE__ */ (0,
|
|
14908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
|
|
14107
14909
|
EChartBase,
|
|
14108
14910
|
{
|
|
14109
14911
|
slot: "tree-chart",
|