@gradio/dataframe 0.16.5 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -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 +91 -10
- package/dist/shared/CellMenu.svelte.d.ts +6 -0
- package/dist/shared/CellMenuButton.svelte +45 -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 +564 -1121
- 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 +22 -3
- package/dist/shared/utils/sort_utils.js +44 -24
- package/dist/shared/utils/table_utils.d.ts +6 -5
- package/dist/shared/utils/table_utils.js +13 -56
- package/package.json +7 -7
- package/shared/CellMenu.svelte +90 -10
- package/shared/CellMenuButton.svelte +46 -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 +604 -1235
- 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 +67 -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,32 +1,43 @@
|
|
|
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 {
|
|
25
31
|
copy_table_data,
|
|
26
32
|
get_max,
|
|
27
|
-
handle_file_upload
|
|
28
|
-
sort_table_data
|
|
33
|
+
handle_file_upload
|
|
29
34
|
} from "./utils/table_utils";
|
|
35
|
+
import { make_headers, process_data } from "./utils/data_processing";
|
|
36
|
+
import { handle_keydown } from "./utils/keyboard_utils";
|
|
37
|
+
import {
|
|
38
|
+
create_drag_handlers
|
|
39
|
+
} from "./utils/drag_utils";
|
|
40
|
+
import { sort_data_and_preserve_selection } from "./utils/sort_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,135 @@ 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
|
-
|
|
142
|
-
let
|
|
143
|
-
|
|
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;
|
|
139
|
+
if (parent) {
|
|
140
|
+
const is_reset2 = values.length === 0 || values.length === 1 && values[0].length === 0;
|
|
141
|
+
const is_different_structure2 = old_val !== void 0 && (values.length !== old_val.length || values[0] && old_val[0] && values[0].length !== old_val[0].length);
|
|
142
|
+
if (is_reset2 || is_different_structure2) {
|
|
143
|
+
for (let i = 0; i < 50; i++) {
|
|
144
|
+
parent.style.removeProperty(`--cell-width-${i}`);
|
|
197
145
|
}
|
|
198
|
-
|
|
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;
|
|
146
|
+
last_width_data_length = 0;
|
|
147
|
+
last_width_column_count = 0;
|
|
215
148
|
}
|
|
216
149
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
150
|
+
const is_reset = values.length === 0 || values.length === 1 && values[0].length === 0;
|
|
151
|
+
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);
|
|
152
|
+
data = process_data(
|
|
153
|
+
values,
|
|
154
|
+
els,
|
|
155
|
+
data_binding,
|
|
156
|
+
make_id,
|
|
157
|
+
display_value
|
|
158
|
+
);
|
|
159
|
+
old_val = JSON.parse(JSON.stringify(values));
|
|
160
|
+
if (is_reset || is_different_structure) {
|
|
161
|
+
df_actions.reset_sort_state();
|
|
162
|
+
} else if ($df_state.sort_state.sort_columns.length > 0) {
|
|
163
|
+
sort_data(data, display_value, styling);
|
|
228
164
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
await handle_copy();
|
|
165
|
+
if ($df_state.current_search_query) {
|
|
166
|
+
df_actions.handle_search(null);
|
|
167
|
+
}
|
|
168
|
+
if (parent && cells.length > 0) {
|
|
169
|
+
set_cell_widths();
|
|
235
170
|
}
|
|
236
|
-
return;
|
|
237
171
|
}
|
|
238
|
-
|
|
239
|
-
|
|
172
|
+
$:
|
|
173
|
+
if ($df_state.current_search_query !== void 0) {
|
|
174
|
+
const cell_map = /* @__PURE__ */ new Map();
|
|
175
|
+
data.forEach((row, row_idx) => {
|
|
176
|
+
row.forEach((cell, col_idx) => {
|
|
177
|
+
cell_map.set(cell.id, {
|
|
178
|
+
value: cell.value,
|
|
179
|
+
styling: styling?.[row_idx]?.[col_idx] || ""
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
const filtered = df_actions.filter_data(data);
|
|
184
|
+
search_results = filtered.map(
|
|
185
|
+
(row) => row.map((cell) => {
|
|
186
|
+
const original = cell_map.get(cell.id);
|
|
187
|
+
return {
|
|
188
|
+
...cell,
|
|
189
|
+
display_value: original?.display_value || String(cell.value),
|
|
190
|
+
styling: original?.styling || ""
|
|
191
|
+
};
|
|
192
|
+
})
|
|
193
|
+
);
|
|
240
194
|
}
|
|
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
|
-
}
|
|
195
|
+
let previous_headers = _headers.map((h) => h.value);
|
|
196
|
+
let previous_data = data.map((row) => row.map((cell) => String(cell.value)));
|
|
197
|
+
$: {
|
|
198
|
+
if (data || _headers) {
|
|
199
|
+
df_actions.trigger_change(
|
|
200
|
+
data,
|
|
201
|
+
_headers,
|
|
202
|
+
previous_data,
|
|
203
|
+
previous_headers,
|
|
204
|
+
value_is_output,
|
|
205
|
+
dispatch
|
|
206
|
+
);
|
|
207
|
+
previous_data = data.map((row) => row.map((cell) => String(cell.value)));
|
|
208
|
+
previous_headers = _headers.map((h) => h.value);
|
|
324
209
|
}
|
|
325
210
|
}
|
|
326
|
-
let sort_direction;
|
|
327
|
-
let sort_by;
|
|
328
211
|
function handle_sort(col, direction) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
212
|
+
df_actions.handle_sort(col, direction);
|
|
213
|
+
sort_data(data, display_value, styling);
|
|
214
|
+
}
|
|
215
|
+
function clear_sort() {
|
|
216
|
+
df_actions.reset_sort_state();
|
|
217
|
+
sort_data(data, display_value, styling);
|
|
218
|
+
}
|
|
219
|
+
$: {
|
|
220
|
+
df_actions.sort_data(data, display_value, styling);
|
|
221
|
+
df_actions.update_row_order(data);
|
|
222
|
+
}
|
|
223
|
+
$: {
|
|
224
|
+
if ($df_state.sort_state.sort_columns) {
|
|
225
|
+
if ($df_state.sort_state.sort_columns.length > 0) {
|
|
226
|
+
sort_data(data, display_value, styling);
|
|
338
227
|
}
|
|
339
228
|
}
|
|
340
229
|
}
|
|
341
230
|
async function edit_header(i, _select = false) {
|
|
342
231
|
if (!editable || header_edit === i)
|
|
343
232
|
return;
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
233
|
+
if (!editable || col_count[1] !== "dynamic" || header_edit === i)
|
|
234
|
+
return;
|
|
235
|
+
df_actions.set_header_edit(i);
|
|
236
|
+
}
|
|
237
|
+
function handle_header_click(event, col) {
|
|
238
|
+
if (event.target instanceof HTMLAnchorElement) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
event.preventDefault();
|
|
242
|
+
event.stopPropagation();
|
|
243
|
+
if (!editable)
|
|
244
|
+
return;
|
|
245
|
+
clear_on_focus = false;
|
|
246
|
+
df_actions.set_editing(false);
|
|
247
|
+
df_actions.handle_header_click(col, editable);
|
|
248
|
+
parent.focus();
|
|
348
249
|
}
|
|
349
250
|
function end_header_edit(event) {
|
|
350
251
|
if (!editable)
|
|
351
252
|
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
|
-
}
|
|
253
|
+
df_actions.end_header_edit(event.detail.key);
|
|
254
|
+
parent.focus();
|
|
363
255
|
}
|
|
364
256
|
async function add_row(index) {
|
|
365
257
|
parent.focus();
|
|
@@ -380,84 +272,93 @@ async function add_row(index) {
|
|
|
380
272
|
data = data;
|
|
381
273
|
selected = [index !== void 0 ? index : data.length - 1, 0];
|
|
382
274
|
}
|
|
383
|
-
$:
|
|
384
|
-
(data || _headers) && trigger_change();
|
|
385
275
|
async function add_col(index) {
|
|
386
276
|
parent.focus();
|
|
387
277
|
if (col_count[1] !== "dynamic")
|
|
388
278
|
return;
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
279
|
+
const result = df_actions.add_col(data, headers, make_id, index);
|
|
280
|
+
result.data.forEach((row) => {
|
|
281
|
+
row.forEach((cell) => {
|
|
282
|
+
if (!els[cell.id]) {
|
|
283
|
+
els[cell.id] = { cell: null, input: null };
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
data = result.data;
|
|
288
|
+
headers = result.headers;
|
|
398
289
|
await tick();
|
|
399
290
|
requestAnimationFrame(() => {
|
|
400
|
-
edit_header(
|
|
291
|
+
edit_header(index !== void 0 ? index : data[0].length - 1, true);
|
|
401
292
|
const new_w = parent.querySelectorAll("tbody")[1].offsetWidth;
|
|
402
293
|
parent.querySelectorAll("table")[1].scrollTo({ left: new_w });
|
|
403
294
|
});
|
|
404
295
|
}
|
|
405
296
|
function handle_click_outside(event) {
|
|
406
297
|
if (handle_click_outside_util(event, parent)) {
|
|
407
|
-
|
|
408
|
-
selected_cells = [];
|
|
298
|
+
df_actions.clear_ui_state();
|
|
409
299
|
header_edit = false;
|
|
410
300
|
selected_header = false;
|
|
411
|
-
active_cell_menu = null;
|
|
412
|
-
active_header_menu = null;
|
|
413
301
|
}
|
|
414
302
|
}
|
|
415
303
|
$:
|
|
416
304
|
max = get_max(data);
|
|
417
305
|
$:
|
|
418
|
-
cells[0] && set_cell_widths();
|
|
306
|
+
cells[0] && cells[0]?.clientWidth && set_cell_widths();
|
|
419
307
|
let cells = [];
|
|
420
308
|
let parent;
|
|
421
309
|
let table;
|
|
310
|
+
let last_width_data_length = 0;
|
|
311
|
+
let last_width_column_count = 0;
|
|
422
312
|
function set_cell_widths() {
|
|
313
|
+
const column_count = data[0]?.length || 0;
|
|
314
|
+
if (last_width_data_length === data.length && last_width_column_count === column_count && $df_state.sort_state.sort_columns.length > 0) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
last_width_data_length = data.length;
|
|
318
|
+
last_width_column_count = column_count;
|
|
423
319
|
const widths = cells.map((el) => el?.clientWidth || 0);
|
|
424
320
|
if (widths.length === 0)
|
|
425
321
|
return;
|
|
426
322
|
if (show_row_numbers) {
|
|
427
323
|
parent.style.setProperty(`--cell-width-row-number`, `${widths[0]}px`);
|
|
428
324
|
}
|
|
429
|
-
|
|
430
|
-
data_cells.forEach((width, i) => {
|
|
325
|
+
for (let i = 0; i < 50; i++) {
|
|
431
326
|
if (!column_widths[i]) {
|
|
432
|
-
parent.style.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
);
|
|
327
|
+
parent.style.removeProperty(`--cell-width-${i}`);
|
|
328
|
+
} else if (column_widths[i].endsWith("%")) {
|
|
329
|
+
const percentage = parseFloat(column_widths[i]);
|
|
330
|
+
const pixel_width = Math.floor(percentage / 100 * parent.clientWidth);
|
|
331
|
+
parent.style.setProperty(`--cell-width-${i}`, `${pixel_width}px`);
|
|
332
|
+
} else {
|
|
333
|
+
parent.style.setProperty(`--cell-width-${i}`, column_widths[i]);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
widths.forEach((width, i) => {
|
|
337
|
+
if (!column_widths[i]) {
|
|
338
|
+
const calculated_width = `${Math.max(width, 45)}px`;
|
|
339
|
+
parent.style.setProperty(`--cell-width-${i}`, calculated_width);
|
|
436
340
|
}
|
|
437
341
|
});
|
|
438
342
|
}
|
|
439
343
|
function get_cell_width(index) {
|
|
440
|
-
return
|
|
344
|
+
return `var(--cell-width-${index})`;
|
|
441
345
|
}
|
|
442
346
|
let table_height = values.slice(0, max_height / values.length * 37).length * 37 + 37;
|
|
443
347
|
let scrollbar_width = 0;
|
|
444
|
-
function sort_data(_data, _display_value, _styling
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
data = data;
|
|
454
|
-
|
|
455
|
-
const [i, j] = get_current_indices(id, data);
|
|
456
|
-
selected = [i, j];
|
|
457
|
-
}
|
|
348
|
+
function sort_data(_data, _display_value, _styling) {
|
|
349
|
+
const result = sort_data_and_preserve_selection(
|
|
350
|
+
_data,
|
|
351
|
+
_display_value,
|
|
352
|
+
_styling,
|
|
353
|
+
$df_state.sort_state.sort_columns,
|
|
354
|
+
selected,
|
|
355
|
+
get_current_indices
|
|
356
|
+
);
|
|
357
|
+
data = result.data;
|
|
358
|
+
selected = result.selected;
|
|
458
359
|
}
|
|
459
360
|
$:
|
|
460
|
-
sort_data(data, display_value, styling
|
|
361
|
+
sort_data(data, display_value, styling);
|
|
461
362
|
$:
|
|
462
363
|
selected_index = !!selected && selected[0];
|
|
463
364
|
let is_visible = false;
|
|
@@ -485,80 +386,58 @@ onMount(() => {
|
|
|
485
386
|
);
|
|
486
387
|
};
|
|
487
388
|
});
|
|
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;
|
|
389
|
+
$:
|
|
390
|
+
keyboard_ctx = create_keyboard_context({
|
|
391
|
+
selected_header,
|
|
392
|
+
header_edit,
|
|
393
|
+
editing,
|
|
394
|
+
selected,
|
|
395
|
+
selected_cells,
|
|
396
|
+
editable,
|
|
397
|
+
data,
|
|
398
|
+
headers: _headers,
|
|
399
|
+
els,
|
|
400
|
+
df_actions,
|
|
401
|
+
dispatch,
|
|
402
|
+
add_row,
|
|
403
|
+
get_next_cell_coordinates,
|
|
404
|
+
get_range_selection,
|
|
405
|
+
move_cursor,
|
|
406
|
+
copy_flash,
|
|
407
|
+
parent_element: parent,
|
|
408
|
+
set_copy_flash: (value) => {
|
|
409
|
+
copy_flash = value;
|
|
410
|
+
if (value) {
|
|
411
|
+
setTimeout(() => {
|
|
412
|
+
copy_flash = false;
|
|
413
|
+
}, 800);
|
|
414
|
+
}
|
|
515
415
|
}
|
|
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
416
|
});
|
|
417
|
+
$:
|
|
418
|
+
selection_ctx = create_selection_context({
|
|
419
|
+
df_actions,
|
|
420
|
+
dispatch,
|
|
421
|
+
data,
|
|
422
|
+
els,
|
|
423
|
+
editable,
|
|
424
|
+
show_row_numbers,
|
|
425
|
+
get_data_at,
|
|
426
|
+
clear_on_focus,
|
|
427
|
+
selected_cells,
|
|
428
|
+
parent_element: parent
|
|
429
|
+
});
|
|
430
|
+
function handle_cell_click(event, row, col) {
|
|
431
|
+
selection_ctx.actions.handle_cell_click(event, row, col);
|
|
523
432
|
}
|
|
524
433
|
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
|
-
}
|
|
535
|
-
}
|
|
536
|
-
function add_row_at(index, position) {
|
|
537
|
-
const row_index = position === "above" ? index : index + 1;
|
|
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;
|
|
434
|
+
selection_ctx.actions.toggle_cell_menu(event, row, col);
|
|
547
435
|
}
|
|
548
|
-
function
|
|
549
|
-
|
|
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 };
|
|
436
|
+
function handle_select_column(col) {
|
|
437
|
+
selection_ctx.actions.handle_select_column(col);
|
|
559
438
|
}
|
|
560
|
-
function
|
|
561
|
-
|
|
439
|
+
function handle_select_row(row) {
|
|
440
|
+
selection_ctx.actions.handle_select_row(row);
|
|
562
441
|
}
|
|
563
442
|
function toggle_fullscreen() {
|
|
564
443
|
if (!document.fullscreenElement) {
|
|
@@ -572,93 +451,44 @@ function toggle_fullscreen() {
|
|
|
572
451
|
function handle_fullscreen_change() {
|
|
573
452
|
is_fullscreen = !!document.fullscreenElement;
|
|
574
453
|
}
|
|
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
454
|
function toggle_header_menu(event, col) {
|
|
583
455
|
event.stopPropagation();
|
|
584
456
|
if (active_header_menu && active_header_menu.col === col) {
|
|
585
|
-
|
|
457
|
+
df_actions.set_active_header_menu(null);
|
|
586
458
|
} else {
|
|
587
459
|
const header = event.target.closest("th");
|
|
588
460
|
if (header) {
|
|
589
461
|
const rect = header.getBoundingClientRect();
|
|
590
|
-
|
|
462
|
+
df_actions.set_active_header_menu({
|
|
463
|
+
col,
|
|
464
|
+
x: rect.right,
|
|
465
|
+
y: rect.bottom
|
|
466
|
+
});
|
|
591
467
|
}
|
|
592
468
|
}
|
|
593
469
|
}
|
|
594
470
|
afterUpdate(() => {
|
|
595
471
|
value_is_output = false;
|
|
596
472
|
});
|
|
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();
|
|
473
|
+
function delete_col_at(index) {
|
|
609
474
|
if (col_count[1] !== "dynamic")
|
|
610
475
|
return;
|
|
611
|
-
if (
|
|
476
|
+
if (data[0].length <= 1)
|
|
612
477
|
return;
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
478
|
+
const result = df_actions.delete_col_at(data, headers, index);
|
|
479
|
+
data = result.data;
|
|
480
|
+
headers = result.headers;
|
|
481
|
+
_headers = make_headers(headers, col_count, els, make_id);
|
|
482
|
+
df_actions.set_active_cell_menu(null);
|
|
483
|
+
df_actions.set_active_header_menu(null);
|
|
484
|
+
df_actions.set_selected(false);
|
|
485
|
+
df_actions.set_selected_cells([]);
|
|
486
|
+
df_actions.set_editing(false);
|
|
622
487
|
}
|
|
623
488
|
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;
|
|
489
|
+
data = df_actions.delete_row_at(data, index);
|
|
490
|
+
df_actions.set_active_cell_menu(null);
|
|
491
|
+
df_actions.set_active_header_menu(null);
|
|
662
492
|
}
|
|
663
493
|
let coords;
|
|
664
494
|
$:
|
|
@@ -677,48 +507,111 @@ $:
|
|
|
677
507
|
"--selected-col-pos",
|
|
678
508
|
positions.col_pos
|
|
679
509
|
);
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
);
|
|
685
|
-
}
|
|
510
|
+
document.documentElement.style.setProperty(
|
|
511
|
+
"--selected-row-pos",
|
|
512
|
+
positions.row_pos || "0px"
|
|
513
|
+
);
|
|
686
514
|
}
|
|
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
515
|
function commit_filter() {
|
|
693
|
-
if (current_search_query && show_search === "filter") {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
516
|
+
if ($df_state.current_search_query && show_search === "filter") {
|
|
517
|
+
const filtered_data = [];
|
|
518
|
+
const filtered_display_values = [];
|
|
519
|
+
const filtered_styling = [];
|
|
520
|
+
search_results.forEach((row) => {
|
|
521
|
+
const data_row = [];
|
|
522
|
+
const display_row = [];
|
|
523
|
+
const styling_row = [];
|
|
524
|
+
row.forEach((cell) => {
|
|
525
|
+
data_row.push(cell.value);
|
|
526
|
+
display_row.push(cell.display_value || String(cell.value));
|
|
527
|
+
styling_row.push(cell.styling || "");
|
|
528
|
+
});
|
|
529
|
+
filtered_data.push(data_row);
|
|
530
|
+
filtered_display_values.push(display_row);
|
|
531
|
+
filtered_styling.push(styling_row);
|
|
698
532
|
});
|
|
533
|
+
const change_payload = {
|
|
534
|
+
data: filtered_data,
|
|
535
|
+
headers: _headers.map((h) => h.value),
|
|
536
|
+
metadata: {
|
|
537
|
+
display_value: filtered_display_values,
|
|
538
|
+
styling: filtered_styling
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
dispatch("change", change_payload);
|
|
699
542
|
if (!value_is_output) {
|
|
700
543
|
dispatch("input");
|
|
701
544
|
}
|
|
702
|
-
|
|
545
|
+
df_actions.handle_search(null);
|
|
703
546
|
}
|
|
704
547
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
548
|
+
let viewport;
|
|
549
|
+
let show_scroll_button = false;
|
|
550
|
+
function scroll_to_top() {
|
|
551
|
+
viewport.scrollTo({
|
|
552
|
+
top: 0
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
function handle_resize() {
|
|
556
|
+
df_actions.set_active_cell_menu(null);
|
|
557
|
+
df_actions.set_active_header_menu(null);
|
|
558
|
+
selected_cells = [];
|
|
559
|
+
selected = false;
|
|
560
|
+
editing = false;
|
|
561
|
+
set_cell_widths();
|
|
562
|
+
}
|
|
563
|
+
function add_row_at(index, position) {
|
|
564
|
+
const row_index = position === "above" ? index : index + 1;
|
|
565
|
+
add_row(row_index);
|
|
714
566
|
active_cell_menu = null;
|
|
715
567
|
active_header_menu = null;
|
|
716
|
-
selected = false;
|
|
717
|
-
selected_cells = [];
|
|
718
|
-
selected_header = col;
|
|
719
|
-
header_edit = col;
|
|
720
|
-
parent.focus();
|
|
721
568
|
}
|
|
569
|
+
function add_col_at(index, position) {
|
|
570
|
+
const col_index = position === "left" ? index : index + 1;
|
|
571
|
+
add_col(col_index);
|
|
572
|
+
active_cell_menu = null;
|
|
573
|
+
active_header_menu = null;
|
|
574
|
+
}
|
|
575
|
+
export function reset_sort_state() {
|
|
576
|
+
df_actions.reset_sort_state();
|
|
577
|
+
}
|
|
578
|
+
let is_dragging = false;
|
|
579
|
+
let drag_start = null;
|
|
580
|
+
let mouse_down_pos = null;
|
|
581
|
+
const drag_state = {
|
|
582
|
+
is_dragging,
|
|
583
|
+
drag_start,
|
|
584
|
+
mouse_down_pos
|
|
585
|
+
};
|
|
586
|
+
$: {
|
|
587
|
+
is_dragging = drag_state.is_dragging;
|
|
588
|
+
drag_start = drag_state.drag_start;
|
|
589
|
+
mouse_down_pos = drag_state.mouse_down_pos;
|
|
590
|
+
}
|
|
591
|
+
let drag_handlers;
|
|
592
|
+
function init_drag_handlers() {
|
|
593
|
+
drag_handlers = create_drag_handlers(
|
|
594
|
+
drag_state,
|
|
595
|
+
(value) => is_dragging = value,
|
|
596
|
+
(cells2) => df_actions.set_selected_cells(cells2),
|
|
597
|
+
(cell) => df_actions.set_selected(cell),
|
|
598
|
+
(event, row, col) => selection_ctx.actions.handle_cell_click(event, row, col),
|
|
599
|
+
show_row_numbers,
|
|
600
|
+
parent
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
$:
|
|
604
|
+
if (parent)
|
|
605
|
+
init_drag_handlers();
|
|
606
|
+
$:
|
|
607
|
+
handle_mouse_down = drag_handlers?.handle_mouse_down || (() => {
|
|
608
|
+
});
|
|
609
|
+
$:
|
|
610
|
+
handle_mouse_move = drag_handlers?.handle_mouse_move || (() => {
|
|
611
|
+
});
|
|
612
|
+
$:
|
|
613
|
+
handle_mouse_up = drag_handlers?.handle_mouse_up || (() => {
|
|
614
|
+
});
|
|
722
615
|
</script>
|
|
723
616
|
|
|
724
617
|
<svelte:window on:resize={() => set_cell_widths()} />
|
|
@@ -735,140 +628,70 @@ function handle_header_click(event, col) {
|
|
|
735
628
|
{show_fullscreen_button}
|
|
736
629
|
{is_fullscreen}
|
|
737
630
|
on:click={toggle_fullscreen}
|
|
738
|
-
on_copy={
|
|
631
|
+
on_copy={async () => await copy_table_data(data, null)}
|
|
739
632
|
{show_copy_button}
|
|
740
633
|
{show_search}
|
|
741
|
-
on:search={(e) => handle_search(e.detail)}
|
|
634
|
+
on:search={(e) => df_actions.handle_search(e.detail)}
|
|
742
635
|
on_commit_filter={commit_filter}
|
|
743
|
-
{current_search_query}
|
|
636
|
+
current_search_query={$df_state.current_search_query}
|
|
744
637
|
/>
|
|
745
638
|
</div>
|
|
746
639
|
{/if}
|
|
747
640
|
<div
|
|
748
641
|
bind:this={parent}
|
|
749
642
|
class="table-wrap"
|
|
750
|
-
class:dragging
|
|
643
|
+
class:dragging={is_dragging}
|
|
751
644
|
class:no-wrap={!wrap}
|
|
752
645
|
style="height:{table_height}px;"
|
|
753
646
|
class:menu-open={active_cell_menu || active_header_menu}
|
|
754
|
-
on:keydown={(e) => handle_keydown(e)}
|
|
647
|
+
on:keydown={(e) => handle_keydown(e, keyboard_ctx)}
|
|
648
|
+
on:mousemove={handle_mouse_move}
|
|
649
|
+
on:mouseup={handle_mouse_up}
|
|
650
|
+
on:mouseleave={handle_mouse_up}
|
|
755
651
|
role="grid"
|
|
756
652
|
tabindex="0"
|
|
757
653
|
>
|
|
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
|
-
>
|
|
654
|
+
<table bind:this={table}>
|
|
779
655
|
{#if label && label.length !== 0}
|
|
780
656
|
<caption class="sr-only">{label}</caption>
|
|
781
657
|
{/if}
|
|
782
658
|
<thead>
|
|
783
659
|
<tr>
|
|
784
660
|
{#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>
|
|
661
|
+
<RowNumber is_header={true} />
|
|
795
662
|
{/if}
|
|
796
663
|
{#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>
|
|
664
|
+
<TableHeader
|
|
665
|
+
bind:value={_headers[i].value}
|
|
666
|
+
{i}
|
|
667
|
+
{actual_pinned_columns}
|
|
668
|
+
{header_edit}
|
|
669
|
+
{selected_header}
|
|
670
|
+
get_sort_status={df_actions.get_sort_status}
|
|
671
|
+
{headers}
|
|
672
|
+
{get_cell_width}
|
|
673
|
+
{handle_header_click}
|
|
674
|
+
{toggle_header_menu}
|
|
675
|
+
{end_header_edit}
|
|
676
|
+
sort_columns={$df_state.sort_state.sort_columns}
|
|
677
|
+
{latex_delimiters}
|
|
678
|
+
{line_breaks}
|
|
679
|
+
{max_chars}
|
|
680
|
+
{root}
|
|
681
|
+
{editable}
|
|
682
|
+
is_static={static_columns.includes(i)}
|
|
683
|
+
{i18n}
|
|
684
|
+
bind:el={els[id].input}
|
|
685
|
+
{col_count}
|
|
686
|
+
/>
|
|
867
687
|
{/each}
|
|
868
688
|
</tr>
|
|
869
689
|
</thead>
|
|
870
690
|
<tbody>
|
|
871
691
|
<tr>
|
|
692
|
+
{#if show_row_numbers}
|
|
693
|
+
<RowNumber index={0} />
|
|
694
|
+
{/if}
|
|
872
695
|
{#each max as { value, id }, j (id)}
|
|
873
696
|
<td tabindex="-1" bind:this={cells[j]}>
|
|
874
697
|
<div class="cell-wrap">
|
|
@@ -881,6 +704,14 @@ function handle_header_click(event, col) {
|
|
|
881
704
|
el={null}
|
|
882
705
|
{root}
|
|
883
706
|
{editable}
|
|
707
|
+
{i18n}
|
|
708
|
+
show_selection_buttons={selected_cells.length === 1 &&
|
|
709
|
+
selected_cells[0][0] === 0 &&
|
|
710
|
+
selected_cells[0][1] === j}
|
|
711
|
+
coords={[0, j]}
|
|
712
|
+
on_select_column={handle_select_column}
|
|
713
|
+
on_select_row={handle_select_row}
|
|
714
|
+
{is_dragging}
|
|
884
715
|
/>
|
|
885
716
|
</div>
|
|
886
717
|
</td>
|
|
@@ -903,7 +734,8 @@ function handle_header_click(event, col) {
|
|
|
903
734
|
_headers = make_headers(
|
|
904
735
|
head.map((h) => h ?? ""),
|
|
905
736
|
col_count,
|
|
906
|
-
els
|
|
737
|
+
els,
|
|
738
|
+
make_id
|
|
907
739
|
);
|
|
908
740
|
return _headers;
|
|
909
741
|
},
|
|
@@ -916,258 +748,160 @@ function handle_header_click(event, col) {
|
|
|
916
748
|
>
|
|
917
749
|
<div class="table-wrap">
|
|
918
750
|
<VirtualTable
|
|
919
|
-
bind:items={
|
|
751
|
+
bind:items={search_results}
|
|
920
752
|
{max_height}
|
|
921
753
|
bind:actual_height={table_height}
|
|
922
754
|
bind:table_scrollbar_width={scrollbar_width}
|
|
923
755
|
selected={selected_index}
|
|
924
756
|
disable_scroll={active_cell_menu !== null ||
|
|
925
757
|
active_header_menu !== null}
|
|
758
|
+
bind:viewport
|
|
759
|
+
bind:show_scroll_button
|
|
760
|
+
on:scroll_top={(_) => {}}
|
|
926
761
|
>
|
|
927
762
|
{#if label && label.length !== 0}
|
|
928
763
|
<caption class="sr-only">{label}</caption>
|
|
929
764
|
{/if}
|
|
930
765
|
<tr slot="thead">
|
|
931
766
|
{#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>
|
|
767
|
+
<RowNumber is_header={true} />
|
|
942
768
|
{/if}
|
|
943
769
|
{#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>
|
|
770
|
+
<TableHeader
|
|
771
|
+
bind:value={_headers[i].value}
|
|
772
|
+
{i}
|
|
773
|
+
{actual_pinned_columns}
|
|
774
|
+
{header_edit}
|
|
775
|
+
{selected_header}
|
|
776
|
+
get_sort_status={df_actions.get_sort_status}
|
|
777
|
+
{headers}
|
|
778
|
+
{get_cell_width}
|
|
779
|
+
{handle_header_click}
|
|
780
|
+
{toggle_header_menu}
|
|
781
|
+
{end_header_edit}
|
|
782
|
+
sort_columns={$df_state.sort_state.sort_columns}
|
|
783
|
+
{latex_delimiters}
|
|
784
|
+
{line_breaks}
|
|
785
|
+
{max_chars}
|
|
786
|
+
{root}
|
|
787
|
+
{editable}
|
|
788
|
+
is_static={static_columns.includes(i)}
|
|
789
|
+
{i18n}
|
|
790
|
+
bind:el={els[id].input}
|
|
791
|
+
{col_count}
|
|
792
|
+
/>
|
|
1013
793
|
{/each}
|
|
1014
794
|
</tr>
|
|
1015
|
-
<tr slot="tbody" let:item let:index class:
|
|
795
|
+
<tr slot="tbody" let:item let:index class:row-odd={index % 2 === 0}>
|
|
1016
796
|
{#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>
|
|
797
|
+
<RowNumber {index} />
|
|
1024
798
|
{/if}
|
|
1025
799
|
{#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>
|
|
800
|
+
<TableCell
|
|
801
|
+
bind:value={search_results[index][j].value}
|
|
802
|
+
{index}
|
|
803
|
+
{j}
|
|
804
|
+
{actual_pinned_columns}
|
|
805
|
+
{get_cell_width}
|
|
806
|
+
handle_cell_click={(e, r, c) => handle_mouse_down(e, r, c)}
|
|
807
|
+
{toggle_cell_menu}
|
|
808
|
+
{is_cell_selected}
|
|
809
|
+
{should_show_cell_menu}
|
|
810
|
+
{selected_cells}
|
|
811
|
+
{copy_flash}
|
|
812
|
+
{active_cell_menu}
|
|
813
|
+
styling={search_results[index][j].styling}
|
|
814
|
+
{latex_delimiters}
|
|
815
|
+
{line_breaks}
|
|
816
|
+
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
817
|
+
{editing}
|
|
818
|
+
{clear_on_focus}
|
|
819
|
+
{max_chars}
|
|
820
|
+
{root}
|
|
821
|
+
{editable}
|
|
822
|
+
is_static={static_columns.includes(j)}
|
|
823
|
+
{i18n}
|
|
824
|
+
{components}
|
|
825
|
+
{handle_select_column}
|
|
826
|
+
{handle_select_row}
|
|
827
|
+
bind:el={els[id]}
|
|
828
|
+
{is_dragging}
|
|
829
|
+
/>
|
|
1104
830
|
{/each}
|
|
1105
831
|
</tr>
|
|
1106
832
|
</VirtualTable>
|
|
1107
833
|
</div>
|
|
1108
834
|
</Upload>
|
|
835
|
+
{#if show_scroll_button}
|
|
836
|
+
<button class="scroll-top-button" on:click={scroll_to_top}>
|
|
837
|
+
↑
|
|
838
|
+
</button>
|
|
839
|
+
{/if}
|
|
1109
840
|
</div>
|
|
1110
841
|
</div>
|
|
1111
842
|
{#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>
|
|
1117
|
-
{/if}
|
|
1118
|
-
|
|
1119
|
-
{#if active_cell_menu}
|
|
1120
|
-
<CellMenu
|
|
1121
|
-
x={active_cell_menu.x}
|
|
1122
|
-
y={active_cell_menu.y}
|
|
1123
|
-
row={active_cell_menu.row}
|
|
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
|
-
/>
|
|
843
|
+
<EmptyRowButton on_click={() => add_row()} />
|
|
1136
844
|
{/if}
|
|
1137
845
|
|
|
1138
|
-
{#if
|
|
846
|
+
{#if active_cell_menu || active_header_menu}
|
|
1139
847
|
<CellMenu
|
|
1140
|
-
{
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
row={-1}
|
|
848
|
+
x={active_cell_menu?.x ?? active_header_menu?.x ?? 0}
|
|
849
|
+
y={active_cell_menu?.y ?? active_header_menu?.y ?? 0}
|
|
850
|
+
row={active_header_menu ? -1 : active_cell_menu?.row ?? 0}
|
|
1144
851
|
{col_count}
|
|
1145
852
|
{row_count}
|
|
1146
853
|
on_add_row_above={() => add_row_at(active_cell_menu?.row ?? -1, "above")}
|
|
1147
854
|
on_add_row_below={() => add_row_at(active_cell_menu?.row ?? -1, "below")}
|
|
1148
|
-
on_add_column_left={() =>
|
|
855
|
+
on_add_column_left={() =>
|
|
856
|
+
add_col_at(
|
|
857
|
+
active_cell_menu?.col ?? active_header_menu?.col ?? -1,
|
|
858
|
+
"left"
|
|
859
|
+
)}
|
|
1149
860
|
on_add_column_right={() =>
|
|
1150
|
-
add_col_at(
|
|
861
|
+
add_col_at(
|
|
862
|
+
active_cell_menu?.col ?? active_header_menu?.col ?? -1,
|
|
863
|
+
"right"
|
|
864
|
+
)}
|
|
1151
865
|
on_delete_row={() => delete_row_at(active_cell_menu?.row ?? -1)}
|
|
1152
|
-
on_delete_col={() =>
|
|
1153
|
-
|
|
1154
|
-
|
|
866
|
+
on_delete_col={() =>
|
|
867
|
+
delete_col_at(active_cell_menu?.col ?? active_header_menu?.col ?? -1)}
|
|
868
|
+
{editable}
|
|
869
|
+
can_delete_rows={!active_header_menu && data.length > 1 && editable}
|
|
870
|
+
can_delete_cols={data.length > 0 && data[0]?.length > 1 && editable}
|
|
871
|
+
{i18n}
|
|
872
|
+
on_sort={active_header_menu
|
|
873
|
+
? (direction) => {
|
|
874
|
+
if (active_header_menu) {
|
|
875
|
+
handle_sort(active_header_menu.col, direction);
|
|
876
|
+
df_actions.set_active_header_menu(null);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
: undefined}
|
|
880
|
+
on_clear_sort={active_header_menu
|
|
881
|
+
? () => {
|
|
882
|
+
clear_sort();
|
|
883
|
+
df_actions.set_active_header_menu(null);
|
|
884
|
+
}
|
|
885
|
+
: undefined}
|
|
886
|
+
sort_direction={active_header_menu
|
|
887
|
+
? $df_state.sort_state.sort_columns.find(
|
|
888
|
+
(item) => item.col === (active_header_menu?.col ?? -1)
|
|
889
|
+
)?.direction ?? null
|
|
890
|
+
: null}
|
|
891
|
+
sort_priority={active_header_menu
|
|
892
|
+
? $df_state.sort_state.sort_columns.findIndex(
|
|
893
|
+
(item) => item.col === (active_header_menu?.col ?? -1)
|
|
894
|
+
) + 1 || null
|
|
895
|
+
: null}
|
|
1155
896
|
/>
|
|
1156
897
|
{/if}
|
|
1157
898
|
|
|
1158
899
|
<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
900
|
.table-container {
|
|
1168
901
|
display: flex;
|
|
1169
902
|
flex-direction: column;
|
|
1170
903
|
gap: var(--size-2);
|
|
904
|
+
position: relative;
|
|
1171
905
|
}
|
|
1172
906
|
|
|
1173
907
|
.table-wrap {
|
|
@@ -1183,17 +917,26 @@ function handle_header_click(event, col) {
|
|
|
1183
917
|
outline: none;
|
|
1184
918
|
}
|
|
1185
919
|
|
|
1186
|
-
.dragging {
|
|
1187
|
-
|
|
920
|
+
.table-wrap.dragging {
|
|
921
|
+
cursor: crosshair !important;
|
|
922
|
+
user-select: none;
|
|
1188
923
|
}
|
|
1189
924
|
|
|
1190
|
-
.
|
|
1191
|
-
|
|
925
|
+
.table-wrap.dragging * {
|
|
926
|
+
cursor: crosshair !important;
|
|
927
|
+
user-select: none;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
.table-wrap > :global(button) {
|
|
931
|
+
border: 1px solid var(--border-color-primary);
|
|
932
|
+
border-radius: var(--table-radius);
|
|
933
|
+
overflow: hidden;
|
|
1192
934
|
}
|
|
1193
935
|
|
|
1194
936
|
table {
|
|
1195
937
|
position: absolute;
|
|
1196
938
|
opacity: 0;
|
|
939
|
+
z-index: -1;
|
|
1197
940
|
transition: 150ms;
|
|
1198
941
|
width: var(--size-full);
|
|
1199
942
|
table-layout: auto;
|
|
@@ -1205,159 +948,39 @@ function handle_header_click(event, col) {
|
|
|
1205
948
|
border-collapse: separate;
|
|
1206
949
|
}
|
|
1207
950
|
|
|
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
951
|
thead {
|
|
1227
952
|
position: sticky;
|
|
1228
953
|
top: 0;
|
|
1229
|
-
z-index:
|
|
954
|
+
z-index: 5;
|
|
1230
955
|
box-shadow: var(--shadow-drop);
|
|
1231
956
|
}
|
|
1232
957
|
|
|
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);
|
|
958
|
+
thead :global(th.pinned-column) {
|
|
959
|
+
position: sticky;
|
|
960
|
+
z-index: 6;
|
|
961
|
+
background: var(--table-even-background-fill) !important;
|
|
1285
962
|
}
|
|
1286
963
|
|
|
1287
|
-
.
|
|
1288
|
-
|
|
1289
|
-
align-items: center;
|
|
1290
|
-
flex-shrink: 0;
|
|
1291
|
-
order: -1;
|
|
964
|
+
.dragging {
|
|
965
|
+
border-color: var(--color-accent);
|
|
1292
966
|
}
|
|
1293
967
|
|
|
1294
|
-
.
|
|
1295
|
-
|
|
968
|
+
.no-wrap {
|
|
969
|
+
white-space: nowrap;
|
|
1296
970
|
}
|
|
1297
971
|
|
|
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);
|
|
972
|
+
div:not(.no-wrap) td {
|
|
973
|
+
overflow-wrap: anywhere;
|
|
1313
974
|
}
|
|
1314
975
|
|
|
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);
|
|
976
|
+
div.no-wrap td {
|
|
977
|
+
overflow-x: hidden;
|
|
1326
978
|
}
|
|
1327
979
|
|
|
1328
|
-
.
|
|
980
|
+
.row-odd {
|
|
1329
981
|
background: var(--table-odd-background-fill);
|
|
1330
982
|
}
|
|
1331
983
|
|
|
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
984
|
.header-row {
|
|
1362
985
|
display: flex;
|
|
1363
986
|
justify-content: flex-end;
|
|
@@ -1368,225 +991,45 @@ function handle_header_click(event, col) {
|
|
|
1368
991
|
width: 100%;
|
|
1369
992
|
}
|
|
1370
993
|
|
|
1371
|
-
.label {
|
|
994
|
+
.header-row .label {
|
|
1372
995
|
flex: 1 1 auto;
|
|
1373
996
|
margin-right: auto;
|
|
1374
997
|
}
|
|
1375
998
|
|
|
1376
|
-
.label p {
|
|
999
|
+
.header-row .label p {
|
|
1377
1000
|
margin: 0;
|
|
1378
1001
|
color: var(--block-label-text-color);
|
|
1379
1002
|
font-size: var(--block-label-text-size);
|
|
1380
1003
|
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
1004
|
position: relative;
|
|
1005
|
+
z-index: 4;
|
|
1423
1006
|
}
|
|
1424
1007
|
|
|
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 {
|
|
1008
|
+
.scroll-top-button {
|
|
1510
1009
|
position: absolute;
|
|
1010
|
+
right: var(--size-4);
|
|
1011
|
+
bottom: var(--size-4);
|
|
1012
|
+
width: var(--size-8);
|
|
1013
|
+
height: var(--size-8);
|
|
1014
|
+
border-radius: var(--table-radius);
|
|
1015
|
+
background: var(--color-accent);
|
|
1016
|
+
color: white;
|
|
1017
|
+
border: none;
|
|
1018
|
+
cursor: pointer;
|
|
1511
1019
|
display: flex;
|
|
1512
1020
|
align-items: center;
|
|
1513
1021
|
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);
|
|
1022
|
+
font-size: var(--text-lg);
|
|
1023
|
+
z-index: 9;
|
|
1024
|
+
opacity: 0.5;
|
|
1526
1025
|
}
|
|
1527
1026
|
|
|
1528
|
-
.
|
|
1529
|
-
|
|
1530
|
-
height: var(--size-5);
|
|
1531
|
-
left: -7px;
|
|
1532
|
-
top: calc(var(--selected-row-pos) - var(--size-5) / 2);
|
|
1027
|
+
.scroll-top-button:hover {
|
|
1028
|
+
opacity: 1;
|
|
1533
1029
|
}
|
|
1534
1030
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
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);
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
|
-
.add-row-container {
|
|
1574
|
-
margin-top: var(--size-2);
|
|
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;
|
|
1031
|
+
tr {
|
|
1032
|
+
border-bottom: 1px solid var(--border-color-primary);
|
|
1033
|
+
text-align: left;
|
|
1591
1034
|
}
|
|
1592
1035
|
</style>
|