@gradio/dataframe 0.16.5 → 0.17.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 +28 -0
- package/Dataframe.stories.svelte +202 -9
- package/Index.svelte +7 -13
- package/dist/Index.svelte +5 -9
- package/dist/Index.svelte.d.ts +9 -2
- package/dist/shared/CellMenu.svelte +53 -1
- package/dist/shared/CellMenu.svelte.d.ts +5 -0
- package/dist/shared/CellMenuButton.svelte +44 -0
- package/dist/shared/CellMenuButton.svelte.d.ts +16 -0
- package/dist/shared/CellMenuIcons.svelte +79 -0
- package/dist/shared/EditableCell.svelte +83 -14
- package/dist/shared/EditableCell.svelte.d.ts +12 -3
- package/dist/shared/EmptyRowButton.svelte +28 -0
- package/dist/shared/EmptyRowButton.svelte.d.ts +16 -0
- package/dist/shared/RowNumber.svelte +40 -0
- package/dist/shared/RowNumber.svelte.d.ts +17 -0
- package/dist/shared/Table.svelte +543 -1110
- package/dist/shared/Table.svelte.d.ts +4 -0
- package/dist/shared/TableCell.svelte +291 -0
- package/dist/shared/TableCell.svelte.d.ts +57 -0
- package/dist/shared/TableHeader.svelte +239 -0
- package/dist/shared/TableHeader.svelte.d.ts +45 -0
- package/dist/shared/Toolbar.svelte +18 -8
- package/dist/shared/VirtualTable.svelte +66 -19
- package/dist/shared/VirtualTable.svelte.d.ts +4 -0
- package/dist/shared/context/keyboard_context.d.ts +37 -0
- package/dist/shared/context/keyboard_context.js +12 -0
- package/dist/shared/context/selection_context.d.ts +32 -0
- package/dist/shared/context/selection_context.js +107 -0
- package/dist/shared/context/table_context.d.ts +141 -0
- package/dist/shared/context/table_context.js +375 -0
- package/dist/shared/icons/Padlock.svelte +24 -0
- package/dist/shared/icons/Padlock.svelte.d.ts +23 -0
- package/dist/shared/icons/SelectionButtons.svelte +85 -0
- package/dist/shared/icons/SelectionButtons.svelte.d.ts +18 -0
- package/dist/shared/icons/SortArrowDown.svelte +24 -0
- package/dist/shared/icons/SortArrowDown.svelte.d.ts +16 -0
- package/dist/shared/icons/SortArrowUp.svelte +24 -0
- package/dist/shared/icons/SortArrowUp.svelte.d.ts +16 -0
- package/dist/shared/icons/SortButtonDown.svelte +14 -0
- package/dist/shared/icons/SortButtonDown.svelte.d.ts +23 -0
- package/dist/shared/icons/SortButtonUp.svelte +15 -0
- package/dist/shared/icons/SortButtonUp.svelte.d.ts +23 -0
- package/dist/shared/icons/SortIcon.svelte +46 -68
- package/dist/shared/icons/SortIcon.svelte.d.ts +3 -2
- package/dist/shared/selection_utils.d.ts +2 -1
- package/dist/shared/selection_utils.js +39 -10
- package/dist/shared/utils/data_processing.d.ts +13 -0
- package/dist/shared/utils/data_processing.js +45 -0
- package/dist/shared/utils/drag_utils.d.ts +15 -0
- package/dist/shared/utils/drag_utils.js +57 -0
- package/dist/shared/utils/keyboard_utils.d.ts +2 -0
- package/dist/shared/utils/keyboard_utils.js +186 -0
- package/dist/shared/utils/sort_utils.d.ts +9 -3
- package/dist/shared/utils/sort_utils.js +30 -24
- package/dist/shared/utils/table_utils.d.ts +6 -5
- package/dist/shared/utils/table_utils.js +13 -56
- package/package.json +8 -8
- package/shared/CellMenu.svelte +52 -1
- package/shared/CellMenuButton.svelte +45 -0
- package/shared/CellMenuIcons.svelte +79 -0
- package/shared/EditableCell.svelte +97 -18
- package/shared/EmptyRowButton.svelte +29 -0
- package/shared/RowNumber.svelte +41 -0
- package/shared/Table.svelte +568 -1223
- package/shared/TableCell.svelte +324 -0
- package/shared/TableHeader.svelte +256 -0
- package/shared/Toolbar.svelte +19 -8
- package/shared/VirtualTable.svelte +72 -19
- package/shared/context/keyboard_context.ts +65 -0
- package/shared/context/selection_context.ts +168 -0
- package/shared/context/table_context.ts +625 -0
- package/shared/icons/Padlock.svelte +24 -0
- package/shared/icons/SelectionButtons.svelte +93 -0
- package/shared/icons/SortArrowDown.svelte +25 -0
- package/shared/icons/SortArrowUp.svelte +25 -0
- package/shared/icons/SortButtonDown.svelte +14 -0
- package/shared/icons/SortButtonUp.svelte +15 -0
- package/shared/icons/SortIcon.svelte +47 -70
- package/shared/selection_utils.ts +39 -13
- package/shared/utils/data_processing.ts +72 -0
- package/shared/utils/drag_utils.ts +92 -0
- package/shared/utils/keyboard_utils.ts +238 -0
- package/shared/utils/sort_utils.test.ts +262 -14
- package/shared/utils/sort_utils.ts +39 -31
- package/shared/utils/table_utils.test.ts +66 -45
- package/shared/utils/table_utils.ts +16 -86
package/dist/shared/Table.svelte
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
|
+
<script context="module">import {
|
|
2
|
+
create_dataframe_context
|
|
3
|
+
} from "./context/table_context";
|
|
4
|
+
import { create_keyboard_context } from "./context/keyboard_context";
|
|
5
|
+
import { create_selection_context } from "./context/selection_context";
|
|
6
|
+
</script>
|
|
7
|
+
|
|
1
8
|
<script>import { afterUpdate, createEventDispatcher, tick, onMount } from "svelte";
|
|
2
9
|
import { dequal } from "dequal/lite";
|
|
3
10
|
import { Upload } from "@gradio/upload";
|
|
4
11
|
import EditableCell from "./EditableCell.svelte";
|
|
12
|
+
import RowNumber from "./RowNumber.svelte";
|
|
13
|
+
import TableHeader from "./TableHeader.svelte";
|
|
14
|
+
import TableCell from "./TableCell.svelte";
|
|
15
|
+
import EmptyRowButton from "./EmptyRowButton.svelte";
|
|
5
16
|
import {} from "@gradio/client";
|
|
6
17
|
import VirtualTable from "./VirtualTable.svelte";
|
|
7
18
|
import CellMenu from "./CellMenu.svelte";
|
|
8
19
|
import Toolbar from "./Toolbar.svelte";
|
|
9
|
-
import SortIcon from "./icons/SortIcon.svelte";
|
|
10
20
|
import {
|
|
11
21
|
is_cell_selected,
|
|
12
|
-
handle_selection,
|
|
13
|
-
handle_delete_key,
|
|
14
22
|
should_show_cell_menu,
|
|
15
23
|
get_next_cell_coordinates,
|
|
16
24
|
get_range_selection,
|
|
17
25
|
move_cursor,
|
|
18
26
|
get_current_indices,
|
|
19
27
|
handle_click_outside as handle_click_outside_util,
|
|
20
|
-
select_column,
|
|
21
|
-
select_row,
|
|
22
28
|
calculate_selection_positions
|
|
23
29
|
} from "./selection_utils";
|
|
24
30
|
import {
|
|
@@ -27,6 +33,11 @@ import {
|
|
|
27
33
|
handle_file_upload,
|
|
28
34
|
sort_table_data
|
|
29
35
|
} from "./utils/table_utils";
|
|
36
|
+
import { make_headers, process_data } from "./utils/data_processing";
|
|
37
|
+
import { handle_keydown } from "./utils/keyboard_utils";
|
|
38
|
+
import {
|
|
39
|
+
create_drag_handlers
|
|
40
|
+
} from "./utils/drag_utils";
|
|
30
41
|
export let datatype;
|
|
31
42
|
export let label = null;
|
|
32
43
|
export let show_label = true;
|
|
@@ -35,6 +46,7 @@ export let values = [];
|
|
|
35
46
|
export let col_count;
|
|
36
47
|
export let row_count;
|
|
37
48
|
export let latex_delimiters;
|
|
49
|
+
export let components = {};
|
|
38
50
|
export let editable = true;
|
|
39
51
|
export let wrap = false;
|
|
40
52
|
export let root;
|
|
@@ -51,27 +63,50 @@ export let value_is_output = false;
|
|
|
51
63
|
export let max_chars = void 0;
|
|
52
64
|
export let show_search = "none";
|
|
53
65
|
export let pinned_columns = 0;
|
|
54
|
-
let
|
|
66
|
+
export let static_columns = [];
|
|
55
67
|
$:
|
|
56
68
|
actual_pinned_columns = pinned_columns && data?.[0]?.length ? Math.min(pinned_columns, data[0].length) : 0;
|
|
57
|
-
|
|
69
|
+
const { state: df_state, actions: df_actions } = create_dataframe_context({
|
|
70
|
+
show_fullscreen_button,
|
|
71
|
+
show_copy_button,
|
|
72
|
+
show_search,
|
|
73
|
+
show_row_numbers,
|
|
74
|
+
editable,
|
|
75
|
+
pinned_columns,
|
|
76
|
+
show_label,
|
|
77
|
+
line_breaks,
|
|
78
|
+
wrap,
|
|
79
|
+
max_height,
|
|
80
|
+
column_widths,
|
|
81
|
+
max_chars
|
|
82
|
+
});
|
|
58
83
|
$:
|
|
59
|
-
selected_cells =
|
|
60
|
-
let
|
|
84
|
+
selected_cells = $df_state.ui_state.selected_cells;
|
|
85
|
+
let previous_selected_cells = [];
|
|
86
|
+
$: {
|
|
87
|
+
if (copy_flash && !dequal(selected_cells, previous_selected_cells)) {
|
|
88
|
+
keyboard_ctx?.set_copy_flash(false);
|
|
89
|
+
}
|
|
90
|
+
previous_selected_cells = selected_cells;
|
|
91
|
+
}
|
|
61
92
|
$:
|
|
62
|
-
selected =
|
|
93
|
+
selected = $df_state.ui_state.selected;
|
|
63
94
|
export let display_value = null;
|
|
64
95
|
export let styling = null;
|
|
65
|
-
let t_rect;
|
|
66
96
|
let els = {};
|
|
67
97
|
let data_binding = {};
|
|
68
98
|
const dispatch = createEventDispatcher();
|
|
69
|
-
|
|
99
|
+
$:
|
|
100
|
+
editing = $df_state.ui_state.editing;
|
|
70
101
|
let clear_on_focus = false;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
102
|
+
$:
|
|
103
|
+
header_edit = $df_state.ui_state.header_edit;
|
|
104
|
+
$:
|
|
105
|
+
selected_header = $df_state.ui_state.selected_header;
|
|
106
|
+
$:
|
|
107
|
+
active_cell_menu = $df_state.ui_state.active_cell_menu;
|
|
108
|
+
$:
|
|
109
|
+
active_header_menu = $df_state.ui_state.active_header_menu;
|
|
75
110
|
let is_fullscreen = false;
|
|
76
111
|
let dragging = false;
|
|
77
112
|
let copy_flash = false;
|
|
@@ -88,278 +123,129 @@ const get_data_at = (row, col) => data?.[row]?.[col]?.value;
|
|
|
88
123
|
function make_id() {
|
|
89
124
|
return Math.random().toString(36).substring(2, 15);
|
|
90
125
|
}
|
|
91
|
-
|
|
92
|
-
let _h = _head || [];
|
|
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}`);
|
|
95
|
-
_h = _h.concat(fill);
|
|
96
|
-
}
|
|
97
|
-
if (!_h || _h.length === 0) {
|
|
98
|
-
return Array(col_count2[0]).fill(0).map((_, i) => {
|
|
99
|
-
const _id = make_id();
|
|
100
|
-
els2[_id] = { cell: null, input: null };
|
|
101
|
-
return { id: _id, value: JSON.stringify(i + 1) };
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
return _h.map((h, i) => {
|
|
105
|
-
const _id = make_id();
|
|
106
|
-
els2[_id] = { cell: null, input: null };
|
|
107
|
-
return { id: _id, value: h ?? "" };
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
function process_data(_values) {
|
|
111
|
-
const data_row_length = _values.length;
|
|
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
|
|
117
|
-
).fill(0).map((_2, j) => {
|
|
118
|
-
const id = make_id();
|
|
119
|
-
els[id] = els[id] || { input: null, cell: null };
|
|
120
|
-
const obj = { value: _values?.[i]?.[j] ?? "", id };
|
|
121
|
-
data_binding[id] = obj;
|
|
122
|
-
return obj;
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
let _headers = make_headers(headers, col_count, els);
|
|
126
|
+
let _headers = make_headers(headers, col_count, els, make_id);
|
|
127
127
|
let old_headers = headers;
|
|
128
128
|
$: {
|
|
129
129
|
if (!dequal(headers, old_headers)) {
|
|
130
|
-
_headers = make_headers(headers, col_count, els);
|
|
130
|
+
_headers = make_headers(headers, col_count, els, make_id);
|
|
131
131
|
old_headers = JSON.parse(JSON.stringify(headers));
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
let data = [[]];
|
|
135
135
|
let old_val = void 0;
|
|
136
|
+
let search_results = [[]];
|
|
136
137
|
$:
|
|
137
138
|
if (!dequal(values, old_val)) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
let previous_headers = _headers.map((h) => h.value);
|
|
142
|
-
let previous_data = data.map((row) => row.map((cell) => String(cell.value)));
|
|
143
|
-
async function trigger_change() {
|
|
144
|
-
if (current_search_query)
|
|
145
|
-
return;
|
|
146
|
-
const current_headers = _headers.map((h) => h.value);
|
|
147
|
-
const current_data = data.map(
|
|
148
|
-
(row) => row.map((cell) => String(cell.value))
|
|
149
|
-
);
|
|
150
|
-
if (!dequal(current_data, previous_data) || !dequal(current_headers, previous_headers)) {
|
|
151
|
-
dispatch("change", {
|
|
152
|
-
data: data.map((row) => row.map((cell) => cell.value)),
|
|
153
|
-
headers: _headers.map((h) => h.value),
|
|
154
|
-
metadata: null
|
|
155
|
-
// the metadata (display value, styling) cannot be changed by the user so we don't need to pass it up
|
|
156
|
-
});
|
|
157
|
-
if (!value_is_output) {
|
|
158
|
-
dispatch("input");
|
|
159
|
-
}
|
|
160
|
-
previous_data = current_data;
|
|
161
|
-
previous_headers = current_headers;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
function get_sort_status(name, _sort, direction) {
|
|
165
|
-
if (!_sort)
|
|
166
|
-
return "none";
|
|
167
|
-
if (headers[_sort] === name) {
|
|
168
|
-
if (direction === "asc")
|
|
169
|
-
return "ascending";
|
|
170
|
-
if (direction === "des")
|
|
171
|
-
return "descending";
|
|
172
|
-
}
|
|
173
|
-
return "none";
|
|
174
|
-
}
|
|
175
|
-
async function handle_keydown(event) {
|
|
176
|
-
if (selected_header !== false && header_edit === false) {
|
|
177
|
-
switch (event.key) {
|
|
178
|
-
case "ArrowDown":
|
|
179
|
-
selected = [0, selected_header];
|
|
180
|
-
selected_cells = [[0, selected_header]];
|
|
181
|
-
selected_header = false;
|
|
182
|
-
return;
|
|
183
|
-
case "ArrowLeft":
|
|
184
|
-
selected_header = selected_header > 0 ? selected_header - 1 : selected_header;
|
|
185
|
-
return;
|
|
186
|
-
case "ArrowRight":
|
|
187
|
-
selected_header = selected_header < _headers.length - 1 ? selected_header + 1 : selected_header;
|
|
188
|
-
return;
|
|
189
|
-
case "Escape":
|
|
190
|
-
event.preventDefault();
|
|
191
|
-
selected_header = false;
|
|
192
|
-
break;
|
|
193
|
-
case "Enter":
|
|
194
|
-
event.preventDefault();
|
|
195
|
-
if (editable) {
|
|
196
|
-
header_edit = selected_header;
|
|
197
|
-
}
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
if (event.key === "Delete" || event.key === "Backspace") {
|
|
202
|
-
if (!editable)
|
|
203
|
-
return;
|
|
204
|
-
if (editing) {
|
|
205
|
-
const [row, col] = editing;
|
|
206
|
-
const input_el = els[data[row][col].id].input;
|
|
207
|
-
if (input_el && input_el.selectionStart !== input_el.selectionEnd) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
if (event.key === "Delete" && input_el?.selectionStart !== input_el?.value.length) {
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
if (event.key === "Backspace" && input_el?.selectionStart !== 0) {
|
|
214
|
-
return;
|
|
139
|
+
if (parent) {
|
|
140
|
+
for (let i = 0; i < 50; i++) {
|
|
141
|
+
parent.style.removeProperty(`--cell-width-${i}`);
|
|
215
142
|
}
|
|
216
143
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
144
|
+
const is_reset = values.length === 0 || values.length === 1 && values[0].length === 0;
|
|
145
|
+
const is_different_structure = old_val !== void 0 && (values.length !== old_val.length || values[0] && old_val[0] && values[0].length !== old_val[0].length);
|
|
146
|
+
data = process_data(
|
|
147
|
+
values,
|
|
148
|
+
els,
|
|
149
|
+
data_binding,
|
|
150
|
+
make_id,
|
|
151
|
+
display_value
|
|
152
|
+
);
|
|
153
|
+
old_val = JSON.parse(JSON.stringify(values));
|
|
154
|
+
if (is_reset || is_different_structure) {
|
|
155
|
+
df_actions.reset_sort_state();
|
|
156
|
+
} else if ($df_state.sort_state.sort_columns.length > 0) {
|
|
157
|
+
sort_data(data, display_value, styling);
|
|
228
158
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
await handle_copy();
|
|
159
|
+
if ($df_state.current_search_query) {
|
|
160
|
+
df_actions.handle_search(null);
|
|
161
|
+
}
|
|
162
|
+
if (parent && cells.length > 0) {
|
|
163
|
+
set_cell_widths();
|
|
235
164
|
}
|
|
236
|
-
return;
|
|
237
165
|
}
|
|
238
|
-
|
|
239
|
-
|
|
166
|
+
$:
|
|
167
|
+
if ($df_state.current_search_query !== void 0) {
|
|
168
|
+
const cell_map = /* @__PURE__ */ new Map();
|
|
169
|
+
data.forEach((row, row_idx) => {
|
|
170
|
+
row.forEach((cell, col_idx) => {
|
|
171
|
+
cell_map.set(cell.id, {
|
|
172
|
+
value: cell.value,
|
|
173
|
+
styling: styling?.[row_idx]?.[col_idx] || ""
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
const filtered = df_actions.filter_data(data);
|
|
178
|
+
search_results = filtered.map(
|
|
179
|
+
(row) => row.map((cell) => {
|
|
180
|
+
const original = cell_map.get(cell.id);
|
|
181
|
+
return {
|
|
182
|
+
...cell,
|
|
183
|
+
display_value: original?.display_value || String(cell.value),
|
|
184
|
+
styling: original?.styling || ""
|
|
185
|
+
};
|
|
186
|
+
})
|
|
187
|
+
);
|
|
240
188
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
next_coords
|
|
256
|
-
);
|
|
257
|
-
editing = false;
|
|
258
|
-
} else {
|
|
259
|
-
selected_cells = [next_coords];
|
|
260
|
-
editing = false;
|
|
261
|
-
}
|
|
262
|
-
selected = next_coords;
|
|
263
|
-
} else if (next_coords === false && event.key === "ArrowUp" && i === 0) {
|
|
264
|
-
selected_header = j;
|
|
265
|
-
selected = false;
|
|
266
|
-
selected_cells = [];
|
|
267
|
-
editing = false;
|
|
268
|
-
}
|
|
269
|
-
break;
|
|
270
|
-
case "Escape":
|
|
271
|
-
if (!editable)
|
|
272
|
-
break;
|
|
273
|
-
event.preventDefault();
|
|
274
|
-
editing = false;
|
|
275
|
-
break;
|
|
276
|
-
case "Enter":
|
|
277
|
-
event.preventDefault();
|
|
278
|
-
if (editable) {
|
|
279
|
-
if (event.shiftKey) {
|
|
280
|
-
add_row(i);
|
|
281
|
-
await tick();
|
|
282
|
-
selected = [i + 1, j];
|
|
283
|
-
} else {
|
|
284
|
-
if (dequal(editing, [i, j])) {
|
|
285
|
-
const cell_id = data[i][j].id;
|
|
286
|
-
const input_el = els[cell_id].input;
|
|
287
|
-
if (input_el) {
|
|
288
|
-
data[i][j].value = input_el.value;
|
|
289
|
-
}
|
|
290
|
-
editing = false;
|
|
291
|
-
await tick();
|
|
292
|
-
selected = [i, j];
|
|
293
|
-
} else {
|
|
294
|
-
editing = [i, j];
|
|
295
|
-
clear_on_focus = false;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
break;
|
|
300
|
-
case "Tab":
|
|
301
|
-
event.preventDefault();
|
|
302
|
-
editing = false;
|
|
303
|
-
const next_cell = get_next_cell_coordinates(
|
|
304
|
-
[i, j],
|
|
305
|
-
data,
|
|
306
|
-
event.shiftKey
|
|
307
|
-
);
|
|
308
|
-
if (next_cell) {
|
|
309
|
-
selected_cells = [next_cell];
|
|
310
|
-
selected = next_cell;
|
|
311
|
-
if (editable) {
|
|
312
|
-
editing = next_cell;
|
|
313
|
-
clear_on_focus = false;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
break;
|
|
317
|
-
default:
|
|
318
|
-
if (!editable)
|
|
319
|
-
break;
|
|
320
|
-
if ((!editing || editing && dequal(editing, [i, j])) && event.key.length === 1) {
|
|
321
|
-
clear_on_focus = true;
|
|
322
|
-
editing = [i, j];
|
|
323
|
-
}
|
|
189
|
+
let previous_headers = _headers.map((h) => h.value);
|
|
190
|
+
let previous_data = data.map((row) => row.map((cell) => String(cell.value)));
|
|
191
|
+
$: {
|
|
192
|
+
if (data || _headers) {
|
|
193
|
+
df_actions.trigger_change(
|
|
194
|
+
data,
|
|
195
|
+
_headers,
|
|
196
|
+
previous_data,
|
|
197
|
+
previous_headers,
|
|
198
|
+
value_is_output,
|
|
199
|
+
dispatch
|
|
200
|
+
);
|
|
201
|
+
previous_data = data.map((row) => row.map((cell) => String(cell.value)));
|
|
202
|
+
previous_headers = _headers.map((h) => h.value);
|
|
324
203
|
}
|
|
325
204
|
}
|
|
326
|
-
let sort_direction;
|
|
327
|
-
let sort_by;
|
|
328
205
|
function handle_sort(col, direction) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
206
|
+
df_actions.handle_sort(col, direction);
|
|
207
|
+
sort_data(data, display_value, styling);
|
|
208
|
+
}
|
|
209
|
+
function clear_sort() {
|
|
210
|
+
df_actions.reset_sort_state();
|
|
211
|
+
sort_data(data, display_value, styling);
|
|
212
|
+
}
|
|
213
|
+
$: {
|
|
214
|
+
df_actions.sort_data(data, display_value, styling);
|
|
215
|
+
df_actions.update_row_order(data);
|
|
216
|
+
}
|
|
217
|
+
$: {
|
|
218
|
+
if ($df_state.sort_state.sort_columns) {
|
|
219
|
+
if ($df_state.sort_state.sort_columns.length > 0) {
|
|
220
|
+
sort_data(data, display_value, styling);
|
|
338
221
|
}
|
|
339
222
|
}
|
|
340
223
|
}
|
|
341
224
|
async function edit_header(i, _select = false) {
|
|
342
225
|
if (!editable || header_edit === i)
|
|
343
226
|
return;
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
227
|
+
if (!editable || col_count[1] !== "dynamic" || header_edit === i)
|
|
228
|
+
return;
|
|
229
|
+
df_actions.set_header_edit(i);
|
|
230
|
+
}
|
|
231
|
+
function handle_header_click(event, col) {
|
|
232
|
+
if (event.target instanceof HTMLAnchorElement) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
event.preventDefault();
|
|
236
|
+
event.stopPropagation();
|
|
237
|
+
if (!editable)
|
|
238
|
+
return;
|
|
239
|
+
clear_on_focus = false;
|
|
240
|
+
df_actions.set_editing(false);
|
|
241
|
+
df_actions.handle_header_click(col, editable);
|
|
242
|
+
parent.focus();
|
|
348
243
|
}
|
|
349
244
|
function end_header_edit(event) {
|
|
350
245
|
if (!editable)
|
|
351
246
|
return;
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
case "Enter":
|
|
355
|
-
case "Tab":
|
|
356
|
-
event.preventDefault();
|
|
357
|
-
selected = false;
|
|
358
|
-
selected_header = header_edit;
|
|
359
|
-
header_edit = false;
|
|
360
|
-
parent.focus();
|
|
361
|
-
break;
|
|
362
|
-
}
|
|
247
|
+
df_actions.end_header_edit(event.detail.key);
|
|
248
|
+
parent.focus();
|
|
363
249
|
}
|
|
364
250
|
async function add_row(index) {
|
|
365
251
|
parent.focus();
|
|
@@ -380,36 +266,32 @@ async function add_row(index) {
|
|
|
380
266
|
data = data;
|
|
381
267
|
selected = [index !== void 0 ? index : data.length - 1, 0];
|
|
382
268
|
}
|
|
383
|
-
$:
|
|
384
|
-
(data || _headers) && trigger_change();
|
|
385
269
|
async function add_col(index) {
|
|
386
270
|
parent.focus();
|
|
387
271
|
if (col_count[1] !== "dynamic")
|
|
388
272
|
return;
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
273
|
+
const result = df_actions.add_col(data, headers, make_id, index);
|
|
274
|
+
result.data.forEach((row) => {
|
|
275
|
+
row.forEach((cell) => {
|
|
276
|
+
if (!els[cell.id]) {
|
|
277
|
+
els[cell.id] = { cell: null, input: null };
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
data = result.data;
|
|
282
|
+
headers = result.headers;
|
|
398
283
|
await tick();
|
|
399
284
|
requestAnimationFrame(() => {
|
|
400
|
-
edit_header(
|
|
285
|
+
edit_header(index !== void 0 ? index : data[0].length - 1, true);
|
|
401
286
|
const new_w = parent.querySelectorAll("tbody")[1].offsetWidth;
|
|
402
287
|
parent.querySelectorAll("table")[1].scrollTo({ left: new_w });
|
|
403
288
|
});
|
|
404
289
|
}
|
|
405
290
|
function handle_click_outside(event) {
|
|
406
291
|
if (handle_click_outside_util(event, parent)) {
|
|
407
|
-
|
|
408
|
-
selected_cells = [];
|
|
292
|
+
df_actions.clear_ui_state();
|
|
409
293
|
header_edit = false;
|
|
410
294
|
selected_header = false;
|
|
411
|
-
active_cell_menu = null;
|
|
412
|
-
active_header_menu = null;
|
|
413
295
|
}
|
|
414
296
|
}
|
|
415
297
|
$:
|
|
@@ -426,30 +308,40 @@ function set_cell_widths() {
|
|
|
426
308
|
if (show_row_numbers) {
|
|
427
309
|
parent.style.setProperty(`--cell-width-row-number`, `${widths[0]}px`);
|
|
428
310
|
}
|
|
429
|
-
|
|
430
|
-
data_cells.forEach((width, i) => {
|
|
311
|
+
for (let i = 0; i < 50; i++) {
|
|
431
312
|
if (!column_widths[i]) {
|
|
432
|
-
parent.style.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
);
|
|
313
|
+
parent.style.removeProperty(`--cell-width-${i}`);
|
|
314
|
+
} else if (column_widths[i].endsWith("%")) {
|
|
315
|
+
const percentage = parseFloat(column_widths[i]);
|
|
316
|
+
const pixel_width = Math.floor(percentage / 100 * parent.clientWidth);
|
|
317
|
+
parent.style.setProperty(`--cell-width-${i}`, `${pixel_width}px`);
|
|
318
|
+
} else {
|
|
319
|
+
parent.style.setProperty(`--cell-width-${i}`, column_widths[i]);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
widths.forEach((width, i) => {
|
|
323
|
+
if (!column_widths[i]) {
|
|
324
|
+
const calculated_width = `${Math.max(width, 45)}px`;
|
|
325
|
+
parent.style.setProperty(`--cell-width-${i}`, calculated_width);
|
|
436
326
|
}
|
|
437
327
|
});
|
|
438
328
|
}
|
|
439
329
|
function get_cell_width(index) {
|
|
440
|
-
return
|
|
330
|
+
return `var(--cell-width-${index})`;
|
|
441
331
|
}
|
|
442
332
|
let table_height = values.slice(0, max_height / values.length * 37).length * 37 + 37;
|
|
443
333
|
let scrollbar_width = 0;
|
|
444
|
-
function sort_data(_data, _display_value, _styling
|
|
334
|
+
function sort_data(_data, _display_value, _styling) {
|
|
445
335
|
let id = null;
|
|
446
336
|
if (selected && selected[0] in _data && selected[1] in _data[selected[0]]) {
|
|
447
337
|
id = _data[selected[0]][selected[1]].id;
|
|
448
338
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
339
|
+
sort_table_data(
|
|
340
|
+
_data,
|
|
341
|
+
_display_value,
|
|
342
|
+
_styling,
|
|
343
|
+
$df_state.sort_state.sort_columns
|
|
344
|
+
);
|
|
453
345
|
data = data;
|
|
454
346
|
if (id) {
|
|
455
347
|
const [i, j] = get_current_indices(id, data);
|
|
@@ -457,7 +349,7 @@ function sort_data(_data, _display_value, _styling, col, dir) {
|
|
|
457
349
|
}
|
|
458
350
|
}
|
|
459
351
|
$:
|
|
460
|
-
sort_data(data, display_value, styling
|
|
352
|
+
sort_data(data, display_value, styling);
|
|
461
353
|
$:
|
|
462
354
|
selected_index = !!selected && selected[0];
|
|
463
355
|
let is_visible = false;
|
|
@@ -485,80 +377,58 @@ onMount(() => {
|
|
|
485
377
|
);
|
|
486
378
|
};
|
|
487
379
|
});
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
editing = false;
|
|
380
|
+
$:
|
|
381
|
+
keyboard_ctx = create_keyboard_context({
|
|
382
|
+
selected_header,
|
|
383
|
+
header_edit,
|
|
384
|
+
editing,
|
|
385
|
+
selected,
|
|
386
|
+
selected_cells,
|
|
387
|
+
editable,
|
|
388
|
+
data,
|
|
389
|
+
headers: _headers,
|
|
390
|
+
els,
|
|
391
|
+
df_actions,
|
|
392
|
+
dispatch,
|
|
393
|
+
add_row,
|
|
394
|
+
get_next_cell_coordinates,
|
|
395
|
+
get_range_selection,
|
|
396
|
+
move_cursor,
|
|
397
|
+
copy_flash,
|
|
398
|
+
parent_element: parent,
|
|
399
|
+
set_copy_flash: (value) => {
|
|
400
|
+
copy_flash = value;
|
|
401
|
+
if (value) {
|
|
402
|
+
setTimeout(() => {
|
|
403
|
+
copy_flash = false;
|
|
404
|
+
}, 800);
|
|
405
|
+
}
|
|
515
406
|
}
|
|
516
|
-
}
|
|
517
|
-
toggle_cell_button(row, col);
|
|
518
|
-
dispatch("select", {
|
|
519
|
-
index: [row, col],
|
|
520
|
-
value: get_data_at(row, col),
|
|
521
|
-
row_value: data[row].map((d) => d.value)
|
|
522
407
|
});
|
|
408
|
+
$:
|
|
409
|
+
selection_ctx = create_selection_context({
|
|
410
|
+
df_actions,
|
|
411
|
+
dispatch,
|
|
412
|
+
data,
|
|
413
|
+
els,
|
|
414
|
+
editable,
|
|
415
|
+
show_row_numbers,
|
|
416
|
+
get_data_at,
|
|
417
|
+
clear_on_focus,
|
|
418
|
+
selected_cells,
|
|
419
|
+
parent_element: parent
|
|
420
|
+
});
|
|
421
|
+
function handle_cell_click(event, row, col) {
|
|
422
|
+
selection_ctx.actions.handle_cell_click(event, row, col);
|
|
523
423
|
}
|
|
524
424
|
function toggle_cell_menu(event, row, col) {
|
|
525
|
-
|
|
526
|
-
if (active_cell_menu && active_cell_menu.row === row && active_cell_menu.col === col) {
|
|
527
|
-
active_cell_menu = null;
|
|
528
|
-
} else {
|
|
529
|
-
const cell = event.target.closest("td");
|
|
530
|
-
if (cell) {
|
|
531
|
-
const rect = cell.getBoundingClientRect();
|
|
532
|
-
active_cell_menu = { row, col, x: rect.right, y: rect.bottom };
|
|
533
|
-
}
|
|
534
|
-
}
|
|
425
|
+
selection_ctx.actions.toggle_cell_menu(event, row, col);
|
|
535
426
|
}
|
|
536
|
-
function
|
|
537
|
-
|
|
538
|
-
add_row(row_index);
|
|
539
|
-
active_cell_menu = null;
|
|
540
|
-
active_header_menu = null;
|
|
541
|
-
}
|
|
542
|
-
function add_col_at(index, position) {
|
|
543
|
-
const col_index = position === "left" ? index : index + 1;
|
|
544
|
-
add_col(col_index);
|
|
545
|
-
active_cell_menu = null;
|
|
546
|
-
active_header_menu = null;
|
|
547
|
-
}
|
|
548
|
-
function handle_resize() {
|
|
549
|
-
active_cell_menu = null;
|
|
550
|
-
active_header_menu = null;
|
|
551
|
-
selected_cells = [];
|
|
552
|
-
selected = false;
|
|
553
|
-
editing = false;
|
|
554
|
-
set_cell_widths();
|
|
555
|
-
}
|
|
556
|
-
let active_button = null;
|
|
557
|
-
function toggle_header_button(col) {
|
|
558
|
-
active_button = active_button?.type === "header" && active_button.col === col ? null : { type: "header", col };
|
|
427
|
+
function handle_select_column(col) {
|
|
428
|
+
selection_ctx.actions.handle_select_column(col);
|
|
559
429
|
}
|
|
560
|
-
function
|
|
561
|
-
|
|
430
|
+
function handle_select_row(row) {
|
|
431
|
+
selection_ctx.actions.handle_select_row(row);
|
|
562
432
|
}
|
|
563
433
|
function toggle_fullscreen() {
|
|
564
434
|
if (!document.fullscreenElement) {
|
|
@@ -572,93 +442,44 @@ function toggle_fullscreen() {
|
|
|
572
442
|
function handle_fullscreen_change() {
|
|
573
443
|
is_fullscreen = !!document.fullscreenElement;
|
|
574
444
|
}
|
|
575
|
-
async function handle_copy() {
|
|
576
|
-
await copy_table_data(data, selected_cells);
|
|
577
|
-
copy_flash = true;
|
|
578
|
-
setTimeout(() => {
|
|
579
|
-
copy_flash = false;
|
|
580
|
-
}, 800);
|
|
581
|
-
}
|
|
582
445
|
function toggle_header_menu(event, col) {
|
|
583
446
|
event.stopPropagation();
|
|
584
447
|
if (active_header_menu && active_header_menu.col === col) {
|
|
585
|
-
|
|
448
|
+
df_actions.set_active_header_menu(null);
|
|
586
449
|
} else {
|
|
587
450
|
const header = event.target.closest("th");
|
|
588
451
|
if (header) {
|
|
589
452
|
const rect = header.getBoundingClientRect();
|
|
590
|
-
|
|
453
|
+
df_actions.set_active_header_menu({
|
|
454
|
+
col,
|
|
455
|
+
x: rect.right,
|
|
456
|
+
y: rect.bottom
|
|
457
|
+
});
|
|
591
458
|
}
|
|
592
459
|
}
|
|
593
460
|
}
|
|
594
461
|
afterUpdate(() => {
|
|
595
462
|
value_is_output = false;
|
|
596
463
|
});
|
|
597
|
-
|
|
598
|
-
parent.focus();
|
|
599
|
-
if (row_count[1] !== "dynamic")
|
|
600
|
-
return;
|
|
601
|
-
if (data.length <= 1)
|
|
602
|
-
return;
|
|
603
|
-
data.splice(index, 1);
|
|
604
|
-
data = data;
|
|
605
|
-
selected = false;
|
|
606
|
-
}
|
|
607
|
-
async function delete_col(index) {
|
|
608
|
-
parent.focus();
|
|
464
|
+
function delete_col_at(index) {
|
|
609
465
|
if (col_count[1] !== "dynamic")
|
|
610
466
|
return;
|
|
611
|
-
if (
|
|
467
|
+
if (data[0].length <= 1)
|
|
612
468
|
return;
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
469
|
+
const result = df_actions.delete_col_at(data, headers, index);
|
|
470
|
+
data = result.data;
|
|
471
|
+
headers = result.headers;
|
|
472
|
+
_headers = make_headers(headers, col_count, els, make_id);
|
|
473
|
+
df_actions.set_active_cell_menu(null);
|
|
474
|
+
df_actions.set_active_header_menu(null);
|
|
475
|
+
df_actions.set_selected(false);
|
|
476
|
+
df_actions.set_selected_cells([]);
|
|
477
|
+
df_actions.set_editing(false);
|
|
622
478
|
}
|
|
623
479
|
function delete_row_at(index) {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
}
|
|
628
|
-
function delete_col_at(index) {
|
|
629
|
-
delete_col(index);
|
|
630
|
-
active_cell_menu = null;
|
|
631
|
-
active_header_menu = null;
|
|
632
|
-
}
|
|
633
|
-
let row_order = [];
|
|
634
|
-
$: {
|
|
635
|
-
if (typeof sort_by === "number" && sort_direction && sort_by >= 0 && sort_by < data[0].length) {
|
|
636
|
-
const indices = [...Array(data.length)].map((_, i) => i);
|
|
637
|
-
const sort_index = sort_by;
|
|
638
|
-
indices.sort((a, b) => {
|
|
639
|
-
const row_a = data[a];
|
|
640
|
-
const row_b = data[b];
|
|
641
|
-
if (!row_a || !row_b || sort_index >= row_a.length || sort_index >= row_b.length)
|
|
642
|
-
return 0;
|
|
643
|
-
const val_a = row_a[sort_index].value;
|
|
644
|
-
const val_b = row_b[sort_index].value;
|
|
645
|
-
const comp = val_a < val_b ? -1 : val_a > val_b ? 1 : 0;
|
|
646
|
-
return sort_direction === "asc" ? comp : -comp;
|
|
647
|
-
});
|
|
648
|
-
row_order = indices;
|
|
649
|
-
} else {
|
|
650
|
-
row_order = [...Array(data.length)].map((_, i) => i);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
function handle_select_column(col) {
|
|
654
|
-
selected_cells = select_column(data, col);
|
|
655
|
-
selected = selected_cells[0];
|
|
656
|
-
editing = false;
|
|
657
|
-
}
|
|
658
|
-
function handle_select_row(row) {
|
|
659
|
-
selected_cells = select_row(data, row);
|
|
660
|
-
selected = selected_cells[0];
|
|
661
|
-
editing = false;
|
|
480
|
+
data = df_actions.delete_row_at(data, index);
|
|
481
|
+
df_actions.set_active_cell_menu(null);
|
|
482
|
+
df_actions.set_active_header_menu(null);
|
|
662
483
|
}
|
|
663
484
|
let coords;
|
|
664
485
|
$:
|
|
@@ -677,48 +498,111 @@ $:
|
|
|
677
498
|
"--selected-col-pos",
|
|
678
499
|
positions.col_pos
|
|
679
500
|
);
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
);
|
|
685
|
-
}
|
|
501
|
+
document.documentElement.style.setProperty(
|
|
502
|
+
"--selected-row-pos",
|
|
503
|
+
positions.row_pos || "0px"
|
|
504
|
+
);
|
|
686
505
|
}
|
|
687
|
-
let current_search_query = null;
|
|
688
|
-
function handle_search(search_query) {
|
|
689
|
-
current_search_query = search_query;
|
|
690
|
-
dispatch("search", search_query);
|
|
691
|
-
}
|
|
692
506
|
function commit_filter() {
|
|
693
|
-
if (current_search_query && show_search === "filter") {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
507
|
+
if ($df_state.current_search_query && show_search === "filter") {
|
|
508
|
+
const filtered_data = [];
|
|
509
|
+
const filtered_display_values = [];
|
|
510
|
+
const filtered_styling = [];
|
|
511
|
+
search_results.forEach((row) => {
|
|
512
|
+
const data_row = [];
|
|
513
|
+
const display_row = [];
|
|
514
|
+
const styling_row = [];
|
|
515
|
+
row.forEach((cell) => {
|
|
516
|
+
data_row.push(cell.value);
|
|
517
|
+
display_row.push(cell.display_value || String(cell.value));
|
|
518
|
+
styling_row.push(cell.styling || "");
|
|
519
|
+
});
|
|
520
|
+
filtered_data.push(data_row);
|
|
521
|
+
filtered_display_values.push(display_row);
|
|
522
|
+
filtered_styling.push(styling_row);
|
|
698
523
|
});
|
|
524
|
+
const change_payload = {
|
|
525
|
+
data: filtered_data,
|
|
526
|
+
headers: _headers.map((h) => h.value),
|
|
527
|
+
metadata: {
|
|
528
|
+
display_value: filtered_display_values,
|
|
529
|
+
styling: filtered_styling
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
dispatch("change", change_payload);
|
|
699
533
|
if (!value_is_output) {
|
|
700
534
|
dispatch("input");
|
|
701
535
|
}
|
|
702
|
-
|
|
536
|
+
df_actions.handle_search(null);
|
|
703
537
|
}
|
|
704
538
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
539
|
+
let viewport;
|
|
540
|
+
let show_scroll_button = false;
|
|
541
|
+
function scroll_to_top() {
|
|
542
|
+
viewport.scrollTo({
|
|
543
|
+
top: 0
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
function handle_resize() {
|
|
547
|
+
df_actions.set_active_cell_menu(null);
|
|
548
|
+
df_actions.set_active_header_menu(null);
|
|
549
|
+
selected_cells = [];
|
|
550
|
+
selected = false;
|
|
551
|
+
editing = false;
|
|
552
|
+
set_cell_widths();
|
|
553
|
+
}
|
|
554
|
+
function add_row_at(index, position) {
|
|
555
|
+
const row_index = position === "above" ? index : index + 1;
|
|
556
|
+
add_row(row_index);
|
|
714
557
|
active_cell_menu = null;
|
|
715
558
|
active_header_menu = null;
|
|
716
|
-
selected = false;
|
|
717
|
-
selected_cells = [];
|
|
718
|
-
selected_header = col;
|
|
719
|
-
header_edit = col;
|
|
720
|
-
parent.focus();
|
|
721
559
|
}
|
|
560
|
+
function add_col_at(index, position) {
|
|
561
|
+
const col_index = position === "left" ? index : index + 1;
|
|
562
|
+
add_col(col_index);
|
|
563
|
+
active_cell_menu = null;
|
|
564
|
+
active_header_menu = null;
|
|
565
|
+
}
|
|
566
|
+
export function reset_sort_state() {
|
|
567
|
+
df_actions.reset_sort_state();
|
|
568
|
+
}
|
|
569
|
+
let is_dragging = false;
|
|
570
|
+
let drag_start = null;
|
|
571
|
+
let mouse_down_pos = null;
|
|
572
|
+
const drag_state = {
|
|
573
|
+
is_dragging,
|
|
574
|
+
drag_start,
|
|
575
|
+
mouse_down_pos
|
|
576
|
+
};
|
|
577
|
+
$: {
|
|
578
|
+
is_dragging = drag_state.is_dragging;
|
|
579
|
+
drag_start = drag_state.drag_start;
|
|
580
|
+
mouse_down_pos = drag_state.mouse_down_pos;
|
|
581
|
+
}
|
|
582
|
+
let drag_handlers;
|
|
583
|
+
function init_drag_handlers() {
|
|
584
|
+
drag_handlers = create_drag_handlers(
|
|
585
|
+
drag_state,
|
|
586
|
+
(value) => is_dragging = value,
|
|
587
|
+
(cells2) => df_actions.set_selected_cells(cells2),
|
|
588
|
+
(cell) => df_actions.set_selected(cell),
|
|
589
|
+
(event, row, col) => selection_ctx.actions.handle_cell_click(event, row, col),
|
|
590
|
+
show_row_numbers,
|
|
591
|
+
parent
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
$:
|
|
595
|
+
if (parent)
|
|
596
|
+
init_drag_handlers();
|
|
597
|
+
$:
|
|
598
|
+
handle_mouse_down = drag_handlers?.handle_mouse_down || (() => {
|
|
599
|
+
});
|
|
600
|
+
$:
|
|
601
|
+
handle_mouse_move = drag_handlers?.handle_mouse_move || (() => {
|
|
602
|
+
});
|
|
603
|
+
$:
|
|
604
|
+
handle_mouse_up = drag_handlers?.handle_mouse_up || (() => {
|
|
605
|
+
});
|
|
722
606
|
</script>
|
|
723
607
|
|
|
724
608
|
<svelte:window on:resize={() => set_cell_widths()} />
|
|
@@ -735,140 +619,70 @@ function handle_header_click(event, col) {
|
|
|
735
619
|
{show_fullscreen_button}
|
|
736
620
|
{is_fullscreen}
|
|
737
621
|
on:click={toggle_fullscreen}
|
|
738
|
-
on_copy={
|
|
622
|
+
on_copy={async () => await copy_table_data(data, null)}
|
|
739
623
|
{show_copy_button}
|
|
740
624
|
{show_search}
|
|
741
|
-
on:search={(e) => handle_search(e.detail)}
|
|
625
|
+
on:search={(e) => df_actions.handle_search(e.detail)}
|
|
742
626
|
on_commit_filter={commit_filter}
|
|
743
|
-
{current_search_query}
|
|
627
|
+
current_search_query={$df_state.current_search_query}
|
|
744
628
|
/>
|
|
745
629
|
</div>
|
|
746
630
|
{/if}
|
|
747
631
|
<div
|
|
748
632
|
bind:this={parent}
|
|
749
633
|
class="table-wrap"
|
|
750
|
-
class:dragging
|
|
634
|
+
class:dragging={is_dragging}
|
|
751
635
|
class:no-wrap={!wrap}
|
|
752
636
|
style="height:{table_height}px;"
|
|
753
637
|
class:menu-open={active_cell_menu || active_header_menu}
|
|
754
|
-
on:keydown={(e) => handle_keydown(e)}
|
|
638
|
+
on:keydown={(e) => handle_keydown(e, keyboard_ctx)}
|
|
639
|
+
on:mousemove={handle_mouse_move}
|
|
640
|
+
on:mouseup={handle_mouse_up}
|
|
641
|
+
on:mouseleave={handle_mouse_up}
|
|
755
642
|
role="grid"
|
|
756
643
|
tabindex="0"
|
|
757
644
|
>
|
|
758
|
-
{
|
|
759
|
-
<button
|
|
760
|
-
class="selection-button selection-button-column"
|
|
761
|
-
on:click|stopPropagation={() => handle_select_column(coords[1])}
|
|
762
|
-
aria-label="Select column"
|
|
763
|
-
>
|
|
764
|
-
⋮
|
|
765
|
-
</button>
|
|
766
|
-
<button
|
|
767
|
-
class="selection-button selection-button-row"
|
|
768
|
-
on:click|stopPropagation={() => handle_select_row(coords[0])}
|
|
769
|
-
aria-label="Select row"
|
|
770
|
-
>
|
|
771
|
-
⋮
|
|
772
|
-
</button>
|
|
773
|
-
{/if}
|
|
774
|
-
<table
|
|
775
|
-
bind:contentRect={t_rect}
|
|
776
|
-
bind:this={table}
|
|
777
|
-
class:fixed-layout={column_widths.length != 0}
|
|
778
|
-
>
|
|
645
|
+
<table bind:this={table}>
|
|
779
646
|
{#if label && label.length !== 0}
|
|
780
647
|
<caption class="sr-only">{label}</caption>
|
|
781
648
|
{/if}
|
|
782
649
|
<thead>
|
|
783
650
|
<tr>
|
|
784
651
|
{#if show_row_numbers}
|
|
785
|
-
<
|
|
786
|
-
class="row-number-header frozen-column always-frozen"
|
|
787
|
-
style="left: 0;"
|
|
788
|
-
>
|
|
789
|
-
<div class="cell-wrap">
|
|
790
|
-
<div class="header-content">
|
|
791
|
-
<div class="header-text"></div>
|
|
792
|
-
</div>
|
|
793
|
-
</div>
|
|
794
|
-
</th>
|
|
652
|
+
<RowNumber is_header={true} />
|
|
795
653
|
{/if}
|
|
796
654
|
{#each _headers as { value, id }, i (id)}
|
|
797
|
-
<
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
>
|
|
821
|
-
<div class="cell-wrap">
|
|
822
|
-
<div class="header-content">
|
|
823
|
-
<EditableCell
|
|
824
|
-
{max_chars}
|
|
825
|
-
bind:value={_headers[i].value}
|
|
826
|
-
bind:el={els[id].input}
|
|
827
|
-
{latex_delimiters}
|
|
828
|
-
{line_breaks}
|
|
829
|
-
edit={header_edit === i}
|
|
830
|
-
on:keydown={end_header_edit}
|
|
831
|
-
header
|
|
832
|
-
{root}
|
|
833
|
-
{editable}
|
|
834
|
-
/>
|
|
835
|
-
{#if header_edit !== i}
|
|
836
|
-
<div class="sort-buttons">
|
|
837
|
-
<SortIcon
|
|
838
|
-
direction={sort_by === i ? sort_direction : null}
|
|
839
|
-
on:sort={({ detail }) => handle_sort(i, detail)}
|
|
840
|
-
{i18n}
|
|
841
|
-
/>
|
|
842
|
-
</div>
|
|
843
|
-
{/if}
|
|
844
|
-
</div>
|
|
845
|
-
{#if editable}
|
|
846
|
-
<button
|
|
847
|
-
class="cell-menu-button"
|
|
848
|
-
on:click={(event) => toggle_header_menu(event, i)}
|
|
849
|
-
on:touchstart={(event) => {
|
|
850
|
-
event.preventDefault();
|
|
851
|
-
const touch = event.touches[0];
|
|
852
|
-
const mouseEvent = new MouseEvent("click", {
|
|
853
|
-
clientX: touch.clientX,
|
|
854
|
-
clientY: touch.clientY,
|
|
855
|
-
bubbles: true,
|
|
856
|
-
cancelable: true,
|
|
857
|
-
view: window
|
|
858
|
-
});
|
|
859
|
-
toggle_header_menu(mouseEvent, i);
|
|
860
|
-
}}
|
|
861
|
-
>
|
|
862
|
-
⋮
|
|
863
|
-
</button>
|
|
864
|
-
{/if}
|
|
865
|
-
</div>
|
|
866
|
-
</th>
|
|
655
|
+
<TableHeader
|
|
656
|
+
bind:value={_headers[i].value}
|
|
657
|
+
{i}
|
|
658
|
+
{actual_pinned_columns}
|
|
659
|
+
{header_edit}
|
|
660
|
+
{selected_header}
|
|
661
|
+
get_sort_status={df_actions.get_sort_status}
|
|
662
|
+
{headers}
|
|
663
|
+
{get_cell_width}
|
|
664
|
+
{handle_header_click}
|
|
665
|
+
{toggle_header_menu}
|
|
666
|
+
{end_header_edit}
|
|
667
|
+
sort_columns={$df_state.sort_state.sort_columns}
|
|
668
|
+
{latex_delimiters}
|
|
669
|
+
{line_breaks}
|
|
670
|
+
{max_chars}
|
|
671
|
+
{root}
|
|
672
|
+
{editable}
|
|
673
|
+
is_static={static_columns.includes(i)}
|
|
674
|
+
{i18n}
|
|
675
|
+
bind:el={els[id].input}
|
|
676
|
+
{col_count}
|
|
677
|
+
/>
|
|
867
678
|
{/each}
|
|
868
679
|
</tr>
|
|
869
680
|
</thead>
|
|
870
681
|
<tbody>
|
|
871
682
|
<tr>
|
|
683
|
+
{#if show_row_numbers}
|
|
684
|
+
<RowNumber index={0} />
|
|
685
|
+
{/if}
|
|
872
686
|
{#each max as { value, id }, j (id)}
|
|
873
687
|
<td tabindex="-1" bind:this={cells[j]}>
|
|
874
688
|
<div class="cell-wrap">
|
|
@@ -881,6 +695,14 @@ function handle_header_click(event, col) {
|
|
|
881
695
|
el={null}
|
|
882
696
|
{root}
|
|
883
697
|
{editable}
|
|
698
|
+
{i18n}
|
|
699
|
+
show_selection_buttons={selected_cells.length === 1 &&
|
|
700
|
+
selected_cells[0][0] === 0 &&
|
|
701
|
+
selected_cells[0][1] === j}
|
|
702
|
+
coords={[0, j]}
|
|
703
|
+
on_select_column={handle_select_column}
|
|
704
|
+
on_select_row={handle_select_row}
|
|
705
|
+
{is_dragging}
|
|
884
706
|
/>
|
|
885
707
|
</div>
|
|
886
708
|
</td>
|
|
@@ -903,7 +725,8 @@ function handle_header_click(event, col) {
|
|
|
903
725
|
_headers = make_headers(
|
|
904
726
|
head.map((h) => h ?? ""),
|
|
905
727
|
col_count,
|
|
906
|
-
els
|
|
728
|
+
els,
|
|
729
|
+
make_id
|
|
907
730
|
);
|
|
908
731
|
return _headers;
|
|
909
732
|
},
|
|
@@ -916,258 +739,159 @@ function handle_header_click(event, col) {
|
|
|
916
739
|
>
|
|
917
740
|
<div class="table-wrap">
|
|
918
741
|
<VirtualTable
|
|
919
|
-
bind:items={
|
|
742
|
+
bind:items={search_results}
|
|
920
743
|
{max_height}
|
|
921
744
|
bind:actual_height={table_height}
|
|
922
745
|
bind:table_scrollbar_width={scrollbar_width}
|
|
923
746
|
selected={selected_index}
|
|
924
747
|
disable_scroll={active_cell_menu !== null ||
|
|
925
748
|
active_header_menu !== null}
|
|
749
|
+
bind:viewport
|
|
750
|
+
bind:show_scroll_button
|
|
751
|
+
on:scroll_top={(_) => {}}
|
|
926
752
|
>
|
|
927
753
|
{#if label && label.length !== 0}
|
|
928
754
|
<caption class="sr-only">{label}</caption>
|
|
929
755
|
{/if}
|
|
930
756
|
<tr slot="thead">
|
|
931
757
|
{#if show_row_numbers}
|
|
932
|
-
<
|
|
933
|
-
class="row-number-header frozen-column always-frozen"
|
|
934
|
-
style="left: 0;"
|
|
935
|
-
>
|
|
936
|
-
<div class="cell-wrap">
|
|
937
|
-
<div class="header-content">
|
|
938
|
-
<div class="header-text"></div>
|
|
939
|
-
</div>
|
|
940
|
-
</div>
|
|
941
|
-
</th>
|
|
758
|
+
<RowNumber is_header={true} />
|
|
942
759
|
{/if}
|
|
943
760
|
{#each _headers as { value, id }, i (id)}
|
|
944
|
-
<
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
>
|
|
968
|
-
<div class="cell-wrap">
|
|
969
|
-
<div class="header-content">
|
|
970
|
-
<EditableCell
|
|
971
|
-
{max_chars}
|
|
972
|
-
bind:value={_headers[i].value}
|
|
973
|
-
bind:el={els[id].input}
|
|
974
|
-
{latex_delimiters}
|
|
975
|
-
{line_breaks}
|
|
976
|
-
edit={header_edit === i}
|
|
977
|
-
header
|
|
978
|
-
{root}
|
|
979
|
-
{editable}
|
|
980
|
-
/>
|
|
981
|
-
{#if header_edit !== i}
|
|
982
|
-
<div class="sort-buttons">
|
|
983
|
-
<SortIcon
|
|
984
|
-
direction={sort_by === i ? sort_direction : null}
|
|
985
|
-
on:sort={({ detail }) => handle_sort(i, detail)}
|
|
986
|
-
{i18n}
|
|
987
|
-
/>
|
|
988
|
-
</div>
|
|
989
|
-
{/if}
|
|
990
|
-
</div>
|
|
991
|
-
{#if editable}
|
|
992
|
-
<button
|
|
993
|
-
class="cell-menu-button"
|
|
994
|
-
on:click={(event) => toggle_header_menu(event, i)}
|
|
995
|
-
on:touchstart={(event) => {
|
|
996
|
-
event.preventDefault();
|
|
997
|
-
const touch = event.touches[0];
|
|
998
|
-
const mouseEvent = new MouseEvent("click", {
|
|
999
|
-
clientX: touch.clientX,
|
|
1000
|
-
clientY: touch.clientY,
|
|
1001
|
-
bubbles: true,
|
|
1002
|
-
cancelable: true,
|
|
1003
|
-
view: window
|
|
1004
|
-
});
|
|
1005
|
-
toggle_header_menu(mouseEvent, i);
|
|
1006
|
-
}}
|
|
1007
|
-
>
|
|
1008
|
-
⋮
|
|
1009
|
-
</button>
|
|
1010
|
-
{/if}
|
|
1011
|
-
</div>
|
|
1012
|
-
</th>
|
|
761
|
+
<TableHeader
|
|
762
|
+
bind:value={_headers[i].value}
|
|
763
|
+
{i}
|
|
764
|
+
{actual_pinned_columns}
|
|
765
|
+
{header_edit}
|
|
766
|
+
{selected_header}
|
|
767
|
+
get_sort_status={df_actions.get_sort_status}
|
|
768
|
+
{headers}
|
|
769
|
+
{get_cell_width}
|
|
770
|
+
{handle_header_click}
|
|
771
|
+
{toggle_header_menu}
|
|
772
|
+
{end_header_edit}
|
|
773
|
+
sort_columns={$df_state.sort_state.sort_columns}
|
|
774
|
+
{latex_delimiters}
|
|
775
|
+
{line_breaks}
|
|
776
|
+
{max_chars}
|
|
777
|
+
{root}
|
|
778
|
+
{editable}
|
|
779
|
+
is_static={static_columns.includes(i)}
|
|
780
|
+
{i18n}
|
|
781
|
+
bind:el={els[id].input}
|
|
782
|
+
{col_count}
|
|
783
|
+
/>
|
|
1013
784
|
{/each}
|
|
1014
785
|
</tr>
|
|
1015
|
-
<tr slot="tbody" let:item let:index class:
|
|
786
|
+
<tr slot="tbody" let:item let:index class:row-odd={index % 2 === 0}>
|
|
1016
787
|
{#if show_row_numbers}
|
|
1017
|
-
<
|
|
1018
|
-
class="row-number frozen-column always-frozen"
|
|
1019
|
-
style="left: 0;"
|
|
1020
|
-
tabindex="-1"
|
|
1021
|
-
>
|
|
1022
|
-
{index + 1}
|
|
1023
|
-
</td>
|
|
788
|
+
<RowNumber {index} />
|
|
1024
789
|
{/if}
|
|
1025
790
|
{#each item as { value, id }, j (id)}
|
|
1026
|
-
<
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
.fill(0)
|
|
1057
|
-
.map((_, idx) => `var(--cell-width-${idx})`)
|
|
1058
|
-
.join(' + ')})`
|
|
1059
|
-
: 'auto'}; {styling?.[index]?.[j] || ''}"
|
|
1060
|
-
class:flash={copy_flash &&
|
|
1061
|
-
is_cell_selected([index, j], selected_cells)}
|
|
1062
|
-
class={is_cell_selected([index, j], selected_cells)}
|
|
1063
|
-
class:menu-active={active_cell_menu &&
|
|
1064
|
-
active_cell_menu.row === index &&
|
|
1065
|
-
active_cell_menu.col === j}
|
|
1066
|
-
>
|
|
1067
|
-
<div class="cell-wrap">
|
|
1068
|
-
<EditableCell
|
|
1069
|
-
bind:value={data[index][j].value}
|
|
1070
|
-
bind:el={els[id].input}
|
|
1071
|
-
display_value={display_value?.[index]?.[j]}
|
|
1072
|
-
{latex_delimiters}
|
|
1073
|
-
{line_breaks}
|
|
1074
|
-
{editable}
|
|
1075
|
-
edit={dequal(editing, [index, j])}
|
|
1076
|
-
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
1077
|
-
on:blur={() => {
|
|
1078
|
-
clear_on_focus = false;
|
|
1079
|
-
parent.focus();
|
|
1080
|
-
}}
|
|
1081
|
-
on:focus={() => {
|
|
1082
|
-
const row = index;
|
|
1083
|
-
const col = j;
|
|
1084
|
-
if (
|
|
1085
|
-
!selected_cells.some(([r, c]) => r === row && c === col)
|
|
1086
|
-
) {
|
|
1087
|
-
selected_cells = [[row, col]];
|
|
1088
|
-
}
|
|
1089
|
-
}}
|
|
1090
|
-
{clear_on_focus}
|
|
1091
|
-
{root}
|
|
1092
|
-
{max_chars}
|
|
1093
|
-
/>
|
|
1094
|
-
{#if editable && should_show_cell_menu([index, j], selected_cells, editable)}
|
|
1095
|
-
<button
|
|
1096
|
-
class="cell-menu-button"
|
|
1097
|
-
on:click={(event) => toggle_cell_menu(event, index, j)}
|
|
1098
|
-
>
|
|
1099
|
-
⋮
|
|
1100
|
-
</button>
|
|
1101
|
-
{/if}
|
|
1102
|
-
</div>
|
|
1103
|
-
</td>
|
|
791
|
+
<TableCell
|
|
792
|
+
bind:value={search_results[index][j].value}
|
|
793
|
+
{index}
|
|
794
|
+
{j}
|
|
795
|
+
{actual_pinned_columns}
|
|
796
|
+
{get_cell_width}
|
|
797
|
+
handle_cell_click={(e, r, c) => handle_mouse_down(e, r, c)}
|
|
798
|
+
{toggle_cell_menu}
|
|
799
|
+
{is_cell_selected}
|
|
800
|
+
{should_show_cell_menu}
|
|
801
|
+
{selected_cells}
|
|
802
|
+
{copy_flash}
|
|
803
|
+
{active_cell_menu}
|
|
804
|
+
styling={search_results[index][j].styling}
|
|
805
|
+
{latex_delimiters}
|
|
806
|
+
{line_breaks}
|
|
807
|
+
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
808
|
+
{editing}
|
|
809
|
+
{clear_on_focus}
|
|
810
|
+
{max_chars}
|
|
811
|
+
{root}
|
|
812
|
+
{editable}
|
|
813
|
+
is_static={static_columns.includes(j)}
|
|
814
|
+
{i18n}
|
|
815
|
+
{components}
|
|
816
|
+
{handle_select_column}
|
|
817
|
+
{handle_select_row}
|
|
818
|
+
bind:el={els[id]}
|
|
819
|
+
{is_dragging}
|
|
820
|
+
/>
|
|
1104
821
|
{/each}
|
|
1105
822
|
</tr>
|
|
1106
823
|
</VirtualTable>
|
|
1107
824
|
</div>
|
|
1108
825
|
</Upload>
|
|
826
|
+
{#if show_scroll_button}
|
|
827
|
+
<button class="scroll-top-button" on:click={scroll_to_top}>
|
|
828
|
+
↑
|
|
829
|
+
</button>
|
|
830
|
+
{/if}
|
|
1109
831
|
</div>
|
|
1110
832
|
</div>
|
|
1111
833
|
{#if data.length === 0 && editable && row_count[1] === "dynamic"}
|
|
1112
|
-
<
|
|
1113
|
-
<button class="add-row-button" on:click={() => add_row()}>
|
|
1114
|
-
<span>+</span>
|
|
1115
|
-
</button>
|
|
1116
|
-
</div>
|
|
834
|
+
<EmptyRowButton on_click={() => add_row()} />
|
|
1117
835
|
{/if}
|
|
1118
836
|
|
|
1119
|
-
{#if active_cell_menu}
|
|
837
|
+
{#if active_cell_menu || active_header_menu}
|
|
1120
838
|
<CellMenu
|
|
1121
|
-
x={active_cell_menu
|
|
1122
|
-
y={active_cell_menu
|
|
1123
|
-
row={active_cell_menu
|
|
1124
|
-
{col_count}
|
|
1125
|
-
{row_count}
|
|
1126
|
-
on_add_row_above={() => add_row_at(active_cell_menu?.row || 0, "above")}
|
|
1127
|
-
on_add_row_below={() => add_row_at(active_cell_menu?.row || 0, "below")}
|
|
1128
|
-
on_add_column_left={() => add_col_at(active_cell_menu?.col || 0, "left")}
|
|
1129
|
-
on_add_column_right={() => add_col_at(active_cell_menu?.col || 0, "right")}
|
|
1130
|
-
on_delete_row={() => delete_row_at(active_cell_menu?.row || 0)}
|
|
1131
|
-
on_delete_col={() => delete_col_at(active_cell_menu?.col || 0)}
|
|
1132
|
-
can_delete_rows={data.length > 1}
|
|
1133
|
-
can_delete_cols={data[0].length > 1}
|
|
1134
|
-
{i18n}
|
|
1135
|
-
/>
|
|
1136
|
-
{/if}
|
|
1137
|
-
|
|
1138
|
-
{#if active_header_menu !== null}
|
|
1139
|
-
<CellMenu
|
|
1140
|
-
{i18n}
|
|
1141
|
-
x={active_header_menu.x}
|
|
1142
|
-
y={active_header_menu.y}
|
|
1143
|
-
row={-1}
|
|
839
|
+
x={active_cell_menu?.x ?? active_header_menu?.x ?? 0}
|
|
840
|
+
y={active_cell_menu?.y ?? active_header_menu?.y ?? 0}
|
|
841
|
+
row={active_header_menu ? -1 : active_cell_menu?.row ?? 0}
|
|
1144
842
|
{col_count}
|
|
1145
843
|
{row_count}
|
|
1146
844
|
on_add_row_above={() => add_row_at(active_cell_menu?.row ?? -1, "above")}
|
|
1147
845
|
on_add_row_below={() => add_row_at(active_cell_menu?.row ?? -1, "below")}
|
|
1148
|
-
on_add_column_left={() =>
|
|
846
|
+
on_add_column_left={() =>
|
|
847
|
+
add_col_at(
|
|
848
|
+
active_cell_menu?.col ?? active_header_menu?.col ?? -1,
|
|
849
|
+
"left"
|
|
850
|
+
)}
|
|
1149
851
|
on_add_column_right={() =>
|
|
1150
|
-
add_col_at(
|
|
852
|
+
add_col_at(
|
|
853
|
+
active_cell_menu?.col ?? active_header_menu?.col ?? -1,
|
|
854
|
+
"right"
|
|
855
|
+
)}
|
|
1151
856
|
on_delete_row={() => delete_row_at(active_cell_menu?.row ?? -1)}
|
|
1152
|
-
on_delete_col={() =>
|
|
1153
|
-
|
|
1154
|
-
|
|
857
|
+
on_delete_col={() =>
|
|
858
|
+
delete_col_at(active_cell_menu?.col ?? active_header_menu?.col ?? -1)}
|
|
859
|
+
can_delete_rows={!active_header_menu && data.length > 1}
|
|
860
|
+
can_delete_cols={data.length > 0 && data[0]?.length > 1}
|
|
861
|
+
{i18n}
|
|
862
|
+
on_sort={active_header_menu
|
|
863
|
+
? (direction) => {
|
|
864
|
+
if (active_header_menu) {
|
|
865
|
+
handle_sort(active_header_menu.col, direction);
|
|
866
|
+
df_actions.set_active_header_menu(null);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
: undefined}
|
|
870
|
+
on_clear_sort={active_header_menu
|
|
871
|
+
? () => {
|
|
872
|
+
clear_sort();
|
|
873
|
+
df_actions.set_active_header_menu(null);
|
|
874
|
+
}
|
|
875
|
+
: undefined}
|
|
876
|
+
sort_direction={active_header_menu
|
|
877
|
+
? $df_state.sort_state.sort_columns.find(
|
|
878
|
+
(item) => item.col === (active_header_menu?.col ?? -1)
|
|
879
|
+
)?.direction ?? null
|
|
880
|
+
: null}
|
|
881
|
+
sort_priority={active_header_menu
|
|
882
|
+
? $df_state.sort_state.sort_columns.findIndex(
|
|
883
|
+
(item) => item.col === (active_header_menu?.col ?? -1)
|
|
884
|
+
) + 1 || null
|
|
885
|
+
: null}
|
|
1155
886
|
/>
|
|
1156
887
|
{/if}
|
|
1157
888
|
|
|
1158
889
|
<style>
|
|
1159
|
-
.label p {
|
|
1160
|
-
position: relative;
|
|
1161
|
-
z-index: var(--layer-4);
|
|
1162
|
-
margin-bottom: var(--size-2);
|
|
1163
|
-
color: var(--block-label-text-color);
|
|
1164
|
-
font-size: var(--block-label-text-size);
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
890
|
.table-container {
|
|
1168
891
|
display: flex;
|
|
1169
892
|
flex-direction: column;
|
|
1170
893
|
gap: var(--size-2);
|
|
894
|
+
position: relative;
|
|
1171
895
|
}
|
|
1172
896
|
|
|
1173
897
|
.table-wrap {
|
|
@@ -1183,17 +907,26 @@ function handle_header_click(event, col) {
|
|
|
1183
907
|
outline: none;
|
|
1184
908
|
}
|
|
1185
909
|
|
|
1186
|
-
.dragging {
|
|
1187
|
-
|
|
910
|
+
.table-wrap.dragging {
|
|
911
|
+
cursor: crosshair !important;
|
|
912
|
+
user-select: none;
|
|
1188
913
|
}
|
|
1189
914
|
|
|
1190
|
-
.
|
|
1191
|
-
|
|
915
|
+
.table-wrap.dragging * {
|
|
916
|
+
cursor: crosshair !important;
|
|
917
|
+
user-select: none;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
.table-wrap > :global(button) {
|
|
921
|
+
border: 1px solid var(--border-color-primary);
|
|
922
|
+
border-radius: var(--table-radius);
|
|
923
|
+
overflow: hidden;
|
|
1192
924
|
}
|
|
1193
925
|
|
|
1194
926
|
table {
|
|
1195
927
|
position: absolute;
|
|
1196
928
|
opacity: 0;
|
|
929
|
+
z-index: -1;
|
|
1197
930
|
transition: 150ms;
|
|
1198
931
|
width: var(--size-full);
|
|
1199
932
|
table-layout: auto;
|
|
@@ -1205,159 +938,39 @@ function handle_header_click(event, col) {
|
|
|
1205
938
|
border-collapse: separate;
|
|
1206
939
|
}
|
|
1207
940
|
|
|
1208
|
-
.table-wrap > :global(button) {
|
|
1209
|
-
border: 1px solid var(--border-color-primary);
|
|
1210
|
-
border-radius: var(--table-radius);
|
|
1211
|
-
overflow: hidden;
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
div:not(.no-wrap) td {
|
|
1215
|
-
overflow-wrap: anywhere;
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
div.no-wrap td {
|
|
1219
|
-
overflow-x: hidden;
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
|
-
table.fixed-layout {
|
|
1223
|
-
table-layout: fixed;
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
941
|
thead {
|
|
1227
942
|
position: sticky;
|
|
1228
943
|
top: 0;
|
|
1229
|
-
z-index:
|
|
944
|
+
z-index: 5;
|
|
1230
945
|
box-shadow: var(--shadow-drop);
|
|
1231
946
|
}
|
|
1232
947
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
tr > * + * {
|
|
1239
|
-
border-right-width: 0px;
|
|
1240
|
-
border-left-width: 1px;
|
|
1241
|
-
border-style: solid;
|
|
1242
|
-
border-color: var(--border-color-primary);
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
th,
|
|
1246
|
-
td {
|
|
1247
|
-
--ring-color: transparent;
|
|
1248
|
-
position: relative;
|
|
1249
|
-
outline: none;
|
|
1250
|
-
box-shadow: inset 0 0 0 1px var(--ring-color);
|
|
1251
|
-
padding: 0;
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
th:first-child {
|
|
1255
|
-
border-top-left-radius: var(--table-radius);
|
|
1256
|
-
border-bottom-left-radius: var(--table-radius);
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
th:last-child {
|
|
1260
|
-
border-top-right-radius: var(--table-radius);
|
|
1261
|
-
border-bottom-right-radius: var(--table-radius);
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
th.focus,
|
|
1265
|
-
td.focus {
|
|
1266
|
-
--ring-color: var(--color-accent);
|
|
1267
|
-
box-shadow: inset 0 0 0 2px var(--ring-color);
|
|
1268
|
-
z-index: var(--layer-1);
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
th.focus {
|
|
1272
|
-
z-index: var(--layer-2);
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
tr:last-child td:first-child {
|
|
1276
|
-
border-bottom-left-radius: var(--table-radius);
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
tr:last-child td:last-child {
|
|
1280
|
-
border-bottom-right-radius: var(--table-radius);
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
tr th {
|
|
1284
|
-
background: var(--table-even-background-fill);
|
|
948
|
+
thead :global(th.pinned-column) {
|
|
949
|
+
position: sticky;
|
|
950
|
+
z-index: 6;
|
|
951
|
+
background: var(--table-even-background-fill) !important;
|
|
1285
952
|
}
|
|
1286
953
|
|
|
1287
|
-
.
|
|
1288
|
-
|
|
1289
|
-
align-items: center;
|
|
1290
|
-
flex-shrink: 0;
|
|
1291
|
-
order: -1;
|
|
954
|
+
.dragging {
|
|
955
|
+
border-color: var(--color-accent);
|
|
1292
956
|
}
|
|
1293
957
|
|
|
1294
|
-
.
|
|
1295
|
-
|
|
958
|
+
.no-wrap {
|
|
959
|
+
white-space: nowrap;
|
|
1296
960
|
}
|
|
1297
961
|
|
|
1298
|
-
.
|
|
1299
|
-
|
|
1300
|
-
align-items: center;
|
|
1301
|
-
justify-content: flex-start;
|
|
1302
|
-
outline: none;
|
|
1303
|
-
min-height: var(--size-9);
|
|
1304
|
-
position: relative;
|
|
1305
|
-
height: 100%;
|
|
1306
|
-
padding: var(--size-2);
|
|
1307
|
-
box-sizing: border-box;
|
|
1308
|
-
margin: 0;
|
|
1309
|
-
gap: var(--size-1);
|
|
1310
|
-
overflow: visible;
|
|
1311
|
-
min-width: 0;
|
|
1312
|
-
border-radius: var(--table-radius);
|
|
962
|
+
div:not(.no-wrap) td {
|
|
963
|
+
overflow-wrap: anywhere;
|
|
1313
964
|
}
|
|
1314
965
|
|
|
1315
|
-
.
|
|
1316
|
-
|
|
1317
|
-
align-items: center;
|
|
1318
|
-
overflow: hidden;
|
|
1319
|
-
flex-grow: 1;
|
|
1320
|
-
min-width: 0;
|
|
1321
|
-
white-space: normal;
|
|
1322
|
-
overflow-wrap: break-word;
|
|
1323
|
-
word-break: normal;
|
|
1324
|
-
height: 100%;
|
|
1325
|
-
gap: var(--size-1);
|
|
966
|
+
div.no-wrap td {
|
|
967
|
+
overflow-x: hidden;
|
|
1326
968
|
}
|
|
1327
969
|
|
|
1328
|
-
.
|
|
970
|
+
.row-odd {
|
|
1329
971
|
background: var(--table-odd-background-fill);
|
|
1330
972
|
}
|
|
1331
973
|
|
|
1332
|
-
.row_odd.focus {
|
|
1333
|
-
background: var(--background-fill-primary);
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
.cell-menu-button {
|
|
1337
|
-
flex-shrink: 0;
|
|
1338
|
-
display: none;
|
|
1339
|
-
background-color: var(--block-background-fill);
|
|
1340
|
-
border: 1px solid var(--border-color-primary);
|
|
1341
|
-
border-radius: var(--block-radius);
|
|
1342
|
-
width: var(--size-5);
|
|
1343
|
-
height: var(--size-5);
|
|
1344
|
-
min-width: var(--size-5);
|
|
1345
|
-
padding: 0;
|
|
1346
|
-
margin-right: var(--spacing-sm);
|
|
1347
|
-
z-index: var(--layer-1);
|
|
1348
|
-
position: absolute;
|
|
1349
|
-
right: var(--size-1);
|
|
1350
|
-
top: 50%;
|
|
1351
|
-
transform: translateY(-50%);
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
.cell-selected .cell-menu-button,
|
|
1355
|
-
th:hover .cell-menu-button {
|
|
1356
|
-
display: flex;
|
|
1357
|
-
align-items: center;
|
|
1358
|
-
justify-content: center;
|
|
1359
|
-
}
|
|
1360
|
-
|
|
1361
974
|
.header-row {
|
|
1362
975
|
display: flex;
|
|
1363
976
|
justify-content: flex-end;
|
|
@@ -1368,225 +981,45 @@ function handle_header_click(event, col) {
|
|
|
1368
981
|
width: 100%;
|
|
1369
982
|
}
|
|
1370
983
|
|
|
1371
|
-
.label {
|
|
984
|
+
.header-row .label {
|
|
1372
985
|
flex: 1 1 auto;
|
|
1373
986
|
margin-right: auto;
|
|
1374
987
|
}
|
|
1375
988
|
|
|
1376
|
-
.label p {
|
|
989
|
+
.header-row .label p {
|
|
1377
990
|
margin: 0;
|
|
1378
991
|
color: var(--block-label-text-color);
|
|
1379
992
|
font-size: var(--block-label-text-size);
|
|
1380
993
|
line-height: var(--line-sm);
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
|
-
.toolbar {
|
|
1384
|
-
flex: 0 0 auto;
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
.row-number,
|
|
1388
|
-
.row-number-header {
|
|
1389
|
-
text-align: center;
|
|
1390
|
-
background: var(--table-even-background-fill);
|
|
1391
|
-
font-size: var(--input-text-size);
|
|
1392
|
-
color: var(--body-text-color);
|
|
1393
|
-
padding: var(--size-1);
|
|
1394
|
-
min-width: var(--size-12);
|
|
1395
|
-
width: var(--size-12);
|
|
1396
|
-
overflow: hidden;
|
|
1397
|
-
text-overflow: ellipsis;
|
|
1398
|
-
white-space: nowrap;
|
|
1399
|
-
font-weight: var(--weight-semibold);
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
.row-number-header .header-content {
|
|
1403
|
-
justify-content: space-between;
|
|
1404
|
-
padding: var(--size-1);
|
|
1405
|
-
height: var(--size-9);
|
|
1406
|
-
display: flex;
|
|
1407
|
-
align-items: center;
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
.row-number-header :global(.sort-icons) {
|
|
1411
|
-
margin-right: 0;
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
:global(tbody > tr:nth-child(odd)) .row-number {
|
|
1415
|
-
background: var(--table-odd-background-fill);
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
.cell-selected {
|
|
1419
|
-
--ring-color: var(--color-accent);
|
|
1420
|
-
box-shadow: inset 0 0 0 2px var(--ring-color);
|
|
1421
|
-
z-index: var(--layer-1);
|
|
1422
994
|
position: relative;
|
|
995
|
+
z-index: 4;
|
|
1423
996
|
}
|
|
1424
997
|
|
|
1425
|
-
.
|
|
1426
|
-
box-shadow:
|
|
1427
|
-
inset 2px 0 0 var(--ring-color),
|
|
1428
|
-
inset -2px 0 0 var(--ring-color),
|
|
1429
|
-
inset 0 -2px 0 var(--ring-color);
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
.cell-selected.no-bottom {
|
|
1433
|
-
box-shadow:
|
|
1434
|
-
inset 2px 0 0 var(--ring-color),
|
|
1435
|
-
inset -2px 0 0 var(--ring-color),
|
|
1436
|
-
inset 0 2px 0 var(--ring-color);
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
.cell-selected.no-left {
|
|
1440
|
-
box-shadow:
|
|
1441
|
-
inset 0 2px 0 var(--ring-color),
|
|
1442
|
-
inset -2px 0 0 var(--ring-color),
|
|
1443
|
-
inset 0 -2px 0 var(--ring-color);
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
.cell-selected.no-right {
|
|
1447
|
-
box-shadow:
|
|
1448
|
-
inset 0 2px 0 var(--ring-color),
|
|
1449
|
-
inset 2px 0 0 var(--ring-color),
|
|
1450
|
-
inset 0 -2px 0 var(--ring-color);
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
.cell-selected.no-top.no-left {
|
|
1454
|
-
box-shadow:
|
|
1455
|
-
inset -2px 0 0 var(--ring-color),
|
|
1456
|
-
inset 0 -2px 0 var(--ring-color);
|
|
1457
|
-
}
|
|
1458
|
-
|
|
1459
|
-
.cell-selected.no-top.no-right {
|
|
1460
|
-
box-shadow:
|
|
1461
|
-
inset 2px 0 0 var(--ring-color),
|
|
1462
|
-
inset 0 -2px 0 var(--ring-color);
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
.cell-selected.no-bottom.no-left {
|
|
1466
|
-
box-shadow:
|
|
1467
|
-
inset -2px 0 0 var(--ring-color),
|
|
1468
|
-
inset 0 2px 0 var(--ring-color);
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
.cell-selected.no-bottom.no-right {
|
|
1472
|
-
box-shadow:
|
|
1473
|
-
inset 2px 0 0 var(--ring-color),
|
|
1474
|
-
inset 0 2px 0 var(--ring-color);
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
.cell-selected.no-top.no-bottom {
|
|
1478
|
-
box-shadow:
|
|
1479
|
-
inset 2px 0 0 var(--ring-color),
|
|
1480
|
-
inset -2px 0 0 var(--ring-color);
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
.cell-selected.no-left.no-right {
|
|
1484
|
-
box-shadow:
|
|
1485
|
-
inset 0 2px 0 var(--ring-color),
|
|
1486
|
-
inset 0 -2px 0 var(--ring-color);
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
.cell-selected.no-top.no-left.no-right {
|
|
1490
|
-
box-shadow: inset 0 -2px 0 var(--ring-color);
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
.cell-selected.no-bottom.no-left.no-right {
|
|
1494
|
-
box-shadow: inset 0 2px 0 var(--ring-color);
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
.cell-selected.no-left.no-top.no-bottom {
|
|
1498
|
-
box-shadow: inset -2px 0 0 var(--ring-color);
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
.cell-selected.no-right.no-top.no-bottom {
|
|
1502
|
-
box-shadow: inset 2px 0 0 var(--ring-color);
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
.cell-selected.no-top.no-bottom.no-left.no-right {
|
|
1506
|
-
box-shadow: none;
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
.selection-button {
|
|
998
|
+
.scroll-top-button {
|
|
1510
999
|
position: absolute;
|
|
1000
|
+
right: var(--size-4);
|
|
1001
|
+
bottom: var(--size-4);
|
|
1002
|
+
width: var(--size-8);
|
|
1003
|
+
height: var(--size-8);
|
|
1004
|
+
border-radius: var(--table-radius);
|
|
1005
|
+
background: var(--color-accent);
|
|
1006
|
+
color: white;
|
|
1007
|
+
border: none;
|
|
1008
|
+
cursor: pointer;
|
|
1511
1009
|
display: flex;
|
|
1512
1010
|
align-items: center;
|
|
1513
1011
|
justify-content: center;
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
z-index: var(--layer-4);
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
.selection-button-column {
|
|
1521
|
-
width: var(--size-3);
|
|
1522
|
-
height: var(--size-5);
|
|
1523
|
-
top: -10px;
|
|
1524
|
-
left: var(--selected-col-pos);
|
|
1525
|
-
transform: rotate(90deg);
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
.selection-button-row {
|
|
1529
|
-
width: var(--size-3);
|
|
1530
|
-
height: var(--size-5);
|
|
1531
|
-
left: -7px;
|
|
1532
|
-
top: calc(var(--selected-row-pos) - var(--size-5) / 2);
|
|
1012
|
+
font-size: var(--text-lg);
|
|
1013
|
+
z-index: 9;
|
|
1014
|
+
opacity: 0.5;
|
|
1533
1015
|
}
|
|
1534
1016
|
|
|
1535
|
-
.
|
|
1536
|
-
opacity:
|
|
1537
|
-
pointer-events: none;
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
|
-
.flash.cell-selected {
|
|
1541
|
-
animation: flash-color 700ms ease-out;
|
|
1542
|
-
}
|
|
1543
|
-
|
|
1544
|
-
@keyframes flash-color {
|
|
1545
|
-
0%,
|
|
1546
|
-
30% {
|
|
1547
|
-
background: var(--color-accent-copied);
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
100% {
|
|
1551
|
-
background: transparent;
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
.frozen-column {
|
|
1556
|
-
position: sticky;
|
|
1557
|
-
z-index: var(--layer-2);
|
|
1558
|
-
border-right: 1px solid var(--border-color-primary);
|
|
1559
|
-
}
|
|
1560
|
-
|
|
1561
|
-
tr:nth-child(odd) .frozen-column {
|
|
1562
|
-
background: var(--table-odd-background-fill);
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
tr:nth-child(even) .frozen-column {
|
|
1566
|
-
background: var(--table-even-background-fill);
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
.always-frozen {
|
|
1570
|
-
z-index: var(--layer-3);
|
|
1017
|
+
.scroll-top-button:hover {
|
|
1018
|
+
opacity: 1;
|
|
1571
1019
|
}
|
|
1572
1020
|
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
.add-row-button {
|
|
1578
|
-
width: 100%;
|
|
1579
|
-
padding: var(--size-1);
|
|
1580
|
-
background: transparent;
|
|
1581
|
-
border: 1px dashed var(--border-color-primary);
|
|
1582
|
-
border-radius: var(--radius-sm);
|
|
1583
|
-
color: var(--body-text-color);
|
|
1584
|
-
cursor: pointer;
|
|
1585
|
-
transition: all 150ms;
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
.add-row-button:hover {
|
|
1589
|
-
background: var(--background-fill-secondary);
|
|
1590
|
-
border-style: solid;
|
|
1021
|
+
tr {
|
|
1022
|
+
border-bottom: 1px solid var(--border-color-primary);
|
|
1023
|
+
text-align: left;
|
|
1591
1024
|
}
|
|
1592
1025
|
</style>
|