@expcat/tigercat-core 2.1.2 → 2.1.3

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 (76) hide show
  1. package/dist/{data-export-CLWdsrRn.d.ts → data-export-D01yjggE.d.ts} +18 -7
  2. package/dist/datepicker-locales/ar-SA.d.ts +2 -1
  3. package/dist/datepicker-locales/ar-SA.js +8 -1
  4. package/dist/datepicker-locales/de-DE.d.ts +2 -1
  5. package/dist/datepicker-locales/de-DE.js +8 -1
  6. package/dist/datepicker-locales/en-US.d.ts +2 -1
  7. package/dist/datepicker-locales/en-US.js +3 -1
  8. package/dist/datepicker-locales/es-ES.d.ts +2 -1
  9. package/dist/datepicker-locales/es-ES.js +8 -1
  10. package/dist/datepicker-locales/fr-FR.d.ts +2 -1
  11. package/dist/datepicker-locales/fr-FR.js +8 -1
  12. package/dist/datepicker-locales/id-ID.d.ts +2 -1
  13. package/dist/datepicker-locales/id-ID.js +8 -1
  14. package/dist/datepicker-locales/ja-JP.d.ts +2 -1
  15. package/dist/datepicker-locales/ja-JP.js +8 -1
  16. package/dist/datepicker-locales/ko-KR.d.ts +2 -1
  17. package/dist/datepicker-locales/ko-KR.js +8 -1
  18. package/dist/datepicker-locales/pt-BR.d.ts +2 -1
  19. package/dist/datepicker-locales/pt-BR.js +8 -1
  20. package/dist/datepicker-locales/registry.d.ts +2 -1
  21. package/dist/datepicker-locales/registry.js +94 -13
  22. package/dist/datepicker-locales/th-TH.d.ts +2 -1
  23. package/dist/datepicker-locales/th-TH.js +8 -1
  24. package/dist/datepicker-locales/vi-VN.d.ts +2 -1
  25. package/dist/datepicker-locales/vi-VN.js +8 -1
  26. package/dist/datepicker-locales/zh-CN.d.ts +2 -1
  27. package/dist/datepicker-locales/zh-CN.js +3 -1
  28. package/dist/datepicker-locales/zh-TW.d.ts +2 -1
  29. package/dist/datepicker-locales/zh-TW.js +8 -1
  30. package/dist/icons/common.d.ts +2 -2
  31. package/dist/icons/common.js +14 -8
  32. package/dist/index.d.ts +10277 -5385
  33. package/dist/index.js +30920 -16435
  34. package/dist/locale-qoiGEqe_.d.ts +1507 -0
  35. package/dist/locales/ar-SA.d.ts +2 -2
  36. package/dist/locales/ar-SA.js +448 -442
  37. package/dist/locales/de-DE.d.ts +2 -2
  38. package/dist/locales/de-DE.js +456 -450
  39. package/dist/locales/en-US.d.ts +2 -2
  40. package/dist/locales/en-US.js +259 -62
  41. package/dist/locales/es-ES.d.ts +2 -2
  42. package/dist/locales/es-ES.js +450 -444
  43. package/dist/locales/fr-FR.d.ts +2 -2
  44. package/dist/locales/fr-FR.js +453 -447
  45. package/dist/locales/id-ID.d.ts +3 -3
  46. package/dist/locales/id-ID.js +471 -448
  47. package/dist/locales/ja-JP.d.ts +3 -3
  48. package/dist/locales/ja-JP.js +465 -442
  49. package/dist/locales/ko-KR.d.ts +3 -3
  50. package/dist/locales/ko-KR.js +465 -442
  51. package/dist/locales/pt-BR.d.ts +2 -2
  52. package/dist/locales/pt-BR.js +452 -446
  53. package/dist/locales/th-TH.d.ts +3 -3
  54. package/dist/locales/th-TH.js +467 -444
  55. package/dist/locales/vi-VN.d.ts +3 -3
  56. package/dist/locales/vi-VN.js +467 -444
  57. package/dist/locales/zh-CN.d.ts +2 -2
  58. package/dist/locales/zh-CN.js +257 -60
  59. package/dist/locales/zh-TW.d.ts +3 -3
  60. package/dist/locales/zh-TW.js +467 -444
  61. package/dist/{table-CHeBgM_2.d.ts → table-R9Yp1aVa.d.ts} +77 -54
  62. package/dist/tailwind/modern.js +1364 -150
  63. package/dist/{tailwind-entry-nnuviNxx.d.ts → tailwind-entry-C26Y3TZG.d.ts} +13 -10
  64. package/dist/tailwind.d.ts +1 -1
  65. package/dist/tailwind.js +1406 -136
  66. package/dist/utils/data-export.d.ts +19 -5
  67. package/dist/utils/data-export.js +138 -13
  68. package/dist/utils/table-export.d.ts +21 -12
  69. package/dist/utils/table-export.js +75 -46
  70. package/package.json +1 -1
  71. package/tokens/figma-variables.json +223 -147
  72. package/tokens/tokens.css +224 -57
  73. package/tokens/tokens.json +205 -31
  74. package/dist/datepicker-Digy7Stt.d.ts +0 -201
  75. package/dist/locale-KMGxL6bT.d.ts +0 -625
  76. package/tokens/tailwind-tokens.js +0 -145
@@ -1,7 +1,7 @@
1
- import { T as TableColumn } from '../table-CHeBgM_2.js';
2
- import { D as DataExportFormat, a as DataExportOptions } from '../data-export-CLWdsrRn.js';
3
- import '../locale-KMGxL6bT.js';
4
- import '../datepicker-Digy7Stt.js';
1
+ import { T as TableColumn } from '../table-R9Yp1aVa.js';
2
+ import { D as DataExportOptions, a as DataExportFormat } from '../data-export-D01yjggE.js';
3
+ import '../locale-qoiGEqe_.js';
4
+ import '@floating-ui/dom';
5
5
 
6
6
  /**
7
7
  * DataExport serialization utilities (real .xlsx workbook / GitHub-flavored Markdown table)
@@ -30,6 +30,10 @@ declare function exportDataToXlsx<T>(columns: TableColumn<T>[], data: T[], optio
30
30
  * Serialize columns + records into a GitHub-flavored Markdown table
31
31
  */
32
32
  declare function exportDataToMarkdown<T>(columns: TableColumn<T>[], data: T[], options?: DataExportOptions<T>): string;
33
+ /**
34
+ * Serialize columns + records into UTF-8 BOM + CRLF CSV.
35
+ */
36
+ declare function exportDataToCsv<T>(columns: TableColumn<T>[], data: T[], options?: DataExportOptions<T>): string;
33
37
  /**
34
38
  * Serialize columns + records into the given format
35
39
  */
@@ -38,5 +42,15 @@ declare function exportData<T>(columns: TableColumn<T>[], data: T[], format: Dat
38
42
  * Trigger a browser download for serialized export content
39
43
  */
40
44
  declare function downloadDataExport(content: Uint8Array | string, filename?: string, format?: DataExportFormat): void;
45
+ interface RunDataExportInput<T = Record<string, unknown>> extends DataExportOptions<T> {
46
+ columns: TableColumn<T>[];
47
+ dataSource: T[];
48
+ format: string;
49
+ fileName?: string;
50
+ }
51
+ /**
52
+ * Serialize and download one format. Unknown formats warn and throw.
53
+ */
54
+ declare function runDataExport<T>(input: RunDataExportInput<T>): DataExportFormat;
41
55
 
42
- export { type ZipEntrySource, buildStoredZip, crc32, downloadDataExport, exportData, exportDataToMarkdown, exportDataToXlsx };
56
+ export { type RunDataExportInput, type ZipEntrySource, buildStoredZip, crc32, downloadDataExport, exportData, exportDataToCsv, exportDataToMarkdown, exportDataToXlsx, runDataExport };
@@ -3,11 +3,95 @@ function isBrowser() {
3
3
  return typeof window !== "undefined" && typeof document !== "undefined";
4
4
  }
5
5
 
6
+ // src/utils/dev-warn.ts
7
+ function isDevEnvironment() {
8
+ const proc = globalThis.process;
9
+ return !proc?.env || proc.env.NODE_ENV !== "production";
10
+ }
11
+ var warnedKeys = /* @__PURE__ */ new Set();
12
+ function devWarn(key, message) {
13
+ if (!isDevEnvironment() || warnedKeys.has(key)) return;
14
+ warnedKeys.add(key);
15
+ console.warn(message);
16
+ }
17
+
18
+ // src/utils/data-export-value.ts
19
+ function columnField(column) {
20
+ return column.dataKey || column.key;
21
+ }
22
+ var DATA_EXPORT_SOFT_CELL_LIMIT = 1e5;
23
+ var DATA_EXPORT_MAX_CELL_CHARS = 32767;
24
+ var DATA_EXPORT_FORMULA_PREFIX = /^[=+\-@]/;
25
+ function isDataExportFormat(value) {
26
+ return value === "xlsx" || value === "markdown" || value === "csv";
27
+ }
28
+ function formatDataExportCellValue(value) {
29
+ if (value === null || value === void 0) return "";
30
+ if (value instanceof Date) {
31
+ return Number.isNaN(value.getTime()) ? "" : value.toISOString();
32
+ }
33
+ if (typeof value === "object") {
34
+ try {
35
+ return JSON.stringify(value);
36
+ } catch {
37
+ return "";
38
+ }
39
+ }
40
+ return value;
41
+ }
42
+ function sanitizeDataExportText(value) {
43
+ let str = value === null || value === void 0 ? "" : String(value);
44
+ if (DATA_EXPORT_FORMULA_PREFIX.test(str)) {
45
+ str = `'${str}`;
46
+ }
47
+ if (str.length > DATA_EXPORT_MAX_CELL_CHARS) {
48
+ return str.slice(0, DATA_EXPORT_MAX_CELL_CHARS);
49
+ }
50
+ return str;
51
+ }
52
+ function isRenderOnlyExportColumn(column, data) {
53
+ if (!column.render) return false;
54
+ const field = columnField(column);
55
+ if (!field) return true;
56
+ return data.every((record) => record[field] === void 0);
57
+ }
58
+ function resolveDataExportColumns(columns, data, hiddenColumnKeys) {
59
+ const hidden = hiddenColumnKeys ? new Set(hiddenColumnKeys) : null;
60
+ return columns.filter((column) => {
61
+ if (hidden?.has(column.key)) return false;
62
+ return !isRenderOnlyExportColumn(column, data);
63
+ });
64
+ }
65
+ function getDataExportCellValue(record, column, cellFormatter) {
66
+ const field = columnField(column);
67
+ const raw = field ? record[field] : void 0;
68
+ const next = cellFormatter ? cellFormatter(raw, column, record) : raw;
69
+ return formatDataExportCellValue(next);
70
+ }
71
+ function resolveDataExportFilename(fileName, extension) {
72
+ const trimmed = (fileName ?? "").trim();
73
+ const cleaned = (trimmed || "export").replace(/[\\/:*?"<>|]+/g, "-");
74
+ const suffix = `.${extension}`;
75
+ if (cleaned.toLowerCase().endsWith(suffix.toLowerCase())) return cleaned;
76
+ return `${cleaned}${suffix}`;
77
+ }
78
+
6
79
  // src/utils/data-export-utils.ts
80
+ function needsCsvQuotes(value) {
81
+ return /[",\n\r]/.test(value);
82
+ }
83
+ function escapeExportCsvValue(value) {
84
+ const str = sanitizeDataExportText(formatDataExportCellValue(value));
85
+ if (needsCsvQuotes(str)) {
86
+ return `"${str.replace(/"/g, '""')}"`;
87
+ }
88
+ return str;
89
+ }
7
90
  function getCellValue(record, column, options) {
8
- const key = column.dataKey || column.key;
9
- const raw = record[key];
10
- return options?.cellFormatter ? options.cellFormatter(raw, column, record) : raw;
91
+ return getDataExportCellValue(record, column, options?.cellFormatter);
92
+ }
93
+ function resolveExportColumns(columns, data, options) {
94
+ return resolveDataExportColumns(columns, data, options?.hiddenColumnKeys);
11
95
  }
12
96
  var crc32Table = null;
13
97
  function getCrc32Table() {
@@ -124,16 +208,17 @@ function buildSheetCell(value, columnIndex, rowNumber) {
124
208
  if (typeof value === "number" && Number.isFinite(value)) {
125
209
  return `<c r="${ref}"><v>${value}</v></c>`;
126
210
  }
127
- const str = value === null || value === void 0 ? "" : String(value);
211
+ const str = sanitizeDataExportText(value);
128
212
  if (str === "") return "";
129
213
  return `<c r="${ref}" t="inlineStr"><is><t xml:space="preserve">${escapeXml(str)}</t></is></c>`;
130
214
  }
131
215
  function exportDataToXlsx(columns, data, options) {
132
- const headerCells = columns.map((column, index) => buildSheetCell(column.title, index, 1)).join("");
216
+ const exportColumns = resolveExportColumns(columns, data, options);
217
+ const headerCells = exportColumns.map((column, index) => buildSheetCell(column.title, index, 1)).join("");
133
218
  const rows = [`<row r="1">${headerCells}</row>`];
134
219
  data.forEach((record, rowIndex) => {
135
220
  const rowNumber = rowIndex + 2;
136
- const cells = columns.map(
221
+ const cells = exportColumns.map(
137
222
  (column, columnIndex) => buildSheetCell(getCellValue(record, column, options), columnIndex, rowNumber)
138
223
  ).join("");
139
224
  rows.push(`<row r="${rowNumber}">${cells}</row>`);
@@ -162,42 +247,82 @@ function markdownSeparator(align) {
162
247
  return "---";
163
248
  }
164
249
  function exportDataToMarkdown(columns, data, options) {
165
- const header = `| ${columns.map((column) => escapeMarkdownCell(column.title)).join(" | ")} |`;
166
- const separator = `| ${columns.map((column) => markdownSeparator(column.align)).join(" | ")} |`;
250
+ const exportColumns = resolveExportColumns(columns, data, options);
251
+ const header = `| ${exportColumns.map((column) => escapeMarkdownCell(column.title)).join(" | ")} |`;
252
+ const separator = `| ${exportColumns.map((column) => markdownSeparator(column.align)).join(" | ")} |`;
167
253
  const rows = data.map(
168
- (record) => `| ${columns.map((column) => escapeMarkdownCell(getCellValue(record, column, options))).join(" | ")} |`
254
+ (record) => `| ${exportColumns.map((column) => escapeMarkdownCell(getCellValue(record, column, options))).join(" | ")} |`
169
255
  );
170
256
  return [header, separator, ...rows].join("\n");
171
257
  }
258
+ function exportDataToCsv(columns, data, options) {
259
+ const exportColumns = resolveExportColumns(columns, data, options);
260
+ const headers = exportColumns.map((column) => escapeExportCsvValue(column.title));
261
+ const rows = data.map(
262
+ (record) => exportColumns.map((column) => escapeExportCsvValue(getCellValue(record, column, options))).join(",")
263
+ );
264
+ return `\uFEFF${[headers.join(","), ...rows].join("\r\n")}`;
265
+ }
172
266
  function exportData(columns, data, format, options) {
173
- return format === "xlsx" ? exportDataToXlsx(columns, data, options) : exportDataToMarkdown(columns, data, options);
267
+ if (format === "xlsx") return exportDataToXlsx(columns, data, options);
268
+ if (format === "csv") return exportDataToCsv(columns, data, options);
269
+ if (format === "markdown") return exportDataToMarkdown(columns, data, options);
270
+ devWarn("DataExport.format", `Unknown export format "${String(format)}"`);
271
+ throw new Error(`Unknown export format: ${String(format)}`);
174
272
  }
175
273
  var DATA_EXPORT_FILE_META = {
176
274
  xlsx: {
177
275
  extension: "xlsx",
178
276
  mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
179
277
  },
180
- markdown: { extension: "md", mime: "text/markdown;charset=utf-8;" }
278
+ markdown: { extension: "md", mime: "text/markdown;charset=utf-8;" },
279
+ csv: { extension: "csv", mime: "text/csv;charset=utf-8;" }
181
280
  };
182
281
  function downloadDataExport(content, filename = "export", format = "xlsx") {
183
282
  if (!isBrowser()) return;
283
+ if (!isDataExportFormat(format)) {
284
+ devWarn("DataExport.format", `Unknown export format "${String(format)}"`);
285
+ return;
286
+ }
184
287
  const meta = DATA_EXPORT_FILE_META[format];
185
288
  const blob = new Blob([content], { type: meta.mime });
186
289
  const url = URL.createObjectURL(blob);
187
290
  const link = document.createElement("a");
188
291
  link.href = url;
189
- link.download = `${filename}.${meta.extension}`;
292
+ link.download = resolveDataExportFilename(filename, meta.extension);
190
293
  link.style.display = "none";
191
294
  document.body.appendChild(link);
192
295
  link.click();
193
296
  document.body.removeChild(link);
194
297
  URL.revokeObjectURL(url);
195
298
  }
299
+ function runDataExport(input) {
300
+ if (!isDataExportFormat(input.format)) {
301
+ devWarn("DataExport.format", `Unknown export format "${String(input.format)}"`);
302
+ throw new Error(`Unknown export format: ${String(input.format)}`);
303
+ }
304
+ const columns = resolveDataExportColumns(input.columns, input.dataSource, input.hiddenColumnKeys);
305
+ const cellCount = columns.length * (input.dataSource.length + 1);
306
+ if (cellCount > DATA_EXPORT_SOFT_CELL_LIMIT) {
307
+ devWarn(
308
+ "DataExport.size",
309
+ `Export has ${cellCount} cells; files above ${DATA_EXPORT_SOFT_CELL_LIMIT} may be slow or fail to open`
310
+ );
311
+ }
312
+ const content = exportData(columns, input.dataSource, input.format, {
313
+ sheetName: input.sheetName,
314
+ cellFormatter: input.cellFormatter
315
+ });
316
+ downloadDataExport(content, input.fileName, input.format);
317
+ return input.format;
318
+ }
196
319
  export {
197
320
  buildStoredZip,
198
321
  crc32,
199
322
  downloadDataExport,
200
323
  exportData,
324
+ exportDataToCsv,
201
325
  exportDataToMarkdown,
202
- exportDataToXlsx
326
+ exportDataToXlsx,
327
+ runDataExport
203
328
  };
@@ -1,26 +1,35 @@
1
- import { x as TableExportFormat, T as TableColumn } from '../table-CHeBgM_2.js';
2
- import '../locale-KMGxL6bT.js';
3
- import '../datepicker-Digy7Stt.js';
1
+ import { T as TableColumn } from '../table-R9Yp1aVa.js';
2
+ import '../locale-qoiGEqe_.js';
3
+ import '@floating-ui/dom';
4
4
 
5
5
  /**
6
- * Table export utilities (CSV / Excel-compatible HTML worksheet)
6
+ * Table CSV export.
7
+ *
8
+ * Excel / xlsx is DataExport (`@expcat/tigercat-core/utils/data-export`), not
9
+ * an HTML worksheet pretending to be `.xls`.
7
10
  */
8
11
 
9
12
  /**
10
- * Export table data to CSV string
13
+ * Escape a value for RFC 4180 CSV output.
11
14
  */
12
- declare function exportTableToCsv<T>(columns: TableColumn<T>[], data: T[], _filename?: string): string;
13
- declare function exportTableToExcel<T>(columns: TableColumn<T>[], data: T[]): string;
15
+ declare function escapeCsvValue(value: unknown): string;
14
16
  /**
15
- * Trigger a CSV file download in the browser
17
+ * Export table data to a CSV string (UTF-8 BOM + CRLF).
18
+ *
19
+ * Cell values use `dataKey || key`. `filename` is ignored — pass it to
20
+ * {@link downloadCsv}.
21
+ */
22
+ declare function exportTableToCsv<T>(columns: TableColumn<T>[], data: T[]): string;
23
+ declare function exportTableData<T>(columns: TableColumn<T>[], data: T[]): string;
24
+ /**
25
+ * Trigger a CSV file download in the browser.
26
+ * Existing `.csv` suffixes are not duplicated.
16
27
  */
17
28
  declare function downloadCsv(csvContent: string, filename?: string): void;
18
- declare function downloadExcel(excelContent: string, filename?: string): void;
19
- declare function exportTableData<T>(columns: TableColumn<T>[], data: T[], format?: TableExportFormat): string;
20
- declare function downloadTableExport(content: string, filename?: string, format?: TableExportFormat): void;
29
+ declare function downloadTableExport(content: string, filename?: string): void;
21
30
  /**
22
31
  * Get export button classes
23
32
  */
24
33
  declare const tableExportButtonClasses = "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--tiger-radius-md,0.5rem)] border border-[var(--tiger-border,#e5e7eb)] text-[var(--tiger-text,#111827)] bg-[var(--tiger-surface,#ffffff)] hover:bg-[var(--tiger-surface-muted,#f9fafb)] transition-colors";
25
34
 
26
- export { downloadCsv, downloadExcel, downloadTableExport, exportTableData, exportTableToCsv, exportTableToExcel, tableExportButtonClasses };
35
+ export { downloadCsv, downloadTableExport, escapeCsvValue, exportTableData, exportTableToCsv, tableExportButtonClasses };
@@ -3,84 +3,113 @@ function isBrowser() {
3
3
  return typeof window !== "undefined" && typeof document !== "undefined";
4
4
  }
5
5
 
6
+ // src/utils/class-names.ts
7
+ function classNames(...classes) {
8
+ let result = "";
9
+ for (const cls of classes) {
10
+ if (cls && cls !== "") {
11
+ result += (result ? " " : "") + String(cls);
12
+ }
13
+ }
14
+ return result;
15
+ }
16
+
17
+ // src/utils/table-utils.ts
18
+ var tableLoadingOverlayClasses = classNames(
19
+ "absolute inset-0 bg-[var(--tiger-surface,#ffffff)]/80 flex items-center justify-center z-20"
20
+ );
21
+ function getTableColumnDataKey(column) {
22
+ return column.dataKey || column.key;
23
+ }
24
+
25
+ // src/utils/data-export-value.ts
26
+ var DATA_EXPORT_MAX_CELL_CHARS = 32767;
27
+ var DATA_EXPORT_FORMULA_PREFIX = /^[=+\-@]/;
28
+ function formatDataExportCellValue(value) {
29
+ if (value === null || value === void 0) return "";
30
+ if (value instanceof Date) {
31
+ return Number.isNaN(value.getTime()) ? "" : value.toISOString();
32
+ }
33
+ if (typeof value === "object") {
34
+ try {
35
+ return JSON.stringify(value);
36
+ } catch {
37
+ return "";
38
+ }
39
+ }
40
+ return value;
41
+ }
42
+ function sanitizeDataExportText(value) {
43
+ let str = value === null || value === void 0 ? "" : String(value);
44
+ if (DATA_EXPORT_FORMULA_PREFIX.test(str)) {
45
+ str = `'${str}`;
46
+ }
47
+ if (str.length > DATA_EXPORT_MAX_CELL_CHARS) {
48
+ return str.slice(0, DATA_EXPORT_MAX_CELL_CHARS);
49
+ }
50
+ return str;
51
+ }
52
+ function resolveDataExportFilename(fileName, extension) {
53
+ const trimmed = (fileName ?? "").trim();
54
+ const cleaned = (trimmed || "export").replace(/[\\/:*?"<>|]+/g, "-");
55
+ const suffix = `.${extension}`;
56
+ if (cleaned.toLowerCase().endsWith(suffix.toLowerCase())) return cleaned;
57
+ return `${cleaned}${suffix}`;
58
+ }
59
+
6
60
  // src/utils/table-export-utils.ts
61
+ var CSV_BOM = "\uFEFF";
62
+ function needsCsvQuotes(value) {
63
+ return /[",\n\r]/.test(value);
64
+ }
7
65
  function escapeCsvValue(value) {
8
- const str = value === null || value === void 0 ? "" : String(value);
9
- if (str.includes(",") || str.includes('"') || str.includes("\n")) {
66
+ const str = sanitizeDataExportText(formatDataExportCellValue(value));
67
+ if (needsCsvQuotes(str)) {
10
68
  return `"${str.replace(/"/g, '""')}"`;
11
69
  }
12
70
  return str;
13
71
  }
14
- function exportTableToCsv(columns, data, _filename) {
72
+ function withCsvExtension(filename) {
73
+ return resolveDataExportFilename(filename, "csv");
74
+ }
75
+ function exportTableToCsv(columns, data) {
15
76
  const headers = columns.map((col) => escapeCsvValue(col.title));
16
77
  const rows = data.map(
17
78
  (record) => columns.map((col) => {
18
- const key = col.dataKey || col.key;
19
- const value = record[key];
79
+ const value = record[getTableColumnDataKey(col)];
20
80
  return escapeCsvValue(value);
21
81
  }).join(",")
22
82
  );
23
- return [headers.join(","), ...rows].join("\n");
24
- }
25
- function escapeHtmlValue(value) {
26
- const str = value === null || value === void 0 ? "" : String(value);
27
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
83
+ return `${CSV_BOM}${[headers.join(","), ...rows].join("\r\n")}`;
28
84
  }
29
- function exportTableToExcel(columns, data) {
30
- const headerCells = columns.map((column) => `<th>${escapeHtmlValue(column.title)}</th>`).join("");
31
- const bodyRows = data.map((record) => {
32
- const cells = columns.map((column) => {
33
- const key = column.dataKey || column.key;
34
- const value = record[key];
35
- return `<td>${escapeHtmlValue(value)}</td>`;
36
- }).join("");
37
- return `<tr>${cells}</tr>`;
38
- }).join("");
39
- return `<!doctype html><html><head><meta charset="utf-8"></head><body><table><thead><tr>${headerCells}</tr></thead><tbody>${bodyRows}</tbody></table></body></html>`;
85
+ function exportTableData(columns, data) {
86
+ return exportTableToCsv(columns, data);
40
87
  }
41
- function downloadCsv(csvContent, filename = "export") {
88
+ function downloadBlob(content, filename, mime) {
42
89
  if (!isBrowser()) return;
43
- const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
90
+ const blob = new Blob([content], { type: mime });
44
91
  const url = URL.createObjectURL(blob);
45
92
  const link = document.createElement("a");
46
93
  link.href = url;
47
- link.download = `${filename}.csv`;
94
+ link.download = filename;
48
95
  link.style.display = "none";
49
96
  document.body.appendChild(link);
50
97
  link.click();
51
98
  document.body.removeChild(link);
52
99
  URL.revokeObjectURL(url);
53
100
  }
54
- function downloadExcel(excelContent, filename = "export") {
55
- if (!isBrowser()) return;
56
- const blob = new Blob([excelContent], { type: "application/vnd.ms-excel;charset=utf-8;" });
57
- const url = URL.createObjectURL(blob);
58
- const link = document.createElement("a");
59
- link.href = url;
60
- link.download = `${filename}.xls`;
61
- link.style.display = "none";
62
- document.body.appendChild(link);
63
- link.click();
64
- document.body.removeChild(link);
65
- URL.revokeObjectURL(url);
66
- }
67
- function exportTableData(columns, data, format = "csv") {
68
- return format === "excel" ? exportTableToExcel(columns, data) : exportTableToCsv(columns, data);
101
+ function downloadCsv(csvContent, filename = "export") {
102
+ downloadBlob(csvContent, withCsvExtension(filename), "text/csv;charset=utf-8;");
69
103
  }
70
- function downloadTableExport(content, filename = "export", format = "csv") {
71
- if (format === "excel") {
72
- downloadExcel(content, filename);
73
- return;
74
- }
104
+ function downloadTableExport(content, filename = "export") {
75
105
  downloadCsv(content, filename);
76
106
  }
77
107
  var tableExportButtonClasses = "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-[var(--tiger-radius-md,0.5rem)] border border-[var(--tiger-border,#e5e7eb)] text-[var(--tiger-text,#111827)] bg-[var(--tiger-surface,#ffffff)] hover:bg-[var(--tiger-surface-muted,#f9fafb)] transition-colors";
78
108
  export {
79
109
  downloadCsv,
80
- downloadExcel,
81
110
  downloadTableExport,
111
+ escapeCsvValue,
82
112
  exportTableData,
83
113
  exportTableToCsv,
84
- exportTableToExcel,
85
114
  tableExportButtonClasses
86
115
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expcat/tigercat-core",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "type": "module",
5
5
  "description": "Core utilities for Tigercat UI library",
6
6
  "license": "MIT",