@gradio/dataframe 0.24.4 → 0.24.6
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/CHANGELOG.md +25 -0
- package/Dataframe.test.ts +1202 -122
- package/Index.svelte +1 -0
- package/dist/Index.svelte +1 -0
- package/dist/shared/EmptyRowButton.svelte +0 -1
- package/dist/shared/Table.svelte +258 -51
- package/dist/shared/Table.svelte.d.ts +1 -0
- package/dist/shared/Toolbar.svelte +2 -3
- package/dist/shared/Toolbar.svelte.d.ts +1 -1
- package/dist/shared/types.d.ts +0 -4
- package/dist/shared/types.js +0 -1
- package/dist/shared/utils/selection_utils.d.ts +1 -1
- package/dist/shared/utils/selection_utils.js +6 -3
- package/dist/shared/utils/table_utils.d.ts +6 -5
- package/dist/shared/utils/table_utils.js +45 -40
- package/dist/shared/utils/utils.d.ts +0 -4
- package/dist/standalone/default_i18n.js +7 -0
- package/dist/types.d.ts +1 -0
- package/package.json +7 -7
- package/shared/EmptyRowButton.svelte +0 -1
- package/shared/Table.svelte +258 -51
- package/shared/Toolbar.svelte +2 -3
- package/shared/types.ts +0 -6
- package/shared/utils/selection_utils.ts +8 -3
- package/shared/utils/table_utils.ts +49 -52
- package/shared/utils/utils.ts +0 -1
- package/standalone/default_i18n.ts +12 -0
- package/test/selection_utils.test.ts +40 -7
- package/test/table_utils.test.ts +92 -28
- package/types.ts +1 -0
|
@@ -8,11 +8,12 @@ export function make_header_id(col) {
|
|
|
8
8
|
export async function copy_table_data(data, selected_cells) {
|
|
9
9
|
if (!data || !data.length)
|
|
10
10
|
return;
|
|
11
|
-
const
|
|
12
|
-
data.flatMap((row, r) => row.map((_, c) => [r, c]));
|
|
13
|
-
const csv = cells_to_copy.reduce((acc, [row, col]) => {
|
|
11
|
+
const csv = selected_cells.reduce((acc, [row, col]) => {
|
|
14
12
|
acc[row] = acc[row] || {};
|
|
15
|
-
|
|
13
|
+
// only the headers are padded out to the column count on the way in, so
|
|
14
|
+
// a selection can name a cell a short row does not have
|
|
15
|
+
const cell = data[row]?.[col];
|
|
16
|
+
const value = cell ? String(cell.value) : "";
|
|
16
17
|
acc[row][col] =
|
|
17
18
|
value.includes(",") || value.includes('"') || value.includes("\n")
|
|
18
19
|
? `"${value.replace(/"/g, '""')}"`
|
|
@@ -22,7 +23,9 @@ export async function copy_table_data(data, selected_cells) {
|
|
|
22
23
|
const rows = Object.keys(csv).sort((a, b) => +a - +b);
|
|
23
24
|
if (!rows.length)
|
|
24
25
|
return;
|
|
25
|
-
|
|
26
|
+
// every column any selected row contributes: taking them from the first row
|
|
27
|
+
// alone drops the rest of a selection that is not rectangular there
|
|
28
|
+
const cols = Array.from(new Set(rows.flatMap((r) => Object.keys(csv[r])))).sort((a, b) => +a - +b);
|
|
26
29
|
const text = rows
|
|
27
30
|
.map((r) => cols.map((c) => csv[r][c] || "").join(","))
|
|
28
31
|
.join("\n");
|
|
@@ -33,41 +36,43 @@ export async function copy_table_data(data, selected_cells) {
|
|
|
33
36
|
throw new Error("Failed to copy to clipboard: " + err.message);
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
|
-
export function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
export async function parse_table_file(file) {
|
|
40
|
+
const text = await file.text();
|
|
41
|
+
if (!text.trim())
|
|
42
|
+
return { headers: [], values: [] };
|
|
43
|
+
// the drop zone only accepts .csv and .tsv, so the extension goes first and
|
|
44
|
+
// wins any tie, but a mislabeled file is still read by its content: a
|
|
45
|
+
// separator only takes the file if it splits every line the same way, which
|
|
46
|
+
// is what tells a real separator from one that sits in a header name. the
|
|
47
|
+
// split is d3's rather than a raw count, so a separator inside a quoted
|
|
48
|
+
// field does not throw the detection off.
|
|
49
|
+
const by_extension = file.name.toLowerCase().endsWith(".tsv") ? "\t" : ",";
|
|
50
|
+
const candidates = by_extension === "\t" ? ["\t", ","] : [",", "\t"];
|
|
51
|
+
let consistent;
|
|
52
|
+
let ragged;
|
|
53
|
+
let unsplit;
|
|
54
|
+
for (const delimiter of candidates) {
|
|
55
|
+
// a blank line parses to a single empty field, which both the width
|
|
56
|
+
// checks below and the caller's ragged check would read as a short row
|
|
57
|
+
const parsed = dsvFormat(delimiter)
|
|
58
|
+
.parseRows(text)
|
|
59
|
+
.filter((row) => row.length > 1 || row[0] !== "");
|
|
60
|
+
const width = parsed[0]?.length ?? 0;
|
|
61
|
+
// the extension is first in `candidates`, so this keeps its parse for the
|
|
62
|
+
// single-column case rather than running it again at the end
|
|
63
|
+
unsplit ??= parsed;
|
|
64
|
+
if (width < 2)
|
|
65
|
+
continue;
|
|
66
|
+
if (parsed.every((row) => row.length === width)) {
|
|
67
|
+
consistent = parsed;
|
|
68
|
+
break;
|
|
48
69
|
}
|
|
70
|
+
// a separator that splits the header but leaves the rows uneven is
|
|
71
|
+
// usually the one that just happens to appear in a header name. keep it
|
|
72
|
+
// only in case the other does not split at all, where a ragged table is
|
|
73
|
+
// still better to report on than an unsplit one
|
|
74
|
+
ragged ??= parsed;
|
|
49
75
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const byte_str = atob(data_uri.split(",")[1]);
|
|
53
|
-
const mime_str = data_uri.split(",")[0].split(":")[1].split(";")[0];
|
|
54
|
-
const ab = new ArrayBuffer(byte_str.length);
|
|
55
|
-
const ia = new Uint8Array(ab);
|
|
56
|
-
for (let i = 0; i < byte_str.length; i++) {
|
|
57
|
-
ia[i] = byte_str.charCodeAt(i);
|
|
58
|
-
}
|
|
59
|
-
return new Blob([ab], { type: mime_str });
|
|
60
|
-
}
|
|
61
|
-
export function handle_file_upload(data_uri, update_headers, update_values) {
|
|
62
|
-
const blob = data_uri_to_blob(data_uri);
|
|
63
|
-
const reader = new FileReader();
|
|
64
|
-
reader.addEventListener("loadend", (e) => {
|
|
65
|
-
if (!e?.target?.result || typeof e.target.result !== "string")
|
|
66
|
-
return;
|
|
67
|
-
const [delimiter] = guess_delimiter(e.target.result, [",", "\t"]);
|
|
68
|
-
const [head, ...rest] = dsvFormat(delimiter).parseRows(e.target.result);
|
|
69
|
-
update_headers(head);
|
|
70
|
-
update_values(rest);
|
|
71
|
-
});
|
|
72
|
-
reader.readAsText(blob);
|
|
76
|
+
const [head = [], ...rest] = consistent ?? ragged ?? unsplit ?? [];
|
|
77
|
+
return { headers: head.map((h) => h ?? ""), values: rest };
|
|
73
78
|
}
|
|
@@ -5,10 +5,6 @@ export type Datatype = "str" | "number" | "bool" | "date" | "markdown" | "html"
|
|
|
5
5
|
export type Metadata = {
|
|
6
6
|
[key: string]: string[][] | null;
|
|
7
7
|
} | null;
|
|
8
|
-
export type HeadersWithIDs = {
|
|
9
|
-
value: string;
|
|
10
|
-
id: string;
|
|
11
|
-
}[];
|
|
12
8
|
export type DataframeValue = {
|
|
13
9
|
data: Data;
|
|
14
10
|
headers: Headers;
|
|
@@ -5,6 +5,13 @@ export const default_i18n = {
|
|
|
5
5
|
"dataframe.add_column_left": "Add column left",
|
|
6
6
|
"dataframe.add_column_right": "Add column right",
|
|
7
7
|
"dataframe.delete_column": "Delete column",
|
|
8
|
+
"dataframe.drop_to_upload": "Drop CSV or TSV files here to import data into dataframe",
|
|
9
|
+
"dataframe.import_empty_file": "The dropped file is empty.",
|
|
10
|
+
"dataframe.import_no_column_names": "The dropped file has no column names.",
|
|
11
|
+
"dataframe.import_ragged_row": "Line {line} of the file has {fields} fields, the header has {columns}.",
|
|
12
|
+
"dataframe.import_static_columns": "Cannot import into a table with read-only columns.",
|
|
13
|
+
"dataframe.import_fixed_columns": "This table takes exactly {expected} columns, the file has {actual}.",
|
|
14
|
+
"dataframe.import_fixed_rows": "This table takes exactly {expected} rows, the file has {actual}.",
|
|
8
15
|
"dataframe.sort_asc": "Sort ascending",
|
|
9
16
|
"dataframe.sort_desc": "Sort descending",
|
|
10
17
|
"dataframe.sort_ascending": "Sort ascending",
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/dataframe",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.6",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"@tanstack/table-core": "^8.21.3",
|
|
17
17
|
"@tanstack/virtual-core": "^3.13.6",
|
|
18
18
|
"@gradio/atoms": "^0.26.2",
|
|
19
|
+
"@gradio/button": "^0.8.3",
|
|
19
20
|
"@gradio/checkbox": "^0.8.3",
|
|
20
|
-
"@gradio/
|
|
21
|
+
"@gradio/client": "^2.7.1",
|
|
21
22
|
"@gradio/icons": "^0.16.0",
|
|
22
|
-
"@gradio/client": "^2.6.0",
|
|
23
23
|
"@gradio/markdown-code": "^0.10.1",
|
|
24
|
-
"@gradio/
|
|
25
|
-
"@gradio/
|
|
26
|
-
"@gradio/utils": "^0.14.
|
|
24
|
+
"@gradio/statustracker": "^0.15.4",
|
|
25
|
+
"@gradio/upload": "^0.19.0",
|
|
26
|
+
"@gradio/utils": "^0.14.2"
|
|
27
27
|
},
|
|
28
28
|
"exports": {
|
|
29
29
|
".": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"svelte": "^5.48.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@gradio/preview": "^0.17.
|
|
45
|
+
"@gradio/preview": "^0.17.1"
|
|
46
46
|
},
|
|
47
47
|
"repository": {
|
|
48
48
|
"type": "git",
|