@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
package/dist/shared/Table.svelte
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script>import { afterUpdate, createEventDispatcher, tick, onMount } from "svelte";
|
|
2
|
-
import { dsvFormat } from "d3-dsv";
|
|
3
2
|
import { dequal } from "dequal/lite";
|
|
4
3
|
import { Upload } from "@gradio/upload";
|
|
5
4
|
import EditableCell from "./EditableCell.svelte";
|
|
@@ -7,7 +6,27 @@ import {} from "@gradio/client";
|
|
|
7
6
|
import VirtualTable from "./VirtualTable.svelte";
|
|
8
7
|
import CellMenu from "./CellMenu.svelte";
|
|
9
8
|
import Toolbar from "./Toolbar.svelte";
|
|
10
|
-
import
|
|
9
|
+
import SortIcon from "./icons/SortIcon.svelte";
|
|
10
|
+
import {
|
|
11
|
+
is_cell_selected,
|
|
12
|
+
handle_selection,
|
|
13
|
+
handle_delete_key,
|
|
14
|
+
should_show_cell_menu,
|
|
15
|
+
get_next_cell_coordinates,
|
|
16
|
+
get_range_selection,
|
|
17
|
+
move_cursor,
|
|
18
|
+
get_current_indices,
|
|
19
|
+
handle_click_outside as handle_click_outside_util,
|
|
20
|
+
select_column,
|
|
21
|
+
select_row,
|
|
22
|
+
calculate_selection_positions
|
|
23
|
+
} from "./selection_utils";
|
|
24
|
+
import {
|
|
25
|
+
copy_table_data,
|
|
26
|
+
get_max,
|
|
27
|
+
handle_file_upload,
|
|
28
|
+
sort_table_data
|
|
29
|
+
} from "./utils/table_utils";
|
|
11
30
|
export let datatype;
|
|
12
31
|
export let label = null;
|
|
13
32
|
export let show_label = true;
|
|
@@ -29,56 +48,69 @@ export let stream_handler;
|
|
|
29
48
|
export let show_fullscreen_button = false;
|
|
30
49
|
export let show_copy_button = false;
|
|
31
50
|
export let value_is_output = false;
|
|
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;
|
|
57
|
+
let selected_cells = [];
|
|
58
|
+
$:
|
|
59
|
+
selected_cells = [...selected_cells];
|
|
32
60
|
let selected = false;
|
|
33
|
-
|
|
61
|
+
$:
|
|
62
|
+
selected = selected_cells.length > 0 ? selected_cells[selected_cells.length - 1] : false;
|
|
34
63
|
export let display_value = null;
|
|
35
64
|
export let styling = null;
|
|
36
65
|
let t_rect;
|
|
66
|
+
let els = {};
|
|
67
|
+
let data_binding = {};
|
|
37
68
|
const dispatch = createEventDispatcher();
|
|
38
69
|
let editing = false;
|
|
70
|
+
let clear_on_focus = false;
|
|
71
|
+
let header_edit = false;
|
|
72
|
+
let selected_header = false;
|
|
73
|
+
let active_cell_menu = null;
|
|
74
|
+
let active_header_menu = null;
|
|
75
|
+
let is_fullscreen = false;
|
|
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
|
+
});
|
|
39
87
|
const get_data_at = (row, col) => data?.[row]?.[col]?.value;
|
|
40
|
-
let last_selected = null;
|
|
41
|
-
$: {
|
|
42
|
-
if (selected !== false && !dequal(selected, last_selected)) {
|
|
43
|
-
const [row, col] = selected;
|
|
44
|
-
if (!isNaN(row) && !isNaN(col) && data[row]) {
|
|
45
|
-
dispatch("select", {
|
|
46
|
-
index: [row, col],
|
|
47
|
-
value: get_data_at(row, col),
|
|
48
|
-
row_value: data[row].map((d) => d.value)
|
|
49
|
-
});
|
|
50
|
-
last_selected = selected;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
let els = {};
|
|
55
|
-
let data_binding = {};
|
|
56
88
|
function make_id() {
|
|
57
89
|
return Math.random().toString(36).substring(2, 15);
|
|
58
90
|
}
|
|
59
|
-
function make_headers(_head) {
|
|
91
|
+
function make_headers(_head, col_count2, els2) {
|
|
60
92
|
let _h = _head || [];
|
|
61
|
-
if (
|
|
62
|
-
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}`);
|
|
63
95
|
_h = _h.concat(fill);
|
|
64
96
|
}
|
|
65
97
|
if (!_h || _h.length === 0) {
|
|
66
|
-
return Array(
|
|
98
|
+
return Array(col_count2[0]).fill(0).map((_, i) => {
|
|
67
99
|
const _id = make_id();
|
|
68
|
-
|
|
100
|
+
els2[_id] = { cell: null, input: null };
|
|
69
101
|
return { id: _id, value: JSON.stringify(i + 1) };
|
|
70
102
|
});
|
|
71
103
|
}
|
|
72
104
|
return _h.map((h, i) => {
|
|
73
105
|
const _id = make_id();
|
|
74
|
-
|
|
106
|
+
els2[_id] = { cell: null, input: null };
|
|
75
107
|
return { id: _id, value: h ?? "" };
|
|
76
108
|
});
|
|
77
109
|
}
|
|
78
110
|
function process_data(_values) {
|
|
79
111
|
const data_row_length = _values.length;
|
|
80
|
-
return Array(row_count[1] === "fixed" ? row_count[0] : data_row_length).fill(0).map(
|
|
81
|
-
|
|
112
|
+
return Array(row_count[1] === "fixed" ? row_count[0] : data_row_length).fill(0).map((_, i) => {
|
|
113
|
+
return Array(
|
|
82
114
|
col_count[1] === "fixed" ? col_count[0] : data_row_length > 0 ? _values[0].length : headers.length
|
|
83
115
|
).fill(0).map((_2, j) => {
|
|
84
116
|
const id = make_id();
|
|
@@ -86,14 +118,14 @@ function process_data(_values) {
|
|
|
86
118
|
const obj = { value: _values?.[i]?.[j] ?? "", id };
|
|
87
119
|
data_binding[id] = obj;
|
|
88
120
|
return obj;
|
|
89
|
-
})
|
|
90
|
-
);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
91
123
|
}
|
|
92
|
-
let _headers = make_headers(headers);
|
|
124
|
+
let _headers = make_headers(headers, col_count, els);
|
|
93
125
|
let old_headers = headers;
|
|
94
126
|
$: {
|
|
95
127
|
if (!dequal(headers, old_headers)) {
|
|
96
|
-
_headers = make_headers(headers);
|
|
128
|
+
_headers = make_headers(headers, col_count, els);
|
|
97
129
|
old_headers = JSON.parse(JSON.stringify(headers));
|
|
98
130
|
}
|
|
99
131
|
}
|
|
@@ -107,6 +139,8 @@ $:
|
|
|
107
139
|
let previous_headers = _headers.map((h) => h.value);
|
|
108
140
|
let previous_data = data.map((row) => row.map((cell) => String(cell.value)));
|
|
109
141
|
async function trigger_change() {
|
|
142
|
+
if (current_search_query)
|
|
143
|
+
return;
|
|
110
144
|
const current_headers = _headers.map((h) => h.value);
|
|
111
145
|
const current_data = data.map(
|
|
112
146
|
(row) => row.map((cell) => String(cell.value))
|
|
@@ -135,36 +169,6 @@ function get_sort_status(name, _sort, direction) {
|
|
|
135
169
|
}
|
|
136
170
|
return "none";
|
|
137
171
|
}
|
|
138
|
-
function get_current_indices(id) {
|
|
139
|
-
return data.reduce(
|
|
140
|
-
(acc, arr, i) => {
|
|
141
|
-
const j = arr.reduce(
|
|
142
|
-
(_acc, _data, k) => id === _data.id ? k : _acc,
|
|
143
|
-
-1
|
|
144
|
-
);
|
|
145
|
-
return j === -1 ? acc : [i, j];
|
|
146
|
-
},
|
|
147
|
-
[-1, -1]
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
function move_cursor(key, current_coords) {
|
|
151
|
-
const dir = {
|
|
152
|
-
ArrowRight: [0, 1],
|
|
153
|
-
ArrowLeft: [0, -1],
|
|
154
|
-
ArrowDown: [1, 0],
|
|
155
|
-
ArrowUp: [-1, 0]
|
|
156
|
-
}[key];
|
|
157
|
-
const i = current_coords[0] + dir[0];
|
|
158
|
-
const j = current_coords[1] + dir[1];
|
|
159
|
-
if (i < 0 && j <= 0) {
|
|
160
|
-
selected_header = j;
|
|
161
|
-
selected = false;
|
|
162
|
-
} else {
|
|
163
|
-
const is_data = data[i]?.[j];
|
|
164
|
-
selected = is_data ? [i, j] : selected;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
let clear_on_focus = false;
|
|
168
172
|
async function handle_keydown(event) {
|
|
169
173
|
if (selected_header !== false && header_edit === false) {
|
|
170
174
|
switch (event.key) {
|
|
@@ -187,6 +191,43 @@ async function handle_keydown(event) {
|
|
|
187
191
|
break;
|
|
188
192
|
}
|
|
189
193
|
}
|
|
194
|
+
if (event.key === "Delete" || event.key === "Backspace") {
|
|
195
|
+
if (!editable)
|
|
196
|
+
return;
|
|
197
|
+
if (editing) {
|
|
198
|
+
const [row, col] = editing;
|
|
199
|
+
const input_el = els[data[row][col].id].input;
|
|
200
|
+
if (input_el && input_el.selectionStart !== input_el.selectionEnd) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (event.key === "Delete" && input_el?.selectionStart !== input_el?.value.length) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (event.key === "Backspace" && input_el?.selectionStart !== 0) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
event.preventDefault();
|
|
211
|
+
if (selected_cells.length > 0) {
|
|
212
|
+
data = handle_delete_key(data, selected_cells);
|
|
213
|
+
dispatch("change", {
|
|
214
|
+
data: data.map((row) => row.map((cell) => cell.value)),
|
|
215
|
+
headers: _headers.map((h) => h.value),
|
|
216
|
+
metadata: null
|
|
217
|
+
});
|
|
218
|
+
if (!value_is_output) {
|
|
219
|
+
dispatch("input");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (event.key === "c" && (event.metaKey || event.ctrlKey)) {
|
|
225
|
+
event.preventDefault();
|
|
226
|
+
if (selected_cells.length > 0) {
|
|
227
|
+
await handle_copy();
|
|
228
|
+
}
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
190
231
|
if (!selected) {
|
|
191
232
|
return;
|
|
192
233
|
}
|
|
@@ -199,7 +240,27 @@ async function handle_keydown(event) {
|
|
|
199
240
|
if (editing)
|
|
200
241
|
break;
|
|
201
242
|
event.preventDefault();
|
|
202
|
-
move_cursor(event.key, [i, j]);
|
|
243
|
+
const next_coords = move_cursor(event.key, [i, j], data);
|
|
244
|
+
if (next_coords) {
|
|
245
|
+
if (event.shiftKey) {
|
|
246
|
+
selected_cells = get_range_selection(
|
|
247
|
+
selected_cells.length > 0 ? selected_cells[0] : [i, j],
|
|
248
|
+
next_coords
|
|
249
|
+
);
|
|
250
|
+
editing = false;
|
|
251
|
+
} else {
|
|
252
|
+
selected_cells = [next_coords];
|
|
253
|
+
if (editable) {
|
|
254
|
+
editing = next_coords;
|
|
255
|
+
clear_on_focus = false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
selected = next_coords;
|
|
259
|
+
} else if (next_coords === false && event.key === "ArrowUp" && i === 0) {
|
|
260
|
+
selected_header = j;
|
|
261
|
+
selected = false;
|
|
262
|
+
editing = false;
|
|
263
|
+
}
|
|
203
264
|
break;
|
|
204
265
|
case "Escape":
|
|
205
266
|
if (!editable)
|
|
@@ -208,53 +269,45 @@ async function handle_keydown(event) {
|
|
|
208
269
|
editing = false;
|
|
209
270
|
break;
|
|
210
271
|
case "Enter":
|
|
211
|
-
if (!editable)
|
|
212
|
-
break;
|
|
213
272
|
event.preventDefault();
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
selected = [i + 1, j];
|
|
218
|
-
} else {
|
|
219
|
-
if (dequal(editing, [i, j])) {
|
|
220
|
-
const cell_id = data[i][j].id;
|
|
221
|
-
const input_el = els[cell_id].input;
|
|
222
|
-
if (input_el) {
|
|
223
|
-
data[i][j].value = input_el.value;
|
|
224
|
-
}
|
|
225
|
-
editing = false;
|
|
273
|
+
if (editable) {
|
|
274
|
+
if (event.shiftKey) {
|
|
275
|
+
add_row(i);
|
|
226
276
|
await tick();
|
|
227
|
-
selected = [i, j];
|
|
277
|
+
selected = [i + 1, j];
|
|
228
278
|
} else {
|
|
229
|
-
editing
|
|
279
|
+
if (dequal(editing, [i, j])) {
|
|
280
|
+
const cell_id = data[i][j].id;
|
|
281
|
+
const input_el = els[cell_id].input;
|
|
282
|
+
if (input_el) {
|
|
283
|
+
data[i][j].value = input_el.value;
|
|
284
|
+
}
|
|
285
|
+
editing = false;
|
|
286
|
+
await tick();
|
|
287
|
+
selected = [i, j];
|
|
288
|
+
} else {
|
|
289
|
+
editing = [i, j];
|
|
290
|
+
clear_on_focus = false;
|
|
291
|
+
}
|
|
230
292
|
}
|
|
231
293
|
}
|
|
232
294
|
break;
|
|
233
|
-
case "Backspace":
|
|
234
|
-
if (!editable)
|
|
235
|
-
break;
|
|
236
|
-
if (!editing) {
|
|
237
|
-
event.preventDefault();
|
|
238
|
-
data[i][j].value = "";
|
|
239
|
-
}
|
|
240
|
-
break;
|
|
241
|
-
case "Delete":
|
|
242
|
-
if (!editable)
|
|
243
|
-
break;
|
|
244
|
-
if (!editing) {
|
|
245
|
-
event.preventDefault();
|
|
246
|
-
data[i][j].value = "";
|
|
247
|
-
}
|
|
248
|
-
break;
|
|
249
295
|
case "Tab":
|
|
250
|
-
|
|
251
|
-
let is_data_x = data[i][j + direction];
|
|
252
|
-
let is_data_y = data?.[i + direction]?.[direction > 0 ? 0 : _headers.length - 1];
|
|
253
|
-
if (is_data_x || is_data_y) {
|
|
254
|
-
event.preventDefault();
|
|
255
|
-
selected = is_data_x ? [i, j + direction] : [i + direction, direction > 0 ? 0 : _headers.length - 1];
|
|
256
|
-
}
|
|
296
|
+
event.preventDefault();
|
|
257
297
|
editing = false;
|
|
298
|
+
const next_cell = get_next_cell_coordinates(
|
|
299
|
+
[i, j],
|
|
300
|
+
data,
|
|
301
|
+
event.shiftKey
|
|
302
|
+
);
|
|
303
|
+
if (next_cell) {
|
|
304
|
+
selected_cells = [next_cell];
|
|
305
|
+
selected = next_cell;
|
|
306
|
+
if (editable) {
|
|
307
|
+
editing = next_cell;
|
|
308
|
+
clear_on_focus = false;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
258
311
|
break;
|
|
259
312
|
default:
|
|
260
313
|
if (!editable)
|
|
@@ -267,28 +320,26 @@ async function handle_keydown(event) {
|
|
|
267
320
|
}
|
|
268
321
|
let sort_direction;
|
|
269
322
|
let sort_by;
|
|
270
|
-
function handle_sort(col) {
|
|
323
|
+
function handle_sort(col, direction) {
|
|
271
324
|
if (typeof sort_by !== "number" || sort_by !== col) {
|
|
272
|
-
sort_direction =
|
|
325
|
+
sort_direction = direction;
|
|
273
326
|
sort_by = col;
|
|
274
|
-
} else {
|
|
275
|
-
if (sort_direction ===
|
|
276
|
-
sort_direction =
|
|
277
|
-
|
|
278
|
-
|
|
327
|
+
} else if (sort_by === col) {
|
|
328
|
+
if (sort_direction === direction) {
|
|
329
|
+
sort_direction = void 0;
|
|
330
|
+
sort_by = void 0;
|
|
331
|
+
} else {
|
|
332
|
+
sort_direction = direction;
|
|
279
333
|
}
|
|
280
334
|
}
|
|
281
335
|
}
|
|
282
|
-
let header_edit;
|
|
283
|
-
let select_on_focus = false;
|
|
284
|
-
let selected_header = false;
|
|
285
336
|
async function edit_header(i, _select = false) {
|
|
286
337
|
if (!editable || col_count[1] !== "dynamic" || header_edit === i)
|
|
287
338
|
return;
|
|
288
339
|
selected = false;
|
|
340
|
+
selected_cells = [];
|
|
289
341
|
selected_header = i;
|
|
290
342
|
header_edit = i;
|
|
291
|
-
select_on_focus = _select;
|
|
292
343
|
}
|
|
293
344
|
function end_header_edit(event) {
|
|
294
345
|
if (!editable)
|
|
@@ -349,78 +400,14 @@ async function add_col(index) {
|
|
|
349
400
|
});
|
|
350
401
|
}
|
|
351
402
|
function handle_click_outside(event) {
|
|
352
|
-
if (
|
|
403
|
+
if (handle_click_outside_util(event, parent)) {
|
|
404
|
+
editing = false;
|
|
405
|
+
selected_cells = [];
|
|
406
|
+
header_edit = false;
|
|
407
|
+
selected_header = false;
|
|
353
408
|
active_cell_menu = null;
|
|
354
409
|
active_header_menu = null;
|
|
355
410
|
}
|
|
356
|
-
const [trigger] = event.composedPath();
|
|
357
|
-
if (parent.contains(trigger)) {
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
clicked_cell = void 0;
|
|
361
|
-
editing = false;
|
|
362
|
-
selected = false;
|
|
363
|
-
header_edit = false;
|
|
364
|
-
selected_header = false;
|
|
365
|
-
active_cell_menu = null;
|
|
366
|
-
active_header_menu = null;
|
|
367
|
-
}
|
|
368
|
-
function guess_delimitaor(text, possibleDelimiters) {
|
|
369
|
-
return possibleDelimiters.filter(weedOut);
|
|
370
|
-
function weedOut(delimiter) {
|
|
371
|
-
var cache = -1;
|
|
372
|
-
return text.split("\n").every(checkLength);
|
|
373
|
-
function checkLength(line) {
|
|
374
|
-
if (!line) {
|
|
375
|
-
return true;
|
|
376
|
-
}
|
|
377
|
-
var length = line.split(delimiter).length;
|
|
378
|
-
if (cache < 0) {
|
|
379
|
-
cache = length;
|
|
380
|
-
}
|
|
381
|
-
return cache === length && length > 1;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
function data_uri_to_blob(data_uri) {
|
|
386
|
-
const byte_str = atob(data_uri.split(",")[1]);
|
|
387
|
-
const mime_str = data_uri.split(",")[0].split(":")[1].split(";")[0];
|
|
388
|
-
const ab = new ArrayBuffer(byte_str.length);
|
|
389
|
-
const ia = new Uint8Array(ab);
|
|
390
|
-
for (let i = 0; i < byte_str.length; i++) {
|
|
391
|
-
ia[i] = byte_str.charCodeAt(i);
|
|
392
|
-
}
|
|
393
|
-
return new Blob([ab], { type: mime_str });
|
|
394
|
-
}
|
|
395
|
-
function blob_to_string(blob) {
|
|
396
|
-
const reader = new FileReader();
|
|
397
|
-
function handle_read(e) {
|
|
398
|
-
if (!e?.target?.result || typeof e.target.result !== "string")
|
|
399
|
-
return;
|
|
400
|
-
const [delimiter] = guess_delimitaor(e.target.result, [",", " "]);
|
|
401
|
-
const [head, ...rest] = dsvFormat(delimiter).parseRows(e.target.result);
|
|
402
|
-
_headers = make_headers(
|
|
403
|
-
col_count[1] === "fixed" ? head.slice(0, col_count[0]) : head
|
|
404
|
-
);
|
|
405
|
-
values = rest;
|
|
406
|
-
reader.removeEventListener("loadend", handle_read);
|
|
407
|
-
}
|
|
408
|
-
reader.addEventListener("loadend", handle_read);
|
|
409
|
-
reader.readAsText(blob);
|
|
410
|
-
}
|
|
411
|
-
let dragging = false;
|
|
412
|
-
function get_max(_d) {
|
|
413
|
-
if (!_d || _d.length === 0 || !_d[0])
|
|
414
|
-
return [];
|
|
415
|
-
let max2 = _d[0].slice();
|
|
416
|
-
for (let i = 0; i < _d.length; i++) {
|
|
417
|
-
for (let j = 0; j < _d[i].length; j++) {
|
|
418
|
-
if (`${max2[j].value}`.length < `${_d[i][j].value}`.length) {
|
|
419
|
-
max2[j] = _d[i][j];
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
return max2;
|
|
424
411
|
}
|
|
425
412
|
$:
|
|
426
413
|
max = get_max(data);
|
|
@@ -430,53 +417,39 @@ let cells = [];
|
|
|
430
417
|
let parent;
|
|
431
418
|
let table;
|
|
432
419
|
function set_cell_widths() {
|
|
433
|
-
const widths = cells.map((el
|
|
434
|
-
return el?.clientWidth || 0;
|
|
435
|
-
});
|
|
420
|
+
const widths = cells.map((el) => el?.clientWidth || 0);
|
|
436
421
|
if (widths.length === 0)
|
|
437
422
|
return;
|
|
438
|
-
|
|
439
|
-
parent.style.setProperty(
|
|
440
|
-
`--cell-width-${i}`,
|
|
441
|
-
`${widths[i] - scrollbar_width / widths.length}px`
|
|
442
|
-
);
|
|
423
|
+
if (show_row_numbers) {
|
|
424
|
+
parent.style.setProperty(`--cell-width-row-number`, `${widths[0]}px`);
|
|
443
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})`;
|
|
444
438
|
}
|
|
445
439
|
let table_height = values.slice(0, max_height / values.length * 37).length * 37 + 37;
|
|
446
440
|
let scrollbar_width = 0;
|
|
447
441
|
function sort_data(_data, _display_value, _styling, col, dir) {
|
|
448
442
|
let id = null;
|
|
449
|
-
if (selected && selected[0] in
|
|
450
|
-
id =
|
|
443
|
+
if (selected && selected[0] in _data && selected[1] in _data[selected[0]]) {
|
|
444
|
+
id = _data[selected[0]][selected[1]].id;
|
|
451
445
|
}
|
|
452
446
|
if (typeof col !== "number" || !dir) {
|
|
453
447
|
return;
|
|
454
448
|
}
|
|
455
|
-
|
|
456
|
-
if (dir === "asc") {
|
|
457
|
-
indices.sort(
|
|
458
|
-
(i, j) => _data[i][col].value < _data[j][col].value ? -1 : 1
|
|
459
|
-
);
|
|
460
|
-
} else if (dir === "des") {
|
|
461
|
-
indices.sort(
|
|
462
|
-
(i, j) => _data[i][col].value > _data[j][col].value ? -1 : 1
|
|
463
|
-
);
|
|
464
|
-
} else {
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
const temp_data = [..._data];
|
|
468
|
-
const temp_display_value = _display_value ? [..._display_value] : null;
|
|
469
|
-
const temp_styling = _styling ? [..._styling] : null;
|
|
470
|
-
indices.forEach((originalIndex, sortedIndex) => {
|
|
471
|
-
_data[sortedIndex] = temp_data[originalIndex];
|
|
472
|
-
if (_display_value && temp_display_value)
|
|
473
|
-
_display_value[sortedIndex] = temp_display_value[originalIndex];
|
|
474
|
-
if (_styling && temp_styling)
|
|
475
|
-
_styling[sortedIndex] = temp_styling[originalIndex];
|
|
476
|
-
});
|
|
449
|
+
sort_table_data(_data, _display_value, _styling, col, dir);
|
|
477
450
|
data = data;
|
|
478
451
|
if (id) {
|
|
479
|
-
const [i, j] = get_current_indices(id);
|
|
452
|
+
const [i, j] = get_current_indices(id, data);
|
|
480
453
|
selected = [i, j];
|
|
481
454
|
}
|
|
482
455
|
}
|
|
@@ -486,7 +459,7 @@ $:
|
|
|
486
459
|
selected_index = !!selected && selected[0];
|
|
487
460
|
let is_visible = false;
|
|
488
461
|
onMount(() => {
|
|
489
|
-
const observer = new IntersectionObserver((entries
|
|
462
|
+
const observer = new IntersectionObserver((entries) => {
|
|
490
463
|
entries.forEach((entry) => {
|
|
491
464
|
if (entry.isIntersecting && !is_visible) {
|
|
492
465
|
set_cell_widths();
|
|
@@ -509,8 +482,42 @@ onMount(() => {
|
|
|
509
482
|
);
|
|
510
483
|
};
|
|
511
484
|
});
|
|
512
|
-
|
|
513
|
-
|
|
485
|
+
function handle_cell_click(event, row, col) {
|
|
486
|
+
if (event.target instanceof HTMLAnchorElement) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
event.preventDefault();
|
|
490
|
+
event.stopPropagation();
|
|
491
|
+
if (show_row_numbers && col === -1)
|
|
492
|
+
return;
|
|
493
|
+
clear_on_focus = false;
|
|
494
|
+
active_cell_menu = null;
|
|
495
|
+
active_header_menu = null;
|
|
496
|
+
selected_header = false;
|
|
497
|
+
header_edit = false;
|
|
498
|
+
selected_cells = handle_selection([row, col], selected_cells, event);
|
|
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
|
+
}
|
|
513
|
+
}
|
|
514
|
+
toggle_cell_button(row, col);
|
|
515
|
+
dispatch("select", {
|
|
516
|
+
index: [row, col],
|
|
517
|
+
value: get_data_at(row, col),
|
|
518
|
+
row_value: data[row].map((d) => d.value)
|
|
519
|
+
});
|
|
520
|
+
}
|
|
514
521
|
function toggle_cell_menu(event, row, col) {
|
|
515
522
|
event.stopPropagation();
|
|
516
523
|
if (active_cell_menu && active_cell_menu.row === row && active_cell_menu.col === col) {
|
|
@@ -519,12 +526,7 @@ function toggle_cell_menu(event, row, col) {
|
|
|
519
526
|
const cell = event.target.closest("td");
|
|
520
527
|
if (cell) {
|
|
521
528
|
const rect = cell.getBoundingClientRect();
|
|
522
|
-
active_cell_menu = {
|
|
523
|
-
row,
|
|
524
|
-
col,
|
|
525
|
-
x: rect.right,
|
|
526
|
-
y: rect.bottom
|
|
527
|
-
};
|
|
529
|
+
active_cell_menu = { row, col, x: rect.right, y: rect.bottom };
|
|
528
530
|
}
|
|
529
531
|
}
|
|
530
532
|
}
|
|
@@ -543,25 +545,18 @@ function add_col_at(index, position) {
|
|
|
543
545
|
function handle_resize() {
|
|
544
546
|
active_cell_menu = null;
|
|
545
547
|
active_header_menu = null;
|
|
548
|
+
selected_cells = [];
|
|
549
|
+
selected = false;
|
|
550
|
+
editing = false;
|
|
546
551
|
set_cell_widths();
|
|
547
552
|
}
|
|
548
553
|
let active_button = null;
|
|
549
554
|
function toggle_header_button(col) {
|
|
550
|
-
|
|
551
|
-
active_button = null;
|
|
552
|
-
} else {
|
|
553
|
-
active_button = { type: "header", col };
|
|
554
|
-
}
|
|
555
|
+
active_button = active_button?.type === "header" && active_button.col === col ? null : { type: "header", col };
|
|
555
556
|
}
|
|
556
557
|
function toggle_cell_button(row, col) {
|
|
557
|
-
|
|
558
|
-
active_button = null;
|
|
559
|
-
} else {
|
|
560
|
-
active_button = { type: "cell", row, col };
|
|
561
|
-
}
|
|
558
|
+
active_button = active_button?.type === "cell" && active_button.row === row && active_button.col === col ? null : { type: "cell", row, col };
|
|
562
559
|
}
|
|
563
|
-
let active_header_menu = null;
|
|
564
|
-
let is_fullscreen = false;
|
|
565
560
|
function toggle_fullscreen() {
|
|
566
561
|
if (!document.fullscreenElement) {
|
|
567
562
|
parent.requestFullscreen();
|
|
@@ -575,7 +570,11 @@ function handle_fullscreen_change() {
|
|
|
575
570
|
is_fullscreen = !!document.fullscreenElement;
|
|
576
571
|
}
|
|
577
572
|
async function handle_copy() {
|
|
578
|
-
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);
|
|
579
578
|
}
|
|
580
579
|
function toggle_header_menu(event, col) {
|
|
581
580
|
event.stopPropagation();
|
|
@@ -585,11 +584,7 @@ function toggle_header_menu(event, col) {
|
|
|
585
584
|
const header = event.target.closest("th");
|
|
586
585
|
if (header) {
|
|
587
586
|
const rect = header.getBoundingClientRect();
|
|
588
|
-
active_header_menu = {
|
|
589
|
-
col,
|
|
590
|
-
x: rect.right,
|
|
591
|
-
y: rect.bottom
|
|
592
|
-
};
|
|
587
|
+
active_header_menu = { col, x: rect.right, y: rect.bottom };
|
|
593
588
|
}
|
|
594
589
|
}
|
|
595
590
|
}
|
|
@@ -630,6 +625,78 @@ function delete_col_at(index) {
|
|
|
630
625
|
active_cell_menu = null;
|
|
631
626
|
active_header_menu = null;
|
|
632
627
|
}
|
|
628
|
+
let row_order = [];
|
|
629
|
+
$: {
|
|
630
|
+
if (typeof sort_by === "number" && sort_direction && sort_by >= 0 && sort_by < data[0].length) {
|
|
631
|
+
const indices = [...Array(data.length)].map((_, i) => i);
|
|
632
|
+
const sort_index = sort_by;
|
|
633
|
+
indices.sort((a, b) => {
|
|
634
|
+
const row_a = data[a];
|
|
635
|
+
const row_b = data[b];
|
|
636
|
+
if (!row_a || !row_b || sort_index >= row_a.length || sort_index >= row_b.length)
|
|
637
|
+
return 0;
|
|
638
|
+
const val_a = row_a[sort_index].value;
|
|
639
|
+
const val_b = row_b[sort_index].value;
|
|
640
|
+
const comp = val_a < val_b ? -1 : val_a > val_b ? 1 : 0;
|
|
641
|
+
return sort_direction === "asc" ? comp : -comp;
|
|
642
|
+
});
|
|
643
|
+
row_order = indices;
|
|
644
|
+
} else {
|
|
645
|
+
row_order = [...Array(data.length)].map((_, i) => i);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
function handle_select_column(col) {
|
|
649
|
+
selected_cells = select_column(data, col);
|
|
650
|
+
selected = selected_cells[0];
|
|
651
|
+
editing = false;
|
|
652
|
+
}
|
|
653
|
+
function handle_select_row(row) {
|
|
654
|
+
selected_cells = select_row(data, row);
|
|
655
|
+
selected = selected_cells[0];
|
|
656
|
+
editing = false;
|
|
657
|
+
}
|
|
658
|
+
let coords;
|
|
659
|
+
$:
|
|
660
|
+
if (selected !== false)
|
|
661
|
+
coords = selected;
|
|
662
|
+
$:
|
|
663
|
+
if (selected !== false) {
|
|
664
|
+
const positions = calculate_selection_positions(
|
|
665
|
+
selected,
|
|
666
|
+
data,
|
|
667
|
+
els,
|
|
668
|
+
parent,
|
|
669
|
+
table
|
|
670
|
+
);
|
|
671
|
+
document.documentElement.style.setProperty(
|
|
672
|
+
"--selected-col-pos",
|
|
673
|
+
positions.col_pos
|
|
674
|
+
);
|
|
675
|
+
if (positions.row_pos) {
|
|
676
|
+
document.documentElement.style.setProperty(
|
|
677
|
+
"--selected-row-pos",
|
|
678
|
+
positions.row_pos
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
let current_search_query = null;
|
|
683
|
+
function handle_search(search_query) {
|
|
684
|
+
current_search_query = search_query;
|
|
685
|
+
dispatch("search", search_query);
|
|
686
|
+
}
|
|
687
|
+
function commit_filter() {
|
|
688
|
+
if (current_search_query && show_search === "filter") {
|
|
689
|
+
dispatch("change", {
|
|
690
|
+
data: data.map((row) => row.map((cell) => cell.value)),
|
|
691
|
+
headers: _headers.map((h) => h.value),
|
|
692
|
+
metadata: null
|
|
693
|
+
});
|
|
694
|
+
if (!value_is_output) {
|
|
695
|
+
dispatch("input");
|
|
696
|
+
}
|
|
697
|
+
current_search_query = null;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
633
700
|
</script>
|
|
634
701
|
|
|
635
702
|
<svelte:window on:resize={() => set_cell_widths()} />
|
|
@@ -647,6 +714,10 @@ function delete_col_at(index) {
|
|
|
647
714
|
on:click={toggle_fullscreen}
|
|
648
715
|
on_copy={handle_copy}
|
|
649
716
|
{show_copy_button}
|
|
717
|
+
{show_search}
|
|
718
|
+
on:search={(e) => handle_search(e.detail)}
|
|
719
|
+
on_commit_filter={commit_filter}
|
|
720
|
+
{current_search_query}
|
|
650
721
|
/>
|
|
651
722
|
</div>
|
|
652
723
|
<div
|
|
@@ -654,11 +725,28 @@ function delete_col_at(index) {
|
|
|
654
725
|
class="table-wrap"
|
|
655
726
|
class:dragging
|
|
656
727
|
class:no-wrap={!wrap}
|
|
657
|
-
style="height:{table_height}px"
|
|
728
|
+
style="height:{table_height}px;"
|
|
729
|
+
class:menu-open={active_cell_menu || active_header_menu}
|
|
658
730
|
on:keydown={(e) => handle_keydown(e)}
|
|
659
731
|
role="grid"
|
|
660
732
|
tabindex="0"
|
|
661
733
|
>
|
|
734
|
+
{#if selected !== false && selected_cells.length === 1}
|
|
735
|
+
<button
|
|
736
|
+
class="selection-button selection-button-column"
|
|
737
|
+
on:click|stopPropagation={() => handle_select_column(coords[1])}
|
|
738
|
+
aria-label="Select column"
|
|
739
|
+
>
|
|
740
|
+
⋮
|
|
741
|
+
</button>
|
|
742
|
+
<button
|
|
743
|
+
class="selection-button selection-button-row"
|
|
744
|
+
on:click|stopPropagation={() => handle_select_row(coords[0])}
|
|
745
|
+
aria-label="Select row"
|
|
746
|
+
>
|
|
747
|
+
⋮
|
|
748
|
+
</button>
|
|
749
|
+
{/if}
|
|
662
750
|
<table
|
|
663
751
|
bind:contentRect={t_rect}
|
|
664
752
|
bind:this={table}
|
|
@@ -670,39 +758,59 @@ function delete_col_at(index) {
|
|
|
670
758
|
<thead>
|
|
671
759
|
<tr>
|
|
672
760
|
{#if show_row_numbers}
|
|
673
|
-
<th
|
|
761
|
+
<th
|
|
762
|
+
class="row-number-header frozen-column always-frozen"
|
|
763
|
+
style="left: 0;"
|
|
764
|
+
>
|
|
765
|
+
<div class="cell-wrap">
|
|
766
|
+
<div class="header-content">
|
|
767
|
+
<div class="header-text"></div>
|
|
768
|
+
</div>
|
|
769
|
+
</div>
|
|
770
|
+
</th>
|
|
674
771
|
{/if}
|
|
675
772
|
{#each _headers as { value, id }, i (id)}
|
|
676
773
|
<th
|
|
774
|
+
class:frozen-column={i < actual_pinned_columns}
|
|
775
|
+
class:last-frozen={show_row_numbers
|
|
776
|
+
? i === actual_pinned_columns - 1
|
|
777
|
+
: i === actual_pinned_columns - 1}
|
|
677
778
|
class:editing={header_edit === i}
|
|
678
779
|
aria-sort={get_sort_status(value, sort_by, sort_direction)}
|
|
679
|
-
style:
|
|
780
|
+
style="width: {column_widths.length
|
|
781
|
+
? column_widths[i]
|
|
782
|
+
: undefined}; left: {i < actual_pinned_columns
|
|
783
|
+
? i === 0
|
|
784
|
+
? show_row_numbers
|
|
785
|
+
? 'var(--cell-width-row-number)'
|
|
786
|
+
: '0'
|
|
787
|
+
: `calc(${show_row_numbers ? 'var(--cell-width-row-number) + ' : ''}${Array(
|
|
788
|
+
i
|
|
789
|
+
)
|
|
790
|
+
.fill(0)
|
|
791
|
+
.map((_, idx) => `var(--cell-width-${idx})`)
|
|
792
|
+
.join(' + ')})`
|
|
793
|
+
: 'auto'};"
|
|
680
794
|
>
|
|
681
795
|
<div class="cell-wrap">
|
|
682
|
-
<
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
class
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
viewBox="0 0 9 7"
|
|
701
|
-
fill="none"
|
|
702
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
703
|
-
>
|
|
704
|
-
<path d="M4.49999 0L8.3971 6.75H0.602875L4.49999 0Z" />
|
|
705
|
-
</svg>
|
|
796
|
+
<div class="header-content">
|
|
797
|
+
<EditableCell
|
|
798
|
+
{value}
|
|
799
|
+
{latex_delimiters}
|
|
800
|
+
{line_breaks}
|
|
801
|
+
header
|
|
802
|
+
edit={false}
|
|
803
|
+
el={null}
|
|
804
|
+
{root}
|
|
805
|
+
{editable}
|
|
806
|
+
/>
|
|
807
|
+
<div class="sort-buttons">
|
|
808
|
+
<SortIcon
|
|
809
|
+
direction={sort_by === i ? sort_direction : null}
|
|
810
|
+
on:sort={({ detail }) => handle_sort(i, detail)}
|
|
811
|
+
{i18n}
|
|
812
|
+
/>
|
|
813
|
+
</div>
|
|
706
814
|
</div>
|
|
707
815
|
</div>
|
|
708
816
|
</th>
|
|
@@ -722,6 +830,7 @@ function delete_col_at(index) {
|
|
|
722
830
|
edit={false}
|
|
723
831
|
el={null}
|
|
724
832
|
{root}
|
|
833
|
+
{editable}
|
|
725
834
|
/>
|
|
726
835
|
</div>
|
|
727
836
|
</td>
|
|
@@ -737,8 +846,23 @@ function delete_col_at(index) {
|
|
|
737
846
|
boundedheight={false}
|
|
738
847
|
disable_click={true}
|
|
739
848
|
{root}
|
|
740
|
-
on:load={(
|
|
849
|
+
on:load={({ detail }) =>
|
|
850
|
+
handle_file_upload(
|
|
851
|
+
detail.data,
|
|
852
|
+
(head) => {
|
|
853
|
+
_headers = make_headers(
|
|
854
|
+
head.map((h) => h ?? ""),
|
|
855
|
+
col_count,
|
|
856
|
+
els
|
|
857
|
+
);
|
|
858
|
+
return _headers;
|
|
859
|
+
},
|
|
860
|
+
(vals) => {
|
|
861
|
+
values = vals;
|
|
862
|
+
}
|
|
863
|
+
)}
|
|
741
864
|
bind:dragging
|
|
865
|
+
aria_label={i18n("dataframe.drop_to_upload")}
|
|
742
866
|
>
|
|
743
867
|
<VirtualTable
|
|
744
868
|
bind:items={data}
|
|
@@ -746,19 +870,44 @@ function delete_col_at(index) {
|
|
|
746
870
|
bind:actual_height={table_height}
|
|
747
871
|
bind:table_scrollbar_width={scrollbar_width}
|
|
748
872
|
selected={selected_index}
|
|
873
|
+
disable_scroll={active_cell_menu !== null ||
|
|
874
|
+
active_header_menu !== null}
|
|
749
875
|
>
|
|
750
876
|
{#if label && label.length !== 0}
|
|
751
877
|
<caption class="sr-only">{label}</caption>
|
|
752
878
|
{/if}
|
|
753
879
|
<tr slot="thead">
|
|
754
880
|
{#if show_row_numbers}
|
|
755
|
-
<th
|
|
881
|
+
<th
|
|
882
|
+
class="row-number-header frozen-column always-frozen"
|
|
883
|
+
style="left: 0;"
|
|
884
|
+
>
|
|
885
|
+
<div class="cell-wrap">
|
|
886
|
+
<div class="header-content">
|
|
887
|
+
<div class="header-text"></div>
|
|
888
|
+
</div>
|
|
889
|
+
</div>
|
|
890
|
+
</th>
|
|
756
891
|
{/if}
|
|
757
892
|
{#each _headers as { value, id }, i (id)}
|
|
758
893
|
<th
|
|
894
|
+
class:frozen-column={i < actual_pinned_columns}
|
|
895
|
+
class:last-frozen={i === actual_pinned_columns - 1}
|
|
759
896
|
class:focus={header_edit === i || selected_header === i}
|
|
760
897
|
aria-sort={get_sort_status(value, sort_by, sort_direction)}
|
|
761
|
-
style="width:
|
|
898
|
+
style="width: {get_cell_width(i)}; left: {i <
|
|
899
|
+
actual_pinned_columns
|
|
900
|
+
? i === 0
|
|
901
|
+
? show_row_numbers
|
|
902
|
+
? 'var(--cell-width-row-number)'
|
|
903
|
+
: '0'
|
|
904
|
+
: `calc(${show_row_numbers ? 'var(--cell-width-row-number) + ' : ''}${Array(
|
|
905
|
+
i
|
|
906
|
+
)
|
|
907
|
+
.fill(0)
|
|
908
|
+
.map((_, idx) => `var(--cell-width-${idx})`)
|
|
909
|
+
.join(' + ')})`
|
|
910
|
+
: 'auto'};"
|
|
762
911
|
on:click={() => {
|
|
763
912
|
toggle_header_button(i);
|
|
764
913
|
}}
|
|
@@ -766,6 +915,7 @@ function delete_col_at(index) {
|
|
|
766
915
|
<div class="cell-wrap">
|
|
767
916
|
<div class="header-content">
|
|
768
917
|
<EditableCell
|
|
918
|
+
{max_chars}
|
|
769
919
|
bind:value={_headers[i].value}
|
|
770
920
|
bind:el={els[id].input}
|
|
771
921
|
{latex_delimiters}
|
|
@@ -775,84 +925,76 @@ function delete_col_at(index) {
|
|
|
775
925
|
on:dblclick={() => edit_header(i)}
|
|
776
926
|
header
|
|
777
927
|
{root}
|
|
928
|
+
{editable}
|
|
778
929
|
/>
|
|
779
|
-
<
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
handle_sort(i);
|
|
787
|
-
}}
|
|
788
|
-
>
|
|
789
|
-
<svg
|
|
790
|
-
width="1em"
|
|
791
|
-
height="1em"
|
|
792
|
-
viewBox="0 0 9 7"
|
|
793
|
-
fill="none"
|
|
794
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
795
|
-
>
|
|
796
|
-
<path d="M4.49999 0L8.3971 6.75H0.602875L4.49999 0Z" />
|
|
797
|
-
</svg>
|
|
798
|
-
</button>
|
|
930
|
+
<div class="sort-buttons">
|
|
931
|
+
<SortIcon
|
|
932
|
+
direction={sort_by === i ? sort_direction : null}
|
|
933
|
+
on:sort={({ detail }) => handle_sort(i, detail)}
|
|
934
|
+
{i18n}
|
|
935
|
+
/>
|
|
936
|
+
</div>
|
|
799
937
|
</div>
|
|
800
|
-
|
|
801
938
|
{#if editable}
|
|
802
939
|
<button
|
|
803
940
|
class="cell-menu-button"
|
|
804
941
|
on:click={(event) => toggle_header_menu(event, i)}
|
|
805
942
|
>
|
|
806
|
-
|
|
943
|
+
⋮
|
|
807
944
|
</button>
|
|
808
945
|
{/if}
|
|
809
946
|
</div>
|
|
810
947
|
</th>
|
|
811
948
|
{/each}
|
|
812
949
|
</tr>
|
|
813
|
-
|
|
814
950
|
<tr slot="tbody" let:item let:index class:row_odd={index % 2 === 0}>
|
|
815
951
|
{#if show_row_numbers}
|
|
816
|
-
<td
|
|
952
|
+
<td
|
|
953
|
+
class="row-number frozen-column always-frozen"
|
|
954
|
+
style="left: 0;"
|
|
955
|
+
tabindex="-1"
|
|
956
|
+
>
|
|
957
|
+
{index + 1}
|
|
958
|
+
</td>
|
|
817
959
|
{/if}
|
|
818
960
|
{#each item as { value, id }, j (id)}
|
|
819
961
|
<td
|
|
820
|
-
|
|
962
|
+
class:frozen-column={j < actual_pinned_columns}
|
|
963
|
+
class:last-frozen={j === actual_pinned_columns - 1}
|
|
964
|
+
tabindex={show_row_numbers && j === 0 ? -1 : 0}
|
|
965
|
+
bind:this={els[id].cell}
|
|
821
966
|
on:touchstart={(event) => {
|
|
822
|
-
event.
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
}
|
|
832
|
-
toggle_cell_button(index, j);
|
|
967
|
+
const touch = event.touches[0];
|
|
968
|
+
const mouseEvent = new MouseEvent("click", {
|
|
969
|
+
clientX: touch.clientX,
|
|
970
|
+
clientY: touch.clientY,
|
|
971
|
+
bubbles: true,
|
|
972
|
+
cancelable: true,
|
|
973
|
+
view: window
|
|
974
|
+
});
|
|
975
|
+
handle_cell_click(mouseEvent, index, j);
|
|
833
976
|
}}
|
|
834
977
|
on:mousedown={(event) => {
|
|
835
978
|
event.preventDefault();
|
|
836
979
|
event.stopPropagation();
|
|
837
980
|
}}
|
|
838
|
-
on:click={(event) =>
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
class:focus={dequal(selected, [index, j])}
|
|
981
|
+
on:click={(event) => handle_cell_click(event, index, j)}
|
|
982
|
+
style="width: {get_cell_width(j)}; left: {j <
|
|
983
|
+
actual_pinned_columns
|
|
984
|
+
? j === 0
|
|
985
|
+
? show_row_numbers
|
|
986
|
+
? 'var(--cell-width-row-number)'
|
|
987
|
+
: '0'
|
|
988
|
+
: `calc(${show_row_numbers ? 'var(--cell-width-row-number) + ' : ''}${Array(
|
|
989
|
+
j
|
|
990
|
+
)
|
|
991
|
+
.fill(0)
|
|
992
|
+
.map((_, idx) => `var(--cell-width-${idx})`)
|
|
993
|
+
.join(' + ')})`
|
|
994
|
+
: 'auto'}; {styling?.[index]?.[j] || ''}"
|
|
995
|
+
class:flash={copy_flash &&
|
|
996
|
+
is_cell_selected([index, j], selected_cells)}
|
|
997
|
+
class={is_cell_selected([index, j], selected_cells)}
|
|
856
998
|
class:menu-active={active_cell_menu &&
|
|
857
999
|
active_cell_menu.row === index &&
|
|
858
1000
|
active_cell_menu.col === j}
|
|
@@ -871,15 +1013,25 @@ function delete_col_at(index) {
|
|
|
871
1013
|
clear_on_focus = false;
|
|
872
1014
|
parent.focus();
|
|
873
1015
|
}}
|
|
1016
|
+
on:focus={() => {
|
|
1017
|
+
const row = index;
|
|
1018
|
+
const col = j;
|
|
1019
|
+
if (
|
|
1020
|
+
!selected_cells.some(([r, c]) => r === row && c === col)
|
|
1021
|
+
) {
|
|
1022
|
+
selected_cells = [[row, col]];
|
|
1023
|
+
}
|
|
1024
|
+
}}
|
|
874
1025
|
{clear_on_focus}
|
|
875
1026
|
{root}
|
|
1027
|
+
{max_chars}
|
|
876
1028
|
/>
|
|
877
|
-
{#if editable}
|
|
1029
|
+
{#if editable && should_show_cell_menu([index, j], selected_cells, editable)}
|
|
878
1030
|
<button
|
|
879
1031
|
class="cell-menu-button"
|
|
880
1032
|
on:click={(event) => toggle_cell_menu(event, index, j)}
|
|
881
1033
|
>
|
|
882
|
-
|
|
1034
|
+
⋮
|
|
883
1035
|
</button>
|
|
884
1036
|
{/if}
|
|
885
1037
|
</div>
|
|
@@ -931,15 +1083,6 @@ function delete_col_at(index) {
|
|
|
931
1083
|
{/if}
|
|
932
1084
|
|
|
933
1085
|
<style>
|
|
934
|
-
.button-wrap:hover svg {
|
|
935
|
-
color: var(--color-accent);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
.button-wrap svg {
|
|
939
|
-
margin-right: var(--size-1);
|
|
940
|
-
margin-left: -5px;
|
|
941
|
-
}
|
|
942
|
-
|
|
943
1086
|
.label p {
|
|
944
1087
|
position: relative;
|
|
945
1088
|
z-index: var(--layer-4);
|
|
@@ -948,17 +1091,25 @@ function delete_col_at(index) {
|
|
|
948
1091
|
font-size: var(--block-label-text-size);
|
|
949
1092
|
}
|
|
950
1093
|
|
|
1094
|
+
.table-container {
|
|
1095
|
+
display: flex;
|
|
1096
|
+
flex-direction: column;
|
|
1097
|
+
gap: var(--size-2);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
951
1100
|
.table-wrap {
|
|
952
1101
|
position: relative;
|
|
953
1102
|
transition: 150ms;
|
|
954
1103
|
border: 1px solid var(--border-color-primary);
|
|
955
1104
|
border-radius: var(--table-radius);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
.table-wrap.menu-open {
|
|
956
1108
|
overflow: hidden;
|
|
957
1109
|
}
|
|
958
1110
|
|
|
959
1111
|
.table-wrap:focus-within {
|
|
960
1112
|
outline: none;
|
|
961
|
-
background-color: none;
|
|
962
1113
|
}
|
|
963
1114
|
|
|
964
1115
|
.dragging {
|
|
@@ -980,6 +1131,7 @@ function delete_col_at(index) {
|
|
|
980
1131
|
line-height: var(--line-md);
|
|
981
1132
|
font-family: var(--font-mono);
|
|
982
1133
|
border-spacing: 0;
|
|
1134
|
+
border-collapse: separate;
|
|
983
1135
|
}
|
|
984
1136
|
|
|
985
1137
|
div:not(.no-wrap) td {
|
|
@@ -997,8 +1149,7 @@ function delete_col_at(index) {
|
|
|
997
1149
|
thead {
|
|
998
1150
|
position: sticky;
|
|
999
1151
|
top: 0;
|
|
1000
|
-
|
|
1001
|
-
z-index: var(--layer-1);
|
|
1152
|
+
z-index: var(--layer-2);
|
|
1002
1153
|
box-shadow: var(--shadow-drop);
|
|
1003
1154
|
}
|
|
1004
1155
|
|
|
@@ -1034,6 +1185,12 @@ function delete_col_at(index) {
|
|
|
1034
1185
|
th.focus,
|
|
1035
1186
|
td.focus {
|
|
1036
1187
|
--ring-color: var(--color-accent);
|
|
1188
|
+
box-shadow: inset 0 0 0 2px var(--ring-color);
|
|
1189
|
+
z-index: var(--layer-1);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
th.focus {
|
|
1193
|
+
z-index: var(--layer-2);
|
|
1037
1194
|
}
|
|
1038
1195
|
|
|
1039
1196
|
tr:last-child td:first-child {
|
|
@@ -1048,33 +1205,10 @@ function delete_col_at(index) {
|
|
|
1048
1205
|
background: var(--table-even-background-fill);
|
|
1049
1206
|
}
|
|
1050
1207
|
|
|
1051
|
-
|
|
1052
|
-
fill: currentColor;
|
|
1053
|
-
font-size: 10px;
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
.sort-button {
|
|
1208
|
+
.sort-buttons {
|
|
1057
1209
|
display: flex;
|
|
1058
|
-
flex: none;
|
|
1059
|
-
justify-content: center;
|
|
1060
1210
|
align-items: center;
|
|
1061
|
-
|
|
1062
|
-
cursor: pointer;
|
|
1063
|
-
padding: var(--size-2);
|
|
1064
|
-
color: var(--body-text-color-subdued);
|
|
1065
|
-
line-height: var(--text-sm);
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
.sort-button:hover {
|
|
1069
|
-
color: var(--body-text-color);
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
.des {
|
|
1073
|
-
transform: scaleY(-1);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
.sort-button.sorted {
|
|
1077
|
-
color: var(--color-accent);
|
|
1211
|
+
flex-shrink: 0;
|
|
1078
1212
|
}
|
|
1079
1213
|
|
|
1080
1214
|
.editing {
|
|
@@ -1083,25 +1217,26 @@ function delete_col_at(index) {
|
|
|
1083
1217
|
|
|
1084
1218
|
.cell-wrap {
|
|
1085
1219
|
display: flex;
|
|
1086
|
-
align-items:
|
|
1220
|
+
align-items: flex-start;
|
|
1087
1221
|
outline: none;
|
|
1088
|
-
height: var(--size-full);
|
|
1089
1222
|
min-height: var(--size-9);
|
|
1090
|
-
|
|
1223
|
+
position: relative;
|
|
1224
|
+
height: auto;
|
|
1091
1225
|
}
|
|
1092
1226
|
|
|
1093
1227
|
.header-content {
|
|
1094
1228
|
display: flex;
|
|
1095
1229
|
align-items: center;
|
|
1230
|
+
justify-content: space-between;
|
|
1096
1231
|
overflow: hidden;
|
|
1097
1232
|
flex-grow: 1;
|
|
1098
1233
|
min-width: 0;
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1234
|
+
white-space: normal;
|
|
1235
|
+
overflow-wrap: break-word;
|
|
1236
|
+
word-break: normal;
|
|
1237
|
+
height: 100%;
|
|
1238
|
+
padding: var(--size-1);
|
|
1239
|
+
gap: var(--size-1);
|
|
1105
1240
|
}
|
|
1106
1241
|
|
|
1107
1242
|
.row_odd {
|
|
@@ -1112,10 +1247,6 @@ function delete_col_at(index) {
|
|
|
1112
1247
|
background: var(--background-fill-primary);
|
|
1113
1248
|
}
|
|
1114
1249
|
|
|
1115
|
-
table {
|
|
1116
|
-
border-collapse: separate;
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
1250
|
.cell-menu-button {
|
|
1120
1251
|
flex-shrink: 0;
|
|
1121
1252
|
display: none;
|
|
@@ -1128,77 +1259,227 @@ function delete_col_at(index) {
|
|
|
1128
1259
|
padding: 0;
|
|
1129
1260
|
margin-right: var(--spacing-sm);
|
|
1130
1261
|
z-index: var(--layer-1);
|
|
1262
|
+
position: absolute;
|
|
1263
|
+
right: var(--size-1);
|
|
1264
|
+
top: 50%;
|
|
1265
|
+
transform: translateY(-50%);
|
|
1131
1266
|
}
|
|
1132
1267
|
|
|
1133
|
-
.cell-menu-button
|
|
1134
|
-
|
|
1268
|
+
.cell-selected .cell-menu-button {
|
|
1269
|
+
display: flex;
|
|
1270
|
+
align-items: center;
|
|
1271
|
+
justify-content: center;
|
|
1135
1272
|
}
|
|
1136
1273
|
|
|
1137
|
-
|
|
1274
|
+
.header-row {
|
|
1138
1275
|
display: flex;
|
|
1276
|
+
justify-content: flex-end;
|
|
1139
1277
|
align-items: center;
|
|
1140
|
-
|
|
1278
|
+
gap: var(--size-2);
|
|
1279
|
+
min-height: var(--size-6);
|
|
1280
|
+
flex-wrap: nowrap;
|
|
1281
|
+
width: 100%;
|
|
1141
1282
|
}
|
|
1142
1283
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
word-break: break-word;
|
|
1284
|
+
.label {
|
|
1285
|
+
flex: 1 1 auto;
|
|
1286
|
+
margin-right: auto;
|
|
1147
1287
|
}
|
|
1148
1288
|
|
|
1149
|
-
.
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1289
|
+
.label p {
|
|
1290
|
+
margin: 0;
|
|
1291
|
+
color: var(--block-label-text-color);
|
|
1292
|
+
font-size: var(--block-label-text-size);
|
|
1293
|
+
line-height: var(--line-sm);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
.toolbar {
|
|
1297
|
+
flex: 0 0 auto;
|
|
1153
1298
|
}
|
|
1154
1299
|
|
|
1155
1300
|
.row-number,
|
|
1156
1301
|
.row-number-header {
|
|
1157
|
-
width: var(--size-7);
|
|
1158
|
-
min-width: var(--size-7);
|
|
1159
1302
|
text-align: center;
|
|
1160
1303
|
background: var(--table-even-background-fill);
|
|
1161
|
-
position: sticky;
|
|
1162
|
-
left: 0;
|
|
1163
1304
|
font-size: var(--input-text-size);
|
|
1164
1305
|
color: var(--body-text-color);
|
|
1165
|
-
padding: var(--size-1)
|
|
1306
|
+
padding: var(--size-1);
|
|
1307
|
+
min-width: var(--size-12);
|
|
1308
|
+
width: var(--size-12);
|
|
1166
1309
|
overflow: hidden;
|
|
1167
1310
|
text-overflow: ellipsis;
|
|
1168
1311
|
white-space: nowrap;
|
|
1169
1312
|
font-weight: var(--weight-semibold);
|
|
1170
1313
|
}
|
|
1171
1314
|
|
|
1172
|
-
.row-number-header {
|
|
1173
|
-
|
|
1315
|
+
.row-number-header .header-content {
|
|
1316
|
+
justify-content: space-between;
|
|
1317
|
+
padding: var(--size-1);
|
|
1318
|
+
height: var(--size-9);
|
|
1319
|
+
display: flex;
|
|
1320
|
+
align-items: center;
|
|
1174
1321
|
}
|
|
1175
1322
|
|
|
1176
|
-
.row-number {
|
|
1177
|
-
|
|
1323
|
+
.row-number-header :global(.sort-icons) {
|
|
1324
|
+
margin-right: 0;
|
|
1178
1325
|
}
|
|
1179
1326
|
|
|
1180
1327
|
:global(tbody > tr:nth-child(odd)) .row-number {
|
|
1181
1328
|
background: var(--table-odd-background-fill);
|
|
1182
1329
|
}
|
|
1183
1330
|
|
|
1184
|
-
.
|
|
1331
|
+
.cell-selected {
|
|
1332
|
+
--ring-color: var(--color-accent);
|
|
1333
|
+
box-shadow: inset 0 0 0 2px var(--ring-color);
|
|
1334
|
+
z-index: var(--layer-1);
|
|
1335
|
+
position: relative;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
.cell-selected.no-top {
|
|
1339
|
+
box-shadow:
|
|
1340
|
+
inset 2px 0 0 var(--ring-color),
|
|
1341
|
+
inset -2px 0 0 var(--ring-color),
|
|
1342
|
+
inset 0 -2px 0 var(--ring-color);
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
.cell-selected.no-bottom {
|
|
1346
|
+
box-shadow:
|
|
1347
|
+
inset 2px 0 0 var(--ring-color),
|
|
1348
|
+
inset -2px 0 0 var(--ring-color),
|
|
1349
|
+
inset 0 2px 0 var(--ring-color);
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
.cell-selected.no-left {
|
|
1353
|
+
box-shadow:
|
|
1354
|
+
inset 0 2px 0 var(--ring-color),
|
|
1355
|
+
inset -2px 0 0 var(--ring-color),
|
|
1356
|
+
inset 0 -2px 0 var(--ring-color);
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
.cell-selected.no-right {
|
|
1360
|
+
box-shadow:
|
|
1361
|
+
inset 0 2px 0 var(--ring-color),
|
|
1362
|
+
inset 2px 0 0 var(--ring-color),
|
|
1363
|
+
inset 0 -2px 0 var(--ring-color);
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
.cell-selected.no-top.no-left {
|
|
1367
|
+
box-shadow:
|
|
1368
|
+
inset -2px 0 0 var(--ring-color),
|
|
1369
|
+
inset 0 -2px 0 var(--ring-color);
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
.cell-selected.no-top.no-right {
|
|
1373
|
+
box-shadow:
|
|
1374
|
+
inset 2px 0 0 var(--ring-color),
|
|
1375
|
+
inset 0 -2px 0 var(--ring-color);
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
.cell-selected.no-bottom.no-left {
|
|
1379
|
+
box-shadow:
|
|
1380
|
+
inset -2px 0 0 var(--ring-color),
|
|
1381
|
+
inset 0 2px 0 var(--ring-color);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
.cell-selected.no-bottom.no-right {
|
|
1385
|
+
box-shadow:
|
|
1386
|
+
inset 2px 0 0 var(--ring-color),
|
|
1387
|
+
inset 0 2px 0 var(--ring-color);
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
.cell-selected.no-top.no-bottom {
|
|
1391
|
+
box-shadow:
|
|
1392
|
+
inset 2px 0 0 var(--ring-color),
|
|
1393
|
+
inset -2px 0 0 var(--ring-color);
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
.cell-selected.no-left.no-right {
|
|
1397
|
+
box-shadow:
|
|
1398
|
+
inset 0 2px 0 var(--ring-color),
|
|
1399
|
+
inset 0 -2px 0 var(--ring-color);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
.cell-selected.no-top.no-left.no-right {
|
|
1403
|
+
box-shadow: inset 0 -2px 0 var(--ring-color);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
.cell-selected.no-bottom.no-left.no-right {
|
|
1407
|
+
box-shadow: inset 0 2px 0 var(--ring-color);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
.cell-selected.no-left.no-top.no-bottom {
|
|
1411
|
+
box-shadow: inset -2px 0 0 var(--ring-color);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
.cell-selected.no-right.no-top.no-bottom {
|
|
1415
|
+
box-shadow: inset 2px 0 0 var(--ring-color);
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
.cell-selected.no-top.no-bottom.no-left.no-right {
|
|
1419
|
+
box-shadow: none;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
.selection-button {
|
|
1423
|
+
position: absolute;
|
|
1185
1424
|
display: flex;
|
|
1186
|
-
justify-content: space-between;
|
|
1187
1425
|
align-items: center;
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1426
|
+
justify-content: center;
|
|
1427
|
+
background: var(--color-accent);
|
|
1428
|
+
color: white;
|
|
1429
|
+
border-radius: var(--radius-sm);
|
|
1430
|
+
z-index: var(--layer-4);
|
|
1191
1431
|
}
|
|
1192
1432
|
|
|
1193
|
-
.
|
|
1194
|
-
|
|
1433
|
+
.selection-button-column {
|
|
1434
|
+
width: var(--size-3);
|
|
1435
|
+
height: var(--size-5);
|
|
1436
|
+
top: -10px;
|
|
1437
|
+
left: var(--selected-col-pos);
|
|
1438
|
+
transform: rotate(90deg);
|
|
1195
1439
|
}
|
|
1196
1440
|
|
|
1197
|
-
.
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1441
|
+
.selection-button-row {
|
|
1442
|
+
width: var(--size-3);
|
|
1443
|
+
height: var(--size-5);
|
|
1444
|
+
left: -7px;
|
|
1445
|
+
top: calc(var(--selected-row-pos) - var(--size-5) / 2);
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
.table-wrap:not(:focus-within) .selection-button {
|
|
1449
|
+
opacity: 0;
|
|
1450
|
+
pointer-events: none;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
.flash.cell-selected {
|
|
1454
|
+
animation: flash-color 700ms ease-out;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
@keyframes flash-color {
|
|
1458
|
+
0%,
|
|
1459
|
+
30% {
|
|
1460
|
+
background: var(--color-accent-copied);
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
100% {
|
|
1464
|
+
background: transparent;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
.frozen-column {
|
|
1469
|
+
position: sticky;
|
|
1470
|
+
z-index: var(--layer-2);
|
|
1471
|
+
border-right: 1px solid var(--border-color-primary);
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
tr:nth-child(odd) .frozen-column {
|
|
1475
|
+
background: var(--table-odd-background-fill);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
tr:nth-child(even) .frozen-column {
|
|
1479
|
+
background: var(--table-even-background-fill);
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
.always-frozen {
|
|
1483
|
+
z-index: var(--layer-3);
|
|
1203
1484
|
}
|
|
1204
1485
|
</style>
|