@frontmcp/ui 0.5.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 (393) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +438 -0
  3. package/package.json +147 -0
  4. package/src/adapters/index.d.ts +10 -0
  5. package/src/adapters/index.js +18 -0
  6. package/src/adapters/index.js.map +1 -0
  7. package/src/adapters/platform-meta.d.ts +165 -0
  8. package/src/adapters/platform-meta.js +310 -0
  9. package/src/adapters/platform-meta.js.map +1 -0
  10. package/src/base-template/bridge.d.ts +89 -0
  11. package/src/base-template/bridge.js +452 -0
  12. package/src/base-template/bridge.js.map +1 -0
  13. package/src/base-template/default-base-template.d.ts +91 -0
  14. package/src/base-template/default-base-template.js +435 -0
  15. package/src/base-template/default-base-template.js.map +1 -0
  16. package/src/base-template/index.d.ts +14 -0
  17. package/src/base-template/index.js +30 -0
  18. package/src/base-template/index.js.map +1 -0
  19. package/src/base-template/polyfills.d.ts +30 -0
  20. package/src/base-template/polyfills.js +190 -0
  21. package/src/base-template/polyfills.js.map +1 -0
  22. package/src/base-template/theme-styles.d.ts +73 -0
  23. package/src/base-template/theme-styles.js +95 -0
  24. package/src/base-template/theme-styles.js.map +1 -0
  25. package/src/bridge/adapters/base-adapter.d.ts +103 -0
  26. package/src/bridge/adapters/base-adapter.js +314 -0
  27. package/src/bridge/adapters/base-adapter.js.map +1 -0
  28. package/src/bridge/adapters/claude.adapter.d.ts +66 -0
  29. package/src/bridge/adapters/claude.adapter.js +145 -0
  30. package/src/bridge/adapters/claude.adapter.js.map +1 -0
  31. package/src/bridge/adapters/ext-apps.adapter.d.ts +142 -0
  32. package/src/bridge/adapters/ext-apps.adapter.js +416 -0
  33. package/src/bridge/adapters/ext-apps.adapter.js.map +1 -0
  34. package/src/bridge/adapters/gemini.adapter.d.ts +63 -0
  35. package/src/bridge/adapters/gemini.adapter.js +160 -0
  36. package/src/bridge/adapters/gemini.adapter.js.map +1 -0
  37. package/src/bridge/adapters/generic.adapter.d.ts +55 -0
  38. package/src/bridge/adapters/generic.adapter.js +108 -0
  39. package/src/bridge/adapters/generic.adapter.js.map +1 -0
  40. package/src/bridge/adapters/index.d.ts +25 -0
  41. package/src/bridge/adapters/index.js +65 -0
  42. package/src/bridge/adapters/index.js.map +1 -0
  43. package/src/bridge/adapters/openai.adapter.d.ts +64 -0
  44. package/src/bridge/adapters/openai.adapter.js +194 -0
  45. package/src/bridge/adapters/openai.adapter.js.map +1 -0
  46. package/src/bridge/core/adapter-registry.d.ts +121 -0
  47. package/src/bridge/core/adapter-registry.js +271 -0
  48. package/src/bridge/core/adapter-registry.js.map +1 -0
  49. package/src/bridge/core/bridge-factory.d.ts +198 -0
  50. package/src/bridge/core/bridge-factory.js +428 -0
  51. package/src/bridge/core/bridge-factory.js.map +1 -0
  52. package/src/bridge/core/index.d.ts +9 -0
  53. package/src/bridge/core/index.js +22 -0
  54. package/src/bridge/core/index.js.map +1 -0
  55. package/src/bridge/index.d.ts +61 -0
  56. package/src/bridge/index.js +94 -0
  57. package/src/bridge/index.js.map +1 -0
  58. package/src/bridge/runtime/iife-generator.d.ts +61 -0
  59. package/src/bridge/runtime/iife-generator.js +940 -0
  60. package/src/bridge/runtime/iife-generator.js.map +1 -0
  61. package/src/bridge/runtime/index.d.ts +8 -0
  62. package/src/bridge/runtime/index.js +16 -0
  63. package/src/bridge/runtime/index.js.map +1 -0
  64. package/src/bridge/types.d.ts +385 -0
  65. package/src/bridge/types.js +11 -0
  66. package/src/bridge/types.js.map +1 -0
  67. package/src/build/cdn-resources.d.ts +140 -0
  68. package/src/build/cdn-resources.js +314 -0
  69. package/src/build/cdn-resources.js.map +1 -0
  70. package/src/build/index.d.ts +294 -0
  71. package/src/build/index.js +325 -0
  72. package/src/build/index.js.map +1 -0
  73. package/src/build/widget-manifest.d.ts +212 -0
  74. package/src/build/widget-manifest.js +652 -0
  75. package/src/build/widget-manifest.js.map +1 -0
  76. package/src/bundler/bundler.d.ts +110 -0
  77. package/src/bundler/bundler.js +432 -0
  78. package/src/bundler/bundler.js.map +1 -0
  79. package/src/bundler/cache.d.ts +172 -0
  80. package/src/bundler/cache.js +250 -0
  81. package/src/bundler/cache.js.map +1 -0
  82. package/src/bundler/index.d.ts +41 -0
  83. package/src/bundler/index.js +73 -0
  84. package/src/bundler/index.js.map +1 -0
  85. package/src/bundler/sandbox/enclave-adapter.d.ts +120 -0
  86. package/src/bundler/sandbox/enclave-adapter.js +339 -0
  87. package/src/bundler/sandbox/enclave-adapter.js.map +1 -0
  88. package/src/bundler/sandbox/executor.d.ts +13 -0
  89. package/src/bundler/sandbox/executor.js +22 -0
  90. package/src/bundler/sandbox/executor.js.map +1 -0
  91. package/src/bundler/sandbox/policy.d.ts +61 -0
  92. package/src/bundler/sandbox/policy.js +238 -0
  93. package/src/bundler/sandbox/policy.js.map +1 -0
  94. package/src/bundler/types.d.ts +347 -0
  95. package/src/bundler/types.js +132 -0
  96. package/src/bundler/types.js.map +1 -0
  97. package/src/components/alert.d.ts +71 -0
  98. package/src/components/alert.js +189 -0
  99. package/src/components/alert.js.map +1 -0
  100. package/src/components/alert.schema.d.ts +114 -0
  101. package/src/components/alert.schema.js +105 -0
  102. package/src/components/alert.schema.js.map +1 -0
  103. package/src/components/avatar.d.ts +76 -0
  104. package/src/components/avatar.js +176 -0
  105. package/src/components/avatar.js.map +1 -0
  106. package/src/components/avatar.schema.d.ts +169 -0
  107. package/src/components/avatar.schema.js +103 -0
  108. package/src/components/avatar.schema.js.map +1 -0
  109. package/src/components/badge.d.ts +70 -0
  110. package/src/components/badge.js +149 -0
  111. package/src/components/badge.js.map +1 -0
  112. package/src/components/badge.schema.d.ts +109 -0
  113. package/src/components/badge.schema.js +96 -0
  114. package/src/components/badge.schema.js.map +1 -0
  115. package/src/components/button.d.ts +111 -0
  116. package/src/components/button.js +336 -0
  117. package/src/components/button.js.map +1 -0
  118. package/src/components/button.schema.d.ts +148 -0
  119. package/src/components/button.schema.js +121 -0
  120. package/src/components/button.schema.js.map +1 -0
  121. package/src/components/card.d.ts +60 -0
  122. package/src/components/card.js +117 -0
  123. package/src/components/card.js.map +1 -0
  124. package/src/components/card.schema.d.ts +113 -0
  125. package/src/components/card.schema.js +98 -0
  126. package/src/components/card.schema.js.map +1 -0
  127. package/src/components/form.d.ts +239 -0
  128. package/src/components/form.js +420 -0
  129. package/src/components/form.js.map +1 -0
  130. package/src/components/form.schema.d.ts +441 -0
  131. package/src/components/form.schema.js +406 -0
  132. package/src/components/form.schema.js.map +1 -0
  133. package/src/components/index.d.ts +29 -0
  134. package/src/components/index.js +98 -0
  135. package/src/components/index.js.map +1 -0
  136. package/src/components/list.d.ts +127 -0
  137. package/src/components/list.js +279 -0
  138. package/src/components/list.js.map +1 -0
  139. package/src/components/list.schema.d.ts +134 -0
  140. package/src/components/list.schema.js +168 -0
  141. package/src/components/list.schema.js.map +1 -0
  142. package/src/components/modal.d.ts +111 -0
  143. package/src/components/modal.js +260 -0
  144. package/src/components/modal.js.map +1 -0
  145. package/src/components/modal.schema.d.ts +186 -0
  146. package/src/components/modal.schema.js +167 -0
  147. package/src/components/modal.schema.js.map +1 -0
  148. package/src/components/table.d.ts +105 -0
  149. package/src/components/table.js +283 -0
  150. package/src/components/table.js.map +1 -0
  151. package/src/components/table.schema.d.ts +159 -0
  152. package/src/components/table.schema.js +173 -0
  153. package/src/components/table.schema.js.map +1 -0
  154. package/src/handlebars/helpers.d.ts +348 -0
  155. package/src/handlebars/helpers.js +605 -0
  156. package/src/handlebars/helpers.js.map +1 -0
  157. package/src/handlebars/index.d.ts +193 -0
  158. package/src/handlebars/index.js +350 -0
  159. package/src/handlebars/index.js.map +1 -0
  160. package/src/index.d.ts +50 -0
  161. package/src/index.js +192 -0
  162. package/src/index.js.map +1 -0
  163. package/src/layouts/base.d.ts +88 -0
  164. package/src/layouts/base.js +227 -0
  165. package/src/layouts/base.js.map +1 -0
  166. package/src/layouts/index.d.ts +7 -0
  167. package/src/layouts/index.js +25 -0
  168. package/src/layouts/index.js.map +1 -0
  169. package/src/layouts/presets.d.ts +133 -0
  170. package/src/layouts/presets.js +277 -0
  171. package/src/layouts/presets.js.map +1 -0
  172. package/src/pages/consent.d.ts +116 -0
  173. package/src/pages/consent.js +218 -0
  174. package/src/pages/consent.js.map +1 -0
  175. package/src/pages/error.d.ts +100 -0
  176. package/src/pages/error.js +263 -0
  177. package/src/pages/error.js.map +1 -0
  178. package/src/pages/index.d.ts +8 -0
  179. package/src/pages/index.js +27 -0
  180. package/src/pages/index.js.map +1 -0
  181. package/src/react/Alert.d.ts +101 -0
  182. package/src/react/Alert.js +51 -0
  183. package/src/react/Alert.js.map +1 -0
  184. package/src/react/Badge.d.ts +100 -0
  185. package/src/react/Badge.js +55 -0
  186. package/src/react/Badge.js.map +1 -0
  187. package/src/react/Button.d.ts +108 -0
  188. package/src/react/Button.js +52 -0
  189. package/src/react/Button.js.map +1 -0
  190. package/src/react/Card.d.ts +103 -0
  191. package/src/react/Card.js +55 -0
  192. package/src/react/Card.js.map +1 -0
  193. package/src/react/hooks/context.d.ts +178 -0
  194. package/src/react/hooks/context.js +287 -0
  195. package/src/react/hooks/context.js.map +1 -0
  196. package/src/react/hooks/index.d.ts +41 -0
  197. package/src/react/hooks/index.js +61 -0
  198. package/src/react/hooks/index.js.map +1 -0
  199. package/src/react/hooks/tools.d.ts +283 -0
  200. package/src/react/hooks/tools.js +465 -0
  201. package/src/react/hooks/tools.js.map +1 -0
  202. package/src/react/index.d.ts +80 -0
  203. package/src/react/index.js +113 -0
  204. package/src/react/index.js.map +1 -0
  205. package/src/react/types.d.ts +105 -0
  206. package/src/react/types.js +12 -0
  207. package/src/react/types.js.map +1 -0
  208. package/src/react/utils.d.ts +42 -0
  209. package/src/react/utils.js +99 -0
  210. package/src/react/utils.js.map +1 -0
  211. package/src/registry/index.d.ts +45 -0
  212. package/src/registry/index.js +67 -0
  213. package/src/registry/index.js.map +1 -0
  214. package/src/registry/render-template.d.ts +86 -0
  215. package/src/registry/render-template.js +239 -0
  216. package/src/registry/render-template.js.map +1 -0
  217. package/src/registry/tool-ui.registry.d.ts +260 -0
  218. package/src/registry/tool-ui.registry.js +438 -0
  219. package/src/registry/tool-ui.registry.js.map +1 -0
  220. package/src/registry/uri-utils.d.ts +55 -0
  221. package/src/registry/uri-utils.js +97 -0
  222. package/src/registry/uri-utils.js.map +1 -0
  223. package/src/render/index.d.ts +7 -0
  224. package/src/render/index.js +14 -0
  225. package/src/render/index.js.map +1 -0
  226. package/src/render/prerender.d.ts +56 -0
  227. package/src/render/prerender.js +98 -0
  228. package/src/render/prerender.js.map +1 -0
  229. package/src/renderers/cache.d.ts +144 -0
  230. package/src/renderers/cache.js +240 -0
  231. package/src/renderers/cache.js.map +1 -0
  232. package/src/renderers/html.renderer.d.ts +122 -0
  233. package/src/renderers/html.renderer.js +204 -0
  234. package/src/renderers/html.renderer.js.map +1 -0
  235. package/src/renderers/index.d.ts +35 -0
  236. package/src/renderers/index.js +70 -0
  237. package/src/renderers/index.js.map +1 -0
  238. package/src/renderers/mdx.renderer.d.ts +119 -0
  239. package/src/renderers/mdx.renderer.js +305 -0
  240. package/src/renderers/mdx.renderer.js.map +1 -0
  241. package/src/renderers/react.renderer.d.ts +95 -0
  242. package/src/renderers/react.renderer.js +260 -0
  243. package/src/renderers/react.renderer.js.map +1 -0
  244. package/src/renderers/registry.d.ts +133 -0
  245. package/src/renderers/registry.js +232 -0
  246. package/src/renderers/registry.js.map +1 -0
  247. package/src/renderers/types.d.ts +341 -0
  248. package/src/renderers/types.js +9 -0
  249. package/src/renderers/types.js.map +1 -0
  250. package/src/renderers/utils/detect.d.ts +106 -0
  251. package/src/renderers/utils/detect.js +267 -0
  252. package/src/renderers/utils/detect.js.map +1 -0
  253. package/src/renderers/utils/hash.d.ts +39 -0
  254. package/src/renderers/utils/hash.js +75 -0
  255. package/src/renderers/utils/hash.js.map +1 -0
  256. package/src/renderers/utils/index.d.ts +8 -0
  257. package/src/renderers/utils/index.js +28 -0
  258. package/src/renderers/utils/index.js.map +1 -0
  259. package/src/renderers/utils/transpiler.d.ts +88 -0
  260. package/src/renderers/utils/transpiler.js +215 -0
  261. package/src/renderers/utils/transpiler.js.map +1 -0
  262. package/src/runtime/adapters/html.adapter.d.ts +58 -0
  263. package/src/runtime/adapters/html.adapter.js +131 -0
  264. package/src/runtime/adapters/html.adapter.js.map +1 -0
  265. package/src/runtime/adapters/index.d.ts +25 -0
  266. package/src/runtime/adapters/index.js +54 -0
  267. package/src/runtime/adapters/index.js.map +1 -0
  268. package/src/runtime/adapters/mdx.adapter.d.ts +72 -0
  269. package/src/runtime/adapters/mdx.adapter.js +241 -0
  270. package/src/runtime/adapters/mdx.adapter.js.map +1 -0
  271. package/src/runtime/adapters/react.adapter.d.ts +69 -0
  272. package/src/runtime/adapters/react.adapter.js +245 -0
  273. package/src/runtime/adapters/react.adapter.js.map +1 -0
  274. package/src/runtime/adapters/types.d.ts +94 -0
  275. package/src/runtime/adapters/types.js +11 -0
  276. package/src/runtime/adapters/types.js.map +1 -0
  277. package/src/runtime/csp.d.ts +37 -0
  278. package/src/runtime/csp.js +140 -0
  279. package/src/runtime/csp.js.map +1 -0
  280. package/src/runtime/index.d.ts +16 -0
  281. package/src/runtime/index.js +72 -0
  282. package/src/runtime/index.js.map +1 -0
  283. package/src/runtime/mcp-bridge.d.ts +100 -0
  284. package/src/runtime/mcp-bridge.js +581 -0
  285. package/src/runtime/mcp-bridge.js.map +1 -0
  286. package/src/runtime/renderer-runtime.d.ts +132 -0
  287. package/src/runtime/renderer-runtime.js +389 -0
  288. package/src/runtime/renderer-runtime.js.map +1 -0
  289. package/src/runtime/sanitizer.d.ts +171 -0
  290. package/src/runtime/sanitizer.js +318 -0
  291. package/src/runtime/sanitizer.js.map +1 -0
  292. package/src/runtime/types.d.ts +414 -0
  293. package/src/runtime/types.js +12 -0
  294. package/src/runtime/types.js.map +1 -0
  295. package/src/runtime/wrapper.d.ts +375 -0
  296. package/src/runtime/wrapper.js +1793 -0
  297. package/src/runtime/wrapper.js.map +1 -0
  298. package/src/styles/index.d.ts +7 -0
  299. package/src/styles/index.js +11 -0
  300. package/src/styles/index.js.map +1 -0
  301. package/src/styles/variants.d.ts +50 -0
  302. package/src/styles/variants.js +175 -0
  303. package/src/styles/variants.js.map +1 -0
  304. package/src/theme/cdn.d.ts +194 -0
  305. package/src/theme/cdn.js +375 -0
  306. package/src/theme/cdn.js.map +1 -0
  307. package/src/theme/index.d.ts +17 -0
  308. package/src/theme/index.js +57 -0
  309. package/src/theme/index.js.map +1 -0
  310. package/src/theme/platforms.d.ts +106 -0
  311. package/src/theme/platforms.js +161 -0
  312. package/src/theme/platforms.js.map +1 -0
  313. package/src/theme/presets/github-openai.d.ts +49 -0
  314. package/src/theme/presets/github-openai.js +189 -0
  315. package/src/theme/presets/github-openai.js.map +1 -0
  316. package/src/theme/presets/index.d.ts +10 -0
  317. package/src/theme/presets/index.js +17 -0
  318. package/src/theme/presets/index.js.map +1 -0
  319. package/src/theme/theme.d.ts +395 -0
  320. package/src/theme/theme.js +332 -0
  321. package/src/theme/theme.js.map +1 -0
  322. package/src/tool-template/builder.d.ts +212 -0
  323. package/src/tool-template/builder.js +397 -0
  324. package/src/tool-template/builder.js.map +1 -0
  325. package/src/tool-template/index.d.ts +15 -0
  326. package/src/tool-template/index.js +38 -0
  327. package/src/tool-template/index.js.map +1 -0
  328. package/src/types/index.d.ts +13 -0
  329. package/src/types/index.js +26 -0
  330. package/src/types/index.js.map +1 -0
  331. package/src/types/ui-config.d.ts +357 -0
  332. package/src/types/ui-config.js +12 -0
  333. package/src/types/ui-config.js.map +1 -0
  334. package/src/types/ui-runtime.d.ts +965 -0
  335. package/src/types/ui-runtime.js +117 -0
  336. package/src/types/ui-runtime.js.map +1 -0
  337. package/src/validation/error-box.d.ts +55 -0
  338. package/src/validation/error-box.js +75 -0
  339. package/src/validation/error-box.js.map +1 -0
  340. package/src/validation/index.d.ts +12 -0
  341. package/src/validation/index.js +21 -0
  342. package/src/validation/index.js.map +1 -0
  343. package/src/validation/wrapper.d.ts +96 -0
  344. package/src/validation/wrapper.js +117 -0
  345. package/src/validation/wrapper.js.map +1 -0
  346. package/src/web-components/core/attribute-parser.d.ts +85 -0
  347. package/src/web-components/core/attribute-parser.js +189 -0
  348. package/src/web-components/core/attribute-parser.js.map +1 -0
  349. package/src/web-components/core/base-element.d.ts +197 -0
  350. package/src/web-components/core/base-element.js +289 -0
  351. package/src/web-components/core/base-element.js.map +1 -0
  352. package/src/web-components/core/index.d.ts +8 -0
  353. package/src/web-components/core/index.js +18 -0
  354. package/src/web-components/core/index.js.map +1 -0
  355. package/src/web-components/elements/fmcp-alert.d.ts +45 -0
  356. package/src/web-components/elements/fmcp-alert.js +93 -0
  357. package/src/web-components/elements/fmcp-alert.js.map +1 -0
  358. package/src/web-components/elements/fmcp-badge.d.ts +46 -0
  359. package/src/web-components/elements/fmcp-badge.js +99 -0
  360. package/src/web-components/elements/fmcp-badge.js.map +1 -0
  361. package/src/web-components/elements/fmcp-button.d.ts +124 -0
  362. package/src/web-components/elements/fmcp-button.js +233 -0
  363. package/src/web-components/elements/fmcp-button.js.map +1 -0
  364. package/src/web-components/elements/fmcp-card.d.ts +52 -0
  365. package/src/web-components/elements/fmcp-card.js +115 -0
  366. package/src/web-components/elements/fmcp-card.js.map +1 -0
  367. package/src/web-components/elements/fmcp-input.d.ts +95 -0
  368. package/src/web-components/elements/fmcp-input.js +248 -0
  369. package/src/web-components/elements/fmcp-input.js.map +1 -0
  370. package/src/web-components/elements/fmcp-select.d.ts +99 -0
  371. package/src/web-components/elements/fmcp-select.js +243 -0
  372. package/src/web-components/elements/fmcp-select.js.map +1 -0
  373. package/src/web-components/elements/index.d.ts +12 -0
  374. package/src/web-components/elements/index.js +34 -0
  375. package/src/web-components/elements/index.js.map +1 -0
  376. package/src/web-components/index.d.ts +49 -0
  377. package/src/web-components/index.js +75 -0
  378. package/src/web-components/index.js.map +1 -0
  379. package/src/web-components/register.d.ts +56 -0
  380. package/src/web-components/register.js +80 -0
  381. package/src/web-components/register.js.map +1 -0
  382. package/src/web-components/types.d.ts +121 -0
  383. package/src/web-components/types.js +25 -0
  384. package/src/web-components/types.js.map +1 -0
  385. package/src/widgets/index.d.ts +7 -0
  386. package/src/widgets/index.js +24 -0
  387. package/src/widgets/index.js.map +1 -0
  388. package/src/widgets/progress.d.ts +132 -0
  389. package/src/widgets/progress.js +303 -0
  390. package/src/widgets/progress.js.map +1 -0
  391. package/src/widgets/resource.d.ts +162 -0
  392. package/src/widgets/resource.js +340 -0
  393. package/src/widgets/resource.js.map +1 -0
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @file Card.tsx
3
+ * @description React Card component with static HTML rendering support.
4
+ *
5
+ * This is the single source of truth for the Card component. It can be used:
6
+ * 1. As a React component: `<Card title="Hello">Content</Card>`
7
+ * 2. As a static HTML generator: `await renderCard({ title: 'Hello', children: 'Content' })`
8
+ *
9
+ * @example React usage
10
+ * ```tsx
11
+ * import { Card } from '@frontmcp/ui/react';
12
+ *
13
+ * function App() {
14
+ * return (
15
+ * <Card title="Welcome" variant="elevated">
16
+ * <p>Card content goes here</p>
17
+ * </Card>
18
+ * );
19
+ * }
20
+ * ```
21
+ *
22
+ * @example Static HTML generation
23
+ * ```typescript
24
+ * import { renderCard } from '@frontmcp/ui/react';
25
+ *
26
+ * const html = await renderCard({
27
+ * title: 'Product',
28
+ * subtitle: 'Details',
29
+ * variant: 'elevated',
30
+ * children: '<p>Product description...</p>',
31
+ * });
32
+ * ```
33
+ *
34
+ * @module @frontmcp/ui/react/Card
35
+ */
36
+ import type { ReactNode, ReactElement } from 'react';
37
+ import { type CardVariant, type CardSize } from '../styles/variants';
38
+ /**
39
+ * Card component props
40
+ */
41
+ export interface CardProps {
42
+ /** Card title */
43
+ title?: string;
44
+ /** Card subtitle/description */
45
+ subtitle?: string;
46
+ /** Header actions (React elements) */
47
+ headerActions?: ReactNode;
48
+ /** Footer content (React elements) */
49
+ footer?: ReactNode;
50
+ /** Card variant */
51
+ variant?: CardVariant;
52
+ /** Card size (padding) */
53
+ size?: CardSize;
54
+ /** Additional CSS classes */
55
+ className?: string;
56
+ /** Card ID */
57
+ id?: string;
58
+ /** Clickable card (adds hover effects) */
59
+ clickable?: boolean;
60
+ /** Click handler URL */
61
+ href?: string;
62
+ /** Card content */
63
+ children?: ReactNode;
64
+ }
65
+ /**
66
+ * Card component.
67
+ *
68
+ * A versatile container component for grouping related content.
69
+ * Uses Tailwind CSS classes for styling.
70
+ */
71
+ export declare function Card({ title, subtitle, headerActions, footer, variant, size, className, id, clickable, href, children, }: CardProps): ReactElement;
72
+ /**
73
+ * Props for static render functions (children is always a string)
74
+ */
75
+ export interface CardRenderProps extends Omit<CardProps, 'children' | 'headerActions' | 'footer'> {
76
+ /** Card content as HTML string */
77
+ children?: string;
78
+ /** Header actions as HTML string */
79
+ headerActions?: string;
80
+ /** Footer content as HTML string */
81
+ footer?: string;
82
+ }
83
+ /**
84
+ * Render Card component to static HTML string (async).
85
+ *
86
+ * Uses React 19's prerender API for optimal static HTML generation.
87
+ *
88
+ * @param props - Card props (with string children)
89
+ * @returns Promise resolving to HTML string
90
+ */
91
+ export declare function renderCard(props: CardRenderProps): Promise<string>;
92
+ /**
93
+ * Render Card component to static HTML string (sync).
94
+ *
95
+ * Uses React's renderToStaticMarkup for synchronous rendering.
96
+ * Does NOT wait for Suspense boundaries.
97
+ *
98
+ * @param props - Card props (with string children)
99
+ * @returns HTML string
100
+ */
101
+ export declare function renderCardSync(props: CardRenderProps): string;
102
+ export type { CardVariant, CardSize };
103
+ export default Card;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Card = Card;
4
+ exports.renderCard = renderCard;
5
+ exports.renderCardSync = renderCardSync;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const variants_1 = require("../styles/variants");
8
+ const prerender_1 = require("../render/prerender");
9
+ /**
10
+ * Card component.
11
+ *
12
+ * A versatile container component for grouping related content.
13
+ * Uses Tailwind CSS classes for styling.
14
+ */
15
+ function Card({ title, subtitle, headerActions, footer, variant = 'default', size = 'md', className, id, clickable, href, children, }) {
16
+ const variantClasses = (0, variants_1.getCardVariantClasses)(variant);
17
+ const sizeClasses = (0, variants_1.getCardSizeClasses)(size);
18
+ const clickableClasses = clickable ? 'cursor-pointer hover:shadow-md transition-shadow' : '';
19
+ const allClasses = (0, variants_1.cn)(variantClasses, sizeClasses, clickableClasses, className);
20
+ const hasHeader = title || subtitle || headerActions;
21
+ const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [hasHeader && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-start justify-between mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [title && (0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-semibold text-text-primary", children: title }), subtitle && (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-text-secondary mt-1", children: subtitle })] }), headerActions && (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: headerActions })] })), children, footer && (0, jsx_runtime_1.jsx)("div", { className: "mt-4 pt-4 border-t border-divider", children: footer })] }));
22
+ if (href) {
23
+ return ((0, jsx_runtime_1.jsx)("a", { href: href, className: allClasses, id: id, children: content }));
24
+ }
25
+ return ((0, jsx_runtime_1.jsx)("div", { className: allClasses, id: id, children: content }));
26
+ }
27
+ /**
28
+ * Render Card component to static HTML string (async).
29
+ *
30
+ * Uses React 19's prerender API for optimal static HTML generation.
31
+ *
32
+ * @param props - Card props (with string children)
33
+ * @returns Promise resolving to HTML string
34
+ */
35
+ async function renderCard(props) {
36
+ const { children, headerActions, footer, ...rest } = props;
37
+ const element = ((0, jsx_runtime_1.jsx)(Card, { ...rest, headerActions: headerActions ? (0, jsx_runtime_1.jsx)("span", { dangerouslySetInnerHTML: { __html: headerActions } }) : undefined, footer: footer ? (0, jsx_runtime_1.jsx)("span", { dangerouslySetInnerHTML: { __html: footer } }) : undefined, children: children ? (0, jsx_runtime_1.jsx)("span", { dangerouslySetInnerHTML: { __html: children } }) : undefined }));
38
+ return (0, prerender_1.renderToString)(element);
39
+ }
40
+ /**
41
+ * Render Card component to static HTML string (sync).
42
+ *
43
+ * Uses React's renderToStaticMarkup for synchronous rendering.
44
+ * Does NOT wait for Suspense boundaries.
45
+ *
46
+ * @param props - Card props (with string children)
47
+ * @returns HTML string
48
+ */
49
+ function renderCardSync(props) {
50
+ const { children, headerActions, footer, ...rest } = props;
51
+ const element = ((0, jsx_runtime_1.jsx)(Card, { ...rest, headerActions: headerActions ? (0, jsx_runtime_1.jsx)("span", { dangerouslySetInnerHTML: { __html: headerActions } }) : undefined, footer: footer ? (0, jsx_runtime_1.jsx)("span", { dangerouslySetInnerHTML: { __html: footer } }) : undefined, children: children ? (0, jsx_runtime_1.jsx)("span", { dangerouslySetInnerHTML: { __html: children } }) : undefined }));
52
+ return (0, prerender_1.renderToStringSync)(element);
53
+ }
54
+ exports.default = Card;
55
+ //# sourceMappingURL=Card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.js","sourceRoot":"","sources":["../../../src/react/Card.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file Card.tsx\n * @description React Card component with static HTML rendering support.\n *\n * This is the single source of truth for the Card component. It can be used:\n * 1. As a React component: `<Card title=\"Hello\">Content</Card>`\n * 2. As a static HTML generator: `await renderCard({ title: 'Hello', children: 'Content' })`\n *\n * @example React usage\n * ```tsx\n * import { Card } from '@frontmcp/ui/react';\n *\n * function App() {\n * return (\n * <Card title=\"Welcome\" variant=\"elevated\">\n * <p>Card content goes here</p>\n * </Card>\n * );\n * }\n * ```\n *\n * @example Static HTML generation\n * ```typescript\n * import { renderCard } from '@frontmcp/ui/react';\n *\n * const html = await renderCard({\n * title: 'Product',\n * subtitle: 'Details',\n * variant: 'elevated',\n * children: '<p>Product description...</p>',\n * });\n * ```\n *\n * @module @frontmcp/ui/react/Card\n */\n\nimport React from 'react';\nimport type { ReactNode, ReactElement } from 'react';\nimport { type CardVariant, type CardSize, getCardVariantClasses, getCardSizeClasses, cn } from '../styles/variants';\nimport { renderToString, renderToStringSync } from '../render/prerender';\n\n/**\n * Card component props\n */\nexport interface CardProps {\n /** Card title */\n title?: string;\n /** Card subtitle/description */\n subtitle?: string;\n /** Header actions (React elements) */\n headerActions?: ReactNode;\n /** Footer content (React elements) */\n footer?: ReactNode;\n /** Card variant */\n variant?: CardVariant;\n /** Card size (padding) */\n size?: CardSize;\n /** Additional CSS classes */\n className?: string;\n /** Card ID */\n id?: string;\n /** Clickable card (adds hover effects) */\n clickable?: boolean;\n /** Click handler URL */\n href?: string;\n /** Card content */\n children?: ReactNode;\n}\n\n/**\n * Card component.\n *\n * A versatile container component for grouping related content.\n * Uses Tailwind CSS classes for styling.\n */\nexport function Card({\n title,\n subtitle,\n headerActions,\n footer,\n variant = 'default',\n size = 'md',\n className,\n id,\n clickable,\n href,\n children,\n}: CardProps): ReactElement {\n const variantClasses = getCardVariantClasses(variant);\n const sizeClasses = getCardSizeClasses(size);\n const clickableClasses = clickable ? 'cursor-pointer hover:shadow-md transition-shadow' : '';\n const allClasses = cn(variantClasses, sizeClasses, clickableClasses, className);\n\n const hasHeader = title || subtitle || headerActions;\n\n const content = (\n <>\n {hasHeader && (\n <div className=\"flex items-start justify-between mb-4\">\n <div>\n {title && <h3 className=\"text-lg font-semibold text-text-primary\">{title}</h3>}\n {subtitle && <p className=\"text-sm text-text-secondary mt-1\">{subtitle}</p>}\n </div>\n {headerActions && <div className=\"flex items-center gap-2\">{headerActions}</div>}\n </div>\n )}\n {children}\n {footer && <div className=\"mt-4 pt-4 border-t border-divider\">{footer}</div>}\n </>\n );\n\n if (href) {\n return (\n <a href={href} className={allClasses} id={id}>\n {content}\n </a>\n );\n }\n\n return (\n <div className={allClasses} id={id}>\n {content}\n </div>\n );\n}\n\n/**\n * Props for static render functions (children is always a string)\n */\nexport interface CardRenderProps extends Omit<CardProps, 'children' | 'headerActions' | 'footer'> {\n /** Card content as HTML string */\n children?: string;\n /** Header actions as HTML string */\n headerActions?: string;\n /** Footer content as HTML string */\n footer?: string;\n}\n\n/**\n * Render Card component to static HTML string (async).\n *\n * Uses React 19's prerender API for optimal static HTML generation.\n *\n * @param props - Card props (with string children)\n * @returns Promise resolving to HTML string\n */\nexport async function renderCard(props: CardRenderProps): Promise<string> {\n const { children, headerActions, footer, ...rest } = props;\n const element = (\n <Card\n {...rest}\n headerActions={headerActions ? <span dangerouslySetInnerHTML={{ __html: headerActions }} /> : undefined}\n footer={footer ? <span dangerouslySetInnerHTML={{ __html: footer }} /> : undefined}\n >\n {children ? <span dangerouslySetInnerHTML={{ __html: children }} /> : undefined}\n </Card>\n );\n return renderToString(element);\n}\n\n/**\n * Render Card component to static HTML string (sync).\n *\n * Uses React's renderToStaticMarkup for synchronous rendering.\n * Does NOT wait for Suspense boundaries.\n *\n * @param props - Card props (with string children)\n * @returns HTML string\n */\nexport function renderCardSync(props: CardRenderProps): string {\n const { children, headerActions, footer, ...rest } = props;\n const element = (\n <Card\n {...rest}\n headerActions={headerActions ? <span dangerouslySetInnerHTML={{ __html: headerActions }} /> : undefined}\n footer={footer ? <span dangerouslySetInnerHTML={{ __html: footer }} /> : undefined}\n >\n {children ? <span dangerouslySetInnerHTML={{ __html: children }} /> : undefined}\n </Card>\n );\n return renderToStringSync(element);\n}\n\n// Re-export types\nexport type { CardVariant, CardSize };\n\nexport default Card;\n"]}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @file context.tsx
3
+ * @description React context for FrontMcpBridge.
4
+ *
5
+ * Provides a context provider that initializes and exposes the MCP bridge
6
+ * to all child components via hooks.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { McpBridgeProvider, useMcpBridge } from '@frontmcp/ui/react';
11
+ *
12
+ * function App() {
13
+ * return (
14
+ * <McpBridgeProvider>
15
+ * <MyComponent />
16
+ * </McpBridgeProvider>
17
+ * );
18
+ * }
19
+ * ```
20
+ *
21
+ * @module @frontmcp/ui/react/hooks
22
+ */
23
+ import { type ReactNode } from 'react';
24
+ import type { FrontMcpBridgeInterface, BridgeConfig, AdapterCapabilities, HostContext, DisplayMode } from '../../bridge/types';
25
+ /**
26
+ * MCP Bridge context value.
27
+ */
28
+ export interface McpBridgeContextValue {
29
+ /** The bridge instance (null until initialized) */
30
+ bridge: FrontMcpBridgeInterface | null;
31
+ /** Whether the bridge is currently initializing */
32
+ loading: boolean;
33
+ /** Initialization error, if any */
34
+ error: Error | null;
35
+ /** Whether the bridge is initialized and ready */
36
+ ready: boolean;
37
+ /** Current adapter ID */
38
+ adapterId: string | undefined;
39
+ /** Current adapter capabilities */
40
+ capabilities: AdapterCapabilities | undefined;
41
+ }
42
+ /**
43
+ * Props for McpBridgeProvider.
44
+ */
45
+ export interface McpBridgeProviderProps {
46
+ /** Child components */
47
+ children: ReactNode;
48
+ /** Bridge configuration */
49
+ config?: BridgeConfig;
50
+ /** Callback when bridge is ready */
51
+ onReady?: (bridge: FrontMcpBridgeInterface) => void;
52
+ /** Callback when bridge initialization fails */
53
+ onError?: (error: Error) => void;
54
+ }
55
+ /**
56
+ * Provider component that initializes the MCP bridge.
57
+ *
58
+ * @example Basic usage
59
+ * ```tsx
60
+ * <McpBridgeProvider>
61
+ * <App />
62
+ * </McpBridgeProvider>
63
+ * ```
64
+ *
65
+ * @example With configuration
66
+ * ```tsx
67
+ * <McpBridgeProvider
68
+ * config={{ debug: true, forceAdapter: 'generic' }}
69
+ * onReady={(bridge) => console.log('Bridge ready:', bridge.adapterId)}
70
+ * onError={(err) => console.error('Bridge error:', err)}
71
+ * >
72
+ * <App />
73
+ * </McpBridgeProvider>
74
+ * ```
75
+ */
76
+ export declare function McpBridgeProvider({ children, config, onReady, onError }: McpBridgeProviderProps): import("react/jsx-runtime").JSX.Element;
77
+ /**
78
+ * Hook to access the MCP bridge context.
79
+ *
80
+ * During client-side rendering, must be used within a McpBridgeProvider.
81
+ * During SSR (outside of provider), returns a default "not ready" state.
82
+ *
83
+ * @example
84
+ * ```tsx
85
+ * function MyComponent() {
86
+ * const { bridge, loading, error, ready } = useMcpBridgeContext();
87
+ *
88
+ * if (loading) return <div>Loading...</div>;
89
+ * if (error) return <div>Error: {error.message}</div>;
90
+ * if (!ready) return null;
91
+ *
92
+ * return <div>Adapter: {bridge.adapterId}</div>;
93
+ * }
94
+ * ```
95
+ */
96
+ export declare function useMcpBridgeContext(): McpBridgeContextValue;
97
+ /**
98
+ * Hook to get the MCP bridge instance.
99
+ * Returns null while loading or if not initialized.
100
+ *
101
+ * @example
102
+ * ```tsx
103
+ * function MyComponent() {
104
+ * const bridge = useMcpBridge();
105
+ *
106
+ * if (!bridge) return <div>Loading...</div>;
107
+ *
108
+ * const theme = bridge.getTheme();
109
+ * const input = bridge.getToolInput();
110
+ *
111
+ * return <div>Theme: {theme}</div>;
112
+ * }
113
+ * ```
114
+ */
115
+ export declare function useMcpBridge(): FrontMcpBridgeInterface | null;
116
+ /**
117
+ * Hook to get the current theme from the bridge.
118
+ * Automatically updates when theme changes.
119
+ *
120
+ * @example
121
+ * ```tsx
122
+ * function MyComponent() {
123
+ * const theme = useTheme();
124
+ * return <div className={theme === 'dark' ? 'bg-black' : 'bg-white'}>...</div>;
125
+ * }
126
+ * ```
127
+ */
128
+ export declare function useTheme(): 'light' | 'dark';
129
+ /**
130
+ * Hook to get the current display mode from the bridge.
131
+ * Automatically updates when display mode changes.
132
+ *
133
+ * @example
134
+ * ```tsx
135
+ * function MyComponent() {
136
+ * const displayMode = useDisplayMode();
137
+ * return <div>Mode: {displayMode}</div>;
138
+ * }
139
+ * ```
140
+ */
141
+ export declare function useDisplayMode(): DisplayMode;
142
+ /**
143
+ * Hook to get the full host context from the bridge.
144
+ * Automatically updates when context changes.
145
+ *
146
+ * @example
147
+ * ```tsx
148
+ * function MyComponent() {
149
+ * const context = useHostContext();
150
+ * return (
151
+ * <div>
152
+ * Theme: {context?.theme}
153
+ * Locale: {context?.locale}
154
+ * </div>
155
+ * );
156
+ * }
157
+ * ```
158
+ */
159
+ export declare function useHostContext(): HostContext | null;
160
+ /**
161
+ * Hook to check if the bridge has a specific capability.
162
+ *
163
+ * @example
164
+ * ```tsx
165
+ * function MyComponent() {
166
+ * const canCallTools = useCapability('canCallTools');
167
+ * const canSendMessages = useCapability('canSendMessages');
168
+ *
169
+ * return (
170
+ * <div>
171
+ * {canCallTools && <button>Call Tool</button>}
172
+ * {canSendMessages && <button>Send Message</button>}
173
+ * </div>
174
+ * );
175
+ * }
176
+ * ```
177
+ */
178
+ export declare function useCapability(cap: keyof AdapterCapabilities): boolean;
@@ -0,0 +1,287 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.McpBridgeProvider = McpBridgeProvider;
4
+ exports.useMcpBridgeContext = useMcpBridgeContext;
5
+ exports.useMcpBridge = useMcpBridge;
6
+ exports.useTheme = useTheme;
7
+ exports.useDisplayMode = useDisplayMode;
8
+ exports.useHostContext = useHostContext;
9
+ exports.useCapability = useCapability;
10
+ const jsx_runtime_1 = require("react/jsx-runtime");
11
+ /**
12
+ * @file context.tsx
13
+ * @description React context for FrontMcpBridge.
14
+ *
15
+ * Provides a context provider that initializes and exposes the MCP bridge
16
+ * to all child components via hooks.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { McpBridgeProvider, useMcpBridge } from '@frontmcp/ui/react';
21
+ *
22
+ * function App() {
23
+ * return (
24
+ * <McpBridgeProvider>
25
+ * <MyComponent />
26
+ * </McpBridgeProvider>
27
+ * );
28
+ * }
29
+ * ```
30
+ *
31
+ * @module @frontmcp/ui/react/hooks
32
+ */
33
+ const react_1 = require("react");
34
+ const bridge_factory_1 = require("../../bridge/core/bridge-factory");
35
+ // ============================================
36
+ // Context
37
+ // ============================================
38
+ const McpBridgeContext = (0, react_1.createContext)(null);
39
+ /**
40
+ * Provider component that initializes the MCP bridge.
41
+ *
42
+ * @example Basic usage
43
+ * ```tsx
44
+ * <McpBridgeProvider>
45
+ * <App />
46
+ * </McpBridgeProvider>
47
+ * ```
48
+ *
49
+ * @example With configuration
50
+ * ```tsx
51
+ * <McpBridgeProvider
52
+ * config={{ debug: true, forceAdapter: 'generic' }}
53
+ * onReady={(bridge) => console.log('Bridge ready:', bridge.adapterId)}
54
+ * onError={(err) => console.error('Bridge error:', err)}
55
+ * >
56
+ * <App />
57
+ * </McpBridgeProvider>
58
+ * ```
59
+ */
60
+ function McpBridgeProvider({ children, config, onReady, onError }) {
61
+ const [bridge, setBridge] = (0, react_1.useState)(null);
62
+ const [loading, setLoading] = (0, react_1.useState)(true);
63
+ const [error, setError] = (0, react_1.useState)(null);
64
+ (0, react_1.useEffect)(() => {
65
+ let mounted = true;
66
+ let bridgeInstance = null;
67
+ const initBridge = async () => {
68
+ try {
69
+ bridgeInstance = new bridge_factory_1.FrontMcpBridge(config);
70
+ await bridgeInstance.initialize();
71
+ if (mounted) {
72
+ setBridge(bridgeInstance);
73
+ setLoading(false);
74
+ onReady?.(bridgeInstance);
75
+ }
76
+ }
77
+ catch (err) {
78
+ if (mounted) {
79
+ const error = err instanceof Error ? err : new Error(String(err));
80
+ setError(error);
81
+ setLoading(false);
82
+ onError?.(error);
83
+ }
84
+ }
85
+ };
86
+ initBridge();
87
+ return () => {
88
+ mounted = false;
89
+ if (bridgeInstance) {
90
+ bridgeInstance.dispose();
91
+ }
92
+ };
93
+ }, [config, onReady, onError]);
94
+ const contextValue = (0, react_1.useMemo)(() => ({
95
+ bridge,
96
+ loading,
97
+ error,
98
+ ready: !loading && !error && bridge !== null,
99
+ adapterId: bridge?.adapterId,
100
+ capabilities: bridge?.capabilities,
101
+ }), [bridge, loading, error]);
102
+ return (0, jsx_runtime_1.jsx)(McpBridgeContext.Provider, { value: contextValue, children: children });
103
+ }
104
+ // ============================================
105
+ // Hooks
106
+ // ============================================
107
+ /**
108
+ * Default context value for SSR.
109
+ * When the component is rendered outside of McpBridgeProvider (e.g., during SSR),
110
+ * this value is returned instead of throwing an error.
111
+ */
112
+ const SSR_DEFAULT_CONTEXT = {
113
+ bridge: null,
114
+ loading: false,
115
+ error: null,
116
+ ready: false,
117
+ adapterId: undefined,
118
+ capabilities: undefined,
119
+ };
120
+ /**
121
+ * Hook to access the MCP bridge context.
122
+ *
123
+ * During client-side rendering, must be used within a McpBridgeProvider.
124
+ * During SSR (outside of provider), returns a default "not ready" state.
125
+ *
126
+ * @example
127
+ * ```tsx
128
+ * function MyComponent() {
129
+ * const { bridge, loading, error, ready } = useMcpBridgeContext();
130
+ *
131
+ * if (loading) return <div>Loading...</div>;
132
+ * if (error) return <div>Error: {error.message}</div>;
133
+ * if (!ready) return null;
134
+ *
135
+ * return <div>Adapter: {bridge.adapterId}</div>;
136
+ * }
137
+ * ```
138
+ */
139
+ function useMcpBridgeContext() {
140
+ const context = (0, react_1.useContext)(McpBridgeContext);
141
+ // During SSR or outside of provider, return default context instead of throwing
142
+ if (!context) {
143
+ return SSR_DEFAULT_CONTEXT;
144
+ }
145
+ return context;
146
+ }
147
+ /**
148
+ * Hook to get the MCP bridge instance.
149
+ * Returns null while loading or if not initialized.
150
+ *
151
+ * @example
152
+ * ```tsx
153
+ * function MyComponent() {
154
+ * const bridge = useMcpBridge();
155
+ *
156
+ * if (!bridge) return <div>Loading...</div>;
157
+ *
158
+ * const theme = bridge.getTheme();
159
+ * const input = bridge.getToolInput();
160
+ *
161
+ * return <div>Theme: {theme}</div>;
162
+ * }
163
+ * ```
164
+ */
165
+ function useMcpBridge() {
166
+ const { bridge } = useMcpBridgeContext();
167
+ return bridge;
168
+ }
169
+ /**
170
+ * Hook to get the current theme from the bridge.
171
+ * Automatically updates when theme changes.
172
+ *
173
+ * @example
174
+ * ```tsx
175
+ * function MyComponent() {
176
+ * const theme = useTheme();
177
+ * return <div className={theme === 'dark' ? 'bg-black' : 'bg-white'}>...</div>;
178
+ * }
179
+ * ```
180
+ */
181
+ function useTheme() {
182
+ const { bridge, ready } = useMcpBridgeContext();
183
+ const [theme, setTheme] = (0, react_1.useState)('light');
184
+ (0, react_1.useEffect)(() => {
185
+ if (!ready || !bridge)
186
+ return;
187
+ // Get initial theme
188
+ setTheme(bridge.getTheme());
189
+ // Subscribe to changes
190
+ const unsubscribe = bridge.onContextChange((changes) => {
191
+ if (changes.theme) {
192
+ setTheme(changes.theme);
193
+ }
194
+ });
195
+ return unsubscribe;
196
+ }, [bridge, ready]);
197
+ return theme;
198
+ }
199
+ /**
200
+ * Hook to get the current display mode from the bridge.
201
+ * Automatically updates when display mode changes.
202
+ *
203
+ * @example
204
+ * ```tsx
205
+ * function MyComponent() {
206
+ * const displayMode = useDisplayMode();
207
+ * return <div>Mode: {displayMode}</div>;
208
+ * }
209
+ * ```
210
+ */
211
+ function useDisplayMode() {
212
+ const { bridge, ready } = useMcpBridgeContext();
213
+ const [displayMode, setDisplayMode] = (0, react_1.useState)('inline');
214
+ (0, react_1.useEffect)(() => {
215
+ if (!ready || !bridge)
216
+ return;
217
+ // Get initial display mode
218
+ setDisplayMode(bridge.getDisplayMode());
219
+ // Subscribe to changes
220
+ const unsubscribe = bridge.onContextChange((changes) => {
221
+ if (changes.displayMode) {
222
+ setDisplayMode(changes.displayMode);
223
+ }
224
+ });
225
+ return unsubscribe;
226
+ }, [bridge, ready]);
227
+ return displayMode;
228
+ }
229
+ /**
230
+ * Hook to get the full host context from the bridge.
231
+ * Automatically updates when context changes.
232
+ *
233
+ * @example
234
+ * ```tsx
235
+ * function MyComponent() {
236
+ * const context = useHostContext();
237
+ * return (
238
+ * <div>
239
+ * Theme: {context?.theme}
240
+ * Locale: {context?.locale}
241
+ * </div>
242
+ * );
243
+ * }
244
+ * ```
245
+ */
246
+ function useHostContext() {
247
+ const { bridge, ready } = useMcpBridgeContext();
248
+ const [context, setContext] = (0, react_1.useState)(null);
249
+ (0, react_1.useEffect)(() => {
250
+ if (!ready || !bridge)
251
+ return;
252
+ // Get initial context
253
+ const adapter = bridge.getAdapter?.();
254
+ if (adapter) {
255
+ setContext(adapter.getHostContext());
256
+ }
257
+ // Subscribe to changes
258
+ const unsubscribe = bridge.onContextChange((changes) => {
259
+ setContext((prev) => (prev ? { ...prev, ...changes } : null));
260
+ });
261
+ return unsubscribe;
262
+ }, [bridge, ready]);
263
+ return context;
264
+ }
265
+ /**
266
+ * Hook to check if the bridge has a specific capability.
267
+ *
268
+ * @example
269
+ * ```tsx
270
+ * function MyComponent() {
271
+ * const canCallTools = useCapability('canCallTools');
272
+ * const canSendMessages = useCapability('canSendMessages');
273
+ *
274
+ * return (
275
+ * <div>
276
+ * {canCallTools && <button>Call Tool</button>}
277
+ * {canSendMessages && <button>Send Message</button>}
278
+ * </div>
279
+ * );
280
+ * }
281
+ * ```
282
+ */
283
+ function useCapability(cap) {
284
+ const { capabilities } = useMcpBridgeContext();
285
+ return capabilities?.[cap] === true;
286
+ }
287
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/react/hooks/context.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file context.tsx\n * @description React context for FrontMcpBridge.\n *\n * Provides a context provider that initializes and exposes the MCP bridge\n * to all child components via hooks.\n *\n * @example\n * ```tsx\n * import { McpBridgeProvider, useMcpBridge } from '@frontmcp/ui/react';\n *\n * function App() {\n * return (\n * <McpBridgeProvider>\n * <MyComponent />\n * </McpBridgeProvider>\n * );\n * }\n * ```\n *\n * @module @frontmcp/ui/react/hooks\n */\n\nimport { createContext, useContext, useEffect, useState, useCallback, useMemo, type ReactNode } from 'react';\nimport type {\n FrontMcpBridgeInterface,\n BridgeConfig,\n AdapterCapabilities,\n HostContext,\n DisplayMode,\n} from '../../bridge/types';\nimport { FrontMcpBridge } from '../../bridge/core/bridge-factory';\n\n// ============================================\n// Types\n// ============================================\n\n/**\n * MCP Bridge context value.\n */\nexport interface McpBridgeContextValue {\n /** The bridge instance (null until initialized) */\n bridge: FrontMcpBridgeInterface | null;\n /** Whether the bridge is currently initializing */\n loading: boolean;\n /** Initialization error, if any */\n error: Error | null;\n /** Whether the bridge is initialized and ready */\n ready: boolean;\n /** Current adapter ID */\n adapterId: string | undefined;\n /** Current adapter capabilities */\n capabilities: AdapterCapabilities | undefined;\n}\n\n/**\n * Props for McpBridgeProvider.\n */\nexport interface McpBridgeProviderProps {\n /** Child components */\n children: ReactNode;\n /** Bridge configuration */\n config?: BridgeConfig;\n /** Callback when bridge is ready */\n onReady?: (bridge: FrontMcpBridgeInterface) => void;\n /** Callback when bridge initialization fails */\n onError?: (error: Error) => void;\n}\n\n// ============================================\n// Context\n// ============================================\n\nconst McpBridgeContext = createContext<McpBridgeContextValue | null>(null);\n\n/**\n * Provider component that initializes the MCP bridge.\n *\n * @example Basic usage\n * ```tsx\n * <McpBridgeProvider>\n * <App />\n * </McpBridgeProvider>\n * ```\n *\n * @example With configuration\n * ```tsx\n * <McpBridgeProvider\n * config={{ debug: true, forceAdapter: 'generic' }}\n * onReady={(bridge) => console.log('Bridge ready:', bridge.adapterId)}\n * onError={(err) => console.error('Bridge error:', err)}\n * >\n * <App />\n * </McpBridgeProvider>\n * ```\n */\nexport function McpBridgeProvider({ children, config, onReady, onError }: McpBridgeProviderProps) {\n const [bridge, setBridge] = useState<FrontMcpBridgeInterface | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let mounted = true;\n let bridgeInstance: FrontMcpBridge | null = null;\n\n const initBridge = async () => {\n try {\n bridgeInstance = new FrontMcpBridge(config);\n await bridgeInstance.initialize();\n\n if (mounted) {\n setBridge(bridgeInstance);\n setLoading(false);\n onReady?.(bridgeInstance);\n }\n } catch (err) {\n if (mounted) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n setLoading(false);\n onError?.(error);\n }\n }\n };\n\n initBridge();\n\n return () => {\n mounted = false;\n if (bridgeInstance) {\n bridgeInstance.dispose();\n }\n };\n }, [config, onReady, onError]);\n\n const contextValue = useMemo<McpBridgeContextValue>(\n () => ({\n bridge,\n loading,\n error,\n ready: !loading && !error && bridge !== null,\n adapterId: bridge?.adapterId,\n capabilities: bridge?.capabilities,\n }),\n [bridge, loading, error],\n );\n\n return <McpBridgeContext.Provider value={contextValue}>{children}</McpBridgeContext.Provider>;\n}\n\n// ============================================\n// Hooks\n// ============================================\n\n/**\n * Default context value for SSR.\n * When the component is rendered outside of McpBridgeProvider (e.g., during SSR),\n * this value is returned instead of throwing an error.\n */\nconst SSR_DEFAULT_CONTEXT: McpBridgeContextValue = {\n bridge: null,\n loading: false,\n error: null,\n ready: false,\n adapterId: undefined,\n capabilities: undefined,\n};\n\n/**\n * Hook to access the MCP bridge context.\n *\n * During client-side rendering, must be used within a McpBridgeProvider.\n * During SSR (outside of provider), returns a default \"not ready\" state.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { bridge, loading, error, ready } = useMcpBridgeContext();\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * if (!ready) return null;\n *\n * return <div>Adapter: {bridge.adapterId}</div>;\n * }\n * ```\n */\nexport function useMcpBridgeContext(): McpBridgeContextValue {\n const context = useContext(McpBridgeContext);\n\n // During SSR or outside of provider, return default context instead of throwing\n if (!context) {\n return SSR_DEFAULT_CONTEXT;\n }\n\n return context;\n}\n\n/**\n * Hook to get the MCP bridge instance.\n * Returns null while loading or if not initialized.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const bridge = useMcpBridge();\n *\n * if (!bridge) return <div>Loading...</div>;\n *\n * const theme = bridge.getTheme();\n * const input = bridge.getToolInput();\n *\n * return <div>Theme: {theme}</div>;\n * }\n * ```\n */\nexport function useMcpBridge(): FrontMcpBridgeInterface | null {\n const { bridge } = useMcpBridgeContext();\n return bridge;\n}\n\n/**\n * Hook to get the current theme from the bridge.\n * Automatically updates when theme changes.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const theme = useTheme();\n * return <div className={theme === 'dark' ? 'bg-black' : 'bg-white'}>...</div>;\n * }\n * ```\n */\nexport function useTheme(): 'light' | 'dark' {\n const { bridge, ready } = useMcpBridgeContext();\n const [theme, setTheme] = useState<'light' | 'dark'>('light');\n\n useEffect(() => {\n if (!ready || !bridge) return;\n\n // Get initial theme\n setTheme(bridge.getTheme());\n\n // Subscribe to changes\n const unsubscribe = bridge.onContextChange((changes) => {\n if (changes.theme) {\n setTheme(changes.theme);\n }\n });\n\n return unsubscribe;\n }, [bridge, ready]);\n\n return theme;\n}\n\n/**\n * Hook to get the current display mode from the bridge.\n * Automatically updates when display mode changes.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const displayMode = useDisplayMode();\n * return <div>Mode: {displayMode}</div>;\n * }\n * ```\n */\nexport function useDisplayMode(): DisplayMode {\n const { bridge, ready } = useMcpBridgeContext();\n const [displayMode, setDisplayMode] = useState<DisplayMode>('inline');\n\n useEffect(() => {\n if (!ready || !bridge) return;\n\n // Get initial display mode\n setDisplayMode(bridge.getDisplayMode());\n\n // Subscribe to changes\n const unsubscribe = bridge.onContextChange((changes) => {\n if (changes.displayMode) {\n setDisplayMode(changes.displayMode);\n }\n });\n\n return unsubscribe;\n }, [bridge, ready]);\n\n return displayMode;\n}\n\n/**\n * Hook to get the full host context from the bridge.\n * Automatically updates when context changes.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const context = useHostContext();\n * return (\n * <div>\n * Theme: {context?.theme}\n * Locale: {context?.locale}\n * </div>\n * );\n * }\n * ```\n */\nexport function useHostContext(): HostContext | null {\n const { bridge, ready } = useMcpBridgeContext();\n const [context, setContext] = useState<HostContext | null>(null);\n\n useEffect(() => {\n if (!ready || !bridge) return;\n\n // Get initial context\n const adapter = bridge.getAdapter?.();\n if (adapter) {\n setContext(adapter.getHostContext());\n }\n\n // Subscribe to changes\n const unsubscribe = bridge.onContextChange((changes) => {\n setContext((prev) => (prev ? { ...prev, ...changes } : null));\n });\n\n return unsubscribe;\n }, [bridge, ready]);\n\n return context;\n}\n\n/**\n * Hook to check if the bridge has a specific capability.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const canCallTools = useCapability('canCallTools');\n * const canSendMessages = useCapability('canSendMessages');\n *\n * return (\n * <div>\n * {canCallTools && <button>Call Tool</button>}\n * {canSendMessages && <button>Send Message</button>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useCapability(cap: keyof AdapterCapabilities): boolean {\n const { capabilities } = useMcpBridgeContext();\n return capabilities?.[cap] === true;\n}\n"]}