@mcp-b/react-components 0.5.4 → 0.5.5
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/components/AgentChat.d.ts +3 -0
- package/dist/components/AgentChat.js +14 -3
- package/dist/components/McpServerPicker.d.ts +6 -1
- package/dist/components/McpServerPicker.js +21 -14
- package/dist/components/PromptInput.d.ts +2 -2
- package/dist/components/PromptInput.js +3 -3
- package/dist/components/ThinkChat.d.ts +2 -0
- package/dist/styles/agent-chat.css +8 -0
- package/package.json +2 -2
|
@@ -30,6 +30,8 @@ interface AgentChatProps<MessageT extends UIMessage = UIMessage> {
|
|
|
30
30
|
emptyState?: React.ReactNode;
|
|
31
31
|
/** Extra controls rendered in the composer toolbar. */
|
|
32
32
|
composerTools?: React.ReactNode;
|
|
33
|
+
/** Extra rows rendered in the built-in plus menu after files. */
|
|
34
|
+
composerAddMenuItems?: React.ReactNode;
|
|
33
35
|
/**
|
|
34
36
|
* Transient status rendered between the transcript and the composer —
|
|
35
37
|
* e.g. a "Reconnecting…" pill. `ThinkChat.Messages` fills this from the
|
|
@@ -86,6 +88,7 @@ declare function AgentChat<MessageT extends UIMessage = UIMessage>({
|
|
|
86
88
|
disabled,
|
|
87
89
|
emptyState,
|
|
88
90
|
composerTools,
|
|
91
|
+
composerAddMenuItems,
|
|
89
92
|
notice,
|
|
90
93
|
onRegenerate,
|
|
91
94
|
onApprovalResponse,
|
|
@@ -4,7 +4,7 @@ import { Activity, ActivityContent, ActivityPanel, ActivityTrigger } from "./Act
|
|
|
4
4
|
import { Context, ContextContent, ContextContentBody, ContextContentHeader, ContextTrigger, getContextUsage, getContextUsedTokens } from "./Context.js";
|
|
5
5
|
import { Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton } from "./Conversation.js";
|
|
6
6
|
import { Message, MessageAction, MessageActions, MessageAttachment, MessageContent, MessageResponse } from "./Message.js";
|
|
7
|
-
import { PromptInput, PromptInputApproval, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputFooter, PromptInputPermissionSelector, PromptInputSubmit, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getPendingToolApprovals, usePromptInputAttachments } from "./PromptInput.js";
|
|
7
|
+
import { PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuTrigger, PromptInputApproval, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputFooter, PromptInputPermissionSelector, PromptInputSubmit, PromptInputTextarea, PromptInputTools, getApprovalRequestId, getPendingToolApprovals, usePromptInputAttachments } from "./PromptInput.js";
|
|
8
8
|
import { Reasoning, ReasoningContent, ReasoningTrigger } from "./Reasoning.js";
|
|
9
9
|
import * as React from "react";
|
|
10
10
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -18,6 +18,17 @@ function AgentChatAttachButton() {
|
|
|
18
18
|
children: /* @__PURE__ */ jsx(PlusIcon, {})
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
+
function AgentChatAddMenu({ children }) {
|
|
22
|
+
if (!children) return /* @__PURE__ */ jsx(AgentChatAttachButton, {});
|
|
23
|
+
return /* @__PURE__ */ jsxs(PromptInputActionMenu, { children: [/* @__PURE__ */ jsx(PromptInputActionMenuTrigger, { "aria-label": "Add context" }), /* @__PURE__ */ jsxs(PromptInputActionMenuContent, {
|
|
24
|
+
side: "top",
|
|
25
|
+
align: "start",
|
|
26
|
+
sideOffset: 12,
|
|
27
|
+
collisionPadding: 8,
|
|
28
|
+
className: "agent-chat__add-menu",
|
|
29
|
+
children: [/* @__PURE__ */ jsx(PromptInputActionAddAttachments, {}), children]
|
|
30
|
+
})] });
|
|
31
|
+
}
|
|
21
32
|
function isCompactedPart(message, part, partIndex) {
|
|
22
33
|
const metadata = message.metadata;
|
|
23
34
|
if (isTextUIPart(part)) return Array.isArray(metadata?.compactedTextParts) && metadata.compactedTextParts.includes(partIndex);
|
|
@@ -88,7 +99,7 @@ function renderDefaultPart(part) {
|
|
|
88
99
|
* transport. Use it directly with plain AI SDK `useChat` or a read-only
|
|
89
100
|
* transcript; if you have a Cloudflare Think agent, use `ThinkChat` instead.
|
|
90
101
|
*/
|
|
91
|
-
function AgentChat({ className, messages, status = "ready", onSubmit, onStop, placeholder = "Ask anything...", disabled, emptyState, composerTools, notice, onRegenerate, onApprovalResponse, executionApprovals, contextWindow, renderPart, renderMessageAfter, ref }) {
|
|
102
|
+
function AgentChat({ className, messages, status = "ready", onSubmit, onStop, placeholder = "Ask anything...", disabled, emptyState, composerTools, composerAddMenuItems, notice, onRegenerate, onApprovalResponse, executionApprovals, contextWindow, renderPart, renderMessageAfter, ref }) {
|
|
92
103
|
const handleSubmit = React.useCallback((message) => {
|
|
93
104
|
onSubmit?.(message);
|
|
94
105
|
}, [onSubmit]);
|
|
@@ -194,7 +205,7 @@ function AgentChat({ className, messages, status = "ready", onSubmit, onStop, pl
|
|
|
194
205
|
disabled
|
|
195
206
|
}) }),
|
|
196
207
|
/* @__PURE__ */ jsxs(PromptInputFooter, { children: [/* @__PURE__ */ jsxs(PromptInputTools, { children: [
|
|
197
|
-
/* @__PURE__ */ jsx(
|
|
208
|
+
/* @__PURE__ */ jsx(AgentChatAddMenu, { children: composerAddMenuItems }),
|
|
198
209
|
approvalsWired ? /* @__PURE__ */ jsx(PromptInputPermissionSelector, {
|
|
199
210
|
value: permissionMode,
|
|
200
211
|
onValueChange: setPermissionMode
|
|
@@ -21,6 +21,7 @@ interface McpServerPickerProps {
|
|
|
21
21
|
/** Offset from the plus trigger to the menu, useful for prompt composers. */
|
|
22
22
|
sideOffset?: number;
|
|
23
23
|
}
|
|
24
|
+
type McpServerPickerItemsProps = Pick<McpServerPickerProps, "servers" | "onConnect">;
|
|
24
25
|
/**
|
|
25
26
|
* Prompt plus-menu picker for choosing an MCP server and handing connection
|
|
26
27
|
* work back to the host app.
|
|
@@ -30,5 +31,9 @@ declare function McpServerPicker({
|
|
|
30
31
|
onConnect,
|
|
31
32
|
sideOffset
|
|
32
33
|
}: McpServerPickerProps): React.JSX.Element;
|
|
34
|
+
declare function McpServerPickerItems({
|
|
35
|
+
servers,
|
|
36
|
+
onConnect
|
|
37
|
+
}: McpServerPickerItemsProps): React.JSX.Element | React.JSX.Element[];
|
|
33
38
|
//#endregion
|
|
34
|
-
export { McpServerCard, McpServerPicker, McpServerPickerProps, McpServerPickerStatus };
|
|
39
|
+
export { McpServerCard, McpServerPicker, McpServerPickerItems, McpServerPickerItemsProps, McpServerPickerProps, McpServerPickerStatus };
|
|
@@ -9,8 +9,6 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
9
9
|
* work back to the host app.
|
|
10
10
|
*/
|
|
11
11
|
function McpServerPicker({ servers, onConnect, sideOffset = 80 }) {
|
|
12
|
-
const groups = groupServers(servers);
|
|
13
|
-
const showHeadings = groups.some((group) => group.category);
|
|
14
12
|
return /* @__PURE__ */ jsx("div", {
|
|
15
13
|
className: "mcp-server-picker",
|
|
16
14
|
children: /* @__PURE__ */ jsxs(MenuRoot, { children: [/* @__PURE__ */ jsx(MenuTrigger, { render: /* @__PURE__ */ jsx(Button, {
|
|
@@ -28,20 +26,29 @@ function McpServerPicker({ servers, onConnect, sideOffset = 80 }) {
|
|
|
28
26
|
collisionPadding: 8,
|
|
29
27
|
"aria-label": "MCP servers",
|
|
30
28
|
className: "mcp-server-picker__popup",
|
|
31
|
-
children:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}) : groups.map((group) => /* @__PURE__ */ jsxs(MenuGroup, {
|
|
36
|
-
className: "mcp-server-picker__group",
|
|
37
|
-
children: [showHeadings ? /* @__PURE__ */ jsx(MenuGroupLabel, { children: group.category || "Servers" }) : null, group.servers.map((server) => /* @__PURE__ */ jsx(McpServerPickerRow, {
|
|
38
|
-
server,
|
|
39
|
-
onConnect
|
|
40
|
-
}, server.id))]
|
|
41
|
-
}, group.category))
|
|
29
|
+
children: /* @__PURE__ */ jsx(McpServerPickerItems, {
|
|
30
|
+
servers,
|
|
31
|
+
onConnect
|
|
32
|
+
})
|
|
42
33
|
})] })
|
|
43
34
|
});
|
|
44
35
|
}
|
|
36
|
+
function McpServerPickerItems({ servers, onConnect }) {
|
|
37
|
+
const groups = groupServers(servers);
|
|
38
|
+
const showHeadings = groups.some((group) => group.category);
|
|
39
|
+
if (servers.length === 0) return /* @__PURE__ */ jsx(MenuItem, {
|
|
40
|
+
disabled: true,
|
|
41
|
+
className: "mcp-server-picker__empty",
|
|
42
|
+
children: "No MCP servers available."
|
|
43
|
+
});
|
|
44
|
+
return groups.map((group) => /* @__PURE__ */ jsxs(MenuGroup, {
|
|
45
|
+
className: "mcp-server-picker__group",
|
|
46
|
+
children: [showHeadings ? /* @__PURE__ */ jsx(MenuGroupLabel, { children: group.category || "Servers" }) : null, group.servers.map((server) => /* @__PURE__ */ jsx(McpServerPickerRow, {
|
|
47
|
+
server,
|
|
48
|
+
onConnect
|
|
49
|
+
}, server.id))]
|
|
50
|
+
}, group.category));
|
|
51
|
+
}
|
|
45
52
|
function McpServerPickerRow({ server, onConnect }) {
|
|
46
53
|
const descriptionId = React.useId();
|
|
47
54
|
const statusText = server.statusLabel ?? getStatusLabel(server.status);
|
|
@@ -130,4 +137,4 @@ function groupServers(servers) {
|
|
|
130
137
|
return groups;
|
|
131
138
|
}
|
|
132
139
|
//#endregion
|
|
133
|
-
export { McpServerPicker };
|
|
140
|
+
export { McpServerPicker, McpServerPickerItems };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { A as SelectTriggerProps, M as SelectValueProps, S as SelectProps, f as SelectOption, j as SelectValue, r as SelectContentProps, s as SelectItemProps, t as Select } from "../Select-CRsKCJ9x.js";
|
|
2
2
|
import { c as ComboboxGroup, d as ComboboxLabel, f as ComboboxList, g as ComboboxTrigger, h as ComboboxSeparator, l as ComboboxInput, m as ComboboxPositioner, p as ComboboxPopup, s as ComboboxEmpty, t as Combobox, u as ComboboxItem } from "../Combobox-D9anamNr.js";
|
|
3
|
-
import { h as MenuItemProps,
|
|
3
|
+
import { h as MenuItemProps, l as MenuContentProps, w as MenuProps } from "../Menu-B5vDqZe_.js";
|
|
4
4
|
import { c as TabsList, n as TabPanel, t as Tab } from "../Tabs-D9EAq09D.js";
|
|
5
5
|
import { r as ButtonProps } from "../Button-Ct5I6aTu.js";
|
|
6
6
|
import * as React from "react";
|
|
@@ -261,7 +261,7 @@ declare function PromptInputActionMenuTrigger({
|
|
|
261
261
|
children,
|
|
262
262
|
...props
|
|
263
263
|
}: PromptInputActionMenuTriggerProps): React.JSX.Element;
|
|
264
|
-
type PromptInputActionMenuContentProps =
|
|
264
|
+
type PromptInputActionMenuContentProps = MenuContentProps;
|
|
265
265
|
declare function PromptInputActionMenuContent({
|
|
266
266
|
className,
|
|
267
267
|
children,
|
|
@@ -4,7 +4,7 @@ import { Button } from "./Button.js";
|
|
|
4
4
|
import { Tooltip, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipTrigger } from "./Tooltip.js";
|
|
5
5
|
import { t as AttachmentPreview } from "../attachment-preview-ChtC3HiU.js";
|
|
6
6
|
import { Combobox, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxList, ComboboxSeparator } from "./Combobox.js";
|
|
7
|
-
import { MenuItem, MenuPopup, MenuPortal, MenuPositioner, MenuRadioGroup, MenuRadioItem, MenuRadioItemIndicator, MenuRoot, MenuTrigger } from "./Menu.js";
|
|
7
|
+
import { MenuContent, MenuItem, MenuPopup, MenuPortal, MenuPositioner, MenuRadioGroup, MenuRadioItem, MenuRadioItemIndicator, MenuRoot, MenuTrigger } from "./Menu.js";
|
|
8
8
|
import { Select, SelectContent, SelectItem, SelectPortal, SelectPositioner, SelectTrigger, SelectValue } from "./Select.js";
|
|
9
9
|
import { Tab, TabPanel, TabsList } from "./Tabs.js";
|
|
10
10
|
import * as React from "react";
|
|
@@ -538,11 +538,11 @@ function PromptInputActionMenuTrigger({ className, children, ...props }) {
|
|
|
538
538
|
}) });
|
|
539
539
|
}
|
|
540
540
|
function PromptInputActionMenuContent({ className, children, ...props }) {
|
|
541
|
-
return /* @__PURE__ */ jsx(
|
|
541
|
+
return /* @__PURE__ */ jsx(MenuContent, {
|
|
542
542
|
className: cx("prompt-input__action-menu", className),
|
|
543
543
|
...props,
|
|
544
544
|
children
|
|
545
|
-
})
|
|
545
|
+
});
|
|
546
546
|
}
|
|
547
547
|
function PromptInputActionMenuItem({ className, ...props }) {
|
|
548
548
|
return /* @__PURE__ */ jsx(MenuItem, {
|
|
@@ -31,6 +31,8 @@ interface ThinkChatMessagesProps extends ThinkChatActivityRendererOptions {
|
|
|
31
31
|
emptyState?: React.ReactNode;
|
|
32
32
|
/** Extra controls rendered inside the composer, next to the send button. */
|
|
33
33
|
composerTools?: React.ReactNode;
|
|
34
|
+
/** Extra rows rendered in the built-in plus menu after files. */
|
|
35
|
+
composerAddMenuItems?: AgentChatProps["composerAddMenuItems"];
|
|
34
36
|
/** Composer placeholder text. */
|
|
35
37
|
placeholder?: string;
|
|
36
38
|
/** Rendered after each message (e.g. per-message actions). */
|
|
@@ -43,6 +43,14 @@
|
|
|
43
43
|
margin-inline: auto;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
.agent-chat__add-menu {
|
|
47
|
+
inline-size: min(32rem, calc(100dvw - 1rem));
|
|
48
|
+
max-block-size: min(28rem, calc(100dvh - 2rem));
|
|
49
|
+
overflow-y: auto;
|
|
50
|
+
overscroll-behavior: contain;
|
|
51
|
+
scrollbar-gutter: stable;
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
/* Transient status pill between transcript and composer (recovery, errors). */
|
|
47
55
|
.agent-chat__notice {
|
|
48
56
|
display: flex;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-b/react-components",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"description": "MCP-B React components built on Base UI and shared design tokens, including Cloudflare Think chat primitives.",
|
|
5
5
|
"homepage": "https://design-system.sigvelo.com",
|
|
6
6
|
"bugs": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"anser": "^2.3.5",
|
|
50
50
|
"shiki": "^3.23.0",
|
|
51
51
|
"streamdown": "^2.5.0",
|
|
52
|
-
"@mcp-b/design-tokens": "0.5.
|
|
52
|
+
"@mcp-b/design-tokens": "0.5.5"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@ai-sdk/react": "^3.0.194",
|