@gradio/dataframe 0.14.0 → 0.16.0
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 +45 -0
- package/Dataframe.stories.svelte +283 -7
- package/Index.svelte +22 -3
- package/dist/Index.svelte +18 -4
- package/dist/Index.svelte.d.ts +16 -0
- package/dist/shared/EditableCell.svelte +49 -7
- package/dist/shared/EditableCell.svelte.d.ts +1 -1
- package/dist/shared/Table.svelte +692 -411
- package/dist/shared/Table.svelte.d.ts +4 -0
- package/dist/shared/Toolbar.svelte +122 -30
- package/dist/shared/Toolbar.svelte.d.ts +4 -0
- package/dist/shared/VirtualTable.svelte +70 -26
- package/dist/shared/VirtualTable.svelte.d.ts +1 -0
- package/dist/shared/icons/FilterIcon.svelte +11 -0
- package/dist/shared/icons/FilterIcon.svelte.d.ts +16 -0
- package/dist/shared/icons/SortIcon.svelte +90 -0
- package/dist/shared/icons/SortIcon.svelte.d.ts +20 -0
- package/dist/shared/selection_utils.d.ts +30 -0
- package/dist/shared/selection_utils.js +139 -0
- package/dist/shared/types.d.ts +18 -0
- package/dist/shared/types.js +2 -0
- package/dist/shared/utils/menu_utils.d.ts +42 -0
- package/dist/shared/utils/menu_utils.js +58 -0
- package/dist/shared/utils/sort_utils.d.ts +7 -0
- package/dist/shared/utils/sort_utils.js +39 -0
- package/dist/shared/utils/table_utils.d.ts +12 -0
- package/dist/shared/utils/table_utils.js +148 -0
- package/package.json +8 -8
- package/shared/EditableCell.svelte +55 -7
- package/shared/Table.svelte +762 -478
- package/shared/Toolbar.svelte +125 -30
- package/shared/VirtualTable.svelte +73 -26
- package/shared/icons/FilterIcon.svelte +12 -0
- package/shared/icons/SortIcon.svelte +95 -0
- package/shared/selection_utils.ts +230 -0
- package/shared/types.ts +29 -0
- package/shared/utils/menu_utils.ts +115 -0
- package/shared/utils/sort_utils.test.ts +71 -0
- package/shared/utils/sort_utils.ts +55 -0
- package/shared/utils/table_utils.test.ts +114 -0
- package/shared/utils/table_utils.ts +206 -0
- package/dist/shared/table_utils.d.ts +0 -6
- package/dist/shared/table_utils.js +0 -27
- package/shared/table_utils.ts +0 -38
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare function toggle_header_menu(event: MouseEvent, col: number, active_header_menu: {
|
|
2
|
+
col: number;
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
} | null, set_active_header_menu: (menu: {
|
|
6
|
+
col: number;
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
} | null) => void): void;
|
|
10
|
+
export declare function toggle_cell_menu(event: MouseEvent, row: number, col: number, active_cell_menu: {
|
|
11
|
+
row: number;
|
|
12
|
+
col: number;
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
} | null, set_active_cell_menu: (menu: {
|
|
16
|
+
row: number;
|
|
17
|
+
col: number;
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
} | null) => void): void;
|
|
21
|
+
export declare function add_row_at(index: number, position: "above" | "below", add_row: (index?: number) => void, clear_menus: () => void): void;
|
|
22
|
+
export declare function add_col_at(index: number, position: "left" | "right", add_col: (index?: number) => void, clear_menus: () => void): void;
|
|
23
|
+
export declare function delete_row_at(index: number, delete_row: (index: number) => void, clear_menus: () => void): void;
|
|
24
|
+
export declare function delete_col_at(index: number, delete_col: (index: number) => void, clear_menus: () => void): void;
|
|
25
|
+
export declare function toggle_header_button(col: number, active_button: {
|
|
26
|
+
type: "header" | "cell";
|
|
27
|
+
row?: number;
|
|
28
|
+
col: number;
|
|
29
|
+
} | null, set_active_button: (button: {
|
|
30
|
+
type: "header" | "cell";
|
|
31
|
+
row?: number;
|
|
32
|
+
col: number;
|
|
33
|
+
} | null) => void): void;
|
|
34
|
+
export declare function toggle_cell_button(row: number, col: number, active_button: {
|
|
35
|
+
type: "header" | "cell";
|
|
36
|
+
row?: number;
|
|
37
|
+
col: number;
|
|
38
|
+
} | null, set_active_button: (button: {
|
|
39
|
+
type: "header" | "cell";
|
|
40
|
+
row?: number;
|
|
41
|
+
col: number;
|
|
42
|
+
} | null) => void): void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export function toggle_header_menu(event, col, active_header_menu, set_active_header_menu) {
|
|
2
|
+
event.stopPropagation();
|
|
3
|
+
if (active_header_menu && active_header_menu.col === col) {
|
|
4
|
+
set_active_header_menu(null);
|
|
5
|
+
}
|
|
6
|
+
else {
|
|
7
|
+
const header = event.target.closest("th");
|
|
8
|
+
if (header) {
|
|
9
|
+
const rect = header.getBoundingClientRect();
|
|
10
|
+
set_active_header_menu({ col, x: rect.right, y: rect.bottom });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function toggle_cell_menu(event, row, col, active_cell_menu, set_active_cell_menu) {
|
|
15
|
+
event.stopPropagation();
|
|
16
|
+
if (active_cell_menu &&
|
|
17
|
+
active_cell_menu.row === row &&
|
|
18
|
+
active_cell_menu.col === col) {
|
|
19
|
+
set_active_cell_menu(null);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const cell = event.target.closest("td");
|
|
23
|
+
if (cell) {
|
|
24
|
+
const rect = cell.getBoundingClientRect();
|
|
25
|
+
set_active_cell_menu({ row, col, x: rect.right, y: rect.bottom });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function add_row_at(index, position, add_row, clear_menus) {
|
|
30
|
+
const row_index = position === "above" ? index : index + 1;
|
|
31
|
+
add_row(row_index);
|
|
32
|
+
clear_menus();
|
|
33
|
+
}
|
|
34
|
+
export function add_col_at(index, position, add_col, clear_menus) {
|
|
35
|
+
const col_index = position === "left" ? index : index + 1;
|
|
36
|
+
add_col(col_index);
|
|
37
|
+
clear_menus();
|
|
38
|
+
}
|
|
39
|
+
export function delete_row_at(index, delete_row, clear_menus) {
|
|
40
|
+
delete_row(index);
|
|
41
|
+
clear_menus();
|
|
42
|
+
}
|
|
43
|
+
export function delete_col_at(index, delete_col, clear_menus) {
|
|
44
|
+
delete_col(index);
|
|
45
|
+
clear_menus();
|
|
46
|
+
}
|
|
47
|
+
export function toggle_header_button(col, active_button, set_active_button) {
|
|
48
|
+
set_active_button(active_button?.type === "header" && active_button.col === col
|
|
49
|
+
? null
|
|
50
|
+
: { type: "header", col });
|
|
51
|
+
}
|
|
52
|
+
export function toggle_cell_button(row, col, active_button, set_active_button) {
|
|
53
|
+
set_active_button(active_button?.type === "cell" &&
|
|
54
|
+
active_button.row === row &&
|
|
55
|
+
active_button.col === col
|
|
56
|
+
? null
|
|
57
|
+
: { type: "cell", row, col });
|
|
58
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Headers } from "../types";
|
|
2
|
+
export type SortDirection = "asc" | "des";
|
|
3
|
+
export declare function get_sort_status(name: string, sort_by: number | undefined, direction: SortDirection | undefined, headers: Headers): "none" | "ascending" | "descending";
|
|
4
|
+
export declare function sort_data(data: {
|
|
5
|
+
id: string;
|
|
6
|
+
value: string | number;
|
|
7
|
+
}[][], sort_by: number | undefined, sort_direction: SortDirection | undefined): number[];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function get_sort_status(name, sort_by, direction, headers) {
|
|
2
|
+
if (typeof sort_by !== "number")
|
|
3
|
+
return "none";
|
|
4
|
+
if (sort_by < 0 || sort_by >= headers.length)
|
|
5
|
+
return "none";
|
|
6
|
+
if (headers[sort_by] === name) {
|
|
7
|
+
if (direction === "asc")
|
|
8
|
+
return "ascending";
|
|
9
|
+
if (direction === "des")
|
|
10
|
+
return "descending";
|
|
11
|
+
}
|
|
12
|
+
return "none";
|
|
13
|
+
}
|
|
14
|
+
export function sort_data(data, sort_by, sort_direction) {
|
|
15
|
+
if (!data || !data.length || !data[0]) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
if (typeof sort_by === "number" &&
|
|
19
|
+
sort_direction &&
|
|
20
|
+
sort_by >= 0 &&
|
|
21
|
+
sort_by < data[0].length) {
|
|
22
|
+
const row_indices = [...Array(data.length)].map((_, i) => i);
|
|
23
|
+
row_indices.sort((row_a_idx, row_b_idx) => {
|
|
24
|
+
const row_a = data[row_a_idx];
|
|
25
|
+
const row_b = data[row_b_idx];
|
|
26
|
+
if (!row_a ||
|
|
27
|
+
!row_b ||
|
|
28
|
+
sort_by >= row_a.length ||
|
|
29
|
+
sort_by >= row_b.length)
|
|
30
|
+
return 0;
|
|
31
|
+
const val_a = row_a[sort_by].value;
|
|
32
|
+
const val_b = row_b[sort_by].value;
|
|
33
|
+
const comparison = val_a < val_b ? -1 : val_a > val_b ? 1 : 0;
|
|
34
|
+
return sort_direction === "asc" ? comparison : -comparison;
|
|
35
|
+
});
|
|
36
|
+
return row_indices;
|
|
37
|
+
}
|
|
38
|
+
return [...Array(data.length)].map((_, i) => i);
|
|
39
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Headers, HeadersWithIDs, TableCell, TableData, CountConfig, ElementRefs, DataBinding } from "../types";
|
|
2
|
+
import type { SortDirection } from "./sort_utils";
|
|
3
|
+
export declare function make_cell_id(row: number, col: number): string;
|
|
4
|
+
export declare function make_header_id(col: number): string;
|
|
5
|
+
export declare function process_data(input_values: (string | number)[][], row_count: CountConfig, col_count: CountConfig, headers: Headers, show_row_numbers: boolean, element_refs: ElementRefs, data_binding: DataBinding): TableData;
|
|
6
|
+
export declare function make_headers(input_headers: Headers, show_row_numbers: boolean, col_count: CountConfig, element_refs: ElementRefs): HeadersWithIDs[];
|
|
7
|
+
export declare function get_max(data: TableData): TableCell[];
|
|
8
|
+
export declare function sort_table_data(data: TableData, display_value: string[][] | null, styling: string[][] | null, col: number, dir: SortDirection): void;
|
|
9
|
+
export declare function copy_table_data(data: TableData, selected_cells: [number, number][]): Promise<void>;
|
|
10
|
+
export declare function guess_delimiter(text: string, possibleDelimiters: string[]): string[];
|
|
11
|
+
export declare function data_uri_to_blob(data_uri: string): Blob;
|
|
12
|
+
export declare function handle_file_upload(data_uri: string, update_headers: (headers: Headers) => HeadersWithIDs[], update_values: (values: (string | number)[][]) => void): void;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { sort_data } from "./sort_utils";
|
|
2
|
+
import { dsvFormat } from "d3-dsv";
|
|
3
|
+
export function make_cell_id(row, col) {
|
|
4
|
+
return `cell-${row}-${col}`;
|
|
5
|
+
}
|
|
6
|
+
export function make_header_id(col) {
|
|
7
|
+
return `header-${col}`;
|
|
8
|
+
}
|
|
9
|
+
export function process_data(input_values, row_count, col_count, headers, show_row_numbers, element_refs, data_binding) {
|
|
10
|
+
const data_row_length = input_values.length;
|
|
11
|
+
return Array(row_count[1] === "fixed" ? row_count[0] : data_row_length)
|
|
12
|
+
.fill(0)
|
|
13
|
+
.map((_, row) => {
|
|
14
|
+
return Array(col_count[1] === "fixed"
|
|
15
|
+
? col_count[0]
|
|
16
|
+
: data_row_length > 0
|
|
17
|
+
? input_values[0].length
|
|
18
|
+
: headers.length)
|
|
19
|
+
.fill(0)
|
|
20
|
+
.map((_, col) => {
|
|
21
|
+
const cell_id = make_cell_id(row, col);
|
|
22
|
+
element_refs[cell_id] = element_refs[cell_id] || {
|
|
23
|
+
input: null,
|
|
24
|
+
cell: null
|
|
25
|
+
};
|
|
26
|
+
const cell_obj = {
|
|
27
|
+
value: input_values?.[row]?.[col] ?? "",
|
|
28
|
+
id: cell_id
|
|
29
|
+
};
|
|
30
|
+
data_binding[cell_id] = cell_obj;
|
|
31
|
+
return cell_obj;
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function make_headers(input_headers, show_row_numbers, col_count, element_refs) {
|
|
36
|
+
let header_list = input_headers || [];
|
|
37
|
+
if (show_row_numbers) {
|
|
38
|
+
header_list = ["", ...header_list];
|
|
39
|
+
}
|
|
40
|
+
if (col_count[1] === "fixed" && header_list.length < col_count[0]) {
|
|
41
|
+
const fill_headers = Array(col_count[0] - header_list.length)
|
|
42
|
+
.fill("")
|
|
43
|
+
.map((_, i) => `${i + header_list.length}`);
|
|
44
|
+
header_list = header_list.concat(fill_headers);
|
|
45
|
+
}
|
|
46
|
+
if (!header_list || header_list.length === 0) {
|
|
47
|
+
return Array(col_count[0])
|
|
48
|
+
.fill(0)
|
|
49
|
+
.map((_, col) => {
|
|
50
|
+
const header_id = make_header_id(col);
|
|
51
|
+
element_refs[header_id] = { cell: null, input: null };
|
|
52
|
+
return { id: header_id, value: JSON.stringify(col + 1) };
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return header_list.map((header, col) => {
|
|
56
|
+
const header_id = make_header_id(col);
|
|
57
|
+
element_refs[header_id] = { cell: null, input: null };
|
|
58
|
+
return { id: header_id, value: header ?? "" };
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
export function get_max(data) {
|
|
62
|
+
if (!data || !data.length)
|
|
63
|
+
return [];
|
|
64
|
+
let max = data[0].slice();
|
|
65
|
+
for (let i = 0; i < data.length; i++) {
|
|
66
|
+
for (let j = 0; j < data[i].length; j++) {
|
|
67
|
+
if (`${max[j].value}`.length < `${data[i][j].value}`.length) {
|
|
68
|
+
max[j] = data[i][j];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return max;
|
|
73
|
+
}
|
|
74
|
+
export function sort_table_data(data, display_value, styling, col, dir) {
|
|
75
|
+
const indices = sort_data(data, col, dir);
|
|
76
|
+
const new_data = indices.map((i) => data[i]);
|
|
77
|
+
data.splice(0, data.length, ...new_data);
|
|
78
|
+
if (display_value) {
|
|
79
|
+
const new_display = indices.map((i) => display_value[i]);
|
|
80
|
+
display_value.splice(0, display_value.length, ...new_display);
|
|
81
|
+
}
|
|
82
|
+
if (styling) {
|
|
83
|
+
const new_styling = indices.map((i) => styling[i]);
|
|
84
|
+
styling.splice(0, styling.length, ...new_styling);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export async function copy_table_data(data, selected_cells) {
|
|
88
|
+
const csv = selected_cells.reduce((acc, [row, col]) => {
|
|
89
|
+
acc[row] = acc[row] || {};
|
|
90
|
+
const value = String(data[row][col].value);
|
|
91
|
+
acc[row][col] =
|
|
92
|
+
value.includes(",") || value.includes('"') || value.includes("\n")
|
|
93
|
+
? `"${value.replace(/"/g, '""')}"`
|
|
94
|
+
: value;
|
|
95
|
+
return acc;
|
|
96
|
+
}, {});
|
|
97
|
+
const rows = Object.keys(csv).sort((a, b) => +a - +b);
|
|
98
|
+
const cols = Object.keys(csv[rows[0]]).sort((a, b) => +a - +b);
|
|
99
|
+
const text = rows
|
|
100
|
+
.map((r) => cols.map((c) => csv[r][c] || "").join(","))
|
|
101
|
+
.join("\n");
|
|
102
|
+
try {
|
|
103
|
+
await navigator.clipboard.writeText(text);
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
console.error("Copy failed:", err);
|
|
107
|
+
throw new Error("Failed to copy to clipboard: " + err.message);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// File Import/Export
|
|
111
|
+
export function guess_delimiter(text, possibleDelimiters) {
|
|
112
|
+
return possibleDelimiters.filter(weedOut);
|
|
113
|
+
function weedOut(delimiter) {
|
|
114
|
+
var cache = -1;
|
|
115
|
+
return text.split("\n").every(checkLength);
|
|
116
|
+
function checkLength(line) {
|
|
117
|
+
if (!line)
|
|
118
|
+
return true;
|
|
119
|
+
var length = line.split(delimiter).length;
|
|
120
|
+
if (cache < 0)
|
|
121
|
+
cache = length;
|
|
122
|
+
return cache === length && length > 1;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
export function data_uri_to_blob(data_uri) {
|
|
127
|
+
const byte_str = atob(data_uri.split(",")[1]);
|
|
128
|
+
const mime_str = data_uri.split(",")[0].split(":")[1].split(";")[0];
|
|
129
|
+
const ab = new ArrayBuffer(byte_str.length);
|
|
130
|
+
const ia = new Uint8Array(ab);
|
|
131
|
+
for (let i = 0; i < byte_str.length; i++) {
|
|
132
|
+
ia[i] = byte_str.charCodeAt(i);
|
|
133
|
+
}
|
|
134
|
+
return new Blob([ab], { type: mime_str });
|
|
135
|
+
}
|
|
136
|
+
export function handle_file_upload(data_uri, update_headers, update_values) {
|
|
137
|
+
const blob = data_uri_to_blob(data_uri);
|
|
138
|
+
const reader = new FileReader();
|
|
139
|
+
reader.addEventListener("loadend", (e) => {
|
|
140
|
+
if (!e?.target?.result || typeof e.target.result !== "string")
|
|
141
|
+
return;
|
|
142
|
+
const [delimiter] = guess_delimiter(e.target.result, [",", "\t"]);
|
|
143
|
+
const [head, ...rest] = dsvFormat(delimiter).parseRows(e.target.result);
|
|
144
|
+
update_headers(head);
|
|
145
|
+
update_values(rest);
|
|
146
|
+
});
|
|
147
|
+
reader.readAsText(blob);
|
|
148
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/dataframe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
"dompurify": "^3.0.3",
|
|
18
18
|
"katex": "^0.16.7",
|
|
19
19
|
"marked": "^12.0.0",
|
|
20
|
-
"@gradio/atoms": "^0.13.
|
|
21
|
-
"@gradio/button": "^0.4.
|
|
22
|
-
"@gradio/
|
|
20
|
+
"@gradio/atoms": "^0.13.2",
|
|
21
|
+
"@gradio/button": "^0.4.6",
|
|
22
|
+
"@gradio/markdown-code": "^0.4.0",
|
|
23
|
+
"@gradio/client": "^1.12.0",
|
|
24
|
+
"@gradio/statustracker": "^0.10.3",
|
|
23
25
|
"@gradio/icons": "^0.10.0",
|
|
24
|
-
"@gradio/
|
|
25
|
-
"@gradio/
|
|
26
|
-
"@gradio/utils": "^0.10.0",
|
|
27
|
-
"@gradio/upload": "^0.14.8"
|
|
26
|
+
"@gradio/upload": "^0.15.1",
|
|
27
|
+
"@gradio/utils": "^0.10.1"
|
|
28
28
|
},
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
@@ -23,12 +23,27 @@
|
|
|
23
23
|
export let line_breaks = true;
|
|
24
24
|
export let editable = true;
|
|
25
25
|
export let root: string;
|
|
26
|
+
export let max_chars: number | null = null;
|
|
26
27
|
|
|
27
28
|
const dispatch = createEventDispatcher();
|
|
29
|
+
let is_expanded = false;
|
|
28
30
|
|
|
29
31
|
export let el: HTMLInputElement | null;
|
|
30
32
|
$: _value = value;
|
|
31
33
|
|
|
34
|
+
function truncate_text(
|
|
35
|
+
text: string | number,
|
|
36
|
+
max_length: number | null = null
|
|
37
|
+
): string {
|
|
38
|
+
const str = String(text);
|
|
39
|
+
if (!max_length || str.length <= max_length) return str;
|
|
40
|
+
return str.slice(0, max_length) + "...";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
$: display_text = is_expanded
|
|
44
|
+
? value
|
|
45
|
+
: truncate_text(display_value || value, max_chars);
|
|
46
|
+
|
|
32
47
|
function use_focus(node: HTMLInputElement): any {
|
|
33
48
|
if (clear_on_focus) {
|
|
34
49
|
_value = "";
|
|
@@ -52,11 +67,21 @@
|
|
|
52
67
|
|
|
53
68
|
function handle_keydown(event: KeyboardEvent): void {
|
|
54
69
|
if (event.key === "Enter") {
|
|
55
|
-
|
|
56
|
-
|
|
70
|
+
if (edit) {
|
|
71
|
+
value = _value;
|
|
72
|
+
dispatch("blur");
|
|
73
|
+
} else if (!header) {
|
|
74
|
+
is_expanded = !is_expanded;
|
|
75
|
+
}
|
|
57
76
|
}
|
|
58
77
|
dispatch("keydown", event);
|
|
59
78
|
}
|
|
79
|
+
|
|
80
|
+
function handle_click(): void {
|
|
81
|
+
if (!edit && !header) {
|
|
82
|
+
is_expanded = !is_expanded;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
60
85
|
</script>
|
|
61
86
|
|
|
62
87
|
{#if edit}
|
|
@@ -76,27 +101,31 @@
|
|
|
76
101
|
{/if}
|
|
77
102
|
|
|
78
103
|
<span
|
|
79
|
-
on:
|
|
80
|
-
|
|
104
|
+
on:click={handle_click}
|
|
105
|
+
on:keydown={handle_keydown}
|
|
106
|
+
tabindex="0"
|
|
81
107
|
role="button"
|
|
82
108
|
class:edit
|
|
109
|
+
class:expanded={is_expanded}
|
|
110
|
+
class:multiline={header}
|
|
83
111
|
on:focus|preventDefault
|
|
84
112
|
style={styling}
|
|
85
113
|
class="table-cell-text"
|
|
114
|
+
data-editable={editable}
|
|
86
115
|
placeholder=" "
|
|
87
116
|
>
|
|
88
117
|
{#if datatype === "html"}
|
|
89
|
-
{@html
|
|
118
|
+
{@html display_text}
|
|
90
119
|
{:else if datatype === "markdown"}
|
|
91
120
|
<MarkdownCode
|
|
92
|
-
message={
|
|
121
|
+
message={display_text.toLocaleString()}
|
|
93
122
|
{latex_delimiters}
|
|
94
123
|
{line_breaks}
|
|
95
124
|
chatbot={false}
|
|
96
125
|
{root}
|
|
97
126
|
/>
|
|
98
127
|
{:else}
|
|
99
|
-
{editable ?
|
|
128
|
+
{editable ? display_text : display_value || display_text}
|
|
100
129
|
{/if}
|
|
101
130
|
</span>
|
|
102
131
|
|
|
@@ -117,18 +146,37 @@
|
|
|
117
146
|
|
|
118
147
|
span {
|
|
119
148
|
flex: 1 1 0%;
|
|
149
|
+
position: relative;
|
|
150
|
+
display: inline-block;
|
|
120
151
|
outline: none;
|
|
121
152
|
padding: var(--size-2);
|
|
153
|
+
padding-right: 0;
|
|
122
154
|
-webkit-user-select: text;
|
|
123
155
|
-moz-user-select: text;
|
|
124
156
|
-ms-user-select: text;
|
|
125
157
|
user-select: text;
|
|
126
158
|
cursor: text;
|
|
159
|
+
width: 100%;
|
|
160
|
+
height: 100%;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
span.expanded {
|
|
164
|
+
height: auto;
|
|
165
|
+
min-height: 100%;
|
|
166
|
+
white-space: pre-wrap;
|
|
167
|
+
word-break: break-word;
|
|
168
|
+
white-space: normal;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.multiline {
|
|
172
|
+
white-space: pre-line;
|
|
127
173
|
}
|
|
128
174
|
|
|
129
175
|
.header {
|
|
130
176
|
transform: translateX(0);
|
|
131
177
|
font-weight: var(--weight-bold);
|
|
178
|
+
white-space: normal;
|
|
179
|
+
word-break: break-word;
|
|
132
180
|
}
|
|
133
181
|
|
|
134
182
|
.edit {
|