@databricks/appkit-ui 0.14.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/NOTICE.md +1 -0
  2. package/dist/cli/commands/plugin/add-resource/add-resource.js +10 -4
  3. package/dist/cli/commands/plugin/add-resource/add-resource.js.map +1 -1
  4. package/dist/cli/commands/plugin/create/scaffold.js +10 -16
  5. package/dist/cli/commands/plugin/create/scaffold.js.map +1 -1
  6. package/dist/cli/commands/plugin/list/list.js +44 -26
  7. package/dist/cli/commands/plugin/list/list.js.map +1 -1
  8. package/dist/cli/commands/plugin/manifest-resolve.js +57 -0
  9. package/dist/cli/commands/plugin/manifest-resolve.js.map +1 -0
  10. package/dist/cli/commands/plugin/sync/sync.js +121 -71
  11. package/dist/cli/commands/plugin/sync/sync.js.map +1 -1
  12. package/dist/cli/commands/plugin/trusted-js-manifest.js +28 -0
  13. package/dist/cli/commands/plugin/trusted-js-manifest.js.map +1 -0
  14. package/dist/cli/commands/plugin/validate/validate.js +32 -14
  15. package/dist/cli/commands/plugin/validate/validate.js.map +1 -1
  16. package/dist/js/arrow/arrow-client.d.ts.map +1 -1
  17. package/dist/js/arrow/index.d.ts +3 -0
  18. package/dist/js/arrow/lazy-arrow.d.ts +0 -1
  19. package/dist/js/arrow/lazy-arrow.d.ts.map +1 -1
  20. package/dist/js/constants.d.ts.map +1 -1
  21. package/dist/js/index.d.ts +2 -0
  22. package/dist/js/sse/connect-sse.d.ts +0 -1
  23. package/dist/js/sse/connect-sse.d.ts.map +1 -1
  24. package/dist/js/sse/types.d.ts +1 -3
  25. package/dist/js/sse/types.d.ts.map +1 -1
  26. package/dist/react/charts/area/index.d.ts +2 -3
  27. package/dist/react/charts/area/index.d.ts.map +1 -1
  28. package/dist/react/charts/bar/index.d.ts +2 -3
  29. package/dist/react/charts/bar/index.d.ts.map +1 -1
  30. package/dist/react/charts/base.d.ts +2 -2
  31. package/dist/react/charts/base.d.ts.map +1 -1
  32. package/dist/react/charts/base.js.map +1 -1
  33. package/dist/react/charts/chart-error-boundary.js.map +1 -1
  34. package/dist/react/charts/constants.d.ts.map +1 -1
  35. package/dist/react/charts/create-chart.d.ts +2 -3
  36. package/dist/react/charts/create-chart.d.ts.map +1 -1
  37. package/dist/react/charts/create-chart.js.map +1 -1
  38. package/dist/react/charts/empty.js.map +1 -1
  39. package/dist/react/charts/error.js.map +1 -1
  40. package/dist/react/charts/heatmap/index.d.ts +2 -3
  41. package/dist/react/charts/heatmap/index.d.ts.map +1 -1
  42. package/dist/react/charts/index.d.ts +18 -0
  43. package/dist/react/charts/line/index.d.ts +2 -3
  44. package/dist/react/charts/line/index.d.ts.map +1 -1
  45. package/dist/react/charts/loading.js.map +1 -1
  46. package/dist/react/charts/normalize.d.ts +0 -1
  47. package/dist/react/charts/normalize.d.ts.map +1 -1
  48. package/dist/react/charts/options.d.ts.map +1 -1
  49. package/dist/react/charts/pie/index.d.ts +3 -4
  50. package/dist/react/charts/pie/index.d.ts.map +1 -1
  51. package/dist/react/charts/radar/index.d.ts +2 -3
  52. package/dist/react/charts/radar/index.d.ts.map +1 -1
  53. package/dist/react/charts/scatter/index.d.ts +2 -3
  54. package/dist/react/charts/scatter/index.d.ts.map +1 -1
  55. package/dist/react/charts/theme.d.ts +0 -1
  56. package/dist/react/charts/theme.d.ts.map +1 -1
  57. package/dist/react/charts/types.d.ts.map +1 -1
  58. package/dist/react/charts/utils.d.ts.map +1 -1
  59. package/dist/react/charts/wrapper.d.ts +2 -2
  60. package/dist/react/charts/wrapper.d.ts.map +1 -1
  61. package/dist/react/charts/wrapper.js.map +1 -1
  62. package/dist/react/genie/genie-chat-input.d.ts +2 -2
  63. package/dist/react/genie/genie-chat-input.d.ts.map +1 -1
  64. package/dist/react/genie/genie-chat-input.js.map +1 -1
  65. package/dist/react/genie/genie-chat-message-list.d.ts +2 -2
  66. package/dist/react/genie/genie-chat-message-list.d.ts.map +1 -1
  67. package/dist/react/genie/genie-chat-message-list.js.map +1 -1
  68. package/dist/react/genie/genie-chat-message.d.ts +2 -2
  69. package/dist/react/genie/genie-chat-message.d.ts.map +1 -1
  70. package/dist/react/genie/genie-chat-message.js.map +1 -1
  71. package/dist/react/genie/genie-chat.d.ts +2 -2
  72. package/dist/react/genie/genie-chat.d.ts.map +1 -1
  73. package/dist/react/genie/genie-chat.js.map +1 -1
  74. package/dist/react/genie/index.d.ts +7 -0
  75. package/dist/react/genie/types.d.ts +1 -0
  76. package/dist/react/genie/types.d.ts.map +1 -1
  77. package/dist/react/genie/use-genie-chat.d.ts +0 -1
  78. package/dist/react/genie/use-genie-chat.d.ts.map +1 -1
  79. package/dist/react/hooks/index.d.ts +3 -0
  80. package/dist/react/hooks/types.d.ts.map +1 -1
  81. package/dist/react/hooks/use-analytics-query.d.ts +0 -1
  82. package/dist/react/hooks/use-analytics-query.d.ts.map +1 -1
  83. package/dist/react/hooks/use-chart-data.d.ts.map +1 -1
  84. package/dist/react/index.d.ts +5 -0
  85. package/dist/react/lib/utils.d.ts.map +1 -1
  86. package/dist/react/portal-container-context.d.ts +0 -1
  87. package/dist/react/portal-container-context.d.ts.map +1 -1
  88. package/dist/react/portal-container-context.js.map +1 -1
  89. package/dist/react/table/data-table.d.ts +2 -3
  90. package/dist/react/table/data-table.d.ts.map +1 -1
  91. package/dist/react/table/data-table.js.map +1 -1
  92. package/dist/react/table/empty.js.map +1 -1
  93. package/dist/react/table/error.js.map +1 -1
  94. package/dist/react/table/index.d.ts +1 -0
  95. package/dist/react/table/loading.js.map +1 -1
  96. package/dist/react/table/table-wrapper.js.map +1 -1
  97. package/dist/react/table/types.d.ts +0 -1
  98. package/dist/react/table/types.d.ts.map +1 -1
  99. package/dist/react/ui/accordion.d.ts +5 -5
  100. package/dist/react/ui/accordion.d.ts.map +1 -1
  101. package/dist/react/ui/accordion.js.map +1 -1
  102. package/dist/react/ui/alert-dialog.d.ts +12 -12
  103. package/dist/react/ui/alert-dialog.d.ts.map +1 -1
  104. package/dist/react/ui/alert-dialog.js.map +1 -1
  105. package/dist/react/ui/alert.d.ts +4 -4
  106. package/dist/react/ui/alert.d.ts.map +1 -1
  107. package/dist/react/ui/alert.js.map +1 -1
  108. package/dist/react/ui/aspect-ratio.d.ts +2 -2
  109. package/dist/react/ui/aspect-ratio.d.ts.map +1 -1
  110. package/dist/react/ui/aspect-ratio.js.map +1 -1
  111. package/dist/react/ui/avatar.d.ts +4 -4
  112. package/dist/react/ui/avatar.d.ts.map +1 -1
  113. package/dist/react/ui/avatar.js.map +1 -1
  114. package/dist/react/ui/badge.d.ts +2 -2
  115. package/dist/react/ui/badge.d.ts.map +1 -1
  116. package/dist/react/ui/badge.js.map +1 -1
  117. package/dist/react/ui/breadcrumb.d.ts +8 -8
  118. package/dist/react/ui/breadcrumb.d.ts.map +1 -1
  119. package/dist/react/ui/breadcrumb.js.map +1 -1
  120. package/dist/react/ui/button-group.d.ts +6 -6
  121. package/dist/react/ui/button-group.d.ts.map +1 -1
  122. package/dist/react/ui/button-group.js.map +1 -1
  123. package/dist/react/ui/button.d.ts +4 -4
  124. package/dist/react/ui/button.d.ts.map +1 -1
  125. package/dist/react/ui/button.js.map +1 -1
  126. package/dist/react/ui/calendar.d.ts +3 -3
  127. package/dist/react/ui/calendar.d.ts.map +1 -1
  128. package/dist/react/ui/calendar.js.map +1 -1
  129. package/dist/react/ui/card.d.ts +8 -8
  130. package/dist/react/ui/card.d.ts.map +1 -1
  131. package/dist/react/ui/card.js.map +1 -1
  132. package/dist/react/ui/carousel.d.ts +6 -6
  133. package/dist/react/ui/carousel.d.ts.map +1 -1
  134. package/dist/react/ui/carousel.js.map +1 -1
  135. package/dist/react/ui/chart.d.ts +19 -19
  136. package/dist/react/ui/chart.d.ts.map +1 -1
  137. package/dist/react/ui/chart.js.map +1 -1
  138. package/dist/react/ui/checkbox.d.ts +2 -2
  139. package/dist/react/ui/checkbox.d.ts.map +1 -1
  140. package/dist/react/ui/checkbox.js.map +1 -1
  141. package/dist/react/ui/collapsible.d.ts +4 -4
  142. package/dist/react/ui/collapsible.d.ts.map +1 -1
  143. package/dist/react/ui/collapsible.js.map +1 -1
  144. package/dist/react/ui/command.d.ts +10 -10
  145. package/dist/react/ui/command.d.ts.map +1 -1
  146. package/dist/react/ui/command.js.map +1 -1
  147. package/dist/react/ui/context-menu.d.ts +16 -16
  148. package/dist/react/ui/context-menu.d.ts.map +1 -1
  149. package/dist/react/ui/context-menu.js.map +1 -1
  150. package/dist/react/ui/dialog.d.ts +11 -11
  151. package/dist/react/ui/dialog.d.ts.map +1 -1
  152. package/dist/react/ui/dialog.js.map +1 -1
  153. package/dist/react/ui/drawer.d.ts +11 -11
  154. package/dist/react/ui/drawer.d.ts.map +1 -1
  155. package/dist/react/ui/drawer.js.map +1 -1
  156. package/dist/react/ui/dropdown-menu.d.ts +16 -16
  157. package/dist/react/ui/dropdown-menu.d.ts.map +1 -1
  158. package/dist/react/ui/dropdown-menu.js.map +1 -1
  159. package/dist/react/ui/empty.d.ts +9 -9
  160. package/dist/react/ui/empty.d.ts.map +1 -1
  161. package/dist/react/ui/empty.js.map +1 -1
  162. package/dist/react/ui/field.d.ts +13 -13
  163. package/dist/react/ui/field.d.ts.map +1 -1
  164. package/dist/react/ui/field.js.map +1 -1
  165. package/dist/react/ui/form.d.ts +9 -9
  166. package/dist/react/ui/form.d.ts.map +1 -1
  167. package/dist/react/ui/form.js.map +1 -1
  168. package/dist/react/ui/hover-card.d.ts +4 -4
  169. package/dist/react/ui/hover-card.d.ts.map +1 -1
  170. package/dist/react/ui/hover-card.js.map +1 -1
  171. package/dist/react/ui/index.d.ts +53 -0
  172. package/dist/react/ui/input-group.d.ts +10 -10
  173. package/dist/react/ui/input-group.d.ts.map +1 -1
  174. package/dist/react/ui/input-group.js.map +1 -1
  175. package/dist/react/ui/input-otp.d.ts +5 -5
  176. package/dist/react/ui/input-otp.d.ts.map +1 -1
  177. package/dist/react/ui/input-otp.js.map +1 -1
  178. package/dist/react/ui/input.d.ts +2 -2
  179. package/dist/react/ui/input.d.ts.map +1 -1
  180. package/dist/react/ui/input.js.map +1 -1
  181. package/dist/react/ui/item.d.ts +14 -14
  182. package/dist/react/ui/item.d.ts.map +1 -1
  183. package/dist/react/ui/item.js.map +1 -1
  184. package/dist/react/ui/kbd.d.ts +3 -3
  185. package/dist/react/ui/kbd.d.ts.map +1 -1
  186. package/dist/react/ui/kbd.js.map +1 -1
  187. package/dist/react/ui/label.d.ts +2 -2
  188. package/dist/react/ui/label.d.ts.map +1 -1
  189. package/dist/react/ui/label.js.map +1 -1
  190. package/dist/react/ui/menubar.d.ts +17 -17
  191. package/dist/react/ui/menubar.d.ts.map +1 -1
  192. package/dist/react/ui/menubar.js.map +1 -1
  193. package/dist/react/ui/navigation-menu.d.ts +11 -11
  194. package/dist/react/ui/navigation-menu.d.ts.map +1 -1
  195. package/dist/react/ui/navigation-menu.js.map +1 -1
  196. package/dist/react/ui/pagination.d.ts +8 -8
  197. package/dist/react/ui/pagination.d.ts.map +1 -1
  198. package/dist/react/ui/pagination.js.map +1 -1
  199. package/dist/react/ui/popover.d.ts +5 -5
  200. package/dist/react/ui/popover.d.ts.map +1 -1
  201. package/dist/react/ui/popover.js.map +1 -1
  202. package/dist/react/ui/progress.d.ts +2 -2
  203. package/dist/react/ui/progress.d.ts.map +1 -1
  204. package/dist/react/ui/progress.js.map +1 -1
  205. package/dist/react/ui/radio-group.d.ts +3 -3
  206. package/dist/react/ui/radio-group.d.ts.map +1 -1
  207. package/dist/react/ui/radio-group.js.map +1 -1
  208. package/dist/react/ui/resizable.d.ts +4 -4
  209. package/dist/react/ui/resizable.d.ts.map +1 -1
  210. package/dist/react/ui/resizable.js.map +1 -1
  211. package/dist/react/ui/scroll-area.d.ts +3 -3
  212. package/dist/react/ui/scroll-area.d.ts.map +1 -1
  213. package/dist/react/ui/scroll-area.js.map +1 -1
  214. package/dist/react/ui/select.d.ts +11 -11
  215. package/dist/react/ui/select.d.ts.map +1 -1
  216. package/dist/react/ui/select.js.map +1 -1
  217. package/dist/react/ui/separator.d.ts +2 -2
  218. package/dist/react/ui/separator.d.ts.map +1 -1
  219. package/dist/react/ui/separator.js.map +1 -1
  220. package/dist/react/ui/sheet.d.ts +9 -9
  221. package/dist/react/ui/sheet.d.ts.map +1 -1
  222. package/dist/react/ui/sheet.js.map +1 -1
  223. package/dist/react/ui/sidebar.d.ts +38 -55
  224. package/dist/react/ui/sidebar.d.ts.map +1 -1
  225. package/dist/react/ui/sidebar.js.map +1 -1
  226. package/dist/react/ui/skeleton.d.ts +2 -2
  227. package/dist/react/ui/skeleton.d.ts.map +1 -1
  228. package/dist/react/ui/skeleton.js.map +1 -1
  229. package/dist/react/ui/slider.d.ts +2 -2
  230. package/dist/react/ui/slider.d.ts.map +1 -1
  231. package/dist/react/ui/slider.js.map +1 -1
  232. package/dist/react/ui/sonner.d.ts +2 -2
  233. package/dist/react/ui/sonner.d.ts.map +1 -1
  234. package/dist/react/ui/sonner.js.map +1 -1
  235. package/dist/react/ui/spinner.d.ts +2 -2
  236. package/dist/react/ui/spinner.d.ts.map +1 -1
  237. package/dist/react/ui/spinner.js.map +1 -1
  238. package/dist/react/ui/switch.d.ts +2 -2
  239. package/dist/react/ui/switch.d.ts.map +1 -1
  240. package/dist/react/ui/switch.js.map +1 -1
  241. package/dist/react/ui/table.d.ts +9 -9
  242. package/dist/react/ui/table.d.ts.map +1 -1
  243. package/dist/react/ui/table.js.map +1 -1
  244. package/dist/react/ui/tabs.d.ts +5 -5
  245. package/dist/react/ui/tabs.d.ts.map +1 -1
  246. package/dist/react/ui/tabs.js.map +1 -1
  247. package/dist/react/ui/textarea.d.ts +2 -2
  248. package/dist/react/ui/textarea.d.ts.map +1 -1
  249. package/dist/react/ui/textarea.js.map +1 -1
  250. package/dist/react/ui/toggle-group.d.ts +3 -3
  251. package/dist/react/ui/toggle-group.d.ts.map +1 -1
  252. package/dist/react/ui/toggle-group.js.map +1 -1
  253. package/dist/react/ui/toggle.d.ts +4 -4
  254. package/dist/react/ui/toggle.d.ts.map +1 -1
  255. package/dist/react/ui/toggle.js.map +1 -1
  256. package/dist/react/ui/tooltip.d.ts.map +1 -1
  257. package/dist/react/ui/tooltip.js.map +1 -1
  258. package/dist/shared/src/cache.d.ts +1 -0
  259. package/dist/shared/src/execute.d.ts +1 -0
  260. package/dist/shared/src/genie.d.ts.map +1 -1
  261. package/dist/shared/src/index.d.ts +7 -0
  262. package/dist/shared/src/plugin.d.ts +2 -0
  263. package/dist/shared/src/sql/helpers.d.ts +0 -1
  264. package/dist/shared/src/sql/helpers.d.ts.map +1 -1
  265. package/dist/shared/src/sql/types.d.ts.map +1 -1
  266. package/dist/shared/src/tunnel.d.ts +1 -0
  267. package/docs/development/project-setup.md +1 -1
  268. package/docs/plugins/plugin-management.md +16 -2
  269. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"wrapper.js","names":[],"sources":["../../../src/react/charts/wrapper.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useChartData } from \"../hooks/use-chart-data\";\nimport { ChartErrorBoundary } from \"./chart-error-boundary\";\nimport { EmptyState } from \"./empty\";\nimport { ErrorState } from \"./error\";\nimport { LoadingSkeleton } from \"./loading\";\nimport type { ChartData, DataFormat } from \"./types\";\nimport { isArrowTable } from \"./types\";\n\n// ============================================================================\n// Props Types\n// ============================================================================\n\ninterface ChartWrapperQueryProps {\n /** Analytics query key */\n queryKey: string;\n /** Query parameters */\n parameters?: Record<string, unknown>;\n /** Data format preference */\n format?: DataFormat;\n /** Transform data after fetching */\n transformer?: <T>(data: T) => T;\n /** Direct data - not used in query mode */\n data?: never;\n}\n\ninterface ChartWrapperDataProps {\n /** Direct data (Arrow Table or JSON array) */\n data: ChartData;\n /** Not used in data mode */\n queryKey?: never;\n parameters?: never;\n format?: never;\n transformer?: never;\n}\n\ninterface CommonProps {\n /** Chart height in pixels */\n height?: number;\n /** Additional CSS classes */\n className?: string;\n /** Accessibility label */\n ariaLabel?: string;\n /** Test ID for automated testing */\n testId?: string;\n /** Render function receiving the chart data */\n children: (data: ChartData) => ReactNode;\n}\n\nexport type ChartWrapperProps = CommonProps &\n (ChartWrapperQueryProps | ChartWrapperDataProps);\n\n// ============================================================================\n// Query Mode Content\n// ============================================================================\n\nfunction QueryModeContent({\n queryKey,\n parameters,\n format,\n transformer,\n height,\n className,\n ariaLabel,\n testId,\n children,\n}: CommonProps & ChartWrapperQueryProps) {\n const { data, loading, error, isEmpty } = useChartData({\n queryKey,\n parameters,\n format,\n transformer,\n });\n\n if (loading) return <LoadingSkeleton height={height ?? 300} />;\n if (error) return <ErrorState error={error} />;\n if (isEmpty || !data) return <EmptyState />;\n\n return (\n <ChartErrorBoundary\n fallback={<ErrorState error=\"Failed to render chart\" />}\n >\n <div\n className={className}\n style={{ height }}\n aria-label={ariaLabel}\n data-testid={testId}\n role=\"img\"\n >\n {children(data)}\n </div>\n </ChartErrorBoundary>\n );\n}\n\n// ============================================================================\n// Data Mode Content\n// ============================================================================\n\nfunction DataModeContent({\n data,\n height,\n className,\n ariaLabel,\n testId,\n children,\n}: CommonProps & ChartWrapperDataProps) {\n const isEmpty = isArrowTable(data)\n ? data.numRows === 0\n : !Array.isArray(data) || data.length === 0;\n\n if (isEmpty) return <EmptyState />;\n\n return (\n <ChartErrorBoundary\n fallback={<ErrorState error=\"Failed to render chart\" />}\n >\n <div\n className={className}\n style={{ height }}\n aria-label={ariaLabel}\n data-testid={testId}\n role=\"img\"\n >\n {children(data)}\n </div>\n </ChartErrorBoundary>\n );\n}\n\n// ============================================================================\n// Main Wrapper Component\n// ============================================================================\n\n/**\n * Wrapper component for charts.\n * Handles data fetching (query mode) or direct data injection (data mode).\n *\n * @example Query mode - fetches data from analytics endpoint\n * ```tsx\n * <ChartWrapper\n * queryKey=\"spend_data\"\n * parameters={{ limit: 100 }}\n * format=\"auto\"\n * >\n * {(data) => <MyChart data={data} />}\n * </ChartWrapper>\n * ```\n *\n * @example Data mode - uses provided data directly\n * ```tsx\n * <ChartWrapper data={myArrowTable}>\n * {(data) => <MyChart data={data} />}\n * </ChartWrapper>\n * ```\n */\nexport function ChartWrapper(props: ChartWrapperProps) {\n const { height = 300, className, ariaLabel, testId, children } = props;\n\n // Data mode: use provided data directly\n if (\"data\" in props && props.data !== undefined) {\n return (\n <DataModeContent\n data={props.data}\n height={height}\n className={className}\n ariaLabel={ariaLabel}\n testId={testId}\n >\n {children}\n </DataModeContent>\n );\n }\n\n // Query mode: fetch data from analytics endpoint\n if (\"queryKey\" in props && props.queryKey !== undefined) {\n return (\n <QueryModeContent\n queryKey={props.queryKey}\n parameters={props.parameters}\n format={props.format}\n transformer={props.transformer}\n height={height}\n className={className}\n ariaLabel={ariaLabel}\n testId={testId}\n >\n {children}\n </QueryModeContent>\n );\n }\n\n // Should never reach here due to TypeScript, but safety fallback\n return <ErrorState error=\"Chart requires either 'queryKey' or 'data' prop\" />;\n}\n"],"mappings":";;;;;;;;;AAwDA,SAAS,iBAAiB,EACxB,UACA,YACA,QACA,aACA,QACA,WACA,WACA,QACA,YACuC;CACvC,MAAM,EAAE,MAAM,SAAS,OAAO,YAAY,aAAa;EACrD;EACA;EACA;EACA;EACD,CAAC;AAEF,KAAI,QAAS,QAAO,oBAAC,iBAAD,EAAiB,QAAQ,UAAU,KAAO;AAC9D,KAAI,MAAO,QAAO,oBAAC,YAAD,EAAmB,OAAS;AAC9C,KAAI,WAAW,CAAC,KAAM,QAAO,oBAAC,YAAD,EAAc;AAE3C,QACE,oBAAC,oBAAD;EACE,UAAU,oBAAC,YAAD,EAAY,OAAM,0BAA2B;YAEvD,oBAAC,OAAD;GACa;GACX,OAAO,EAAE,QAAQ;GACjB,cAAY;GACZ,eAAa;GACb,MAAK;aAEJ,SAAS,KAAK;GACX;EACa;;AAQzB,SAAS,gBAAgB,EACvB,MACA,QACA,WACA,WACA,QACA,YACsC;AAKtC,KAJgB,aAAa,KAAK,GAC9B,KAAK,YAAY,IACjB,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,WAAW,EAE/B,QAAO,oBAAC,YAAD,EAAc;AAElC,QACE,oBAAC,oBAAD;EACE,UAAU,oBAAC,YAAD,EAAY,OAAM,0BAA2B;YAEvD,oBAAC,OAAD;GACa;GACX,OAAO,EAAE,QAAQ;GACjB,cAAY;GACZ,eAAa;GACb,MAAK;aAEJ,SAAS,KAAK;GACX;EACa;;;;;;;;;;;;;;;;;;;;;;;;AA8BzB,SAAgB,aAAa,OAA0B;CACrD,MAAM,EAAE,SAAS,KAAK,WAAW,WAAW,QAAQ,aAAa;AAGjE,KAAI,UAAU,SAAS,MAAM,SAAS,OACpC,QACE,oBAAC,iBAAD;EACE,MAAM,MAAM;EACJ;EACG;EACA;EACH;EAEP;EACe;AAKtB,KAAI,cAAc,SAAS,MAAM,aAAa,OAC5C,QACE,oBAAC,kBAAD;EACE,UAAU,MAAM;EAChB,YAAY,MAAM;EAClB,QAAQ,MAAM;EACd,aAAa,MAAM;EACX;EACG;EACA;EACH;EAEP;EACgB;AAKvB,QAAO,oBAAC,YAAD,EAAY,OAAM,mDAAoD"}
1
+ {"version":3,"file":"wrapper.js","names":[],"sources":["../../../src/react/charts/wrapper.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useChartData } from \"../hooks/use-chart-data\";\nimport { ChartErrorBoundary } from \"./chart-error-boundary\";\nimport { EmptyState } from \"./empty\";\nimport { ErrorState } from \"./error\";\nimport { LoadingSkeleton } from \"./loading\";\nimport type { ChartData, DataFormat } from \"./types\";\nimport { isArrowTable } from \"./types\";\n\n// ============================================================================\n// Props Types\n// ============================================================================\n\ninterface ChartWrapperQueryProps {\n /** Analytics query key */\n queryKey: string;\n /** Query parameters */\n parameters?: Record<string, unknown>;\n /** Data format preference */\n format?: DataFormat;\n /** Transform data after fetching */\n transformer?: <T>(data: T) => T;\n /** Direct data - not used in query mode */\n data?: never;\n}\n\ninterface ChartWrapperDataProps {\n /** Direct data (Arrow Table or JSON array) */\n data: ChartData;\n /** Not used in data mode */\n queryKey?: never;\n parameters?: never;\n format?: never;\n transformer?: never;\n}\n\ninterface CommonProps {\n /** Chart height in pixels */\n height?: number;\n /** Additional CSS classes */\n className?: string;\n /** Accessibility label */\n ariaLabel?: string;\n /** Test ID for automated testing */\n testId?: string;\n /** Render function receiving the chart data */\n children: (data: ChartData) => ReactNode;\n}\n\nexport type ChartWrapperProps = CommonProps &\n (ChartWrapperQueryProps | ChartWrapperDataProps);\n\n// ============================================================================\n// Query Mode Content\n// ============================================================================\n\nfunction QueryModeContent({\n queryKey,\n parameters,\n format,\n transformer,\n height,\n className,\n ariaLabel,\n testId,\n children,\n}: CommonProps & ChartWrapperQueryProps) {\n const { data, loading, error, isEmpty } = useChartData({\n queryKey,\n parameters,\n format,\n transformer,\n });\n\n if (loading) return <LoadingSkeleton height={height ?? 300} />;\n if (error) return <ErrorState error={error} />;\n if (isEmpty || !data) return <EmptyState />;\n\n return (\n <ChartErrorBoundary\n fallback={<ErrorState error=\"Failed to render chart\" />}\n >\n <div\n className={className}\n style={{ height }}\n aria-label={ariaLabel}\n data-testid={testId}\n role=\"img\"\n >\n {children(data)}\n </div>\n </ChartErrorBoundary>\n );\n}\n\n// ============================================================================\n// Data Mode Content\n// ============================================================================\n\nfunction DataModeContent({\n data,\n height,\n className,\n ariaLabel,\n testId,\n children,\n}: CommonProps & ChartWrapperDataProps) {\n const isEmpty = isArrowTable(data)\n ? data.numRows === 0\n : !Array.isArray(data) || data.length === 0;\n\n if (isEmpty) return <EmptyState />;\n\n return (\n <ChartErrorBoundary\n fallback={<ErrorState error=\"Failed to render chart\" />}\n >\n <div\n className={className}\n style={{ height }}\n aria-label={ariaLabel}\n data-testid={testId}\n role=\"img\"\n >\n {children(data)}\n </div>\n </ChartErrorBoundary>\n );\n}\n\n// ============================================================================\n// Main Wrapper Component\n// ============================================================================\n\n/**\n * Wrapper component for charts.\n * Handles data fetching (query mode) or direct data injection (data mode).\n *\n * @example Query mode - fetches data from analytics endpoint\n * ```tsx\n * <ChartWrapper\n * queryKey=\"spend_data\"\n * parameters={{ limit: 100 }}\n * format=\"auto\"\n * >\n * {(data) => <MyChart data={data} />}\n * </ChartWrapper>\n * ```\n *\n * @example Data mode - uses provided data directly\n * ```tsx\n * <ChartWrapper data={myArrowTable}>\n * {(data) => <MyChart data={data} />}\n * </ChartWrapper>\n * ```\n */\nexport function ChartWrapper(props: ChartWrapperProps) {\n const { height = 300, className, ariaLabel, testId, children } = props;\n\n // Data mode: use provided data directly\n if (\"data\" in props && props.data !== undefined) {\n return (\n <DataModeContent\n data={props.data}\n height={height}\n className={className}\n ariaLabel={ariaLabel}\n testId={testId}\n >\n {children}\n </DataModeContent>\n );\n }\n\n // Query mode: fetch data from analytics endpoint\n if (\"queryKey\" in props && props.queryKey !== undefined) {\n return (\n <QueryModeContent\n queryKey={props.queryKey}\n parameters={props.parameters}\n format={props.format}\n transformer={props.transformer}\n height={height}\n className={className}\n ariaLabel={ariaLabel}\n testId={testId}\n >\n {children}\n </QueryModeContent>\n );\n }\n\n // Should never reach here due to TypeScript, but safety fallback\n return <ErrorState error=\"Chart requires either 'queryKey' or 'data' prop\" />;\n}\n"],"mappings":";;;;;;;;;AAwDA,SAAS,iBAAiB,EACxB,UACA,YACA,QACA,aACA,QACA,WACA,WACA,QACA,YACuC;CACvC,MAAM,EAAE,MAAM,SAAS,OAAO,YAAY,aAAa;EACrD;EACA;EACA;EACA;EACD,CAAC;AAEF,KAAI,QAAS,QAAO,oBAAC,mBAAgB,QAAQ,UAAU,MAAO;AAC9D,KAAI,MAAO,QAAO,oBAAC,cAAkB,QAAS;AAC9C,KAAI,WAAW,CAAC,KAAM,QAAO,oBAAC,eAAa;AAE3C,QACE,oBAAC;EACC,UAAU,oBAAC,cAAW,OAAM,2BAA2B;YAEvD,oBAAC;GACY;GACX,OAAO,EAAE,QAAQ;GACjB,cAAY;GACZ,eAAa;GACb,MAAK;aAEJ,SAAS,KAAK;IACX;GACa;;AAQzB,SAAS,gBAAgB,EACvB,MACA,QACA,WACA,WACA,QACA,YACsC;AAKtC,KAJgB,aAAa,KAAK,GAC9B,KAAK,YAAY,IACjB,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,WAAW,EAE/B,QAAO,oBAAC,eAAa;AAElC,QACE,oBAAC;EACC,UAAU,oBAAC,cAAW,OAAM,2BAA2B;YAEvD,oBAAC;GACY;GACX,OAAO,EAAE,QAAQ;GACjB,cAAY;GACZ,eAAa;GACb,MAAK;aAEJ,SAAS,KAAK;IACX;GACa;;;;;;;;;;;;;;;;;;;;;;;;AA8BzB,SAAgB,aAAa,OAA0B;CACrD,MAAM,EAAE,SAAS,KAAK,WAAW,WAAW,QAAQ,aAAa;AAGjE,KAAI,UAAU,SAAS,MAAM,SAAS,OACpC,QACE,oBAAC;EACC,MAAM,MAAM;EACJ;EACG;EACA;EACH;EAEP;GACe;AAKtB,KAAI,cAAc,SAAS,MAAM,aAAa,OAC5C,QACE,oBAAC;EACC,UAAU,MAAM;EAChB,YAAY,MAAM;EAClB,QAAQ,MAAM;EACd,aAAa,MAAM;EACX;EACG;EACA;EACH;EAEP;GACgB;AAKvB,QAAO,oBAAC,cAAW,OAAM,oDAAoD"}
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime287 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/react/genie/genie-chat-input.d.ts
4
4
  interface GenieChatInputProps {
@@ -17,7 +17,7 @@ declare function GenieChatInput({
17
17
  disabled,
18
18
  placeholder,
19
19
  className
20
- }: GenieChatInputProps): react_jsx_runtime287.JSX.Element;
20
+ }: GenieChatInputProps): react_jsx_runtime0.JSX.Element;
21
21
  //#endregion
22
22
  export { GenieChatInput };
23
23
  //# sourceMappingURL=genie-chat-input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"genie-chat-input.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat-input.tsx"],"sourcesContent":[],"mappings":";;;UAIiB,mBAAA;;;EAAA;EAYD,QAAA,CAAA,EAAA,OAAc;EAAA;aAC5B,CAAA,EAAA,MAAA;;WAEA,CAAA,EAAA,MAAA;;;AAEoB,iBALN,cAAA,CAKM;EAAA,MAAA;EAAA,QAAA;EAAA,WAAA;EAAA;AAAA,CAAA,EAAnB,mBAAmB,CAAA,EAAA,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"genie-chat-input.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat-input.tsx"],"mappings":";;;UAIiB,mBAAA;;EAEf,MAAA,GAAS,OAAA;EAFM;EAIf,QAAA;;EAEA,WAAA;EAJA;EAMA,SAAA;AAAA;;iBAIc,cAAA,CAAA;EACd,MAAA;EACA,QAAA;EACA,WAAA;EACA;AAAA,GACC,mBAAA,GAAmB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"genie-chat-input.js","names":[],"sources":["../../../src/react/genie/genie-chat-input.tsx"],"sourcesContent":["import { type KeyboardEvent, useRef, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"../ui/button\";\n\nexport interface GenieChatInputProps {\n /** Callback fired when the user submits a message */\n onSend: (content: string) => void;\n /** Disable the input and send button */\n disabled?: boolean;\n /** Placeholder text shown in the textarea */\n placeholder?: string;\n /** Additional CSS class for the container */\n className?: string;\n}\n\n/** Auto-expanding textarea input with a send button for chat messages. Submits on Enter (Shift+Enter for newline). */\nexport function GenieChatInput({\n onSend,\n disabled = false,\n placeholder = \"Ask a question...\",\n className,\n}: GenieChatInputProps) {\n const [value, setValue] = useState(\"\");\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const handleSubmit = () => {\n const trimmed = value.trim();\n if (!trimmed || disabled) return;\n onSend(trimmed);\n setValue(\"\");\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const MAX_HEIGHT = 200;\n\n const handleInput = () => {\n const textarea = textareaRef.current;\n if (textarea) {\n textarea.style.height = \"auto\";\n const clamped = Math.min(textarea.scrollHeight, MAX_HEIGHT);\n textarea.style.height = `${clamped}px`;\n textarea.style.overflowY =\n textarea.scrollHeight > MAX_HEIGHT ? \"auto\" : \"hidden\";\n }\n };\n\n return (\n <div className={cn(\"flex gap-2 p-4 border-t shrink-0\", className)}>\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onInput={handleInput}\n placeholder={placeholder}\n disabled={disabled}\n rows={1}\n className={cn(\n \"flex-1 resize-none overflow-hidden rounded-md border border-input bg-background px-3 py-2\",\n \"text-sm placeholder:text-muted-foreground\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n )}\n />\n <Button\n onClick={handleSubmit}\n disabled={disabled || !value.trim()}\n size=\"default\"\n className=\"self-end\"\n >\n Send\n </Button>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAgBA,SAAgB,eAAe,EAC7B,QACA,WAAW,OACX,cAAc,qBACd,aACsB;CACtB,MAAM,CAAC,OAAO,YAAY,SAAS,GAAG;CACtC,MAAM,cAAc,OAA4B,KAAK;CAErD,MAAM,qBAAqB;EACzB,MAAM,UAAU,MAAM,MAAM;AAC5B,MAAI,CAAC,WAAW,SAAU;AAC1B,SAAO,QAAQ;AACf,WAAS,GAAG;AACZ,MAAI,YAAY,QACd,aAAY,QAAQ,MAAM,SAAS;;CAIvC,MAAM,iBAAiB,MAA0C;AAC/D,MAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;AACpC,KAAE,gBAAgB;AAClB,iBAAc;;;CAIlB,MAAM,aAAa;CAEnB,MAAM,oBAAoB;EACxB,MAAM,WAAW,YAAY;AAC7B,MAAI,UAAU;AACZ,YAAS,MAAM,SAAS;GACxB,MAAM,UAAU,KAAK,IAAI,SAAS,cAAc,WAAW;AAC3D,YAAS,MAAM,SAAS,GAAG,QAAQ;AACnC,YAAS,MAAM,YACb,SAAS,eAAe,aAAa,SAAS;;;AAIpD,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,oCAAoC,UAAU;YAAjE,CACE,oBAAC,YAAD;GACE,KAAK;GACE;GACP,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;GACzC,WAAW;GACX,SAAS;GACI;GACH;GACV,MAAM;GACN,WAAW,GACT,6FACA,6CACA,2EACA,kDACD;GACD,GACF,oBAAC,QAAD;GACE,SAAS;GACT,UAAU,YAAY,CAAC,MAAM,MAAM;GACnC,MAAK;GACL,WAAU;aACX;GAEQ,EACL"}
1
+ {"version":3,"file":"genie-chat-input.js","names":[],"sources":["../../../src/react/genie/genie-chat-input.tsx"],"sourcesContent":["import { type KeyboardEvent, useRef, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"../ui/button\";\n\nexport interface GenieChatInputProps {\n /** Callback fired when the user submits a message */\n onSend: (content: string) => void;\n /** Disable the input and send button */\n disabled?: boolean;\n /** Placeholder text shown in the textarea */\n placeholder?: string;\n /** Additional CSS class for the container */\n className?: string;\n}\n\n/** Auto-expanding textarea input with a send button for chat messages. Submits on Enter (Shift+Enter for newline). */\nexport function GenieChatInput({\n onSend,\n disabled = false,\n placeholder = \"Ask a question...\",\n className,\n}: GenieChatInputProps) {\n const [value, setValue] = useState(\"\");\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const handleSubmit = () => {\n const trimmed = value.trim();\n if (!trimmed || disabled) return;\n onSend(trimmed);\n setValue(\"\");\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const MAX_HEIGHT = 200;\n\n const handleInput = () => {\n const textarea = textareaRef.current;\n if (textarea) {\n textarea.style.height = \"auto\";\n const clamped = Math.min(textarea.scrollHeight, MAX_HEIGHT);\n textarea.style.height = `${clamped}px`;\n textarea.style.overflowY =\n textarea.scrollHeight > MAX_HEIGHT ? \"auto\" : \"hidden\";\n }\n };\n\n return (\n <div className={cn(\"flex gap-2 p-4 border-t shrink-0\", className)}>\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onInput={handleInput}\n placeholder={placeholder}\n disabled={disabled}\n rows={1}\n className={cn(\n \"flex-1 resize-none overflow-hidden rounded-md border border-input bg-background px-3 py-2\",\n \"text-sm placeholder:text-muted-foreground\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n )}\n />\n <Button\n onClick={handleSubmit}\n disabled={disabled || !value.trim()}\n size=\"default\"\n className=\"self-end\"\n >\n Send\n </Button>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAgBA,SAAgB,eAAe,EAC7B,QACA,WAAW,OACX,cAAc,qBACd,aACsB;CACtB,MAAM,CAAC,OAAO,YAAY,SAAS,GAAG;CACtC,MAAM,cAAc,OAA4B,KAAK;CAErD,MAAM,qBAAqB;EACzB,MAAM,UAAU,MAAM,MAAM;AAC5B,MAAI,CAAC,WAAW,SAAU;AAC1B,SAAO,QAAQ;AACf,WAAS,GAAG;AACZ,MAAI,YAAY,QACd,aAAY,QAAQ,MAAM,SAAS;;CAIvC,MAAM,iBAAiB,MAA0C;AAC/D,MAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;AACpC,KAAE,gBAAgB;AAClB,iBAAc;;;CAIlB,MAAM,aAAa;CAEnB,MAAM,oBAAoB;EACxB,MAAM,WAAW,YAAY;AAC7B,MAAI,UAAU;AACZ,YAAS,MAAM,SAAS;GACxB,MAAM,UAAU,KAAK,IAAI,SAAS,cAAc,WAAW;AAC3D,YAAS,MAAM,SAAS,GAAG,QAAQ;AACnC,YAAS,MAAM,YACb,SAAS,eAAe,aAAa,SAAS;;;AAIpD,QACE,qBAAC;EAAI,WAAW,GAAG,oCAAoC,UAAU;aAC/D,oBAAC;GACC,KAAK;GACE;GACP,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;GACzC,WAAW;GACX,SAAS;GACI;GACH;GACV,MAAM;GACN,WAAW,GACT,6FACA,6CACA,2EACA,kDACD;IACD,EACF,oBAAC;GACC,SAAS;GACT,UAAU,YAAY,CAAC,MAAM,MAAM;GACnC,MAAK;GACL,WAAU;aACX;IAEQ;GACL"}
@@ -1,5 +1,5 @@
1
1
  import { GenieChatStatus, GenieMessageItem } from "./types.js";
2
- import * as react_jsx_runtime289 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/genie/genie-chat-message-list.d.ts
5
5
  interface GenieChatMessageListProps {
@@ -15,7 +15,7 @@ declare function GenieChatMessageList({
15
15
  messages,
16
16
  status,
17
17
  className
18
- }: GenieChatMessageListProps): react_jsx_runtime289.JSX.Element;
18
+ }: GenieChatMessageListProps): react_jsx_runtime0.JSX.Element;
19
19
  //#endregion
20
20
  export { GenieChatMessageList };
21
21
  //# sourceMappingURL=genie-chat-message-list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"genie-chat-message-list.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat-message-list.tsx"],"sourcesContent":[],"mappings":";;;;UAQiB,yBAAA;;YAEL;EAFK;EAAyB,MAAA,EAIhC,eAJgC;;WAIhC,CAAA,EAAA,MAAA;;AA8BV;AAAoC,iBAApB,oBAAA,CAAoB;EAAA,QAAA;EAAA,MAAA;EAAA;AAAA,CAAA,EAIjC,yBAJiC,CAAA,EAIR,oBAAA,CAAA,GAAA,CAAA,OAJQ"}
1
+ {"version":3,"file":"genie-chat-message-list.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat-message-list.tsx"],"mappings":";;;;UAQiB,yBAAA;;EAEf,QAAA,EAAU,gBAAA;EAFK;EAIf,MAAA,EAAQ,eAAA;;EAER,SAAA;AAAA;;iBA4Bc,oBAAA,CAAA;EACd,QAAA;EACA,MAAA;EACA;AAAA,GACC,yBAAA,GAAyB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"genie-chat-message-list.js","names":[],"sources":["../../../src/react/genie/genie-chat-message-list.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { ScrollArea } from \"../ui/scroll-area\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport { Spinner } from \"../ui/spinner\";\nimport { GenieChatMessage } from \"./genie-chat-message\";\nimport type { GenieChatStatus, GenieMessageItem } from \"./types\";\n\nexport interface GenieChatMessageListProps {\n /** Array of messages to display */\n messages: GenieMessageItem[];\n /** Current chat status (controls loading indicators and skeleton placeholders) */\n status: GenieChatStatus;\n /** Additional CSS class for the scroll area */\n className?: string;\n}\n\nconst STATUS_LABELS: Record<string, string> = {\n ASKING_AI: \"Asking AI...\",\n EXECUTING_QUERY: \"Executing query...\",\n FILTERING_RESULTS: \"Filtering results...\",\n COMPLETED: \"Done\",\n};\n\nfunction formatStatus(status: string): string {\n return STATUS_LABELS[status] ?? status.replace(/_/g, \" \").toLowerCase();\n}\n\nfunction StreamingIndicator({ messages }: { messages: GenieMessageItem[] }) {\n const last = messages[messages.length - 1];\n if (last?.role === \"assistant\" && last.id === \"\") {\n return (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground px-11\">\n <Spinner className=\"h-3 w-3\" />\n <span>{formatStatus(last.status)}</span>\n </div>\n );\n }\n return null;\n}\n\n/** Scrollable message list that renders Genie chat messages with auto-scroll, skeleton loaders, and a streaming indicator. */\nexport function GenieChatMessageList({\n messages,\n status,\n className,\n}: GenieChatMessageListProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n\n // Scroll only the ScrollArea viewport, not the page\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional triggers for auto-scroll\n useEffect(() => {\n const viewport = scrollRef.current?.querySelector<HTMLElement>(\n '[data-slot=\"scroll-area-viewport\"]',\n );\n if (viewport) {\n viewport.scrollTop = viewport.scrollHeight;\n }\n }, [messages.length, status]);\n\n return (\n <ScrollArea ref={scrollRef} className={cn(\"flex-1 min-h-0 p-4\", className)}>\n <div className=\"flex flex-col gap-4\">\n {status === \"loading-history\" && messages.length === 0 && (\n <div className=\"flex flex-col gap-4\">\n <Skeleton className=\"h-12 w-3/4\" />\n <Skeleton className=\"h-20 w-4/5 self-start\" />\n <Skeleton className=\"h-12 w-2/3 self-end\" />\n </div>\n )}\n\n {messages.map((msg) => {\n if (msg.role === \"assistant\" && msg.id === \"\" && !msg.content) {\n return null;\n }\n return <GenieChatMessage key={msg.id} message={msg} />;\n })}\n\n {status === \"streaming\" && messages.length > 0 && (\n <StreamingIndicator messages={messages} />\n )}\n\n {messages.length === 0 && status === \"idle\" && (\n <div className=\"flex items-center justify-center h-full text-muted-foreground text-sm py-12\">\n Start a conversation by typing a question below.\n </div>\n )}\n </div>\n </ScrollArea>\n );\n}\n"],"mappings":";;;;;;;;;AAiBA,MAAM,gBAAwC;CAC5C,WAAW;CACX,iBAAiB;CACjB,mBAAmB;CACnB,WAAW;CACZ;AAED,SAAS,aAAa,QAAwB;AAC5C,QAAO,cAAc,WAAW,OAAO,QAAQ,MAAM,IAAI,CAAC,aAAa;;AAGzE,SAAS,mBAAmB,EAAE,YAA8C;CAC1E,MAAM,OAAO,SAAS,SAAS,SAAS;AACxC,KAAI,MAAM,SAAS,eAAe,KAAK,OAAO,GAC5C,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,SAAD,EAAS,WAAU,WAAY,GAC/B,oBAAC,QAAD,YAAO,aAAa,KAAK,OAAO,EAAQ,EACpC;;AAGV,QAAO;;;AAIT,SAAgB,qBAAqB,EACnC,UACA,QACA,aAC4B;CAC5B,MAAM,YAAY,OAAuB,KAAK;AAI9C,iBAAgB;EACd,MAAM,WAAW,UAAU,SAAS,cAClC,uCACD;AACD,MAAI,SACF,UAAS,YAAY,SAAS;IAE/B,CAAC,SAAS,QAAQ,OAAO,CAAC;AAE7B,QACE,oBAAC,YAAD;EAAY,KAAK;EAAW,WAAW,GAAG,sBAAsB,UAAU;YACxE,qBAAC,OAAD;GAAK,WAAU;aAAf;IACG,WAAW,qBAAqB,SAAS,WAAW,KACnD,qBAAC,OAAD;KAAK,WAAU;eAAf;MACE,oBAAC,UAAD,EAAU,WAAU,cAAe;MACnC,oBAAC,UAAD,EAAU,WAAU,yBAA0B;MAC9C,oBAAC,UAAD,EAAU,WAAU,uBAAwB;MACxC;;IAGP,SAAS,KAAK,QAAQ;AACrB,SAAI,IAAI,SAAS,eAAe,IAAI,OAAO,MAAM,CAAC,IAAI,QACpD,QAAO;AAET,YAAO,oBAAC,kBAAD,EAA+B,SAAS,KAAO,EAAxB,IAAI,GAAoB;MACtD;IAED,WAAW,eAAe,SAAS,SAAS,KAC3C,oBAAC,oBAAD,EAA8B,UAAY;IAG3C,SAAS,WAAW,KAAK,WAAW,UACnC,oBAAC,OAAD;KAAK,WAAU;eAA8E;KAEvF;IAEJ;;EACK"}
1
+ {"version":3,"file":"genie-chat-message-list.js","names":[],"sources":["../../../src/react/genie/genie-chat-message-list.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { ScrollArea } from \"../ui/scroll-area\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport { Spinner } from \"../ui/spinner\";\nimport { GenieChatMessage } from \"./genie-chat-message\";\nimport type { GenieChatStatus, GenieMessageItem } from \"./types\";\n\nexport interface GenieChatMessageListProps {\n /** Array of messages to display */\n messages: GenieMessageItem[];\n /** Current chat status (controls loading indicators and skeleton placeholders) */\n status: GenieChatStatus;\n /** Additional CSS class for the scroll area */\n className?: string;\n}\n\nconst STATUS_LABELS: Record<string, string> = {\n ASKING_AI: \"Asking AI...\",\n EXECUTING_QUERY: \"Executing query...\",\n FILTERING_RESULTS: \"Filtering results...\",\n COMPLETED: \"Done\",\n};\n\nfunction formatStatus(status: string): string {\n return STATUS_LABELS[status] ?? status.replace(/_/g, \" \").toLowerCase();\n}\n\nfunction StreamingIndicator({ messages }: { messages: GenieMessageItem[] }) {\n const last = messages[messages.length - 1];\n if (last?.role === \"assistant\" && last.id === \"\") {\n return (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground px-11\">\n <Spinner className=\"h-3 w-3\" />\n <span>{formatStatus(last.status)}</span>\n </div>\n );\n }\n return null;\n}\n\n/** Scrollable message list that renders Genie chat messages with auto-scroll, skeleton loaders, and a streaming indicator. */\nexport function GenieChatMessageList({\n messages,\n status,\n className,\n}: GenieChatMessageListProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n\n // Scroll only the ScrollArea viewport, not the page\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentional triggers for auto-scroll\n useEffect(() => {\n const viewport = scrollRef.current?.querySelector<HTMLElement>(\n '[data-slot=\"scroll-area-viewport\"]',\n );\n if (viewport) {\n viewport.scrollTop = viewport.scrollHeight;\n }\n }, [messages.length, status]);\n\n return (\n <ScrollArea ref={scrollRef} className={cn(\"flex-1 min-h-0 p-4\", className)}>\n <div className=\"flex flex-col gap-4\">\n {status === \"loading-history\" && messages.length === 0 && (\n <div className=\"flex flex-col gap-4\">\n <Skeleton className=\"h-12 w-3/4\" />\n <Skeleton className=\"h-20 w-4/5 self-start\" />\n <Skeleton className=\"h-12 w-2/3 self-end\" />\n </div>\n )}\n\n {messages.map((msg) => {\n if (msg.role === \"assistant\" && msg.id === \"\" && !msg.content) {\n return null;\n }\n return <GenieChatMessage key={msg.id} message={msg} />;\n })}\n\n {status === \"streaming\" && messages.length > 0 && (\n <StreamingIndicator messages={messages} />\n )}\n\n {messages.length === 0 && status === \"idle\" && (\n <div className=\"flex items-center justify-center h-full text-muted-foreground text-sm py-12\">\n Start a conversation by typing a question below.\n </div>\n )}\n </div>\n </ScrollArea>\n );\n}\n"],"mappings":";;;;;;;;;AAiBA,MAAM,gBAAwC;CAC5C,WAAW;CACX,iBAAiB;CACjB,mBAAmB;CACnB,WAAW;CACZ;AAED,SAAS,aAAa,QAAwB;AAC5C,QAAO,cAAc,WAAW,OAAO,QAAQ,MAAM,IAAI,CAAC,aAAa;;AAGzE,SAAS,mBAAmB,EAAE,YAA8C;CAC1E,MAAM,OAAO,SAAS,SAAS,SAAS;AACxC,KAAI,MAAM,SAAS,eAAe,KAAK,OAAO,GAC5C,QACE,qBAAC;EAAI,WAAU;aACb,oBAAC,WAAQ,WAAU,YAAY,EAC/B,oBAAC,oBAAM,aAAa,KAAK,OAAO,GAAQ;GACpC;AAGV,QAAO;;;AAIT,SAAgB,qBAAqB,EACnC,UACA,QACA,aAC4B;CAC5B,MAAM,YAAY,OAAuB,KAAK;AAI9C,iBAAgB;EACd,MAAM,WAAW,UAAU,SAAS,cAClC,uCACD;AACD,MAAI,SACF,UAAS,YAAY,SAAS;IAE/B,CAAC,SAAS,QAAQ,OAAO,CAAC;AAE7B,QACE,oBAAC;EAAW,KAAK;EAAW,WAAW,GAAG,sBAAsB,UAAU;YACxE,qBAAC;GAAI,WAAU;;IACZ,WAAW,qBAAqB,SAAS,WAAW,KACnD,qBAAC;KAAI,WAAU;;MACb,oBAAC,YAAS,WAAU,eAAe;MACnC,oBAAC,YAAS,WAAU,0BAA0B;MAC9C,oBAAC,YAAS,WAAU,wBAAwB;;MACxC;IAGP,SAAS,KAAK,QAAQ;AACrB,SAAI,IAAI,SAAS,eAAe,IAAI,OAAO,MAAM,CAAC,IAAI,QACpD,QAAO;AAET,YAAO,oBAAC,oBAA8B,SAAS,OAAjB,IAAI,GAAoB;MACtD;IAED,WAAW,eAAe,SAAS,SAAS,KAC3C,oBAAC,sBAA6B,WAAY;IAG3C,SAAS,WAAW,KAAK,WAAW,UACnC,oBAAC;KAAI,WAAU;eAA8E;MAEvF;;IAEJ;GACK"}
@@ -1,5 +1,5 @@
1
1
  import { GenieMessageItem } from "./types.js";
2
- import * as react_jsx_runtime288 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/genie/genie-chat-message.d.ts
5
5
  interface GenieChatMessageProps {
@@ -12,7 +12,7 @@ interface GenieChatMessageProps {
12
12
  declare function GenieChatMessage({
13
13
  message,
14
14
  className
15
- }: GenieChatMessageProps): react_jsx_runtime288.JSX.Element;
15
+ }: GenieChatMessageProps): react_jsx_runtime0.JSX.Element;
16
16
  //#endregion
17
17
  export { GenieChatMessage };
18
18
  //# sourceMappingURL=genie-chat-message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"genie-chat-message.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"sourcesContent":[],"mappings":";;;;UAyBiB,qBAAA;;WAEN;EAFM;EAYD,SAAA,CAAA,EAAA,MAAA;;;AAEd,iBAFc,gBAAA,CAEd;EAAA,OAAA;EAAA;AAAA,CAAA,EACC,qBADD,CAAA,EACsB,oBAAA,CAAA,GAAA,CAAA,OADtB"}
1
+ {"version":3,"file":"genie-chat-message.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"mappings":";;;;UAyBiB,qBAAA;;EAEf,OAAA,EAAS,gBAAA;EAFM;EAIf,SAAA;AAAA;;iBAQc,gBAAA,CAAA;EACd,OAAA;EACA;AAAA,GACC,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"genie-chat-message.js","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"sourcesContent":["import { marked } from \"marked\";\nimport { useMemo } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Avatar, AvatarFallback } from \"../ui/avatar\";\nimport { Card } from \"../ui/card\";\nimport type { GenieAttachmentResponse, GenieMessageItem } from \"./types\";\n\n/**\n * Using `marked` instead of `react-markdown` because `react-markdown` depends on\n * `micromark-util-symbol` which has broken ESM exports with `rolldown-vite`.\n * Content comes from our own Genie API so `dangerouslySetInnerHTML` is safe.\n */\nmarked.setOptions({ breaks: true, gfm: true });\n\nconst markdownStyles = cn(\n \"text-sm\",\n \"[&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1 [&_li]:my-0\",\n \"[&_pre]:bg-background/50 [&_pre]:p-2 [&_pre]:rounded [&_pre]:text-xs [&_pre]:overflow-x-auto\",\n \"[&_code]:text-xs [&_code]:bg-background/50 [&_code]:px-1 [&_code]:rounded\",\n \"[&_table]:text-xs [&_th]:px-2 [&_th]:py-1 [&_td]:px-2 [&_td]:py-1\",\n \"[&_table]:border-collapse [&_th]:border [&_td]:border\",\n \"[&_th]:border-border [&_td]:border-border\",\n \"[&_a]:underline\",\n);\n\nexport interface GenieChatMessageProps {\n /** The message object to render */\n message: GenieMessageItem;\n /** Additional CSS class */\n className?: string;\n}\n\nfunction isQueryAttachment(att: GenieAttachmentResponse): boolean {\n return !!(att.query?.title || att.query?.query);\n}\n\n/** Renders a single Genie message bubble with optional expandable SQL query attachments. */\nexport function GenieChatMessage({\n message,\n className,\n}: GenieChatMessageProps) {\n const isUser = message.role === \"user\";\n const queryAttachments = message.attachments.filter(isQueryAttachment);\n const html = useMemo(\n () => (message.content ? (marked.parse(message.content) as string) : \"\"),\n [message.content],\n );\n\n return (\n <div\n className={cn(\n \"flex gap-3\",\n isUser ? \"flex-row-reverse\" : \"flex-row\",\n className,\n )}\n >\n <Avatar className=\"h-8 w-8 shrink-0 mt-1\">\n <AvatarFallback\n className={cn(\n \"text-xs font-medium\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {isUser ? \"You\" : \"AI\"}\n </AvatarFallback>\n </Avatar>\n\n <div\n className={cn(\n \"flex flex-col gap-2 max-w-[80%] min-w-0 overflow-hidden\",\n isUser ? \"items-end\" : \"items-start\",\n )}\n >\n <Card\n className={cn(\n \"px-4 py-3 max-w-full overflow-hidden\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {html && (\n <div\n className={markdownStyles}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n )}\n\n {message.error && (\n <p className=\"text-sm text-destructive mt-1\">{message.error}</p>\n )}\n </Card>\n\n {queryAttachments.length > 0 && (\n <div className=\"flex flex-col gap-2 w-full min-w-0\">\n {queryAttachments.map((att) => (\n <Card\n key={att.attachmentId ?? \"query\"}\n className=\"px-4 py-3 text-xs overflow-hidden shadow-none\"\n >\n <details>\n <summary className=\"cursor-pointer select-none font-medium\">\n {att.query?.title ?? \"SQL Query\"}\n </summary>\n <div className=\"mt-2 flex flex-col gap-1\">\n {att.query?.description && (\n <span className=\"text-muted-foreground\">\n {att.query.description}\n </span>\n )}\n {att.query?.query && (\n <pre className=\"mt-1 p-2 rounded bg-background text-[11px] whitespace-pre-wrap break-all\">\n {att.query.query}\n </pre>\n )}\n </div>\n </details>\n </Card>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,OAAO,WAAW;CAAE,QAAQ;CAAM,KAAK;CAAM,CAAC;AAE9C,MAAM,iBAAiB,GACrB,WACA,kDACA,gGACA,6EACA,qEACA,yDACA,6CACA,kBACD;AASD,SAAS,kBAAkB,KAAuC;AAChE,QAAO,CAAC,EAAE,IAAI,OAAO,SAAS,IAAI,OAAO;;;AAI3C,SAAgB,iBAAiB,EAC/B,SACA,aACwB;CACxB,MAAM,SAAS,QAAQ,SAAS;CAChC,MAAM,mBAAmB,QAAQ,YAAY,OAAO,kBAAkB;CACtE,MAAM,OAAO,cACJ,QAAQ,UAAW,OAAO,MAAM,QAAQ,QAAQ,GAAc,IACrE,CAAC,QAAQ,QAAQ,CAClB;AAED,QACE,qBAAC,OAAD;EACE,WAAW,GACT,cACA,SAAS,qBAAqB,YAC9B,UACD;YALH,CAOE,oBAAC,QAAD;GAAQ,WAAU;aAChB,oBAAC,gBAAD;IACE,WAAW,GACT,uBACA,SAAS,uCAAuC,WACjD;cAEA,SAAS,QAAQ;IACH;GACV,GAET,qBAAC,OAAD;GACE,WAAW,GACT,2DACA,SAAS,cAAc,cACxB;aAJH,CAME,qBAAC,MAAD;IACE,WAAW,GACT,wCACA,SAAS,uCAAuC,WACjD;cAJH,CAMG,QACC,oBAAC,OAAD;KACE,WAAW;KACX,yBAAyB,EAAE,QAAQ,MAAM;KACzC,GAGH,QAAQ,SACP,oBAAC,KAAD;KAAG,WAAU;eAAiC,QAAQ;KAAU,EAE7D;OAEN,iBAAiB,SAAS,KACzB,oBAAC,OAAD;IAAK,WAAU;cACZ,iBAAiB,KAAK,QACrB,oBAAC,MAAD;KAEE,WAAU;eAEV,qBAAC,WAAD,aACE,oBAAC,WAAD;MAAS,WAAU;gBAChB,IAAI,OAAO,SAAS;MACb,GACV,qBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,IAAI,OAAO,eACV,oBAAC,QAAD;OAAM,WAAU;iBACb,IAAI,MAAM;OACN,GAER,IAAI,OAAO,SACV,oBAAC,OAAD;OAAK,WAAU;iBACZ,IAAI,MAAM;OACP,EAEJ;QACE;KACL,EApBA,IAAI,gBAAgB,QAoBpB,CACP;IACE,EAEJ;KACF"}
1
+ {"version":3,"file":"genie-chat-message.js","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"sourcesContent":["import { marked } from \"marked\";\nimport { useMemo } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Avatar, AvatarFallback } from \"../ui/avatar\";\nimport { Card } from \"../ui/card\";\nimport type { GenieAttachmentResponse, GenieMessageItem } from \"./types\";\n\n/**\n * Using `marked` instead of `react-markdown` because `react-markdown` depends on\n * `micromark-util-symbol` which has broken ESM exports with `rolldown-vite`.\n * Content comes from our own Genie API so `dangerouslySetInnerHTML` is safe.\n */\nmarked.setOptions({ breaks: true, gfm: true });\n\nconst markdownStyles = cn(\n \"text-sm\",\n \"[&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1 [&_li]:my-0\",\n \"[&_pre]:bg-background/50 [&_pre]:p-2 [&_pre]:rounded [&_pre]:text-xs [&_pre]:overflow-x-auto\",\n \"[&_code]:text-xs [&_code]:bg-background/50 [&_code]:px-1 [&_code]:rounded\",\n \"[&_table]:text-xs [&_th]:px-2 [&_th]:py-1 [&_td]:px-2 [&_td]:py-1\",\n \"[&_table]:border-collapse [&_th]:border [&_td]:border\",\n \"[&_th]:border-border [&_td]:border-border\",\n \"[&_a]:underline\",\n);\n\nexport interface GenieChatMessageProps {\n /** The message object to render */\n message: GenieMessageItem;\n /** Additional CSS class */\n className?: string;\n}\n\nfunction isQueryAttachment(att: GenieAttachmentResponse): boolean {\n return !!(att.query?.title || att.query?.query);\n}\n\n/** Renders a single Genie message bubble with optional expandable SQL query attachments. */\nexport function GenieChatMessage({\n message,\n className,\n}: GenieChatMessageProps) {\n const isUser = message.role === \"user\";\n const queryAttachments = message.attachments.filter(isQueryAttachment);\n const html = useMemo(\n () => (message.content ? (marked.parse(message.content) as string) : \"\"),\n [message.content],\n );\n\n return (\n <div\n className={cn(\n \"flex gap-3\",\n isUser ? \"flex-row-reverse\" : \"flex-row\",\n className,\n )}\n >\n <Avatar className=\"h-8 w-8 shrink-0 mt-1\">\n <AvatarFallback\n className={cn(\n \"text-xs font-medium\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {isUser ? \"You\" : \"AI\"}\n </AvatarFallback>\n </Avatar>\n\n <div\n className={cn(\n \"flex flex-col gap-2 max-w-[80%] min-w-0 overflow-hidden\",\n isUser ? \"items-end\" : \"items-start\",\n )}\n >\n <Card\n className={cn(\n \"px-4 py-3 max-w-full overflow-hidden\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {html && (\n <div\n className={markdownStyles}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n )}\n\n {message.error && (\n <p className=\"text-sm text-destructive mt-1\">{message.error}</p>\n )}\n </Card>\n\n {queryAttachments.length > 0 && (\n <div className=\"flex flex-col gap-2 w-full min-w-0\">\n {queryAttachments.map((att) => (\n <Card\n key={att.attachmentId ?? \"query\"}\n className=\"px-4 py-3 text-xs overflow-hidden shadow-none\"\n >\n <details>\n <summary className=\"cursor-pointer select-none font-medium\">\n {att.query?.title ?? \"SQL Query\"}\n </summary>\n <div className=\"mt-2 flex flex-col gap-1\">\n {att.query?.description && (\n <span className=\"text-muted-foreground\">\n {att.query.description}\n </span>\n )}\n {att.query?.query && (\n <pre className=\"mt-1 p-2 rounded bg-background text-[11px] whitespace-pre-wrap break-all\">\n {att.query.query}\n </pre>\n )}\n </div>\n </details>\n </Card>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,OAAO,WAAW;CAAE,QAAQ;CAAM,KAAK;CAAM,CAAC;AAE9C,MAAM,iBAAiB,GACrB,WACA,kDACA,gGACA,6EACA,qEACA,yDACA,6CACA,kBACD;AASD,SAAS,kBAAkB,KAAuC;AAChE,QAAO,CAAC,EAAE,IAAI,OAAO,SAAS,IAAI,OAAO;;;AAI3C,SAAgB,iBAAiB,EAC/B,SACA,aACwB;CACxB,MAAM,SAAS,QAAQ,SAAS;CAChC,MAAM,mBAAmB,QAAQ,YAAY,OAAO,kBAAkB;CACtE,MAAM,OAAO,cACJ,QAAQ,UAAW,OAAO,MAAM,QAAQ,QAAQ,GAAc,IACrE,CAAC,QAAQ,QAAQ,CAClB;AAED,QACE,qBAAC;EACC,WAAW,GACT,cACA,SAAS,qBAAqB,YAC9B,UACD;aAED,oBAAC;GAAO,WAAU;aAChB,oBAAC;IACC,WAAW,GACT,uBACA,SAAS,uCAAuC,WACjD;cAEA,SAAS,QAAQ;KACH;IACV,EAET,qBAAC;GACC,WAAW,GACT,2DACA,SAAS,cAAc,cACxB;cAED,qBAAC;IACC,WAAW,GACT,wCACA,SAAS,uCAAuC,WACjD;eAEA,QACC,oBAAC;KACC,WAAW;KACX,yBAAyB,EAAE,QAAQ,MAAM;MACzC,EAGH,QAAQ,SACP,oBAAC;KAAE,WAAU;eAAiC,QAAQ;MAAU;KAE7D,EAEN,iBAAiB,SAAS,KACzB,oBAAC;IAAI,WAAU;cACZ,iBAAiB,KAAK,QACrB,oBAAC;KAEC,WAAU;eAEV,qBAAC,wBACC,oBAAC;MAAQ,WAAU;gBAChB,IAAI,OAAO,SAAS;OACb,EACV,qBAAC;MAAI,WAAU;iBACZ,IAAI,OAAO,eACV,oBAAC;OAAK,WAAU;iBACb,IAAI,MAAM;QACN,EAER,IAAI,OAAO,SACV,oBAAC;OAAI,WAAU;iBACZ,IAAI,MAAM;QACP;OAEJ,IACE;OAnBL,IAAI,gBAAgB,QAoBpB,CACP;KACE;IAEJ;GACF"}
@@ -1,5 +1,5 @@
1
1
  import { GenieChatProps } from "./types.js";
2
- import * as react_jsx_runtime286 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/genie/genie-chat.d.ts
5
5
  /** Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE. */
@@ -8,7 +8,7 @@ declare function GenieChat({
8
8
  basePath,
9
9
  placeholder,
10
10
  className
11
- }: GenieChatProps): react_jsx_runtime286.JSX.Element;
11
+ }: GenieChatProps): react_jsx_runtime0.JSX.Element;
12
12
  //#endregion
13
13
  export { GenieChat };
14
14
  //# sourceMappingURL=genie-chat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"genie-chat.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat.tsx"],"sourcesContent":[],"mappings":";;;;;iBAQgB,SAAA;;;;;GAKb,iBAAc,oBAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"genie-chat.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat.tsx"],"mappings":";;;;;iBAQgB,SAAA,CAAA;EACd,KAAA;EACA,QAAA;EACA,WAAA;EACA;AAAA,GACC,cAAA,GAAc,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"genie-chat.js","names":[],"sources":["../../../src/react/genie/genie-chat.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { GenieChatInput } from \"./genie-chat-input\";\nimport { GenieChatMessageList } from \"./genie-chat-message-list\";\nimport type { GenieChatProps } from \"./types\";\nimport { useGenieChat } from \"./use-genie-chat\";\n\n/** Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE. */\nexport function GenieChat({\n alias,\n basePath,\n placeholder,\n className,\n}: GenieChatProps) {\n const { messages, status, error, sendMessage, reset } = useGenieChat({\n alias,\n basePath,\n });\n\n return (\n <div className={cn(\"flex flex-col h-full overflow-hidden\", className)}>\n {messages.length > 0 && (\n <div className=\"shrink-0 flex justify-end px-4 pt-3 pb-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={reset}\n className=\"text-xs text-muted-foreground\"\n >\n New conversation\n </Button>\n </div>\n )}\n\n <GenieChatMessageList messages={messages} status={status} />\n\n {error && (\n <div className=\"shrink-0 px-4 py-2 text-sm text-destructive bg-destructive/10 border-t\">\n {error}\n </div>\n )}\n\n <GenieChatInput\n onSend={sendMessage}\n disabled={status === \"streaming\" || status === \"loading-history\"}\n placeholder={placeholder}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,UAAU,EACxB,OACA,UACA,aACA,aACiB;CACjB,MAAM,EAAE,UAAU,QAAQ,OAAO,aAAa,UAAU,aAAa;EACnE;EACA;EACD,CAAC;AAEF,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,wCAAwC,UAAU;YAArE;GACG,SAAS,SAAS,KACjB,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,QAAD;KACE,SAAQ;KACR,MAAK;KACL,SAAS;KACT,WAAU;eACX;KAEQ;IACL;GAGR,oBAAC,sBAAD;IAAgC;IAAkB;IAAU;GAE3D,SACC,oBAAC,OAAD;IAAK,WAAU;cACZ;IACG;GAGR,oBAAC,gBAAD;IACE,QAAQ;IACR,UAAU,WAAW,eAAe,WAAW;IAClC;IACb;GACE"}
1
+ {"version":3,"file":"genie-chat.js","names":[],"sources":["../../../src/react/genie/genie-chat.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { GenieChatInput } from \"./genie-chat-input\";\nimport { GenieChatMessageList } from \"./genie-chat-message-list\";\nimport type { GenieChatProps } from \"./types\";\nimport { useGenieChat } from \"./use-genie-chat\";\n\n/** Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE. */\nexport function GenieChat({\n alias,\n basePath,\n placeholder,\n className,\n}: GenieChatProps) {\n const { messages, status, error, sendMessage, reset } = useGenieChat({\n alias,\n basePath,\n });\n\n return (\n <div className={cn(\"flex flex-col h-full overflow-hidden\", className)}>\n {messages.length > 0 && (\n <div className=\"shrink-0 flex justify-end px-4 pt-3 pb-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={reset}\n className=\"text-xs text-muted-foreground\"\n >\n New conversation\n </Button>\n </div>\n )}\n\n <GenieChatMessageList messages={messages} status={status} />\n\n {error && (\n <div className=\"shrink-0 px-4 py-2 text-sm text-destructive bg-destructive/10 border-t\">\n {error}\n </div>\n )}\n\n <GenieChatInput\n onSend={sendMessage}\n disabled={status === \"streaming\" || status === \"loading-history\"}\n placeholder={placeholder}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,UAAU,EACxB,OACA,UACA,aACA,aACiB;CACjB,MAAM,EAAE,UAAU,QAAQ,OAAO,aAAa,UAAU,aAAa;EACnE;EACA;EACD,CAAC;AAEF,QACE,qBAAC;EAAI,WAAW,GAAG,wCAAwC,UAAU;;GAClE,SAAS,SAAS,KACjB,oBAAC;IAAI,WAAU;cACb,oBAAC;KACC,SAAQ;KACR,MAAK;KACL,SAAS;KACT,WAAU;eACX;MAEQ;KACL;GAGR,oBAAC;IAA+B;IAAkB;KAAU;GAE3D,SACC,oBAAC;IAAI,WAAU;cACZ;KACG;GAGR,oBAAC;IACC,QAAQ;IACR,UAAU,WAAW,eAAe,WAAW;IAClC;KACb;;GACE"}
@@ -0,0 +1,7 @@
1
+ import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
2
+ import { GenieChatProps, GenieChatStatus, GenieMessageItem, UseGenieChatOptions, UseGenieChatReturn } from "./types.js";
3
+ import { GenieChat } from "./genie-chat.js";
4
+ import { GenieChatInput } from "./genie-chat-input.js";
5
+ import { GenieChatMessage } from "./genie-chat-message.js";
6
+ import { GenieChatMessageList } from "./genie-chat-message-list.js";
7
+ import { useGenieChat } from "./use-genie-chat.js";
@@ -1,4 +1,5 @@
1
1
  import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
2
+ import "../../shared/src/index.js";
2
3
 
3
4
  //#region src/react/genie/types.d.ts
4
5
  type GenieChatStatus = "idle" | "loading-history" | "streaming" | "error";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/genie/types.ts"],"sourcesContent":[],"mappings":";;;KAQY,eAAA;AAAA,UAMK,gBAAA,CANU;EAMV,EAAA,EAAA,MAAA;EAAgB,IAAA,EAAA,MAAA,GAAA,WAAA;SAKlB,EAAA,MAAA;QACC,EAAA,MAAA;EAAG,WAAA,EADJ,uBACI,EAAA;EAIF,YAAA,EAJD,GAIC,CAAA,MAAmB,EAAA,OAAA,CAAA;EAWnB,KAAA,CAAA,EAAA,MAAA;;AACL,UAZK,mBAAA,CAYL;;EACa,KAAA,EAAA,MAAA;EAOR;;;;;;;UATA,kBAAA;YACL;UACF;;;;;;UAOO,cAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/genie/types.ts"],"mappings":";;;;KAQY,eAAA;AAAA,UAMK,gBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;EACA,MAAA;EACA,WAAA,EAAa,uBAAA;EACb,YAAA,EAAc,GAAA;EACd,KAAA;AAAA;AAAA,UAGe,mBAAA;EATf;EAWA,KAAA;EATA;EAWA,QAAA;EATA;EAWA,YAAA;EAVA;EAYA,YAAA;AAAA;AAAA,UAGe,kBAAA;EACf,QAAA,EAAU,gBAAA;EACV,MAAA,EAAQ,eAAA;EACR,cAAA;EACA,KAAA;EACA,WAAA,GAAc,OAAA;EACd,KAAA;AAAA;AAAA,UAGe,cAAA;EAZf;EAcA,KAAA;EAdY;EAgBZ,QAAA;EAbiC;EAejC,WAAA;EAbuB;EAevB,SAAA;AAAA"}
@@ -1,7 +1,6 @@
1
1
  import { UseGenieChatOptions, UseGenieChatReturn } from "./types.js";
2
2
 
3
3
  //#region src/react/genie/use-genie-chat.d.ts
4
-
5
4
  /**
6
5
  * Manages the full Genie chat lifecycle:
7
6
  * SSE streaming, conversation persistence via URL, and history replay.
@@ -1 +1 @@
1
- {"version":3,"file":"use-genie-chat.d.ts","names":[],"sources":["../../../src/react/genie/use-genie-chat.ts"],"sourcesContent":[],"mappings":";;;;;;AAoFA;;;;;;;iBAAgB,YAAA,UAAsB,sBAAsB"}
1
+ {"version":3,"file":"use-genie-chat.d.ts","names":[],"sources":["../../../src/react/genie/use-genie-chat.ts"],"mappings":";;;;;AAoFA;;;;;;;iBAAgB,YAAA,CAAa,OAAA,EAAS,mBAAA,GAAsB,kBAAA"}
@@ -0,0 +1,3 @@
1
+ import { UseChartDataOptions, UseChartDataResult, useChartData } from "./use-chart-data.js";
2
+ import { AnalyticsFormat, InferResultByFormat, InferRowType, PluginRegistry, QueryRegistry, TypedArrowTable, UseAnalyticsQueryOptions, UseAnalyticsQueryResult } from "./types.js";
3
+ import { useAnalyticsQuery } from "./use-analytics-query.js";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/hooks/types.ts"],"sourcesContent":[],"mappings":";;;;KAOY,eAAA;AAAZ;AAYA;;;;;;;AAeA;;AAAoD,UAfnC,eAemC,CAAA,aAdrC,MAcqC,CAAA,MAAA,EAAA,OAAA,CAAA,GAdX,MAcW,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,SAb1C,KAa0C,CAAA;;;AAYpD;AA2BA;EASY,SAAA,SAAA,CAAA,EAxDW,IAwDM;;;AACK,UAjDjB,wBAiDiB,CAAA,UAjDkB,eAiDlB,GAAA,MAAA,CAAA,CAAA;;QAAgB,CAAA,EA/CvC,CA+CuC;;EAAG,iBAAA,CAAA,EAAA,MAAA;EAIzC;EAAQ,SAAA,CAAA,EAAA,OAAA;;;AAEE,UA3CL,uBA2CK,CAAA,CAAA,CAAA,CAAA;;EAAD,IAAA,EAzCb,CAyCa,GAAA,IAAA;EAMT;EAAW,OAAA,EAAA,OAAA;;OAAqC,EAAA,MAAA,GAAA,IAAA;;;;;;;;AAU5D;;;;;;;;;;;;AAKM,UArCW,aAAA,CAqCX;MACF,EAAA,MAAA,CAAA,EAAA;IAAM,IAAA,EAAA,MAAA;IAOE,UAAA,EA1CI,MA0Ce,CAAA,MAAA,EAAA,OAAA,CAAA;IAAA,MAAA,EAAA,OAAA,EAAA;;;;AAIS,KAxC5B,iBAwC4B,CAAA,CAAA,CAAA,GAAA,MAAA,QAAhB,MAvCV,CAuCU,IAAA,MAAA,SAvCU,CAuCV,GAAA,KAAA,GAvCsB,CAuCtB,GAvC0B,CAuC1B,CAvC4B,CAuC5B,CAAA;;AAAmC,KAnC/C,QAAA,GAAW,iBAmCoC,CAnClB,aAmCkB,CAAA,SAAA,KAAA,GAAA,MAAA,GAjCvD,iBAiCuD,CAjCrC,aAiCqC,CAAA;;AAK3D;;;AAAyD,KAhC7C,WAgC6C,CAAA,CAAA,EAAA,CAAA,CAAA,GAhCzB,CAgCyB,SAhCf,iBAgCe,CAhCG,aAgCH,CAAA,GA/BrD,aA+BqD,CA/BvC,CA+BuC,CAAA,SAAA;QAAlB,EAAA,KAAA,EAAA;IA9BjC,IACA,CA8BF,GA7BA,CA6BA;;;;;AAGM,KA1BE,YA0BF,CAAA,CAAA,CAAA,GA1BoB,CA0BpB,SA1B8B,iBA0B9B,CA1BgD,aA0BhD,CAAA,GAzBN,aAyBM,CAzBQ,CAyBR,CAAA,SAAA;EAEO,MAAA,EA3BsB,KA2BtB,CAAA,KAAc,EAAA,CAAA;IA1BzB,UAAU,0BACR,IACA,0BACF,0BACF;;;;;;KAOQ,oCAGA,mBACR,oBAAoB,gBAAgB,aAAa,MAAM,YAAY,GAAG;;;;KAK9D,iBAAiB,UAAU,kBAAkB,iBACrD,cAAc;;IACZ,IACA,0BACF;UAEa,cAAA;iBACA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/hooks/types.ts"],"mappings":";;;;KAOY,eAAA;AAAZ;;;;;AAYA;;;;;AAZA,UAYiB,eAAA,cACF,MAAA,oBAA0B,MAAA,2BAC/B,KAAA;EAAA;;;;EAAA,SAKC,SAAA,GAAY,IAAA;AAAA;;UAQN,wBAAA,WAAmC,eAAA;EAR7B;EAUrB,MAAA,GAAS,CAAA;EAVgB;EAazB,iBAAA;EALuC;EAQvC,SAAA;AAAA;;UAIe,uBAAA;EAVf;EAYA,IAAA,EAAM,CAAA;EATN;EAWA,OAAA;EARS;EAUT,KAAA;AAAA;;;;;;;;;;;AAqBF;;;;;;;;UAAiB,aAAA;EAAA,CACd,GAAA;IACC,IAAA;IACA,UAAA,EAAY,MAAA;IACZ,MAAA;EAAA;AAAA;;KAKQ,iBAAA,0BACE,CAAA,mBAAoB,CAAA,WAAY,CAAA,GAAI,CAAA,CAAE,CAAA;;KAIxC,QAAA,GAAW,iBAAA,CAAkB,aAAA,2BAErC,iBAAA,CAAkB,aAAA;;;;;KAMV,WAAA,SAAoB,CAAA,SAAU,iBAAA,CAAkB,aAAA,IACxD,aAAA,CAAc,CAAA;EAAa,MAAA;AAAA,IACzB,CAAA,GACA,CAAA,GACF,CAAA;;;AAZJ;;KAkBY,YAAA,MAAkB,CAAA,SAAU,iBAAA,CAAkB,aAAA,IACtD,aAAA,CAAc,CAAA;EAAa,MAAA,EAAQ,KAAA;AAAA,IACjC,CAAA,SAAU,MAAA,oBACR,CAAA,GACA,MAAA,oBACF,MAAA,oBACF,MAAA;;;;;;KAOQ,mBAAA,iBAGA,eAAA,IACR,CAAA,mBAAoB,eAAA,CAAgB,YAAA,CAAa,CAAA,KAAM,WAAA,CAAY,CAAA,EAAG,CAAA;;;;KAK9D,WAAA,MAAiB,CAAA,SAAU,iBAAA,CAAkB,aAAA,IACrD,aAAA,CAAc,CAAA;EAAa,UAAA;AAAA,IACzB,CAAA,GACA,MAAA,oBACF,MAAA;AAAA,UAEa,cAAA;EAAA,CACd,GAAA,WAAc,MAAA;AAAA"}
@@ -1,7 +1,6 @@
1
1
  import { AnalyticsFormat, InferParams, InferResultByFormat, QueryKey, UseAnalyticsQueryOptions, UseAnalyticsQueryResult } from "./types.js";
2
2
 
3
3
  //#region src/react/hooks/use-analytics-query.d.ts
4
-
5
4
  /**
6
5
  * Subscribe to an analytics query over SSE and returns its latest result.
7
6
  * Integration hook between client and analytics plugin.
@@ -1 +1 @@
1
- {"version":3,"file":"use-analytics-query.d.ts","names":[],"sources":["../../../src/react/hooks/use-analytics-query.ts"],"sourcesContent":[],"mappings":";;;;;;AAqDA;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,yCAEJ,WAAW,oBACX,oCAEA,gBACG,YAAY,qBAChB,yBAAyB,KACjC,wBAAwB,oBAAoB,GAAG,GAAG"}
1
+ {"version":3,"file":"use-analytics-query.d.ts","names":[],"sources":["../../../src/react/hooks/use-analytics-query.ts"],"mappings":";;;;;AAqDA;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,iBAAA,wBAEJ,QAAA,GAAW,QAAA,YACX,eAAA,UAAA,CAEV,QAAA,EAAU,CAAA,EACV,UAAA,GAAa,WAAA,CAAY,CAAA,UACzB,OAAA,GAAS,wBAAA,CAAyB,CAAA,IACjC,uBAAA,CAAwB,mBAAA,CAAoB,CAAA,EAAG,CAAA,EAAG,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-chart-data.d.ts","names":[],"sources":["../../../src/react/hooks/use-chart-data.ts"],"sourcesContent":[],"mappings":";;;UAYiB,mBAAA;;EAAA,QAAA,EAAA,MAAA;EAAmB;YAIrB,CAAA,EAAA,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;;;;;AAaf;AA0EA;;QAAsC,CAAA,EA/E3B,UA+E2B;;EAAwC,WAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EA7EpD,CA6EoD,EAAA,GA7E9C,CA6E8C;;UA1E7D,kBAAA;;QAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwEQ,YAAA,UAAsB,sBAAsB"}
1
+ {"version":3,"file":"use-chart-data.d.ts","names":[],"sources":["../../../src/react/hooks/use-chart-data.ts"],"mappings":";;;UAYiB,mBAAA;;EAEf,QAAA;EAFkC;EAIlC,UAAA,GAAa,MAAA;EAAA;;;;;;;EAQb,MAAA,GAAS,UAAA;EARI;EAUb,WAAA,OAAkB,IAAA,EAAM,CAAA,KAAM,CAAA;AAAA;AAAA,UAGf,kBAAA;EAHA;EAKf,IAAA,EAAM,SAAA;EALY;EAOlB,OAAA;EAP+B;EAS/B,OAAA;EANe;EAQf,KAAA;;EAEA,OAAA;AAAA;;;;;;;;AAgEF;;;;;;;;;;;;iBAAgB,YAAA,CAAa,OAAA,EAAS,mBAAA,GAAsB,kBAAA"}
@@ -17,17 +17,21 @@ import { CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERG
17
17
  import { useAllThemeColors, useThemeColors } from "./charts/theme.js";
18
18
  import { createTimeSeriesData, formatLabel, sortTimeSeriesAscending, toChartArray, toChartValue, truncateLabel } from "./charts/utils.js";
19
19
  import { CartesianContext, HeatmapContext, OptionBuilderContext, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption } from "./charts/options.js";
20
+ import "./charts/index.js";
20
21
  import { GenieChatProps, GenieChatStatus, GenieMessageItem, UseGenieChatOptions, UseGenieChatReturn } from "./genie/types.js";
21
22
  import { GenieChat } from "./genie/genie-chat.js";
22
23
  import { GenieChatInput } from "./genie/genie-chat-input.js";
23
24
  import { GenieChatMessage } from "./genie/genie-chat-message.js";
24
25
  import { GenieChatMessageList } from "./genie/genie-chat-message-list.js";
25
26
  import { useGenieChat } from "./genie/use-genie-chat.js";
27
+ import "./genie/index.js";
26
28
  import { AnalyticsFormat, InferResultByFormat, InferRowType, PluginRegistry, QueryRegistry, TypedArrowTable, UseAnalyticsQueryOptions, UseAnalyticsQueryResult } from "./hooks/types.js";
27
29
  import { useAnalyticsQuery } from "./hooks/use-analytics-query.js";
30
+ import "./hooks/index.js";
28
31
  import { cn } from "./lib/utils.js";
29
32
  import { PortalContainerContext, PortalContainerProvider, usePortalContainer, useResolvedPortalContainer } from "./portal-container-context.js";
30
33
  import { DataTable } from "./table/data-table.js";
34
+ import "./table/index.js";
31
35
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./ui/accordion.js";
32
36
  import { Alert, AlertDescription, AlertTitle } from "./ui/alert.js";
33
37
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger } from "./ui/alert-dialog.js";
@@ -81,4 +85,5 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs.js";
81
85
  import { Textarea } from "./ui/textarea.js";
82
86
  import { Toggle, toggleVariants } from "./ui/toggle.js";
83
87
  import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group.js";
88
+ import "./ui/index.js";
84
89
  export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnalyticsFormat, AreaChart, AreaChartProps, AreaChartSpecificProps, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BarChart, BarChartProps, BarChartSpecificProps, BaseChart, BaseChartProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERGING, CHART_COLOR_VARS_SEQUENTIAL, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, CartesianContext, ChartBaseProps, ChartColorPalette, ChartConfig, ChartContainer, ChartData, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChartType, ChartWrapper, ChartWrapperProps, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DATE_FIELD_PATTERNS, DataFormat, DataProps, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DonutChart, DonutChartProps, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, FALLBACK_COLORS, FALLBACK_COLORS_CATEGORICAL, FALLBACK_COLORS_DIVERGING, FALLBACK_COLORS_SEQUENTIAL, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GenieAttachmentResponse, GenieChat, GenieChatInput, GenieChatMessage, GenieChatMessageList, GenieChatProps, GenieChatStatus, GenieMessageItem, GenieMessageResponse, GenieStreamEvent, HeatmapChart, HeatmapChartProps, HeatmapChartSpecificProps, HeatmapContext, HoverCard, HoverCardContent, HoverCardTrigger, InferResultByFormat, InferRowType, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label, LineChart, LineChartProps, LineChartSpecificProps, METADATA_DATE_PATTERNS, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NAME_FIELD_PATTERNS, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NormalizedChartData, NormalizedChartDataBase, NormalizedHeatmapData, OptionBuilderContext, Orientation, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PieChart, PieChartProps, PieChartSpecificProps, PluginRegistry, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalContainerContext, PortalContainerProvider, Progress, QueryProps, QueryRegistry, RadarChart, RadarChartProps, RadarChartSpecificProps, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScatterChart, ScatterChartProps, ScatterChartSpecificProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TypedArrowTable, UnifiedChartProps, UseAnalyticsQueryOptions, UseAnalyticsQueryResult, UseChartDataOptions, UseChartDataResult, UseGenieChatOptions, UseGenieChatReturn, badgeVariants, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption, buttonGroupVariants, buttonVariants, cn, createChart, createTimeSeriesData, formatLabel, isArrowTable, isDataProps, isQueryProps, navigationMenuTriggerStyle, normalizeChartData, normalizeHeatmapData, sortTimeSeriesAscending, toChartArray, toChartValue, toggleVariants, truncateLabel, useAllThemeColors, useAnalyticsQuery, useChartData, useFormField, useGenieChat, usePortalContainer, useResolvedPortalContainer, useSidebar, useThemeColors };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","names":[],"sources":["../../../src/react/lib/utils.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,EAAA,YAAc"}
1
+ {"version":3,"file":"utils.d.ts","names":[],"sources":["../../../src/react/lib/utils.ts"],"mappings":";;;iBAGgB,EAAA,CAAA,GAAM,MAAA,EAAQ,UAAA"}
@@ -2,7 +2,6 @@ import React from "react";
2
2
  import * as react_jsx_runtime0 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/portal-container-context.d.ts
5
-
6
5
  /**
7
6
  * Context for providing a custom portal container.
8
7
  * This is used when rendering components in isolated contexts like iframes or shadow DOM.
@@ -1 +1 @@
1
- {"version":3,"file":"portal-container-context.d.ts","names":[],"sources":["../../src/react/portal-container-context.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAQA;;AAAmC,cAAtB,sBAAsB,EAAA,KAAA,CAAA,OAAA,CAAA,WAAA,GAAA,IAAA,CAAA;AAAA,iBAEnB,kBAAA,CAAA,CAFmB,EAED,WAFC,GAAA,IAAA;;AAEnC;AA4BA;;;;;;;;;AAKC;;;;;AAOD;;;;;;;;iBAZgB,0BAAA,iBACE,UAAU,mBAAmB,iCAC5C,UAAU,mBAAmB;UAKtB,4BAAA;aACG;YACD,KAAA,CAAM;;iBAGF,uBAAA;;;GAGb,+BAA4B,kBAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"portal-container-context.d.ts","names":[],"sources":["../../src/react/portal-container-context.tsx"],"mappings":";;;;;;;AAQA;;cAAa,sBAAA,EAAsB,KAAA,CAAA,OAAA,CAAA,WAAA;AAAA,iBAEnB,kBAAA,CAAA,GAAkB,WAAA;;;;;;AAAlC;;;;;AA4BA;;;;;;;;;;;;;;iBAAgB,0BAAA,CACd,aAAA,GAAgB,OAAA,GAAU,gBAAA,GAAmB,WAAA,sBAC5C,OAAA,GAAU,gBAAA,GAAmB,WAAA;AAAA,UAKtB,4BAAA;EACR,SAAA,EAAW,WAAA;EACX,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;AAAA,iBAGF,uBAAA,CAAA;EACd,SAAA;EACA;AAAA,GACC,4BAAA,GAA4B,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"portal-container-context.js","names":[],"sources":["../../src/react/portal-container-context.tsx"],"sourcesContent":["import type React from \"react\";\nimport { createContext, useContext } from \"react\";\n\n/**\n * Context for providing a custom portal container.\n * This is used when rendering components in isolated contexts like iframes or shadow DOM.\n * Portal components (AlertDialog, ContextMenu, etc.) will use this container instead of document.body\n */\nexport const PortalContainerContext = createContext<HTMLElement | null>(null);\n\nexport function usePortalContainer() {\n return useContext(PortalContainerContext);\n}\n\n/**\n * Resolves the final portal container from explicit prop or context.\n *\n * This hook enables Portal components to work seamlessly in isolated rendering contexts\n * (like iframes, shadow DOM, or isolated component previews) by accepting a container\n * from either:\n * 1. An explicit `container` prop (highest priority)\n * 2. A `PortalContainerProvider` context (fallback)\n * 3. undefined (lets Radix UI use document.body as default)\n *\n * @param containerProp - Optional explicit container element from props\n * @returns The resolved container element to use for portal rendering\n *\n * @example\n * ```tsx\n * function MyPortal({ container, ...props }) {\n * return (\n * <RadixPortal container={useResolvedPortalContainer(container)} {...props}>\n * <MyContent />\n * </RadixPortal>\n * );\n * }\n * ```\n */\nexport function useResolvedPortalContainer(\n containerProp?: Element | DocumentFragment | HTMLElement | null | undefined,\n): Element | DocumentFragment | HTMLElement | null | undefined {\n const containerFromContext = usePortalContainer();\n return containerProp ?? containerFromContext ?? undefined;\n}\n\ninterface PortalContainerProviderProps {\n container: HTMLElement | null;\n children: React.ReactNode;\n}\n\nexport function PortalContainerProvider({\n container,\n children,\n}: PortalContainerProviderProps) {\n return (\n <PortalContainerContext.Provider value={container}>\n {children}\n </PortalContainerContext.Provider>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,MAAa,yBAAyB,cAAkC,KAAK;AAE7E,SAAgB,qBAAqB;AACnC,QAAO,WAAW,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;AA2B3C,SAAgB,2BACd,eAC6D;CAC7D,MAAM,uBAAuB,oBAAoB;AACjD,QAAO,iBAAiB,wBAAwB;;AAQlD,SAAgB,wBAAwB,EACtC,WACA,YAC+B;AAC/B,QACE,oBAAC,uBAAuB,UAAxB;EAAiC,OAAO;EACrC;EAC+B"}
1
+ {"version":3,"file":"portal-container-context.js","names":[],"sources":["../../src/react/portal-container-context.tsx"],"sourcesContent":["import type React from \"react\";\nimport { createContext, useContext } from \"react\";\n\n/**\n * Context for providing a custom portal container.\n * This is used when rendering components in isolated contexts like iframes or shadow DOM.\n * Portal components (AlertDialog, ContextMenu, etc.) will use this container instead of document.body\n */\nexport const PortalContainerContext = createContext<HTMLElement | null>(null);\n\nexport function usePortalContainer() {\n return useContext(PortalContainerContext);\n}\n\n/**\n * Resolves the final portal container from explicit prop or context.\n *\n * This hook enables Portal components to work seamlessly in isolated rendering contexts\n * (like iframes, shadow DOM, or isolated component previews) by accepting a container\n * from either:\n * 1. An explicit `container` prop (highest priority)\n * 2. A `PortalContainerProvider` context (fallback)\n * 3. undefined (lets Radix UI use document.body as default)\n *\n * @param containerProp - Optional explicit container element from props\n * @returns The resolved container element to use for portal rendering\n *\n * @example\n * ```tsx\n * function MyPortal({ container, ...props }) {\n * return (\n * <RadixPortal container={useResolvedPortalContainer(container)} {...props}>\n * <MyContent />\n * </RadixPortal>\n * );\n * }\n * ```\n */\nexport function useResolvedPortalContainer(\n containerProp?: Element | DocumentFragment | HTMLElement | null | undefined,\n): Element | DocumentFragment | HTMLElement | null | undefined {\n const containerFromContext = usePortalContainer();\n return containerProp ?? containerFromContext ?? undefined;\n}\n\ninterface PortalContainerProviderProps {\n container: HTMLElement | null;\n children: React.ReactNode;\n}\n\nexport function PortalContainerProvider({\n container,\n children,\n}: PortalContainerProviderProps) {\n return (\n <PortalContainerContext.Provider value={container}>\n {children}\n </PortalContainerContext.Provider>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,MAAa,yBAAyB,cAAkC,KAAK;AAE7E,SAAgB,qBAAqB;AACnC,QAAO,WAAW,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;AA2B3C,SAAgB,2BACd,eAC6D;CAC7D,MAAM,uBAAuB,oBAAoB;AACjD,QAAO,iBAAiB,wBAAwB;;AAQlD,SAAgB,wBAAwB,EACtC,WACA,YAC+B;AAC/B,QACE,oBAAC,uBAAuB;EAAS,OAAO;EACrC;GAC+B"}
@@ -1,8 +1,7 @@
1
1
  import { DataTableProps } from "./types.js";
2
- import * as react_jsx_runtime274 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/table/data-table.d.ts
5
-
6
5
  /**
7
6
  * Production-ready data table with automatic data fetching and state management
8
7
  *
@@ -44,7 +43,7 @@ import * as react_jsx_runtime274 from "react/jsx-runtime";
44
43
  * )}
45
44
  * </DataTable>
46
45
  */
47
- declare function DataTable(props: DataTableProps): react_jsx_runtime274.JSX.Element;
46
+ declare function DataTable(props: DataTableProps): react_jsx_runtime0.JSX.Element;
48
47
  //#endregion
49
48
  export { DataTable };
50
49
  //# sourceMappingURL=data-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.d.ts","names":[],"sources":["../../../src/react/table/data-table.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAsEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,SAAA,QAAiB,iBAAc,oBAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"data-table.d.ts","names":[],"sources":["../../../src/react/table/data-table.tsx"],"mappings":";;;;;;;AAsEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,SAAA,CAAU,KAAA,EAAO,cAAA,GAAc,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.js","names":["Table"],"sources":["../../../src/react/table/data-table.tsx"],"sourcesContent":["import { flexRender } from \"@tanstack/react-table\";\nimport { ChevronDown } from \"lucide-react\";\nimport { formatFieldLabel } from \"../lib/format\";\nimport { Button } from \"../ui/button\";\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\nimport { Input } from \"../ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"../ui/table\";\nimport { TableWrapper } from \"./table-wrapper\";\nimport type { DataTableLabels, DataTableProps } from \"./types\";\n\n/**\n * Production-ready data table with automatic data fetching and state management\n *\n * Features:\n * - Automatic column generation from data structure\n * - Integrated with useAnalyticsQuery for data fetching\n * - Built-in loading, error, and empty states\n * - Dynamic filtering, sorting and pagination\n * - Column visibility controls\n * - Responsive design\n * - Supports opinionated mode (auto columns) and full-control mode (`children(table)`)\n *\n * @param props - Props for the DataTable component\n * @param props.queryKey - The query key to fetch the data\n * @param props.parameters - The parameters to pass to the query. Required - use `{}` if none.\n * @param props.filterColumn - The column to filter by\n * @param props.filterPlaceholder - The placeholder for the filter input\n * @param props.children - Optional children for full control mode\n * @returns - The rendered data table component\n *\n * @example\n * // Opinionated mode\n * <DataTable\n * queryKey=\"users-list\"\n * parameters={{ status: \"active\" }}\n * filterColumn=\"email\"\n * filterPlaceholder=\"Filter by email...\"\n * />\n * @example\n * // full control mode\n * <DataTable queryKey=\"users-list\" parameters={{ status: \"active\" }}>\n * {(table) => (\n * <div>\n * <h2>Custom Table UI</h2>\n * {table.getRowModel().rows.map(row => (\n * <div key={row.id}>{row.original.name}</div>\n * ))}\n * </div>\n * )}\n * </DataTable>\n */\nexport function DataTable(props: DataTableProps) {\n const {\n parameters,\n queryKey,\n filterColumn,\n filterPlaceholder,\n transform,\n labels,\n ariaLabel,\n testId,\n className,\n enableRowSelection,\n onRowSelectionChange,\n children,\n pageSize = 10,\n pageSizeOptions = [10, 25, 50, 100],\n } = props;\n\n const defaultLabels: Required<DataTableLabels> = {\n columnsButton: \"Columns\",\n noResults: \"No results found.\",\n rowsFound: `\\${count} row(s) found`,\n previousButton: \"Previous\",\n nextButton: \"Next\",\n rowsPerPage: \"Rows per page\",\n showing: `Showing \\${from} to \\${to} of \\${total}`,\n };\n\n const finalLabels = { ...defaultLabels, ...labels };\n\n return (\n <TableWrapper\n queryKey={queryKey}\n parameters={parameters}\n ariaLabel={ariaLabel}\n testId={testId}\n className={className}\n transformer={transform}\n enableRowSelection={enableRowSelection}\n onRowSelectionChange={onRowSelectionChange}\n pageSize={pageSize}\n >\n {(table) => {\n if (children) {\n return children(table);\n }\n\n const data = table.options.data;\n\n const defaultFilterColumn =\n filterColumn ||\n (data && data.length > 0\n ? Object.keys(data[0] as Record<string, any>).find(\n (key) =>\n typeof (data[0] as Record<string, any>)[key] === \"string\",\n )\n : null);\n\n const totalRows = table.getFilteredRowModel().rows.length;\n const currentPage = table.getState().pagination.pageIndex + 1;\n const currentPageSize = table.getState().pagination.pageSize;\n const fromRow =\n totalRows === 0 ? 0 : (currentPage - 1) * currentPageSize + 1;\n const toRow = Math.min(currentPage * currentPageSize, totalRows);\n\n return (\n <div className=\"w-full\">\n <div className=\"flex items-center py-4 gap-2\">\n {defaultFilterColumn && (\n <Input\n placeholder={\n filterPlaceholder ||\n `Filter by ${formatFieldLabel(defaultFilterColumn)}...`\n }\n value={\n (table\n .getColumn(defaultFilterColumn)\n ?.getFilterValue() as string) ?? \"\"\n }\n onChange={(event) =>\n table\n .getColumn(defaultFilterColumn)\n ?.setFilterValue(event.target.value)\n }\n className=\"max-w-sm\"\n />\n )}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"ml-auto\">\n {finalLabels.columnsButton}{\" \"}\n <ChevronDown className=\"ml-2 h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {table\n .getAllColumns()\n .filter((column) => column.getCanHide())\n .map((column) => {\n return (\n <DropdownMenuCheckboxItem\n key={column.id}\n className=\"capitalize\"\n checked={column.getIsVisible()}\n onCheckedChange={(value) =>\n column.toggleVisibility(!!value)\n }\n >\n {formatFieldLabel(column.id)}\n </DropdownMenuCheckboxItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div className=\"overflow-hidden rounded-md border border-border\">\n <div className=\"max-h-[600px] overflow-y-auto\">\n <Table>\n <TableHeader className=\"sticky top-0 bg-background z-10\">\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => {\n const isSelectColumn = header.column.id === \"select\";\n return (\n <TableHead\n key={header.id}\n style={{\n width: header.getSize(),\n position: \"relative\",\n }}\n className={\n isSelectColumn ? \"w-[40px] p-0\" : undefined\n }\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </TableHead>\n );\n })}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow\n key={row.id}\n data-state={row.getIsSelected() && \"selected\"}\n >\n {row.getVisibleCells().map((cell) => {\n const isSelectColumn = cell.column.id === \"select\";\n return (\n <TableCell\n key={cell.id}\n style={{\n width: cell.column.getSize(),\n }}\n className={\n isSelectColumn ? \"w-[40px] p-0\" : undefined\n }\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </TableCell>\n );\n })}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell\n colSpan={table.getAllColumns().length}\n className=\"h-24 text-center\"\n >\n {finalLabels.noResults}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n </div>\n <div className=\"flex items-center justify-between py-4\">\n <div className=\"flex items-center gap-6\">\n <div className=\"text-foreground text-sm\">\n {totalRows > 0\n ? finalLabels.showing\n .replace(`\\${from}`, fromRow.toString())\n .replace(`\\${to}`, toRow.toString())\n .replace(`\\${total}`, totalRows.toString())\n : finalLabels.noResults}\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-foreground\">\n {finalLabels.rowsPerPage}\n </span>\n <Select\n value={currentPageSize.toString()}\n onValueChange={(value) => {\n table.setPageSize(Number(value));\n }}\n >\n <SelectTrigger className=\"w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {pageSizeOptions.map((size) => (\n <SelectItem key={size} value={size.toString()}>\n {size}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n {finalLabels.previousButton}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n {finalLabels.nextButton}\n </Button>\n </div>\n </div>\n </div>\n );\n }}\n </TableWrapper>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"data-table.js","names":["Table"],"sources":["../../../src/react/table/data-table.tsx"],"sourcesContent":["import { flexRender } from \"@tanstack/react-table\";\nimport { ChevronDown } from \"lucide-react\";\nimport { formatFieldLabel } from \"../lib/format\";\nimport { Button } from \"../ui/button\";\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\nimport { Input } from \"../ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"../ui/table\";\nimport { TableWrapper } from \"./table-wrapper\";\nimport type { DataTableLabels, DataTableProps } from \"./types\";\n\n/**\n * Production-ready data table with automatic data fetching and state management\n *\n * Features:\n * - Automatic column generation from data structure\n * - Integrated with useAnalyticsQuery for data fetching\n * - Built-in loading, error, and empty states\n * - Dynamic filtering, sorting and pagination\n * - Column visibility controls\n * - Responsive design\n * - Supports opinionated mode (auto columns) and full-control mode (`children(table)`)\n *\n * @param props - Props for the DataTable component\n * @param props.queryKey - The query key to fetch the data\n * @param props.parameters - The parameters to pass to the query. Required - use `{}` if none.\n * @param props.filterColumn - The column to filter by\n * @param props.filterPlaceholder - The placeholder for the filter input\n * @param props.children - Optional children for full control mode\n * @returns - The rendered data table component\n *\n * @example\n * // Opinionated mode\n * <DataTable\n * queryKey=\"users-list\"\n * parameters={{ status: \"active\" }}\n * filterColumn=\"email\"\n * filterPlaceholder=\"Filter by email...\"\n * />\n * @example\n * // full control mode\n * <DataTable queryKey=\"users-list\" parameters={{ status: \"active\" }}>\n * {(table) => (\n * <div>\n * <h2>Custom Table UI</h2>\n * {table.getRowModel().rows.map(row => (\n * <div key={row.id}>{row.original.name}</div>\n * ))}\n * </div>\n * )}\n * </DataTable>\n */\nexport function DataTable(props: DataTableProps) {\n const {\n parameters,\n queryKey,\n filterColumn,\n filterPlaceholder,\n transform,\n labels,\n ariaLabel,\n testId,\n className,\n enableRowSelection,\n onRowSelectionChange,\n children,\n pageSize = 10,\n pageSizeOptions = [10, 25, 50, 100],\n } = props;\n\n const defaultLabels: Required<DataTableLabels> = {\n columnsButton: \"Columns\",\n noResults: \"No results found.\",\n rowsFound: `\\${count} row(s) found`,\n previousButton: \"Previous\",\n nextButton: \"Next\",\n rowsPerPage: \"Rows per page\",\n showing: `Showing \\${from} to \\${to} of \\${total}`,\n };\n\n const finalLabels = { ...defaultLabels, ...labels };\n\n return (\n <TableWrapper\n queryKey={queryKey}\n parameters={parameters}\n ariaLabel={ariaLabel}\n testId={testId}\n className={className}\n transformer={transform}\n enableRowSelection={enableRowSelection}\n onRowSelectionChange={onRowSelectionChange}\n pageSize={pageSize}\n >\n {(table) => {\n if (children) {\n return children(table);\n }\n\n const data = table.options.data;\n\n const defaultFilterColumn =\n filterColumn ||\n (data && data.length > 0\n ? Object.keys(data[0] as Record<string, any>).find(\n (key) =>\n typeof (data[0] as Record<string, any>)[key] === \"string\",\n )\n : null);\n\n const totalRows = table.getFilteredRowModel().rows.length;\n const currentPage = table.getState().pagination.pageIndex + 1;\n const currentPageSize = table.getState().pagination.pageSize;\n const fromRow =\n totalRows === 0 ? 0 : (currentPage - 1) * currentPageSize + 1;\n const toRow = Math.min(currentPage * currentPageSize, totalRows);\n\n return (\n <div className=\"w-full\">\n <div className=\"flex items-center py-4 gap-2\">\n {defaultFilterColumn && (\n <Input\n placeholder={\n filterPlaceholder ||\n `Filter by ${formatFieldLabel(defaultFilterColumn)}...`\n }\n value={\n (table\n .getColumn(defaultFilterColumn)\n ?.getFilterValue() as string) ?? \"\"\n }\n onChange={(event) =>\n table\n .getColumn(defaultFilterColumn)\n ?.setFilterValue(event.target.value)\n }\n className=\"max-w-sm\"\n />\n )}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"ml-auto\">\n {finalLabels.columnsButton}{\" \"}\n <ChevronDown className=\"ml-2 h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {table\n .getAllColumns()\n .filter((column) => column.getCanHide())\n .map((column) => {\n return (\n <DropdownMenuCheckboxItem\n key={column.id}\n className=\"capitalize\"\n checked={column.getIsVisible()}\n onCheckedChange={(value) =>\n column.toggleVisibility(!!value)\n }\n >\n {formatFieldLabel(column.id)}\n </DropdownMenuCheckboxItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div className=\"overflow-hidden rounded-md border border-border\">\n <div className=\"max-h-[600px] overflow-y-auto\">\n <Table>\n <TableHeader className=\"sticky top-0 bg-background z-10\">\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => {\n const isSelectColumn = header.column.id === \"select\";\n return (\n <TableHead\n key={header.id}\n style={{\n width: header.getSize(),\n position: \"relative\",\n }}\n className={\n isSelectColumn ? \"w-[40px] p-0\" : undefined\n }\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </TableHead>\n );\n })}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow\n key={row.id}\n data-state={row.getIsSelected() && \"selected\"}\n >\n {row.getVisibleCells().map((cell) => {\n const isSelectColumn = cell.column.id === \"select\";\n return (\n <TableCell\n key={cell.id}\n style={{\n width: cell.column.getSize(),\n }}\n className={\n isSelectColumn ? \"w-[40px] p-0\" : undefined\n }\n >\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </TableCell>\n );\n })}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell\n colSpan={table.getAllColumns().length}\n className=\"h-24 text-center\"\n >\n {finalLabels.noResults}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n </div>\n <div className=\"flex items-center justify-between py-4\">\n <div className=\"flex items-center gap-6\">\n <div className=\"text-foreground text-sm\">\n {totalRows > 0\n ? finalLabels.showing\n .replace(`\\${from}`, fromRow.toString())\n .replace(`\\${to}`, toRow.toString())\n .replace(`\\${total}`, totalRows.toString())\n : finalLabels.noResults}\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-foreground\">\n {finalLabels.rowsPerPage}\n </span>\n <Select\n value={currentPageSize.toString()}\n onValueChange={(value) => {\n table.setPageSize(Number(value));\n }}\n >\n <SelectTrigger className=\"w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {pageSizeOptions.map((size) => (\n <SelectItem key={size} value={size.toString()}>\n {size}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n {finalLabels.previousButton}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n {finalLabels.nextButton}\n </Button>\n </div>\n </div>\n </div>\n );\n }}\n </TableWrapper>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"empty.js","names":[],"sources":["../../../src/react/table/empty.tsx"],"sourcesContent":["export function EmptyState() {\n return (\n <div className=\"w-full p-8 text-center\">\n <p className=\"text-sm text-muted-foreground\">No data available</p>\n </div>\n );\n}\n"],"mappings":";;;AAAA,SAAgB,aAAa;AAC3B,QACE,oBAAC,OAAD;EAAK,WAAU;YACb,oBAAC,KAAD;GAAG,WAAU;aAAgC;GAAqB;EAC9D"}
1
+ {"version":3,"file":"empty.js","names":[],"sources":["../../../src/react/table/empty.tsx"],"sourcesContent":["export function EmptyState() {\n return (\n <div className=\"w-full p-8 text-center\">\n <p className=\"text-sm text-muted-foreground\">No data available</p>\n </div>\n );\n}\n"],"mappings":";;;AAAA,SAAgB,aAAa;AAC3B,QACE,oBAAC;EAAI,WAAU;YACb,oBAAC;GAAE,WAAU;aAAgC;IAAqB;GAC9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","names":[],"sources":["../../../src/react/table/error.tsx"],"sourcesContent":["export function ErrorState({ error }: { error: string }) {\n return (\n <div className=\"w-full p-8 text-center\">\n <p className=\"text-sm text-destructive\">Error loading table: {error}</p>\n </div>\n );\n}\n"],"mappings":";;;AAAA,SAAgB,WAAW,EAAE,SAA4B;AACvD,QACE,oBAAC,OAAD;EAAK,WAAU;YACb,qBAAC,KAAD;GAAG,WAAU;aAAb,CAAwC,yBAAsB,MAAU;;EACpE"}
1
+ {"version":3,"file":"error.js","names":[],"sources":["../../../src/react/table/error.tsx"],"sourcesContent":["export function ErrorState({ error }: { error: string }) {\n return (\n <div className=\"w-full p-8 text-center\">\n <p className=\"text-sm text-destructive\">Error loading table: {error}</p>\n </div>\n );\n}\n"],"mappings":";;;AAAA,SAAgB,WAAW,EAAE,SAA4B;AACvD,QACE,oBAAC;EAAI,WAAU;YACb,qBAAC;GAAE,WAAU;cAA2B,yBAAsB;IAAU;GACpE"}
@@ -0,0 +1 @@
1
+ import { DataTable } from "./data-table.js";
@@ -1 +1 @@
1
- {"version":3,"file":"loading.js","names":[],"sources":["../../../src/react/table/loading.tsx"],"sourcesContent":["export function LoadingSkeleton() {\n return (\n <div className=\"w-full space-y-3 mt-2\">\n <div className=\"flex items-center gap-2 mt-4\">\n <div className=\"h-10 bg-muted rounded animate-pulse flex-1 max-w-sm\" />\n <div className=\"h-10 bg-muted rounded animate-pulse w-24 ml-auto\" />\n </div>\n\n <div className=\"rounded-md border overflow-hidden\">\n <div className=\"border-b bg-secondary p-4\">\n <div className=\"flex gap-4\">\n <div className=\"h-8 bg-muted rounded animate-pulse flex-1\" />\n <div className=\"h-8 bg-muted rounded animate-pulse flex-1\" />\n <div className=\"h-8 bg-muted rounded animate-pulse flex-1\" />\n </div>\n </div>\n\n {Array.from({ length: 5 }).map(() => (\n <div\n key={`loading-row-${Math.random()}`}\n className=\"border-b p-4 last:border-b-0\"\n >\n <div className=\"flex gap-4\">\n <div className=\"h-6 bg-muted rounded animate-pulse flex-1\" />\n <div className=\"h-6 bg-muted rounded animate-pulse flex-1\" />\n <div className=\"h-6 bg-muted rounded animate-pulse flex-1\" />\n </div>\n </div>\n ))}\n </div>\n\n <div className=\"flex items-center justify-end gap-2\">\n <div className=\"h-4 bg-muted rounded animate-pulse w-32\" />\n <div className=\"h-9 bg-muted rounded animate-pulse w-20\" />\n <div className=\"h-9 bg-muted rounded animate-pulse w-20\" />\n </div>\n </div>\n );\n}\n"],"mappings":";;;AAAA,SAAgB,kBAAkB;AAChC,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,OAAD,EAAK,WAAU,uDAAwD,GACvE,oBAAC,OAAD,EAAK,WAAU,oDAAqD,EAChE;;GAEN,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,OAAD;KAAK,WAAU;eACb,qBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,oBAAC,OAAD,EAAK,WAAU,6CAA8C;OAC7D,oBAAC,OAAD,EAAK,WAAU,6CAA8C;OAC7D,oBAAC,OAAD,EAAK,WAAU,6CAA8C;OACzD;;KACF,GAEL,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,UACzB,oBAAC,OAAD;KAEE,WAAU;eAEV,qBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,oBAAC,OAAD,EAAK,WAAU,6CAA8C;OAC7D,oBAAC,OAAD,EAAK,WAAU,6CAA8C;OAC7D,oBAAC,OAAD,EAAK,WAAU,6CAA8C;OACzD;;KACF,EARC,eAAe,KAAK,QAAQ,GAQ7B,CACN,CACE;;GAEN,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,OAAD,EAAK,WAAU,2CAA4C;KAC3D,oBAAC,OAAD,EAAK,WAAU,2CAA4C;KAC3D,oBAAC,OAAD,EAAK,WAAU,2CAA4C;KACvD;;GACF"}
1
+ {"version":3,"file":"loading.js","names":[],"sources":["../../../src/react/table/loading.tsx"],"sourcesContent":["export function LoadingSkeleton() {\n return (\n <div className=\"w-full space-y-3 mt-2\">\n <div className=\"flex items-center gap-2 mt-4\">\n <div className=\"h-10 bg-muted rounded animate-pulse flex-1 max-w-sm\" />\n <div className=\"h-10 bg-muted rounded animate-pulse w-24 ml-auto\" />\n </div>\n\n <div className=\"rounded-md border overflow-hidden\">\n <div className=\"border-b bg-secondary p-4\">\n <div className=\"flex gap-4\">\n <div className=\"h-8 bg-muted rounded animate-pulse flex-1\" />\n <div className=\"h-8 bg-muted rounded animate-pulse flex-1\" />\n <div className=\"h-8 bg-muted rounded animate-pulse flex-1\" />\n </div>\n </div>\n\n {Array.from({ length: 5 }).map(() => (\n <div\n key={`loading-row-${Math.random()}`}\n className=\"border-b p-4 last:border-b-0\"\n >\n <div className=\"flex gap-4\">\n <div className=\"h-6 bg-muted rounded animate-pulse flex-1\" />\n <div className=\"h-6 bg-muted rounded animate-pulse flex-1\" />\n <div className=\"h-6 bg-muted rounded animate-pulse flex-1\" />\n </div>\n </div>\n ))}\n </div>\n\n <div className=\"flex items-center justify-end gap-2\">\n <div className=\"h-4 bg-muted rounded animate-pulse w-32\" />\n <div className=\"h-9 bg-muted rounded animate-pulse w-20\" />\n <div className=\"h-9 bg-muted rounded animate-pulse w-20\" />\n </div>\n </div>\n );\n}\n"],"mappings":";;;AAAA,SAAgB,kBAAkB;AAChC,QACE,qBAAC;EAAI,WAAU;;GACb,qBAAC;IAAI,WAAU;eACb,oBAAC,SAAI,WAAU,wDAAwD,EACvE,oBAAC,SAAI,WAAU,qDAAqD;KAChE;GAEN,qBAAC;IAAI,WAAU;eACb,oBAAC;KAAI,WAAU;eACb,qBAAC;MAAI,WAAU;;OACb,oBAAC,SAAI,WAAU,8CAA8C;OAC7D,oBAAC,SAAI,WAAU,8CAA8C;OAC7D,oBAAC,SAAI,WAAU,8CAA8C;;OACzD;MACF,EAEL,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,UACzB,oBAAC;KAEC,WAAU;eAEV,qBAAC;MAAI,WAAU;;OACb,oBAAC,SAAI,WAAU,8CAA8C;OAC7D,oBAAC,SAAI,WAAU,8CAA8C;OAC7D,oBAAC,SAAI,WAAU,8CAA8C;;OACzD;OAPD,eAAe,KAAK,QAAQ,GAQ7B,CACN;KACE;GAEN,qBAAC;IAAI,WAAU;;KACb,oBAAC,SAAI,WAAU,4CAA4C;KAC3D,oBAAC,SAAI,WAAU,4CAA4C;KAC3D,oBAAC,SAAI,WAAU,4CAA4C;;KACvD;;GACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"table-wrapper.js","names":[],"sources":["../../../src/react/table/table-wrapper.tsx"],"sourcesContent":["import {\n type Column,\n type ColumnFiltersState,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type Row,\n type RowSelectionState,\n type SortingState,\n type Table,\n useReactTable,\n type VisibilityState,\n} from \"@tanstack/react-table\";\nimport { ArrowUpDown } from \"lucide-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useAnalyticsQuery } from \"..\";\nimport {\n formatChartValue,\n formatFieldLabel,\n SAFE_KEY_REGEX,\n} from \"../lib/format\";\nimport { Button } from \"../ui/button\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport { EmptyState } from \"./empty\";\nimport { ErrorState } from \"./error\";\nimport { LoadingSkeleton } from \"./loading\";\nimport type { TableWrapperProps } from \"./types\";\n\nconst CHECKBOX_COLUMN_WIDTH = 40;\n\n/**\n * Wrapper component for tables with automatic data fetching and state management\n * This component handles:\n * - Data fetching via useAnalyticsQuery\n * - Loading, error, and empty states with proper UI components\n * - Data transformation (optional)\n * - Dynamic column generation from data structure\n * - TanStack Table instance creation with all features (sorting, filtering, pagination, etc.)\n *\n * @template TRaw - The raw data type returned by the analytics query\n * @template TProcessed - The processed data type after transformation\n *\n * @param props - Props for the TableWrapper component\n * @param props.queryKey - The query key to fetch the data\n * @param props.parameters - The parameters to pass to the query\n * @param props.transformer - Optional function to transform raw data before creating table\n * @param props.children - Render function that receives the TanStack Table instance\n * @param props.className - Optional CSS class name for the wrapper\n * @param props.ariaLabel - Optional accessibility label\n * @param props.testId - Optional test ID for testing\n *\n * @returns The rendered table with state management\n */\nexport function TableWrapper<TRaw = any, TProcessed = any>(\n props: TableWrapperProps<TRaw, TProcessed>,\n) {\n const {\n queryKey,\n parameters,\n transformer,\n children,\n className,\n ariaLabel,\n testId,\n enableRowSelection = false,\n onRowSelectionChange,\n pageSize = 10,\n } = props;\n\n const [sorting, setSorting] = useState<SortingState>([]);\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n\n const { data, loading, error } = useAnalyticsQuery<TRaw[]>(\n queryKey,\n parameters,\n );\n\n useEffect(() => {\n if (onRowSelectionChange && enableRowSelection) {\n onRowSelectionChange(rowSelection);\n }\n }, [rowSelection, onRowSelectionChange, enableRowSelection]);\n\n const hasData = data && data.length > 0;\n\n const processedData = hasData\n ? transformer\n ? transformer(data)\n : (data as unknown as TProcessed[])\n : [];\n\n const tableColumns = useMemo(() => {\n if (!hasData) return [];\n\n if (!processedData[0] || typeof processedData[0] !== \"object\") {\n console.warn(\"Invalid data format for DataTable\");\n return [];\n }\n\n const dataColumns = Object.keys(processedData[0] as object)\n .filter((key) => SAFE_KEY_REGEX.test(key))\n .map((key) => {\n const formattedLabel = formatFieldLabel(key);\n return {\n accessorKey: key,\n header: ({ column }: { column: Column<TProcessed> }) => {\n return (\n <Button\n variant=\"ghost\"\n onClick={() =>\n column.toggleSorting(column.getIsSorted() === \"asc\")\n }\n className=\"h-8 px-2\"\n >\n {formattedLabel}\n <ArrowUpDown className=\"ml-2 h-4 w-4\" />\n </Button>\n );\n },\n cell: ({ row }: { row: Row<TProcessed> }) => {\n const value = row.getValue(key);\n if (typeof value === \"number\" || Number.isFinite(Number(value))) {\n return (\n <div className=\"text-right font-mono\">\n {formatChartValue(Number(value), key)}\n </div>\n );\n }\n return <div>{String(value)}</div>;\n },\n };\n });\n\n if (enableRowSelection) {\n return [\n {\n id: \"select\",\n maxSize: CHECKBOX_COLUMN_WIDTH,\n minSize: CHECKBOX_COLUMN_WIDTH,\n header: ({ table }: { table: Table<TProcessed> }) => (\n <div className=\"flex items-center justify-center\">\n <Checkbox\n checked={\n table.getIsAllPageRowsSelected() ||\n (table.getIsSomePageRowsSelected() && \"indeterminate\")\n }\n onCheckedChange={(value) =>\n table.toggleAllPageRowsSelected(!!value)\n }\n aria-label=\"Select all\"\n />\n </div>\n ),\n cell: ({ row }: { row: Row<TProcessed> }) => (\n <div className=\"flex items-center justify-center\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n </div>\n ),\n enableSorting: false,\n enableHiding: false,\n },\n ...dataColumns,\n ];\n }\n\n return dataColumns;\n }, [hasData, processedData, enableRowSelection]);\n\n const table = useReactTable({\n data: processedData,\n columns: tableColumns,\n onSortingChange: setSorting,\n onColumnFiltersChange: setColumnFilters,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: setColumnVisibility,\n onRowSelectionChange: setRowSelection,\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n },\n initialState: {\n pagination: {\n pageSize: pageSize,\n },\n },\n });\n\n if (loading) return <LoadingSkeleton />;\n if (error)\n return (\n <ErrorState error={typeof error === \"string\" ? error : \"Unknown error\"} />\n );\n\n if (!hasData) return <EmptyState />;\n\n return (\n <section className={className} aria-label={ariaLabel} data-testid={testId}>\n {children(table)}\n </section>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"table-wrapper.js","names":[],"sources":["../../../src/react/table/table-wrapper.tsx"],"sourcesContent":["import {\n type Column,\n type ColumnFiltersState,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type Row,\n type RowSelectionState,\n type SortingState,\n type Table,\n useReactTable,\n type VisibilityState,\n} from \"@tanstack/react-table\";\nimport { ArrowUpDown } from \"lucide-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useAnalyticsQuery } from \"..\";\nimport {\n formatChartValue,\n formatFieldLabel,\n SAFE_KEY_REGEX,\n} from \"../lib/format\";\nimport { Button } from \"../ui/button\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport { EmptyState } from \"./empty\";\nimport { ErrorState } from \"./error\";\nimport { LoadingSkeleton } from \"./loading\";\nimport type { TableWrapperProps } from \"./types\";\n\nconst CHECKBOX_COLUMN_WIDTH = 40;\n\n/**\n * Wrapper component for tables with automatic data fetching and state management\n * This component handles:\n * - Data fetching via useAnalyticsQuery\n * - Loading, error, and empty states with proper UI components\n * - Data transformation (optional)\n * - Dynamic column generation from data structure\n * - TanStack Table instance creation with all features (sorting, filtering, pagination, etc.)\n *\n * @template TRaw - The raw data type returned by the analytics query\n * @template TProcessed - The processed data type after transformation\n *\n * @param props - Props for the TableWrapper component\n * @param props.queryKey - The query key to fetch the data\n * @param props.parameters - The parameters to pass to the query\n * @param props.transformer - Optional function to transform raw data before creating table\n * @param props.children - Render function that receives the TanStack Table instance\n * @param props.className - Optional CSS class name for the wrapper\n * @param props.ariaLabel - Optional accessibility label\n * @param props.testId - Optional test ID for testing\n *\n * @returns The rendered table with state management\n */\nexport function TableWrapper<TRaw = any, TProcessed = any>(\n props: TableWrapperProps<TRaw, TProcessed>,\n) {\n const {\n queryKey,\n parameters,\n transformer,\n children,\n className,\n ariaLabel,\n testId,\n enableRowSelection = false,\n onRowSelectionChange,\n pageSize = 10,\n } = props;\n\n const [sorting, setSorting] = useState<SortingState>([]);\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);\n const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n\n const { data, loading, error } = useAnalyticsQuery<TRaw[]>(\n queryKey,\n parameters,\n );\n\n useEffect(() => {\n if (onRowSelectionChange && enableRowSelection) {\n onRowSelectionChange(rowSelection);\n }\n }, [rowSelection, onRowSelectionChange, enableRowSelection]);\n\n const hasData = data && data.length > 0;\n\n const processedData = hasData\n ? transformer\n ? transformer(data)\n : (data as unknown as TProcessed[])\n : [];\n\n const tableColumns = useMemo(() => {\n if (!hasData) return [];\n\n if (!processedData[0] || typeof processedData[0] !== \"object\") {\n console.warn(\"Invalid data format for DataTable\");\n return [];\n }\n\n const dataColumns = Object.keys(processedData[0] as object)\n .filter((key) => SAFE_KEY_REGEX.test(key))\n .map((key) => {\n const formattedLabel = formatFieldLabel(key);\n return {\n accessorKey: key,\n header: ({ column }: { column: Column<TProcessed> }) => {\n return (\n <Button\n variant=\"ghost\"\n onClick={() =>\n column.toggleSorting(column.getIsSorted() === \"asc\")\n }\n className=\"h-8 px-2\"\n >\n {formattedLabel}\n <ArrowUpDown className=\"ml-2 h-4 w-4\" />\n </Button>\n );\n },\n cell: ({ row }: { row: Row<TProcessed> }) => {\n const value = row.getValue(key);\n if (typeof value === \"number\" || Number.isFinite(Number(value))) {\n return (\n <div className=\"text-right font-mono\">\n {formatChartValue(Number(value), key)}\n </div>\n );\n }\n return <div>{String(value)}</div>;\n },\n };\n });\n\n if (enableRowSelection) {\n return [\n {\n id: \"select\",\n maxSize: CHECKBOX_COLUMN_WIDTH,\n minSize: CHECKBOX_COLUMN_WIDTH,\n header: ({ table }: { table: Table<TProcessed> }) => (\n <div className=\"flex items-center justify-center\">\n <Checkbox\n checked={\n table.getIsAllPageRowsSelected() ||\n (table.getIsSomePageRowsSelected() && \"indeterminate\")\n }\n onCheckedChange={(value) =>\n table.toggleAllPageRowsSelected(!!value)\n }\n aria-label=\"Select all\"\n />\n </div>\n ),\n cell: ({ row }: { row: Row<TProcessed> }) => (\n <div className=\"flex items-center justify-center\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n </div>\n ),\n enableSorting: false,\n enableHiding: false,\n },\n ...dataColumns,\n ];\n }\n\n return dataColumns;\n }, [hasData, processedData, enableRowSelection]);\n\n const table = useReactTable({\n data: processedData,\n columns: tableColumns,\n onSortingChange: setSorting,\n onColumnFiltersChange: setColumnFilters,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n getSortedRowModel: getSortedRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: setColumnVisibility,\n onRowSelectionChange: setRowSelection,\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n },\n initialState: {\n pagination: {\n pageSize: pageSize,\n },\n },\n });\n\n if (loading) return <LoadingSkeleton />;\n if (error)\n return (\n <ErrorState error={typeof error === \"string\" ? error : \"Unknown error\"} />\n );\n\n if (!hasData) return <EmptyState />;\n\n return (\n <section className={className} aria-label={ariaLabel} data-testid={testId}>\n {children(table)}\n </section>\n );\n}\n"],"mappings":"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"}