@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.
- package/dist/{data-export-CLWdsrRn.d.ts → data-export-D01yjggE.d.ts} +18 -7
- package/dist/datepicker-locales/ar-SA.d.ts +2 -1
- package/dist/datepicker-locales/ar-SA.js +8 -1
- package/dist/datepicker-locales/de-DE.d.ts +2 -1
- package/dist/datepicker-locales/de-DE.js +8 -1
- package/dist/datepicker-locales/en-US.d.ts +2 -1
- package/dist/datepicker-locales/en-US.js +3 -1
- package/dist/datepicker-locales/es-ES.d.ts +2 -1
- package/dist/datepicker-locales/es-ES.js +8 -1
- package/dist/datepicker-locales/fr-FR.d.ts +2 -1
- package/dist/datepicker-locales/fr-FR.js +8 -1
- package/dist/datepicker-locales/id-ID.d.ts +2 -1
- package/dist/datepicker-locales/id-ID.js +8 -1
- package/dist/datepicker-locales/ja-JP.d.ts +2 -1
- package/dist/datepicker-locales/ja-JP.js +8 -1
- package/dist/datepicker-locales/ko-KR.d.ts +2 -1
- package/dist/datepicker-locales/ko-KR.js +8 -1
- package/dist/datepicker-locales/pt-BR.d.ts +2 -1
- package/dist/datepicker-locales/pt-BR.js +8 -1
- package/dist/datepicker-locales/registry.d.ts +2 -1
- package/dist/datepicker-locales/registry.js +94 -13
- package/dist/datepicker-locales/th-TH.d.ts +2 -1
- package/dist/datepicker-locales/th-TH.js +8 -1
- package/dist/datepicker-locales/vi-VN.d.ts +2 -1
- package/dist/datepicker-locales/vi-VN.js +8 -1
- package/dist/datepicker-locales/zh-CN.d.ts +2 -1
- package/dist/datepicker-locales/zh-CN.js +3 -1
- package/dist/datepicker-locales/zh-TW.d.ts +2 -1
- package/dist/datepicker-locales/zh-TW.js +8 -1
- package/dist/icons/common.d.ts +2 -2
- package/dist/icons/common.js +14 -8
- package/dist/index.d.ts +10277 -5385
- package/dist/index.js +30920 -16435
- package/dist/locale-qoiGEqe_.d.ts +1507 -0
- package/dist/locales/ar-SA.d.ts +2 -2
- package/dist/locales/ar-SA.js +448 -442
- package/dist/locales/de-DE.d.ts +2 -2
- package/dist/locales/de-DE.js +456 -450
- package/dist/locales/en-US.d.ts +2 -2
- package/dist/locales/en-US.js +259 -62
- package/dist/locales/es-ES.d.ts +2 -2
- package/dist/locales/es-ES.js +450 -444
- package/dist/locales/fr-FR.d.ts +2 -2
- package/dist/locales/fr-FR.js +453 -447
- package/dist/locales/id-ID.d.ts +3 -3
- package/dist/locales/id-ID.js +471 -448
- package/dist/locales/ja-JP.d.ts +3 -3
- package/dist/locales/ja-JP.js +465 -442
- package/dist/locales/ko-KR.d.ts +3 -3
- package/dist/locales/ko-KR.js +465 -442
- package/dist/locales/pt-BR.d.ts +2 -2
- package/dist/locales/pt-BR.js +452 -446
- package/dist/locales/th-TH.d.ts +3 -3
- package/dist/locales/th-TH.js +467 -444
- package/dist/locales/vi-VN.d.ts +3 -3
- package/dist/locales/vi-VN.js +467 -444
- package/dist/locales/zh-CN.d.ts +2 -2
- package/dist/locales/zh-CN.js +257 -60
- package/dist/locales/zh-TW.d.ts +3 -3
- package/dist/locales/zh-TW.js +467 -444
- package/dist/{table-CHeBgM_2.d.ts → table-R9Yp1aVa.d.ts} +77 -54
- package/dist/tailwind/modern.js +1364 -150
- package/dist/{tailwind-entry-nnuviNxx.d.ts → tailwind-entry-C26Y3TZG.d.ts} +13 -10
- package/dist/tailwind.d.ts +1 -1
- package/dist/tailwind.js +1406 -136
- package/dist/utils/data-export.d.ts +19 -5
- package/dist/utils/data-export.js +138 -13
- package/dist/utils/table-export.d.ts +21 -12
- package/dist/utils/table-export.js +75 -46
- package/package.json +1 -1
- package/tokens/figma-variables.json +223 -147
- package/tokens/tokens.css +224 -57
- package/tokens/tokens.json +205 -31
- package/dist/datepicker-Digy7Stt.d.ts +0 -201
- package/dist/locale-KMGxL6bT.d.ts +0 -625
- package/tokens/tailwind-tokens.js +0 -145
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { T as TableColumn } from '../table-
|
|
2
|
-
import { D as
|
|
3
|
-
import '../locale-
|
|
4
|
-
import '
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
166
|
-
const
|
|
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) => `| ${
|
|
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
|
-
|
|
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 =
|
|
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 {
|
|
2
|
-
import '../locale-
|
|
3
|
-
import '
|
|
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
|
|
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
|
-
*
|
|
13
|
+
* Escape a value for RFC 4180 CSV output.
|
|
11
14
|
*/
|
|
12
|
-
declare function
|
|
13
|
-
declare function exportTableToExcel<T>(columns: TableColumn<T>[], data: T[]): string;
|
|
15
|
+
declare function escapeCsvValue(value: unknown): string;
|
|
14
16
|
/**
|
|
15
|
-
*
|
|
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
|
|
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,
|
|
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 =
|
|
9
|
-
if (
|
|
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
|
|
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
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
83
|
+
return `${CSV_BOM}${[headers.join(","), ...rows].join("\r\n")}`;
|
|
28
84
|
}
|
|
29
|
-
function
|
|
30
|
-
|
|
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
|
|
88
|
+
function downloadBlob(content, filename, mime) {
|
|
42
89
|
if (!isBrowser()) return;
|
|
43
|
-
const blob = new Blob([
|
|
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 =
|
|
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
|
|
55
|
-
|
|
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"
|
|
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
|
};
|