@gradio/dataframe 0.17.3 → 0.17.5
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 +23 -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 +7 -7
- 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,45 +1,77 @@
|
|
|
1
1
|
import { dequal } from "dequal/lite";
|
|
2
2
|
import { handle_delete_key } from "../selection_utils";
|
|
3
3
|
import { tick } from "svelte";
|
|
4
|
+
import { get } from "svelte/store";
|
|
4
5
|
import { copy_table_data } from "./table_utils";
|
|
6
|
+
async function save_cell_value(input_value, ctx, row, col) {
|
|
7
|
+
if (!ctx.data || !ctx.data[row] || !ctx.data[row][col])
|
|
8
|
+
return;
|
|
9
|
+
const old_value = ctx.data[row][col].value;
|
|
10
|
+
ctx.data[row][col].value = input_value;
|
|
11
|
+
if (old_value !== input_value && ctx.dispatch) {
|
|
12
|
+
ctx.dispatch("change", {
|
|
13
|
+
data: ctx.data.map((row) => row.map((cell) => cell.value)),
|
|
14
|
+
headers: ctx.headers?.map((h) => h.value) || [],
|
|
15
|
+
metadata: null
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
ctx.actions.set_selected([row, col]);
|
|
19
|
+
}
|
|
20
|
+
export async function handle_cell_blur(event, ctx, coords) {
|
|
21
|
+
if (!ctx.data || !ctx.headers || !ctx.els)
|
|
22
|
+
return;
|
|
23
|
+
const input_el = event.target;
|
|
24
|
+
if (!input_el || input_el.value === undefined)
|
|
25
|
+
return;
|
|
26
|
+
await save_cell_value(input_el.value, ctx, coords[0], coords[1]);
|
|
27
|
+
}
|
|
5
28
|
function handle_header_navigation(event, ctx) {
|
|
6
|
-
|
|
29
|
+
const state = get(ctx.state);
|
|
30
|
+
const selected_header = state.ui_state.selected_header;
|
|
31
|
+
const header_edit = state.ui_state.header_edit;
|
|
32
|
+
const headers = ctx.headers || [];
|
|
33
|
+
if (selected_header === false || header_edit !== false)
|
|
7
34
|
return false;
|
|
8
35
|
switch (event.key) {
|
|
9
36
|
case "ArrowDown":
|
|
10
|
-
ctx.
|
|
11
|
-
ctx.
|
|
12
|
-
ctx.
|
|
37
|
+
ctx.actions.set_selected_header(false);
|
|
38
|
+
ctx.actions.set_selected([0, selected_header]);
|
|
39
|
+
ctx.actions.set_selected_cells([[0, selected_header]]);
|
|
13
40
|
return true;
|
|
14
41
|
case "ArrowLeft":
|
|
15
|
-
ctx.
|
|
42
|
+
ctx.actions.set_selected_header(selected_header > 0 ? selected_header - 1 : selected_header);
|
|
16
43
|
return true;
|
|
17
44
|
case "ArrowRight":
|
|
18
|
-
ctx.
|
|
19
|
-
?
|
|
20
|
-
:
|
|
45
|
+
ctx.actions.set_selected_header(selected_header < headers.length - 1
|
|
46
|
+
? selected_header + 1
|
|
47
|
+
: selected_header);
|
|
21
48
|
return true;
|
|
22
49
|
case "Escape":
|
|
23
50
|
event.preventDefault();
|
|
24
|
-
ctx.
|
|
51
|
+
ctx.actions.set_selected_header(false);
|
|
25
52
|
return true;
|
|
26
53
|
case "Enter":
|
|
27
54
|
event.preventDefault();
|
|
28
|
-
if (
|
|
29
|
-
ctx.
|
|
55
|
+
if (state.config.editable) {
|
|
56
|
+
ctx.actions.set_header_edit(selected_header);
|
|
30
57
|
}
|
|
31
58
|
return true;
|
|
32
59
|
}
|
|
33
60
|
return false;
|
|
34
61
|
}
|
|
35
62
|
function handle_delete_operation(event, ctx) {
|
|
36
|
-
if (!ctx.
|
|
63
|
+
if (!ctx.data || !ctx.headers || !ctx.els || !ctx.dispatch)
|
|
64
|
+
return false;
|
|
65
|
+
const state = get(ctx.state);
|
|
66
|
+
if (!state.config.editable)
|
|
37
67
|
return false;
|
|
38
68
|
if (event.key !== "Delete" && event.key !== "Backspace")
|
|
39
69
|
return false;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
70
|
+
const editing = state.ui_state.editing;
|
|
71
|
+
const selected_cells = state.ui_state.selected_cells;
|
|
72
|
+
if (editing) {
|
|
73
|
+
const [row, col] = editing;
|
|
74
|
+
const input_el = ctx.els[ctx.data[row][col].id]?.input;
|
|
43
75
|
if (input_el && input_el.selectionStart !== input_el.selectionEnd) {
|
|
44
76
|
return false;
|
|
45
77
|
}
|
|
@@ -52,106 +84,110 @@ function handle_delete_operation(event, ctx) {
|
|
|
52
84
|
}
|
|
53
85
|
}
|
|
54
86
|
event.preventDefault();
|
|
55
|
-
if (
|
|
56
|
-
const new_data = handle_delete_key(ctx.data,
|
|
87
|
+
if (selected_cells.length > 0) {
|
|
88
|
+
const new_data = handle_delete_key(ctx.data, selected_cells);
|
|
57
89
|
ctx.dispatch("change", {
|
|
58
90
|
data: new_data.map((row) => row.map((cell) => cell.value)),
|
|
59
91
|
headers: ctx.headers.map((h) => h.value),
|
|
60
92
|
metadata: null
|
|
61
93
|
});
|
|
62
|
-
ctx.dispatch("input");
|
|
63
94
|
}
|
|
64
95
|
return true;
|
|
65
96
|
}
|
|
66
97
|
function handle_arrow_keys(event, ctx, i, j) {
|
|
67
|
-
|
|
98
|
+
const state = get(ctx.state);
|
|
99
|
+
const editing = state.ui_state.editing;
|
|
100
|
+
const selected_cells = state.ui_state.selected_cells;
|
|
101
|
+
if (editing)
|
|
102
|
+
return false;
|
|
103
|
+
if (!ctx.data)
|
|
68
104
|
return false;
|
|
69
105
|
event.preventDefault();
|
|
70
|
-
const next_coords = ctx.move_cursor(event, [i, j], ctx.data);
|
|
106
|
+
const next_coords = ctx.actions.move_cursor(event, [i, j], ctx.data);
|
|
71
107
|
if (next_coords) {
|
|
72
108
|
if (event.shiftKey) {
|
|
73
|
-
ctx.
|
|
74
|
-
ctx.
|
|
109
|
+
ctx.actions.set_selected_cells(ctx.actions.get_range_selection(selected_cells.length > 0 ? selected_cells[0] : [i, j], next_coords));
|
|
110
|
+
ctx.actions.set_editing(false);
|
|
75
111
|
}
|
|
76
112
|
else {
|
|
77
|
-
ctx.
|
|
78
|
-
ctx.
|
|
113
|
+
ctx.actions.set_selected_cells([next_coords]);
|
|
114
|
+
ctx.actions.set_editing(false);
|
|
79
115
|
}
|
|
80
|
-
ctx.
|
|
116
|
+
ctx.actions.set_selected(next_coords);
|
|
81
117
|
}
|
|
82
118
|
else if (next_coords === false && event.key === "ArrowUp" && i === 0) {
|
|
83
|
-
ctx.
|
|
84
|
-
ctx.
|
|
85
|
-
ctx.
|
|
86
|
-
ctx.
|
|
119
|
+
ctx.actions.set_selected_header(j);
|
|
120
|
+
ctx.actions.set_selected(false);
|
|
121
|
+
ctx.actions.set_selected_cells([]);
|
|
122
|
+
ctx.actions.set_editing(false);
|
|
87
123
|
}
|
|
88
124
|
return true;
|
|
89
125
|
}
|
|
90
126
|
async function handle_enter_key(event, ctx, i, j) {
|
|
91
|
-
|
|
92
|
-
|
|
127
|
+
if (!ctx.data || !ctx.els)
|
|
128
|
+
return false;
|
|
129
|
+
const state = get(ctx.state);
|
|
130
|
+
if (!state.config.editable)
|
|
93
131
|
return false;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
ctx.
|
|
132
|
+
event.preventDefault();
|
|
133
|
+
const editing = state.ui_state.editing;
|
|
134
|
+
if (editing && dequal(editing, [i, j])) {
|
|
135
|
+
const cell_id = ctx.data[i][j].id;
|
|
136
|
+
const input_el = ctx.els[cell_id]?.input;
|
|
137
|
+
if (input_el) {
|
|
138
|
+
await save_cell_value(input_el.value, ctx, i, j);
|
|
139
|
+
}
|
|
140
|
+
ctx.actions.set_editing(false);
|
|
98
141
|
}
|
|
99
142
|
else {
|
|
100
|
-
|
|
101
|
-
const cell_id = ctx.data[i][j].id;
|
|
102
|
-
const input_el = ctx.els[cell_id].input;
|
|
103
|
-
if (input_el) {
|
|
104
|
-
const old_value = ctx.data[i][j].value;
|
|
105
|
-
ctx.data[i][j].value = input_el.value;
|
|
106
|
-
if (old_value !== input_el.value) {
|
|
107
|
-
ctx.dispatch("input");
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
ctx.df_actions.set_editing(false);
|
|
111
|
-
await tick();
|
|
112
|
-
ctx.df_actions.set_selected([i, j]);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
ctx.df_actions.set_editing([i, j]);
|
|
116
|
-
}
|
|
143
|
+
ctx.actions.set_editing([i, j]);
|
|
117
144
|
}
|
|
118
145
|
return true;
|
|
119
146
|
}
|
|
120
147
|
function handle_tab_key(event, ctx, i, j) {
|
|
148
|
+
if (!ctx.data)
|
|
149
|
+
return false;
|
|
121
150
|
event.preventDefault();
|
|
122
|
-
ctx.
|
|
123
|
-
const next_cell = ctx.get_next_cell_coordinates([i, j], ctx.data, event.shiftKey);
|
|
151
|
+
ctx.actions.set_editing(false);
|
|
152
|
+
const next_cell = ctx.actions.get_next_cell_coordinates([i, j], ctx.data, event.shiftKey);
|
|
124
153
|
if (next_cell) {
|
|
125
|
-
ctx.
|
|
126
|
-
ctx.
|
|
127
|
-
if (ctx.editable) {
|
|
128
|
-
ctx.
|
|
154
|
+
ctx.actions.set_selected_cells([next_cell]);
|
|
155
|
+
ctx.actions.set_selected(next_cell);
|
|
156
|
+
if (get(ctx.state).config.editable) {
|
|
157
|
+
ctx.actions.set_editing(next_cell);
|
|
129
158
|
}
|
|
130
159
|
}
|
|
131
160
|
return true;
|
|
132
161
|
}
|
|
133
162
|
function handle_default_key(event, ctx, i, j) {
|
|
134
|
-
|
|
163
|
+
const state = get(ctx.state);
|
|
164
|
+
if (!state.config.editable)
|
|
135
165
|
return false;
|
|
136
|
-
|
|
166
|
+
const editing = state.ui_state.editing;
|
|
167
|
+
if ((!editing || (editing && dequal(editing, [i, j]))) &&
|
|
137
168
|
event.key.length === 1) {
|
|
138
|
-
ctx.
|
|
169
|
+
ctx.actions.set_editing([i, j]);
|
|
139
170
|
return true;
|
|
140
171
|
}
|
|
141
172
|
return false;
|
|
142
173
|
}
|
|
143
174
|
async function handle_cell_navigation(event, ctx) {
|
|
144
|
-
if (!ctx.
|
|
175
|
+
if (!ctx.data)
|
|
176
|
+
return false;
|
|
177
|
+
const state = get(ctx.state);
|
|
178
|
+
const selected = state.ui_state.selected;
|
|
179
|
+
const selected_cells = state.ui_state.selected_cells;
|
|
180
|
+
if (!selected)
|
|
145
181
|
return false;
|
|
146
182
|
if (event.key === "c" && (event.metaKey || event.ctrlKey)) {
|
|
147
183
|
event.preventDefault();
|
|
148
|
-
if (
|
|
149
|
-
await copy_table_data(ctx.data,
|
|
184
|
+
if (selected_cells.length > 0) {
|
|
185
|
+
await copy_table_data(ctx.data, selected_cells);
|
|
150
186
|
}
|
|
151
|
-
ctx.set_copy_flash(true);
|
|
187
|
+
ctx.actions.set_copy_flash(true);
|
|
152
188
|
return true;
|
|
153
189
|
}
|
|
154
|
-
const [i, j] =
|
|
190
|
+
const [i, j] = selected;
|
|
155
191
|
switch (event.key) {
|
|
156
192
|
case "ArrowRight":
|
|
157
193
|
case "ArrowLeft":
|
|
@@ -159,10 +195,10 @@ async function handle_cell_navigation(event, ctx) {
|
|
|
159
195
|
case "ArrowUp":
|
|
160
196
|
return handle_arrow_keys(event, ctx, i, j);
|
|
161
197
|
case "Escape":
|
|
162
|
-
if (!
|
|
198
|
+
if (!state.config.editable)
|
|
163
199
|
return false;
|
|
164
200
|
event.preventDefault();
|
|
165
|
-
ctx.
|
|
201
|
+
ctx.actions.set_editing(false);
|
|
166
202
|
tick().then(() => {
|
|
167
203
|
if (ctx.parent_element) {
|
|
168
204
|
ctx.parent_element.focus();
|
|
@@ -173,6 +209,9 @@ async function handle_cell_navigation(event, ctx) {
|
|
|
173
209
|
return await handle_enter_key(event, ctx, i, j);
|
|
174
210
|
case "Tab":
|
|
175
211
|
return handle_tab_key(event, ctx, i, j);
|
|
212
|
+
case "Delete":
|
|
213
|
+
case "Backspace":
|
|
214
|
+
return handle_delete_operation(event, ctx);
|
|
176
215
|
default:
|
|
177
216
|
return handle_default_key(event, ctx, i, j);
|
|
178
217
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/dataframe",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.5",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
"dompurify": "^3.0.3",
|
|
18
18
|
"katex": "^0.16.7",
|
|
19
19
|
"marked": "^12.0.0",
|
|
20
|
-
"@gradio/atoms": "^0.
|
|
21
|
-
"@gradio/
|
|
22
|
-
"@gradio/
|
|
20
|
+
"@gradio/atoms": "^0.15.0",
|
|
21
|
+
"@gradio/button": "^0.4.13",
|
|
22
|
+
"@gradio/icons": "^0.11.0",
|
|
23
23
|
"@gradio/markdown-code": "^0.4.2",
|
|
24
|
-
"@gradio/
|
|
25
|
-
"@gradio/
|
|
26
|
-
"@gradio/upload": "^0.
|
|
24
|
+
"@gradio/client": "^1.14.1",
|
|
25
|
+
"@gradio/statustracker": "^0.10.7",
|
|
26
|
+
"@gradio/upload": "^0.16.0",
|
|
27
27
|
"@gradio/utils": "^0.10.1"
|
|
28
28
|
},
|
|
29
29
|
"exports": {
|
package/shared/CellMenu.svelte
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { onMount } from "svelte";
|
|
3
3
|
import CellMenuIcons from "./CellMenuIcons.svelte";
|
|
4
4
|
import type { I18nFormatter } from "js/utils/src";
|
|
5
|
-
import type { SortDirection } from "./context/
|
|
5
|
+
import type { SortDirection } from "./context/dataframe_context";
|
|
6
6
|
|
|
7
7
|
export let x: number;
|
|
8
8
|
export let y: number;
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
right: string;
|
|
22
22
|
display: boolean;
|
|
23
23
|
}[];
|
|
24
|
-
export let clear_on_focus = false;
|
|
25
24
|
export let line_breaks = true;
|
|
26
25
|
export let editable = true;
|
|
27
26
|
export let is_static = false;
|
|
@@ -33,19 +32,18 @@
|
|
|
33
32
|
export let wrap_text = false;
|
|
34
33
|
|
|
35
34
|
export let show_selection_buttons = false;
|
|
36
|
-
export let coords: [number, number]
|
|
35
|
+
export let coords: [number, number];
|
|
37
36
|
export let on_select_column: ((col: number) => void) | null = null;
|
|
38
37
|
export let on_select_row: ((row: number) => void) | null = null;
|
|
39
38
|
|
|
40
39
|
const dispatch = createEventDispatcher<{
|
|
41
|
-
blur:
|
|
40
|
+
blur: { blur_event: FocusEvent; coords: [number, number] };
|
|
42
41
|
keydown: KeyboardEvent;
|
|
43
42
|
}>();
|
|
44
43
|
|
|
45
44
|
let is_expanded = false;
|
|
46
45
|
|
|
47
46
|
export let el: HTMLInputElement | null;
|
|
48
|
-
$: _value = value;
|
|
49
47
|
|
|
50
48
|
function truncate_text(
|
|
51
49
|
text: string | number,
|
|
@@ -73,10 +71,6 @@
|
|
|
73
71
|
: display_content;
|
|
74
72
|
|
|
75
73
|
function use_focus(node: HTMLInputElement): any {
|
|
76
|
-
if (clear_on_focus) {
|
|
77
|
-
_value = "";
|
|
78
|
-
}
|
|
79
|
-
|
|
80
74
|
requestAnimationFrame(() => {
|
|
81
75
|
node.focus();
|
|
82
76
|
});
|
|
@@ -84,21 +78,16 @@
|
|
|
84
78
|
return {};
|
|
85
79
|
}
|
|
86
80
|
|
|
87
|
-
function handle_blur({
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
value = currentTarget.value;
|
|
93
|
-
dispatch("blur");
|
|
81
|
+
function handle_blur(event: FocusEvent): void {
|
|
82
|
+
dispatch("blur", {
|
|
83
|
+
blur_event: event,
|
|
84
|
+
coords: coords
|
|
85
|
+
});
|
|
94
86
|
}
|
|
95
87
|
|
|
96
88
|
function handle_keydown(event: KeyboardEvent): void {
|
|
97
89
|
if (event.key === "Enter") {
|
|
98
|
-
if (
|
|
99
|
-
value = _value;
|
|
100
|
-
dispatch("blur");
|
|
101
|
-
} else if (!header) {
|
|
90
|
+
if (!header) {
|
|
102
91
|
is_expanded = !is_expanded;
|
|
103
92
|
}
|
|
104
93
|
}
|
|
@@ -119,7 +108,7 @@
|
|
|
119
108
|
role="textbox"
|
|
120
109
|
aria-label={is_static ? "Cell is read-only" : "Edit cell"}
|
|
121
110
|
bind:this={el}
|
|
122
|
-
bind:value
|
|
111
|
+
bind:value
|
|
123
112
|
class:header
|
|
124
113
|
tabindex="-1"
|
|
125
114
|
on:blur={handle_blur}
|