@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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @gradio/dataframe
2
2
 
3
+ ## 0.17.5
4
+
5
+ ### Fixes
6
+
7
+ - [#10955](https://github.com/gradio-app/gradio/pull/10955) [`d654e60`](https://github.com/gradio-app/gradio/commit/d654e60ff61f76ebcf37f294f1d85305d344a70b) - Map search-filtered row indices to original data indices in gr.Dataframe. Thanks @hannahblair!
8
+ - [#10918](https://github.com/gradio-app/gradio/pull/10918) [`36da6d0`](https://github.com/gradio-app/gradio/commit/36da6d0d5466dd251f46359019959702523f1afc) - Fix value synchronisation issue in gr.Dataframe. Thanks @hannahblair!
9
+
10
+ ### Dependency updates
11
+
12
+ - @gradio/statustracker@0.10.7
13
+ - @gradio/button@0.4.13
14
+ - @gradio/atoms@0.15.0
15
+ - @gradio/icons@0.11.0
16
+ - @gradio/upload@0.16.0
17
+
3
18
  ## 0.17.4
4
19
 
5
20
  ### Dependency updates
@@ -562,6 +562,7 @@
562
562
 
563
563
  const search_input = canvas.getByPlaceholderText("Filter...");
564
564
  await user.type(search_input, "Pet");
565
+ await user.click(canvas.getByText("Cat"));
565
566
 
566
567
  await new Promise((resolve) => setTimeout(resolve, 100));
567
568
 
@@ -751,6 +752,34 @@
751
752
  }}
752
753
  />
753
754
 
755
+ <Story
756
+ name="Dataframe with display values"
757
+ args={{
758
+ values: [
759
+ [95, 92, 88],
760
+ [89, 90, 85],
761
+ [92, 88, 91],
762
+ [87, 85, 89],
763
+ [91, 93, 90],
764
+ [82, 81, 83]
765
+ ],
766
+ headers: ["Model A", "Model B", "Model C"],
767
+ display_value: [
768
+ ["🥇 95", "92", "88"],
769
+ ["🥈 89", "90", "85"],
770
+ ["🥉 92", "88", "91"],
771
+ ["87", "85", "89"],
772
+ ["91", "93", "90"],
773
+ ["82", "81", "83"]
774
+ ],
775
+ label: "Model Performance with Medal Indicators",
776
+ col_count: [3, "dynamic"],
777
+ row_count: [6, "dynamic"],
778
+ show_row_numbers: true,
779
+ editable: false
780
+ }}
781
+ />
782
+
754
783
  <Story
755
784
  name="Dataframe with text wrapping, no max chars"
756
785
  args={{
@@ -1,6 +1,6 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import type { I18nFormatter } from "js/utils/src";
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
  x: number;
@@ -8,7 +8,6 @@ export let styling = "";
8
8
  export let header = false;
9
9
  export let datatype = "str";
10
10
  export let latex_delimiters;
11
- export let clear_on_focus = false;
12
11
  export let line_breaks = true;
13
12
  export let editable = true;
14
13
  export let is_static = false;
@@ -19,14 +18,12 @@ export let i18n;
19
18
  export let is_dragging = false;
20
19
  export let wrap_text = false;
21
20
  export let show_selection_buttons = false;
22
- export let coords = null;
21
+ export let coords;
23
22
  export let on_select_column = null;
24
23
  export let on_select_row = null;
25
24
  const dispatch = createEventDispatcher();
26
25
  let is_expanded = false;
27
26
  export let el;
28
- $:
29
- _value = value;
30
27
  function truncate_text(text, max_length = null, is_image = false) {
31
28
  if (is_image)
32
29
  return String(text);
@@ -44,26 +41,20 @@ $:
44
41
  $:
45
42
  display_text = should_truncate ? truncate_text(display_content, max_chars, datatype === "image") : display_content;
46
43
  function use_focus(node) {
47
- if (clear_on_focus) {
48
- _value = "";
49
- }
50
44
  requestAnimationFrame(() => {
51
45
  node.focus();
52
46
  });
53
47
  return {};
54
48
  }
55
- function handle_blur({
56
- currentTarget
57
- }) {
58
- value = currentTarget.value;
59
- dispatch("blur");
49
+ function handle_blur(event) {
50
+ dispatch("blur", {
51
+ blur_event: event,
52
+ coords
53
+ });
60
54
  }
61
55
  function handle_keydown(event) {
62
56
  if (event.key === "Enter") {
63
- if (edit) {
64
- value = _value;
65
- dispatch("blur");
66
- } else if (!header) {
57
+ if (!header) {
67
58
  is_expanded = !is_expanded;
68
59
  }
69
60
  }
@@ -83,7 +74,7 @@ function handle_click() {
83
74
  role="textbox"
84
75
  aria-label={is_static ? "Cell is read-only" : "Edit cell"}
85
76
  bind:this={el}
86
- bind:value={_value}
77
+ bind:value
87
78
  class:header
88
79
  tabindex="-1"
89
80
  on:blur={handle_blur}
@@ -13,7 +13,6 @@ declare const __propDef: {
13
13
  right: string;
14
14
  display: boolean;
15
15
  }[];
16
- clear_on_focus?: boolean | undefined;
17
16
  line_breaks?: boolean | undefined;
18
17
  editable?: boolean | undefined;
19
18
  is_static?: boolean | undefined;
@@ -24,7 +23,7 @@ declare const __propDef: {
24
23
  is_dragging?: boolean | undefined;
25
24
  wrap_text?: boolean | undefined;
26
25
  show_selection_buttons?: boolean | undefined;
27
- coords?: ([number, number] | null) | undefined;
26
+ coords: [number, number];
28
27
  on_select_column?: (((col: number) => void) | null) | undefined;
29
28
  on_select_row?: (((row: number) => void) | null) | undefined;
30
29
  el: HTMLInputElement | null;
@@ -34,7 +33,10 @@ declare const __propDef: {
34
33
  mouseup: MouseEvent;
35
34
  click: MouseEvent;
36
35
  focus: FocusEvent;
37
- blur: CustomEvent<void>;
36
+ blur: CustomEvent<{
37
+ blur_event: FocusEvent;
38
+ coords: [number, number];
39
+ }>;
38
40
  keydown: CustomEvent<KeyboardEvent>;
39
41
  } & {
40
42
  [evt: string]: CustomEvent<any>;
@@ -1,8 +1,6 @@
1
1
  <script context="module">import {
2
2
  create_dataframe_context
3
- } from "./context/table_context";
4
- import { create_keyboard_context } from "./context/keyboard_context";
5
- import { create_selection_context } from "./context/selection_context";
3
+ } from "./context/dataframe_context";
6
4
  </script>
7
5
 
8
6
  <script>import { afterUpdate, createEventDispatcher, tick, onMount } from "svelte";
@@ -20,9 +18,6 @@ import Toolbar from "./Toolbar.svelte";
20
18
  import {
21
19
  is_cell_selected,
22
20
  should_show_cell_menu,
23
- get_next_cell_coordinates,
24
- get_range_selection,
25
- move_cursor,
26
21
  get_current_indices,
27
22
  handle_click_outside as handle_click_outside_util,
28
23
  calculate_selection_positions
@@ -33,7 +28,7 @@ import {
33
28
  handle_file_upload
34
29
  } from "./utils/table_utils";
35
30
  import { make_headers, process_data } from "./utils/data_processing";
36
- import { handle_keydown } from "./utils/keyboard_utils";
31
+ import { handle_keydown, handle_cell_blur } from "./utils/keyboard_utils";
37
32
  import {
38
33
  create_drag_handlers
39
34
  } from "./utils/drag_utils";
@@ -64,9 +59,7 @@ export let max_chars = void 0;
64
59
  export let show_search = "none";
65
60
  export let pinned_columns = 0;
66
61
  export let static_columns = [];
67
- $:
68
- actual_pinned_columns = pinned_columns && data?.[0]?.length ? Math.min(pinned_columns, data[0].length) : 0;
69
- const { state: df_state, actions: df_actions } = create_dataframe_context({
62
+ const df_ctx = create_dataframe_context({
70
63
  show_fullscreen_button,
71
64
  show_copy_button,
72
65
  show_search,
@@ -80,25 +73,13 @@ const { state: df_state, actions: df_actions } = create_dataframe_context({
80
73
  column_widths,
81
74
  max_chars
82
75
  });
76
+ const { state: df_state, actions: df_actions } = df_ctx;
83
77
  $:
84
78
  selected_cells = $df_state.ui_state.selected_cells;
85
- let previous_selected_cells = [];
86
- $: {
87
- if (copy_flash && !dequal(selected_cells, previous_selected_cells)) {
88
- keyboard_ctx?.set_copy_flash(false);
89
- }
90
- previous_selected_cells = selected_cells;
91
- }
92
79
  $:
93
80
  selected = $df_state.ui_state.selected;
94
- export let display_value = null;
95
- export let styling = null;
96
- let els = {};
97
- let data_binding = {};
98
- const dispatch = createEventDispatcher();
99
81
  $:
100
82
  editing = $df_state.ui_state.editing;
101
- let clear_on_focus = false;
102
83
  $:
103
84
  header_edit = $df_state.ui_state.header_edit;
104
85
  $:
@@ -107,10 +88,55 @@ $:
107
88
  active_cell_menu = $df_state.ui_state.active_cell_menu;
108
89
  $:
109
90
  active_header_menu = $df_state.ui_state.active_header_menu;
91
+ $:
92
+ copy_flash = $df_state.ui_state.copy_flash;
93
+ $:
94
+ actual_pinned_columns = pinned_columns && data?.[0]?.length ? Math.min(pinned_columns, data[0].length) : 0;
95
+ onMount(() => {
96
+ df_ctx.parent_element = parent;
97
+ df_ctx.get_data_at = get_data_at;
98
+ df_ctx.dispatch = dispatch;
99
+ init_drag_handlers();
100
+ const observer = new IntersectionObserver((entries) => {
101
+ entries.forEach((entry) => {
102
+ if (entry.isIntersecting && !is_visible) {
103
+ set_cell_widths();
104
+ }
105
+ is_visible = entry.isIntersecting;
106
+ });
107
+ });
108
+ observer.observe(parent);
109
+ document.addEventListener("click", handle_click_outside);
110
+ window.addEventListener("resize", handle_resize);
111
+ document.addEventListener("fullscreenchange", handle_fullscreen_change);
112
+ return () => {
113
+ observer.disconnect();
114
+ document.removeEventListener("click", handle_click_outside);
115
+ window.removeEventListener("resize", handle_resize);
116
+ document.removeEventListener(
117
+ "fullscreenchange",
118
+ handle_fullscreen_change
119
+ );
120
+ };
121
+ });
122
+ $:
123
+ if (data || _headers || els) {
124
+ df_ctx.data = data;
125
+ df_ctx.headers = _headers;
126
+ df_ctx.els = els;
127
+ }
128
+ const dispatch = createEventDispatcher();
129
+ let els = {};
130
+ let data_binding = {};
131
+ let _headers = make_headers(headers, col_count, els, make_id);
132
+ let old_headers = headers;
133
+ let data = [[]];
134
+ let old_val = void 0;
135
+ let search_results = [[]];
110
136
  let is_fullscreen = false;
111
137
  let dragging = false;
112
- let copy_flash = false;
113
138
  let color_accent_copied;
139
+ let filtered_to_original_map = [];
114
140
  onMount(() => {
115
141
  const color = getComputedStyle(document.documentElement).getPropertyValue("--color-accent").trim();
116
142
  color_accent_copied = color + "40";
@@ -120,20 +146,17 @@ onMount(() => {
120
146
  );
121
147
  });
122
148
  const get_data_at = (row, col) => data?.[row]?.[col]?.value;
123
- function make_id() {
124
- return Math.random().toString(36).substring(2, 15);
125
- }
126
- let _headers = make_headers(headers, col_count, els, make_id);
127
- let old_headers = headers;
128
149
  $: {
129
150
  if (!dequal(headers, old_headers)) {
130
151
  _headers = make_headers(headers, col_count, els, make_id);
131
152
  old_headers = JSON.parse(JSON.stringify(headers));
132
153
  }
133
154
  }
134
- let data = [[]];
135
- let old_val = void 0;
136
- let search_results = [[]];
155
+ function make_id() {
156
+ return Math.random().toString(36).substring(2, 15);
157
+ }
158
+ export let display_value = null;
159
+ export let styling = null;
137
160
  $:
138
161
  if (!dequal(values, old_val)) {
139
162
  if (parent) {
@@ -172,10 +195,17 @@ $:
172
195
  $:
173
196
  if ($df_state.current_search_query !== void 0) {
174
197
  const cell_map = /* @__PURE__ */ new Map();
198
+ filtered_to_original_map = [];
175
199
  data.forEach((row, row_idx) => {
200
+ if (row.some(
201
+ (cell) => String(cell?.value).toLowerCase().includes($df_state.current_search_query?.toLowerCase() || "")
202
+ )) {
203
+ filtered_to_original_map.push(row_idx);
204
+ }
176
205
  row.forEach((cell, col_idx) => {
177
206
  cell_map.set(cell.id, {
178
207
  value: cell.value,
208
+ display_value: cell.display_value || String(cell.value),
179
209
  styling: styling?.[row_idx]?.[col_idx] || ""
180
210
  });
181
211
  });
@@ -191,6 +221,8 @@ $:
191
221
  };
192
222
  })
193
223
  );
224
+ } else {
225
+ filtered_to_original_map = [];
194
226
  }
195
227
  let previous_headers = _headers.map((h) => h.value);
196
228
  let previous_data = data.map((row) => row.map((cell) => String(cell.value)));
@@ -216,21 +248,13 @@ function clear_sort() {
216
248
  df_actions.reset_sort_state();
217
249
  sort_data(data, display_value, styling);
218
250
  }
219
- $: {
220
- df_actions.sort_data(data, display_value, styling);
221
- df_actions.update_row_order(data);
222
- }
223
- $: {
224
- if ($df_state.sort_state.sort_columns) {
225
- if ($df_state.sort_state.sort_columns.length > 0) {
226
- sort_data(data, display_value, styling);
227
- }
251
+ $:
252
+ if ($df_state.sort_state.sort_columns.length > 0) {
253
+ sort_data(data, display_value, styling);
254
+ df_actions.update_row_order(data);
228
255
  }
229
- }
230
256
  async function edit_header(i, _select = false) {
231
- if (!editable || header_edit === i)
232
- return;
233
- if (!editable || col_count[1] !== "dynamic" || header_edit === i)
257
+ if (!editable || header_edit === i || col_count[1] !== "dynamic")
234
258
  return;
235
259
  df_actions.set_header_edit(i);
236
260
  }
@@ -242,7 +266,6 @@ function handle_header_click(event, col) {
242
266
  event.stopPropagation();
243
267
  if (!editable)
244
268
  return;
245
- clear_on_focus = false;
246
269
  df_actions.set_editing(false);
247
270
  df_actions.handle_header_click(col, editable);
248
271
  parent.focus();
@@ -269,7 +292,6 @@ async function add_row(index) {
269
292
  } else {
270
293
  data.push(new_row);
271
294
  }
272
- data = data;
273
295
  selected = [index !== void 0 ? index : data.length - 1, 0];
274
296
  }
275
297
  async function add_col(index) {
@@ -357,87 +379,25 @@ function sort_data(_data, _display_value, _styling) {
357
379
  data = result.data;
358
380
  selected = result.selected;
359
381
  }
360
- $:
361
- sort_data(data, display_value, styling);
362
382
  $:
363
383
  selected_index = !!selected && selected[0];
364
384
  let is_visible = false;
365
- onMount(() => {
366
- const observer = new IntersectionObserver((entries) => {
367
- entries.forEach((entry) => {
368
- if (entry.isIntersecting && !is_visible) {
369
- set_cell_widths();
370
- data = data;
371
- }
372
- is_visible = entry.isIntersecting;
373
- });
374
- });
375
- observer.observe(parent);
376
- document.addEventListener("click", handle_click_outside);
377
- window.addEventListener("resize", handle_resize);
378
- document.addEventListener("fullscreenchange", handle_fullscreen_change);
379
- return () => {
380
- observer.disconnect();
381
- document.removeEventListener("click", handle_click_outside);
382
- window.removeEventListener("resize", handle_resize);
383
- document.removeEventListener(
384
- "fullscreenchange",
385
- handle_fullscreen_change
386
- );
387
- };
388
- });
389
- $:
390
- keyboard_ctx = create_keyboard_context({
391
- selected_header,
392
- header_edit,
393
- editing,
394
- selected,
395
- selected_cells,
396
- editable,
397
- data,
398
- headers: _headers,
399
- els,
400
- df_actions,
401
- dispatch,
402
- add_row,
403
- get_next_cell_coordinates,
404
- get_range_selection,
405
- move_cursor,
406
- copy_flash,
407
- parent_element: parent,
408
- set_copy_flash: (value) => {
409
- copy_flash = value;
410
- if (value) {
411
- setTimeout(() => {
412
- copy_flash = false;
413
- }, 800);
414
- }
415
- }
416
- });
417
- $:
418
- selection_ctx = create_selection_context({
419
- df_actions,
420
- dispatch,
421
- data,
422
- els,
423
- editable,
424
- show_row_numbers,
425
- get_data_at,
426
- clear_on_focus,
427
- selected_cells,
428
- parent_element: parent
429
- });
430
- function handle_cell_click(event, row, col) {
431
- selection_ctx.actions.handle_cell_click(event, row, col);
432
- }
433
- function toggle_cell_menu(event, row, col) {
434
- selection_ctx.actions.toggle_cell_menu(event, row, col);
435
- }
436
- function handle_select_column(col) {
437
- selection_ctx.actions.handle_select_column(col);
385
+ const set_copy_flash = (value) => {
386
+ df_actions.set_copy_flash(value);
387
+ if (value) {
388
+ setTimeout(() => df_actions.set_copy_flash(false), 800);
389
+ }
390
+ };
391
+ let previous_selected_cells = [];
392
+ $: {
393
+ if (copy_flash && !dequal(selected_cells, previous_selected_cells)) {
394
+ set_copy_flash(false);
395
+ }
396
+ previous_selected_cells = selected_cells;
438
397
  }
439
- function handle_select_row(row) {
440
- selection_ctx.actions.handle_select_row(row);
398
+ function handle_blur(event) {
399
+ const { blur_event, coords } = event.detail;
400
+ handle_cell_blur(blur_event, df_ctx, coords);
441
401
  }
442
402
  function toggle_fullscreen() {
443
403
  if (!document.fullscreenElement) {
@@ -490,10 +450,10 @@ function delete_row_at(index) {
490
450
  df_actions.set_active_cell_menu(null);
491
451
  df_actions.set_active_header_menu(null);
492
452
  }
493
- let coords;
453
+ let selected_cell_coords;
494
454
  $:
495
455
  if (selected !== false)
496
- coords = selected;
456
+ selected_cell_coords = selected;
497
457
  $:
498
458
  if (selected !== false) {
499
459
  const positions = calculate_selection_positions(
@@ -595,7 +555,7 @@ function init_drag_handlers() {
595
555
  (value) => is_dragging = value,
596
556
  (cells2) => df_actions.set_selected_cells(cells2),
597
557
  (cell) => df_actions.set_selected(cell),
598
- (event, row, col) => selection_ctx.actions.handle_cell_click(event, row, col),
558
+ (event, row, col) => df_actions.handle_cell_click(event, row, col),
599
559
  show_row_numbers,
600
560
  parent
601
561
  );
@@ -612,6 +572,16 @@ $:
612
572
  $:
613
573
  handle_mouse_up = drag_handlers?.handle_mouse_up || (() => {
614
574
  });
575
+ function get_cell_display_value(row, col) {
576
+ const is_search_active = $df_state.current_search_query !== void 0;
577
+ if (is_search_active && search_results?.[row]?.[col]) {
578
+ return search_results[row][col].display_value || String(search_results[row][col].value);
579
+ }
580
+ if (data?.[row]?.[col]) {
581
+ return data[row][col].display_value || String(data[row][col].value);
582
+ }
583
+ return "";
584
+ }
615
585
  </script>
616
586
 
617
587
  <svelte:window on:resize={() => set_cell_widths()} />
@@ -644,7 +614,7 @@ $:
644
614
  class:no-wrap={!wrap}
645
615
  style="height:{table_height}px;"
646
616
  class:menu-open={active_cell_menu || active_header_menu}
647
- on:keydown={(e) => handle_keydown(e, keyboard_ctx)}
617
+ on:keydown={(e) => handle_keydown(e, df_ctx)}
648
618
  on:mousemove={handle_mouse_move}
649
619
  on:mouseup={handle_mouse_up}
650
620
  on:mouseleave={handle_mouse_up}
@@ -667,7 +637,6 @@ $:
667
637
  {actual_pinned_columns}
668
638
  {header_edit}
669
639
  {selected_header}
670
- get_sort_status={df_actions.get_sort_status}
671
640
  {headers}
672
641
  {get_cell_width}
673
642
  {handle_header_click}
@@ -708,10 +677,11 @@ $:
708
677
  show_selection_buttons={selected_cells.length === 1 &&
709
678
  selected_cells[0][0] === 0 &&
710
679
  selected_cells[0][1] === j}
711
- coords={[0, j]}
712
- on_select_column={handle_select_column}
713
- on_select_row={handle_select_row}
680
+ coords={selected_cell_coords}
681
+ on_select_column={df_actions.handle_select_column}
682
+ on_select_row={df_actions.handle_select_row}
714
683
  {is_dragging}
684
+ on:blur={handle_blur}
715
685
  />
716
686
  </div>
717
687
  </td>
@@ -773,7 +743,6 @@ $:
773
743
  {actual_pinned_columns}
774
744
  {header_edit}
775
745
  {selected_header}
776
- get_sort_status={df_actions.get_sort_status}
777
746
  {headers}
778
747
  {get_cell_width}
779
748
  {handle_header_click}
@@ -799,12 +768,17 @@ $:
799
768
  {#each item as { value, id }, j (id)}
800
769
  <TableCell
801
770
  bind:value={search_results[index][j].value}
802
- {index}
771
+ display_value={get_cell_display_value(index, j)}
772
+ index={$df_state.current_search_query !== undefined &&
773
+ filtered_to_original_map[index] !== undefined
774
+ ? filtered_to_original_map[index]
775
+ : index}
803
776
  {j}
804
777
  {actual_pinned_columns}
805
778
  {get_cell_width}
806
779
  handle_cell_click={(e, r, c) => handle_mouse_down(e, r, c)}
807
- {toggle_cell_menu}
780
+ {handle_blur}
781
+ toggle_cell_menu={df_actions.toggle_cell_menu}
808
782
  {is_cell_selected}
809
783
  {should_show_cell_menu}
810
784
  {selected_cells}
@@ -815,15 +789,14 @@ $:
815
789
  {line_breaks}
816
790
  datatype={Array.isArray(datatype) ? datatype[j] : datatype}
817
791
  {editing}
818
- {clear_on_focus}
819
792
  {max_chars}
820
793
  {root}
821
794
  {editable}
822
795
  is_static={static_columns.includes(j)}
823
796
  {i18n}
824
797
  {components}
825
- {handle_select_column}
826
- {handle_select_row}
798
+ handle_select_column={df_actions.handle_select_column}
799
+ handle_select_row={df_actions.handle_select_row}
827
800
  bind:el={els[id]}
828
801
  {is_dragging}
829
802
  {wrap}
@@ -7,6 +7,7 @@ export let j;
7
7
  export let actual_pinned_columns;
8
8
  export let get_cell_width;
9
9
  export let handle_cell_click;
10
+ export let handle_blur;
10
11
  export let toggle_cell_menu;
11
12
  export let is_cell_selected;
12
13
  export let should_show_cell_menu;
@@ -18,7 +19,6 @@ export let latex_delimiters;
18
19
  export let line_breaks;
19
20
  export let datatype;
20
21
  export let editing;
21
- export let clear_on_focus;
22
22
  export let max_chars;
23
23
  export let root;
24
24
  export let editable;
@@ -29,6 +29,7 @@ export let el;
29
29
  export let handle_select_column;
30
30
  export let handle_select_row;
31
31
  export let is_dragging;
32
+ export let display_value;
32
33
  export let wrap = false;
33
34
  function get_cell_position(col_index) {
34
35
  if (col_index >= actual_pinned_columns) {
@@ -83,16 +84,13 @@ $:
83
84
  <EditableCell
84
85
  bind:value
85
86
  bind:el={el.input}
86
- display_value={String(value)}
87
+ display_value={display_value || String(value)}
87
88
  {latex_delimiters}
88
89
  {line_breaks}
89
90
  {editable}
90
91
  {is_static}
91
92
  edit={editing && editing[0] === index && editing[1] === j}
92
93
  {datatype}
93
- on:blur={() => {
94
- clear_on_focus = false;
95
- }}
96
94
  on:focus={() => {
97
95
  const row = index;
98
96
  const col = j;
@@ -100,7 +98,7 @@ $:
100
98
  selected_cells = [[row, col]];
101
99
  }
102
100
  }}
103
- {clear_on_focus}
101
+ on:blur={handle_blur}
104
102
  {root}
105
103
  {max_chars}
106
104
  {i18n}
@@ -9,6 +9,10 @@ declare const __propDef: {
9
9
  actual_pinned_columns: number;
10
10
  get_cell_width: (index: number) => string;
11
11
  handle_cell_click: (event: MouseEvent, row: number, col: number) => void;
12
+ handle_blur: (event: CustomEvent<{
13
+ blur_event: FocusEvent;
14
+ coords: [number, number];
15
+ }>) => void;
12
16
  toggle_cell_menu: (event: MouseEvent, row: number, col: number) => void;
13
17
  is_cell_selected: (coords: [number, number], selected_cells: [number, number][]) => string;
14
18
  should_show_cell_menu: (coords: [number, number], selected_cells: [number, number][], editable: boolean) => boolean;
@@ -29,7 +33,6 @@ declare const __propDef: {
29
33
  line_breaks: boolean;
30
34
  datatype: Datatype;
31
35
  editing: [number, number] | false;
32
- clear_on_focus: boolean;
33
36
  max_chars: number | undefined;
34
37
  root: string;
35
38
  editable: boolean;
@@ -43,6 +46,7 @@ declare const __propDef: {
43
46
  handle_select_column: (col: number) => void;
44
47
  handle_select_row: (row: number) => void;
45
48
  is_dragging: boolean;
49
+ display_value: string | undefined;
46
50
  wrap?: boolean | undefined;
47
51
  };
48
52
  events: {