@pactor-app/ui 1.21.0 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7WB4TS55.js → chunk-44DAGWXZ.js} +2 -0
- package/dist/{chunk-2A5MHANX.js → chunk-QQBAMERO.js} +1 -1
- package/dist/{chunk-XXOY57SN.js → chunk-VTCNWVKQ.js} +1074 -263
- package/dist/components/index.cjs +1063 -261
- package/dist/components/index.d.cts +181 -55
- package/dist/components/index.d.ts +181 -55
- package/dist/components/index.js +2 -2
- package/dist/index.cjs +1213 -411
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/layout/index.cjs +1 -0
- package/dist/layout/index.js +2 -2
- package/package.json +6 -6
- package/styles.css +66 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
Icon,
|
|
3
3
|
Menu,
|
|
4
4
|
Sidebar
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-44DAGWXZ.js";
|
|
6
6
|
import {
|
|
7
7
|
Alert,
|
|
8
8
|
AlertDescription,
|
|
@@ -1611,6 +1611,7 @@ function Command2({
|
|
|
1611
1611
|
import { useRenderer as useRenderer5 } from "@pactor-app/runtime";
|
|
1612
1612
|
import { ArrowUp } from "lucide-react";
|
|
1613
1613
|
import {
|
|
1614
|
+
isValidElement,
|
|
1614
1615
|
useRef as useRef3,
|
|
1615
1616
|
useState as useState10
|
|
1616
1617
|
} from "react";
|
|
@@ -1625,6 +1626,7 @@ function ChatInput({
|
|
|
1625
1626
|
toolbarEnd,
|
|
1626
1627
|
header,
|
|
1627
1628
|
footer,
|
|
1629
|
+
field,
|
|
1628
1630
|
onChange,
|
|
1629
1631
|
onSubmit,
|
|
1630
1632
|
className,
|
|
@@ -1635,6 +1637,8 @@ function ChatInput({
|
|
|
1635
1637
|
const [draft, setDraft] = useState10("");
|
|
1636
1638
|
const text = controlled ? value : draft;
|
|
1637
1639
|
const canSubmit = !disabled && text.trim() !== "";
|
|
1640
|
+
const customField = field !== void 0 && field !== null;
|
|
1641
|
+
const renderSlot = (slot) => isValidElement(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
1638
1642
|
const composingRef = useRef3(false);
|
|
1639
1643
|
const handleChange = (next) => {
|
|
1640
1644
|
if (!controlled) {
|
|
@@ -1670,8 +1674,8 @@ function ChatInput({
|
|
|
1670
1674
|
),
|
|
1671
1675
|
style,
|
|
1672
1676
|
children: [
|
|
1673
|
-
header ? /* @__PURE__ */ jsx26("div", { className: "px-3 pt-3", children:
|
|
1674
|
-
/* @__PURE__ */ jsx26(
|
|
1677
|
+
header ? /* @__PURE__ */ jsx26("div", { className: "px-3 pt-3", children: renderSlot(header) }) : null,
|
|
1678
|
+
customField ? field : /* @__PURE__ */ jsx26(
|
|
1675
1679
|
Textarea,
|
|
1676
1680
|
{
|
|
1677
1681
|
value: text,
|
|
@@ -1686,9 +1690,9 @@ function ChatInput({
|
|
|
1686
1690
|
}
|
|
1687
1691
|
),
|
|
1688
1692
|
toolbarStart || toolbarEnd || !hideSend ? /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1 px-2 pb-2", children: [
|
|
1689
|
-
toolbarStart ?
|
|
1693
|
+
toolbarStart ? renderSlot(toolbarStart) : null,
|
|
1690
1694
|
/* @__PURE__ */ jsx26("span", { className: "flex-1" }),
|
|
1691
|
-
toolbarEnd ?
|
|
1695
|
+
toolbarEnd ? renderSlot(toolbarEnd) : null,
|
|
1692
1696
|
hideSend ? null : /* @__PURE__ */ jsx26(
|
|
1693
1697
|
Button,
|
|
1694
1698
|
{
|
|
@@ -1702,7 +1706,7 @@ function ChatInput({
|
|
|
1702
1706
|
}
|
|
1703
1707
|
)
|
|
1704
1708
|
] }) : null,
|
|
1705
|
-
footer ? /* @__PURE__ */ jsx26("div", { className: "border-t border-border px-3 py-2", children:
|
|
1709
|
+
footer ? /* @__PURE__ */ jsx26("div", { className: "border-t border-border px-3 py-2", children: renderSlot(footer) }) : null
|
|
1706
1710
|
]
|
|
1707
1711
|
}
|
|
1708
1712
|
);
|
|
@@ -2138,7 +2142,8 @@ function DatePicker(props) {
|
|
|
2138
2142
|
onSelect: handleRangeDaySelect,
|
|
2139
2143
|
modifiers: rangeModifiers,
|
|
2140
2144
|
modifiersClassNames: rangeModifierClassNames,
|
|
2141
|
-
locale: dfLocale
|
|
2145
|
+
locale: dfLocale,
|
|
2146
|
+
showOutsideDays: false
|
|
2142
2147
|
}
|
|
2143
2148
|
)
|
|
2144
2149
|
}
|
|
@@ -2152,7 +2157,8 @@ function DatePicker(props) {
|
|
|
2152
2157
|
onSelect: handleRangeDaySelect,
|
|
2153
2158
|
modifiers: rangeModifiers,
|
|
2154
2159
|
modifiersClassNames: rangeModifierClassNames,
|
|
2155
|
-
locale: dfLocale
|
|
2160
|
+
locale: dfLocale,
|
|
2161
|
+
showOutsideDays: false
|
|
2156
2162
|
}
|
|
2157
2163
|
) })
|
|
2158
2164
|
] }) : /* @__PURE__ */ jsx31(
|
|
@@ -7557,7 +7563,14 @@ function ArtifactTreeRow({
|
|
|
7557
7563
|
className: "flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-accent",
|
|
7558
7564
|
onClick: () => setOpen((value) => !value),
|
|
7559
7565
|
children: [
|
|
7560
|
-
/* @__PURE__ */ jsx113(
|
|
7566
|
+
/* @__PURE__ */ jsx113(
|
|
7567
|
+
"span",
|
|
7568
|
+
{
|
|
7569
|
+
className: "inline-flex transition-transform data-[open=true]:rotate-90",
|
|
7570
|
+
"data-open": open,
|
|
7571
|
+
children: /* @__PURE__ */ jsx113(Icon, { name: "chevron-right", size: 12 })
|
|
7572
|
+
}
|
|
7573
|
+
),
|
|
7561
7574
|
/* @__PURE__ */ jsx113(Icon, { name: "folder", size: 13 }),
|
|
7562
7575
|
/* @__PURE__ */ jsx113("span", { className: "min-w-0 flex-1 truncate", children: node.name })
|
|
7563
7576
|
]
|
|
@@ -7689,6 +7702,7 @@ function ArtifactPanel({
|
|
|
7689
7702
|
icon: "download",
|
|
7690
7703
|
variant: "text",
|
|
7691
7704
|
tooltip: "\u4E0B\u8F7D\u4EA7\u7269",
|
|
7705
|
+
className: "px-2",
|
|
7692
7706
|
onClick: () => onDownload ? onDownload(artifact) : void downloadArtifact(artifact)
|
|
7693
7707
|
}
|
|
7694
7708
|
) : null,
|
|
@@ -7698,11 +7712,12 @@ function ArtifactPanel({
|
|
|
7698
7712
|
icon: "x",
|
|
7699
7713
|
variant: "text",
|
|
7700
7714
|
tooltip: "\u6536\u8D77\u4EA7\u7269\u533A",
|
|
7715
|
+
className: "px-2",
|
|
7701
7716
|
onClick: () => onClose?.()
|
|
7702
7717
|
}
|
|
7703
7718
|
)
|
|
7704
7719
|
] }),
|
|
7705
|
-
/* @__PURE__ */ jsx113("div", { className: "min-h-0 flex-1 overflow-auto p-4", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ jsx113(
|
|
7720
|
+
/* @__PURE__ */ jsx113("div", { className: "scrollbar-subtle min-h-0 flex-1 overflow-auto p-4", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ jsx113(
|
|
7706
7721
|
ArtifactListView,
|
|
7707
7722
|
{
|
|
7708
7723
|
nodes: buildArtifactTree(artifacts),
|
|
@@ -7873,7 +7888,7 @@ function Thinking({
|
|
|
7873
7888
|
{
|
|
7874
7889
|
"data-slot": "thinking",
|
|
7875
7890
|
"data-status": status,
|
|
7876
|
-
className: cn("w-full
|
|
7891
|
+
className: cn("w-full", className),
|
|
7877
7892
|
style,
|
|
7878
7893
|
children: [
|
|
7879
7894
|
/* @__PURE__ */ jsxs82(
|
|
@@ -7882,12 +7897,12 @@ function Thinking({
|
|
|
7882
7897
|
type: "button",
|
|
7883
7898
|
"data-slot": "thinking-trigger",
|
|
7884
7899
|
"aria-expanded": isExpanded,
|
|
7885
|
-
className: "flex w-full items-center gap-2
|
|
7900
|
+
className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
|
|
7886
7901
|
onClick: toggle,
|
|
7887
7902
|
children: [
|
|
7888
7903
|
/* @__PURE__ */ jsx118("span", { className: cn("text-muted-foreground", status === "thinking" && "animate-pulse motion-reduce:animate-none"), children: /* @__PURE__ */ jsx118(Icon, { name: "brain", size: "sm" }) }),
|
|
7889
|
-
/* @__PURE__ */ jsx118("span", { "data-slot": "thinking-title", className: "
|
|
7890
|
-
/* @__PURE__ */ jsx118(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" })
|
|
7904
|
+
/* @__PURE__ */ jsx118("span", { "data-slot": "thinking-title", className: "text-muted-foreground", children: resolvedTitle }),
|
|
7905
|
+
/* @__PURE__ */ jsx118("span", { className: "text-muted-foreground", children: /* @__PURE__ */ jsx118(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" }) })
|
|
7891
7906
|
]
|
|
7892
7907
|
}
|
|
7893
7908
|
),
|
|
@@ -7895,7 +7910,7 @@ function Thinking({
|
|
|
7895
7910
|
"div",
|
|
7896
7911
|
{
|
|
7897
7912
|
"data-slot": "thinking-content",
|
|
7898
|
-
className: "
|
|
7913
|
+
className: "py-1 pl-6 text-sm whitespace-pre-wrap text-muted-foreground",
|
|
7899
7914
|
children: content
|
|
7900
7915
|
}
|
|
7901
7916
|
) : null
|
|
@@ -7906,7 +7921,7 @@ function Thinking({
|
|
|
7906
7921
|
|
|
7907
7922
|
// src/components/chat/ToolCall/index.tsx
|
|
7908
7923
|
import { useState as useState40 } from "react";
|
|
7909
|
-
import { jsx as jsx119, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
7924
|
+
import { Fragment as Fragment11, jsx as jsx119, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
7910
7925
|
var statusIcon3 = {
|
|
7911
7926
|
running: { icon: "loader-circle", className: "text-info", spin: true },
|
|
7912
7927
|
done: { icon: "circle-check", className: "text-success" },
|
|
@@ -7925,42 +7940,51 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
|
|
|
7925
7940
|
const [expanded, setExpanded] = useState40(defaultExpanded ?? status === "running");
|
|
7926
7941
|
const meta = statusIcon3[status];
|
|
7927
7942
|
const paramsText = renderValue(params);
|
|
7943
|
+
const hasDetail = Boolean(paramsText) || Boolean(result);
|
|
7944
|
+
const headerInner = /* @__PURE__ */ jsxs83(Fragment11, { children: [
|
|
7945
|
+
/* @__PURE__ */ jsx119("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ jsx119(Icon, { name: "terminal", size: "sm" }) }),
|
|
7946
|
+
/* @__PURE__ */ jsx119("span", { "data-slot": "tool-call-name", className: "min-w-0 truncate font-medium", children: name ?? "\u5DE5\u5177\u8C03\u7528" }),
|
|
7947
|
+
/* @__PURE__ */ jsx119("span", { className: cn("shrink-0", meta.className, meta.spin && "animate-spin motion-reduce:animate-none"), children: /* @__PURE__ */ jsx119(Icon, { name: meta.icon, size: "sm" }) }),
|
|
7948
|
+
durationMs !== void 0 ? /* @__PURE__ */ jsxs83("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
7949
|
+
(durationMs / 1e3).toFixed(1),
|
|
7950
|
+
"s"
|
|
7951
|
+
] }) : null,
|
|
7952
|
+
hasDetail ? /* @__PURE__ */ jsx119("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ jsx119(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" }) }) : null
|
|
7953
|
+
] });
|
|
7928
7954
|
return /* @__PURE__ */ jsxs83(
|
|
7929
7955
|
"div",
|
|
7930
7956
|
{
|
|
7931
7957
|
"data-slot": "tool-call",
|
|
7932
7958
|
"data-status": status,
|
|
7933
|
-
className: cn("w-full
|
|
7959
|
+
className: cn("w-full", className),
|
|
7934
7960
|
style,
|
|
7935
7961
|
children: [
|
|
7936
|
-
/* @__PURE__ */
|
|
7962
|
+
hasDetail ? /* @__PURE__ */ jsx119(
|
|
7937
7963
|
"button",
|
|
7938
7964
|
{
|
|
7939
7965
|
type: "button",
|
|
7940
7966
|
"data-slot": "tool-call-trigger",
|
|
7941
7967
|
"aria-expanded": expanded,
|
|
7942
|
-
className: "flex w-full items-center gap-2
|
|
7968
|
+
className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
|
|
7943
7969
|
onClick: () => setExpanded((value) => !value),
|
|
7944
|
-
children:
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
/* @__PURE__ */ jsx119(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" })
|
|
7953
|
-
]
|
|
7970
|
+
children: headerInner
|
|
7971
|
+
}
|
|
7972
|
+
) : /* @__PURE__ */ jsx119(
|
|
7973
|
+
"div",
|
|
7974
|
+
{
|
|
7975
|
+
"data-slot": "tool-call-trigger",
|
|
7976
|
+
className: "flex w-full items-center gap-2 py-1 text-left text-sm",
|
|
7977
|
+
children: headerInner
|
|
7954
7978
|
}
|
|
7955
7979
|
),
|
|
7956
|
-
expanded ? /* @__PURE__ */ jsxs83("div", { "data-slot": "tool-call-body", className: "flex flex-col gap-2
|
|
7980
|
+
hasDetail && expanded ? /* @__PURE__ */ jsxs83("div", { "data-slot": "tool-call-body", className: "flex flex-col gap-2 py-1 pl-6", children: [
|
|
7957
7981
|
paramsText ? /* @__PURE__ */ jsxs83("div", { children: [
|
|
7958
7982
|
/* @__PURE__ */ jsx119("div", { className: "text-xs font-medium text-muted-foreground", children: "\u53C2\u6570" }),
|
|
7959
|
-
/* @__PURE__ */ jsx119("pre", { "data-slot": "tool-call-params", className: "mt-1 overflow-x-auto
|
|
7983
|
+
/* @__PURE__ */ jsx119("pre", { "data-slot": "tool-call-params", className: "mt-1 overflow-x-auto text-xs whitespace-pre-wrap text-muted-foreground", children: paramsText })
|
|
7960
7984
|
] }) : null,
|
|
7961
7985
|
result ? /* @__PURE__ */ jsxs83("div", { children: [
|
|
7962
7986
|
/* @__PURE__ */ jsx119("div", { className: "text-xs font-medium text-muted-foreground", children: "\u7ED3\u679C" }),
|
|
7963
|
-
/* @__PURE__ */ jsx119("pre", { "data-slot": "tool-call-result", className: "mt-1 overflow-x-auto
|
|
7987
|
+
/* @__PURE__ */ jsx119("pre", { "data-slot": "tool-call-result", className: "mt-1 overflow-x-auto text-xs whitespace-pre-wrap text-muted-foreground", children: result })
|
|
7964
7988
|
] }) : null
|
|
7965
7989
|
] }) : null
|
|
7966
7990
|
]
|
|
@@ -7970,12 +7994,26 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
|
|
|
7970
7994
|
|
|
7971
7995
|
// src/components/chat/ChatMessage/index.tsx
|
|
7972
7996
|
import { jsx as jsx120, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
7973
|
-
function PartView({
|
|
7997
|
+
function PartView({
|
|
7998
|
+
part,
|
|
7999
|
+
role,
|
|
8000
|
+
onOpenArtifacts
|
|
8001
|
+
}) {
|
|
8002
|
+
if (role === "system" && (part.type === "text" || part.type === "markdown")) {
|
|
8003
|
+
return /* @__PURE__ */ jsx120(
|
|
8004
|
+
"div",
|
|
8005
|
+
{
|
|
8006
|
+
"data-slot": "chat-message-system-part",
|
|
8007
|
+
className: "w-full text-center text-xs text-muted-foreground",
|
|
8008
|
+
children: part.type === "markdown" ? /* @__PURE__ */ jsx120(MarkdownDslComponent, { content: part.content }) : part.content
|
|
8009
|
+
}
|
|
8010
|
+
);
|
|
8011
|
+
}
|
|
7974
8012
|
switch (part.type) {
|
|
7975
8013
|
case "text":
|
|
7976
8014
|
return /* @__PURE__ */ jsx120(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "muted", children: /* @__PURE__ */ jsx120("span", { className: "text-sm whitespace-pre-wrap", children: part.content }) });
|
|
7977
8015
|
case "markdown":
|
|
7978
|
-
return /* @__PURE__ */ jsx120(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "ghost", children: /* @__PURE__ */ jsx120(MarkdownDslComponent, { content: part.content
|
|
8016
|
+
return /* @__PURE__ */ jsx120(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "ghost", children: /* @__PURE__ */ jsx120(MarkdownDslComponent, { content: part.content }) });
|
|
7979
8017
|
case "thinking":
|
|
7980
8018
|
return /* @__PURE__ */ jsx120(Thinking, { content: part.content, status: part.status ?? "done" });
|
|
7981
8019
|
case "tool-call":
|
|
@@ -7983,10 +8021,31 @@ function PartView({ part, role }) {
|
|
|
7983
8021
|
case "tool-result":
|
|
7984
8022
|
return /* @__PURE__ */ jsx120("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 });
|
|
7985
8023
|
case "status":
|
|
7986
|
-
return /* @__PURE__ */ jsxs84("div", { "data-slot": "chat-message-status", className: "flex items-center gap-1.5 text-
|
|
8024
|
+
return /* @__PURE__ */ jsxs84("div", { "data-slot": "chat-message-status", className: "flex w-fit items-center gap-1.5 text-muted-foreground", children: [
|
|
7987
8025
|
/* @__PURE__ */ jsx120(Icon, { name: "clock", size: "sm" }),
|
|
7988
8026
|
part.text
|
|
7989
8027
|
] });
|
|
8028
|
+
case "artifacts": {
|
|
8029
|
+
const artifactsClass = "flex w-fit items-center gap-1.5 text-muted-foreground";
|
|
8030
|
+
const label = `\u5DF2\u751F\u6210 ${part.count} \u4E2A\u4EA7\u7269`;
|
|
8031
|
+
return onOpenArtifacts ? /* @__PURE__ */ jsxs84(
|
|
8032
|
+
"button",
|
|
8033
|
+
{
|
|
8034
|
+
type: "button",
|
|
8035
|
+
"data-slot": "chat-message-artifacts",
|
|
8036
|
+
className: cn(artifactsClass, "cursor-pointer hover:text-foreground"),
|
|
8037
|
+
onClick: onOpenArtifacts,
|
|
8038
|
+
children: [
|
|
8039
|
+
/* @__PURE__ */ jsx120(Icon, { name: "package", size: "sm" }),
|
|
8040
|
+
label,
|
|
8041
|
+
/* @__PURE__ */ jsx120(Icon, { name: "chevron-right", size: 12 })
|
|
8042
|
+
]
|
|
8043
|
+
}
|
|
8044
|
+
) : /* @__PURE__ */ jsxs84("div", { "data-slot": "chat-message-artifacts", className: artifactsClass, children: [
|
|
8045
|
+
/* @__PURE__ */ jsx120(Icon, { name: "package", size: "sm" }),
|
|
8046
|
+
label
|
|
8047
|
+
] });
|
|
8048
|
+
}
|
|
7990
8049
|
case "error":
|
|
7991
8050
|
return /* @__PURE__ */ jsxs84("div", { "data-slot": "chat-message-error", className: "flex items-center gap-1.5 text-sm text-destructive", children: [
|
|
7992
8051
|
/* @__PURE__ */ jsx120(Icon, { name: "circle-alert", size: "sm" }),
|
|
@@ -7996,19 +8055,31 @@ function PartView({ part, role }) {
|
|
|
7996
8055
|
return null;
|
|
7997
8056
|
}
|
|
7998
8057
|
}
|
|
8058
|
+
var ACTION_ICON_BY_NAME = {
|
|
8059
|
+
copy: "copy",
|
|
8060
|
+
retry: "rotate-ccw",
|
|
8061
|
+
regenerate: "refresh-ccw",
|
|
8062
|
+
edit: "pencil",
|
|
8063
|
+
like: "thumbs-up",
|
|
8064
|
+
dislike: "thumbs-down",
|
|
8065
|
+
share: "share",
|
|
8066
|
+
delete: "trash"
|
|
8067
|
+
};
|
|
7999
8068
|
function ChatMessage({
|
|
8000
8069
|
role = "assistant",
|
|
8001
8070
|
parts = [],
|
|
8002
8071
|
status = "completed",
|
|
8003
8072
|
agent,
|
|
8004
8073
|
time,
|
|
8005
|
-
showSender =
|
|
8074
|
+
showSender = false,
|
|
8006
8075
|
actions = [],
|
|
8007
8076
|
onAction,
|
|
8077
|
+
onOpenArtifacts,
|
|
8008
8078
|
className,
|
|
8009
8079
|
style
|
|
8010
8080
|
}) {
|
|
8011
8081
|
const isUser = role === "user";
|
|
8082
|
+
const isSystem = role === "system";
|
|
8012
8083
|
const senderName = isUser ? "\u6211" : agent?.name ?? "\u52A9\u624B";
|
|
8013
8084
|
return /* @__PURE__ */ jsxs84(
|
|
8014
8085
|
"div",
|
|
@@ -8016,10 +8087,16 @@ function ChatMessage({
|
|
|
8016
8087
|
"data-slot": "chat-message",
|
|
8017
8088
|
"data-role": role,
|
|
8018
8089
|
"data-status": status,
|
|
8019
|
-
className: cn(
|
|
8090
|
+
className: cn(
|
|
8091
|
+
"flex w-full flex-col gap-1.5",
|
|
8092
|
+
isUser && "items-end",
|
|
8093
|
+
// system 居中弱提示(参考 @pactor-app/chat MessageBubble)
|
|
8094
|
+
isSystem && "items-center text-muted-foreground",
|
|
8095
|
+
className
|
|
8096
|
+
),
|
|
8020
8097
|
style,
|
|
8021
8098
|
children: [
|
|
8022
|
-
showSender
|
|
8099
|
+
showSender ? /* @__PURE__ */ jsx120(
|
|
8023
8100
|
Sender,
|
|
8024
8101
|
{
|
|
8025
8102
|
name: senderName,
|
|
@@ -8028,35 +8105,454 @@ function ChatMessage({
|
|
|
8028
8105
|
align: isUser ? "end" : "start"
|
|
8029
8106
|
}
|
|
8030
8107
|
) : null,
|
|
8031
|
-
/* @__PURE__ */ jsxs84("div", { className: cn("flex min-w-0 w-full max-w-full flex-col gap-2", isUser && "items-end"), children: [
|
|
8032
|
-
parts.map((part, index) => /* @__PURE__ */ jsx120(PartView, { part, role }, index)),
|
|
8108
|
+
/* @__PURE__ */ jsxs84("div", { className: cn("flex min-w-0 w-full max-w-full flex-col gap-2", isUser && "items-end", isSystem && "items-center"), children: [
|
|
8109
|
+
parts.map((part, index) => /* @__PURE__ */ jsx120(PartView, { part, role, onOpenArtifacts }, index)),
|
|
8033
8110
|
status === "streaming" ? /* @__PURE__ */ jsx120(StreamingText, { content: "", streaming: true }) : null
|
|
8034
8111
|
] }),
|
|
8035
|
-
actions.length > 0 && (status === "completed" || status === "error") ? /* @__PURE__ */ jsx120("div", { "data-slot": "chat-message-actions", className: "flex items-center gap-1", children: actions.map((action) =>
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8112
|
+
actions.length > 0 && (status === "completed" || status === "error") ? /* @__PURE__ */ jsx120("div", { "data-slot": "chat-message-actions", className: "flex items-center gap-1 mt-2", children: actions.map((action) => {
|
|
8113
|
+
const label = action.label ?? action.name;
|
|
8114
|
+
const iconName = action.icon ?? ACTION_ICON_BY_NAME[action.name];
|
|
8115
|
+
if (iconName) {
|
|
8116
|
+
return /* @__PURE__ */ jsx120(Tooltip2, { content: label, side: "top", children: /* @__PURE__ */ jsx120(
|
|
8117
|
+
"button",
|
|
8118
|
+
{
|
|
8119
|
+
type: "button",
|
|
8120
|
+
"data-slot": "chat-message-action",
|
|
8121
|
+
"data-action": action.name,
|
|
8122
|
+
"aria-label": label,
|
|
8123
|
+
className: "flex cursor-pointer items-center rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
8124
|
+
onClick: () => onAction?.(action.name),
|
|
8125
|
+
children: /* @__PURE__ */ jsx120(Icon, { name: iconName, size: "sm" })
|
|
8126
|
+
}
|
|
8127
|
+
) }, action.name);
|
|
8128
|
+
}
|
|
8129
|
+
return /* @__PURE__ */ jsx120(
|
|
8130
|
+
"button",
|
|
8131
|
+
{
|
|
8132
|
+
type: "button",
|
|
8133
|
+
"data-slot": "chat-message-action",
|
|
8134
|
+
"data-action": action.name,
|
|
8135
|
+
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",
|
|
8136
|
+
onClick: () => onAction?.(action.name),
|
|
8137
|
+
children: label
|
|
8138
|
+
},
|
|
8139
|
+
action.name
|
|
8140
|
+
);
|
|
8141
|
+
}) }) : null
|
|
8050
8142
|
]
|
|
8051
8143
|
}
|
|
8052
8144
|
);
|
|
8053
8145
|
}
|
|
8054
8146
|
|
|
8055
8147
|
// src/components/chat/ChatPage/index.tsx
|
|
8056
|
-
import {
|
|
8148
|
+
import { useRenderer as useRenderer18 } from "@pactor-app/runtime";
|
|
8149
|
+
import { isValidElement as isValidElement2, useState as useState44 } from "react";
|
|
8057
8150
|
|
|
8058
8151
|
// src/components/chat/Composer/index.tsx
|
|
8059
|
-
import {
|
|
8152
|
+
import {
|
|
8153
|
+
useRef as useRef9,
|
|
8154
|
+
useState as useState42
|
|
8155
|
+
} from "react";
|
|
8156
|
+
|
|
8157
|
+
// src/components/chat/Composer/mention-input.tsx
|
|
8158
|
+
import {
|
|
8159
|
+
forwardRef,
|
|
8160
|
+
useEffect as useEffect34,
|
|
8161
|
+
useImperativeHandle,
|
|
8162
|
+
useRef as useRef8,
|
|
8163
|
+
useState as useState41
|
|
8164
|
+
} from "react";
|
|
8165
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
8166
|
+
import { Fragment as Fragment12, jsx as jsx121, jsxs as jsxs85 } from "react/jsx-runtime";
|
|
8167
|
+
var NBSP = "\xA0";
|
|
8168
|
+
var CHIP_ATTR = "data-mention-chip";
|
|
8169
|
+
function escapeRegExp(text) {
|
|
8170
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8171
|
+
}
|
|
8172
|
+
function isChipElement(node) {
|
|
8173
|
+
return node instanceof HTMLElement && node.hasAttribute(CHIP_ATTR);
|
|
8174
|
+
}
|
|
8175
|
+
function serializeNode(node) {
|
|
8176
|
+
let out = "";
|
|
8177
|
+
node.childNodes.forEach((child) => {
|
|
8178
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
8179
|
+
out += (child.textContent ?? "").replace(/\u00A0/g, " ");
|
|
8180
|
+
} else if (isChipElement(child)) {
|
|
8181
|
+
out += `${child.dataset["trigger"] ?? ""}${child.dataset["label"] ?? ""}`;
|
|
8182
|
+
} else if (child instanceof HTMLBRElement) {
|
|
8183
|
+
out += "\n";
|
|
8184
|
+
} else if (child instanceof HTMLElement) {
|
|
8185
|
+
const inner = serializeNode(child).replace(/\n$/, "");
|
|
8186
|
+
out += (out === "" || out.endsWith("\n") ? "" : "\n") + inner + "\n";
|
|
8187
|
+
}
|
|
8188
|
+
});
|
|
8189
|
+
return out;
|
|
8190
|
+
}
|
|
8191
|
+
function collectChips(field) {
|
|
8192
|
+
return Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).map((el) => ({
|
|
8193
|
+
id: el.dataset["id"] ?? "",
|
|
8194
|
+
label: el.dataset["label"] ?? "",
|
|
8195
|
+
trigger: el.dataset["trigger"] ?? ""
|
|
8196
|
+
}));
|
|
8197
|
+
}
|
|
8198
|
+
function detectActiveMention(field, sources) {
|
|
8199
|
+
const selection = window.getSelection();
|
|
8200
|
+
if (!selection || selection.rangeCount === 0 || !selection.isCollapsed) {
|
|
8201
|
+
return null;
|
|
8202
|
+
}
|
|
8203
|
+
const anchor = selection.anchorNode;
|
|
8204
|
+
if (!anchor || anchor.nodeType !== Node.TEXT_NODE || !field.contains(anchor)) {
|
|
8205
|
+
return null;
|
|
8206
|
+
}
|
|
8207
|
+
const caretOffset = selection.anchorOffset;
|
|
8208
|
+
const beforeCaret = (anchor.textContent ?? "").slice(0, caretOffset);
|
|
8209
|
+
for (const source of sources) {
|
|
8210
|
+
const trigger = source.trigger;
|
|
8211
|
+
const match = new RegExp(
|
|
8212
|
+
`(?:^|\\s)${escapeRegExp(trigger)}([^\\s${escapeRegExp(trigger)}]*)$`
|
|
8213
|
+
).exec(beforeCaret);
|
|
8214
|
+
if (match) {
|
|
8215
|
+
const query = match[1] ?? "";
|
|
8216
|
+
return {
|
|
8217
|
+
source,
|
|
8218
|
+
query,
|
|
8219
|
+
node: anchor,
|
|
8220
|
+
triggerStart: caretOffset - query.length - trigger.length,
|
|
8221
|
+
caretOffset
|
|
8222
|
+
};
|
|
8223
|
+
}
|
|
8224
|
+
}
|
|
8225
|
+
return null;
|
|
8226
|
+
}
|
|
8227
|
+
function chipIcon(item, source) {
|
|
8228
|
+
return item.icon ?? source.icon ?? (source.trigger === "@" ? "user" : "file-text");
|
|
8229
|
+
}
|
|
8230
|
+
var MentionInput = forwardRef(
|
|
8231
|
+
function MentionInput2({
|
|
8232
|
+
value,
|
|
8233
|
+
placeholder,
|
|
8234
|
+
disabled,
|
|
8235
|
+
sources,
|
|
8236
|
+
chips,
|
|
8237
|
+
onChipsChange,
|
|
8238
|
+
onChange,
|
|
8239
|
+
onSubmit,
|
|
8240
|
+
className,
|
|
8241
|
+
style
|
|
8242
|
+
}, ref) {
|
|
8243
|
+
const fieldRef = useRef8(null);
|
|
8244
|
+
const [menu, setMenu] = useState41(null);
|
|
8245
|
+
const [empty, setEmpty] = useState41(true);
|
|
8246
|
+
const suppressSyncRef = useRef8(false);
|
|
8247
|
+
const composingRef = useRef8(false);
|
|
8248
|
+
const emitChips = () => {
|
|
8249
|
+
if (suppressSyncRef.current || !fieldRef.current) {
|
|
8250
|
+
return;
|
|
8251
|
+
}
|
|
8252
|
+
onChipsChange?.(collectChips(fieldRef.current));
|
|
8253
|
+
};
|
|
8254
|
+
const serialize = () => fieldRef.current ? serializeNode(fieldRef.current).replace(/\n$/, "") : "";
|
|
8255
|
+
const buildChipElement = (item, source) => {
|
|
8256
|
+
const chip = document.createElement("span");
|
|
8257
|
+
chip.setAttribute(CHIP_ATTR, "");
|
|
8258
|
+
chip.dataset["id"] = item.id;
|
|
8259
|
+
chip.dataset["label"] = item.label;
|
|
8260
|
+
chip.dataset["trigger"] = item.trigger ?? source.trigger;
|
|
8261
|
+
chip.contentEditable = "false";
|
|
8262
|
+
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";
|
|
8263
|
+
const iconMarkup = renderToStaticMarkup(
|
|
8264
|
+
/* @__PURE__ */ jsx121(Icon, { name: chipIcon(item, source), size: 12 })
|
|
8265
|
+
);
|
|
8266
|
+
const label = document.createElement("span");
|
|
8267
|
+
label.textContent = item.label;
|
|
8268
|
+
chip.innerHTML = iconMarkup;
|
|
8269
|
+
chip.appendChild(label);
|
|
8270
|
+
return chip;
|
|
8271
|
+
};
|
|
8272
|
+
const insertChipElement = (item, source, replace) => {
|
|
8273
|
+
const field = fieldRef.current;
|
|
8274
|
+
if (!field) {
|
|
8275
|
+
return;
|
|
8276
|
+
}
|
|
8277
|
+
const chip = buildChipElement(item, source);
|
|
8278
|
+
let caretNode;
|
|
8279
|
+
if (replace) {
|
|
8280
|
+
const { node, start, end } = replace;
|
|
8281
|
+
const text = node.textContent ?? "";
|
|
8282
|
+
node.textContent = text.slice(0, start);
|
|
8283
|
+
caretNode = document.createTextNode(`${NBSP}${text.slice(end)}`);
|
|
8284
|
+
node.after(chip, caretNode);
|
|
8285
|
+
} else {
|
|
8286
|
+
caretNode = document.createTextNode(NBSP);
|
|
8287
|
+
const selection2 = window.getSelection();
|
|
8288
|
+
if (selection2 && selection2.rangeCount > 0 && selection2.anchorNode !== null && field.contains(selection2.anchorNode)) {
|
|
8289
|
+
const range = selection2.getRangeAt(0);
|
|
8290
|
+
range.deleteContents();
|
|
8291
|
+
range.insertNode(caretNode);
|
|
8292
|
+
range.insertNode(chip);
|
|
8293
|
+
} else {
|
|
8294
|
+
field.append(chip, caretNode);
|
|
8295
|
+
}
|
|
8296
|
+
}
|
|
8297
|
+
const selection = window.getSelection();
|
|
8298
|
+
if (selection) {
|
|
8299
|
+
const range = document.createRange();
|
|
8300
|
+
range.setStart(caretNode, 1);
|
|
8301
|
+
range.collapse(true);
|
|
8302
|
+
selection.removeAllRanges();
|
|
8303
|
+
selection.addRange(range);
|
|
8304
|
+
}
|
|
8305
|
+
setEmpty(false);
|
|
8306
|
+
onChange?.(serialize());
|
|
8307
|
+
emitChips();
|
|
8308
|
+
};
|
|
8309
|
+
useImperativeHandle(ref, () => ({
|
|
8310
|
+
insertChip: (item, source) => {
|
|
8311
|
+
fieldRef.current?.focus();
|
|
8312
|
+
insertChipElement(item, source);
|
|
8313
|
+
},
|
|
8314
|
+
focus: () => fieldRef.current?.focus()
|
|
8315
|
+
}));
|
|
8316
|
+
useEffect34(() => {
|
|
8317
|
+
const field = fieldRef.current;
|
|
8318
|
+
if (field && value === "" && serializeNode(field).trim() !== "") {
|
|
8319
|
+
suppressSyncRef.current = true;
|
|
8320
|
+
field.innerHTML = "";
|
|
8321
|
+
setEmpty(true);
|
|
8322
|
+
setMenu(null);
|
|
8323
|
+
suppressSyncRef.current = false;
|
|
8324
|
+
}
|
|
8325
|
+
}, [value]);
|
|
8326
|
+
useEffect34(() => {
|
|
8327
|
+
const field = fieldRef.current;
|
|
8328
|
+
if (!field) {
|
|
8329
|
+
return;
|
|
8330
|
+
}
|
|
8331
|
+
const keep = new Set(chips.map((chip) => `${chip.trigger}:${chip.id}`));
|
|
8332
|
+
const stale = Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).filter(
|
|
8333
|
+
(el) => !keep.has(
|
|
8334
|
+
`${el.dataset["trigger"]}:${el.dataset["id"]}`
|
|
8335
|
+
)
|
|
8336
|
+
);
|
|
8337
|
+
if (stale.length > 0) {
|
|
8338
|
+
suppressSyncRef.current = true;
|
|
8339
|
+
stale.forEach((el) => el.remove());
|
|
8340
|
+
suppressSyncRef.current = false;
|
|
8341
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
8342
|
+
}
|
|
8343
|
+
}, [chips]);
|
|
8344
|
+
const closeMenu = () => setMenu(null);
|
|
8345
|
+
const filteredItems = (state) => state.query ? state.source.items.filter((item) => item.label.includes(state.query)) : state.source.items;
|
|
8346
|
+
const refreshMenu = () => {
|
|
8347
|
+
const field = fieldRef.current;
|
|
8348
|
+
if (!field) {
|
|
8349
|
+
return;
|
|
8350
|
+
}
|
|
8351
|
+
const active = detectActiveMention(field, sources);
|
|
8352
|
+
if (!active) {
|
|
8353
|
+
setMenu(null);
|
|
8354
|
+
return;
|
|
8355
|
+
}
|
|
8356
|
+
const range = document.createRange();
|
|
8357
|
+
range.setStart(active.node, active.triggerStart);
|
|
8358
|
+
range.setEnd(active.node, active.caretOffset);
|
|
8359
|
+
const rect = typeof range.getBoundingClientRect === "function" ? range.getBoundingClientRect() : field.getBoundingClientRect();
|
|
8360
|
+
setMenu((prev) => ({
|
|
8361
|
+
source: active.source,
|
|
8362
|
+
query: active.query,
|
|
8363
|
+
left: rect.left,
|
|
8364
|
+
top: rect.top,
|
|
8365
|
+
// 过滤结果变化后候选下标钳制在有效范围内(DSL 每次渲染产出新
|
|
8366
|
+
// props 对象,source 按 trigger 比较而非引用)
|
|
8367
|
+
activeIndex: Math.min(
|
|
8368
|
+
prev?.source.trigger === active.source.trigger ? prev.activeIndex : 0,
|
|
8369
|
+
Math.max(filteredItems({ source: active.source, query: active.query, left: 0, top: 0, activeIndex: 0 }).length - 1, 0)
|
|
8370
|
+
)
|
|
8371
|
+
}));
|
|
8372
|
+
};
|
|
8373
|
+
const selectMenuItem = (item) => {
|
|
8374
|
+
const field = fieldRef.current;
|
|
8375
|
+
if (!field || !menu) {
|
|
8376
|
+
return;
|
|
8377
|
+
}
|
|
8378
|
+
const active = detectActiveMention(field, sources);
|
|
8379
|
+
insertChipElement(
|
|
8380
|
+
{ ...item, trigger: item.trigger ?? menu.source.trigger },
|
|
8381
|
+
menu.source,
|
|
8382
|
+
active && active.source.trigger === menu.source.trigger ? { node: active.node, start: active.triggerStart, end: active.caretOffset } : void 0
|
|
8383
|
+
);
|
|
8384
|
+
setMenu(null);
|
|
8385
|
+
};
|
|
8386
|
+
const handleInput = () => {
|
|
8387
|
+
const field = fieldRef.current;
|
|
8388
|
+
if (!field) {
|
|
8389
|
+
return;
|
|
8390
|
+
}
|
|
8391
|
+
if ((field.textContent ?? "") === "" && field.querySelector(`[${CHIP_ATTR}]`) === null) {
|
|
8392
|
+
field.innerHTML = "";
|
|
8393
|
+
}
|
|
8394
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
8395
|
+
onChange?.(serialize());
|
|
8396
|
+
refreshMenu();
|
|
8397
|
+
};
|
|
8398
|
+
const handleKeyDown = (event) => {
|
|
8399
|
+
if (menu) {
|
|
8400
|
+
const items = filteredItems(menu);
|
|
8401
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
8402
|
+
event.preventDefault();
|
|
8403
|
+
if (items.length > 0) {
|
|
8404
|
+
const delta = event.key === "ArrowDown" ? 1 : -1;
|
|
8405
|
+
setMenu({
|
|
8406
|
+
...menu,
|
|
8407
|
+
activeIndex: (menu.activeIndex + delta + items.length) % items.length
|
|
8408
|
+
});
|
|
8409
|
+
}
|
|
8410
|
+
return;
|
|
8411
|
+
}
|
|
8412
|
+
if (event.key === "Enter" && !composingRef.current && !event.nativeEvent.isComposing) {
|
|
8413
|
+
event.preventDefault();
|
|
8414
|
+
const item = items[Math.min(menu.activeIndex, items.length - 1)];
|
|
8415
|
+
if (item) {
|
|
8416
|
+
selectMenuItem(item);
|
|
8417
|
+
} else {
|
|
8418
|
+
closeMenu();
|
|
8419
|
+
}
|
|
8420
|
+
return;
|
|
8421
|
+
}
|
|
8422
|
+
if (event.key === "Escape") {
|
|
8423
|
+
event.preventDefault();
|
|
8424
|
+
closeMenu();
|
|
8425
|
+
return;
|
|
8426
|
+
}
|
|
8427
|
+
}
|
|
8428
|
+
if (event.key === "Enter" && !event.shiftKey && !composingRef.current && !event.nativeEvent.isComposing) {
|
|
8429
|
+
event.preventDefault();
|
|
8430
|
+
const text = serialize();
|
|
8431
|
+
if (text.trim() !== "" && !disabled) {
|
|
8432
|
+
onSubmit?.(text);
|
|
8433
|
+
}
|
|
8434
|
+
return;
|
|
8435
|
+
}
|
|
8436
|
+
if (event.key === "Backspace") {
|
|
8437
|
+
const selection = window.getSelection();
|
|
8438
|
+
const field = fieldRef.current;
|
|
8439
|
+
if (!selection || !selection.isCollapsed || !field) {
|
|
8440
|
+
return;
|
|
8441
|
+
}
|
|
8442
|
+
let chip = null;
|
|
8443
|
+
const anchor = selection.anchorNode;
|
|
8444
|
+
if (anchor === field && selection.anchorOffset > 0) {
|
|
8445
|
+
const before = field.childNodes[selection.anchorOffset - 1];
|
|
8446
|
+
if (isChipElement(before)) {
|
|
8447
|
+
chip = before;
|
|
8448
|
+
}
|
|
8449
|
+
} else if (anchor?.nodeType === Node.TEXT_NODE && selection.anchorOffset === 0) {
|
|
8450
|
+
if (isChipElement(anchor.previousSibling)) {
|
|
8451
|
+
chip = anchor.previousSibling;
|
|
8452
|
+
}
|
|
8453
|
+
}
|
|
8454
|
+
if (chip) {
|
|
8455
|
+
event.preventDefault();
|
|
8456
|
+
chip.remove();
|
|
8457
|
+
onChange?.(serialize());
|
|
8458
|
+
emitChips();
|
|
8459
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
8460
|
+
}
|
|
8461
|
+
}
|
|
8462
|
+
};
|
|
8463
|
+
const menuItems = menu ? filteredItems(menu) : [];
|
|
8464
|
+
const activeIndex = Math.min(menu?.activeIndex ?? 0, Math.max(menuItems.length - 1, 0));
|
|
8465
|
+
return /* @__PURE__ */ jsxs85("div", { className: "relative", children: [
|
|
8466
|
+
/* @__PURE__ */ jsx121(
|
|
8467
|
+
"div",
|
|
8468
|
+
{
|
|
8469
|
+
ref: fieldRef,
|
|
8470
|
+
"data-slot": "mention-input",
|
|
8471
|
+
role: "textbox",
|
|
8472
|
+
"aria-multiline": "true",
|
|
8473
|
+
"aria-placeholder": placeholder,
|
|
8474
|
+
contentEditable: !disabled,
|
|
8475
|
+
suppressContentEditableWarning: true,
|
|
8476
|
+
className: cn(
|
|
8477
|
+
"min-h-[60px] w-full px-4 pt-3 pb-1 text-sm whitespace-pre-wrap break-words outline-none",
|
|
8478
|
+
className
|
|
8479
|
+
),
|
|
8480
|
+
style,
|
|
8481
|
+
onInput: handleInput,
|
|
8482
|
+
onKeyDown: handleKeyDown,
|
|
8483
|
+
onCompositionStart: () => {
|
|
8484
|
+
composingRef.current = true;
|
|
8485
|
+
},
|
|
8486
|
+
onCompositionEnd: () => {
|
|
8487
|
+
composingRef.current = false;
|
|
8488
|
+
},
|
|
8489
|
+
onPaste: (event) => {
|
|
8490
|
+
event.preventDefault();
|
|
8491
|
+
const text = event.clipboardData?.getData("text/plain") ?? "";
|
|
8492
|
+
if (text) {
|
|
8493
|
+
document.execCommand("insertText", false, text);
|
|
8494
|
+
}
|
|
8495
|
+
}
|
|
8496
|
+
}
|
|
8497
|
+
),
|
|
8498
|
+
empty && placeholder !== void 0 ? /* @__PURE__ */ jsx121("span", { className: "pointer-events-none absolute top-3 left-4 text-sm text-muted-foreground", children: placeholder }) : null,
|
|
8499
|
+
menu ? /* @__PURE__ */ jsxs85(Fragment12, { children: [
|
|
8500
|
+
/* @__PURE__ */ jsx121(
|
|
8501
|
+
"div",
|
|
8502
|
+
{
|
|
8503
|
+
className: "fixed inset-0 z-40",
|
|
8504
|
+
onMouseDown: (event) => {
|
|
8505
|
+
event.preventDefault();
|
|
8506
|
+
closeMenu();
|
|
8507
|
+
}
|
|
8508
|
+
}
|
|
8509
|
+
),
|
|
8510
|
+
/* @__PURE__ */ jsxs85(
|
|
8511
|
+
"div",
|
|
8512
|
+
{
|
|
8513
|
+
"data-slot": "mention-menu",
|
|
8514
|
+
role: "listbox",
|
|
8515
|
+
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",
|
|
8516
|
+
style: {
|
|
8517
|
+
left: menu.left,
|
|
8518
|
+
bottom: typeof window === "undefined" ? void 0 : window.innerHeight - menu.top + 6
|
|
8519
|
+
},
|
|
8520
|
+
children: [
|
|
8521
|
+
/* @__PURE__ */ jsx121("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: menu.source.label }),
|
|
8522
|
+
menuItems.length === 0 ? /* @__PURE__ */ jsx121("div", { className: "px-2 py-2 text-xs text-muted-foreground", children: "\u65E0\u5339\u914D\u9879" }) : menuItems.map((item, index) => /* @__PURE__ */ jsxs85(
|
|
8523
|
+
"button",
|
|
8524
|
+
{
|
|
8525
|
+
type: "button",
|
|
8526
|
+
role: "option",
|
|
8527
|
+
"aria-selected": index === activeIndex,
|
|
8528
|
+
className: cn(
|
|
8529
|
+
"flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm",
|
|
8530
|
+
index === activeIndex ? "bg-accent" : "hover:bg-accent"
|
|
8531
|
+
),
|
|
8532
|
+
onMouseDown: (event) => {
|
|
8533
|
+
event.preventDefault();
|
|
8534
|
+
selectMenuItem(item);
|
|
8535
|
+
},
|
|
8536
|
+
children: [
|
|
8537
|
+
/* @__PURE__ */ jsx121(Icon, { name: chipIcon(item, menu.source), size: "sm" }),
|
|
8538
|
+
/* @__PURE__ */ jsx121("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
8539
|
+
]
|
|
8540
|
+
},
|
|
8541
|
+
item.id
|
|
8542
|
+
))
|
|
8543
|
+
]
|
|
8544
|
+
}
|
|
8545
|
+
)
|
|
8546
|
+
] }) : null
|
|
8547
|
+
] });
|
|
8548
|
+
}
|
|
8549
|
+
);
|
|
8550
|
+
|
|
8551
|
+
// src/components/chat/Composer/index.tsx
|
|
8552
|
+
import { Fragment as Fragment13, jsx as jsx122, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
8553
|
+
var toolButtonClass3 = "flex cursor-pointer items-center rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground";
|
|
8554
|
+
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";
|
|
8555
|
+
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";
|
|
8060
8556
|
function Composer({
|
|
8061
8557
|
value,
|
|
8062
8558
|
placeholder,
|
|
@@ -8066,33 +8562,236 @@ function Composer({
|
|
|
8066
8562
|
attachments = [],
|
|
8067
8563
|
onRemoveAttachment,
|
|
8068
8564
|
onRetryAttachment,
|
|
8565
|
+
onAttachFiles,
|
|
8069
8566
|
onChange,
|
|
8070
8567
|
onSubmit,
|
|
8568
|
+
models,
|
|
8569
|
+
model,
|
|
8570
|
+
onModelChange,
|
|
8571
|
+
contexts,
|
|
8572
|
+
contextItems,
|
|
8573
|
+
onContextItemsChange,
|
|
8574
|
+
footer,
|
|
8071
8575
|
className,
|
|
8072
8576
|
style
|
|
8073
8577
|
}) {
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8578
|
+
const textControlled = value !== void 0;
|
|
8579
|
+
const [innerText, setInnerText] = useState42("");
|
|
8580
|
+
const text = textControlled ? value : innerText;
|
|
8581
|
+
const [dragOver, setDragOver] = useState42(false);
|
|
8582
|
+
const [plusOpen, setPlusOpen] = useState42(false);
|
|
8583
|
+
const [modelOpen, setModelOpen] = useState42(false);
|
|
8584
|
+
const fileInputRef = useRef9(null);
|
|
8585
|
+
const mentionRef = useRef9(null);
|
|
8586
|
+
const sources = contexts ?? [];
|
|
8587
|
+
const rich = sources.length > 0;
|
|
8588
|
+
const plusSources = sources.filter((s) => s.trigger === "+");
|
|
8589
|
+
const plusEnabled = plusSources.length > 0;
|
|
8590
|
+
const modelEnabled = models !== void 0 && models.length > 0;
|
|
8591
|
+
const currentModel = models?.find((m) => m.value === model) ?? models?.[0];
|
|
8592
|
+
const chips = contextItems ?? [];
|
|
8593
|
+
const closePopovers = () => {
|
|
8594
|
+
setPlusOpen(false);
|
|
8595
|
+
setModelOpen(false);
|
|
8596
|
+
};
|
|
8597
|
+
const handleChange = (next) => {
|
|
8598
|
+
if (!textControlled) {
|
|
8599
|
+
setInnerText(next);
|
|
8600
|
+
}
|
|
8601
|
+
onChange?.(next);
|
|
8602
|
+
};
|
|
8603
|
+
const handleSubmit = (submitted) => {
|
|
8604
|
+
onSubmit?.(submitted);
|
|
8605
|
+
if (!textControlled) {
|
|
8606
|
+
setInnerText("");
|
|
8607
|
+
}
|
|
8608
|
+
closePopovers();
|
|
8609
|
+
};
|
|
8610
|
+
const selectContext = (item, source) => {
|
|
8611
|
+
if (rich) {
|
|
8612
|
+
mentionRef.current?.insertChip(item, source);
|
|
8613
|
+
} else {
|
|
8614
|
+
const chip = { ...item, trigger: item.trigger ?? source.trigger };
|
|
8615
|
+
const duplicated = chips.some(
|
|
8616
|
+
(existing) => existing.id === chip.id && existing.trigger === chip.trigger
|
|
8617
|
+
);
|
|
8618
|
+
if (!duplicated) {
|
|
8619
|
+
onContextItemsChange?.([...chips, chip]);
|
|
8620
|
+
}
|
|
8621
|
+
}
|
|
8622
|
+
closePopovers();
|
|
8623
|
+
};
|
|
8624
|
+
const emitFiles = (files) => {
|
|
8625
|
+
if (files.length > 0 && onAttachFiles) {
|
|
8626
|
+
onAttachFiles(files);
|
|
8627
|
+
}
|
|
8628
|
+
};
|
|
8629
|
+
const handleDrop = (event) => {
|
|
8630
|
+
if (!onAttachFiles) {
|
|
8631
|
+
return;
|
|
8632
|
+
}
|
|
8633
|
+
event.preventDefault();
|
|
8634
|
+
setDragOver(false);
|
|
8635
|
+
emitFiles(Array.from(event.dataTransfer?.files ?? []));
|
|
8636
|
+
};
|
|
8637
|
+
const toolbarStart = plusEnabled || onAttachFiles ? /* @__PURE__ */ jsxs86(Fragment13, { children: [
|
|
8638
|
+
plusEnabled ? /* @__PURE__ */ jsx122(
|
|
8639
|
+
"button",
|
|
8078
8640
|
{
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8641
|
+
type: "button",
|
|
8642
|
+
"aria-label": "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
8643
|
+
title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
8644
|
+
className: toolButtonClass3,
|
|
8645
|
+
onClick: () => {
|
|
8646
|
+
setPlusOpen((prev) => !prev);
|
|
8647
|
+
setModelOpen(false);
|
|
8648
|
+
},
|
|
8649
|
+
children: /* @__PURE__ */ jsx122(Icon, { name: "plus", size: "sm" })
|
|
8085
8650
|
}
|
|
8086
|
-
)
|
|
8087
|
-
|
|
8651
|
+
) : null,
|
|
8652
|
+
onAttachFiles ? /* @__PURE__ */ jsx122(
|
|
8653
|
+
"button",
|
|
8654
|
+
{
|
|
8655
|
+
type: "button",
|
|
8656
|
+
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
8657
|
+
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
8658
|
+
className: toolButtonClass3,
|
|
8659
|
+
onClick: () => fileInputRef.current?.click(),
|
|
8660
|
+
children: /* @__PURE__ */ jsx122(Icon, { name: "paperclip", size: "sm" })
|
|
8661
|
+
}
|
|
8662
|
+
) : null
|
|
8663
|
+
] }) : void 0;
|
|
8664
|
+
const toolbarEnd = modelEnabled ? /* @__PURE__ */ jsxs86(
|
|
8665
|
+
"button",
|
|
8666
|
+
{
|
|
8667
|
+
type: "button",
|
|
8668
|
+
"aria-label": "\u9009\u62E9\u6A21\u578B",
|
|
8669
|
+
title: "\u9009\u62E9\u6A21\u578B",
|
|
8670
|
+
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",
|
|
8671
|
+
onClick: () => {
|
|
8672
|
+
setModelOpen((prev) => !prev);
|
|
8673
|
+
setPlusOpen(false);
|
|
8674
|
+
},
|
|
8675
|
+
children: [
|
|
8676
|
+
currentModel?.label,
|
|
8677
|
+
/* @__PURE__ */ jsx122(Icon, { name: "chevrons-up-down", size: 12 })
|
|
8678
|
+
]
|
|
8679
|
+
}
|
|
8680
|
+
) : void 0;
|
|
8681
|
+
const activePopover = plusOpen ? "plus" : modelOpen ? "model" : null;
|
|
8682
|
+
return /* @__PURE__ */ jsxs86(
|
|
8683
|
+
"div",
|
|
8684
|
+
{
|
|
8685
|
+
"data-slot": "composer",
|
|
8686
|
+
className: cn("relative flex w-full flex-col gap-2", className),
|
|
8687
|
+
style,
|
|
8688
|
+
onDragOver: (event) => {
|
|
8689
|
+
if (onAttachFiles) {
|
|
8690
|
+
event.preventDefault();
|
|
8691
|
+
setDragOver(true);
|
|
8692
|
+
}
|
|
8693
|
+
},
|
|
8694
|
+
onDragLeave: () => setDragOver(false),
|
|
8695
|
+
onDrop: handleDrop,
|
|
8696
|
+
onPaste: (event) => {
|
|
8697
|
+
const files = Array.from(event.clipboardData?.files ?? []);
|
|
8698
|
+
if (files.length > 0 && onAttachFiles) {
|
|
8699
|
+
event.preventDefault();
|
|
8700
|
+
emitFiles(files);
|
|
8701
|
+
}
|
|
8702
|
+
},
|
|
8703
|
+
children: [
|
|
8704
|
+
attachments.length > 0 ? /* @__PURE__ */ jsx122(Attachment, { items: attachments, onRemove: onRemoveAttachment, onRetry: onRetryAttachment }) : null,
|
|
8705
|
+
/* @__PURE__ */ jsx122("div", { className: cn(dragOver && "rounded-xl ring-2 ring-ring/50"), children: /* @__PURE__ */ jsx122(
|
|
8706
|
+
ChatInput,
|
|
8707
|
+
{
|
|
8708
|
+
value: text,
|
|
8709
|
+
placeholder,
|
|
8710
|
+
disabled: disabled || loading,
|
|
8711
|
+
rows,
|
|
8712
|
+
toolbarStart,
|
|
8713
|
+
toolbarEnd,
|
|
8714
|
+
footer,
|
|
8715
|
+
field: rich ? /* @__PURE__ */ jsx122(
|
|
8716
|
+
MentionInput,
|
|
8717
|
+
{
|
|
8718
|
+
ref: mentionRef,
|
|
8719
|
+
value: text,
|
|
8720
|
+
placeholder,
|
|
8721
|
+
disabled: disabled || loading,
|
|
8722
|
+
sources,
|
|
8723
|
+
chips,
|
|
8724
|
+
onChipsChange: onContextItemsChange,
|
|
8725
|
+
onChange: handleChange,
|
|
8726
|
+
onSubmit: handleSubmit
|
|
8727
|
+
}
|
|
8728
|
+
) : void 0,
|
|
8729
|
+
onChange: handleChange,
|
|
8730
|
+
onSubmit: handleSubmit
|
|
8731
|
+
}
|
|
8732
|
+
) }),
|
|
8733
|
+
onAttachFiles ? /* @__PURE__ */ jsx122(
|
|
8734
|
+
"input",
|
|
8735
|
+
{
|
|
8736
|
+
ref: fileInputRef,
|
|
8737
|
+
type: "file",
|
|
8738
|
+
multiple: true,
|
|
8739
|
+
hidden: true,
|
|
8740
|
+
onChange: (event) => {
|
|
8741
|
+
emitFiles(Array.from(event.target.files ?? []));
|
|
8742
|
+
event.target.value = "";
|
|
8743
|
+
}
|
|
8744
|
+
}
|
|
8745
|
+
) : null,
|
|
8746
|
+
activePopover !== null ? /* @__PURE__ */ jsxs86(Fragment13, { children: [
|
|
8747
|
+
/* @__PURE__ */ jsx122("div", { className: "fixed inset-0 z-40", onClick: closePopovers }),
|
|
8748
|
+
activePopover === "model" ? /* @__PURE__ */ jsx122("div", { "data-slot": "composer-model-popover", className: cn(popoverPanelClass, "right-0 left-auto w-48"), role: "listbox", children: models.map((option) => /* @__PURE__ */ jsxs86(
|
|
8749
|
+
"button",
|
|
8750
|
+
{
|
|
8751
|
+
type: "button",
|
|
8752
|
+
role: "option",
|
|
8753
|
+
"aria-selected": option.value === currentModel?.value,
|
|
8754
|
+
className: popoverItemClass,
|
|
8755
|
+
onClick: () => {
|
|
8756
|
+
onModelChange?.(option.value);
|
|
8757
|
+
closePopovers();
|
|
8758
|
+
},
|
|
8759
|
+
children: [
|
|
8760
|
+
/* @__PURE__ */ jsx122("span", { className: "min-w-0 flex-1 truncate", children: option.label }),
|
|
8761
|
+
option.value === currentModel?.value ? /* @__PURE__ */ jsx122(Icon, { name: "check", size: 14 }) : null
|
|
8762
|
+
]
|
|
8763
|
+
},
|
|
8764
|
+
option.value
|
|
8765
|
+
)) }) : /* @__PURE__ */ jsx122("div", { "data-slot": "composer-context-popover", className: popoverPanelClass, role: "listbox", children: plusSources.map(
|
|
8766
|
+
(source) => source.items.length === 0 ? null : /* @__PURE__ */ jsxs86("div", { children: [
|
|
8767
|
+
/* @__PURE__ */ jsx122("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: source.label }),
|
|
8768
|
+
source.items.map((item) => /* @__PURE__ */ jsxs86(
|
|
8769
|
+
"button",
|
|
8770
|
+
{
|
|
8771
|
+
type: "button",
|
|
8772
|
+
className: popoverItemClass,
|
|
8773
|
+
onClick: () => selectContext(item, source),
|
|
8774
|
+
children: [
|
|
8775
|
+
/* @__PURE__ */ jsx122(Icon, { name: item.icon ?? source.icon ?? "file-text", size: "sm" }),
|
|
8776
|
+
/* @__PURE__ */ jsx122("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
8777
|
+
]
|
|
8778
|
+
},
|
|
8779
|
+
item.id
|
|
8780
|
+
))
|
|
8781
|
+
] }, source.trigger)
|
|
8782
|
+
) })
|
|
8783
|
+
] }) : null
|
|
8784
|
+
]
|
|
8785
|
+
}
|
|
8786
|
+
);
|
|
8088
8787
|
}
|
|
8089
8788
|
|
|
8090
8789
|
// src/components/chat/ConversationList/index.tsx
|
|
8091
|
-
import { useMemo as useMemo6, useState as
|
|
8092
|
-
import { jsx as
|
|
8790
|
+
import { useMemo as useMemo6, useState as useState43 } from "react";
|
|
8791
|
+
import { jsx as jsx123, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
8093
8792
|
function ConversationList({ items = [], activeId, searchable, onSelect, onDelete, className, style }) {
|
|
8094
|
-
const [innerActive, setInnerActive] =
|
|
8095
|
-
const [keyword, setKeyword] =
|
|
8793
|
+
const [innerActive, setInnerActive] = useState43();
|
|
8794
|
+
const [keyword, setKeyword] = useState43("");
|
|
8096
8795
|
const active = activeId ?? innerActive;
|
|
8097
8796
|
const filtered = useMemo6(() => {
|
|
8098
8797
|
const query = keyword.trim().toLowerCase();
|
|
@@ -8107,10 +8806,10 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
8107
8806
|
}
|
|
8108
8807
|
onSelect?.(id);
|
|
8109
8808
|
};
|
|
8110
|
-
return /* @__PURE__ */
|
|
8111
|
-
searchable ? /* @__PURE__ */
|
|
8112
|
-
/* @__PURE__ */
|
|
8113
|
-
/* @__PURE__ */
|
|
8809
|
+
return /* @__PURE__ */ jsxs87("div", { "data-slot": "conversation-list", className: cn("flex w-full flex-col gap-1", className), style, children: [
|
|
8810
|
+
searchable ? /* @__PURE__ */ jsxs87("div", { className: "relative mb-1", children: [
|
|
8811
|
+
/* @__PURE__ */ jsx123("span", { className: "absolute top-1/2 left-2 -translate-y-1/2 text-muted-foreground", children: /* @__PURE__ */ jsx123(Icon, { name: "search", size: "sm" }) }),
|
|
8812
|
+
/* @__PURE__ */ jsx123(
|
|
8114
8813
|
"input",
|
|
8115
8814
|
{
|
|
8116
8815
|
"data-slot": "conversation-list-search",
|
|
@@ -8121,7 +8820,7 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
8121
8820
|
}
|
|
8122
8821
|
)
|
|
8123
8822
|
] }) : null,
|
|
8124
|
-
filtered.map((item) => /* @__PURE__ */
|
|
8823
|
+
filtered.map((item) => /* @__PURE__ */ jsxs87(
|
|
8125
8824
|
"div",
|
|
8126
8825
|
{
|
|
8127
8826
|
"data-slot": "conversation-list-item",
|
|
@@ -8132,12 +8831,12 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
8132
8831
|
),
|
|
8133
8832
|
onClick: () => select(item.id),
|
|
8134
8833
|
children: [
|
|
8135
|
-
/* @__PURE__ */
|
|
8136
|
-
/* @__PURE__ */
|
|
8137
|
-
item.description ? /* @__PURE__ */
|
|
8834
|
+
/* @__PURE__ */ jsxs87("div", { className: "min-w-0 flex-1", children: [
|
|
8835
|
+
/* @__PURE__ */ jsx123("div", { className: cn("truncate text-sm", item.id === active && "font-medium"), children: item.title }),
|
|
8836
|
+
item.description ? /* @__PURE__ */ jsx123("div", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
|
|
8138
8837
|
] }),
|
|
8139
|
-
item.time ? /* @__PURE__ */
|
|
8140
|
-
onDelete ? /* @__PURE__ */
|
|
8838
|
+
item.time ? /* @__PURE__ */ jsx123("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.time }) : null,
|
|
8839
|
+
onDelete ? /* @__PURE__ */ jsx123(
|
|
8141
8840
|
"button",
|
|
8142
8841
|
{
|
|
8143
8842
|
type: "button",
|
|
@@ -8148,41 +8847,42 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
8148
8847
|
event.stopPropagation();
|
|
8149
8848
|
onDelete(item.id);
|
|
8150
8849
|
},
|
|
8151
|
-
children: /* @__PURE__ */
|
|
8850
|
+
children: /* @__PURE__ */ jsx123(Icon, { name: "trash-2", size: "sm" })
|
|
8152
8851
|
}
|
|
8153
8852
|
) : null
|
|
8154
8853
|
]
|
|
8155
8854
|
},
|
|
8156
8855
|
item.id
|
|
8157
8856
|
)),
|
|
8158
|
-
filtered.length === 0 ? /* @__PURE__ */
|
|
8857
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx123("div", { className: "px-2 py-4 text-center text-sm text-muted-foreground", children: "\u65E0\u5339\u914D\u4F1A\u8BDD" }) : null
|
|
8159
8858
|
] });
|
|
8160
8859
|
}
|
|
8161
8860
|
|
|
8162
8861
|
// src/components/chat/MessageList/index.tsx
|
|
8163
|
-
import { useEffect as
|
|
8164
|
-
import { jsx as
|
|
8165
|
-
function MessageList({ messages = [], autoScroll = true, onAction, className, style }) {
|
|
8166
|
-
const listRef =
|
|
8167
|
-
|
|
8862
|
+
import { useEffect as useEffect35, useRef as useRef10 } from "react";
|
|
8863
|
+
import { jsx as jsx124 } from "react/jsx-runtime";
|
|
8864
|
+
function MessageList({ messages = [], autoScroll = true, onAction, onOpenArtifacts, className, style }) {
|
|
8865
|
+
const listRef = useRef10(null);
|
|
8866
|
+
useEffect35(() => {
|
|
8168
8867
|
if (!autoScroll) return;
|
|
8169
8868
|
const el = listRef.current;
|
|
8170
8869
|
if (el) {
|
|
8171
8870
|
el.scrollTop = el.scrollHeight;
|
|
8172
8871
|
}
|
|
8173
8872
|
}, [messages, autoScroll]);
|
|
8174
|
-
return /* @__PURE__ */
|
|
8873
|
+
return /* @__PURE__ */ jsx124(
|
|
8175
8874
|
"div",
|
|
8176
8875
|
{
|
|
8177
8876
|
ref: listRef,
|
|
8178
8877
|
"data-slot": "message-list",
|
|
8179
8878
|
className: cn("flex w-full flex-col gap-4 overflow-y-auto", className),
|
|
8180
8879
|
style,
|
|
8181
|
-
children: messages.map((message, index) => /* @__PURE__ */
|
|
8880
|
+
children: messages.map((message, index) => /* @__PURE__ */ jsx124(
|
|
8182
8881
|
ChatMessage,
|
|
8183
8882
|
{
|
|
8184
8883
|
...message,
|
|
8185
|
-
onAction: (action) => onAction?.({ id: message.id, action })
|
|
8884
|
+
onAction: (action) => onAction?.({ id: message.id, action }),
|
|
8885
|
+
onOpenArtifacts: onOpenArtifacts ? () => onOpenArtifacts({ id: message.id }) : void 0
|
|
8186
8886
|
},
|
|
8187
8887
|
message.id ?? index
|
|
8188
8888
|
))
|
|
@@ -8191,9 +8891,9 @@ function MessageList({ messages = [], autoScroll = true, onAction, className, st
|
|
|
8191
8891
|
}
|
|
8192
8892
|
|
|
8193
8893
|
// src/components/chat/Prompt/index.tsx
|
|
8194
|
-
import { jsx as
|
|
8894
|
+
import { jsx as jsx125, jsxs as jsxs88 } from "react/jsx-runtime";
|
|
8195
8895
|
function Prompt({ title, description, icon, value, disabled, onSelect, className, style }) {
|
|
8196
|
-
return /* @__PURE__ */
|
|
8896
|
+
return /* @__PURE__ */ jsxs88(
|
|
8197
8897
|
"button",
|
|
8198
8898
|
{
|
|
8199
8899
|
type: "button",
|
|
@@ -8206,10 +8906,10 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
|
|
|
8206
8906
|
style,
|
|
8207
8907
|
onClick: () => onSelect?.(value ?? title ?? ""),
|
|
8208
8908
|
children: [
|
|
8209
|
-
icon ? /* @__PURE__ */
|
|
8210
|
-
/* @__PURE__ */
|
|
8211
|
-
/* @__PURE__ */
|
|
8212
|
-
description ? /* @__PURE__ */
|
|
8909
|
+
icon ? /* @__PURE__ */ jsx125("span", { className: "mt-0.5 shrink-0 text-primary", children: /* @__PURE__ */ jsx125(Icon, { name: icon, size: "sm" }) }) : null,
|
|
8910
|
+
/* @__PURE__ */ jsxs88("span", { className: "min-w-0", children: [
|
|
8911
|
+
/* @__PURE__ */ jsx125("span", { "data-slot": "prompt-title", className: "block text-sm font-medium", children: title }),
|
|
8912
|
+
description ? /* @__PURE__ */ jsx125("span", { "data-slot": "prompt-description", className: "mt-0.5 block text-xs text-muted-foreground", children: description }) : null
|
|
8213
8913
|
] })
|
|
8214
8914
|
]
|
|
8215
8915
|
}
|
|
@@ -8217,7 +8917,7 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
|
|
|
8217
8917
|
}
|
|
8218
8918
|
|
|
8219
8919
|
// src/components/chat/Welcome/index.tsx
|
|
8220
|
-
import { jsx as
|
|
8920
|
+
import { jsx as jsx126, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
8221
8921
|
function Welcome({
|
|
8222
8922
|
title = "\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F",
|
|
8223
8923
|
description,
|
|
@@ -8227,19 +8927,19 @@ function Welcome({
|
|
|
8227
8927
|
className,
|
|
8228
8928
|
style
|
|
8229
8929
|
}) {
|
|
8230
|
-
return /* @__PURE__ */
|
|
8930
|
+
return /* @__PURE__ */ jsxs89(
|
|
8231
8931
|
"div",
|
|
8232
8932
|
{
|
|
8233
8933
|
"data-slot": "welcome",
|
|
8234
8934
|
className: cn("flex w-full flex-col items-center gap-4 py-10 text-center", className),
|
|
8235
8935
|
style,
|
|
8236
8936
|
children: [
|
|
8237
|
-
/* @__PURE__ */
|
|
8238
|
-
/* @__PURE__ */
|
|
8239
|
-
/* @__PURE__ */
|
|
8240
|
-
description ? /* @__PURE__ */
|
|
8937
|
+
/* @__PURE__ */ jsx126("span", { "data-slot": "welcome-icon", className: "text-primary", children: /* @__PURE__ */ jsx126(Icon, { name: icon, size: "lg" }) }),
|
|
8938
|
+
/* @__PURE__ */ jsxs89("div", { children: [
|
|
8939
|
+
/* @__PURE__ */ jsx126("div", { "data-slot": "welcome-title", className: "text-xl font-semibold", children: title }),
|
|
8940
|
+
description ? /* @__PURE__ */ jsx126("div", { "data-slot": "welcome-description", className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
8241
8941
|
] }),
|
|
8242
|
-
prompts.length > 0 ? /* @__PURE__ */
|
|
8942
|
+
prompts.length > 0 ? /* @__PURE__ */ jsx126("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__ */ jsx126(
|
|
8243
8943
|
Prompt,
|
|
8244
8944
|
{
|
|
8245
8945
|
title: item.title,
|
|
@@ -8256,7 +8956,7 @@ function Welcome({
|
|
|
8256
8956
|
}
|
|
8257
8957
|
|
|
8258
8958
|
// src/components/chat/ChatPage/index.tsx
|
|
8259
|
-
import { jsx as
|
|
8959
|
+
import { jsx as jsx127, jsxs as jsxs90 } from "react/jsx-runtime";
|
|
8260
8960
|
function ChatPage({
|
|
8261
8961
|
brand,
|
|
8262
8962
|
menuItems = [],
|
|
@@ -8282,12 +8982,26 @@ function ChatPage({
|
|
|
8282
8982
|
defaultFooterSectionCollapsed = false,
|
|
8283
8983
|
onFooterSectionToggle,
|
|
8284
8984
|
conversationTitle,
|
|
8985
|
+
conversationHeaderAction,
|
|
8986
|
+
onConversationHeaderAction,
|
|
8285
8987
|
messages = [],
|
|
8286
8988
|
sending,
|
|
8287
8989
|
composerPlaceholder,
|
|
8288
8990
|
welcome,
|
|
8289
8991
|
onSend,
|
|
8290
8992
|
onMessageAction,
|
|
8993
|
+
models,
|
|
8994
|
+
model,
|
|
8995
|
+
onModelChange,
|
|
8996
|
+
contexts,
|
|
8997
|
+
contextItems,
|
|
8998
|
+
onContextItemsChange,
|
|
8999
|
+
attachments,
|
|
9000
|
+
onAttachFiles,
|
|
9001
|
+
onRemoveAttachment,
|
|
9002
|
+
onRetryAttachment,
|
|
9003
|
+
composerFooter,
|
|
9004
|
+
composerBottom,
|
|
8291
9005
|
artifactTitle = "\u4EA7\u7269",
|
|
8292
9006
|
artifacts = [],
|
|
8293
9007
|
activeArtifactId,
|
|
@@ -8298,20 +9012,22 @@ function ChatPage({
|
|
|
8298
9012
|
artifactViewers,
|
|
8299
9013
|
onDownloadArtifact,
|
|
8300
9014
|
artifactOpen,
|
|
8301
|
-
defaultArtifactOpen =
|
|
9015
|
+
defaultArtifactOpen = false,
|
|
8302
9016
|
onArtifactOpenChange,
|
|
8303
9017
|
className,
|
|
8304
9018
|
style
|
|
8305
9019
|
}) {
|
|
8306
9020
|
const controlled = artifactOpen !== void 0;
|
|
8307
|
-
const [innerOpen, setInnerOpen] =
|
|
9021
|
+
const [innerOpen, setInnerOpen] = useState44(defaultArtifactOpen);
|
|
8308
9022
|
const open = controlled ? artifactOpen === true : innerOpen;
|
|
8309
9023
|
const setOpen = (next) => {
|
|
8310
9024
|
if (!controlled) setInnerOpen(next);
|
|
8311
9025
|
onArtifactOpenChange?.(next);
|
|
8312
9026
|
};
|
|
9027
|
+
const { renderChildren } = useRenderer18();
|
|
9028
|
+
const renderSlot = (slot) => isValidElement2(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
8313
9029
|
const convCollControlled = conversationSectionCollapsed !== void 0;
|
|
8314
|
-
const [convCollapsedInner, setConvCollapsedInner] =
|
|
9030
|
+
const [convCollapsedInner, setConvCollapsedInner] = useState44(
|
|
8315
9031
|
defaultConversationSectionCollapsed
|
|
8316
9032
|
);
|
|
8317
9033
|
const convCollapsed = convCollControlled ? conversationSectionCollapsed === true : convCollapsedInner;
|
|
@@ -8321,7 +9037,7 @@ function ChatPage({
|
|
|
8321
9037
|
onConversationSectionToggle?.(next);
|
|
8322
9038
|
};
|
|
8323
9039
|
const footerCollControlled = footerSectionCollapsed !== void 0;
|
|
8324
|
-
const [footerCollapsedInner, setFooterCollapsedInner] =
|
|
9040
|
+
const [footerCollapsedInner, setFooterCollapsedInner] = useState44(
|
|
8325
9041
|
defaultFooterSectionCollapsed
|
|
8326
9042
|
);
|
|
8327
9043
|
const footerCollapsed = footerCollControlled ? footerSectionCollapsed === true : footerCollapsedInner;
|
|
@@ -8331,7 +9047,7 @@ function ChatPage({
|
|
|
8331
9047
|
onFooterSectionToggle?.(next);
|
|
8332
9048
|
};
|
|
8333
9049
|
const railVisible = railItems.length > 0 || railFooterItems.length > 0;
|
|
8334
|
-
const railButton = (item) => /* @__PURE__ */
|
|
9050
|
+
const railButton = (item) => /* @__PURE__ */ jsx127(Tooltip2, { content: item.label, side: "right", children: /* @__PURE__ */ jsx127(
|
|
8335
9051
|
Button2,
|
|
8336
9052
|
{
|
|
8337
9053
|
icon: item.icon,
|
|
@@ -8339,17 +9055,25 @@ function ChatPage({
|
|
|
8339
9055
|
onClick: () => onMenuSelect?.(item.key)
|
|
8340
9056
|
}
|
|
8341
9057
|
) }, item.key);
|
|
8342
|
-
const chatArea = /* @__PURE__ */
|
|
8343
|
-
/* @__PURE__ */
|
|
9058
|
+
const chatArea = /* @__PURE__ */ jsxs90("div", { "data-slot": "chat-page-conversation", className: "flex h-full min-w-0 flex-1 flex-col", children: [
|
|
9059
|
+
/* @__PURE__ */ jsxs90(
|
|
8344
9060
|
"div",
|
|
8345
9061
|
{
|
|
8346
9062
|
className: "flex shrink-0 items-center justify-between border-b border-border px-4 py-2.5",
|
|
8347
9063
|
children: [
|
|
8348
|
-
/* @__PURE__ */
|
|
8349
|
-
/* @__PURE__ */
|
|
9064
|
+
/* @__PURE__ */ jsx127(Text, { text: conversationTitle, strong: true }),
|
|
9065
|
+
conversationHeaderAction ? /* @__PURE__ */ jsx127(Tooltip2, { content: conversationHeaderAction.tooltip ?? conversationHeaderAction.label, side: "bottom", children: /* @__PURE__ */ jsx127(
|
|
8350
9066
|
Button2,
|
|
8351
9067
|
{
|
|
8352
|
-
|
|
9068
|
+
text: conversationHeaderAction.label,
|
|
9069
|
+
icon: conversationHeaderAction.icon,
|
|
9070
|
+
variant: "text",
|
|
9071
|
+
onClick: () => onConversationHeaderAction?.()
|
|
9072
|
+
}
|
|
9073
|
+
) }) : /* @__PURE__ */ jsx127(Tooltip2, { content: open ? "\u6536\u8D77\u4EA7\u7269\u533A" : artifactTitle, side: "bottom", children: /* @__PURE__ */ jsx127(
|
|
9074
|
+
Button2,
|
|
9075
|
+
{
|
|
9076
|
+
icon: open ? "panel-right-close" : "panel-right-open",
|
|
8353
9077
|
variant: "text",
|
|
8354
9078
|
onClick: () => setOpen(!open)
|
|
8355
9079
|
}
|
|
@@ -8357,40 +9081,63 @@ function ChatPage({
|
|
|
8357
9081
|
]
|
|
8358
9082
|
}
|
|
8359
9083
|
),
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
{
|
|
8363
|
-
title: welcome?.title,
|
|
8364
|
-
description: welcome?.description,
|
|
8365
|
-
prompts: welcome?.prompts,
|
|
8366
|
-
style: { flex: 1 },
|
|
8367
|
-
onSelect: (value) => onSend?.(value)
|
|
8368
|
-
}
|
|
8369
|
-
) : /* @__PURE__ */ jsx126(
|
|
8370
|
-
MessageList,
|
|
8371
|
-
{
|
|
8372
|
-
messages,
|
|
8373
|
-
style: { flex: 1, minHeight: 0, padding: 16 },
|
|
8374
|
-
onAction: onMessageAction
|
|
8375
|
-
}
|
|
8376
|
-
),
|
|
8377
|
-
/* @__PURE__ */ jsx126(
|
|
8378
|
-
Composer,
|
|
9084
|
+
/* @__PURE__ */ jsxs90(
|
|
9085
|
+
"div",
|
|
8379
9086
|
{
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
9087
|
+
"data-slot": "chat-page-conversation-body",
|
|
9088
|
+
className: "mx-auto flex min-h-0 w-[61.8cqw] max-w-full flex-1 flex-col",
|
|
9089
|
+
children: [
|
|
9090
|
+
messages.length === 0 ? /* @__PURE__ */ jsx127(
|
|
9091
|
+
Welcome,
|
|
9092
|
+
{
|
|
9093
|
+
title: welcome?.title,
|
|
9094
|
+
description: welcome?.description,
|
|
9095
|
+
prompts: welcome?.prompts,
|
|
9096
|
+
style: { flex: 1 },
|
|
9097
|
+
onSelect: (value) => onSend?.(value)
|
|
9098
|
+
}
|
|
9099
|
+
) : /* @__PURE__ */ jsx127(
|
|
9100
|
+
MessageList,
|
|
9101
|
+
{
|
|
9102
|
+
messages,
|
|
9103
|
+
className: "scrollbar-subtle",
|
|
9104
|
+
style: { flex: 1, minHeight: 0, padding: 16 },
|
|
9105
|
+
onAction: onMessageAction,
|
|
9106
|
+
onOpenArtifacts: () => setOpen(true)
|
|
9107
|
+
}
|
|
9108
|
+
),
|
|
9109
|
+
/* @__PURE__ */ jsx127(
|
|
9110
|
+
Composer,
|
|
9111
|
+
{
|
|
9112
|
+
placeholder: composerPlaceholder,
|
|
9113
|
+
loading: sending,
|
|
9114
|
+
models,
|
|
9115
|
+
model,
|
|
9116
|
+
contexts,
|
|
9117
|
+
contextItems,
|
|
9118
|
+
attachments,
|
|
9119
|
+
footer: composerFooter,
|
|
9120
|
+
style: { padding: 16, paddingBottom: composerBottom ? 8 : 16, flexShrink: 0 },
|
|
9121
|
+
onModelChange,
|
|
9122
|
+
onContextItemsChange,
|
|
9123
|
+
onAttachFiles,
|
|
9124
|
+
onRemoveAttachment,
|
|
9125
|
+
onRetryAttachment,
|
|
9126
|
+
onSubmit: (text) => onSend?.(text)
|
|
9127
|
+
}
|
|
9128
|
+
),
|
|
9129
|
+
composerBottom ? /* @__PURE__ */ jsx127("div", { "data-slot": "chat-page-composer-bottom", className: "shrink-0 px-4 pb-2 text-center", children: renderSlot(composerBottom) }) : null
|
|
9130
|
+
]
|
|
8384
9131
|
}
|
|
8385
9132
|
)
|
|
8386
9133
|
] });
|
|
8387
9134
|
const activeArtifact = artifacts.find((item) => item.id === activeArtifactId) ?? (activeArtifactId === void 0 || activeArtifactId === "" ? artifacts[artifacts.length - 1] : void 0);
|
|
8388
|
-
const artifactPanel = /* @__PURE__ */
|
|
9135
|
+
const artifactPanel = /* @__PURE__ */ jsx127(
|
|
8389
9136
|
"div",
|
|
8390
9137
|
{
|
|
8391
9138
|
"data-slot": "chat-page-artifact",
|
|
8392
9139
|
className: "flex h-full min-w-0 flex-col border-l border-border bg-muted",
|
|
8393
|
-
children: /* @__PURE__ */
|
|
9140
|
+
children: /* @__PURE__ */ jsx127(
|
|
8394
9141
|
ArtifactPanel,
|
|
8395
9142
|
{
|
|
8396
9143
|
artifact: activeArtifact,
|
|
@@ -8408,37 +9155,37 @@ function ChatPage({
|
|
|
8408
9155
|
)
|
|
8409
9156
|
}
|
|
8410
9157
|
);
|
|
8411
|
-
return /* @__PURE__ */
|
|
9158
|
+
return /* @__PURE__ */ jsxs90(
|
|
8412
9159
|
"div",
|
|
8413
9160
|
{
|
|
8414
9161
|
"data-slot": "chat-page",
|
|
8415
9162
|
className: cn("flex w-full overflow-hidden", className),
|
|
8416
9163
|
style: { height: "100vh", ...style },
|
|
8417
9164
|
children: [
|
|
8418
|
-
railVisible ? /* @__PURE__ */
|
|
9165
|
+
railVisible ? /* @__PURE__ */ jsxs90(
|
|
8419
9166
|
"div",
|
|
8420
9167
|
{
|
|
8421
9168
|
"data-slot": "chat-page-rail",
|
|
8422
9169
|
className: "flex h-full w-[52px] shrink-0 flex-col items-center gap-1 border-r border-border py-2.5",
|
|
8423
9170
|
children: [
|
|
8424
9171
|
railItems.map(railButton),
|
|
8425
|
-
/* @__PURE__ */
|
|
9172
|
+
/* @__PURE__ */ jsx127("div", { className: "flex-1" }),
|
|
8426
9173
|
railFooterItems.map(railButton)
|
|
8427
9174
|
]
|
|
8428
9175
|
}
|
|
8429
9176
|
) : null,
|
|
8430
|
-
/* @__PURE__ */
|
|
9177
|
+
/* @__PURE__ */ jsxs90(
|
|
8431
9178
|
"div",
|
|
8432
9179
|
{
|
|
8433
9180
|
"data-slot": "chat-page-menu",
|
|
8434
|
-
className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-
|
|
9181
|
+
className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-hidden border-r border-border px-2 py-3",
|
|
8435
9182
|
children: [
|
|
8436
|
-
brand ? /* @__PURE__ */
|
|
8437
|
-
/* @__PURE__ */
|
|
8438
|
-
/* @__PURE__ */
|
|
8439
|
-
brand.version !== void 0 ? /* @__PURE__ */
|
|
9183
|
+
brand ? /* @__PURE__ */ jsxs90("div", { className: "flex shrink-0 items-center justify-between px-2", children: [
|
|
9184
|
+
/* @__PURE__ */ jsxs90("div", { className: "flex flex-col gap-0.5", children: [
|
|
9185
|
+
/* @__PURE__ */ jsx127(Text, { text: brand.title, strong: true, size: "large" }),
|
|
9186
|
+
brand.version !== void 0 ? /* @__PURE__ */ jsx127(Text, { text: brand.version, type: "secondary", size: "small" }) : null
|
|
8440
9187
|
] }),
|
|
8441
|
-
menuAction ? /* @__PURE__ */
|
|
9188
|
+
menuAction ? /* @__PURE__ */ jsx127(
|
|
8442
9189
|
Button2,
|
|
8443
9190
|
{
|
|
8444
9191
|
text: menuAction.label,
|
|
@@ -8448,24 +9195,24 @@ function ChatPage({
|
|
|
8448
9195
|
}
|
|
8449
9196
|
) : null
|
|
8450
9197
|
] }) : null,
|
|
8451
|
-
/* @__PURE__ */
|
|
9198
|
+
/* @__PURE__ */ jsx127("div", { className: "scrollbar-subtle max-h-[40%] min-h-0 shrink-0 overflow-y-auto", children: /* @__PURE__ */ jsx127(
|
|
8452
9199
|
Menu,
|
|
8453
9200
|
{
|
|
8454
9201
|
items: menuItems,
|
|
8455
9202
|
selectedKey: activeMenuKey,
|
|
8456
9203
|
onSelect: (key) => onMenuSelect?.(key)
|
|
8457
9204
|
}
|
|
8458
|
-
),
|
|
8459
|
-
conversationSectionTitle !== void 0 ? /* @__PURE__ */
|
|
9205
|
+
) }),
|
|
9206
|
+
conversationSectionTitle !== void 0 ? /* @__PURE__ */ jsxs90(
|
|
8460
9207
|
"button",
|
|
8461
9208
|
{
|
|
8462
9209
|
type: "button",
|
|
8463
9210
|
"data-slot": "chat-page-section-toggle",
|
|
8464
9211
|
"aria-expanded": !convCollapsed,
|
|
8465
|
-
className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
|
|
9212
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
|
|
8466
9213
|
onClick: toggleConvSection,
|
|
8467
9214
|
children: [
|
|
8468
|
-
/* @__PURE__ */
|
|
9215
|
+
/* @__PURE__ */ jsx127(
|
|
8469
9216
|
Text,
|
|
8470
9217
|
{
|
|
8471
9218
|
text: `${conversationSectionTitle} (${conversations.length})`,
|
|
@@ -8474,48 +9221,50 @@ function ChatPage({
|
|
|
8474
9221
|
strong: true
|
|
8475
9222
|
}
|
|
8476
9223
|
),
|
|
8477
|
-
/* @__PURE__ */
|
|
9224
|
+
/* @__PURE__ */ jsx127(Icon, { name: convCollapsed ? "chevron-right" : "chevron-down", size: 14 })
|
|
8478
9225
|
]
|
|
8479
9226
|
}
|
|
8480
9227
|
) : null,
|
|
8481
|
-
!convCollapsed ? /* @__PURE__ */
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
9228
|
+
!convCollapsed ? /* @__PURE__ */ jsxs90("div", { "data-slot": "chat-page-section-body", className: "scrollbar-subtle flex min-h-0 flex-1 flex-col overflow-y-auto", children: [
|
|
9229
|
+
/* @__PURE__ */ jsx127(
|
|
9230
|
+
ConversationList,
|
|
9231
|
+
{
|
|
9232
|
+
items: conversations,
|
|
9233
|
+
activeId: activeConversationId,
|
|
9234
|
+
onSelect: (id) => onSelectConversation?.(id),
|
|
9235
|
+
onDelete: (id) => onDeleteConversation?.(id)
|
|
9236
|
+
}
|
|
9237
|
+
),
|
|
9238
|
+
moreLabel !== void 0 ? /* @__PURE__ */ jsx127("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx127(Button2, { text: `${moreLabel} >>`, variant: "link", size: "small", onClick: () => onMore?.() }) }) : null
|
|
9239
|
+
] }) : null,
|
|
9240
|
+
footerSectionTitle !== void 0 ? /* @__PURE__ */ jsxs90(
|
|
8492
9241
|
"button",
|
|
8493
9242
|
{
|
|
8494
9243
|
type: "button",
|
|
8495
9244
|
"data-slot": "chat-page-section-toggle",
|
|
8496
9245
|
"aria-expanded": !footerCollapsed,
|
|
8497
|
-
className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
|
|
9246
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
|
|
8498
9247
|
onClick: toggleFooterSection,
|
|
8499
9248
|
children: [
|
|
8500
|
-
/* @__PURE__ */
|
|
8501
|
-
/* @__PURE__ */
|
|
9249
|
+
/* @__PURE__ */ jsx127(Text, { text: footerSectionTitle, type: "secondary", className: "text-sm", strong: true }),
|
|
9250
|
+
/* @__PURE__ */ jsx127(Icon, { name: footerCollapsed ? "chevron-right" : "chevron-down", size: 14 })
|
|
8502
9251
|
]
|
|
8503
9252
|
}
|
|
8504
9253
|
) : null,
|
|
8505
|
-
!footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */
|
|
9254
|
+
!footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */ jsx127("div", { "data-slot": "chat-page-section-body", className: "scrollbar-subtle min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx127(
|
|
8506
9255
|
Menu,
|
|
8507
9256
|
{
|
|
8508
9257
|
items: footerItems,
|
|
8509
9258
|
onSelect: (key) => onMenuSelect?.(key)
|
|
8510
9259
|
}
|
|
8511
|
-
) : null
|
|
9260
|
+
) }) : null
|
|
8512
9261
|
]
|
|
8513
9262
|
}
|
|
8514
9263
|
),
|
|
8515
|
-
/* @__PURE__ */
|
|
8516
|
-
/* @__PURE__ */
|
|
8517
|
-
/* @__PURE__ */
|
|
8518
|
-
/* @__PURE__ */
|
|
9264
|
+
/* @__PURE__ */ jsx127("div", { className: "@container h-full min-w-0 flex-1", children: open ? /* @__PURE__ */ jsxs90(PanelGroup, { orientation: "horizontal", style: { width: "100%", height: "100%" }, children: [
|
|
9265
|
+
/* @__PURE__ */ jsx127(Panel, { defaultSize: "62%", children: chatArea }),
|
|
9266
|
+
/* @__PURE__ */ jsx127(ResizableHandle, { withHandle: true }),
|
|
9267
|
+
/* @__PURE__ */ jsx127(Panel, { defaultSize: "38%", minSize: "380px", maxSize: "760px", children: artifactPanel })
|
|
8519
9268
|
] }) : chatArea })
|
|
8520
9269
|
]
|
|
8521
9270
|
}
|
|
@@ -8523,10 +9272,10 @@ function ChatPage({
|
|
|
8523
9272
|
}
|
|
8524
9273
|
|
|
8525
9274
|
// src/components/chat/Citation/index.tsx
|
|
8526
|
-
import { jsx as
|
|
9275
|
+
import { jsx as jsx128, jsxs as jsxs91 } from "react/jsx-runtime";
|
|
8527
9276
|
function Citation({ items = [], start = 1, className, style }) {
|
|
8528
|
-
return /* @__PURE__ */
|
|
8529
|
-
/* @__PURE__ */
|
|
9277
|
+
return /* @__PURE__ */ jsx128("span", { "data-slot": "citation", className: cn("inline-flex gap-1 align-super", className), style, children: items.map((item, index) => /* @__PURE__ */ jsxs91(HoverCard, { children: [
|
|
9278
|
+
/* @__PURE__ */ jsxs91(
|
|
8530
9279
|
HoverCardTrigger,
|
|
8531
9280
|
{
|
|
8532
9281
|
"data-slot": "citation-marker",
|
|
@@ -8538,10 +9287,10 @@ function Citation({ items = [], start = 1, className, style }) {
|
|
|
8538
9287
|
]
|
|
8539
9288
|
}
|
|
8540
9289
|
),
|
|
8541
|
-
/* @__PURE__ */
|
|
8542
|
-
/* @__PURE__ */
|
|
8543
|
-
item.snippet ? /* @__PURE__ */
|
|
8544
|
-
item.url ? /* @__PURE__ */
|
|
9290
|
+
/* @__PURE__ */ jsxs91(HoverCardContent, { "data-slot": "citation-card", className: "w-72", children: [
|
|
9291
|
+
/* @__PURE__ */ jsx128("div", { className: "text-sm font-medium", children: item.title }),
|
|
9292
|
+
item.snippet ? /* @__PURE__ */ jsx128("div", { className: "mt-1 line-clamp-3 text-xs text-muted-foreground", children: item.snippet }) : null,
|
|
9293
|
+
item.url ? /* @__PURE__ */ jsx128(
|
|
8545
9294
|
"a",
|
|
8546
9295
|
{
|
|
8547
9296
|
href: item.url,
|
|
@@ -8556,13 +9305,13 @@ function Citation({ items = [], start = 1, className, style }) {
|
|
|
8556
9305
|
}
|
|
8557
9306
|
|
|
8558
9307
|
// src/components/chat/Suggestion/index.tsx
|
|
8559
|
-
import { jsx as
|
|
9308
|
+
import { jsx as jsx129, jsxs as jsxs92 } from "react/jsx-runtime";
|
|
8560
9309
|
function normalize(item) {
|
|
8561
9310
|
if (typeof item === "string") return { label: item, value: item };
|
|
8562
9311
|
return { label: item.label, value: item.value ?? item.label, icon: item.icon };
|
|
8563
9312
|
}
|
|
8564
9313
|
function Suggestion({ items = [], justify = "start", onSelect, className, style }) {
|
|
8565
|
-
return /* @__PURE__ */
|
|
9314
|
+
return /* @__PURE__ */ jsx129(
|
|
8566
9315
|
"div",
|
|
8567
9316
|
{
|
|
8568
9317
|
"data-slot": "suggestion",
|
|
@@ -8570,7 +9319,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
8570
9319
|
style,
|
|
8571
9320
|
children: items.map((item, index) => {
|
|
8572
9321
|
const { label, value, icon } = normalize(item);
|
|
8573
|
-
return /* @__PURE__ */
|
|
9322
|
+
return /* @__PURE__ */ jsxs92(
|
|
8574
9323
|
"button",
|
|
8575
9324
|
{
|
|
8576
9325
|
type: "button",
|
|
@@ -8579,7 +9328,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
8579
9328
|
className: "flex items-center gap-1.5 rounded-full border border-border px-3 py-1 text-sm transition-colors hover:bg-accent",
|
|
8580
9329
|
onClick: () => onSelect?.(value),
|
|
8581
9330
|
children: [
|
|
8582
|
-
icon ? /* @__PURE__ */
|
|
9331
|
+
icon ? /* @__PURE__ */ jsx129(Icon, { name: icon, size: "sm" }) : null,
|
|
8583
9332
|
label
|
|
8584
9333
|
]
|
|
8585
9334
|
},
|
|
@@ -8591,7 +9340,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
8591
9340
|
}
|
|
8592
9341
|
|
|
8593
9342
|
// src/components/chart/EChartBase/index.tsx
|
|
8594
|
-
import { useEffect as
|
|
9343
|
+
import { useEffect as useEffect36, useRef as useRef11, useState as useState45 } from "react";
|
|
8595
9344
|
|
|
8596
9345
|
// src/components/chart/echarts-modules.ts
|
|
8597
9346
|
import * as echarts from "echarts/core";
|
|
@@ -8643,7 +9392,7 @@ echarts.use([
|
|
|
8643
9392
|
]);
|
|
8644
9393
|
|
|
8645
9394
|
// src/components/chart/EChartBase/index.tsx
|
|
8646
|
-
import { jsx as
|
|
9395
|
+
import { jsx as jsx130 } from "react/jsx-runtime";
|
|
8647
9396
|
function EChartBase({
|
|
8648
9397
|
option,
|
|
8649
9398
|
height = 256,
|
|
@@ -8652,12 +9401,12 @@ function EChartBase({
|
|
|
8652
9401
|
style,
|
|
8653
9402
|
slot
|
|
8654
9403
|
}) {
|
|
8655
|
-
const hostRef =
|
|
8656
|
-
const chartRef =
|
|
8657
|
-
const onSelectRef =
|
|
9404
|
+
const hostRef = useRef11(null);
|
|
9405
|
+
const chartRef = useRef11(null);
|
|
9406
|
+
const onSelectRef = useRef11(onSelect);
|
|
8658
9407
|
onSelectRef.current = onSelect;
|
|
8659
|
-
const [failed, setFailed] =
|
|
8660
|
-
|
|
9408
|
+
const [failed, setFailed] = useState45(false);
|
|
9409
|
+
useEffect36(() => {
|
|
8661
9410
|
const host = hostRef.current;
|
|
8662
9411
|
if (!host) return;
|
|
8663
9412
|
let chart = null;
|
|
@@ -8676,22 +9425,22 @@ function EChartBase({
|
|
|
8676
9425
|
dataIndex: params.dataIndex
|
|
8677
9426
|
});
|
|
8678
9427
|
});
|
|
8679
|
-
const
|
|
8680
|
-
|
|
9428
|
+
const observer2 = new ResizeObserver(() => chart?.resize());
|
|
9429
|
+
observer2.observe(host);
|
|
8681
9430
|
return () => {
|
|
8682
|
-
|
|
9431
|
+
observer2.disconnect();
|
|
8683
9432
|
chart?.dispose();
|
|
8684
9433
|
chartRef.current = null;
|
|
8685
9434
|
};
|
|
8686
9435
|
}, []);
|
|
8687
|
-
|
|
9436
|
+
useEffect36(() => {
|
|
8688
9437
|
try {
|
|
8689
9438
|
chartRef.current?.setOption(option, { notMerge: true });
|
|
8690
9439
|
} catch {
|
|
8691
9440
|
}
|
|
8692
9441
|
}, [option]);
|
|
8693
9442
|
if (failed) {
|
|
8694
|
-
return /* @__PURE__ */
|
|
9443
|
+
return /* @__PURE__ */ jsx130(
|
|
8695
9444
|
"div",
|
|
8696
9445
|
{
|
|
8697
9446
|
"data-slot": "chart-fallback",
|
|
@@ -8704,7 +9453,7 @@ function EChartBase({
|
|
|
8704
9453
|
}
|
|
8705
9454
|
);
|
|
8706
9455
|
}
|
|
8707
|
-
return /* @__PURE__ */
|
|
9456
|
+
return /* @__PURE__ */ jsx130(
|
|
8708
9457
|
"div",
|
|
8709
9458
|
{
|
|
8710
9459
|
ref: hostRef,
|
|
@@ -9140,6 +9889,9 @@ function buildComposedOption(input, theme) {
|
|
|
9140
9889
|
};
|
|
9141
9890
|
}
|
|
9142
9891
|
|
|
9892
|
+
// src/components/chart/lib/use-chart-theme.ts
|
|
9893
|
+
import { useSyncExternalStore } from "react";
|
|
9894
|
+
|
|
9143
9895
|
// src/components/chart/lib/color.ts
|
|
9144
9896
|
var LPAREN = String.fromCharCode(40);
|
|
9145
9897
|
var RPAREN = String.fromCharCode(41);
|
|
@@ -9236,9 +9988,67 @@ function getChartTheme() {
|
|
|
9236
9988
|
return FALLBACK_THEME;
|
|
9237
9989
|
}
|
|
9238
9990
|
}
|
|
9991
|
+
function resetChartTheme() {
|
|
9992
|
+
cached = null;
|
|
9993
|
+
}
|
|
9994
|
+
var CHART_SKIN_CHANGE_EVENT = "pactor:skin-change";
|
|
9995
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
9996
|
+
var observer = null;
|
|
9997
|
+
var scheduled = false;
|
|
9998
|
+
function scheduleNotify() {
|
|
9999
|
+
if (scheduled) return;
|
|
10000
|
+
scheduled = true;
|
|
10001
|
+
const enqueue = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
10002
|
+
enqueue(() => {
|
|
10003
|
+
scheduled = false;
|
|
10004
|
+
resetChartTheme();
|
|
10005
|
+
for (const listener of [...listeners]) {
|
|
10006
|
+
listener();
|
|
10007
|
+
}
|
|
10008
|
+
});
|
|
10009
|
+
}
|
|
10010
|
+
function handleResourceLoad(event) {
|
|
10011
|
+
const target = event.target;
|
|
10012
|
+
if (target instanceof HTMLLinkElement || target instanceof HTMLStyleElement) {
|
|
10013
|
+
scheduleNotify();
|
|
10014
|
+
}
|
|
10015
|
+
}
|
|
10016
|
+
function subscribeChartTheme(listener) {
|
|
10017
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") {
|
|
10018
|
+
return () => {
|
|
10019
|
+
};
|
|
10020
|
+
}
|
|
10021
|
+
listeners.add(listener);
|
|
10022
|
+
if (!observer) {
|
|
10023
|
+
observer = new MutationObserver(scheduleNotify);
|
|
10024
|
+
observer.observe(document.documentElement, { attributes: true });
|
|
10025
|
+
observer.observe(document.head, {
|
|
10026
|
+
attributes: true,
|
|
10027
|
+
childList: true,
|
|
10028
|
+
characterData: true,
|
|
10029
|
+
subtree: true
|
|
10030
|
+
});
|
|
10031
|
+
document.addEventListener("load", handleResourceLoad, true);
|
|
10032
|
+
window.addEventListener(CHART_SKIN_CHANGE_EVENT, scheduleNotify);
|
|
10033
|
+
}
|
|
10034
|
+
return () => {
|
|
10035
|
+
listeners.delete(listener);
|
|
10036
|
+
if (listeners.size === 0 && observer) {
|
|
10037
|
+
observer.disconnect();
|
|
10038
|
+
observer = null;
|
|
10039
|
+
document.removeEventListener("load", handleResourceLoad, true);
|
|
10040
|
+
window.removeEventListener(CHART_SKIN_CHANGE_EVENT, scheduleNotify);
|
|
10041
|
+
}
|
|
10042
|
+
};
|
|
10043
|
+
}
|
|
10044
|
+
|
|
10045
|
+
// src/components/chart/lib/use-chart-theme.ts
|
|
10046
|
+
function useChartTheme() {
|
|
10047
|
+
return useSyncExternalStore(subscribeChartTheme, getChartTheme, getChartTheme);
|
|
10048
|
+
}
|
|
9239
10049
|
|
|
9240
10050
|
// src/components/chart/AreaChart/index.tsx
|
|
9241
|
-
import { jsx as
|
|
10051
|
+
import { jsx as jsx131 } from "react/jsx-runtime";
|
|
9242
10052
|
function AreaChart({
|
|
9243
10053
|
data = [],
|
|
9244
10054
|
xKey,
|
|
@@ -9254,9 +10064,9 @@ function AreaChart({
|
|
|
9254
10064
|
}) {
|
|
9255
10065
|
const option = buildAreaOption(
|
|
9256
10066
|
{ data, xKey, yKeys, stacked, fillOpacity, colors, title },
|
|
9257
|
-
|
|
10067
|
+
useChartTheme()
|
|
9258
10068
|
);
|
|
9259
|
-
return /* @__PURE__ */
|
|
10069
|
+
return /* @__PURE__ */ jsx131(
|
|
9260
10070
|
EChartBase,
|
|
9261
10071
|
{
|
|
9262
10072
|
slot: "area-chart",
|
|
@@ -9270,7 +10080,7 @@ function AreaChart({
|
|
|
9270
10080
|
}
|
|
9271
10081
|
|
|
9272
10082
|
// src/components/chart/BarChart/index.tsx
|
|
9273
|
-
import { jsx as
|
|
10083
|
+
import { jsx as jsx132 } from "react/jsx-runtime";
|
|
9274
10084
|
function BarChart2({
|
|
9275
10085
|
data = [],
|
|
9276
10086
|
yKey,
|
|
@@ -9285,9 +10095,9 @@ function BarChart2({
|
|
|
9285
10095
|
}) {
|
|
9286
10096
|
const option = buildBarOption(
|
|
9287
10097
|
{ data, yKey, yKeys: xKeys, stacked, colors, title },
|
|
9288
|
-
|
|
10098
|
+
useChartTheme()
|
|
9289
10099
|
);
|
|
9290
|
-
return /* @__PURE__ */
|
|
10100
|
+
return /* @__PURE__ */ jsx132(
|
|
9291
10101
|
EChartBase,
|
|
9292
10102
|
{
|
|
9293
10103
|
slot: "bar-chart",
|
|
@@ -9301,7 +10111,7 @@ function BarChart2({
|
|
|
9301
10111
|
}
|
|
9302
10112
|
|
|
9303
10113
|
// src/components/chart/BubbleChart/index.tsx
|
|
9304
|
-
import { jsx as
|
|
10114
|
+
import { jsx as jsx133 } from "react/jsx-runtime";
|
|
9305
10115
|
function BubbleChart({
|
|
9306
10116
|
data = [],
|
|
9307
10117
|
xKey,
|
|
@@ -9317,9 +10127,9 @@ function BubbleChart({
|
|
|
9317
10127
|
}) {
|
|
9318
10128
|
const option = buildBubbleOption(
|
|
9319
10129
|
{ data, xKey, yKey, sizeKey, seriesKey, colors, title },
|
|
9320
|
-
|
|
10130
|
+
useChartTheme()
|
|
9321
10131
|
);
|
|
9322
|
-
return /* @__PURE__ */
|
|
10132
|
+
return /* @__PURE__ */ jsx133(
|
|
9323
10133
|
EChartBase,
|
|
9324
10134
|
{
|
|
9325
10135
|
slot: "bubble-chart",
|
|
@@ -9333,7 +10143,7 @@ function BubbleChart({
|
|
|
9333
10143
|
}
|
|
9334
10144
|
|
|
9335
10145
|
// src/components/chart/ColumnChart/index.tsx
|
|
9336
|
-
import { jsx as
|
|
10146
|
+
import { jsx as jsx134 } from "react/jsx-runtime";
|
|
9337
10147
|
function ColumnChart({
|
|
9338
10148
|
data = [],
|
|
9339
10149
|
xKey,
|
|
@@ -9348,9 +10158,9 @@ function ColumnChart({
|
|
|
9348
10158
|
}) {
|
|
9349
10159
|
const option = buildColumnOption(
|
|
9350
10160
|
{ data, xKey, yKeys, stacked, colors, title },
|
|
9351
|
-
|
|
10161
|
+
useChartTheme()
|
|
9352
10162
|
);
|
|
9353
|
-
return /* @__PURE__ */
|
|
10163
|
+
return /* @__PURE__ */ jsx134(
|
|
9354
10164
|
EChartBase,
|
|
9355
10165
|
{
|
|
9356
10166
|
slot: "column-chart",
|
|
@@ -9364,7 +10174,7 @@ function ColumnChart({
|
|
|
9364
10174
|
}
|
|
9365
10175
|
|
|
9366
10176
|
// src/components/chart/ComposedChart/index.tsx
|
|
9367
|
-
import { jsx as
|
|
10177
|
+
import { jsx as jsx135 } from "react/jsx-runtime";
|
|
9368
10178
|
function ComposedChart({
|
|
9369
10179
|
data = [],
|
|
9370
10180
|
xKey,
|
|
@@ -9378,9 +10188,9 @@ function ComposedChart({
|
|
|
9378
10188
|
}) {
|
|
9379
10189
|
const option = buildComposedOption(
|
|
9380
10190
|
{ data, xKey, series, colors, title },
|
|
9381
|
-
|
|
10191
|
+
useChartTheme()
|
|
9382
10192
|
);
|
|
9383
|
-
return /* @__PURE__ */
|
|
10193
|
+
return /* @__PURE__ */ jsx135(
|
|
9384
10194
|
EChartBase,
|
|
9385
10195
|
{
|
|
9386
10196
|
slot: "composed-chart",
|
|
@@ -9394,7 +10204,7 @@ function ComposedChart({
|
|
|
9394
10204
|
}
|
|
9395
10205
|
|
|
9396
10206
|
// src/components/chart/DonutChart/index.tsx
|
|
9397
|
-
import { jsx as
|
|
10207
|
+
import { jsx as jsx136 } from "react/jsx-runtime";
|
|
9398
10208
|
function DonutChart({
|
|
9399
10209
|
data = [],
|
|
9400
10210
|
nameKey,
|
|
@@ -9424,9 +10234,9 @@ function DonutChart({
|
|
|
9424
10234
|
colors,
|
|
9425
10235
|
title
|
|
9426
10236
|
},
|
|
9427
|
-
|
|
10237
|
+
useChartTheme()
|
|
9428
10238
|
);
|
|
9429
|
-
return /* @__PURE__ */
|
|
10239
|
+
return /* @__PURE__ */ jsx136(
|
|
9430
10240
|
EChartBase,
|
|
9431
10241
|
{
|
|
9432
10242
|
slot: "donut-chart",
|
|
@@ -9440,7 +10250,7 @@ function DonutChart({
|
|
|
9440
10250
|
}
|
|
9441
10251
|
|
|
9442
10252
|
// src/components/chart/FunnelChart/index.tsx
|
|
9443
|
-
import { jsx as
|
|
10253
|
+
import { jsx as jsx137 } from "react/jsx-runtime";
|
|
9444
10254
|
function FunnelChart2({
|
|
9445
10255
|
data = [],
|
|
9446
10256
|
nameKey,
|
|
@@ -9455,9 +10265,9 @@ function FunnelChart2({
|
|
|
9455
10265
|
}) {
|
|
9456
10266
|
const option = buildFunnelOption(
|
|
9457
10267
|
{ data, nameKey, valueKey, sort, colors, title },
|
|
9458
|
-
|
|
10268
|
+
useChartTheme()
|
|
9459
10269
|
);
|
|
9460
|
-
return /* @__PURE__ */
|
|
10270
|
+
return /* @__PURE__ */ jsx137(
|
|
9461
10271
|
EChartBase,
|
|
9462
10272
|
{
|
|
9463
10273
|
slot: "funnel-chart",
|
|
@@ -9471,7 +10281,7 @@ function FunnelChart2({
|
|
|
9471
10281
|
}
|
|
9472
10282
|
|
|
9473
10283
|
// src/components/chart/GaugeChart/index.tsx
|
|
9474
|
-
import { jsx as
|
|
10284
|
+
import { jsx as jsx138 } from "react/jsx-runtime";
|
|
9475
10285
|
function GaugeChart2({
|
|
9476
10286
|
value = 0,
|
|
9477
10287
|
min,
|
|
@@ -9486,9 +10296,9 @@ function GaugeChart2({
|
|
|
9486
10296
|
}) {
|
|
9487
10297
|
const option = buildGaugeOption(
|
|
9488
10298
|
{ value, min, max, thresholds, unit, title },
|
|
9489
|
-
|
|
10299
|
+
useChartTheme()
|
|
9490
10300
|
);
|
|
9491
|
-
return /* @__PURE__ */
|
|
10301
|
+
return /* @__PURE__ */ jsx138(
|
|
9492
10302
|
EChartBase,
|
|
9493
10303
|
{
|
|
9494
10304
|
slot: "gauge-chart",
|
|
@@ -9502,7 +10312,7 @@ function GaugeChart2({
|
|
|
9502
10312
|
}
|
|
9503
10313
|
|
|
9504
10314
|
// src/components/chart/Heatmap/index.tsx
|
|
9505
|
-
import { jsx as
|
|
10315
|
+
import { jsx as jsx139 } from "react/jsx-runtime";
|
|
9506
10316
|
function Heatmap({
|
|
9507
10317
|
data = [],
|
|
9508
10318
|
xKey,
|
|
@@ -9516,9 +10326,9 @@ function Heatmap({
|
|
|
9516
10326
|
}) {
|
|
9517
10327
|
const option = buildHeatmapOption(
|
|
9518
10328
|
{ data, xKey, yKey, valueKey, title },
|
|
9519
|
-
|
|
10329
|
+
useChartTheme()
|
|
9520
10330
|
);
|
|
9521
|
-
return /* @__PURE__ */
|
|
10331
|
+
return /* @__PURE__ */ jsx139(
|
|
9522
10332
|
EChartBase,
|
|
9523
10333
|
{
|
|
9524
10334
|
slot: "heatmap",
|
|
@@ -9532,7 +10342,7 @@ function Heatmap({
|
|
|
9532
10342
|
}
|
|
9533
10343
|
|
|
9534
10344
|
// src/components/chart/LineChart/index.tsx
|
|
9535
|
-
import { jsx as
|
|
10345
|
+
import { jsx as jsx140 } from "react/jsx-runtime";
|
|
9536
10346
|
function LineChart2({
|
|
9537
10347
|
data = [],
|
|
9538
10348
|
xKey,
|
|
@@ -9549,9 +10359,9 @@ function LineChart2({
|
|
|
9549
10359
|
}) {
|
|
9550
10360
|
const option = buildLineOption(
|
|
9551
10361
|
{ data, xKey, yKeys, smooth, showArea, stacked, colors, title },
|
|
9552
|
-
|
|
10362
|
+
useChartTheme()
|
|
9553
10363
|
);
|
|
9554
|
-
return /* @__PURE__ */
|
|
10364
|
+
return /* @__PURE__ */ jsx140(
|
|
9555
10365
|
EChartBase,
|
|
9556
10366
|
{
|
|
9557
10367
|
slot: "line-chart",
|
|
@@ -9565,8 +10375,8 @@ function LineChart2({
|
|
|
9565
10375
|
}
|
|
9566
10376
|
|
|
9567
10377
|
// src/components/chart/MapChart/index.tsx
|
|
9568
|
-
import { useEffect as
|
|
9569
|
-
import { jsx as
|
|
10378
|
+
import { useEffect as useEffect37, useState as useState46 } from "react";
|
|
10379
|
+
import { jsx as jsx141 } from "react/jsx-runtime";
|
|
9570
10380
|
var fetchedMaps = /* @__PURE__ */ new Set();
|
|
9571
10381
|
function hasRegisteredMap(mapName) {
|
|
9572
10382
|
try {
|
|
@@ -9588,7 +10398,8 @@ function MapChart2({
|
|
|
9588
10398
|
className,
|
|
9589
10399
|
style
|
|
9590
10400
|
}) {
|
|
9591
|
-
const
|
|
10401
|
+
const theme = useChartTheme();
|
|
10402
|
+
const [loadState, setLoadState] = useState46(
|
|
9592
10403
|
() => geoJson || !geoJsonUrl || hasRegisteredMap(mapName) ? "idle" : "loading"
|
|
9593
10404
|
);
|
|
9594
10405
|
if (geoJson) {
|
|
@@ -9597,7 +10408,7 @@ function MapChart2({
|
|
|
9597
10408
|
} catch {
|
|
9598
10409
|
}
|
|
9599
10410
|
}
|
|
9600
|
-
|
|
10411
|
+
useEffect37(() => {
|
|
9601
10412
|
if (geoJson || !geoJsonUrl || hasRegisteredMap(mapName) || fetchedMaps.has(mapName)) {
|
|
9602
10413
|
setLoadState("idle");
|
|
9603
10414
|
return;
|
|
@@ -9622,7 +10433,7 @@ function MapChart2({
|
|
|
9622
10433
|
};
|
|
9623
10434
|
}, [geoJson, geoJsonUrl, mapName]);
|
|
9624
10435
|
if (geoJsonUrl && !geoJson && loadState === "loading") {
|
|
9625
|
-
return /* @__PURE__ */
|
|
10436
|
+
return /* @__PURE__ */ jsx141(
|
|
9626
10437
|
"div",
|
|
9627
10438
|
{
|
|
9628
10439
|
"data-slot": "map-chart-loading",
|
|
@@ -9632,7 +10443,7 @@ function MapChart2({
|
|
|
9632
10443
|
);
|
|
9633
10444
|
}
|
|
9634
10445
|
if (!geoJson && loadState === "error") {
|
|
9635
|
-
return /* @__PURE__ */
|
|
10446
|
+
return /* @__PURE__ */ jsx141(
|
|
9636
10447
|
Empty2,
|
|
9637
10448
|
{
|
|
9638
10449
|
title: "\u5730\u56FE\u52A0\u8F7D\u5931\u8D25",
|
|
@@ -9644,7 +10455,7 @@ function MapChart2({
|
|
|
9644
10455
|
}
|
|
9645
10456
|
if (!geoJson && !hasRegisteredMap(mapName)) {
|
|
9646
10457
|
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`);
|
|
9647
|
-
return /* @__PURE__ */
|
|
10458
|
+
return /* @__PURE__ */ jsx141(
|
|
9648
10459
|
Empty2,
|
|
9649
10460
|
{
|
|
9650
10461
|
title: "\u5730\u56FE\u672A\u6CE8\u518C",
|
|
@@ -9654,8 +10465,8 @@ function MapChart2({
|
|
|
9654
10465
|
}
|
|
9655
10466
|
);
|
|
9656
10467
|
}
|
|
9657
|
-
const option = buildMapOption({ mapName, data, nameKey, valueKey, title },
|
|
9658
|
-
return /* @__PURE__ */
|
|
10468
|
+
const option = buildMapOption({ mapName, data, nameKey, valueKey, title }, theme);
|
|
10469
|
+
return /* @__PURE__ */ jsx141(
|
|
9659
10470
|
EChartBase,
|
|
9660
10471
|
{
|
|
9661
10472
|
slot: "map-chart",
|
|
@@ -9670,7 +10481,7 @@ function MapChart2({
|
|
|
9670
10481
|
|
|
9671
10482
|
// src/components/chart/MetricCard/index.tsx
|
|
9672
10483
|
import { ArrowDownRight, ArrowUpRight } from "lucide-react";
|
|
9673
|
-
import { jsx as
|
|
10484
|
+
import { jsx as jsx142, jsxs as jsxs93 } from "react/jsx-runtime";
|
|
9674
10485
|
function MetricCard({
|
|
9675
10486
|
title,
|
|
9676
10487
|
value,
|
|
@@ -9683,15 +10494,15 @@ function MetricCard({
|
|
|
9683
10494
|
}) {
|
|
9684
10495
|
const showTrend = typeof trend === "number" && trend !== 0;
|
|
9685
10496
|
const rising = (trend ?? 0) > 0;
|
|
9686
|
-
return /* @__PURE__ */
|
|
10497
|
+
return /* @__PURE__ */ jsxs93(
|
|
9687
10498
|
"div",
|
|
9688
10499
|
{
|
|
9689
10500
|
"data-slot": "metric-card",
|
|
9690
10501
|
className: cn("rounded-lg border bg-card p-4 text-card-foreground shadow-sm", className),
|
|
9691
10502
|
style,
|
|
9692
10503
|
children: [
|
|
9693
|
-
title ? /* @__PURE__ */
|
|
9694
|
-
/* @__PURE__ */
|
|
10504
|
+
title ? /* @__PURE__ */ jsx142("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
|
|
10505
|
+
/* @__PURE__ */ jsxs93(
|
|
9695
10506
|
"div",
|
|
9696
10507
|
{
|
|
9697
10508
|
"data-slot": "metric-card-value",
|
|
@@ -9703,7 +10514,7 @@ function MetricCard({
|
|
|
9703
10514
|
]
|
|
9704
10515
|
}
|
|
9705
10516
|
),
|
|
9706
|
-
showTrend ? /* @__PURE__ */
|
|
10517
|
+
showTrend ? /* @__PURE__ */ jsxs93(
|
|
9707
10518
|
"div",
|
|
9708
10519
|
{
|
|
9709
10520
|
"data-slot": "metric-card-trend",
|
|
@@ -9713,10 +10524,10 @@ function MetricCard({
|
|
|
9713
10524
|
rising ? "text-success" : "text-destructive"
|
|
9714
10525
|
),
|
|
9715
10526
|
children: [
|
|
9716
|
-
rising ? /* @__PURE__ */
|
|
10527
|
+
rising ? /* @__PURE__ */ jsx142(ArrowUpRight, { className: "size-4" }) : /* @__PURE__ */ jsx142(ArrowDownRight, { className: "size-4" }),
|
|
9717
10528
|
Math.abs(trend ?? 0),
|
|
9718
10529
|
"%",
|
|
9719
|
-
trendLabel ? /* @__PURE__ */
|
|
10530
|
+
trendLabel ? /* @__PURE__ */ jsx142("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
|
|
9720
10531
|
]
|
|
9721
10532
|
}
|
|
9722
10533
|
) : null
|
|
@@ -9726,7 +10537,7 @@ function MetricCard({
|
|
|
9726
10537
|
}
|
|
9727
10538
|
|
|
9728
10539
|
// src/components/chart/PieChart/index.tsx
|
|
9729
|
-
import { jsx as
|
|
10540
|
+
import { jsx as jsx143 } from "react/jsx-runtime";
|
|
9730
10541
|
function PieChart2({
|
|
9731
10542
|
data = [],
|
|
9732
10543
|
nameKey,
|
|
@@ -9741,9 +10552,9 @@ function PieChart2({
|
|
|
9741
10552
|
}) {
|
|
9742
10553
|
const option = buildPieOption(
|
|
9743
10554
|
{ data, nameKey, valueKey, showLabel, colors, title },
|
|
9744
|
-
|
|
10555
|
+
useChartTheme()
|
|
9745
10556
|
);
|
|
9746
|
-
return /* @__PURE__ */
|
|
10557
|
+
return /* @__PURE__ */ jsx143(
|
|
9747
10558
|
EChartBase,
|
|
9748
10559
|
{
|
|
9749
10560
|
slot: "pie-chart",
|
|
@@ -9757,7 +10568,7 @@ function PieChart2({
|
|
|
9757
10568
|
}
|
|
9758
10569
|
|
|
9759
10570
|
// src/components/chart/RadarChart/index.tsx
|
|
9760
|
-
import { jsx as
|
|
10571
|
+
import { jsx as jsx144 } from "react/jsx-runtime";
|
|
9761
10572
|
function RadarChart2({
|
|
9762
10573
|
data = [],
|
|
9763
10574
|
indicatorKey,
|
|
@@ -9771,9 +10582,9 @@ function RadarChart2({
|
|
|
9771
10582
|
}) {
|
|
9772
10583
|
const option = buildRadarOption(
|
|
9773
10584
|
{ data, indicatorKey, yKeys, colors, title },
|
|
9774
|
-
|
|
10585
|
+
useChartTheme()
|
|
9775
10586
|
);
|
|
9776
|
-
return /* @__PURE__ */
|
|
10587
|
+
return /* @__PURE__ */ jsx144(
|
|
9777
10588
|
EChartBase,
|
|
9778
10589
|
{
|
|
9779
10590
|
slot: "radar-chart",
|
|
@@ -9787,7 +10598,7 @@ function RadarChart2({
|
|
|
9787
10598
|
}
|
|
9788
10599
|
|
|
9789
10600
|
// src/components/chart/SankeyChart/index.tsx
|
|
9790
|
-
import { jsx as
|
|
10601
|
+
import { jsx as jsx145 } from "react/jsx-runtime";
|
|
9791
10602
|
function SankeyChart2({
|
|
9792
10603
|
nodes = [],
|
|
9793
10604
|
links = [],
|
|
@@ -9797,8 +10608,8 @@ function SankeyChart2({
|
|
|
9797
10608
|
className,
|
|
9798
10609
|
style
|
|
9799
10610
|
}) {
|
|
9800
|
-
const option = buildSankeyOption({ nodes, links, title },
|
|
9801
|
-
return /* @__PURE__ */
|
|
10611
|
+
const option = buildSankeyOption({ nodes, links, title }, useChartTheme());
|
|
10612
|
+
return /* @__PURE__ */ jsx145(
|
|
9802
10613
|
EChartBase,
|
|
9803
10614
|
{
|
|
9804
10615
|
slot: "sankey-chart",
|
|
@@ -9812,7 +10623,7 @@ function SankeyChart2({
|
|
|
9812
10623
|
}
|
|
9813
10624
|
|
|
9814
10625
|
// src/components/chart/ScatterChart/index.tsx
|
|
9815
|
-
import { jsx as
|
|
10626
|
+
import { jsx as jsx146 } from "react/jsx-runtime";
|
|
9816
10627
|
function ScatterChart2({
|
|
9817
10628
|
data = [],
|
|
9818
10629
|
xKey,
|
|
@@ -9827,9 +10638,9 @@ function ScatterChart2({
|
|
|
9827
10638
|
}) {
|
|
9828
10639
|
const option = buildScatterOption(
|
|
9829
10640
|
{ data, xKey, yKey, seriesKey, colors, title },
|
|
9830
|
-
|
|
10641
|
+
useChartTheme()
|
|
9831
10642
|
);
|
|
9832
|
-
return /* @__PURE__ */
|
|
10643
|
+
return /* @__PURE__ */ jsx146(
|
|
9833
10644
|
EChartBase,
|
|
9834
10645
|
{
|
|
9835
10646
|
slot: "scatter-chart",
|
|
@@ -9843,7 +10654,7 @@ function ScatterChart2({
|
|
|
9843
10654
|
}
|
|
9844
10655
|
|
|
9845
10656
|
// src/components/chart/TreeChart/index.tsx
|
|
9846
|
-
import { jsx as
|
|
10657
|
+
import { jsx as jsx147 } from "react/jsx-runtime";
|
|
9847
10658
|
function TreeChart2({
|
|
9848
10659
|
data = [],
|
|
9849
10660
|
title,
|
|
@@ -9857,9 +10668,9 @@ function TreeChart2({
|
|
|
9857
10668
|
}) {
|
|
9858
10669
|
const option = buildTreeOption(
|
|
9859
10670
|
{ data, title, orient, edgeShape, initialTreeDepth },
|
|
9860
|
-
|
|
10671
|
+
useChartTheme()
|
|
9861
10672
|
);
|
|
9862
|
-
return /* @__PURE__ */
|
|
10673
|
+
return /* @__PURE__ */ jsx147(
|
|
9863
10674
|
EChartBase,
|
|
9864
10675
|
{
|
|
9865
10676
|
slot: "tree-chart",
|