@gradio/dataframe 0.17.4 → 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.
Files changed (38) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/Dataframe.stories.svelte +29 -0
  3. package/dist/shared/CellMenu.svelte.d.ts +1 -1
  4. package/dist/shared/EditableCell.svelte +8 -17
  5. package/dist/shared/EditableCell.svelte.d.ts +5 -3
  6. package/dist/shared/Table.svelte +111 -138
  7. package/dist/shared/TableCell.svelte +4 -6
  8. package/dist/shared/TableCell.svelte.d.ts +5 -1
  9. package/dist/shared/TableHeader.svelte +4 -3
  10. package/dist/shared/TableHeader.svelte.d.ts +1 -2
  11. package/dist/shared/context/dataframe_context.d.ts +147 -0
  12. package/dist/shared/context/dataframe_context.js +335 -0
  13. package/dist/shared/selection_utils.d.ts +1 -2
  14. package/dist/shared/selection_utils.js +0 -13
  15. package/dist/shared/utils/drag_utils.js +1 -0
  16. package/dist/shared/utils/keyboard_utils.d.ts +3 -2
  17. package/dist/shared/utils/keyboard_utils.js +107 -68
  18. package/package.json +7 -7
  19. package/shared/CellMenu.svelte +1 -1
  20. package/shared/EditableCell.svelte +9 -20
  21. package/shared/Table.svelte +147 -165
  22. package/shared/TableCell.svelte +9 -6
  23. package/shared/TableHeader.svelte +5 -8
  24. package/shared/context/dataframe_context.ts +576 -0
  25. package/shared/selection_utils.ts +1 -23
  26. package/shared/utils/drag_utils.ts +1 -0
  27. package/shared/utils/keyboard_utils.ts +142 -80
  28. package/{shared/utils → test}/sort_utils.test.ts +5 -1
  29. package/{shared/utils → test}/table_utils.test.ts +2 -2
  30. package/dist/shared/context/keyboard_context.d.ts +0 -37
  31. package/dist/shared/context/keyboard_context.js +0 -12
  32. package/dist/shared/context/selection_context.d.ts +0 -32
  33. package/dist/shared/context/selection_context.js +0 -107
  34. package/dist/shared/context/table_context.d.ts +0 -141
  35. package/dist/shared/context/table_context.js +0 -375
  36. package/shared/context/keyboard_context.ts +0 -65
  37. package/shared/context/selection_context.ts +0 -168
  38. 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
- if (ctx.selected_header === false || ctx.header_edit !== false)
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.df_actions.set_selected_header(false);
11
- ctx.df_actions.set_selected([0, ctx.selected_header]);
12
- ctx.df_actions.set_selected_cells([[0, ctx.selected_header]]);
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.df_actions.set_selected_header(ctx.selected_header > 0 ? ctx.selected_header - 1 : ctx.selected_header);
42
+ ctx.actions.set_selected_header(selected_header > 0 ? selected_header - 1 : selected_header);
16
43
  return true;
17
44
  case "ArrowRight":
18
- ctx.df_actions.set_selected_header(ctx.selected_header < ctx.headers.length - 1
19
- ? ctx.selected_header + 1
20
- : ctx.selected_header);
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.df_actions.set_selected_header(false);
51
+ ctx.actions.set_selected_header(false);
25
52
  return true;
26
53
  case "Enter":
27
54
  event.preventDefault();
28
- if (ctx.editable) {
29
- ctx.df_actions.set_header_edit(ctx.selected_header);
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.editable)
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
- if (ctx.editing) {
41
- const [row, col] = ctx.editing;
42
- const input_el = ctx.els[ctx.data[row][col].id].input;
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 (ctx.selected_cells.length > 0) {
56
- const new_data = handle_delete_key(ctx.data, ctx.selected_cells);
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
- if (ctx.editing)
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.df_actions.set_selected_cells(ctx.get_range_selection(ctx.selected_cells.length > 0 ? ctx.selected_cells[0] : [i, j], next_coords));
74
- ctx.df_actions.set_editing(false);
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.df_actions.set_selected_cells([next_coords]);
78
- ctx.df_actions.set_editing(false);
113
+ ctx.actions.set_selected_cells([next_coords]);
114
+ ctx.actions.set_editing(false);
79
115
  }
80
- ctx.df_actions.set_selected(next_coords);
116
+ ctx.actions.set_selected(next_coords);
81
117
  }
82
118
  else if (next_coords === false && event.key === "ArrowUp" && i === 0) {
83
- ctx.df_actions.set_selected_header(j);
84
- ctx.df_actions.set_selected(false);
85
- ctx.df_actions.set_selected_cells([]);
86
- ctx.df_actions.set_editing(false);
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
- event.preventDefault();
92
- if (!ctx.editable)
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
- if (event.shiftKey) {
95
- await ctx.add_row(i);
96
- await tick();
97
- ctx.df_actions.set_selected([i + 1, j]);
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
- if (dequal(ctx.editing, [i, j])) {
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.df_actions.set_editing(false);
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.df_actions.set_selected_cells([next_cell]);
126
- ctx.df_actions.set_selected(next_cell);
127
- if (ctx.editable) {
128
- ctx.df_actions.set_editing(next_cell);
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
- if (!ctx.editable)
163
+ const state = get(ctx.state);
164
+ if (!state.config.editable)
135
165
  return false;
136
- if ((!ctx.editing || (ctx.editing && dequal(ctx.editing, [i, j]))) &&
166
+ const editing = state.ui_state.editing;
167
+ if ((!editing || (editing && dequal(editing, [i, j]))) &&
137
168
  event.key.length === 1) {
138
- ctx.df_actions.set_editing([i, j]);
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.selected)
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 (ctx.selected_cells.length > 0) {
149
- await copy_table_data(ctx.data, ctx.selected_cells);
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] = ctx.selected;
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 (!ctx.editable)
198
+ if (!state.config.editable)
163
199
  return false;
164
200
  event.preventDefault();
165
- ctx.df_actions.set_editing(false);
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.4",
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.14.1",
21
- "@gradio/client": "^1.14.1",
22
- "@gradio/button": "^0.4.12",
23
- "@gradio/icons": "^0.10.0",
24
- "@gradio/statustracker": "^0.10.6",
20
+ "@gradio/atoms": "^0.15.0",
21
+ "@gradio/button": "^0.4.13",
22
+ "@gradio/icons": "^0.11.0",
25
23
  "@gradio/markdown-code": "^0.4.2",
26
- "@gradio/upload": "^0.15.7",
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": {
@@ -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/table_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] | null = null;
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: void;
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
- currentTarget
89
- }: Event & {
90
- currentTarget: HTMLInputElement;
91
- }): void {
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 (edit) {
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={_value}
111
+ bind:value
123
112
  class:header
124
113
  tabindex="-1"
125
114
  on:blur={handle_blur}