@gradio/dataframe 0.15.0 → 0.16.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.
- package/CHANGELOG.md +36 -0
- package/Dataframe.stories.svelte +183 -2
- package/Example.svelte +7 -0
- package/Index.svelte +20 -3
- package/dist/Example.svelte +7 -0
- package/dist/Index.svelte +16 -4
- package/dist/Index.svelte.d.ts +12 -0
- package/dist/shared/CellMenu.svelte +1 -1
- package/dist/shared/EditableCell.svelte +1 -6
- package/dist/shared/Table.svelte +620 -319
- package/dist/shared/Table.svelte.d.ts +3 -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 +12 -2
- package/dist/shared/selection_utils.js +33 -5
- package/dist/shared/types.d.ts +16 -0
- package/dist/shared/types.js +1 -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/CellMenu.svelte +1 -1
- package/shared/EditableCell.svelte +1 -6
- package/shared/Table.svelte +649 -322
- 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 +51 -9
- package/shared/types.ts +27 -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 -12
- package/dist/shared/table_utils.js +0 -113
- package/shared/table_utils.ts +0 -148
package/dist/shared/Table.svelte
CHANGED
|
@@ -6,6 +6,7 @@ import {} from "@gradio/client";
|
|
|
6
6
|
import VirtualTable from "./VirtualTable.svelte";
|
|
7
7
|
import CellMenu from "./CellMenu.svelte";
|
|
8
8
|
import Toolbar from "./Toolbar.svelte";
|
|
9
|
+
import SortIcon from "./icons/SortIcon.svelte";
|
|
9
10
|
import {
|
|
10
11
|
is_cell_selected,
|
|
11
12
|
handle_selection,
|
|
@@ -15,9 +16,17 @@ import {
|
|
|
15
16
|
get_range_selection,
|
|
16
17
|
move_cursor,
|
|
17
18
|
get_current_indices,
|
|
18
|
-
handle_click_outside as handle_click_outside_util
|
|
19
|
+
handle_click_outside as handle_click_outside_util,
|
|
20
|
+
select_column,
|
|
21
|
+
select_row,
|
|
22
|
+
calculate_selection_positions
|
|
19
23
|
} from "./selection_utils";
|
|
20
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
copy_table_data,
|
|
26
|
+
get_max,
|
|
27
|
+
handle_file_upload,
|
|
28
|
+
sort_table_data
|
|
29
|
+
} from "./utils/table_utils";
|
|
21
30
|
export let datatype;
|
|
22
31
|
export let label = null;
|
|
23
32
|
export let show_label = true;
|
|
@@ -40,6 +49,11 @@ export let show_fullscreen_button = false;
|
|
|
40
49
|
export let show_copy_button = false;
|
|
41
50
|
export let value_is_output = false;
|
|
42
51
|
export let max_chars = void 0;
|
|
52
|
+
export let show_search = "none";
|
|
53
|
+
export let pinned_columns = 0;
|
|
54
|
+
let actual_pinned_columns = 0;
|
|
55
|
+
$:
|
|
56
|
+
actual_pinned_columns = pinned_columns && data?.[0]?.length ? Math.min(pinned_columns, data[0].length) : 0;
|
|
43
57
|
let selected_cells = [];
|
|
44
58
|
$:
|
|
45
59
|
selected_cells = [...selected_cells];
|
|
@@ -60,48 +74,60 @@ let active_cell_menu = null;
|
|
|
60
74
|
let active_header_menu = null;
|
|
61
75
|
let is_fullscreen = false;
|
|
62
76
|
let dragging = false;
|
|
77
|
+
let copy_flash = false;
|
|
78
|
+
let color_accent_copied;
|
|
79
|
+
onMount(() => {
|
|
80
|
+
const color = getComputedStyle(document.documentElement).getPropertyValue("--color-accent").trim();
|
|
81
|
+
color_accent_copied = color + "40";
|
|
82
|
+
document.documentElement.style.setProperty(
|
|
83
|
+
"--color-accent-copied",
|
|
84
|
+
color_accent_copied
|
|
85
|
+
);
|
|
86
|
+
});
|
|
63
87
|
const get_data_at = (row, col) => data?.[row]?.[col]?.value;
|
|
64
88
|
function make_id() {
|
|
65
89
|
return Math.random().toString(36).substring(2, 15);
|
|
66
90
|
}
|
|
67
|
-
function make_headers(_head) {
|
|
91
|
+
function make_headers(_head, col_count2, els2) {
|
|
68
92
|
let _h = _head || [];
|
|
69
|
-
if (
|
|
70
|
-
const fill = Array(
|
|
93
|
+
if (col_count2[1] === "fixed" && _h.length < col_count2[0]) {
|
|
94
|
+
const fill = Array(col_count2[0] - _h.length).fill("").map((_, i) => `${i + _h.length}`);
|
|
71
95
|
_h = _h.concat(fill);
|
|
72
96
|
}
|
|
73
97
|
if (!_h || _h.length === 0) {
|
|
74
|
-
return Array(
|
|
98
|
+
return Array(col_count2[0]).fill(0).map((_, i) => {
|
|
75
99
|
const _id = make_id();
|
|
76
|
-
|
|
100
|
+
els2[_id] = { cell: null, input: null };
|
|
77
101
|
return { id: _id, value: JSON.stringify(i + 1) };
|
|
78
102
|
});
|
|
79
103
|
}
|
|
80
104
|
return _h.map((h, i) => {
|
|
81
105
|
const _id = make_id();
|
|
82
|
-
|
|
106
|
+
els2[_id] = { cell: null, input: null };
|
|
83
107
|
return { id: _id, value: h ?? "" };
|
|
84
108
|
});
|
|
85
109
|
}
|
|
86
110
|
function process_data(_values) {
|
|
87
111
|
const data_row_length = _values.length;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
112
|
+
if (data_row_length === 0)
|
|
113
|
+
return [];
|
|
114
|
+
return Array(row_count[1] === "fixed" ? row_count[0] : data_row_length).fill(0).map((_, i) => {
|
|
115
|
+
return Array(
|
|
116
|
+
col_count[1] === "fixed" ? col_count[0] : _values[0].length || headers.length
|
|
91
117
|
).fill(0).map((_2, j) => {
|
|
92
118
|
const id = make_id();
|
|
93
119
|
els[id] = els[id] || { input: null, cell: null };
|
|
94
120
|
const obj = { value: _values?.[i]?.[j] ?? "", id };
|
|
95
121
|
data_binding[id] = obj;
|
|
96
122
|
return obj;
|
|
97
|
-
})
|
|
98
|
-
);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
99
125
|
}
|
|
100
|
-
let _headers = make_headers(headers);
|
|
126
|
+
let _headers = make_headers(headers, col_count, els);
|
|
101
127
|
let old_headers = headers;
|
|
102
128
|
$: {
|
|
103
129
|
if (!dequal(headers, old_headers)) {
|
|
104
|
-
_headers = make_headers(headers);
|
|
130
|
+
_headers = make_headers(headers, col_count, els);
|
|
105
131
|
old_headers = JSON.parse(JSON.stringify(headers));
|
|
106
132
|
}
|
|
107
133
|
}
|
|
@@ -115,6 +141,8 @@ $:
|
|
|
115
141
|
let previous_headers = _headers.map((h) => h.value);
|
|
116
142
|
let previous_data = data.map((row) => row.map((cell) => String(cell.value)));
|
|
117
143
|
async function trigger_change() {
|
|
144
|
+
if (current_search_query)
|
|
145
|
+
return;
|
|
118
146
|
const current_headers = _headers.map((h) => h.value);
|
|
119
147
|
const current_data = data.map(
|
|
120
148
|
(row) => row.map((cell) => String(cell.value))
|
|
@@ -224,8 +252,10 @@ async function handle_keydown(event) {
|
|
|
224
252
|
editing = false;
|
|
225
253
|
} else {
|
|
226
254
|
selected_cells = [next_coords];
|
|
227
|
-
|
|
228
|
-
|
|
255
|
+
if (editable) {
|
|
256
|
+
editing = next_coords;
|
|
257
|
+
clear_on_focus = false;
|
|
258
|
+
}
|
|
229
259
|
}
|
|
230
260
|
selected = next_coords;
|
|
231
261
|
} else if (next_coords === false && event.key === "ArrowUp" && i === 0) {
|
|
@@ -241,26 +271,26 @@ async function handle_keydown(event) {
|
|
|
241
271
|
editing = false;
|
|
242
272
|
break;
|
|
243
273
|
case "Enter":
|
|
244
|
-
if (!editable)
|
|
245
|
-
break;
|
|
246
274
|
event.preventDefault();
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
selected = [i + 1, j];
|
|
251
|
-
} else {
|
|
252
|
-
if (dequal(editing, [i, j])) {
|
|
253
|
-
const cell_id = data[i][j].id;
|
|
254
|
-
const input_el = els[cell_id].input;
|
|
255
|
-
if (input_el) {
|
|
256
|
-
data[i][j].value = input_el.value;
|
|
257
|
-
}
|
|
258
|
-
editing = false;
|
|
275
|
+
if (editable) {
|
|
276
|
+
if (event.shiftKey) {
|
|
277
|
+
add_row(i);
|
|
259
278
|
await tick();
|
|
260
|
-
selected = [i, j];
|
|
279
|
+
selected = [i + 1, j];
|
|
261
280
|
} else {
|
|
262
|
-
editing
|
|
263
|
-
|
|
281
|
+
if (dequal(editing, [i, j])) {
|
|
282
|
+
const cell_id = data[i][j].id;
|
|
283
|
+
const input_el = els[cell_id].input;
|
|
284
|
+
if (input_el) {
|
|
285
|
+
data[i][j].value = input_el.value;
|
|
286
|
+
}
|
|
287
|
+
editing = false;
|
|
288
|
+
await tick();
|
|
289
|
+
selected = [i, j];
|
|
290
|
+
} else {
|
|
291
|
+
editing = [i, j];
|
|
292
|
+
clear_on_focus = false;
|
|
293
|
+
}
|
|
264
294
|
}
|
|
265
295
|
}
|
|
266
296
|
break;
|
|
@@ -292,15 +322,16 @@ async function handle_keydown(event) {
|
|
|
292
322
|
}
|
|
293
323
|
let sort_direction;
|
|
294
324
|
let sort_by;
|
|
295
|
-
function handle_sort(col) {
|
|
325
|
+
function handle_sort(col, direction) {
|
|
296
326
|
if (typeof sort_by !== "number" || sort_by !== col) {
|
|
297
|
-
sort_direction =
|
|
327
|
+
sort_direction = direction;
|
|
298
328
|
sort_by = col;
|
|
299
|
-
} else {
|
|
300
|
-
if (sort_direction ===
|
|
301
|
-
sort_direction =
|
|
302
|
-
|
|
303
|
-
|
|
329
|
+
} else if (sort_by === col) {
|
|
330
|
+
if (sort_direction === direction) {
|
|
331
|
+
sort_direction = void 0;
|
|
332
|
+
sort_by = void 0;
|
|
333
|
+
} else {
|
|
334
|
+
sort_direction = direction;
|
|
304
335
|
}
|
|
305
336
|
}
|
|
306
337
|
}
|
|
@@ -331,16 +362,14 @@ async function add_row(index) {
|
|
|
331
362
|
parent.focus();
|
|
332
363
|
if (row_count[1] !== "dynamic")
|
|
333
364
|
return;
|
|
334
|
-
|
|
335
|
-
values = [Array(headers.length).fill("")];
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
const new_row = Array(data[0].length).fill(0).map((_, i) => {
|
|
365
|
+
const new_row = Array(data[0]?.length || headers.length).fill(0).map((_, i) => {
|
|
339
366
|
const _id = make_id();
|
|
340
367
|
els[_id] = { cell: null, input: null };
|
|
341
368
|
return { id: _id, value: "" };
|
|
342
369
|
});
|
|
343
|
-
if (
|
|
370
|
+
if (data.length === 0) {
|
|
371
|
+
data = [new_row];
|
|
372
|
+
} else if (index !== void 0 && index >= 0 && index <= data.length) {
|
|
344
373
|
data.splice(index, 0, new_row);
|
|
345
374
|
} else {
|
|
346
375
|
data.push(new_row);
|
|
@@ -388,50 +417,36 @@ let cells = [];
|
|
|
388
417
|
let parent;
|
|
389
418
|
let table;
|
|
390
419
|
function set_cell_widths() {
|
|
391
|
-
const widths = cells.map((el
|
|
392
|
-
return el?.clientWidth || 0;
|
|
393
|
-
});
|
|
420
|
+
const widths = cells.map((el) => el?.clientWidth || 0);
|
|
394
421
|
if (widths.length === 0)
|
|
395
422
|
return;
|
|
396
|
-
|
|
397
|
-
parent.style.setProperty(
|
|
398
|
-
`--cell-width-${i}`,
|
|
399
|
-
`${widths[i] - scrollbar_width / widths.length}px`
|
|
400
|
-
);
|
|
423
|
+
if (show_row_numbers) {
|
|
424
|
+
parent.style.setProperty(`--cell-width-row-number`, `${widths[0]}px`);
|
|
401
425
|
}
|
|
426
|
+
const data_cells = show_row_numbers ? widths.slice(1) : widths;
|
|
427
|
+
data_cells.forEach((width, i) => {
|
|
428
|
+
if (!column_widths[i]) {
|
|
429
|
+
parent.style.setProperty(
|
|
430
|
+
`--cell-width-${i}`,
|
|
431
|
+
`${width - scrollbar_width / data_cells.length}px`
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
function get_cell_width(index) {
|
|
437
|
+
return column_widths[index] || `var(--cell-width-${index})`;
|
|
402
438
|
}
|
|
403
439
|
let table_height = values.slice(0, max_height / values.length * 37).length * 37 + 37;
|
|
404
440
|
let scrollbar_width = 0;
|
|
405
441
|
function sort_data(_data, _display_value, _styling, col, dir) {
|
|
406
442
|
let id = null;
|
|
407
|
-
if (selected && selected[0] in
|
|
408
|
-
id =
|
|
443
|
+
if (selected && selected[0] in _data && selected[1] in _data[selected[0]]) {
|
|
444
|
+
id = _data[selected[0]][selected[1]].id;
|
|
409
445
|
}
|
|
410
446
|
if (typeof col !== "number" || !dir) {
|
|
411
447
|
return;
|
|
412
448
|
}
|
|
413
|
-
|
|
414
|
-
if (dir === "asc") {
|
|
415
|
-
indices.sort(
|
|
416
|
-
(i, j) => _data[i][col].value < _data[j][col].value ? -1 : 1
|
|
417
|
-
);
|
|
418
|
-
} else if (dir === "des") {
|
|
419
|
-
indices.sort(
|
|
420
|
-
(i, j) => _data[i][col].value > _data[j][col].value ? -1 : 1
|
|
421
|
-
);
|
|
422
|
-
} else {
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
const temp_data = [..._data];
|
|
426
|
-
const temp_display_value = _display_value ? [..._display_value] : null;
|
|
427
|
-
const temp_styling = _styling ? [..._styling] : null;
|
|
428
|
-
indices.forEach((originalIndex, sortedIndex) => {
|
|
429
|
-
_data[sortedIndex] = temp_data[originalIndex];
|
|
430
|
-
if (_display_value && temp_display_value)
|
|
431
|
-
_display_value[sortedIndex] = temp_display_value[originalIndex];
|
|
432
|
-
if (_styling && temp_styling)
|
|
433
|
-
_styling[sortedIndex] = temp_styling[originalIndex];
|
|
434
|
-
});
|
|
449
|
+
sort_table_data(_data, _display_value, _styling, col, dir);
|
|
435
450
|
data = data;
|
|
436
451
|
if (id) {
|
|
437
452
|
const [i, j] = get_current_indices(id, data);
|
|
@@ -468,25 +483,33 @@ onMount(() => {
|
|
|
468
483
|
};
|
|
469
484
|
});
|
|
470
485
|
function handle_cell_click(event, row, col) {
|
|
486
|
+
if (event.target instanceof HTMLAnchorElement) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
471
489
|
event.preventDefault();
|
|
472
490
|
event.stopPropagation();
|
|
491
|
+
if (show_row_numbers && col === -1)
|
|
492
|
+
return;
|
|
473
493
|
clear_on_focus = false;
|
|
474
494
|
active_cell_menu = null;
|
|
475
495
|
active_header_menu = null;
|
|
476
496
|
selected_header = false;
|
|
477
497
|
header_edit = false;
|
|
478
498
|
selected_cells = handle_selection([row, col], selected_cells, event);
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
input_el.
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
499
|
+
parent.focus();
|
|
500
|
+
if (editable) {
|
|
501
|
+
if (selected_cells.length === 1) {
|
|
502
|
+
editing = [row, col];
|
|
503
|
+
tick().then(() => {
|
|
504
|
+
const input_el = els[data[row][col].id].input;
|
|
505
|
+
if (input_el) {
|
|
506
|
+
input_el.focus();
|
|
507
|
+
input_el.selectionStart = input_el.selectionEnd = input_el.value.length;
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
} else {
|
|
511
|
+
editing = false;
|
|
512
|
+
}
|
|
490
513
|
}
|
|
491
514
|
toggle_cell_button(row, col);
|
|
492
515
|
dispatch("select", {
|
|
@@ -522,6 +545,9 @@ function add_col_at(index, position) {
|
|
|
522
545
|
function handle_resize() {
|
|
523
546
|
active_cell_menu = null;
|
|
524
547
|
active_header_menu = null;
|
|
548
|
+
selected_cells = [];
|
|
549
|
+
selected = false;
|
|
550
|
+
editing = false;
|
|
525
551
|
set_cell_widths();
|
|
526
552
|
}
|
|
527
553
|
let active_button = null;
|
|
@@ -544,7 +570,11 @@ function handle_fullscreen_change() {
|
|
|
544
570
|
is_fullscreen = !!document.fullscreenElement;
|
|
545
571
|
}
|
|
546
572
|
async function handle_copy() {
|
|
547
|
-
await copy_table_data(data,
|
|
573
|
+
await copy_table_data(data, selected_cells);
|
|
574
|
+
copy_flash = true;
|
|
575
|
+
setTimeout(() => {
|
|
576
|
+
copy_flash = false;
|
|
577
|
+
}, 800);
|
|
548
578
|
}
|
|
549
579
|
function toggle_header_menu(event, col) {
|
|
550
580
|
event.stopPropagation();
|
|
@@ -575,14 +605,16 @@ async function delete_col(index) {
|
|
|
575
605
|
parent.focus();
|
|
576
606
|
if (col_count[1] !== "dynamic")
|
|
577
607
|
return;
|
|
578
|
-
if (
|
|
608
|
+
if (_headers.length <= 1)
|
|
579
609
|
return;
|
|
580
610
|
_headers.splice(index, 1);
|
|
581
611
|
_headers = _headers;
|
|
582
|
-
data.
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
612
|
+
if (data.length > 0) {
|
|
613
|
+
data.forEach((row) => {
|
|
614
|
+
row.splice(index, 1);
|
|
615
|
+
});
|
|
616
|
+
data = data;
|
|
617
|
+
}
|
|
586
618
|
selected = false;
|
|
587
619
|
}
|
|
588
620
|
function delete_row_at(index) {
|
|
@@ -595,35 +627,130 @@ function delete_col_at(index) {
|
|
|
595
627
|
active_cell_menu = null;
|
|
596
628
|
active_header_menu = null;
|
|
597
629
|
}
|
|
630
|
+
let row_order = [];
|
|
631
|
+
$: {
|
|
632
|
+
if (typeof sort_by === "number" && sort_direction && sort_by >= 0 && sort_by < data[0].length) {
|
|
633
|
+
const indices = [...Array(data.length)].map((_, i) => i);
|
|
634
|
+
const sort_index = sort_by;
|
|
635
|
+
indices.sort((a, b) => {
|
|
636
|
+
const row_a = data[a];
|
|
637
|
+
const row_b = data[b];
|
|
638
|
+
if (!row_a || !row_b || sort_index >= row_a.length || sort_index >= row_b.length)
|
|
639
|
+
return 0;
|
|
640
|
+
const val_a = row_a[sort_index].value;
|
|
641
|
+
const val_b = row_b[sort_index].value;
|
|
642
|
+
const comp = val_a < val_b ? -1 : val_a > val_b ? 1 : 0;
|
|
643
|
+
return sort_direction === "asc" ? comp : -comp;
|
|
644
|
+
});
|
|
645
|
+
row_order = indices;
|
|
646
|
+
} else {
|
|
647
|
+
row_order = [...Array(data.length)].map((_, i) => i);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
function handle_select_column(col) {
|
|
651
|
+
selected_cells = select_column(data, col);
|
|
652
|
+
selected = selected_cells[0];
|
|
653
|
+
editing = false;
|
|
654
|
+
}
|
|
655
|
+
function handle_select_row(row) {
|
|
656
|
+
selected_cells = select_row(data, row);
|
|
657
|
+
selected = selected_cells[0];
|
|
658
|
+
editing = false;
|
|
659
|
+
}
|
|
660
|
+
let coords;
|
|
661
|
+
$:
|
|
662
|
+
if (selected !== false)
|
|
663
|
+
coords = selected;
|
|
664
|
+
$:
|
|
665
|
+
if (selected !== false) {
|
|
666
|
+
const positions = calculate_selection_positions(
|
|
667
|
+
selected,
|
|
668
|
+
data,
|
|
669
|
+
els,
|
|
670
|
+
parent,
|
|
671
|
+
table
|
|
672
|
+
);
|
|
673
|
+
document.documentElement.style.setProperty(
|
|
674
|
+
"--selected-col-pos",
|
|
675
|
+
positions.col_pos
|
|
676
|
+
);
|
|
677
|
+
if (positions.row_pos) {
|
|
678
|
+
document.documentElement.style.setProperty(
|
|
679
|
+
"--selected-row-pos",
|
|
680
|
+
positions.row_pos
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
let current_search_query = null;
|
|
685
|
+
function handle_search(search_query) {
|
|
686
|
+
current_search_query = search_query;
|
|
687
|
+
dispatch("search", search_query);
|
|
688
|
+
}
|
|
689
|
+
function commit_filter() {
|
|
690
|
+
if (current_search_query && show_search === "filter") {
|
|
691
|
+
dispatch("change", {
|
|
692
|
+
data: data.map((row) => row.map((cell) => cell.value)),
|
|
693
|
+
headers: _headers.map((h) => h.value),
|
|
694
|
+
metadata: null
|
|
695
|
+
});
|
|
696
|
+
if (!value_is_output) {
|
|
697
|
+
dispatch("input");
|
|
698
|
+
}
|
|
699
|
+
current_search_query = null;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
598
702
|
</script>
|
|
599
703
|
|
|
600
704
|
<svelte:window on:resize={() => set_cell_widths()} />
|
|
601
705
|
|
|
602
706
|
<div class="table-container">
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
<
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
707
|
+
{#if (label && label.length !== 0 && show_label) || show_fullscreen_button || show_copy_button || show_search !== "none"}
|
|
708
|
+
<div class="header-row">
|
|
709
|
+
{#if label && label.length !== 0 && show_label}
|
|
710
|
+
<div class="label">
|
|
711
|
+
<p>{label}</p>
|
|
712
|
+
</div>
|
|
713
|
+
{/if}
|
|
714
|
+
<Toolbar
|
|
715
|
+
{show_fullscreen_button}
|
|
716
|
+
{is_fullscreen}
|
|
717
|
+
on:click={toggle_fullscreen}
|
|
718
|
+
on_copy={handle_copy}
|
|
719
|
+
{show_copy_button}
|
|
720
|
+
{show_search}
|
|
721
|
+
on:search={(e) => handle_search(e.detail)}
|
|
722
|
+
on_commit_filter={commit_filter}
|
|
723
|
+
{current_search_query}
|
|
724
|
+
/>
|
|
725
|
+
</div>
|
|
726
|
+
{/if}
|
|
617
727
|
<div
|
|
618
728
|
bind:this={parent}
|
|
619
729
|
class="table-wrap"
|
|
620
730
|
class:dragging
|
|
621
731
|
class:no-wrap={!wrap}
|
|
622
|
-
style="height:{table_height}px"
|
|
732
|
+
style="height:{table_height}px;"
|
|
733
|
+
class:menu-open={active_cell_menu || active_header_menu}
|
|
623
734
|
on:keydown={(e) => handle_keydown(e)}
|
|
624
735
|
role="grid"
|
|
625
736
|
tabindex="0"
|
|
626
737
|
>
|
|
738
|
+
{#if selected !== false && selected_cells.length === 1}
|
|
739
|
+
<button
|
|
740
|
+
class="selection-button selection-button-column"
|
|
741
|
+
on:click|stopPropagation={() => handle_select_column(coords[1])}
|
|
742
|
+
aria-label="Select column"
|
|
743
|
+
>
|
|
744
|
+
⋮
|
|
745
|
+
</button>
|
|
746
|
+
<button
|
|
747
|
+
class="selection-button selection-button-row"
|
|
748
|
+
on:click|stopPropagation={() => handle_select_row(coords[0])}
|
|
749
|
+
aria-label="Select row"
|
|
750
|
+
>
|
|
751
|
+
⋮
|
|
752
|
+
</button>
|
|
753
|
+
{/if}
|
|
627
754
|
<table
|
|
628
755
|
bind:contentRect={t_rect}
|
|
629
756
|
bind:this={table}
|
|
@@ -635,40 +762,59 @@ function delete_col_at(index) {
|
|
|
635
762
|
<thead>
|
|
636
763
|
<tr>
|
|
637
764
|
{#if show_row_numbers}
|
|
638
|
-
<th
|
|
765
|
+
<th
|
|
766
|
+
class="row-number-header frozen-column always-frozen"
|
|
767
|
+
style="left: 0;"
|
|
768
|
+
>
|
|
769
|
+
<div class="cell-wrap">
|
|
770
|
+
<div class="header-content">
|
|
771
|
+
<div class="header-text"></div>
|
|
772
|
+
</div>
|
|
773
|
+
</div>
|
|
774
|
+
</th>
|
|
639
775
|
{/if}
|
|
640
776
|
{#each _headers as { value, id }, i (id)}
|
|
641
777
|
<th
|
|
778
|
+
class:frozen-column={i < actual_pinned_columns}
|
|
779
|
+
class:last-frozen={show_row_numbers
|
|
780
|
+
? i === actual_pinned_columns - 1
|
|
781
|
+
: i === actual_pinned_columns - 1}
|
|
642
782
|
class:editing={header_edit === i}
|
|
643
783
|
aria-sort={get_sort_status(value, sort_by, sort_direction)}
|
|
644
|
-
style:
|
|
784
|
+
style="width: {column_widths.length
|
|
785
|
+
? column_widths[i]
|
|
786
|
+
: undefined}; left: {i < actual_pinned_columns
|
|
787
|
+
? i === 0
|
|
788
|
+
? show_row_numbers
|
|
789
|
+
? 'var(--cell-width-row-number)'
|
|
790
|
+
: '0'
|
|
791
|
+
: `calc(${show_row_numbers ? 'var(--cell-width-row-number) + ' : ''}${Array(
|
|
792
|
+
i
|
|
793
|
+
)
|
|
794
|
+
.fill(0)
|
|
795
|
+
.map((_, idx) => `var(--cell-width-${idx})`)
|
|
796
|
+
.join(' + ')})`
|
|
797
|
+
: 'auto'};"
|
|
645
798
|
>
|
|
646
799
|
<div class="cell-wrap">
|
|
647
|
-
<
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
height="1em"
|
|
666
|
-
viewBox="0 0 9 7"
|
|
667
|
-
fill="none"
|
|
668
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
669
|
-
>
|
|
670
|
-
<path d="M4.49999 0L8.3971 6.75H0.602875L4.49999 0Z" />
|
|
671
|
-
</svg>
|
|
800
|
+
<div class="header-content">
|
|
801
|
+
<EditableCell
|
|
802
|
+
{value}
|
|
803
|
+
{latex_delimiters}
|
|
804
|
+
{line_breaks}
|
|
805
|
+
header
|
|
806
|
+
edit={false}
|
|
807
|
+
el={null}
|
|
808
|
+
{root}
|
|
809
|
+
{editable}
|
|
810
|
+
/>
|
|
811
|
+
<div class="sort-buttons">
|
|
812
|
+
<SortIcon
|
|
813
|
+
direction={sort_by === i ? sort_direction : null}
|
|
814
|
+
on:sort={({ detail }) => handle_sort(i, detail)}
|
|
815
|
+
{i18n}
|
|
816
|
+
/>
|
|
817
|
+
</div>
|
|
672
818
|
</div>
|
|
673
819
|
</div>
|
|
674
820
|
</th>
|
|
@@ -707,9 +853,12 @@ function delete_col_at(index) {
|
|
|
707
853
|
on:load={({ detail }) =>
|
|
708
854
|
handle_file_upload(
|
|
709
855
|
detail.data,
|
|
710
|
-
col_count,
|
|
711
856
|
(head) => {
|
|
712
|
-
_headers = make_headers(
|
|
857
|
+
_headers = make_headers(
|
|
858
|
+
head.map((h) => h ?? ""),
|
|
859
|
+
col_count,
|
|
860
|
+
els
|
|
861
|
+
);
|
|
713
862
|
return _headers;
|
|
714
863
|
},
|
|
715
864
|
(vals) => {
|
|
@@ -719,152 +868,205 @@ function delete_col_at(index) {
|
|
|
719
868
|
bind:dragging
|
|
720
869
|
aria_label={i18n("dataframe.drop_to_upload")}
|
|
721
870
|
>
|
|
722
|
-
<
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
<th class="row-number-header"></th>
|
|
871
|
+
<div class="table-wrap">
|
|
872
|
+
<VirtualTable
|
|
873
|
+
bind:items={data}
|
|
874
|
+
{max_height}
|
|
875
|
+
bind:actual_height={table_height}
|
|
876
|
+
bind:table_scrollbar_width={scrollbar_width}
|
|
877
|
+
selected={selected_index}
|
|
878
|
+
disable_scroll={active_cell_menu !== null ||
|
|
879
|
+
active_header_menu !== null}
|
|
880
|
+
>
|
|
881
|
+
{#if label && label.length !== 0}
|
|
882
|
+
<caption class="sr-only">{label}</caption>
|
|
735
883
|
{/if}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
884
|
+
<tr slot="thead">
|
|
885
|
+
{#if show_row_numbers}
|
|
886
|
+
<th
|
|
887
|
+
class="row-number-header frozen-column always-frozen"
|
|
888
|
+
style="left: 0;"
|
|
889
|
+
>
|
|
890
|
+
<div class="cell-wrap">
|
|
891
|
+
<div class="header-content">
|
|
892
|
+
<div class="header-text"></div>
|
|
893
|
+
</div>
|
|
894
|
+
</div>
|
|
895
|
+
</th>
|
|
896
|
+
{/if}
|
|
897
|
+
{#each _headers as { value, id }, i (id)}
|
|
898
|
+
<th
|
|
899
|
+
class:frozen-column={i < actual_pinned_columns}
|
|
900
|
+
class:last-frozen={i === actual_pinned_columns - 1}
|
|
901
|
+
class:focus={header_edit === i || selected_header === i}
|
|
902
|
+
aria-sort={get_sort_status(value, sort_by, sort_direction)}
|
|
903
|
+
style="width: {get_cell_width(i)}; left: {i <
|
|
904
|
+
actual_pinned_columns
|
|
905
|
+
? i === 0
|
|
906
|
+
? show_row_numbers
|
|
907
|
+
? 'var(--cell-width-row-number)'
|
|
908
|
+
: '0'
|
|
909
|
+
: `calc(${show_row_numbers ? 'var(--cell-width-row-number) + ' : ''}${Array(
|
|
910
|
+
i
|
|
911
|
+
)
|
|
912
|
+
.fill(0)
|
|
913
|
+
.map((_, idx) => `var(--cell-width-${idx})`)
|
|
914
|
+
.join(' + ')})`
|
|
915
|
+
: 'auto'};"
|
|
916
|
+
on:click={() => {
|
|
917
|
+
toggle_header_button(i);
|
|
918
|
+
}}
|
|
919
|
+
>
|
|
920
|
+
<div class="cell-wrap">
|
|
921
|
+
<div class="header-content">
|
|
922
|
+
<EditableCell
|
|
923
|
+
{max_chars}
|
|
924
|
+
bind:value={_headers[i].value}
|
|
925
|
+
bind:el={els[id].input}
|
|
926
|
+
{latex_delimiters}
|
|
927
|
+
{line_breaks}
|
|
928
|
+
edit={header_edit === i}
|
|
929
|
+
on:keydown={end_header_edit}
|
|
930
|
+
on:dblclick={() => edit_header(i)}
|
|
931
|
+
header
|
|
932
|
+
{root}
|
|
933
|
+
{editable}
|
|
934
|
+
/>
|
|
935
|
+
<div class="sort-buttons">
|
|
936
|
+
<SortIcon
|
|
937
|
+
direction={sort_by === i ? sort_direction : null}
|
|
938
|
+
on:sort={({ detail }) => handle_sort(i, detail)}
|
|
939
|
+
{i18n}
|
|
940
|
+
/>
|
|
941
|
+
</div>
|
|
942
|
+
</div>
|
|
943
|
+
{#if editable}
|
|
944
|
+
<button
|
|
945
|
+
class="cell-menu-button"
|
|
946
|
+
on:click={(event) => toggle_header_menu(event, i)}
|
|
947
|
+
on:touchstart={(event) => {
|
|
948
|
+
event.preventDefault();
|
|
949
|
+
const touch = event.touches[0];
|
|
950
|
+
const mouseEvent = new MouseEvent("click", {
|
|
951
|
+
clientX: touch.clientX,
|
|
952
|
+
clientY: touch.clientY,
|
|
953
|
+
bubbles: true,
|
|
954
|
+
cancelable: true,
|
|
955
|
+
view: window
|
|
956
|
+
});
|
|
957
|
+
toggle_header_menu(mouseEvent, i);
|
|
958
|
+
}}
|
|
959
|
+
>
|
|
960
|
+
⋮
|
|
961
|
+
</button>
|
|
962
|
+
{/if}
|
|
963
|
+
</div>
|
|
964
|
+
</th>
|
|
965
|
+
{/each}
|
|
966
|
+
</tr>
|
|
967
|
+
<tr slot="tbody" let:item let:index class:row_odd={index % 2 === 0}>
|
|
968
|
+
{#if show_row_numbers}
|
|
969
|
+
<td
|
|
970
|
+
class="row-number frozen-column always-frozen"
|
|
971
|
+
style="left: 0;"
|
|
972
|
+
tabindex="-1"
|
|
973
|
+
>
|
|
974
|
+
{index + 1}
|
|
975
|
+
</td>
|
|
976
|
+
{/if}
|
|
977
|
+
{#each item as { value, id }, j (id)}
|
|
978
|
+
<td
|
|
979
|
+
class:frozen-column={j < actual_pinned_columns}
|
|
980
|
+
class:last-frozen={j === actual_pinned_columns - 1}
|
|
981
|
+
tabindex={show_row_numbers && j === 0 ? -1 : 0}
|
|
982
|
+
bind:this={els[id].cell}
|
|
983
|
+
on:touchstart={(event) => {
|
|
984
|
+
const touch = event.touches[0];
|
|
985
|
+
const mouseEvent = new MouseEvent("click", {
|
|
986
|
+
clientX: touch.clientX,
|
|
987
|
+
clientY: touch.clientY,
|
|
988
|
+
bubbles: true,
|
|
989
|
+
cancelable: true,
|
|
990
|
+
view: window
|
|
991
|
+
});
|
|
992
|
+
handle_cell_click(mouseEvent, index, j);
|
|
993
|
+
}}
|
|
994
|
+
on:mousedown={(event) => {
|
|
995
|
+
event.preventDefault();
|
|
996
|
+
event.stopPropagation();
|
|
997
|
+
}}
|
|
998
|
+
on:click={(event) => handle_cell_click(event, index, j)}
|
|
999
|
+
style="width: {get_cell_width(j)}; left: {j <
|
|
1000
|
+
actual_pinned_columns
|
|
1001
|
+
? j === 0
|
|
1002
|
+
? show_row_numbers
|
|
1003
|
+
? 'var(--cell-width-row-number)'
|
|
1004
|
+
: '0'
|
|
1005
|
+
: `calc(${show_row_numbers ? 'var(--cell-width-row-number) + ' : ''}${Array(
|
|
1006
|
+
j
|
|
1007
|
+
)
|
|
1008
|
+
.fill(0)
|
|
1009
|
+
.map((_, idx) => `var(--cell-width-${idx})`)
|
|
1010
|
+
.join(' + ')})`
|
|
1011
|
+
: 'auto'}; {styling?.[index]?.[j] || ''}"
|
|
1012
|
+
class:flash={copy_flash &&
|
|
1013
|
+
is_cell_selected([index, j], selected_cells)}
|
|
1014
|
+
class={is_cell_selected([index, j], selected_cells)}
|
|
1015
|
+
class:menu-active={active_cell_menu &&
|
|
1016
|
+
active_cell_menu.row === index &&
|
|
1017
|
+
active_cell_menu.col === j}
|
|
1018
|
+
>
|
|
1019
|
+
<div class="cell-wrap">
|
|
747
1020
|
<EditableCell
|
|
748
|
-
{
|
|
749
|
-
bind:value={_headers[i].value}
|
|
1021
|
+
bind:value={data[index][j].value}
|
|
750
1022
|
bind:el={els[id].input}
|
|
1023
|
+
display_value={display_value?.[index]?.[j]}
|
|
751
1024
|
{latex_delimiters}
|
|
752
1025
|
{line_breaks}
|
|
753
|
-
edit={header_edit === i}
|
|
754
|
-
on:keydown={end_header_edit}
|
|
755
|
-
on:dblclick={() => edit_header(i)}
|
|
756
|
-
header
|
|
757
|
-
{root}
|
|
758
1026
|
{editable}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
tabindex="0"
|
|
765
|
-
on:click={(event) => {
|
|
766
|
-
event.stopPropagation();
|
|
767
|
-
handle_sort(i);
|
|
1027
|
+
edit={dequal(editing, [index, j])}
|
|
1028
|
+
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
1029
|
+
on:blur={() => {
|
|
1030
|
+
clear_on_focus = false;
|
|
1031
|
+
parent.focus();
|
|
768
1032
|
}}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
1033
|
+
on:focus={() => {
|
|
1034
|
+
const row = index;
|
|
1035
|
+
const col = j;
|
|
1036
|
+
if (
|
|
1037
|
+
!selected_cells.some(([r, c]) => r === row && c === col)
|
|
1038
|
+
) {
|
|
1039
|
+
selected_cells = [[row, col]];
|
|
1040
|
+
}
|
|
1041
|
+
}}
|
|
1042
|
+
{clear_on_focus}
|
|
1043
|
+
{root}
|
|
1044
|
+
{max_chars}
|
|
1045
|
+
/>
|
|
1046
|
+
{#if editable && should_show_cell_menu([index, j], selected_cells, editable)}
|
|
1047
|
+
<button
|
|
1048
|
+
class="cell-menu-button"
|
|
1049
|
+
on:click={(event) => toggle_cell_menu(event, index, j)}
|
|
776
1050
|
>
|
|
777
|
-
|
|
778
|
-
</
|
|
779
|
-
|
|
1051
|
+
⋮
|
|
1052
|
+
</button>
|
|
1053
|
+
{/if}
|
|
780
1054
|
</div>
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
>
|
|
787
|
-
⋮
|
|
788
|
-
</button>
|
|
789
|
-
{/if}
|
|
790
|
-
</div>
|
|
791
|
-
</th>
|
|
792
|
-
{/each}
|
|
793
|
-
</tr>
|
|
794
|
-
|
|
795
|
-
<tr slot="tbody" let:item let:index class:row_odd={index % 2 === 0}>
|
|
796
|
-
{#if show_row_numbers}
|
|
797
|
-
<td class="row-number" title={`Row ${index + 1}`}>{index + 1}</td>
|
|
798
|
-
{/if}
|
|
799
|
-
{#each item as { value, id }, j (id)}
|
|
800
|
-
<td
|
|
801
|
-
tabindex="0"
|
|
802
|
-
on:touchstart={(event) => {
|
|
803
|
-
const touch = event.touches[0];
|
|
804
|
-
const mouseEvent = new MouseEvent("click", {
|
|
805
|
-
clientX: touch.clientX,
|
|
806
|
-
clientY: touch.clientY,
|
|
807
|
-
bubbles: true,
|
|
808
|
-
cancelable: true,
|
|
809
|
-
view: window
|
|
810
|
-
});
|
|
811
|
-
handle_cell_click(mouseEvent, index, j);
|
|
812
|
-
}}
|
|
813
|
-
on:mousedown={(event) => {
|
|
814
|
-
event.preventDefault();
|
|
815
|
-
event.stopPropagation();
|
|
816
|
-
}}
|
|
817
|
-
on:click={(event) => handle_cell_click(event, index, j)}
|
|
818
|
-
style:width="var(--cell-width-{j})"
|
|
819
|
-
style={styling?.[index]?.[j] || ""}
|
|
820
|
-
class={is_cell_selected([index, j], selected_cells)}
|
|
821
|
-
class:menu-active={active_cell_menu &&
|
|
822
|
-
active_cell_menu.row === index &&
|
|
823
|
-
active_cell_menu.col === j}
|
|
824
|
-
>
|
|
825
|
-
<div class="cell-wrap">
|
|
826
|
-
<EditableCell
|
|
827
|
-
bind:value={data[index][j].value}
|
|
828
|
-
bind:el={els[id].input}
|
|
829
|
-
display_value={display_value?.[index]?.[j]}
|
|
830
|
-
{latex_delimiters}
|
|
831
|
-
{line_breaks}
|
|
832
|
-
{editable}
|
|
833
|
-
edit={dequal(editing, [index, j])}
|
|
834
|
-
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
835
|
-
on:blur={() => {
|
|
836
|
-
clear_on_focus = false;
|
|
837
|
-
parent.focus();
|
|
838
|
-
}}
|
|
839
|
-
on:focus={() => {
|
|
840
|
-
const row = index;
|
|
841
|
-
const col = j;
|
|
842
|
-
if (
|
|
843
|
-
!selected_cells.some(([r, c]) => r === row && c === col)
|
|
844
|
-
) {
|
|
845
|
-
selected_cells = [[row, col]];
|
|
846
|
-
}
|
|
847
|
-
}}
|
|
848
|
-
{clear_on_focus}
|
|
849
|
-
{root}
|
|
850
|
-
{max_chars}
|
|
851
|
-
/>
|
|
852
|
-
{#if editable && should_show_cell_menu([index, j], selected_cells, editable)}
|
|
853
|
-
<button
|
|
854
|
-
class="cell-menu-button"
|
|
855
|
-
on:click={(event) => toggle_cell_menu(event, index, j)}
|
|
856
|
-
>
|
|
857
|
-
⋮
|
|
858
|
-
</button>
|
|
859
|
-
{/if}
|
|
860
|
-
</div>
|
|
861
|
-
</td>
|
|
862
|
-
{/each}
|
|
863
|
-
</tr>
|
|
864
|
-
</VirtualTable>
|
|
1055
|
+
</td>
|
|
1056
|
+
{/each}
|
|
1057
|
+
</tr>
|
|
1058
|
+
</VirtualTable>
|
|
1059
|
+
</div>
|
|
865
1060
|
</Upload>
|
|
866
1061
|
</div>
|
|
867
1062
|
</div>
|
|
1063
|
+
{#if data.length === 0 && editable && row_count[1] === "dynamic"}
|
|
1064
|
+
<div class="add-row-container">
|
|
1065
|
+
<button class="add-row-button" on:click={() => add_row()}>
|
|
1066
|
+
<span>+</span>
|
|
1067
|
+
</button>
|
|
1068
|
+
</div>
|
|
1069
|
+
{/if}
|
|
868
1070
|
|
|
869
1071
|
{#if active_cell_menu}
|
|
870
1072
|
<CellMenu
|
|
@@ -901,11 +1103,19 @@ function delete_col_at(index) {
|
|
|
901
1103
|
on_delete_row={() => delete_row_at(active_cell_menu?.row ?? -1)}
|
|
902
1104
|
on_delete_col={() => delete_col_at(active_header_menu?.col ?? -1)}
|
|
903
1105
|
can_delete_rows={false}
|
|
904
|
-
can_delete_cols={
|
|
1106
|
+
can_delete_cols={_headers.length > 1}
|
|
905
1107
|
/>
|
|
906
1108
|
{/if}
|
|
907
1109
|
|
|
908
1110
|
<style>
|
|
1111
|
+
.label p {
|
|
1112
|
+
position: relative;
|
|
1113
|
+
z-index: var(--layer-4);
|
|
1114
|
+
margin-bottom: var(--size-2);
|
|
1115
|
+
color: var(--block-label-text-color);
|
|
1116
|
+
font-size: var(--block-label-text-size);
|
|
1117
|
+
}
|
|
1118
|
+
|
|
909
1119
|
.table-container {
|
|
910
1120
|
display: flex;
|
|
911
1121
|
flex-direction: column;
|
|
@@ -915,8 +1125,9 @@ function delete_col_at(index) {
|
|
|
915
1125
|
.table-wrap {
|
|
916
1126
|
position: relative;
|
|
917
1127
|
transition: 150ms;
|
|
918
|
-
|
|
919
|
-
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
.table-wrap.menu-open {
|
|
920
1131
|
overflow: hidden;
|
|
921
1132
|
}
|
|
922
1133
|
|
|
@@ -946,6 +1157,12 @@ function delete_col_at(index) {
|
|
|
946
1157
|
border-collapse: separate;
|
|
947
1158
|
}
|
|
948
1159
|
|
|
1160
|
+
.table-wrap > :global(button) {
|
|
1161
|
+
border: 1px solid var(--border-color-primary);
|
|
1162
|
+
border-radius: var(--table-radius);
|
|
1163
|
+
overflow: hidden;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
949
1166
|
div:not(.no-wrap) td {
|
|
950
1167
|
overflow-wrap: anywhere;
|
|
951
1168
|
}
|
|
@@ -961,8 +1178,7 @@ function delete_col_at(index) {
|
|
|
961
1178
|
thead {
|
|
962
1179
|
position: sticky;
|
|
963
1180
|
top: 0;
|
|
964
|
-
|
|
965
|
-
z-index: var(--layer-1);
|
|
1181
|
+
z-index: var(--layer-2);
|
|
966
1182
|
box-shadow: var(--shadow-drop);
|
|
967
1183
|
}
|
|
968
1184
|
|
|
@@ -989,10 +1205,12 @@ function delete_col_at(index) {
|
|
|
989
1205
|
|
|
990
1206
|
th:first-child {
|
|
991
1207
|
border-top-left-radius: var(--table-radius);
|
|
1208
|
+
border-bottom-left-radius: var(--table-radius);
|
|
992
1209
|
}
|
|
993
1210
|
|
|
994
1211
|
th:last-child {
|
|
995
1212
|
border-top-right-radius: var(--table-radius);
|
|
1213
|
+
border-bottom-right-radius: var(--table-radius);
|
|
996
1214
|
}
|
|
997
1215
|
|
|
998
1216
|
th.focus,
|
|
@@ -1018,32 +1236,11 @@ function delete_col_at(index) {
|
|
|
1018
1236
|
background: var(--table-even-background-fill);
|
|
1019
1237
|
}
|
|
1020
1238
|
|
|
1021
|
-
|
|
1022
|
-
fill: currentColor;
|
|
1023
|
-
font-size: 10px;
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
.sort-button {
|
|
1239
|
+
.sort-buttons {
|
|
1027
1240
|
display: flex;
|
|
1028
|
-
flex: none;
|
|
1029
|
-
justify-content: center;
|
|
1030
1241
|
align-items: center;
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
padding: var(--size-2);
|
|
1034
|
-
color: var(--body-text-color-subdued);
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
.sort-button:hover {
|
|
1038
|
-
color: var(--body-text-color);
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
.des {
|
|
1042
|
-
transform: scaleY(-1);
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
.sort-button.sorted {
|
|
1046
|
-
color: var(--color-accent);
|
|
1242
|
+
flex-shrink: 0;
|
|
1243
|
+
order: -1;
|
|
1047
1244
|
}
|
|
1048
1245
|
|
|
1049
1246
|
.editing {
|
|
@@ -1052,11 +1249,19 @@ function delete_col_at(index) {
|
|
|
1052
1249
|
|
|
1053
1250
|
.cell-wrap {
|
|
1054
1251
|
display: flex;
|
|
1055
|
-
align-items:
|
|
1252
|
+
align-items: center;
|
|
1253
|
+
justify-content: flex-start;
|
|
1056
1254
|
outline: none;
|
|
1057
1255
|
min-height: var(--size-9);
|
|
1058
1256
|
position: relative;
|
|
1059
|
-
height:
|
|
1257
|
+
height: 100%;
|
|
1258
|
+
padding: var(--size-2);
|
|
1259
|
+
box-sizing: border-box;
|
|
1260
|
+
margin: 0;
|
|
1261
|
+
gap: var(--size-1);
|
|
1262
|
+
overflow: visible;
|
|
1263
|
+
min-width: 0;
|
|
1264
|
+
border-radius: var(--table-radius);
|
|
1060
1265
|
}
|
|
1061
1266
|
|
|
1062
1267
|
.header-content {
|
|
@@ -1067,7 +1272,9 @@ function delete_col_at(index) {
|
|
|
1067
1272
|
min-width: 0;
|
|
1068
1273
|
white-space: normal;
|
|
1069
1274
|
overflow-wrap: break-word;
|
|
1070
|
-
word-break:
|
|
1275
|
+
word-break: normal;
|
|
1276
|
+
height: 100%;
|
|
1277
|
+
gap: var(--size-1);
|
|
1071
1278
|
}
|
|
1072
1279
|
|
|
1073
1280
|
.row_odd {
|
|
@@ -1096,7 +1303,8 @@ function delete_col_at(index) {
|
|
|
1096
1303
|
transform: translateY(-50%);
|
|
1097
1304
|
}
|
|
1098
1305
|
|
|
1099
|
-
.cell-selected .cell-menu-button
|
|
1306
|
+
.cell-selected .cell-menu-button,
|
|
1307
|
+
th:hover .cell-menu-button {
|
|
1100
1308
|
display: flex;
|
|
1101
1309
|
align-items: center;
|
|
1102
1310
|
justify-content: center;
|
|
@@ -1104,46 +1312,55 @@ function delete_col_at(index) {
|
|
|
1104
1312
|
|
|
1105
1313
|
.header-row {
|
|
1106
1314
|
display: flex;
|
|
1107
|
-
justify-content:
|
|
1315
|
+
justify-content: flex-end;
|
|
1108
1316
|
align-items: center;
|
|
1109
1317
|
gap: var(--size-2);
|
|
1110
|
-
height: var(--size-6);
|
|
1111
1318
|
min-height: var(--size-6);
|
|
1319
|
+
flex-wrap: nowrap;
|
|
1320
|
+
width: 100%;
|
|
1112
1321
|
}
|
|
1113
1322
|
|
|
1114
1323
|
.label {
|
|
1115
|
-
flex: 1;
|
|
1324
|
+
flex: 1 1 auto;
|
|
1325
|
+
margin-right: auto;
|
|
1116
1326
|
}
|
|
1117
1327
|
|
|
1118
1328
|
.label p {
|
|
1119
1329
|
margin: 0;
|
|
1120
1330
|
color: var(--block-label-text-color);
|
|
1121
1331
|
font-size: var(--block-label-text-size);
|
|
1332
|
+
line-height: var(--line-sm);
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
.toolbar {
|
|
1336
|
+
flex: 0 0 auto;
|
|
1122
1337
|
}
|
|
1123
1338
|
|
|
1124
1339
|
.row-number,
|
|
1125
1340
|
.row-number-header {
|
|
1126
|
-
width: var(--size-7);
|
|
1127
|
-
min-width: var(--size-7);
|
|
1128
1341
|
text-align: center;
|
|
1129
1342
|
background: var(--table-even-background-fill);
|
|
1130
|
-
position: sticky;
|
|
1131
|
-
left: 0;
|
|
1132
1343
|
font-size: var(--input-text-size);
|
|
1133
1344
|
color: var(--body-text-color);
|
|
1134
|
-
padding: var(--size-1)
|
|
1345
|
+
padding: var(--size-1);
|
|
1346
|
+
min-width: var(--size-12);
|
|
1347
|
+
width: var(--size-12);
|
|
1135
1348
|
overflow: hidden;
|
|
1136
1349
|
text-overflow: ellipsis;
|
|
1137
1350
|
white-space: nowrap;
|
|
1138
1351
|
font-weight: var(--weight-semibold);
|
|
1139
1352
|
}
|
|
1140
1353
|
|
|
1141
|
-
.row-number-header {
|
|
1142
|
-
|
|
1354
|
+
.row-number-header .header-content {
|
|
1355
|
+
justify-content: space-between;
|
|
1356
|
+
padding: var(--size-1);
|
|
1357
|
+
height: var(--size-9);
|
|
1358
|
+
display: flex;
|
|
1359
|
+
align-items: center;
|
|
1143
1360
|
}
|
|
1144
1361
|
|
|
1145
|
-
.row-number {
|
|
1146
|
-
|
|
1362
|
+
.row-number-header :global(.sort-icons) {
|
|
1363
|
+
margin-right: 0;
|
|
1147
1364
|
}
|
|
1148
1365
|
|
|
1149
1366
|
:global(tbody > tr:nth-child(odd)) .row-number {
|
|
@@ -1240,4 +1457,88 @@ function delete_col_at(index) {
|
|
|
1240
1457
|
.cell-selected.no-top.no-bottom.no-left.no-right {
|
|
1241
1458
|
box-shadow: none;
|
|
1242
1459
|
}
|
|
1460
|
+
|
|
1461
|
+
.selection-button {
|
|
1462
|
+
position: absolute;
|
|
1463
|
+
display: flex;
|
|
1464
|
+
align-items: center;
|
|
1465
|
+
justify-content: center;
|
|
1466
|
+
background: var(--color-accent);
|
|
1467
|
+
color: white;
|
|
1468
|
+
border-radius: var(--radius-sm);
|
|
1469
|
+
z-index: var(--layer-4);
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
.selection-button-column {
|
|
1473
|
+
width: var(--size-3);
|
|
1474
|
+
height: var(--size-5);
|
|
1475
|
+
top: -10px;
|
|
1476
|
+
left: var(--selected-col-pos);
|
|
1477
|
+
transform: rotate(90deg);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
.selection-button-row {
|
|
1481
|
+
width: var(--size-3);
|
|
1482
|
+
height: var(--size-5);
|
|
1483
|
+
left: -7px;
|
|
1484
|
+
top: calc(var(--selected-row-pos) - var(--size-5) / 2);
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
.table-wrap:not(:focus-within) .selection-button {
|
|
1488
|
+
opacity: 0;
|
|
1489
|
+
pointer-events: none;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
.flash.cell-selected {
|
|
1493
|
+
animation: flash-color 700ms ease-out;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
@keyframes flash-color {
|
|
1497
|
+
0%,
|
|
1498
|
+
30% {
|
|
1499
|
+
background: var(--color-accent-copied);
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
100% {
|
|
1503
|
+
background: transparent;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
.frozen-column {
|
|
1508
|
+
position: sticky;
|
|
1509
|
+
z-index: var(--layer-2);
|
|
1510
|
+
border-right: 1px solid var(--border-color-primary);
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
tr:nth-child(odd) .frozen-column {
|
|
1514
|
+
background: var(--table-odd-background-fill);
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
tr:nth-child(even) .frozen-column {
|
|
1518
|
+
background: var(--table-even-background-fill);
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
.always-frozen {
|
|
1522
|
+
z-index: var(--layer-3);
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
.add-row-container {
|
|
1526
|
+
margin-top: var(--size-2);
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
.add-row-button {
|
|
1530
|
+
width: 100%;
|
|
1531
|
+
padding: var(--size-1);
|
|
1532
|
+
background: transparent;
|
|
1533
|
+
border: 1px dashed var(--border-color-primary);
|
|
1534
|
+
border-radius: var(--radius-sm);
|
|
1535
|
+
color: var(--body-text-color);
|
|
1536
|
+
cursor: pointer;
|
|
1537
|
+
transition: all 150ms;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
.add-row-button:hover {
|
|
1541
|
+
background: var(--background-fill-secondary);
|
|
1542
|
+
border-style: solid;
|
|
1543
|
+
}
|
|
1243
1544
|
</style>
|