@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.
Files changed (241) hide show
  1. package/dist/AgentActivity-BNUNrP9O.d.ts +36 -0
  2. package/dist/{AgentChat-Cgb1xuT7.d.ts → AgentChat-CrlpbvQJ.d.ts} +62 -8
  3. package/dist/{CodeBlock-DUh9WOGo.d.ts → CodeBlock-BRajW4QU.d.ts} +1 -1
  4. package/dist/{CodeBlock-BUFXG8HW.js → CodeBlock-BmB4Xaqq.js} +15 -4
  5. package/dist/{FileTree-mpEIcfzA.js → FileTree-CkVbIMWV.js} +82 -89
  6. package/dist/Message-BkMdE3bS.js +375 -0
  7. package/dist/{ModelSelector-DVgVBdvw.js → ModelSelector-SlJNgwKY.js} +17 -8
  8. package/dist/{PromptInput-ClNqBiIw.d.ts → PromptInput-BWTuXMOD.d.ts} +123 -5
  9. package/dist/ResponsiveSidebarShell-Dd9DCcBT.d.ts +67 -0
  10. package/dist/{Select-Dl_vF_Bt.d.ts → Select-BeEsefzh.d.ts} +12 -2
  11. package/dist/{ThinkChat-7DQ2CogF.js → ThinkChat-CzC-zNGA.js} +27 -37
  12. package/dist/{ThinkChatActivity-m9orbdeI.d.ts → ThinkChatActivity-BFQnb2ct.d.ts} +3 -10
  13. package/dist/ThinkChatActivitySummary-BPmu9a-c.d.ts +39 -0
  14. package/dist/{ThinkChatToolParts-Cv4o7j6F.d.ts → ThinkChatToolParts-CSzVwMXf.d.ts} +62 -3
  15. package/dist/ThinkExecutionRun-ChhWhOoU.d.ts +30 -0
  16. package/dist/Toggle-CAAlNl-M.d.ts +69 -0
  17. package/dist/ToggleGroup-8hPv-b69.d.ts +73 -0
  18. package/dist/Workspace-D39LxGvP.d.ts +62 -0
  19. package/dist/WorkspaceFile-DOZkPwzu.d.ts +106 -0
  20. package/dist/WorkspaceFileView-rSN_yT0L.js +744 -0
  21. package/dist/WorkspaceLink-DIPbXrUM.js +337 -0
  22. package/dist/WorkspaceLink-DK1DWMHe.d.ts +89 -0
  23. package/dist/components/Activity.d.ts +27 -1
  24. package/dist/components/Activity.js +33 -15
  25. package/dist/components/AgentActivity.d.ts +2 -0
  26. package/dist/components/AgentActivity.js +45 -0
  27. package/dist/components/AgentActivityPreview.d.ts +46 -0
  28. package/dist/components/AgentActivityPreview.js +94 -0
  29. package/dist/components/AgentAttention.d.ts +73 -0
  30. package/dist/components/AgentAttention.js +85 -0
  31. package/dist/components/AgentChat.d.ts +2 -2
  32. package/dist/components/AgentChat.js +231 -205
  33. package/dist/components/AgentChatMessageEditor.d.ts +29 -0
  34. package/dist/components/AgentChatMessageEditor.js +92 -0
  35. package/dist/components/AgentChatTurnError.d.ts +17 -0
  36. package/dist/components/AgentChatTurnError.js +40 -0
  37. package/dist/components/AgentConnection.d.ts +12 -17
  38. package/dist/components/AgentConnection.js +99 -91
  39. package/dist/components/AppFrame.d.ts +24 -0
  40. package/dist/components/AppFrame.js +25 -0
  41. package/dist/components/AppTopBar.d.ts +71 -0
  42. package/dist/components/AppTopBar.js +82 -0
  43. package/dist/components/Artifact.js +1 -1
  44. package/dist/components/BrowserLiveView.js +1 -1
  45. package/dist/components/BrowserReplay.js +1 -1
  46. package/dist/components/BrowserRunPanel.js +1 -1
  47. package/dist/components/Card.d.ts +3 -0
  48. package/dist/components/Card.js +2 -1
  49. package/dist/components/ChainOfThought.d.ts +1 -1
  50. package/dist/components/ChainOfThought.js +1 -1
  51. package/dist/components/ChatGptSignInScreen.js +2 -2
  52. package/dist/components/Checkbox.js +5 -13
  53. package/dist/components/CheckboxGroup.d.ts +58 -2
  54. package/dist/components/CheckboxGroup.js +59 -1
  55. package/dist/components/CodeBlock.d.ts +1 -1
  56. package/dist/components/CodeBlock.js +1 -1
  57. package/dist/components/CodexModelSelector.js +1 -1
  58. package/dist/components/Commit.js +2 -2
  59. package/dist/components/ContextMenu.js +1 -1
  60. package/dist/components/Conversation.js +1 -1
  61. package/dist/components/DescriptionList.d.ts +12 -0
  62. package/dist/components/DescriptionList.js +11 -0
  63. package/dist/components/DescriptionListParts.d.ts +37 -0
  64. package/dist/components/DescriptionListParts.js +35 -0
  65. package/dist/components/EnvironmentVariables.js +2 -2
  66. package/dist/components/Fieldset.d.ts +13 -1
  67. package/dist/components/Fieldset.js +11 -2
  68. package/dist/components/FileTree.js +1 -1
  69. package/dist/components/IconButton.d.ts +33 -0
  70. package/dist/components/IconButton.js +27 -0
  71. package/dist/components/McpConnectionRequest.d.ts +44 -0
  72. package/dist/components/McpConnectionRequest.js +122 -0
  73. package/dist/components/McpServerPicker.d.ts +48 -23
  74. package/dist/components/McpServerPicker.js +238 -189
  75. package/dist/components/Menubar.js +1 -1
  76. package/dist/components/Message.d.ts +1 -0
  77. package/dist/components/Message.js +1 -285
  78. package/dist/components/MessageScroller.js +1 -1
  79. package/dist/components/ModelSelector.d.ts +15 -3
  80. package/dist/components/ModelSelector.js +1 -1
  81. package/dist/components/NaniteScene.d.ts +10 -1
  82. package/dist/components/NaniteScene.js +36 -1
  83. package/dist/components/Pricing.d.ts +37 -0
  84. package/dist/components/Pricing.js +17 -0
  85. package/dist/components/PricingBillingToggle.d.ts +23 -0
  86. package/dist/components/PricingBillingToggle.js +86 -0
  87. package/dist/components/PricingConfirmationDialog.d.ts +25 -0
  88. package/dist/components/PricingConfirmationDialog.js +57 -0
  89. package/dist/components/PricingFAQ.d.ts +18 -0
  90. package/dist/components/PricingFAQ.js +27 -0
  91. package/dist/components/PricingPage.d.ts +2 -38
  92. package/dist/components/PricingPage.js +39 -359
  93. package/dist/components/PricingPlanCard.d.ts +22 -0
  94. package/dist/components/PricingPlanCard.js +109 -0
  95. package/dist/components/PricingUsageCalculator.d.ts +22 -0
  96. package/dist/components/PricingUsageCalculator.js +96 -0
  97. package/dist/components/PromptInput.d.ts +2 -2
  98. package/dist/components/PromptInput.js +210 -15
  99. package/dist/components/Queue.js +1 -1
  100. package/dist/components/Reasoning.d.ts +2 -1
  101. package/dist/components/Reasoning.js +14 -29
  102. package/dist/components/ResizableSidePanel.d.ts +57 -0
  103. package/dist/components/ResizableSidePanel.js +151 -0
  104. package/dist/components/ResponsiveSidebarShell.d.ts +2 -0
  105. package/dist/components/ResponsiveSidebarShell.js +129 -0
  106. package/dist/components/Select.d.ts +2 -2
  107. package/dist/components/Select.js +11 -2
  108. package/dist/components/Slider.d.ts +13 -1
  109. package/dist/components/Slider.js +11 -0
  110. package/dist/components/Sources.js +1 -1
  111. package/dist/components/Stepper.d.ts +4 -0
  112. package/dist/components/Stepper.js +5 -3
  113. package/dist/components/SubagentRun.d.ts +86 -0
  114. package/dist/components/SubagentRun.js +108 -0
  115. package/dist/components/SubagentRunDetails.d.ts +44 -0
  116. package/dist/components/SubagentRunDetails.js +48 -0
  117. package/dist/components/SubagentRunIndicator.d.ts +22 -0
  118. package/dist/components/SubagentRunIndicator.js +33 -0
  119. package/dist/components/SubagentRunList.d.ts +25 -0
  120. package/dist/components/SubagentRunList.js +26 -0
  121. package/dist/components/SubagentRunSelector.d.ts +47 -0
  122. package/dist/components/SubagentRunSelector.js +55 -0
  123. package/dist/components/Task.js +1 -1
  124. package/dist/components/Terminal.js +2 -2
  125. package/dist/components/TestResults.js +1 -1
  126. package/dist/components/Textarea.d.ts +21 -0
  127. package/dist/components/Textarea.js +19 -0
  128. package/dist/components/ThemeModeControl.d.ts +24 -0
  129. package/dist/components/ThemeModeControl.js +52 -0
  130. package/dist/components/ThemeProvider.d.ts +38 -0
  131. package/dist/components/ThemeProvider.js +80 -0
  132. package/dist/components/ThinkChat.d.ts +34 -7
  133. package/dist/components/ThinkChat.js +7 -4
  134. package/dist/components/ThinkChatActivity.d.ts +3 -2
  135. package/dist/components/ThinkChatActivity.js +18 -297
  136. package/dist/components/ThinkChatActivitySummary.d.ts +2 -0
  137. package/dist/components/ThinkChatActivitySummary.js +421 -0
  138. package/dist/components/ThinkChatToolPanels.d.ts +15 -5
  139. package/dist/components/ThinkChatToolPanels.js +116 -9
  140. package/dist/components/ThinkChatToolParts.d.ts +2 -2
  141. package/dist/components/ThinkChatToolParts.js +51 -9
  142. package/dist/components/ThinkExecutionDetail.d.ts +20 -0
  143. package/dist/components/ThinkExecutionDetail.js +80 -0
  144. package/dist/components/ThinkExecutionRun.d.ts +2 -0
  145. package/dist/components/ThinkExecutionRun.js +72 -0
  146. package/dist/components/ThinkExecutionStatus.d.ts +22 -0
  147. package/dist/components/ThinkExecutionStatus.js +36 -0
  148. package/dist/components/ThinkExecutionWorkbench.d.ts +7 -0
  149. package/dist/components/ThinkExecutionWorkbench.js +69 -225
  150. package/dist/components/ThinkFullApp.d.ts +58 -14
  151. package/dist/components/ThinkFullApp.js +129 -160
  152. package/dist/components/ThinkFullAppViewSwitch.d.ts +31 -0
  153. package/dist/components/ThinkFullAppViewSwitch.js +34 -0
  154. package/dist/components/ThinkRoutine.d.ts +36 -0
  155. package/dist/components/ThinkRoutine.js +15 -0
  156. package/dist/components/ThinkRoutineBrowser.d.ts +25 -0
  157. package/dist/components/ThinkRoutineBrowser.js +156 -0
  158. package/dist/components/ThinkRoutineDetail.d.ts +24 -0
  159. package/dist/components/ThinkRoutineDetail.js +102 -0
  160. package/dist/components/ThinkRoutineForm.d.ts +32 -0
  161. package/dist/components/ThinkRoutineForm.js +151 -0
  162. package/dist/components/ThinkRoutineLibrary.d.ts +74 -0
  163. package/dist/components/ThinkRoutineLibrary.js +178 -0
  164. package/dist/components/ThinkRoutineRuns.d.ts +24 -0
  165. package/dist/components/ThinkRoutineRuns.js +68 -0
  166. package/dist/components/ThinkThreadPicker.d.ts +18 -1
  167. package/dist/components/ThinkThreadPicker.js +51 -5
  168. package/dist/components/ThinkThreadShell.d.ts +12 -9
  169. package/dist/components/ThinkThreadShell.js +17 -137
  170. package/dist/components/Toggle.d.ts +1 -68
  171. package/dist/components/ToggleGroup.d.ts +1 -72
  172. package/dist/components/Tooltip.d.ts +3 -1
  173. package/dist/components/Tooltip.js +4 -2
  174. package/dist/components/WebPreview.js +1 -1
  175. package/dist/components/Workspace.d.ts +2 -0
  176. package/dist/components/Workspace.js +424 -0
  177. package/dist/components/WorkspaceBrowser.d.ts +32 -0
  178. package/dist/components/WorkspaceBrowser.js +103 -0
  179. package/dist/components/WorkspaceExplorer.d.ts +12 -79
  180. package/dist/components/WorkspaceExplorer.js +116 -330
  181. package/dist/components/WorkspaceFile.d.ts +2 -0
  182. package/dist/components/WorkspaceFile.js +195 -0
  183. package/dist/components/WorkspaceFileView.d.ts +26 -0
  184. package/dist/components/WorkspaceFileView.js +2 -0
  185. package/dist/components/WorkspaceHeader.d.ts +35 -0
  186. package/dist/components/WorkspaceHeader.js +51 -0
  187. package/dist/components/WorkspaceLink.d.ts +2 -0
  188. package/dist/components/WorkspaceLink.js +2 -0
  189. package/dist/components/icons.d.ts +2 -2
  190. package/dist/components/icons.js +2 -2
  191. package/dist/{copy-button-DUMLYdsk.js → copy-button-Dejn5heL.js} +1 -1
  192. package/dist/icons-CpfUer49.js +85 -0
  193. package/dist/{icons-CUCz_Sft.d.ts → icons-GQd1xF4e.d.ts} +51 -1
  194. package/dist/styles/activity-header.css +75 -0
  195. package/dist/styles/activity.css +49 -63
  196. package/dist/styles/agent-activity-preview-overlay.css +80 -0
  197. package/dist/styles/agent-activity-preview.css +235 -0
  198. package/dist/styles/agent-attention.css +122 -0
  199. package/dist/styles/agent-chat.css +141 -4
  200. package/dist/styles/app-frame.css +15 -0
  201. package/dist/styles/app-top-bar.css +100 -0
  202. package/dist/styles/avatar.css +0 -1
  203. package/dist/styles/browser-control-overlay.css +184 -0
  204. package/dist/styles/card.css +21 -0
  205. package/dist/styles/checkbox-group.css +69 -0
  206. package/dist/styles/description-list.css +50 -0
  207. package/dist/styles/fieldset.css +11 -0
  208. package/dist/styles/index.css +15 -2
  209. package/dist/styles/mcp-connection-request.css +60 -0
  210. package/dist/styles/mcp-server-picker.css +95 -68
  211. package/dist/styles/message.css +4 -43
  212. package/dist/styles/nanite-scene.css +16 -0
  213. package/dist/styles/pricing-page.css +21 -27
  214. package/dist/styles/prompt-input.css +225 -32
  215. package/dist/styles/reasoning.css +1 -55
  216. package/dist/styles/recipes.css +23 -15
  217. package/dist/styles/resizable-side-panel.css +66 -0
  218. package/dist/styles/responsive-sidebar-shell.css +169 -0
  219. package/dist/styles/select.css +10 -0
  220. package/dist/styles/stepper.css +13 -0
  221. package/dist/styles/streamdown.css +0 -4
  222. package/dist/styles/subagent-run.css +205 -0
  223. package/dist/styles/textarea.css +20 -0
  224. package/dist/styles/theme-mode-control.css +72 -0
  225. package/dist/styles/think-execution-status.css +49 -0
  226. package/dist/styles/think-execution-workbench.css +8 -72
  227. package/dist/styles/think-full-app.css +106 -131
  228. package/dist/styles/think-routine-library.css +491 -0
  229. package/dist/styles/think-thread-picker.css +47 -3
  230. package/dist/styles/toggle-group.css +7 -0
  231. package/dist/styles/workspace-explorer.css +511 -64
  232. package/dist/utils/codex-model-catalog.d.ts +4 -4
  233. package/dist/utils/mcp-server-catalog.d.ts +82 -78
  234. package/dist/utils/mcp-server-catalog.js +64 -41
  235. package/dist/utils/structured-code.d.ts +1 -1
  236. package/dist/utils/theme.d.ts +22 -0
  237. package/dist/utils/theme.js +55 -0
  238. package/package.json +34 -28
  239. package/dist/icons-Ba9THQKz.js +0 -64
  240. package/dist/styles/think-resize-handle.css +0 -33
  241. package/dist/styles/think-thread-shell.css +0 -219
@@ -0,0 +1,18 @@
1
+ import { FAQItem } from "./Pricing.js";
2
+ import * as React from "react";
3
+
4
+ //#region src/components/PricingFAQ.d.ts
5
+ interface PricingFAQProps {
6
+ items: readonly FAQItem[];
7
+ title?: string;
8
+ /** Additional class name for placement in a consuming layout. */
9
+ className?: string;
10
+ }
11
+ /** Pricing FAQ section composed from the shared Base UI-backed Accordion. */
12
+ declare function PricingFAQ({
13
+ items,
14
+ title,
15
+ className
16
+ }: PricingFAQProps): React.JSX.Element | null;
17
+ //#endregion
18
+ export { PricingFAQ, PricingFAQProps };
@@ -0,0 +1,27 @@
1
+ import { Accordion } from "./Accordion.js";
2
+ import { t as cx } from "../class-names-9UtZwb0J.js";
3
+ import * as React from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/PricingFAQ.tsx
6
+ /** Pricing FAQ section composed from the shared Base UI-backed Accordion. */
7
+ function PricingFAQ({ items, title = "Frequently Asked Questions", className }) {
8
+ const titleId = React.useId();
9
+ if (items.length === 0) return null;
10
+ return /* @__PURE__ */ jsxs("section", {
11
+ className: cx("pricing-page__faq", className),
12
+ "aria-labelledby": titleId,
13
+ children: [/* @__PURE__ */ jsx("h2", {
14
+ id: titleId,
15
+ className: "pricing-page__faq-title",
16
+ children: title
17
+ }), /* @__PURE__ */ jsx(Accordion.Root, {
18
+ className: "pricing-page__faq-accordion",
19
+ children: items.map((item) => /* @__PURE__ */ jsxs(Accordion.Item, {
20
+ value: item.question,
21
+ children: [/* @__PURE__ */ jsx(Accordion.Header, { children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: item.question }) }), /* @__PURE__ */ jsx(Accordion.Panel, { children: /* @__PURE__ */ jsx("p", { children: item.answer }) })]
22
+ }, item.question))
23
+ })]
24
+ });
25
+ }
26
+ //#endregion
27
+ export { PricingFAQ };
@@ -1,43 +1,7 @@
1
+ import { FAQItem, Plan, PlanFeature, UsageTier } from "./Pricing.js";
1
2
  import * as React from "react";
2
3
 
3
4
  //#region src/components/PricingPage.d.ts
4
- /**
5
- * Plan feature definition
6
- */
7
- interface PlanFeature {
8
- name: string;
9
- included: boolean;
10
- tooltip?: string;
11
- limit?: string;
12
- }
13
- /**
14
- * Plan definition for the pricing page
15
- */
16
- interface Plan {
17
- id: string;
18
- name: string;
19
- description: string;
20
- monthlyPrice: number;
21
- yearlyPrice: number;
22
- features: PlanFeature[];
23
- popular?: boolean;
24
- cta?: string;
25
- }
26
- /**
27
- * FAQ item definition
28
- */
29
- interface FAQItem {
30
- question: string;
31
- answer: string;
32
- }
33
- /**
34
- * Usage tier for calculator
35
- */
36
- interface UsageTier {
37
- limit: number;
38
- price: number;
39
- label: string;
40
- }
41
5
  interface PricingPageProps {
42
6
  /**
43
7
  * The title of the pricing page
@@ -206,4 +170,4 @@ declare function PricingPage({
206
170
  onPortalRedirect
207
171
  }: PricingPageProps): React.JSX.Element;
208
172
  //#endregion
209
- export { FAQItem, Plan, PlanFeature, PricingPage, PricingPageProps, UsageTier };
173
+ export { type FAQItem, type Plan, type PlanFeature, PricingPage, PricingPageProps, type UsageTier };
@@ -1,80 +1,12 @@
1
- import { Accordion } from "./Accordion.js";
2
- import { Separator } from "./Separator.js";
3
- import { Button } from "./Button.js";
4
- import { Tooltip } from "./Tooltip.js";
5
- import { AlertDialog } from "./AlertDialog.js";
6
- import { Badge } from "./Badge.js";
7
- import { Slider } from "./Slider.js";
8
- import { Card } from "./Card.js";
9
- import { Checkbox } from "./Checkbox.js";
10
- import { Switch } from "./Switch.js";
11
- import { Label } from "./Label.js";
12
- import { ToggleGroup } from "./ToggleGroup.js";
13
- import { Progress } from "./Progress.js";
1
+ import { getPlanPrice } from "./Pricing.js";
2
+ import { PricingBillingToggle } from "./PricingBillingToggle.js";
3
+ import { PricingConfirmationDialog } from "./PricingConfirmationDialog.js";
4
+ import { PricingFAQ } from "./PricingFAQ.js";
5
+ import { PricingPlanCard } from "./PricingPlanCard.js";
6
+ import { PricingUsageCalculator } from "./PricingUsageCalculator.js";
14
7
  import * as React from "react";
15
8
  import { jsx, jsxs } from "react/jsx-runtime";
16
9
  //#region src/components/PricingPage.tsx
17
- const CheckIcon = () => /* @__PURE__ */ jsx("svg", {
18
- width: "16",
19
- height: "16",
20
- viewBox: "0 0 16 16",
21
- fill: "none",
22
- xmlns: "http://www.w3.org/2000/svg",
23
- "aria-hidden": "true",
24
- focusable: "false",
25
- children: /* @__PURE__ */ jsx("path", {
26
- d: "M13.5 4.5L6.5 11.5L3 8",
27
- stroke: "currentColor",
28
- strokeWidth: "2",
29
- strokeLinecap: "round",
30
- strokeLinejoin: "round"
31
- })
32
- });
33
- const MinusIcon = () => /* @__PURE__ */ jsx("svg", {
34
- width: "16",
35
- height: "16",
36
- viewBox: "0 0 16 16",
37
- fill: "none",
38
- xmlns: "http://www.w3.org/2000/svg",
39
- "aria-hidden": "true",
40
- focusable: "false",
41
- children: /* @__PURE__ */ jsx("path", {
42
- d: "M3 8H13",
43
- stroke: "currentColor",
44
- strokeWidth: "2",
45
- strokeLinecap: "round"
46
- })
47
- });
48
- const InfoIcon = () => /* @__PURE__ */ jsxs("svg", {
49
- width: "14",
50
- height: "14",
51
- viewBox: "0 0 14 14",
52
- fill: "none",
53
- xmlns: "http://www.w3.org/2000/svg",
54
- "aria-hidden": "true",
55
- focusable: "false",
56
- children: [/* @__PURE__ */ jsx("circle", {
57
- cx: "7",
58
- cy: "7",
59
- r: "6",
60
- stroke: "currentColor",
61
- strokeWidth: "1.5"
62
- }), /* @__PURE__ */ jsx("path", {
63
- d: "M7 6V10M7 4.5V4",
64
- stroke: "currentColor",
65
- strokeWidth: "1.5",
66
- strokeLinecap: "round"
67
- })]
68
- });
69
- function getSavings(plan) {
70
- const yearlyTotal = plan.yearlyPrice * 12;
71
- return plan.monthlyPrice * 12 - yearlyTotal;
72
- }
73
- function formatNumber(num) {
74
- if (num >= 1e6) return `${(num / 1e6).toFixed(1)}M`;
75
- if (num >= 1e3) return `${(num / 1e3).toFixed(0)}K`;
76
- return num.toString();
77
- }
78
10
  /**
79
11
  * A comprehensive pricing page component that demonstrates all pricing-related
80
12
  * components working together.
@@ -98,16 +30,9 @@ function formatNumber(num) {
98
30
  */
99
31
  function PricingPage({ title = "Simple, transparent pricing", subtitle, plans, faq, showUsageCalculator = false, usageTiers = [], maxUsage = 1e5, usageUnit = "API calls", onSelectPlan, onConfirmUpgrade, className = "", billingToggleVariant, productIds, currentProductId, isSubscribed = false, checkoutUrl = "/api/checkout", switchPlanUrl = "/api/switch-plan", portalUrl = "/api/portal", isLoggedIn = false, loginUrl = "/auth/login", hasPolarAccount = false, onCheckout, onSwitchPlan, onPortalRedirect }) {
100
32
  const [billingPeriod, setBillingPeriod] = React.useState("monthly");
101
- const [useSwitchToggle, setUseSwitchToggle] = React.useState(true);
102
- const showSwitch = billingToggleVariant ? billingToggleVariant === "switch" : useSwitchToggle;
103
33
  const [selectedPlan, setSelectedPlan] = React.useState(null);
104
34
  const [confirmDialogOpen, setConfirmDialogOpen] = React.useState(false);
105
35
  const [switching, setSwitching] = React.useState(false);
106
- const [usage, setUsage] = React.useState(5e4);
107
- const isYearly = billingPeriod === "yearly";
108
- const getPrice = (plan) => {
109
- return isYearly ? plan.yearlyPrice : plan.monthlyPrice;
110
- };
111
36
  const yearlySavingsPercent = React.useMemo(() => {
112
37
  const paidPlans = plans.filter((p) => p.monthlyPrice > 0);
113
38
  if (paidPlans.length === 0) return 0;
@@ -125,8 +50,8 @@ function PricingPage({ title = "Simple, transparent pricing", subtitle, plans, f
125
50
  const currentPlan = isSubscribed ? plans.find((p) => isCurrentPlan(p)) : void 0;
126
51
  const getSwitchDirection = (target) => {
127
52
  if (!currentPlan) return "upgrade";
128
- const currentPrice = getPrice(currentPlan);
129
- const targetPrice = getPrice(target);
53
+ const currentPrice = getPlanPrice(currentPlan, billingPeriod);
54
+ const targetPrice = getPlanPrice(target, billingPeriod);
130
55
  if (targetPrice > currentPrice) return "upgrade";
131
56
  if (targetPrice < currentPrice) return "downgrade";
132
57
  return "switch";
@@ -135,7 +60,7 @@ function PricingPage({ title = "Simple, transparent pricing", subtitle, plans, f
135
60
  if (!productIds) return void 0;
136
61
  const ids = productIds[plan.id];
137
62
  if (!ids) return void 0;
138
- return isYearly ? ids.yearly : ids.monthly;
63
+ return billingPeriod === "yearly" ? ids.yearly : ids.monthly;
139
64
  };
140
65
  const doCheckout = async (productId) => {
141
66
  if (onCheckout) await onCheckout(productId);
@@ -204,301 +129,56 @@ function PricingPage({ title = "Simple, transparent pricing", subtitle, plans, f
204
129
  }
205
130
  setConfirmDialogOpen(false);
206
131
  };
207
- const calculateUsagePrice = (currentUsage) => {
208
- for (let i = usageTiers.length - 1; i >= 0; i--) if (currentUsage >= usageTiers[i].limit) return usageTiers[i].price;
209
- return usageTiers[0]?.price ?? 0;
132
+ const getPlanAction = (plan) => {
133
+ if (isCurrentPlan(plan)) return "current";
134
+ return isSubscribed ? getSwitchDirection(plan) : "select";
210
135
  };
211
136
  return /* @__PURE__ */ jsxs("div", {
212
137
  className: ["pricing-page", className].filter(Boolean).join(" "),
213
138
  children: [
214
- /* @__PURE__ */ jsxs("div", {
139
+ /* @__PURE__ */ jsxs("header", {
215
140
  className: "pricing-page__header",
216
141
  children: [
217
142
  /* @__PURE__ */ jsx("h1", {
218
143
  className: "pricing-page__title",
219
144
  children: title
220
145
  }),
221
- subtitle && /* @__PURE__ */ jsx("p", {
146
+ subtitle ? /* @__PURE__ */ jsx("p", {
222
147
  className: "pricing-page__subtitle",
223
148
  children: subtitle
224
- }),
225
- /* @__PURE__ */ jsxs("div", {
226
- className: "pricing-page__billing-toggle",
227
- children: [!billingToggleVariant && /* @__PURE__ */ jsxs("div", {
228
- className: "pricing-page__toggle-options",
229
- children: [/* @__PURE__ */ jsx(Checkbox.Root, {
230
- checked: useSwitchToggle,
231
- onCheckedChange: (checked) => setUseSwitchToggle(!!checked),
232
- id: "toggle-type",
233
- "aria-label": "Use switch style",
234
- children: /* @__PURE__ */ jsx(Checkbox.Indicator, {})
235
- }), /* @__PURE__ */ jsx(Label, {
236
- htmlFor: "toggle-type",
237
- style: { fontSize: "0.75rem" },
238
- children: "Use switch style"
239
- })]
240
- }), showSwitch ? /* @__PURE__ */ jsxs("div", {
241
- className: "pricing-page__switch-container",
242
- children: [
243
- /* @__PURE__ */ jsx("span", {
244
- className: `pricing-page__period-label ${!isYearly ? "pricing-page__period-label--active" : ""}`,
245
- children: "Monthly"
246
- }),
247
- /* @__PURE__ */ jsx(Switch.Root, {
248
- checked: isYearly,
249
- onCheckedChange: (checked) => setBillingPeriod(checked ? "yearly" : "monthly"),
250
- "aria-label": "Toggle yearly billing",
251
- children: /* @__PURE__ */ jsx(Switch.Thumb, {})
252
- }),
253
- /* @__PURE__ */ jsxs("span", {
254
- className: `pricing-page__period-label ${isYearly ? "pricing-page__period-label--active" : ""}`,
255
- children: ["Yearly", /* @__PURE__ */ jsxs(Badge, {
256
- color: "success",
257
- size: "sm",
258
- style: { marginLeft: "0.5rem" },
259
- children: [
260
- "Save ",
261
- yearlySavingsPercent,
262
- "%"
263
- ]
264
- })]
265
- })
266
- ]
267
- }) : /* @__PURE__ */ jsxs(ToggleGroup.Root, {
268
- value: [billingPeriod],
269
- onValueChange: (v) => v.length > 0 && setBillingPeriod(v[0]),
270
- children: [/* @__PURE__ */ jsx(ToggleGroup.Item, {
271
- value: "monthly",
272
- children: "Monthly"
273
- }), /* @__PURE__ */ jsxs(ToggleGroup.Item, {
274
- value: "yearly",
275
- children: ["Yearly", /* @__PURE__ */ jsxs(Badge, {
276
- color: "success",
277
- size: "sm",
278
- style: { marginLeft: "0.375rem" },
279
- children: [
280
- "-",
281
- yearlySavingsPercent,
282
- "%"
283
- ]
284
- })]
285
- })]
286
- })]
149
+ }) : null,
150
+ /* @__PURE__ */ jsx(PricingBillingToggle, {
151
+ value: billingPeriod,
152
+ onValueChange: setBillingPeriod,
153
+ yearlySavingsPercent,
154
+ variant: billingToggleVariant
287
155
  })
288
156
  ]
289
157
  }),
290
- /* @__PURE__ */ jsx("div", {
158
+ /* @__PURE__ */ jsx("section", {
291
159
  className: "pricing-page__plans",
292
- children: plans.map((plan) => /* @__PURE__ */ jsxs(Card, {
293
- hover: true,
294
- className: `pricing-page__plan ${plan.popular ? "pricing-page__plan--popular" : ""}`,
295
- children: [
296
- plan.popular && /* @__PURE__ */ jsx(Badge, {
297
- color: "success",
298
- className: "pricing-page__popular-badge",
299
- children: "Most Popular"
300
- }),
301
- /* @__PURE__ */ jsxs("div", {
302
- className: "pricing-page__plan-header",
303
- children: [/* @__PURE__ */ jsx("h2", {
304
- className: "pricing-page__plan-name",
305
- children: plan.name
306
- }), /* @__PURE__ */ jsx("p", {
307
- className: "pricing-page__plan-description",
308
- children: plan.description
309
- })]
310
- }),
311
- /* @__PURE__ */ jsxs("div", {
312
- className: "pricing-page__plan-price",
313
- children: [
314
- /* @__PURE__ */ jsxs("span", {
315
- className: "pricing-page__price-amount",
316
- children: ["$", getPrice(plan)]
317
- }),
318
- /* @__PURE__ */ jsx("span", {
319
- className: "pricing-page__price-period",
320
- children: "/month"
321
- }),
322
- isYearly && getSavings(plan) > 0 && /* @__PURE__ */ jsxs("span", {
323
- className: "pricing-page__price-savings",
324
- children: [
325
- "Save $",
326
- getSavings(plan),
327
- "/year"
328
- ]
329
- })
330
- ]
331
- }),
332
- /* @__PURE__ */ jsx(Button, {
333
- variant: isCurrentPlan(plan) ? "outline" : plan.popular ? "normal" : "outline",
334
- className: "pricing-page__plan-cta",
335
- onClick: () => handleSelectPlan(plan),
336
- disabled: isCurrentPlan(plan),
337
- children: isCurrentPlan(plan) ? "Current Plan" : isSubscribed ? getSwitchDirection(plan) === "upgrade" ? "Upgrade" : getSwitchDirection(plan) === "downgrade" ? "Downgrade" : "Switch Plan" : plan.cta || "Get Started"
338
- }),
339
- /* @__PURE__ */ jsx(Separator, { className: "pricing-page__features-separator" }),
340
- /* @__PURE__ */ jsx("ul", {
341
- className: "pricing-page__features",
342
- children: plan.features.map((feature, index) => /* @__PURE__ */ jsxs("li", {
343
- className: `pricing-page__feature ${!feature.included ? "pricing-page__feature--disabled" : ""}`,
344
- children: [
345
- /* @__PURE__ */ jsx("span", {
346
- className: `pricing-page__feature-icon ${feature.included ? "pricing-page__feature-icon--included" : ""}`,
347
- children: feature.included ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(MinusIcon, {})
348
- }),
349
- /* @__PURE__ */ jsxs("span", {
350
- className: "pricing-page__feature-name",
351
- children: [feature.name, feature.limit && /* @__PURE__ */ jsxs("span", {
352
- className: "pricing-page__feature-limit",
353
- children: [
354
- "(",
355
- feature.limit,
356
- ")"
357
- ]
358
- })]
359
- }),
360
- feature.tooltip && /* @__PURE__ */ jsxs(Tooltip.Root, { children: [/* @__PURE__ */ jsx(Tooltip.Trigger, {
361
- className: "pricing-page__feature-info",
362
- "aria-label": `More information about ${feature.name}`,
363
- children: /* @__PURE__ */ jsx(InfoIcon, {})
364
- }), /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, { children: /* @__PURE__ */ jsx(Tooltip.Popup, { children: feature.tooltip }) }) })] })
365
- ]
366
- }, index))
367
- })
368
- ]
160
+ "aria-label": "Plans",
161
+ children: plans.map((plan) => /* @__PURE__ */ jsx(PricingPlanCard, {
162
+ plan,
163
+ billingPeriod,
164
+ action: getPlanAction(plan),
165
+ onSelect: handleSelectPlan
369
166
  }, plan.id))
370
167
  }),
371
- showUsageCalculator && usageTiers.length > 0 && /* @__PURE__ */ jsxs(Card, {
372
- className: "pricing-page__calculator",
373
- children: [
374
- /* @__PURE__ */ jsx("h2", {
375
- className: "pricing-page__calculator-title",
376
- children: "Estimate your usage"
377
- }),
378
- /* @__PURE__ */ jsxs("p", {
379
- className: "pricing-page__calculator-description",
380
- children: ["Adjust the slider to see pricing based on your expected ", usageUnit]
381
- }),
382
- /* @__PURE__ */ jsxs(Slider.Root, {
383
- value: usage,
384
- onValueChange: (v) => setUsage(Array.isArray(v) ? v[0] : v),
385
- min: 0,
386
- max: maxUsage,
387
- step: Math.ceil(maxUsage / 100),
388
- className: "pricing-page__calculator-slider",
389
- children: [
390
- /* @__PURE__ */ jsxs("div", {
391
- className: "pricing-page__calculator-labels",
392
- children: [/* @__PURE__ */ jsxs(Label, { children: ["Monthly ", usageUnit] }), /* @__PURE__ */ jsx("span", {
393
- className: "pricing-page__calculator-value",
394
- children: formatNumber(usage)
395
- })]
396
- }),
397
- /* @__PURE__ */ jsx(Slider.Control, { children: /* @__PURE__ */ jsxs(Slider.Track, { children: [/* @__PURE__ */ jsx(Slider.Indicator, {}), /* @__PURE__ */ jsx(Slider.Thumb, { "aria-label": `Monthly ${usageUnit}` })] }) }),
398
- /* @__PURE__ */ jsxs("div", {
399
- className: "pricing-page__calculator-range",
400
- children: [/* @__PURE__ */ jsx("span", { children: "0" }), /* @__PURE__ */ jsx("span", { children: formatNumber(maxUsage) })]
401
- })
402
- ]
403
- }),
404
- /* @__PURE__ */ jsx(Separator, { style: { margin: "1.5rem 0" } }),
405
- /* @__PURE__ */ jsxs("div", {
406
- className: "pricing-page__calculator-result",
407
- children: [/* @__PURE__ */ jsx("span", {
408
- className: "pricing-page__calculator-result-label",
409
- children: "Estimated monthly cost"
410
- }), /* @__PURE__ */ jsxs("div", {
411
- className: "pricing-page__calculator-result-price",
412
- children: [/* @__PURE__ */ jsxs("span", {
413
- className: "pricing-page__calculator-amount",
414
- children: ["$", calculateUsagePrice(usage)]
415
- }), /* @__PURE__ */ jsx("span", {
416
- className: "pricing-page__calculator-period",
417
- children: "/month"
418
- })]
419
- })]
420
- }),
421
- /* @__PURE__ */ jsx("div", {
422
- className: "pricing-page__tiers",
423
- children: usageTiers.map((tier, index) => {
424
- const isActive = usage >= tier.limit;
425
- return /* @__PURE__ */ jsxs("div", {
426
- className: "pricing-page__tier",
427
- children: [/* @__PURE__ */ jsxs("div", {
428
- className: "pricing-page__tier-info",
429
- children: [/* @__PURE__ */ jsx("span", {
430
- className: "pricing-page__tier-label",
431
- children: tier.label
432
- }), /* @__PURE__ */ jsxs("span", {
433
- className: "pricing-page__tier-price",
434
- children: [
435
- "$",
436
- tier.price,
437
- "/mo"
438
- ]
439
- })]
440
- }), /* @__PURE__ */ jsx(Progress.Root, {
441
- "aria-label": `Progress toward ${tier.label}`,
442
- value: isActive ? 100 : tier.limit > 0 ? usage / tier.limit * 100 : 0,
443
- color: isActive ? "success" : "primary",
444
- children: /* @__PURE__ */ jsx(Progress.Track, { children: /* @__PURE__ */ jsx(Progress.Indicator, {}) })
445
- })]
446
- }, index);
447
- })
448
- })
449
- ]
450
- }),
451
- faq && faq.length > 0 && /* @__PURE__ */ jsxs("div", {
452
- className: "pricing-page__faq",
453
- children: [/* @__PURE__ */ jsx("h2", {
454
- className: "pricing-page__faq-title",
455
- children: "Frequently Asked Questions"
456
- }), /* @__PURE__ */ jsx(Accordion.Root, {
457
- className: "pricing-page__faq-accordion",
458
- children: faq.map((item, index) => /* @__PURE__ */ jsxs(Accordion.Item, {
459
- value: `faq-${index}`,
460
- children: [/* @__PURE__ */ jsx(Accordion.Header, { children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: item.question }) }), /* @__PURE__ */ jsx(Accordion.Panel, { children: /* @__PURE__ */ jsx("p", { children: item.answer }) })]
461
- }, index))
462
- })]
463
- }),
464
- /* @__PURE__ */ jsx(AlertDialog.Root, {
168
+ showUsageCalculator && usageTiers.length > 0 ? /* @__PURE__ */ jsx(PricingUsageCalculator, {
169
+ usageTiers,
170
+ maxUsage,
171
+ usageUnit
172
+ }) : null,
173
+ faq ? /* @__PURE__ */ jsx(PricingFAQ, { items: faq }) : null,
174
+ /* @__PURE__ */ jsx(PricingConfirmationDialog, {
465
175
  open: confirmDialogOpen,
466
176
  onOpenChange: setConfirmDialogOpen,
467
- children: /* @__PURE__ */ jsxs(AlertDialog.Portal, { children: [/* @__PURE__ */ jsx(AlertDialog.Backdrop, {}), /* @__PURE__ */ jsx(AlertDialog.Viewport, { children: /* @__PURE__ */ jsxs(AlertDialog.Popup, { children: [
468
- /* @__PURE__ */ jsx(AlertDialog.Title, { children: isSubscribed && selectedPlan ? `${getSwitchDirection(selectedPlan) === "upgrade" ? "Upgrade" : getSwitchDirection(selectedPlan) === "downgrade" ? "Downgrade" : "Switch"} to ${selectedPlan.name}?` : `Subscribe to ${selectedPlan?.name}?` }),
469
- /* @__PURE__ */ jsx(AlertDialog.Description, { children: isSubscribed && selectedPlan ? getSwitchDirection(selectedPlan) === "downgrade" ? `You'll be downgraded to the ${selectedPlan.name} plan. A prorated credit will be applied to your next invoice.` : `You'll be upgraded to the ${selectedPlan.name} plan. The prorated difference will be added to your next invoice.` : `You're about to subscribe to the ${selectedPlan?.name} plan at $${selectedPlan ? getPrice(selectedPlan) : 0}/month${isYearly ? " (billed yearly)" : ""}.` }),
470
- selectedPlan && /* @__PURE__ */ jsxs("div", {
471
- className: "pricing-page__confirm-summary",
472
- children: [/* @__PURE__ */ jsxs("div", {
473
- className: "pricing-page__confirm-row",
474
- children: [/* @__PURE__ */ jsxs("span", { children: [
475
- selectedPlan.name,
476
- " Plan (",
477
- isYearly ? "Yearly" : "Monthly",
478
- ")"
479
- ] }), /* @__PURE__ */ jsxs("span", { children: [
480
- "$",
481
- getPrice(selectedPlan),
482
- "/mo"
483
- ] })]
484
- }), isYearly && /* @__PURE__ */ jsxs("div", {
485
- className: "pricing-page__confirm-row pricing-page__confirm-row--savings",
486
- children: [/* @__PURE__ */ jsx("span", { children: "Annual savings" }), /* @__PURE__ */ jsxs("span", { children: ["-$", getSavings(selectedPlan)] })]
487
- })]
488
- }),
489
- /* @__PURE__ */ jsxs("div", {
490
- className: "pricing-page__confirm-actions",
491
- children: [/* @__PURE__ */ jsx(AlertDialog.Close, {
492
- disabled: switching,
493
- children: "Cancel"
494
- }), /* @__PURE__ */ jsx(Button, {
495
- color: "primary",
496
- onClick: handleConfirmUpgrade,
497
- disabled: switching,
498
- children: switching ? "Switching…" : isSubscribed && selectedPlan ? `Confirm ${getSwitchDirection(selectedPlan) === "upgrade" ? "Upgrade" : getSwitchDirection(selectedPlan) === "downgrade" ? "Downgrade" : "Switch"}` : "Confirm"
499
- })]
500
- })
501
- ] }) })] })
177
+ plan: selectedPlan,
178
+ billingPeriod,
179
+ action: isSubscribed && selectedPlan ? getSwitchDirection(selectedPlan) : void 0,
180
+ switching,
181
+ onConfirm: handleConfirmUpgrade
502
182
  })
503
183
  ]
504
184
  });
@@ -0,0 +1,22 @@
1
+ import { Plan, PricingBillingPeriod } from "./Pricing.js";
2
+
3
+ //#region src/components/PricingPlanCard.d.ts
4
+ type PricingPlanAction = "current" | "upgrade" | "downgrade" | "switch" | "select";
5
+ interface PricingPlanCardProps {
6
+ plan: Plan;
7
+ billingPeriod: PricingBillingPeriod;
8
+ action?: PricingPlanAction;
9
+ onSelect?: (plan: Plan) => void;
10
+ /** Additional class name for placement in a consuming layout. */
11
+ className?: string;
12
+ }
13
+ /** A single plan card with shared Badge, Button, Separator, and Tooltip primitives. */
14
+ declare function PricingPlanCard({
15
+ plan,
16
+ billingPeriod,
17
+ action,
18
+ onSelect,
19
+ className
20
+ }: PricingPlanCardProps): import("react").JSX.Element;
21
+ //#endregion
22
+ export { PricingPlanAction, PricingPlanCard, PricingPlanCardProps };