@mcp-b/react-components 0.14.1 → 0.16.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/AgentActivity-BNUNrP9O.d.ts +36 -0
- package/dist/{AgentChat-Cgb1xuT7.d.ts → AgentChat-CrlpbvQJ.d.ts} +62 -8
- package/dist/{CodeBlock-DUh9WOGo.d.ts → CodeBlock-BRajW4QU.d.ts} +1 -1
- package/dist/{CodeBlock-BUFXG8HW.js → CodeBlock-BmB4Xaqq.js} +15 -4
- package/dist/{FileTree-mpEIcfzA.js → FileTree-CkVbIMWV.js} +82 -89
- package/dist/Message-BkMdE3bS.js +375 -0
- package/dist/{ModelSelector-DVgVBdvw.js → ModelSelector-SlJNgwKY.js} +17 -8
- package/dist/{PromptInput-ClNqBiIw.d.ts → PromptInput-BWTuXMOD.d.ts} +123 -5
- package/dist/ResponsiveSidebarShell-Dd9DCcBT.d.ts +67 -0
- package/dist/{Select-Dl_vF_Bt.d.ts → Select-BeEsefzh.d.ts} +12 -2
- package/dist/{ThinkChat-7DQ2CogF.js → ThinkChat-CzC-zNGA.js} +27 -37
- package/dist/{ThinkChatActivity-m9orbdeI.d.ts → ThinkChatActivity-BFQnb2ct.d.ts} +3 -10
- package/dist/ThinkChatActivitySummary-BPmu9a-c.d.ts +39 -0
- package/dist/{ThinkChatToolParts-Cv4o7j6F.d.ts → ThinkChatToolParts-CSzVwMXf.d.ts} +62 -3
- package/dist/ThinkExecutionRun-ChhWhOoU.d.ts +30 -0
- package/dist/Toggle-CAAlNl-M.d.ts +69 -0
- package/dist/ToggleGroup-8hPv-b69.d.ts +73 -0
- package/dist/Workspace-D39LxGvP.d.ts +62 -0
- package/dist/WorkspaceFile-DOZkPwzu.d.ts +106 -0
- package/dist/WorkspaceFileView-rSN_yT0L.js +744 -0
- package/dist/WorkspaceLink-DIPbXrUM.js +337 -0
- package/dist/WorkspaceLink-DK1DWMHe.d.ts +89 -0
- package/dist/components/Activity.d.ts +27 -1
- package/dist/components/Activity.js +33 -15
- package/dist/components/AgentActivity.d.ts +2 -0
- package/dist/components/AgentActivity.js +45 -0
- package/dist/components/AgentActivityPreview.d.ts +46 -0
- package/dist/components/AgentActivityPreview.js +94 -0
- package/dist/components/AgentAttention.d.ts +73 -0
- package/dist/components/AgentAttention.js +85 -0
- package/dist/components/AgentChat.d.ts +2 -2
- package/dist/components/AgentChat.js +231 -205
- package/dist/components/AgentChatMessageEditor.d.ts +29 -0
- package/dist/components/AgentChatMessageEditor.js +92 -0
- package/dist/components/AgentChatTurnError.d.ts +17 -0
- package/dist/components/AgentChatTurnError.js +40 -0
- package/dist/components/AgentConnection.d.ts +12 -17
- package/dist/components/AgentConnection.js +99 -91
- package/dist/components/AppFrame.d.ts +24 -0
- package/dist/components/AppFrame.js +25 -0
- package/dist/components/AppTopBar.d.ts +71 -0
- package/dist/components/AppTopBar.js +82 -0
- package/dist/components/Artifact.js +1 -1
- package/dist/components/BrowserLiveView.js +1 -1
- package/dist/components/BrowserReplay.js +1 -1
- package/dist/components/BrowserRunPanel.js +1 -1
- package/dist/components/Card.d.ts +3 -0
- package/dist/components/Card.js +2 -1
- package/dist/components/ChainOfThought.d.ts +1 -1
- package/dist/components/ChainOfThought.js +1 -1
- package/dist/components/ChatGptSignInScreen.js +2 -2
- package/dist/components/Checkbox.js +5 -13
- package/dist/components/CheckboxGroup.d.ts +58 -2
- package/dist/components/CheckboxGroup.js +59 -1
- package/dist/components/CodeBlock.d.ts +1 -1
- package/dist/components/CodeBlock.js +1 -1
- package/dist/components/CodexModelSelector.js +1 -1
- package/dist/components/Commit.js +2 -2
- package/dist/components/ContextMenu.js +1 -1
- package/dist/components/Conversation.js +1 -1
- package/dist/components/DescriptionList.d.ts +12 -0
- package/dist/components/DescriptionList.js +11 -0
- package/dist/components/DescriptionListParts.d.ts +37 -0
- package/dist/components/DescriptionListParts.js +35 -0
- package/dist/components/EnvironmentVariables.js +2 -2
- package/dist/components/Fieldset.d.ts +13 -1
- package/dist/components/Fieldset.js +11 -2
- package/dist/components/FileTree.js +1 -1
- package/dist/components/IconButton.d.ts +33 -0
- package/dist/components/IconButton.js +27 -0
- package/dist/components/McpConnectionRequest.d.ts +44 -0
- package/dist/components/McpConnectionRequest.js +122 -0
- package/dist/components/McpServerPicker.d.ts +48 -23
- package/dist/components/McpServerPicker.js +238 -189
- package/dist/components/Menubar.js +1 -1
- package/dist/components/Message.d.ts +1 -0
- package/dist/components/Message.js +1 -285
- package/dist/components/MessageScroller.js +1 -1
- package/dist/components/ModelSelector.d.ts +15 -3
- package/dist/components/ModelSelector.js +1 -1
- package/dist/components/NaniteScene.d.ts +10 -1
- package/dist/components/NaniteScene.js +36 -1
- package/dist/components/Pricing.d.ts +37 -0
- package/dist/components/Pricing.js +17 -0
- package/dist/components/PricingBillingToggle.d.ts +23 -0
- package/dist/components/PricingBillingToggle.js +86 -0
- package/dist/components/PricingConfirmationDialog.d.ts +25 -0
- package/dist/components/PricingConfirmationDialog.js +57 -0
- package/dist/components/PricingFAQ.d.ts +18 -0
- package/dist/components/PricingFAQ.js +27 -0
- package/dist/components/PricingPage.d.ts +2 -38
- package/dist/components/PricingPage.js +39 -359
- package/dist/components/PricingPlanCard.d.ts +22 -0
- package/dist/components/PricingPlanCard.js +109 -0
- package/dist/components/PricingUsageCalculator.d.ts +22 -0
- package/dist/components/PricingUsageCalculator.js +96 -0
- package/dist/components/PromptInput.d.ts +2 -2
- package/dist/components/PromptInput.js +210 -15
- package/dist/components/Queue.js +1 -1
- package/dist/components/Reasoning.d.ts +2 -1
- package/dist/components/Reasoning.js +14 -29
- package/dist/components/ResizableSidePanel.d.ts +57 -0
- package/dist/components/ResizableSidePanel.js +151 -0
- package/dist/components/ResponsiveSidebarShell.d.ts +2 -0
- package/dist/components/ResponsiveSidebarShell.js +129 -0
- package/dist/components/Select.d.ts +2 -2
- package/dist/components/Select.js +11 -2
- package/dist/components/Slider.d.ts +13 -1
- package/dist/components/Slider.js +11 -0
- package/dist/components/Sources.js +1 -1
- package/dist/components/Stepper.d.ts +4 -0
- package/dist/components/Stepper.js +5 -3
- package/dist/components/SubagentRun.d.ts +86 -0
- package/dist/components/SubagentRun.js +108 -0
- package/dist/components/SubagentRunDetails.d.ts +44 -0
- package/dist/components/SubagentRunDetails.js +48 -0
- package/dist/components/SubagentRunIndicator.d.ts +22 -0
- package/dist/components/SubagentRunIndicator.js +33 -0
- package/dist/components/SubagentRunList.d.ts +25 -0
- package/dist/components/SubagentRunList.js +26 -0
- package/dist/components/SubagentRunSelector.d.ts +47 -0
- package/dist/components/SubagentRunSelector.js +55 -0
- package/dist/components/Task.js +1 -1
- package/dist/components/Terminal.js +2 -2
- package/dist/components/TestResults.js +1 -1
- package/dist/components/Textarea.d.ts +21 -0
- package/dist/components/Textarea.js +19 -0
- package/dist/components/ThemeModeControl.d.ts +24 -0
- package/dist/components/ThemeModeControl.js +52 -0
- package/dist/components/ThemeProvider.d.ts +38 -0
- package/dist/components/ThemeProvider.js +80 -0
- package/dist/components/ThinkChat.d.ts +34 -7
- package/dist/components/ThinkChat.js +7 -4
- package/dist/components/ThinkChatActivity.d.ts +3 -2
- package/dist/components/ThinkChatActivity.js +18 -297
- package/dist/components/ThinkChatActivitySummary.d.ts +2 -0
- package/dist/components/ThinkChatActivitySummary.js +421 -0
- package/dist/components/ThinkChatToolPanels.d.ts +15 -5
- package/dist/components/ThinkChatToolPanels.js +116 -9
- package/dist/components/ThinkChatToolParts.d.ts +2 -2
- package/dist/components/ThinkChatToolParts.js +51 -9
- package/dist/components/ThinkExecutionDetail.d.ts +20 -0
- package/dist/components/ThinkExecutionDetail.js +80 -0
- package/dist/components/ThinkExecutionRun.d.ts +2 -0
- package/dist/components/ThinkExecutionRun.js +72 -0
- package/dist/components/ThinkExecutionStatus.d.ts +22 -0
- package/dist/components/ThinkExecutionStatus.js +36 -0
- package/dist/components/ThinkExecutionWorkbench.d.ts +7 -0
- package/dist/components/ThinkExecutionWorkbench.js +69 -225
- package/dist/components/ThinkFullApp.d.ts +58 -14
- package/dist/components/ThinkFullApp.js +129 -160
- package/dist/components/ThinkFullAppViewSwitch.d.ts +31 -0
- package/dist/components/ThinkFullAppViewSwitch.js +34 -0
- package/dist/components/ThinkRoutine.d.ts +36 -0
- package/dist/components/ThinkRoutine.js +15 -0
- package/dist/components/ThinkRoutineBrowser.d.ts +25 -0
- package/dist/components/ThinkRoutineBrowser.js +156 -0
- package/dist/components/ThinkRoutineDetail.d.ts +24 -0
- package/dist/components/ThinkRoutineDetail.js +102 -0
- package/dist/components/ThinkRoutineForm.d.ts +32 -0
- package/dist/components/ThinkRoutineForm.js +151 -0
- package/dist/components/ThinkRoutineLibrary.d.ts +74 -0
- package/dist/components/ThinkRoutineLibrary.js +178 -0
- package/dist/components/ThinkRoutineRuns.d.ts +24 -0
- package/dist/components/ThinkRoutineRuns.js +68 -0
- package/dist/components/ThinkThreadPicker.d.ts +18 -1
- package/dist/components/ThinkThreadPicker.js +51 -5
- package/dist/components/ThinkThreadShell.d.ts +12 -9
- package/dist/components/ThinkThreadShell.js +17 -137
- package/dist/components/Toggle.d.ts +1 -68
- package/dist/components/ToggleGroup.d.ts +1 -72
- package/dist/components/Tooltip.d.ts +3 -1
- package/dist/components/Tooltip.js +4 -2
- package/dist/components/WebPreview.js +1 -1
- package/dist/components/Workspace.d.ts +2 -0
- package/dist/components/Workspace.js +424 -0
- package/dist/components/WorkspaceBrowser.d.ts +32 -0
- package/dist/components/WorkspaceBrowser.js +103 -0
- package/dist/components/WorkspaceExplorer.d.ts +12 -79
- package/dist/components/WorkspaceExplorer.js +116 -330
- package/dist/components/WorkspaceFile.d.ts +2 -0
- package/dist/components/WorkspaceFile.js +195 -0
- package/dist/components/WorkspaceFileView.d.ts +26 -0
- package/dist/components/WorkspaceFileView.js +2 -0
- package/dist/components/WorkspaceHeader.d.ts +35 -0
- package/dist/components/WorkspaceHeader.js +51 -0
- package/dist/components/WorkspaceLink.d.ts +2 -0
- package/dist/components/WorkspaceLink.js +2 -0
- package/dist/components/icons.d.ts +2 -2
- package/dist/components/icons.js +2 -2
- package/dist/{copy-button-DUMLYdsk.js → copy-button-Dejn5heL.js} +1 -1
- package/dist/icons-CpfUer49.js +85 -0
- package/dist/{icons-CUCz_Sft.d.ts → icons-GQd1xF4e.d.ts} +51 -1
- package/dist/styles/activity-header.css +75 -0
- package/dist/styles/activity.css +49 -63
- package/dist/styles/agent-activity-preview-overlay.css +80 -0
- package/dist/styles/agent-activity-preview.css +235 -0
- package/dist/styles/agent-attention.css +122 -0
- package/dist/styles/agent-chat.css +141 -4
- package/dist/styles/app-frame.css +15 -0
- package/dist/styles/app-top-bar.css +100 -0
- package/dist/styles/avatar.css +0 -1
- package/dist/styles/browser-control-overlay.css +184 -0
- package/dist/styles/card.css +21 -0
- package/dist/styles/checkbox-group.css +69 -0
- package/dist/styles/description-list.css +50 -0
- package/dist/styles/fieldset.css +11 -0
- package/dist/styles/index.css +15 -2
- package/dist/styles/mcp-connection-request.css +60 -0
- package/dist/styles/mcp-server-picker.css +95 -68
- package/dist/styles/message.css +4 -43
- package/dist/styles/nanite-scene.css +16 -0
- package/dist/styles/pricing-page.css +21 -27
- package/dist/styles/prompt-input.css +225 -32
- package/dist/styles/reasoning.css +1 -55
- package/dist/styles/recipes.css +23 -15
- package/dist/styles/resizable-side-panel.css +66 -0
- package/dist/styles/responsive-sidebar-shell.css +169 -0
- package/dist/styles/select.css +10 -0
- package/dist/styles/stepper.css +13 -0
- package/dist/styles/streamdown.css +0 -4
- package/dist/styles/subagent-run.css +205 -0
- package/dist/styles/textarea.css +20 -0
- package/dist/styles/theme-mode-control.css +72 -0
- package/dist/styles/think-execution-status.css +49 -0
- package/dist/styles/think-execution-workbench.css +8 -72
- package/dist/styles/think-full-app.css +106 -131
- package/dist/styles/think-routine-library.css +491 -0
- package/dist/styles/think-thread-picker.css +47 -3
- package/dist/styles/toggle-group.css +7 -0
- package/dist/styles/workspace-explorer.css +511 -64
- package/dist/utils/codex-model-catalog.d.ts +4 -4
- package/dist/utils/mcp-server-catalog.d.ts +82 -78
- package/dist/utils/mcp-server-catalog.js +64 -41
- package/dist/utils/structured-code.d.ts +1 -1
- package/dist/utils/theme.d.ts +22 -0
- package/dist/utils/theme.js +55 -0
- package/package.json +34 -28
- package/dist/icons-Ba9THQKz.js +0 -64
- package/dist/styles/think-resize-handle.css +0 -33
- package/dist/styles/think-thread-shell.css +0 -219
|
@@ -1,286 +1,2 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import { h as FileIcon, n as ArrowLeftIcon, r as ArrowRightIcon } from "../icons-Ba9THQKz.js";
|
|
3
|
-
import { Button } from "./Button.js";
|
|
4
|
-
import { Tooltip } from "./Tooltip.js";
|
|
5
|
-
import { t as AttachmentPreview } from "../attachment-preview-DIs50Q0h.js";
|
|
6
|
-
import * as React from "react";
|
|
7
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { cjk } from "@streamdown/cjk";
|
|
9
|
-
import { code } from "@streamdown/code";
|
|
10
|
-
import { math } from "@streamdown/math";
|
|
11
|
-
import { mermaid } from "@streamdown/mermaid";
|
|
12
|
-
import { Streamdown } from "streamdown";
|
|
13
|
-
//#region src/components/Message.tsx
|
|
14
|
-
/**
|
|
15
|
-
* A chat message row. Aligns and styles itself based on {@link from}.
|
|
16
|
-
* Adapted from Vercel AI Elements and restyled with Sigvelo CSS tokens.
|
|
17
|
-
*
|
|
18
|
-
* Compose with {@link MessageContent} for the bubble, {@link MessageActions}
|
|
19
|
-
* for toolbar actions, and {@link MessageBranch} for multi-version responses.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```tsx
|
|
23
|
-
* <Message from="assistant">
|
|
24
|
-
* <MessageContent>Hello there!</MessageContent>
|
|
25
|
-
* <MessageActions>
|
|
26
|
-
* <MessageAction label="Copy" tooltip="Copy to clipboard">
|
|
27
|
-
* <CopyIcon />
|
|
28
|
-
* </MessageAction>
|
|
29
|
-
* </MessageActions>
|
|
30
|
-
* </Message>
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* @see {@link https://elements.ai-sdk.dev/components/message | AI Elements Message}
|
|
34
|
-
*/
|
|
35
|
-
function Message({ className, from = "assistant", children, ref, ...props }) {
|
|
36
|
-
return /* @__PURE__ */ jsx("div", {
|
|
37
|
-
ref,
|
|
38
|
-
className: cx("message", className),
|
|
39
|
-
"data-from": from,
|
|
40
|
-
...props,
|
|
41
|
-
children
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* The visible bubble/body of a message. Styled differently based on the
|
|
46
|
-
* parent {@link Message}'s `from` attribute.
|
|
47
|
-
*/
|
|
48
|
-
function MessageContent({ className, children, ref, ...props }) {
|
|
49
|
-
return /* @__PURE__ */ jsx("div", {
|
|
50
|
-
ref,
|
|
51
|
-
className: cx("message__content", className),
|
|
52
|
-
...props,
|
|
53
|
-
children
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
const streamdownPlugins = {
|
|
57
|
-
cjk,
|
|
58
|
-
code,
|
|
59
|
-
math,
|
|
60
|
-
mermaid
|
|
61
|
-
};
|
|
62
|
-
const messageResponseComponents = { img: "img" };
|
|
63
|
-
const MessageResponse = React.memo(function MessageResponse({ className, components, ...props }) {
|
|
64
|
-
const mergedComponents = components ? {
|
|
65
|
-
...messageResponseComponents,
|
|
66
|
-
...components
|
|
67
|
-
} : messageResponseComponents;
|
|
68
|
-
return /* @__PURE__ */ jsx(Streamdown, {
|
|
69
|
-
className: cx("message__response", className),
|
|
70
|
-
components: mergedComponents,
|
|
71
|
-
plugins: streamdownPlugins,
|
|
72
|
-
...props
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
/**
|
|
76
|
-
* A `file` part inside a message: images render inline (click to zoom),
|
|
77
|
-
* anything else becomes a download chip. Covers both directions — files the
|
|
78
|
-
* user attached and files the agent emitted.
|
|
79
|
-
*/
|
|
80
|
-
function MessageAttachment({ part, className, ...props }) {
|
|
81
|
-
const name = part.filename ?? (part.mediaType || "attachment");
|
|
82
|
-
if (part.mediaType.startsWith("image/")) return /* @__PURE__ */ jsx(AttachmentPreview, {
|
|
83
|
-
url: part.url,
|
|
84
|
-
filename: part.filename,
|
|
85
|
-
children: /* @__PURE__ */ jsx(Button, {
|
|
86
|
-
variant: "ghost",
|
|
87
|
-
color: "neutral",
|
|
88
|
-
className: cx("message__attachment-zoom", className),
|
|
89
|
-
"aria-label": `Preview ${name}`,
|
|
90
|
-
...props,
|
|
91
|
-
children: /* @__PURE__ */ jsx("img", {
|
|
92
|
-
className: "message__attachment-image",
|
|
93
|
-
src: part.url,
|
|
94
|
-
alt: part.filename ?? "Attached image"
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
});
|
|
98
|
-
return /* @__PURE__ */ jsxs("a", {
|
|
99
|
-
className: cx("message__attachment", className),
|
|
100
|
-
href: part.url,
|
|
101
|
-
download: part.filename,
|
|
102
|
-
...props,
|
|
103
|
-
children: [/* @__PURE__ */ jsx(FileIcon, { className: "message__attachment-icon" }), /* @__PURE__ */ jsx("span", {
|
|
104
|
-
className: "message__attachment-name",
|
|
105
|
-
children: name
|
|
106
|
-
})]
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Horizontal list of action buttons (copy, retry, thumbs-up, etc.) shown
|
|
111
|
-
* alongside or beneath a message.
|
|
112
|
-
*/
|
|
113
|
-
function MessageActions({ className, children, ref, ...props }) {
|
|
114
|
-
return /* @__PURE__ */ jsx("div", {
|
|
115
|
-
ref,
|
|
116
|
-
className: cx("message__actions", className),
|
|
117
|
-
role: "group",
|
|
118
|
-
...props,
|
|
119
|
-
children
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* A single icon button inside {@link MessageActions}. Always has an accessible
|
|
124
|
-
* name; shows a tooltip on hover/focus when {@link tooltip} is set.
|
|
125
|
-
*/
|
|
126
|
-
function MessageAction({ className, label, tooltip, variant = "ghost", color = "neutral", size = "icon-xs", children, ref, ...props }) {
|
|
127
|
-
const button = /* @__PURE__ */ jsx(Button, {
|
|
128
|
-
ref,
|
|
129
|
-
type: "button",
|
|
130
|
-
variant,
|
|
131
|
-
color,
|
|
132
|
-
size,
|
|
133
|
-
className: cx("message__action", className),
|
|
134
|
-
"aria-label": label ?? tooltip,
|
|
135
|
-
...props,
|
|
136
|
-
children
|
|
137
|
-
});
|
|
138
|
-
if (!tooltip) return button;
|
|
139
|
-
return /* @__PURE__ */ jsxs(Tooltip.Root, { children: [/* @__PURE__ */ jsx(Tooltip.Trigger, { render: button }), /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
|
|
140
|
-
sideOffset: 6,
|
|
141
|
-
children: /* @__PURE__ */ jsx(Tooltip.Popup, { children: tooltip })
|
|
142
|
-
}) })] });
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Horizontal container that places children in a row with space between —
|
|
146
|
-
* typically a {@link MessageBranchSelector} on one side and
|
|
147
|
-
* {@link MessageActions} on the other.
|
|
148
|
-
*/
|
|
149
|
-
function MessageToolbar({ className, children, ref, ...props }) {
|
|
150
|
-
return /* @__PURE__ */ jsx("div", {
|
|
151
|
-
ref,
|
|
152
|
-
className: cx("message__toolbar", className),
|
|
153
|
-
...props,
|
|
154
|
-
children
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
const MessageBranchContext = React.createContext(null);
|
|
158
|
-
function useMessageBranch(component) {
|
|
159
|
-
const ctx = React.useContext(MessageBranchContext);
|
|
160
|
-
if (!ctx) throw new Error(`${component} must be used inside a <MessageBranch>.`);
|
|
161
|
-
return ctx;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Container for a message response with multiple versions. Tracks which
|
|
165
|
-
* branch is active and exposes navigation through {@link MessageBranchSelector},
|
|
166
|
-
* {@link MessageBranchPrevious}, {@link MessageBranchNext}, and {@link MessageBranchPage}.
|
|
167
|
-
*/
|
|
168
|
-
function MessageBranch({ className, defaultBranch = 0, branch, onBranchChange, children, ref, ...props }) {
|
|
169
|
-
const [internalIndex, setInternalIndex] = React.useState(defaultBranch);
|
|
170
|
-
const [branchCount, setBranchCount] = React.useState(0);
|
|
171
|
-
const isControlled = branch !== void 0;
|
|
172
|
-
const branchIndex = isControlled ? branch : internalIndex;
|
|
173
|
-
const setBranchIndex = React.useCallback((next) => {
|
|
174
|
-
if (!isControlled) setInternalIndex(next);
|
|
175
|
-
onBranchChange?.(next);
|
|
176
|
-
}, [isControlled, onBranchChange]);
|
|
177
|
-
const ctx = React.useMemo(() => ({
|
|
178
|
-
branchIndex,
|
|
179
|
-
branchCount,
|
|
180
|
-
setBranchIndex,
|
|
181
|
-
registerCount: setBranchCount
|
|
182
|
-
}), [
|
|
183
|
-
branchCount,
|
|
184
|
-
branchIndex,
|
|
185
|
-
setBranchIndex
|
|
186
|
-
]);
|
|
187
|
-
return /* @__PURE__ */ jsx(MessageBranchContext.Provider, {
|
|
188
|
-
value: ctx,
|
|
189
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
190
|
-
ref,
|
|
191
|
-
className: cx("message__branch", className),
|
|
192
|
-
...props,
|
|
193
|
-
children
|
|
194
|
-
})
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Renders only the active branch's child. Expects siblings to represent
|
|
199
|
-
* alternative versions of the same response.
|
|
200
|
-
*/
|
|
201
|
-
function MessageBranchContent({ className, children, ref, ...props }) {
|
|
202
|
-
const { branchIndex, registerCount } = useMessageBranch("MessageBranchContent");
|
|
203
|
-
const items = React.Children.toArray(children);
|
|
204
|
-
React.useEffect(() => {
|
|
205
|
-
registerCount(items.length);
|
|
206
|
-
}, [items.length, registerCount]);
|
|
207
|
-
const safeIndex = items.length === 0 ? 0 : Math.min(Math.max(branchIndex, 0), items.length - 1);
|
|
208
|
-
return /* @__PURE__ */ jsx("div", {
|
|
209
|
-
ref,
|
|
210
|
-
className: cx("message__branch-content", className),
|
|
211
|
-
...props,
|
|
212
|
-
children: items.map((item, index) => /* @__PURE__ */ jsx("div", {
|
|
213
|
-
className: "message__branch-panel",
|
|
214
|
-
hidden: index !== safeIndex,
|
|
215
|
-
children: item
|
|
216
|
-
}, React.isValidElement(item) && item.key != null ? item.key : index))
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Inline group containing branch navigation controls (previous / page /
|
|
221
|
-
* next). Hidden automatically when there is only one branch.
|
|
222
|
-
*/
|
|
223
|
-
function MessageBranchSelector({ className, children, ref, ...props }) {
|
|
224
|
-
const { branchCount } = useMessageBranch("MessageBranchSelector");
|
|
225
|
-
if (branchCount <= 1) return null;
|
|
226
|
-
return /* @__PURE__ */ jsx("div", {
|
|
227
|
-
ref,
|
|
228
|
-
className: cx("message__branch-selector", className),
|
|
229
|
-
...props,
|
|
230
|
-
children
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
/** Button that selects the previous branch. Disabled at the first branch. */
|
|
234
|
-
function MessageBranchPrevious({ className, label = "Previous response", variant = "ghost", color = "neutral", size = "icon-xs", children, onClick, ref, ...props }) {
|
|
235
|
-
const { branchIndex, branchCount, setBranchIndex } = useMessageBranch("MessageBranchPrevious");
|
|
236
|
-
return /* @__PURE__ */ jsx(Button, {
|
|
237
|
-
ref,
|
|
238
|
-
type: "button",
|
|
239
|
-
variant,
|
|
240
|
-
color,
|
|
241
|
-
size,
|
|
242
|
-
disabled: branchCount <= 1,
|
|
243
|
-
className: cx("message__branch-prev", className),
|
|
244
|
-
"aria-label": label,
|
|
245
|
-
onClick: (event) => {
|
|
246
|
-
onClick?.(event);
|
|
247
|
-
if (!event.defaultPrevented) setBranchIndex(branchIndex > 0 ? branchIndex - 1 : branchCount - 1);
|
|
248
|
-
},
|
|
249
|
-
...props,
|
|
250
|
-
children: children ?? /* @__PURE__ */ jsx(ArrowLeftIcon, {})
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
/** Button that selects the next branch. Disabled at the last branch. */
|
|
254
|
-
function MessageBranchNext({ className, label = "Next response", variant = "ghost", color = "neutral", size = "icon-xs", children, onClick, ref, ...props }) {
|
|
255
|
-
const { branchIndex, branchCount, setBranchIndex } = useMessageBranch("MessageBranchNext");
|
|
256
|
-
return /* @__PURE__ */ jsx(Button, {
|
|
257
|
-
ref,
|
|
258
|
-
type: "button",
|
|
259
|
-
variant,
|
|
260
|
-
color,
|
|
261
|
-
size,
|
|
262
|
-
disabled: branchCount <= 1,
|
|
263
|
-
className: cx("message__branch-next", className),
|
|
264
|
-
"aria-label": label,
|
|
265
|
-
onClick: (event) => {
|
|
266
|
-
onClick?.(event);
|
|
267
|
-
if (!event.defaultPrevented) setBranchIndex(branchIndex < branchCount - 1 ? branchIndex + 1 : 0);
|
|
268
|
-
},
|
|
269
|
-
...props,
|
|
270
|
-
children: children ?? /* @__PURE__ */ jsx(ArrowRightIcon, {})
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
/** Page indicator (e.g. "1 / 3") for the current branch selection. */
|
|
274
|
-
function MessageBranchPage({ className, format, ref, ...props }) {
|
|
275
|
-
const { branchIndex, branchCount } = useMessageBranch("MessageBranchPage");
|
|
276
|
-
const label = format ? format(branchIndex + 1, branchCount) : `${branchIndex + 1} / ${branchCount}`;
|
|
277
|
-
return /* @__PURE__ */ jsx("span", {
|
|
278
|
-
ref,
|
|
279
|
-
className: cx("message__branch-page", className),
|
|
280
|
-
"aria-live": "polite",
|
|
281
|
-
...props,
|
|
282
|
-
children: label
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
//#endregion
|
|
1
|
+
import { a as MessageBranch, c as MessageBranchPage, d as MessageContent, f as MessageResponse, i as MessageAttachment, l as MessageBranchPrevious, n as MessageAction, o as MessageBranchContent, p as MessageToolbar, r as MessageActions, s as MessageBranchNext, t as Message, u as MessageBranchSelector } from "../Message-BkMdE3bS.js";
|
|
286
2
|
export { Message, MessageAction, MessageActions, MessageAttachment, MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, MessageContent, MessageResponse, MessageToolbar };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
|
-
import { t as ArrowDownIcon } from "../icons-
|
|
2
|
+
import { t as ArrowDownIcon } from "../icons-CpfUer49.js";
|
|
3
3
|
import { Button } from "./Button.js";
|
|
4
4
|
import "react";
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -5,7 +5,19 @@ import Cloudflare from "cloudflare";
|
|
|
5
5
|
import { AiModelsSearchObject } from "@cloudflare/workers-types";
|
|
6
6
|
|
|
7
7
|
//#region src/components/ModelSelector.d.ts
|
|
8
|
-
type CloudflareModelSelectorModels = readonly Cloudflare.AI.ModelListResponse[] | readonly AiModelsSearchObject[] | readonly string[];
|
|
8
|
+
type CloudflareModelSelectorModels = readonly Cloudflare.AI.ModelListResponse[] | readonly CloudflareModelCatalogEntry[] | readonly AiModelsSearchObject[] | readonly string[];
|
|
9
|
+
interface CloudflareModelCatalogEntry {
|
|
10
|
+
readonly model_id: string;
|
|
11
|
+
readonly name?: string;
|
|
12
|
+
readonly description?: string;
|
|
13
|
+
readonly task?: string;
|
|
14
|
+
readonly private?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface CloudflareModelCatalogListParams {
|
|
17
|
+
readonly account_id: string;
|
|
18
|
+
readonly task?: string;
|
|
19
|
+
readonly per_page?: number;
|
|
20
|
+
}
|
|
9
21
|
interface CloudflareModelSelectorOption {
|
|
10
22
|
readonly id: string;
|
|
11
23
|
readonly provider: string;
|
|
@@ -36,7 +48,7 @@ declare function readCloudflareModelId(entry: unknown): string | null;
|
|
|
36
48
|
declare function getCloudflareModelProvider(modelId: string): string;
|
|
37
49
|
declare function formatCloudflareModelProvider(provider: string): string;
|
|
38
50
|
declare function normalizeCloudflareModelSelectorModels(models: CloudflareModelSelectorModels): CloudflareModelSelectorOption[];
|
|
39
|
-
declare function listCloudflareModelSelectorOptions(client: Cloudflare, params:
|
|
51
|
+
declare function listCloudflareModelSelectorOptions(client: Cloudflare, params: CloudflareModelCatalogListParams): Promise<CloudflareModelSelectorOption[]>;
|
|
40
52
|
interface ModelSelectorProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
41
53
|
/** Controlled dialog open state. */
|
|
42
54
|
open?: boolean;
|
|
@@ -244,4 +256,4 @@ declare function ModelSelectorShortcut({
|
|
|
244
256
|
ref?: React.Ref<HTMLSpanElement>;
|
|
245
257
|
}): React.JSX.Element;
|
|
246
258
|
//#endregion
|
|
247
|
-
export { CloudflareModelSelector, CloudflareModelSelectorModels, CloudflareModelSelectorOption, CloudflareModelSelectorProps, ModelSelector, ModelSelectorContent, ModelSelectorContentProps, ModelSelectorDialog, ModelSelectorDialogProps, ModelSelectorEmpty, ModelSelectorEmptyProps, ModelSelectorGroup, ModelSelectorGroupProps, ModelSelectorInput, ModelSelectorInputProps, ModelSelectorItem, ModelSelectorItemProps, ModelSelectorList, ModelSelectorListProps, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorLogoGroupProps, ModelSelectorLogoProps, ModelSelectorName, ModelSelectorNameProps, ModelSelectorProps, ModelSelectorSeparator, ModelSelectorSeparatorProps, ModelSelectorShortcut, ModelSelectorShortcutProps, ModelSelectorTrigger, ModelSelectorTriggerProps, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
|
|
259
|
+
export { CloudflareModelCatalogEntry, CloudflareModelCatalogListParams, CloudflareModelSelector, CloudflareModelSelectorModels, CloudflareModelSelectorOption, CloudflareModelSelectorProps, ModelSelector, ModelSelectorContent, ModelSelectorContentProps, ModelSelectorDialog, ModelSelectorDialogProps, ModelSelectorEmpty, ModelSelectorEmptyProps, ModelSelectorGroup, ModelSelectorGroupProps, ModelSelectorInput, ModelSelectorInputProps, ModelSelectorItem, ModelSelectorItemProps, ModelSelectorList, ModelSelectorListProps, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorLogoGroupProps, ModelSelectorLogoProps, ModelSelectorName, ModelSelectorNameProps, ModelSelectorProps, ModelSelectorSeparator, ModelSelectorSeparatorProps, ModelSelectorShortcut, ModelSelectorShortcutProps, ModelSelectorTrigger, ModelSelectorTriggerProps, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as getCloudflareModelProvider, a as ModelSelectorEmpty, b as normalizeCloudflareModelSelectorModels, c as ModelSelectorItem, d as ModelSelectorLogoGroup, f as ModelSelectorName, g as formatCloudflareModelProvider, h as ModelSelectorTrigger, i as ModelSelectorDialog, l as ModelSelectorList, m as ModelSelectorShortcut, n as ModelSelector, o as ModelSelectorGroup, p as ModelSelectorSeparator, r as ModelSelectorContent, s as ModelSelectorInput, t as CloudflareModelSelector, u as ModelSelectorLogo, v as isCloudflareRunnableModelId, x as readCloudflareModelId, y as listCloudflareModelSelectorOptions } from "../ModelSelector-
|
|
1
|
+
import { _ as getCloudflareModelProvider, a as ModelSelectorEmpty, b as normalizeCloudflareModelSelectorModels, c as ModelSelectorItem, d as ModelSelectorLogoGroup, f as ModelSelectorName, g as formatCloudflareModelProvider, h as ModelSelectorTrigger, i as ModelSelectorDialog, l as ModelSelectorList, m as ModelSelectorShortcut, n as ModelSelector, o as ModelSelectorGroup, p as ModelSelectorSeparator, r as ModelSelectorContent, s as ModelSelectorInput, t as CloudflareModelSelector, u as ModelSelectorLogo, v as isCloudflareRunnableModelId, x as readCloudflareModelId, y as listCloudflareModelSelectorOptions } from "../ModelSelector-SlJNgwKY.js";
|
|
2
2
|
export { CloudflareModelSelector, ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorShortcut, ModelSelectorTrigger, formatCloudflareModelProvider, getCloudflareModelProvider, isCloudflareRunnableModelId, listCloudflareModelSelectorOptions, normalizeCloudflareModelSelectorModels, readCloudflareModelId };
|
|
@@ -6,6 +6,15 @@ type NaniteSceneProps = {
|
|
|
6
6
|
readonly className?: string; /** Accessible title when the illustration communicates state. */
|
|
7
7
|
readonly title?: string;
|
|
8
8
|
};
|
|
9
|
+
type NaniteMarkProps = {
|
|
10
|
+
/** Selects one of the established Nanite body colors. */readonly index?: number; /** Additional class names for layout only. */
|
|
11
|
+
readonly className?: string;
|
|
12
|
+
};
|
|
13
|
+
/** Compact decorative Nanite identity mark for dense agent and task UI. */
|
|
14
|
+
declare function NaniteMark({
|
|
15
|
+
index,
|
|
16
|
+
className
|
|
17
|
+
}: NaniteMarkProps): import("react").JSX.Element;
|
|
9
18
|
/**
|
|
10
19
|
* Decorative Nanites illustration used in setup, status, and empty states.
|
|
11
20
|
* Pass a title when the illustration communicates state; otherwise it remains
|
|
@@ -30,4 +39,4 @@ declare function NaniteScene({
|
|
|
30
39
|
title
|
|
31
40
|
}: NaniteSceneProps): import("react").JSX.Element;
|
|
32
41
|
//#endregion
|
|
33
|
-
export { NaniteScene, NaniteSceneProps, NaniteSceneVariant };
|
|
42
|
+
export { NaniteMark, NaniteMarkProps, NaniteScene, NaniteSceneProps, NaniteSceneVariant };
|
|
@@ -22,6 +22,41 @@ const TRIO_XS = [
|
|
|
22
22
|
100,
|
|
23
23
|
160
|
|
24
24
|
];
|
|
25
|
+
/** Compact decorative Nanite identity mark for dense agent and task UI. */
|
|
26
|
+
function NaniteMark({ index = 0, className }) {
|
|
27
|
+
return /* @__PURE__ */ jsx("span", {
|
|
28
|
+
className: ["nanite-mark", className].filter(Boolean).join(" "),
|
|
29
|
+
"aria-hidden": "true",
|
|
30
|
+
children: /* @__PURE__ */ jsxs("svg", {
|
|
31
|
+
viewBox: "-18 -34 36 54",
|
|
32
|
+
focusable: "false",
|
|
33
|
+
fill: "none",
|
|
34
|
+
children: [/* @__PURE__ */ jsx(NaniteBody, { index }), /* @__PURE__ */ jsxs("g", {
|
|
35
|
+
className: "nanite-mark__hat",
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx("path", {
|
|
38
|
+
d: "M -9 -22 Q -9 -31 0 -31 Q 9 -31 9 -22 Z",
|
|
39
|
+
fill: HAT_SHELL
|
|
40
|
+
}),
|
|
41
|
+
/* @__PURE__ */ jsx("rect", {
|
|
42
|
+
x: "-12",
|
|
43
|
+
y: "-23",
|
|
44
|
+
width: "24",
|
|
45
|
+
height: "3.5",
|
|
46
|
+
rx: "1.5",
|
|
47
|
+
fill: HAT_BRIM
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ jsx("circle", {
|
|
50
|
+
cx: "0",
|
|
51
|
+
cy: "-28",
|
|
52
|
+
r: "2",
|
|
53
|
+
fill: HAT_BULB
|
|
54
|
+
})
|
|
55
|
+
]
|
|
56
|
+
})]
|
|
57
|
+
})
|
|
58
|
+
});
|
|
59
|
+
}
|
|
25
60
|
/**
|
|
26
61
|
* Decorative Nanites illustration used in setup, status, and empty states.
|
|
27
62
|
* Pass a title when the illustration communicates state; otherwise it remains
|
|
@@ -402,4 +437,4 @@ function Nanite({ index, cx, cy, scale }) {
|
|
|
402
437
|
});
|
|
403
438
|
}
|
|
404
439
|
//#endregion
|
|
405
|
-
export { NaniteScene };
|
|
440
|
+
export { NaniteMark, NaniteScene };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/components/Pricing.d.ts
|
|
2
|
+
type PricingBillingPeriod = "monthly" | "yearly";
|
|
3
|
+
/** A feature presented within a pricing plan. */
|
|
4
|
+
interface PlanFeature {
|
|
5
|
+
name: string;
|
|
6
|
+
included: boolean;
|
|
7
|
+
tooltip?: string;
|
|
8
|
+
limit?: string;
|
|
9
|
+
}
|
|
10
|
+
/** A purchasable plan presented by the pricing surfaces. */
|
|
11
|
+
interface Plan {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
monthlyPrice: number;
|
|
16
|
+
yearlyPrice: number;
|
|
17
|
+
features: PlanFeature[];
|
|
18
|
+
popular?: boolean;
|
|
19
|
+
cta?: string;
|
|
20
|
+
}
|
|
21
|
+
/** A question and answer presented by PricingFAQ. */
|
|
22
|
+
interface FAQItem {
|
|
23
|
+
question: string;
|
|
24
|
+
answer: string;
|
|
25
|
+
}
|
|
26
|
+
/** A threshold and monthly price presented by PricingUsageCalculator. */
|
|
27
|
+
interface UsageTier {
|
|
28
|
+
limit: number;
|
|
29
|
+
price: number;
|
|
30
|
+
label: string;
|
|
31
|
+
}
|
|
32
|
+
declare function getPlanPrice(plan: Plan, billingPeriod: PricingBillingPeriod): number;
|
|
33
|
+
declare function getPlanYearlySavings(plan: Plan): number;
|
|
34
|
+
declare function formatPricingUsage(value: number): string;
|
|
35
|
+
declare function getUsagePrice(usageTiers: readonly UsageTier[], usage: number): number;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { FAQItem, Plan, PlanFeature, PricingBillingPeriod, UsageTier, formatPricingUsage, getPlanPrice, getPlanYearlySavings, getUsagePrice };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/components/Pricing.ts
|
|
2
|
+
function getPlanPrice(plan, billingPeriod) {
|
|
3
|
+
return billingPeriod === "yearly" ? plan.yearlyPrice : plan.monthlyPrice;
|
|
4
|
+
}
|
|
5
|
+
function getPlanYearlySavings(plan) {
|
|
6
|
+
return (plan.monthlyPrice - plan.yearlyPrice) * 12;
|
|
7
|
+
}
|
|
8
|
+
function formatPricingUsage(value) {
|
|
9
|
+
if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
|
|
10
|
+
if (value >= 1e3) return `${(value / 1e3).toFixed(0)}K`;
|
|
11
|
+
return value.toString();
|
|
12
|
+
}
|
|
13
|
+
function getUsagePrice(usageTiers, usage) {
|
|
14
|
+
return usageTiers.findLast((tier) => usage >= tier.limit)?.price ?? usageTiers[0]?.price ?? 0;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { formatPricingUsage, getPlanPrice, getPlanYearlySavings, getUsagePrice };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PricingBillingPeriod } from "./Pricing.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/PricingBillingToggle.d.ts
|
|
5
|
+
interface PricingBillingToggleProps {
|
|
6
|
+
value: PricingBillingPeriod;
|
|
7
|
+
onValueChange: (value: PricingBillingPeriod) => void;
|
|
8
|
+
yearlySavingsPercent: number;
|
|
9
|
+
/** Fixes the presentation. Omit only in component demos that expose the style switcher. */
|
|
10
|
+
variant?: "switch" | "buttons";
|
|
11
|
+
/** Additional class name for placement in a consuming layout. */
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Controlled billing-period selector composed from the shared Switch or ToggleGroup. */
|
|
15
|
+
declare function PricingBillingToggle({
|
|
16
|
+
value,
|
|
17
|
+
onValueChange,
|
|
18
|
+
yearlySavingsPercent,
|
|
19
|
+
variant,
|
|
20
|
+
className
|
|
21
|
+
}: PricingBillingToggleProps): React.JSX.Element;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { PricingBillingToggle, PricingBillingToggleProps };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { t as cx } from "../class-names-9UtZwb0J.js";
|
|
2
|
+
import { Badge } from "./Badge.js";
|
|
3
|
+
import { Checkbox } from "./Checkbox.js";
|
|
4
|
+
import { Switch } from "./Switch.js";
|
|
5
|
+
import { Label } from "./Label.js";
|
|
6
|
+
import { ToggleGroup } from "./ToggleGroup.js";
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/components/PricingBillingToggle.tsx
|
|
10
|
+
/** Controlled billing-period selector composed from the shared Switch or ToggleGroup. */
|
|
11
|
+
function PricingBillingToggle({ value, onValueChange, yearlySavingsPercent, variant, className }) {
|
|
12
|
+
const [demoVariant, setDemoVariant] = React.useState("switch");
|
|
13
|
+
const demoToggleId = React.useId();
|
|
14
|
+
const resolvedVariant = variant ?? demoVariant;
|
|
15
|
+
const isYearly = value === "yearly";
|
|
16
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
17
|
+
className: cx("pricing-page__billing-toggle", className),
|
|
18
|
+
children: [!variant ? /* @__PURE__ */ jsxs("div", {
|
|
19
|
+
className: "pricing-page__toggle-options",
|
|
20
|
+
children: [/* @__PURE__ */ jsx(Checkbox.Root, {
|
|
21
|
+
checked: demoVariant === "switch",
|
|
22
|
+
onCheckedChange: (checked) => setDemoVariant(checked ? "switch" : "buttons"),
|
|
23
|
+
id: demoToggleId,
|
|
24
|
+
children: /* @__PURE__ */ jsx(Checkbox.Indicator, {})
|
|
25
|
+
}), /* @__PURE__ */ jsx(Label, {
|
|
26
|
+
htmlFor: demoToggleId,
|
|
27
|
+
className: "pricing-page__toggle-label",
|
|
28
|
+
children: "Use switch style"
|
|
29
|
+
})]
|
|
30
|
+
}) : null, resolvedVariant === "switch" ? /* @__PURE__ */ jsxs("div", {
|
|
31
|
+
className: "pricing-page__switch-container",
|
|
32
|
+
children: [
|
|
33
|
+
/* @__PURE__ */ jsx("span", {
|
|
34
|
+
className: "pricing-page__period-label",
|
|
35
|
+
"data-active": !isYearly || void 0,
|
|
36
|
+
children: "Monthly"
|
|
37
|
+
}),
|
|
38
|
+
/* @__PURE__ */ jsx(Switch.Root, {
|
|
39
|
+
checked: isYearly,
|
|
40
|
+
onCheckedChange: (checked) => onValueChange(checked ? "yearly" : "monthly"),
|
|
41
|
+
"aria-label": "Toggle yearly billing",
|
|
42
|
+
children: /* @__PURE__ */ jsx(Switch.Thumb, {})
|
|
43
|
+
}),
|
|
44
|
+
/* @__PURE__ */ jsxs("span", {
|
|
45
|
+
className: "pricing-page__period-label",
|
|
46
|
+
"data-active": isYearly || void 0,
|
|
47
|
+
children: ["Yearly", /* @__PURE__ */ jsxs(Badge, {
|
|
48
|
+
color: "success",
|
|
49
|
+
size: "sm",
|
|
50
|
+
className: "pricing-page__billing-badge",
|
|
51
|
+
children: [
|
|
52
|
+
"Save ",
|
|
53
|
+
yearlySavingsPercent,
|
|
54
|
+
"%"
|
|
55
|
+
]
|
|
56
|
+
})]
|
|
57
|
+
})
|
|
58
|
+
]
|
|
59
|
+
}) : /* @__PURE__ */ jsxs(ToggleGroup.Root, {
|
|
60
|
+
"aria-label": "Billing period",
|
|
61
|
+
value: [value],
|
|
62
|
+
onValueChange: (nextValue) => {
|
|
63
|
+
const nextPeriod = nextValue[0];
|
|
64
|
+
if (nextPeriod === "monthly" || nextPeriod === "yearly") onValueChange(nextPeriod);
|
|
65
|
+
},
|
|
66
|
+
children: [/* @__PURE__ */ jsx(ToggleGroup.Item, {
|
|
67
|
+
value: "monthly",
|
|
68
|
+
children: "Monthly"
|
|
69
|
+
}), /* @__PURE__ */ jsxs(ToggleGroup.Item, {
|
|
70
|
+
value: "yearly",
|
|
71
|
+
children: ["Yearly", /* @__PURE__ */ jsxs(Badge, {
|
|
72
|
+
color: "success",
|
|
73
|
+
size: "sm",
|
|
74
|
+
className: "pricing-page__billing-badge",
|
|
75
|
+
children: [
|
|
76
|
+
"-",
|
|
77
|
+
yearlySavingsPercent,
|
|
78
|
+
"%"
|
|
79
|
+
]
|
|
80
|
+
})]
|
|
81
|
+
})]
|
|
82
|
+
})]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { PricingBillingToggle };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Plan, PricingBillingPeriod } from "./Pricing.js";
|
|
2
|
+
import { PricingPlanAction } from "./PricingPlanCard.js";
|
|
3
|
+
|
|
4
|
+
//#region src/components/PricingConfirmationDialog.d.ts
|
|
5
|
+
interface PricingConfirmationDialogProps {
|
|
6
|
+
open: boolean;
|
|
7
|
+
onOpenChange: (open: boolean) => void;
|
|
8
|
+
plan: Plan | null;
|
|
9
|
+
billingPeriod: PricingBillingPeriod;
|
|
10
|
+
action?: Exclude<PricingPlanAction, "current" | "select">;
|
|
11
|
+
switching?: boolean;
|
|
12
|
+
onConfirm: () => void | Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
/** Confirmation surface for subscribing to or changing a pricing plan. */
|
|
15
|
+
declare function PricingConfirmationDialog({
|
|
16
|
+
open,
|
|
17
|
+
onOpenChange,
|
|
18
|
+
plan,
|
|
19
|
+
billingPeriod,
|
|
20
|
+
action,
|
|
21
|
+
switching,
|
|
22
|
+
onConfirm
|
|
23
|
+
}: PricingConfirmationDialogProps): import("react").JSX.Element;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { PricingConfirmationDialog, PricingConfirmationDialogProps };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Button } from "./Button.js";
|
|
2
|
+
import { AlertDialog } from "./AlertDialog.js";
|
|
3
|
+
import { getPlanPrice, getPlanYearlySavings } from "./Pricing.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/PricingConfirmationDialog.tsx
|
|
6
|
+
function getActionLabel(action) {
|
|
7
|
+
if (action === "downgrade") return "Downgrade";
|
|
8
|
+
if (action === "switch") return "Switch";
|
|
9
|
+
return "Upgrade";
|
|
10
|
+
}
|
|
11
|
+
/** Confirmation surface for subscribing to or changing a pricing plan. */
|
|
12
|
+
function PricingConfirmationDialog({ open, onOpenChange, plan, billingPeriod, action, switching = false, onConfirm }) {
|
|
13
|
+
const isYearly = billingPeriod === "yearly";
|
|
14
|
+
const actionLabel = getActionLabel(action);
|
|
15
|
+
return /* @__PURE__ */ jsx(AlertDialog.Root, {
|
|
16
|
+
open,
|
|
17
|
+
onOpenChange,
|
|
18
|
+
children: /* @__PURE__ */ jsxs(AlertDialog.Portal, { children: [/* @__PURE__ */ jsx(AlertDialog.Backdrop, {}), /* @__PURE__ */ jsx(AlertDialog.Viewport, { children: /* @__PURE__ */ jsxs(AlertDialog.Popup, { children: [
|
|
19
|
+
/* @__PURE__ */ jsx(AlertDialog.Title, { children: action && plan ? `${actionLabel} to ${plan.name}?` : `Subscribe to ${plan?.name}?` }),
|
|
20
|
+
/* @__PURE__ */ jsx(AlertDialog.Description, { children: action && plan ? action === "downgrade" ? `You'll be downgraded to the ${plan.name} plan. A prorated credit will be applied to your next invoice.` : `You'll be upgraded to the ${plan.name} plan. The prorated difference will be added to your next invoice.` : `You're about to subscribe to the ${plan?.name} plan at $${plan ? getPlanPrice(plan, billingPeriod) : 0}/month${isYearly ? " (billed yearly)" : ""}.` }),
|
|
21
|
+
plan ? /* @__PURE__ */ jsxs("div", {
|
|
22
|
+
className: "pricing-page__confirm-summary",
|
|
23
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
24
|
+
className: "pricing-page__confirm-row",
|
|
25
|
+
children: [/* @__PURE__ */ jsxs("span", { children: [
|
|
26
|
+
plan.name,
|
|
27
|
+
" Plan (",
|
|
28
|
+
isYearly ? "Yearly" : "Monthly",
|
|
29
|
+
")"
|
|
30
|
+
] }), /* @__PURE__ */ jsxs("span", { children: [
|
|
31
|
+
"$",
|
|
32
|
+
getPlanPrice(plan, billingPeriod),
|
|
33
|
+
"/mo"
|
|
34
|
+
] })]
|
|
35
|
+
}), isYearly ? /* @__PURE__ */ jsxs("div", {
|
|
36
|
+
className: "pricing-page__confirm-row",
|
|
37
|
+
"data-savings": true,
|
|
38
|
+
children: [/* @__PURE__ */ jsx("span", { children: "Annual savings" }), /* @__PURE__ */ jsxs("span", { children: ["-$", getPlanYearlySavings(plan)] })]
|
|
39
|
+
}) : null]
|
|
40
|
+
}) : null,
|
|
41
|
+
/* @__PURE__ */ jsxs("div", {
|
|
42
|
+
className: "pricing-page__confirm-actions",
|
|
43
|
+
children: [/* @__PURE__ */ jsx(AlertDialog.Close, {
|
|
44
|
+
disabled: switching,
|
|
45
|
+
children: "Cancel"
|
|
46
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
47
|
+
color: "primary",
|
|
48
|
+
onClick: onConfirm,
|
|
49
|
+
disabled: switching,
|
|
50
|
+
children: switching ? "Switching…" : action ? `Confirm ${actionLabel}` : "Confirm"
|
|
51
|
+
})]
|
|
52
|
+
})
|
|
53
|
+
] }) })] })
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { PricingConfirmationDialog };
|