@useatlas/react 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +95 -0
  2. package/dist/chunk-2WFDP7G5.js +231 -0
  3. package/dist/chunk-2WFDP7G5.js.map +1 -0
  4. package/dist/chunk-44HBZYKP.js +224 -0
  5. package/dist/chunk-44HBZYKP.js.map +1 -0
  6. package/dist/chunk-5SEVKHS5.cjs +229 -0
  7. package/dist/chunk-5SEVKHS5.cjs.map +1 -0
  8. package/dist/chunk-UIRB6L36.cjs +249 -0
  9. package/dist/chunk-UIRB6L36.cjs.map +1 -0
  10. package/dist/hooks.cjs +251 -0
  11. package/dist/hooks.cjs.map +1 -0
  12. package/dist/hooks.d.cts +132 -0
  13. package/dist/hooks.d.ts +132 -0
  14. package/dist/hooks.js +237 -0
  15. package/dist/hooks.js.map +1 -0
  16. package/dist/index.cjs +2976 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.cts +69 -0
  19. package/dist/index.d.ts +69 -0
  20. package/dist/index.js +2926 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/result-chart-NFAJ4IQ5.js +398 -0
  23. package/dist/result-chart-NFAJ4IQ5.js.map +1 -0
  24. package/dist/result-chart-YLCKBNV4.cjs +400 -0
  25. package/dist/result-chart-YLCKBNV4.cjs.map +1 -0
  26. package/dist/styles.css +59 -0
  27. package/dist/use-dark-mode-rFxawUv1.d.cts +123 -0
  28. package/dist/use-dark-mode-rFxawUv1.d.ts +123 -0
  29. package/dist/widget.css +2 -0
  30. package/dist/widget.js +445 -0
  31. package/package.json +113 -0
  32. package/src/components/__tests__/tool-renderers.test.tsx +239 -0
  33. package/src/components/actions/action-approval-card.tsx +296 -0
  34. package/src/components/actions/action-status-badge.tsx +50 -0
  35. package/src/components/admin/change-password-dialog.tsx +128 -0
  36. package/src/components/atlas-chat.tsx +656 -0
  37. package/src/components/chart/chart-detection.ts +318 -0
  38. package/src/components/chart/result-chart.tsx +590 -0
  39. package/src/components/chat/api-key-bar.tsx +66 -0
  40. package/src/components/chat/copy-button.tsx +25 -0
  41. package/src/components/chat/data-table.tsx +104 -0
  42. package/src/components/chat/error-banner.tsx +32 -0
  43. package/src/components/chat/explore-card.tsx +41 -0
  44. package/src/components/chat/follow-up-chips.tsx +29 -0
  45. package/src/components/chat/loading-card.tsx +10 -0
  46. package/src/components/chat/managed-auth-card.tsx +116 -0
  47. package/src/components/chat/markdown.tsx +146 -0
  48. package/src/components/chat/python-result-card.tsx +245 -0
  49. package/src/components/chat/sql-block.tsx +54 -0
  50. package/src/components/chat/sql-result-card.tsx +163 -0
  51. package/src/components/chat/starter-prompts.ts +6 -0
  52. package/src/components/chat/tool-part.tsx +106 -0
  53. package/src/components/chat/typing-indicator.tsx +22 -0
  54. package/src/components/conversations/conversation-item.tsx +135 -0
  55. package/src/components/conversations/conversation-list.tsx +69 -0
  56. package/src/components/conversations/conversation-sidebar.tsx +113 -0
  57. package/src/components/conversations/delete-confirmation.tsx +27 -0
  58. package/src/components/schema-explorer/schema-explorer.tsx +517 -0
  59. package/src/components/ui/alert-dialog.tsx +196 -0
  60. package/src/components/ui/badge.tsx +48 -0
  61. package/src/components/ui/button.tsx +64 -0
  62. package/src/components/ui/card.tsx +92 -0
  63. package/src/components/ui/dialog.tsx +158 -0
  64. package/src/components/ui/dropdown-menu.tsx +257 -0
  65. package/src/components/ui/input.tsx +21 -0
  66. package/src/components/ui/label.tsx +24 -0
  67. package/src/components/ui/scroll-area.tsx +62 -0
  68. package/src/components/ui/separator.tsx +28 -0
  69. package/src/components/ui/sheet.tsx +143 -0
  70. package/src/components/ui/table.tsx +116 -0
  71. package/src/components/ui/toggle-group.tsx +83 -0
  72. package/src/components/ui/toggle.tsx +47 -0
  73. package/src/context.tsx +85 -0
  74. package/src/env.d.ts +9 -0
  75. package/src/hooks/__tests__/provider.test.tsx +83 -0
  76. package/src/hooks/__tests__/use-atlas-auth.test.tsx +283 -0
  77. package/src/hooks/__tests__/use-atlas-chat.test.tsx +157 -0
  78. package/src/hooks/__tests__/use-atlas-conversations.test.tsx +159 -0
  79. package/src/hooks/__tests__/use-atlas-theme.test.tsx +56 -0
  80. package/src/hooks/index.ts +47 -0
  81. package/src/hooks/provider.tsx +77 -0
  82. package/src/hooks/theme-init-script.ts +17 -0
  83. package/src/hooks/use-atlas-auth.ts +131 -0
  84. package/src/hooks/use-atlas-chat.ts +102 -0
  85. package/src/hooks/use-atlas-conversations.ts +61 -0
  86. package/src/hooks/use-atlas-theme.ts +34 -0
  87. package/src/hooks/use-conversations.ts +189 -0
  88. package/src/hooks/use-dark-mode.ts +150 -0
  89. package/src/index.ts +36 -0
  90. package/src/lib/action-types.ts +11 -0
  91. package/src/lib/helpers.ts +198 -0
  92. package/src/lib/tool-renderer-types.ts +76 -0
  93. package/src/lib/types.ts +29 -0
  94. package/src/lib/utils.ts +6 -0
  95. package/src/styles.css +59 -0
  96. package/src/test-setup.ts +55 -0
  97. package/src/widget-entry.ts +20 -0
  98. package/src/widget.css +12 -0
@@ -0,0 +1,400 @@
1
+ 'use strict';
2
+
3
+ var chunk5SEVKHS5_cjs = require('./chunk-5SEVKHS5.cjs');
4
+ var react = require('react');
5
+ var recharts = require('recharts');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ var ChartErrorBoundary = class extends react.Component {
9
+ constructor(props) {
10
+ super(props);
11
+ this.state = { hasError: false };
12
+ }
13
+ static getDerivedStateFromError() {
14
+ return { hasError: true };
15
+ }
16
+ componentDidCatch(error, info) {
17
+ console.error("Chart rendering failed:", error, info.componentStack);
18
+ }
19
+ render() {
20
+ if (this.state.hasError) {
21
+ return this.props.fallback ?? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-yellow-300 bg-yellow-50 px-3 py-2 text-xs text-yellow-700 dark:border-yellow-900/50 dark:bg-yellow-950/20 dark:text-yellow-400", children: "Chart could not be rendered. Switch to Table view to see your data." });
22
+ }
23
+ return this.props.children;
24
+ }
25
+ };
26
+ function getColors(dark) {
27
+ return dark ? chunk5SEVKHS5_cjs.CHART_COLORS_DARK : chunk5SEVKHS5_cjs.CHART_COLORS_LIGHT;
28
+ }
29
+ function themeTokens(dark) {
30
+ return {
31
+ grid: dark ? "#3f3f46" : "#e4e4e7",
32
+ axis: dark ? "#a1a1aa" : "#71717a",
33
+ tooltipBg: dark ? "#18181b" : "#ffffff",
34
+ tooltipBorder: dark ? "#3f3f46" : "#e4e4e7",
35
+ tooltipText: dark ? "#e4e4e7" : "#27272a",
36
+ legendText: dark ? "#a1a1aa" : "#71717a"
37
+ };
38
+ }
39
+ function formatNumber(value) {
40
+ const num = Number(value);
41
+ if (!isFinite(num)) return String(value ?? "");
42
+ if (Math.abs(num) >= 1e6) return `${(num / 1e6).toFixed(1)}M`;
43
+ if (Math.abs(num) >= 1e3) return `${(num / 1e3).toFixed(1)}K`;
44
+ return Number.isInteger(num) ? num.toLocaleString() : num.toFixed(2);
45
+ }
46
+ function truncateLabel(label, maxLen = 12) {
47
+ const str = String(label ?? "");
48
+ return str.length > maxLen ? str.slice(0, maxLen) + "\u2026" : str;
49
+ }
50
+ var TOOLTIP_LABEL_STYLE = { fontWeight: 600, marginBottom: 4 };
51
+ var tooltipStyleCache = /* @__PURE__ */ new Map();
52
+ function getTooltipStyle(dark) {
53
+ let style = tooltipStyleCache.get(dark);
54
+ if (!style) {
55
+ const t = themeTokens(dark);
56
+ style = {
57
+ background: t.tooltipBg,
58
+ border: `1px solid ${t.tooltipBorder}`,
59
+ borderRadius: 6,
60
+ padding: "8px 12px",
61
+ fontSize: 12,
62
+ color: t.tooltipText
63
+ };
64
+ tooltipStyleCache.set(dark, style);
65
+ }
66
+ return style;
67
+ }
68
+ function ChartTooltip({ active, payload, label, dark }) {
69
+ if (!active || !payload?.length) return null;
70
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: getTooltipStyle(dark), children: [
71
+ label && /* @__PURE__ */ jsxRuntime.jsx("p", { style: TOOLTIP_LABEL_STYLE, children: label }),
72
+ payload.map((entry, i) => /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { color: entry.color }, children: [
73
+ entry.name,
74
+ ": ",
75
+ typeof entry.value === "number" ? formatNumber(entry.value) : entry.value
76
+ ] }, i))
77
+ ] });
78
+ }
79
+ function BarChartView({
80
+ data,
81
+ rec,
82
+ dark
83
+ }) {
84
+ const colors = getColors(dark);
85
+ const t = themeTokens(dark);
86
+ const catKey = rec.categoryColumn.header;
87
+ const valKeys = rec.valueColumns.map((c) => c.header);
88
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[4/3] sm:aspect-[16/9]", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data, margin: { top: 8, right: 8, bottom: 40, left: 8 }, children: [
89
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3", stroke: t.grid }),
90
+ /* @__PURE__ */ jsxRuntime.jsx(
91
+ recharts.XAxis,
92
+ {
93
+ dataKey: catKey,
94
+ tick: { fill: t.axis, fontSize: 11 },
95
+ tickFormatter: (v) => truncateLabel(v),
96
+ angle: -45,
97
+ textAnchor: "end",
98
+ height: 60
99
+ }
100
+ ),
101
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { tick: { fill: t.axis, fontSize: 11 }, tickFormatter: formatNumber }),
102
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { dark }) }),
103
+ valKeys.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { wrapperStyle: { fontSize: 12, color: t.legendText } }),
104
+ valKeys.map((key, i) => /* @__PURE__ */ jsxRuntime.jsx(
105
+ recharts.Bar,
106
+ {
107
+ dataKey: key,
108
+ fill: colors[i % colors.length],
109
+ radius: [4, 4, 0, 0]
110
+ },
111
+ key
112
+ ))
113
+ ] }) }) });
114
+ }
115
+ function LineChartView({
116
+ data,
117
+ rec,
118
+ dark
119
+ }) {
120
+ const colors = getColors(dark);
121
+ const t = themeTokens(dark);
122
+ const catKey = rec.categoryColumn.header;
123
+ const valKeys = rec.valueColumns.map((c) => c.header);
124
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[4/3] sm:aspect-[16/9]", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data, margin: { top: 8, right: 8, bottom: 40, left: 8 }, children: [
125
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3", stroke: t.grid }),
126
+ /* @__PURE__ */ jsxRuntime.jsx(
127
+ recharts.XAxis,
128
+ {
129
+ dataKey: catKey,
130
+ tick: { fill: t.axis, fontSize: 11 },
131
+ tickFormatter: (v) => truncateLabel(v),
132
+ angle: -45,
133
+ textAnchor: "end",
134
+ height: 60
135
+ }
136
+ ),
137
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { tick: { fill: t.axis, fontSize: 11 }, tickFormatter: formatNumber }),
138
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { dark }) }),
139
+ valKeys.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { wrapperStyle: { fontSize: 12, color: t.legendText } }),
140
+ valKeys.map((key, i) => /* @__PURE__ */ jsxRuntime.jsx(
141
+ recharts.Line,
142
+ {
143
+ type: "monotone",
144
+ dataKey: key,
145
+ stroke: colors[i % colors.length],
146
+ strokeWidth: 2,
147
+ dot: { r: 3, fill: colors[i % colors.length] },
148
+ activeDot: { r: 5 }
149
+ },
150
+ key
151
+ ))
152
+ ] }) }) });
153
+ }
154
+ function PieChartView({
155
+ data,
156
+ rec,
157
+ dark
158
+ }) {
159
+ const colors = getColors(dark);
160
+ const t = themeTokens(dark);
161
+ const catKey = rec.categoryColumn.header;
162
+ const valKey = rec.valueColumns[0].header;
163
+ const total = data.reduce((sum, d) => sum + (typeof d[valKey] === "number" ? d[valKey] : 0), 0);
164
+ const hasNegative = data.some((d) => typeof d[valKey] === "number" && d[valKey] < 0);
165
+ if (total <= 0 || hasNegative) {
166
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex aspect-[4/3] items-center justify-center text-xs text-zinc-400 sm:aspect-[16/9]", children: "Pie chart is not suitable for this data." });
167
+ }
168
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[4/3] sm:aspect-[16/9]", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.PieChart, { children: [
169
+ /* @__PURE__ */ jsxRuntime.jsx(
170
+ recharts.Pie,
171
+ {
172
+ data,
173
+ dataKey: valKey,
174
+ nameKey: catKey,
175
+ cx: "50%",
176
+ cy: "50%",
177
+ innerRadius: 40,
178
+ outerRadius: 100,
179
+ label: ({ name, value }) => `${truncateLabel(String(name ?? ""), 10)} ${total > 0 && value != null ? (value / total * 100).toFixed(0) : 0}%`,
180
+ labelLine: { stroke: t.axis },
181
+ fontSize: 11,
182
+ children: data.map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(recharts.Cell, { fill: colors[i % colors.length] }, i))
183
+ }
184
+ ),
185
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { dark }) })
186
+ ] }) }) });
187
+ }
188
+ function AreaChartView({
189
+ data,
190
+ rec,
191
+ dark
192
+ }) {
193
+ const chartId = react.useId();
194
+ const colors = getColors(dark);
195
+ const t = themeTokens(dark);
196
+ const catKey = rec.categoryColumn.header;
197
+ const valKeys = rec.valueColumns.map((c) => c.header);
198
+ return /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 300, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.AreaChart, { data, margin: { top: 8, right: 8, bottom: 40, left: 8 }, children: [
199
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: valKeys.map((key, i) => /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: `area-grad-${chartId}-${i}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
200
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: colors[i % colors.length], stopOpacity: 0.3 }),
201
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "95%", stopColor: colors[i % colors.length], stopOpacity: 0.05 })
202
+ ] }, key)) }),
203
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3", stroke: t.grid }),
204
+ /* @__PURE__ */ jsxRuntime.jsx(
205
+ recharts.XAxis,
206
+ {
207
+ dataKey: catKey,
208
+ tick: { fill: t.axis, fontSize: 11 },
209
+ tickFormatter: (v) => truncateLabel(v),
210
+ angle: -45,
211
+ textAnchor: "end",
212
+ height: 60
213
+ }
214
+ ),
215
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { tick: { fill: t.axis, fontSize: 11 }, tickFormatter: formatNumber }),
216
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { dark }) }),
217
+ valKeys.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { wrapperStyle: { fontSize: 12, color: t.legendText } }),
218
+ valKeys.map((key, i) => /* @__PURE__ */ jsxRuntime.jsx(
219
+ recharts.Area,
220
+ {
221
+ type: "monotone",
222
+ dataKey: key,
223
+ stroke: colors[i % colors.length],
224
+ strokeWidth: 2,
225
+ fill: `url(#area-grad-${chartId}-${i})`
226
+ },
227
+ key
228
+ ))
229
+ ] }) });
230
+ }
231
+ function StackedBarChartView({
232
+ data,
233
+ rec,
234
+ dark
235
+ }) {
236
+ const colors = getColors(dark);
237
+ const t = themeTokens(dark);
238
+ const catKey = rec.categoryColumn.header;
239
+ const valKeys = rec.valueColumns.map((c) => c.header);
240
+ return /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 300, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data, margin: { top: 8, right: 8, bottom: 40, left: 8 }, children: [
241
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3", stroke: t.grid }),
242
+ /* @__PURE__ */ jsxRuntime.jsx(
243
+ recharts.XAxis,
244
+ {
245
+ dataKey: catKey,
246
+ tick: { fill: t.axis, fontSize: 11 },
247
+ tickFormatter: (v) => truncateLabel(v),
248
+ angle: -45,
249
+ textAnchor: "end",
250
+ height: 60
251
+ }
252
+ ),
253
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { tick: { fill: t.axis, fontSize: 11 }, tickFormatter: formatNumber }),
254
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { dark }) }),
255
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { wrapperStyle: { fontSize: 12, color: t.legendText } }),
256
+ valKeys.map((key, i) => /* @__PURE__ */ jsxRuntime.jsx(
257
+ recharts.Bar,
258
+ {
259
+ dataKey: key,
260
+ stackId: "a",
261
+ fill: colors[i % colors.length],
262
+ radius: i === valKeys.length - 1 ? [4, 4, 0, 0] : void 0
263
+ },
264
+ key
265
+ ))
266
+ ] }) });
267
+ }
268
+ function ScatterChartView({
269
+ data,
270
+ rec,
271
+ dark
272
+ }) {
273
+ const colors = getColors(dark);
274
+ const t = themeTokens(dark);
275
+ const xKey = rec.categoryColumn.header;
276
+ const yKey = rec.valueColumns[0].header;
277
+ const zKey = rec.valueColumns.length > 1 ? rec.valueColumns[1].header : void 0;
278
+ return /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: 300, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ScatterChart, { margin: { top: 8, right: 8, bottom: 40, left: 8 }, children: [
279
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3", stroke: t.grid }),
280
+ /* @__PURE__ */ jsxRuntime.jsx(
281
+ recharts.XAxis,
282
+ {
283
+ dataKey: xKey,
284
+ type: "number",
285
+ name: xKey,
286
+ tick: { fill: t.axis, fontSize: 11 },
287
+ tickFormatter: formatNumber
288
+ }
289
+ ),
290
+ /* @__PURE__ */ jsxRuntime.jsx(
291
+ recharts.YAxis,
292
+ {
293
+ dataKey: yKey,
294
+ type: "number",
295
+ name: yKey,
296
+ tick: { fill: t.axis, fontSize: 11 },
297
+ tickFormatter: formatNumber
298
+ }
299
+ ),
300
+ zKey && /* @__PURE__ */ jsxRuntime.jsx(recharts.ZAxis, { dataKey: zKey, type: "number", name: zKey, range: [40, 400] }),
301
+ /* @__PURE__ */ jsxRuntime.jsx(
302
+ recharts.Tooltip,
303
+ {
304
+ content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { dark }),
305
+ cursor: { strokeDasharray: "3 3" }
306
+ }
307
+ ),
308
+ /* @__PURE__ */ jsxRuntime.jsx(
309
+ recharts.Scatter,
310
+ {
311
+ data,
312
+ fill: colors[0]
313
+ }
314
+ )
315
+ ] }) });
316
+ }
317
+ var CHART_LABELS = {
318
+ bar: "Bar",
319
+ line: "Line",
320
+ pie: "Pie",
321
+ area: "Area",
322
+ "stacked-bar": "Stacked",
323
+ scatter: "Scatter"
324
+ };
325
+ function ChartTypeSelector({
326
+ recommendations,
327
+ active,
328
+ onChange
329
+ }) {
330
+ if (recommendations.length <= 1) return null;
331
+ const seen = /* @__PURE__ */ new Set();
332
+ const unique = recommendations.filter((r) => {
333
+ if (seen.has(r.type)) return false;
334
+ seen.add(r.type);
335
+ return true;
336
+ });
337
+ if (unique.length <= 1) return null;
338
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1", children: unique.map((rec) => /* @__PURE__ */ jsxRuntime.jsx(
339
+ "button",
340
+ {
341
+ onClick: () => onChange(rec.type),
342
+ className: `rounded px-2 py-0.5 text-xs font-medium transition-colors ${active === rec.type ? "bg-blue-100 text-blue-700 dark:bg-blue-600/20 dark:text-blue-400" : "text-zinc-500 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-200"}`,
343
+ children: CHART_LABELS[rec.type]
344
+ },
345
+ rec.type
346
+ )) });
347
+ }
348
+ function ChartRenderer({
349
+ rows,
350
+ rec,
351
+ defaultData,
352
+ defaultRec,
353
+ dark
354
+ }) {
355
+ const chartData = rec === defaultRec ? defaultData : chunk5SEVKHS5_cjs.transformData(rows, rec);
356
+ const type = rec.type;
357
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: type === "bar" ? /* @__PURE__ */ jsxRuntime.jsx(BarChartView, { data: chartData, rec, dark }) : type === "line" ? /* @__PURE__ */ jsxRuntime.jsx(LineChartView, { data: chartData, rec, dark }) : type === "area" ? /* @__PURE__ */ jsxRuntime.jsx(AreaChartView, { data: chartData, rec, dark }) : type === "stacked-bar" ? /* @__PURE__ */ jsxRuntime.jsx(StackedBarChartView, { data: chartData, rec, dark }) : type === "scatter" ? /* @__PURE__ */ jsxRuntime.jsx(ScatterChartView, { data: chartData, rec, dark }) : /* @__PURE__ */ jsxRuntime.jsx(PieChartView, { data: chartData, rec, dark }) });
358
+ }
359
+ function ResultChart({
360
+ headers,
361
+ rows,
362
+ dark,
363
+ detectionResult
364
+ }) {
365
+ const result = react.useMemo(
366
+ () => detectionResult ?? chunk5SEVKHS5_cjs.detectCharts(headers, rows),
367
+ [headers, rows, detectionResult]
368
+ );
369
+ const [activeType, setActiveType] = react.useState(null);
370
+ if (!result.chartable) return null;
371
+ const currentType = activeType ?? result.recommendations[0].type;
372
+ const currentRec = result.recommendations.find((r) => r.type === currentType) ?? result.recommendations[0];
373
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700", children: [
374
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b border-zinc-100 bg-zinc-50/50 px-3 py-2 dark:border-zinc-800 dark:bg-zinc-900/50", children: [
375
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-zinc-500 dark:text-zinc-400", children: currentRec.reason }),
376
+ /* @__PURE__ */ jsxRuntime.jsx(
377
+ ChartTypeSelector,
378
+ {
379
+ recommendations: result.recommendations,
380
+ active: currentType,
381
+ onChange: setActiveType
382
+ }
383
+ )
384
+ ] }),
385
+ /* @__PURE__ */ jsxRuntime.jsx(ChartErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(
386
+ ChartRenderer,
387
+ {
388
+ rows,
389
+ rec: currentRec,
390
+ defaultData: result.data,
391
+ defaultRec: result.recommendations[0],
392
+ dark
393
+ }
394
+ ) }, currentType)
395
+ ] });
396
+ }
397
+
398
+ exports.ResultChart = ResultChart;
399
+ //# sourceMappingURL=result-chart-YLCKBNV4.cjs.map
400
+ //# sourceMappingURL=result-chart-YLCKBNV4.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/chart/result-chart.tsx"],"names":["Component","CHART_COLORS_DARK","CHART_COLORS_LIGHT","jsxs","jsx","ResponsiveContainer","BarChart","CartesianGrid","XAxis","YAxis","Tooltip","Legend","Bar","LineChart","Line","PieChart","Pie","Cell","useId","AreaChart","Area","ScatterChart","ZAxis","Scatter","transformData","useMemo","detectCharts","useState"],"mappings":"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","file":"result-chart-YLCKBNV4.cjs","sourcesContent":["\"use client\";\n\nimport { Component, type ReactNode, type ErrorInfo, useMemo, useId, useState } from \"react\";\nimport {\n ResponsiveContainer,\n BarChart,\n Bar,\n LineChart,\n Line,\n AreaChart,\n Area,\n ScatterChart,\n Scatter,\n ZAxis,\n PieChart,\n Pie,\n Cell,\n CartesianGrid,\n XAxis,\n YAxis,\n Tooltip,\n Legend,\n} from \"recharts\";\nimport {\n detectCharts,\n transformData,\n CHART_COLORS_LIGHT,\n CHART_COLORS_DARK,\n type ChartRecommendation,\n type ChartType,\n type RechartsRow,\n type ChartDetectionResult,\n} from \"./chart-detection\";\n\n/* ------------------------------------------------------------------ */\n/* Error boundary */\n/* ------------------------------------------------------------------ */\n\nclass ChartErrorBoundary extends Component<\n { children: ReactNode; fallback?: ReactNode },\n { hasError: boolean }\n> {\n constructor(props: { children: ReactNode; fallback?: ReactNode }) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): { hasError: boolean } {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n console.error(\"Chart rendering failed:\", error, info.componentStack);\n }\n\n render() {\n if (this.state.hasError) {\n return this.props.fallback ?? (\n <div className=\"rounded-lg border border-yellow-300 bg-yellow-50 px-3 py-2 text-xs text-yellow-700 dark:border-yellow-900/50 dark:bg-yellow-950/20 dark:text-yellow-400\">\n Chart could not be rendered. Switch to Table view to see your data.\n </div>\n );\n }\n return this.props.children;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Theme helpers */\n/* ------------------------------------------------------------------ */\n\nfunction getColors(dark: boolean) {\n return dark ? CHART_COLORS_DARK : CHART_COLORS_LIGHT;\n}\n\nfunction themeTokens(dark: boolean) {\n return {\n grid: dark ? \"#3f3f46\" : \"#e4e4e7\",\n axis: dark ? \"#a1a1aa\" : \"#71717a\",\n tooltipBg: dark ? \"#18181b\" : \"#ffffff\",\n tooltipBorder: dark ? \"#3f3f46\" : \"#e4e4e7\",\n tooltipText: dark ? \"#e4e4e7\" : \"#27272a\",\n legendText: dark ? \"#a1a1aa\" : \"#71717a\",\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Number formatter for axis / tooltip */\n/* ------------------------------------------------------------------ */\n\nfunction formatNumber(value: unknown): string {\n const num = Number(value);\n if (!isFinite(num)) return String(value ?? \"\");\n if (Math.abs(num) >= 1_000_000) return `${(num / 1_000_000).toFixed(1)}M`;\n if (Math.abs(num) >= 1_000) return `${(num / 1_000).toFixed(1)}K`;\n return Number.isInteger(num) ? num.toLocaleString() : num.toFixed(2);\n}\n\nfunction truncateLabel(label: unknown, maxLen = 12): string {\n const str = String(label ?? \"\");\n return str.length > maxLen ? str.slice(0, maxLen) + \"\\u2026\" : str;\n}\n\n/* ------------------------------------------------------------------ */\n/* Tooltip */\n/* ------------------------------------------------------------------ */\n\nconst TOOLTIP_LABEL_STYLE = { fontWeight: 600, marginBottom: 4 } as const;\n\nconst tooltipStyleCache = new Map<boolean, React.CSSProperties>();\nfunction getTooltipStyle(dark: boolean): React.CSSProperties {\n let style = tooltipStyleCache.get(dark);\n if (!style) {\n const t = themeTokens(dark);\n style = {\n background: t.tooltipBg,\n border: `1px solid ${t.tooltipBorder}`,\n borderRadius: 6,\n padding: \"8px 12px\",\n fontSize: 12,\n color: t.tooltipText,\n };\n tooltipStyleCache.set(dark, style);\n }\n return style;\n}\n\nfunction ChartTooltip({ active, payload, label, dark }: {\n active?: boolean;\n payload?: Array<{ name: string; value: number; color: string }>;\n label?: string;\n dark: boolean;\n}) {\n if (!active || !payload?.length) return null;\n return (\n <div style={getTooltipStyle(dark)}>\n {label && <p style={TOOLTIP_LABEL_STYLE}>{label}</p>}\n {payload.map((entry, i) => (\n <p key={i} style={{ color: entry.color }}>\n {entry.name}: {typeof entry.value === \"number\" ? formatNumber(entry.value) : entry.value}\n </p>\n ))}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Sub-chart components */\n/* ------------------------------------------------------------------ */\n\nfunction BarChartView({\n data,\n rec,\n dark,\n}: {\n data: RechartsRow[];\n rec: ChartRecommendation;\n dark: boolean;\n}) {\n const colors = getColors(dark);\n const t = themeTokens(dark);\n const catKey = rec.categoryColumn.header;\n const valKeys = rec.valueColumns.map((c) => c.header);\n\n return (\n <div className=\"aspect-[4/3] sm:aspect-[16/9]\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={data} margin={{ top: 8, right: 8, bottom: 40, left: 8 }}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={t.grid} />\n <XAxis\n dataKey={catKey}\n tick={{ fill: t.axis, fontSize: 11 }}\n tickFormatter={(v: string) => truncateLabel(v)}\n angle={-45}\n textAnchor=\"end\"\n height={60}\n />\n <YAxis tick={{ fill: t.axis, fontSize: 11 }} tickFormatter={formatNumber} />\n <Tooltip content={<ChartTooltip dark={dark} />} />\n {valKeys.length > 1 && (\n <Legend wrapperStyle={{ fontSize: 12, color: t.legendText }} />\n )}\n {valKeys.map((key, i) => (\n <Bar\n key={key}\n dataKey={key}\n fill={colors[i % colors.length]}\n radius={[4, 4, 0, 0]}\n />\n ))}\n </BarChart>\n </ResponsiveContainer>\n </div>\n );\n}\n\nfunction LineChartView({\n data,\n rec,\n dark,\n}: {\n data: RechartsRow[];\n rec: ChartRecommendation;\n dark: boolean;\n}) {\n const colors = getColors(dark);\n const t = themeTokens(dark);\n const catKey = rec.categoryColumn.header;\n const valKeys = rec.valueColumns.map((c) => c.header);\n\n return (\n <div className=\"aspect-[4/3] sm:aspect-[16/9]\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <LineChart data={data} margin={{ top: 8, right: 8, bottom: 40, left: 8 }}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={t.grid} />\n <XAxis\n dataKey={catKey}\n tick={{ fill: t.axis, fontSize: 11 }}\n tickFormatter={(v: string) => truncateLabel(v)}\n angle={-45}\n textAnchor=\"end\"\n height={60}\n />\n <YAxis tick={{ fill: t.axis, fontSize: 11 }} tickFormatter={formatNumber} />\n <Tooltip content={<ChartTooltip dark={dark} />} />\n {valKeys.length > 1 && (\n <Legend wrapperStyle={{ fontSize: 12, color: t.legendText }} />\n )}\n {valKeys.map((key, i) => (\n <Line\n key={key}\n type=\"monotone\"\n dataKey={key}\n stroke={colors[i % colors.length]}\n strokeWidth={2}\n dot={{ r: 3, fill: colors[i % colors.length] }}\n activeDot={{ r: 5 }}\n />\n ))}\n </LineChart>\n </ResponsiveContainer>\n </div>\n );\n}\n\nfunction PieChartView({\n data,\n rec,\n dark,\n}: {\n data: RechartsRow[];\n rec: ChartRecommendation;\n dark: boolean;\n}) {\n const colors = getColors(dark);\n const t = themeTokens(dark);\n const catKey = rec.categoryColumn.header;\n const valKey = rec.valueColumns[0].header;\n\n const total = data.reduce((sum, d) => sum + (typeof d[valKey] === \"number\" ? (d[valKey] as number) : 0), 0);\n\n const hasNegative = data.some(d => typeof d[valKey] === \"number\" && (d[valKey] as number) < 0);\n if (total <= 0 || hasNegative) {\n return (\n <div className=\"flex aspect-[4/3] items-center justify-center text-xs text-zinc-400 sm:aspect-[16/9]\">\n Pie chart is not suitable for this data.\n </div>\n );\n }\n\n return (\n <div className=\"aspect-[4/3] sm:aspect-[16/9]\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <PieChart>\n <Pie\n data={data}\n dataKey={valKey}\n nameKey={catKey}\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={40}\n outerRadius={100}\n label={({ name, value }: { name?: string; value?: number }) =>\n `${truncateLabel(String(name ?? \"\"), 10)} ${total > 0 && value != null ? ((value / total) * 100).toFixed(0) : 0}%`\n }\n labelLine={{ stroke: t.axis }}\n fontSize={11}\n >\n {data.map((_, i) => (\n <Cell key={i} fill={colors[i % colors.length]} />\n ))}\n </Pie>\n <Tooltip content={<ChartTooltip dark={dark} />} />\n </PieChart>\n </ResponsiveContainer>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Area chart */\n/* ------------------------------------------------------------------ */\n\nfunction AreaChartView({\n data,\n rec,\n dark,\n}: {\n data: RechartsRow[];\n rec: ChartRecommendation;\n dark: boolean;\n}) {\n const chartId = useId();\n const colors = getColors(dark);\n const t = themeTokens(dark);\n const catKey = rec.categoryColumn.header;\n const valKeys = rec.valueColumns.map((c) => c.header);\n\n return (\n <ResponsiveContainer width=\"100%\" height={300}>\n <AreaChart data={data} margin={{ top: 8, right: 8, bottom: 40, left: 8 }}>\n <defs>\n {valKeys.map((key, i) => (\n <linearGradient key={key} id={`area-grad-${chartId}-${i}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"5%\" stopColor={colors[i % colors.length]} stopOpacity={0.3} />\n <stop offset=\"95%\" stopColor={colors[i % colors.length]} stopOpacity={0.05} />\n </linearGradient>\n ))}\n </defs>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={t.grid} />\n <XAxis\n dataKey={catKey}\n tick={{ fill: t.axis, fontSize: 11 }}\n tickFormatter={(v: string) => truncateLabel(v)}\n angle={-45}\n textAnchor=\"end\"\n height={60}\n />\n <YAxis tick={{ fill: t.axis, fontSize: 11 }} tickFormatter={formatNumber} />\n <Tooltip content={<ChartTooltip dark={dark} />} />\n {valKeys.length > 1 && (\n <Legend wrapperStyle={{ fontSize: 12, color: t.legendText }} />\n )}\n {valKeys.map((key, i) => (\n <Area\n key={key}\n type=\"monotone\"\n dataKey={key}\n stroke={colors[i % colors.length]}\n strokeWidth={2}\n fill={`url(#area-grad-${chartId}-${i})`}\n />\n ))}\n </AreaChart>\n </ResponsiveContainer>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Stacked bar chart */\n/* ------------------------------------------------------------------ */\n\nfunction StackedBarChartView({\n data,\n rec,\n dark,\n}: {\n data: RechartsRow[];\n rec: ChartRecommendation;\n dark: boolean;\n}) {\n const colors = getColors(dark);\n const t = themeTokens(dark);\n const catKey = rec.categoryColumn.header;\n const valKeys = rec.valueColumns.map((c) => c.header);\n\n return (\n <ResponsiveContainer width=\"100%\" height={300}>\n <BarChart data={data} margin={{ top: 8, right: 8, bottom: 40, left: 8 }}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={t.grid} />\n <XAxis\n dataKey={catKey}\n tick={{ fill: t.axis, fontSize: 11 }}\n tickFormatter={(v: string) => truncateLabel(v)}\n angle={-45}\n textAnchor=\"end\"\n height={60}\n />\n <YAxis tick={{ fill: t.axis, fontSize: 11 }} tickFormatter={formatNumber} />\n <Tooltip content={<ChartTooltip dark={dark} />} />\n <Legend wrapperStyle={{ fontSize: 12, color: t.legendText }} />\n {valKeys.map((key, i) => (\n <Bar\n key={key}\n dataKey={key}\n stackId=\"a\"\n fill={colors[i % colors.length]}\n radius={i === valKeys.length - 1 ? [4, 4, 0, 0] : undefined}\n />\n ))}\n </BarChart>\n </ResponsiveContainer>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Scatter chart */\n/* ------------------------------------------------------------------ */\n\nfunction ScatterChartView({\n data,\n rec,\n dark,\n}: {\n data: RechartsRow[];\n rec: ChartRecommendation;\n dark: boolean;\n}) {\n const colors = getColors(dark);\n const t = themeTokens(dark);\n const xKey = rec.categoryColumn.header;\n const yKey = rec.valueColumns[0].header;\n const zKey = rec.valueColumns.length > 1 ? rec.valueColumns[1].header : undefined;\n\n return (\n <ResponsiveContainer width=\"100%\" height={300}>\n <ScatterChart margin={{ top: 8, right: 8, bottom: 40, left: 8 }}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={t.grid} />\n <XAxis\n dataKey={xKey}\n type=\"number\"\n name={xKey}\n tick={{ fill: t.axis, fontSize: 11 }}\n tickFormatter={formatNumber}\n />\n <YAxis\n dataKey={yKey}\n type=\"number\"\n name={yKey}\n tick={{ fill: t.axis, fontSize: 11 }}\n tickFormatter={formatNumber}\n />\n {zKey && <ZAxis dataKey={zKey} type=\"number\" name={zKey} range={[40, 400]} />}\n <Tooltip\n content={<ChartTooltip dark={dark} />}\n cursor={{ strokeDasharray: \"3 3\" }}\n />\n <Scatter\n data={data}\n fill={colors[0]}\n />\n </ScatterChart>\n </ResponsiveContainer>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Chart type selector */\n/* ------------------------------------------------------------------ */\n\nconst CHART_LABELS: Record<ChartType, string> = {\n bar: \"Bar\",\n line: \"Line\",\n pie: \"Pie\",\n area: \"Area\",\n \"stacked-bar\": \"Stacked\",\n scatter: \"Scatter\",\n};\n\nfunction ChartTypeSelector({\n recommendations,\n active,\n onChange,\n}: {\n recommendations: ChartRecommendation[];\n active: ChartType;\n onChange: (t: ChartType) => void;\n}) {\n if (recommendations.length <= 1) return null;\n\n const seen = new Set<ChartType>();\n const unique = recommendations.filter((r) => {\n if (seen.has(r.type)) return false;\n seen.add(r.type);\n return true;\n });\n\n if (unique.length <= 1) return null;\n\n return (\n <div className=\"flex gap-1\">\n {unique.map((rec) => (\n <button\n key={rec.type}\n onClick={() => onChange(rec.type)}\n className={`rounded px-2 py-0.5 text-xs font-medium transition-colors ${\n active === rec.type\n ? \"bg-blue-100 text-blue-700 dark:bg-blue-600/20 dark:text-blue-400\"\n : \"text-zinc-500 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-200\"\n }`}\n >\n {CHART_LABELS[rec.type]}\n </button>\n ))}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Chart renderer (inside error boundary) */\n/* ------------------------------------------------------------------ */\n\nfunction ChartRenderer({\n rows,\n rec,\n defaultData,\n defaultRec,\n dark,\n}: {\n rows: string[][];\n rec: ChartRecommendation;\n defaultData: RechartsRow[];\n defaultRec: ChartRecommendation;\n dark: boolean;\n}) {\n // Re-transform data when switching chart type (category axis may differ)\n const chartData = rec === defaultRec ? defaultData : transformData(rows, rec);\n const type = rec.type;\n\n return (\n <div className=\"p-2\">\n {type === \"bar\" ? <BarChartView data={chartData} rec={rec} dark={dark} />\n : type === \"line\" ? <LineChartView data={chartData} rec={rec} dark={dark} />\n : type === \"area\" ? <AreaChartView data={chartData} rec={rec} dark={dark} />\n : type === \"stacked-bar\" ? <StackedBarChartView data={chartData} rec={rec} dark={dark} />\n : type === \"scatter\" ? <ScatterChartView data={chartData} rec={rec} dark={dark} />\n : <PieChartView data={chartData} rec={rec} dark={dark} />}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Main ResultChart component */\n/* ------------------------------------------------------------------ */\n\nexport function ResultChart({\n headers,\n rows,\n dark,\n detectionResult,\n}: {\n headers: string[];\n rows: string[][];\n dark: boolean;\n detectionResult?: ChartDetectionResult;\n}) {\n const result = useMemo(\n () => detectionResult ?? detectCharts(headers, rows),\n [headers, rows, detectionResult],\n );\n\n const [activeType, setActiveType] = useState<ChartType | null>(null);\n\n if (!result.chartable) return null;\n\n const currentType = activeType ?? result.recommendations[0].type;\n const currentRec = result.recommendations.find((r) => r.type === currentType) ?? result.recommendations[0];\n\n return (\n <div className=\"overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700\">\n <div className=\"flex items-center justify-between border-b border-zinc-100 bg-zinc-50/50 px-3 py-2 dark:border-zinc-800 dark:bg-zinc-900/50\">\n <span className=\"text-xs text-zinc-500 dark:text-zinc-400\">{currentRec.reason}</span>\n <ChartTypeSelector\n recommendations={result.recommendations}\n active={currentType}\n onChange={setActiveType}\n />\n </div>\n <ChartErrorBoundary key={currentType}>\n <ChartRenderer\n rows={rows}\n rec={currentRec}\n defaultData={result.data}\n defaultRec={result.recommendations[0]}\n dark={dark}\n />\n </ChartErrorBoundary>\n </div>\n );\n}\n"]}
@@ -0,0 +1,59 @@
1
+ /*
2
+ * @useatlas/react — Base styles
3
+ *
4
+ * Import this CSS in your app:
5
+ * import "@useatlas/react/styles.css";
6
+ *
7
+ * Also configure Tailwind CSS 4 to scan this package:
8
+ * @source "../node_modules/@useatlas/react/dist";
9
+ *
10
+ * These CSS custom properties define the Atlas design tokens.
11
+ * They match shadcn/ui's "neutral" base with "new-york" style.
12
+ * Scoped to .atlas-root to avoid clobbering host app styles.
13
+ */
14
+
15
+ .atlas-root {
16
+ --radius: 0.625rem;
17
+ --background: oklch(1 0 0);
18
+ --foreground: oklch(0.145 0 0);
19
+ --card: oklch(1 0 0);
20
+ --card-foreground: oklch(0.145 0 0);
21
+ --popover: oklch(1 0 0);
22
+ --popover-foreground: oklch(0.145 0 0);
23
+ --primary: oklch(0.205 0 0);
24
+ --primary-foreground: oklch(0.985 0 0);
25
+ --secondary: oklch(0.97 0 0);
26
+ --secondary-foreground: oklch(0.205 0 0);
27
+ --muted: oklch(0.97 0 0);
28
+ --muted-foreground: oklch(0.556 0 0);
29
+ --accent: oklch(0.97 0 0);
30
+ --accent-foreground: oklch(0.205 0 0);
31
+ --destructive: oklch(0.577 0.245 27.325);
32
+ --destructive-foreground: oklch(0.577 0.245 27.325);
33
+ --border: oklch(0.922 0 0);
34
+ --input: oklch(0.922 0 0);
35
+ --ring: oklch(0.708 0 0);
36
+ --atlas-brand: oklch(0.759 0.148 167.71);
37
+ }
38
+
39
+ .dark .atlas-root {
40
+ --background: oklch(0.145 0 0);
41
+ --foreground: oklch(0.985 0 0);
42
+ --card: oklch(0.145 0 0);
43
+ --card-foreground: oklch(0.985 0 0);
44
+ --popover: oklch(0.145 0 0);
45
+ --popover-foreground: oklch(0.985 0 0);
46
+ --primary: oklch(0.985 0 0);
47
+ --primary-foreground: oklch(0.205 0 0);
48
+ --secondary: oklch(0.269 0 0);
49
+ --secondary-foreground: oklch(0.985 0 0);
50
+ --muted: oklch(0.269 0 0);
51
+ --muted-foreground: oklch(0.708 0 0);
52
+ --accent: oklch(0.269 0 0);
53
+ --accent-foreground: oklch(0.985 0 0);
54
+ --destructive: oklch(0.396 0.141 25.723);
55
+ --destructive-foreground: oklch(0.637 0.237 25.331);
56
+ --border: oklch(0.269 0 0);
57
+ --input: oklch(0.269 0 0);
58
+ --ring: oklch(0.439 0 0);
59
+ }
@@ -0,0 +1,123 @@
1
+ import { ComponentType, ReactNode } from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ /** Props passed to custom tool renderers. */
5
+ interface ToolRendererProps<T = unknown> {
6
+ /** Name of the tool being rendered. */
7
+ toolName: string;
8
+ /** Input arguments passed to the tool invocation. */
9
+ args: Record<string, unknown>;
10
+ /** Tool output. For built-in tools, `null` while the tool is still running. */
11
+ result: T;
12
+ /** Whether the tool invocation is still in progress. */
13
+ isLoading: boolean;
14
+ }
15
+ /** Result shape from the executeSQL tool. Subset covering fields most useful for rendering. */
16
+ type SQLToolResult = {
17
+ success: true;
18
+ columns: string[];
19
+ rows: Record<string, unknown>[];
20
+ truncated?: boolean;
21
+ explanation?: string;
22
+ row_count?: number;
23
+ } | {
24
+ success: false;
25
+ error: string;
26
+ };
27
+ /** Result shape from the explore tool (semantic layer exploration output). */
28
+ type ExploreToolResult = string;
29
+ /** Result shape from the executePython tool. */
30
+ type PythonToolResult = {
31
+ success: true;
32
+ output?: string;
33
+ explanation?: string;
34
+ table?: {
35
+ columns: string[];
36
+ rows: unknown[][];
37
+ };
38
+ charts?: {
39
+ base64: string;
40
+ mimeType: "image/png";
41
+ }[];
42
+ rechartsCharts?: {
43
+ type: "line" | "bar" | "pie";
44
+ data: Record<string, unknown>[];
45
+ categoryKey: string;
46
+ valueKeys: string[];
47
+ }[];
48
+ } | {
49
+ success: false;
50
+ error: string;
51
+ output?: string;
52
+ };
53
+ /**
54
+ * Map of tool names to custom renderer components.
55
+ *
56
+ * Known tool names (executeSQL, explore, executePython) get typed result generics.
57
+ * Arbitrary tool names are also supported via the index signature with `unknown` result type.
58
+ *
59
+ * Custom renderers take precedence over built-in defaults, including the action approval UI.
60
+ */
61
+ type ToolRenderers = {
62
+ executeSQL?: ComponentType<ToolRendererProps<SQLToolResult | null>>;
63
+ explore?: ComponentType<ToolRendererProps<ExploreToolResult | null>>;
64
+ executePython?: ComponentType<ToolRendererProps<PythonToolResult | null>>;
65
+ } & {
66
+ [toolName: string]: ComponentType<ToolRendererProps> | undefined;
67
+ };
68
+
69
+ /**
70
+ * Duck-typed interface that matches better-auth's client shape.
71
+ * Components like ManagedAuthCard call signIn/signUp/signOut and useSession().
72
+ */
73
+ interface AtlasAuthClient {
74
+ signIn: {
75
+ email: (opts: {
76
+ email: string;
77
+ password: string;
78
+ }) => Promise<{
79
+ error?: {
80
+ message?: string;
81
+ } | null;
82
+ }>;
83
+ };
84
+ signUp: {
85
+ email: (opts: {
86
+ email: string;
87
+ password: string;
88
+ name: string;
89
+ }) => Promise<{
90
+ error?: {
91
+ message?: string;
92
+ } | null;
93
+ }>;
94
+ };
95
+ signOut: () => Promise<unknown>;
96
+ useSession: () => {
97
+ data?: {
98
+ user?: {
99
+ email?: string;
100
+ };
101
+ } | null;
102
+ isPending?: boolean;
103
+ };
104
+ }
105
+ interface AtlasUIConfig {
106
+ apiUrl: string;
107
+ authClient: AtlasAuthClient;
108
+ }
109
+ /** Internal context value — includes derived `isCrossOrigin` computed by the provider. */
110
+ interface AtlasUIContextValue extends AtlasUIConfig {
111
+ isCrossOrigin: boolean;
112
+ }
113
+ declare function useAtlasConfig(): AtlasUIContextValue;
114
+ declare function AtlasUIProvider({ config, children, }: {
115
+ config: AtlasUIConfig;
116
+ children: ReactNode;
117
+ }): react_jsx_runtime.JSX.Element;
118
+
119
+ type ThemeMode = "light" | "dark" | "system";
120
+
121
+ declare function setTheme(mode: ThemeMode): void;
122
+
123
+ export { type AtlasAuthClient as A, type ExploreToolResult as E, type PythonToolResult as P, type SQLToolResult as S, type ThemeMode as T, type ToolRenderers as a, type AtlasUIConfig as b, AtlasUIProvider as c, type ToolRendererProps as d, setTheme as s, useAtlasConfig as u };