@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.
package/dist/index.cjs CHANGED
@@ -502,6 +502,7 @@ var ICONS = {
502
502
  "file-text": import_lucide_react2.FileText,
503
503
  "panel-left": import_lucide_react2.PanelLeft,
504
504
  "panel-right-open": import_lucide_react2.PanelRightOpen,
505
+ "panel-right-close": import_lucide_react2.PanelRightClose,
505
506
  square: import_lucide_react2.Square,
506
507
  history: import_lucide_react2.History,
507
508
  "rotate-ccw": import_lucide_react2.RotateCcw,
@@ -3069,6 +3070,7 @@ function ChatInput({
3069
3070
  toolbarEnd,
3070
3071
  header,
3071
3072
  footer,
3073
+ field,
3072
3074
  onChange,
3073
3075
  onSubmit,
3074
3076
  className,
@@ -3079,6 +3081,8 @@ function ChatInput({
3079
3081
  const [draft, setDraft] = (0, import_react14.useState)("");
3080
3082
  const text = controlled ? value : draft;
3081
3083
  const canSubmit = !disabled && text.trim() !== "";
3084
+ const customField = field !== void 0 && field !== null;
3085
+ const renderSlot = (slot) => (0, import_react14.isValidElement)(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
3082
3086
  const composingRef = (0, import_react14.useRef)(false);
3083
3087
  const handleChange = (next) => {
3084
3088
  if (!controlled) {
@@ -3114,8 +3118,8 @@ function ChatInput({
3114
3118
  ),
3115
3119
  style,
3116
3120
  children: [
3117
- header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "px-3 pt-3", children: renderChildren([header]) }) : null,
3118
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3121
+ header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "px-3 pt-3", children: renderSlot(header) }) : null,
3122
+ customField ? field : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3119
3123
  Textarea,
3120
3124
  {
3121
3125
  value: text,
@@ -3130,9 +3134,9 @@ function ChatInput({
3130
3134
  }
3131
3135
  ),
3132
3136
  toolbarStart || toolbarEnd || !hideSend ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1 px-2 pb-2", children: [
3133
- toolbarStart ? renderChildren([toolbarStart]) : null,
3137
+ toolbarStart ? renderSlot(toolbarStart) : null,
3134
3138
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1" }),
3135
- toolbarEnd ? renderChildren([toolbarEnd]) : null,
3139
+ toolbarEnd ? renderSlot(toolbarEnd) : null,
3136
3140
  hideSend ? null : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3137
3141
  Button,
3138
3142
  {
@@ -3146,7 +3150,7 @@ function ChatInput({
3146
3150
  }
3147
3151
  )
3148
3152
  ] }) : null,
3149
- footer ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-t border-border px-3 py-2", children: renderChildren([footer]) }) : null
3153
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-t border-border px-3 py-2", children: renderSlot(footer) }) : null
3150
3154
  ]
3151
3155
  }
3152
3156
  );
@@ -3698,7 +3702,8 @@ function DatePicker(props) {
3698
3702
  onSelect: handleRangeDaySelect,
3699
3703
  modifiers: rangeModifiers,
3700
3704
  modifiersClassNames: rangeModifierClassNames,
3701
- locale: dfLocale
3705
+ locale: dfLocale,
3706
+ showOutsideDays: false
3702
3707
  }
3703
3708
  )
3704
3709
  }
@@ -3712,7 +3717,8 @@ function DatePicker(props) {
3712
3717
  onSelect: handleRangeDaySelect,
3713
3718
  modifiers: rangeModifiers,
3714
3719
  modifiersClassNames: rangeModifierClassNames,
3715
- locale: dfLocale
3720
+ locale: dfLocale,
3721
+ showOutsideDays: false
3716
3722
  }
3717
3723
  ) })
3718
3724
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
@@ -11774,7 +11780,14 @@ function ArtifactTreeRow({
11774
11780
  className: "flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-accent",
11775
11781
  onClick: () => setOpen((value) => !value),
11776
11782
  children: [
11777
- /* @__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 }) }),
11783
+ /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
11784
+ "span",
11785
+ {
11786
+ className: "inline-flex transition-transform data-[open=true]:rotate-90",
11787
+ "data-open": open,
11788
+ children: /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(Icon, { name: "chevron-right", size: 12 })
11789
+ }
11790
+ ),
11778
11791
  /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(Icon, { name: "folder", size: 13 }),
11779
11792
  /* @__PURE__ */ (0, import_jsx_runtime170.jsx)("span", { className: "min-w-0 flex-1 truncate", children: node.name })
11780
11793
  ]
@@ -11906,6 +11919,7 @@ function ArtifactPanel({
11906
11919
  icon: "download",
11907
11920
  variant: "text",
11908
11921
  tooltip: "\u4E0B\u8F7D\u4EA7\u7269",
11922
+ className: "px-2",
11909
11923
  onClick: () => onDownload ? onDownload(artifact) : void downloadArtifact(artifact)
11910
11924
  }
11911
11925
  ) : null,
@@ -11915,11 +11929,12 @@ function ArtifactPanel({
11915
11929
  icon: "x",
11916
11930
  variant: "text",
11917
11931
  tooltip: "\u6536\u8D77\u4EA7\u7269\u533A",
11932
+ className: "px-2",
11918
11933
  onClick: () => onClose?.()
11919
11934
  }
11920
11935
  )
11921
11936
  ] }),
11922
- /* @__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)(
11937
+ /* @__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)(
11923
11938
  ArtifactListView,
11924
11939
  {
11925
11940
  nodes: buildArtifactTree(artifacts),
@@ -12177,7 +12192,7 @@ function Thinking({
12177
12192
  {
12178
12193
  "data-slot": "thinking",
12179
12194
  "data-status": status,
12180
- className: cn("w-full overflow-hidden rounded-md border border-border bg-muted/50", className),
12195
+ className: cn("w-full", className),
12181
12196
  style,
12182
12197
  children: [
12183
12198
  /* @__PURE__ */ (0, import_jsx_runtime176.jsxs)(
@@ -12186,12 +12201,12 @@ function Thinking({
12186
12201
  type: "button",
12187
12202
  "data-slot": "thinking-trigger",
12188
12203
  "aria-expanded": isExpanded,
12189
- className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm",
12204
+ className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
12190
12205
  onClick: toggle,
12191
12206
  children: [
12192
12207
  /* @__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" }) }),
12193
- /* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { "data-slot": "thinking-title", className: "flex-1 text-muted-foreground", children: resolvedTitle }),
12194
- /* @__PURE__ */ (0, import_jsx_runtime176.jsx)(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" })
12208
+ /* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { "data-slot": "thinking-title", className: "text-muted-foreground", children: resolvedTitle }),
12209
+ /* @__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" }) })
12195
12210
  ]
12196
12211
  }
12197
12212
  ),
@@ -12199,7 +12214,7 @@ function Thinking({
12199
12214
  "div",
12200
12215
  {
12201
12216
  "data-slot": "thinking-content",
12202
- className: "border-t border-border px-3 py-2 text-sm whitespace-pre-wrap text-muted-foreground",
12217
+ className: "py-1 pl-6 text-sm whitespace-pre-wrap text-muted-foreground",
12203
12218
  children: content
12204
12219
  }
12205
12220
  ) : null
@@ -12229,42 +12244,51 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
12229
12244
  const [expanded, setExpanded] = (0, import_react62.useState)(defaultExpanded ?? status === "running");
12230
12245
  const meta = statusIcon3[status];
12231
12246
  const paramsText = renderValue(params);
12247
+ const hasDetail = Boolean(paramsText) || Boolean(result);
12248
+ const headerInner = /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)(import_jsx_runtime177.Fragment, { children: [
12249
+ /* @__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" }) }),
12250
+ /* @__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" }),
12251
+ /* @__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" }) }),
12252
+ durationMs !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
12253
+ (durationMs / 1e3).toFixed(1),
12254
+ "s"
12255
+ ] }) : null,
12256
+ 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
12257
+ ] });
12232
12258
  return /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)(
12233
12259
  "div",
12234
12260
  {
12235
12261
  "data-slot": "tool-call",
12236
12262
  "data-status": status,
12237
- className: cn("w-full overflow-hidden rounded-md border border-border", className),
12263
+ className: cn("w-full", className),
12238
12264
  style,
12239
12265
  children: [
12240
- /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)(
12266
+ hasDetail ? /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(
12241
12267
  "button",
12242
12268
  {
12243
12269
  type: "button",
12244
12270
  "data-slot": "tool-call-trigger",
12245
12271
  "aria-expanded": expanded,
12246
- className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm",
12272
+ className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
12247
12273
  onClick: () => setExpanded((value) => !value),
12248
- children: [
12249
- /* @__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" }) }),
12250
- /* @__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" }),
12251
- /* @__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" }) }),
12252
- durationMs !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
12253
- (durationMs / 1e3).toFixed(1),
12254
- "s"
12255
- ] }) : null,
12256
- /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" })
12257
- ]
12274
+ children: headerInner
12275
+ }
12276
+ ) : /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(
12277
+ "div",
12278
+ {
12279
+ "data-slot": "tool-call-trigger",
12280
+ className: "flex w-full items-center gap-2 py-1 text-left text-sm",
12281
+ children: headerInner
12258
12282
  }
12259
12283
  ),
12260
- 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: [
12284
+ 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: [
12261
12285
  paramsText ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { children: [
12262
12286
  /* @__PURE__ */ (0, import_jsx_runtime177.jsx)("div", { className: "text-xs font-medium text-muted-foreground", children: "\u53C2\u6570" }),
12263
- /* @__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 })
12287
+ /* @__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 })
12264
12288
  ] }) : null,
12265
12289
  result ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { children: [
12266
12290
  /* @__PURE__ */ (0, import_jsx_runtime177.jsx)("div", { className: "text-xs font-medium text-muted-foreground", children: "\u7ED3\u679C" }),
12267
- /* @__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 })
12291
+ /* @__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 })
12268
12292
  ] }) : null
12269
12293
  ] }) : null
12270
12294
  ]
@@ -12274,12 +12298,26 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
12274
12298
 
12275
12299
  // src/components/chat/ChatMessage/index.tsx
12276
12300
  var import_jsx_runtime178 = require("react/jsx-runtime");
12277
- function PartView({ part, role }) {
12301
+ function PartView({
12302
+ part,
12303
+ role,
12304
+ onOpenArtifacts
12305
+ }) {
12306
+ if (role === "system" && (part.type === "text" || part.type === "markdown")) {
12307
+ return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
12308
+ "div",
12309
+ {
12310
+ "data-slot": "chat-message-system-part",
12311
+ className: "w-full text-center text-xs text-muted-foreground",
12312
+ children: part.type === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(import_markdown2.MarkdownDslComponent, { content: part.content }) : part.content
12313
+ }
12314
+ );
12315
+ }
12278
12316
  switch (part.type) {
12279
12317
  case "text":
12280
12318
  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 }) });
12281
12319
  case "markdown":
12282
- 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" }) });
12320
+ 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 }) });
12283
12321
  case "thinking":
12284
12322
  return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Thinking, { content: part.content, status: part.status ?? "done" });
12285
12323
  case "tool-call":
@@ -12287,10 +12325,31 @@ function PartView({ part, role }) {
12287
12325
  case "tool-result":
12288
12326
  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 });
12289
12327
  case "status":
12290
- 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: [
12328
+ 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: [
12291
12329
  /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "clock", size: "sm" }),
12292
12330
  part.text
12293
12331
  ] });
12332
+ case "artifacts": {
12333
+ const artifactsClass = "flex w-fit items-center gap-1.5 text-muted-foreground";
12334
+ const label = `\u5DF2\u751F\u6210 ${part.count} \u4E2A\u4EA7\u7269`;
12335
+ return onOpenArtifacts ? /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)(
12336
+ "button",
12337
+ {
12338
+ type: "button",
12339
+ "data-slot": "chat-message-artifacts",
12340
+ className: cn(artifactsClass, "cursor-pointer hover:text-foreground"),
12341
+ onClick: onOpenArtifacts,
12342
+ children: [
12343
+ /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "package", size: "sm" }),
12344
+ label,
12345
+ /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "chevron-right", size: 12 })
12346
+ ]
12347
+ }
12348
+ ) : /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-artifacts", className: artifactsClass, children: [
12349
+ /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "package", size: "sm" }),
12350
+ label
12351
+ ] });
12352
+ }
12294
12353
  case "error":
12295
12354
  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: [
12296
12355
  /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "circle-alert", size: "sm" }),
@@ -12300,19 +12359,31 @@ function PartView({ part, role }) {
12300
12359
  return null;
12301
12360
  }
12302
12361
  }
12362
+ var ACTION_ICON_BY_NAME = {
12363
+ copy: "copy",
12364
+ retry: "rotate-ccw",
12365
+ regenerate: "refresh-ccw",
12366
+ edit: "pencil",
12367
+ like: "thumbs-up",
12368
+ dislike: "thumbs-down",
12369
+ share: "share",
12370
+ delete: "trash"
12371
+ };
12303
12372
  function ChatMessage({
12304
12373
  role = "assistant",
12305
12374
  parts = [],
12306
12375
  status = "completed",
12307
12376
  agent,
12308
12377
  time,
12309
- showSender = true,
12378
+ showSender = false,
12310
12379
  actions = [],
12311
12380
  onAction,
12381
+ onOpenArtifacts,
12312
12382
  className,
12313
12383
  style
12314
12384
  }) {
12315
12385
  const isUser = role === "user";
12386
+ const isSystem = role === "system";
12316
12387
  const senderName = isUser ? "\u6211" : agent?.name ?? "\u52A9\u624B";
12317
12388
  return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)(
12318
12389
  "div",
@@ -12320,10 +12391,16 @@ function ChatMessage({
12320
12391
  "data-slot": "chat-message",
12321
12392
  "data-role": role,
12322
12393
  "data-status": status,
12323
- className: cn("flex w-full flex-col gap-1.5", isUser && "items-end", className),
12394
+ className: cn(
12395
+ "flex w-full flex-col gap-1.5",
12396
+ isUser && "items-end",
12397
+ // system 居中弱提示(参考 @pactor-app/chat MessageBubble)
12398
+ isSystem && "items-center text-muted-foreground",
12399
+ className
12400
+ ),
12324
12401
  style,
12325
12402
  children: [
12326
- showSender && role !== "system" ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
12403
+ showSender ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
12327
12404
  Sender,
12328
12405
  {
12329
12406
  name: senderName,
@@ -12332,35 +12409,445 @@ function ChatMessage({
12332
12409
  align: isUser ? "end" : "start"
12333
12410
  }
12334
12411
  ) : null,
12335
- /* @__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: [
12336
- parts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(PartView, { part, role }, index)),
12412
+ /* @__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: [
12413
+ parts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(PartView, { part, role, onOpenArtifacts }, index)),
12337
12414
  status === "streaming" ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(StreamingText, { content: "", streaming: true }) : null
12338
12415
  ] }),
12339
- 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)(
12340
- "button",
12341
- {
12342
- type: "button",
12343
- "data-slot": "chat-message-action",
12344
- "data-action": action.name,
12345
- 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",
12346
- onClick: () => onAction?.(action.name),
12347
- children: [
12348
- action.icon ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: action.icon, size: "sm" }) : null,
12349
- action.label ?? action.name
12350
- ]
12351
- },
12352
- action.name
12353
- )) }) : null
12416
+ 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) => {
12417
+ const label = action.label ?? action.name;
12418
+ const iconName = action.icon ?? ACTION_ICON_BY_NAME[action.name];
12419
+ if (iconName) {
12420
+ return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Tooltip2, { content: label, side: "top", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
12421
+ "button",
12422
+ {
12423
+ type: "button",
12424
+ "data-slot": "chat-message-action",
12425
+ "data-action": action.name,
12426
+ "aria-label": label,
12427
+ className: "flex cursor-pointer items-center rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-foreground",
12428
+ onClick: () => onAction?.(action.name),
12429
+ children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: iconName, size: "sm" })
12430
+ }
12431
+ ) }, action.name);
12432
+ }
12433
+ return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
12434
+ "button",
12435
+ {
12436
+ type: "button",
12437
+ "data-slot": "chat-message-action",
12438
+ "data-action": action.name,
12439
+ 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",
12440
+ onClick: () => onAction?.(action.name),
12441
+ children: label
12442
+ },
12443
+ action.name
12444
+ );
12445
+ }) }) : null
12354
12446
  ]
12355
12447
  }
12356
12448
  );
12357
12449
  }
12358
12450
 
12359
12451
  // src/components/chat/ChatPage/index.tsx
12360
- var import_react65 = require("react");
12452
+ var import_runtime26 = require("@pactor-app/runtime");
12453
+ var import_react67 = require("react");
12361
12454
 
12362
12455
  // src/components/chat/Composer/index.tsx
12456
+ var import_react64 = require("react");
12457
+
12458
+ // src/components/chat/Composer/mention-input.tsx
12459
+ var import_react63 = require("react");
12460
+ var import_server = require("react-dom/server");
12363
12461
  var import_jsx_runtime179 = require("react/jsx-runtime");
12462
+ var NBSP = "\xA0";
12463
+ var CHIP_ATTR = "data-mention-chip";
12464
+ function escapeRegExp(text) {
12465
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12466
+ }
12467
+ function isChipElement(node) {
12468
+ return node instanceof HTMLElement && node.hasAttribute(CHIP_ATTR);
12469
+ }
12470
+ function serializeNode(node) {
12471
+ let out = "";
12472
+ node.childNodes.forEach((child) => {
12473
+ if (child.nodeType === Node.TEXT_NODE) {
12474
+ out += (child.textContent ?? "").replace(/\u00A0/g, " ");
12475
+ } else if (isChipElement(child)) {
12476
+ out += `${child.dataset["trigger"] ?? ""}${child.dataset["label"] ?? ""}`;
12477
+ } else if (child instanceof HTMLBRElement) {
12478
+ out += "\n";
12479
+ } else if (child instanceof HTMLElement) {
12480
+ const inner = serializeNode(child).replace(/\n$/, "");
12481
+ out += (out === "" || out.endsWith("\n") ? "" : "\n") + inner + "\n";
12482
+ }
12483
+ });
12484
+ return out;
12485
+ }
12486
+ function collectChips(field) {
12487
+ return Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).map((el) => ({
12488
+ id: el.dataset["id"] ?? "",
12489
+ label: el.dataset["label"] ?? "",
12490
+ trigger: el.dataset["trigger"] ?? ""
12491
+ }));
12492
+ }
12493
+ function detectActiveMention(field, sources) {
12494
+ const selection = window.getSelection();
12495
+ if (!selection || selection.rangeCount === 0 || !selection.isCollapsed) {
12496
+ return null;
12497
+ }
12498
+ const anchor = selection.anchorNode;
12499
+ if (!anchor || anchor.nodeType !== Node.TEXT_NODE || !field.contains(anchor)) {
12500
+ return null;
12501
+ }
12502
+ const caretOffset = selection.anchorOffset;
12503
+ const beforeCaret = (anchor.textContent ?? "").slice(0, caretOffset);
12504
+ for (const source of sources) {
12505
+ const trigger = source.trigger;
12506
+ const match = new RegExp(
12507
+ `(?:^|\\s)${escapeRegExp(trigger)}([^\\s${escapeRegExp(trigger)}]*)$`
12508
+ ).exec(beforeCaret);
12509
+ if (match) {
12510
+ const query = match[1] ?? "";
12511
+ return {
12512
+ source,
12513
+ query,
12514
+ node: anchor,
12515
+ triggerStart: caretOffset - query.length - trigger.length,
12516
+ caretOffset
12517
+ };
12518
+ }
12519
+ }
12520
+ return null;
12521
+ }
12522
+ function chipIcon(item, source) {
12523
+ return item.icon ?? source.icon ?? (source.trigger === "@" ? "user" : "file-text");
12524
+ }
12525
+ var MentionInput = (0, import_react63.forwardRef)(
12526
+ function MentionInput2({
12527
+ value,
12528
+ placeholder,
12529
+ disabled,
12530
+ sources,
12531
+ chips,
12532
+ onChipsChange,
12533
+ onChange,
12534
+ onSubmit,
12535
+ className,
12536
+ style
12537
+ }, ref) {
12538
+ const fieldRef = (0, import_react63.useRef)(null);
12539
+ const [menu, setMenu] = (0, import_react63.useState)(null);
12540
+ const [empty, setEmpty] = (0, import_react63.useState)(true);
12541
+ const suppressSyncRef = (0, import_react63.useRef)(false);
12542
+ const composingRef = (0, import_react63.useRef)(false);
12543
+ const emitChips = () => {
12544
+ if (suppressSyncRef.current || !fieldRef.current) {
12545
+ return;
12546
+ }
12547
+ onChipsChange?.(collectChips(fieldRef.current));
12548
+ };
12549
+ const serialize = () => fieldRef.current ? serializeNode(fieldRef.current).replace(/\n$/, "") : "";
12550
+ const buildChipElement = (item, source) => {
12551
+ const chip = document.createElement("span");
12552
+ chip.setAttribute(CHIP_ATTR, "");
12553
+ chip.dataset["id"] = item.id;
12554
+ chip.dataset["label"] = item.label;
12555
+ chip.dataset["trigger"] = item.trigger ?? source.trigger;
12556
+ chip.contentEditable = "false";
12557
+ 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";
12558
+ const iconMarkup = (0, import_server.renderToStaticMarkup)(
12559
+ /* @__PURE__ */ (0, import_jsx_runtime179.jsx)(Icon, { name: chipIcon(item, source), size: 12 })
12560
+ );
12561
+ const label = document.createElement("span");
12562
+ label.textContent = item.label;
12563
+ chip.innerHTML = iconMarkup;
12564
+ chip.appendChild(label);
12565
+ return chip;
12566
+ };
12567
+ const insertChipElement = (item, source, replace) => {
12568
+ const field = fieldRef.current;
12569
+ if (!field) {
12570
+ return;
12571
+ }
12572
+ const chip = buildChipElement(item, source);
12573
+ let caretNode;
12574
+ if (replace) {
12575
+ const { node, start, end } = replace;
12576
+ const text = node.textContent ?? "";
12577
+ node.textContent = text.slice(0, start);
12578
+ caretNode = document.createTextNode(`${NBSP}${text.slice(end)}`);
12579
+ node.after(chip, caretNode);
12580
+ } else {
12581
+ caretNode = document.createTextNode(NBSP);
12582
+ const selection2 = window.getSelection();
12583
+ if (selection2 && selection2.rangeCount > 0 && selection2.anchorNode !== null && field.contains(selection2.anchorNode)) {
12584
+ const range = selection2.getRangeAt(0);
12585
+ range.deleteContents();
12586
+ range.insertNode(caretNode);
12587
+ range.insertNode(chip);
12588
+ } else {
12589
+ field.append(chip, caretNode);
12590
+ }
12591
+ }
12592
+ const selection = window.getSelection();
12593
+ if (selection) {
12594
+ const range = document.createRange();
12595
+ range.setStart(caretNode, 1);
12596
+ range.collapse(true);
12597
+ selection.removeAllRanges();
12598
+ selection.addRange(range);
12599
+ }
12600
+ setEmpty(false);
12601
+ onChange?.(serialize());
12602
+ emitChips();
12603
+ };
12604
+ (0, import_react63.useImperativeHandle)(ref, () => ({
12605
+ insertChip: (item, source) => {
12606
+ fieldRef.current?.focus();
12607
+ insertChipElement(item, source);
12608
+ },
12609
+ focus: () => fieldRef.current?.focus()
12610
+ }));
12611
+ (0, import_react63.useEffect)(() => {
12612
+ const field = fieldRef.current;
12613
+ if (field && value === "" && serializeNode(field).trim() !== "") {
12614
+ suppressSyncRef.current = true;
12615
+ field.innerHTML = "";
12616
+ setEmpty(true);
12617
+ setMenu(null);
12618
+ suppressSyncRef.current = false;
12619
+ }
12620
+ }, [value]);
12621
+ (0, import_react63.useEffect)(() => {
12622
+ const field = fieldRef.current;
12623
+ if (!field) {
12624
+ return;
12625
+ }
12626
+ const keep = new Set(chips.map((chip) => `${chip.trigger}:${chip.id}`));
12627
+ const stale = Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).filter(
12628
+ (el) => !keep.has(
12629
+ `${el.dataset["trigger"]}:${el.dataset["id"]}`
12630
+ )
12631
+ );
12632
+ if (stale.length > 0) {
12633
+ suppressSyncRef.current = true;
12634
+ stale.forEach((el) => el.remove());
12635
+ suppressSyncRef.current = false;
12636
+ setEmpty(serializeNode(field).trim() === "");
12637
+ }
12638
+ }, [chips]);
12639
+ const closeMenu = () => setMenu(null);
12640
+ const filteredItems = (state) => state.query ? state.source.items.filter((item) => item.label.includes(state.query)) : state.source.items;
12641
+ const refreshMenu = () => {
12642
+ const field = fieldRef.current;
12643
+ if (!field) {
12644
+ return;
12645
+ }
12646
+ const active = detectActiveMention(field, sources);
12647
+ if (!active) {
12648
+ setMenu(null);
12649
+ return;
12650
+ }
12651
+ const range = document.createRange();
12652
+ range.setStart(active.node, active.triggerStart);
12653
+ range.setEnd(active.node, active.caretOffset);
12654
+ const rect = typeof range.getBoundingClientRect === "function" ? range.getBoundingClientRect() : field.getBoundingClientRect();
12655
+ setMenu((prev) => ({
12656
+ source: active.source,
12657
+ query: active.query,
12658
+ left: rect.left,
12659
+ top: rect.top,
12660
+ // 过滤结果变化后候选下标钳制在有效范围内(DSL 每次渲染产出新
12661
+ // props 对象,source 按 trigger 比较而非引用)
12662
+ activeIndex: Math.min(
12663
+ prev?.source.trigger === active.source.trigger ? prev.activeIndex : 0,
12664
+ Math.max(filteredItems({ source: active.source, query: active.query, left: 0, top: 0, activeIndex: 0 }).length - 1, 0)
12665
+ )
12666
+ }));
12667
+ };
12668
+ const selectMenuItem = (item) => {
12669
+ const field = fieldRef.current;
12670
+ if (!field || !menu) {
12671
+ return;
12672
+ }
12673
+ const active = detectActiveMention(field, sources);
12674
+ insertChipElement(
12675
+ { ...item, trigger: item.trigger ?? menu.source.trigger },
12676
+ menu.source,
12677
+ active && active.source.trigger === menu.source.trigger ? { node: active.node, start: active.triggerStart, end: active.caretOffset } : void 0
12678
+ );
12679
+ setMenu(null);
12680
+ };
12681
+ const handleInput = () => {
12682
+ const field = fieldRef.current;
12683
+ if (!field) {
12684
+ return;
12685
+ }
12686
+ if ((field.textContent ?? "") === "" && field.querySelector(`[${CHIP_ATTR}]`) === null) {
12687
+ field.innerHTML = "";
12688
+ }
12689
+ setEmpty(serializeNode(field).trim() === "");
12690
+ onChange?.(serialize());
12691
+ refreshMenu();
12692
+ };
12693
+ const handleKeyDown = (event) => {
12694
+ if (menu) {
12695
+ const items = filteredItems(menu);
12696
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
12697
+ event.preventDefault();
12698
+ if (items.length > 0) {
12699
+ const delta = event.key === "ArrowDown" ? 1 : -1;
12700
+ setMenu({
12701
+ ...menu,
12702
+ activeIndex: (menu.activeIndex + delta + items.length) % items.length
12703
+ });
12704
+ }
12705
+ return;
12706
+ }
12707
+ if (event.key === "Enter" && !composingRef.current && !event.nativeEvent.isComposing) {
12708
+ event.preventDefault();
12709
+ const item = items[Math.min(menu.activeIndex, items.length - 1)];
12710
+ if (item) {
12711
+ selectMenuItem(item);
12712
+ } else {
12713
+ closeMenu();
12714
+ }
12715
+ return;
12716
+ }
12717
+ if (event.key === "Escape") {
12718
+ event.preventDefault();
12719
+ closeMenu();
12720
+ return;
12721
+ }
12722
+ }
12723
+ if (event.key === "Enter" && !event.shiftKey && !composingRef.current && !event.nativeEvent.isComposing) {
12724
+ event.preventDefault();
12725
+ const text = serialize();
12726
+ if (text.trim() !== "" && !disabled) {
12727
+ onSubmit?.(text);
12728
+ }
12729
+ return;
12730
+ }
12731
+ if (event.key === "Backspace") {
12732
+ const selection = window.getSelection();
12733
+ const field = fieldRef.current;
12734
+ if (!selection || !selection.isCollapsed || !field) {
12735
+ return;
12736
+ }
12737
+ let chip = null;
12738
+ const anchor = selection.anchorNode;
12739
+ if (anchor === field && selection.anchorOffset > 0) {
12740
+ const before = field.childNodes[selection.anchorOffset - 1];
12741
+ if (isChipElement(before)) {
12742
+ chip = before;
12743
+ }
12744
+ } else if (anchor?.nodeType === Node.TEXT_NODE && selection.anchorOffset === 0) {
12745
+ if (isChipElement(anchor.previousSibling)) {
12746
+ chip = anchor.previousSibling;
12747
+ }
12748
+ }
12749
+ if (chip) {
12750
+ event.preventDefault();
12751
+ chip.remove();
12752
+ onChange?.(serialize());
12753
+ emitChips();
12754
+ setEmpty(serializeNode(field).trim() === "");
12755
+ }
12756
+ }
12757
+ };
12758
+ const menuItems = menu ? filteredItems(menu) : [];
12759
+ const activeIndex = Math.min(menu?.activeIndex ?? 0, Math.max(menuItems.length - 1, 0));
12760
+ return /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)("div", { className: "relative", children: [
12761
+ /* @__PURE__ */ (0, import_jsx_runtime179.jsx)(
12762
+ "div",
12763
+ {
12764
+ ref: fieldRef,
12765
+ "data-slot": "mention-input",
12766
+ role: "textbox",
12767
+ "aria-multiline": "true",
12768
+ "aria-placeholder": placeholder,
12769
+ contentEditable: !disabled,
12770
+ suppressContentEditableWarning: true,
12771
+ className: cn(
12772
+ "min-h-[60px] w-full px-4 pt-3 pb-1 text-sm whitespace-pre-wrap break-words outline-none",
12773
+ className
12774
+ ),
12775
+ style,
12776
+ onInput: handleInput,
12777
+ onKeyDown: handleKeyDown,
12778
+ onCompositionStart: () => {
12779
+ composingRef.current = true;
12780
+ },
12781
+ onCompositionEnd: () => {
12782
+ composingRef.current = false;
12783
+ },
12784
+ onPaste: (event) => {
12785
+ event.preventDefault();
12786
+ const text = event.clipboardData?.getData("text/plain") ?? "";
12787
+ if (text) {
12788
+ document.execCommand("insertText", false, text);
12789
+ }
12790
+ }
12791
+ }
12792
+ ),
12793
+ 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,
12794
+ menu ? /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)(import_jsx_runtime179.Fragment, { children: [
12795
+ /* @__PURE__ */ (0, import_jsx_runtime179.jsx)(
12796
+ "div",
12797
+ {
12798
+ className: "fixed inset-0 z-40",
12799
+ onMouseDown: (event) => {
12800
+ event.preventDefault();
12801
+ closeMenu();
12802
+ }
12803
+ }
12804
+ ),
12805
+ /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)(
12806
+ "div",
12807
+ {
12808
+ "data-slot": "mention-menu",
12809
+ role: "listbox",
12810
+ 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",
12811
+ style: {
12812
+ left: menu.left,
12813
+ bottom: typeof window === "undefined" ? void 0 : window.innerHeight - menu.top + 6
12814
+ },
12815
+ children: [
12816
+ /* @__PURE__ */ (0, import_jsx_runtime179.jsx)("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: menu.source.label }),
12817
+ 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)(
12818
+ "button",
12819
+ {
12820
+ type: "button",
12821
+ role: "option",
12822
+ "aria-selected": index === activeIndex,
12823
+ className: cn(
12824
+ "flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm",
12825
+ index === activeIndex ? "bg-accent" : "hover:bg-accent"
12826
+ ),
12827
+ onMouseDown: (event) => {
12828
+ event.preventDefault();
12829
+ selectMenuItem(item);
12830
+ },
12831
+ children: [
12832
+ /* @__PURE__ */ (0, import_jsx_runtime179.jsx)(Icon, { name: chipIcon(item, menu.source), size: "sm" }),
12833
+ /* @__PURE__ */ (0, import_jsx_runtime179.jsx)("span", { className: "min-w-0 flex-1 truncate", children: item.label })
12834
+ ]
12835
+ },
12836
+ item.id
12837
+ ))
12838
+ ]
12839
+ }
12840
+ )
12841
+ ] }) : null
12842
+ ] });
12843
+ }
12844
+ );
12845
+
12846
+ // src/components/chat/Composer/index.tsx
12847
+ var import_jsx_runtime180 = require("react/jsx-runtime");
12848
+ var toolButtonClass3 = "flex cursor-pointer items-center rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground";
12849
+ 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";
12850
+ 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";
12364
12851
  function Composer({
12365
12852
  value,
12366
12853
  placeholder,
@@ -12370,35 +12857,238 @@ function Composer({
12370
12857
  attachments = [],
12371
12858
  onRemoveAttachment,
12372
12859
  onRetryAttachment,
12860
+ onAttachFiles,
12373
12861
  onChange,
12374
12862
  onSubmit,
12863
+ models,
12864
+ model,
12865
+ onModelChange,
12866
+ contexts,
12867
+ contextItems,
12868
+ onContextItemsChange,
12869
+ footer,
12375
12870
  className,
12376
12871
  style
12377
12872
  }) {
12378
- return /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)("div", { "data-slot": "composer", className: cn("flex w-full flex-col gap-2", className), style, children: [
12379
- attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime179.jsx)(Attachment, { items: attachments, onRemove: onRemoveAttachment, onRetry: onRetryAttachment }) : null,
12380
- /* @__PURE__ */ (0, import_jsx_runtime179.jsx)(
12381
- ChatInput,
12873
+ const textControlled = value !== void 0;
12874
+ const [innerText, setInnerText] = (0, import_react64.useState)("");
12875
+ const text = textControlled ? value : innerText;
12876
+ const [dragOver, setDragOver] = (0, import_react64.useState)(false);
12877
+ const [plusOpen, setPlusOpen] = (0, import_react64.useState)(false);
12878
+ const [modelOpen, setModelOpen] = (0, import_react64.useState)(false);
12879
+ const fileInputRef = (0, import_react64.useRef)(null);
12880
+ const mentionRef = (0, import_react64.useRef)(null);
12881
+ const sources = contexts ?? [];
12882
+ const rich = sources.length > 0;
12883
+ const plusSources = sources.filter((s) => s.trigger === "+");
12884
+ const plusEnabled = plusSources.length > 0;
12885
+ const modelEnabled = models !== void 0 && models.length > 0;
12886
+ const currentModel = models?.find((m) => m.value === model) ?? models?.[0];
12887
+ const chips = contextItems ?? [];
12888
+ const closePopovers = () => {
12889
+ setPlusOpen(false);
12890
+ setModelOpen(false);
12891
+ };
12892
+ const handleChange = (next) => {
12893
+ if (!textControlled) {
12894
+ setInnerText(next);
12895
+ }
12896
+ onChange?.(next);
12897
+ };
12898
+ const handleSubmit = (submitted) => {
12899
+ onSubmit?.(submitted);
12900
+ if (!textControlled) {
12901
+ setInnerText("");
12902
+ }
12903
+ closePopovers();
12904
+ };
12905
+ const selectContext = (item, source) => {
12906
+ if (rich) {
12907
+ mentionRef.current?.insertChip(item, source);
12908
+ } else {
12909
+ const chip = { ...item, trigger: item.trigger ?? source.trigger };
12910
+ const duplicated = chips.some(
12911
+ (existing) => existing.id === chip.id && existing.trigger === chip.trigger
12912
+ );
12913
+ if (!duplicated) {
12914
+ onContextItemsChange?.([...chips, chip]);
12915
+ }
12916
+ }
12917
+ closePopovers();
12918
+ };
12919
+ const emitFiles = (files) => {
12920
+ if (files.length > 0 && onAttachFiles) {
12921
+ onAttachFiles(files);
12922
+ }
12923
+ };
12924
+ const handleDrop = (event) => {
12925
+ if (!onAttachFiles) {
12926
+ return;
12927
+ }
12928
+ event.preventDefault();
12929
+ setDragOver(false);
12930
+ emitFiles(Array.from(event.dataTransfer?.files ?? []));
12931
+ };
12932
+ const toolbarStart = plusEnabled || onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(import_jsx_runtime180.Fragment, { children: [
12933
+ plusEnabled ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
12934
+ "button",
12382
12935
  {
12383
- value,
12384
- placeholder,
12385
- disabled: disabled || loading,
12386
- rows,
12387
- onChange,
12388
- onSubmit
12936
+ type: "button",
12937
+ "aria-label": "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
12938
+ title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
12939
+ className: toolButtonClass3,
12940
+ onClick: () => {
12941
+ setPlusOpen((prev) => !prev);
12942
+ setModelOpen(false);
12943
+ },
12944
+ children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "plus", size: "sm" })
12389
12945
  }
12390
- )
12391
- ] });
12946
+ ) : null,
12947
+ onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
12948
+ "button",
12949
+ {
12950
+ type: "button",
12951
+ "aria-label": "\u6DFB\u52A0\u9644\u4EF6",
12952
+ title: "\u6DFB\u52A0\u9644\u4EF6",
12953
+ className: toolButtonClass3,
12954
+ onClick: () => fileInputRef.current?.click(),
12955
+ children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "paperclip", size: "sm" })
12956
+ }
12957
+ ) : null
12958
+ ] }) : void 0;
12959
+ const toolbarEnd = modelEnabled ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
12960
+ "button",
12961
+ {
12962
+ type: "button",
12963
+ "aria-label": "\u9009\u62E9\u6A21\u578B",
12964
+ title: "\u9009\u62E9\u6A21\u578B",
12965
+ 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",
12966
+ onClick: () => {
12967
+ setModelOpen((prev) => !prev);
12968
+ setPlusOpen(false);
12969
+ },
12970
+ children: [
12971
+ currentModel?.label,
12972
+ /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "chevrons-up-down", size: 12 })
12973
+ ]
12974
+ }
12975
+ ) : void 0;
12976
+ const activePopover = plusOpen ? "plus" : modelOpen ? "model" : null;
12977
+ return /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
12978
+ "div",
12979
+ {
12980
+ "data-slot": "composer",
12981
+ className: cn("relative flex w-full flex-col gap-2", className),
12982
+ style,
12983
+ onDragOver: (event) => {
12984
+ if (onAttachFiles) {
12985
+ event.preventDefault();
12986
+ setDragOver(true);
12987
+ }
12988
+ },
12989
+ onDragLeave: () => setDragOver(false),
12990
+ onDrop: handleDrop,
12991
+ onPaste: (event) => {
12992
+ const files = Array.from(event.clipboardData?.files ?? []);
12993
+ if (files.length > 0 && onAttachFiles) {
12994
+ event.preventDefault();
12995
+ emitFiles(files);
12996
+ }
12997
+ },
12998
+ children: [
12999
+ attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Attachment, { items: attachments, onRemove: onRemoveAttachment, onRetry: onRetryAttachment }) : null,
13000
+ /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: cn(dragOver && "rounded-xl ring-2 ring-ring/50"), children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
13001
+ ChatInput,
13002
+ {
13003
+ value: text,
13004
+ placeholder,
13005
+ disabled: disabled || loading,
13006
+ rows,
13007
+ toolbarStart,
13008
+ toolbarEnd,
13009
+ footer,
13010
+ field: rich ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
13011
+ MentionInput,
13012
+ {
13013
+ ref: mentionRef,
13014
+ value: text,
13015
+ placeholder,
13016
+ disabled: disabled || loading,
13017
+ sources,
13018
+ chips,
13019
+ onChipsChange: onContextItemsChange,
13020
+ onChange: handleChange,
13021
+ onSubmit: handleSubmit
13022
+ }
13023
+ ) : void 0,
13024
+ onChange: handleChange,
13025
+ onSubmit: handleSubmit
13026
+ }
13027
+ ) }),
13028
+ onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
13029
+ "input",
13030
+ {
13031
+ ref: fileInputRef,
13032
+ type: "file",
13033
+ multiple: true,
13034
+ hidden: true,
13035
+ onChange: (event) => {
13036
+ emitFiles(Array.from(event.target.files ?? []));
13037
+ event.target.value = "";
13038
+ }
13039
+ }
13040
+ ) : null,
13041
+ activePopover !== null ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(import_jsx_runtime180.Fragment, { children: [
13042
+ /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: "fixed inset-0 z-40", onClick: closePopovers }),
13043
+ 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)(
13044
+ "button",
13045
+ {
13046
+ type: "button",
13047
+ role: "option",
13048
+ "aria-selected": option.value === currentModel?.value,
13049
+ className: popoverItemClass,
13050
+ onClick: () => {
13051
+ onModelChange?.(option.value);
13052
+ closePopovers();
13053
+ },
13054
+ children: [
13055
+ /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("span", { className: "min-w-0 flex-1 truncate", children: option.label }),
13056
+ option.value === currentModel?.value ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "check", size: 14 }) : null
13057
+ ]
13058
+ },
13059
+ option.value
13060
+ )) }) : /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { "data-slot": "composer-context-popover", className: popoverPanelClass, role: "listbox", children: plusSources.map(
13061
+ (source) => source.items.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)("div", { children: [
13062
+ /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: source.label }),
13063
+ source.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
13064
+ "button",
13065
+ {
13066
+ type: "button",
13067
+ className: popoverItemClass,
13068
+ onClick: () => selectContext(item, source),
13069
+ children: [
13070
+ /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: item.icon ?? source.icon ?? "file-text", size: "sm" }),
13071
+ /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("span", { className: "min-w-0 flex-1 truncate", children: item.label })
13072
+ ]
13073
+ },
13074
+ item.id
13075
+ ))
13076
+ ] }, source.trigger)
13077
+ ) })
13078
+ ] }) : null
13079
+ ]
13080
+ }
13081
+ );
12392
13082
  }
12393
13083
 
12394
13084
  // src/components/chat/ConversationList/index.tsx
12395
- var import_react63 = require("react");
12396
- var import_jsx_runtime180 = require("react/jsx-runtime");
13085
+ var import_react65 = require("react");
13086
+ var import_jsx_runtime181 = require("react/jsx-runtime");
12397
13087
  function ConversationList({ items = [], activeId, searchable, onSelect, onDelete, className, style }) {
12398
- const [innerActive, setInnerActive] = (0, import_react63.useState)();
12399
- const [keyword, setKeyword] = (0, import_react63.useState)("");
13088
+ const [innerActive, setInnerActive] = (0, import_react65.useState)();
13089
+ const [keyword, setKeyword] = (0, import_react65.useState)("");
12400
13090
  const active = activeId ?? innerActive;
12401
- const filtered = (0, import_react63.useMemo)(() => {
13091
+ const filtered = (0, import_react65.useMemo)(() => {
12402
13092
  const query = keyword.trim().toLowerCase();
12403
13093
  if (!query) return items;
12404
13094
  return items.filter(
@@ -12411,10 +13101,10 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
12411
13101
  }
12412
13102
  onSelect?.(id);
12413
13103
  };
12414
- return /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)("div", { "data-slot": "conversation-list", className: cn("flex w-full flex-col gap-1", className), style, children: [
12415
- searchable ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)("div", { className: "relative mb-1", children: [
12416
- /* @__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" }) }),
12417
- /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
13104
+ return /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { "data-slot": "conversation-list", className: cn("flex w-full flex-col gap-1", className), style, children: [
13105
+ searchable ? /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { className: "relative mb-1", children: [
13106
+ /* @__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" }) }),
13107
+ /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(
12418
13108
  "input",
12419
13109
  {
12420
13110
  "data-slot": "conversation-list-search",
@@ -12425,7 +13115,7 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
12425
13115
  }
12426
13116
  )
12427
13117
  ] }) : null,
12428
- filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
13118
+ filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)(
12429
13119
  "div",
12430
13120
  {
12431
13121
  "data-slot": "conversation-list-item",
@@ -12436,12 +13126,12 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
12436
13126
  ),
12437
13127
  onClick: () => select(item.id),
12438
13128
  children: [
12439
- /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)("div", { className: "min-w-0 flex-1", children: [
12440
- /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: cn("truncate text-sm", item.id === active && "font-medium"), children: item.title }),
12441
- item.description ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
13129
+ /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { className: "min-w-0 flex-1", children: [
13130
+ /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("div", { className: cn("truncate text-sm", item.id === active && "font-medium"), children: item.title }),
13131
+ item.description ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
12442
13132
  ] }),
12443
- item.time ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.time }) : null,
12444
- onDelete ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
13133
+ item.time ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.time }) : null,
13134
+ onDelete ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(
12445
13135
  "button",
12446
13136
  {
12447
13137
  type: "button",
@@ -12452,41 +13142,42 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
12452
13142
  event.stopPropagation();
12453
13143
  onDelete(item.id);
12454
13144
  },
12455
- children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "trash-2", size: "sm" })
13145
+ children: /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(Icon, { name: "trash-2", size: "sm" })
12456
13146
  }
12457
13147
  ) : null
12458
13148
  ]
12459
13149
  },
12460
13150
  item.id
12461
13151
  )),
12462
- 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
13152
+ 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
12463
13153
  ] });
12464
13154
  }
12465
13155
 
12466
13156
  // src/components/chat/MessageList/index.tsx
12467
- var import_react64 = require("react");
12468
- var import_jsx_runtime181 = require("react/jsx-runtime");
12469
- function MessageList({ messages = [], autoScroll = true, onAction, className, style }) {
12470
- const listRef = (0, import_react64.useRef)(null);
12471
- (0, import_react64.useEffect)(() => {
13157
+ var import_react66 = require("react");
13158
+ var import_jsx_runtime182 = require("react/jsx-runtime");
13159
+ function MessageList({ messages = [], autoScroll = true, onAction, onOpenArtifacts, className, style }) {
13160
+ const listRef = (0, import_react66.useRef)(null);
13161
+ (0, import_react66.useEffect)(() => {
12472
13162
  if (!autoScroll) return;
12473
13163
  const el = listRef.current;
12474
13164
  if (el) {
12475
13165
  el.scrollTop = el.scrollHeight;
12476
13166
  }
12477
13167
  }, [messages, autoScroll]);
12478
- return /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(
13168
+ return /* @__PURE__ */ (0, import_jsx_runtime182.jsx)(
12479
13169
  "div",
12480
13170
  {
12481
13171
  ref: listRef,
12482
13172
  "data-slot": "message-list",
12483
13173
  className: cn("flex w-full flex-col gap-4 overflow-y-auto", className),
12484
13174
  style,
12485
- children: messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(
13175
+ children: messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime182.jsx)(
12486
13176
  ChatMessage,
12487
13177
  {
12488
13178
  ...message,
12489
- onAction: (action) => onAction?.({ id: message.id, action })
13179
+ onAction: (action) => onAction?.({ id: message.id, action }),
13180
+ onOpenArtifacts: onOpenArtifacts ? () => onOpenArtifacts({ id: message.id }) : void 0
12490
13181
  },
12491
13182
  message.id ?? index
12492
13183
  ))
@@ -12495,9 +13186,9 @@ function MessageList({ messages = [], autoScroll = true, onAction, className, st
12495
13186
  }
12496
13187
 
12497
13188
  // src/components/chat/Prompt/index.tsx
12498
- var import_jsx_runtime182 = require("react/jsx-runtime");
13189
+ var import_jsx_runtime183 = require("react/jsx-runtime");
12499
13190
  function Prompt({ title, description, icon, value, disabled, onSelect, className, style }) {
12500
- return /* @__PURE__ */ (0, import_jsx_runtime182.jsxs)(
13191
+ return /* @__PURE__ */ (0, import_jsx_runtime183.jsxs)(
12501
13192
  "button",
12502
13193
  {
12503
13194
  type: "button",
@@ -12510,10 +13201,10 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
12510
13201
  style,
12511
13202
  onClick: () => onSelect?.(value ?? title ?? ""),
12512
13203
  children: [
12513
- 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,
12514
- /* @__PURE__ */ (0, import_jsx_runtime182.jsxs)("span", { className: "min-w-0", children: [
12515
- /* @__PURE__ */ (0, import_jsx_runtime182.jsx)("span", { "data-slot": "prompt-title", className: "block text-sm font-medium", children: title }),
12516
- 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
13204
+ 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,
13205
+ /* @__PURE__ */ (0, import_jsx_runtime183.jsxs)("span", { className: "min-w-0", children: [
13206
+ /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("span", { "data-slot": "prompt-title", className: "block text-sm font-medium", children: title }),
13207
+ 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
12517
13208
  ] })
12518
13209
  ]
12519
13210
  }
@@ -12521,7 +13212,7 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
12521
13212
  }
12522
13213
 
12523
13214
  // src/components/chat/Welcome/index.tsx
12524
- var import_jsx_runtime183 = require("react/jsx-runtime");
13215
+ var import_jsx_runtime184 = require("react/jsx-runtime");
12525
13216
  function Welcome({
12526
13217
  title = "\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F",
12527
13218
  description,
@@ -12531,19 +13222,19 @@ function Welcome({
12531
13222
  className,
12532
13223
  style
12533
13224
  }) {
12534
- return /* @__PURE__ */ (0, import_jsx_runtime183.jsxs)(
13225
+ return /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
12535
13226
  "div",
12536
13227
  {
12537
13228
  "data-slot": "welcome",
12538
13229
  className: cn("flex w-full flex-col items-center gap-4 py-10 text-center", className),
12539
13230
  style,
12540
13231
  children: [
12541
- /* @__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" }) }),
12542
- /* @__PURE__ */ (0, import_jsx_runtime183.jsxs)("div", { children: [
12543
- /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("div", { "data-slot": "welcome-title", className: "text-xl font-semibold", children: title }),
12544
- description ? /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("div", { "data-slot": "welcome-description", className: "mt-1 text-sm text-muted-foreground", children: description }) : null
13232
+ /* @__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" }) }),
13233
+ /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("div", { children: [
13234
+ /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { "data-slot": "welcome-title", className: "text-xl font-semibold", children: title }),
13235
+ description ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { "data-slot": "welcome-description", className: "mt-1 text-sm text-muted-foreground", children: description }) : null
12545
13236
  ] }),
12546
- 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)(
13237
+ 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)(
12547
13238
  Prompt,
12548
13239
  {
12549
13240
  title: item.title,
@@ -12560,7 +13251,7 @@ function Welcome({
12560
13251
  }
12561
13252
 
12562
13253
  // src/components/chat/ChatPage/index.tsx
12563
- var import_jsx_runtime184 = require("react/jsx-runtime");
13254
+ var import_jsx_runtime185 = require("react/jsx-runtime");
12564
13255
  function ChatPage({
12565
13256
  brand,
12566
13257
  menuItems = [],
@@ -12586,12 +13277,26 @@ function ChatPage({
12586
13277
  defaultFooterSectionCollapsed = false,
12587
13278
  onFooterSectionToggle,
12588
13279
  conversationTitle,
13280
+ conversationHeaderAction,
13281
+ onConversationHeaderAction,
12589
13282
  messages = [],
12590
13283
  sending,
12591
13284
  composerPlaceholder,
12592
13285
  welcome,
12593
13286
  onSend,
12594
13287
  onMessageAction,
13288
+ models,
13289
+ model,
13290
+ onModelChange,
13291
+ contexts,
13292
+ contextItems,
13293
+ onContextItemsChange,
13294
+ attachments,
13295
+ onAttachFiles,
13296
+ onRemoveAttachment,
13297
+ onRetryAttachment,
13298
+ composerFooter,
13299
+ composerBottom,
12595
13300
  artifactTitle = "\u4EA7\u7269",
12596
13301
  artifacts = [],
12597
13302
  activeArtifactId,
@@ -12602,20 +13307,22 @@ function ChatPage({
12602
13307
  artifactViewers,
12603
13308
  onDownloadArtifact,
12604
13309
  artifactOpen,
12605
- defaultArtifactOpen = true,
13310
+ defaultArtifactOpen = false,
12606
13311
  onArtifactOpenChange,
12607
13312
  className,
12608
13313
  style
12609
13314
  }) {
12610
13315
  const controlled = artifactOpen !== void 0;
12611
- const [innerOpen, setInnerOpen] = (0, import_react65.useState)(defaultArtifactOpen);
13316
+ const [innerOpen, setInnerOpen] = (0, import_react67.useState)(defaultArtifactOpen);
12612
13317
  const open = controlled ? artifactOpen === true : innerOpen;
12613
13318
  const setOpen = (next) => {
12614
13319
  if (!controlled) setInnerOpen(next);
12615
13320
  onArtifactOpenChange?.(next);
12616
13321
  };
13322
+ const { renderChildren } = (0, import_runtime26.useRenderer)();
13323
+ const renderSlot = (slot) => (0, import_react67.isValidElement)(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
12617
13324
  const convCollControlled = conversationSectionCollapsed !== void 0;
12618
- const [convCollapsedInner, setConvCollapsedInner] = (0, import_react65.useState)(
13325
+ const [convCollapsedInner, setConvCollapsedInner] = (0, import_react67.useState)(
12619
13326
  defaultConversationSectionCollapsed
12620
13327
  );
12621
13328
  const convCollapsed = convCollControlled ? conversationSectionCollapsed === true : convCollapsedInner;
@@ -12625,7 +13332,7 @@ function ChatPage({
12625
13332
  onConversationSectionToggle?.(next);
12626
13333
  };
12627
13334
  const footerCollControlled = footerSectionCollapsed !== void 0;
12628
- const [footerCollapsedInner, setFooterCollapsedInner] = (0, import_react65.useState)(
13335
+ const [footerCollapsedInner, setFooterCollapsedInner] = (0, import_react67.useState)(
12629
13336
  defaultFooterSectionCollapsed
12630
13337
  );
12631
13338
  const footerCollapsed = footerCollControlled ? footerSectionCollapsed === true : footerCollapsedInner;
@@ -12635,7 +13342,7 @@ function ChatPage({
12635
13342
  onFooterSectionToggle?.(next);
12636
13343
  };
12637
13344
  const railVisible = railItems.length > 0 || railFooterItems.length > 0;
12638
- const railButton = (item) => /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Tooltip2, { content: item.label, side: "right", children: /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
13345
+ const railButton = (item) => /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: item.label, side: "right", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
12639
13346
  Button2,
12640
13347
  {
12641
13348
  icon: item.icon,
@@ -12643,17 +13350,25 @@ function ChatPage({
12643
13350
  onClick: () => onMenuSelect?.(item.key)
12644
13351
  }
12645
13352
  ) }, item.key);
12646
- 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: [
12647
- /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
13353
+ 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: [
13354
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
12648
13355
  "div",
12649
13356
  {
12650
13357
  className: "flex shrink-0 items-center justify-between border-b border-border px-4 py-2.5",
12651
13358
  children: [
12652
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Text, { text: conversationTitle, strong: true }),
12653
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Tooltip2, { content: artifactTitle, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
13359
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: conversationTitle, strong: true }),
13360
+ conversationHeaderAction ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: conversationHeaderAction.tooltip ?? conversationHeaderAction.label, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
13361
+ Button2,
13362
+ {
13363
+ text: conversationHeaderAction.label,
13364
+ icon: conversationHeaderAction.icon,
13365
+ variant: "text",
13366
+ onClick: () => onConversationHeaderAction?.()
13367
+ }
13368
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: open ? "\u6536\u8D77\u4EA7\u7269\u533A" : artifactTitle, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
12654
13369
  Button2,
12655
13370
  {
12656
- icon: "panel-right-open",
13371
+ icon: open ? "panel-right-close" : "panel-right-open",
12657
13372
  variant: "text",
12658
13373
  onClick: () => setOpen(!open)
12659
13374
  }
@@ -12661,40 +13376,63 @@ function ChatPage({
12661
13376
  ]
12662
13377
  }
12663
13378
  ),
12664
- messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
12665
- Welcome,
12666
- {
12667
- title: welcome?.title,
12668
- description: welcome?.description,
12669
- prompts: welcome?.prompts,
12670
- style: { flex: 1 },
12671
- onSelect: (value) => onSend?.(value)
12672
- }
12673
- ) : /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
12674
- MessageList,
12675
- {
12676
- messages,
12677
- style: { flex: 1, minHeight: 0, padding: 16 },
12678
- onAction: onMessageAction
12679
- }
12680
- ),
12681
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
12682
- Composer,
13379
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
13380
+ "div",
12683
13381
  {
12684
- placeholder: composerPlaceholder,
12685
- loading: sending,
12686
- style: { padding: 16, borderTop: "1px solid var(--border)", flexShrink: 0 },
12687
- onSubmit: (text) => onSend?.(text)
13382
+ "data-slot": "chat-page-conversation-body",
13383
+ className: "mx-auto flex min-h-0 w-[61.8cqw] max-w-full flex-1 flex-col",
13384
+ children: [
13385
+ messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
13386
+ Welcome,
13387
+ {
13388
+ title: welcome?.title,
13389
+ description: welcome?.description,
13390
+ prompts: welcome?.prompts,
13391
+ style: { flex: 1 },
13392
+ onSelect: (value) => onSend?.(value)
13393
+ }
13394
+ ) : /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
13395
+ MessageList,
13396
+ {
13397
+ messages,
13398
+ className: "scrollbar-subtle",
13399
+ style: { flex: 1, minHeight: 0, padding: 16 },
13400
+ onAction: onMessageAction,
13401
+ onOpenArtifacts: () => setOpen(true)
13402
+ }
13403
+ ),
13404
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
13405
+ Composer,
13406
+ {
13407
+ placeholder: composerPlaceholder,
13408
+ loading: sending,
13409
+ models,
13410
+ model,
13411
+ contexts,
13412
+ contextItems,
13413
+ attachments,
13414
+ footer: composerFooter,
13415
+ style: { padding: 16, paddingBottom: composerBottom ? 8 : 16, flexShrink: 0 },
13416
+ onModelChange,
13417
+ onContextItemsChange,
13418
+ onAttachFiles,
13419
+ onRemoveAttachment,
13420
+ onRetryAttachment,
13421
+ onSubmit: (text) => onSend?.(text)
13422
+ }
13423
+ ),
13424
+ 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
13425
+ ]
12688
13426
  }
12689
13427
  )
12690
13428
  ] });
12691
13429
  const activeArtifact = artifacts.find((item) => item.id === activeArtifactId) ?? (activeArtifactId === void 0 || activeArtifactId === "" ? artifacts[artifacts.length - 1] : void 0);
12692
- const artifactPanel = /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
13430
+ const artifactPanel = /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
12693
13431
  "div",
12694
13432
  {
12695
13433
  "data-slot": "chat-page-artifact",
12696
13434
  className: "flex h-full min-w-0 flex-col border-l border-border bg-muted",
12697
- children: /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
13435
+ children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
12698
13436
  ArtifactPanel,
12699
13437
  {
12700
13438
  artifact: activeArtifact,
@@ -12712,37 +13450,37 @@ function ChatPage({
12712
13450
  )
12713
13451
  }
12714
13452
  );
12715
- return /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
13453
+ return /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
12716
13454
  "div",
12717
13455
  {
12718
13456
  "data-slot": "chat-page",
12719
13457
  className: cn("flex w-full overflow-hidden", className),
12720
13458
  style: { height: "100vh", ...style },
12721
13459
  children: [
12722
- railVisible ? /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
13460
+ railVisible ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
12723
13461
  "div",
12724
13462
  {
12725
13463
  "data-slot": "chat-page-rail",
12726
13464
  className: "flex h-full w-[52px] shrink-0 flex-col items-center gap-1 border-r border-border py-2.5",
12727
13465
  children: [
12728
13466
  railItems.map(railButton),
12729
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { className: "flex-1" }),
13467
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "flex-1" }),
12730
13468
  railFooterItems.map(railButton)
12731
13469
  ]
12732
13470
  }
12733
13471
  ) : null,
12734
- /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
13472
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
12735
13473
  "div",
12736
13474
  {
12737
13475
  "data-slot": "chat-page-menu",
12738
- className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-auto border-r border-border px-2 py-3",
13476
+ className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-hidden border-r border-border px-2 py-3",
12739
13477
  children: [
12740
- brand ? /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("div", { className: "flex items-center justify-between px-2", children: [
12741
- /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
12742
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Text, { text: brand.title, strong: true, size: "large" }),
12743
- brand.version !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Text, { text: brand.version, type: "secondary", size: "small" }) : null
13478
+ brand ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { className: "flex shrink-0 items-center justify-between px-2", children: [
13479
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
13480
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: brand.title, strong: true, size: "large" }),
13481
+ brand.version !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: brand.version, type: "secondary", size: "small" }) : null
12744
13482
  ] }),
12745
- menuAction ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
13483
+ menuAction ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
12746
13484
  Button2,
12747
13485
  {
12748
13486
  text: menuAction.label,
@@ -12752,24 +13490,24 @@ function ChatPage({
12752
13490
  }
12753
13491
  ) : null
12754
13492
  ] }) : null,
12755
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
13493
+ /* @__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)(
12756
13494
  Menu2,
12757
13495
  {
12758
13496
  items: menuItems,
12759
13497
  selectedKey: activeMenuKey,
12760
13498
  onSelect: (key) => onMenuSelect?.(key)
12761
13499
  }
12762
- ),
12763
- conversationSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
13500
+ ) }),
13501
+ conversationSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
12764
13502
  "button",
12765
13503
  {
12766
13504
  type: "button",
12767
13505
  "data-slot": "chat-page-section-toggle",
12768
13506
  "aria-expanded": !convCollapsed,
12769
- className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
13507
+ className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
12770
13508
  onClick: toggleConvSection,
12771
13509
  children: [
12772
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
13510
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
12773
13511
  Text,
12774
13512
  {
12775
13513
  text: `${conversationSectionTitle} (${conversations.length})`,
@@ -12778,48 +13516,50 @@ function ChatPage({
12778
13516
  strong: true
12779
13517
  }
12780
13518
  ),
12781
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Icon, { name: convCollapsed ? "chevron-right" : "chevron-down", size: 14 })
13519
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Icon, { name: convCollapsed ? "chevron-right" : "chevron-down", size: 14 })
12782
13520
  ]
12783
13521
  }
12784
13522
  ) : null,
12785
- !convCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
12786
- ConversationList,
12787
- {
12788
- items: conversations,
12789
- activeId: activeConversationId,
12790
- onSelect: (id) => onSelectConversation?.(id),
12791
- onDelete: (id) => onDeleteConversation?.(id)
12792
- }
12793
- ) : null,
12794
- !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,
12795
- footerSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
13523
+ !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: [
13524
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
13525
+ ConversationList,
13526
+ {
13527
+ items: conversations,
13528
+ activeId: activeConversationId,
13529
+ onSelect: (id) => onSelectConversation?.(id),
13530
+ onDelete: (id) => onDeleteConversation?.(id)
13531
+ }
13532
+ ),
13533
+ 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
13534
+ ] }) : null,
13535
+ footerSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
12796
13536
  "button",
12797
13537
  {
12798
13538
  type: "button",
12799
13539
  "data-slot": "chat-page-section-toggle",
12800
13540
  "aria-expanded": !footerCollapsed,
12801
- className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
13541
+ className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
12802
13542
  onClick: toggleFooterSection,
12803
13543
  children: [
12804
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Text, { text: footerSectionTitle, type: "secondary", className: "text-sm", strong: true }),
12805
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Icon, { name: footerCollapsed ? "chevron-right" : "chevron-down", size: 14 })
13544
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: footerSectionTitle, type: "secondary", className: "text-sm", strong: true }),
13545
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Icon, { name: footerCollapsed ? "chevron-right" : "chevron-down", size: 14 })
12806
13546
  ]
12807
13547
  }
12808
13548
  ) : null,
12809
- !footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
13549
+ !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)(
12810
13550
  Menu2,
12811
13551
  {
12812
13552
  items: footerItems,
12813
13553
  onSelect: (key) => onMenuSelect?.(key)
12814
13554
  }
12815
- ) : null
13555
+ ) }) : null
12816
13556
  ]
12817
13557
  }
12818
13558
  ),
12819
- /* @__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: [
12820
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Panel, { defaultSize: "62%", children: chatArea }),
12821
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(ResizableHandle, { withHandle: true }),
12822
- /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Panel, { defaultSize: "38%", minSize: "320px", maxSize: "760px", children: artifactPanel })
13559
+ /* @__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: [
13560
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Panel, { defaultSize: "62%", children: chatArea }),
13561
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(ResizableHandle, { withHandle: true }),
13562
+ /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Panel, { defaultSize: "38%", minSize: "380px", maxSize: "760px", children: artifactPanel })
12823
13563
  ] }) : chatArea })
12824
13564
  ]
12825
13565
  }
@@ -12827,10 +13567,10 @@ function ChatPage({
12827
13567
  }
12828
13568
 
12829
13569
  // src/components/chat/Citation/index.tsx
12830
- var import_jsx_runtime185 = require("react/jsx-runtime");
13570
+ var import_jsx_runtime186 = require("react/jsx-runtime");
12831
13571
  function Citation({ items = [], start = 1, className, style }) {
12832
- 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: [
12833
- /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
13572
+ 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: [
13573
+ /* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(
12834
13574
  HoverCardTrigger,
12835
13575
  {
12836
13576
  "data-slot": "citation-marker",
@@ -12842,10 +13582,10 @@ function Citation({ items = [], start = 1, className, style }) {
12842
13582
  ]
12843
13583
  }
12844
13584
  ),
12845
- /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(HoverCardContent, { "data-slot": "citation-card", className: "w-72", children: [
12846
- /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "text-sm font-medium", children: item.title }),
12847
- item.snippet ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "mt-1 line-clamp-3 text-xs text-muted-foreground", children: item.snippet }) : null,
12848
- item.url ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
13585
+ /* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(HoverCardContent, { "data-slot": "citation-card", className: "w-72", children: [
13586
+ /* @__PURE__ */ (0, import_jsx_runtime186.jsx)("div", { className: "text-sm font-medium", children: item.title }),
13587
+ item.snippet ? /* @__PURE__ */ (0, import_jsx_runtime186.jsx)("div", { className: "mt-1 line-clamp-3 text-xs text-muted-foreground", children: item.snippet }) : null,
13588
+ item.url ? /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
12849
13589
  "a",
12850
13590
  {
12851
13591
  href: item.url,
@@ -12860,13 +13600,13 @@ function Citation({ items = [], start = 1, className, style }) {
12860
13600
  }
12861
13601
 
12862
13602
  // src/components/chat/Suggestion/index.tsx
12863
- var import_jsx_runtime186 = require("react/jsx-runtime");
13603
+ var import_jsx_runtime187 = require("react/jsx-runtime");
12864
13604
  function normalize(item) {
12865
13605
  if (typeof item === "string") return { label: item, value: item };
12866
13606
  return { label: item.label, value: item.value ?? item.label, icon: item.icon };
12867
13607
  }
12868
13608
  function Suggestion({ items = [], justify = "start", onSelect, className, style }) {
12869
- return /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
13609
+ return /* @__PURE__ */ (0, import_jsx_runtime187.jsx)(
12870
13610
  "div",
12871
13611
  {
12872
13612
  "data-slot": "suggestion",
@@ -12874,7 +13614,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
12874
13614
  style,
12875
13615
  children: items.map((item, index) => {
12876
13616
  const { label, value, icon } = normalize(item);
12877
- return /* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(
13617
+ return /* @__PURE__ */ (0, import_jsx_runtime187.jsxs)(
12878
13618
  "button",
12879
13619
  {
12880
13620
  type: "button",
@@ -12883,7 +13623,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
12883
13623
  className: "flex items-center gap-1.5 rounded-full border border-border px-3 py-1 text-sm transition-colors hover:bg-accent",
12884
13624
  onClick: () => onSelect?.(value),
12885
13625
  children: [
12886
- icon ? /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(Icon, { name: icon, size: "sm" }) : null,
13626
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime187.jsx)(Icon, { name: icon, size: "sm" }) : null,
12887
13627
  label
12888
13628
  ]
12889
13629
  },
@@ -12895,7 +13635,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
12895
13635
  }
12896
13636
 
12897
13637
  // src/components/chart/EChartBase/index.tsx
12898
- var import_react66 = require("react");
13638
+ var import_react68 = require("react");
12899
13639
 
12900
13640
  // src/components/chart/echarts-modules.ts
12901
13641
  var echarts = __toESM(require("echarts/core"), 1);
@@ -12926,7 +13666,7 @@ echarts.use([
12926
13666
  ]);
12927
13667
 
12928
13668
  // src/components/chart/EChartBase/index.tsx
12929
- var import_jsx_runtime187 = require("react/jsx-runtime");
13669
+ var import_jsx_runtime188 = require("react/jsx-runtime");
12930
13670
  function EChartBase({
12931
13671
  option,
12932
13672
  height = 256,
@@ -12935,12 +13675,12 @@ function EChartBase({
12935
13675
  style,
12936
13676
  slot
12937
13677
  }) {
12938
- const hostRef = (0, import_react66.useRef)(null);
12939
- const chartRef = (0, import_react66.useRef)(null);
12940
- const onSelectRef = (0, import_react66.useRef)(onSelect);
13678
+ const hostRef = (0, import_react68.useRef)(null);
13679
+ const chartRef = (0, import_react68.useRef)(null);
13680
+ const onSelectRef = (0, import_react68.useRef)(onSelect);
12941
13681
  onSelectRef.current = onSelect;
12942
- const [failed, setFailed] = (0, import_react66.useState)(false);
12943
- (0, import_react66.useEffect)(() => {
13682
+ const [failed, setFailed] = (0, import_react68.useState)(false);
13683
+ (0, import_react68.useEffect)(() => {
12944
13684
  const host = hostRef.current;
12945
13685
  if (!host) return;
12946
13686
  let chart = null;
@@ -12967,14 +13707,14 @@ function EChartBase({
12967
13707
  chartRef.current = null;
12968
13708
  };
12969
13709
  }, []);
12970
- (0, import_react66.useEffect)(() => {
13710
+ (0, import_react68.useEffect)(() => {
12971
13711
  try {
12972
13712
  chartRef.current?.setOption(option, { notMerge: true });
12973
13713
  } catch {
12974
13714
  }
12975
13715
  }, [option]);
12976
13716
  if (failed) {
12977
- return /* @__PURE__ */ (0, import_jsx_runtime187.jsx)(
13717
+ return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
12978
13718
  "div",
12979
13719
  {
12980
13720
  "data-slot": "chart-fallback",
@@ -12987,7 +13727,7 @@ function EChartBase({
12987
13727
  }
12988
13728
  );
12989
13729
  }
12990
- return /* @__PURE__ */ (0, import_jsx_runtime187.jsx)(
13730
+ return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
12991
13731
  "div",
12992
13732
  {
12993
13733
  ref: hostRef,
@@ -13521,7 +14261,7 @@ function getChartTheme() {
13521
14261
  }
13522
14262
 
13523
14263
  // src/components/chart/AreaChart/index.tsx
13524
- var import_jsx_runtime188 = require("react/jsx-runtime");
14264
+ var import_jsx_runtime189 = require("react/jsx-runtime");
13525
14265
  function AreaChart({
13526
14266
  data = [],
13527
14267
  xKey,
@@ -13539,7 +14279,7 @@ function AreaChart({
13539
14279
  { data, xKey, yKeys, stacked, fillOpacity, colors, title },
13540
14280
  getChartTheme()
13541
14281
  );
13542
- return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
14282
+ return /* @__PURE__ */ (0, import_jsx_runtime189.jsx)(
13543
14283
  EChartBase,
13544
14284
  {
13545
14285
  slot: "area-chart",
@@ -13553,7 +14293,7 @@ function AreaChart({
13553
14293
  }
13554
14294
 
13555
14295
  // src/components/chart/BarChart/index.tsx
13556
- var import_jsx_runtime189 = require("react/jsx-runtime");
14296
+ var import_jsx_runtime190 = require("react/jsx-runtime");
13557
14297
  function BarChart2({
13558
14298
  data = [],
13559
14299
  yKey,
@@ -13570,7 +14310,7 @@ function BarChart2({
13570
14310
  { data, yKey, yKeys: xKeys, stacked, colors, title },
13571
14311
  getChartTheme()
13572
14312
  );
13573
- return /* @__PURE__ */ (0, import_jsx_runtime189.jsx)(
14313
+ return /* @__PURE__ */ (0, import_jsx_runtime190.jsx)(
13574
14314
  EChartBase,
13575
14315
  {
13576
14316
  slot: "bar-chart",
@@ -13584,7 +14324,7 @@ function BarChart2({
13584
14324
  }
13585
14325
 
13586
14326
  // src/components/chart/BubbleChart/index.tsx
13587
- var import_jsx_runtime190 = require("react/jsx-runtime");
14327
+ var import_jsx_runtime191 = require("react/jsx-runtime");
13588
14328
  function BubbleChart({
13589
14329
  data = [],
13590
14330
  xKey,
@@ -13602,7 +14342,7 @@ function BubbleChart({
13602
14342
  { data, xKey, yKey, sizeKey, seriesKey, colors, title },
13603
14343
  getChartTheme()
13604
14344
  );
13605
- return /* @__PURE__ */ (0, import_jsx_runtime190.jsx)(
14345
+ return /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
13606
14346
  EChartBase,
13607
14347
  {
13608
14348
  slot: "bubble-chart",
@@ -13616,7 +14356,7 @@ function BubbleChart({
13616
14356
  }
13617
14357
 
13618
14358
  // src/components/chart/ColumnChart/index.tsx
13619
- var import_jsx_runtime191 = require("react/jsx-runtime");
14359
+ var import_jsx_runtime192 = require("react/jsx-runtime");
13620
14360
  function ColumnChart({
13621
14361
  data = [],
13622
14362
  xKey,
@@ -13633,7 +14373,7 @@ function ColumnChart({
13633
14373
  { data, xKey, yKeys, stacked, colors, title },
13634
14374
  getChartTheme()
13635
14375
  );
13636
- return /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
14376
+ return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(
13637
14377
  EChartBase,
13638
14378
  {
13639
14379
  slot: "column-chart",
@@ -13647,7 +14387,7 @@ function ColumnChart({
13647
14387
  }
13648
14388
 
13649
14389
  // src/components/chart/ComposedChart/index.tsx
13650
- var import_jsx_runtime192 = require("react/jsx-runtime");
14390
+ var import_jsx_runtime193 = require("react/jsx-runtime");
13651
14391
  function ComposedChart({
13652
14392
  data = [],
13653
14393
  xKey,
@@ -13663,7 +14403,7 @@ function ComposedChart({
13663
14403
  { data, xKey, series, colors, title },
13664
14404
  getChartTheme()
13665
14405
  );
13666
- return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(
14406
+ return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(
13667
14407
  EChartBase,
13668
14408
  {
13669
14409
  slot: "composed-chart",
@@ -13677,7 +14417,7 @@ function ComposedChart({
13677
14417
  }
13678
14418
 
13679
14419
  // src/components/chart/DonutChart/index.tsx
13680
- var import_jsx_runtime193 = require("react/jsx-runtime");
14420
+ var import_jsx_runtime194 = require("react/jsx-runtime");
13681
14421
  function DonutChart({
13682
14422
  data = [],
13683
14423
  nameKey,
@@ -13709,7 +14449,7 @@ function DonutChart({
13709
14449
  },
13710
14450
  getChartTheme()
13711
14451
  );
13712
- return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(
14452
+ return /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(
13713
14453
  EChartBase,
13714
14454
  {
13715
14455
  slot: "donut-chart",
@@ -13723,7 +14463,7 @@ function DonutChart({
13723
14463
  }
13724
14464
 
13725
14465
  // src/components/chart/FunnelChart/index.tsx
13726
- var import_jsx_runtime194 = require("react/jsx-runtime");
14466
+ var import_jsx_runtime195 = require("react/jsx-runtime");
13727
14467
  function FunnelChart2({
13728
14468
  data = [],
13729
14469
  nameKey,
@@ -13740,7 +14480,7 @@ function FunnelChart2({
13740
14480
  { data, nameKey, valueKey, sort, colors, title },
13741
14481
  getChartTheme()
13742
14482
  );
13743
- return /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(
14483
+ return /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(
13744
14484
  EChartBase,
13745
14485
  {
13746
14486
  slot: "funnel-chart",
@@ -13754,7 +14494,7 @@ function FunnelChart2({
13754
14494
  }
13755
14495
 
13756
14496
  // src/components/chart/GaugeChart/index.tsx
13757
- var import_jsx_runtime195 = require("react/jsx-runtime");
14497
+ var import_jsx_runtime196 = require("react/jsx-runtime");
13758
14498
  function GaugeChart2({
13759
14499
  value = 0,
13760
14500
  min,
@@ -13771,7 +14511,7 @@ function GaugeChart2({
13771
14511
  { value, min, max, thresholds, unit, title },
13772
14512
  getChartTheme()
13773
14513
  );
13774
- return /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(
14514
+ return /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
13775
14515
  EChartBase,
13776
14516
  {
13777
14517
  slot: "gauge-chart",
@@ -13785,7 +14525,7 @@ function GaugeChart2({
13785
14525
  }
13786
14526
 
13787
14527
  // src/components/chart/Heatmap/index.tsx
13788
- var import_jsx_runtime196 = require("react/jsx-runtime");
14528
+ var import_jsx_runtime197 = require("react/jsx-runtime");
13789
14529
  function Heatmap({
13790
14530
  data = [],
13791
14531
  xKey,
@@ -13801,7 +14541,7 @@ function Heatmap({
13801
14541
  { data, xKey, yKey, valueKey, title },
13802
14542
  getChartTheme()
13803
14543
  );
13804
- return /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
14544
+ return /* @__PURE__ */ (0, import_jsx_runtime197.jsx)(
13805
14545
  EChartBase,
13806
14546
  {
13807
14547
  slot: "heatmap",
@@ -13815,7 +14555,7 @@ function Heatmap({
13815
14555
  }
13816
14556
 
13817
14557
  // src/components/chart/LineChart/index.tsx
13818
- var import_jsx_runtime197 = require("react/jsx-runtime");
14558
+ var import_jsx_runtime198 = require("react/jsx-runtime");
13819
14559
  function LineChart2({
13820
14560
  data = [],
13821
14561
  xKey,
@@ -13834,7 +14574,7 @@ function LineChart2({
13834
14574
  { data, xKey, yKeys, smooth, showArea, stacked, colors, title },
13835
14575
  getChartTheme()
13836
14576
  );
13837
- return /* @__PURE__ */ (0, import_jsx_runtime197.jsx)(
14577
+ return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
13838
14578
  EChartBase,
13839
14579
  {
13840
14580
  slot: "line-chart",
@@ -13848,8 +14588,8 @@ function LineChart2({
13848
14588
  }
13849
14589
 
13850
14590
  // src/components/chart/MapChart/index.tsx
13851
- var import_react67 = require("react");
13852
- var import_jsx_runtime198 = require("react/jsx-runtime");
14591
+ var import_react69 = require("react");
14592
+ var import_jsx_runtime199 = require("react/jsx-runtime");
13853
14593
  var fetchedMaps = /* @__PURE__ */ new Set();
13854
14594
  function hasRegisteredMap(mapName) {
13855
14595
  try {
@@ -13871,7 +14611,7 @@ function MapChart2({
13871
14611
  className,
13872
14612
  style
13873
14613
  }) {
13874
- const [loadState, setLoadState] = (0, import_react67.useState)(
14614
+ const [loadState, setLoadState] = (0, import_react69.useState)(
13875
14615
  () => geoJson || !geoJsonUrl || hasRegisteredMap(mapName) ? "idle" : "loading"
13876
14616
  );
13877
14617
  if (geoJson) {
@@ -13880,7 +14620,7 @@ function MapChart2({
13880
14620
  } catch {
13881
14621
  }
13882
14622
  }
13883
- (0, import_react67.useEffect)(() => {
14623
+ (0, import_react69.useEffect)(() => {
13884
14624
  if (geoJson || !geoJsonUrl || hasRegisteredMap(mapName) || fetchedMaps.has(mapName)) {
13885
14625
  setLoadState("idle");
13886
14626
  return;
@@ -13905,7 +14645,7 @@ function MapChart2({
13905
14645
  };
13906
14646
  }, [geoJson, geoJsonUrl, mapName]);
13907
14647
  if (geoJsonUrl && !geoJson && loadState === "loading") {
13908
- return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
14648
+ return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
13909
14649
  "div",
13910
14650
  {
13911
14651
  "data-slot": "map-chart-loading",
@@ -13915,7 +14655,7 @@ function MapChart2({
13915
14655
  );
13916
14656
  }
13917
14657
  if (!geoJson && loadState === "error") {
13918
- return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
14658
+ return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
13919
14659
  Empty2,
13920
14660
  {
13921
14661
  title: "\u5730\u56FE\u52A0\u8F7D\u5931\u8D25",
@@ -13927,7 +14667,7 @@ function MapChart2({
13927
14667
  }
13928
14668
  if (!geoJson && !hasRegisteredMap(mapName)) {
13929
14669
  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`);
13930
- return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
14670
+ return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
13931
14671
  Empty2,
13932
14672
  {
13933
14673
  title: "\u5730\u56FE\u672A\u6CE8\u518C",
@@ -13938,7 +14678,7 @@ function MapChart2({
13938
14678
  );
13939
14679
  }
13940
14680
  const option = buildMapOption({ mapName, data, nameKey, valueKey, title }, getChartTheme());
13941
- return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
14681
+ return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
13942
14682
  EChartBase,
13943
14683
  {
13944
14684
  slot: "map-chart",
@@ -13953,7 +14693,7 @@ function MapChart2({
13953
14693
 
13954
14694
  // src/components/chart/MetricCard/index.tsx
13955
14695
  var import_lucide_react37 = require("lucide-react");
13956
- var import_jsx_runtime199 = require("react/jsx-runtime");
14696
+ var import_jsx_runtime200 = require("react/jsx-runtime");
13957
14697
  function MetricCard({
13958
14698
  title,
13959
14699
  value,
@@ -13966,15 +14706,15 @@ function MetricCard({
13966
14706
  }) {
13967
14707
  const showTrend = typeof trend === "number" && trend !== 0;
13968
14708
  const rising = (trend ?? 0) > 0;
13969
- return /* @__PURE__ */ (0, import_jsx_runtime199.jsxs)(
14709
+ return /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
13970
14710
  "div",
13971
14711
  {
13972
14712
  "data-slot": "metric-card",
13973
14713
  className: cn("rounded-lg border bg-card p-4 text-card-foreground shadow-sm", className),
13974
14714
  style,
13975
14715
  children: [
13976
- title ? /* @__PURE__ */ (0, import_jsx_runtime199.jsx)("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
13977
- /* @__PURE__ */ (0, import_jsx_runtime199.jsxs)(
14716
+ title ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
14717
+ /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
13978
14718
  "div",
13979
14719
  {
13980
14720
  "data-slot": "metric-card-value",
@@ -13986,7 +14726,7 @@ function MetricCard({
13986
14726
  ]
13987
14727
  }
13988
14728
  ),
13989
- showTrend ? /* @__PURE__ */ (0, import_jsx_runtime199.jsxs)(
14729
+ showTrend ? /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
13990
14730
  "div",
13991
14731
  {
13992
14732
  "data-slot": "metric-card-trend",
@@ -13996,10 +14736,10 @@ function MetricCard({
13996
14736
  rising ? "text-success" : "text-destructive"
13997
14737
  ),
13998
14738
  children: [
13999
- 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" }),
14739
+ 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" }),
14000
14740
  Math.abs(trend ?? 0),
14001
14741
  "%",
14002
- trendLabel ? /* @__PURE__ */ (0, import_jsx_runtime199.jsx)("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
14742
+ trendLabel ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
14003
14743
  ]
14004
14744
  }
14005
14745
  ) : null
@@ -14009,7 +14749,7 @@ function MetricCard({
14009
14749
  }
14010
14750
 
14011
14751
  // src/components/chart/PieChart/index.tsx
14012
- var import_jsx_runtime200 = require("react/jsx-runtime");
14752
+ var import_jsx_runtime201 = require("react/jsx-runtime");
14013
14753
  function PieChart2({
14014
14754
  data = [],
14015
14755
  nameKey,
@@ -14026,7 +14766,7 @@ function PieChart2({
14026
14766
  { data, nameKey, valueKey, showLabel, colors, title },
14027
14767
  getChartTheme()
14028
14768
  );
14029
- return /* @__PURE__ */ (0, import_jsx_runtime200.jsx)(
14769
+ return /* @__PURE__ */ (0, import_jsx_runtime201.jsx)(
14030
14770
  EChartBase,
14031
14771
  {
14032
14772
  slot: "pie-chart",
@@ -14040,7 +14780,7 @@ function PieChart2({
14040
14780
  }
14041
14781
 
14042
14782
  // src/components/chart/RadarChart/index.tsx
14043
- var import_jsx_runtime201 = require("react/jsx-runtime");
14783
+ var import_jsx_runtime202 = require("react/jsx-runtime");
14044
14784
  function RadarChart2({
14045
14785
  data = [],
14046
14786
  indicatorKey,
@@ -14056,7 +14796,7 @@ function RadarChart2({
14056
14796
  { data, indicatorKey, yKeys, colors, title },
14057
14797
  getChartTheme()
14058
14798
  );
14059
- return /* @__PURE__ */ (0, import_jsx_runtime201.jsx)(
14799
+ return /* @__PURE__ */ (0, import_jsx_runtime202.jsx)(
14060
14800
  EChartBase,
14061
14801
  {
14062
14802
  slot: "radar-chart",
@@ -14070,7 +14810,7 @@ function RadarChart2({
14070
14810
  }
14071
14811
 
14072
14812
  // src/components/chart/SankeyChart/index.tsx
14073
- var import_jsx_runtime202 = require("react/jsx-runtime");
14813
+ var import_jsx_runtime203 = require("react/jsx-runtime");
14074
14814
  function SankeyChart2({
14075
14815
  nodes = [],
14076
14816
  links = [],
@@ -14081,7 +14821,7 @@ function SankeyChart2({
14081
14821
  style
14082
14822
  }) {
14083
14823
  const option = buildSankeyOption({ nodes, links, title }, getChartTheme());
14084
- return /* @__PURE__ */ (0, import_jsx_runtime202.jsx)(
14824
+ return /* @__PURE__ */ (0, import_jsx_runtime203.jsx)(
14085
14825
  EChartBase,
14086
14826
  {
14087
14827
  slot: "sankey-chart",
@@ -14095,7 +14835,7 @@ function SankeyChart2({
14095
14835
  }
14096
14836
 
14097
14837
  // src/components/chart/ScatterChart/index.tsx
14098
- var import_jsx_runtime203 = require("react/jsx-runtime");
14838
+ var import_jsx_runtime204 = require("react/jsx-runtime");
14099
14839
  function ScatterChart2({
14100
14840
  data = [],
14101
14841
  xKey,
@@ -14112,7 +14852,7 @@ function ScatterChart2({
14112
14852
  { data, xKey, yKey, seriesKey, colors, title },
14113
14853
  getChartTheme()
14114
14854
  );
14115
- return /* @__PURE__ */ (0, import_jsx_runtime203.jsx)(
14855
+ return /* @__PURE__ */ (0, import_jsx_runtime204.jsx)(
14116
14856
  EChartBase,
14117
14857
  {
14118
14858
  slot: "scatter-chart",
@@ -14126,7 +14866,7 @@ function ScatterChart2({
14126
14866
  }
14127
14867
 
14128
14868
  // src/components/chart/TreeChart/index.tsx
14129
- var import_jsx_runtime204 = require("react/jsx-runtime");
14869
+ var import_jsx_runtime205 = require("react/jsx-runtime");
14130
14870
  function TreeChart2({
14131
14871
  data = [],
14132
14872
  title,
@@ -14142,7 +14882,7 @@ function TreeChart2({
14142
14882
  { data, title, orient, edgeShape, initialTreeDepth },
14143
14883
  getChartTheme()
14144
14884
  );
14145
- return /* @__PURE__ */ (0, import_jsx_runtime204.jsx)(
14885
+ return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
14146
14886
  EChartBase,
14147
14887
  {
14148
14888
  slot: "tree-chart",
@@ -14376,11 +15116,11 @@ function collectDefaultOpenKeys(registry, activeMenuId) {
14376
15116
  // src/layout/admin/AdminLayout.tsx
14377
15117
  var import_permission = require("@pactor-app/permission");
14378
15118
  var import_router = require("@pactor-app/router");
14379
- var import_runtime26 = require("@pactor-app/runtime");
14380
- var import_react69 = require("react");
15119
+ var import_runtime27 = require("@pactor-app/runtime");
15120
+ var import_react71 = require("react");
14381
15121
 
14382
15122
  // src/layout/admin/use-media-query.ts
14383
- var import_react68 = require("react");
15123
+ var import_react70 = require("react");
14384
15124
  var BREAKPOINT_PX = {
14385
15125
  xs: 480,
14386
15126
  sm: 576,
@@ -14390,10 +15130,10 @@ var BREAKPOINT_PX = {
14390
15130
  xxl: 1600
14391
15131
  };
14392
15132
  function useMediaQuery(query) {
14393
- const [matches, setMatches] = (0, import_react68.useState)(
15133
+ const [matches, setMatches] = (0, import_react70.useState)(
14394
15134
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false
14395
15135
  );
14396
- (0, import_react68.useEffect)(() => {
15136
+ (0, import_react70.useEffect)(() => {
14397
15137
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
14398
15138
  return;
14399
15139
  }
@@ -14413,7 +15153,7 @@ function useBreakpointBelow(breakpoint) {
14413
15153
  }
14414
15154
 
14415
15155
  // src/layout/admin/AdminLayout.tsx
14416
- var import_jsx_runtime205 = require("react/jsx-runtime");
15156
+ var import_jsx_runtime206 = require("react/jsx-runtime");
14417
15157
  function buildVisibleMenuTree(registry, permissionChecker) {
14418
15158
  const tree = registry.tree();
14419
15159
  return permissionChecker === void 0 ? [...tree] : (0, import_permission.filterMenusByPermission)(tree, permissionChecker);
@@ -14436,8 +15176,8 @@ function CollapsedGroupFlyout({
14436
15176
  activeMenuId,
14437
15177
  defaultOpenKeys
14438
15178
  }) {
14439
- const [open, setOpen] = (0, import_react69.useState)(false);
14440
- const closeTimer = (0, import_react69.useRef)(void 0);
15179
+ const [open, setOpen] = (0, import_react71.useState)(false);
15180
+ const closeTimer = (0, import_react71.useRef)(void 0);
14441
15181
  const openNow = () => {
14442
15182
  window.clearTimeout(closeTimer.current);
14443
15183
  setOpen(true);
@@ -14446,12 +15186,12 @@ function CollapsedGroupFlyout({
14446
15186
  window.clearTimeout(closeTimer.current);
14447
15187
  closeTimer.current = window.setTimeout(() => setOpen(false), 200);
14448
15188
  };
14449
- (0, import_react69.useEffect)(() => () => window.clearTimeout(closeTimer.current), []);
14450
- return /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(Popover, { open, onOpenChange: setOpen, children: [
14451
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15189
+ (0, import_react71.useEffect)(() => () => window.clearTimeout(closeTimer.current), []);
15190
+ return /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(Popover, { open, onOpenChange: setOpen, children: [
15191
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14452
15192
  PopoverTrigger,
14453
15193
  {
14454
- render: /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15194
+ render: /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14455
15195
  "button",
14456
15196
  {
14457
15197
  type: "button",
@@ -14469,7 +15209,7 @@ function CollapsedGroupFlyout({
14469
15209
  )
14470
15210
  }
14471
15211
  ),
14472
- /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15212
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14473
15213
  PopoverContent,
14474
15214
  {
14475
15215
  "data-slot": "menu-flyout",
@@ -14486,8 +15226,8 @@ function CollapsedGroupFlyout({
14486
15226
  }
14487
15227
  },
14488
15228
  children: [
14489
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("div", { className: "px-3 pt-2 pb-1 text-xs font-semibold text-muted-foreground", children: menu.title }),
14490
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15229
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("div", { className: "px-3 pt-2 pb-1 text-xs font-semibold text-muted-foreground", children: menu.title }),
15230
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14491
15231
  MenuTree,
14492
15232
  {
14493
15233
  menus: menu.children ?? [],
@@ -14511,9 +15251,9 @@ function MenuTree({
14511
15251
  collapsed = false
14512
15252
  }) {
14513
15253
  if (collapsed) {
14514
- return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("div", { "data-slot": "menu", "data-collapsed": "true", className: "flex flex-col gap-1", children: menus.map((menu) => {
15254
+ return /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("div", { "data-slot": "menu", "data-collapsed": "true", className: "flex flex-col gap-1", children: menus.map((menu) => {
14515
15255
  if (menu.type === "group") {
14516
- return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15256
+ return /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14517
15257
  CollapsedGroupFlyout,
14518
15258
  {
14519
15259
  menu,
@@ -14525,7 +15265,7 @@ function MenuTree({
14525
15265
  menu.id
14526
15266
  );
14527
15267
  }
14528
- return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15268
+ return /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14529
15269
  "button",
14530
15270
  {
14531
15271
  type: "button",
@@ -14545,7 +15285,7 @@ function MenuTree({
14545
15285
  );
14546
15286
  }) });
14547
15287
  }
14548
- return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15288
+ return /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14549
15289
  Accordion,
14550
15290
  {
14551
15291
  type: "multiple",
@@ -14554,27 +15294,27 @@ function MenuTree({
14554
15294
  className: "flex flex-col gap-0.5 px-2",
14555
15295
  children: menus.map((menu) => {
14556
15296
  if (menu.type === "group") {
14557
- return /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15297
+ return /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14558
15298
  AccordionItem,
14559
15299
  {
14560
15300
  value: menu.id,
14561
15301
  "data-slot": "menu-group",
14562
15302
  className: "border-b-0",
14563
15303
  children: [
14564
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15304
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14565
15305
  AccordionTrigger,
14566
15306
  {
14567
15307
  "data-slot": "menu-group-trigger",
14568
15308
  className: cn(menuItemClass2, "py-2 font-medium"),
14569
15309
  disabled: menu.disabled,
14570
15310
  title: menu.title,
14571
- children: /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
14572
- menu.icon ? /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(Icon, { name: menu.icon, size: "sm" }) : null,
15311
+ children: /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
15312
+ menu.icon ? /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(Icon, { name: menu.icon, size: "sm" }) : null,
14573
15313
  menu.title
14574
15314
  ] })
14575
15315
  }
14576
15316
  ),
14577
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(AccordionContent, { "data-slot": "menu-group-content", className: "pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("div", { className: "flex flex-col gap-0.5 pl-3", children: /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15317
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(AccordionContent, { "data-slot": "menu-group-content", className: "pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("div", { className: "flex flex-col gap-0.5 pl-3", children: /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14578
15318
  MenuTree,
14579
15319
  {
14580
15320
  menus: menu.children ?? [],
@@ -14589,7 +15329,7 @@ function MenuTree({
14589
15329
  menu.id
14590
15330
  );
14591
15331
  }
14592
- return /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15332
+ return /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14593
15333
  "button",
14594
15334
  {
14595
15335
  type: "button",
@@ -14603,7 +15343,7 @@ function MenuTree({
14603
15343
  title: menu.title,
14604
15344
  onClick: () => navigateMenuItem(registry.findById(menu.id), bridge),
14605
15345
  children: [
14606
- menu.icon ? /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(Icon, { name: menu.icon, size: "sm" }) : null,
15346
+ menu.icon ? /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(Icon, { name: menu.icon, size: "sm" }) : null,
14607
15347
  menu.title
14608
15348
  ]
14609
15349
  },
@@ -14623,23 +15363,23 @@ function AdminLayout({
14623
15363
  headerExtra,
14624
15364
  children
14625
15365
  }) {
14626
- const { t } = (0, import_runtime26.useI18n)();
15366
+ const { t } = (0, import_runtime27.useI18n)();
14627
15367
  const mode = config.mode ?? "top-side";
14628
15368
  const showHeader = config.header ?? true;
14629
15369
  const showSidebar = (config.sidebar ?? true) && mode !== "top-bottom";
14630
15370
  const showTabs = config.tabs ?? false;
14631
15371
  const showBreadcrumb = config.breadcrumb ?? false;
14632
15372
  const showFooter = config.footer ?? false;
14633
- const [collapsed, setCollapsed] = (0, import_react69.useState)(config.collapsed ?? false);
15373
+ const [collapsed, setCollapsed] = (0, import_react71.useState)(config.collapsed ?? false);
14634
15374
  const broken = useBreakpointBelow(config.breakpoint);
14635
15375
  const effectiveCollapsed = collapsed || broken;
14636
- const [bridgeRoute, setBridgeRoute] = (0, import_react69.useState)(
15376
+ const [bridgeRoute, setBridgeRoute] = (0, import_react71.useState)(
14637
15377
  () => (0, import_router.resolveRoute)(registry, bridge.getLocation())
14638
15378
  );
14639
- const [tabs, setTabs] = (0, import_react69.useState)([]);
14640
- const tabsRef = (0, import_react69.useRef)(tabs);
15379
+ const [tabs, setTabs] = (0, import_react71.useState)([]);
15380
+ const tabsRef = (0, import_react71.useRef)(tabs);
14641
15381
  tabsRef.current = tabs;
14642
- (0, import_react69.useEffect)(() => {
15382
+ (0, import_react71.useEffect)(() => {
14643
15383
  const handleLocation = (location) => {
14644
15384
  const next = (0, import_router.resolveRoute)(registry, location);
14645
15385
  setBridgeRoute(next);
@@ -14660,16 +15400,16 @@ function AdminLayout({
14660
15400
  }, [registry, bridge]);
14661
15401
  const route = routeProp ?? bridgeRoute;
14662
15402
  const activeMenuId = route?.activeMenu;
14663
- const visibleMenus = (0, import_react69.useMemo)(
15403
+ const visibleMenus = (0, import_react71.useMemo)(
14664
15404
  () => buildVisibleMenuTree(registry, permissionChecker),
14665
15405
  [registry, permissionChecker]
14666
15406
  );
14667
- const defaultOpenKeysRef = (0, import_react69.useRef)(null);
15407
+ const defaultOpenKeysRef = (0, import_react71.useRef)(null);
14668
15408
  if (defaultOpenKeysRef.current === null) {
14669
15409
  defaultOpenKeysRef.current = collectDefaultOpenKeys(registry, activeMenuId);
14670
15410
  }
14671
15411
  const defaultOpenKeys = defaultOpenKeysRef.current;
14672
- const activeTopId = (0, import_react69.useMemo)(() => {
15412
+ const activeTopId = (0, import_react71.useMemo)(() => {
14673
15413
  if (activeMenuId !== void 0) {
14674
15414
  const chain = findMenuChain(registry, activeMenuId);
14675
15415
  if (chain.length > 0) {
@@ -14678,11 +15418,11 @@ function AdminLayout({
14678
15418
  }
14679
15419
  return void 0;
14680
15420
  }, [registry, activeMenuId]);
14681
- const [selectedTopId, setSelectedTopId] = (0, import_react69.useState)();
15421
+ const [selectedTopId, setSelectedTopId] = (0, import_react71.useState)();
14682
15422
  const secondaryTopId = selectedTopId ?? activeTopId ?? visibleMenus.find((m) => m.type === "group")?.id ?? visibleMenus[0]?.id;
14683
15423
  const secondaryTop = visibleMenus.find((m) => m.id === secondaryTopId);
14684
15424
  const hasSecondary = (secondaryTop?.children?.length ?? 0) > 0;
14685
- const breadcrumbItems = (0, import_react69.useMemo)(() => {
15425
+ const breadcrumbItems = (0, import_react71.useMemo)(() => {
14686
15426
  if (!showBreadcrumb || activeMenuId === void 0) {
14687
15427
  return [];
14688
15428
  }
@@ -14698,7 +15438,7 @@ function AdminLayout({
14698
15438
  };
14699
15439
  const fixedHeader = config.fixedHeader ?? true;
14700
15440
  const fixedSider = config.fixedSider ?? true;
14701
- const header = showHeader ? /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15441
+ const header = showHeader ? /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14702
15442
  "header",
14703
15443
  {
14704
15444
  "data-slot": "admin-header",
@@ -14707,21 +15447,21 @@ function AdminLayout({
14707
15447
  fixedHeader && "sticky top-0 z-20"
14708
15448
  ),
14709
15449
  children: [
14710
- mode !== "side-full" && /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(import_jsx_runtime205.Fragment, { children: [
15450
+ mode !== "side-full" && /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(import_jsx_runtime206.Fragment, { children: [
14711
15451
  brand.logo,
14712
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("span", { "data-slot": "admin-brand", className: "text-lg font-semibold", children: brand.title })
15452
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("span", { "data-slot": "admin-brand", className: "text-lg font-semibold", children: brand.title })
14713
15453
  ] }),
14714
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("div", { className: "flex-1" }),
15454
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("div", { className: "flex-1" }),
14715
15455
  headerExtra
14716
15456
  ]
14717
15457
  }
14718
15458
  ) : null;
14719
- const primaryColumn = /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15459
+ const primaryColumn = /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14720
15460
  "div",
14721
15461
  {
14722
15462
  "data-slot": "admin-primary-col",
14723
15463
  className: "flex w-12 shrink-0 flex-col items-center gap-1 border-r border-border py-2",
14724
- children: visibleMenus.map((menu) => /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15464
+ children: visibleMenus.map((menu) => /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14725
15465
  "button",
14726
15466
  {
14727
15467
  type: "button",
@@ -14748,7 +15488,7 @@ function AdminLayout({
14748
15488
  }
14749
15489
  );
14750
15490
  const showTrigger = config.collapsible && mode !== "two-column";
14751
- const sidebar = showSidebar ? /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15491
+ const sidebar = showSidebar ? /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14752
15492
  "aside",
14753
15493
  {
14754
15494
  "data-slot": "admin-sidebar",
@@ -14760,20 +15500,20 @@ function AdminLayout({
14760
15500
  ),
14761
15501
  style: mode === "two-column" && !hasSecondary ? { width: 56 } : void 0,
14762
15502
  children: [
14763
- mode === "side-full" && /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15503
+ mode === "side-full" && /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14764
15504
  "div",
14765
15505
  {
14766
15506
  "data-slot": "admin-sidebar-brand",
14767
15507
  className: "flex items-center gap-2 border-b border-border px-4 py-4 font-semibold",
14768
15508
  children: [
14769
15509
  brand.logo,
14770
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("span", { children: brand.title })
15510
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("span", { children: brand.title })
14771
15511
  ]
14772
15512
  }
14773
15513
  ),
14774
- mode === "two-column" ? /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)("div", { "data-slot": "admin-two-col", className: "flex h-full", children: [
15514
+ mode === "two-column" ? /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)("div", { "data-slot": "admin-two-col", className: "flex h-full", children: [
14775
15515
  primaryColumn,
14776
- hasSecondary && /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("div", { "data-slot": "admin-secondary-col", className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15516
+ hasSecondary && /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("div", { "data-slot": "admin-secondary-col", className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14777
15517
  MenuTree,
14778
15518
  {
14779
15519
  menus: secondaryTop?.children ?? [],
@@ -14783,7 +15523,7 @@ function AdminLayout({
14783
15523
  defaultOpenKeys
14784
15524
  }
14785
15525
  ) })
14786
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15526
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14787
15527
  MenuTree,
14788
15528
  {
14789
15529
  menus: visibleMenus,
@@ -14794,7 +15534,7 @@ function AdminLayout({
14794
15534
  collapsed: effectiveCollapsed
14795
15535
  }
14796
15536
  ),
14797
- showTrigger && /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15537
+ showTrigger && /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14798
15538
  "button",
14799
15539
  {
14800
15540
  type: "button",
@@ -14809,14 +15549,14 @@ function AdminLayout({
14809
15549
  ]
14810
15550
  }
14811
15551
  ) : null;
14812
- const body = /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)("div", { "data-slot": "admin-body", className: "flex min-w-0 flex-1 flex-col", children: [
14813
- showTabs && /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15552
+ const body = /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)("div", { "data-slot": "admin-body", className: "flex min-w-0 flex-1 flex-col", children: [
15553
+ showTabs && /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14814
15554
  "div",
14815
15555
  {
14816
15556
  "data-slot": "admin-tabs",
14817
15557
  role: "tablist",
14818
15558
  className: "flex items-center gap-1 border-b border-border bg-card px-4 pt-2",
14819
- children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15559
+ children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14820
15560
  "div",
14821
15561
  {
14822
15562
  "data-slot": "admin-tab",
@@ -14827,7 +15567,7 @@ function AdminLayout({
14827
15567
  tab.key === currentPath ? "bg-card font-medium text-foreground" : "bg-muted text-muted-foreground"
14828
15568
  ),
14829
15569
  children: [
14830
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15570
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14831
15571
  "button",
14832
15572
  {
14833
15573
  type: "button",
@@ -14838,7 +15578,7 @@ function AdminLayout({
14838
15578
  children: tab.title
14839
15579
  }
14840
15580
  ),
14841
- index > 0 && /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15581
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14842
15582
  "button",
14843
15583
  {
14844
15584
  type: "button",
@@ -14855,21 +15595,21 @@ function AdminLayout({
14855
15595
  ))
14856
15596
  }
14857
15597
  ),
14858
- /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15598
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14859
15599
  "main",
14860
15600
  {
14861
15601
  "data-slot": "admin-content",
14862
15602
  className: "flex-1 bg-muted/40 p-6",
14863
15603
  children: [
14864
- showBreadcrumb && breadcrumbItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15604
+ showBreadcrumb && breadcrumbItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14865
15605
  "nav",
14866
15606
  {
14867
15607
  "data-slot": "admin-breadcrumb",
14868
15608
  "aria-label": t("pactor.layout.breadcrumb"),
14869
15609
  className: "mb-4",
14870
- children: /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("ol", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: breadcrumbItems.map((title, index) => /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)("li", { className: "flex items-center gap-2", children: [
14871
- index > 0 && /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("span", { "aria-hidden": true, children: "/" }),
14872
- /* @__PURE__ */ (0, import_jsx_runtime205.jsx)("span", { "data-slot": "breadcrumb-link", children: title })
15610
+ children: /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("ol", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: breadcrumbItems.map((title, index) => /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)("li", { className: "flex items-center gap-2", children: [
15611
+ index > 0 && /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("span", { "aria-hidden": true, children: "/" }),
15612
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsx)("span", { "data-slot": "breadcrumb-link", children: title })
14873
15613
  ] }, index)) })
14874
15614
  }
14875
15615
  ),
@@ -14878,7 +15618,7 @@ function AdminLayout({
14878
15618
  }
14879
15619
  )
14880
15620
  ] });
14881
- const footer = showFooter ? /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15621
+ const footer = showFooter ? /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14882
15622
  "footer",
14883
15623
  {
14884
15624
  "data-slot": "admin-footer",
@@ -14886,7 +15626,7 @@ function AdminLayout({
14886
15626
  children: brand.title
14887
15627
  }
14888
15628
  ) : null;
14889
- return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
15629
+ return /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
14890
15630
  "div",
14891
15631
  {
14892
15632
  "data-slot": "admin-layout",
@@ -14894,9 +15634,9 @@ function AdminLayout({
14894
15634
  "data-fixed-header": fixedHeader || void 0,
14895
15635
  "data-fixed-sider": fixedSider || void 0,
14896
15636
  className: "flex min-h-screen flex-col bg-background text-foreground",
14897
- children: mode === "side-full" ? /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)("div", { "data-slot": "admin-side-full", className: "flex min-h-screen flex-1", children: [
15637
+ children: mode === "side-full" ? /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)("div", { "data-slot": "admin-side-full", className: "flex min-h-screen flex-1", children: [
14898
15638
  sidebar,
14899
- /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(
15639
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(
14900
15640
  "div",
14901
15641
  {
14902
15642
  "data-slot": "admin-side-full-main",
@@ -14908,9 +15648,9 @@ function AdminLayout({
14908
15648
  ]
14909
15649
  }
14910
15650
  )
14911
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)(import_jsx_runtime205.Fragment, { children: [
15651
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)(import_jsx_runtime206.Fragment, { children: [
14912
15652
  header,
14913
- /* @__PURE__ */ (0, import_jsx_runtime205.jsxs)("div", { "data-slot": "admin-main", className: "flex min-h-0 flex-1", children: [
15653
+ /* @__PURE__ */ (0, import_jsx_runtime206.jsxs)("div", { "data-slot": "admin-main", className: "flex min-h-0 flex-1", children: [
14914
15654
  sidebar,
14915
15655
  body
14916
15656
  ] }),
@@ -14921,9 +15661,9 @@ function AdminLayout({
14921
15661
  }
14922
15662
 
14923
15663
  // src/layout/basic/BlankLayout.tsx
14924
- var import_jsx_runtime206 = require("react/jsx-runtime");
15664
+ var import_jsx_runtime207 = require("react/jsx-runtime");
14925
15665
  function BlankLayout({ children }) {
14926
- return /* @__PURE__ */ (0, import_jsx_runtime206.jsx)(
15666
+ return /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(
14927
15667
  "div",
14928
15668
  {
14929
15669
  "data-slot": "blank-layout",
@@ -14935,8 +15675,8 @@ function BlankLayout({ children }) {
14935
15675
 
14936
15676
  // src/layout/chat/ChatLayout.tsx
14937
15677
  var import_permission2 = require("@pactor-app/permission");
14938
- var import_react70 = require("react");
14939
- var import_jsx_runtime207 = require("react/jsx-runtime");
15678
+ var import_react72 = require("react");
15679
+ var import_jsx_runtime208 = require("react/jsx-runtime");
14940
15680
  function ChatLayout({
14941
15681
  brand,
14942
15682
  menu,
@@ -14951,7 +15691,7 @@ function ChatLayout({
14951
15691
  sidebarFooter,
14952
15692
  children
14953
15693
  }) {
14954
- const registryMenus = (0, import_react70.useMemo)(() => {
15694
+ const registryMenus = (0, import_react72.useMemo)(() => {
14955
15695
  if (menu !== void 0 || registry === void 0) {
14956
15696
  return [];
14957
15697
  }
@@ -14960,10 +15700,10 @@ function ChatLayout({
14960
15700
  return visible.flatMap((item) => menuItemToMenuData(item));
14961
15701
  }, [menu, registry, permissionChecker]);
14962
15702
  const menuItems = menu ?? registryMenus;
14963
- const [bridgePath, setBridgePath] = (0, import_react70.useState)(
15703
+ const [bridgePath, setBridgePath] = (0, import_react72.useState)(
14964
15704
  () => bridge?.getLocation().pathname ?? "/"
14965
15705
  );
14966
- (0, import_react70.useEffect)(() => {
15706
+ (0, import_react72.useEffect)(() => {
14967
15707
  if (bridge === void 0) {
14968
15708
  return;
14969
15709
  }
@@ -14971,7 +15711,7 @@ function ChatLayout({
14971
15711
  setBridgePath(location.pathname);
14972
15712
  });
14973
15713
  }, [bridge]);
14974
- const activeKey = (0, import_react70.useMemo)(() => {
15714
+ const activeKey = (0, import_react72.useMemo)(() => {
14975
15715
  if (activeMenuKey !== void 0) {
14976
15716
  return activeMenuKey;
14977
15717
  }
@@ -14991,7 +15731,7 @@ function ChatLayout({
14991
15731
  bridge.push(item.path);
14992
15732
  }
14993
15733
  };
14994
- const sidebarContent = sidebar !== void 0 && sidebar !== null ? sidebar : menuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(
15734
+ const sidebarContent = sidebar !== void 0 && sidebar !== null ? sidebar : menuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(
14995
15735
  Menu2,
14996
15736
  {
14997
15737
  items: menuItems.map((item) => chatMenuItemToUiMenuItem(item)),
@@ -14999,7 +15739,7 @@ function ChatLayout({
14999
15739
  onSelect: handleSelect
15000
15740
  }
15001
15741
  ) : void 0;
15002
- return /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(
15742
+ return /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(
15003
15743
  Sidebar,
15004
15744
  {
15005
15745
  brand,
@@ -15007,7 +15747,7 @@ function ChatLayout({
15007
15747
  sidebarFooter,
15008
15748
  collapsible,
15009
15749
  locationKey: routeProp?.path ?? bridgePath,
15010
- children: /* @__PURE__ */ (0, import_jsx_runtime207.jsx)(
15750
+ children: /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(
15011
15751
  "div",
15012
15752
  {
15013
15753
  "data-slot": "chat-layout-content",
@@ -15061,26 +15801,26 @@ function menuItemToMenuData(item) {
15061
15801
  }
15062
15802
 
15063
15803
  // src/layout/basic/LoginLayout.tsx
15064
- var import_jsx_runtime208 = require("react/jsx-runtime");
15804
+ var import_jsx_runtime209 = require("react/jsx-runtime");
15065
15805
  function LoginLayout({
15066
15806
  variant = "center",
15067
15807
  brand,
15068
15808
  children
15069
15809
  }) {
15070
- const brandBlock = /* @__PURE__ */ (0, import_jsx_runtime208.jsxs)("div", { "data-slot": "login-brand", className: "flex flex-col items-center gap-2", children: [
15810
+ const brandBlock = /* @__PURE__ */ (0, import_jsx_runtime209.jsxs)("div", { "data-slot": "login-brand", className: "flex flex-col items-center gap-2", children: [
15071
15811
  brand.logo,
15072
- /* @__PURE__ */ (0, import_jsx_runtime208.jsx)("h1", { className: "text-xl font-semibold", children: brand.title }),
15073
- brand.description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime208.jsx)("div", { className: "text-sm text-muted-foreground", children: brand.description })
15812
+ /* @__PURE__ */ (0, import_jsx_runtime209.jsx)("h1", { className: "text-xl font-semibold", children: brand.title }),
15813
+ brand.description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime209.jsx)("div", { className: "text-sm text-muted-foreground", children: brand.description })
15074
15814
  ] });
15075
15815
  if (variant === "split") {
15076
- return /* @__PURE__ */ (0, import_jsx_runtime208.jsxs)(
15816
+ return /* @__PURE__ */ (0, import_jsx_runtime209.jsxs)(
15077
15817
  "div",
15078
15818
  {
15079
15819
  "data-slot": "login-layout",
15080
15820
  "data-variant": "split",
15081
15821
  className: "grid min-h-screen grid-cols-2 bg-background text-foreground",
15082
15822
  children: [
15083
- /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(
15823
+ /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(
15084
15824
  "div",
15085
15825
  {
15086
15826
  "data-slot": "login-brand-panel",
@@ -15088,7 +15828,7 @@ function LoginLayout({
15088
15828
  children: brandBlock
15089
15829
  }
15090
15830
  ),
15091
- /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(
15831
+ /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(
15092
15832
  "div",
15093
15833
  {
15094
15834
  "data-slot": "login-form-panel",
@@ -15100,37 +15840,37 @@ function LoginLayout({
15100
15840
  }
15101
15841
  );
15102
15842
  }
15103
- return /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(
15843
+ return /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(
15104
15844
  "div",
15105
15845
  {
15106
15846
  "data-slot": "login-layout",
15107
15847
  "data-variant": "center",
15108
15848
  className: "flex min-h-screen items-center justify-center bg-muted/40 text-foreground",
15109
- children: /* @__PURE__ */ (0, import_jsx_runtime208.jsxs)(Card, { "data-slot": "login-card", className: "w-full max-w-sm gap-4 py-6", children: [
15110
- /* @__PURE__ */ (0, import_jsx_runtime208.jsxs)(CardHeader, { className: "px-6", children: [
15111
- /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(CardTitle, { className: "sr-only", children: brand.title }),
15849
+ children: /* @__PURE__ */ (0, import_jsx_runtime209.jsxs)(Card, { "data-slot": "login-card", className: "w-full max-w-sm gap-4 py-6", children: [
15850
+ /* @__PURE__ */ (0, import_jsx_runtime209.jsxs)(CardHeader, { className: "px-6", children: [
15851
+ /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(CardTitle, { className: "sr-only", children: brand.title }),
15112
15852
  brandBlock
15113
15853
  ] }),
15114
- /* @__PURE__ */ (0, import_jsx_runtime208.jsx)(CardContent, { className: "flex flex-col gap-4 px-6", children })
15854
+ /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(CardContent, { className: "flex flex-col gap-4 px-6", children })
15115
15855
  ] })
15116
15856
  }
15117
15857
  );
15118
15858
  }
15119
15859
 
15120
15860
  // src/layout/basic/LandingLayout.tsx
15121
- var import_jsx_runtime209 = require("react/jsx-runtime");
15861
+ var import_jsx_runtime210 = require("react/jsx-runtime");
15122
15862
  function LandingLayout({
15123
15863
  navbar,
15124
15864
  footer,
15125
15865
  children
15126
15866
  }) {
15127
- return /* @__PURE__ */ (0, import_jsx_runtime209.jsxs)(
15867
+ return /* @__PURE__ */ (0, import_jsx_runtime210.jsxs)(
15128
15868
  "div",
15129
15869
  {
15130
15870
  "data-slot": "landing-layout",
15131
15871
  className: "flex min-h-screen flex-col bg-background text-foreground",
15132
15872
  children: [
15133
- navbar !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(
15873
+ navbar !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
15134
15874
  "header",
15135
15875
  {
15136
15876
  "data-slot": "landing-navbar",
@@ -15138,8 +15878,8 @@ function LandingLayout({
15138
15878
  children: navbar
15139
15879
  }
15140
15880
  ),
15141
- /* @__PURE__ */ (0, import_jsx_runtime209.jsx)("main", { "data-slot": "landing-content", className: "flex-1", children }),
15142
- footer !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime209.jsx)(
15881
+ /* @__PURE__ */ (0, import_jsx_runtime210.jsx)("main", { "data-slot": "landing-content", className: "flex-1", children }),
15882
+ footer !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
15143
15883
  "footer",
15144
15884
  {
15145
15885
  "data-slot": "landing-footer",
@@ -15266,7 +16006,7 @@ var OverlayManager = class {
15266
16006
  };
15267
16007
 
15268
16008
  // src/interaction/actions.ts
15269
- var import_runtime27 = require("@pactor-app/runtime");
16009
+ var import_runtime28 = require("@pactor-app/runtime");
15270
16010
  function createUiBridge() {
15271
16011
  return {};
15272
16012
  }
@@ -15282,7 +16022,7 @@ function registerInteractionActions(actions, manager, ui) {
15282
16022
  return failure("[pactor-interaction] overlay.open \u7F3A\u5C11 overlay \u914D\u7F6E\u53C2\u6570");
15283
16023
  }
15284
16024
  const { content, ...rest } = overlay;
15285
- const resolved = (0, import_runtime27.resolveDeep)(rest, ctx.scope);
16025
+ const resolved = (0, import_runtime28.resolveDeep)(rest, ctx.scope);
15286
16026
  const config = { ...resolved, content };
15287
16027
  const data = await manager.open(config, {
15288
16028
  parentScope: { ...ctx.scope }
@@ -15345,10 +16085,10 @@ function isRecord(value) {
15345
16085
  }
15346
16086
 
15347
16087
  // src/interaction/provider.tsx
15348
- var import_runtime28 = require("@pactor-app/runtime");
15349
- var import_react71 = require("react");
16088
+ var import_runtime29 = require("@pactor-app/runtime");
16089
+ var import_react73 = require("react");
15350
16090
  var import_react_dom2 = require("react-dom");
15351
- var import_jsx_runtime210 = require("react/jsx-runtime");
16091
+ var import_jsx_runtime211 = require("react/jsx-runtime");
15352
16092
  var TOAST_DURATION = 3e3;
15353
16093
  var toastTypeClass = {
15354
16094
  success: "border-l-4 border-l-success",
@@ -15360,11 +16100,11 @@ function InteractionProvider({
15360
16100
  bridge,
15361
16101
  children
15362
16102
  }) {
15363
- const [confirmState, setConfirmState] = (0, import_react71.useState)(null);
15364
- const [confirmOpen, setConfirmOpen] = (0, import_react71.useState)(false);
15365
- const [toasts, setToasts] = (0, import_react71.useState)([]);
15366
- const { t } = (0, import_runtime28.useI18n)();
15367
- const { modal, message } = (0, import_react71.useMemo)(() => {
16103
+ const [confirmState, setConfirmState] = (0, import_react73.useState)(null);
16104
+ const [confirmOpen, setConfirmOpen] = (0, import_react73.useState)(false);
16105
+ const [toasts, setToasts] = (0, import_react73.useState)([]);
16106
+ const { t } = (0, import_runtime29.useI18n)();
16107
+ const { modal, message } = (0, import_react73.useMemo)(() => {
15368
16108
  const pushToast = (type, content) => {
15369
16109
  const id = Date.now() + Math.random();
15370
16110
  setToasts((prev) => [...prev, { id, type, content }]);
@@ -15386,7 +16126,7 @@ function InteractionProvider({
15386
16126
  };
15387
16127
  return { modal: modalImpl, message: messageImpl };
15388
16128
  }, []);
15389
- (0, import_react71.useEffect)(() => {
16129
+ (0, import_react73.useEffect)(() => {
15390
16130
  bridge.modal = modal;
15391
16131
  bridge.message = message;
15392
16132
  return () => {
@@ -15404,11 +16144,11 @@ function InteractionProvider({
15404
16144
  setConfirmOpen(false);
15405
16145
  state?.onCancel?.();
15406
16146
  };
15407
- return /* @__PURE__ */ (0, import_jsx_runtime210.jsxs)(import_jsx_runtime210.Fragment, { children: [
16147
+ return /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(import_jsx_runtime211.Fragment, { children: [
15408
16148
  children,
15409
16149
  typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
15410
- /* @__PURE__ */ (0, import_jsx_runtime210.jsxs)(import_jsx_runtime210.Fragment, { children: [
15411
- /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
16150
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(import_jsx_runtime211.Fragment, { children: [
16151
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
15412
16152
  Dialog,
15413
16153
  {
15414
16154
  open: confirmOpen,
@@ -15422,29 +16162,29 @@ function InteractionProvider({
15422
16162
  setConfirmState(null);
15423
16163
  }
15424
16164
  },
15425
- children: /* @__PURE__ */ (0, import_jsx_runtime210.jsxs)(DialogContent, { "data-slot": "confirm-dialog", className: "sm:max-w-sm", children: [
15426
- /* @__PURE__ */ (0, import_jsx_runtime210.jsxs)(DialogHeader, { children: [
15427
- /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(DialogTitle, { children: confirmState?.title ?? "" }),
15428
- confirmState?.content !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
16165
+ children: /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(DialogContent, { "data-slot": "confirm-dialog", className: "sm:max-w-sm", children: [
16166
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(DialogHeader, { children: [
16167
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(DialogTitle, { children: confirmState?.title ?? "" }),
16168
+ confirmState?.content !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
15429
16169
  DialogDescription,
15430
16170
  {
15431
- render: /* @__PURE__ */ (0, import_jsx_runtime210.jsx)("div", { children: confirmState.content })
16171
+ render: /* @__PURE__ */ (0, import_jsx_runtime211.jsx)("div", { children: confirmState.content })
15432
16172
  }
15433
16173
  )
15434
16174
  ] }),
15435
- /* @__PURE__ */ (0, import_jsx_runtime210.jsxs)(DialogFooter, { children: [
15436
- /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(Button, { type: "button", variant: "outline", onClick: handleCancel, children: t("pactor.alertDialog.cancel") }),
15437
- /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(Button, { type: "button", onClick: handleOk, children: t("pactor.alertDialog.confirm") })
16175
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(DialogFooter, { children: [
16176
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(Button, { type: "button", variant: "outline", onClick: handleCancel, children: t("pactor.alertDialog.cancel") }),
16177
+ /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(Button, { type: "button", onClick: handleOk, children: t("pactor.alertDialog.confirm") })
15438
16178
  ] })
15439
16179
  ] })
15440
16180
  }
15441
16181
  ),
15442
- toasts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
16182
+ toasts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
15443
16183
  "div",
15444
16184
  {
15445
16185
  "data-slot": "toast-container",
15446
16186
  className: "fixed top-4 right-4 z-[100] flex w-80 flex-col gap-2",
15447
- children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime210.jsx)(
16187
+ children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
15448
16188
  "div",
15449
16189
  {
15450
16190
  "data-slot": "toast",
@@ -15468,9 +16208,9 @@ function InteractionProvider({
15468
16208
 
15469
16209
  // src/interaction/host.tsx
15470
16210
  var import_lucide_react38 = require("lucide-react");
15471
- var import_runtime29 = require("@pactor-app/runtime");
15472
- var import_react72 = require("react");
15473
- var import_jsx_runtime211 = require("react/jsx-runtime");
16211
+ var import_runtime30 = require("@pactor-app/runtime");
16212
+ var import_react74 = require("react");
16213
+ var import_jsx_runtime212 = require("react/jsx-runtime");
15474
16214
  function toCssWidth(width) {
15475
16215
  if (width === void 0) {
15476
16216
  return void 0;
@@ -15478,12 +16218,12 @@ function toCssWidth(width) {
15478
16218
  return typeof width === "number" ? `${width}px` : width;
15479
16219
  }
15480
16220
  function OverlayHost({ manager, resolvePage }) {
15481
- const renderer = (0, import_runtime29.useRenderer)();
15482
- const stack = (0, import_react72.useSyncExternalStore)(
16221
+ const renderer = (0, import_runtime30.useRenderer)();
16222
+ const stack = (0, import_react74.useSyncExternalStore)(
15483
16223
  (onChange) => manager.subscribe(onChange),
15484
16224
  () => manager.stack()
15485
16225
  );
15486
- (0, import_react72.useSyncExternalStore)(
16226
+ (0, import_react74.useSyncExternalStore)(
15487
16227
  (onChange) => {
15488
16228
  const offState = renderer.context.state.subscribe(onChange);
15489
16229
  const offData = renderer.context.data.subscribe(onChange);
@@ -15494,7 +16234,7 @@ function OverlayHost({ manager, resolvePage }) {
15494
16234
  },
15495
16235
  () => `${renderer.context.state.getVersion()}:${renderer.context.data.getVersion()}`
15496
16236
  );
15497
- return /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(import_jsx_runtime211.Fragment, { children: stack.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
16237
+ return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(import_jsx_runtime212.Fragment, { children: stack.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
15498
16238
  OverlayEntryView,
15499
16239
  {
15500
16240
  entry,
@@ -15511,7 +16251,7 @@ function OverlayEntryView({
15511
16251
  renderer,
15512
16252
  resolvePage
15513
16253
  }) {
15514
- const { t } = (0, import_runtime29.useI18n)();
16254
+ const { t } = (0, import_runtime30.useI18n)();
15515
16255
  const handleCancel = () => manager.close(entry.id);
15516
16256
  let body = null;
15517
16257
  if (entry.content) {
@@ -15520,7 +16260,7 @@ function OverlayEntryView({
15520
16260
  parent: manager.parentScopeOf(entry.id)
15521
16261
  });
15522
16262
  } else if (entry.page) {
15523
- body = /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
16263
+ body = /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
15524
16264
  PageOverlayBody,
15525
16265
  {
15526
16266
  entry,
@@ -15530,9 +16270,9 @@ function OverlayEntryView({
15530
16270
  );
15531
16271
  }
15532
16272
  if (entry.type === "drawer") {
15533
- return /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(ShadcnDrawerView, { entry, onCancel: handleCancel, children: body });
16273
+ return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(ShadcnDrawerView, { entry, onCancel: handleCancel, children: body });
15534
16274
  }
15535
- return /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
16275
+ return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
15536
16276
  Dialog,
15537
16277
  {
15538
16278
  open: true,
@@ -15541,7 +16281,7 @@ function OverlayEntryView({
15541
16281
  handleCancel();
15542
16282
  }
15543
16283
  },
15544
- children: /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(
16284
+ children: /* @__PURE__ */ (0, import_jsx_runtime212.jsxs)(
15545
16285
  DialogContent,
15546
16286
  {
15547
16287
  "data-slot": "overlay-modal",
@@ -15549,25 +16289,25 @@ function OverlayEntryView({
15549
16289
  style: entry.width === void 0 ? void 0 : { width: toCssWidth(entry.width) },
15550
16290
  showCloseButton: false,
15551
16291
  children: [
15552
- /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(DialogHeader, { children: [
15553
- /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(DialogTitle, { children: entry.title ?? "" }),
15554
- /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
16292
+ /* @__PURE__ */ (0, import_jsx_runtime212.jsxs)(DialogHeader, { children: [
16293
+ /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(DialogTitle, { children: entry.title ?? "" }),
16294
+ /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
15555
16295
  DialogClose,
15556
16296
  {
15557
- render: /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
16297
+ render: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
15558
16298
  "button",
15559
16299
  {
15560
16300
  type: "button",
15561
16301
  "data-slot": "overlay-modal-close",
15562
16302
  "aria-label": t("pactor.overlay.close"),
15563
16303
  className: "absolute top-4 right-4 cursor-pointer rounded-xs opacity-70 transition-opacity hover:opacity-100 focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none",
15564
- children: /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(import_lucide_react38.XIcon, { className: "size-4" })
16304
+ children: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(import_lucide_react38.XIcon, { className: "size-4" })
15565
16305
  }
15566
16306
  )
15567
16307
  }
15568
16308
  )
15569
16309
  ] }),
15570
- /* @__PURE__ */ (0, import_jsx_runtime211.jsx)("div", { "data-slot": "overlay-modal-body", children: body })
16310
+ /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { "data-slot": "overlay-modal-body", children: body })
15571
16311
  ]
15572
16312
  }
15573
16313
  )
@@ -15579,9 +16319,9 @@ function ShadcnDrawerView({
15579
16319
  onCancel,
15580
16320
  children
15581
16321
  }) {
15582
- const { t } = (0, import_runtime29.useI18n)();
16322
+ const { t } = (0, import_runtime30.useI18n)();
15583
16323
  const panelStyle = entry.width === void 0 ? void 0 : { width: toCssWidth(entry.width) };
15584
- return /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
16324
+ return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
15585
16325
  Drawer,
15586
16326
  {
15587
16327
  direction: "right",
@@ -15591,34 +16331,34 @@ function ShadcnDrawerView({
15591
16331
  onCancel();
15592
16332
  }
15593
16333
  },
15594
- children: /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(
16334
+ children: /* @__PURE__ */ (0, import_jsx_runtime212.jsxs)(
15595
16335
  DrawerContent,
15596
16336
  {
15597
16337
  "data-slot": "drawer-panel",
15598
16338
  className: cn(entry.width !== void 0 && "sm:max-w-none"),
15599
16339
  style: panelStyle,
15600
16340
  children: [
15601
- /* @__PURE__ */ (0, import_jsx_runtime211.jsxs)(
16341
+ /* @__PURE__ */ (0, import_jsx_runtime212.jsxs)(
15602
16342
  DrawerHeader,
15603
16343
  {
15604
16344
  "data-slot": "drawer-header",
15605
16345
  className: "flex flex-row items-center justify-between border-b border-border px-6 py-4",
15606
16346
  children: [
15607
- /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(DrawerTitle, { className: "text-lg", children: entry.title ?? "" }),
15608
- /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(DrawerClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(
16347
+ /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(DrawerTitle, { className: "text-lg", children: entry.title ?? "" }),
16348
+ /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(DrawerClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(
15609
16349
  "button",
15610
16350
  {
15611
16351
  type: "button",
15612
16352
  "data-slot": "drawer-close",
15613
16353
  "aria-label": t("pactor.overlay.close"),
15614
16354
  className: "cursor-pointer rounded-xs opacity-70 transition-opacity hover:opacity-100 focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none",
15615
- children: /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(import_lucide_react38.XIcon, { className: "size-4" })
16355
+ children: /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(import_lucide_react38.XIcon, { className: "size-4" })
15616
16356
  }
15617
16357
  ) })
15618
16358
  ]
15619
16359
  }
15620
16360
  ),
15621
- /* @__PURE__ */ (0, import_jsx_runtime211.jsx)("div", { "data-slot": "drawer-body", className: "flex-1 overflow-auto p-6", children })
16361
+ /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { "data-slot": "drawer-body", className: "flex-1 overflow-auto p-6", children })
15622
16362
  ]
15623
16363
  }
15624
16364
  )
@@ -15630,9 +16370,9 @@ function PageOverlayBody({
15630
16370
  renderer,
15631
16371
  resolvePage
15632
16372
  }) {
15633
- const [child, setChild] = (0, import_react72.useState)(null);
15634
- const [error, setError] = (0, import_react72.useState)(null);
15635
- (0, import_react72.useEffect)(() => {
16373
+ const [child, setChild] = (0, import_react74.useState)(null);
16374
+ const [error, setError] = (0, import_react74.useState)(null);
16375
+ (0, import_react74.useEffect)(() => {
15636
16376
  if (!resolvePage) {
15637
16377
  setError(
15638
16378
  new Error(
@@ -15650,7 +16390,7 @@ function PageOverlayBody({
15650
16390
  return;
15651
16391
  }
15652
16392
  const host = renderer.context;
15653
- created = (0, import_runtime29.createPageRuntime)(pageDsl, {
16393
+ created = (0, import_runtime30.createPageRuntime)(pageDsl, {
15654
16394
  app: host.app,
15655
16395
  user: host.user,
15656
16396
  components: host.components,
@@ -15674,12 +16414,12 @@ function PageOverlayBody({
15674
16414
  };
15675
16415
  }, [entry.id]);
15676
16416
  if (error) {
15677
- return /* @__PURE__ */ (0, import_jsx_runtime211.jsx)("div", { role: "alert", children: error.message });
16417
+ return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)("div", { role: "alert", children: error.message });
15678
16418
  }
15679
16419
  if (!child) {
15680
16420
  return null;
15681
16421
  }
15682
- return /* @__PURE__ */ (0, import_jsx_runtime211.jsx)(import_runtime29.PageRuntimeView, { runtime: child });
16422
+ return /* @__PURE__ */ (0, import_jsx_runtime212.jsx)(import_runtime30.PageRuntimeView, { runtime: child });
15683
16423
  }
15684
16424
  // Annotate the CommonJS export names for ESM import in node:
15685
16425
  0 && (module.exports = {