@mcp-b/react-components 0.27.0 → 0.29.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/{AgentChat-B6sgfQ_q.d.ts → AgentChat-Dy3cKCd-.d.ts} +13 -5
- package/dist/{AgentChatStartScreen-DDZ25aax.d.ts → AgentChatStartScreen-DXZ0hAX0.d.ts} +23 -5
- package/dist/{PromptInput-CES0WO4u.d.ts → PromptInput-B75Np5VB.d.ts} +7 -1
- package/dist/SessionCompaction-DMa1vv6Y.d.ts +59 -0
- package/dist/{ThinkChat-DVhCEjq-.js → ThinkChat-Bp-nAnoW.js} +14 -2
- package/dist/{ThinkChatActivity-DawPYgga.d.ts → ThinkChatActivity-Dq0lOAgw.d.ts} +3 -3
- package/dist/{ThinkChatActivitySummary-kr5fE0wg.d.ts → ThinkChatActivitySummary-F062wneC.d.ts} +1 -1
- package/dist/{ThinkChatToolParts-CSzVwMXf.d.ts → ThinkChatToolParts-BfroXQ4F.d.ts} +19 -1
- package/dist/{Workspace-CIycQ4xE.d.ts → Workspace-Bn6In4wi.d.ts} +5 -1
- package/dist/{WorkspaceExplorer-BCipn7Vd.d.ts → WorkspaceExplorer-D0aiscG6.d.ts} +1 -1
- package/dist/components/ActionGuide.d.ts +23 -5
- package/dist/components/ActionGuide.js +18 -4
- package/dist/components/AgentChat.d.ts +1 -1
- package/dist/components/AgentChat.js +24 -11
- package/dist/components/AgentChatStartScreen.d.ts +2 -2
- package/dist/components/AgentChatStartScreen.js +16 -5
- package/dist/components/AgentConnection.d.ts +1 -1
- package/dist/components/AgentToolDetail.js +1 -1
- package/dist/components/ChatGptSignInScreen.d.ts +9 -1
- package/dist/components/ChatGptSignInScreen.js +15 -4
- package/dist/components/ConversationTabPicker.d.ts +31 -0
- package/dist/components/ConversationTabPicker.js +117 -0
- package/dist/components/Goal.d.ts +28 -1
- package/dist/components/Goal.js +76 -3
- package/dist/components/McpConnectionRequest.d.ts +11 -5
- package/dist/components/McpConnectionRequest.js +22 -16
- package/dist/components/McpPluginCatalog.d.ts +1 -1
- package/dist/components/McpServerPicker.d.ts +18 -3
- package/dist/components/McpServerPicker.js +38 -23
- package/dist/components/Plan.d.ts +18 -1
- package/dist/components/Plan.js +17 -1
- package/dist/components/PromptInput.d.ts +2 -2
- package/dist/components/PromptInput.js +43 -5
- package/dist/components/SessionCompaction.d.ts +1 -58
- package/dist/components/SettingsFormDialog.d.ts +43 -0
- package/dist/components/SettingsFormDialog.js +110 -0
- package/dist/components/ThinkChat.d.ts +13 -7
- package/dist/components/ThinkChat.js +3 -3
- package/dist/components/ThinkChatActivity.d.ts +3 -3
- package/dist/components/ThinkChatActivitySummary.d.ts +1 -1
- package/dist/components/ThinkChatToolPanels.d.ts +1 -1
- package/dist/components/ThinkChatToolPanels.js +1 -1
- package/dist/components/ThinkChatToolParts.d.ts +1 -1
- package/dist/components/ThinkFullApp.d.ts +6 -12
- package/dist/components/ThinkFullApp.js +4 -4
- package/dist/components/ThinkThreadPicker.d.ts +4 -1
- package/dist/components/ThinkThreadPicker.js +6 -1
- package/dist/components/Workspace.d.ts +2 -2
- package/dist/components/Workspace.js +10 -6
- package/dist/components/WorkspaceBrowser.d.ts +1 -1
- package/dist/components/WorkspaceExplorer.d.ts +3 -3
- package/dist/components/WorkspaceExplorer.js +2 -2
- package/dist/components/WorkspaceMountManager.d.ts +32 -0
- package/dist/components/WorkspaceMountManager.js +89 -0
- package/dist/{mcp-server-catalog-BewjV7Eq.d.ts → mcp-server-catalog-CO7GAl1f.d.ts} +1 -1
- package/dist/styles/chatgpt-sign-in-screen.css +10 -1
- package/dist/styles/conversation-tab-picker.css +24 -0
- package/dist/styles/index.css +2 -0
- package/dist/styles/workspace-mount-manager.css +24 -0
- package/dist/utils/mcp-server-catalog.d.ts +1 -1
- package/dist/utils/mcp-server-catalog.js +1 -1
- package/package.json +13 -13
|
@@ -6,7 +6,7 @@ import "react";
|
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/ChatGptSignInScreen.tsx
|
|
8
8
|
/** Full-screen ChatGPT authentication prompt for MCP-B onboarding. */
|
|
9
|
-
function ChatGptSignInScreen({ busy = false, error = false, label = "Sign in with ChatGPT", title = "Welcome to MCP-B", brandName = "SigVelo", brandLogo = /* @__PURE__ */ jsx(SigVeloMark, {}), className, onPointerLeave, onPointerMove, onSignIn, ref, ...props }) {
|
|
9
|
+
function ChatGptSignInScreen({ busy = false, error = false, label = "Sign in with ChatGPT", title = "Welcome to MCP-B", brandName = "SigVelo", brandLogo = /* @__PURE__ */ jsx(SigVeloMark, {}), className, onPointerLeave, onPointerMove, onSignIn, secondaryAction, ref, ...props }) {
|
|
10
10
|
const handlePointerMove = (event) => {
|
|
11
11
|
onPointerMove?.(event);
|
|
12
12
|
setPointerPosition(event.currentTarget, event, "chatgpt-sign-in-pointer");
|
|
@@ -16,14 +16,14 @@ function ChatGptSignInScreen({ busy = false, error = false, label = "Sign in wit
|
|
|
16
16
|
onPointerLeave?.(event);
|
|
17
17
|
delete event.currentTarget.dataset.pointerActive;
|
|
18
18
|
};
|
|
19
|
-
return /* @__PURE__ */
|
|
19
|
+
return /* @__PURE__ */ jsxs("main", {
|
|
20
20
|
ref,
|
|
21
21
|
className: cx("chatgpt-sign-in", className),
|
|
22
22
|
"aria-label": "ChatGPT authentication",
|
|
23
23
|
onPointerLeave: handlePointerLeave,
|
|
24
24
|
onPointerMove: handlePointerMove,
|
|
25
25
|
...props,
|
|
26
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
26
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
27
27
|
className: "chatgpt-sign-in__panel",
|
|
28
28
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
29
29
|
className: "chatgpt-sign-in__brand",
|
|
@@ -56,7 +56,18 @@ function ChatGptSignInScreen({ busy = false, error = false, label = "Sign in wit
|
|
|
56
56
|
children: label
|
|
57
57
|
})]
|
|
58
58
|
})]
|
|
59
|
-
})
|
|
59
|
+
}), secondaryAction ? /* @__PURE__ */ jsx("div", {
|
|
60
|
+
className: "chatgpt-sign-in__secondary-action",
|
|
61
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
62
|
+
type: "button",
|
|
63
|
+
variant: "ghost",
|
|
64
|
+
color: "neutral",
|
|
65
|
+
size: "xs",
|
|
66
|
+
disabled: secondaryAction.disabled,
|
|
67
|
+
onClick: secondaryAction.onSelect,
|
|
68
|
+
children: secondaryAction.label
|
|
69
|
+
})
|
|
70
|
+
}) : null]
|
|
60
71
|
});
|
|
61
72
|
}
|
|
62
73
|
function handleSignInButtonPointerMove(event) {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/components/ConversationTabPicker.d.ts
|
|
4
|
+
type ConversationTabId = string | number;
|
|
5
|
+
interface ConversationTabPickerItem {
|
|
6
|
+
id: ConversationTabId;
|
|
7
|
+
title?: string;
|
|
8
|
+
url?: string;
|
|
9
|
+
iconSrc?: string;
|
|
10
|
+
}
|
|
11
|
+
interface ConversationTabPickerProps {
|
|
12
|
+
/** Browser-enriched tabs already scoped to the current conversation. */
|
|
13
|
+
tabs: readonly ConversationTabPickerItem[];
|
|
14
|
+
/** Host-owned activation, such as Chrome tab/window focus. */
|
|
15
|
+
onSelect: (id: ConversationTabId) => void | Promise<void>;
|
|
16
|
+
/** Maximum avatars shown in the collapsed trigger. */
|
|
17
|
+
maxVisible?: number;
|
|
18
|
+
groupLabel?: React.ReactNode;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Shared tab-menu presentation over host-resolved browser data.
|
|
22
|
+
*
|
|
23
|
+
* The browser adapter owns tab lookup and activation. This component owns URL
|
|
24
|
+
* labels, favicon fallbacks, menu state, and async activation feedback.
|
|
25
|
+
*/
|
|
26
|
+
declare function ConversationTabPicker({
|
|
27
|
+
tabs,
|
|
28
|
+
...props
|
|
29
|
+
}: ConversationTabPickerProps): React.JSX.Element | null;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { ConversationTabId, ConversationTabPicker, ConversationTabPickerItem, ConversationTabPickerProps };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Button } from "./Button.js";
|
|
2
|
+
import { tt as WarningIcon } from "../icons-B4mGvCvc.js";
|
|
3
|
+
import { Avatar } from "./Avatar.js";
|
|
4
|
+
import { Menu } from "./Menu.js";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/components/ConversationTabPicker.tsx
|
|
8
|
+
function tabFallback(tab) {
|
|
9
|
+
const domain = tabDomain(tab);
|
|
10
|
+
if (domain && domain !== `Tab ${tab.id}`) return domain.charAt(0).toUpperCase();
|
|
11
|
+
return tab.title?.trim().charAt(0).toUpperCase() || "T";
|
|
12
|
+
}
|
|
13
|
+
function tabDomain(tab) {
|
|
14
|
+
if (!tab.url) return `Tab ${tab.id}`;
|
|
15
|
+
try {
|
|
16
|
+
return new URL(tab.url).hostname.replace(/^www\./, "") || tab.url;
|
|
17
|
+
} catch {
|
|
18
|
+
return tab.url;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function TabAvatar({ tab }) {
|
|
22
|
+
return /* @__PURE__ */ jsxs(Avatar.Root, {
|
|
23
|
+
size: "sm",
|
|
24
|
+
"aria-hidden": "true",
|
|
25
|
+
children: [tab.iconSrc ? /* @__PURE__ */ jsx(Avatar.Image, {
|
|
26
|
+
src: tab.iconSrc,
|
|
27
|
+
alt: "",
|
|
28
|
+
referrerPolicy: "no-referrer"
|
|
29
|
+
}) : null, /* @__PURE__ */ jsx(Avatar.Fallback, {
|
|
30
|
+
"aria-hidden": "true",
|
|
31
|
+
children: tabFallback(tab)
|
|
32
|
+
})]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Shared tab-menu presentation over host-resolved browser data.
|
|
37
|
+
*
|
|
38
|
+
* The browser adapter owns tab lookup and activation. This component owns URL
|
|
39
|
+
* labels, favicon fallbacks, menu state, and async activation feedback.
|
|
40
|
+
*/
|
|
41
|
+
function ConversationTabPicker({ tabs, ...props }) {
|
|
42
|
+
if (tabs.length === 0) return null;
|
|
43
|
+
return /* @__PURE__ */ jsx(ConversationTabPickerMenu, {
|
|
44
|
+
tabs,
|
|
45
|
+
...props
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function ConversationTabPickerMenu({ tabs, onSelect, maxVisible = 3, groupLabel = "Tabs in this conversation" }) {
|
|
49
|
+
const [open, setOpen] = React.useState(false);
|
|
50
|
+
const [action, setAction] = React.useState(null);
|
|
51
|
+
const visibleTabs = tabs.slice(0, Math.max(0, maxVisible));
|
|
52
|
+
const hiddenCount = tabs.length - visibleTabs.length;
|
|
53
|
+
const pending = action && "pending" in action ? action.pending : null;
|
|
54
|
+
const error = action && "error" in action ? action.error : null;
|
|
55
|
+
const label = `${tabs.length} controlled ${tabs.length === 1 ? "tab" : "tabs"}`;
|
|
56
|
+
async function selectTab(id) {
|
|
57
|
+
if (pending !== null) return;
|
|
58
|
+
setAction({ pending: id });
|
|
59
|
+
try {
|
|
60
|
+
await onSelect(id);
|
|
61
|
+
setAction(null);
|
|
62
|
+
setOpen(false);
|
|
63
|
+
} catch (cause) {
|
|
64
|
+
setAction({ error: cause instanceof Error ? cause.message : String(cause) });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return /* @__PURE__ */ jsxs(Menu.Root, {
|
|
68
|
+
open,
|
|
69
|
+
onOpenChange: setOpen,
|
|
70
|
+
children: [/* @__PURE__ */ jsx(Menu.Trigger, {
|
|
71
|
+
render: /* @__PURE__ */ jsx(Button, {
|
|
72
|
+
type: "button",
|
|
73
|
+
variant: "ghost",
|
|
74
|
+
color: "neutral",
|
|
75
|
+
size: "sm",
|
|
76
|
+
disabled: pending !== null,
|
|
77
|
+
focusableWhenDisabled: pending !== null
|
|
78
|
+
}),
|
|
79
|
+
"aria-label": `Show ${label}`,
|
|
80
|
+
children: /* @__PURE__ */ jsxs(Avatar.Group, {
|
|
81
|
+
"aria-hidden": "true",
|
|
82
|
+
children: [visibleTabs.map((tab) => /* @__PURE__ */ jsx(TabAvatar, { tab }, tab.id)), hiddenCount > 0 ? /* @__PURE__ */ jsxs(Avatar.GroupCount, { children: ["+", hiddenCount] }) : null]
|
|
83
|
+
})
|
|
84
|
+
}), /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
|
|
85
|
+
side: "top",
|
|
86
|
+
align: "start",
|
|
87
|
+
sideOffset: 8,
|
|
88
|
+
children: /* @__PURE__ */ jsx(Menu.Popup, { children: /* @__PURE__ */ jsxs(Menu.Group, { children: [
|
|
89
|
+
/* @__PURE__ */ jsx(Menu.GroupLabel, { children: groupLabel }),
|
|
90
|
+
error ? /* @__PURE__ */ jsxs("div", {
|
|
91
|
+
className: "conversation-tab-picker__error",
|
|
92
|
+
role: "alert",
|
|
93
|
+
children: [/* @__PURE__ */ jsx(WarningIcon, {}), error]
|
|
94
|
+
}) : null,
|
|
95
|
+
tabs.map((tab) => /* @__PURE__ */ jsxs(Menu.Item, {
|
|
96
|
+
"aria-busy": pending === tab.id || void 0,
|
|
97
|
+
closeOnClick: false,
|
|
98
|
+
"data-tab-id": tab.id,
|
|
99
|
+
disabled: pending !== null,
|
|
100
|
+
onClick: () => void selectTab(tab.id),
|
|
101
|
+
children: [/* @__PURE__ */ jsx(TabAvatar, { tab }), /* @__PURE__ */ jsxs("span", {
|
|
102
|
+
className: "conversation-tab-picker__identity sigvelo-truncate-grow",
|
|
103
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
104
|
+
className: "sigvelo-truncate",
|
|
105
|
+
children: tab.title ?? tab.url ?? `Tab ${tab.id}`
|
|
106
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
107
|
+
className: "conversation-tab-picker__domain sigvelo-truncate",
|
|
108
|
+
children: tabDomain(tab)
|
|
109
|
+
})]
|
|
110
|
+
})]
|
|
111
|
+
}, tab.id))
|
|
112
|
+
] }) })
|
|
113
|
+
}) })]
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
export { ConversationTabPicker };
|
|
@@ -85,5 +85,32 @@ declare function GoalActions({
|
|
|
85
85
|
}: GoalActionsProps & {
|
|
86
86
|
ref?: React.Ref<HTMLDivElement>;
|
|
87
87
|
}): React.JSX.Element;
|
|
88
|
+
interface GoalBannerProps extends Omit<GoalProps, "children" | "title"> {
|
|
89
|
+
/** User- or model-authored objective. */
|
|
90
|
+
objective: string;
|
|
91
|
+
/** Host-formatted progress such as elapsed time or token spend. */
|
|
92
|
+
meta?: React.ReactNode;
|
|
93
|
+
/** Full progress detail exposed without expanding the capped row. */
|
|
94
|
+
progressSummary?: string;
|
|
95
|
+
onPause?: () => void | Promise<void>;
|
|
96
|
+
onResume?: () => void | Promise<void>;
|
|
97
|
+
onClear?: () => void | Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Data-and-callable rendering of the standard goal anatomy.
|
|
101
|
+
*
|
|
102
|
+
* The host still owns persistence and lifecycle policy. This component owns
|
|
103
|
+
* action pending/error state and the shared banner markup.
|
|
104
|
+
*/
|
|
105
|
+
declare function GoalBanner({
|
|
106
|
+
objective,
|
|
107
|
+
meta,
|
|
108
|
+
progressSummary,
|
|
109
|
+
status,
|
|
110
|
+
onPause,
|
|
111
|
+
onResume,
|
|
112
|
+
onClear,
|
|
113
|
+
...props
|
|
114
|
+
}: GoalBannerProps): React.JSX.Element;
|
|
88
115
|
//#endregion
|
|
89
|
-
export { Goal, GoalActions, GoalActionsProps, GoalContent, GoalContentProps, GoalIcon, GoalIconProps, GoalMeta, GoalMetaProps, GoalObjective, GoalObjectiveProps, GoalProps, GoalStatus, GoalTitle, GoalTitleProps };
|
|
116
|
+
export { Goal, GoalActions, GoalActionsProps, GoalBanner, GoalBannerProps, GoalContent, GoalContentProps, GoalIcon, GoalIconProps, GoalMeta, GoalMetaProps, GoalObjective, GoalObjectiveProps, GoalProps, GoalStatus, GoalTitle, GoalTitleProps };
|
package/dist/components/Goal.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-BiMDVpUo.js";
|
|
2
|
-
import { Q as TargetIcon } from "../icons-B4mGvCvc.js";
|
|
2
|
+
import { Q as TargetIcon, V as PlayIcon, et as TrashIcon, z as PauseIcon } from "../icons-B4mGvCvc.js";
|
|
3
|
+
import { IconButton } from "./IconButton.js";
|
|
3
4
|
import * as React from "react";
|
|
4
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
//#region src/components/Goal.tsx
|
|
6
7
|
const GoalStatusContext = React.createContext("pursuing");
|
|
7
8
|
const STATUS_LABELS = {
|
|
@@ -90,5 +91,77 @@ function GoalActions({ className, ref, ...props }) {
|
|
|
90
91
|
...props
|
|
91
92
|
});
|
|
92
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Data-and-callable rendering of the standard goal anatomy.
|
|
96
|
+
*
|
|
97
|
+
* The host still owns persistence and lifecycle policy. This component owns
|
|
98
|
+
* action pending/error state and the shared banner markup.
|
|
99
|
+
*/
|
|
100
|
+
function GoalBanner({ objective, meta, progressSummary, status = "pursuing", onPause, onResume, onClear, ...props }) {
|
|
101
|
+
const [action, setAction] = React.useState(null);
|
|
102
|
+
const pending = action && "pending" in action ? action.pending : null;
|
|
103
|
+
const error = action && "error" in action ? action.error : null;
|
|
104
|
+
async function runAction(name, callback) {
|
|
105
|
+
if (pending) return;
|
|
106
|
+
setAction({ pending: name });
|
|
107
|
+
try {
|
|
108
|
+
await callback();
|
|
109
|
+
setAction(null);
|
|
110
|
+
} catch (cause) {
|
|
111
|
+
setAction({ error: cause instanceof Error ? cause.message : String(cause) });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return /* @__PURE__ */ jsxs(Goal, {
|
|
115
|
+
status,
|
|
116
|
+
title: progressSummary,
|
|
117
|
+
...props,
|
|
118
|
+
children: [
|
|
119
|
+
/* @__PURE__ */ jsx(GoalIcon, {}),
|
|
120
|
+
/* @__PURE__ */ jsxs(GoalContent, { children: [
|
|
121
|
+
/* @__PURE__ */ jsx(GoalTitle, {}),
|
|
122
|
+
/* @__PURE__ */ jsx(GoalObjective, {
|
|
123
|
+
title: objective,
|
|
124
|
+
children: objective
|
|
125
|
+
}),
|
|
126
|
+
error ? /* @__PURE__ */ jsx(GoalMeta, {
|
|
127
|
+
role: "alert",
|
|
128
|
+
children: error
|
|
129
|
+
}) : meta ? /* @__PURE__ */ jsx(GoalMeta, { children: meta }) : null
|
|
130
|
+
] }),
|
|
131
|
+
onPause || onResume || onClear ? /* @__PURE__ */ jsxs(GoalActions, { children: [
|
|
132
|
+
status === "pursuing" && onPause ? /* @__PURE__ */ jsx(IconButton, {
|
|
133
|
+
label: pending === "pause" ? "Pausing goal" : "Pause goal",
|
|
134
|
+
size: "xs",
|
|
135
|
+
variant: "ghost",
|
|
136
|
+
color: "neutral",
|
|
137
|
+
disabled: pending !== null,
|
|
138
|
+
focusableWhenDisabled: pending !== null,
|
|
139
|
+
onClick: () => void runAction("pause", onPause),
|
|
140
|
+
children: /* @__PURE__ */ jsx(PauseIcon, {})
|
|
141
|
+
}) : null,
|
|
142
|
+
status === "paused" && onResume ? /* @__PURE__ */ jsx(IconButton, {
|
|
143
|
+
label: pending === "resume" ? "Resuming goal" : "Resume goal",
|
|
144
|
+
size: "xs",
|
|
145
|
+
variant: "ghost",
|
|
146
|
+
color: "neutral",
|
|
147
|
+
disabled: pending !== null,
|
|
148
|
+
focusableWhenDisabled: pending !== null,
|
|
149
|
+
onClick: () => void runAction("resume", onResume),
|
|
150
|
+
children: /* @__PURE__ */ jsx(PlayIcon, {})
|
|
151
|
+
}) : null,
|
|
152
|
+
onClear ? /* @__PURE__ */ jsx(IconButton, {
|
|
153
|
+
label: pending === "clear" ? "Clearing goal" : "Clear goal",
|
|
154
|
+
size: "xs",
|
|
155
|
+
variant: "ghost",
|
|
156
|
+
color: "neutral",
|
|
157
|
+
disabled: pending !== null,
|
|
158
|
+
focusableWhenDisabled: pending !== null,
|
|
159
|
+
onClick: () => void runAction("clear", onClear),
|
|
160
|
+
children: /* @__PURE__ */ jsx(TrashIcon, {})
|
|
161
|
+
}) : null
|
|
162
|
+
] }) : null
|
|
163
|
+
]
|
|
164
|
+
});
|
|
165
|
+
}
|
|
93
166
|
//#endregion
|
|
94
|
-
export { Goal, GoalActions, GoalContent, GoalIcon, GoalMeta, GoalObjective, GoalTitle };
|
|
167
|
+
export { Goal, GoalActions, GoalBanner, GoalContent, GoalIcon, GoalMeta, GoalObjective, GoalTitle };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { o as McpServerCard } from "../mcp-server-catalog-
|
|
1
|
+
import { o as McpServerCard } from "../mcp-server-catalog-CO7GAl1f.js";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { DynamicToolUIPart, ToolUIPart } from "ai";
|
|
4
4
|
import { MCPServersState } from "agents";
|
|
5
5
|
|
|
6
6
|
//#region src/components/McpConnectionRequest.d.ts
|
|
7
|
-
type McpConnectionRequestOutcome = "connected" | "declined" | "failed";
|
|
8
|
-
interface
|
|
7
|
+
type McpConnectionRequestOutcome = "authorization-required" | "connected" | "declined" | "failed";
|
|
8
|
+
interface McpConnectionRequestBaseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "part"> {
|
|
9
9
|
/** Whole upstream AI SDK tool part whose lifecycle this card renders. */
|
|
10
10
|
part: ToolUIPart | DynamicToolUIPart;
|
|
11
11
|
/** Canonical catalog/custom display data after the host validates the request. */
|
|
@@ -14,13 +14,18 @@ interface McpConnectionRequestProps extends Omit<React.HTMLAttributes<HTMLDivEle
|
|
|
14
14
|
reason: React.ReactNode;
|
|
15
15
|
/** Whole upstream Agents MCP state, kept separate from the tool lifecycle. */
|
|
16
16
|
mcp?: MCPServersState;
|
|
17
|
-
/** App-validated meaning of an available tool output. */
|
|
18
|
-
outcome?: McpConnectionRequestOutcome;
|
|
19
17
|
/** Starts a new connection or replaces a stale non-ready upstream entry. */
|
|
20
18
|
onConnect?: (server: McpServerCard) => void | Promise<void>;
|
|
21
19
|
/** Declines the request. The host may remove any existing non-ready entry. */
|
|
22
20
|
onDecline?: () => void | Promise<void>;
|
|
23
21
|
}
|
|
22
|
+
type McpConnectionRequestProps = (McpConnectionRequestBaseProps & {
|
|
23
|
+
/** A live authorization outcome must identify its assigned Agents MCP entry. */outcome: "authorization-required";
|
|
24
|
+
serverId: string;
|
|
25
|
+
}) | (McpConnectionRequestBaseProps & {
|
|
26
|
+
/** App-validated terminal outcome, or omitted while the request is active. */outcome?: Exclude<McpConnectionRequestOutcome, "authorization-required">;
|
|
27
|
+
serverId?: never;
|
|
28
|
+
});
|
|
24
29
|
/**
|
|
25
30
|
* In-chat MCP connection request backed by the AI SDK tool part and Agents MCP
|
|
26
31
|
* state. Failed and interrupted connections deliberately restart through the
|
|
@@ -31,6 +36,7 @@ declare function McpConnectionRequest({
|
|
|
31
36
|
server,
|
|
32
37
|
reason,
|
|
33
38
|
mcp,
|
|
39
|
+
serverId,
|
|
34
40
|
outcome,
|
|
35
41
|
onConnect,
|
|
36
42
|
onDecline,
|
|
@@ -13,18 +13,23 @@ import { getToolPartState } from "@cloudflare/think/react";
|
|
|
13
13
|
* state. Failed and interrupted connections deliberately restart through the
|
|
14
14
|
* same `onConnect` seam instead of introducing recovery operations.
|
|
15
15
|
*/
|
|
16
|
-
function McpConnectionRequest({ part, server, reason, mcp, outcome, onConnect, onDecline, className, ref, ...props }) {
|
|
16
|
+
function McpConnectionRequest({ part, server, reason, mcp, serverId, outcome, onConnect, onDecline, className, ref, ...props }) {
|
|
17
17
|
const [action, setAction] = React.useState(null);
|
|
18
|
-
const
|
|
18
|
+
const entry = getMcpServerEntry(server, mcp);
|
|
19
|
+
const connectedServer = serverId === void 0 ? entry?.[1] : mcp?.servers[serverId];
|
|
19
20
|
const serverState = connectedServer ? getMcpServerRuntimeState(connectedServer) : void 0;
|
|
20
21
|
const pendingAction = action && "pending" in action ? action.pending : null;
|
|
21
22
|
const actionError = action && "error" in action ? action.error : null;
|
|
22
23
|
const toolState = part.state === "output-available" && part.preliminary === true ? "streaming" : getToolPartState(part);
|
|
23
|
-
const
|
|
24
|
+
const authorizationPending = outcome === "authorization-required" && toolState === "complete";
|
|
25
|
+
const settled = toolState === "error" || toolState === "denied" || toolState === "complete" && !authorizationPending;
|
|
24
26
|
const preparing = !settled && (toolState === "streaming" || toolState === "waiting-approval" || toolState === "approved");
|
|
25
|
-
const
|
|
27
|
+
const ready = serverState === "ready";
|
|
28
|
+
const authorizationFailed = authorizationPending && (serverState === "failed" || serverState === "not-connected" || Boolean(connectedServer?.error) || Boolean(actionError));
|
|
29
|
+
const authorizing = authorizationPending && !ready && !authorizationFailed;
|
|
30
|
+
const connecting = !authorizationPending && (pendingAction === "connect" || serverState === "connecting" || serverState === "discovering" || serverState === "connected" && !connectedServer?.error);
|
|
26
31
|
const reconnect = Boolean(actionError) || serverState === "authenticating" || serverState === "failed" || serverState === "not-connected" || serverState === "connected" && Boolean(connectedServer?.error);
|
|
27
|
-
const connectionError = actionError ?? connectedServer?.error ?? (serverState === "failed" ? "Connection failed. Reconnect to try again." : void 0);
|
|
32
|
+
const connectionError = actionError ?? connectedServer?.error ?? (serverState === "failed" ? "Connection failed. Reconnect to try again." : authorizationFailed ? "Connection did not complete." : void 0);
|
|
28
33
|
async function runAction(kind, callback) {
|
|
29
34
|
if (pendingAction) return;
|
|
30
35
|
setAction({ pending: kind });
|
|
@@ -56,21 +61,22 @@ function McpConnectionRequest({ part, server, reason, mcp, outcome, onConnect, o
|
|
|
56
61
|
}) }) : null]
|
|
57
62
|
});
|
|
58
63
|
}
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const description = preparing ? "Reading assistant request" : connecting ? "Setting up connection" : ready ? "Connection is ready" : reconnect ? "The previous connection needs attention" : "Assistant requested access";
|
|
64
|
+
const title = preparing ? "Preparing connection request" : authorizationFailed ? `Couldn’t connect ${server.name}` : authorizing ? `Authorizing ${server.name}` : connecting ? `Connecting ${server.name}` : ready ? `Connected to ${server.name}` : reconnect ? `Reconnect ${server.name}` : `Connect ${server.name}`;
|
|
65
|
+
const description = preparing ? "Reading assistant request" : authorizationFailed ? "Connection failed" : authorizing ? "The agent is completing sign-in" : connecting ? "Setting up connection" : ready ? "Connection is ready" : reconnect ? "The previous connection needs attention" : "Assistant requested access";
|
|
62
66
|
const connectLabel = pendingAction === "connect" ? "Connecting…" : ready ? "Continue" : reconnect ? `Reconnect ${server.name}` : `Connect ${server.name}`;
|
|
63
67
|
return /* @__PURE__ */ jsxs(AgentAttention, {
|
|
64
68
|
ref,
|
|
65
69
|
...props,
|
|
66
|
-
|
|
70
|
+
"aria-atomic": "true",
|
|
71
|
+
busy: preparing || connecting || authorizing,
|
|
67
72
|
className: cx("mcp-connection-request", className),
|
|
68
|
-
"data-state": serverState ?? (preparing ? "preparing" : "idle"),
|
|
73
|
+
"data-state": authorizationFailed ? "failed" : serverState ?? (preparing ? "preparing" : authorizing ? "authenticating" : "idle"),
|
|
74
|
+
role: authorizationFailed ? "alert" : "status",
|
|
69
75
|
tone: connectionError ? "warning" : "neutral",
|
|
70
76
|
children: [
|
|
71
77
|
/* @__PURE__ */ jsx(AgentAttentionHeader, {
|
|
72
78
|
description,
|
|
73
|
-
icon: preparing || connecting ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : ready ? /* @__PURE__ */ jsx(CheckIcon, {}) : reconnect ? /* @__PURE__ */ jsx(WarningIcon, {}) : /* @__PURE__ */ jsx(McpIcon, {}),
|
|
79
|
+
icon: preparing || connecting ? /* @__PURE__ */ jsx(SpinnerIcon, {}) : ready ? /* @__PURE__ */ jsx(CheckIcon, {}) : authorizing ? /* @__PURE__ */ jsx(McpIcon, {}) : reconnect ? /* @__PURE__ */ jsx(WarningIcon, {}) : /* @__PURE__ */ jsx(McpIcon, {}),
|
|
74
80
|
title
|
|
75
81
|
}),
|
|
76
82
|
/* @__PURE__ */ jsxs(AgentAttentionBody, {
|
|
@@ -93,21 +99,21 @@ function McpConnectionRequest({ part, server, reason, mcp, outcome, onConnect, o
|
|
|
93
99
|
}),
|
|
94
100
|
connectionError ? /* @__PURE__ */ jsxs("div", {
|
|
95
101
|
className: "mcp-connection-request__error",
|
|
96
|
-
role: "alert",
|
|
102
|
+
role: authorizationFailed ? void 0 : "alert",
|
|
97
103
|
children: [/* @__PURE__ */ jsx(WarningIcon, {}), /* @__PURE__ */ jsx("span", { children: connectionError })]
|
|
98
104
|
}) : null
|
|
99
105
|
]
|
|
100
106
|
}),
|
|
101
107
|
onConnect || onDecline ? /* @__PURE__ */ jsxs(AgentAttentionActions, { children: [onConnect ? /* @__PURE__ */ jsx(Button, {
|
|
102
|
-
disabled: preparing || connecting || pendingAction !== null,
|
|
103
|
-
focusableWhenDisabled: preparing || connecting,
|
|
108
|
+
disabled: preparing || connecting || authorizing || pendingAction !== null,
|
|
109
|
+
focusableWhenDisabled: preparing || connecting || authorizing,
|
|
104
110
|
onClick: () => void runAction("connect", () => onConnect(server)),
|
|
105
111
|
size: "sm",
|
|
106
112
|
type: "button",
|
|
107
|
-
children: preparing ? "Preparing…" : connecting ? "Connecting…" : connectLabel
|
|
113
|
+
children: preparing ? "Preparing…" : connecting ? "Connecting…" : authorizing ? "Authorizing…" : connectLabel
|
|
108
114
|
}) : null, onDecline ? /* @__PURE__ */ jsx(Button, {
|
|
109
115
|
color: "neutral",
|
|
110
|
-
disabled: preparing || pendingAction !== null,
|
|
116
|
+
disabled: preparing || authorizing || pendingAction !== null,
|
|
111
117
|
focusableWhenDisabled: pendingAction === "decline",
|
|
112
118
|
onClick: () => void runAction("decline", onDecline),
|
|
113
119
|
size: "sm",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as McpServerCard } from "../mcp-server-catalog-
|
|
1
|
+
import { o as McpServerCard } from "../mcp-server-catalog-CO7GAl1f.js";
|
|
2
2
|
import { l as DialogProps } from "../Dialog-BD8NBKaE.js";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { MCPServersState } from "agents";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { s as MenuItemProps, t as Menu } from "../Menu-L6MZm-7N.js";
|
|
2
|
-
import { o as McpServerCard } from "../mcp-server-catalog-
|
|
2
|
+
import { o as McpServerCard } from "../mcp-server-catalog-CO7GAl1f.js";
|
|
3
3
|
import { McpConnectorFormProps } from "./AgentConnection.js";
|
|
4
4
|
import { l as DialogProps } from "../Dialog-BD8NBKaE.js";
|
|
5
5
|
import * as React from "react";
|
|
@@ -15,6 +15,9 @@ interface McpServerPickerProps {
|
|
|
15
15
|
mcp?: MCPServersState;
|
|
16
16
|
/** Called when an upstream server entry should be removed. */
|
|
17
17
|
onDisconnect?: (serverId: string) => void | Promise<void>;
|
|
18
|
+
/** App-owned connection actions shown before the server catalog. */
|
|
19
|
+
actions?: readonly McpServerPickerActionItem[];
|
|
20
|
+
actionsLabel?: React.ReactNode;
|
|
18
21
|
/** Offset from the plus trigger to the menu, useful for prompt composers. */
|
|
19
22
|
sideOffset?: number;
|
|
20
23
|
/** Accessible name for the plus trigger. */
|
|
@@ -31,6 +34,14 @@ interface McpServerPickerActionProps extends Omit<MenuItemProps, "children" | "l
|
|
|
31
34
|
label: React.ReactNode;
|
|
32
35
|
description?: React.ReactNode;
|
|
33
36
|
}
|
|
37
|
+
interface McpServerPickerActionItem {
|
|
38
|
+
id: string;
|
|
39
|
+
icon?: React.ReactNode;
|
|
40
|
+
label: React.ReactNode;
|
|
41
|
+
description?: React.ReactNode;
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
onSelect: () => void;
|
|
44
|
+
}
|
|
34
45
|
interface McpServerSetupDialogProps extends Pick<McpConnectorFormProps, "defaults" | "onSubmit" | "redirectUrl" | "status"> {
|
|
35
46
|
/** Selected catalog entry. Passing null closes the dialog. */
|
|
36
47
|
server: McpServerCard | null;
|
|
@@ -52,6 +63,8 @@ declare function McpServerPicker({
|
|
|
52
63
|
onConnect,
|
|
53
64
|
mcp,
|
|
54
65
|
onDisconnect,
|
|
66
|
+
actions,
|
|
67
|
+
actionsLabel,
|
|
55
68
|
sideOffset,
|
|
56
69
|
triggerLabel
|
|
57
70
|
}: McpServerPickerProps): React.JSX.Element;
|
|
@@ -59,7 +72,9 @@ declare function McpServerPickerItems({
|
|
|
59
72
|
servers,
|
|
60
73
|
onConnect,
|
|
61
74
|
mcp,
|
|
62
|
-
onDisconnect
|
|
75
|
+
onDisconnect,
|
|
76
|
+
actions,
|
|
77
|
+
actionsLabel
|
|
63
78
|
}: McpServerPickerItemsProps): React.JSX.Element;
|
|
64
79
|
declare function McpServerPickerGroup({
|
|
65
80
|
label,
|
|
@@ -75,4 +90,4 @@ declare function McpServerPickerAction({
|
|
|
75
90
|
...props
|
|
76
91
|
}: McpServerPickerActionProps): React.JSX.Element;
|
|
77
92
|
//#endregion
|
|
78
|
-
export { McpServerPicker, McpServerPickerAction, McpServerPickerActionProps, McpServerPickerGroup, McpServerPickerGroupProps, McpServerPickerItems, McpServerPickerItemsProps, McpServerPickerProps, McpServerSetupDialog, McpServerSetupDialogProps };
|
|
93
|
+
export { McpServerPicker, McpServerPickerAction, McpServerPickerActionItem, McpServerPickerActionProps, McpServerPickerGroup, McpServerPickerGroupProps, McpServerPickerItems, McpServerPickerItemsProps, McpServerPickerProps, McpServerSetupDialog, McpServerSetupDialogProps };
|
|
@@ -56,7 +56,7 @@ function McpServerSetupDialog({ server, defaults, onOpenChange, onSubmit, redire
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
/** Prompt plus-menu picker for connecting and removing MCP servers. */
|
|
59
|
-
function McpServerPicker({ servers, onConnect, mcp, onDisconnect, sideOffset = 12, triggerLabel = "Add server" }) {
|
|
59
|
+
function McpServerPicker({ servers, onConnect, mcp, onDisconnect, actions, actionsLabel, sideOffset = 12, triggerLabel = "Add server" }) {
|
|
60
60
|
return /* @__PURE__ */ jsxs(PromptInputActionMenu, { children: [/* @__PURE__ */ jsx(PromptInputActionMenuTrigger, { "aria-label": triggerLabel }), /* @__PURE__ */ jsx(PromptInputActionMenuContent, {
|
|
61
61
|
tabIndex: -1,
|
|
62
62
|
"aria-label": "Servers",
|
|
@@ -70,11 +70,13 @@ function McpServerPicker({ servers, onConnect, mcp, onDisconnect, sideOffset = 1
|
|
|
70
70
|
servers,
|
|
71
71
|
onConnect,
|
|
72
72
|
mcp,
|
|
73
|
-
onDisconnect
|
|
73
|
+
onDisconnect,
|
|
74
|
+
actions,
|
|
75
|
+
actionsLabel
|
|
74
76
|
})
|
|
75
77
|
})] });
|
|
76
78
|
}
|
|
77
|
-
function McpServerPickerItems({ servers, onConnect, mcp, onDisconnect }) {
|
|
79
|
+
function McpServerPickerItems({ servers, onConnect, mcp, onDisconnect, actions, actionsLabel = "Connections" }) {
|
|
78
80
|
const [action, setAction] = React.useState(null);
|
|
79
81
|
const rows = getPickerRows(servers, mcp);
|
|
80
82
|
const pendingAction = action && "pending" in action ? action.pending : null;
|
|
@@ -89,26 +91,39 @@ function McpServerPickerItems({ servers, onConnect, mcp, onDisconnect }) {
|
|
|
89
91
|
setAction({ error: error instanceof Error ? error.message : String(error) });
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
},
|
|
111
|
-
|
|
94
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
95
|
+
actionError ? /* @__PURE__ */ jsxs(Menu.Item, {
|
|
96
|
+
"aria-atomic": "true",
|
|
97
|
+
"aria-live": "polite",
|
|
98
|
+
className: "mcp-server-picker__action-error",
|
|
99
|
+
closeOnClick: false,
|
|
100
|
+
disabled: true,
|
|
101
|
+
children: [/* @__PURE__ */ jsx(WarningIcon, { size: 14 }), /* @__PURE__ */ jsx("span", { children: actionError })]
|
|
102
|
+
}) : null,
|
|
103
|
+
actions?.length ? /* @__PURE__ */ jsx(McpServerPickerGroup, {
|
|
104
|
+
label: actionsLabel,
|
|
105
|
+
children: actions.map((item) => /* @__PURE__ */ jsx(McpServerPickerAction, {
|
|
106
|
+
icon: item.icon,
|
|
107
|
+
label: item.label,
|
|
108
|
+
description: item.description,
|
|
109
|
+
disabled: item.disabled,
|
|
110
|
+
onClick: item.onSelect
|
|
111
|
+
}, item.id))
|
|
112
|
+
}) : null,
|
|
113
|
+
rows.length === 0 ? /* @__PURE__ */ jsx(Menu.Item, {
|
|
114
|
+
disabled: true,
|
|
115
|
+
className: "mcp-server-picker__empty",
|
|
116
|
+
children: "No servers available."
|
|
117
|
+
}) : groupPickerRows(rows).map(([label, groupRows]) => /* @__PURE__ */ jsx(McpServerPickerGroup, {
|
|
118
|
+
label,
|
|
119
|
+
children: groupRows.map((row) => /* @__PURE__ */ jsx(McpServerPickerRow, {
|
|
120
|
+
pendingAction,
|
|
121
|
+
row,
|
|
122
|
+
onConnect: onConnect ? (server) => runAction(`connect:${server.id}:${server.url}`, () => onConnect(server)) : void 0,
|
|
123
|
+
onDisconnect: onDisconnect ? (id) => runAction(`disconnect:${id}`, () => onDisconnect(id)) : void 0
|
|
124
|
+
}, `${row.server.id}:${row.server.url}`))
|
|
125
|
+
}, label))
|
|
126
|
+
] });
|
|
112
127
|
}
|
|
113
128
|
function McpServerPickerGroup({ label, children, className, ...props }) {
|
|
114
129
|
return /* @__PURE__ */ jsxs(Menu.Group, {
|
|
@@ -159,5 +159,22 @@ declare function PlanSummaryContent({
|
|
|
159
159
|
children,
|
|
160
160
|
...props
|
|
161
161
|
}: PlanSummaryContentProps): React.JSX.Element;
|
|
162
|
+
interface PlanSummaryStep {
|
|
163
|
+
/** Stable optional identity; the list index is used when omitted. */
|
|
164
|
+
id?: React.Key;
|
|
165
|
+
step: React.ReactNode;
|
|
166
|
+
status: PlanStepStatus;
|
|
167
|
+
}
|
|
168
|
+
interface PlanSummaryListProps {
|
|
169
|
+
/** Complete normalized plan state from the host. */
|
|
170
|
+
steps: readonly PlanSummaryStep[];
|
|
171
|
+
/** The pill usually sits above a composer, so default "top". */
|
|
172
|
+
side?: PlanSummaryContentProps["side"];
|
|
173
|
+
}
|
|
174
|
+
/** Data-only convenience renderer for the complete plan summary anatomy. */
|
|
175
|
+
declare function PlanSummaryList({
|
|
176
|
+
steps,
|
|
177
|
+
side
|
|
178
|
+
}: PlanSummaryListProps): React.JSX.Element | null;
|
|
162
179
|
//#endregion
|
|
163
|
-
export { Plan, PlanContent, PlanContentProps, PlanDescription, PlanDescriptionProps, PlanHeader, PlanHeaderProps, PlanProps, PlanStep, PlanStepDescription, PlanStepDescriptionProps, PlanStepIndicator, PlanStepIndicatorProps, PlanStepProps, PlanStepStatus, PlanStepTitle, PlanStepTitleProps, PlanSummary, PlanSummaryContent, PlanSummaryContentProps, PlanSummaryProps, PlanSummaryTrigger, PlanSummaryTriggerProps, PlanTitle, PlanTitleProps };
|
|
180
|
+
export { Plan, PlanContent, PlanContentProps, PlanDescription, PlanDescriptionProps, PlanHeader, PlanHeaderProps, PlanProps, PlanStep, PlanStepDescription, PlanStepDescriptionProps, PlanStepIndicator, PlanStepIndicatorProps, PlanStepProps, PlanStepStatus, PlanStepTitle, PlanStepTitleProps, PlanSummary, PlanSummaryContent, PlanSummaryContentProps, PlanSummaryList, PlanSummaryListProps, PlanSummaryProps, PlanSummaryStep, PlanSummaryTrigger, PlanSummaryTriggerProps, PlanTitle, PlanTitleProps };
|
package/dist/components/Plan.js
CHANGED
|
@@ -189,5 +189,21 @@ function PlanSummaryContent({ className, side = "top", children, ...props }) {
|
|
|
189
189
|
})
|
|
190
190
|
}) });
|
|
191
191
|
}
|
|
192
|
+
/** Data-only convenience renderer for the complete plan summary anatomy. */
|
|
193
|
+
function PlanSummaryList({ steps, side }) {
|
|
194
|
+
if (steps.length === 0) return null;
|
|
195
|
+
const completed = steps.filter((item) => item.status === "complete").length;
|
|
196
|
+
return /* @__PURE__ */ jsxs(PlanSummary, {
|
|
197
|
+
completed,
|
|
198
|
+
total: steps.length,
|
|
199
|
+
children: [/* @__PURE__ */ jsx(PlanSummaryTrigger, {}), /* @__PURE__ */ jsx(PlanSummaryContent, {
|
|
200
|
+
side,
|
|
201
|
+
children: /* @__PURE__ */ jsx(Plan, { children: /* @__PURE__ */ jsx(PlanContent, { children: steps.map((item, index) => /* @__PURE__ */ jsxs(PlanStep, {
|
|
202
|
+
status: item.status,
|
|
203
|
+
children: [/* @__PURE__ */ jsx(PlanStepIndicator, {}), /* @__PURE__ */ jsx(PlanStepTitle, { children: item.step })]
|
|
204
|
+
}, item.id ?? index)) }) })
|
|
205
|
+
})]
|
|
206
|
+
});
|
|
207
|
+
}
|
|
192
208
|
//#endregion
|
|
193
|
-
export { Plan, PlanContent, PlanDescription, PlanHeader, PlanStep, PlanStepDescription, PlanStepIndicator, PlanStepTitle, PlanSummary, PlanSummaryContent, PlanSummaryTrigger, PlanTitle };
|
|
209
|
+
export { Plan, PlanContent, PlanDescription, PlanHeader, PlanStep, PlanStepDescription, PlanStepIndicator, PlanStepTitle, PlanSummary, PlanSummaryContent, PlanSummaryList, PlanSummaryTrigger, PlanTitle };
|