@miragon/mcp-toolkit-ui 0.10.1

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 (320) hide show
  1. package/README.md +36 -0
  2. package/dist/app/adapt-data-widget.d.ts +33 -0
  3. package/dist/app/adapt-data-widget.d.ts.map +1 -0
  4. package/dist/app/adapt-data-widget.js +35 -0
  5. package/dist/app/adapt-data-widget.js.map +1 -0
  6. package/dist/app/builder/CatalogueSheet.d.ts +13 -0
  7. package/dist/app/builder/CatalogueSheet.d.ts.map +1 -0
  8. package/dist/app/builder/CatalogueSheet.js +33 -0
  9. package/dist/app/builder/CatalogueSheet.js.map +1 -0
  10. package/dist/app/builder/PipelineStrip.d.ts +22 -0
  11. package/dist/app/builder/PipelineStrip.d.ts.map +1 -0
  12. package/dist/app/builder/PipelineStrip.js +31 -0
  13. package/dist/app/builder/PipelineStrip.js.map +1 -0
  14. package/dist/app/builder/PreviewPane.d.ts +13 -0
  15. package/dist/app/builder/PreviewPane.d.ts.map +1 -0
  16. package/dist/app/builder/PreviewPane.js +21 -0
  17. package/dist/app/builder/PreviewPane.js.map +1 -0
  18. package/dist/app/builder/SaveDialog.d.ts +14 -0
  19. package/dist/app/builder/SaveDialog.d.ts.map +1 -0
  20. package/dist/app/builder/SaveDialog.js +14 -0
  21. package/dist/app/builder/SaveDialog.js.map +1 -0
  22. package/dist/app/builder/Toolbar.d.ts +17 -0
  23. package/dist/app/builder/Toolbar.d.ts.map +1 -0
  24. package/dist/app/builder/Toolbar.js +15 -0
  25. package/dist/app/builder/Toolbar.js.map +1 -0
  26. package/dist/app/builder/Workspace.d.ts +28 -0
  27. package/dist/app/builder/Workspace.d.ts.map +1 -0
  28. package/dist/app/builder/Workspace.js +117 -0
  29. package/dist/app/builder/Workspace.js.map +1 -0
  30. package/dist/app/builder/builder-model.d.ts +86 -0
  31. package/dist/app/builder/builder-model.d.ts.map +1 -0
  32. package/dist/app/builder/builder-model.js +174 -0
  33. package/dist/app/builder/builder-model.js.map +1 -0
  34. package/dist/app/builder/builder-reducer.d.ts +71 -0
  35. package/dist/app/builder/builder-reducer.d.ts.map +1 -0
  36. package/dist/app/builder/builder-reducer.js +201 -0
  37. package/dist/app/builder/builder-reducer.js.map +1 -0
  38. package/dist/app/builder/labels.d.ts +78 -0
  39. package/dist/app/builder/labels.d.ts.map +1 -0
  40. package/dist/app/builder/labels.js +71 -0
  41. package/dist/app/builder/labels.js.map +1 -0
  42. package/dist/app/builder/status-chip.d.ts +10 -0
  43. package/dist/app/builder/status-chip.d.ts.map +1 -0
  44. package/dist/app/builder/status-chip.js +16 -0
  45. package/dist/app/builder/status-chip.js.map +1 -0
  46. package/dist/app/host-bridge.d.ts +211 -0
  47. package/dist/app/host-bridge.d.ts.map +1 -0
  48. package/dist/app/host-bridge.js +247 -0
  49. package/dist/app/host-bridge.js.map +1 -0
  50. package/dist/app/index.d.ts +16 -0
  51. package/dist/app/index.d.ts.map +1 -0
  52. package/dist/app/index.js +18 -0
  53. package/dist/app/index.js.map +1 -0
  54. package/dist/app/layout-builder.d.ts +48 -0
  55. package/dist/app/layout-builder.d.ts.map +1 -0
  56. package/dist/app/layout-builder.js +418 -0
  57. package/dist/app/layout-builder.js.map +1 -0
  58. package/dist/app/mcp-app-view.d.ts +43 -0
  59. package/dist/app/mcp-app-view.d.ts.map +1 -0
  60. package/dist/app/mcp-app-view.js +169 -0
  61. package/dist/app/mcp-app-view.js.map +1 -0
  62. package/dist/app/mcp-toolkit-app.d.ts +18 -0
  63. package/dist/app/mcp-toolkit-app.d.ts.map +1 -0
  64. package/dist/app/mcp-toolkit-app.js +22 -0
  65. package/dist/app/mcp-toolkit-app.js.map +1 -0
  66. package/dist/app/use-host-actions.d.ts +57 -0
  67. package/dist/app/use-host-actions.d.ts.map +1 -0
  68. package/dist/app/use-host-actions.js +42 -0
  69. package/dist/app/use-host-actions.js.map +1 -0
  70. package/dist/app/widget-fixture.d.ts +180 -0
  71. package/dist/app/widget-fixture.d.ts.map +1 -0
  72. package/dist/app/widget-fixture.js +273 -0
  73. package/dist/app/widget-fixture.js.map +1 -0
  74. package/dist/app/widget-props-sheet.d.ts +20 -0
  75. package/dist/app/widget-props-sheet.d.ts.map +1 -0
  76. package/dist/app/widget-props-sheet.js +87 -0
  77. package/dist/app/widget-props-sheet.js.map +1 -0
  78. package/dist/app/widget-renderer.d.ts +87 -0
  79. package/dist/app/widget-renderer.d.ts.map +1 -0
  80. package/dist/app/widget-renderer.js +105 -0
  81. package/dist/app/widget-renderer.js.map +1 -0
  82. package/dist/components/DrillButton.d.ts +22 -0
  83. package/dist/components/DrillButton.d.ts.map +1 -0
  84. package/dist/components/DrillButton.js +13 -0
  85. package/dist/components/DrillButton.js.map +1 -0
  86. package/dist/components/FilterBar.d.ts +28 -0
  87. package/dist/components/FilterBar.d.ts.map +1 -0
  88. package/dist/components/FilterBar.js +12 -0
  89. package/dist/components/FilterBar.js.map +1 -0
  90. package/dist/components/GridLayout.d.ts +26 -0
  91. package/dist/components/GridLayout.d.ts.map +1 -0
  92. package/dist/components/GridLayout.js +31 -0
  93. package/dist/components/GridLayout.js.map +1 -0
  94. package/dist/components/GroupCard.d.ts +21 -0
  95. package/dist/components/GroupCard.d.ts.map +1 -0
  96. package/dist/components/GroupCard.js +24 -0
  97. package/dist/components/GroupCard.js.map +1 -0
  98. package/dist/components/KpiGrid.d.ts +43 -0
  99. package/dist/components/KpiGrid.d.ts.map +1 -0
  100. package/dist/components/KpiGrid.js +35 -0
  101. package/dist/components/KpiGrid.js.map +1 -0
  102. package/dist/components/ListFooter.d.ts +22 -0
  103. package/dist/components/ListFooter.d.ts.map +1 -0
  104. package/dist/components/ListFooter.js +13 -0
  105. package/dist/components/ListFooter.js.map +1 -0
  106. package/dist/components/Pills.d.ts +25 -0
  107. package/dist/components/Pills.d.ts.map +1 -0
  108. package/dist/components/Pills.js +17 -0
  109. package/dist/components/Pills.js.map +1 -0
  110. package/dist/components/SectionHeading.d.ts +16 -0
  111. package/dist/components/SectionHeading.d.ts.map +1 -0
  112. package/dist/components/SectionHeading.js +10 -0
  113. package/dist/components/SectionHeading.js.map +1 -0
  114. package/dist/components/WidgetHeader.d.ts +21 -0
  115. package/dist/components/WidgetHeader.d.ts.map +1 -0
  116. package/dist/components/WidgetHeader.js +11 -0
  117. package/dist/components/WidgetHeader.js.map +1 -0
  118. package/dist/hooks/index.d.ts +11 -0
  119. package/dist/hooks/index.d.ts.map +1 -0
  120. package/dist/hooks/index.js +7 -0
  121. package/dist/hooks/index.js.map +1 -0
  122. package/dist/hooks/use-debounced-value.d.ts +7 -0
  123. package/dist/hooks/use-debounced-value.d.ts.map +1 -0
  124. package/dist/hooks/use-debounced-value.js +15 -0
  125. package/dist/hooks/use-debounced-value.js.map +1 -0
  126. package/dist/hooks/use-mobile.d.ts +6 -0
  127. package/dist/hooks/use-mobile.d.ts.map +1 -0
  128. package/dist/hooks/use-mobile.js +19 -0
  129. package/dist/hooks/use-mobile.js.map +1 -0
  130. package/dist/hooks/use-tool-query.d.ts +21 -0
  131. package/dist/hooks/use-tool-query.d.ts.map +1 -0
  132. package/dist/hooks/use-tool-query.js +47 -0
  133. package/dist/hooks/use-tool-query.js.map +1 -0
  134. package/dist/hooks/use-tool-result-recovery.d.ts +54 -0
  135. package/dist/hooks/use-tool-result-recovery.d.ts.map +1 -0
  136. package/dist/hooks/use-tool-result-recovery.js +93 -0
  137. package/dist/hooks/use-tool-result-recovery.js.map +1 -0
  138. package/dist/hooks/use-view-data.d.ts +19 -0
  139. package/dist/hooks/use-view-data.d.ts.map +1 -0
  140. package/dist/hooks/use-view-data.js +18 -0
  141. package/dist/hooks/use-view-data.js.map +1 -0
  142. package/dist/hooks/use-view-tool-query.d.ts +18 -0
  143. package/dist/hooks/use-view-tool-query.d.ts.map +1 -0
  144. package/dist/hooks/use-view-tool-query.js +29 -0
  145. package/dist/hooks/use-view-tool-query.js.map +1 -0
  146. package/dist/index.d.ts +47 -0
  147. package/dist/index.d.ts.map +1 -0
  148. package/dist/index.js +56 -0
  149. package/dist/index.js.map +1 -0
  150. package/dist/lib/parse-tool-result.d.ts +39 -0
  151. package/dist/lib/parse-tool-result.d.ts.map +1 -0
  152. package/dist/lib/parse-tool-result.js +66 -0
  153. package/dist/lib/parse-tool-result.js.map +1 -0
  154. package/dist/lib/tone-utils.d.ts +18 -0
  155. package/dist/lib/tone-utils.d.ts.map +1 -0
  156. package/dist/lib/tone-utils.js +25 -0
  157. package/dist/lib/tone-utils.js.map +1 -0
  158. package/dist/lib/utils.d.ts +3 -0
  159. package/dist/lib/utils.d.ts.map +1 -0
  160. package/dist/lib/utils.js +6 -0
  161. package/dist/lib/utils.js.map +1 -0
  162. package/dist/locale/index.d.ts +3 -0
  163. package/dist/locale/index.d.ts.map +1 -0
  164. package/dist/locale/index.js +7 -0
  165. package/dist/locale/index.js.map +1 -0
  166. package/dist/locale/locale-provider.d.ts +50 -0
  167. package/dist/locale/locale-provider.d.ts.map +1 -0
  168. package/dist/locale/locale-provider.js +47 -0
  169. package/dist/locale/locale-provider.js.map +1 -0
  170. package/dist/primitives/alert.d.ts +10 -0
  171. package/dist/primitives/alert.d.ts.map +1 -0
  172. package/dist/primitives/alert.js +25 -0
  173. package/dist/primitives/alert.js.map +1 -0
  174. package/dist/primitives/badge.d.ts +8 -0
  175. package/dist/primitives/badge.d.ts.map +1 -0
  176. package/dist/primitives/badge.js +34 -0
  177. package/dist/primitives/badge.js.map +1 -0
  178. package/dist/primitives/button.d.ts +11 -0
  179. package/dist/primitives/button.d.ts.map +1 -0
  180. package/dist/primitives/button.js +36 -0
  181. package/dist/primitives/button.js.map +1 -0
  182. package/dist/primitives/card.d.ts +12 -0
  183. package/dist/primitives/card.d.ts.map +1 -0
  184. package/dist/primitives/card.js +25 -0
  185. package/dist/primitives/card.js.map +1 -0
  186. package/dist/primitives/dialog.d.ts +18 -0
  187. package/dist/primitives/dialog.d.ts.map +1 -0
  188. package/dist/primitives/dialog.js +38 -0
  189. package/dist/primitives/dialog.js.map +1 -0
  190. package/dist/primitives/input.d.ts +4 -0
  191. package/dist/primitives/input.d.ts.map +1 -0
  192. package/dist/primitives/input.js +7 -0
  193. package/dist/primitives/input.js.map +1 -0
  194. package/dist/primitives/scroll-area.d.ts +6 -0
  195. package/dist/primitives/scroll-area.d.ts.map +1 -0
  196. package/dist/primitives/scroll-area.js +11 -0
  197. package/dist/primitives/scroll-area.js.map +1 -0
  198. package/dist/primitives/select.d.ts +16 -0
  199. package/dist/primitives/select.d.ts.map +1 -0
  200. package/dist/primitives/select.js +38 -0
  201. package/dist/primitives/select.js.map +1 -0
  202. package/dist/primitives/separator.d.ts +4 -0
  203. package/dist/primitives/separator.d.ts.map +1 -0
  204. package/dist/primitives/separator.js +9 -0
  205. package/dist/primitives/separator.js.map +1 -0
  206. package/dist/primitives/sheet.d.ts +15 -0
  207. package/dist/primitives/sheet.d.ts.map +1 -0
  208. package/dist/primitives/sheet.js +41 -0
  209. package/dist/primitives/sheet.js.map +1 -0
  210. package/dist/primitives/skeleton.d.ts +3 -0
  211. package/dist/primitives/skeleton.d.ts.map +1 -0
  212. package/dist/primitives/skeleton.js +7 -0
  213. package/dist/primitives/skeleton.js.map +1 -0
  214. package/dist/primitives/switch.d.ts +5 -0
  215. package/dist/primitives/switch.d.ts.map +1 -0
  216. package/dist/primitives/switch.js +8 -0
  217. package/dist/primitives/switch.js.map +1 -0
  218. package/dist/primitives/table.d.ts +11 -0
  219. package/dist/primitives/table.d.ts.map +1 -0
  220. package/dist/primitives/table.js +28 -0
  221. package/dist/primitives/table.js.map +1 -0
  222. package/dist/primitives/tabs.d.ts +12 -0
  223. package/dist/primitives/tabs.d.ts.map +1 -0
  224. package/dist/primitives/tabs.js +29 -0
  225. package/dist/primitives/tabs.js.map +1 -0
  226. package/dist/providers/query-provider.d.ts +11 -0
  227. package/dist/providers/query-provider.d.ts.map +1 -0
  228. package/dist/providers/query-provider.js +20 -0
  229. package/dist/providers/query-provider.js.map +1 -0
  230. package/dist/theme/create-theme.d.ts +130 -0
  231. package/dist/theme/create-theme.d.ts.map +1 -0
  232. package/dist/theme/create-theme.js +65 -0
  233. package/dist/theme/create-theme.js.map +1 -0
  234. package/dist/theme/index.d.ts +7 -0
  235. package/dist/theme/index.d.ts.map +1 -0
  236. package/dist/theme/index.js +7 -0
  237. package/dist/theme/index.js.map +1 -0
  238. package/dist/theme/presets.d.ts +25 -0
  239. package/dist/theme/presets.d.ts.map +1 -0
  240. package/dist/theme/presets.js +68 -0
  241. package/dist/theme/presets.js.map +1 -0
  242. package/dist/theme/theme-provider.d.ts +69 -0
  243. package/dist/theme/theme-provider.d.ts.map +1 -0
  244. package/dist/theme/theme-provider.js +79 -0
  245. package/dist/theme/theme-provider.js.map +1 -0
  246. package/package.json +71 -0
  247. package/src/app/adapt-data-widget.tsx +51 -0
  248. package/src/app/builder/CatalogueSheet.tsx +230 -0
  249. package/src/app/builder/PipelineStrip.tsx +260 -0
  250. package/src/app/builder/PreviewPane.tsx +72 -0
  251. package/src/app/builder/SaveDialog.tsx +95 -0
  252. package/src/app/builder/Toolbar.tsx +95 -0
  253. package/src/app/builder/Workspace.tsx +483 -0
  254. package/src/app/builder/builder-model.test.ts +351 -0
  255. package/src/app/builder/builder-model.ts +213 -0
  256. package/src/app/builder/builder-reducer.test.ts +441 -0
  257. package/src/app/builder/builder-reducer.ts +289 -0
  258. package/src/app/builder/labels.ts +139 -0
  259. package/src/app/builder/status-chip.tsx +37 -0
  260. package/src/app/host-bridge.test.ts +206 -0
  261. package/src/app/host-bridge.tsx +371 -0
  262. package/src/app/index.ts +51 -0
  263. package/src/app/layout-builder.tsx +872 -0
  264. package/src/app/mcp-app-view.tsx +367 -0
  265. package/src/app/mcp-toolkit-app.tsx +25 -0
  266. package/src/app/use-host-actions.test.ts +16 -0
  267. package/src/app/use-host-actions.tsx +88 -0
  268. package/src/app/widget-fixture.test.ts +108 -0
  269. package/src/app/widget-fixture.tsx +441 -0
  270. package/src/app/widget-props-sheet.tsx +285 -0
  271. package/src/app/widget-renderer.test.ts +42 -0
  272. package/src/app/widget-renderer.tsx +200 -0
  273. package/src/components/DrillButton.tsx +37 -0
  274. package/src/components/FilterBar.tsx +68 -0
  275. package/src/components/GridLayout.tsx +49 -0
  276. package/src/components/GroupCard.tsx +52 -0
  277. package/src/components/KpiGrid.tsx +134 -0
  278. package/src/components/ListFooter.tsx +48 -0
  279. package/src/components/Pills.tsx +45 -0
  280. package/src/components/SectionHeading.tsx +26 -0
  281. package/src/components/WidgetHeader.tsx +51 -0
  282. package/src/globals.css +168 -0
  283. package/src/hooks/index.ts +17 -0
  284. package/src/hooks/use-debounced-value.ts +15 -0
  285. package/src/hooks/use-mobile.ts +24 -0
  286. package/src/hooks/use-tool-query.ts +63 -0
  287. package/src/hooks/use-tool-result-recovery.test.ts +65 -0
  288. package/src/hooks/use-tool-result-recovery.ts +144 -0
  289. package/src/hooks/use-view-data.ts +31 -0
  290. package/src/hooks/use-view-tool-query.ts +38 -0
  291. package/src/index.ts +134 -0
  292. package/src/lib/parse-tool-result.test.ts +139 -0
  293. package/src/lib/parse-tool-result.ts +89 -0
  294. package/src/lib/tone-utils.test.ts +35 -0
  295. package/src/lib/tone-utils.ts +38 -0
  296. package/src/lib/utils.ts +6 -0
  297. package/src/locale/index.ts +7 -0
  298. package/src/locale/locale-provider.tsx +81 -0
  299. package/src/primitives/alert.tsx +60 -0
  300. package/src/primitives/badge.tsx +49 -0
  301. package/src/primitives/button.tsx +62 -0
  302. package/src/primitives/card.tsx +92 -0
  303. package/src/primitives/dialog.tsx +144 -0
  304. package/src/primitives/input.tsx +21 -0
  305. package/src/primitives/scroll-area.tsx +54 -0
  306. package/src/primitives/select.tsx +173 -0
  307. package/src/primitives/separator.tsx +21 -0
  308. package/src/primitives/sheet.tsx +134 -0
  309. package/src/primitives/skeleton.tsx +13 -0
  310. package/src/primitives/switch.tsx +24 -0
  311. package/src/primitives/table.tsx +87 -0
  312. package/src/primitives/tabs.tsx +79 -0
  313. package/src/providers/query-provider.tsx +38 -0
  314. package/src/theme/create-theme.test.ts +108 -0
  315. package/src/theme/create-theme.ts +158 -0
  316. package/src/theme/index.ts +9 -0
  317. package/src/theme/presets.ts +82 -0
  318. package/src/theme/theme-provider.tsx +152 -0
  319. package/src/ui-catalog.test.ts +112 -0
  320. package/ui-catalog.json +1280 -0
@@ -0,0 +1,22 @@
1
+ import type { ReactNode } from "react";
2
+ export interface DrillButtonProps {
3
+ /** Button label. */
4
+ children: ReactNode;
5
+ /** Drill/navigation handler — wire to in-widget navigation (e.g. `showWidget`). */
6
+ onDrill: () => void;
7
+ /** Optional leading glyph (e.g. a domain icon). The trailing → is always rendered. */
8
+ icon?: ReactNode;
9
+ /** `sm` for table rows, `md` for surface headers. Default `"sm"`. */
10
+ size?: "sm" | "md";
11
+ /** Accessible label when the visible text is terse. */
12
+ ariaLabel?: string;
13
+ }
14
+ /**
15
+ * The single, deterministic in-widget navigation control: a neutral outline
16
+ * button with a trailing → that drills into a detail/sub-view. Use it for
17
+ * every in-app drill (row "Open", header nav) so they read identically and stay
18
+ * visually quieter than primary/agentic actions. Decoupled from any host — pass
19
+ * an `onDrill` callback (e.g. wrapping `useHostActions().showWidget`).
20
+ */
21
+ export declare function DrillButton({ children, onDrill, icon, size, ariaLabel }: DrillButtonProps): import("react").JSX.Element;
22
+ //# sourceMappingURL=DrillButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrillButton.d.ts","sourceRoot":"","sources":["../../src/components/DrillButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB;IACpB,QAAQ,EAAE,SAAS,CAAA;IACnB,mFAAmF;IACnF,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,sFAAsF;IACtF,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,qEAAqE;IACrE,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IAClB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAW,EAAE,SAAS,EAAE,EAAE,gBAAgB,+BAchG"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * The single, deterministic in-widget navigation control: a neutral outline
4
+ * button with a trailing → that drills into a detail/sub-view. Use it for
5
+ * every in-app drill (row "Open", header nav) so they read identically and stay
6
+ * visually quieter than primary/agentic actions. Decoupled from any host — pass
7
+ * an `onDrill` callback (e.g. wrapping `useHostActions().showWidget`).
8
+ */
9
+ export function DrillButton({ children, onDrill, icon, size = "sm", ariaLabel }) {
10
+ const pad = size === "md" ? "px-3 py-1.5 text-sm" : "px-2.5 py-1 text-xs";
11
+ return (_jsxs("button", { type: "button", onClick: onDrill, "aria-label": ariaLabel, className: `border-border text-foreground hover:bg-muted focus-visible:ring-ring inline-flex items-center gap-1 rounded-md border font-medium transition-colors outline-none focus-visible:ring-2 ${pad}`, children: [icon && _jsx("span", { "aria-hidden": "true", children: icon }), children, _jsx("span", { "aria-hidden": "true", children: "\u2192" })] }));
12
+ }
13
+ //# sourceMappingURL=DrillButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DrillButton.js","sourceRoot":"","sources":["../../src/components/DrillButton.tsx"],"names":[],"mappings":";AAeA;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,SAAS,EAAoB;IAC/F,MAAM,GAAG,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,qBAAqB,CAAA;IACzE,OAAO,CACL,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,OAAO,gBACJ,SAAS,EACrB,SAAS,EAAE,yLAAyL,GAAG,EAAE,aAExM,IAAI,IAAI,8BAAkB,MAAM,YAAE,IAAI,GAAQ,EAC9C,QAAQ,EACT,8BAAkB,MAAM,uBAAS,IAC1B,CACV,CAAA;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ export interface FilterChip {
2
+ /** Stable id passed back to `onChipToggle`. */
3
+ id: string;
4
+ /** Visible chip label. */
5
+ label: string;
6
+ /** Optional count rendered after the label. */
7
+ count?: number | string;
8
+ /** Whether the chip is currently active. */
9
+ active?: boolean;
10
+ }
11
+ export interface FilterBarProps {
12
+ /** Current search text (controlled). */
13
+ search: string;
14
+ /** Placeholder for the search input. Default `"Filter…"`. */
15
+ searchPlaceholder?: string;
16
+ /** Called with the new search text on every keystroke. */
17
+ onSearchChange: (next: string) => void;
18
+ /** Filter chips rendered to the right of the search input. */
19
+ chips: FilterChip[];
20
+ /** Called with a chip id when it is toggled. */
21
+ onChipToggle: (id: string) => void;
22
+ }
23
+ /**
24
+ * Search input + toggleable chip row for filtering a list/table of widget
25
+ * items. Pair with `useDebouncedValue` to avoid re-querying on every keystroke.
26
+ */
27
+ export declare function FilterBar({ search, searchPlaceholder, onSearchChange, chips, onChipToggle, }: FilterBarProps): import("react").JSX.Element;
28
+ //# sourceMappingURL=FilterBar.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Input } from "../primitives/input.js";
3
+ /**
4
+ * Search input + toggleable chip row for filtering a list/table of widget
5
+ * items. Pair with `useDebouncedValue` to avoid re-querying on every keystroke.
6
+ */
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))) })] }));
11
+ }
12
+ //# sourceMappingURL=FilterBar.js.map
@@ -0,0 +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"}
@@ -0,0 +1,26 @@
1
+ import * as React from "react";
2
+ export interface GridLayoutProps {
3
+ /** `GridItem` children to lay out across the 12 columns. */
4
+ children: React.ReactNode;
5
+ /** Extra classes merged onto the grid container (e.g. to change the gap). */
6
+ className?: string;
7
+ }
8
+ /**
9
+ * 12-column responsive grid container. Wrap `GridItem`s in it to compose
10
+ * dashboard rows; this is the same grid `WidgetRenderer` uses internally.
11
+ */
12
+ export declare function GridLayout({ children, className }: GridLayoutProps): React.JSX.Element;
13
+ export interface GridItemProps {
14
+ /** Column span from 1–12. Defaults to a full-width `12`. */
15
+ span?: number;
16
+ /** Cell content. */
17
+ children: React.ReactNode;
18
+ /** Extra classes merged onto the cell. */
19
+ className?: string;
20
+ }
21
+ /**
22
+ * A cell inside a `GridLayout`, spanning `span` of the 12 columns. Out-of-range
23
+ * spans fall back to full width.
24
+ */
25
+ export declare function GridItem({ span, children, className }: GridItemProps): React.JSX.Element;
26
+ //# sourceMappingURL=GridLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GridLayout.d.ts","sourceRoot":"","sources":["../../src/components/GridLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,eAAe,qBAElE;AAED,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oBAAoB;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAiBD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,IAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,aAAa,qBAEzE"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ /**
4
+ * 12-column responsive grid container. Wrap `GridItem`s in it to compose
5
+ * dashboard rows; this is the same grid `WidgetRenderer` uses internally.
6
+ */
7
+ export function GridLayout({ children, className }) {
8
+ return _jsx("div", { className: cn("grid grid-cols-12 gap-4", className), children: children });
9
+ }
10
+ const spanClasses = {
11
+ 1: "col-span-1",
12
+ 2: "col-span-2",
13
+ 3: "col-span-3",
14
+ 4: "col-span-4",
15
+ 5: "col-span-5",
16
+ 6: "col-span-6",
17
+ 7: "col-span-7",
18
+ 8: "col-span-8",
19
+ 9: "col-span-9",
20
+ 10: "col-span-10",
21
+ 11: "col-span-11",
22
+ 12: "col-span-12",
23
+ };
24
+ /**
25
+ * A cell inside a `GridLayout`, spanning `span` of the 12 columns. Out-of-range
26
+ * spans fall back to full width.
27
+ */
28
+ export function GridItem({ span = 12, children, className }) {
29
+ return _jsx("div", { className: cn(spanClasses[span] ?? "col-span-12", className), children: children });
30
+ }
31
+ //# sourceMappingURL=GridLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GridLayout.js","sourceRoot":"","sources":["../../src/components/GridLayout.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AASpC;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAmB;IACjE,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE,SAAS,CAAC,YAAG,QAAQ,GAAO,CAAA;AACnF,CAAC;AAWD,MAAM,WAAW,GAA2B;IAC1C,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,EAAE,EAAE,aAAa;IACjB,EAAE,EAAE,aAAa;IACjB,EAAE,EAAE,aAAa;CAClB,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAiB;IACxE,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,aAAa,EAAE,SAAS,CAAC,YAAG,QAAQ,GAAO,CAAA;AAC5F,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { ReactNode } from "react";
2
+ export interface GroupCardProps {
3
+ /** Whether the body is expanded. */
4
+ expanded: boolean;
5
+ /** Toggle handler for the summary bar. */
6
+ onToggle: () => void;
7
+ /** Always-visible summary bar (may contain its own buttons/links). */
8
+ summary: ReactNode;
9
+ /** Collapsible body, rendered only when `expanded`. */
10
+ children?: ReactNode;
11
+ }
12
+ /**
13
+ * Bordered card with a clickable summary bar and a collapsible body. Use to
14
+ * group related rows behind an expandable header (e.g. items grouped by a key).
15
+ *
16
+ * The summary uses `role="button"` rather than a `<button>` element so it can
17
+ * contain its own controls (drill buttons, links) without producing invalid
18
+ * nested-interactive HTML; clicks landing on those controls do not toggle.
19
+ */
20
+ export declare function GroupCard({ expanded, onToggle, summary, children }: GroupCardProps): import("react").JSX.Element;
21
+ //# sourceMappingURL=GroupCard.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Bordered card with a clickable summary bar and a collapsible body. Use to
4
+ * group related rows behind an expandable header (e.g. items grouped by a key).
5
+ *
6
+ * The summary uses `role="button"` rather than a `<button>` element so it can
7
+ * contain its own controls (drill buttons, links) without producing invalid
8
+ * nested-interactive HTML; clicks landing on those controls do not toggle.
9
+ */
10
+ export function GroupCard({ expanded, onToggle, summary, children }) {
11
+ function handleKeyDown(e) {
12
+ if (e.key === "Enter" || e.key === " ") {
13
+ e.preventDefault();
14
+ onToggle();
15
+ }
16
+ }
17
+ function handleClick(e) {
18
+ if (e.target.closest("button, a, input, select, textarea, label"))
19
+ return;
20
+ onToggle();
21
+ }
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
+ }
24
+ //# sourceMappingURL=GroupCard.js.map
@@ -0,0 +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"}
@@ -0,0 +1,43 @@
1
+ import type { ReactNode } from "react";
2
+ import { type ToneVariant } from "../lib/tone-utils.js";
3
+ export interface KpiCell {
4
+ /** Caption shown above the value. */
5
+ label: ReactNode;
6
+ /** The headline figure. Pre-format numbers for locale/currency. */
7
+ value: ReactNode;
8
+ /** Small fraction shown next to the value, e.g. ` /14`. */
9
+ fraction?: ReactNode;
10
+ /** Optional trend line under the value (e.g. `"+12% vs last week"`). */
11
+ 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;
16
+ /** When set, the cell renders as a button — turns a metric into a nav entry point. */
17
+ onClick?: () => void;
18
+ /** Accessible label for the clickable cell (recommended when `onClick` is set). */
19
+ ariaLabel?: string;
20
+ }
21
+ export interface KpiGridHeader {
22
+ /** Group label, rendered uppercase in the strip header. */
23
+ label: ReactNode;
24
+ /** Optional muted badge to the right of the label. */
25
+ badge?: ReactNode;
26
+ }
27
+ export interface KpiGridProps {
28
+ /** The metric cells, flowed as columns (1–6, clamped). */
29
+ cells: KpiCell[];
30
+ /** Wrap the strip in a bordered card with an optional group `header`. Default `false`. */
31
+ boxed?: boolean;
32
+ /** Group header shown above the strip when `boxed`. */
33
+ header?: KpiGridHeader;
34
+ }
35
+ /**
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.
41
+ */
42
+ export declare function KpiGrid({ cells, boxed, header }: KpiGridProps): import("react").JSX.Element;
43
+ //# sourceMappingURL=KpiGrid.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,35 @@
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. */
4
+ const TREND_TONE = {
5
+ up: "text-danger",
6
+ down: "text-success",
7
+ flat: "text-muted-foreground",
8
+ };
9
+ const COL_CLASS = {
10
+ 1: "grid-cols-1",
11
+ 2: "grid-cols-2",
12
+ 3: "grid-cols-3",
13
+ 4: "grid-cols-4",
14
+ 5: "grid-cols-5",
15
+ 6: "grid-cols-6",
16
+ };
17
+ /**
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.
23
+ */
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
+ }) })] }));
34
+ }
35
+ //# sourceMappingURL=KpiGrid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KpiGrid.js","sourceRoot":"","sources":["../../src/components/KpiGrid.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAA;AAElE,qEAAqE;AACrE,MAAM,UAAU,GAA2C;IACzD,EAAE,EAAE,aAAa;IACjB,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,uBAAuB;CAC9B,CAAA;AAqBD,MAAM,SAAS,GAA2B;IACxC,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,aAAa;CACjB,CAAA;AAkBD;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,MAAM,EAAgB;IACpE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACnD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,CAAA;IACjD,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,iDAAiD,CAAC,CAAC,CAAC,EAAE,CAAA;IACnF,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAA;IACxD,OAAO,CACL,eAAK,SAAS,EAAE,YAAY,aACzB,MAAM,IAAI,CACT,eAAK,SAAS,EAAC,2IAA2I,aACxJ,yBAAO,MAAM,CAAC,KAAK,GAAQ,EAC1B,MAAM,CAAC,KAAK,IAAI,CACf,eAAM,SAAS,EAAC,4GAA4G,YACzH,MAAM,CAAC,KAAK,GACR,CACR,IACG,CACP,EACD,cAAK,SAAS,EAAE,QAAQ,QAAQ,IAAI,UAAU,EAAE,YAC7C,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;oBACvB,MAAM,WAAW,GAAG,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAA;oBAC1E,MAAM,OAAO,GAAG,CACd,8BACE,eAAK,SAAS,EAAC,mFAAmF,aAChG,yBAAO,IAAI,CAAC,KAAK,GAAQ,EACxB,IAAI,CAAC,OAAO,IAAI,CACf,8BAAkB,MAAM,EAAC,SAAS,EAAC,sBAAsB,uBAElD,CACR,IACG,EACN,eACE,SAAS,EAAE,sEACT,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,iBACzC,EAAE,aAED,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,QAAQ,IAAI,CAChB,eAAM,SAAS,EAAC,kDAAkD,YAC/D,IAAI,CAAC,QAAQ,GACT,CACR,IACG,EACL,IAAI,CAAC,KAAK,IAAI,CACb,cACE,SAAS,EAAE,kBACT,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,uBAC1D,EAAE,YAED,IAAI,CAAC,KAAK,GACP,CACP,IACA,CACJ,CAAA;oBACD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CACpB,iBAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,IAAI,CAAC,OAAO,gBACT,IAAI,CAAC,SAAS,EAC1B,SAAS,EAAE,0JAA0J,WAAW,EAAE,YAEjL,OAAO,IANH,GAAG,CAOD,CACV,CAAC,CAAC,CAAC,CACF,cAAe,SAAS,EAAE,aAAa,WAAW,EAAE,YACjD,OAAO,IADA,GAAG,CAEP,CACP,CAAA;gBACH,CAAC,CAAC,GACE,IACF,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ export interface ListFooterProps {
2
+ /** How many rows are currently rendered. */
3
+ shown: number;
4
+ /** The total number of rows available. */
5
+ total: number;
6
+ /** Whether more rows can be loaded. */
7
+ hasMore: boolean;
8
+ /** Disables the button and shows a loading label while a fetch is in flight. */
9
+ loadingMore?: boolean;
10
+ /** Called when the user asks for the next page. */
11
+ onLoadMore: () => void;
12
+ /** Plural noun for the count, e.g. `"instances"`. Default `"rows"`. */
13
+ noun?: string;
14
+ }
15
+ /**
16
+ * Footer for a paginated list: an honest "Showing X of Y" total plus an
17
+ * explicit "Load more" control. Deliberately not infinite scroll — the user
18
+ * gets the total, a reachable footer, and control over fetching. Renders
19
+ * nothing when `total` is 0.
20
+ */
21
+ export declare function ListFooter({ shown, total, hasMore, loadingMore, onLoadMore, noun, }: ListFooterProps): import("react").JSX.Element | null;
22
+ //# sourceMappingURL=ListFooter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListFooter.d.ts","sourceRoot":"","sources":["../../src/components/ListFooter.tsx"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAA;IAChB,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,mDAAmD;IACnD,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,OAAO,EACP,WAAmB,EACnB,UAAU,EACV,IAAa,GACd,EAAE,eAAe,sCAmBjB"}
@@ -0,0 +1,13 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Footer for a paginated list: an honest "Showing X of Y" total plus an
4
+ * explicit "Load more" control. Deliberately not infinite scroll — the user
5
+ * gets the total, a reachable footer, and control over fetching. Renders
6
+ * nothing when `total` is 0.
7
+ */
8
+ export function ListFooter({ shown, total, hasMore, loadingMore = false, onLoadMore, noun = "rows", }) {
9
+ if (total <= 0)
10
+ return null;
11
+ return (_jsxs("div", { className: "text-muted-foreground flex items-center justify-between gap-3 px-1 py-2 text-xs", children: [_jsxs("span", { children: ["Showing ", shown.toLocaleString(), " of ", total.toLocaleString(), " ", noun] }), hasMore && (_jsx("button", { type: "button", onClick: onLoadMore, disabled: loadingMore, className: "border-border text-foreground hover:bg-muted focus-visible:ring-ring inline-flex items-center gap-1 rounded-md border px-3 py-1.5 font-medium outline-none focus-visible:ring-2 disabled:opacity-50", children: loadingMore ? "Loading…" : "Load more" }))] }));
12
+ }
13
+ //# sourceMappingURL=ListFooter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListFooter.js","sourceRoot":"","sources":["../../src/components/ListFooter.tsx"],"names":[],"mappings":";AAeA;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,OAAO,EACP,WAAW,GAAG,KAAK,EACnB,UAAU,EACV,IAAI,GAAG,MAAM,GACG;IAChB,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3B,OAAO,CACL,eAAK,SAAS,EAAC,iFAAiF,aAC9F,uCACW,KAAK,CAAC,cAAc,EAAE,UAAM,KAAK,CAAC,cAAc,EAAE,OAAG,IAAI,IAC7D,EACN,OAAO,IAAI,CACV,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAC,qMAAqM,YAE9M,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,GAChC,CACV,IACG,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { ReactNode } from "react";
2
+ import { type ToneVariant } from "../lib/tone-utils.js";
3
+ export interface LivePillProps {
4
+ /** Status tone driving the dot + tint. Default `"info"`. */
5
+ tone?: ToneVariant;
6
+ /** Pill label. Defaults to `"Live"`. */
7
+ children?: ReactNode;
8
+ }
9
+ /**
10
+ * Small tinted pill with a pulsing dot. Use in a widget header to signal that
11
+ * the data is live/real-time. Tone-based, so it inherits the active theme.
12
+ */
13
+ export declare function LivePill({ tone, children }: LivePillProps): import("react").JSX.Element;
14
+ export interface CountPillProps {
15
+ /** Status tone driving the tint. Default `"neutral"`. */
16
+ tone?: ToneVariant;
17
+ /** The count/value to display (tabular numbers). */
18
+ children: ReactNode;
19
+ }
20
+ /**
21
+ * Compact count badge — tabular numbers on a tinted background. Use as the
22
+ * right-aligned indicator on a list/group row (e.g. a per-group item count).
23
+ */
24
+ export declare function CountPill({ tone, children }: CountPillProps): import("react").JSX.Element;
25
+ //# sourceMappingURL=Pills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pills.d.ts","sourceRoot":"","sources":["../../src/components/Pills.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAE5E,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,IAAa,EAAE,QAAQ,EAAE,EAAE,aAAa,+BASlE;AAED,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,oDAAoD;IACpD,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EAAE,IAAgB,EAAE,QAAQ,EAAE,EAAE,cAAc,+BAQvE"}
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { TONE_DOT, TONE_SOFT } from "../lib/tone-utils.js";
3
+ /**
4
+ * Small tinted pill with a pulsing dot. Use in a widget header to signal that
5
+ * the data is live/real-time. Tone-based, so it inherits the active theme.
6
+ */
7
+ export function LivePill({ tone = "info", children }) {
8
+ return (_jsxs("span", { className: `inline-flex items-center gap-1.5 rounded-md px-2 py-0.5 text-xs font-semibold ${TONE_SOFT[tone]}`, children: [_jsx("span", { className: `size-1.5 animate-pulse rounded-full ${TONE_DOT[tone]}` }), children ?? "Live"] }));
9
+ }
10
+ /**
11
+ * Compact count badge — tabular numbers on a tinted background. Use as the
12
+ * right-aligned indicator on a list/group row (e.g. a per-group item count).
13
+ */
14
+ export function CountPill({ tone = "neutral", children }) {
15
+ return (_jsx("span", { className: `inline-flex min-w-[2.5rem] items-center justify-center rounded-md px-2.5 py-0.5 text-sm font-semibold tabular-nums ${TONE_SOFT[tone]}`, children: children }));
16
+ }
17
+ //# sourceMappingURL=Pills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pills.js","sourceRoot":"","sources":["../../src/components/Pills.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAA;AAS5E;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,GAAG,MAAM,EAAE,QAAQ,EAAiB;IACjE,OAAO,CACL,gBACE,SAAS,EAAE,iFAAiF,SAAS,CAAC,IAAI,CAAC,EAAE,aAE7G,eAAM,SAAS,EAAE,uCAAuC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAI,EAC3E,QAAQ,IAAI,MAAM,IACd,CACR,CAAA;AACH,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,GAAG,SAAS,EAAE,QAAQ,EAAkB;IACtE,OAAO,CACL,eACE,SAAS,EAAE,sHAAsH,SAAS,CAAC,IAAI,CAAC,EAAE,YAEjJ,QAAQ,GACJ,CACR,CAAA;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from "react";
2
+ export interface SectionHeadingProps {
3
+ /** The section title. */
4
+ title: ReactNode;
5
+ /** Optional muted hint shown on the right (e.g. a count or last-updated note). */
6
+ hint?: ReactNode;
7
+ /** Right-aligned slot that overrides `hint` when set (e.g. a control). */
8
+ trailing?: ReactNode;
9
+ }
10
+ /**
11
+ * Section title row — a small semibold heading with an optional muted hint or
12
+ * control on the right. Use to label a block inside a widget body (e.g. a list
13
+ * or sub-table) without the visual weight of a full card header.
14
+ */
15
+ export declare function SectionHeading({ title, hint, trailing }: SectionHeadingProps): import("react").JSX.Element;
16
+ //# sourceMappingURL=SectionHeading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionHeading.d.ts","sourceRoot":"","sources":["../../src/components/SectionHeading.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,mBAAmB;IAClC,yBAAyB;IACzB,KAAK,EAAE,SAAS,CAAA;IAChB,kFAAkF;IAClF,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,mBAAmB,+BAS5E"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Section title row — a small semibold heading with an optional muted hint or
4
+ * control on the right. Use to label a block inside a widget body (e.g. a list
5
+ * or sub-table) without the visual weight of a full card header.
6
+ */
7
+ export function SectionHeading({ title, hint, trailing }) {
8
+ return (_jsxs("div", { className: "text-muted-foreground mb-3 flex items-center justify-between text-sm font-semibold", children: [_jsx("span", { children: title }), (hint || trailing) && (_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: trailing ?? hint }))] }));
9
+ }
10
+ //# sourceMappingURL=SectionHeading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionHeading.js","sourceRoot":"","sources":["../../src/components/SectionHeading.tsx"],"names":[],"mappings":";AAWA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAuB;IAC3E,OAAO,CACL,eAAK,SAAS,EAAC,oFAAoF,aACjG,yBAAO,KAAK,GAAQ,EACnB,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CACrB,eAAM,SAAS,EAAC,2CAA2C,YAAE,QAAQ,IAAI,IAAI,GAAQ,CACtF,IACG,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { ReactNode } from "react";
2
+ import { type ToneVariant } from "../lib/tone-utils.js";
3
+ export interface WidgetHeaderProps {
4
+ /** Optional icon/glyph rendered in a tinted tile above the title. */
5
+ icon?: ReactNode;
6
+ /** Tone for the icon tile. Default `"neutral"`. */
7
+ iconTone?: ToneVariant;
8
+ /** The widget title. */
9
+ title: ReactNode;
10
+ /** Subtitle/meta row under the title (e.g. a live pill + counts). */
11
+ sub?: ReactNode;
12
+ /** Right-aligned actions slot (buttons, drill controls). */
13
+ actions?: ReactNode;
14
+ }
15
+ /**
16
+ * Page-level header for the top of a dashboard widget: an optional tinted icon
17
+ * tile, a large title, a subtitle/meta row, and a right-aligned actions slot.
18
+ * Use once per widget surface to anchor it.
19
+ */
20
+ export declare function WidgetHeader({ icon, iconTone, title, sub, actions, }: WidgetHeaderProps): import("react").JSX.Element;
21
+ //# sourceMappingURL=WidgetHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetHeader.d.ts","sourceRoot":"","sources":["../../src/components/WidgetHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElE,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,WAAW,CAAA;IACtB,wBAAwB;IACxB,KAAK,EAAE,SAAS,CAAA;IAChB,qEAAqE;IACrE,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,4DAA4D;IAC5D,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,QAAoB,EACpB,KAAK,EACL,GAAG,EACH,OAAO,GACR,EAAE,iBAAiB,+BAuBnB"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { TONE_SOFT } from "../lib/tone-utils.js";
3
+ /**
4
+ * Page-level header for the top of a dashboard widget: an optional tinted icon
5
+ * tile, a large title, a subtitle/meta row, and a right-aligned actions slot.
6
+ * Use once per widget surface to anchor it.
7
+ */
8
+ export function WidgetHeader({ icon, iconTone = "neutral", title, sub, actions, }) {
9
+ return (_jsxs("header", { className: "flex flex-wrap items-start justify-between gap-4", children: [_jsxs("div", { className: "min-w-0", children: [icon && (_jsx("div", { className: `mb-3.5 grid size-11 place-items-center rounded-xl text-xl ${TONE_SOFT[iconTone]}`, children: icon })), _jsx("h1", { className: "text-foreground mb-1.5 text-3xl leading-tight font-bold tracking-tight", children: title }), sub && (_jsx("div", { className: "text-muted-foreground flex flex-wrap items-center gap-2 text-sm", children: sub }))] }), actions && _jsx("div", { className: "flex flex-wrap items-center gap-2", children: actions })] }));
10
+ }
11
+ //# sourceMappingURL=WidgetHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetHeader.js","sourceRoot":"","sources":["../../src/components/WidgetHeader.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAA;AAelE;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,IAAI,EACJ,QAAQ,GAAG,SAAS,EACpB,KAAK,EACL,GAAG,EACH,OAAO,GACW;IAClB,OAAO,CACL,kBAAQ,SAAS,EAAC,kDAAkD,aAClE,eAAK,SAAS,EAAC,SAAS,aACrB,IAAI,IAAI,CACP,cACE,SAAS,EAAE,6DAA6D,SAAS,CAAC,QAAQ,CAAC,EAAE,YAE5F,IAAI,GACD,CACP,EACD,aAAI,SAAS,EAAC,wEAAwE,YACnF,KAAK,GACH,EACJ,GAAG,IAAI,CACN,cAAK,SAAS,EAAC,iEAAiE,YAC7E,GAAG,GACA,CACP,IACG,EACL,OAAO,IAAI,cAAK,SAAS,EAAC,mCAAmC,YAAE,OAAO,GAAO,IACvE,CACV,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ export { useIsMobile } from "./use-mobile.js";
2
+ export { useDebouncedValue } from "./use-debounced-value.js";
3
+ export { useToolQuery, useToolMutation } from "./use-tool-query.js";
4
+ export type { UseToolQueryOptions } from "./use-tool-query.js";
5
+ export { useViewToolQuery } from "./use-view-tool-query.js";
6
+ export type { UseViewToolQueryOptions } from "./use-view-tool-query.js";
7
+ export { useViewData } from "./use-view-data.js";
8
+ export type { ViewDataResult } from "./use-view-data.js";
9
+ export { useToolResultRecovery, resolveRecoveryToolName, decodeRecoveredResult, } from "./use-tool-result-recovery.js";
10
+ export type { ToolResultRecoveryOptions, ToolResultRecoveryState, } from "./use-tool-result-recovery.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACnE,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,+BAA+B,CAAA;AACtC,YAAY,EACV,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,+BAA+B,CAAA"}
@@ -0,0 +1,7 @@
1
+ export { useIsMobile } from "./use-mobile.js";
2
+ export { useDebouncedValue } from "./use-debounced-value.js";
3
+ export { useToolQuery, useToolMutation } from "./use-tool-query.js";
4
+ export { useViewToolQuery } from "./use-view-tool-query.js";
5
+ export { useViewData } from "./use-view-data.js";
6
+ export { useToolResultRecovery, resolveRecoveryToolName, decodeRecoveredResult, } from "./use-tool-result-recovery.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAEnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,+BAA+B,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Returns `value` delayed by `delayMs`, resetting the timer on every change.
3
+ * Use to debounce a search box so a server-side filter only re-queries once the
4
+ * user pauses typing (not on every keystroke). Pure React — no host dependency.
5
+ */
6
+ export declare function useDebouncedValue<T>(value: T, delayMs?: number): T;
7
+ //# sourceMappingURL=use-debounced-value.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-debounced-value.d.ts","sourceRoot":"","sources":["../../src/hooks/use-debounced-value.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,SAAM,GAAG,CAAC,CAO/D"}
@@ -0,0 +1,15 @@
1
+ import { useEffect, useState } from "react";
2
+ /**
3
+ * Returns `value` delayed by `delayMs`, resetting the timer on every change.
4
+ * Use to debounce a search box so a server-side filter only re-queries once the
5
+ * user pauses typing (not on every keystroke). Pure React — no host dependency.
6
+ */
7
+ export function useDebouncedValue(value, delayMs = 300) {
8
+ const [debounced, setDebounced] = useState(value);
9
+ useEffect(() => {
10
+ const id = setTimeout(() => setDebounced(value), delayMs);
11
+ return () => clearTimeout(id);
12
+ }, [value, delayMs]);
13
+ return debounced;
14
+ }
15
+ //# sourceMappingURL=use-debounced-value.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-debounced-value.js","sourceRoot":"","sources":["../../src/hooks/use-debounced-value.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE3C;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAI,KAAQ,EAAE,OAAO,GAAG,GAAG;IAC1D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACjD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAA;QACzD,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;IAC/B,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;IACpB,OAAO,SAAS,CAAA;AAClB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tracks whether the viewport is below the mobile breakpoint (768px), updating
3
+ * on resize. Use to switch a widget between a compact and a wide layout.
4
+ */
5
+ export declare function useIsMobile(): boolean;
6
+ //# sourceMappingURL=use-mobile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-mobile.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mobile.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,WAAW,YAe1B"}
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+ const MOBILE_BREAKPOINT = 768;
3
+ /**
4
+ * Tracks whether the viewport is below the mobile breakpoint (768px), updating
5
+ * on resize. Use to switch a widget between a compact and a wide layout.
6
+ */
7
+ export function useIsMobile() {
8
+ const [isMobile, setIsMobile] = React.useState(() => typeof window === "undefined" ? undefined : window.innerWidth < MOBILE_BREAKPOINT);
9
+ React.useEffect(() => {
10
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
11
+ const onChange = () => {
12
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
13
+ };
14
+ mql.addEventListener("change", onChange);
15
+ return () => mql.removeEventListener("change", onChange);
16
+ }, []);
17
+ return !!isMobile;
18
+ }
19
+ //# sourceMappingURL=use-mobile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-mobile.js","sourceRoot":"","sources":["../../src/hooks/use-mobile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAE7B;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAsB,GAAG,EAAE,CACvE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,iBAAiB,CAClF,CAAA;IAED,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,eAAe,iBAAiB,GAAG,CAAC,KAAK,CAAC,CAAA;QACxE,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,WAAW,CAAC,MAAM,CAAC,UAAU,GAAG,iBAAiB,CAAC,CAAA;QACpD,CAAC,CAAA;QACD,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACxC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC1D,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CAAC,CAAC,QAAQ,CAAA;AACnB,CAAC"}