@seed-ship/mcp-ui-solid 4.0.3 → 4.0.5

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.
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const web = require("solid-js/web");
4
4
  const solidJs = require("solid-js");
5
- var _tmpl$ = /* @__PURE__ */ web.template(`<div class="text-xs text-amber-600 dark:text-amber-400 p-2">[DataPreviewSection] Invalid content format`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class=font-medium>`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class="px-1.5 py-0.5 rounded bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300">`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="flex items-center gap-1"><button class="px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"title="Export CSV (sorted)">CSV</button><button class="px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"title="Export JSON (sorted)">JSON`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class="flex items-center gap-1"><button class="px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 transition-colors">&laquo;</button><span><!$><!/> / <!$><!/></span><button class="px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 transition-colors">&raquo;`), _tmpl$6 = /* @__PURE__ */ web.template(`<div class=data-preview-section><div class="flex items-center justify-between mb-2"><div class="flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400"><!$><!/><!$><!/></div><!$><!/></div><div class="overflow-x-auto rounded border border-gray-200 dark:border-gray-700"><table class="w-full text-sm"><thead><tr class="bg-gray-50 dark:bg-gray-800"></tr></thead><tbody></tbody></table></div><div class="flex items-center justify-between mt-2 text-xs text-gray-500 dark:text-gray-400"><span></span><!$><!/>`), _tmpl$7 = /* @__PURE__ */ web.template(`<th class="px-3 py-2 font-medium text-xs text-gray-600 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 cursor-pointer select-none hover:bg-gray-100 dark:hover:bg-gray-700/50 transition-colors"><span class="inline-flex items-center gap-1"><!$><!/><span class="text-[10px] leading-none">`), _tmpl$8 = /* @__PURE__ */ web.template(`<tr class="border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors">`), _tmpl$9 = /* @__PURE__ */ web.template(`<td class="px-3 py-2 text-gray-800 dark:text-gray-200">`);
5
+ var _tmpl$ = /* @__PURE__ */ web.template(`<div class="text-xs text-amber-600 dark:text-amber-400 p-2">[DataPreviewSection] Invalid content format`), _tmpl$2 = /* @__PURE__ */ web.template(`<span class=font-medium>`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class="px-1.5 py-0.5 rounded bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300">`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="flex items-center gap-1"><button class="px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors">CSV</button><button class="px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors">JSON`), _tmpl$5 = /* @__PURE__ */ web.template(`<span><!$><!/><!$><!/>`), _tmpl$6 = /* @__PURE__ */ web.template(`<span>`), _tmpl$7 = /* @__PURE__ */ web.template(`<div class="flex items-center gap-1"><button class="px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors">&#x25C0; Prev</button><span class=px-2>Page <!$><!/> / <!$><!/></span><button class="px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors">Next &#x25B6;`), _tmpl$8 = /* @__PURE__ */ web.template(`<div class=data-preview-section><div class="flex items-center justify-between mb-2"><div class="flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400"><!$><!/><!$><!/></div><!$><!/></div><div class="overflow-x-auto rounded border border-gray-200 dark:border-gray-700"><table class="w-full text-sm"><thead><tr class="bg-gray-50 dark:bg-gray-800"></tr></thead><tbody></tbody></table></div><div class="flex items-center justify-between mt-2 text-xs text-gray-500 dark:text-gray-400"><!$><!/><!$><!/><!$><!/>`), _tmpl$9 = /* @__PURE__ */ web.template(`<th class="px-3 py-2 font-medium text-xs text-gray-600 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 cursor-pointer select-none hover:bg-gray-100 dark:hover:bg-gray-700/50 transition-colors"><span class="inline-flex items-center gap-1"><!$><!/><span class="text-[10px] leading-none">`), _tmpl$0 = /* @__PURE__ */ web.template(`<tr class="border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors">`), _tmpl$1 = /* @__PURE__ */ web.template(`<td class="px-3 py-2 text-gray-800 dark:text-gray-200">`);
6
6
  function formatNumber(value, format) {
7
7
  if (typeof value !== "number" || !isFinite(value)) return String(value ?? "");
8
8
  if (format === "percent") return `${(value * 100).toFixed(1)}%`;
@@ -85,28 +85,38 @@ function resolveContent(raw) {
85
85
  return null;
86
86
  }
87
87
  function DataPreviewSection(props) {
88
+ var _a;
88
89
  const content = solidJs.createMemo(() => {
89
90
  const resolved = resolveContent(props.content);
90
91
  if (!resolved) {
91
- console.warn("[MCP-UI] DataPreviewSection: invalid content — expected { columns: [...], rows: [...] }, got:", props.content);
92
+ console.warn("[MCP-UI] DataPreviewSection: invalid content — expected { columns, rows }", props.content);
92
93
  }
93
94
  return resolved;
94
95
  });
95
96
  const columns = () => {
96
- var _a;
97
- return ((_a = content()) == null ? void 0 : _a.columns) || [];
97
+ var _a2;
98
+ return ((_a2 = content()) == null ? void 0 : _a2.columns) || [];
98
99
  };
99
100
  const rawRows = () => {
100
- var _a;
101
- return ((_a = content()) == null ? void 0 : _a.rows) || [];
101
+ var _a2;
102
+ return ((_a2 = content()) == null ? void 0 : _a2.rows) || [];
102
103
  };
103
- const pageSize = () => {
104
- var _a;
105
- return ((_a = content()) == null ? void 0 : _a.pageSize) || 25;
104
+ const pageSizeVal = () => {
105
+ var _a2;
106
+ return ((_a2 = content()) == null ? void 0 : _a2.pageSize) ?? 25;
106
107
  };
107
- const [page, setPage] = solidJs.createSignal(0);
108
+ const showPageInfo = () => {
109
+ var _a2;
110
+ return ((_a2 = content()) == null ? void 0 : _a2.showPageInfo) !== false;
111
+ };
112
+ const [page, setPage] = solidJs.createSignal(((_a = content()) == null ? void 0 : _a.initialPage) ?? 0);
108
113
  const [sortKey, setSortKey] = solidJs.createSignal(null);
109
114
  const [sortDir, setSortDir] = solidJs.createSignal(null);
115
+ solidJs.createEffect(() => {
116
+ var _a2, _b;
117
+ const p = page();
118
+ (_b = (_a2 = content()) == null ? void 0 : _a2.onPageChange) == null ? void 0 : _b.call(_a2, p);
119
+ });
110
120
  const handleSort = (key) => {
111
121
  if (sortKey() === key) {
112
122
  if (sortDir() === "asc") setSortDir("desc");
@@ -126,27 +136,27 @@ function DataPreviewSection(props) {
126
136
  const dir = sortDir();
127
137
  if (!key || !dir) return r;
128
138
  const col = columns().find((c) => c.key === key);
129
- const type = col == null ? void 0 : col.type;
130
139
  return [...r].sort((a, b) => {
131
- const cmp = compareValues(a[key], b[key], type);
140
+ const cmp = compareValues(a[key], b[key], col == null ? void 0 : col.type);
132
141
  return dir === "desc" ? -cmp : cmp;
133
142
  });
134
143
  });
135
- const totalRows = () => sortedRows().length;
136
- const totalPages = () => Math.max(1, Math.ceil(totalRows() / pageSize()));
137
- const pagedRows = solidJs.createMemo(() => {
138
- const start = page() * pageSize();
139
- return sortedRows().slice(start, start + pageSize());
144
+ const isPaginated = () => pageSizeVal() > 0 && sortedRows().length > pageSizeVal();
145
+ const totalPages = () => isPaginated() ? Math.ceil(sortedRows().length / pageSizeVal()) : 1;
146
+ const visibleRows = solidJs.createMemo(() => {
147
+ if (!isPaginated()) return sortedRows();
148
+ const start = page() * pageSizeVal();
149
+ return sortedRows().slice(start, start + pageSizeVal());
140
150
  });
151
+ const rangeStart = () => isPaginated() ? page() * pageSizeVal() + 1 : 1;
152
+ const rangeEnd = () => isPaginated() ? Math.min((page() + 1) * pageSizeVal(), sortedRows().length) : sortedRows().length;
141
153
  const handleExportCSV = () => {
142
154
  const c = content();
143
155
  if (!c) return;
144
- const csv = toCSV(c.columns, sortedRows());
145
- downloadFile(csv, "data-export.csv", "text/csv;charset=utf-8");
156
+ downloadFile(toCSV(c.columns, sortedRows()), "data-export.csv", "text/csv;charset=utf-8");
146
157
  };
147
158
  const handleExportJSON = () => {
148
- const json = JSON.stringify(sortedRows(), null, 2);
149
- downloadFile(json, "data-export.json", "application/json");
159
+ downloadFile(JSON.stringify(sortedRows(), null, 2), "data-export.json", "application/json");
150
160
  };
151
161
  const columnAlign = (col) => {
152
162
  if (col.align) return col.align;
@@ -165,7 +175,7 @@ function DataPreviewSection(props) {
165
175
  return web.getNextElement(_tmpl$);
166
176
  },
167
177
  children: (c) => (() => {
168
- var _el$2 = web.getNextElement(_tmpl$6), _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$7 = _el$4.firstChild, [_el$8, _co$] = web.getNextMarker(_el$7.nextSibling), _el$9 = _el$8.nextSibling, [_el$0, _co$2] = web.getNextMarker(_el$9.nextSibling), _el$12 = _el$4.nextSibling, [_el$13, _co$3] = web.getNextMarker(_el$12.nextSibling), _el$14 = _el$3.nextSibling, _el$15 = _el$14.firstChild, _el$16 = _el$15.firstChild, _el$17 = _el$16.firstChild, _el$18 = _el$16.nextSibling, _el$19 = _el$14.nextSibling, _el$20 = _el$19.firstChild, _el$30 = _el$20.nextSibling, [_el$31, _co$6] = web.getNextMarker(_el$30.nextSibling);
178
+ var _el$2 = web.getNextElement(_tmpl$8), _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$7 = _el$4.firstChild, [_el$8, _co$] = web.getNextMarker(_el$7.nextSibling), _el$9 = _el$8.nextSibling, [_el$0, _co$2] = web.getNextMarker(_el$9.nextSibling), _el$12 = _el$4.nextSibling, [_el$13, _co$3] = web.getNextMarker(_el$12.nextSibling), _el$14 = _el$3.nextSibling, _el$15 = _el$14.firstChild, _el$16 = _el$15.firstChild, _el$17 = _el$16.firstChild, _el$18 = _el$16.nextSibling, _el$19 = _el$14.nextSibling, _el$36 = _el$19.firstChild, [_el$37, _co$8] = web.getNextMarker(_el$36.nextSibling), _el$38 = _el$37.nextSibling, [_el$39, _co$9] = web.getNextMarker(_el$38.nextSibling), _el$40 = _el$39.nextSibling, [_el$41, _co$0] = web.getNextMarker(_el$40.nextSibling);
169
179
  web.insert(_el$4, web.createComponent(solidJs.Show, {
170
180
  get when() {
171
181
  return c().source;
@@ -194,6 +204,15 @@ function DataPreviewSection(props) {
194
204
  var _el$1 = web.getNextElement(_tmpl$4), _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling;
195
205
  _el$10.$$click = handleExportCSV;
196
206
  _el$11.$$click = handleExportJSON;
207
+ web.effect((_p$) => {
208
+ var _v$ = `Export CSV (${sortedRows().length} rows)`, _v$2 = `Export JSON (${sortedRows().length} rows)`;
209
+ _v$ !== _p$.e && web.setAttribute(_el$10, "title", _p$.e = _v$);
210
+ _v$2 !== _p$.t && web.setAttribute(_el$11, "title", _p$.t = _v$2);
211
+ return _p$;
212
+ }, {
213
+ e: void 0,
214
+ t: void 0
215
+ });
197
216
  web.runHydrationEvents();
198
217
  return _el$1;
199
218
  }
@@ -203,18 +222,18 @@ function DataPreviewSection(props) {
203
222
  return columns();
204
223
  },
205
224
  children: (col) => (() => {
206
- var _el$32 = web.getNextElement(_tmpl$7), _el$33 = _el$32.firstChild, _el$35 = _el$33.firstChild, [_el$36, _co$7] = web.getNextMarker(_el$35.nextSibling), _el$34 = _el$36.nextSibling;
207
- _el$32.$$click = () => handleSort(col.key);
208
- web.insert(_el$33, () => col.label, _el$36, _co$7);
209
- web.insert(_el$34, () => sortIndicator(col.key));
225
+ var _el$42 = web.getNextElement(_tmpl$9), _el$43 = _el$42.firstChild, _el$45 = _el$43.firstChild, [_el$46, _co$1] = web.getNextMarker(_el$45.nextSibling), _el$44 = _el$46.nextSibling;
226
+ _el$42.$$click = () => handleSort(col.key);
227
+ web.insert(_el$43, () => col.label, _el$46, _co$1);
228
+ web.insert(_el$44, () => sortIndicator(col.key));
210
229
  web.effect((_p$) => {
211
- var _v$3 = columnAlign(col), _v$4 = `Sort by ${col.label}`, _v$5 = {
230
+ var _v$5 = columnAlign(col), _v$6 = `Sort by ${col.label}`, _v$7 = {
212
231
  "opacity-30": sortKey() !== col.key,
213
232
  "opacity-100 text-blue-600 dark:text-blue-400": sortKey() === col.key
214
233
  };
215
- _v$3 !== _p$.e && web.setStyleProperty(_el$32, "text-align", _p$.e = _v$3);
216
- _v$4 !== _p$.t && web.setAttribute(_el$32, "title", _p$.t = _v$4);
217
- _p$.a = web.classList(_el$34, _v$5, _p$.a);
234
+ _v$5 !== _p$.e && web.setStyleProperty(_el$42, "text-align", _p$.e = _v$5);
235
+ _v$6 !== _p$.t && web.setAttribute(_el$42, "title", _p$.t = _v$6);
236
+ _p$.a = web.classList(_el$44, _v$7, _p$.a);
218
237
  return _p$;
219
238
  }, {
220
239
  e: void 0,
@@ -222,59 +241,80 @@ function DataPreviewSection(props) {
222
241
  a: void 0
223
242
  });
224
243
  web.runHydrationEvents();
225
- return _el$32;
244
+ return _el$42;
226
245
  })()
227
246
  }));
228
247
  web.insert(_el$18, web.createComponent(solidJs.For, {
229
248
  get each() {
230
- return pagedRows();
249
+ return visibleRows();
231
250
  },
232
251
  children: (row, i) => (() => {
233
- var _el$37 = web.getNextElement(_tmpl$8);
234
- web.insert(_el$37, web.createComponent(solidJs.For, {
252
+ var _el$47 = web.getNextElement(_tmpl$0);
253
+ web.insert(_el$47, web.createComponent(solidJs.For, {
235
254
  get each() {
236
255
  return columns();
237
256
  },
238
257
  children: (col) => (() => {
239
- var _el$38 = web.getNextElement(_tmpl$9);
240
- web.insert(_el$38, () => formatCell(row[col.key], col));
241
- web.effect((_$p) => web.setStyleProperty(_el$38, "text-align", columnAlign(col)));
242
- return _el$38;
258
+ var _el$48 = web.getNextElement(_tmpl$1);
259
+ web.insert(_el$48, () => formatCell(row[col.key], col));
260
+ web.effect((_$p) => web.setStyleProperty(_el$48, "text-align", columnAlign(col)));
261
+ return _el$48;
243
262
  })()
244
263
  }));
245
- web.effect((_$p) => web.classList(_el$37, {
264
+ web.effect((_$p) => web.classList(_el$47, {
246
265
  "bg-gray-25 dark:bg-gray-850": i() % 2 === 1
247
266
  }, _$p));
248
- return _el$37;
267
+ return _el$47;
249
268
  })()
250
269
  }));
251
- web.insert(_el$20, (() => {
252
- var _c$ = web.memo(() => !!c().totalRows);
253
- return () => _c$() ? `${totalRows()} / ${c().totalRows.toLocaleString("fr-FR")} rows` : `${totalRows()} row${totalRows() !== 1 ? "s" : ""}`;
254
- })());
255
270
  web.insert(_el$19, web.createComponent(solidJs.Show, {
256
271
  get when() {
257
- return totalPages() > 1;
272
+ return showPageInfo();
273
+ },
274
+ get children() {
275
+ var _el$20 = web.getNextElement(_tmpl$5), _el$21 = _el$20.firstChild, [_el$22, _co$4] = web.getNextMarker(_el$21.nextSibling), _el$23 = _el$22.nextSibling, [_el$24, _co$5] = web.getNextMarker(_el$23.nextSibling);
276
+ web.insert(_el$20, (() => {
277
+ var _c$ = web.memo(() => !!isPaginated());
278
+ return () => _c$() ? `Showing ${rangeStart()}–${rangeEnd()} of ${sortedRows().length.toLocaleString("fr-FR")}` : `${sortedRows().length} row${sortedRows().length !== 1 ? "s" : ""}`;
279
+ })(), _el$22, _co$4);
280
+ web.insert(_el$20, (() => {
281
+ var _c$2 = web.memo(() => !!(c().totalRows && c().totalRows > sortedRows().length));
282
+ return () => _c$2() ? ` (${c().totalRows.toLocaleString("fr-FR")} total)` : "";
283
+ })(), _el$24, _co$5);
284
+ return _el$20;
285
+ }
286
+ }), _el$37, _co$8);
287
+ web.insert(_el$19, web.createComponent(solidJs.Show, {
288
+ get when() {
289
+ return !showPageInfo();
290
+ },
291
+ get children() {
292
+ return web.getNextElement(_tmpl$6);
293
+ }
294
+ }), _el$39, _co$9);
295
+ web.insert(_el$19, web.createComponent(solidJs.Show, {
296
+ get when() {
297
+ return isPaginated();
258
298
  },
259
299
  get children() {
260
- var _el$21 = web.getNextElement(_tmpl$5), _el$22 = _el$21.firstChild, _el$23 = _el$22.nextSibling, _el$25 = _el$23.firstChild, [_el$26, _co$4] = web.getNextMarker(_el$25.nextSibling), _el$24 = _el$26.nextSibling, _el$27 = _el$24.nextSibling, [_el$28, _co$5] = web.getNextMarker(_el$27.nextSibling), _el$29 = _el$23.nextSibling;
261
- _el$22.$$click = () => setPage((p) => p - 1);
262
- web.insert(_el$23, () => page() + 1, _el$26, _co$4);
263
- web.insert(_el$23, totalPages, _el$28, _co$5);
264
- _el$29.$$click = () => setPage((p) => p + 1);
300
+ var _el$26 = web.getNextElement(_tmpl$7), _el$27 = _el$26.firstChild, _el$28 = _el$27.nextSibling, _el$29 = _el$28.firstChild, _el$31 = _el$29.nextSibling, [_el$32, _co$6] = web.getNextMarker(_el$31.nextSibling), _el$30 = _el$32.nextSibling, _el$33 = _el$30.nextSibling, [_el$34, _co$7] = web.getNextMarker(_el$33.nextSibling), _el$35 = _el$28.nextSibling;
301
+ _el$27.$$click = () => setPage((p) => p - 1);
302
+ web.insert(_el$28, () => page() + 1, _el$32, _co$6);
303
+ web.insert(_el$28, totalPages, _el$34, _co$7);
304
+ _el$35.$$click = () => setPage((p) => p + 1);
265
305
  web.effect((_p$) => {
266
- var _v$ = page() === 0, _v$2 = page() >= totalPages() - 1;
267
- _v$ !== _p$.e && web.setProperty(_el$22, "disabled", _p$.e = _v$);
268
- _v$2 !== _p$.t && web.setProperty(_el$29, "disabled", _p$.t = _v$2);
306
+ var _v$3 = page() === 0, _v$4 = page() >= totalPages() - 1;
307
+ _v$3 !== _p$.e && web.setProperty(_el$27, "disabled", _p$.e = _v$3);
308
+ _v$4 !== _p$.t && web.setProperty(_el$35, "disabled", _p$.t = _v$4);
269
309
  return _p$;
270
310
  }, {
271
311
  e: void 0,
272
312
  t: void 0
273
313
  });
274
314
  web.runHydrationEvents();
275
- return _el$21;
315
+ return _el$26;
276
316
  }
277
- }), _el$31, _co$6);
317
+ }), _el$41, _co$0);
278
318
  return _el$2;
279
319
  })()
280
320
  });
@@ -1 +1 @@
1
- {"version":3,"file":"DataPreviewSection.cjs","sources":["../../src/components/DataPreviewSection.tsx"],"sourcesContent":["/**\n * DataPreviewSection — paginated, sortable data table with export\n * v4.0.3: Sortable columns (click header: asc → desc → reset)\n *\n * @experimental\n *\n * Features:\n * - Sortable columns (type-aware: number, string, date)\n * - Column types (number right-aligned, string left-aligned)\n * - Pagination (configurable page size)\n * - CSV / JSON export buttons\n * - Source attribution + freshness label\n * - Number formatting (FR locale)\n */\n\nimport { createSignal, createMemo, For, Show } from 'solid-js'\nimport type { DataPreviewContent, DataPreviewColumn } from '../types/chat-bus'\n\nexport interface DataPreviewSectionProps {\n content: DataPreviewContent\n}\n\ntype SortDir = 'asc' | 'desc' | null\n\n/** Format a number for display (French locale) */\nfunction formatNumber(value: unknown, format?: string): string {\n if (typeof value !== 'number' || !isFinite(value)) return String(value ?? '')\n if (format === 'percent') return `${(value * 100).toFixed(1)}%`\n if (format === 'currency') return `${value.toLocaleString('fr-FR')} EUR`\n if (Number.isInteger(value)) return value.toLocaleString('fr-FR')\n return value.toLocaleString('fr-FR', { maximumFractionDigits: 2 })\n}\n\n/** Format a cell value based on column type */\nfunction formatCell(value: unknown, col: DataPreviewColumn): string {\n if (value == null) return '\\u2014'\n if (col.type === 'number') return formatNumber(value, col.format)\n if (col.type === 'date' && typeof value === 'string') {\n try {\n return new Date(value).toLocaleDateString('fr-FR')\n } catch {\n return value\n }\n }\n return String(value)\n}\n\n/** Compare two values for sorting, type-aware */\nfunction compareValues(a: unknown, b: unknown, type?: string): number {\n if (a == null && b == null) return 0\n if (a == null) return 1\n if (b == null) return -1\n\n if (type === 'number') {\n const na = typeof a === 'number' ? a : Number(a)\n const nb = typeof b === 'number' ? b : Number(b)\n if (isNaN(na) && isNaN(nb)) return 0\n if (isNaN(na)) return 1\n if (isNaN(nb)) return -1\n return na - nb\n }\n\n if (type === 'date') {\n const da = new Date(String(a)).getTime()\n const db = new Date(String(b)).getTime()\n if (isNaN(da) && isNaN(db)) return 0\n if (isNaN(da)) return 1\n if (isNaN(db)) return -1\n return da - db\n }\n\n return String(a).localeCompare(String(b), 'fr', { sensitivity: 'base' })\n}\n\n/** Generate CSV from columns + rows */\nfunction toCSV(columns: DataPreviewColumn[], rows: Record<string, unknown>[]): string {\n const header = columns.map(c => `\"${c.label.replace(/\"/g, '\"\"')}\"`).join(';')\n const body = rows.map(row =>\n columns.map(c => {\n const val = row[c.key]\n if (val == null) return ''\n if (typeof val === 'string') return `\"${val.replace(/\"/g, '\"\"')}\"`\n return String(val)\n }).join(';')\n ).join('\\n')\n return `${header}\\n${body}`\n}\n\n/** Trigger browser download */\nfunction downloadFile(content: string, filename: string, mimeType: string) {\n const blob = new Blob([content], { type: mimeType })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = filename\n a.click()\n URL.revokeObjectURL(url)\n}\n\n/**\n * Extract a valid DataPreviewContent from props.content.\n * Handles: direct DataPreviewContent, or wrapped in an extra layer.\n */\nfunction resolveContent(raw: unknown): DataPreviewContent | null {\n if (!raw || typeof raw !== 'object') return null\n const obj = raw as Record<string, unknown>\n\n if (Array.isArray(obj.columns) && Array.isArray(obj.rows)) {\n return obj as unknown as DataPreviewContent\n }\n\n if (obj.content && typeof obj.content === 'object') {\n const inner = obj.content as Record<string, unknown>\n if (Array.isArray(inner.columns) && Array.isArray(inner.rows)) {\n return inner as unknown as DataPreviewContent\n }\n }\n\n return null\n}\n\nexport function DataPreviewSection(props: DataPreviewSectionProps) {\n const content = createMemo(() => {\n const resolved = resolveContent(props.content)\n if (!resolved) {\n console.warn(\n '[MCP-UI] DataPreviewSection: invalid content — expected { columns: [...], rows: [...] }, got:',\n props.content\n )\n }\n return resolved\n })\n\n const columns = () => content()?.columns || []\n const rawRows = () => content()?.rows || []\n const pageSize = () => content()?.pageSize || 25\n const [page, setPage] = createSignal(0)\n const [sortKey, setSortKey] = createSignal<string | null>(null)\n const [sortDir, setSortDir] = createSignal<SortDir>(null)\n\n const handleSort = (key: string) => {\n if (sortKey() === key) {\n // Cycle: asc → desc → reset\n if (sortDir() === 'asc') setSortDir('desc')\n else { setSortKey(null); setSortDir(null) }\n } else {\n setSortKey(key)\n setSortDir('asc')\n }\n setPage(0)\n }\n\n const sortedRows = createMemo(() => {\n const r = rawRows()\n const key = sortKey()\n const dir = sortDir()\n if (!key || !dir) return r\n\n const col = columns().find(c => c.key === key)\n const type = col?.type\n\n return [...r].sort((a, b) => {\n const cmp = compareValues(a[key], b[key], type)\n return dir === 'desc' ? -cmp : cmp\n })\n })\n\n const totalRows = () => sortedRows().length\n const totalPages = () => Math.max(1, Math.ceil(totalRows() / pageSize()))\n\n const pagedRows = createMemo(() => {\n const start = page() * pageSize()\n return sortedRows().slice(start, start + pageSize())\n })\n\n const handleExportCSV = () => {\n const c = content()\n if (!c) return\n const csv = toCSV(c.columns, sortedRows())\n downloadFile(csv, 'data-export.csv', 'text/csv;charset=utf-8')\n }\n\n const handleExportJSON = () => {\n const json = JSON.stringify(sortedRows(), null, 2)\n downloadFile(json, 'data-export.json', 'application/json')\n }\n\n const columnAlign = (col: DataPreviewColumn) => {\n if (col.align) return col.align\n if (col.type === 'number') return 'right'\n return 'left'\n }\n\n const sortIndicator = (key: string) => {\n if (sortKey() !== key) return '\\u2195' // ↕ neutral\n return sortDir() === 'asc' ? '\\u2191' : '\\u2193' // ↑ or ↓\n }\n\n return (\n <Show when={content()} fallback={\n <div class=\"text-xs text-amber-600 dark:text-amber-400 p-2\">\n [DataPreviewSection] Invalid content format\n </div>\n }>\n {(c) => (\n <div class=\"data-preview-section\">\n {/* Header with source + export */}\n <div class=\"flex items-center justify-between mb-2\">\n <div class=\"flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400\">\n <Show when={c().source}>\n <span class=\"font-medium\">{c().source}</span>\n </Show>\n <Show when={c().freshness}>\n <span class=\"px-1.5 py-0.5 rounded bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300\">\n {c().freshness}\n </span>\n </Show>\n </div>\n\n <Show when={c().exportable !== false}>\n <div class=\"flex items-center gap-1\">\n <button\n class=\"px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n onClick={handleExportCSV}\n title=\"Export CSV (sorted)\"\n >\n CSV\n </button>\n <button\n class=\"px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n onClick={handleExportJSON}\n title=\"Export JSON (sorted)\"\n >\n JSON\n </button>\n </div>\n </Show>\n </div>\n\n {/* Table */}\n <div class=\"overflow-x-auto rounded border border-gray-200 dark:border-gray-700\">\n <table class=\"w-full text-sm\">\n <thead>\n <tr class=\"bg-gray-50 dark:bg-gray-800\">\n <For each={columns()}>\n {(col) => (\n <th\n class=\"px-3 py-2 font-medium text-xs text-gray-600 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 cursor-pointer select-none hover:bg-gray-100 dark:hover:bg-gray-700/50 transition-colors\"\n style={{ \"text-align\": columnAlign(col) }}\n onClick={() => handleSort(col.key)}\n title={`Sort by ${col.label}`}\n >\n <span class=\"inline-flex items-center gap-1\">\n {col.label}\n <span\n class=\"text-[10px] leading-none\"\n classList={{\n 'opacity-30': sortKey() !== col.key,\n 'opacity-100 text-blue-600 dark:text-blue-400': sortKey() === col.key,\n }}\n >\n {sortIndicator(col.key)}\n </span>\n </span>\n </th>\n )}\n </For>\n </tr>\n </thead>\n <tbody>\n <For each={pagedRows()}>\n {(row, i) => (\n <tr\n class=\"border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors\"\n classList={{ 'bg-gray-25 dark:bg-gray-850': i() % 2 === 1 }}\n >\n <For each={columns()}>\n {(col) => (\n <td\n class=\"px-3 py-2 text-gray-800 dark:text-gray-200\"\n style={{ \"text-align\": columnAlign(col) }}\n >\n {formatCell(row[col.key], col)}\n </td>\n )}\n </For>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n </div>\n\n {/* Footer: pagination + row count */}\n <div class=\"flex items-center justify-between mt-2 text-xs text-gray-500 dark:text-gray-400\">\n <span>\n {c().totalRows\n ? `${totalRows()} / ${c().totalRows!.toLocaleString('fr-FR')} rows`\n : `${totalRows()} row${totalRows() !== 1 ? 's' : ''}`}\n </span>\n\n <Show when={totalPages() > 1}>\n <div class=\"flex items-center gap-1\">\n <button\n class=\"px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 transition-colors\"\n disabled={page() === 0}\n onClick={() => setPage(p => p - 1)}\n >\n &laquo;\n </button>\n <span>{page() + 1} / {totalPages()}</span>\n <button\n class=\"px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 transition-colors\"\n disabled={page() >= totalPages() - 1}\n onClick={() => setPage(p => p + 1)}\n >\n &raquo;\n </button>\n </div>\n </Show>\n </div>\n </div>\n )}\n </Show>\n )\n}\n"],"names":["formatNumber","value","format","isFinite","String","toFixed","toLocaleString","Number","isInteger","maximumFractionDigits","formatCell","col","type","Date","toLocaleDateString","compareValues","a","b","na","nb","isNaN","da","getTime","db","localeCompare","sensitivity","toCSV","columns","rows","header","map","c","label","replace","join","body","row","val","key","downloadFile","content","filename","mimeType","blob","Blob","url","URL","createObjectURL","document","createElement","href","download","click","revokeObjectURL","resolveContent","raw","obj","Array","isArray","inner","DataPreviewSection","props","createMemo","resolved","console","warn","rawRows","pageSize","page","setPage","createSignal","sortKey","setSortKey","sortDir","setSortDir","handleSort","sortedRows","r","dir","find","sort","cmp","totalRows","length","totalPages","Math","max","ceil","pagedRows","start","slice","handleExportCSV","csv","handleExportJSON","json","JSON","stringify","columnAlign","align","sortIndicator","_$createComponent","Show","when","fallback","_$getNextElement","_tmpl$","children","_el$2","_tmpl$6","_el$3","firstChild","_el$4","_el$7","_el$8","_co$","_$getNextMarker","nextSibling","_el$9","_el$0","_co$2","_el$12","_el$13","_co$3","_el$14","_el$15","_el$16","_el$17","_el$18","_el$19","_el$20","_el$30","_el$31","_co$6","_$insert","source","_el$5","_tmpl$2","freshness","_el$6","_tmpl$3","exportable","_el$1","_tmpl$4","_el$10","_el$11","$$click","_$runHydrationEvents","For","each","_el$32","_tmpl$7","_el$33","_el$35","_el$36","_co$7","_el$34","_$effect","_p$","_v$3","_v$4","_v$5","e","_$setStyleProperty","t","_$setAttribute","_$classList","undefined","i","_el$37","_tmpl$8","_el$38","_tmpl$9","_$p","_c$","_$memo","_el$21","_tmpl$5","_el$22","_el$23","_el$25","_el$26","_co$4","_el$24","_el$27","_el$28","_co$5","_el$29","p","_v$","_v$2","_$setProperty","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"DataPreviewSection.cjs","sources":["../../src/components/DataPreviewSection.tsx"],"sourcesContent":["/**\n * DataPreviewSection — paginated, sortable data table with export\n * v4.0.4: Full pagination spec (auto-activate, pageSize=0 disable, showPageInfo, onPageChange)\n *\n * @experimental\n */\n\nimport { createSignal, createMemo, createEffect, For, Show } from 'solid-js'\nimport type { DataPreviewContent, DataPreviewColumn } from '../types/chat-bus'\n\nexport interface DataPreviewSectionProps {\n content: DataPreviewContent\n}\n\ntype SortDir = 'asc' | 'desc' | null\n\n// ─── Formatting helpers ─────────────────────────────────────\n\nfunction formatNumber(value: unknown, format?: string): string {\n if (typeof value !== 'number' || !isFinite(value)) return String(value ?? '')\n if (format === 'percent') return `${(value * 100).toFixed(1)}%`\n if (format === 'currency') return `${value.toLocaleString('fr-FR')} EUR`\n if (Number.isInteger(value)) return value.toLocaleString('fr-FR')\n return value.toLocaleString('fr-FR', { maximumFractionDigits: 2 })\n}\n\nfunction formatCell(value: unknown, col: DataPreviewColumn): string {\n if (value == null) return '\\u2014'\n if (col.type === 'number') return formatNumber(value, col.format)\n if (col.type === 'date' && typeof value === 'string') {\n try { return new Date(value).toLocaleDateString('fr-FR') } catch { return value }\n }\n return String(value)\n}\n\nfunction compareValues(a: unknown, b: unknown, type?: string): number {\n if (a == null && b == null) return 0\n if (a == null) return 1\n if (b == null) return -1\n if (type === 'number') {\n const na = typeof a === 'number' ? a : Number(a)\n const nb = typeof b === 'number' ? b : Number(b)\n if (isNaN(na) && isNaN(nb)) return 0\n if (isNaN(na)) return 1\n if (isNaN(nb)) return -1\n return na - nb\n }\n if (type === 'date') {\n const da = new Date(String(a)).getTime()\n const db = new Date(String(b)).getTime()\n if (isNaN(da) && isNaN(db)) return 0\n if (isNaN(da)) return 1\n if (isNaN(db)) return -1\n return da - db\n }\n return String(a).localeCompare(String(b), 'fr', { sensitivity: 'base' })\n}\n\n// ─── Export helpers ─────────────────────────────────────────\n\nfunction toCSV(columns: DataPreviewColumn[], rows: Record<string, unknown>[]): string {\n const header = columns.map(c => `\"${c.label.replace(/\"/g, '\"\"')}\"`).join(';')\n const body = rows.map(row =>\n columns.map(c => {\n const val = row[c.key]\n if (val == null) return ''\n if (typeof val === 'string') return `\"${val.replace(/\"/g, '\"\"')}\"`\n return String(val)\n }).join(';')\n ).join('\\n')\n return `${header}\\n${body}`\n}\n\nfunction downloadFile(content: string, filename: string, mimeType: string) {\n const blob = new Blob([content], { type: mimeType })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = filename\n a.click()\n URL.revokeObjectURL(url)\n}\n\n// ─── Content resolver ───────────────────────────────────────\n\nfunction resolveContent(raw: unknown): DataPreviewContent | null {\n if (!raw || typeof raw !== 'object') return null\n const obj = raw as Record<string, unknown>\n if (Array.isArray(obj.columns) && Array.isArray(obj.rows)) {\n return obj as unknown as DataPreviewContent\n }\n if (obj.content && typeof obj.content === 'object') {\n const inner = obj.content as Record<string, unknown>\n if (Array.isArray(inner.columns) && Array.isArray(inner.rows)) {\n return inner as unknown as DataPreviewContent\n }\n }\n return null\n}\n\n// ─── Component ──────────────────────────────────────────────\n\nexport function DataPreviewSection(props: DataPreviewSectionProps) {\n const content = createMemo(() => {\n const resolved = resolveContent(props.content)\n if (!resolved) {\n console.warn('[MCP-UI] DataPreviewSection: invalid content — expected { columns, rows }', props.content)\n }\n return resolved\n })\n\n const columns = () => content()?.columns || []\n const rawRows = () => content()?.rows || []\n const pageSizeVal = () => content()?.pageSize ?? 25\n const showPageInfo = () => content()?.showPageInfo !== false\n\n const [page, setPage] = createSignal(content()?.initialPage ?? 0)\n const [sortKey, setSortKey] = createSignal<string | null>(null)\n const [sortDir, setSortDir] = createSignal<SortDir>(null)\n\n // Notify parent on page change\n createEffect(() => {\n const p = page()\n content()?.onPageChange?.(p)\n })\n\n const handleSort = (key: string) => {\n if (sortKey() === key) {\n if (sortDir() === 'asc') setSortDir('desc')\n else { setSortKey(null); setSortDir(null) }\n } else {\n setSortKey(key)\n setSortDir('asc')\n }\n setPage(0)\n }\n\n const sortedRows = createMemo(() => {\n const r = rawRows()\n const key = sortKey()\n const dir = sortDir()\n if (!key || !dir) return r\n const col = columns().find(c => c.key === key)\n return [...r].sort((a, b) => {\n const cmp = compareValues(a[key], b[key], col?.type)\n return dir === 'desc' ? -cmp : cmp\n })\n })\n\n // Pagination: auto-enabled when rows > pageSize, disabled when pageSize=0\n const isPaginated = () => pageSizeVal() > 0 && sortedRows().length > pageSizeVal()\n const totalPages = () => isPaginated() ? Math.ceil(sortedRows().length / pageSizeVal()) : 1\n\n const visibleRows = createMemo(() => {\n if (!isPaginated()) return sortedRows()\n const start = page() * pageSizeVal()\n return sortedRows().slice(start, start + pageSizeVal())\n })\n\n const rangeStart = () => isPaginated() ? page() * pageSizeVal() + 1 : 1\n const rangeEnd = () => isPaginated()\n ? Math.min((page() + 1) * pageSizeVal(), sortedRows().length)\n : sortedRows().length\n\n // Export ALL rows (not just page)\n const handleExportCSV = () => {\n const c = content()\n if (!c) return\n downloadFile(toCSV(c.columns, sortedRows()), 'data-export.csv', 'text/csv;charset=utf-8')\n }\n const handleExportJSON = () => {\n downloadFile(JSON.stringify(sortedRows(), null, 2), 'data-export.json', 'application/json')\n }\n\n const columnAlign = (col: DataPreviewColumn) => {\n if (col.align) return col.align\n if (col.type === 'number') return 'right'\n return 'left'\n }\n\n const sortIndicator = (key: string) => {\n if (sortKey() !== key) return '\\u2195'\n return sortDir() === 'asc' ? '\\u2191' : '\\u2193'\n }\n\n return (\n <Show when={content()} fallback={\n <div class=\"text-xs text-amber-600 dark:text-amber-400 p-2\">\n [DataPreviewSection] Invalid content format\n </div>\n }>\n {(c) => (\n <div class=\"data-preview-section\">\n {/* Header: source + export */}\n <div class=\"flex items-center justify-between mb-2\">\n <div class=\"flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400\">\n <Show when={c().source}>\n <span class=\"font-medium\">{c().source}</span>\n </Show>\n <Show when={c().freshness}>\n <span class=\"px-1.5 py-0.5 rounded bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300\">\n {c().freshness}\n </span>\n </Show>\n </div>\n <Show when={c().exportable !== false}>\n <div class=\"flex items-center gap-1\">\n <button\n class=\"px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n onClick={handleExportCSV}\n title={`Export CSV (${sortedRows().length} rows)`}\n >\n CSV\n </button>\n <button\n class=\"px-2 py-1 text-xs rounded border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n onClick={handleExportJSON}\n title={`Export JSON (${sortedRows().length} rows)`}\n >\n JSON\n </button>\n </div>\n </Show>\n </div>\n\n {/* Table */}\n <div class=\"overflow-x-auto rounded border border-gray-200 dark:border-gray-700\">\n <table class=\"w-full text-sm\">\n <thead>\n <tr class=\"bg-gray-50 dark:bg-gray-800\">\n <For each={columns()}>\n {(col) => (\n <th\n class=\"px-3 py-2 font-medium text-xs text-gray-600 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 cursor-pointer select-none hover:bg-gray-100 dark:hover:bg-gray-700/50 transition-colors\"\n style={{ \"text-align\": columnAlign(col) }}\n onClick={() => handleSort(col.key)}\n title={`Sort by ${col.label}`}\n >\n <span class=\"inline-flex items-center gap-1\">\n {col.label}\n <span\n class=\"text-[10px] leading-none\"\n classList={{\n 'opacity-30': sortKey() !== col.key,\n 'opacity-100 text-blue-600 dark:text-blue-400': sortKey() === col.key,\n }}\n >\n {sortIndicator(col.key)}\n </span>\n </span>\n </th>\n )}\n </For>\n </tr>\n </thead>\n <tbody>\n <For each={visibleRows()}>\n {(row, i) => (\n <tr\n class=\"border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors\"\n classList={{ 'bg-gray-25 dark:bg-gray-850': i() % 2 === 1 }}\n >\n <For each={columns()}>\n {(col) => (\n <td\n class=\"px-3 py-2 text-gray-800 dark:text-gray-200\"\n style={{ \"text-align\": columnAlign(col) }}\n >\n {formatCell(row[col.key], col)}\n </td>\n )}\n </For>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n </div>\n\n {/* Footer: pagination + page info */}\n <div class=\"flex items-center justify-between mt-2 text-xs text-gray-500 dark:text-gray-400\">\n <Show when={showPageInfo()}>\n <span>\n {isPaginated()\n ? `Showing ${rangeStart()}\\u2013${rangeEnd()} of ${sortedRows().length.toLocaleString('fr-FR')}`\n : `${sortedRows().length} row${sortedRows().length !== 1 ? 's' : ''}`\n }\n {c().totalRows && c().totalRows! > sortedRows().length\n ? ` (${c().totalRows!.toLocaleString('fr-FR')} total)`\n : ''\n }\n </span>\n </Show>\n <Show when={!showPageInfo()}><span /></Show>\n\n <Show when={isPaginated()}>\n <div class=\"flex items-center gap-1\">\n <button\n class=\"px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors\"\n disabled={page() === 0}\n onClick={() => setPage(p => p - 1)}\n >\n &#x25C0; Prev\n </button>\n <span class=\"px-2\">Page {page() + 1} / {totalPages()}</span>\n <button\n class=\"px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors\"\n disabled={page() >= totalPages() - 1}\n onClick={() => setPage(p => p + 1)}\n >\n Next &#x25B6;\n </button>\n </div>\n </Show>\n </div>\n </div>\n )}\n </Show>\n )\n}\n"],"names":["formatNumber","value","format","isFinite","String","toFixed","toLocaleString","Number","isInteger","maximumFractionDigits","formatCell","col","type","Date","toLocaleDateString","compareValues","a","b","na","nb","isNaN","da","getTime","db","localeCompare","sensitivity","toCSV","columns","rows","header","map","c","label","replace","join","body","row","val","key","downloadFile","content","filename","mimeType","blob","Blob","url","URL","createObjectURL","document","createElement","href","download","click","revokeObjectURL","resolveContent","raw","obj","Array","isArray","inner","DataPreviewSection","props","createMemo","resolved","console","warn","rawRows","pageSizeVal","pageSize","showPageInfo","page","setPage","createSignal","initialPage","sortKey","setSortKey","sortDir","setSortDir","createEffect","p","onPageChange","handleSort","sortedRows","r","dir","find","sort","cmp","isPaginated","length","totalPages","Math","ceil","visibleRows","start","slice","rangeStart","rangeEnd","min","handleExportCSV","handleExportJSON","JSON","stringify","columnAlign","align","sortIndicator","_$createComponent","Show","when","fallback","_$getNextElement","_tmpl$","children","_el$2","_tmpl$8","_el$3","firstChild","_el$4","_el$7","_el$8","_co$","_$getNextMarker","nextSibling","_el$9","_el$0","_co$2","_el$12","_el$13","_co$3","_el$14","_el$15","_el$16","_el$17","_el$18","_el$19","_el$36","_el$37","_co$8","_el$38","_el$39","_co$9","_el$40","_el$41","_co$0","_$insert","source","_el$5","_tmpl$2","freshness","_el$6","_tmpl$3","exportable","_el$1","_tmpl$4","_el$10","_el$11","$$click","_$effect","_p$","_v$","_v$2","e","_$setAttribute","t","undefined","_$runHydrationEvents","For","each","_el$42","_tmpl$9","_el$43","_el$45","_el$46","_co$1","_el$44","_v$5","_v$6","_v$7","_$setStyleProperty","_$classList","i","_el$47","_tmpl$0","_el$48","_tmpl$1","_$p","_el$20","_tmpl$5","_el$21","_el$22","_co$4","_el$23","_el$24","_co$5","_c$","_$memo","_c$2","totalRows","_tmpl$6","_el$26","_tmpl$7","_el$27","_el$28","_el$29","_el$31","_el$32","_co$6","_el$30","_el$33","_el$34","_co$7","_el$35","_v$3","_v$4","_$setProperty","_$delegateEvents"],"mappings":"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"}
@@ -1,16 +1,8 @@
1
1
  /**
2
2
  * DataPreviewSection — paginated, sortable data table with export
3
- * v4.0.3: Sortable columns (click header: asc desc → reset)
3
+ * v4.0.4: Full pagination spec (auto-activate, pageSize=0 disable, showPageInfo, onPageChange)
4
4
  *
5
5
  * @experimental
6
- *
7
- * Features:
8
- * - Sortable columns (type-aware: number, string, date)
9
- * - Column types (number right-aligned, string left-aligned)
10
- * - Pagination (configurable page size)
11
- * - CSV / JSON export buttons
12
- * - Source attribution + freshness label
13
- * - Number formatting (FR locale)
14
6
  */
15
7
  import type { DataPreviewContent } from '../types/chat-bus';
16
8
  export interface DataPreviewSectionProps {
@@ -1 +1 @@
1
- {"version":3,"file":"DataPreviewSection.d.ts","sourceRoot":"","sources":["../../src/components/DataPreviewSection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAqB,MAAM,mBAAmB,CAAA;AAE9E,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,kBAAkB,CAAA;CAC5B;AAqGD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,kCA4MhE"}
1
+ {"version":3,"file":"DataPreviewSection.d.ts","sourceRoot":"","sources":["../../src/components/DataPreviewSection.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAqB,MAAM,mBAAmB,CAAA;AAE9E,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,kBAAkB,CAAA;CAC5B;AA0FD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,kCAyNhE"}