@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
@@ -0,0 +1,53 @@
1
+ import type { ReactNode } from "react";
2
+ import { type LucideIcon } from "lucide-react";
3
+ import type { StateHeadingLevel } from "./EmptyState.js";
4
+ /** Status tone of an {@link ErrorState}. */
5
+ export type ErrorStateTone = "danger" | "warning" | "info";
6
+ export interface ErrorStateProps {
7
+ /** What happened, in plain words ("This view couldn't be loaded"). */
8
+ title: ReactNode;
9
+ /** What you can do next — or the human reason, when you can map the raw one. */
10
+ description?: ReactNode;
11
+ /**
12
+ * The raw technical reason (engine exception, HTTP status), shown collapsed
13
+ * under a "Details" disclosure so it informs without leading.
14
+ */
15
+ details?: ReactNode;
16
+ /** Summary text of the details disclosure. Default: the locale's "Details". */
17
+ detailsLabel?: string;
18
+ /** Renders a retry button when set. */
19
+ onRetry?: () => void;
20
+ /** Retry button label. Default: the locale's "Try again". */
21
+ retryLabel?: string;
22
+ /** Further actions after the retry button (e.g. a link to another view). */
23
+ actions?: ReactNode;
24
+ /**
25
+ * Default `"danger"`. `"warning"` for partial failures, `"info"` for
26
+ * notices. An untyped retired name still resolves (`error` → `danger`).
27
+ */
28
+ tone?: ErrorStateTone;
29
+ /** Replace the tone's default Lucide icon. */
30
+ icon?: LucideIcon;
31
+ /**
32
+ * `"block"` (default): the state that replaces a whole view or widget body.
33
+ * `"inline"`: a compact alert above content that still renders.
34
+ */
35
+ variant?: "block" | "inline";
36
+ /**
37
+ * Live-region role. Default `"alert"` — an error that appears after the
38
+ * fact is announced. Use `"status"` for a quieter notice, or `"none"` when
39
+ * the state is part of the first paint.
40
+ */
41
+ role?: "alert" | "status" | "none";
42
+ /** Element of the title. Default `"h2"` for `block`, `"p"` for `inline`. */
43
+ titleAs?: StateHeadingLevel;
44
+ className?: string;
45
+ }
46
+ /**
47
+ * The one error pattern: a Lucide icon, a title that says what happened, a
48
+ * line that says what you can do, the raw reason collapsed under "Details",
49
+ * and a retry. `inline` is the alert form above content that still renders
50
+ * (failed data steps); `block` replaces a whole view or widget body.
51
+ */
52
+ export declare function ErrorState({ title, description, details, detailsLabel, onRetry, retryLabel, actions, tone: toneProp, icon, variant, role, titleAs, className, }: ErrorStateProps): import("react").JSX.Element;
53
+ //# sourceMappingURL=ErrorState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorState.d.ts","sourceRoot":"","sources":["../../src/components/ErrorState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAA+C,KAAK,UAAU,EAAE,MAAM,cAAc,CAAA;AAM3F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAA;AAE1D,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,KAAK,EAAE,SAAS,CAAA;IAChB,gFAAgF;IAChF,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAC5B;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAqDD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,OAAO,EACP,YAAY,EACZ,OAAO,EACP,UAAU,EACV,OAAO,EACP,IAAI,EAAE,QAAQ,EACd,IAAI,EACJ,OAAiB,EACjB,IAAc,EACd,OAAO,EACP,SAAS,GACV,EAAE,eAAe,+BAoCjB"}
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CircleAlert, Info, RefreshCw, TriangleAlert } from "lucide-react";
3
+ import { useToolkitMessages } from "../locale/locale-provider.js";
4
+ import { Button } from "../primitives/button.js";
5
+ import { FOCUS_RING } from "../lib/focus-ring.js";
6
+ import { resolveTone, TONE_BORDER, TONE_ICON, TONE_SOFT } from "../lib/tone-utils.js";
7
+ import { cn } from "../lib/utils.js";
8
+ const STATE_ICON = {
9
+ danger: CircleAlert,
10
+ warning: TriangleAlert,
11
+ info: Info,
12
+ };
13
+ /**
14
+ * The state's tone from whatever arrives: its three tones as is, a retired
15
+ * name through `resolveTone` (`error` → `danger`, `notice` → `info`), any
16
+ * other tone or unknown name as the default `danger`. A tone from untyped
17
+ * data (plain JS, the wire) never crashes the view on a missing icon.
18
+ */
19
+ function stateTone(name) {
20
+ const tone = resolveTone(name, "danger");
21
+ return tone === "warning" || tone === "info" ? tone : "danger";
22
+ }
23
+ /**
24
+ * Per-variant geometry: `block` replaces a surface and reads as running text
25
+ * (16 px), `inline` is the compact alert box above content that still renders
26
+ * (14 px, the dense-controls exception of the type scale).
27
+ */
28
+ const VARIANT = {
29
+ block: {
30
+ box: "gap-4 p-4",
31
+ icon: "size-5",
32
+ title: "text-body",
33
+ description: "text-body",
34
+ defaultTitleAs: "h2",
35
+ retry: "default",
36
+ },
37
+ inline: {
38
+ box: "gap-3 px-4 py-3 text-dense",
39
+ icon: "size-4",
40
+ title: "text-dense",
41
+ description: "text-dense",
42
+ defaultTitleAs: "p",
43
+ retry: "outline",
44
+ },
45
+ };
46
+ /**
47
+ * The one error pattern: a Lucide icon, a title that says what happened, a
48
+ * line that says what you can do, the raw reason collapsed under "Details",
49
+ * and a retry. `inline` is the alert form above content that still renders
50
+ * (failed data steps); `block` replaces a whole view or widget body.
51
+ */
52
+ export function ErrorState({ title, description, details, detailsLabel, onRetry, retryLabel, actions, tone: toneProp, icon, variant = "block", role = "alert", titleAs, className, }) {
53
+ const tone = stateTone(toneProp);
54
+ const style = VARIANT[variant];
55
+ const Icon = icon ?? STATE_ICON[tone];
56
+ const Title = titleAs ?? style.defaultTitleAs;
57
+ // The status colour as rim, tint and icon; every word on the tint is the
58
+ // foreground (TONE_SOFT, CI §3.3). On dark the tint is transparent and the
59
+ // rim carries the tone.
60
+ return (_jsxs("div", { "data-slot": "error-state", "data-variant": variant, "data-tone": tone, role: role === "none" ? undefined : role, className: cn("flex items-start rounded-md border", style.box, TONE_SOFT[tone], TONE_BORDER[tone], className), children: [_jsx(Icon, { "aria-hidden": "true", className: cn("mt-0.5 shrink-0", style.icon, TONE_ICON[tone]) }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [_jsx(Title, { className: cn("font-semibold", style.title), children: title }), description && _jsx("div", { className: cn("break-words", style.description), children: description }), details && _jsx(ErrorDetails, { label: detailsLabel, children: details }), _jsx(ErrorActions, { onRetry: onRetry, retryLabel: retryLabel, retryVariant: style.retry, actions: actions })] })] }));
61
+ }
62
+ /**
63
+ * The raw reason, collapsed: a native disclosure (keyboard + screen-reader
64
+ * ready). It sits on the tint, so its text stays the foreground; the collapse
65
+ * and the small mono type keep it quieter than the title.
66
+ */
67
+ function ErrorDetails({ label, children }) {
68
+ const messages = useToolkitMessages();
69
+ return (_jsxs("details", { className: "text-small", children: [_jsx("summary", { className: `w-fit cursor-pointer rounded-sm py-0.5 select-none ${FOCUS_RING}`, children: label ?? messages.common.details }), _jsx("pre", { className: "mt-1 font-mono break-words whitespace-pre-wrap", children: children })] }));
70
+ }
71
+ function ErrorActions({ onRetry, retryLabel, retryVariant, actions, }) {
72
+ const messages = useToolkitMessages();
73
+ if (!onRetry && !actions)
74
+ return null;
75
+ return (_jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [onRetry && (_jsxs(Button, { type: "button", size: "sm", variant: retryVariant, onClick: onRetry, children: [_jsx(RefreshCw, { "aria-hidden": "true" }), retryLabel ?? messages.common.retry] })), actions] }));
76
+ }
77
+ //# sourceMappingURL=ErrorState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorState.js","sourceRoot":"","sources":["../../src/components/ErrorState.tsx"],"names":[],"mappings":"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"}
@@ -1,28 +1,39 @@
1
1
  export interface FilterChip {
2
2
  /** Stable id passed back to `onChipToggle`. */
3
3
  id: string;
4
- /** Visible chip label. */
4
+ /** Visible chip label (its accessible name, with the count). */
5
5
  label: string;
6
6
  /** Optional count rendered after the label. */
7
7
  count?: number | string;
8
- /** Whether the chip is currently active. */
8
+ /** Whether the chip is currently active (`aria-pressed`). */
9
9
  active?: boolean;
10
10
  }
11
11
  export interface FilterBarProps {
12
12
  /** Current search text (controlled). */
13
13
  search: string;
14
- /** Placeholder for the search input. Default `"Filter…"`. */
14
+ /** Placeholder for the search input. Default: the locale's "Filter…". */
15
15
  searchPlaceholder?: string;
16
+ /**
17
+ * Accessible name of the search input. Default: the locale's "Filter" — a
18
+ * placeholder is no label (it disappears while you type).
19
+ */
20
+ searchAriaLabel?: string;
16
21
  /** Called with the new search text on every keystroke. */
17
22
  onSearchChange: (next: string) => void;
18
23
  /** Filter chips rendered to the right of the search input. */
19
24
  chips: FilterChip[];
20
25
  /** Called with a chip id when it is toggled. */
21
26
  onChipToggle: (id: string) => void;
27
+ /** Names the chip row (`role="group"`). Default: the locale's "Filters". */
28
+ chipsAriaLabel?: string;
29
+ className?: string;
22
30
  }
23
31
  /**
24
32
  * Search input + toggleable chip row for filtering a list/table of widget
25
- * items. Pair with `useDebouncedValue` to avoid re-querying on every keystroke.
33
+ * items. The input is labelled; every chip is a toggle button whose state is
34
+ * `aria-pressed`. An active chip is a selection in the CI pattern: the info
35
+ * tint and edge around foreground text. Pair with `useDebouncedValue` to
36
+ * avoid re-querying on every keystroke.
26
37
  */
27
- export declare function FilterBar({ search, searchPlaceholder, onSearchChange, chips, onChipToggle, }: FilterBarProps): import("react").JSX.Element;
38
+ export declare function FilterBar({ search, searchPlaceholder, searchAriaLabel, onSearchChange, chips, onChipToggle, chipsAriaLabel, className, }: FilterBarProps): import("react").JSX.Element;
28
39
  //# sourceMappingURL=FilterBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterBar.d.ts","sourceRoot":"","sources":["../../src/components/FilterBar.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAA;IACV,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,0DAA0D;IAC1D,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,8DAA8D;IAC9D,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,gDAAgD;IAChD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,iBAA6B,EAC7B,cAAc,EACd,KAAK,EACL,YAAY,GACb,EAAE,cAAc,+BA+BhB"}
1
+ {"version":3,"file":"FilterBar.d.ts","sourceRoot":"","sources":["../../src/components/FilterBar.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAA;IACV,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAA;IACd,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,0DAA0D;IAC1D,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,8DAA8D;IAC9D,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,gDAAgD;IAChD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,KAAK,EACL,YAAY,EACZ,cAAc,EACd,SAAS,GACV,EAAE,cAAc,+BA0ChB"}
@@ -1,12 +1,20 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { FOCUS_RING } from "../lib/focus-ring.js";
3
+ import { TONE_BORDER, TONE_SOFT } from "../lib/tone-utils.js";
4
+ import { cn } from "../lib/utils.js";
5
+ import { useToolkitMessages } from "../locale/locale-provider.js";
2
6
  import { Input } from "../primitives/input.js";
3
7
  /**
4
8
  * Search input + toggleable chip row for filtering a list/table of widget
5
- * items. Pair with `useDebouncedValue` to avoid re-querying on every keystroke.
9
+ * items. The input is labelled; every chip is a toggle button whose state is
10
+ * `aria-pressed`. An active chip is a selection in the CI pattern: the info
11
+ * tint and edge around foreground text. Pair with `useDebouncedValue` to
12
+ * avoid re-querying on every keystroke.
6
13
  */
7
- export function FilterBar({ search, searchPlaceholder = "Filter…", onSearchChange, chips, onChipToggle, }) {
8
- return (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Input, { type: "search", value: search, onChange: (e) => onSearchChange(e.target.value), placeholder: searchPlaceholder, className: "h-9 min-w-[220px] flex-1 text-sm" }), _jsx("div", { className: "flex flex-wrap gap-1.5", children: chips.map((chip) => (_jsxs("button", { type: "button", onClick: () => onChipToggle(chip.id), className: `inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-medium transition-colors ${chip.active
9
- ? "bg-accent border-border text-accent-foreground font-semibold"
10
- : "border-border bg-background text-muted-foreground hover:bg-muted hover:text-foreground"}`, children: [chip.label, chip.count !== undefined && chip.count !== "" && (_jsx("span", { className: "tabular-nums opacity-60", children: chip.count }))] }, chip.id))) })] }));
14
+ export function FilterBar({ search, searchPlaceholder, searchAriaLabel, onSearchChange, chips, onChipToggle, chipsAriaLabel, className, }) {
15
+ const { filterBar } = useToolkitMessages();
16
+ return (_jsxs("div", { "data-slot": "filter-bar", className: cn("flex flex-wrap items-center gap-2", className), children: [_jsx(Input, { type: "search", value: search, onChange: (e) => onSearchChange(e.target.value), placeholder: searchPlaceholder ?? filterBar.searchPlaceholder, "aria-label": searchAriaLabel ?? filterBar.searchLabel, className: "text-dense md:text-dense h-9 min-w-[220px] flex-1" }), chips.length > 0 && (_jsx("div", { role: "group", "aria-label": chipsAriaLabel ?? filterBar.chipsLabel, className: "flex flex-wrap gap-1.5", children: chips.map((chip) => (_jsxs("button", { type: "button", onClick: () => onChipToggle(chip.id), "aria-pressed": Boolean(chip.active), className: cn("text-small inline-flex items-center gap-1.5 rounded-sm border px-2.5 py-1 font-medium transition-colors", FOCUS_RING, chip.active
17
+ ? cn(TONE_SOFT.info, TONE_BORDER.info, "font-semibold")
18
+ : "border-border bg-background text-muted-foreground hover:bg-muted hover:text-foreground"), children: [chip.label, chip.count !== undefined && chip.count !== "" && (_jsx("span", { className: "font-normal tabular-nums", children: chip.count }))] }, chip.id))) }))] }));
11
19
  }
12
20
  //# sourceMappingURL=FilterBar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterBar.js","sourceRoot":"","sources":["../../src/components/FilterBar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AA0B9C;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,MAAM,EACN,iBAAiB,GAAG,SAAS,EAC7B,cAAc,EACd,KAAK,EACL,YAAY,GACG;IACf,OAAO,CACL,eAAK,SAAS,EAAC,mCAAmC,aAChD,KAAC,KAAK,IACJ,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC/C,WAAW,EAAE,iBAAiB,EAC9B,SAAS,EAAC,kCAAkC,GAC5C,EACF,cAAK,SAAS,EAAC,wBAAwB,YACpC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,kBACE,IAAI,EAAC,QAAQ,EAEb,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EACpC,SAAS,EAAE,wGACT,IAAI,CAAC,MAAM;wBACT,CAAC,CAAC,8DAA8D;wBAChE,CAAC,CAAC,wFACN,EAAE,aAED,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,CAChD,eAAM,SAAS,EAAC,yBAAyB,YAAE,IAAI,CAAC,KAAK,GAAQ,CAC9D,KAXI,IAAI,CAAC,EAAE,CAYL,CACV,CAAC,GACE,IACF,CACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"FilterBar.js","sourceRoot":"","sources":["../../src/components/FilterBar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAkC9C;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,MAAM,EACN,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,KAAK,EACL,YAAY,EACZ,cAAc,EACd,SAAS,GACM;IACf,MAAM,EAAE,SAAS,EAAE,GAAG,kBAAkB,EAAE,CAAA;IAC1C,OAAO,CACL,4BAAe,YAAY,EAAC,SAAS,EAAE,EAAE,CAAC,mCAAmC,EAAE,SAAS,CAAC,aACvF,KAAC,KAAK,IACJ,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC/C,WAAW,EAAE,iBAAiB,IAAI,SAAS,CAAC,iBAAiB,gBACjD,eAAe,IAAI,SAAS,CAAC,WAAW,EACpD,SAAS,EAAC,mDAAmD,GAC7D,EACD,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CACnB,cACE,IAAI,EAAC,OAAO,gBACA,cAAc,IAAI,SAAS,CAAC,UAAU,EAClD,SAAS,EAAC,wBAAwB,YAEjC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,kBACE,IAAI,EAAC,QAAQ,EAEb,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,kBACtB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAClC,SAAS,EAAE,EAAE,CACX,yGAAyG,EACzG,UAAU,EACV,IAAI,CAAC,MAAM;wBACT,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,eAAe,CAAC;wBACvD,CAAC,CAAC,wFAAwF,CAC7F,aAEA,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,CAChD,eAAM,SAAS,EAAC,0BAA0B,YAAE,IAAI,CAAC,KAAK,GAAQ,CAC/D,KAdI,IAAI,CAAC,EAAE,CAeL,CACV,CAAC,GACE,CACP,IACG,CACP,CAAA;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"GroupCard.d.ts","sourceRoot":"","sources":["../../src/components/GroupCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjE,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,QAAQ,EAAE,OAAO,CAAA;IACjB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,sEAAsE;IACtE,OAAO,EAAE,SAAS,CAAA;IAClB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,cAAc,+BA8BlF"}
1
+ {"version":3,"file":"GroupCard.d.ts","sourceRoot":"","sources":["../../src/components/GroupCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,SAAS,EAAE,MAAM,OAAO,CAAA;AAGjE,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,QAAQ,EAAE,OAAO,CAAA;IACjB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,sEAAsE;IACtE,OAAO,EAAE,SAAS,CAAA;IAClB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,cAAc,+BA8BlF"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { FOCUS_RING_INSET } from "../lib/focus-ring.js";
2
3
  /**
3
4
  * Bordered card with a clickable summary bar and a collapsible body. Use to
4
5
  * group related rows behind an expandable header (e.g. items grouped by a key).
@@ -19,6 +20,6 @@ export function GroupCard({ expanded, onToggle, summary, children }) {
19
20
  return;
20
21
  onToggle();
21
22
  }
22
- return (_jsxs("div", { className: "border-border mb-2 overflow-hidden rounded-lg border", children: [_jsx("div", { role: "button", tabIndex: 0, "aria-expanded": expanded, onClick: handleClick, onKeyDown: handleKeyDown, className: `bg-card hover:bg-muted focus-visible:ring-ring/50 cursor-pointer transition-colors focus:outline-none focus-visible:ring-2 ${expanded ? "border-border border-b" : ""}`, children: summary }), expanded && children && _jsx("div", { children: children })] }));
23
+ return (_jsxs("div", { className: "border-border mb-2 overflow-hidden rounded-md border", children: [_jsx("div", { role: "button", tabIndex: 0, "aria-expanded": expanded, onClick: handleClick, onKeyDown: handleKeyDown, className: `bg-card hover:bg-muted cursor-pointer transition-colors ${FOCUS_RING_INSET} ${expanded ? "border-border border-b" : ""}`, children: summary }), expanded && children && _jsx("div", { children: children })] }));
23
24
  }
24
25
  //# sourceMappingURL=GroupCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GroupCard.js","sourceRoot":"","sources":["../../src/components/GroupCard.tsx"],"names":[],"mappings":";AAaA;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAkB;IACjF,SAAS,aAAa,CAAC,CAAgC;QACrD,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACvC,CAAC,CAAC,cAAc,EAAE,CAAA;YAClB,QAAQ,EAAE,CAAA;QACZ,CAAC;IACH,CAAC;IAED,SAAS,WAAW,CAAC,CAA6B;QAChD,IAAK,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,2CAA2C,CAAC;YAAE,OAAM;QAC1F,QAAQ,EAAE,CAAA;IACZ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,sDAAsD,aACnE,cACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,CAAC,mBACI,QAAQ,EACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,8HACT,QAAQ,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EACxC,EAAE,YAED,OAAO,GACJ,EACL,QAAQ,IAAI,QAAQ,IAAI,wBAAM,QAAQ,GAAO,IAC1C,CACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"GroupCard.js","sourceRoot":"","sources":["../../src/components/GroupCard.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAavD;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAkB;IACjF,SAAS,aAAa,CAAC,CAAgC;QACrD,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACvC,CAAC,CAAC,cAAc,EAAE,CAAA;YAClB,QAAQ,EAAE,CAAA;QACZ,CAAC;IACH,CAAC;IAED,SAAS,WAAW,CAAC,CAA6B;QAChD,IAAK,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,2CAA2C,CAAC;YAAE,OAAM;QAC1F,QAAQ,EAAE,CAAA;IACZ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,sDAAsD,aACnE,cACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,CAAC,mBACI,QAAQ,EACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,2DAA2D,gBAAgB,IACpF,QAAQ,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EACxC,EAAE,YAED,OAAO,GACJ,EACL,QAAQ,IAAI,QAAQ,IAAI,wBAAM,QAAQ,GAAO,IAC1C,CACP,CAAA;AACH,CAAC"}
@@ -1,43 +1,95 @@
1
- import type { ReactNode } from "react";
2
- import { type ToneVariant } from "../lib/tone-utils.js";
1
+ import { type ReactNode } from "react";
2
+ import { type ToneName } from "../lib/tone-utils.js";
3
+ type TrendDirection = "up" | "down" | "flat";
3
4
  export interface KpiCell {
4
- /** Caption shown above the value. */
5
+ /** Caption shown above the value. Part of the cell's accessible name. */
5
6
  label: ReactNode;
6
7
  /** The headline figure. Pre-format numbers for locale/currency. */
7
8
  value: ReactNode;
8
9
  /** Small fraction shown next to the value, e.g. ` /14`. */
9
10
  fraction?: ReactNode;
10
- /** Optional trend line under the value (e.g. `"+12% vs last week"`). */
11
+ /** Optional trend line under the value (e.g. `"+12% vs last week"`); its words stay neutral. */
11
12
  trend?: ReactNode;
12
- /** Colours the trend line. `up` reads as bad (danger), `down` as good (success). */
13
- trendDirection?: "up" | "down" | "flat";
14
- /** Tone applied to the value text (e.g. `"danger"` for a breached metric). */
15
- tone?: ToneVariant;
13
+ /**
14
+ * Draws a Lucide direction icon (TrendingUp / TrendingDown / Minus) before
15
+ * the trend line, in the trend's tone: `up` reads as bad (danger), `down`
16
+ * as good (success) unless {@link KpiCell.trendTone} says otherwise.
17
+ */
18
+ trendDirection?: TrendDirection;
19
+ /**
20
+ * Explicit tone of the trend — overrides the direction's default. Shown as
21
+ * the direction icon's colour, or as a dot when there is no direction.
22
+ */
23
+ trendTone?: ToneName;
24
+ /**
25
+ * The state the figure stands for (e.g. `"danger"` for a breached metric),
26
+ * shown as a dot next to the label (strip) or as the card's tint and edge
27
+ * (`variant="soft"`). The figure itself stays in the foreground colour.
28
+ */
29
+ tone?: ToneName;
16
30
  /** When set, the cell renders as a button — turns a metric into a nav entry point. */
17
31
  onClick?: () => void;
18
- /** Accessible label for the clickable cell (recommended when `onClick` is set). */
32
+ /**
33
+ * What activating the cell does ("Opens the incidents dashboard"). Read as
34
+ * the button's DESCRIPTION (`aria-describedby`), so its accessible name
35
+ * stays the visible label and value (WCAG 2.5.3, label in name).
36
+ */
37
+ actionHint?: string;
38
+ /**
39
+ * @deprecated Replaces the accessible name with text a voice-control user
40
+ * cannot see (WCAG 2.5.3). Say what the click does in
41
+ * {@link KpiCell.actionHint}; the visible label and value name the cell.
42
+ */
19
43
  ariaLabel?: string;
20
44
  }
45
+ /** The responsive column classes for `count` cells (clamped to 1–6). */
46
+ export declare function kpiColumns(count: number): string;
21
47
  export interface KpiGridHeader {
22
- /** Group label, rendered uppercase in the strip header. */
48
+ /** Group label of the strip header (13 px semibold, normal case). */
23
49
  label: ReactNode;
24
50
  /** Optional muted badge to the right of the label. */
25
51
  badge?: ReactNode;
26
52
  }
27
53
  export interface KpiGridProps {
28
- /** The metric cells, flowed as columns (1–6, clamped). */
54
+ /** The metric cells, flowed as columns (1–6; more wrap onto further rows). */
29
55
  cells: KpiCell[];
30
56
  /** Wrap the strip in a bordered card with an optional group `header`. Default `false`. */
31
57
  boxed?: boolean;
32
- /** Group header shown above the strip when `boxed`. */
58
+ /** Group header above the strip (strip variant), usually with `boxed`. */
33
59
  header?: KpiGridHeader;
60
+ /**
61
+ * `"strip"` (default): one bordered strip, the tone as a dot next to the
62
+ * label. `"soft"`: one card per cell in its tone's tint and edge (`boxed`
63
+ * and `header` don't apply).
64
+ */
65
+ variant?: "strip" | "soft";
66
+ /** Names the group of metrics (`role="group"`); omit when a heading right above names it. */
67
+ ariaLabel?: string;
68
+ className?: string;
69
+ }
70
+ /**
71
+ * A row of headline metrics — the canonical way to show KPIs in a widget
72
+ * (replaces the single-metric KPICard). Cells flow as columns (1–6), falling
73
+ * back to 2 columns in narrow frames. A cell's `tone` shows as a dot next to
74
+ * its label (or as a soft card's tint and edge); figures stay in the
75
+ * foreground colour. A clickable cell is a button whose accessible name is
76
+ * its visible label and value; `actionHint` describes what the click does.
77
+ */
78
+ export declare function KpiGrid({ cells, boxed, header, variant, ariaLabel, className, }: KpiGridProps): import("react").JSX.Element;
79
+ export interface KpiGridSkeletonProps {
80
+ /** How many cells the loaded grid will have. */
81
+ cells: number;
82
+ /** The loaded grid's variant. Default `"strip"`. */
83
+ variant?: "strip" | "soft";
84
+ /** The loaded grid's `boxed`. Default `false`. */
85
+ boxed?: boolean;
86
+ className?: string;
34
87
  }
35
88
  /**
36
- * Bordered strip of KPI cells — the canonical way to show a row of headline
37
- * metrics in a widget (replaces the single-metric KPICard). Cells flow as
38
- * columns (1–6) and can be made clickable to drill into a detail view. Use
39
- * `boxed` + `header` for a labelled metric block; unboxed (default) renders the
40
- * lighter `border-y` strip.
89
+ * Loading placeholder with {@link KpiGrid}'s geometry (same wrapper, grid and
90
+ * cell padding in both variants), so the layout doesn't jump when the data
91
+ * arrives. `aria-busy`; pair it with a status line if the wait is long.
41
92
  */
42
- export declare function KpiGrid({ cells, boxed, header }: KpiGridProps): import("react").JSX.Element;
93
+ export declare function KpiGridSkeleton({ cells, variant, boxed, className, }: KpiGridSkeletonProps): import("react").JSX.Element;
94
+ export {};
43
95
  //# sourceMappingURL=KpiGrid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"KpiGrid.d.ts","sourceRoot":"","sources":["../../src/components/KpiGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AASlE,MAAM,WAAW,OAAO;IACtB,qCAAqC;IACrC,KAAK,EAAE,SAAS,CAAA;IAChB,mEAAmE;IACnE,KAAK,EAAE,SAAS,CAAA;IAChB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,wEAAwE;IACxE,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,oFAAoF;IACpF,cAAc,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;IACvC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAWD,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,KAAK,EAAE,SAAS,CAAA;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,0FAA0F;IAC1F,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,uDAAuD;IACvD,MAAM,CAAC,EAAE,aAAa,CAAA;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,KAAa,EAAE,MAAM,EAAE,EAAE,YAAY,+BAwErE"}
1
+ {"version":3,"file":"KpiGrid.d.ts","sourceRoot":"","sources":["../../src/components/KpiGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG7C,OAAO,EAML,KAAK,QAAQ,EAEd,MAAM,sBAAsB,CAAA;AAK7B,KAAK,cAAc,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;AAmB5C,MAAM,WAAW,OAAO;IACtB,yEAAyE;IACzE,KAAK,EAAE,SAAS,CAAA;IAChB,mEAAmE;IACnE,KAAK,EAAE,SAAS,CAAA;IAChB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,gGAAgG;IAChG,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,CAAA;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAgBD,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,KAAK,EAAE,SAAS,CAAA;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,0FAA0F;IAC1F,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,0EAA0E;IAC1E,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAqJD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,KAAa,EACb,MAAM,EACN,OAAiB,EACjB,SAAS,EACT,SAAS,GACV,EAAE,YAAY,+BAiCd;AAED,MAAM,WAAW,oBAAoB;IACnC,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,OAAiB,EACjB,KAAa,EACb,SAAS,GACV,EAAE,oBAAoB,+BAgCtB"}
@@ -1,35 +1,124 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { TONE_TEXT } from "../lib/tone-utils.js";
3
- /** Trend direction → tone for the small trend line under a value. */
2
+ import { useId } from "react";
3
+ import { ChevronRight, Minus, TrendingDown, TrendingUp } from "lucide-react";
4
+ import { FOCUS_RING_INSET, FOCUS_RING } from "../lib/focus-ring.js";
5
+ import { resolveTone, TONE_BORDER, TONE_DOT, TONE_ICON, TONE_TINT, } from "../lib/tone-utils.js";
6
+ import { MICRO_LABEL } from "../lib/typography.js";
7
+ import { cn } from "../lib/utils.js";
8
+ import { Skeleton } from "../primitives/skeleton.js";
9
+ /**
10
+ * Direction → tone when no `trendTone` is set (incident-biased: up reads as
11
+ * worse). The tone shows ONLY as the direction icon's colour or a dot; the
12
+ * trend words stay neutral (no coloured digits, CI §3.3).
13
+ */
4
14
  const TREND_TONE = {
5
- up: "text-danger",
6
- down: "text-success",
7
- flat: "text-muted-foreground",
15
+ up: "danger",
16
+ down: "success",
17
+ flat: "neutral",
18
+ };
19
+ const TREND_ICON = {
20
+ up: TrendingUp,
21
+ down: TrendingDown,
22
+ flat: Minus,
8
23
  };
24
+ /**
25
+ * Columns per cell count. 4+ cells fall back to 2 columns in narrow frames
26
+ * (inline chat views are often under 500 px, where five cells side by side
27
+ * leave ~40 px each); 6 steps through 3.
28
+ */
9
29
  const COL_CLASS = {
10
30
  1: "grid-cols-1",
11
31
  2: "grid-cols-2",
12
32
  3: "grid-cols-3",
13
- 4: "grid-cols-4",
14
- 5: "grid-cols-5",
15
- 6: "grid-cols-6",
33
+ 4: "grid-cols-2 sm:grid-cols-4",
34
+ 5: "grid-cols-2 sm:grid-cols-5",
35
+ 6: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6",
16
36
  };
37
+ /** The responsive column classes for `count` cells (clamped to 1–6). */
38
+ export function kpiColumns(count) {
39
+ const cols = Math.min(Math.max(Math.trunc(count) || 1, 1), 6);
40
+ return COL_CLASS[cols] ?? "grid-cols-1";
41
+ }
42
+ /** A small status dot; decorative — the label next to it carries the meaning. */
43
+ function ToneDot({ tone, className }) {
44
+ return (_jsx("span", { "aria-hidden": "true", "data-tone": tone, className: cn("shrink-0 rounded-full", className, TONE_DOT[tone]) }));
45
+ }
46
+ /**
47
+ * The trend line: neutral words (the foreground next to a state, quiet
48
+ * without one) and the state beside them as a direction icon or a dot in the
49
+ * tone — never as coloured digits.
50
+ */
51
+ function TrendLine({ cell }) {
52
+ const direction = cell.trendDirection;
53
+ const tone = cell.trendTone !== undefined
54
+ ? resolveTone(cell.trendTone)
55
+ : direction
56
+ ? TREND_TONE[direction]
57
+ : "neutral";
58
+ const marked = tone !== "neutral";
59
+ const Icon = direction ? TREND_ICON[direction] : undefined;
60
+ return (_jsxs("div", { "data-slot": "kpi-trend", className: "text-small mt-1.5 flex items-center gap-1.5", children: [Icon ? (_jsx(Icon, { "aria-hidden": "true", className: cn("size-4 shrink-0", TONE_ICON[tone]) })) : (marked && _jsx(ToneDot, { tone: tone, className: "size-1.5" })), _jsx("span", { className: marked ? "text-foreground" : "text-muted-foreground", children: cell.trend })] }));
61
+ }
62
+ /** Label, figure, fraction and trend — shared by the strip and soft variants. */
63
+ function KpiCellBody({ cell, variant }) {
64
+ const tone = resolveTone(cell.tone);
65
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: cn("text-small flex items-center justify-between gap-2 font-medium", variant === "strip" ? "text-muted-foreground" : "text-foreground"), children: [_jsxs("span", { className: "inline-flex min-w-0 items-center gap-1.5", children: [variant === "strip" && tone !== "neutral" && _jsx(ToneDot, { tone: tone, className: "size-2" }), _jsx("span", { className: "min-w-0 break-words", children: cell.label })] }), cell.onClick && _jsx(ChevronRight, { "aria-hidden": "true", className: "size-4 shrink-0" })] }), _jsxs("div", { className: "text-title text-foreground mt-1.5 leading-none tracking-tight break-words tabular-nums", children: [cell.value, cell.fraction && (_jsx("span", { className: "text-dense text-muted-foreground ml-0.5 font-normal", children: cell.fraction }))] }), cell.trend && _jsx(TrendLine, { cell: cell })] }));
66
+ }
67
+ /** One cell: a button when clickable (named by its visible text), else a plain box. */
68
+ function KpiCellView({ cell, variant, className, }) {
69
+ const hintId = useId();
70
+ const body = _jsx(KpiCellBody, { cell: cell, variant: variant });
71
+ const tone = cell.tone === undefined ? undefined : resolveTone(cell.tone);
72
+ if (!cell.onClick) {
73
+ return (_jsx("div", { "data-tone": tone, className: className, children: body }));
74
+ }
75
+ return (_jsxs("button", { type: "button", onClick: cell.onClick, "aria-label": cell.ariaLabel, "aria-describedby": cell.actionHint ? hintId : undefined, "data-tone": tone, className: cn("cursor-pointer text-left transition-colors", variant === "strip" ? cn("hover:bg-muted", FOCUS_RING_INSET) : FOCUS_RING, className), children: [body, cell.actionHint && (_jsx("span", { id: hintId, hidden: true, children: cell.actionHint }))] }));
76
+ }
77
+ /** A soft card: the tone's tint and edge around neutral text. */
78
+ function softCardClass(tone) {
79
+ const t = resolveTone(tone);
80
+ return cn("text-foreground rounded-lg border p-4", TONE_TINT[t], TONE_BORDER[t]);
81
+ }
82
+ /**
83
+ * The strip's dividers. Each cell draws its own right and bottom rule, and the
84
+ * grid reaches 1 px past its clipping frame, so the rules on the outer edges
85
+ * fall away at any column count. An empty track in a short last row (5 cells
86
+ * in 2 columns, 7 in 6) keeps the card colour: a `gap-px` grid on a
87
+ * `bg-border` container would paint it as a solid block of the divider colour.
88
+ */
89
+ const STRIP_FRAME = "bg-card overflow-hidden";
90
+ const STRIP_GRID = "-mr-px -mb-px grid";
91
+ const STRIP_CELL = "border-border min-w-0 border-r border-b px-5 py-4";
92
+ function KpiStripHeader({ header }) {
93
+ return (_jsxs("div", { className: cn("border-border bg-muted text-muted-foreground flex items-center gap-2 border-b px-4 py-2", MICRO_LABEL), children: [_jsx("span", { children: header.label }), header.badge && (_jsx("span", { className: "border-border bg-card text-muted-foreground text-small rounded-sm border px-1.5 font-medium", children: header.badge }))] }));
94
+ }
95
+ /**
96
+ * A row of headline metrics — the canonical way to show KPIs in a widget
97
+ * (replaces the single-metric KPICard). Cells flow as columns (1–6), falling
98
+ * back to 2 columns in narrow frames. A cell's `tone` shows as a dot next to
99
+ * its label (or as a soft card's tint and edge); figures stay in the
100
+ * foreground colour. A clickable cell is a button whose accessible name is
101
+ * its visible label and value; `actionHint` describes what the click does.
102
+ */
103
+ export function KpiGrid({ cells, boxed = false, header, variant = "strip", ariaLabel, className, }) {
104
+ const colClass = kpiColumns(cells.length);
105
+ const group = ariaLabel ? { role: "group", "aria-label": ariaLabel } : {};
106
+ if (variant === "soft") {
107
+ return (_jsx("div", { ...group, "data-slot": "kpi-grid", className: cn("grid gap-4", colClass, className), children: cells.map((cell, idx) => (_jsx(KpiCellView, { cell: cell, variant: "soft", className: cn("min-w-0", softCardClass(cell.tone)) }, idx))) }));
108
+ }
109
+ return (_jsxs("div", { ...group, "data-slot": "kpi-grid", className: cn(boxed && "border-border overflow-hidden rounded-lg border", className), children: [header && _jsx(KpiStripHeader, { header: header }), _jsx("div", { "data-slot": "kpi-strip", className: cn(STRIP_FRAME, !boxed && "border-border border-y"), children: _jsx("div", { className: cn(STRIP_GRID, colClass), children: cells.map((cell, idx) => (_jsx(KpiCellView, { cell: cell, variant: "strip", className: STRIP_CELL }, idx))) }) })] }));
110
+ }
17
111
  /**
18
- * Bordered strip of KPI cells — the canonical way to show a row of headline
19
- * metrics in a widget (replaces the single-metric KPICard). Cells flow as
20
- * columns (1–6) and can be made clickable to drill into a detail view. Use
21
- * `boxed` + `header` for a labelled metric block; unboxed (default) renders the
22
- * lighter `border-y` strip.
112
+ * Loading placeholder with {@link KpiGrid}'s geometry (same wrapper, grid and
113
+ * cell padding in both variants), so the layout doesn't jump when the data
114
+ * arrives. `aria-busy`; pair it with a status line if the wait is long.
23
115
  */
24
- export function KpiGrid({ cells, boxed = false, header }) {
25
- const cols = Math.min(Math.max(cells.length, 1), 6);
26
- const colClass = COL_CLASS[cols] ?? "grid-cols-4";
27
- const wrapperClass = boxed ? "border-border overflow-hidden rounded-lg border" : "";
28
- const stripClass = boxed ? "" : "border-border border-y";
29
- return (_jsxs("div", { className: wrapperClass, children: [header && (_jsxs("div", { className: "border-border bg-muted text-muted-foreground flex items-center gap-2 border-b px-4 py-2 text-[11px] font-semibold tracking-wide uppercase", children: [_jsx("span", { children: header.label }), header.badge && (_jsx("span", { className: "border-border bg-card text-muted-foreground rounded border px-1.5 py-0 text-[10px] font-medium normal-case", children: header.badge }))] })), _jsx("div", { className: `grid ${colClass} ${stripClass}`, children: cells.map((cell, idx) => {
30
- const borderClass = idx < cells.length - 1 ? "border-border border-r" : "";
31
- const content = (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between gap-2 text-xs font-medium", children: [_jsx("span", { children: cell.label }), cell.onClick && (_jsx("span", { "aria-hidden": "true", className: "text-sm leading-none", children: "\u203A" }))] }), _jsxs("div", { className: `mt-1.5 text-2xl leading-none font-bold tracking-tight tabular-nums ${(cell.tone && TONE_TEXT[cell.tone]) || "text-foreground"}`, children: [cell.value, cell.fraction && (_jsx("span", { className: "text-muted-foreground ml-0.5 text-sm font-normal", children: cell.fraction }))] }), cell.trend && (_jsx("div", { className: `mt-1.5 text-xs ${cell.trendDirection ? TREND_TONE[cell.trendDirection] : "text-muted-foreground"}`, children: cell.trend }))] }));
32
- return cell.onClick ? (_jsx("button", { type: "button", onClick: cell.onClick, "aria-label": cell.ariaLabel, className: `hover:bg-muted focus-visible:ring-ring cursor-pointer px-5 py-4 text-left transition-colors outline-none focus-visible:ring-2 focus-visible:ring-inset ${borderClass}`, children: content }, idx)) : (_jsx("div", { className: `px-5 py-4 ${borderClass}`, children: content }, idx));
33
- }) })] }));
116
+ export function KpiGridSkeleton({ cells, variant = "strip", boxed = false, className, }) {
117
+ const colClass = kpiColumns(cells);
118
+ const count = Math.max(Math.trunc(cells) || 0, 0);
119
+ if (variant === "soft") {
120
+ return (_jsx("div", { "aria-busy": "true", className: cn("grid gap-4", colClass, className), children: Array.from({ length: count }, (_, idx) => (_jsxs("div", { className: "bg-muted border-border rounded-lg border p-4", children: [_jsx(Skeleton, { className: "h-4 w-20" }), _jsx(Skeleton, { className: "mt-2 h-7 w-14" })] }, idx))) }));
121
+ }
122
+ return (_jsx("div", { "aria-busy": "true", className: cn(boxed && "border-border overflow-hidden rounded-lg border", className), children: _jsx("div", { "data-slot": "kpi-strip", className: cn(STRIP_FRAME, !boxed && "border-border border-y"), children: _jsx("div", { className: cn(STRIP_GRID, colClass), children: Array.from({ length: count }, (_, idx) => (_jsxs("div", { className: STRIP_CELL, children: [_jsx(Skeleton, { className: "h-4 w-16" }), _jsx(Skeleton, { className: "mt-2.5 h-7 w-14" })] }, idx))) }) }) }));
34
123
  }
35
124
  //# sourceMappingURL=KpiGrid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"KpiGrid.js","sourceRoot":"","sources":["../../src/components/KpiGrid.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KpiGrid.js","sourceRoot":"","sources":["../../src/components/KpiGrid.tsx"],"names":[],"mappings":"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"}