@undevy-org/tablewright 0.8.0 → 0.8.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.
|
@@ -8,17 +8,39 @@ function resolveTableExportButtonSize(size) {
|
|
|
8
8
|
function resolveTableExportButtonVariant(variant) {
|
|
9
9
|
return variant ?? "secondary";
|
|
10
10
|
}
|
|
11
|
+
const PLAIN_DECIMAL_CORE = /^(\d+(\.\d+)?|\.\d+)([eE][+-]?\d+)?$/;
|
|
12
|
+
const FORMULA_TRIGGER_PREFIX = /^[=+\-@\t\r]/;
|
|
11
13
|
function escapeCsvField(value) {
|
|
12
14
|
if (/[",\r\n]/.test(value)) {
|
|
13
15
|
return `"${value.replace(/"/g, '""')}"`;
|
|
14
16
|
}
|
|
15
17
|
return value;
|
|
16
18
|
}
|
|
19
|
+
function isSignedPlainDecimal(value) {
|
|
20
|
+
const first = value[0];
|
|
21
|
+
if (first !== "+" && first !== "-") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return PLAIN_DECIMAL_CORE.test(value.slice(1));
|
|
25
|
+
}
|
|
26
|
+
function shouldPrefixFormulaEscape(value) {
|
|
27
|
+
if (!FORMULA_TRIGGER_PREFIX.test(value)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (isSignedPlainDecimal(value)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
function formatCsvField(value, escapeFormulas) {
|
|
36
|
+
const prepared = escapeFormulas && shouldPrefixFormulaEscape(value) ? `'${value}` : value;
|
|
37
|
+
return escapeCsvField(prepared);
|
|
38
|
+
}
|
|
17
39
|
function exportTableToCsv(options) {
|
|
18
|
-
const { columns, rows, getCellText } = options;
|
|
19
|
-
const headerLine = columns.map((column) =>
|
|
40
|
+
const { columns, rows, getCellText, escapeFormulas = true } = options;
|
|
41
|
+
const headerLine = columns.map((column) => formatCsvField(column.header, escapeFormulas)).join(",");
|
|
20
42
|
const bodyLines = rows.map(
|
|
21
|
-
(row) => columns.map((column) =>
|
|
43
|
+
(row) => columns.map((column) => formatCsvField(getCellText(row, column.id), escapeFormulas)).join(",")
|
|
22
44
|
);
|
|
23
45
|
return [headerLine, ...bodyLines].join("\r\n");
|
|
24
46
|
}
|
package/dist/tablewright.cjs
CHANGED
|
@@ -1824,17 +1824,39 @@ function resolveTableExportButtonSize(size) {
|
|
|
1824
1824
|
function resolveTableExportButtonVariant(variant) {
|
|
1825
1825
|
return variant ?? "secondary";
|
|
1826
1826
|
}
|
|
1827
|
+
const PLAIN_DECIMAL_CORE = /^(\d+(\.\d+)?|\.\d+)([eE][+-]?\d+)?$/;
|
|
1828
|
+
const FORMULA_TRIGGER_PREFIX = /^[=+\-@\t\r]/;
|
|
1827
1829
|
function escapeCsvField(value) {
|
|
1828
1830
|
if (/[",\r\n]/.test(value)) {
|
|
1829
1831
|
return `"${value.replace(/"/g, '""')}"`;
|
|
1830
1832
|
}
|
|
1831
1833
|
return value;
|
|
1832
1834
|
}
|
|
1835
|
+
function isSignedPlainDecimal(value) {
|
|
1836
|
+
const first = value[0];
|
|
1837
|
+
if (first !== "+" && first !== "-") {
|
|
1838
|
+
return false;
|
|
1839
|
+
}
|
|
1840
|
+
return PLAIN_DECIMAL_CORE.test(value.slice(1));
|
|
1841
|
+
}
|
|
1842
|
+
function shouldPrefixFormulaEscape(value) {
|
|
1843
|
+
if (!FORMULA_TRIGGER_PREFIX.test(value)) {
|
|
1844
|
+
return false;
|
|
1845
|
+
}
|
|
1846
|
+
if (isSignedPlainDecimal(value)) {
|
|
1847
|
+
return false;
|
|
1848
|
+
}
|
|
1849
|
+
return true;
|
|
1850
|
+
}
|
|
1851
|
+
function formatCsvField(value, escapeFormulas) {
|
|
1852
|
+
const prepared = escapeFormulas && shouldPrefixFormulaEscape(value) ? `'${value}` : value;
|
|
1853
|
+
return escapeCsvField(prepared);
|
|
1854
|
+
}
|
|
1833
1855
|
function exportTableToCsv(options) {
|
|
1834
|
-
const { columns, rows, getCellText } = options;
|
|
1835
|
-
const headerLine = columns.map((column) =>
|
|
1856
|
+
const { columns, rows, getCellText, escapeFormulas = true } = options;
|
|
1857
|
+
const headerLine = columns.map((column) => formatCsvField(column.header, escapeFormulas)).join(",");
|
|
1836
1858
|
const bodyLines = rows.map(
|
|
1837
|
-
(row) => columns.map((column) =>
|
|
1859
|
+
(row) => columns.map((column) => formatCsvField(getCellText(row, column.id), escapeFormulas)).join(",")
|
|
1838
1860
|
);
|
|
1839
1861
|
return [headerLine, ...bodyLines].join("\r\n");
|
|
1840
1862
|
}
|
|
@@ -6,6 +6,11 @@ export type ExportTableToCsvOptions<TRow> = {
|
|
|
6
6
|
}[];
|
|
7
7
|
rows: TRow[];
|
|
8
8
|
getCellText: (row: TRow, columnId: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Prefix formula-triggering cell text with `'` so spreadsheet apps do not evaluate it.
|
|
11
|
+
* Plain decimal numbers (`-5`, `+3.2`) are left unchanged. @default true
|
|
12
|
+
*/
|
|
13
|
+
escapeFormulas?: boolean;
|
|
9
14
|
};
|
|
10
15
|
export declare const DEFAULT_CSV_EXPORT_LABEL = "Export CSV";
|
|
11
16
|
export declare function resolveCsvExportLabel(labels?: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@undevy-org/tablewright",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "React data-table and application-shell components: filters, drawers, row controls, sortable and resizable columns, built on Radix UI and TanStack Table.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|