@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.
Files changed (38) hide show
  1. package/CHANGELOG.md +25 -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 +6 -6
  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,5 +1,6 @@
1
1
  <script>import EditableCell from "./EditableCell.svelte";
2
2
  import CellMenuButton from "./CellMenuButton.svelte";
3
+ import { get_sort_status } from "./utils/sort_utils";
3
4
  import Padlock from "./icons/Padlock.svelte";
4
5
  import SortArrowUp from "./icons/SortArrowUp.svelte";
5
6
  import SortArrowDown from "./icons/SortArrowDown.svelte";
@@ -8,7 +9,6 @@ export let i;
8
9
  export let actual_pinned_columns;
9
10
  export let header_edit;
10
11
  export let selected_header;
11
- export let get_sort_status;
12
12
  export let headers;
13
13
  export let get_cell_width;
14
14
  export let handle_header_click;
@@ -51,9 +51,9 @@ function get_header_position(col_index) {
51
51
  class:last-pinned={i === actual_pinned_columns - 1}
52
52
  class:focus={header_edit === i || selected_header === i}
53
53
  class:sorted={sort_index !== -1}
54
- aria-sort={get_sort_status(value, headers) === "none"
54
+ aria-sort={get_sort_status(value, sort_columns, headers) === "none"
55
55
  ? "none"
56
- : get_sort_status(value, headers) === "asc"
56
+ : get_sort_status(value, sort_columns, headers) === "asc"
57
57
  ? "ascending"
58
58
  : "descending"}
59
59
  style="width: {get_cell_width(i)}; left: {get_header_position(i)};"
@@ -96,6 +96,7 @@ function get_header_position(col_index) {
96
96
  {editable}
97
97
  {is_static}
98
98
  {i18n}
99
+ coords={[i, 0]}
99
100
  />
100
101
  {#if sort_index !== -1}
101
102
  <div class="sort-indicators">
@@ -1,6 +1,6 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import type { I18nFormatter } from "js/core/src/gradio_helper";
3
- import type { SortDirection } from "./context/table_context";
3
+ import type { SortDirection } from "./context/dataframe_context";
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  value: string;
@@ -8,7 +8,6 @@ declare const __propDef: {
8
8
  actual_pinned_columns: number;
9
9
  header_edit: number | false;
10
10
  selected_header: number | false;
11
- get_sort_status: (value: string, headers: string[]) => "none" | "asc" | "desc";
12
11
  headers: string[];
13
12
  get_cell_width: (index: number) => string;
14
13
  handle_header_click: (event: MouseEvent, col: number) => void;
@@ -0,0 +1,147 @@
1
+ import { writable } from "svelte/store";
2
+ import { get_next_cell_coordinates, get_range_selection, move_cursor } from "../selection_utils";
3
+ export declare const DATAFRAME_KEY: unique symbol;
4
+ export type SortDirection = "asc" | "desc";
5
+ export type CellCoordinate = [number, number];
6
+ interface DataFrameState {
7
+ config: {
8
+ show_fullscreen_button: boolean;
9
+ show_copy_button: boolean;
10
+ show_search: "none" | "search" | "filter";
11
+ show_row_numbers: boolean;
12
+ editable: boolean;
13
+ pinned_columns: number;
14
+ show_label: boolean;
15
+ line_breaks: boolean;
16
+ wrap: boolean;
17
+ max_height: number;
18
+ column_widths: string[];
19
+ max_chars?: number;
20
+ };
21
+ current_search_query: string | null;
22
+ sort_state: {
23
+ sort_columns: {
24
+ col: number;
25
+ direction: SortDirection;
26
+ }[];
27
+ row_order: number[];
28
+ };
29
+ ui_state: {
30
+ active_cell_menu: {
31
+ row: number;
32
+ col: number;
33
+ x: number;
34
+ y: number;
35
+ } | null;
36
+ active_header_menu: {
37
+ col: number;
38
+ x: number;
39
+ y: number;
40
+ } | null;
41
+ selected_cells: CellCoordinate[];
42
+ selected: CellCoordinate | false;
43
+ editing: CellCoordinate | false;
44
+ header_edit: number | false;
45
+ selected_header: number | false;
46
+ active_button: {
47
+ type: "header" | "cell";
48
+ row?: number;
49
+ col: number;
50
+ } | null;
51
+ copy_flash: boolean;
52
+ };
53
+ }
54
+ interface DataFrameActions {
55
+ handle_search: (query: string | null) => void;
56
+ handle_sort: (col: number, direction: SortDirection) => void;
57
+ get_sort_status: (name: string, headers: string[]) => "none" | "asc" | "desc";
58
+ sort_data: (data: any[][], display_value: string[][] | null, styling: string[][] | null) => void;
59
+ update_row_order: (data: any[][]) => void;
60
+ filter_data: (data: any[][]) => any[][];
61
+ add_row: (data: any[][], make_id: () => string, index?: number) => any[][];
62
+ add_col: (data: any[][], headers: string[], make_id: () => string, index?: number) => {
63
+ data: any[][];
64
+ headers: string[];
65
+ };
66
+ add_row_at: (data: any[][], index: number, position: "above" | "below", make_id: () => string) => any[][];
67
+ add_col_at: (data: any[][], headers: string[], index: number, position: "left" | "right", make_id: () => string) => {
68
+ data: any[][];
69
+ headers: string[];
70
+ };
71
+ delete_row: (data: any[][], index: number) => any[][];
72
+ delete_col: (data: any[][], headers: string[], index: number) => {
73
+ data: any[][];
74
+ headers: string[];
75
+ };
76
+ delete_row_at: (data: any[][], index: number) => any[][];
77
+ delete_col_at: (data: any[][], headers: string[], index: number) => {
78
+ data: any[][];
79
+ headers: string[];
80
+ };
81
+ trigger_change: (data: any[][], headers: any[], previous_data: string[][], previous_headers: string[], value_is_output: boolean, dispatch: (e: "change" | "input", detail?: any) => void) => Promise<void>;
82
+ reset_sort_state: () => void;
83
+ set_active_cell_menu: (menu: {
84
+ row: number;
85
+ col: number;
86
+ x: number;
87
+ y: number;
88
+ } | null) => void;
89
+ set_active_header_menu: (menu: {
90
+ col: number;
91
+ x: number;
92
+ y: number;
93
+ } | null) => void;
94
+ set_selected_cells: (cells: CellCoordinate[]) => void;
95
+ set_selected: (selected: CellCoordinate | false) => void;
96
+ set_editing: (editing: CellCoordinate | false) => void;
97
+ clear_ui_state: () => void;
98
+ set_header_edit: (header_index: number | false) => void;
99
+ set_selected_header: (header_index: number | false) => void;
100
+ handle_header_click: (col: number, editable: boolean) => void;
101
+ end_header_edit: (key: string) => void;
102
+ get_selected_cells: () => CellCoordinate[];
103
+ get_active_cell_menu: () => {
104
+ row: number;
105
+ col: number;
106
+ x: number;
107
+ y: number;
108
+ } | null;
109
+ get_active_button: () => {
110
+ type: "header" | "cell";
111
+ row?: number;
112
+ col: number;
113
+ } | null;
114
+ set_active_button: (button: {
115
+ type: "header" | "cell";
116
+ row?: number;
117
+ col: number;
118
+ } | null) => void;
119
+ set_copy_flash: (value: boolean) => void;
120
+ handle_cell_click: (event: MouseEvent, row: number, col: number) => void;
121
+ toggle_cell_menu: (event: MouseEvent, row: number, col: number) => void;
122
+ toggle_cell_button: (row: number, col: number) => void;
123
+ handle_select_column: (col: number) => void;
124
+ handle_select_row: (row: number) => void;
125
+ get_next_cell_coordinates: typeof get_next_cell_coordinates;
126
+ get_range_selection: typeof get_range_selection;
127
+ move_cursor: typeof move_cursor;
128
+ }
129
+ export interface DataFrameContext {
130
+ state: ReturnType<typeof writable<DataFrameState>>;
131
+ actions: DataFrameActions;
132
+ data?: any[][];
133
+ headers?: {
134
+ id: string;
135
+ value: string;
136
+ }[];
137
+ els?: Record<string, {
138
+ cell: HTMLTableCellElement | null;
139
+ input: HTMLInputElement | null;
140
+ }>;
141
+ parent_element?: HTMLElement;
142
+ get_data_at?: (row: number, col: number) => string | number;
143
+ dispatch?: (e: "change" | "select" | "search", detail?: any) => void;
144
+ }
145
+ export declare function create_dataframe_context(config: DataFrameState["config"]): DataFrameContext;
146
+ export declare function get_dataframe_context(): DataFrameContext;
147
+ export {};
@@ -0,0 +1,335 @@
1
+ import { getContext, setContext } from "svelte";
2
+ import { dequal } from "dequal";
3
+ import { writable, get } from "svelte/store";
4
+ import { sort_table_data } from "../utils/table_utils";
5
+ import { tick } from "svelte";
6
+ import { handle_selection, get_next_cell_coordinates, get_range_selection, move_cursor } from "../selection_utils";
7
+ export const DATAFRAME_KEY = Symbol("dataframe");
8
+ function create_actions(state, context) {
9
+ const update_state = (updater) => state.update((s) => ({ ...s, ...updater(s) }));
10
+ const add_row = (data, make_id, index) => {
11
+ const new_row = data[0]?.length
12
+ ? Array(data[0].length)
13
+ .fill(null)
14
+ .map(() => ({ value: "", id: make_id() }))
15
+ : [{ value: "", id: make_id() }];
16
+ const new_data = [...data];
17
+ index !== undefined
18
+ ? new_data.splice(index, 0, new_row)
19
+ : new_data.push(new_row);
20
+ return new_data;
21
+ };
22
+ const add_col = (data, headers, make_id, index) => {
23
+ const new_headers = context.headers
24
+ ? [...headers.map((h) => context.headers[headers.indexOf(h)].value)]
25
+ : [...headers, `Header ${headers.length + 1}`];
26
+ const new_data = data.map((row) => [...row, { value: "", id: make_id() }]);
27
+ if (index !== undefined) {
28
+ new_headers.splice(index, 0, new_headers.pop());
29
+ new_data.forEach((row) => row.splice(index, 0, row.pop()));
30
+ }
31
+ return { data: new_data, headers: new_headers };
32
+ };
33
+ return {
34
+ handle_search: (query) => update_state((s) => ({ current_search_query: query })),
35
+ handle_sort: (col, direction) => update_state((s) => {
36
+ const sort_cols = s.sort_state.sort_columns.filter((c) => c.col !== col);
37
+ if (!s.sort_state.sort_columns.some((c) => c.col === col && c.direction === direction)) {
38
+ sort_cols.push({ col, direction });
39
+ }
40
+ return {
41
+ sort_state: { ...s.sort_state, sort_columns: sort_cols.slice(-3) }
42
+ };
43
+ }),
44
+ get_sort_status: (name, headers) => {
45
+ const s = get(state);
46
+ const sort_item = s.sort_state.sort_columns.find((item) => headers[item.col] === name);
47
+ return sort_item ? sort_item.direction : "none";
48
+ },
49
+ sort_data: (data, display_value, styling) => {
50
+ const { sort_state: { sort_columns } } = get(state);
51
+ if (sort_columns.length)
52
+ sort_table_data(data, display_value, styling, sort_columns);
53
+ },
54
+ update_row_order: (data) => update_state((s) => ({
55
+ sort_state: {
56
+ ...s.sort_state,
57
+ row_order: s.sort_state.sort_columns.length && data[0]
58
+ ? [...Array(data.length)]
59
+ .map((_, i) => i)
60
+ .sort((a, b) => {
61
+ for (const { col, direction } of s.sort_state
62
+ .sort_columns) {
63
+ const comp = (data[a]?.[col]?.value ?? "") <
64
+ (data[b]?.[col]?.value ?? "")
65
+ ? -1
66
+ : 1;
67
+ if (comp)
68
+ return direction === "asc" ? comp : -comp;
69
+ }
70
+ return 0;
71
+ })
72
+ : [...Array(data.length)].map((_, i) => i)
73
+ }
74
+ })),
75
+ filter_data: (data) => {
76
+ const query = get(state).current_search_query?.toLowerCase();
77
+ return query
78
+ ? data.filter((row) => row.some((cell) => String(cell?.value).toLowerCase().includes(query)))
79
+ : data;
80
+ },
81
+ add_row,
82
+ add_col,
83
+ add_row_at: (data, index, position, make_id) => add_row(data, make_id, position === "above" ? index : index + 1),
84
+ add_col_at: (data, headers, index, position, make_id) => add_col(data, headers, make_id, position === "left" ? index : index + 1),
85
+ delete_row: (data, index) => data.length > 1 ? data.filter((_, i) => i !== index) : data,
86
+ delete_col: (data, headers, index) => headers.length > 1
87
+ ? {
88
+ data: data.map((row) => row.filter((_, i) => i !== index)),
89
+ headers: headers.filter((_, i) => i !== index)
90
+ }
91
+ : { data, headers },
92
+ delete_row_at: (data, index) => data.length > 1
93
+ ? [...data.slice(0, index), ...data.slice(index + 1)]
94
+ : data,
95
+ delete_col_at: (data, headers, index) => headers.length > 1
96
+ ? {
97
+ data: data.map((row) => [
98
+ ...row.slice(0, index),
99
+ ...row.slice(index + 1)
100
+ ]),
101
+ headers: [...headers.slice(0, index), ...headers.slice(index + 1)]
102
+ }
103
+ : { data, headers },
104
+ trigger_change: async (data, headers, previous_data, previous_headers, value_is_output, dispatch) => {
105
+ const s = get(state);
106
+ if (s.current_search_query)
107
+ return;
108
+ const current_headers = headers.map((h) => h.value);
109
+ const current_data = data.map((row) => row.map((cell) => String(cell.value)));
110
+ if (!dequal(current_data, previous_data) ||
111
+ !dequal(current_headers, previous_headers)) {
112
+ if (!dequal(current_headers, previous_headers)) {
113
+ update_state((s) => ({
114
+ sort_state: { sort_columns: [], row_order: [] }
115
+ }));
116
+ }
117
+ dispatch("change", {
118
+ data: data.map((row) => row.map((cell) => cell.value)),
119
+ headers: current_headers,
120
+ metadata: null
121
+ });
122
+ if (!value_is_output)
123
+ dispatch("input");
124
+ }
125
+ },
126
+ reset_sort_state: () => update_state((s) => ({
127
+ sort_state: { sort_columns: [], row_order: [] }
128
+ })),
129
+ set_active_cell_menu: (menu) => update_state((s) => ({
130
+ ui_state: { ...s.ui_state, active_cell_menu: menu }
131
+ })),
132
+ set_active_header_menu: (menu) => update_state((s) => ({
133
+ ui_state: { ...s.ui_state, active_header_menu: menu }
134
+ })),
135
+ set_selected_cells: (cells) => update_state((s) => ({
136
+ ui_state: { ...s.ui_state, selected_cells: cells }
137
+ })),
138
+ set_selected: (selected) => update_state((s) => ({ ui_state: { ...s.ui_state, selected } })),
139
+ set_editing: (editing) => update_state((s) => ({ ui_state: { ...s.ui_state, editing } })),
140
+ clear_ui_state: () => update_state((s) => ({
141
+ ui_state: {
142
+ active_cell_menu: null,
143
+ active_header_menu: null,
144
+ selected_cells: [],
145
+ selected: false,
146
+ editing: false,
147
+ header_edit: false,
148
+ selected_header: false,
149
+ active_button: null,
150
+ copy_flash: false
151
+ }
152
+ })),
153
+ set_header_edit: (header_index) => update_state((s) => ({
154
+ ui_state: {
155
+ ...s.ui_state,
156
+ selected_cells: [],
157
+ selected_header: header_index,
158
+ header_edit: header_index
159
+ }
160
+ })),
161
+ set_selected_header: (header_index) => update_state((s) => ({
162
+ ui_state: {
163
+ ...s.ui_state,
164
+ selected_header: header_index,
165
+ selected: false,
166
+ selected_cells: []
167
+ }
168
+ })),
169
+ handle_header_click: (col, editable) => update_state((s) => ({
170
+ ui_state: {
171
+ ...s.ui_state,
172
+ active_cell_menu: null,
173
+ active_header_menu: null,
174
+ selected: false,
175
+ selected_cells: [],
176
+ selected_header: col,
177
+ header_edit: editable ? col : false
178
+ }
179
+ })),
180
+ end_header_edit: (key) => {
181
+ if (["Escape", "Enter", "Tab"].includes(key)) {
182
+ update_state((s) => ({
183
+ ui_state: { ...s.ui_state, selected: false, header_edit: false }
184
+ }));
185
+ }
186
+ },
187
+ get_selected_cells: () => get(state).ui_state.selected_cells,
188
+ get_active_cell_menu: () => get(state).ui_state.active_cell_menu,
189
+ get_active_button: () => get(state).ui_state.active_button,
190
+ set_active_button: (button) => update_state((s) => ({
191
+ ui_state: { ...s.ui_state, active_button: button }
192
+ })),
193
+ set_copy_flash: (value) => update_state((s) => ({ ui_state: { ...s.ui_state, copy_flash: value } })),
194
+ handle_cell_click: (event, row, col) => {
195
+ event.preventDefault();
196
+ event.stopPropagation();
197
+ const s = get(state);
198
+ if (s.config.show_row_numbers && col === -1)
199
+ return;
200
+ let actual_row = row;
201
+ if (s.current_search_query && context.data) {
202
+ const filtered_indices = [];
203
+ context.data.forEach((dataRow, idx) => {
204
+ if (dataRow.some((cell) => String(cell?.value)
205
+ .toLowerCase()
206
+ .includes(s.current_search_query?.toLowerCase() || ""))) {
207
+ filtered_indices.push(idx);
208
+ }
209
+ });
210
+ actual_row = filtered_indices[row] ?? row;
211
+ }
212
+ const cells = handle_selection([actual_row, col], s.ui_state.selected_cells, event);
213
+ update_state((s) => ({
214
+ ui_state: {
215
+ ...s.ui_state,
216
+ active_cell_menu: null,
217
+ active_header_menu: null,
218
+ selected_header: false,
219
+ header_edit: false,
220
+ selected_cells: cells,
221
+ selected: cells[0]
222
+ }
223
+ }));
224
+ if (s.config.editable && cells.length === 1) {
225
+ update_state((s) => ({
226
+ ui_state: { ...s.ui_state, editing: [actual_row, col] }
227
+ }));
228
+ tick().then(() => context.els[context.data[actual_row][col].id]?.input?.focus());
229
+ }
230
+ else {
231
+ // ensure parent has focus for keyboard navigation
232
+ tick().then(() => {
233
+ if (context.parent_element) {
234
+ context.parent_element.focus();
235
+ }
236
+ });
237
+ }
238
+ context.dispatch?.("select", {
239
+ index: [actual_row, col],
240
+ value: context.get_data_at(actual_row, col)
241
+ });
242
+ },
243
+ toggle_cell_menu: (event, row, col) => {
244
+ event.stopPropagation();
245
+ const current_menu = get(state).ui_state.active_cell_menu;
246
+ if (current_menu?.row === row && current_menu.col === col) {
247
+ update_state((s) => ({
248
+ ui_state: { ...s.ui_state, active_cell_menu: null }
249
+ }));
250
+ }
251
+ else {
252
+ const cell = event.target.closest("td");
253
+ if (cell) {
254
+ const rect = cell.getBoundingClientRect();
255
+ update_state((s) => ({
256
+ ui_state: {
257
+ ...s.ui_state,
258
+ active_cell_menu: { row, col, x: rect.right, y: rect.bottom }
259
+ }
260
+ }));
261
+ }
262
+ }
263
+ },
264
+ toggle_cell_button: (row, col) => {
265
+ const current_button = get(state).ui_state.active_button;
266
+ const new_button = current_button?.type === "cell" &&
267
+ current_button.row === row &&
268
+ current_button.col === col
269
+ ? null
270
+ : { type: "cell", row, col };
271
+ update_state((s) => ({
272
+ ui_state: { ...s.ui_state, active_button: new_button }
273
+ }));
274
+ },
275
+ handle_select_column: (col) => {
276
+ if (!context.data)
277
+ return;
278
+ const cells = context.data.map((_, row) => [row, col]);
279
+ update_state((s) => ({
280
+ ui_state: {
281
+ ...s.ui_state,
282
+ selected_cells: cells,
283
+ selected: cells[0],
284
+ editing: false
285
+ }
286
+ }));
287
+ setTimeout(() => context.parent_element?.focus(), 0);
288
+ },
289
+ handle_select_row: (row) => {
290
+ if (!context.data || !context.data[0])
291
+ return;
292
+ const cells = context.data[0].map((_, col) => [row, col]);
293
+ update_state((s) => ({
294
+ ui_state: {
295
+ ...s.ui_state,
296
+ selected_cells: cells,
297
+ selected: cells[0],
298
+ editing: false
299
+ }
300
+ }));
301
+ setTimeout(() => context.parent_element?.focus(), 0);
302
+ },
303
+ get_next_cell_coordinates,
304
+ get_range_selection,
305
+ move_cursor
306
+ };
307
+ }
308
+ export function create_dataframe_context(config) {
309
+ const state = writable({
310
+ config,
311
+ current_search_query: null,
312
+ sort_state: { sort_columns: [], row_order: [] },
313
+ ui_state: {
314
+ active_cell_menu: null,
315
+ active_header_menu: null,
316
+ selected_cells: [],
317
+ selected: false,
318
+ editing: false,
319
+ header_edit: false,
320
+ selected_header: false,
321
+ active_button: null,
322
+ copy_flash: false
323
+ }
324
+ });
325
+ const context = { state, actions: null };
326
+ context.actions = create_actions(state, context);
327
+ const instance_id = Symbol(`dataframe_${Math.random().toString(36).substring(2)}`);
328
+ setContext(instance_id, context);
329
+ setContext(DATAFRAME_KEY, { instance_id, context });
330
+ return context;
331
+ }
332
+ export function get_dataframe_context() {
333
+ const ctx = getContext(DATAFRAME_KEY);
334
+ return ctx?.context ?? getContext(DATAFRAME_KEY);
335
+ }
@@ -1,4 +1,4 @@
1
- import type { CellCoordinate, EditingState } from "./types";
1
+ import type { CellCoordinate } from "./types";
2
2
  export type CellData = {
3
3
  id: string;
4
4
  value: string | number;
@@ -12,7 +12,6 @@ export declare function handle_selection(current: CellCoordinate, selected_cells
12
12
  ctrlKey: boolean;
13
13
  }): CellCoordinate[];
14
14
  export declare function handle_delete_key(data: CellData[][], selected_cells: CellCoordinate[]): CellData[][];
15
- export declare function handle_editing_state(current: CellCoordinate, editing: EditingState, selected_cells: CellCoordinate[], editable: boolean): EditingState;
16
15
  export declare function should_show_cell_menu(cell: CellCoordinate, selected_cells: CellCoordinate[], editable: boolean): boolean;
17
16
  export declare function get_next_cell_coordinates(current: CellCoordinate, data: CellData[][], shift_key: boolean): CellCoordinate | false;
18
17
  export declare function move_cursor(event: KeyboardEvent, current_coords: CellCoordinate, data: CellData[][]): CellCoordinate | false;
@@ -55,19 +55,6 @@ export function handle_delete_key(data, selected_cells) {
55
55
  });
56
56
  return new_data;
57
57
  }
58
- export function handle_editing_state(current, editing, selected_cells, editable) {
59
- const [row, col] = current;
60
- if (!editable)
61
- return false;
62
- if (editing && editing[0] === row && editing[1] === col)
63
- return editing;
64
- if (selected_cells.length === 1 &&
65
- selected_cells[0][0] === row &&
66
- selected_cells[0][1] === col) {
67
- return [row, col];
68
- }
69
- return false;
70
- }
71
58
  export function should_show_cell_menu(cell, selected_cells, editable) {
72
59
  const [row, col] = cell;
73
60
  return (editable &&
@@ -11,6 +11,7 @@ export function create_drag_handlers(state, set_is_dragging, set_selected_cells,
11
11
  if (!event.shiftKey && !event.metaKey && !event.ctrlKey) {
12
12
  set_selected_cells([[row, col]]);
13
13
  set_selected([row, col]);
14
+ handle_cell_click(event, row, col);
14
15
  }
15
16
  };
16
17
  const update_selection = (event) => {
@@ -1,2 +1,3 @@
1
- import type { KeyboardContext } from "../context/keyboard_context";
2
- export declare function handle_keydown(event: KeyboardEvent, context: KeyboardContext): Promise<void>;
1
+ import type { DataFrameContext } from "../context/dataframe_context";
2
+ export declare function handle_cell_blur(event: FocusEvent, ctx: DataFrameContext, coords: [number, number]): Promise<void>;
3
+ export declare function handle_keydown(event: KeyboardEvent, context: DataFrameContext): Promise<void>;