@schandlergarcia/sf-web-components 1.8.0 → 1.9.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 (82) hide show
  1. package/dist/components/library/cards/SemanticTableCard.d.ts +1 -1
  2. package/dist/components/library/chat/ChatBar.d.ts +14 -11
  3. package/dist/components/library/chat/ChatBar.js +2 -3
  4. package/dist/components/library/chat/ChatBar.js.map +1 -1
  5. package/dist/components/library/chat/ChatInput.d.ts +9 -8
  6. package/dist/components/library/chat/ChatInput.js.map +1 -1
  7. package/dist/components/library/chat/ChatMessage.d.ts +18 -4
  8. package/dist/components/library/chat/ChatMessage.js.map +1 -1
  9. package/dist/components/library/chat/ChatMessageList.d.ts +11 -8
  10. package/dist/components/library/chat/ChatMessageList.js.map +1 -1
  11. package/dist/components/library/chat/ChatPanel.d.ts +16 -12
  12. package/dist/components/library/chat/ChatPanel.js +8 -9
  13. package/dist/components/library/chat/ChatPanel.js.map +1 -1
  14. package/dist/components/library/chat/ChatSuggestions.d.ts +5 -4
  15. package/dist/components/library/chat/ChatSuggestions.js +2 -3
  16. package/dist/components/library/chat/ChatSuggestions.js.map +1 -1
  17. package/dist/components/library/chat/ChatToolCall.d.ts +11 -3
  18. package/dist/components/library/chat/ChatToolCall.js.map +1 -1
  19. package/dist/components/library/chat/ChatTypingIndicator.d.ts +4 -3
  20. package/dist/components/library/chat/ChatTypingIndicator.js +2 -3
  21. package/dist/components/library/chat/ChatTypingIndicator.js.map +1 -1
  22. package/dist/components/library/chat/ChatWelcome.d.ts +9 -7
  23. package/dist/components/library/chat/ChatWelcome.js +6 -7
  24. package/dist/components/library/chat/ChatWelcome.js.map +1 -1
  25. package/dist/components/library/chat/index.d.ts +10 -0
  26. package/dist/components/library/chat/useChatState.d.ts +37 -11
  27. package/dist/components/library/chat/useChatState.js +63 -46
  28. package/dist/components/library/chat/useChatState.js.map +1 -1
  29. package/dist/components/library/data/DataModeProvider.d.ts +15 -11
  30. package/dist/components/library/data/DataModeProvider.js +1 -1
  31. package/dist/components/library/data/DataModeProvider.js.map +1 -1
  32. package/dist/components/library/data/DataModeToggle.d.ts +4 -3
  33. package/dist/components/library/data/DataModeToggle.js +4 -5
  34. package/dist/components/library/data/DataModeToggle.js.map +1 -1
  35. package/dist/components/library/data/chartDataProvider.d.ts +41 -3
  36. package/dist/components/library/data/filterUtils.d.ts +38 -9
  37. package/dist/components/library/data/filterUtils.js.map +1 -1
  38. package/dist/components/library/data/useDataSource.d.ts +6 -4
  39. package/dist/components/library/data/useDataSource.js.map +1 -1
  40. package/dist/components/library/data/usePageFilters.d.ts +31 -5
  41. package/dist/components/library/data/usePageFilters.js +6 -2
  42. package/dist/components/library/data/usePageFilters.js.map +1 -1
  43. package/dist/components/library/index.d.ts +92 -73
  44. package/dist/components/library/index.js +25 -25
  45. package/dist/components/library/index.js.map +1 -1
  46. package/dist/components/library/skeletons/CardSkeleton.d.ts +5 -4
  47. package/dist/components/library/skeletons/CardSkeleton.js +2 -3
  48. package/dist/components/library/skeletons/CardSkeleton.js.map +1 -1
  49. package/dist/components/library/theme/AppThemeProvider.d.ts +13 -50
  50. package/dist/components/library/theme/AppThemeProvider.js.map +1 -1
  51. package/dist/components/library/theme/tokens.d.ts +45 -44
  52. package/dist/components/library/theme/tokens.js.map +1 -1
  53. package/dist/components/workspace/ComponentRegistry.d.ts +116 -140
  54. package/dist/components/workspace/ComponentRegistry.js +43 -43
  55. package/dist/components/workspace/ComponentRegistry.js.map +1 -1
  56. package/package.json +2 -2
  57. package/src/components/library/cards/SemanticMetricCard.tsx +1 -1
  58. package/src/components/library/cards/SemanticTableCard.tsx +3 -3
  59. package/src/components/library/chat/{ChatBar.jsx → ChatBar.tsx} +19 -8
  60. package/src/components/library/chat/{ChatInput.jsx → ChatInput.tsx} +13 -11
  61. package/src/components/library/chat/{ChatMessage.jsx → ChatMessage.tsx} +23 -10
  62. package/src/components/library/chat/{ChatMessageList.jsx → ChatMessageList.tsx} +13 -11
  63. package/src/components/library/chat/{ChatPanel.jsx → ChatPanel.tsx} +16 -13
  64. package/src/components/library/chat/{ChatSuggestions.jsx → ChatSuggestions.tsx} +6 -5
  65. package/src/components/library/chat/{ChatToolCall.jsx → ChatToolCall.tsx} +14 -4
  66. package/src/components/library/chat/{ChatTypingIndicator.jsx → ChatTypingIndicator.tsx} +5 -2
  67. package/src/components/library/chat/{ChatWelcome.jsx → ChatWelcome.tsx} +9 -7
  68. package/src/components/library/chat/index.tsx +26 -0
  69. package/src/components/library/chat/useChatState.tsx +182 -0
  70. package/src/components/library/data/{DataModeProvider.jsx → DataModeProvider.tsx} +25 -8
  71. package/src/components/library/data/{DataModeToggle.jsx → DataModeToggle.tsx} +5 -2
  72. package/src/components/library/data/{chartDataProvider.jsx → chartDataProvider.tsx} +49 -5
  73. package/src/components/library/data/{filterUtils.jsx → filterUtils.tsx} +58 -12
  74. package/src/components/library/data/{useDataSource.jsx → useDataSource.tsx} +9 -2
  75. package/src/components/library/data/{usePageFilters.jsx → usePageFilters.tsx} +49 -9
  76. package/src/components/library/{index.jsx → index.ts} +14 -14
  77. package/src/components/library/skeletons/{CardSkeleton.jsx → CardSkeleton.tsx} +5 -4
  78. package/src/components/library/theme/{AppThemeProvider.jsx → AppThemeProvider.tsx} +20 -7
  79. package/src/components/library/theme/{tokens.jsx → tokens.tsx} +37 -3
  80. package/src/components/workspace/{ComponentRegistry.jsx → ComponentRegistry.tsx} +137 -32
  81. package/src/components/library/chat/index.jsx +0 -10
  82. package/src/components/library/chat/useChatState.jsx +0 -130
@@ -1,5 +1,5 @@
1
1
  import { jsxs as i, jsx as e } from "react/jsx-runtime";
2
- import b from "react";
2
+ import * as b from "react";
3
3
  import "../library/theme/AppThemeProvider.js";
4
4
  import u from "../library/ui/UIButton.js";
5
5
  import p from "../library/ui/Chip.js";
@@ -18,14 +18,14 @@ import "react-dom";
18
18
  import "../library/data/DataModeProvider.js";
19
19
  import "@heroicons/react/24/solid";
20
20
  const y = {
21
- NarrativeSummary({ summary: t, title: a }) {
21
+ NarrativeSummary({ summary: r, title: a }) {
22
22
  return /* @__PURE__ */ i("div", { className: "text-sm text-slate-600 dark:text-slate-300", children: [
23
23
  a && /* @__PURE__ */ e("div", { className: "mb-1 font-medium text-slate-900 dark:text-slate-50", children: a }),
24
- t
24
+ r
25
25
  ] });
26
26
  },
27
- MetricsStrip({ metrics: t = [], title: a, collapsible: d = !1, collapsed: l = !1 }) {
28
- const [o, s] = b.useState(l), n = t.length ? t : [
27
+ MetricsStrip({ metrics: r = [], title: a, collapsible: d = !1, collapsed: l = !1 }) {
28
+ const [o, s] = b.useState(l), n = r.length ? r : [
29
29
  { label: "Metric A", value: "—", trend: null },
30
30
  { label: "Metric B", value: "—", trend: null },
31
31
  { label: "Metric C", value: "—", trend: null }
@@ -40,7 +40,7 @@ const y = {
40
40
  /* @__PURE__ */ i("span", { children: [
41
41
  a ?? "Metrics",
42
42
  ": ",
43
- n.map((r) => `${r.label} ${r.value}`).join(" · ")
43
+ n.map((t) => `${t.label} ${t.value}`).join(" · ")
44
44
  ] }),
45
45
  /* @__PURE__ */ e("span", { children: "▸" })
46
46
  ]
@@ -58,26 +58,26 @@ const y = {
58
58
  }
59
59
  )
60
60
  ] }),
61
- /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-4", children: n.map((r) => /* @__PURE__ */ i("div", { className: "min-w-[80px]", children: [
62
- /* @__PURE__ */ e("div", { className: "text-xs text-slate-400 dark:text-slate-500", children: r.label }),
61
+ /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-4", children: n.map((t) => /* @__PURE__ */ i("div", { className: "min-w-[80px]", children: [
62
+ /* @__PURE__ */ e("div", { className: "text-xs text-slate-400 dark:text-slate-500", children: t.label }),
63
63
  /* @__PURE__ */ i("div", { className: "flex items-baseline gap-1.5", children: [
64
- /* @__PURE__ */ e("span", { className: "text-sm font-semibold text-slate-700 dark:text-slate-200", children: r.value }),
65
- r.trend && /* @__PURE__ */ e("span", { className: `text-xs ${String(r.trend).startsWith?.("+") || r.trend > 0 ? "text-red-500" : "text-emerald-500"}`, children: typeof r.trend == "number" && r.trend > 0 ? `+${r.trend}` : r.trend })
64
+ /* @__PURE__ */ e("span", { className: "text-sm font-semibold text-slate-700 dark:text-slate-200", children: t.value }),
65
+ t.trend && /* @__PURE__ */ e("span", { className: `text-xs ${String(t.trend).startsWith?.("+") || typeof t.trend == "number" && t.trend > 0 ? "text-red-500" : "text-emerald-500"}`, children: typeof t.trend == "number" && t.trend > 0 ? `+${t.trend}` : t.trend })
66
66
  ] })
67
- ] }, r.label)) })
67
+ ] }, t.label)) })
68
68
  ] });
69
69
  },
70
- ItemList({ items: t = [], title: a, onItemClick: d }) {
70
+ ItemList({ items: r = [], title: a, onItemClick: d }) {
71
71
  const [l, o] = b.useState(null);
72
- return t.length ? /* @__PURE__ */ i("div", { className: "space-y-2", children: [
72
+ return r.length ? /* @__PURE__ */ i("div", { className: "space-y-2", children: [
73
73
  a && /* @__PURE__ */ i("div", { className: "flex items-center justify-between", children: [
74
74
  /* @__PURE__ */ e("span", { className: "text-sm font-medium text-slate-900 dark:text-slate-50", children: a }),
75
75
  /* @__PURE__ */ i("span", { className: "text-xs text-slate-400 dark:text-slate-500", children: [
76
- t.length,
76
+ r.length,
77
77
  " items"
78
78
  ] })
79
79
  ] }),
80
- /* @__PURE__ */ e("div", { className: "space-y-1.5", children: t.map((s, n) => /* @__PURE__ */ i("div", { className: "rounded-xl border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-900", children: [
80
+ /* @__PURE__ */ e("div", { className: "space-y-1.5", children: r.map((s, n) => /* @__PURE__ */ i("div", { className: "rounded-xl border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-900", children: [
81
81
  /* @__PURE__ */ e(
82
82
  "button",
83
83
  {
@@ -95,19 +95,19 @@ const y = {
95
95
  ] })
96
96
  }
97
97
  ),
98
- l === (s.id ?? n) && s.actions && /* @__PURE__ */ e("div", { className: "border-t border-slate-100 px-3 py-2 dark:border-slate-800", children: /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1.5", children: s.actions.map((r, m) => /* @__PURE__ */ e(
98
+ l === (s.id ?? n) && s.actions && /* @__PURE__ */ e("div", { className: "border-t border-slate-100 px-3 py-2 dark:border-slate-800", children: /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1.5", children: s.actions.map((t, m) => /* @__PURE__ */ e(
99
99
  "button",
100
100
  {
101
101
  type: "button",
102
102
  className: `rounded-md px-2.5 py-1 text-xs font-medium transition-colors ${m === 0 ? "bg-slate-900 text-white hover:bg-slate-800 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-200" : "bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700"}`,
103
- children: typeof r == "string" ? r : r.label
103
+ children: typeof t == "string" ? t : t.label
104
104
  },
105
- typeof r == "string" ? r : r.label
105
+ typeof t == "string" ? t : t.label
106
106
  )) }) })
107
107
  ] }, s.id ?? n)) })
108
108
  ] }) : /* @__PURE__ */ e("div", { className: "text-sm text-slate-500 dark:text-slate-400", children: "No items." });
109
109
  },
110
- DataTable({ title: t, subtitle: a, columns: d = [], data: l = [], rows: o, searchable: s = !0, sortable: n = !0, paginated: r = !0, pageSize: m = 5 }) {
110
+ DataTable({ title: r, subtitle: a, columns: d = [], data: l = [], rows: o, searchable: s = !0, sortable: n = !0, paginated: t = !0, pageSize: m = 5 }) {
111
111
  const c = l.length ? l : o ?? [], x = d.length ? d : [
112
112
  { key: "name", label: "Name" },
113
113
  { key: "status", label: "Status" },
@@ -116,23 +116,23 @@ const y = {
116
116
  return /* @__PURE__ */ e(
117
117
  k,
118
118
  {
119
- title: t ?? "Data",
119
+ title: r ?? "Data",
120
120
  subtitle: a,
121
121
  columns: x,
122
122
  data: c,
123
123
  searchable: s,
124
124
  sortable: n,
125
- paginated: r,
125
+ paginated: t,
126
126
  pageSize: m
127
127
  }
128
128
  );
129
129
  },
130
- DataChart({ title: t, subtitle: a, chartType: d = "line", data: l = [], height: o = 200 }) {
131
- const s = l.length ? l : Array.from({ length: 12 }, (n, r) => ({ x: r, y: Math.random() * 100 }));
130
+ DataChart({ title: r, subtitle: a, chartType: d = "line", data: l = [], height: o = 200 }) {
131
+ const s = l.length ? l : Array.from({ length: 12 }, (n, t) => ({ x: t, y: Math.random() * 100 }));
132
132
  return /* @__PURE__ */ e(
133
133
  h,
134
134
  {
135
- title: t ?? "Trend",
135
+ title: r ?? "Trend",
136
136
  subtitle: a ?? "Data visualization",
137
137
  chartType: d,
138
138
  height: o,
@@ -142,34 +142,34 @@ const y = {
142
142
  data: s,
143
143
  responsive: !0,
144
144
  height: o,
145
- ariaLabel: t,
146
- renderChart: (n, r, m, c) => N.lineChart(n, r, m, c),
145
+ ariaLabel: r,
146
+ renderChart: (n, t, m, c) => N.lineChart(n, t, m, c),
147
147
  options: { xKey: "x", yKey: "y", showGrid: !0, showAxes: !0 }
148
148
  }
149
149
  )
150
150
  }
151
151
  );
152
152
  },
153
- MetricCard({ title: t, label: a, value: d, trend: l, change: o, changeType: s, color: n, icon: r, description: m }) {
153
+ MetricCard({ title: r, label: a, value: d, trend: l, change: o, changeType: s, color: n, icon: t, description: m }) {
154
154
  return /* @__PURE__ */ e(
155
155
  g,
156
156
  {
157
- title: t ?? a,
157
+ title: r ?? a,
158
158
  value: d ?? "—",
159
159
  trend: l,
160
160
  change: o,
161
161
  changeType: s,
162
162
  color: n,
163
- icon: r,
164
- description: m
163
+ icon: t,
164
+ subtitle: m
165
165
  }
166
166
  );
167
167
  },
168
- StatusCard({ title: t, subtitle: a, status: d, items: l, layout: o, showProgress: s, showTimestamp: n }) {
168
+ StatusCard({ title: r, subtitle: a, status: d, items: l, layout: o, showProgress: s, showTimestamp: n }) {
169
169
  return /* @__PURE__ */ e(
170
170
  f,
171
171
  {
172
- title: t,
172
+ title: r,
173
173
  subtitle: a,
174
174
  status: d,
175
175
  items: l,
@@ -179,10 +179,10 @@ const y = {
179
179
  }
180
180
  );
181
181
  },
182
- ActionList({ actions: t = [], title: a, onAction: d }) {
182
+ ActionList({ actions: r = [], title: a, onAction: d }) {
183
183
  return /* @__PURE__ */ i("div", { className: "rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-900", children: [
184
184
  a && /* @__PURE__ */ e("div", { className: "mb-3 text-sm font-medium text-slate-900 dark:text-slate-50", children: a }),
185
- /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-2", children: t.map((l, o) => /* @__PURE__ */ e(
185
+ /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-2", children: r.map((l, o) => /* @__PURE__ */ e(
186
186
  u,
187
187
  {
188
188
  size: "sm",
@@ -194,7 +194,7 @@ const y = {
194
194
  )) })
195
195
  ] });
196
196
  },
197
- CalloutCard({ title: t, message: a, tone: d = "neutral" }) {
197
+ CalloutCard({ title: r, message: a, tone: d = "neutral" }) {
198
198
  const l = {
199
199
  neutral: "border-slate-200 bg-slate-50 text-slate-700 dark:border-slate-800 dark:bg-slate-950/30 dark:text-slate-200",
200
200
  success: "border-emerald-200 bg-emerald-50 text-emerald-800 dark:border-emerald-900/40 dark:bg-emerald-950/20 dark:text-emerald-200",
@@ -202,31 +202,31 @@ const y = {
202
202
  danger: "border-rose-200 bg-rose-50 text-rose-800 dark:border-rose-900/40 dark:bg-rose-950/20 dark:text-rose-200"
203
203
  };
204
204
  return /* @__PURE__ */ i("div", { className: `rounded-xl border p-4 ${l[d] ?? l.neutral}`, children: [
205
- t && /* @__PURE__ */ e("div", { className: "mb-1 text-sm font-semibold", children: t }),
205
+ r && /* @__PURE__ */ e("div", { className: "mb-1 text-sm font-semibold", children: r }),
206
206
  /* @__PURE__ */ e("div", { className: "text-sm", children: a })
207
207
  ] });
208
208
  },
209
209
  Divider() {
210
210
  return /* @__PURE__ */ e("div", { className: "h-px bg-slate-200 dark:bg-slate-800" });
211
211
  },
212
- Spacer({ size: t = "md" }) {
212
+ Spacer({ size: r = "md" }) {
213
213
  const a = { sm: "h-2", md: "h-4", lg: "h-6" };
214
- return /* @__PURE__ */ e("div", { className: a[t] ?? a.md });
214
+ return /* @__PURE__ */ e("div", { className: a[r] ?? a.md });
215
215
  }
216
216
  };
217
217
  let C = { ...y };
218
218
  function w() {
219
219
  return C;
220
220
  }
221
- function V(t, a) {
222
- const l = w()[t.type];
223
- return l ? /* @__PURE__ */ e(l, { ...t.props ?? {} }, t.id ?? a) : /* @__PURE__ */ i("div", { className: "rounded-lg border border-dashed border-slate-300 p-3 text-xs text-slate-500 dark:border-slate-700", children: [
221
+ function P(r, a) {
222
+ const l = w()[r.type];
223
+ return l ? /* @__PURE__ */ e(l, { ...r.props ?? {} }, r.id ?? a) : /* @__PURE__ */ i("div", { className: "rounded-lg border border-dashed border-slate-300 p-3 text-xs text-slate-500 dark:border-slate-700", children: [
224
224
  "Unknown component: ",
225
- t.type
225
+ r.type
226
226
  ] }, a);
227
227
  }
228
228
  export {
229
229
  w as getComponentRegistry,
230
- V as renderSchemaComponent
230
+ P as renderSchemaComponent
231
231
  };
232
232
  //# sourceMappingURL=ComponentRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentRegistry.js","sources":["../../../src/components/workspace/ComponentRegistry.jsx"],"sourcesContent":["import React from \"react\";\nimport {\n BaseCard,\n MetricCard,\n TableCard,\n ChartCard,\n D3Chart,\n D3ChartTemplates,\n StatusCard,\n ListCard,\n UIButton,\n UIChip,\n UIText\n} from \"@/components/library\";\n\nconst BUILTIN_COMPONENTS = {\n NarrativeSummary({ summary, title }) {\n return (\n <div className=\"text-sm text-slate-600 dark:text-slate-300\">\n {title && <div className=\"mb-1 font-medium text-slate-900 dark:text-slate-50\">{title}</div>}\n {summary}\n </div>\n );\n },\n\n MetricsStrip({ metrics = [], title, collapsible = false, collapsed: initialCollapsed = false }) {\n const [collapsed, setCollapsed] = React.useState(initialCollapsed);\n\n const items = metrics.length ? metrics : [\n { label: \"Metric A\", value: \"—\", trend: null },\n { label: \"Metric B\", value: \"—\", trend: null },\n { label: \"Metric C\", value: \"—\", trend: null }\n ];\n\n if (collapsible && collapsed) {\n return (\n <button\n type=\"button\"\n onClick={() => setCollapsed(false)}\n className=\"flex w-full items-center justify-between rounded-lg border border-slate-200 bg-white px-3 py-2 text-left text-xs text-slate-500 hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-400 dark:hover:bg-slate-800\"\n >\n <span>{title ?? \"Metrics\"}: {items.map(m => `${m.label} ${m.value}`).join(\" · \")}</span>\n <span>▸</span>\n </button>\n );\n }\n\n return (\n <div className=\"rounded-xl border border-slate-200 bg-white p-3 dark:border-slate-800 dark:bg-slate-900\">\n {(title || collapsible) && (\n <div className=\"mb-2 flex items-center justify-between\">\n <span className=\"text-xs font-medium text-slate-500 dark:text-slate-400\">{title ?? \"Metrics\"}</span>\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => setCollapsed(true)}\n className=\"text-xs text-slate-400 hover:text-slate-600 dark:text-slate-500 dark:hover:text-slate-300\"\n >\n Collapse\n </button>\n )}\n </div>\n )}\n <div className=\"flex flex-wrap gap-4\">\n {items.map((m) => (\n <div key={m.label} className=\"min-w-[80px]\">\n <div className=\"text-xs text-slate-400 dark:text-slate-500\">{m.label}</div>\n <div className=\"flex items-baseline gap-1.5\">\n <span className=\"text-sm font-semibold text-slate-700 dark:text-slate-200\">{m.value}</span>\n {m.trend && (\n <span className={`text-xs ${String(m.trend).startsWith?.(\"+\") || m.trend > 0 ? \"text-red-500\" : \"text-emerald-500\"}`}>\n {typeof m.trend === \"number\" ? (m.trend > 0 ? `+${m.trend}` : m.trend) : m.trend}\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n },\n\n ItemList({ items = [], title, onItemClick }) {\n const [expanded, setExpanded] = React.useState(null);\n if (!items.length) {\n return <div className=\"text-sm text-slate-500 dark:text-slate-400\">No items.</div>;\n }\n return (\n <div className=\"space-y-2\">\n {title && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium text-slate-900 dark:text-slate-50\">{title}</span>\n <span className=\"text-xs text-slate-400 dark:text-slate-500\">{items.length} items</span>\n </div>\n )}\n <div className=\"space-y-1.5\">\n {items.map((item, idx) => (\n <div key={item.id ?? idx} className=\"rounded-xl border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-900\">\n <button\n type=\"button\"\n onClick={() => {\n setExpanded(expanded === (item.id ?? idx) ? null : (item.id ?? idx));\n onItemClick?.(item);\n }}\n className=\"flex w-full items-start justify-between gap-3 p-3 text-left\"\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"text-sm font-medium text-slate-900 dark:text-slate-50\">\n {item.title ?? item.name ?? `Item ${idx + 1}`}\n </div>\n {item.status && (\n <UIChip tone={item.status === \"critical\" ? \"danger\" : item.status === \"warning\" ? \"warning\" : \"neutral\"} className=\"shrink-0\">\n {item.status}\n </UIChip>\n )}\n </div>\n {item.description && (\n <div className=\"mt-1 text-xs text-slate-500 dark:text-slate-400\">{item.description}</div>\n )}\n </div>\n </button>\n {expanded === (item.id ?? idx) && item.actions && (\n <div className=\"border-t border-slate-100 px-3 py-2 dark:border-slate-800\">\n <div className=\"flex flex-wrap gap-1.5\">\n {item.actions.map((action, i) => (\n <button\n key={typeof action === \"string\" ? action : action.label}\n type=\"button\"\n className={`rounded-md px-2.5 py-1 text-xs font-medium transition-colors ${\n i === 0\n ? \"bg-slate-900 text-white hover:bg-slate-800 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-200\"\n : \"bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700\"\n }`}\n >\n {typeof action === \"string\" ? action : action.label}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n },\n\n DataTable({ title, subtitle, columns = [], data = [], rows, searchable = true, sortable = true, paginated = true, pageSize = 5 }) {\n const tableData = data.length ? data : (rows ?? []);\n const cols = columns.length ? columns : [\n { key: \"name\", label: \"Name\" },\n { key: \"status\", label: \"Status\" },\n { key: \"value\", label: \"Value\" }\n ];\n return (\n <TableCard\n title={title ?? \"Data\"}\n subtitle={subtitle}\n columns={cols}\n data={tableData}\n searchable={searchable}\n sortable={sortable}\n paginated={paginated}\n pageSize={pageSize}\n />\n );\n },\n\n DataChart({ title, subtitle, chartType = \"line\", data = [], height = 200 }) {\n const series = data.length ? data : Array.from({ length: 12 }, (_, i) => ({ x: i, y: Math.random() * 100 }));\n return (\n <ChartCard\n title={title ?? \"Trend\"}\n subtitle={subtitle ?? \"Data visualization\"}\n chartType={chartType}\n height={height}\n chart={\n <D3Chart\n data={series}\n responsive\n height={height}\n ariaLabel={title}\n renderChart={(svg, d, dims, opts) => D3ChartTemplates.lineChart(svg, d, dims, opts)}\n options={{ xKey: \"x\", yKey: \"y\", showGrid: true, showAxes: true }}\n />\n }\n />\n );\n },\n\n MetricCard({ title, label, value, trend, change, changeType, color, icon, description }) {\n return (\n <MetricCard\n title={title ?? label}\n value={value ?? \"—\"}\n trend={trend}\n change={change}\n changeType={changeType}\n color={color}\n icon={icon}\n description={description}\n />\n );\n },\n\n StatusCard({ title, subtitle, status, items, layout, showProgress, showTimestamp }) {\n return (\n <StatusCard\n title={title}\n subtitle={subtitle}\n status={status}\n items={items}\n layout={layout}\n showProgress={showProgress}\n showTimestamp={showTimestamp}\n />\n );\n },\n\n ActionList({ actions = [], title, onAction }) {\n return (\n <div className=\"rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-900\">\n {title && <div className=\"mb-3 text-sm font-medium text-slate-900 dark:text-slate-50\">{title}</div>}\n <div className=\"flex flex-wrap gap-2\">\n {actions.map((action, i) => (\n <UIButton\n key={i}\n size=\"sm\"\n variant={i === 0 ? \"primary\" : \"outline\"}\n onClick={() => onAction?.(action)}\n >\n {typeof action === \"string\" ? action : action.label}\n </UIButton>\n ))}\n </div>\n </div>\n );\n },\n\n CalloutCard({ title, message, tone = \"neutral\" }) {\n const toneClasses = {\n neutral: \"border-slate-200 bg-slate-50 text-slate-700 dark:border-slate-800 dark:bg-slate-950/30 dark:text-slate-200\",\n success: \"border-emerald-200 bg-emerald-50 text-emerald-800 dark:border-emerald-900/40 dark:bg-emerald-950/20 dark:text-emerald-200\",\n warning: \"border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-900/40 dark:bg-amber-950/20 dark:text-amber-200\",\n danger: \"border-rose-200 bg-rose-50 text-rose-800 dark:border-rose-900/40 dark:bg-rose-950/20 dark:text-rose-200\"\n };\n return (\n <div className={`rounded-xl border p-4 ${toneClasses[tone] ?? toneClasses.neutral}`}>\n {title && <div className=\"mb-1 text-sm font-semibold\">{title}</div>}\n <div className=\"text-sm\">{message}</div>\n </div>\n );\n },\n\n Divider() {\n return <div className=\"h-px bg-slate-200 dark:bg-slate-800\" />;\n },\n\n Spacer({ size = \"md\" }) {\n const heights = { sm: \"h-2\", md: \"h-4\", lg: \"h-6\" };\n return <div className={heights[size] ?? heights.md} />;\n }\n};\n\nlet _registry = { ...BUILTIN_COMPONENTS };\n\nexport function getComponentRegistry() {\n return _registry;\n}\n\nexport function registerComponent(type, Component) {\n _registry = { ..._registry, [type]: Component };\n}\n\nexport function registerComponents(map) {\n _registry = { ..._registry, ...map };\n}\n\nexport function renderSchemaComponent(component, index) {\n const registry = getComponentRegistry();\n const Component = registry[component.type];\n if (!Component) {\n return (\n <div key={index} className=\"rounded-lg border border-dashed border-slate-300 p-3 text-xs text-slate-500 dark:border-slate-700\">\n Unknown component: {component.type}\n </div>\n );\n }\n return <Component key={component.id ?? index} {...(component.props ?? {})} />;\n}\n\nexport function renderSchema(components = []) {\n return components.map((c, i) => renderSchemaComponent(c, i));\n}\n\nexport default BUILTIN_COMPONENTS;\n"],"names":["BUILTIN_COMPONENTS","summary","title","jsxs","jsx","metrics","collapsible","initialCollapsed","collapsed","setCollapsed","React","items","m","onItemClick","expanded","setExpanded","item","idx","UIChip","action","i","subtitle","columns","data","rows","searchable","sortable","paginated","pageSize","tableData","cols","TableCard","chartType","height","series","_","ChartCard","D3Chart","svg","d","dims","opts","D3ChartTemplates","label","value","trend","change","changeType","color","icon","description","MetricCard","status","layout","showProgress","showTimestamp","StatusCard","actions","onAction","UIButton","message","tone","toneClasses","size","heights","_registry","getComponentRegistry","renderSchemaComponent","component","index","Component"],"mappings":";;;;;;;;;;;;;;;;;;;AAeA,MAAMA,IAAqB;AAAA,EACzB,iBAAiB,EAAE,SAAAC,GAAS,OAAAC,KAAS;AACnC,WACE,gBAAAC,EAAC,OAAA,EAAI,WAAU,8CACZ,UAAA;AAAA,MAAAD,KAAS,gBAAAE,EAAC,OAAA,EAAI,WAAU,sDAAsD,UAAAF,GAAM;AAAA,MACpFD;AAAA,IAAA,GACH;AAAA,EAEJ;AAAA,EAEA,aAAa,EAAE,SAAAI,IAAU,CAAA,GAAI,OAAAH,GAAO,aAAAI,IAAc,IAAO,WAAWC,IAAmB,MAAS;AAC9F,UAAM,CAACC,GAAWC,CAAY,IAAIC,EAAM,SAASH,CAAgB,GAE3DI,IAAQN,EAAQ,SAASA,IAAU;AAAA,MACvC,EAAE,OAAO,YAAY,OAAO,KAAK,OAAO,KAAA;AAAA,MACxC,EAAE,OAAO,YAAY,OAAO,KAAK,OAAO,KAAA;AAAA,MACxC,EAAE,OAAO,YAAY,OAAO,KAAK,OAAO,KAAA;AAAA,IAAK;AAG/C,WAAIC,KAAeE,IAEf,gBAAAL;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAMM,EAAa,EAAK;AAAA,QACjC,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAAN,EAAC,QAAA,EAAM,UAAA;AAAA,YAAAD,KAAS;AAAA,YAAU;AAAA,YAAGS,EAAM,IAAI,CAAAC,MAAK,GAAGA,EAAE,KAAK,IAAIA,EAAE,KAAK,EAAE,EAAE,KAAK,KAAK;AAAA,UAAA,GAAE;AAAA,UACjF,gBAAAR,EAAC,UAAK,UAAA,IAAA,CAAC;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,IAMX,gBAAAD,EAAC,OAAA,EAAI,WAAU,2FACX,UAAA;AAAA,OAAAD,KAASI,MACT,gBAAAH,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,0DAA0D,UAAAF,KAAS,WAAU;AAAA,QAC5FI,KACC,gBAAAF;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAMK,EAAa,EAAI;AAAA,YAChC,WAAU;AAAA,YACX,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,GAEJ;AAAA,MAEF,gBAAAL,EAAC,OAAA,EAAI,WAAU,wBACZ,UAAAO,EAAM,IAAI,CAACC,MACV,gBAAAT,EAAC,OAAA,EAAkB,WAAU,gBAC3B,UAAA;AAAA,QAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,8CAA8C,UAAAQ,EAAE,OAAM;AAAA,QACrE,gBAAAT,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,4DAA4D,UAAAQ,EAAE,OAAM;AAAA,UACnFA,EAAE,SACD,gBAAAR,EAAC,QAAA,EAAK,WAAW,WAAW,OAAOQ,EAAE,KAAK,EAAE,aAAa,GAAG,KAAKA,EAAE,QAAQ,IAAI,iBAAiB,kBAAkB,IAC/G,UAAA,OAAOA,EAAE,SAAU,YAAYA,EAAE,QAAQ,IAAI,IAAIA,EAAE,KAAK,KAAgBA,EAAE,MAAA,CAC7E;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA,KATQA,EAAE,KAUZ,CACD,EAAA,CACH;AAAA,IAAA,GACF;AAAA,EAEJ;AAAA,EAEA,SAAS,EAAE,OAAAD,IAAQ,CAAA,GAAI,OAAAT,GAAO,aAAAW,KAAe;AAC3C,UAAM,CAACC,GAAUC,CAAW,IAAIL,EAAM,SAAS,IAAI;AACnD,WAAKC,EAAM,SAIT,gBAAAR,EAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,MAAAD,KACC,gBAAAC,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,yDAAyD,UAAAF,GAAM;AAAA,QAC/E,gBAAAC,EAAC,QAAA,EAAK,WAAU,8CAA8C,UAAA;AAAA,UAAAQ,EAAM;AAAA,UAAO;AAAA,QAAA,EAAA,CAAM;AAAA,MAAA,GACnF;AAAA,MAEF,gBAAAP,EAAC,OAAA,EAAI,WAAU,eACZ,UAAAO,EAAM,IAAI,CAACK,GAAMC,MAChB,gBAAAd,EAAC,OAAA,EAAyB,WAAU,uFAClC,UAAA;AAAA,QAAA,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM;AACb,cAAAW,EAAYD,OAAcE,EAAK,MAAMC,KAAO,OAAQD,EAAK,MAAMC,CAAI,GACnEJ,IAAcG,CAAI;AAAA,YACpB;AAAA,YACA,WAAU;AAAA,YAEV,UAAA,gBAAAb,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,cAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,gBAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,yDACZ,UAAAY,EAAK,SAASA,EAAK,QAAQ,QAAQC,IAAM,CAAC,GAAA,CAC7C;AAAA,gBACCD,EAAK,UACJ,gBAAAZ,EAACc,GAAA,EAAO,MAAMF,EAAK,WAAW,aAAa,WAAWA,EAAK,WAAW,YAAY,YAAY,WAAW,WAAU,YAChH,YAAK,OAAA,CACR;AAAA,cAAA,GAEJ;AAAA,cACCA,EAAK,eACJ,gBAAAZ,EAAC,SAAI,WAAU,mDAAmD,YAAK,YAAA,CAAY;AAAA,YAAA,EAAA,CAEvF;AAAA,UAAA;AAAA,QAAA;AAAA,QAEDU,OAAcE,EAAK,MAAMC,MAAQD,EAAK,6BACpC,OAAA,EAAI,WAAU,6DACb,UAAA,gBAAAZ,EAAC,OAAA,EAAI,WAAU,0BACZ,UAAAY,EAAK,QAAQ,IAAI,CAACG,GAAQC,MACzB,gBAAAhB;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,MAAK;AAAA,YACL,WAAW,gEACTgB,MAAM,IACF,4GACA,8GACN;AAAA,YAEC,UAAA,OAAOD,KAAW,WAAWA,IAASA,EAAO;AAAA,UAAA;AAAA,UARzC,OAAOA,KAAW,WAAWA,IAASA,EAAO;AAAA,QAAA,CAUrD,GACH,EAAA,CACF;AAAA,MAAA,EAAA,GA1CMH,EAAK,MAAMC,CA4CrB,CACD,EAAA,CACH;AAAA,IAAA,GACF,IA3DO,gBAAAb,EAAC,OAAA,EAAI,WAAU,8CAA6C,UAAA,aAAS;AAAA,EA6DhF;AAAA,EAEA,UAAU,EAAE,OAAAF,GAAO,UAAAmB,GAAU,SAAAC,IAAU,CAAA,GAAI,MAAAC,IAAO,IAAI,MAAAC,GAAM,YAAAC,IAAa,IAAM,UAAAC,IAAW,IAAM,WAAAC,IAAY,IAAM,UAAAC,IAAW,KAAK;AAChI,UAAMC,IAAYN,EAAK,SAASA,IAAQC,KAAQ,CAAA,GAC1CM,IAAOR,EAAQ,SAASA,IAAU;AAAA,MACtC,EAAE,KAAK,QAAQ,OAAO,OAAA;AAAA,MACtB,EAAE,KAAK,UAAU,OAAO,SAAA;AAAA,MACxB,EAAE,KAAK,SAAS,OAAO,QAAA;AAAA,IAAQ;AAEjC,WACE,gBAAAlB;AAAA,MAAC2B;AAAA,MAAA;AAAA,QACC,OAAO7B,KAAS;AAAA,QAChB,UAAAmB;AAAA,QACA,SAASS;AAAA,QACT,MAAMD;AAAA,QACN,YAAAJ;AAAA,QACA,UAAAC;AAAA,QACA,WAAAC;AAAA,QACA,UAAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAAA,EAEA,UAAU,EAAE,OAAA1B,GAAO,UAAAmB,GAAU,WAAAW,IAAY,QAAQ,MAAAT,IAAO,CAAA,GAAI,QAAAU,IAAS,OAAO;AAC1E,UAAMC,IAASX,EAAK,SAASA,IAAO,MAAM,KAAK,EAAE,QAAQ,GAAA,GAAM,CAACY,GAAGf,OAAO,EAAE,GAAGA,GAAG,GAAG,KAAK,OAAA,IAAW,IAAA,EAAM;AAC3G,WACE,gBAAAhB;AAAA,MAACgC;AAAA,MAAA;AAAA,QACC,OAAOlC,KAAS;AAAA,QAChB,UAAUmB,KAAY;AAAA,QACtB,WAAAW;AAAA,QACA,QAAAC;AAAA,QACA,OACE,gBAAA7B;AAAA,UAACiC;AAAA,UAAA;AAAA,YACC,MAAMH;AAAA,YACN,YAAU;AAAA,YACV,QAAAD;AAAA,YACA,WAAW/B;AAAA,YACX,aAAa,CAACoC,GAAKC,GAAGC,GAAMC,MAASC,EAAiB,UAAUJ,GAAKC,GAAGC,GAAMC,CAAI;AAAA,YAClF,SAAS,EAAE,MAAM,KAAK,MAAM,KAAK,UAAU,IAAM,UAAU,GAAA;AAAA,UAAK;AAAA,QAAA;AAAA,MAClE;AAAA,IAAA;AAAA,EAIR;AAAA,EAEA,WAAW,EAAE,OAAAvC,GAAO,OAAAyC,GAAO,OAAAC,GAAO,OAAAC,GAAO,QAAAC,GAAQ,YAAAC,GAAY,OAAAC,GAAO,MAAAC,GAAM,aAAAC,EAAA,GAAe;AACvF,WACE,gBAAA9C;AAAA,MAAC+C;AAAA,MAAA;AAAA,QACC,OAAOjD,KAASyC;AAAA,QAChB,OAAOC,KAAS;AAAA,QAChB,OAAAC;AAAA,QACA,QAAAC;AAAA,QACA,YAAAC;AAAA,QACA,OAAAC;AAAA,QACA,MAAAC;AAAA,QACA,aAAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAAA,EAEA,WAAW,EAAE,OAAAhD,GAAO,UAAAmB,GAAU,QAAA+B,GAAQ,OAAAzC,GAAO,QAAA0C,GAAQ,cAAAC,GAAc,eAAAC,KAAiB;AAClF,WACE,gBAAAnD;AAAA,MAACoD;AAAA,MAAA;AAAA,QACC,OAAAtD;AAAA,QACA,UAAAmB;AAAA,QACA,QAAA+B;AAAA,QACA,OAAAzC;AAAA,QACA,QAAA0C;AAAA,QACA,cAAAC;AAAA,QACA,eAAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAAA,EAEA,WAAW,EAAE,SAAAE,IAAU,CAAA,GAAI,OAAAvD,GAAO,UAAAwD,KAAY;AAC5C,WACE,gBAAAvD,EAAC,OAAA,EAAI,WAAU,4FACZ,UAAA;AAAA,MAAAD,KAAS,gBAAAE,EAAC,OAAA,EAAI,WAAU,8DAA8D,UAAAF,GAAM;AAAA,MAC7F,gBAAAE,EAAC,SAAI,WAAU,wBACZ,YAAQ,IAAI,CAACe,GAAQC,MACpB,gBAAAhB;AAAA,QAACuD;AAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAASvC,MAAM,IAAI,YAAY;AAAA,UAC/B,SAAS,MAAMsC,IAAWvC,CAAM;AAAA,UAE/B,UAAA,OAAOA,KAAW,WAAWA,IAASA,EAAO;AAAA,QAAA;AAAA,QALzCC;AAAA,MAAA,CAOR,EAAA,CACH;AAAA,IAAA,GACF;AAAA,EAEJ;AAAA,EAEA,YAAY,EAAE,OAAAlB,GAAO,SAAA0D,GAAS,MAAAC,IAAO,aAAa;AAChD,UAAMC,IAAc;AAAA,MAClB,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,QAAQ;AAAA,IAAA;AAEV,WACE,gBAAA3D,EAAC,SAAI,WAAW,yBAAyB2D,EAAYD,CAAI,KAAKC,EAAY,OAAO,IAC9E,UAAA;AAAA,MAAA5D,KAAS,gBAAAE,EAAC,OAAA,EAAI,WAAU,8BAA8B,UAAAF,GAAM;AAAA,MAC7D,gBAAAE,EAAC,OAAA,EAAI,WAAU,WAAW,UAAAwD,EAAA,CAAQ;AAAA,IAAA,GACpC;AAAA,EAEJ;AAAA,EAEA,UAAU;AACR,WAAO,gBAAAxD,EAAC,OAAA,EAAI,WAAU,sCAAA,CAAsC;AAAA,EAC9D;AAAA,EAEA,OAAO,EAAE,MAAA2D,IAAO,QAAQ;AACtB,UAAMC,IAAU,EAAE,IAAI,OAAO,IAAI,OAAO,IAAI,MAAA;AAC5C,6BAAQ,OAAA,EAAI,WAAWA,EAAQD,CAAI,KAAKC,EAAQ,IAAI;AAAA,EACtD;AACF;AAEA,IAAIC,IAAY,EAAE,GAAGjE,EAAA;AAEd,SAASkE,IAAuB;AACrC,SAAOD;AACT;AAUO,SAASE,EAAsBC,GAAWC,GAAO;AAEtD,QAAMC,IADWJ,EAAA,EACUE,EAAU,IAAI;AACzC,SAAKE,IAOE,gBAAAlE,EAACkE,KAAuC,GAAIF,EAAU,SAAS,CAAA,KAA/CA,EAAU,MAAMC,CAAoC,IALvE,gBAAAlE,EAAC,OAAA,EAAgB,WAAU,qGAAoG,UAAA;AAAA,IAAA;AAAA,IACzGiE,EAAU;AAAA,EAAA,EAAA,GADtBC,CAEV;AAIN;"}
1
+ {"version":3,"file":"ComponentRegistry.js","sources":["../../../src/components/workspace/ComponentRegistry.tsx"],"sourcesContent":["import * as React from \"react\";\nimport {\n MetricCard,\n TableCard,\n ChartCard,\n D3Chart,\n D3ChartTemplates,\n StatusCard,\n UIButton,\n UIChip\n} from \"@/components/library\";\n\nexport interface Metric {\n label: string;\n value: string | number;\n trend?: string | number | null;\n}\n\nexport interface MetricsStripProps {\n metrics?: Metric[];\n title?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n}\n\nexport interface ListItem {\n id?: string;\n title?: string;\n name?: string;\n description?: string;\n status?: \"critical\" | \"warning\" | string;\n actions?: Array<string | { label: string }>;\n}\n\nexport interface ItemListProps {\n items?: ListItem[];\n title?: string;\n onItemClick?: (item: ListItem) => void;\n}\n\nexport interface TableColumn {\n key: string;\n label: string;\n}\n\nexport interface DataTableProps {\n title?: string;\n subtitle?: string;\n columns?: TableColumn[];\n data?: any[];\n rows?: any[];\n searchable?: boolean;\n sortable?: boolean;\n paginated?: boolean;\n pageSize?: number;\n}\n\nexport interface DataPoint {\n x: number;\n y: number;\n [key: string]: any;\n}\n\nexport interface DataChartProps {\n title?: string;\n subtitle?: string;\n chartType?: string;\n data?: DataPoint[];\n height?: number;\n}\n\nexport interface MetricCardComponentProps {\n title?: string;\n label?: string;\n value?: string | number;\n trend?: string | number;\n change?: string | number;\n changeType?: string;\n color?: string;\n icon?: React.ReactNode;\n description?: string;\n}\n\nexport interface StatusCardComponentProps {\n title?: string;\n subtitle?: string;\n status?: string;\n items?: any[];\n layout?: string;\n showProgress?: boolean;\n showTimestamp?: boolean;\n}\n\nexport interface ActionListProps {\n actions?: Array<string | { label: string }>;\n title?: string;\n onAction?: (action: string | { label: string }) => void;\n}\n\nexport interface CalloutCardProps {\n title?: string;\n message?: string;\n tone?: \"neutral\" | \"success\" | \"warning\" | \"danger\";\n}\n\nexport interface SpacerProps {\n size?: \"sm\" | \"md\" | \"lg\";\n}\n\nexport interface NarrativeSummaryProps {\n summary?: string;\n title?: string;\n}\n\nexport interface SchemaComponent {\n id?: string;\n type: string;\n props?: Record<string, any>;\n}\n\nconst BUILTIN_COMPONENTS = {\n NarrativeSummary({ summary, title }: NarrativeSummaryProps) {\n return (\n <div className=\"text-sm text-slate-600 dark:text-slate-300\">\n {title && <div className=\"mb-1 font-medium text-slate-900 dark:text-slate-50\">{title}</div>}\n {summary}\n </div>\n );\n },\n\n MetricsStrip({ metrics = [], title, collapsible = false, collapsed: initialCollapsed = false }: MetricsStripProps) {\n const [collapsed, setCollapsed] = React.useState(initialCollapsed);\n\n const items = metrics.length ? metrics : [\n { label: \"Metric A\", value: \"—\", trend: null },\n { label: \"Metric B\", value: \"—\", trend: null },\n { label: \"Metric C\", value: \"—\", trend: null }\n ];\n\n if (collapsible && collapsed) {\n return (\n <button\n type=\"button\"\n onClick={() => setCollapsed(false)}\n className=\"flex w-full items-center justify-between rounded-lg border border-slate-200 bg-white px-3 py-2 text-left text-xs text-slate-500 hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-400 dark:hover:bg-slate-800\"\n >\n <span>{title ?? \"Metrics\"}: {items.map(m => `${m.label} ${m.value}`).join(\" · \")}</span>\n <span>▸</span>\n </button>\n );\n }\n\n return (\n <div className=\"rounded-xl border border-slate-200 bg-white p-3 dark:border-slate-800 dark:bg-slate-900\">\n {(title || collapsible) && (\n <div className=\"mb-2 flex items-center justify-between\">\n <span className=\"text-xs font-medium text-slate-500 dark:text-slate-400\">{title ?? \"Metrics\"}</span>\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => setCollapsed(true)}\n className=\"text-xs text-slate-400 hover:text-slate-600 dark:text-slate-500 dark:hover:text-slate-300\"\n >\n Collapse\n </button>\n )}\n </div>\n )}\n <div className=\"flex flex-wrap gap-4\">\n {items.map((m) => (\n <div key={m.label} className=\"min-w-[80px]\">\n <div className=\"text-xs text-slate-400 dark:text-slate-500\">{m.label}</div>\n <div className=\"flex items-baseline gap-1.5\">\n <span className=\"text-sm font-semibold text-slate-700 dark:text-slate-200\">{m.value}</span>\n {m.trend && (\n <span className={`text-xs ${String(m.trend).startsWith?.(\"+\") || (typeof m.trend === \"number\" && m.trend > 0) ? \"text-red-500\" : \"text-emerald-500\"}`}>\n {typeof m.trend === \"number\" ? (m.trend > 0 ? `+${m.trend}` : m.trend) : m.trend}\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n },\n\n ItemList({ items = [], title, onItemClick }: ItemListProps) {\n const [expanded, setExpanded] = React.useState<string | number | null>(null);\n if (!items.length) {\n return <div className=\"text-sm text-slate-500 dark:text-slate-400\">No items.</div>;\n }\n return (\n <div className=\"space-y-2\">\n {title && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium text-slate-900 dark:text-slate-50\">{title}</span>\n <span className=\"text-xs text-slate-400 dark:text-slate-500\">{items.length} items</span>\n </div>\n )}\n <div className=\"space-y-1.5\">\n {items.map((item, idx) => (\n <div key={item.id ?? idx} className=\"rounded-xl border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-900\">\n <button\n type=\"button\"\n onClick={() => {\n setExpanded(expanded === (item.id ?? idx) ? null : (item.id ?? idx));\n onItemClick?.(item);\n }}\n className=\"flex w-full items-start justify-between gap-3 p-3 text-left\"\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"text-sm font-medium text-slate-900 dark:text-slate-50\">\n {item.title ?? item.name ?? `Item ${idx + 1}`}\n </div>\n {item.status && (\n <UIChip tone={item.status === \"critical\" ? \"danger\" : item.status === \"warning\" ? \"warning\" : \"neutral\"} className=\"shrink-0\">\n {item.status}\n </UIChip>\n )}\n </div>\n {item.description && (\n <div className=\"mt-1 text-xs text-slate-500 dark:text-slate-400\">{item.description}</div>\n )}\n </div>\n </button>\n {expanded === (item.id ?? idx) && item.actions && (\n <div className=\"border-t border-slate-100 px-3 py-2 dark:border-slate-800\">\n <div className=\"flex flex-wrap gap-1.5\">\n {item.actions.map((action, i) => (\n <button\n key={typeof action === \"string\" ? action : action.label}\n type=\"button\"\n className={`rounded-md px-2.5 py-1 text-xs font-medium transition-colors ${\n i === 0\n ? \"bg-slate-900 text-white hover:bg-slate-800 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-200\"\n : \"bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700\"\n }`}\n >\n {typeof action === \"string\" ? action : action.label}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n },\n\n DataTable({ title, subtitle, columns = [], data = [], rows, searchable = true, sortable = true, paginated = true, pageSize = 5 }: DataTableProps) {\n const tableData = data.length ? data : (rows ?? []);\n const cols = columns.length ? columns : [\n { key: \"name\", label: \"Name\" },\n { key: \"status\", label: \"Status\" },\n { key: \"value\", label: \"Value\" }\n ];\n return (\n <TableCard\n title={title ?? \"Data\"}\n subtitle={subtitle}\n columns={cols}\n data={tableData}\n searchable={searchable}\n sortable={sortable}\n paginated={paginated}\n pageSize={pageSize}\n />\n );\n },\n\n DataChart({ title, subtitle, chartType = \"line\", data = [], height = 200 }: DataChartProps) {\n const series = data.length ? data : Array.from({ length: 12 }, (_, i) => ({ x: i, y: Math.random() * 100 }));\n return (\n <ChartCard\n title={title ?? \"Trend\"}\n subtitle={subtitle ?? \"Data visualization\"}\n chartType={chartType}\n height={height}\n chart={\n <D3Chart\n data={series as any}\n responsive\n height={height}\n ariaLabel={title}\n renderChart={(svg, d, dims, opts) => D3ChartTemplates.lineChart(svg, d as any, dims, opts)}\n options={{ xKey: \"x\", yKey: \"y\", showGrid: true, showAxes: true }}\n />\n }\n />\n );\n },\n\n MetricCard({ title, label, value, trend, change, changeType, color, icon, description }: MetricCardComponentProps) {\n return (\n <MetricCard\n title={(title ?? label) as any}\n value={value ?? \"—\"}\n trend={trend as any}\n change={change as any}\n changeType={changeType as any}\n color={color as any}\n icon={icon}\n subtitle={description}\n />\n );\n },\n\n StatusCard({ title, subtitle, status, items, layout, showProgress, showTimestamp }: StatusCardComponentProps) {\n return (\n <StatusCard\n title={title}\n subtitle={subtitle}\n status={status}\n items={items}\n layout={layout as any}\n showProgress={showProgress}\n showTimestamp={showTimestamp}\n />\n );\n },\n\n ActionList({ actions = [], title, onAction }: ActionListProps) {\n return (\n <div className=\"rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-900\">\n {title && <div className=\"mb-3 text-sm font-medium text-slate-900 dark:text-slate-50\">{title}</div>}\n <div className=\"flex flex-wrap gap-2\">\n {actions.map((action, i) => (\n <UIButton\n key={i}\n size=\"sm\"\n variant={i === 0 ? \"primary\" : \"outline\"}\n onClick={() => onAction?.(action)}\n >\n {typeof action === \"string\" ? action : action.label}\n </UIButton>\n ))}\n </div>\n </div>\n );\n },\n\n CalloutCard({ title, message, tone = \"neutral\" }: CalloutCardProps) {\n const toneClasses = {\n neutral: \"border-slate-200 bg-slate-50 text-slate-700 dark:border-slate-800 dark:bg-slate-950/30 dark:text-slate-200\",\n success: \"border-emerald-200 bg-emerald-50 text-emerald-800 dark:border-emerald-900/40 dark:bg-emerald-950/20 dark:text-emerald-200\",\n warning: \"border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-900/40 dark:bg-amber-950/20 dark:text-amber-200\",\n danger: \"border-rose-200 bg-rose-50 text-rose-800 dark:border-rose-900/40 dark:bg-rose-950/20 dark:text-rose-200\"\n };\n return (\n <div className={`rounded-xl border p-4 ${toneClasses[tone] ?? toneClasses.neutral}`}>\n {title && <div className=\"mb-1 text-sm font-semibold\">{title}</div>}\n <div className=\"text-sm\">{message}</div>\n </div>\n );\n },\n\n Divider() {\n return <div className=\"h-px bg-slate-200 dark:bg-slate-800\" />;\n },\n\n Spacer({ size = \"md\" }: SpacerProps) {\n const heights = { sm: \"h-2\", md: \"h-4\", lg: \"h-6\" };\n return <div className={heights[size] ?? heights.md} />;\n }\n};\n\nlet _registry: Record<string, React.ComponentType<any>> = { ...BUILTIN_COMPONENTS };\n\nexport function getComponentRegistry(): Record<string, React.ComponentType<any>> {\n return _registry;\n}\n\nexport function registerComponent(type: string, Component: React.ComponentType<any>): void {\n _registry = { ..._registry, [type]: Component };\n}\n\nexport function registerComponents(map: Record<string, React.ComponentType<any>>): void {\n _registry = { ..._registry, ...map };\n}\n\nexport function renderSchemaComponent(component: SchemaComponent, index: number): React.ReactElement {\n const registry = getComponentRegistry();\n const Component = registry[component.type];\n if (!Component) {\n return (\n <div key={index} className=\"rounded-lg border border-dashed border-slate-300 p-3 text-xs text-slate-500 dark:border-slate-700\">\n Unknown component: {component.type}\n </div>\n );\n }\n return <Component key={component.id ?? index} {...(component.props ?? {})} />;\n}\n\nexport function renderSchema(components: SchemaComponent[] = []): React.ReactElement[] {\n return components.map((c, i) => renderSchemaComponent(c, i));\n}\n\nexport default BUILTIN_COMPONENTS;\n"],"names":["BUILTIN_COMPONENTS","summary","title","jsxs","jsx","metrics","collapsible","initialCollapsed","collapsed","setCollapsed","React","items","m","onItemClick","expanded","setExpanded","item","idx","UIChip","action","i","subtitle","columns","data","rows","searchable","sortable","paginated","pageSize","tableData","cols","TableCard","chartType","height","series","_","ChartCard","D3Chart","svg","d","dims","opts","D3ChartTemplates","label","value","trend","change","changeType","color","icon","description","MetricCard","status","layout","showProgress","showTimestamp","StatusCard","actions","onAction","UIButton","message","tone","toneClasses","size","heights","_registry","getComponentRegistry","renderSchemaComponent","component","index","Component"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schandlergarcia/sf-web-components",
3
- "version": "1.8.0",
3
+ "version": "1.9.1",
4
4
  "description": "Reusable Salesforce web components library with Tailwind CSS v4 and shadcn/ui",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -64,7 +64,7 @@
64
64
  "world-atlas": "^2.0.0"
65
65
  },
66
66
  "dependencies": {
67
- "@schandlergarcia/sf-web-components": "^1.1.1",
67
+ "@schandlergarcia/sf-web-components": "^1.9.0",
68
68
  "class-variance-authority": "^0.7.1",
69
69
  "clsx": "^2.1.1",
70
70
  "glob": "^11.0.0",
@@ -36,7 +36,7 @@ export default function SemanticMetricCard({
36
36
  loading = false,
37
37
  ...rest
38
38
  }: SemanticMetricCardProps) {
39
- const metric = React.useMemo(() => getSemanticMetric(semanticId, metricId), [semanticId, metricId]);
39
+ const metric = React.useMemo(() => getSemanticMetric(semanticId, metricId ?? ""), [semanticId, metricId]);
40
40
 
41
41
  const resolvedTitle = title ?? metric?.title ?? metricId ?? "Metric";
42
42
  const resolvedSubtitle = subtitle ?? metric?.subtitle;
@@ -4,7 +4,7 @@ import { getSemanticDataset } from "../data/chartDataProvider";
4
4
 
5
5
  export interface SemanticTableCardProps extends Omit<TableCardProps, "data" | "columns"> {
6
6
  semanticId: string;
7
- dataOverride?: unknown[];
7
+ dataOverride?: Record<string, unknown>[];
8
8
  columnsOverride?: TableColumn[];
9
9
  compact?: boolean;
10
10
  striped?: boolean;
@@ -35,8 +35,8 @@ export default function SemanticTableCard({
35
35
  const ds = React.useMemo(() => getSemanticDataset(semanticId), [semanticId]);
36
36
  const table = ds?.table;
37
37
 
38
- const resolvedColumns = columnsOverride ?? table?.columns ?? [];
39
- const resolvedData = dataOverride ?? table?.rows ?? [];
38
+ const resolvedColumns = (columnsOverride ?? table?.columns ?? []) as TableColumn[];
39
+ const resolvedData = (dataOverride ?? table?.rows ?? []) as Record<string, unknown>[];
40
40
  const resolvedTitle = title ?? table?.title ?? ds?.title ?? "Table";
41
41
  const resolvedSubtitle = subtitle ?? table?.subtitle;
42
42
 
@@ -9,7 +9,8 @@ import {
9
9
  } from "@heroicons/react/24/outline";
10
10
  import ChatMessageList from "./ChatMessageList";
11
11
  import ChatInput from "./ChatInput";
12
- import useChatState from "./useChatState";
12
+ import useChatState, { UseChatStateOptions, ChatMessage } from "./useChatState";
13
+ import { ChatMessageData } from "./ChatMessage";
13
14
 
14
15
  const BACKDROP_VARIANTS = {
15
16
  hidden: { opacity: 0 },
@@ -23,11 +24,22 @@ const PANEL_VARIANTS = {
23
24
  opacity: 1,
24
25
  y: 0,
25
26
  scale: 1,
26
- transition: { type: "spring", damping: 28, stiffness: 380 },
27
+ transition: { type: "spring" as const, damping: 28, stiffness: 380 },
27
28
  },
28
29
  exit: { opacity: 0, y: 10, scale: 0.97, transition: { duration: 0.12 } },
29
30
  };
30
31
 
32
+ export interface ChatBarProps {
33
+ onSend?: UseChatStateOptions["onSend"];
34
+ suggestions?: string[];
35
+ placeholder?: string;
36
+ title?: string;
37
+ initialMessages?: UseChatStateOptions["initialMessages"];
38
+ className?: string;
39
+ renderAvatar?: (message: ChatMessageData) => React.ReactNode;
40
+ onOpenInTab?: (messages: ChatMessage[]) => void;
41
+ }
42
+
31
43
  /**
32
44
  * Command-palette style AI chat bar.
33
45
  *
@@ -41,17 +53,16 @@ const PANEL_VARIANTS = {
41
53
  export default function ChatBar({
42
54
  onSend,
43
55
  suggestions = [],
44
- placeholder = "Ask a question\u2026",
56
+ placeholder = "Ask a question",
45
57
  title = "AI Assistant",
46
58
  initialMessages = [],
47
59
  className = "",
48
- panelHeight,
49
60
  renderAvatar,
50
61
  onOpenInTab,
51
- }) {
62
+ }: ChatBarProps) {
52
63
  const [open, setOpen] = useState(false);
53
64
  const [portalVisible, setPortalVisible] = useState(false);
54
- const panelRef = useRef(null);
65
+ const panelRef = useRef<HTMLDivElement>(null);
55
66
  const chat = useChatState({ initialMessages, onSend });
56
67
  const isEmpty = chat.messages.length === 0;
57
68
 
@@ -62,7 +73,7 @@ export default function ChatBar({
62
73
  }, [open]);
63
74
 
64
75
  useEffect(() => {
65
- function onKey(e) {
76
+ function onKey(e: KeyboardEvent) {
66
77
  if ((e.metaKey || e.ctrlKey) && e.key === "k") {
67
78
  e.preventDefault();
68
79
  setOpen((prev) => !prev);
@@ -79,7 +90,7 @@ export default function ChatBar({
79
90
  return () => { document.body.style.overflow = ""; };
80
91
  }, [open]);
81
92
 
82
- function handleSend(content) {
93
+ function handleSend(content: string) {
83
94
  if (!open) setOpen(true);
84
95
  chat.sendMessage(content);
85
96
  }
@@ -1,16 +1,18 @@
1
- import React, { useState, useRef, useEffect } from "react";
1
+ import { useState, useRef, useEffect } from "react";
2
2
  import { PaperAirplaneIcon, StopCircleIcon } from "@heroicons/react/24/solid";
3
3
 
4
+ export interface ChatInputProps {
5
+ onSend?: (content: string) => void;
6
+ disabled?: boolean;
7
+ isLoading?: boolean;
8
+ onStop?: () => void;
9
+ placeholder?: string;
10
+ maxRows?: number;
11
+ }
12
+
4
13
  /**
5
14
  * Chat input with auto-resize textarea, Send button, and keyboard shortcuts.
6
15
  * Enter sends, Shift+Enter inserts newline.
7
- *
8
- * @param {Function} onSend — (content: string) => void
9
- * @param {boolean} disabled — disable input while agent is processing
10
- * @param {boolean} isLoading — show stop button instead of send
11
- * @param {Function} onStop — optional: called when stop is clicked
12
- * @param {string} placeholder
13
- * @param {number} maxRows — max visible rows before scroll (default 6)
14
16
  */
15
17
  export default function ChatInput({
16
18
  onSend,
@@ -19,9 +21,9 @@ export default function ChatInput({
19
21
  onStop,
20
22
  placeholder = "Type a message…",
21
23
  maxRows = 6,
22
- }) {
24
+ }: ChatInputProps) {
23
25
  const [value, setValue] = useState("");
24
- const textareaRef = useRef(null);
26
+ const textareaRef = useRef<HTMLTextAreaElement>(null);
25
27
 
26
28
  useEffect(() => {
27
29
  const ta = textareaRef.current;
@@ -41,7 +43,7 @@ export default function ChatInput({
41
43
  }
42
44
  }
43
45
 
44
- function handleKeyDown(e) {
46
+ function handleKeyDown(e: React.KeyboardEvent<HTMLTextAreaElement>) {
45
47
  if (e.key === "Enter" && !e.shiftKey) {
46
48
  e.preventDefault();
47
49
  handleSend();
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
- import { renderSchemaComponent } from "@/components/workspace/ComponentRegistry";
3
- import ChatToolCall from "./ChatToolCall";
2
+ import { renderSchemaComponent, type SchemaComponent } from "@/components/workspace/ComponentRegistry";
3
+ import ChatToolCall, { ToolCall } from "./ChatToolCall";
4
4
  import { UserCircleIcon, CpuChipIcon } from "@heroicons/react/24/solid";
5
5
 
6
- function cx(...classes) {
6
+ function cx(...classes: (string | boolean | undefined)[]): string {
7
7
  return classes.filter(Boolean).join(" ");
8
8
  }
9
9
 
@@ -11,9 +11,9 @@ function cx(...classes) {
11
11
  * Lightweight inline formatter for assistant messages.
12
12
  * Handles code blocks, inline code, bold, italic, and line breaks.
13
13
  */
14
- function formatContent(text) {
14
+ function formatContent(text: string): React.ReactNode {
15
15
  if (!text) return null;
16
- const parts = [];
16
+ const parts: React.ReactNode[] = [];
17
17
  let key = 0;
18
18
 
19
19
  const codeBlockRegex = /```(\w*)\n?([\s\S]*?)```/g;
@@ -46,7 +46,7 @@ function formatContent(text) {
46
46
  return parts;
47
47
  }
48
48
 
49
- function formatInline(text) {
49
+ function formatInline(text: string): React.ReactNode {
50
50
  const tokens = text.split(/(`[^`]+`|\*\*[^*]+\*\*|\*[^*]+\*)/g);
51
51
  return tokens.map((token, i) => {
52
52
  if (token.startsWith("**") && token.endsWith("**")) {
@@ -74,13 +74,26 @@ function formatInline(text) {
74
74
  });
75
75
  }
76
76
 
77
+ export interface ChatMessageData {
78
+ id: string;
79
+ role: "user" | "assistant" | "system";
80
+ content?: string;
81
+ components?: SchemaComponent[];
82
+ toolCalls?: ToolCall[];
83
+ isError?: boolean;
84
+ isStreaming?: boolean;
85
+ timestamp?: string;
86
+ }
87
+
88
+ export interface ChatMessageProps {
89
+ message: ChatMessageData;
90
+ avatar?: React.ReactNode;
91
+ }
92
+
77
93
  /**
78
94
  * Renders a single chat message.
79
- *
80
- * @param {Object} message — { id, role, content, components?, toolCalls?, isError?, isStreaming?, timestamp? }
81
- * @param {React.ReactNode} avatar — custom avatar override
82
95
  */
83
- export default function ChatMessage({ message, avatar }) {
96
+ export default function ChatMessage({ message, avatar }: ChatMessageProps) {
84
97
  const isUser = message.role === "user";
85
98
  const isSystem = message.role === "system";
86
99
  const isAssistant = message.role === "assistant";
@@ -1,17 +1,19 @@
1
1
  import React, { useRef, useEffect } from "react";
2
- import ChatMessage from "./ChatMessage";
2
+ import ChatMessage, { ChatMessageData } from "./ChatMessage";
3
3
  import ChatTypingIndicator from "./ChatTypingIndicator";
4
4
  import ChatSuggestions from "./ChatSuggestions";
5
5
 
6
+ export interface ChatMessageListProps {
7
+ messages?: ChatMessageData[];
8
+ isLoading?: boolean;
9
+ isStreaming?: boolean;
10
+ suggestions?: string[];
11
+ onSuggestion?: (text: string) => void;
12
+ renderAvatar?: (message: ChatMessageData) => React.ReactNode;
13
+ }
14
+
6
15
  /**
7
16
  * Scrollable message area with auto-scroll to latest message.
8
- *
9
- * @param {Array} messages — array of message objects
10
- * @param {boolean} isLoading — show typing indicator
11
- * @param {boolean} isStreaming — agent is streaming (show different indicator text)
12
- * @param {string[]} suggestions — follow-up suggestions shown after last assistant message
13
- * @param {Function} onSuggestion — (text) => void
14
- * @param {Function} renderAvatar — (message) => ReactNode, optional per-message avatar
15
17
  */
16
18
  export default function ChatMessageList({
17
19
  messages = [],
@@ -20,9 +22,9 @@ export default function ChatMessageList({
20
22
  suggestions = [],
21
23
  onSuggestion,
22
24
  renderAvatar,
23
- }) {
24
- const bottomRef = useRef(null);
25
- const containerRef = useRef(null);
25
+ }: ChatMessageListProps) {
26
+ const bottomRef = useRef<HTMLDivElement>(null);
27
+ const containerRef = useRef<HTMLDivElement>(null);
26
28
 
27
29
  useEffect(() => {
28
30
  bottomRef.current?.scrollIntoView({ behavior: "smooth" });