@databricks/appkit-ui 0.17.0 → 0.18.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 (42) hide show
  1. package/CLAUDE.md +1 -0
  2. package/dist/react/charts/base.js +3 -2
  3. package/dist/react/charts/base.js.map +1 -1
  4. package/dist/react/charts/normalize.d.ts.map +1 -1
  5. package/dist/react/charts/normalize.js +3 -1
  6. package/dist/react/charts/normalize.js.map +1 -1
  7. package/dist/react/charts/options.d.ts +1 -0
  8. package/dist/react/charts/options.d.ts.map +1 -1
  9. package/dist/react/charts/options.js +13 -8
  10. package/dist/react/charts/options.js.map +1 -1
  11. package/dist/react/charts/utils.d.ts.map +1 -1
  12. package/dist/react/charts/utils.js +23 -1
  13. package/dist/react/charts/utils.js.map +1 -1
  14. package/dist/react/genie/genie-chart-inference.d.ts +17 -0
  15. package/dist/react/genie/genie-chart-inference.d.ts.map +1 -0
  16. package/dist/react/genie/genie-chart-inference.js +75 -0
  17. package/dist/react/genie/genie-chart-inference.js.map +1 -0
  18. package/dist/react/genie/genie-chat-message.d.ts.map +1 -1
  19. package/dist/react/genie/genie-chat-message.js +26 -15
  20. package/dist/react/genie/genie-chat-message.js.map +1 -1
  21. package/dist/react/genie/genie-query-transform.d.ts +31 -0
  22. package/dist/react/genie/genie-query-transform.d.ts.map +1 -0
  23. package/dist/react/genie/genie-query-transform.js +79 -0
  24. package/dist/react/genie/genie-query-transform.js.map +1 -0
  25. package/dist/react/genie/genie-query-visualization.d.ts +25 -0
  26. package/dist/react/genie/genie-query-visualization.d.ts.map +1 -0
  27. package/dist/react/genie/genie-query-visualization.js +79 -0
  28. package/dist/react/genie/genie-query-visualization.js.map +1 -0
  29. package/dist/react/genie/index.d.ts +4 -1
  30. package/dist/react/genie/index.js +3 -0
  31. package/dist/react/genie/types.d.ts +2 -2
  32. package/dist/react/genie/types.d.ts.map +1 -1
  33. package/dist/react/index.d.ts +5 -2
  34. package/dist/react/index.js +6 -3
  35. package/dist/react/table/data-table.js +1 -1
  36. package/dist/react/ui/index.js +2 -2
  37. package/dist/shared/src/genie.d.ts +16 -2
  38. package/dist/shared/src/genie.d.ts.map +1 -1
  39. package/dist/shared/src/index.d.ts +1 -1
  40. package/docs/api/appkit-ui/genie/GenieQueryVisualization.md +29 -0
  41. package/llms.txt +1 -0
  42. package/package.json +1 -1
@@ -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;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
+ {"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 { GenieQueryVisualization } from \"./genie-query-visualization\";\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 const key = att.attachmentId ?? \"query\";\n const queryResult = att.attachmentId\n ? message.queryResults.get(att.attachmentId)\n : undefined;\n\n return (\n <div key={key} className=\"flex flex-col gap-2\">\n <Card className=\"px-4 py-3 text-xs overflow-hidden shadow-none\">\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 {queryResult != null && (\n <Card className=\"px-4 py-3 overflow-hidden\">\n <GenieQueryVisualization data={queryResult} />\n </Card>\n )}\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,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,QAAQ;KAC7B,MAAM,MAAM,IAAI,gBAAgB;KAChC,MAAM,cAAc,IAAI,eACpB,QAAQ,aAAa,IAAI,IAAI,aAAa,GAC1C;AAEJ,YACE,qBAAC;MAAc,WAAU;iBACvB,oBAAC;OAAK,WAAU;iBACd,qBAAC,wBACC,oBAAC;QAAQ,WAAU;kBAChB,IAAI,OAAO,SAAS;SACb,EACV,qBAAC;QAAI,WAAU;mBACZ,IAAI,OAAO,eACV,oBAAC;SAAK,WAAU;mBACb,IAAI,MAAM;UACN,EAER,IAAI,OAAO,SACV,oBAAC;SAAI,WAAU;mBACZ,IAAI,MAAM;UACP;SAEJ,IACE;QACL,EACN,eAAe,QACd,oBAAC;OAAK,WAAU;iBACd,oBAAC,2BAAwB,MAAM,cAAe;QACzC;QAvBD,IAyBJ;MAER;KACE;IAEJ;GACF"}
@@ -0,0 +1,31 @@
1
+ import { GenieStatementResponse } from "../../shared/src/genie.js";
2
+ import "../../shared/src/index.js";
3
+
4
+ //#region src/react/genie/genie-query-transform.d.ts
5
+ type ColumnCategory = "numeric" | "date" | "string";
6
+ interface GenieColumnMeta {
7
+ name: string;
8
+ typeName: string;
9
+ category: ColumnCategory;
10
+ }
11
+ interface TransformedGenieData {
12
+ rows: Record<string, unknown>[];
13
+ columns: GenieColumnMeta[];
14
+ }
15
+ /**
16
+ * Transform a Genie statement_response into chart-ready rows + column metadata.
17
+ *
18
+ * Expects `data` to have the shape:
19
+ * ```
20
+ * {
21
+ * manifest: { schema: { columns: [{ name, type_name }, ...] } },
22
+ * result: { data_array: [["val", ...], ...] }
23
+ * }
24
+ * ```
25
+ *
26
+ * Returns `null` when the data is empty or malformed.
27
+ */
28
+ declare function transformGenieData(data: GenieStatementResponse | null | undefined): TransformedGenieData | null;
29
+ //#endregion
30
+ export { ColumnCategory, GenieColumnMeta, TransformedGenieData, transformGenieData };
31
+ //# sourceMappingURL=genie-query-transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genie-query-transform.d.ts","names":[],"sources":["../../../src/react/genie/genie-query-transform.ts"],"mappings":";;;;KA8BY,cAAA;AAAA,UAEK,eAAA;EACf,IAAA;EACA,QAAA;EACA,QAAA,EAAU,cAAA;AAAA;AAAA,UAGK,oBAAA;EACf,IAAA,EAAM,MAAA;EACN,OAAA,EAAS,eAAA;AAAA;;;;;;AAuCX;;;;;;;;iBAAgB,kBAAA,CACd,IAAA,EAAM,sBAAA,sBACL,oBAAA"}
@@ -0,0 +1,79 @@
1
+ //#region src/react/genie/genie-query-transform.ts
2
+ const NUMERIC_SQL_TYPES = new Set([
3
+ "DECIMAL",
4
+ "INT",
5
+ "INTEGER",
6
+ "BIGINT",
7
+ "LONG",
8
+ "SMALLINT",
9
+ "TINYINT",
10
+ "FLOAT",
11
+ "DOUBLE",
12
+ "SHORT",
13
+ "BYTE"
14
+ ]);
15
+ const DATE_SQL_TYPES = new Set([
16
+ "DATE",
17
+ "TIMESTAMP",
18
+ "TIMESTAMP_NTZ"
19
+ ]);
20
+ /**
21
+ * Classify a SQL type_name into a high-level category.
22
+ */
23
+ function classifySqlType(typeName) {
24
+ const upper = typeName.toUpperCase();
25
+ if (NUMERIC_SQL_TYPES.has(upper)) return "numeric";
26
+ if (DATE_SQL_TYPES.has(upper)) return "date";
27
+ return "string";
28
+ }
29
+ /**
30
+ * Parse a single cell value based on its column category.
31
+ */
32
+ function parseValue(raw, category) {
33
+ if (raw == null) return null;
34
+ if (category === "numeric") {
35
+ const n = Number(raw);
36
+ return Number.isNaN(n) ? null : n;
37
+ }
38
+ return raw;
39
+ }
40
+ /**
41
+ * Transform a Genie statement_response into chart-ready rows + column metadata.
42
+ *
43
+ * Expects `data` to have the shape:
44
+ * ```
45
+ * {
46
+ * manifest: { schema: { columns: [{ name, type_name }, ...] } },
47
+ * result: { data_array: [["val", ...], ...] }
48
+ * }
49
+ * ```
50
+ *
51
+ * Returns `null` when the data is empty or malformed.
52
+ */
53
+ function transformGenieData(data) {
54
+ if (!data) return null;
55
+ const rawColumns = data.manifest?.schema?.columns;
56
+ if (!rawColumns || rawColumns.length === 0) return null;
57
+ const dataArray = data.result?.data_array;
58
+ if (!dataArray || dataArray.length === 0) return null;
59
+ const columns = rawColumns.map((col) => ({
60
+ name: col.name,
61
+ typeName: col.type_name,
62
+ category: classifySqlType(col.type_name)
63
+ }));
64
+ return {
65
+ rows: dataArray.map((row) => {
66
+ const record = {};
67
+ for (let i = 0; i < columns.length; i++) {
68
+ const col = columns[i];
69
+ record[col.name] = parseValue(row[i] ?? null, col.category);
70
+ }
71
+ return record;
72
+ }),
73
+ columns
74
+ };
75
+ }
76
+
77
+ //#endregion
78
+ export { transformGenieData };
79
+ //# sourceMappingURL=genie-query-transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genie-query-transform.js","names":[],"sources":["../../../src/react/genie/genie-query-transform.ts"],"sourcesContent":["/**\n * Converts Genie's statement_response data into a flat record array\n * suitable for charting.\n *\n * The Genie API returns `{ manifest.schema.columns, result.data_array }`\n * where each column carries a SQL `type_name`. This module parses values\n * according to those types so downstream chart code receives proper\n * numbers and strings.\n */\n\nimport type { GenieStatementResponse } from \"shared\";\n\n// SQL type_name values that map to numeric JS values\nconst NUMERIC_SQL_TYPES = new Set([\n \"DECIMAL\",\n \"INT\",\n \"INTEGER\",\n \"BIGINT\",\n \"LONG\",\n \"SMALLINT\",\n \"TINYINT\",\n \"FLOAT\",\n \"DOUBLE\",\n \"SHORT\",\n \"BYTE\",\n]);\n\n// SQL type_name values that map to date/timestamp strings\nconst DATE_SQL_TYPES = new Set([\"DATE\", \"TIMESTAMP\", \"TIMESTAMP_NTZ\"]);\n\nexport type ColumnCategory = \"numeric\" | \"date\" | \"string\";\n\nexport interface GenieColumnMeta {\n name: string;\n typeName: string;\n category: ColumnCategory;\n}\n\nexport interface TransformedGenieData {\n rows: Record<string, unknown>[];\n columns: GenieColumnMeta[];\n}\n\n/**\n * Classify a SQL type_name into a high-level category.\n */\nexport function classifySqlType(typeName: string): ColumnCategory {\n const upper = typeName.toUpperCase();\n if (NUMERIC_SQL_TYPES.has(upper)) return \"numeric\";\n if (DATE_SQL_TYPES.has(upper)) return \"date\";\n return \"string\";\n}\n\n/**\n * Parse a single cell value based on its column category.\n */\nfunction parseValue(raw: string | null, category: ColumnCategory): unknown {\n if (raw == null) return null;\n if (category === \"numeric\") {\n const n = Number(raw);\n return Number.isNaN(n) ? null : n;\n }\n // Dates and strings stay as strings — normalizeChartData detects ISO dates\n return raw;\n}\n\n/**\n * Transform a Genie statement_response into chart-ready rows + column metadata.\n *\n * Expects `data` to have the shape:\n * ```\n * {\n * manifest: { schema: { columns: [{ name, type_name }, ...] } },\n * result: { data_array: [[\"val\", ...], ...] }\n * }\n * ```\n *\n * Returns `null` when the data is empty or malformed.\n */\nexport function transformGenieData(\n data: GenieStatementResponse | null | undefined,\n): TransformedGenieData | null {\n if (!data) return null;\n\n const rawColumns = data.manifest?.schema?.columns;\n if (!rawColumns || rawColumns.length === 0) {\n return null;\n }\n\n const dataArray = data.result?.data_array;\n if (!dataArray || dataArray.length === 0) {\n return null;\n }\n\n const columns: GenieColumnMeta[] = rawColumns.map((col) => ({\n name: col.name,\n typeName: col.type_name,\n category: classifySqlType(col.type_name),\n }));\n\n const rows: Record<string, unknown>[] = dataArray.map((row) => {\n const record: Record<string, unknown> = {};\n for (let i = 0; i < columns.length; i++) {\n const col = columns[i];\n record[col.name] = parseValue(row[i] ?? null, col.category);\n }\n return record;\n });\n\n return { rows, columns };\n}\n"],"mappings":";AAaA,MAAM,oBAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAGF,MAAM,iBAAiB,IAAI,IAAI;CAAC;CAAQ;CAAa;CAAgB,CAAC;;;;AAkBtE,SAAgB,gBAAgB,UAAkC;CAChE,MAAM,QAAQ,SAAS,aAAa;AACpC,KAAI,kBAAkB,IAAI,MAAM,CAAE,QAAO;AACzC,KAAI,eAAe,IAAI,MAAM,CAAE,QAAO;AACtC,QAAO;;;;;AAMT,SAAS,WAAW,KAAoB,UAAmC;AACzE,KAAI,OAAO,KAAM,QAAO;AACxB,KAAI,aAAa,WAAW;EAC1B,MAAM,IAAI,OAAO,IAAI;AACrB,SAAO,OAAO,MAAM,EAAE,GAAG,OAAO;;AAGlC,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,mBACd,MAC6B;AAC7B,KAAI,CAAC,KAAM,QAAO;CAElB,MAAM,aAAa,KAAK,UAAU,QAAQ;AAC1C,KAAI,CAAC,cAAc,WAAW,WAAW,EACvC,QAAO;CAGT,MAAM,YAAY,KAAK,QAAQ;AAC/B,KAAI,CAAC,aAAa,UAAU,WAAW,EACrC,QAAO;CAGT,MAAM,UAA6B,WAAW,KAAK,SAAS;EAC1D,MAAM,IAAI;EACV,UAAU,IAAI;EACd,UAAU,gBAAgB,IAAI,UAAU;EACzC,EAAE;AAWH,QAAO;EAAE,MAT+B,UAAU,KAAK,QAAQ;GAC7D,MAAM,SAAkC,EAAE;AAC1C,QAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;IACvC,MAAM,MAAM,QAAQ;AACpB,WAAO,IAAI,QAAQ,WAAW,IAAI,MAAM,MAAM,IAAI,SAAS;;AAE7D,UAAO;IACP;EAEa;EAAS"}
@@ -0,0 +1,25 @@
1
+ import { GenieStatementResponse } from "../../shared/src/genie.js";
2
+ import "../../shared/src/index.js";
3
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
4
+
5
+ //#region src/react/genie/genie-query-visualization.d.ts
6
+ interface GenieQueryVisualizationProps {
7
+ /** Raw statement_response from the Genie API */
8
+ data: GenieStatementResponse;
9
+ /** Additional CSS classes */
10
+ className?: string;
11
+ }
12
+ /**
13
+ * Renders a chart + data table for a Genie query result.
14
+ *
15
+ * - When a chart type can be inferred: shows Tabs with "Chart" (default) and "Table"
16
+ * - When no chart fits: shows only the data table
17
+ * - When data is empty/malformed: renders nothing
18
+ */
19
+ declare function GenieQueryVisualization({
20
+ data,
21
+ className
22
+ }: GenieQueryVisualizationProps): react_jsx_runtime0.JSX.Element | null;
23
+ //#endregion
24
+ export { GenieQueryVisualization };
25
+ //# sourceMappingURL=genie-query-visualization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genie-query-visualization.d.ts","names":[],"sources":["../../../src/react/genie/genie-query-visualization.tsx"],"mappings":";;;;;UAmBiB,4BAAA;;EAEf,IAAA,EAAM,sBAAA;;EAEN,SAAA;AAAA;;;;;;;;iBAUc,uBAAA,CAAA;EACd,IAAA;EACA;AAAA,GACC,4BAAA,GAA4B,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,79 @@
1
+ import { BaseChart } from "../charts/base.js";
2
+ import { ChartErrorBoundary } from "../charts/chart-error-boundary.js";
3
+ import { inferChartType } from "./genie-chart-inference.js";
4
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../ui/table.js";
5
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs.js";
6
+ import { transformGenieData } from "./genie-query-transform.js";
7
+ import { useMemo } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+
10
+ //#region src/react/genie/genie-query-visualization.tsx
11
+ const TABLE_ROW_LIMIT = 50;
12
+ const CHART_HEIGHT = 250;
13
+ /**
14
+ * Renders a chart + data table for a Genie query result.
15
+ *
16
+ * - When a chart type can be inferred: shows Tabs with "Chart" (default) and "Table"
17
+ * - When no chart fits: shows only the data table
18
+ * - When data is empty/malformed: renders nothing
19
+ */
20
+ function GenieQueryVisualization({ data, className }) {
21
+ const transformed = useMemo(() => transformGenieData(data), [data]);
22
+ const inference = useMemo(() => transformed ? inferChartType(transformed.rows, transformed.columns) : null, [transformed]);
23
+ if (!transformed || transformed.rows.length === 0) return null;
24
+ const { rows, columns } = transformed;
25
+ const truncated = rows.length > TABLE_ROW_LIMIT;
26
+ const displayRows = truncated ? rows.slice(0, TABLE_ROW_LIMIT) : rows;
27
+ const dataTable = /* @__PURE__ */ jsxs("div", {
28
+ className: "overflow-auto max-h-[300px]",
29
+ children: [/* @__PURE__ */ jsxs(Table, { children: [/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsx(TableRow, { children: columns.map((col) => /* @__PURE__ */ jsx(TableHead, { children: col.name }, col.name)) }) }), /* @__PURE__ */ jsx(TableBody, { children: displayRows.map((row, i) => /* @__PURE__ */ jsx(TableRow, { children: columns.map((col) => /* @__PURE__ */ jsx(TableCell, { children: row[col.name] != null ? String(row[col.name]) : "" }, col.name)) }, i)) })] }), truncated && /* @__PURE__ */ jsxs("p", {
30
+ className: "text-xs text-muted-foreground px-2 py-1",
31
+ children: [
32
+ "Showing ",
33
+ TABLE_ROW_LIMIT,
34
+ " of ",
35
+ rows.length,
36
+ " rows"
37
+ ]
38
+ })]
39
+ });
40
+ if (!inference) return /* @__PURE__ */ jsx("div", {
41
+ className,
42
+ children: dataTable
43
+ });
44
+ return /* @__PURE__ */ jsxs(Tabs, {
45
+ defaultValue: "chart",
46
+ className,
47
+ children: [
48
+ /* @__PURE__ */ jsxs(TabsList, { children: [/* @__PURE__ */ jsx(TabsTrigger, {
49
+ value: "chart",
50
+ children: "Chart"
51
+ }), /* @__PURE__ */ jsx(TabsTrigger, {
52
+ value: "table",
53
+ children: "Table"
54
+ })] }),
55
+ /* @__PURE__ */ jsx(TabsContent, {
56
+ value: "chart",
57
+ children: /* @__PURE__ */ jsx(ChartErrorBoundary, {
58
+ fallback: dataTable,
59
+ children: /* @__PURE__ */ jsx(BaseChart, {
60
+ data: rows,
61
+ chartType: inference.chartType,
62
+ xKey: inference.xKey,
63
+ yKey: inference.yKey,
64
+ height: CHART_HEIGHT,
65
+ showLegend: Array.isArray(inference.yKey)
66
+ })
67
+ })
68
+ }),
69
+ /* @__PURE__ */ jsx(TabsContent, {
70
+ value: "table",
71
+ children: dataTable
72
+ })
73
+ ]
74
+ });
75
+ }
76
+
77
+ //#endregion
78
+ export { GenieQueryVisualization };
79
+ //# sourceMappingURL=genie-query-visualization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genie-query-visualization.js","names":[],"sources":["../../../src/react/genie/genie-query-visualization.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { GenieStatementResponse } from \"shared\";\nimport { BaseChart } from \"../charts/base\";\nimport { ChartErrorBoundary } from \"../charts/chart-error-boundary\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"../ui/table\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../ui/tabs\";\nimport { inferChartType } from \"./genie-chart-inference\";\nimport { transformGenieData } from \"./genie-query-transform\";\n\nconst TABLE_ROW_LIMIT = 50;\nconst CHART_HEIGHT = 250;\n\nexport interface GenieQueryVisualizationProps {\n /** Raw statement_response from the Genie API */\n data: GenieStatementResponse;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Renders a chart + data table for a Genie query result.\n *\n * - When a chart type can be inferred: shows Tabs with \"Chart\" (default) and \"Table\"\n * - When no chart fits: shows only the data table\n * - When data is empty/malformed: renders nothing\n */\nexport function GenieQueryVisualization({\n data,\n className,\n}: GenieQueryVisualizationProps) {\n const transformed = useMemo(() => transformGenieData(data), [data]);\n const inference = useMemo(\n () =>\n transformed\n ? inferChartType(transformed.rows, transformed.columns)\n : null,\n [transformed],\n );\n\n if (!transformed || transformed.rows.length === 0) return null;\n\n const { rows, columns } = transformed;\n const truncated = rows.length > TABLE_ROW_LIMIT;\n const displayRows = truncated ? rows.slice(0, TABLE_ROW_LIMIT) : rows;\n\n const dataTable = (\n <div className=\"overflow-auto max-h-[300px]\">\n <Table>\n <TableHeader>\n <TableRow>\n {columns.map((col) => (\n <TableHead key={col.name}>{col.name}</TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {displayRows.map((row, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: tabular data rows have no unique identifier\n <TableRow key={i}>\n {columns.map((col) => (\n <TableCell key={col.name}>\n {row[col.name] != null ? String(row[col.name]) : \"\"}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableBody>\n </Table>\n {truncated && (\n <p className=\"text-xs text-muted-foreground px-2 py-1\">\n Showing {TABLE_ROW_LIMIT} of {rows.length} rows\n </p>\n )}\n </div>\n );\n\n if (!inference) {\n return <div className={className}>{dataTable}</div>;\n }\n\n return (\n <Tabs defaultValue=\"chart\" className={className}>\n <TabsList>\n <TabsTrigger value=\"chart\">Chart</TabsTrigger>\n <TabsTrigger value=\"table\">Table</TabsTrigger>\n </TabsList>\n <TabsContent value=\"chart\">\n <ChartErrorBoundary fallback={dataTable}>\n <BaseChart\n data={rows}\n chartType={inference.chartType}\n xKey={inference.xKey}\n yKey={inference.yKey}\n height={CHART_HEIGHT}\n showLegend={Array.isArray(inference.yKey)}\n />\n </ChartErrorBoundary>\n </TabsContent>\n <TabsContent value=\"table\">{dataTable}</TabsContent>\n </Tabs>\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,MAAM,kBAAkB;AACxB,MAAM,eAAe;;;;;;;;AAgBrB,SAAgB,wBAAwB,EACtC,MACA,aAC+B;CAC/B,MAAM,cAAc,cAAc,mBAAmB,KAAK,EAAE,CAAC,KAAK,CAAC;CACnE,MAAM,YAAY,cAEd,cACI,eAAe,YAAY,MAAM,YAAY,QAAQ,GACrD,MACN,CAAC,YAAY,CACd;AAED,KAAI,CAAC,eAAe,YAAY,KAAK,WAAW,EAAG,QAAO;CAE1D,MAAM,EAAE,MAAM,YAAY;CAC1B,MAAM,YAAY,KAAK,SAAS;CAChC,MAAM,cAAc,YAAY,KAAK,MAAM,GAAG,gBAAgB,GAAG;CAEjE,MAAM,YACJ,qBAAC;EAAI,WAAU;aACb,qBAAC,oBACC,oBAAC,yBACC,oBAAC,sBACE,QAAQ,KAAK,QACZ,oBAAC,uBAA0B,IAAI,QAAf,IAAI,KAA4B,CAChD,GACO,GACC,EACd,oBAAC,uBACE,YAAY,KAAK,KAAK,MAErB,oBAAC,sBACE,QAAQ,KAAK,QACZ,oBAAC,uBACE,IAAI,IAAI,SAAS,OAAO,OAAO,IAAI,IAAI,MAAM,GAAG,MADnC,IAAI,KAER,CACZ,IALW,EAMJ,CACX,GACQ,IACN,EACP,aACC,qBAAC;GAAE,WAAU;;IAA0C;IAC5C;IAAgB;IAAK,KAAK;IAAO;;IACxC;GAEF;AAGR,KAAI,CAAC,UACH,QAAO,oBAAC;EAAe;YAAY;GAAgB;AAGrD,QACE,qBAAC;EAAK,cAAa;EAAmB;;GACpC,qBAAC,uBACC,oBAAC;IAAY,OAAM;cAAQ;KAAmB,EAC9C,oBAAC;IAAY,OAAM;cAAQ;KAAmB,IACrC;GACX,oBAAC;IAAY,OAAM;cACjB,oBAAC;KAAmB,UAAU;eAC5B,oBAAC;MACC,MAAM;MACN,WAAW,UAAU;MACrB,MAAM,UAAU;MAChB,MAAM,UAAU;MAChB,QAAQ;MACR,YAAY,MAAM,QAAQ,UAAU,KAAK;OACzC;MACiB;KACT;GACd,oBAAC;IAAY,OAAM;cAAS;KAAwB;;GAC/C"}
@@ -1,7 +1,10 @@
1
- import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
1
+ import { GenieAttachmentResponse, GenieMessageResponse, GenieStatementResponse, GenieStreamEvent } from "../../shared/src/genie.js";
2
+ import { ColumnCategory, GenieColumnMeta, TransformedGenieData, transformGenieData } from "./genie-query-transform.js";
3
+ import { ChartInference, inferChartType } from "./genie-chart-inference.js";
2
4
  import { GenieChatProps, GenieChatStatus, GenieMessageItem, UseGenieChatOptions, UseGenieChatReturn } from "./types.js";
3
5
  import { GenieChat } from "./genie-chat.js";
4
6
  import { GenieChatInput } from "./genie-chat-input.js";
5
7
  import { GenieChatMessage } from "./genie-chat-message.js";
6
8
  import { GenieChatMessageList } from "./genie-chat-message-list.js";
9
+ import { GenieQueryVisualization } from "./genie-query-visualization.js";
7
10
  import { useGenieChat } from "./use-genie-chat.js";
@@ -1,4 +1,7 @@
1
+ import { inferChartType } from "./genie-chart-inference.js";
1
2
  import { GenieChatInput } from "./genie-chat-input.js";
3
+ import { transformGenieData } from "./genie-query-transform.js";
4
+ import { GenieQueryVisualization } from "./genie-query-visualization.js";
2
5
  import { GenieChatMessage } from "./genie-chat-message.js";
3
6
  import { GenieChatMessageList } from "./genie-chat-message-list.js";
4
7
  import { useGenieChat } from "./use-genie-chat.js";
@@ -1,4 +1,4 @@
1
- import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
1
+ import { GenieAttachmentResponse, GenieMessageResponse, GenieStatementResponse, GenieStreamEvent } from "../../shared/src/genie.js";
2
2
  import "../../shared/src/index.js";
3
3
 
4
4
  //#region src/react/genie/types.d.ts
@@ -9,7 +9,7 @@ interface GenieMessageItem {
9
9
  content: string;
10
10
  status: string;
11
11
  attachments: GenieAttachmentResponse[];
12
- queryResults: Map<string, unknown>;
12
+ queryResults: Map<string, GenieStatementResponse>;
13
13
  error?: string;
14
14
  }
15
15
  interface UseGenieChatOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/genie/types.ts"],"mappings":";;;;KAQY,eAAA;AAAA,UAOK,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;EAbA;EAeA,eAAA;EAXA;EAaA,sBAAA;EAbY;EAeZ,iBAAA;AAAA;AAAA,UAGe,cAAA;EAbQ;EAevB,KAAA;EAhBU;EAkBV,QAAA;EAjBQ;EAmBR,WAAA;EAjBA;EAmBA,SAAA;AAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/genie/types.ts"],"mappings":";;;;KASY,eAAA;AAAA,UAOK,gBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;EACA,MAAA;EACA,WAAA,EAAa,uBAAA;EACb,YAAA,EAAc,GAAA,SAAY,sBAAA;EAC1B,KAAA;AAAA;AAAA,UAGe,mBAAA;EAJW;EAM1B,KAAA;EANiB;EAQjB,QAAA;EAbA;EAeA,YAAA;EAbA;EAeA,YAAA;AAAA;AAAA,UAGe,kBAAA;EACf,QAAA,EAAU,gBAAA;EACV,MAAA,EAAQ,eAAA;EACR,cAAA;EACA,KAAA;EACA,WAAA,GAAc,OAAA;EACd,KAAA;EAjBe;EAmBf,eAAA;;EAEA,sBAAA;EAnBA;EAqBA,iBAAA;AAAA;AAAA,UAGe,cAAA;EAlBH;EAoBZ,KAAA;EAjBe;EAmBf,QAAA;;EAEA,WAAA;EApBA;EAsBA,SAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../shared/src/genie.js";
1
+ import { GenieAttachmentResponse, GenieMessageResponse, GenieStatementResponse, GenieStreamEvent } from "../shared/src/genie.js";
2
2
  import { DATE_FIELD_PATTERNS, METADATA_DATE_PATTERNS, NAME_FIELD_PATTERNS } from "../js/constants.js";
3
3
  import { AreaChartProps, AreaChartSpecificProps, BarChartProps, BarChartSpecificProps, ChartBaseProps, ChartColorPalette, ChartData, ChartType, DataFormat, DataProps, DonutChartProps, HeatmapChartProps, HeatmapChartSpecificProps, LineChartProps, LineChartSpecificProps, NormalizedChartData, NormalizedChartDataBase, Orientation, PieChartProps, PieChartSpecificProps, QueryProps, RadarChartProps, RadarChartSpecificProps, ScatterChartProps, ScatterChartSpecificProps, UnifiedChartProps, isArrowTable, isDataProps, isQueryProps } from "./charts/types.js";
4
4
  import { AreaChart } from "./charts/area/index.js";
@@ -18,11 +18,14 @@ 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
20
  import "./charts/index.js";
21
+ import { ColumnCategory, GenieColumnMeta, TransformedGenieData, transformGenieData } from "./genie/genie-query-transform.js";
22
+ import { ChartInference, inferChartType } from "./genie/genie-chart-inference.js";
21
23
  import { GenieChatProps, GenieChatStatus, GenieMessageItem, UseGenieChatOptions, UseGenieChatReturn } from "./genie/types.js";
22
24
  import { GenieChat } from "./genie/genie-chat.js";
23
25
  import { GenieChatInput } from "./genie/genie-chat-input.js";
24
26
  import { GenieChatMessage } from "./genie/genie-chat-message.js";
25
27
  import { GenieChatMessageList } from "./genie/genie-chat-message-list.js";
28
+ import { GenieQueryVisualization } from "./genie/genie-query-visualization.js";
26
29
  import { useGenieChat } from "./genie/use-genie-chat.js";
27
30
  import "./genie/index.js";
28
31
  import { AnalyticsFormat, InferResultByFormat, InferRowType, PluginRegistry, QueryRegistry, TypedArrowTable, UseAnalyticsQueryOptions, UseAnalyticsQueryResult } from "./hooks/types.js";
@@ -86,4 +89,4 @@ import { Textarea } from "./ui/textarea.js";
86
89
  import { Toggle, toggleVariants } from "./ui/toggle.js";
87
90
  import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group.js";
88
91
  import "./ui/index.js";
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 };
92
+ 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, ChartInference, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChartType, ChartWrapper, ChartWrapperProps, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, ColumnCategory, 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, GenieColumnMeta, GenieMessageItem, GenieMessageResponse, GenieQueryVisualization, GenieStatementResponse, 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, TransformedGenieData, TypedArrowTable, UnifiedChartProps, UseAnalyticsQueryOptions, UseAnalyticsQueryResult, UseChartDataOptions, UseChartDataResult, UseGenieChatOptions, UseGenieChatReturn, badgeVariants, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption, buttonGroupVariants, buttonVariants, cn, createChart, createTimeSeriesData, formatLabel, inferChartType, isArrowTable, isDataProps, isQueryProps, navigationMenuTriggerStyle, normalizeChartData, normalizeHeatmapData, sortTimeSeriesAscending, toChartArray, toChartValue, toggleVariants, transformGenieData, truncateLabel, useAllThemeColors, useAnalyticsQuery, useChartData, useFormField, useGenieChat, usePortalContainer, useResolvedPortalContainer, useSidebar, useThemeColors };
@@ -18,6 +18,7 @@ import { DonutChart, PieChart } from "./charts/pie/index.js";
18
18
  import { RadarChart } from "./charts/radar/index.js";
19
19
  import { ScatterChart } from "./charts/scatter/index.js";
20
20
  import "./charts/index.js";
21
+ import { inferChartType } from "./genie/genie-chart-inference.js";
21
22
  import { cn } from "./lib/utils.js";
22
23
  import { Button, buttonVariants } from "./ui/button.js";
23
24
  import { GenieChatInput } from "./genie/genie-chat-input.js";
@@ -26,6 +27,10 @@ import { Skeleton } from "./ui/skeleton.js";
26
27
  import { Spinner } from "./ui/spinner.js";
27
28
  import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar.js";
28
29
  import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./ui/card.js";
30
+ import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "./ui/table.js";
31
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs.js";
32
+ import { transformGenieData } from "./genie/genie-query-transform.js";
33
+ import { GenieQueryVisualization } from "./genie/genie-query-visualization.js";
29
34
  import { GenieChatMessage } from "./genie/genie-chat-message.js";
30
35
  import { GenieChatMessageList } from "./genie/genie-chat-message-list.js";
31
36
  import { useGenieChat } from "./genie/use-genie-chat.js";
@@ -36,7 +41,6 @@ import { PortalContainerContext, PortalContainerProvider, usePortalContainer, us
36
41
  import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "./ui/dropdown-menu.js";
37
42
  import { Input } from "./ui/input.js";
38
43
  import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from "./ui/select.js";
39
- import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "./ui/table.js";
40
44
  import { Checkbox } from "./ui/checkbox.js";
41
45
  import { DataTable } from "./table/data-table.js";
42
46
  import "./table/index.js";
@@ -79,9 +83,8 @@ import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupActio
79
83
  import { Slider } from "./ui/slider.js";
80
84
  import { Toaster } from "./ui/sonner.js";
81
85
  import { Switch } from "./ui/switch.js";
82
- import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs.js";
83
86
  import { Toggle, toggleVariants } from "./ui/toggle.js";
84
87
  import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group.js";
85
88
  import "./ui/index.js";
86
89
 
87
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AreaChart, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BarChart, BaseChart, 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, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChartWrapper, 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, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DonutChart, 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, GenieChat, GenieChatInput, GenieChatMessage, GenieChatMessageList, HeatmapChart, HoverCard, HoverCardContent, HoverCardTrigger, 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, 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, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PieChart, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalContainerContext, PortalContainerProvider, Progress, RadarChart, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScatterChart, 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, 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 };
90
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AreaChart, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BarChart, BaseChart, 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, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChartWrapper, 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, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DonutChart, 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, GenieChat, GenieChatInput, GenieChatMessage, GenieChatMessageList, GenieQueryVisualization, HeatmapChart, HoverCard, HoverCardContent, HoverCardTrigger, 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, 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, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PieChart, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalContainerContext, PortalContainerProvider, Progress, RadarChart, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScatterChart, 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, badgeVariants, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption, buttonGroupVariants, buttonVariants, cn, createChart, createTimeSeriesData, formatLabel, inferChartType, isArrowTable, isDataProps, isQueryProps, navigationMenuTriggerStyle, normalizeChartData, normalizeHeatmapData, sortTimeSeriesAscending, toChartArray, toChartValue, toggleVariants, transformGenieData, truncateLabel, useAllThemeColors, useAnalyticsQuery, useChartData, useFormField, useGenieChat, usePortalContainer, useResolvedPortalContainer, useSidebar, useThemeColors };
@@ -1,9 +1,9 @@
1
1
  import { Button } from "../ui/button.js";
2
+ import { Table as Table$1, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../ui/table.js";
2
3
  import { formatFieldLabel } from "../lib/format.js";
3
4
  import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuTrigger } from "../ui/dropdown-menu.js";
4
5
  import { Input } from "../ui/input.js";
5
6
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select.js";
6
- import { Table as Table$1, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../ui/table.js";
7
7
  import { TableWrapper } from "./table-wrapper.js";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { ChevronDown } from "lucide-react";
@@ -4,10 +4,11 @@ import { Skeleton } from "./skeleton.js";
4
4
  import { Spinner } from "./spinner.js";
5
5
  import { Avatar, AvatarFallback, AvatarImage } from "./avatar.js";
6
6
  import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./card.js";
7
+ import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "./table.js";
8
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "./tabs.js";
7
9
  import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "./dropdown-menu.js";
8
10
  import { Input } from "./input.js";
9
11
  import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from "./select.js";
10
- import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "./table.js";
11
12
  import { Checkbox } from "./checkbox.js";
12
13
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./accordion.js";
13
14
  import { Alert, AlertDescription, AlertTitle } from "./alert.js";
@@ -48,6 +49,5 @@ import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupActio
48
49
  import { Slider } from "./slider.js";
49
50
  import { Toaster } from "./sonner.js";
50
51
  import { Switch } from "./switch.js";
51
- import { Tabs, TabsContent, TabsList, TabsTrigger } from "./tabs.js";
52
52
  import { Toggle, toggleVariants } from "./toggle.js";
53
53
  import { ToggleGroup, ToggleGroupItem } from "./toggle-group.js";
@@ -15,7 +15,7 @@ type GenieStreamEvent = {
15
15
  type: "query_result";
16
16
  attachmentId: string;
17
17
  statementId: string;
18
- data: unknown;
18
+ data: GenieStatementResponse;
19
19
  } | {
20
20
  type: "error";
21
21
  error: string;
@@ -26,6 +26,20 @@ type GenieStreamEvent = {
26
26
  nextPageToken: string | null; /** Total messages returned in this initial load */
27
27
  loadedCount: number;
28
28
  };
29
+ /** Shape of the Databricks SQL statement_response returned by Genie queries */
30
+ interface GenieStatementResponse {
31
+ manifest: {
32
+ schema: {
33
+ columns: Array<{
34
+ name: string;
35
+ type_name: string;
36
+ }>;
37
+ };
38
+ };
39
+ result: {
40
+ data_array: (string | null)[][];
41
+ };
42
+ }
29
43
  /** Cleaned response — subset of SDK GenieMessage */
30
44
  interface GenieMessageResponse {
31
45
  messageId: string;
@@ -50,5 +64,5 @@ interface GenieAttachmentResponse {
50
64
  suggestedQuestions?: string[];
51
65
  }
52
66
  //#endregion
53
- export { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent };
67
+ export { GenieAttachmentResponse, GenieMessageResponse, GenieStatementResponse, GenieStreamEvent };
54
68
  //# sourceMappingURL=genie.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"genie.d.ts","names":[],"sources":["../../../../shared/src/genie.ts"],"mappings":";;KACY,gBAAA;EAEN,IAAA;EACA,cAAA;EACA,SAAA;EACA,OAAA;AAAA;EAEA,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;EAAwB,OAAA,EAAS,oBAAA;AAAA;EAEjC,IAAA;EACA,YAAA;EACA,WAAA;EACA,IAAA;AAAA;EAEA,IAAA;EAAe,KAAA;AAAA;EAEf,IAAA;EACA,cAAA;EACA,OAAA,UAIA;EAFA,aAAA,iBAEW;EAAX,WAAA;AAAA;;UAIW,oBAAA;EACf,SAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EACA,WAAA,GAAc,uBAAA;EACd,KAAA;AAAA;AAAA,UAGe,uBAAA;EACf,YAAA;EACA,KAAA;IACE,KAAA;IACA,WAAA;IACA,KAAA;IACA,WAAA;EAAA;EAEF,IAAA;IAAS,OAAA;EAAA;EACT,kBAAA;AAAA"}
1
+ {"version":3,"file":"genie.d.ts","names":[],"sources":["../../../../shared/src/genie.ts"],"mappings":";;KACY,gBAAA;EAEN,IAAA;EACA,cAAA;EACA,SAAA;EACA,OAAA;AAAA;EAEA,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;EAAwB,OAAA,EAAS,oBAAA;AAAA;EAEjC,IAAA;EACA,YAAA;EACA,WAAA;EACA,IAAA,EAAM,sBAAA;AAAA;EAEN,IAAA;EAAe,KAAA;AAAA;EAEf,IAAA;EACA,cAAA;EACA,OAAA,UAEA;EAAA,aAAA,iBAEW;EAAX,WAAA;AAAA;;UAIW,sBAAA;EACf,QAAA;IACE,MAAA;MACE,OAAA,EAAS,KAAA;QAAQ,IAAA;QAAc,SAAA;MAAA;IAAA;EAAA;EAGnC,MAAA;IACE,UAAA;EAAA;AAAA;;UAKa,oBAAA;EACf,SAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EACA,WAAA,GAAc,uBAAA;EACd,KAAA;AAAA;AAAA,UAGe,uBAAA;EACf,YAAA;EACA,KAAA;IACE,KAAA;IACA,WAAA;IACA,KAAA;IACA,WAAA;EAAA;EAEF,IAAA;IAAS,OAAA;EAAA;EACT,kBAAA;AAAA"}
@@ -1,7 +1,7 @@
1
1
  import "./plugin.js";
2
2
  import "./cache.js";
3
3
  import "./execute.js";
4
- import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "./genie.js";
4
+ import { GenieAttachmentResponse, GenieMessageResponse, GenieStatementResponse, GenieStreamEvent } from "./genie.js";
5
5
  import { SQLBinaryMarker, SQLBooleanMarker, SQLDateMarker, SQLNumberMarker, SQLStringMarker, SQLTimestampMarker, SQLTypeMarker } from "./sql/types.js";
6
6
  import { isSQLTypeMarker, sql } from "./sql/helpers.js";
7
7
  import "./tunnel.js";
@@ -0,0 +1,29 @@
1
+ # GenieQueryVisualization
2
+
3
+ Renders a chart + data table for a Genie query result.
4
+
5
+ ## GenieQueryVisualization[​](#geniequeryvisualization-1 "Direct link to GenieQueryVisualization")
6
+
7
+ Renders a chart + data table for a Genie query result.
8
+
9
+ * When a chart type can be inferred: shows Tabs with "Chart" (default) and "Table"
10
+ * When no chart fits: shows only the data table
11
+ * When data is empty/malformed: renders nothing
12
+
13
+ **Source:** [`packages/appkit-ui/src/react/genie/genie-query-visualization.tsx`](https://github.com/databricks/appkit/blob/main/packages/appkit-ui/src/react/genie/genie-query-visualization.tsx)
14
+
15
+ ### Props[​](#props "Direct link to Props")
16
+
17
+ | Prop | Type | Required | Default | Description |
18
+ | ----------- | ------------------------ | -------- | ------- | ------------------------------------------ |
19
+ | `data` | `GenieStatementResponse` | ✓ | - | Raw statement\_response from the Genie API |
20
+ | `className` | `string` | | - | Additional CSS classes |
21
+
22
+ ### Usage[​](#usage "Direct link to Usage")
23
+
24
+ ```tsx
25
+ import { GenieQueryVisualization } from '@databricks/appkit-ui';
26
+
27
+ <GenieQueryVisualization /* props */ />
28
+
29
+ ```
package/llms.txt CHANGED
@@ -114,6 +114,7 @@ npx @databricks/appkit docs <query>
114
114
  - [GenieChatInput](./docs/api/appkit-ui/genie/GenieChatInput.md): Auto-expanding textarea input with a send button for chat messages. Submits on Enter (Shift+Enter for newline).
115
115
  - [GenieChatMessage](./docs/api/appkit-ui/genie/GenieChatMessage.md): Renders a single Genie message bubble with optional expandable SQL query attachments.
116
116
  - [GenieChatMessageList](./docs/api/appkit-ui/genie/GenieChatMessageList.md): Scrollable message list that renders Genie chat messages with auto-scroll, skeleton loaders, and a streaming indicator.
117
+ - [GenieQueryVisualization](./docs/api/appkit-ui/genie/GenieQueryVisualization.md): Renders a chart + data table for a Genie query result.
117
118
  - [Styling](./docs/api/appkit-ui/styling.md): This guide covers how to style AppKit UI components using CSS variables and theming.
118
119
  - [Accordion](./docs/api/appkit-ui/ui/Accordion.md): Collapsible content sections organized in a vertical stack
119
120
  - [Alert](./docs/api/appkit-ui/ui/Alert.md): Displays important information with optional icon and multiple variants
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@databricks/appkit-ui",
3
3
  "type": "module",
4
- "version": "0.17.0",
4
+ "version": "0.18.0",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",