@miragon/mcp-toolkit-ui 2.6.0 → 2.8.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 (511) hide show
  1. package/README.md +14 -5
  2. package/dist/app/adapt-data-widget.d.ts +1 -22
  3. package/dist/app/adapt-data-widget.d.ts.map +1 -1
  4. package/dist/app/adapt-data-widget.js +1 -35
  5. package/dist/app/adapt-data-widget.js.map +1 -1
  6. package/dist/app/builder/BuilderBanners.d.ts +7 -2
  7. package/dist/app/builder/BuilderBanners.d.ts.map +1 -1
  8. package/dist/app/builder/BuilderBanners.js +8 -3
  9. package/dist/app/builder/BuilderBanners.js.map +1 -1
  10. package/dist/app/builder/CanvasRow.d.ts +4 -2
  11. package/dist/app/builder/CanvasRow.d.ts.map +1 -1
  12. package/dist/app/builder/CanvasRow.js +29 -17
  13. package/dist/app/builder/CanvasRow.js.map +1 -1
  14. package/dist/app/builder/CatalogueSheet.d.ts.map +1 -1
  15. package/dist/app/builder/CatalogueSheet.js +14 -6
  16. package/dist/app/builder/CatalogueSheet.js.map +1 -1
  17. package/dist/app/builder/CellPropsSheet.d.ts +7 -3
  18. package/dist/app/builder/CellPropsSheet.d.ts.map +1 -1
  19. package/dist/app/builder/CellPropsSheet.js +10 -3
  20. package/dist/app/builder/CellPropsSheet.js.map +1 -1
  21. package/dist/app/builder/DiscardDialog.d.ts +18 -0
  22. package/dist/app/builder/DiscardDialog.d.ts.map +1 -0
  23. package/dist/app/builder/DiscardDialog.js +18 -0
  24. package/dist/app/builder/DiscardDialog.js.map +1 -0
  25. package/dist/app/builder/EmptyHint.d.ts +4 -0
  26. package/dist/app/builder/EmptyHint.d.ts.map +1 -1
  27. package/dist/app/builder/EmptyHint.js +6 -1
  28. package/dist/app/builder/EmptyHint.js.map +1 -1
  29. package/dist/app/builder/LayoutSurface.d.ts +33 -9
  30. package/dist/app/builder/LayoutSurface.d.ts.map +1 -1
  31. package/dist/app/builder/LayoutSurface.js +74 -23
  32. package/dist/app/builder/LayoutSurface.js.map +1 -1
  33. package/dist/app/builder/PipelineStrip.d.ts +5 -2
  34. package/dist/app/builder/PipelineStrip.d.ts.map +1 -1
  35. package/dist/app/builder/PipelineStrip.js +33 -15
  36. package/dist/app/builder/PipelineStrip.js.map +1 -1
  37. package/dist/app/builder/SaveDialog.d.ts +9 -1
  38. package/dist/app/builder/SaveDialog.d.ts.map +1 -1
  39. package/dist/app/builder/SaveDialog.js +9 -3
  40. package/dist/app/builder/SaveDialog.js.map +1 -1
  41. package/dist/app/builder/Toolbar.d.ts +14 -4
  42. package/dist/app/builder/Toolbar.d.ts.map +1 -1
  43. package/dist/app/builder/Toolbar.js +24 -7
  44. package/dist/app/builder/Toolbar.js.map +1 -1
  45. package/dist/app/builder/Workspace.d.ts +23 -3
  46. package/dist/app/builder/Workspace.d.ts.map +1 -1
  47. package/dist/app/builder/Workspace.js +58 -8
  48. package/dist/app/builder/Workspace.js.map +1 -1
  49. package/dist/app/builder/builder-model.d.ts +146 -3
  50. package/dist/app/builder/builder-model.d.ts.map +1 -1
  51. package/dist/app/builder/builder-model.js +196 -5
  52. package/dist/app/builder/builder-model.js.map +1 -1
  53. package/dist/app/builder/labels.d.ts +13 -62
  54. package/dist/app/builder/labels.d.ts.map +1 -1
  55. package/dist/app/builder/labels.js +9 -58
  56. package/dist/app/builder/labels.js.map +1 -1
  57. package/dist/app/builder/reveal.d.ts +10 -0
  58. package/dist/app/builder/reveal.d.ts.map +1 -0
  59. package/dist/app/builder/reveal.js +10 -0
  60. package/dist/app/builder/reveal.js.map +1 -0
  61. package/dist/app/builder/status-chip.d.ts.map +1 -1
  62. package/dist/app/builder/status-chip.js +3 -2
  63. package/dist/app/builder/status-chip.js.map +1 -1
  64. package/dist/app/builder/use-builder-catalogue.d.ts +5 -1
  65. package/dist/app/builder/use-builder-catalogue.d.ts.map +1 -1
  66. package/dist/app/builder/use-builder-catalogue.js +50 -17
  67. package/dist/app/builder/use-builder-catalogue.js.map +1 -1
  68. package/dist/app/builder/use-builder-session.d.ts +30 -0
  69. package/dist/app/builder/use-builder-session.d.ts.map +1 -0
  70. package/dist/app/builder/use-builder-session.js +58 -0
  71. package/dist/app/builder/use-builder-session.js.map +1 -0
  72. package/dist/app/builder/use-display-resolver.d.ts +17 -0
  73. package/dist/app/builder/use-display-resolver.d.ts.map +1 -0
  74. package/dist/app/builder/use-display-resolver.js +16 -0
  75. package/dist/app/builder/use-display-resolver.js.map +1 -0
  76. package/dist/app/builder/use-save-dashboard.d.ts +3 -1
  77. package/dist/app/builder/use-save-dashboard.d.ts.map +1 -1
  78. package/dist/app/builder/use-save-dashboard.js +3 -1
  79. package/dist/app/builder/use-save-dashboard.js.map +1 -1
  80. package/dist/app/index.d.ts +8 -3
  81. package/dist/app/index.d.ts.map +1 -1
  82. package/dist/app/index.js +8 -2
  83. package/dist/app/index.js.map +1 -1
  84. package/dist/app/layout-builder.d.ts +18 -25
  85. package/dist/app/layout-builder.d.ts.map +1 -1
  86. package/dist/app/layout-builder.js +84 -78
  87. package/dist/app/layout-builder.js.map +1 -1
  88. package/dist/app/mcp-app-view-chrome.d.ts +103 -20
  89. package/dist/app/mcp-app-view-chrome.d.ts.map +1 -1
  90. package/dist/app/mcp-app-view-chrome.js +125 -40
  91. package/dist/app/mcp-app-view-chrome.js.map +1 -1
  92. package/dist/app/mcp-app-view-states.d.ts +23 -0
  93. package/dist/app/mcp-app-view-states.d.ts.map +1 -0
  94. package/dist/app/mcp-app-view-states.js +55 -0
  95. package/dist/app/mcp-app-view-states.js.map +1 -0
  96. package/dist/app/mcp-app-view.d.ts +72 -5
  97. package/dist/app/mcp-app-view.d.ts.map +1 -1
  98. package/dist/app/mcp-app-view.js +241 -141
  99. package/dist/app/mcp-app-view.js.map +1 -1
  100. package/dist/app/mcp-toolkit-app.d.ts +8 -2
  101. package/dist/app/mcp-toolkit-app.d.ts.map +1 -1
  102. package/dist/app/mcp-toolkit-app.js +33 -4
  103. package/dist/app/mcp-toolkit-app.js.map +1 -1
  104. package/dist/app/mcp-use-host-bridge.d.ts +15 -6
  105. package/dist/app/mcp-use-host-bridge.d.ts.map +1 -1
  106. package/dist/app/mcp-use-host-bridge.js +51 -22
  107. package/dist/app/mcp-use-host-bridge.js.map +1 -1
  108. package/dist/app/model-context.d.ts +71 -0
  109. package/dist/app/model-context.d.ts.map +1 -0
  110. package/dist/app/model-context.js +101 -0
  111. package/dist/app/model-context.js.map +1 -0
  112. package/dist/app/use-build-mode-focus.d.ts +33 -0
  113. package/dist/app/use-build-mode-focus.d.ts.map +1 -0
  114. package/dist/app/use-build-mode-focus.js +59 -0
  115. package/dist/app/use-build-mode-focus.js.map +1 -0
  116. package/dist/app/use-view-actions.d.ts +31 -0
  117. package/dist/app/use-view-actions.d.ts.map +1 -0
  118. package/dist/app/use-view-actions.js +81 -0
  119. package/dist/app/use-view-actions.js.map +1 -0
  120. package/dist/app/use-view-lifecycle.d.ts +42 -0
  121. package/dist/app/use-view-lifecycle.d.ts.map +1 -0
  122. package/dist/app/use-view-lifecycle.js +81 -0
  123. package/dist/app/use-view-lifecycle.js.map +1 -0
  124. package/dist/app/view-lifecycle.d.ts +185 -0
  125. package/dist/app/view-lifecycle.d.ts.map +1 -0
  126. package/dist/app/view-lifecycle.js +207 -0
  127. package/dist/app/view-lifecycle.js.map +1 -0
  128. package/dist/app/widget-fixture.d.ts +10 -3
  129. package/dist/app/widget-fixture.d.ts.map +1 -1
  130. package/dist/app/widget-fixture.js +21 -8
  131. package/dist/app/widget-fixture.js.map +1 -1
  132. package/dist/app/widget-props-sheet.d.ts +6 -10
  133. package/dist/app/widget-props-sheet.d.ts.map +1 -1
  134. package/dist/app/widget-props-sheet.js +25 -20
  135. package/dist/app/widget-props-sheet.js.map +1 -1
  136. package/dist/app/widget-renderer.d.ts +41 -1
  137. package/dist/app/widget-renderer.d.ts.map +1 -1
  138. package/dist/app/widget-renderer.js +82 -31
  139. package/dist/app/widget-renderer.js.map +1 -1
  140. package/dist/components/DrillButton.d.ts +9 -6
  141. package/dist/components/DrillButton.d.ts.map +1 -1
  142. package/dist/components/DrillButton.js +9 -6
  143. package/dist/components/DrillButton.js.map +1 -1
  144. package/dist/components/EmptyState.d.ts +33 -0
  145. package/dist/components/EmptyState.d.ts.map +1 -0
  146. package/dist/components/EmptyState.js +19 -0
  147. package/dist/components/EmptyState.js.map +1 -0
  148. package/dist/components/ErrorState.d.ts +53 -0
  149. package/dist/components/ErrorState.d.ts.map +1 -0
  150. package/dist/components/ErrorState.js +77 -0
  151. package/dist/components/ErrorState.js.map +1 -0
  152. package/dist/components/FilterBar.d.ts +16 -5
  153. package/dist/components/FilterBar.d.ts.map +1 -1
  154. package/dist/components/FilterBar.js +13 -5
  155. package/dist/components/FilterBar.js.map +1 -1
  156. package/dist/components/GroupCard.d.ts.map +1 -1
  157. package/dist/components/GroupCard.js +2 -1
  158. package/dist/components/GroupCard.js.map +1 -1
  159. package/dist/components/KpiGrid.d.ts +70 -18
  160. package/dist/components/KpiGrid.d.ts.map +1 -1
  161. package/dist/components/KpiGrid.js +112 -23
  162. package/dist/components/KpiGrid.js.map +1 -1
  163. package/dist/components/ListFooter.d.ts +32 -4
  164. package/dist/components/ListFooter.d.ts.map +1 -1
  165. package/dist/components/ListFooter.js +35 -6
  166. package/dist/components/ListFooter.js.map +1 -1
  167. package/dist/components/PagedListFooter.d.ts +57 -0
  168. package/dist/components/PagedListFooter.d.ts.map +1 -0
  169. package/dist/components/PagedListFooter.js +27 -0
  170. package/dist/components/PagedListFooter.js.map +1 -0
  171. package/dist/components/Pills.d.ts +36 -12
  172. package/dist/components/Pills.d.ts.map +1 -1
  173. package/dist/components/Pills.js +29 -8
  174. package/dist/components/Pills.js.map +1 -1
  175. package/dist/components/SectionHeading.d.ts +3 -1
  176. package/dist/components/SectionHeading.d.ts.map +1 -1
  177. package/dist/components/SectionHeading.js +6 -2
  178. package/dist/components/SectionHeading.js.map +1 -1
  179. package/dist/components/Toast.d.ts +43 -0
  180. package/dist/components/Toast.d.ts.map +1 -0
  181. package/dist/components/Toast.js +106 -0
  182. package/dist/components/Toast.js.map +1 -0
  183. package/dist/components/WidgetHeader.d.ts +34 -10
  184. package/dist/components/WidgetHeader.d.ts.map +1 -1
  185. package/dist/components/WidgetHeader.js +11 -6
  186. package/dist/components/WidgetHeader.js.map +1 -1
  187. package/dist/hooks/index.d.ts +4 -4
  188. package/dist/hooks/index.d.ts.map +1 -1
  189. package/dist/hooks/index.js +1 -1
  190. package/dist/hooks/index.js.map +1 -1
  191. package/dist/hooks/tool-result-recovery-model.d.ts +155 -0
  192. package/dist/hooks/tool-result-recovery-model.d.ts.map +1 -0
  193. package/dist/hooks/tool-result-recovery-model.js +273 -0
  194. package/dist/hooks/tool-result-recovery-model.js.map +1 -0
  195. package/dist/hooks/use-tool-query.d.ts +56 -14
  196. package/dist/hooks/use-tool-query.d.ts.map +1 -1
  197. package/dist/hooks/use-tool-query.js +102 -25
  198. package/dist/hooks/use-tool-query.js.map +1 -1
  199. package/dist/hooks/use-tool-result-recovery.d.ts +61 -44
  200. package/dist/hooks/use-tool-result-recovery.d.ts.map +1 -1
  201. package/dist/hooks/use-tool-result-recovery.js +62 -110
  202. package/dist/hooks/use-tool-result-recovery.js.map +1 -1
  203. package/dist/hooks/use-view-data.d.ts +55 -7
  204. package/dist/hooks/use-view-data.d.ts.map +1 -1
  205. package/dist/hooks/use-view-data.js +81 -11
  206. package/dist/hooks/use-view-data.js.map +1 -1
  207. package/dist/hooks/use-view-tool-query.d.ts +12 -7
  208. package/dist/hooks/use-view-tool-query.d.ts.map +1 -1
  209. package/dist/hooks/use-view-tool-query.js +15 -14
  210. package/dist/hooks/use-view-tool-query.js.map +1 -1
  211. package/dist/index.d.ts +27 -13
  212. package/dist/index.d.ts.map +1 -1
  213. package/dist/index.js +29 -7
  214. package/dist/index.js.map +1 -1
  215. package/dist/lib/focus-return.d.ts +61 -0
  216. package/dist/lib/focus-return.d.ts.map +1 -0
  217. package/dist/lib/focus-return.js +46 -0
  218. package/dist/lib/focus-return.js.map +1 -0
  219. package/dist/lib/focus-ring.d.ts +18 -0
  220. package/dist/lib/focus-ring.d.ts.map +1 -0
  221. package/dist/lib/focus-ring.js +18 -0
  222. package/dist/lib/focus-ring.js.map +1 -0
  223. package/dist/lib/icon-stroke.d.ts +12 -0
  224. package/dist/lib/icon-stroke.d.ts.map +1 -0
  225. package/dist/lib/icon-stroke.js +12 -0
  226. package/dist/lib/icon-stroke.js.map +1 -0
  227. package/dist/lib/parse-tool-result.d.ts +23 -1
  228. package/dist/lib/parse-tool-result.d.ts.map +1 -1
  229. package/dist/lib/parse-tool-result.js +38 -2
  230. package/dist/lib/parse-tool-result.js.map +1 -1
  231. package/dist/lib/toast-model.d.ts +86 -0
  232. package/dist/lib/toast-model.d.ts.map +1 -0
  233. package/dist/lib/toast-model.js +102 -0
  234. package/dist/lib/toast-model.js.map +1 -0
  235. package/dist/lib/tone-utils.d.ts +95 -9
  236. package/dist/lib/tone-utils.d.ts.map +1 -1
  237. package/dist/lib/tone-utils.js +100 -9
  238. package/dist/lib/tone-utils.js.map +1 -1
  239. package/dist/lib/tool-query.d.ts +107 -0
  240. package/dist/lib/tool-query.d.ts.map +1 -0
  241. package/dist/lib/tool-query.js +182 -0
  242. package/dist/lib/tool-query.js.map +1 -0
  243. package/dist/lib/tool-result-observer.d.ts +108 -0
  244. package/dist/lib/tool-result-observer.d.ts.map +1 -0
  245. package/dist/lib/tool-result-observer.js +158 -0
  246. package/dist/lib/tool-result-observer.js.map +1 -0
  247. package/dist/lib/typography.d.ts +37 -0
  248. package/dist/lib/typography.d.ts.map +1 -0
  249. package/dist/lib/typography.js +41 -0
  250. package/dist/lib/typography.js.map +1 -0
  251. package/dist/lib/utils.d.ts.map +1 -1
  252. package/dist/lib/utils.js +11 -1
  253. package/dist/lib/utils.js.map +1 -1
  254. package/dist/locale/index.d.ts +3 -1
  255. package/dist/locale/index.d.ts.map +1 -1
  256. package/dist/locale/index.js +2 -1
  257. package/dist/locale/index.js.map +1 -1
  258. package/dist/locale/locale-provider.d.ts +42 -1
  259. package/dist/locale/locale-provider.d.ts.map +1 -1
  260. package/dist/locale/locale-provider.js +44 -3
  261. package/dist/locale/locale-provider.js.map +1 -1
  262. package/dist/locale/message-types.d.ts +336 -0
  263. package/dist/locale/message-types.d.ts.map +1 -0
  264. package/dist/locale/message-types.js +7 -0
  265. package/dist/locale/message-types.js.map +1 -0
  266. package/dist/locale/messages-de.d.ts +9 -0
  267. package/dist/locale/messages-de.d.ts.map +1 -0
  268. package/dist/locale/messages-de.js +185 -0
  269. package/dist/locale/messages-de.js.map +1 -0
  270. package/dist/locale/messages-en.d.ts +8 -0
  271. package/dist/locale/messages-en.d.ts.map +1 -0
  272. package/dist/locale/messages-en.js +184 -0
  273. package/dist/locale/messages-en.js.map +1 -0
  274. package/dist/locale/toolkit-messages.d.ts +57 -0
  275. package/dist/locale/toolkit-messages.d.ts.map +1 -0
  276. package/dist/locale/toolkit-messages.js +103 -0
  277. package/dist/locale/toolkit-messages.js.map +1 -0
  278. package/dist/primitives/alert.d.ts +1 -1
  279. package/dist/primitives/alert.d.ts.map +1 -1
  280. package/dist/primitives/alert.js +6 -2
  281. package/dist/primitives/alert.js.map +1 -1
  282. package/dist/primitives/badge.d.ts +1 -1
  283. package/dist/primitives/badge.d.ts.map +1 -1
  284. package/dist/primitives/badge.js +19 -6
  285. package/dist/primitives/badge.js.map +1 -1
  286. package/dist/primitives/button.d.ts +1 -1
  287. package/dist/primitives/button.d.ts.map +1 -1
  288. package/dist/primitives/button.js +12 -8
  289. package/dist/primitives/button.js.map +1 -1
  290. package/dist/primitives/card.js +4 -4
  291. package/dist/primitives/card.js.map +1 -1
  292. package/dist/primitives/dialog.d.ts +7 -3
  293. package/dist/primitives/dialog.d.ts.map +1 -1
  294. package/dist/primitives/dialog.js +22 -8
  295. package/dist/primitives/dialog.js.map +1 -1
  296. package/dist/primitives/input.d.ts.map +1 -1
  297. package/dist/primitives/input.js +4 -1
  298. package/dist/primitives/input.js.map +1 -1
  299. package/dist/primitives/scroll-area.js +1 -1
  300. package/dist/primitives/scroll-area.js.map +1 -1
  301. package/dist/primitives/select.d.ts.map +1 -1
  302. package/dist/primitives/select.js +6 -3
  303. package/dist/primitives/select.js.map +1 -1
  304. package/dist/primitives/sheet.d.ts +3 -1
  305. package/dist/primitives/sheet.d.ts.map +1 -1
  306. package/dist/primitives/sheet.js +17 -7
  307. package/dist/primitives/sheet.js.map +1 -1
  308. package/dist/primitives/skeleton.js +1 -1
  309. package/dist/primitives/skeleton.js.map +1 -1
  310. package/dist/primitives/switch.d.ts.map +1 -1
  311. package/dist/primitives/switch.js +2 -1
  312. package/dist/primitives/switch.js.map +1 -1
  313. package/dist/primitives/tabs.d.ts.map +1 -1
  314. package/dist/primitives/tabs.js +5 -3
  315. package/dist/primitives/tabs.js.map +1 -1
  316. package/dist/providers/query-provider.d.ts +32 -1
  317. package/dist/providers/query-provider.d.ts.map +1 -1
  318. package/dist/providers/query-provider.js +53 -4
  319. package/dist/providers/query-provider.js.map +1 -1
  320. package/dist/render-cases-primitives.js +1 -1
  321. package/dist/render-cases-primitives.js.map +1 -1
  322. package/dist/render-cases.d.ts.map +1 -1
  323. package/dist/render-cases.js +48 -6
  324. package/dist/render-cases.js.map +1 -1
  325. package/dist/render-effects.d.ts +42 -0
  326. package/dist/render-effects.d.ts.map +1 -0
  327. package/dist/render-effects.js +81 -0
  328. package/dist/render-effects.js.map +1 -0
  329. package/dist/render-scan.d.ts +25 -0
  330. package/dist/render-scan.d.ts.map +1 -0
  331. package/dist/render-scan.js +66 -0
  332. package/dist/render-scan.js.map +1 -0
  333. package/dist/theme/cd-tokens.d.ts +66 -0
  334. package/dist/theme/cd-tokens.d.ts.map +1 -0
  335. package/dist/theme/cd-tokens.js +64 -0
  336. package/dist/theme/cd-tokens.js.map +1 -0
  337. package/dist/theme/create-theme.d.ts +214 -39
  338. package/dist/theme/create-theme.d.ts.map +1 -1
  339. package/dist/theme/create-theme.js +204 -13
  340. package/dist/theme/create-theme.js.map +1 -1
  341. package/dist/theme/fonts.d.ts +38 -0
  342. package/dist/theme/fonts.d.ts.map +1 -0
  343. package/dist/theme/fonts.js +56 -0
  344. package/dist/theme/fonts.js.map +1 -0
  345. package/dist/theme/host-fonts.d.ts +39 -0
  346. package/dist/theme/host-fonts.d.ts.map +1 -0
  347. package/dist/theme/host-fonts.js +44 -0
  348. package/dist/theme/host-fonts.js.map +1 -0
  349. package/dist/theme/index.d.ts +8 -1
  350. package/dist/theme/index.d.ts.map +1 -1
  351. package/dist/theme/index.js +5 -1
  352. package/dist/theme/index.js.map +1 -1
  353. package/dist/theme/portal-container.d.ts +16 -0
  354. package/dist/theme/portal-container.d.ts.map +1 -0
  355. package/dist/theme/portal-container.js +19 -0
  356. package/dist/theme/portal-container.js.map +1 -0
  357. package/dist/theme/presets.d.ts +24 -9
  358. package/dist/theme/presets.d.ts.map +1 -1
  359. package/dist/theme/presets.js +44 -11
  360. package/dist/theme/presets.js.map +1 -1
  361. package/dist/theme/theme-provider.d.ts +27 -9
  362. package/dist/theme/theme-provider.d.ts.map +1 -1
  363. package/dist/theme/theme-provider.js +42 -20
  364. package/dist/theme/theme-provider.js.map +1 -1
  365. package/package.json +11 -5
  366. package/src/app/adapt-data-widget.tsx +2 -42
  367. package/src/app/builder/BuilderBanners.tsx +26 -13
  368. package/src/app/builder/CanvasRow.tsx +79 -32
  369. package/src/app/builder/CatalogueSheet.tsx +58 -35
  370. package/src/app/builder/CellPropsSheet.tsx +17 -2
  371. package/src/app/builder/DiscardDialog.tsx +59 -0
  372. package/src/app/builder/EmptyHint.tsx +16 -11
  373. package/src/app/builder/LayoutSurface.tsx +207 -67
  374. package/src/app/builder/PipelineStrip.tsx +265 -156
  375. package/src/app/builder/SaveDialog.tsx +25 -14
  376. package/src/app/builder/Toolbar.tsx +154 -57
  377. package/src/app/builder/Workspace.tsx +226 -56
  378. package/src/app/builder/builder-feedback.test.tsx +75 -0
  379. package/src/app/builder/builder-model.test.ts +5 -0
  380. package/src/app/builder/builder-model.ts +346 -6
  381. package/src/app/builder/builder-model.ux.test.ts +456 -0
  382. package/src/app/builder/builder-ux.test.tsx +844 -0
  383. package/src/app/builder/labels.ts +15 -121
  384. package/src/app/builder/reveal.ts +10 -0
  385. package/src/app/builder/status-chip.tsx +8 -4
  386. package/src/app/builder/use-builder-catalogue.ts +62 -19
  387. package/src/app/builder/use-builder-session.ts +68 -0
  388. package/src/app/builder/use-display-resolver.ts +24 -0
  389. package/src/app/builder/use-save-dashboard.ts +5 -0
  390. package/src/app/index.ts +20 -3
  391. package/src/app/layout-builder.tsx +193 -186
  392. package/src/app/mcp-app-view-chrome.test.tsx +487 -14
  393. package/src/app/mcp-app-view-chrome.tsx +328 -100
  394. package/src/app/mcp-app-view-states.tsx +140 -0
  395. package/src/app/mcp-app-view.effects.test.tsx +292 -0
  396. package/src/app/mcp-app-view.test.tsx +478 -0
  397. package/src/app/mcp-app-view.tsx +447 -190
  398. package/src/app/mcp-toolkit-app.test.tsx +40 -0
  399. package/src/app/mcp-toolkit-app.tsx +39 -8
  400. package/src/app/mcp-use-host-bridge.test.tsx +180 -0
  401. package/src/app/mcp-use-host-bridge.tsx +67 -24
  402. package/src/app/model-context.test.tsx +116 -0
  403. package/src/app/model-context.tsx +125 -0
  404. package/src/app/use-build-mode-focus.ts +62 -0
  405. package/src/app/use-view-actions.ts +89 -0
  406. package/src/app/use-view-lifecycle.ts +122 -0
  407. package/src/app/view-lifecycle.test.ts +443 -0
  408. package/src/app/view-lifecycle.ts +334 -0
  409. package/src/app/widget-fixture.effects.test.tsx +51 -0
  410. package/src/app/widget-fixture.render.test.tsx +81 -0
  411. package/src/app/widget-fixture.tsx +34 -11
  412. package/src/app/widget-props-sheet.tsx +67 -39
  413. package/src/app/widget-renderer.render.test.tsx +131 -0
  414. package/src/app/widget-renderer.tsx +136 -38
  415. package/src/components/DrillButton.tsx +24 -10
  416. package/src/components/EmptyState.tsx +83 -0
  417. package/src/components/ErrorState.tsx +204 -0
  418. package/src/components/FilterBar.test.tsx +82 -0
  419. package/src/components/FilterBar.tsx +56 -27
  420. package/src/components/GroupCard.tsx +3 -2
  421. package/src/components/KpiGrid.test.tsx +279 -0
  422. package/src/components/KpiGrid.tsx +329 -91
  423. package/src/components/ListFooter.test.tsx +116 -0
  424. package/src/components/ListFooter.tsx +110 -12
  425. package/src/components/PagedListFooter.test.tsx +140 -0
  426. package/src/components/PagedListFooter.tsx +107 -0
  427. package/src/components/Pills.test.tsx +77 -0
  428. package/src/components/Pills.tsx +78 -16
  429. package/src/components/SectionHeading.tsx +9 -3
  430. package/src/components/Toast.tsx +206 -0
  431. package/src/components/WidgetHeader.test.tsx +78 -0
  432. package/src/components/WidgetHeader.tsx +63 -16
  433. package/src/components/feedback-states.test.tsx +314 -0
  434. package/src/components/tone-figures.test.tsx +58 -0
  435. package/src/fonts.css +19 -0
  436. package/src/globals.css +9 -165
  437. package/src/hooks/index.ts +6 -3
  438. package/src/hooks/tool-result-recovery-model.test.ts +744 -0
  439. package/src/hooks/tool-result-recovery-model.ts +418 -0
  440. package/src/hooks/use-tool-query.effects.test.tsx +205 -0
  441. package/src/hooks/use-tool-query.ts +156 -33
  442. package/src/hooks/use-tool-result-recovery.effects.test.tsx +141 -0
  443. package/src/hooks/use-tool-result-recovery.test.ts +28 -5
  444. package/src/hooks/use-tool-result-recovery.ts +101 -131
  445. package/src/hooks/use-view-data.test.tsx +169 -0
  446. package/src/hooks/use-view-data.ts +131 -10
  447. package/src/hooks/use-view-tool-query.ts +25 -19
  448. package/src/i18n-coverage.test.tsx +425 -0
  449. package/src/index.ts +102 -13
  450. package/src/lib/focus-return.test.ts +288 -0
  451. package/src/lib/focus-return.ts +96 -0
  452. package/src/lib/focus-ring.ts +20 -0
  453. package/src/lib/icon-stroke.test.ts +59 -0
  454. package/src/lib/icon-stroke.ts +13 -0
  455. package/src/lib/parse-tool-result.test.ts +46 -1
  456. package/src/lib/parse-tool-result.ts +40 -2
  457. package/src/lib/toast-model.test.ts +233 -0
  458. package/src/lib/toast-model.ts +165 -0
  459. package/src/lib/tone-utils.test.ts +125 -16
  460. package/src/lib/tone-utils.ts +144 -15
  461. package/src/lib/tool-query.test.ts +569 -0
  462. package/src/lib/tool-query.ts +253 -0
  463. package/src/lib/tool-result-observer.test.ts +296 -0
  464. package/src/lib/tool-result-observer.ts +211 -0
  465. package/src/lib/typography.test.ts +45 -0
  466. package/src/lib/typography.ts +47 -0
  467. package/src/lib/utils.ts +12 -1
  468. package/src/locale/index.ts +14 -1
  469. package/src/locale/locale-provider.test.tsx +87 -0
  470. package/src/locale/locale-provider.tsx +90 -3
  471. package/src/locale/message-types.ts +337 -0
  472. package/src/locale/messages-de.ts +198 -0
  473. package/src/locale/messages-en.ts +196 -0
  474. package/src/locale/toolkit-messages.test.ts +349 -0
  475. package/src/locale/toolkit-messages.ts +143 -0
  476. package/src/no-hardcoded-copy.test.ts +432 -0
  477. package/src/primitives/alert.tsx +7 -2
  478. package/src/primitives/badge.tsx +19 -7
  479. package/src/primitives/button.tsx +13 -8
  480. package/src/primitives/card.tsx +4 -4
  481. package/src/primitives/dialog.tsx +42 -8
  482. package/src/primitives/input.tsx +5 -3
  483. package/src/primitives/scroll-area.tsx +1 -1
  484. package/src/primitives/select.tsx +7 -4
  485. package/src/primitives/sheet.tsx +33 -6
  486. package/src/primitives/skeleton.tsx +1 -1
  487. package/src/primitives/switch.tsx +4 -2
  488. package/src/primitives/tabs.tsx +9 -6
  489. package/src/providers/query-provider.test.tsx +154 -0
  490. package/src/providers/query-provider.tsx +66 -5
  491. package/src/render-cases-primitives.tsx +1 -1
  492. package/src/render-cases.tsx +82 -6
  493. package/src/render-effects.tsx +96 -0
  494. package/src/render-scan.ts +75 -0
  495. package/src/theme/cd-tokens.generated.css +48 -0
  496. package/src/theme/cd-tokens.test.ts +109 -0
  497. package/src/theme/cd-tokens.ts +67 -0
  498. package/src/theme/create-theme.test.ts +253 -5
  499. package/src/theme/create-theme.ts +341 -41
  500. package/src/theme/fonts.test.ts +85 -0
  501. package/src/theme/fonts.ts +72 -0
  502. package/src/theme/host-fonts.test.ts +135 -0
  503. package/src/theme/host-fonts.ts +52 -0
  504. package/src/theme/index.ts +15 -1
  505. package/src/theme/portal-container.ts +20 -0
  506. package/src/theme/presets.ts +44 -11
  507. package/src/theme/theme-css.test.ts +619 -0
  508. package/src/theme/theme-provider.test.tsx +82 -0
  509. package/src/theme/theme-provider.tsx +60 -24
  510. package/src/theme.css +344 -0
  511. package/ui-catalog.json +783 -49
@@ -1,6 +1,6 @@
1
1
  import { memo, useCallback, useRef } from "react"
2
2
  import { ChevronDown, ChevronUp, SlidersHorizontal, Trash2, X } from "lucide-react"
3
- import type { RowDef, WidgetProps } from "@miragon/mcp-toolkit-core"
3
+ import type { DisplayText, RowDef, WidgetProps } from "@miragon/mcp-toolkit-core"
4
4
  import { GridItem, GridLayout } from "../../components/GridLayout.js"
5
5
  import { Button } from "../../primitives/button.js"
6
6
  import {
@@ -10,10 +10,14 @@ import {
10
10
  SelectTrigger,
11
11
  SelectValue,
12
12
  } from "../../primitives/select.js"
13
+ import { FOCUS_RING, FOCUS_RING_INSET } from "../../lib/focus-ring.js"
13
14
  import { cn } from "../../lib/utils.js"
14
15
  import { RenderedWidget, type WidgetComponent } from "../widget-renderer.js"
16
+ import { displayLabel } from "./builder-model.js"
15
17
  import type { LayoutBuilderLabels } from "./labels.js"
16
18
  import { WIDGET_DRAG_MIME } from "./labels.js"
19
+ import { REVEAL_ON_INTENT } from "./reveal.js"
20
+ import { useDisplayResolver } from "./use-display-resolver.js"
17
21
 
18
22
  // -------------------------------------------------------------------------- //
19
23
  // Canvas row — drop target + per-cell controls + resize handle
@@ -36,6 +40,8 @@ function CanvasRowImpl({
36
40
  onAddWidget,
37
41
  onConfigureCell,
38
42
  propsSchemaByWidgetId,
43
+ displayByWidgetId,
44
+ advanced,
39
45
  widgets,
40
46
  widgetProps,
41
47
  }: {
@@ -55,14 +61,25 @@ function CanvasRowImpl({
55
61
  onAddWidget: (widgetId: string, targetRowIdx?: number) => void
56
62
  onConfigureCell: (rowIdx: number, cellIdx: number) => void
57
63
  propsSchemaByWidgetId: Map<string, Record<string, unknown>>
64
+ displayByWidgetId: Map<string, DisplayText>
65
+ advanced: boolean
58
66
  widgets: Record<string, WidgetComponent>
59
67
  widgetProps: WidgetProps
60
68
  }) {
61
69
  const gridRef = useRef<HTMLDivElement | null>(null)
70
+ const { locale, resolveKey } = useDisplayResolver()
71
+ // The target row follows the pointer AND the keyboard: focus moving into a
72
+ // row (its actions, a cell control) makes it the row the palette adds to.
73
+ const target = () => {
74
+ if (!focused) setFocusedRowIndex(rowIdx)
75
+ }
62
76
 
63
77
  return (
64
78
  <div
65
- onClick={() => setFocusedRowIndex(rowIdx)}
79
+ data-slot="builder-row"
80
+ data-target={focused ? "" : undefined}
81
+ onClick={target}
82
+ onFocus={target}
66
83
  onDragOver={(e) => {
67
84
  if (!e.dataTransfer.types.includes(WIDGET_DRAG_MIME)) return
68
85
  e.preventDefault()
@@ -82,21 +99,28 @@ function CanvasRowImpl({
82
99
  }
83
100
  }}
84
101
  className={cn(
85
- "group relative rounded-lg border-l-2 px-3 py-2 transition-colors",
102
+ "group relative rounded-md border-l-2 px-3 py-2 transition-colors",
86
103
  focused
87
104
  ? "border-l-primary bg-card"
88
105
  : "bg-background hover:bg-card/60 border-l-transparent",
89
106
  dragOver && "bg-primary/5 border-l-primary",
90
107
  )}
91
108
  >
92
- <div className="mb-2 flex items-center justify-between">
93
- <div className="text-muted-foreground flex items-center gap-2 text-[11px]">
94
- <span className="font-mono">row {rowIdx + 1}</span>
95
- <span className="bg-muted/60 rounded px-1 py-0.5 text-[10px]">
96
- {row.row.length} {row.row.length === 1 ? "widget" : "widgets"}
97
- </span>
109
+ <div className="mb-2 flex flex-wrap items-center justify-between gap-2">
110
+ <div className="text-muted-foreground text-small flex flex-wrap items-center gap-2">
111
+ <span className="font-medium">{L.rowLabel(rowIdx + 1)}</span>
112
+ <span className="bg-muted rounded px-1.5 py-0.5">{L.elementCount(row.row.length)}</span>
113
+ {focused && (
114
+ <span className="text-foreground inline-flex items-center gap-1.5">
115
+ <span aria-hidden="true" className="bg-primary size-1.5 rounded-full" />
116
+ {L.rowTarget}
117
+ </span>
118
+ )}
98
119
  </div>
99
- <div className="opacity-0 transition-opacity group-hover:opacity-100">
120
+ <div
121
+ data-slot="builder-row-actions"
122
+ className={cn("flex items-center", focused ? "opacity-100" : REVEAL_ON_INTENT)}
123
+ >
100
124
  <Button
101
125
  variant="ghost"
102
126
  size="icon-xs"
@@ -105,7 +129,7 @@ function CanvasRowImpl({
105
129
  onMoveRow(rowIdx, -1)
106
130
  }}
107
131
  disabled={isFirst}
108
- aria-label="Move row up"
132
+ aria-label={L.moveRowUp}
109
133
  >
110
134
  <ChevronUp />
111
135
  </Button>
@@ -117,7 +141,7 @@ function CanvasRowImpl({
117
141
  onMoveRow(rowIdx, 1)
118
142
  }}
119
143
  disabled={isLast}
120
- aria-label="Move row down"
144
+ aria-label={L.moveRowDown}
121
145
  >
122
146
  <ChevronDown />
123
147
  </Button>
@@ -137,10 +161,10 @@ function CanvasRowImpl({
137
161
  {row.row.length === 0 ? (
138
162
  <div
139
163
  className={cn(
140
- "rounded-md border border-dashed py-6 text-center text-[11px] transition-colors",
164
+ "text-small rounded-md border border-dashed py-6 text-center transition-colors",
141
165
  dragOver
142
- ? "border-primary bg-primary/5 text-primary"
143
- : "border-muted-foreground/30 text-muted-foreground",
166
+ ? "border-focus bg-accent text-accent-foreground"
167
+ : "border-input text-muted-foreground",
144
168
  )}
145
169
  >
146
170
  {dragOver ? L.canvasDropHint : L.canvasEmpty}
@@ -153,29 +177,48 @@ function CanvasRowImpl({
153
177
  const Widget = widgets[cell.widget]
154
178
  const hasPropsSchema = propsSchemaByWidgetId.has(cell.widget)
155
179
  const propCount = cell.props ? Object.keys(cell.props).length : 0
180
+ const name = displayLabel(
181
+ displayByWidgetId.get(cell.widget) ?? {},
182
+ cell.widget,
183
+ locale,
184
+ resolveKey,
185
+ )
156
186
  return (
157
187
  <GridItem key={`${cell.widget}-${cellIdx}`} span={span}>
158
- <div className="border-border bg-card relative overflow-hidden rounded-md border shadow-sm">
159
- <div className="text-muted-foreground bg-muted/30 flex items-center justify-between gap-2 border-b px-2 py-1 text-[10px]">
160
- <span className="truncate font-mono">{cell.widget}</span>
188
+ <div className="border-border bg-card shadow-1 relative overflow-hidden rounded-md border">
189
+ <div className="text-muted-foreground bg-muted/30 text-small flex items-center justify-between gap-2 border-b px-2 py-1">
190
+ <span className="flex min-w-0 items-baseline gap-2" title={name.hint}>
191
+ <span className="text-foreground truncate font-medium">{name.label}</span>
192
+ {advanced && name.hint && (
193
+ <span className="truncate font-mono">{name.hint}</span>
194
+ )}
195
+ </span>
161
196
  <div className="flex shrink-0 items-center gap-2">
162
- <label className="text-muted-foreground/80 inline-flex items-center gap-0.5 font-mono">
163
- <span className="sr-only">Column span</span>
197
+ <label className="text-muted-foreground inline-flex items-center gap-0.5 tabular-nums">
198
+ <span className="sr-only">{L.columnSpan}</span>
164
199
  <Select
165
200
  value={String(span)}
166
201
  onValueChange={(v) => onSetCellSpan(rowIdx, cellIdx, Number(v))}
167
202
  >
168
203
  <SelectTrigger
169
204
  size="sm"
170
- className="h-5 gap-0.5 border-none bg-transparent px-1 py-0 font-mono text-[10px] shadow-none focus:ring-0"
171
- aria-label="Column span"
205
+ className={cn(
206
+ "text-small h-6 gap-0.5 border-none bg-transparent px-1 py-0 tabular-nums shadow-none",
207
+ // Borderless, so the input focus edge is gone: the kit ring instead.
208
+ FOCUS_RING,
209
+ )}
210
+ aria-label={L.columnSpan}
172
211
  onClick={(e) => e.stopPropagation()}
173
212
  >
174
213
  <SelectValue />
175
214
  </SelectTrigger>
176
215
  <SelectContent>
177
216
  {Array.from({ length: 12 }, (_, i) => i + 1).map((n) => (
178
- <SelectItem key={n} value={String(n)} className="font-mono text-xs">
217
+ <SelectItem
218
+ key={n}
219
+ value={String(n)}
220
+ className="text-small tabular-nums"
221
+ >
179
222
  {n}
180
223
  </SelectItem>
181
224
  ))}
@@ -191,13 +234,11 @@ function CanvasRowImpl({
191
234
  e.stopPropagation()
192
235
  onConfigureCell(rowIdx, cellIdx)
193
236
  }}
194
- aria-label="Configure widget props"
237
+ aria-label={L.configureElement}
195
238
  title={
196
- propCount > 0
197
- ? `Configure widget props (${propCount} set)`
198
- : "Configure widget props"
239
+ propCount > 0 ? L.configureElementSet(propCount) : L.configureElement
199
240
  }
200
- className={cn(propCount > 0 && "text-primary")}
241
+ className={cn(propCount > 0 && "text-link")}
201
242
  >
202
243
  <SlidersHorizontal />
203
244
  </Button>
@@ -209,7 +250,7 @@ function CanvasRowImpl({
209
250
  e.stopPropagation()
210
251
  onRemoveCell(rowIdx, cellIdx)
211
252
  }}
212
- aria-label="Remove widget"
253
+ aria-label={L.removeElement}
213
254
  >
214
255
  <X />
215
256
  </Button>
@@ -222,10 +263,11 @@ function CanvasRowImpl({
222
263
  props={widgetProps}
223
264
  cellProps={cell.props}
224
265
  showEmptyHint
225
- notBundledClassName="text-muted-foreground rounded border border-dashed p-3 text-center text-[11px]"
266
+ notBundledClassName="text-muted-foreground rounded border border-dashed p-3 text-center text-small"
226
267
  />
227
268
  </div>
228
269
  <ResizeHandle
270
+ label={L.resizeElement}
229
271
  rowIdx={rowIdx}
230
272
  cellIdx={cellIdx}
231
273
  span={span}
@@ -250,12 +292,14 @@ export const CanvasRow = memo(CanvasRowImpl)
250
292
  // -------------------------------------------------------------------------- //
251
293
 
252
294
  function ResizeHandle({
295
+ label,
253
296
  rowIdx,
254
297
  cellIdx,
255
298
  span,
256
299
  getGridEl,
257
300
  onSetCellSpan,
258
301
  }: {
302
+ label: string
259
303
  rowIdx: number
260
304
  cellIdx: number
261
305
  span: number
@@ -304,8 +348,11 @@ function ResizeHandle({
304
348
  onClick={(e) => e.stopPropagation()}
305
349
  onKeyDown={onKeyDown}
306
350
  tabIndex={0}
307
- className="hover:bg-primary/40 focus-visible:bg-primary/40 focus-visible:ring-primary/60 absolute top-0 right-0 h-full w-1.5 cursor-col-resize touch-none select-none focus-visible:ring-1 focus-visible:outline-none"
308
- aria-label="Resize widget"
351
+ className={cn(
352
+ "hover:bg-primary/40 focus-visible:bg-primary/40 absolute top-0 right-0 h-full w-1.5 cursor-col-resize touch-none select-none",
353
+ FOCUS_RING_INSET,
354
+ )}
355
+ aria-label={label}
309
356
  role="separator"
310
357
  aria-orientation="vertical"
311
358
  aria-valuenow={span}
@@ -11,8 +11,11 @@ import {
11
11
  SheetHeader,
12
12
  SheetTitle,
13
13
  } from "../../primitives/sheet.js"
14
+ import { TONE_DOT, TONE_TEXT } from "../../lib/tone-utils.js"
14
15
  import { cn } from "../../lib/utils.js"
16
+ import { displayLabel } from "./builder-model.js"
15
17
  import type { LayoutBuilderLabels } from "./labels.js"
18
+ import { useDisplayResolver } from "./use-display-resolver.js"
16
19
 
17
20
  // -------------------------------------------------------------------------- //
18
21
  // Catalogue Sheet — slides in from the right
@@ -37,6 +40,7 @@ export function CatalogueSheet({
37
40
  onSeedKey: (name: string) => void
38
41
  onAddProducingStep: (key: string) => void
39
42
  }) {
43
+ const { locale, resolveKey } = useDisplayResolver()
40
44
  const producerOf = useMemo(() => {
41
45
  const map = new Map<string, string | undefined>()
42
46
  for (const e of keyCatalog) map.set(e.key, e.producedBySteps[0])
@@ -59,28 +63,29 @@ export function CatalogueSheet({
59
63
  <section className="flex flex-col gap-2">
60
64
  <CatalogueSectionHeader title={L.catalogueKeys} count={keyCatalog.length} />
61
65
  {keyCatalog.length === 0 ? (
62
- <p className="text-muted-foreground text-xs italic">No keys registered.</p>
66
+ <p className="text-muted-foreground text-small italic">{L.noKeysRegistered}</p>
63
67
  ) : (
64
68
  <ul className="flex flex-col gap-1">
65
69
  {keyCatalog.map((entry) => (
66
70
  <li
67
71
  key={entry.key}
68
- className="hover:bg-accent/40 flex flex-col gap-1 rounded-md border px-2 py-1.5 text-xs"
72
+ className="hover:bg-muted text-small flex flex-col gap-1 rounded-md border px-2 py-1.5"
69
73
  >
70
74
  <div className="flex items-start justify-between gap-2">
71
75
  <span className="truncate font-mono">{entry.key}</span>
72
76
  <span
73
77
  className={cn(
74
- "inline-flex shrink-0 items-center gap-1 text-[10px]",
75
- entry.inContext
76
- ? "text-emerald-600 dark:text-emerald-400"
77
- : "text-muted-foreground",
78
+ "text-small inline-flex shrink-0 items-center gap-1",
79
+ entry.inContext ? TONE_TEXT.success : "text-muted-foreground",
78
80
  )}
79
81
  >
80
82
  <span
83
+ aria-hidden="true"
81
84
  className={cn(
82
85
  "size-1.5 rounded-full",
83
- entry.inContext ? "bg-emerald-500" : "bg-muted-foreground/40",
86
+ entry.inContext
87
+ ? TONE_DOT.success
88
+ : "border-input border bg-transparent",
84
89
  )}
85
90
  />
86
91
  {entry.inContext ? L.catalogueLive : L.catalogueMissing}
@@ -89,7 +94,7 @@ export function CatalogueSheet({
89
94
  {(entry.producedBySteps.length > 0 ||
90
95
  entry.consumedBySteps.length > 0 ||
91
96
  entry.consumedByWidgets.length > 0) && (
92
- <div className="text-muted-foreground/80 flex flex-col gap-0.5 text-[10px]">
97
+ <div className="text-muted-foreground text-small flex flex-col gap-0.5">
93
98
  {entry.producedBySteps.length > 0 && (
94
99
  <span>
95
100
  {L.catalogueProducedBy}{" "}
@@ -98,13 +103,13 @@ export function CatalogueSheet({
98
103
  )}
99
104
  {entry.consumedBySteps.length > 0 && (
100
105
  <span>
101
- step {L.catalogueConsumedBy}{" "}
106
+ {L.catalogueStepPrefix} {L.catalogueConsumedBy}{" "}
102
107
  <span className="font-mono">{entry.consumedBySteps.join(", ")}</span>
103
108
  </span>
104
109
  )}
105
110
  {entry.consumedByWidgets.length > 0 && (
106
111
  <span>
107
- widget {L.catalogueConsumedBy}{" "}
112
+ {L.catalogueElementPrefix} {L.catalogueConsumedBy}{" "}
108
113
  <span className="font-mono">
109
114
  {entry.consumedByWidgets.join(", ")}
110
115
  </span>
@@ -137,25 +142,39 @@ export function CatalogueSheet({
137
142
  <section className="flex flex-col gap-2">
138
143
  <CatalogueSectionHeader title={L.catalogueSteps} count={availableSteps.length} />
139
144
  {availableSteps.length === 0 ? (
140
- <p className="text-muted-foreground text-xs italic">No steps registered.</p>
145
+ <p className="text-muted-foreground text-small italic">{L.noStepsRegistered}</p>
141
146
  ) : (
142
147
  <ul className="flex flex-col gap-1">
143
- {availableSteps.map((s) => (
144
- <li
145
- key={s.id}
146
- className="flex flex-col gap-0.5 rounded-md border px-2 py-1.5 text-xs"
147
- >
148
- <span className="truncate font-mono">{s.id}</span>
149
- <div className="text-muted-foreground/80 flex flex-wrap gap-x-3 text-[10px]">
150
- <span className="font-mono">
151
- ← {s.requires.length ? s.requires.join(", ") : "(no inputs)"}
152
- </span>
153
- <span className="font-mono">
154
- → {s.produces.length ? s.produces.join(", ") : "(none)"}
155
- </span>
156
- </div>
157
- </li>
158
- ))}
148
+ {availableSteps.map((s) => {
149
+ const name = displayLabel(s, s.id, locale, resolveKey)
150
+ return (
151
+ <li
152
+ key={s.id}
153
+ className="text-small flex flex-col gap-0.5 rounded-md border px-2 py-1.5"
154
+ >
155
+ <span className="truncate font-medium">{name.label}</span>
156
+ {name.hint && (
157
+ <span className="text-muted-foreground truncate font-mono">
158
+ {name.hint}
159
+ </span>
160
+ )}
161
+ <div className="text-muted-foreground flex flex-wrap gap-x-3">
162
+ <span>
163
+ {L.catalogueNeedsKeys}{" "}
164
+ <span className="font-mono">
165
+ {s.requires.length ? s.requires.join(", ") : L.noInputs}
166
+ </span>
167
+ </span>
168
+ <span>
169
+ {L.stepProvides}{" "}
170
+ <span className="font-mono">
171
+ {s.produces.length ? s.produces.join(", ") : L.noOutputs}
172
+ </span>
173
+ </span>
174
+ </div>
175
+ </li>
176
+ )
177
+ })}
159
178
  </ul>
160
179
  )}
161
180
  </section>
@@ -166,7 +185,7 @@ export function CatalogueSheet({
166
185
  count={unreachableWidgets.length}
167
186
  />
168
187
  {unreachableWidgets.length === 0 ? (
169
- <p className="text-muted-foreground text-xs italic">
188
+ <p className="text-muted-foreground text-small italic">
170
189
  {L.catalogueUnreachableEmpty}
171
190
  </p>
172
191
  ) : (
@@ -175,13 +194,19 @@ export function CatalogueSheet({
175
194
  const candidate = w.missingKeys
176
195
  .map((k) => ({ key: k, step: producerOf.get(k) }))
177
196
  .find((c) => c.step)
197
+ const name = displayLabel(w, w.id, locale, resolveKey)
178
198
  return (
179
199
  <li
180
200
  key={w.id}
181
- className="bg-muted/20 flex flex-col gap-1 rounded-md border px-2 py-1.5 text-xs"
201
+ className="bg-muted/20 text-small flex flex-col gap-1 rounded-md border px-2 py-1.5"
182
202
  >
183
- <span className="truncate font-mono">{w.id}</span>
184
- <span className="text-muted-foreground/80 text-[10px]">
203
+ <span className="truncate font-medium">{name.label}</span>
204
+ {name.hint && (
205
+ <span className="text-muted-foreground truncate font-mono">
206
+ {name.hint}
207
+ </span>
208
+ )}
209
+ <span className="text-muted-foreground">
185
210
  {L.catalogueNeedsKeys}{" "}
186
211
  <span className="font-mono">{w.missingKeys.join(", ")}</span>
187
212
  </span>
@@ -218,11 +243,9 @@ export function CatalogueSheet({
218
243
  function CatalogueSectionHeader({ title, count }: { title: string; count: number }) {
219
244
  return (
220
245
  <div className="flex items-center gap-2">
221
- <span className="text-muted-foreground text-[10px] font-semibold tracking-[0.12em] uppercase">
222
- {title}
223
- </span>
246
+ <h3 className="text-muted-foreground text-small font-semibold">{title}</h3>
224
247
  <span className="bg-border h-px flex-1" aria-hidden="true" />
225
- <Badge variant="outline" className="px-1.5 text-[10px]">
248
+ <Badge variant="outline" className="px-1.5">
226
249
  {count}
227
250
  </Badge>
228
251
  </div>
@@ -1,5 +1,7 @@
1
- import type { RowDef } from "@miragon/mcp-toolkit-core"
1
+ import type { DisplayText, RowDef } from "@miragon/mcp-toolkit-core"
2
2
  import { WidgetPropsSheet } from "../widget-props-sheet.js"
3
+ import { displayLabel } from "./builder-model.js"
4
+ import { useDisplayResolver } from "./use-display-resolver.js"
3
5
 
4
6
  // -------------------------------------------------------------------------- //
5
7
  // Cell props sheet — mounts the WidgetPropsSheet for the configured cell
@@ -10,25 +12,37 @@ import { WidgetPropsSheet } from "../widget-props-sheet.js"
10
12
  * can be open at a time across the entire workspace — including across
11
13
  * tabs. `configuringCell` addresses `{ rowIdx, cellIdx }` on the currently
12
14
  * active draft surface (rows or active tab's rows); renders nothing when no
13
- * cell is being configured or the address no longer resolves.
15
+ * cell is being configured or the address no longer resolves. The sheet is
16
+ * titled with the widget's name; closing it returns focus to the cell's
17
+ * configure button (the kit's `SheetContent` hands it back to the element
18
+ * that opened it, see `lib/focus-return.ts`).
14
19
  */
15
20
  export function CellPropsSheet({
16
21
  configuringCell,
17
22
  activeRows,
18
23
  propsSchemaByWidgetId,
24
+ displayByWidgetId,
19
25
  onApply,
20
26
  onClose,
21
27
  }: {
22
28
  configuringCell: { rowIdx: number; cellIdx: number } | null
23
29
  activeRows: RowDef[]
24
30
  propsSchemaByWidgetId: Map<string, Record<string, unknown>>
31
+ displayByWidgetId: Map<string, DisplayText>
25
32
  onApply: (rowIdx: number, cellIdx: number, next: Record<string, unknown> | undefined) => void
26
33
  onClose: () => void
27
34
  }) {
35
+ const { locale, resolveKey } = useDisplayResolver()
28
36
  if (!configuringCell) return null
29
37
  const cell = activeRows[configuringCell.rowIdx]?.row[configuringCell.cellIdx]
30
38
  if (!cell) return null
31
39
  const schema = propsSchemaByWidgetId.get(cell.widget)
40
+ const name = displayLabel(
41
+ displayByWidgetId.get(cell.widget) ?? {},
42
+ cell.widget,
43
+ locale,
44
+ resolveKey,
45
+ )
32
46
  return (
33
47
  <WidgetPropsSheet
34
48
  open
@@ -36,6 +50,7 @@ export function CellPropsSheet({
36
50
  if (!open) onClose()
37
51
  }}
38
52
  widgetId={cell.widget}
53
+ widgetTitle={name.hint ? name.label : undefined}
39
54
  schema={schema}
40
55
  value={cell.props}
41
56
  onApply={(next) => {
@@ -0,0 +1,59 @@
1
+ import { Button } from "../../primitives/button.js"
2
+ import {
3
+ Dialog,
4
+ DialogClose,
5
+ DialogContent,
6
+ DialogDescription,
7
+ DialogFooter,
8
+ DialogHeader,
9
+ DialogTitle,
10
+ } from "../../primitives/dialog.js"
11
+ import type { LayoutBuilderLabels } from "./labels.js"
12
+
13
+ // -------------------------------------------------------------------------- //
14
+ // Discard confirmation
15
+ // -------------------------------------------------------------------------- //
16
+
17
+ /**
18
+ * Asks before Discard takes the changes out of the view (CI §9: confirm
19
+ * before an irreversible action). When a saved dashboard holds them
20
+ * (`changesSaved`), it says so instead of calling them lost. The safe choice
21
+ * comes first in the DOM, so the dialog opens with focus on "Keep editing";
22
+ * closing it returns focus to Discard (the kit's `DialogContent` hands it
23
+ * back to the element that opened it, see `lib/focus-return.ts`).
24
+ */
25
+ export function DiscardDialog({
26
+ L,
27
+ open,
28
+ onOpenChange,
29
+ changesSaved,
30
+ onConfirm,
31
+ }: {
32
+ L: Required<LayoutBuilderLabels>
33
+ open: boolean
34
+ onOpenChange: (open: boolean) => void
35
+ /** A saved dashboard holds the changes: only the view goes back. */
36
+ changesSaved: boolean
37
+ onConfirm: () => void
38
+ }) {
39
+ return (
40
+ <Dialog open={open} onOpenChange={onOpenChange}>
41
+ <DialogContent>
42
+ <DialogHeader>
43
+ <DialogTitle>{L.discardDialogTitle}</DialogTitle>
44
+ <DialogDescription>
45
+ {changesSaved ? L.discardDialogDescriptionSaved : L.discardDialogDescription}
46
+ </DialogDescription>
47
+ </DialogHeader>
48
+ <DialogFooter>
49
+ <DialogClose asChild>
50
+ <Button variant="outline">{L.keepEditing}</Button>
51
+ </DialogClose>
52
+ <Button variant="destructive" onClick={onConfirm}>
53
+ {L.discardConfirm}
54
+ </Button>
55
+ </DialogFooter>
56
+ </DialogContent>
57
+ </Dialog>
58
+ )
59
+ }
@@ -1,4 +1,5 @@
1
1
  import { Layers, SlidersHorizontal } from "lucide-react"
2
+ import { EmptyState } from "../../components/EmptyState.js"
2
3
  import { Button } from "../../primitives/button.js"
3
4
  import type { LayoutBuilderLabels } from "./labels.js"
4
5
 
@@ -6,6 +7,10 @@ import type { LayoutBuilderLabels } from "./labels.js"
6
7
  // Empty hint — shown on the Layout view before any widget is reachable
7
8
  // -------------------------------------------------------------------------- //
8
9
 
10
+ /**
11
+ * The builder's empty state. Its one next step (open the data sources) is the
12
+ * blue primary button: CI §9 "Leer: Empty-State-Karte mit blauem CTA".
13
+ */
9
14
  export function EmptyHint({
10
15
  L,
11
16
  onGotoPipeline,
@@ -14,16 +19,16 @@ export function EmptyHint({
14
19
  onGotoPipeline: () => void
15
20
  }) {
16
21
  return (
17
- <div className="border-muted-foreground/30 text-muted-foreground flex flex-col items-center gap-2 rounded-md border border-dashed p-10 text-sm">
18
- <Layers className="size-5" />
19
- <p>No widgets reachable yet.</p>
20
- <p className="text-xs">
21
- Open the <span className="font-medium">{L.viewPipelineTab}</span> tab to seed keys or add a
22
- pipeline step — the palette unlocks as soon as a widget's contract is satisfied.
23
- </p>
24
- <Button variant="outline" size="sm" onClick={onGotoPipeline} className="mt-1">
25
- <SlidersHorizontal /> Open {L.viewPipelineTab}
26
- </Button>
27
- </div>
22
+ <EmptyState
23
+ className="rounded-md border border-dashed"
24
+ icon={<Layers />}
25
+ title={L.emptyHintTitle}
26
+ description={L.emptyHintBody}
27
+ action={
28
+ <Button size="sm" onClick={onGotoPipeline}>
29
+ <SlidersHorizontal aria-hidden="true" /> {L.openDataSources}
30
+ </Button>
31
+ }
32
+ />
28
33
  )
29
34
  }