@expcat/tigercat-core 2.0.0-preview.5 → 2.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,203 @@
1
+ // src/utils/env.ts
2
+ function isBrowser() {
3
+ return typeof window !== "undefined" && typeof document !== "undefined";
4
+ }
5
+
6
+ // src/utils/data-export-utils.ts
7
+ 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;
11
+ }
12
+ var crc32Table = null;
13
+ function getCrc32Table() {
14
+ if (crc32Table) return crc32Table;
15
+ const table = new Uint32Array(256);
16
+ for (let i = 0; i < 256; i++) {
17
+ let value = i;
18
+ for (let bit = 0; bit < 8; bit++) {
19
+ value = value & 1 ? 3988292384 ^ value >>> 1 : value >>> 1;
20
+ }
21
+ table[i] = value;
22
+ }
23
+ crc32Table = table;
24
+ return table;
25
+ }
26
+ function crc32(bytes) {
27
+ const table = getCrc32Table();
28
+ let crc = 4294967295;
29
+ for (let i = 0; i < bytes.length; i++) {
30
+ crc = table[(crc ^ bytes[i]) & 255] ^ crc >>> 8;
31
+ }
32
+ return (crc ^ 4294967295) >>> 0;
33
+ }
34
+ var ZIP_DOS_TIME = 0;
35
+ var ZIP_DOS_DATE = 1 << 5 | 1;
36
+ function buildStoredZip(entries) {
37
+ const encoder = new TextEncoder();
38
+ const parts = entries.map((entry) => ({
39
+ nameBytes: encoder.encode(entry.name),
40
+ data: entry.data,
41
+ crc: crc32(entry.data),
42
+ offset: 0
43
+ }));
44
+ const localSize = parts.reduce((sum, p) => sum + 30 + p.nameBytes.length + p.data.length, 0);
45
+ const centralSize = parts.reduce((sum, p) => sum + 46 + p.nameBytes.length, 0);
46
+ const buffer = new Uint8Array(localSize + centralSize + 22);
47
+ const view = new DataView(buffer.buffer);
48
+ let offset = 0;
49
+ const writeCommonFields = (p) => {
50
+ view.setUint16(offset, 20, true);
51
+ view.setUint16(offset + 2, 2048, true);
52
+ view.setUint16(offset + 4, 0, true);
53
+ view.setUint16(offset + 6, ZIP_DOS_TIME, true);
54
+ view.setUint16(offset + 8, ZIP_DOS_DATE, true);
55
+ view.setUint32(offset + 10, p.crc, true);
56
+ view.setUint32(offset + 14, p.data.length, true);
57
+ view.setUint32(offset + 18, p.data.length, true);
58
+ view.setUint16(offset + 22, p.nameBytes.length, true);
59
+ view.setUint16(offset + 24, 0, true);
60
+ offset += 26;
61
+ };
62
+ for (const p of parts) {
63
+ p.offset = offset;
64
+ view.setUint32(offset, 67324752, true);
65
+ offset += 4;
66
+ writeCommonFields(p);
67
+ buffer.set(p.nameBytes, offset);
68
+ offset += p.nameBytes.length;
69
+ buffer.set(p.data, offset);
70
+ offset += p.data.length;
71
+ }
72
+ const centralOffset = offset;
73
+ for (const p of parts) {
74
+ view.setUint32(offset, 33639248, true);
75
+ view.setUint16(offset + 4, 20, true);
76
+ offset += 6;
77
+ writeCommonFields(p);
78
+ view.setUint16(offset, 0, true);
79
+ view.setUint16(offset + 2, 0, true);
80
+ view.setUint16(offset + 4, 0, true);
81
+ view.setUint32(offset + 6, 0, true);
82
+ view.setUint32(offset + 10, p.offset, true);
83
+ offset += 14;
84
+ buffer.set(p.nameBytes, offset);
85
+ offset += p.nameBytes.length;
86
+ }
87
+ view.setUint32(offset, 101010256, true);
88
+ view.setUint16(offset + 4, 0, true);
89
+ view.setUint16(offset + 6, 0, true);
90
+ view.setUint16(offset + 8, parts.length, true);
91
+ view.setUint16(offset + 10, parts.length, true);
92
+ view.setUint32(offset + 12, offset - centralOffset, true);
93
+ view.setUint32(offset + 16, centralOffset, true);
94
+ view.setUint16(offset + 20, 0, true);
95
+ return buffer;
96
+ }
97
+ function escapeXml(value) {
98
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;").replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g, "");
99
+ }
100
+ function columnLetter(index) {
101
+ let letters = "";
102
+ let remaining = index;
103
+ while (remaining >= 0) {
104
+ letters = String.fromCharCode(65 + remaining % 26) + letters;
105
+ remaining = Math.floor(remaining / 26) - 1;
106
+ }
107
+ return letters;
108
+ }
109
+ function sanitizeSheetName(name) {
110
+ const cleaned = (name ?? "").replace(/[:\\/?*[\]]/g, " ").trim().slice(0, 31);
111
+ return cleaned || "Sheet1";
112
+ }
113
+ var XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
114
+ var XLSX_CONTENT_TYPES = `${XML_DECLARATION}
115
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/></Types>`;
116
+ var XLSX_ROOT_RELS = `${XML_DECLARATION}
117
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>`;
118
+ var XLSX_WORKBOOK_RELS = `${XML_DECLARATION}
119
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>`;
120
+ var XLSX_STYLES = `${XML_DECLARATION}
121
+ <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="1"><font><sz val="11"/><name val="Calibri"/></font></fonts><fills count="1"><fill><patternFill patternType="none"/></fill></fills><borders count="1"><border/></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/></cellXfs><cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
122
+ function buildSheetCell(value, columnIndex, rowNumber) {
123
+ const ref = `${columnLetter(columnIndex)}${rowNumber}`;
124
+ if (typeof value === "number" && Number.isFinite(value)) {
125
+ return `<c r="${ref}"><v>${value}</v></c>`;
126
+ }
127
+ const str = value === null || value === void 0 ? "" : String(value);
128
+ if (str === "") return "";
129
+ return `<c r="${ref}" t="inlineStr"><is><t xml:space="preserve">${escapeXml(str)}</t></is></c>`;
130
+ }
131
+ function exportDataToXlsx(columns, data, options) {
132
+ const headerCells = columns.map((column, index) => buildSheetCell(column.title, index, 1)).join("");
133
+ const rows = [`<row r="1">${headerCells}</row>`];
134
+ data.forEach((record, rowIndex) => {
135
+ const rowNumber = rowIndex + 2;
136
+ const cells = columns.map(
137
+ (column, columnIndex) => buildSheetCell(getCellValue(record, column, options), columnIndex, rowNumber)
138
+ ).join("");
139
+ rows.push(`<row r="${rowNumber}">${cells}</row>`);
140
+ });
141
+ const sheetXml = `${XML_DECLARATION}
142
+ <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>${rows.join("")}</sheetData></worksheet>`;
143
+ const workbookXml = `${XML_DECLARATION}
144
+ <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets><sheet name="${escapeXml(sanitizeSheetName(options?.sheetName))}" sheetId="1" r:id="rId1"/></sheets></workbook>`;
145
+ const encoder = new TextEncoder();
146
+ return buildStoredZip([
147
+ { name: "[Content_Types].xml", data: encoder.encode(XLSX_CONTENT_TYPES) },
148
+ { name: "_rels/.rels", data: encoder.encode(XLSX_ROOT_RELS) },
149
+ { name: "xl/workbook.xml", data: encoder.encode(workbookXml) },
150
+ { name: "xl/_rels/workbook.xml.rels", data: encoder.encode(XLSX_WORKBOOK_RELS) },
151
+ { name: "xl/styles.xml", data: encoder.encode(XLSX_STYLES) },
152
+ { name: "xl/worksheets/sheet1.xml", data: encoder.encode(sheetXml) }
153
+ ]);
154
+ }
155
+ function escapeMarkdownCell(value) {
156
+ const str = value === null || value === void 0 ? "" : String(value);
157
+ return str.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\r?\n/g, "<br>");
158
+ }
159
+ function markdownSeparator(align) {
160
+ if (align === "center") return ":---:";
161
+ if (align === "right") return "---:";
162
+ return "---";
163
+ }
164
+ 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(" | ")} |`;
167
+ const rows = data.map(
168
+ (record) => `| ${columns.map((column) => escapeMarkdownCell(getCellValue(record, column, options))).join(" | ")} |`
169
+ );
170
+ return [header, separator, ...rows].join("\n");
171
+ }
172
+ function exportData(columns, data, format, options) {
173
+ return format === "xlsx" ? exportDataToXlsx(columns, data, options) : exportDataToMarkdown(columns, data, options);
174
+ }
175
+ var DATA_EXPORT_FILE_META = {
176
+ xlsx: {
177
+ extension: "xlsx",
178
+ mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
179
+ },
180
+ markdown: { extension: "md", mime: "text/markdown;charset=utf-8;" }
181
+ };
182
+ function downloadDataExport(content, filename = "export", format = "xlsx") {
183
+ if (!isBrowser()) return;
184
+ const meta = DATA_EXPORT_FILE_META[format];
185
+ const blob = new Blob([content], { type: meta.mime });
186
+ const url = URL.createObjectURL(blob);
187
+ const link = document.createElement("a");
188
+ link.href = url;
189
+ link.download = `${filename}.${meta.extension}`;
190
+ link.style.display = "none";
191
+ document.body.appendChild(link);
192
+ link.click();
193
+ document.body.removeChild(link);
194
+ URL.revokeObjectURL(url);
195
+ }
196
+ export {
197
+ buildStoredZip,
198
+ crc32,
199
+ downloadDataExport,
200
+ exportData,
201
+ exportDataToMarkdown,
202
+ exportDataToXlsx
203
+ };
@@ -1,3 +1,26 @@
1
- export { D as downloadCsv, G as downloadExcel, H as downloadTableExport, I as exportTableData, J as exportTableToCsv, K as exportTableToExcel, L as tableExportButtonClasses } from '../table-export-_tTBizGw.js';
2
- import '../locale-DKOXT9k0.js';
1
+ import { x as TableExportFormat, T as TableColumn } from '../table-DtmPxL6W.js';
2
+ import '../locale-CaxkEHEG.js';
3
3
  import '../datepicker-Digy7Stt.js';
4
+
5
+ /**
6
+ * Table export utilities (CSV / Excel-compatible HTML worksheet)
7
+ */
8
+
9
+ /**
10
+ * Export table data to CSV string
11
+ */
12
+ declare function exportTableToCsv<T>(columns: TableColumn<T>[], data: T[], _filename?: string): string;
13
+ declare function exportTableToExcel<T>(columns: TableColumn<T>[], data: T[]): string;
14
+ /**
15
+ * Trigger a CSV file download in the browser
16
+ */
17
+ 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;
21
+ /**
22
+ * Get export button classes
23
+ */
24
+ 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
+
26
+ export { downloadCsv, downloadExcel, downloadTableExport, exportTableData, exportTableToCsv, exportTableToExcel, tableExportButtonClasses };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expcat/tigercat-core",
3
- "version": "2.0.0-preview.5",
3
+ "version": "2.0.0-rc.1",
4
4
  "type": "module",
5
5
  "description": "Core utilities for Tigercat UI library",
6
6
  "license": "MIT",
@@ -169,6 +169,10 @@
169
169
  "./utils/table-export": {
170
170
  "types": "./dist/utils/table-export.d.ts",
171
171
  "import": "./dist/utils/table-export.js"
172
+ },
173
+ "./utils/data-export": {
174
+ "types": "./dist/utils/data-export.d.ts",
175
+ "import": "./dist/utils/data-export.js"
172
176
  }
173
177
  },
174
178
  "files": [