@pactor-app/ui 1.21.0 → 1.22.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.
@@ -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: renderChildren([header]) }) : null,
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 ? renderChildren([toolbarStart]) : null,
3121
+ toolbarStart ? renderSlot(toolbarStart) : null,
3118
3122
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1" }),
3119
- toolbarEnd ? renderChildren([toolbarEnd]) : null,
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: renderChildren([footer]) }) : null
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)("span", { className: "inline-flex transition-transform data-[open=true]:rotate-90", "data-open": open, children: /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(Icon, { name: "chevron-right", size: 12 }) }),
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 overflow-hidden rounded-md border border-border bg-muted/50", className),
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 px-3 py-2 text-left text-sm",
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: "flex-1 text-muted-foreground", children: resolvedTitle }),
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: "border-t border-border px-3 py-2 text-sm whitespace-pre-wrap text-muted-foreground",
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 overflow-hidden rounded-md border border-border", className),
12224
+ className: cn("w-full", className),
12199
12225
  style,
12200
12226
  children: [
12201
- /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)(
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 px-3 py-2 text-left text-sm",
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
- /* @__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 flex-1 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
- /* @__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 border-t border-border px-3 py-2", children: [
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 rounded-sm bg-muted p-2 text-xs whitespace-pre-wrap", children: paramsText })
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 rounded-sm bg-muted p-2 text-xs whitespace-pre-wrap", children: result })
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({ part, role }) {
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, className: "text-sm" }) });
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-xs text-muted-foreground", children: [
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 = true,
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("flex w-full flex-col gap-1.5", isUser && "items-end", className),
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 && role !== "system" ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
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) => /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)(
12301
- "button",
12302
- {
12303
- type: "button",
12304
- "data-slot": "chat-message-action",
12305
- "data-action": action.name,
12306
- className: "flex items-center gap-1 rounded-sm px-1.5 py-0.5 text-xs text-muted-foreground hover:bg-accent hover:text-foreground",
12307
- onClick: () => onAction?.(action.name),
12308
- children: [
12309
- action.icon ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: action.icon, size: "sm" }) : null,
12310
- action.label ?? action.name
12311
- ]
12312
- },
12313
- action.name
12314
- )) }) : null
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 import_react65 = require("react");
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
- return /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)("div", { "data-slot": "composer", className: cn("flex w-full flex-col gap-2", className), style, children: [
12340
- attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime179.jsx)(Attachment, { items: attachments, onRemove: onRemoveAttachment, onRetry: onRetryAttachment }) : null,
12341
- /* @__PURE__ */ (0, import_jsx_runtime179.jsx)(
12342
- ChatInput,
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",
12343
12896
  {
12344
- value,
12345
- placeholder,
12346
- disabled: disabled || loading,
12347
- rows,
12348
- onChange,
12349
- onSubmit
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" })
12350
12906
  }
12351
- )
12352
- ] });
12907
+ ) : null,
12908
+ onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
12909
+ "button",
12910
+ {
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" })
12917
+ }
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 import_react63 = require("react");
12357
- var import_jsx_runtime180 = require("react/jsx-runtime");
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, import_react63.useState)();
12360
- const [keyword, setKeyword] = (0, import_react63.useState)("");
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, import_react63.useMemo)(() => {
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, import_jsx_runtime180.jsxs)("div", { "data-slot": "conversation-list", className: cn("flex w-full flex-col gap-1", className), style, children: [
12376
- searchable ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)("div", { className: "relative mb-1", children: [
12377
- /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("span", { className: "absolute top-1/2 left-2 -translate-y-1/2 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "search", size: "sm" }) }),
12378
- /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
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, import_jsx_runtime180.jsxs)(
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, import_jsx_runtime180.jsxs)("div", { className: "min-w-0 flex-1", children: [
12401
- /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: cn("truncate text-sm", item.id === active && "font-medium"), children: item.title }),
12402
- item.description ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
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, import_jsx_runtime180.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.time }) : null,
12405
- onDelete ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
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, import_jsx_runtime180.jsx)(Icon, { name: "trash-2", size: "sm" })
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, import_jsx_runtime180.jsx)("div", { className: "px-2 py-4 text-center text-sm text-muted-foreground", children: "\u65E0\u5339\u914D\u4F1A\u8BDD" }) : null
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 import_react64 = require("react");
12429
- var import_jsx_runtime181 = require("react/jsx-runtime");
12430
- function MessageList({ messages = [], autoScroll = true, onAction, className, style }) {
12431
- const listRef = (0, import_react64.useRef)(null);
12432
- (0, import_react64.useEffect)(() => {
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, import_jsx_runtime181.jsx)(
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, import_jsx_runtime181.jsx)(
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 import_jsx_runtime182 = require("react/jsx-runtime");
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, import_jsx_runtime182.jsxs)(
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, import_jsx_runtime182.jsx)("span", { className: "mt-0.5 shrink-0 text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime182.jsx)(Icon, { name: icon, size: "sm" }) }) : null,
12475
- /* @__PURE__ */ (0, import_jsx_runtime182.jsxs)("span", { className: "min-w-0", children: [
12476
- /* @__PURE__ */ (0, import_jsx_runtime182.jsx)("span", { "data-slot": "prompt-title", className: "block text-sm font-medium", children: title }),
12477
- description ? /* @__PURE__ */ (0, import_jsx_runtime182.jsx)("span", { "data-slot": "prompt-description", className: "mt-0.5 block text-xs text-muted-foreground", children: description }) : null
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 import_jsx_runtime183 = require("react/jsx-runtime");
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, import_jsx_runtime183.jsxs)(
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, import_jsx_runtime183.jsx)("span", { "data-slot": "welcome-icon", className: "text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime183.jsx)(Icon, { name: icon, size: "lg" }) }),
12503
- /* @__PURE__ */ (0, import_jsx_runtime183.jsxs)("div", { children: [
12504
- /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("div", { "data-slot": "welcome-title", className: "text-xl font-semibold", children: title }),
12505
- description ? /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("div", { "data-slot": "welcome-description", className: "mt-1 text-sm text-muted-foreground", children: description }) : null
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, import_jsx_runtime183.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_runtime183.jsx)(
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 import_jsx_runtime184 = require("react/jsx-runtime");
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 = true,
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, import_react65.useState)(defaultArtifactOpen);
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, import_react65.useState)(
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, import_react65.useState)(
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, import_jsx_runtime184.jsx)(Tooltip2, { content: item.label, side: "right", children: /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
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, import_jsx_runtime184.jsxs)("div", { "data-slot": "chat-page-conversation", className: "flex h-full min-w-0 flex-1 flex-col", children: [
12608
- /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
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, import_jsx_runtime184.jsx)(Text, { text: conversationTitle, strong: true }),
12614
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Tooltip2, { content: artifactTitle, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
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
- messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
12626
- Welcome,
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
- placeholder: composerPlaceholder,
12646
- loading: sending,
12647
- style: { padding: 16, borderTop: "1px solid var(--border)", flexShrink: 0 },
12648
- onSubmit: (text) => onSend?.(text)
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, import_jsx_runtime184.jsx)(
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, import_jsx_runtime184.jsx)(
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, import_jsx_runtime184.jsxs)(
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, import_jsx_runtime184.jsxs)(
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, import_jsx_runtime184.jsx)("div", { className: "flex-1" }),
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, import_jsx_runtime184.jsxs)(
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-auto border-r border-border px-2 py-3",
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, import_jsx_runtime184.jsxs)("div", { className: "flex items-center justify-between px-2", children: [
12702
- /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
12703
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Text, { text: brand.title, strong: true, size: "large" }),
12704
- brand.version !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Text, { text: brand.version, type: "secondary", size: "small" }) : null
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, import_jsx_runtime184.jsx)(
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, import_jsx_runtime184.jsx)(
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, import_jsx_runtime184.jsxs)(
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, import_jsx_runtime184.jsx)(
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, import_jsx_runtime184.jsx)(Icon, { name: convCollapsed ? "chevron-right" : "chevron-down", size: 14 })
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, import_jsx_runtime184.jsx)(
12747
- ConversationList,
12748
- {
12749
- items: conversations,
12750
- activeId: activeConversationId,
12751
- onSelect: (id) => onSelectConversation?.(id),
12752
- onDelete: (id) => onDeleteConversation?.(id)
12753
- }
12754
- ) : null,
12755
- !convCollapsed && moreLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Button2, { text: `${moreLabel} >>`, variant: "link", size: "small", onClick: () => onMore?.() }) }) : null,
12756
- footerSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
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, import_jsx_runtime184.jsx)(Text, { text: footerSectionTitle, type: "secondary", className: "text-sm", strong: true }),
12766
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Icon, { name: footerCollapsed ? "chevron-right" : "chevron-down", size: 14 })
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, import_jsx_runtime184.jsx)(
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, import_jsx_runtime184.jsx)("div", { className: "h-full min-w-0 flex-1", children: open ? /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(PanelGroup, { orientation: "horizontal", style: { width: "100%", height: "100%" }, children: [
12781
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Panel, { defaultSize: "62%", children: chatArea }),
12782
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(ResizableHandle, { withHandle: true }),
12783
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Panel, { defaultSize: "38%", minSize: "320px", maxSize: "760px", children: artifactPanel })
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 import_jsx_runtime185 = require("react/jsx-runtime");
13531
+ var import_jsx_runtime186 = require("react/jsx-runtime");
12792
13532
  function Citation({ items = [], start = 1, className, style }) {
12793
- return /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("span", { "data-slot": "citation", className: cn("inline-flex gap-1 align-super", className), style, children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(HoverCard, { children: [
12794
- /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
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, import_jsx_runtime185.jsxs)(HoverCardContent, { "data-slot": "citation-card", className: "w-72", children: [
12807
- /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "text-sm font-medium", children: item.title }),
12808
- item.snippet ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "mt-1 line-clamp-3 text-xs text-muted-foreground", children: item.snippet }) : null,
12809
- item.url ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
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 import_jsx_runtime186 = require("react/jsx-runtime");
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, import_jsx_runtime186.jsx)(
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, import_jsx_runtime186.jsxs)(
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, import_jsx_runtime186.jsx)(Icon, { name: icon, size: "sm" }) : null,
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 import_react66 = require("react");
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 import_jsx_runtime187 = require("react/jsx-runtime");
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, import_react66.useRef)(null);
12900
- const chartRef = (0, import_react66.useRef)(null);
12901
- const onSelectRef = (0, import_react66.useRef)(onSelect);
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, import_react66.useState)(false);
12904
- (0, import_react66.useEffect)(() => {
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;
@@ -12928,14 +13668,14 @@ function EChartBase({
12928
13668
  chartRef.current = null;
12929
13669
  };
12930
13670
  }, []);
12931
- (0, import_react66.useEffect)(() => {
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, import_jsx_runtime187.jsx)(
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, import_jsx_runtime187.jsx)(
13691
+ return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
12952
13692
  "div",
12953
13693
  {
12954
13694
  ref: hostRef,
@@ -13482,7 +14222,7 @@ function getChartTheme() {
13482
14222
  }
13483
14223
 
13484
14224
  // src/components/chart/AreaChart/index.tsx
13485
- var import_jsx_runtime188 = require("react/jsx-runtime");
14225
+ var import_jsx_runtime189 = require("react/jsx-runtime");
13486
14226
  function AreaChart({
13487
14227
  data = [],
13488
14228
  xKey,
@@ -13500,7 +14240,7 @@ function AreaChart({
13500
14240
  { data, xKey, yKeys, stacked, fillOpacity, colors, title },
13501
14241
  getChartTheme()
13502
14242
  );
13503
- return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
14243
+ return /* @__PURE__ */ (0, import_jsx_runtime189.jsx)(
13504
14244
  EChartBase,
13505
14245
  {
13506
14246
  slot: "area-chart",
@@ -13514,7 +14254,7 @@ function AreaChart({
13514
14254
  }
13515
14255
 
13516
14256
  // src/components/chart/BarChart/index.tsx
13517
- var import_jsx_runtime189 = require("react/jsx-runtime");
14257
+ var import_jsx_runtime190 = require("react/jsx-runtime");
13518
14258
  function BarChart2({
13519
14259
  data = [],
13520
14260
  yKey,
@@ -13531,7 +14271,7 @@ function BarChart2({
13531
14271
  { data, yKey, yKeys: xKeys, stacked, colors, title },
13532
14272
  getChartTheme()
13533
14273
  );
13534
- return /* @__PURE__ */ (0, import_jsx_runtime189.jsx)(
14274
+ return /* @__PURE__ */ (0, import_jsx_runtime190.jsx)(
13535
14275
  EChartBase,
13536
14276
  {
13537
14277
  slot: "bar-chart",
@@ -13545,7 +14285,7 @@ function BarChart2({
13545
14285
  }
13546
14286
 
13547
14287
  // src/components/chart/BubbleChart/index.tsx
13548
- var import_jsx_runtime190 = require("react/jsx-runtime");
14288
+ var import_jsx_runtime191 = require("react/jsx-runtime");
13549
14289
  function BubbleChart({
13550
14290
  data = [],
13551
14291
  xKey,
@@ -13563,7 +14303,7 @@ function BubbleChart({
13563
14303
  { data, xKey, yKey, sizeKey, seriesKey, colors, title },
13564
14304
  getChartTheme()
13565
14305
  );
13566
- return /* @__PURE__ */ (0, import_jsx_runtime190.jsx)(
14306
+ return /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
13567
14307
  EChartBase,
13568
14308
  {
13569
14309
  slot: "bubble-chart",
@@ -13577,7 +14317,7 @@ function BubbleChart({
13577
14317
  }
13578
14318
 
13579
14319
  // src/components/chart/ColumnChart/index.tsx
13580
- var import_jsx_runtime191 = require("react/jsx-runtime");
14320
+ var import_jsx_runtime192 = require("react/jsx-runtime");
13581
14321
  function ColumnChart({
13582
14322
  data = [],
13583
14323
  xKey,
@@ -13594,7 +14334,7 @@ function ColumnChart({
13594
14334
  { data, xKey, yKeys, stacked, colors, title },
13595
14335
  getChartTheme()
13596
14336
  );
13597
- return /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
14337
+ return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(
13598
14338
  EChartBase,
13599
14339
  {
13600
14340
  slot: "column-chart",
@@ -13608,7 +14348,7 @@ function ColumnChart({
13608
14348
  }
13609
14349
 
13610
14350
  // src/components/chart/ComposedChart/index.tsx
13611
- var import_jsx_runtime192 = require("react/jsx-runtime");
14351
+ var import_jsx_runtime193 = require("react/jsx-runtime");
13612
14352
  function ComposedChart({
13613
14353
  data = [],
13614
14354
  xKey,
@@ -13624,7 +14364,7 @@ function ComposedChart({
13624
14364
  { data, xKey, series, colors, title },
13625
14365
  getChartTheme()
13626
14366
  );
13627
- return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(
14367
+ return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(
13628
14368
  EChartBase,
13629
14369
  {
13630
14370
  slot: "composed-chart",
@@ -13638,7 +14378,7 @@ function ComposedChart({
13638
14378
  }
13639
14379
 
13640
14380
  // src/components/chart/DonutChart/index.tsx
13641
- var import_jsx_runtime193 = require("react/jsx-runtime");
14381
+ var import_jsx_runtime194 = require("react/jsx-runtime");
13642
14382
  function DonutChart({
13643
14383
  data = [],
13644
14384
  nameKey,
@@ -13670,7 +14410,7 @@ function DonutChart({
13670
14410
  },
13671
14411
  getChartTheme()
13672
14412
  );
13673
- return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(
14413
+ return /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(
13674
14414
  EChartBase,
13675
14415
  {
13676
14416
  slot: "donut-chart",
@@ -13684,7 +14424,7 @@ function DonutChart({
13684
14424
  }
13685
14425
 
13686
14426
  // src/components/chart/FunnelChart/index.tsx
13687
- var import_jsx_runtime194 = require("react/jsx-runtime");
14427
+ var import_jsx_runtime195 = require("react/jsx-runtime");
13688
14428
  function FunnelChart2({
13689
14429
  data = [],
13690
14430
  nameKey,
@@ -13701,7 +14441,7 @@ function FunnelChart2({
13701
14441
  { data, nameKey, valueKey, sort, colors, title },
13702
14442
  getChartTheme()
13703
14443
  );
13704
- return /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(
14444
+ return /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(
13705
14445
  EChartBase,
13706
14446
  {
13707
14447
  slot: "funnel-chart",
@@ -13715,7 +14455,7 @@ function FunnelChart2({
13715
14455
  }
13716
14456
 
13717
14457
  // src/components/chart/GaugeChart/index.tsx
13718
- var import_jsx_runtime195 = require("react/jsx-runtime");
14458
+ var import_jsx_runtime196 = require("react/jsx-runtime");
13719
14459
  function GaugeChart2({
13720
14460
  value = 0,
13721
14461
  min,
@@ -13732,7 +14472,7 @@ function GaugeChart2({
13732
14472
  { value, min, max, thresholds, unit, title },
13733
14473
  getChartTheme()
13734
14474
  );
13735
- return /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(
14475
+ return /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
13736
14476
  EChartBase,
13737
14477
  {
13738
14478
  slot: "gauge-chart",
@@ -13746,7 +14486,7 @@ function GaugeChart2({
13746
14486
  }
13747
14487
 
13748
14488
  // src/components/chart/Heatmap/index.tsx
13749
- var import_jsx_runtime196 = require("react/jsx-runtime");
14489
+ var import_jsx_runtime197 = require("react/jsx-runtime");
13750
14490
  function Heatmap({
13751
14491
  data = [],
13752
14492
  xKey,
@@ -13762,7 +14502,7 @@ function Heatmap({
13762
14502
  { data, xKey, yKey, valueKey, title },
13763
14503
  getChartTheme()
13764
14504
  );
13765
- return /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
14505
+ return /* @__PURE__ */ (0, import_jsx_runtime197.jsx)(
13766
14506
  EChartBase,
13767
14507
  {
13768
14508
  slot: "heatmap",
@@ -13776,7 +14516,7 @@ function Heatmap({
13776
14516
  }
13777
14517
 
13778
14518
  // src/components/chart/LineChart/index.tsx
13779
- var import_jsx_runtime197 = require("react/jsx-runtime");
14519
+ var import_jsx_runtime198 = require("react/jsx-runtime");
13780
14520
  function LineChart2({
13781
14521
  data = [],
13782
14522
  xKey,
@@ -13795,7 +14535,7 @@ function LineChart2({
13795
14535
  { data, xKey, yKeys, smooth, showArea, stacked, colors, title },
13796
14536
  getChartTheme()
13797
14537
  );
13798
- return /* @__PURE__ */ (0, import_jsx_runtime197.jsx)(
14538
+ return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
13799
14539
  EChartBase,
13800
14540
  {
13801
14541
  slot: "line-chart",
@@ -13809,8 +14549,8 @@ function LineChart2({
13809
14549
  }
13810
14550
 
13811
14551
  // src/components/chart/MapChart/index.tsx
13812
- var import_react67 = require("react");
13813
- var import_jsx_runtime198 = require("react/jsx-runtime");
14552
+ var import_react69 = require("react");
14553
+ var import_jsx_runtime199 = require("react/jsx-runtime");
13814
14554
  var fetchedMaps = /* @__PURE__ */ new Set();
13815
14555
  function hasRegisteredMap(mapName) {
13816
14556
  try {
@@ -13832,7 +14572,7 @@ function MapChart2({
13832
14572
  className,
13833
14573
  style
13834
14574
  }) {
13835
- const [loadState, setLoadState] = (0, import_react67.useState)(
14575
+ const [loadState, setLoadState] = (0, import_react69.useState)(
13836
14576
  () => geoJson || !geoJsonUrl || hasRegisteredMap(mapName) ? "idle" : "loading"
13837
14577
  );
13838
14578
  if (geoJson) {
@@ -13841,7 +14581,7 @@ function MapChart2({
13841
14581
  } catch {
13842
14582
  }
13843
14583
  }
13844
- (0, import_react67.useEffect)(() => {
14584
+ (0, import_react69.useEffect)(() => {
13845
14585
  if (geoJson || !geoJsonUrl || hasRegisteredMap(mapName) || fetchedMaps.has(mapName)) {
13846
14586
  setLoadState("idle");
13847
14587
  return;
@@ -13866,7 +14606,7 @@ function MapChart2({
13866
14606
  };
13867
14607
  }, [geoJson, geoJsonUrl, mapName]);
13868
14608
  if (geoJsonUrl && !geoJson && loadState === "loading") {
13869
- return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
14609
+ return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
13870
14610
  "div",
13871
14611
  {
13872
14612
  "data-slot": "map-chart-loading",
@@ -13876,7 +14616,7 @@ function MapChart2({
13876
14616
  );
13877
14617
  }
13878
14618
  if (!geoJson && loadState === "error") {
13879
- return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
14619
+ return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
13880
14620
  Empty2,
13881
14621
  {
13882
14622
  title: "\u5730\u56FE\u52A0\u8F7D\u5931\u8D25",
@@ -13888,7 +14628,7 @@ function MapChart2({
13888
14628
  }
13889
14629
  if (!geoJson && !hasRegisteredMap(mapName)) {
13890
14630
  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, import_jsx_runtime198.jsx)(
14631
+ return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
13892
14632
  Empty2,
13893
14633
  {
13894
14634
  title: "\u5730\u56FE\u672A\u6CE8\u518C",
@@ -13899,7 +14639,7 @@ function MapChart2({
13899
14639
  );
13900
14640
  }
13901
14641
  const option = buildMapOption({ mapName, data, nameKey, valueKey, title }, getChartTheme());
13902
- return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
14642
+ return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
13903
14643
  EChartBase,
13904
14644
  {
13905
14645
  slot: "map-chart",
@@ -13914,7 +14654,7 @@ function MapChart2({
13914
14654
 
13915
14655
  // src/components/chart/MetricCard/index.tsx
13916
14656
  var import_lucide_react37 = require("lucide-react");
13917
- var import_jsx_runtime199 = require("react/jsx-runtime");
14657
+ var import_jsx_runtime200 = require("react/jsx-runtime");
13918
14658
  function MetricCard({
13919
14659
  title,
13920
14660
  value,
@@ -13927,15 +14667,15 @@ function MetricCard({
13927
14667
  }) {
13928
14668
  const showTrend = typeof trend === "number" && trend !== 0;
13929
14669
  const rising = (trend ?? 0) > 0;
13930
- return /* @__PURE__ */ (0, import_jsx_runtime199.jsxs)(
14670
+ return /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
13931
14671
  "div",
13932
14672
  {
13933
14673
  "data-slot": "metric-card",
13934
14674
  className: cn("rounded-lg border bg-card p-4 text-card-foreground shadow-sm", className),
13935
14675
  style,
13936
14676
  children: [
13937
- title ? /* @__PURE__ */ (0, import_jsx_runtime199.jsx)("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
13938
- /* @__PURE__ */ (0, import_jsx_runtime199.jsxs)(
14677
+ title ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
14678
+ /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
13939
14679
  "div",
13940
14680
  {
13941
14681
  "data-slot": "metric-card-value",
@@ -13947,7 +14687,7 @@ function MetricCard({
13947
14687
  ]
13948
14688
  }
13949
14689
  ),
13950
- showTrend ? /* @__PURE__ */ (0, import_jsx_runtime199.jsxs)(
14690
+ showTrend ? /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
13951
14691
  "div",
13952
14692
  {
13953
14693
  "data-slot": "metric-card-trend",
@@ -13957,10 +14697,10 @@ function MetricCard({
13957
14697
  rising ? "text-success" : "text-destructive"
13958
14698
  ),
13959
14699
  children: [
13960
- rising ? /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(import_lucide_react37.ArrowUpRight, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(import_lucide_react37.ArrowDownRight, { className: "size-4" }),
14700
+ 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
14701
  Math.abs(trend ?? 0),
13962
14702
  "%",
13963
- trendLabel ? /* @__PURE__ */ (0, import_jsx_runtime199.jsx)("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
14703
+ trendLabel ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
13964
14704
  ]
13965
14705
  }
13966
14706
  ) : null
@@ -13970,7 +14710,7 @@ function MetricCard({
13970
14710
  }
13971
14711
 
13972
14712
  // src/components/chart/PieChart/index.tsx
13973
- var import_jsx_runtime200 = require("react/jsx-runtime");
14713
+ var import_jsx_runtime201 = require("react/jsx-runtime");
13974
14714
  function PieChart2({
13975
14715
  data = [],
13976
14716
  nameKey,
@@ -13987,7 +14727,7 @@ function PieChart2({
13987
14727
  { data, nameKey, valueKey, showLabel, colors, title },
13988
14728
  getChartTheme()
13989
14729
  );
13990
- return /* @__PURE__ */ (0, import_jsx_runtime200.jsx)(
14730
+ return /* @__PURE__ */ (0, import_jsx_runtime201.jsx)(
13991
14731
  EChartBase,
13992
14732
  {
13993
14733
  slot: "pie-chart",
@@ -14001,7 +14741,7 @@ function PieChart2({
14001
14741
  }
14002
14742
 
14003
14743
  // src/components/chart/RadarChart/index.tsx
14004
- var import_jsx_runtime201 = require("react/jsx-runtime");
14744
+ var import_jsx_runtime202 = require("react/jsx-runtime");
14005
14745
  function RadarChart2({
14006
14746
  data = [],
14007
14747
  indicatorKey,
@@ -14017,7 +14757,7 @@ function RadarChart2({
14017
14757
  { data, indicatorKey, yKeys, colors, title },
14018
14758
  getChartTheme()
14019
14759
  );
14020
- return /* @__PURE__ */ (0, import_jsx_runtime201.jsx)(
14760
+ return /* @__PURE__ */ (0, import_jsx_runtime202.jsx)(
14021
14761
  EChartBase,
14022
14762
  {
14023
14763
  slot: "radar-chart",
@@ -14031,7 +14771,7 @@ function RadarChart2({
14031
14771
  }
14032
14772
 
14033
14773
  // src/components/chart/SankeyChart/index.tsx
14034
- var import_jsx_runtime202 = require("react/jsx-runtime");
14774
+ var import_jsx_runtime203 = require("react/jsx-runtime");
14035
14775
  function SankeyChart2({
14036
14776
  nodes = [],
14037
14777
  links = [],
@@ -14042,7 +14782,7 @@ function SankeyChart2({
14042
14782
  style
14043
14783
  }) {
14044
14784
  const option = buildSankeyOption({ nodes, links, title }, getChartTheme());
14045
- return /* @__PURE__ */ (0, import_jsx_runtime202.jsx)(
14785
+ return /* @__PURE__ */ (0, import_jsx_runtime203.jsx)(
14046
14786
  EChartBase,
14047
14787
  {
14048
14788
  slot: "sankey-chart",
@@ -14056,7 +14796,7 @@ function SankeyChart2({
14056
14796
  }
14057
14797
 
14058
14798
  // src/components/chart/ScatterChart/index.tsx
14059
- var import_jsx_runtime203 = require("react/jsx-runtime");
14799
+ var import_jsx_runtime204 = require("react/jsx-runtime");
14060
14800
  function ScatterChart2({
14061
14801
  data = [],
14062
14802
  xKey,
@@ -14073,7 +14813,7 @@ function ScatterChart2({
14073
14813
  { data, xKey, yKey, seriesKey, colors, title },
14074
14814
  getChartTheme()
14075
14815
  );
14076
- return /* @__PURE__ */ (0, import_jsx_runtime203.jsx)(
14816
+ return /* @__PURE__ */ (0, import_jsx_runtime204.jsx)(
14077
14817
  EChartBase,
14078
14818
  {
14079
14819
  slot: "scatter-chart",
@@ -14087,7 +14827,7 @@ function ScatterChart2({
14087
14827
  }
14088
14828
 
14089
14829
  // src/components/chart/TreeChart/index.tsx
14090
- var import_jsx_runtime204 = require("react/jsx-runtime");
14830
+ var import_jsx_runtime205 = require("react/jsx-runtime");
14091
14831
  function TreeChart2({
14092
14832
  data = [],
14093
14833
  title,
@@ -14103,7 +14843,7 @@ function TreeChart2({
14103
14843
  { data, title, orient, edgeShape, initialTreeDepth },
14104
14844
  getChartTheme()
14105
14845
  );
14106
- return /* @__PURE__ */ (0, import_jsx_runtime204.jsx)(
14846
+ return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
14107
14847
  EChartBase,
14108
14848
  {
14109
14849
  slot: "tree-chart",