@gradio/dataframe 0.17.4 → 0.17.6
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 +25 -0
- package/Dataframe.stories.svelte +29 -0
- package/dist/shared/CellMenu.svelte.d.ts +1 -1
- package/dist/shared/EditableCell.svelte +8 -17
- package/dist/shared/EditableCell.svelte.d.ts +5 -3
- package/dist/shared/Table.svelte +111 -138
- package/dist/shared/TableCell.svelte +4 -6
- package/dist/shared/TableCell.svelte.d.ts +5 -1
- package/dist/shared/TableHeader.svelte +4 -3
- package/dist/shared/TableHeader.svelte.d.ts +1 -2
- package/dist/shared/context/dataframe_context.d.ts +147 -0
- package/dist/shared/context/dataframe_context.js +335 -0
- package/dist/shared/selection_utils.d.ts +1 -2
- package/dist/shared/selection_utils.js +0 -13
- package/dist/shared/utils/drag_utils.js +1 -0
- package/dist/shared/utils/keyboard_utils.d.ts +3 -2
- package/dist/shared/utils/keyboard_utils.js +107 -68
- package/package.json +6 -6
- package/shared/CellMenu.svelte +1 -1
- package/shared/EditableCell.svelte +9 -20
- package/shared/Table.svelte +147 -165
- package/shared/TableCell.svelte +9 -6
- package/shared/TableHeader.svelte +5 -8
- package/shared/context/dataframe_context.ts +576 -0
- package/shared/selection_utils.ts +1 -23
- package/shared/utils/drag_utils.ts +1 -0
- package/shared/utils/keyboard_utils.ts +142 -80
- package/{shared/utils → test}/sort_utils.test.ts +5 -1
- package/{shared/utils → test}/table_utils.test.ts +2 -2
- package/dist/shared/context/keyboard_context.d.ts +0 -37
- package/dist/shared/context/keyboard_context.js +0 -12
- package/dist/shared/context/selection_context.d.ts +0 -32
- package/dist/shared/context/selection_context.js +0 -107
- package/dist/shared/context/table_context.d.ts +0 -141
- package/dist/shared/context/table_context.js +0 -375
- package/shared/context/keyboard_context.ts +0 -65
- package/shared/context/selection_context.ts +0 -168
- package/shared/context/table_context.ts +0 -625
|
@@ -1,40 +1,82 @@
|
|
|
1
1
|
import { dequal } from "dequal/lite";
|
|
2
2
|
import { handle_delete_key } from "../selection_utils";
|
|
3
|
-
import type {
|
|
3
|
+
import type { DataFrameContext } from "../context/dataframe_context";
|
|
4
4
|
import { tick } from "svelte";
|
|
5
|
+
import { get } from "svelte/store";
|
|
5
6
|
import { copy_table_data } from "./table_utils";
|
|
6
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
|
+
|
|
19
|
+
if (old_value !== input_value && ctx.dispatch) {
|
|
20
|
+
ctx.dispatch("change", {
|
|
21
|
+
data: ctx.data.map((row) => row.map((cell) => cell.value)),
|
|
22
|
+
headers: ctx.headers?.map((h) => h.value) || [],
|
|
23
|
+
metadata: null
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
ctx.actions.set_selected([row, col]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function handle_cell_blur(
|
|
31
|
+
event: FocusEvent,
|
|
32
|
+
ctx: DataFrameContext,
|
|
33
|
+
coords: [number, number]
|
|
34
|
+
): Promise<void> {
|
|
35
|
+
if (!ctx.data || !ctx.headers || !ctx.els) return;
|
|
36
|
+
|
|
37
|
+
const input_el = event.target as HTMLInputElement;
|
|
38
|
+
if (!input_el || input_el.value === undefined) return;
|
|
39
|
+
|
|
40
|
+
await save_cell_value(input_el.value, ctx, coords[0], coords[1]);
|
|
41
|
+
}
|
|
42
|
+
|
|
7
43
|
function handle_header_navigation(
|
|
8
44
|
event: KeyboardEvent,
|
|
9
|
-
ctx:
|
|
45
|
+
ctx: DataFrameContext
|
|
10
46
|
): boolean {
|
|
11
|
-
|
|
47
|
+
const state = get(ctx.state);
|
|
48
|
+
const selected_header = state.ui_state.selected_header;
|
|
49
|
+
const header_edit = state.ui_state.header_edit;
|
|
50
|
+
const headers = ctx.headers || [];
|
|
51
|
+
|
|
52
|
+
if (selected_header === false || header_edit !== false) return false;
|
|
53
|
+
|
|
12
54
|
switch (event.key) {
|
|
13
55
|
case "ArrowDown":
|
|
14
|
-
ctx.
|
|
15
|
-
ctx.
|
|
16
|
-
ctx.
|
|
56
|
+
ctx.actions.set_selected_header(false);
|
|
57
|
+
ctx.actions.set_selected([0, selected_header as number]);
|
|
58
|
+
ctx.actions.set_selected_cells([[0, selected_header as number]]);
|
|
17
59
|
return true;
|
|
18
60
|
case "ArrowLeft":
|
|
19
|
-
ctx.
|
|
20
|
-
|
|
61
|
+
ctx.actions.set_selected_header(
|
|
62
|
+
selected_header > 0 ? selected_header - 1 : selected_header
|
|
21
63
|
);
|
|
22
64
|
return true;
|
|
23
65
|
case "ArrowRight":
|
|
24
|
-
ctx.
|
|
25
|
-
|
|
26
|
-
?
|
|
27
|
-
:
|
|
66
|
+
ctx.actions.set_selected_header(
|
|
67
|
+
selected_header < headers.length - 1
|
|
68
|
+
? selected_header + 1
|
|
69
|
+
: selected_header
|
|
28
70
|
);
|
|
29
71
|
return true;
|
|
30
72
|
case "Escape":
|
|
31
73
|
event.preventDefault();
|
|
32
|
-
ctx.
|
|
74
|
+
ctx.actions.set_selected_header(false);
|
|
33
75
|
return true;
|
|
34
76
|
case "Enter":
|
|
35
77
|
event.preventDefault();
|
|
36
|
-
if (
|
|
37
|
-
ctx.
|
|
78
|
+
if (state.config.editable) {
|
|
79
|
+
ctx.actions.set_header_edit(selected_header);
|
|
38
80
|
}
|
|
39
81
|
return true;
|
|
40
82
|
}
|
|
@@ -43,14 +85,20 @@ function handle_header_navigation(
|
|
|
43
85
|
|
|
44
86
|
function handle_delete_operation(
|
|
45
87
|
event: KeyboardEvent,
|
|
46
|
-
ctx:
|
|
88
|
+
ctx: DataFrameContext
|
|
47
89
|
): boolean {
|
|
48
|
-
if (!ctx.
|
|
90
|
+
if (!ctx.data || !ctx.headers || !ctx.els || !ctx.dispatch) return false;
|
|
91
|
+
|
|
92
|
+
const state = get(ctx.state);
|
|
93
|
+
if (!state.config.editable) return false;
|
|
49
94
|
if (event.key !== "Delete" && event.key !== "Backspace") return false;
|
|
50
95
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
96
|
+
const editing = state.ui_state.editing;
|
|
97
|
+
const selected_cells = state.ui_state.selected_cells;
|
|
98
|
+
|
|
99
|
+
if (editing) {
|
|
100
|
+
const [row, col] = editing;
|
|
101
|
+
const input_el = ctx.els[ctx.data[row][col].id]?.input;
|
|
54
102
|
if (input_el && input_el.selectionStart !== input_el.selectionEnd) {
|
|
55
103
|
return false;
|
|
56
104
|
}
|
|
@@ -66,103 +114,105 @@ function handle_delete_operation(
|
|
|
66
114
|
}
|
|
67
115
|
|
|
68
116
|
event.preventDefault();
|
|
69
|
-
if (
|
|
70
|
-
const new_data = handle_delete_key(ctx.data,
|
|
117
|
+
if (selected_cells.length > 0) {
|
|
118
|
+
const new_data = handle_delete_key(ctx.data, selected_cells);
|
|
71
119
|
ctx.dispatch("change", {
|
|
72
120
|
data: new_data.map((row) => row.map((cell) => cell.value)),
|
|
73
121
|
headers: ctx.headers.map((h) => h.value),
|
|
74
122
|
metadata: null
|
|
75
123
|
});
|
|
76
|
-
ctx.dispatch("input");
|
|
77
124
|
}
|
|
78
125
|
return true;
|
|
79
126
|
}
|
|
80
127
|
|
|
81
128
|
function handle_arrow_keys(
|
|
82
129
|
event: KeyboardEvent,
|
|
83
|
-
ctx:
|
|
130
|
+
ctx: DataFrameContext,
|
|
84
131
|
i: number,
|
|
85
132
|
j: number
|
|
86
133
|
): boolean {
|
|
87
|
-
|
|
134
|
+
const state = get(ctx.state);
|
|
135
|
+
const editing = state.ui_state.editing;
|
|
136
|
+
const selected_cells = state.ui_state.selected_cells;
|
|
137
|
+
|
|
138
|
+
if (editing) return false;
|
|
139
|
+
if (!ctx.data) return false;
|
|
140
|
+
|
|
88
141
|
event.preventDefault();
|
|
89
142
|
|
|
90
|
-
const next_coords = ctx.move_cursor(event, [i, j], ctx.data);
|
|
143
|
+
const next_coords = ctx.actions.move_cursor(event, [i, j], ctx.data);
|
|
91
144
|
if (next_coords) {
|
|
92
145
|
if (event.shiftKey) {
|
|
93
|
-
ctx.
|
|
94
|
-
ctx.get_range_selection(
|
|
95
|
-
|
|
146
|
+
ctx.actions.set_selected_cells(
|
|
147
|
+
ctx.actions.get_range_selection(
|
|
148
|
+
selected_cells.length > 0 ? selected_cells[0] : [i, j],
|
|
96
149
|
next_coords
|
|
97
150
|
)
|
|
98
151
|
);
|
|
99
|
-
ctx.
|
|
152
|
+
ctx.actions.set_editing(false);
|
|
100
153
|
} else {
|
|
101
|
-
ctx.
|
|
102
|
-
ctx.
|
|
154
|
+
ctx.actions.set_selected_cells([next_coords]);
|
|
155
|
+
ctx.actions.set_editing(false);
|
|
103
156
|
}
|
|
104
|
-
ctx.
|
|
157
|
+
ctx.actions.set_selected(next_coords);
|
|
105
158
|
} else if (next_coords === false && event.key === "ArrowUp" && i === 0) {
|
|
106
|
-
ctx.
|
|
107
|
-
ctx.
|
|
108
|
-
ctx.
|
|
109
|
-
ctx.
|
|
159
|
+
ctx.actions.set_selected_header(j);
|
|
160
|
+
ctx.actions.set_selected(false);
|
|
161
|
+
ctx.actions.set_selected_cells([]);
|
|
162
|
+
ctx.actions.set_editing(false);
|
|
110
163
|
}
|
|
111
164
|
return true;
|
|
112
165
|
}
|
|
113
166
|
|
|
114
167
|
async function handle_enter_key(
|
|
115
168
|
event: KeyboardEvent,
|
|
116
|
-
ctx:
|
|
169
|
+
ctx: DataFrameContext,
|
|
117
170
|
i: number,
|
|
118
171
|
j: number
|
|
119
172
|
): Promise<boolean> {
|
|
173
|
+
if (!ctx.data || !ctx.els) return false;
|
|
174
|
+
|
|
175
|
+
const state = get(ctx.state);
|
|
176
|
+
if (!state.config.editable) return false;
|
|
177
|
+
|
|
120
178
|
event.preventDefault();
|
|
121
|
-
if (!ctx.editable) return false;
|
|
122
179
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
ctx.
|
|
127
|
-
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
const input_el = ctx.els[cell_id].input;
|
|
131
|
-
if (input_el) {
|
|
132
|
-
const old_value = ctx.data[i][j].value;
|
|
133
|
-
ctx.data[i][j].value = input_el.value;
|
|
134
|
-
if (old_value !== input_el.value) {
|
|
135
|
-
ctx.dispatch("input");
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
ctx.df_actions.set_editing(false);
|
|
139
|
-
await tick();
|
|
140
|
-
ctx.df_actions.set_selected([i, j]);
|
|
141
|
-
} else {
|
|
142
|
-
ctx.df_actions.set_editing([i, j]);
|
|
180
|
+
const editing = state.ui_state.editing;
|
|
181
|
+
|
|
182
|
+
if (editing && dequal(editing, [i, j])) {
|
|
183
|
+
const cell_id = ctx.data[i][j].id;
|
|
184
|
+
const input_el = ctx.els[cell_id]?.input;
|
|
185
|
+
if (input_el) {
|
|
186
|
+
await save_cell_value(input_el.value, ctx, i, j);
|
|
143
187
|
}
|
|
188
|
+
ctx.actions.set_editing(false);
|
|
189
|
+
} else {
|
|
190
|
+
ctx.actions.set_editing([i, j]);
|
|
144
191
|
}
|
|
192
|
+
|
|
145
193
|
return true;
|
|
146
194
|
}
|
|
147
195
|
|
|
148
196
|
function handle_tab_key(
|
|
149
197
|
event: KeyboardEvent,
|
|
150
|
-
ctx:
|
|
198
|
+
ctx: DataFrameContext,
|
|
151
199
|
i: number,
|
|
152
200
|
j: number
|
|
153
201
|
): boolean {
|
|
202
|
+
if (!ctx.data) return false;
|
|
203
|
+
|
|
154
204
|
event.preventDefault();
|
|
155
|
-
ctx.
|
|
156
|
-
const next_cell = ctx.get_next_cell_coordinates(
|
|
205
|
+
ctx.actions.set_editing(false);
|
|
206
|
+
const next_cell = ctx.actions.get_next_cell_coordinates(
|
|
157
207
|
[i, j],
|
|
158
208
|
ctx.data,
|
|
159
209
|
event.shiftKey
|
|
160
210
|
);
|
|
161
211
|
if (next_cell) {
|
|
162
|
-
ctx.
|
|
163
|
-
ctx.
|
|
164
|
-
if (ctx.editable) {
|
|
165
|
-
ctx.
|
|
212
|
+
ctx.actions.set_selected_cells([next_cell]);
|
|
213
|
+
ctx.actions.set_selected(next_cell);
|
|
214
|
+
if (get(ctx.state).config.editable) {
|
|
215
|
+
ctx.actions.set_editing(next_cell);
|
|
166
216
|
}
|
|
167
217
|
}
|
|
168
218
|
return true;
|
|
@@ -170,16 +220,20 @@ function handle_tab_key(
|
|
|
170
220
|
|
|
171
221
|
function handle_default_key(
|
|
172
222
|
event: KeyboardEvent,
|
|
173
|
-
ctx:
|
|
223
|
+
ctx: DataFrameContext,
|
|
174
224
|
i: number,
|
|
175
225
|
j: number
|
|
176
226
|
): boolean {
|
|
177
|
-
|
|
227
|
+
const state = get(ctx.state);
|
|
228
|
+
if (!state.config.editable) return false;
|
|
229
|
+
|
|
230
|
+
const editing = state.ui_state.editing;
|
|
231
|
+
|
|
178
232
|
if (
|
|
179
|
-
(!
|
|
233
|
+
(!editing || (editing && dequal(editing, [i, j]))) &&
|
|
180
234
|
event.key.length === 1
|
|
181
235
|
) {
|
|
182
|
-
ctx.
|
|
236
|
+
ctx.actions.set_editing([i, j]);
|
|
183
237
|
return true;
|
|
184
238
|
}
|
|
185
239
|
return false;
|
|
@@ -187,20 +241,25 @@ function handle_default_key(
|
|
|
187
241
|
|
|
188
242
|
async function handle_cell_navigation(
|
|
189
243
|
event: KeyboardEvent,
|
|
190
|
-
ctx:
|
|
244
|
+
ctx: DataFrameContext
|
|
191
245
|
): Promise<boolean> {
|
|
192
|
-
if (!ctx.
|
|
246
|
+
if (!ctx.data) return false;
|
|
247
|
+
|
|
248
|
+
const state = get(ctx.state);
|
|
249
|
+
const selected = state.ui_state.selected;
|
|
250
|
+
const selected_cells = state.ui_state.selected_cells;
|
|
251
|
+
|
|
252
|
+
if (!selected) return false;
|
|
193
253
|
if (event.key === "c" && (event.metaKey || event.ctrlKey)) {
|
|
194
254
|
event.preventDefault();
|
|
195
|
-
if (
|
|
196
|
-
await copy_table_data(ctx.data,
|
|
255
|
+
if (selected_cells.length > 0) {
|
|
256
|
+
await copy_table_data(ctx.data, selected_cells);
|
|
197
257
|
}
|
|
198
|
-
ctx.set_copy_flash(true);
|
|
199
|
-
|
|
258
|
+
ctx.actions.set_copy_flash(true);
|
|
200
259
|
return true;
|
|
201
260
|
}
|
|
202
261
|
|
|
203
|
-
const [i, j] =
|
|
262
|
+
const [i, j] = selected;
|
|
204
263
|
|
|
205
264
|
switch (event.key) {
|
|
206
265
|
case "ArrowRight":
|
|
@@ -209,9 +268,9 @@ async function handle_cell_navigation(
|
|
|
209
268
|
case "ArrowUp":
|
|
210
269
|
return handle_arrow_keys(event, ctx, i, j);
|
|
211
270
|
case "Escape":
|
|
212
|
-
if (!
|
|
271
|
+
if (!state.config.editable) return false;
|
|
213
272
|
event.preventDefault();
|
|
214
|
-
ctx.
|
|
273
|
+
ctx.actions.set_editing(false);
|
|
215
274
|
tick().then(() => {
|
|
216
275
|
if (ctx.parent_element) {
|
|
217
276
|
ctx.parent_element.focus();
|
|
@@ -223,6 +282,9 @@ async function handle_cell_navigation(
|
|
|
223
282
|
return await handle_enter_key(event, ctx, i, j);
|
|
224
283
|
case "Tab":
|
|
225
284
|
return handle_tab_key(event, ctx, i, j);
|
|
285
|
+
case "Delete":
|
|
286
|
+
case "Backspace":
|
|
287
|
+
return handle_delete_operation(event, ctx);
|
|
226
288
|
default:
|
|
227
289
|
return handle_default_key(event, ctx, i, j);
|
|
228
290
|
}
|
|
@@ -230,7 +292,7 @@ async function handle_cell_navigation(
|
|
|
230
292
|
|
|
231
293
|
export async function handle_keydown(
|
|
232
294
|
event: KeyboardEvent,
|
|
233
|
-
context:
|
|
295
|
+
context: DataFrameContext
|
|
234
296
|
): Promise<void> {
|
|
235
297
|
if (handle_header_navigation(event, context)) return;
|
|
236
298
|
if (handle_delete_operation(event, context)) return;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { describe, test, expect } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
get_sort_status,
|
|
4
|
+
sort_data,
|
|
5
|
+
SortDirection
|
|
6
|
+
} from "../shared/utils/sort_utils";
|
|
3
7
|
|
|
4
8
|
describe("sort_utils", () => {
|
|
5
9
|
describe("get_sort_status", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, test, expect } from "vitest";
|
|
2
|
-
import { make_cell_id, make_header_id } from "
|
|
3
|
-
import { process_data, make_headers } from "
|
|
2
|
+
import { make_cell_id, make_header_id } from "../shared/utils/table_utils";
|
|
3
|
+
import { process_data, make_headers } from "../shared/utils/data_processing";
|
|
4
4
|
|
|
5
5
|
function make_id(): string {
|
|
6
6
|
return Math.random().toString(36).substring(2, 15);
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { DataFrameContext } from "./table_context";
|
|
2
|
-
import type { CellData } from "../selection_utils";
|
|
3
|
-
import type { DataframeValue } from "../utils";
|
|
4
|
-
import type { CellCoordinate } from "../types";
|
|
5
|
-
export type KeyboardContext = {
|
|
6
|
-
selected_header: number | false;
|
|
7
|
-
header_edit: number | false;
|
|
8
|
-
editing: [number, number] | false;
|
|
9
|
-
selected: [number, number] | false;
|
|
10
|
-
selected_cells: [number, number][];
|
|
11
|
-
editable: boolean;
|
|
12
|
-
data: CellData[][];
|
|
13
|
-
headers: {
|
|
14
|
-
id: string;
|
|
15
|
-
value: string;
|
|
16
|
-
}[];
|
|
17
|
-
els: Record<string, {
|
|
18
|
-
cell: null | HTMLTableCellElement;
|
|
19
|
-
input: null | HTMLInputElement;
|
|
20
|
-
}>;
|
|
21
|
-
df_actions: DataFrameContext["actions"];
|
|
22
|
-
dispatch: {
|
|
23
|
-
(e: "change", detail: DataframeValue): void;
|
|
24
|
-
(e: "input", detail?: undefined): void;
|
|
25
|
-
(e: "select", detail: any): void;
|
|
26
|
-
(e: "search", detail: string | null): void;
|
|
27
|
-
};
|
|
28
|
-
add_row: (index?: number) => Promise<void>;
|
|
29
|
-
get_next_cell_coordinates: (current: CellCoordinate, data: CellData[][], shift_key: boolean) => false | CellCoordinate;
|
|
30
|
-
get_range_selection: (start: CellCoordinate, end: CellCoordinate) => CellCoordinate[];
|
|
31
|
-
move_cursor: (event: KeyboardEvent, current_coords: CellCoordinate, data: CellData[][]) => false | CellCoordinate;
|
|
32
|
-
copy_flash: boolean;
|
|
33
|
-
set_copy_flash: (value: boolean) => void;
|
|
34
|
-
parent_element?: HTMLDivElement;
|
|
35
|
-
};
|
|
36
|
-
export declare function create_keyboard_context(context: KeyboardContext): KeyboardContext;
|
|
37
|
-
export declare function get_keyboard_context(): KeyboardContext | undefined;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { getContext, setContext } from "svelte";
|
|
2
|
-
const KEYBOARD_KEY = Symbol("keyboard");
|
|
3
|
-
export function create_keyboard_context(context) {
|
|
4
|
-
const instance_id = Symbol(`keyboard_${Math.random().toString(36).substring(2)}`);
|
|
5
|
-
setContext(instance_id, context);
|
|
6
|
-
setContext(KEYBOARD_KEY, { instance_id, context });
|
|
7
|
-
return context;
|
|
8
|
-
}
|
|
9
|
-
export function get_keyboard_context() {
|
|
10
|
-
const ctx = getContext(KEYBOARD_KEY);
|
|
11
|
-
return ctx ? ctx.context : getContext(KEYBOARD_KEY);
|
|
12
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { DataFrameContext } from "./table_context";
|
|
2
|
-
import type { CellData } from "../selection_utils";
|
|
3
|
-
import type { DataframeValue } from "../utils";
|
|
4
|
-
export type SelectionContext = {
|
|
5
|
-
df_actions: DataFrameContext["actions"];
|
|
6
|
-
dispatch: {
|
|
7
|
-
(e: "change", detail: DataframeValue): void;
|
|
8
|
-
(e: "input", detail?: undefined): void;
|
|
9
|
-
(e: "select", detail: any): void;
|
|
10
|
-
(e: "search", detail: string | null): void;
|
|
11
|
-
};
|
|
12
|
-
data: CellData[][];
|
|
13
|
-
els: Record<string, {
|
|
14
|
-
cell: null | HTMLTableCellElement;
|
|
15
|
-
input: null | HTMLInputElement;
|
|
16
|
-
}>;
|
|
17
|
-
editable: boolean;
|
|
18
|
-
show_row_numbers: boolean;
|
|
19
|
-
get_data_at: (row: number, col: number) => string | number;
|
|
20
|
-
clear_on_focus: boolean;
|
|
21
|
-
selected_cells: [number, number][];
|
|
22
|
-
parent_element: HTMLElement;
|
|
23
|
-
actions: {
|
|
24
|
-
handle_cell_click: (event: MouseEvent, row: number, col: number) => void;
|
|
25
|
-
toggle_cell_menu: (event: MouseEvent, row: number, col: number) => void;
|
|
26
|
-
toggle_cell_button: (row: number, col: number) => void;
|
|
27
|
-
handle_select_column: (col: number) => void;
|
|
28
|
-
handle_select_row: (row: number) => void;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
export declare function create_selection_context(context: Omit<SelectionContext, "actions">): SelectionContext;
|
|
32
|
-
export declare function get_selection_context(): SelectionContext;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { getContext, setContext } from "svelte";
|
|
2
|
-
import { tick } from "svelte";
|
|
3
|
-
import { handle_selection } from "../selection_utils";
|
|
4
|
-
const SELECTION_KEY = Symbol("selection");
|
|
5
|
-
export function create_selection_context(context) {
|
|
6
|
-
const instance_id = Symbol(`selection_${Math.random().toString(36).substring(2)}`);
|
|
7
|
-
const actions = {
|
|
8
|
-
handle_cell_click: (event, row, col) => {
|
|
9
|
-
if (event.target instanceof HTMLAnchorElement)
|
|
10
|
-
return;
|
|
11
|
-
event.preventDefault();
|
|
12
|
-
event.stopPropagation();
|
|
13
|
-
if (context.show_row_numbers && col === -1)
|
|
14
|
-
return;
|
|
15
|
-
context.clear_on_focus = false;
|
|
16
|
-
context.df_actions.set_active_cell_menu(null);
|
|
17
|
-
context.df_actions.set_active_header_menu(null);
|
|
18
|
-
context.df_actions.set_selected_header(false);
|
|
19
|
-
context.df_actions.set_header_edit(false);
|
|
20
|
-
const new_selected_cells = handle_selection([row, col], context.selected_cells || [], event);
|
|
21
|
-
context.df_actions.set_selected_cells(new_selected_cells);
|
|
22
|
-
context.df_actions.set_selected(new_selected_cells[0]);
|
|
23
|
-
if (context.editable) {
|
|
24
|
-
if (new_selected_cells.length === 1) {
|
|
25
|
-
context.df_actions.set_editing([row, col]);
|
|
26
|
-
tick().then(() => {
|
|
27
|
-
const input_el = context.els[context.data[row][col].id].input;
|
|
28
|
-
if (input_el) {
|
|
29
|
-
input_el.focus();
|
|
30
|
-
input_el.selectionStart = input_el.selectionEnd =
|
|
31
|
-
input_el.value.length;
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
context.df_actions.set_editing(false);
|
|
37
|
-
context.parent_element.focus();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
context.parent_element.focus();
|
|
42
|
-
}
|
|
43
|
-
actions.toggle_cell_button(row, col);
|
|
44
|
-
context.dispatch("select", {
|
|
45
|
-
index: [row, col],
|
|
46
|
-
value: context.get_data_at(row, col),
|
|
47
|
-
row_value: context.data[row].map((d) => d.value)
|
|
48
|
-
});
|
|
49
|
-
},
|
|
50
|
-
toggle_cell_menu: (event, row, col) => {
|
|
51
|
-
event.stopPropagation();
|
|
52
|
-
const current_menu = context.df_actions.get_active_cell_menu();
|
|
53
|
-
if (current_menu &&
|
|
54
|
-
current_menu.row === row &&
|
|
55
|
-
current_menu.col === col) {
|
|
56
|
-
context.df_actions.set_active_cell_menu(null);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
const cell = event.target.closest("td");
|
|
60
|
-
if (cell) {
|
|
61
|
-
const rect = cell.getBoundingClientRect();
|
|
62
|
-
context.df_actions.set_active_cell_menu({
|
|
63
|
-
row,
|
|
64
|
-
col,
|
|
65
|
-
x: rect.right,
|
|
66
|
-
y: rect.bottom
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
toggle_cell_button: (row, col) => {
|
|
72
|
-
const current_button = context.df_actions.get_active_button();
|
|
73
|
-
const new_button = current_button?.type === "cell" &&
|
|
74
|
-
current_button.row === row &&
|
|
75
|
-
current_button.col === col
|
|
76
|
-
? null
|
|
77
|
-
: { type: "cell", row, col };
|
|
78
|
-
context.df_actions.set_active_button(new_button);
|
|
79
|
-
},
|
|
80
|
-
handle_select_column: (col) => {
|
|
81
|
-
const selected_cells = context.data.map((_, row) => [row, col]);
|
|
82
|
-
context.df_actions.set_selected_cells(selected_cells);
|
|
83
|
-
context.df_actions.set_selected(selected_cells[0]);
|
|
84
|
-
context.df_actions.set_editing(false);
|
|
85
|
-
setTimeout(() => {
|
|
86
|
-
context.parent_element.focus();
|
|
87
|
-
}, 0);
|
|
88
|
-
},
|
|
89
|
-
handle_select_row: (row) => {
|
|
90
|
-
const selected_cells = context.data[0].map((_, col) => [row, col]);
|
|
91
|
-
context.df_actions.set_selected_cells(selected_cells);
|
|
92
|
-
context.df_actions.set_selected(selected_cells[0]);
|
|
93
|
-
context.df_actions.set_editing(false);
|
|
94
|
-
setTimeout(() => {
|
|
95
|
-
context.parent_element.focus();
|
|
96
|
-
}, 0);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
const selection_context = { ...context, actions };
|
|
100
|
-
setContext(instance_id, selection_context);
|
|
101
|
-
setContext(SELECTION_KEY, { instance_id, context: selection_context });
|
|
102
|
-
return selection_context;
|
|
103
|
-
}
|
|
104
|
-
export function get_selection_context() {
|
|
105
|
-
const ctx = getContext(SELECTION_KEY);
|
|
106
|
-
return ctx ? ctx.context : getContext(SELECTION_KEY);
|
|
107
|
-
}
|