@gradio/dataframe 0.22.0 → 0.23.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 +14 -0
- package/Dataframe.test.ts +697 -32
- package/Index.svelte +107 -106
- package/dist/Index.svelte +107 -106
- package/dist/Index.svelte.d.ts +0 -1
- package/dist/shared/BooleanCell.svelte +12 -6
- package/dist/shared/BooleanCell.svelte.d.ts +4 -18
- package/dist/shared/CellMenu.svelte +74 -49
- package/dist/shared/CellMenu.svelte.d.ts +5 -19
- package/dist/shared/CellMenuButton.svelte +3 -3
- package/dist/shared/CellMenuButton.svelte.d.ts +4 -18
- package/dist/shared/CellMenuIcons.svelte +1 -1
- package/dist/shared/CellMenuIcons.svelte.d.ts +4 -18
- package/dist/shared/DataCell.svelte +189 -0
- package/dist/shared/DataCell.svelte.d.ts +44 -0
- package/dist/shared/EditableCell.svelte +88 -64
- package/dist/shared/EditableCell.svelte.d.ts +8 -26
- package/dist/shared/EmptyRowButton.svelte +2 -2
- package/dist/shared/EmptyRowButton.svelte.d.ts +4 -18
- package/dist/shared/FilterMenu.svelte +26 -18
- package/dist/shared/FilterMenu.svelte.d.ts +5 -21
- package/dist/shared/HeaderCell.svelte +218 -0
- package/dist/shared/HeaderCell.svelte.d.ts +30 -0
- package/dist/shared/RowNumber.svelte +4 -2
- package/dist/shared/RowNumber.svelte.d.ts +4 -18
- package/dist/shared/Table.svelte +1037 -949
- package/dist/shared/Table.svelte.d.ts +12 -30
- package/dist/shared/Toolbar.svelte +32 -22
- package/dist/shared/Toolbar.svelte.d.ts +6 -21
- package/dist/shared/column_measurement.svelte.d.ts +20 -0
- package/dist/shared/column_measurement.svelte.js +79 -0
- package/dist/shared/icons/FilterIcon.svelte +14 -6
- package/dist/shared/icons/FilterIcon.svelte.d.ts +14 -6
- package/dist/shared/icons/Padlock.svelte +6 -2
- package/dist/shared/icons/Padlock.svelte.d.ts +4 -25
- package/dist/shared/icons/SelectionButtons.svelte +23 -8
- package/dist/shared/icons/SelectionButtons.svelte.d.ts +4 -18
- package/dist/shared/icons/SortButtonDown.svelte +15 -4
- package/dist/shared/icons/SortButtonDown.svelte.d.ts +4 -25
- package/dist/shared/icons/SortButtonUp.svelte +15 -5
- package/dist/shared/icons/SortButtonUp.svelte.d.ts +4 -25
- package/dist/shared/icons/SortIcon.svelte +13 -7
- package/dist/shared/icons/SortIcon.svelte.d.ts +7 -21
- package/dist/shared/tanstack/index.d.ts +3 -0
- package/dist/shared/tanstack/index.js +3 -0
- package/dist/shared/tanstack/table.svelte.d.ts +26 -0
- package/dist/shared/tanstack/table.svelte.js +102 -0
- package/dist/shared/tanstack/virtual.svelte.d.ts +14 -0
- package/dist/shared/tanstack/virtual.svelte.js +76 -0
- package/dist/shared/types.d.ts +2 -0
- package/dist/shared/utils/filter.d.ts +5 -0
- package/dist/shared/utils/filter.js +62 -0
- package/dist/shared/utils/selection_utils.js +1 -1
- package/dist/shared/utils/table_utils.d.ts +1 -14
- package/dist/shared/utils/table_utils.js +0 -61
- package/dist/standalone/Index.svelte +71 -46
- package/dist/standalone/Index.svelte.d.ts +4 -23
- package/dist/types.d.ts +32 -0
- package/dist/types.js +1 -0
- package/package.json +10 -9
- package/shared/BooleanCell.svelte +12 -6
- package/shared/CellMenu.svelte +74 -49
- package/shared/CellMenuButton.svelte +3 -3
- package/shared/CellMenuIcons.svelte +1 -1
- package/shared/DataCell.svelte +189 -0
- package/shared/EditableCell.svelte +88 -64
- package/shared/EmptyRowButton.svelte +2 -2
- package/shared/FilterMenu.svelte +26 -18
- package/shared/HeaderCell.svelte +218 -0
- package/shared/RowNumber.svelte +4 -2
- package/shared/Table.svelte +1037 -949
- package/shared/Toolbar.svelte +32 -22
- package/shared/column_measurement.svelte.ts +103 -0
- package/shared/icons/FilterIcon.svelte +14 -6
- package/shared/icons/Padlock.svelte +6 -2
- package/shared/icons/SelectionButtons.svelte +23 -8
- package/shared/icons/SortButtonDown.svelte +15 -4
- package/shared/icons/SortButtonUp.svelte +15 -5
- package/shared/icons/SortIcon.svelte +13 -7
- package/shared/tanstack/index.ts +23 -0
- package/shared/tanstack/table.svelte.ts +117 -0
- package/shared/tanstack/virtual.svelte.ts +105 -0
- package/shared/types.ts +3 -0
- package/shared/utils/filter.ts +66 -0
- package/shared/utils/selection_utils.ts +1 -1
- package/shared/utils/table_utils.ts +1 -100
- package/standalone/Index.svelte +71 -46
- package/test/filter.test.ts +350 -0
- package/test/selection_utils.test.ts +416 -0
- package/test/table_utils.test.ts +45 -112
- package/types.ts +34 -0
- package/dist/shared/TableCell.svelte +0 -330
- package/dist/shared/TableCell.svelte.d.ts +0 -66
- package/dist/shared/TableHeader.svelte +0 -344
- package/dist/shared/TableHeader.svelte.d.ts +0 -61
- package/dist/shared/VirtualTable.svelte +0 -379
- package/dist/shared/VirtualTable.svelte.d.ts +0 -42
- package/dist/shared/context/dataframe_context.d.ts +0 -180
- package/dist/shared/context/dataframe_context.js +0 -412
- package/dist/shared/icons/SortArrowDown.svelte +0 -25
- package/dist/shared/icons/SortArrowDown.svelte.d.ts +0 -20
- package/dist/shared/icons/SortArrowUp.svelte +0 -25
- package/dist/shared/icons/SortArrowUp.svelte.d.ts +0 -20
- package/dist/shared/utils/data_processing.d.ts +0 -14
- package/dist/shared/utils/data_processing.js +0 -47
- package/dist/shared/utils/drag_utils.d.ts +0 -15
- package/dist/shared/utils/drag_utils.js +0 -67
- package/dist/shared/utils/filter_utils.d.ts +0 -29
- package/dist/shared/utils/filter_utils.js +0 -123
- package/dist/shared/utils/keyboard_utils.d.ts +0 -3
- package/dist/shared/utils/keyboard_utils.js +0 -236
- package/dist/shared/utils/menu_utils.d.ts +0 -42
- package/dist/shared/utils/menu_utils.js +0 -58
- package/dist/shared/utils/sort_utils.d.ts +0 -26
- package/dist/shared/utils/sort_utils.js +0 -59
- package/shared/TableCell.svelte +0 -330
- package/shared/TableHeader.svelte +0 -344
- package/shared/VirtualTable.svelte +0 -379
- package/shared/context/dataframe_context.ts +0 -701
- package/shared/icons/SortArrowDown.svelte +0 -25
- package/shared/icons/SortArrowUp.svelte +0 -25
- package/shared/utils/data_processing.ts +0 -77
- package/shared/utils/drag_utils.ts +0 -105
- package/shared/utils/filter_utils.ts +0 -208
- package/shared/utils/keyboard_utils.ts +0 -309
- package/shared/utils/menu_utils.ts +0 -115
- package/shared/utils/sort_utils.ts +0 -91
- package/test/sort_utils.test.ts +0 -323
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
import { dequal } from "dequal/lite";
|
|
2
|
-
import { handle_delete_key } from "../utils/selection_utils";
|
|
3
|
-
import type { DataFrameContext } from "../context/dataframe_context";
|
|
4
|
-
import { tick } from "svelte";
|
|
5
|
-
import { get } from "svelte/store";
|
|
6
|
-
import { copy_table_data } from "./table_utils";
|
|
7
|
-
|
|
8
|
-
async function save_cell_value(
|
|
9
|
-
input_value: string,
|
|
10
|
-
ctx: DataFrameContext,
|
|
11
|
-
row: number,
|
|
12
|
-
col: number
|
|
13
|
-
): Promise<void> {
|
|
14
|
-
if (!ctx.data || !ctx.data[row] || !ctx.data[row][col]) return;
|
|
15
|
-
|
|
16
|
-
const old_value = ctx.data[row][col].value;
|
|
17
|
-
ctx.data[row][col].value = input_value;
|
|
18
|
-
if (ctx.data[row][col].display_value !== undefined) {
|
|
19
|
-
ctx.data[row][col].display_value = input_value;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (old_value !== input_value && ctx.dispatch) {
|
|
23
|
-
ctx.dispatch("change", {
|
|
24
|
-
data: ctx.data.map((row) => row.map((cell) => cell.value)),
|
|
25
|
-
headers: ctx.headers?.map((h) => h.value) || [],
|
|
26
|
-
metadata: null
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
ctx.actions.set_selected([row, col]);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function handle_cell_blur(
|
|
34
|
-
event: FocusEvent,
|
|
35
|
-
ctx: DataFrameContext,
|
|
36
|
-
coords: [number, number]
|
|
37
|
-
): Promise<void> {
|
|
38
|
-
if (!ctx.data || !ctx.headers || !ctx.els) return;
|
|
39
|
-
|
|
40
|
-
const input_el = event.target as HTMLInputElement;
|
|
41
|
-
if (!input_el || input_el.value === undefined) return;
|
|
42
|
-
|
|
43
|
-
await save_cell_value(input_el.value, ctx, coords[0], coords[1]);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function handle_header_navigation(
|
|
47
|
-
event: KeyboardEvent,
|
|
48
|
-
ctx: DataFrameContext
|
|
49
|
-
): boolean {
|
|
50
|
-
const state = get(ctx.state);
|
|
51
|
-
const selected_header = state.ui_state.selected_header;
|
|
52
|
-
const header_edit = state.ui_state.header_edit;
|
|
53
|
-
const headers = ctx.headers || [];
|
|
54
|
-
|
|
55
|
-
if (selected_header === false || header_edit !== false) return false;
|
|
56
|
-
|
|
57
|
-
switch (event.key) {
|
|
58
|
-
case "ArrowDown":
|
|
59
|
-
ctx.actions.set_selected_header(false);
|
|
60
|
-
ctx.actions.set_selected([0, selected_header as number]);
|
|
61
|
-
ctx.actions.set_selected_cells([[0, selected_header as number]]);
|
|
62
|
-
return true;
|
|
63
|
-
case "ArrowLeft":
|
|
64
|
-
ctx.actions.set_selected_header(
|
|
65
|
-
selected_header > 0 ? selected_header - 1 : selected_header
|
|
66
|
-
);
|
|
67
|
-
return true;
|
|
68
|
-
case "ArrowRight":
|
|
69
|
-
ctx.actions.set_selected_header(
|
|
70
|
-
selected_header < headers.length - 1
|
|
71
|
-
? selected_header + 1
|
|
72
|
-
: selected_header
|
|
73
|
-
);
|
|
74
|
-
return true;
|
|
75
|
-
case "Escape":
|
|
76
|
-
event.preventDefault();
|
|
77
|
-
ctx.actions.set_selected_header(false);
|
|
78
|
-
return true;
|
|
79
|
-
case "Enter":
|
|
80
|
-
event.preventDefault();
|
|
81
|
-
if (state.config.editable) {
|
|
82
|
-
ctx.actions.set_header_edit(selected_header);
|
|
83
|
-
}
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// eslint-disable-next-line complexity
|
|
90
|
-
function handle_delete_operation(
|
|
91
|
-
event: KeyboardEvent,
|
|
92
|
-
ctx: DataFrameContext
|
|
93
|
-
): boolean {
|
|
94
|
-
if (!ctx.data || !ctx.headers || !ctx.els || !ctx.dispatch) return false;
|
|
95
|
-
|
|
96
|
-
const state = get(ctx.state);
|
|
97
|
-
if (!state.config.editable) return false;
|
|
98
|
-
if (event.key !== "Delete" && event.key !== "Backspace") return false;
|
|
99
|
-
|
|
100
|
-
const editing = state.ui_state.editing;
|
|
101
|
-
const selected_cells = state.ui_state.selected_cells;
|
|
102
|
-
|
|
103
|
-
const static_columns = state.config.static_columns || [];
|
|
104
|
-
if (selected_cells.some(([_, col]) => static_columns.includes(col))) {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (editing) {
|
|
109
|
-
const [row, col] = editing;
|
|
110
|
-
const input_el = ctx.els[ctx.data[row][col].id]?.input;
|
|
111
|
-
if (input_el && input_el.selectionStart !== input_el.selectionEnd) {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
if (
|
|
115
|
-
event.key === "Delete" &&
|
|
116
|
-
input_el?.selectionStart !== input_el?.value.length
|
|
117
|
-
) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
if (event.key === "Backspace" && input_el?.selectionStart !== 0) {
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
event.preventDefault();
|
|
126
|
-
if (selected_cells.length > 0) {
|
|
127
|
-
const new_data = handle_delete_key(ctx.data, selected_cells);
|
|
128
|
-
ctx.dispatch("change", {
|
|
129
|
-
data: new_data.map((row) => row.map((cell) => cell.value)),
|
|
130
|
-
headers: ctx.headers.map((h) => h.value),
|
|
131
|
-
metadata: null
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
return true;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function handle_arrow_keys(
|
|
138
|
-
event: KeyboardEvent,
|
|
139
|
-
ctx: DataFrameContext,
|
|
140
|
-
i: number,
|
|
141
|
-
j: number
|
|
142
|
-
): boolean {
|
|
143
|
-
const state = get(ctx.state);
|
|
144
|
-
const editing = state.ui_state.editing;
|
|
145
|
-
const selected_cells = state.ui_state.selected_cells;
|
|
146
|
-
|
|
147
|
-
if (editing) return false;
|
|
148
|
-
if (!ctx.data) return false;
|
|
149
|
-
|
|
150
|
-
event.preventDefault();
|
|
151
|
-
|
|
152
|
-
const next_coords = ctx.actions.move_cursor(event, [i, j], ctx.data);
|
|
153
|
-
if (next_coords) {
|
|
154
|
-
if (event.shiftKey) {
|
|
155
|
-
ctx.actions.set_selected_cells(
|
|
156
|
-
ctx.actions.get_range_selection(
|
|
157
|
-
selected_cells.length > 0 ? selected_cells[0] : [i, j],
|
|
158
|
-
next_coords
|
|
159
|
-
)
|
|
160
|
-
);
|
|
161
|
-
ctx.actions.set_editing(false);
|
|
162
|
-
} else {
|
|
163
|
-
ctx.actions.set_selected_cells([next_coords]);
|
|
164
|
-
ctx.actions.set_editing(false);
|
|
165
|
-
}
|
|
166
|
-
ctx.actions.set_selected(next_coords);
|
|
167
|
-
} else if (next_coords === false && event.key === "ArrowUp" && i === 0) {
|
|
168
|
-
ctx.actions.set_selected_header(j);
|
|
169
|
-
ctx.actions.set_selected(false);
|
|
170
|
-
ctx.actions.set_selected_cells([]);
|
|
171
|
-
ctx.actions.set_editing(false);
|
|
172
|
-
}
|
|
173
|
-
return true;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async function handle_enter_key(
|
|
177
|
-
event: KeyboardEvent,
|
|
178
|
-
ctx: DataFrameContext,
|
|
179
|
-
i: number,
|
|
180
|
-
j: number
|
|
181
|
-
): Promise<boolean> {
|
|
182
|
-
if (!ctx.data || !ctx.els) return false;
|
|
183
|
-
|
|
184
|
-
const state = get(ctx.state);
|
|
185
|
-
if (!state.config.editable) return false;
|
|
186
|
-
|
|
187
|
-
const editing = state.ui_state.editing;
|
|
188
|
-
if (editing && event.shiftKey) return false;
|
|
189
|
-
|
|
190
|
-
event.preventDefault();
|
|
191
|
-
|
|
192
|
-
if (editing && dequal(editing, [i, j])) {
|
|
193
|
-
const cell_id = ctx.data[i][j].id;
|
|
194
|
-
const input_el = ctx.els[cell_id]?.input;
|
|
195
|
-
if (input_el) {
|
|
196
|
-
await save_cell_value(input_el.value, ctx, i, j);
|
|
197
|
-
}
|
|
198
|
-
ctx.actions.set_editing(false);
|
|
199
|
-
await tick();
|
|
200
|
-
ctx.parent_element?.focus();
|
|
201
|
-
} else {
|
|
202
|
-
ctx.actions.set_editing([i, j]);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return true;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function handle_tab_key(
|
|
209
|
-
event: KeyboardEvent,
|
|
210
|
-
ctx: DataFrameContext,
|
|
211
|
-
i: number,
|
|
212
|
-
j: number
|
|
213
|
-
): boolean {
|
|
214
|
-
if (!ctx.data) return false;
|
|
215
|
-
|
|
216
|
-
event.preventDefault();
|
|
217
|
-
ctx.actions.set_editing(false);
|
|
218
|
-
const next_cell = ctx.actions.get_next_cell_coordinates(
|
|
219
|
-
[i, j],
|
|
220
|
-
ctx.data,
|
|
221
|
-
event.shiftKey
|
|
222
|
-
);
|
|
223
|
-
if (next_cell) {
|
|
224
|
-
ctx.actions.set_selected_cells([next_cell]);
|
|
225
|
-
ctx.actions.set_selected(next_cell);
|
|
226
|
-
if (get(ctx.state).config.editable) {
|
|
227
|
-
ctx.actions.set_editing(next_cell);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
return true;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
function handle_default_key(
|
|
234
|
-
event: KeyboardEvent,
|
|
235
|
-
ctx: DataFrameContext,
|
|
236
|
-
i: number,
|
|
237
|
-
j: number
|
|
238
|
-
): boolean {
|
|
239
|
-
const state = get(ctx.state);
|
|
240
|
-
if (!state.config.editable) return false;
|
|
241
|
-
|
|
242
|
-
const editing = state.ui_state.editing;
|
|
243
|
-
|
|
244
|
-
if (event.key.length === 1 && (!editing || !dequal(editing, [i, j]))) {
|
|
245
|
-
ctx.actions.set_editing([i, j]);
|
|
246
|
-
return true;
|
|
247
|
-
}
|
|
248
|
-
return false;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
async function handle_cell_navigation(
|
|
252
|
-
event: KeyboardEvent,
|
|
253
|
-
ctx: DataFrameContext
|
|
254
|
-
): Promise<boolean> {
|
|
255
|
-
if (!ctx.data) return false;
|
|
256
|
-
|
|
257
|
-
const state = get(ctx.state);
|
|
258
|
-
const selected = state.ui_state.selected;
|
|
259
|
-
const selected_cells = state.ui_state.selected_cells;
|
|
260
|
-
|
|
261
|
-
if (!selected) return false;
|
|
262
|
-
if (event.key === "c" && (event.metaKey || event.ctrlKey)) {
|
|
263
|
-
event.preventDefault();
|
|
264
|
-
if (selected_cells.length > 0) {
|
|
265
|
-
await copy_table_data(ctx.data, selected_cells);
|
|
266
|
-
}
|
|
267
|
-
ctx.actions.set_copy_flash(true);
|
|
268
|
-
return true;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const [i, j] = selected;
|
|
272
|
-
|
|
273
|
-
switch (event.key) {
|
|
274
|
-
case "ArrowRight":
|
|
275
|
-
case "ArrowLeft":
|
|
276
|
-
case "ArrowDown":
|
|
277
|
-
case "ArrowUp":
|
|
278
|
-
return handle_arrow_keys(event, ctx, i, j);
|
|
279
|
-
case "Escape":
|
|
280
|
-
if (!state.config.editable) return false;
|
|
281
|
-
event.preventDefault();
|
|
282
|
-
ctx.actions.set_editing(false);
|
|
283
|
-
tick().then(() => {
|
|
284
|
-
if (ctx.parent_element) {
|
|
285
|
-
ctx.parent_element.focus();
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
return true;
|
|
290
|
-
case "Enter":
|
|
291
|
-
return await handle_enter_key(event, ctx, i, j);
|
|
292
|
-
case "Tab":
|
|
293
|
-
return handle_tab_key(event, ctx, i, j);
|
|
294
|
-
case "Delete":
|
|
295
|
-
case "Backspace":
|
|
296
|
-
return handle_delete_operation(event, ctx);
|
|
297
|
-
default:
|
|
298
|
-
return handle_default_key(event, ctx, i, j);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
export async function handle_keydown(
|
|
303
|
-
event: KeyboardEvent,
|
|
304
|
-
context: DataFrameContext
|
|
305
|
-
): Promise<void> {
|
|
306
|
-
if (handle_header_navigation(event, context)) return;
|
|
307
|
-
if (handle_delete_operation(event, context)) return;
|
|
308
|
-
await handle_cell_navigation(event, context);
|
|
309
|
-
}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
export function toggle_header_menu(
|
|
2
|
-
event: MouseEvent,
|
|
3
|
-
col: number,
|
|
4
|
-
active_header_menu: { col: number; x: number; y: number } | null,
|
|
5
|
-
set_active_header_menu: (
|
|
6
|
-
menu: { col: number; x: number; y: number } | null
|
|
7
|
-
) => void
|
|
8
|
-
): void {
|
|
9
|
-
event.stopPropagation();
|
|
10
|
-
if (active_header_menu && active_header_menu.col === col) {
|
|
11
|
-
set_active_header_menu(null);
|
|
12
|
-
} else {
|
|
13
|
-
const header = (event.target as HTMLElement).closest("th");
|
|
14
|
-
if (header) {
|
|
15
|
-
const rect = header.getBoundingClientRect();
|
|
16
|
-
set_active_header_menu({ col, x: rect.right, y: rect.bottom });
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function toggle_cell_menu(
|
|
22
|
-
event: MouseEvent,
|
|
23
|
-
row: number,
|
|
24
|
-
col: number,
|
|
25
|
-
active_cell_menu: { row: number; col: number; x: number; y: number } | null,
|
|
26
|
-
set_active_cell_menu: (
|
|
27
|
-
menu: { row: number; col: number; x: number; y: number } | null
|
|
28
|
-
) => void
|
|
29
|
-
): void {
|
|
30
|
-
event.stopPropagation();
|
|
31
|
-
if (
|
|
32
|
-
active_cell_menu &&
|
|
33
|
-
active_cell_menu.row === row &&
|
|
34
|
-
active_cell_menu.col === col
|
|
35
|
-
) {
|
|
36
|
-
set_active_cell_menu(null);
|
|
37
|
-
} else {
|
|
38
|
-
const cell = (event.target as HTMLElement).closest("td");
|
|
39
|
-
if (cell) {
|
|
40
|
-
const rect = cell.getBoundingClientRect();
|
|
41
|
-
set_active_cell_menu({ row, col, x: rect.right, y: rect.bottom });
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function add_row_at(
|
|
47
|
-
index: number,
|
|
48
|
-
position: "above" | "below",
|
|
49
|
-
add_row: (index?: number) => void,
|
|
50
|
-
clear_menus: () => void
|
|
51
|
-
): void {
|
|
52
|
-
const row_index = position === "above" ? index : index + 1;
|
|
53
|
-
add_row(row_index);
|
|
54
|
-
clear_menus();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function add_col_at(
|
|
58
|
-
index: number,
|
|
59
|
-
position: "left" | "right",
|
|
60
|
-
add_col: (index?: number) => void,
|
|
61
|
-
clear_menus: () => void
|
|
62
|
-
): void {
|
|
63
|
-
const col_index = position === "left" ? index : index + 1;
|
|
64
|
-
add_col(col_index);
|
|
65
|
-
clear_menus();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function delete_row_at(
|
|
69
|
-
index: number,
|
|
70
|
-
delete_row: (index: number) => void,
|
|
71
|
-
clear_menus: () => void
|
|
72
|
-
): void {
|
|
73
|
-
delete_row(index);
|
|
74
|
-
clear_menus();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function delete_col_at(
|
|
78
|
-
index: number,
|
|
79
|
-
delete_col: (index: number) => void,
|
|
80
|
-
clear_menus: () => void
|
|
81
|
-
): void {
|
|
82
|
-
delete_col(index);
|
|
83
|
-
clear_menus();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function toggle_header_button(
|
|
87
|
-
col: number,
|
|
88
|
-
active_button: { type: "header" | "cell"; row?: number; col: number } | null,
|
|
89
|
-
set_active_button: (
|
|
90
|
-
button: { type: "header" | "cell"; row?: number; col: number } | null
|
|
91
|
-
) => void
|
|
92
|
-
): void {
|
|
93
|
-
set_active_button(
|
|
94
|
-
active_button?.type === "header" && active_button.col === col
|
|
95
|
-
? null
|
|
96
|
-
: { type: "header", col }
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function toggle_cell_button(
|
|
101
|
-
row: number,
|
|
102
|
-
col: number,
|
|
103
|
-
active_button: { type: "header" | "cell"; row?: number; col: number } | null,
|
|
104
|
-
set_active_button: (
|
|
105
|
-
button: { type: "header" | "cell"; row?: number; col: number } | null
|
|
106
|
-
) => void
|
|
107
|
-
): void {
|
|
108
|
-
set_active_button(
|
|
109
|
-
active_button?.type === "cell" &&
|
|
110
|
-
active_button.row === row &&
|
|
111
|
-
active_button.col === col
|
|
112
|
-
? null
|
|
113
|
-
: { type: "cell", row, col }
|
|
114
|
-
);
|
|
115
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import type { Headers, CellValue } from "../types";
|
|
2
|
-
import { sort_table_data } from "./table_utils";
|
|
3
|
-
|
|
4
|
-
export type SortDirection = "asc" | "desc";
|
|
5
|
-
|
|
6
|
-
export function get_sort_status(
|
|
7
|
-
name: string,
|
|
8
|
-
sort_columns: { col: number; direction: SortDirection }[],
|
|
9
|
-
headers: Headers
|
|
10
|
-
): "none" | "asc" | "desc" {
|
|
11
|
-
if (!sort_columns.length) return "none";
|
|
12
|
-
|
|
13
|
-
const sort_item = sort_columns.find((item) => {
|
|
14
|
-
const col = item.col;
|
|
15
|
-
if (col < 0 || col >= headers.length) return false;
|
|
16
|
-
return headers[col] === name;
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
if (!sort_item) return "none";
|
|
20
|
-
return sort_item.direction;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function sort_data(
|
|
24
|
-
data: { id: string; value: CellValue }[][],
|
|
25
|
-
sort_columns: { col: number; direction: SortDirection }[]
|
|
26
|
-
): number[] {
|
|
27
|
-
if (!data || !data.length || !data[0]) {
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (sort_columns.length > 0) {
|
|
32
|
-
const row_indices = [...Array(data.length)].map((_, i) => i);
|
|
33
|
-
row_indices.sort((row_a_idx, row_b_idx) => {
|
|
34
|
-
const row_a = data[row_a_idx];
|
|
35
|
-
const row_b = data[row_b_idx];
|
|
36
|
-
|
|
37
|
-
for (const { col: sort_by, direction } of sort_columns) {
|
|
38
|
-
if (
|
|
39
|
-
!row_a ||
|
|
40
|
-
!row_b ||
|
|
41
|
-
sort_by < 0 ||
|
|
42
|
-
sort_by >= row_a.length ||
|
|
43
|
-
sort_by >= row_b.length ||
|
|
44
|
-
!row_a[sort_by] ||
|
|
45
|
-
!row_b[sort_by]
|
|
46
|
-
) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const val_a = row_a[sort_by].value;
|
|
51
|
-
const val_b = row_b[sort_by].value;
|
|
52
|
-
const comparison = val_a < val_b ? -1 : val_a > val_b ? 1 : 0;
|
|
53
|
-
|
|
54
|
-
if (comparison !== 0) {
|
|
55
|
-
return direction === "asc" ? comparison : -comparison;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return 0;
|
|
60
|
-
});
|
|
61
|
-
return row_indices;
|
|
62
|
-
}
|
|
63
|
-
return [...Array(data.length)].map((_, i) => i);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function sort_data_and_preserve_selection(
|
|
67
|
-
data: { id: string; value: CellValue }[][],
|
|
68
|
-
display_value: string[][] | null,
|
|
69
|
-
styling: string[][] | null,
|
|
70
|
-
sort_columns: { col: number; direction: SortDirection }[],
|
|
71
|
-
selected: [number, number] | false,
|
|
72
|
-
get_current_indices: (
|
|
73
|
-
id: string,
|
|
74
|
-
data: { id: string; value: CellValue }[][]
|
|
75
|
-
) => [number, number]
|
|
76
|
-
): { data: typeof data; selected: [number, number] | false } {
|
|
77
|
-
let id = null;
|
|
78
|
-
if (selected && selected[0] in data && selected[1] in data[selected[0]]) {
|
|
79
|
-
id = data[selected[0]][selected[1]].id;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
sort_table_data(data, display_value, styling, sort_columns);
|
|
83
|
-
|
|
84
|
-
let new_selected = selected;
|
|
85
|
-
if (id) {
|
|
86
|
-
const [i, j] = get_current_indices(id, data);
|
|
87
|
-
new_selected = [i, j];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return { data, selected: new_selected };
|
|
91
|
-
}
|