@gradio/dataframe 0.17.10 → 0.17.12

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 CHANGED
@@ -1,5 +1,30 @@
1
1
  # @gradio/dataframe
2
2
 
3
+ ## 0.17.12
4
+
5
+ ### Features
6
+
7
+ - [#11177](https://github.com/gradio-app/gradio/pull/11177) [`3068196`](https://github.com/gradio-app/gradio/commit/3068196d47234fd1c1634f33b9ddfc089f5cbbe0) - Improved, smoother fullscreen mode for components. Thanks @aliabid94!
8
+
9
+ ### Fixes
10
+
11
+ - [#11221](https://github.com/gradio-app/gradio/pull/11221) [`5f3e84d`](https://github.com/gradio-app/gradio/commit/5f3e84d870572b2851a5243be341d7aab4e166c1) - Ensure Clear sort works as expected. Thanks @hannahblair!
12
+
13
+ ### Dependency updates
14
+
15
+ - @gradio/statustracker@0.10.11
16
+ - @gradio/atoms@0.16.1
17
+ - @gradio/client@1.15.0
18
+ - @gradio/upload@0.16.5
19
+ - @gradio/button@0.5.0
20
+
21
+ ## 0.17.11
22
+
23
+ ### Dependency updates
24
+
25
+ - @gradio/button@0.4.18
26
+ - @gradio/upload@0.16.4
27
+
3
28
  ## 0.17.10
4
29
 
5
30
  ### Dependency updates
@@ -364,7 +364,7 @@
364
364
  await userEvent.click(copy_button);
365
365
 
366
366
  const fullscreen_button = canvas.getByRole("button", {
367
- name: "Enter fullscreen"
367
+ name: "Fullscreen"
368
368
  });
369
369
  await userEvent.click(fullscreen_button);
370
370
 
package/Index.svelte CHANGED
@@ -58,6 +58,7 @@
58
58
  export let show_search: "none" | "search" | "filter" = "none";
59
59
  export let pinned_columns = 0;
60
60
  export let static_columns: (string | number)[] = [];
61
+ export let fullscreen = false;
61
62
 
62
63
  $: _headers = [...(value.headers || headers)];
63
64
  $: display_value = value?.metadata?.display_value
@@ -78,6 +79,7 @@
78
79
  {scale}
79
80
  {min_width}
80
81
  overflow_behavior="visible"
82
+ bind:fullscreen
81
83
  >
82
84
  <StatusTracker
83
85
  autoscroll={gradio.autoscroll}
@@ -95,6 +97,7 @@
95
97
  {display_value}
96
98
  {styling}
97
99
  headers={_headers}
100
+ {fullscreen}
98
101
  on:change={(e) => {
99
102
  value.data = e.detail.data;
100
103
  value.headers = e.detail.headers;
@@ -102,6 +105,9 @@
102
105
  }}
103
106
  on:input={(e) => gradio.dispatch("input")}
104
107
  on:select={(e) => gradio.dispatch("select", e.detail)}
108
+ on:fullscreen={({ detail }) => {
109
+ fullscreen = detail;
110
+ }}
105
111
  {wrap}
106
112
  {datatype}
107
113
  {latex_delimiters}
package/dist/Index.svelte CHANGED
@@ -41,6 +41,7 @@ export let show_row_numbers = false;
41
41
  export let show_search = "none";
42
42
  export let pinned_columns = 0;
43
43
  export let static_columns = [];
44
+ export let fullscreen = false;
44
45
  $:
45
46
  _headers = [...value.headers || headers];
46
47
  $:
@@ -58,6 +59,7 @@ $:
58
59
  {scale}
59
60
  {min_width}
60
61
  overflow_behavior="visible"
62
+ bind:fullscreen
61
63
  >
62
64
  <StatusTracker
63
65
  autoscroll={gradio.autoscroll}
@@ -75,6 +77,7 @@ $:
75
77
  {display_value}
76
78
  {styling}
77
79
  headers={_headers}
80
+ {fullscreen}
78
81
  on:change={(e) => {
79
82
  value.data = e.detail.data;
80
83
  value.headers = e.detail.headers;
@@ -82,6 +85,9 @@ $:
82
85
  }}
83
86
  on:input={(e) => gradio.dispatch("input")}
84
87
  on:select={(e) => gradio.dispatch("select", e.detail)}
88
+ on:fullscreen={({ detail }) => {
89
+ fullscreen = detail;
90
+ }}
85
91
  {wrap}
86
92
  {datatype}
87
93
  {latex_delimiters}
@@ -45,6 +45,7 @@ declare const __propDef: {
45
45
  show_search?: ("none" | "search" | "filter") | undefined;
46
46
  pinned_columns?: number | undefined;
47
47
  static_columns?: (string | number)[] | undefined;
48
+ fullscreen?: boolean | undefined;
48
49
  };
49
50
  events: {
50
51
  [evt: string]: CustomEvent<any>;
@@ -162,4 +163,7 @@ export default class Index extends SvelteComponent<IndexProps, IndexEvents, Inde
162
163
  get static_columns(): (string | number)[] | undefined;
163
164
  /**accessor*/
164
165
  set static_columns(_: (string | number)[] | undefined);
166
+ get fullscreen(): boolean | undefined;
167
+ /**accessor*/
168
+ set fullscreen(_: boolean | undefined);
165
169
  }
@@ -59,6 +59,7 @@ export let max_chars = void 0;
59
59
  export let show_search = "none";
60
60
  export let pinned_columns = 0;
61
61
  export let static_columns = [];
62
+ export let fullscreen = false;
62
63
  const df_ctx = create_dataframe_context({
63
64
  show_fullscreen_button,
64
65
  show_copy_button,
@@ -110,23 +111,21 @@ onMount(() => {
110
111
  observer.observe(parent);
111
112
  document.addEventListener("click", handle_click_outside);
112
113
  window.addEventListener("resize", handle_resize);
113
- document.addEventListener("fullscreenchange", handle_fullscreen_change);
114
114
  return () => {
115
115
  observer.disconnect();
116
116
  document.removeEventListener("click", handle_click_outside);
117
117
  window.removeEventListener("resize", handle_resize);
118
- document.removeEventListener(
119
- "fullscreenchange",
120
- handle_fullscreen_change
121
- );
122
118
  };
123
119
  });
124
- $:
120
+ $: {
125
121
  if (data || _headers || els) {
126
122
  df_ctx.data = data;
127
123
  df_ctx.headers = _headers;
128
124
  df_ctx.els = els;
125
+ df_ctx.display_value = display_value;
126
+ df_ctx.styling = styling;
129
127
  }
128
+ }
130
129
  const dispatch = createEventDispatcher();
131
130
  let els = {};
132
131
  let data_binding = {};
@@ -135,7 +134,6 @@ let old_headers = headers;
135
134
  let data = [[]];
136
135
  let old_val = void 0;
137
136
  let search_results = [[]];
138
- let is_fullscreen = false;
139
137
  let dragging = false;
140
138
  let color_accent_copied;
141
139
  let filtered_to_original_map = [];
@@ -188,6 +186,9 @@ $:
188
186
  df_actions.reset_sort_state();
189
187
  } else if ($df_state.sort_state.sort_columns.length > 0) {
190
188
  sort_data(data, display_value, styling);
189
+ } else {
190
+ df_actions.handle_sort(-1, "asc");
191
+ df_actions.reset_sort_state();
191
192
  }
192
193
  if ($df_state.current_search_query) {
193
194
  df_actions.handle_search(null);
@@ -250,7 +251,6 @@ function handle_sort(col, direction) {
250
251
  }
251
252
  function clear_sort() {
252
253
  df_actions.reset_sort_state();
253
- sort_data(data, display_value, styling);
254
254
  }
255
255
  $:
256
256
  if ($df_state.sort_state.sort_columns.length > 0) {
@@ -403,18 +403,6 @@ function handle_blur(event) {
403
403
  const { blur_event, coords } = event.detail;
404
404
  handle_cell_blur(blur_event, df_ctx, coords);
405
405
  }
406
- function toggle_fullscreen() {
407
- if (!document.fullscreenElement) {
408
- parent.requestFullscreen();
409
- is_fullscreen = true;
410
- } else {
411
- document.exitFullscreen();
412
- is_fullscreen = false;
413
- }
414
- }
415
- function handle_fullscreen_change() {
416
- is_fullscreen = !!document.fullscreenElement;
417
- }
418
406
  function toggle_header_menu(event, col) {
419
407
  event.stopPropagation();
420
408
  if (active_header_menu && active_header_menu.col === col) {
@@ -602,12 +590,12 @@ function get_cell_display_value(row, col) {
602
590
  {/if}
603
591
  <Toolbar
604
592
  {show_fullscreen_button}
605
- {is_fullscreen}
606
- on:click={toggle_fullscreen}
593
+ {fullscreen}
607
594
  on_copy={async () => await copy_table_data(data, null)}
608
595
  {show_copy_button}
609
596
  {show_search}
610
597
  on:search={(e) => df_actions.handle_search(e.detail)}
598
+ on:fullscreen
611
599
  on_commit_filter={commit_filter}
612
600
  current_search_query={$df_state.current_search_query}
613
601
  />
@@ -35,11 +35,13 @@ declare const __propDef: {
35
35
  show_search?: ("none" | "search" | "filter") | undefined;
36
36
  pinned_columns?: number | undefined;
37
37
  static_columns?: (string | number)[] | undefined;
38
+ fullscreen?: boolean | undefined;
38
39
  display_value?: (string[][] | null) | undefined;
39
40
  styling?: (string[][] | null) | undefined;
40
41
  reset_sort_state?: (() => void) | undefined;
41
42
  };
42
43
  events: {
44
+ fullscreen: CustomEvent<boolean>;
43
45
  change: CustomEvent<DataframeValue>;
44
46
  input: CustomEvent<undefined>;
45
47
  select: CustomEvent<SelectData>;
@@ -1,10 +1,11 @@
1
- <script>import { Maximize, Minimize, Copy, Check } from "@gradio/icons";
1
+ <script>import { Copy, Check } from "@gradio/icons";
2
+ import { FullscreenButton } from "@gradio/atoms";
2
3
  import { onDestroy } from "svelte";
3
4
  import { createEventDispatcher } from "svelte";
4
5
  export let show_fullscreen_button = false;
5
6
  export let show_copy_button = false;
6
7
  export let show_search = "none";
7
- export let is_fullscreen = false;
8
+ export let fullscreen = false;
8
9
  export let on_copy;
9
10
  export let on_commit_filter;
10
11
  const dispatch = createEventDispatcher();
@@ -79,18 +80,7 @@ onDestroy(() => {
79
80
  </button>
80
81
  {/if}
81
82
  {#if show_fullscreen_button}
82
- <button
83
- class="toolbar-button"
84
- on:click
85
- aria-label={is_fullscreen ? "Exit fullscreen" : "Enter fullscreen"}
86
- title={is_fullscreen ? "Exit fullscreen" : "Enter fullscreen"}
87
- >
88
- {#if is_fullscreen}
89
- <Minimize />
90
- {:else}
91
- <Maximize />
92
- {/if}
93
- </button>
83
+ <FullscreenButton {fullscreen} on:fullscreen />
94
84
  {/if}
95
85
  </div>
96
86
  </div>
@@ -4,13 +4,13 @@ declare const __propDef: {
4
4
  show_fullscreen_button?: boolean | undefined;
5
5
  show_copy_button?: boolean | undefined;
6
6
  show_search?: ("none" | "search" | "filter") | undefined;
7
- is_fullscreen?: boolean | undefined;
7
+ fullscreen?: boolean | undefined;
8
8
  on_copy: () => Promise<void>;
9
9
  on_commit_filter: () => void;
10
10
  current_search_query?: (string | null) | undefined;
11
11
  };
12
12
  events: {
13
- click: MouseEvent;
13
+ fullscreen: CustomEvent<boolean>;
14
14
  search: CustomEvent<string | null>;
15
15
  } & {
16
16
  [evt: string]: CustomEvent<any>;
@@ -25,6 +25,14 @@ interface DataFrameState {
25
25
  direction: SortDirection;
26
26
  }[];
27
27
  row_order: number[];
28
+ initial_data: {
29
+ data: {
30
+ id: string;
31
+ value: string | number;
32
+ }[][];
33
+ display_value: string[][] | null;
34
+ styling: string[][] | null;
35
+ } | null;
28
36
  };
29
37
  ui_state: {
30
38
  active_cell_menu: {
@@ -134,6 +142,8 @@ export interface DataFrameContext {
134
142
  id: string;
135
143
  value: string;
136
144
  }[];
145
+ display_value?: string[][] | null;
146
+ styling?: string[][] | null;
137
147
  els?: Record<string, {
138
148
  cell: HTMLTableCellElement | null;
139
149
  input: HTMLInputElement | null;
@@ -37,8 +37,24 @@ function create_actions(state, context) {
37
37
  if (!s.sort_state.sort_columns.some((c) => c.col === col && c.direction === direction)) {
38
38
  sort_cols.push({ col, direction });
39
39
  }
40
+ const initial_data = s.sort_state.initial_data ||
41
+ (context.data && sort_cols.length > 0
42
+ ? {
43
+ data: JSON.parse(JSON.stringify(context.data)),
44
+ display_value: context.display_value
45
+ ? JSON.parse(JSON.stringify(context.display_value))
46
+ : null,
47
+ styling: context.styling
48
+ ? JSON.parse(JSON.stringify(context.styling))
49
+ : null
50
+ }
51
+ : null);
40
52
  return {
41
- sort_state: { ...s.sort_state, sort_columns: sort_cols.slice(-3) }
53
+ sort_state: {
54
+ ...s.sort_state,
55
+ sort_columns: sort_cols.slice(-3),
56
+ initial_data: initial_data
57
+ }
42
58
  };
43
59
  }),
44
60
  get_sort_status: (name, headers) => {
@@ -111,7 +127,7 @@ function create_actions(state, context) {
111
127
  !dequal(current_headers, previous_headers)) {
112
128
  if (!dequal(current_headers, previous_headers)) {
113
129
  update_state((s) => ({
114
- sort_state: { sort_columns: [], row_order: [] }
130
+ sort_state: { sort_columns: [], row_order: [], initial_data: null }
115
131
  }));
116
132
  }
117
133
  dispatch("change", {
@@ -123,9 +139,22 @@ function create_actions(state, context) {
123
139
  dispatch("input");
124
140
  }
125
141
  },
126
- reset_sort_state: () => update_state((s) => ({
127
- sort_state: { sort_columns: [], row_order: [] }
128
- })),
142
+ reset_sort_state: () => update_state((s) => {
143
+ if (s.sort_state.initial_data && context.data) {
144
+ const original = s.sort_state.initial_data;
145
+ const update_array = (source, target) => {
146
+ if (source && target) {
147
+ target.splice(0, target.length, ...JSON.parse(JSON.stringify(source)));
148
+ }
149
+ };
150
+ update_array(original.data, context.data);
151
+ update_array(original.display_value, context.display_value);
152
+ update_array(original.styling, context.styling);
153
+ }
154
+ return {
155
+ sort_state: { sort_columns: [], row_order: [], initial_data: null }
156
+ };
157
+ }),
129
158
  set_active_cell_menu: (menu) => update_state((s) => ({
130
159
  ui_state: { ...s.ui_state, active_cell_menu: menu }
131
160
  })),
@@ -311,7 +340,7 @@ export function create_dataframe_context(config) {
311
340
  const state = writable({
312
341
  config,
313
342
  current_search_query: null,
314
- sort_state: { sort_columns: [], row_order: [] },
343
+ sort_state: { sort_columns: [], row_order: [], initial_data: null },
315
344
  ui_state: {
316
345
  active_cell_menu: null,
317
346
  active_header_menu: null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/dataframe",
3
- "version": "0.17.10",
3
+ "version": "0.17.12",
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.16.0",
21
- "@gradio/button": "^0.4.17",
22
- "@gradio/client": "^1.14.2",
20
+ "@gradio/atoms": "^0.16.1",
23
21
  "@gradio/markdown-code": "^0.4.3",
24
- "@gradio/statustracker": "^0.10.10",
25
22
  "@gradio/icons": "^0.12.0",
26
- "@gradio/upload": "^0.16.3",
23
+ "@gradio/button": "^0.5.0",
24
+ "@gradio/statustracker": "^0.10.11",
25
+ "@gradio/client": "^1.15.0",
26
+ "@gradio/upload": "^0.16.5",
27
27
  "@gradio/utils": "^0.10.2"
28
28
  },
29
29
  "exports": {
@@ -76,6 +76,7 @@
76
76
  export let show_search: "none" | "search" | "filter" = "none";
77
77
  export let pinned_columns = 0;
78
78
  export let static_columns: (string | number)[] = [];
79
+ export let fullscreen = false;
79
80
 
80
81
  const df_ctx = create_dataframe_context({
81
82
  show_fullscreen_button,
@@ -127,23 +128,22 @@
127
128
  observer.observe(parent);
128
129
  document.addEventListener("click", handle_click_outside);
129
130
  window.addEventListener("resize", handle_resize);
130
- document.addEventListener("fullscreenchange", handle_fullscreen_change);
131
131
 
132
132
  return () => {
133
133
  observer.disconnect();
134
134
  document.removeEventListener("click", handle_click_outside);
135
135
  window.removeEventListener("resize", handle_resize);
136
- document.removeEventListener(
137
- "fullscreenchange",
138
- handle_fullscreen_change
139
- );
140
136
  };
141
137
  });
142
138
 
143
- $: if (data || _headers || els) {
144
- df_ctx.data = data;
145
- df_ctx.headers = _headers;
146
- df_ctx.els = els;
139
+ $: {
140
+ if (data || _headers || els) {
141
+ df_ctx.data = data;
142
+ df_ctx.headers = _headers;
143
+ df_ctx.els = els;
144
+ df_ctx.display_value = display_value;
145
+ df_ctx.styling = styling;
146
+ }
147
147
  }
148
148
 
149
149
  const dispatch = createEventDispatcher<{
@@ -169,7 +169,6 @@
169
169
  display_value?: string;
170
170
  styling?: string;
171
171
  }[][] = [[]];
172
- let is_fullscreen = false;
173
172
  let dragging = false;
174
173
  let color_accent_copied: string;
175
174
  let filtered_to_original_map: number[] = [];
@@ -248,6 +247,9 @@
248
247
  df_actions.reset_sort_state();
249
248
  } else if ($df_state.sort_state.sort_columns.length > 0) {
250
249
  sort_data(data, display_value, styling);
250
+ } else {
251
+ df_actions.handle_sort(-1, "asc");
252
+ df_actions.reset_sort_state();
251
253
  }
252
254
 
253
255
  if ($df_state.current_search_query) {
@@ -329,7 +331,6 @@
329
331
 
330
332
  function clear_sort(): void {
331
333
  df_actions.reset_sort_state();
332
- sort_data(data, display_value, styling);
333
334
  }
334
335
 
335
336
  $: if ($df_state.sort_state.sort_columns.length > 0) {
@@ -525,20 +526,6 @@
525
526
  handle_cell_blur(blur_event, df_ctx, coords);
526
527
  }
527
528
 
528
- function toggle_fullscreen(): void {
529
- if (!document.fullscreenElement) {
530
- parent.requestFullscreen();
531
- is_fullscreen = true;
532
- } else {
533
- document.exitFullscreen();
534
- is_fullscreen = false;
535
- }
536
- }
537
-
538
- function handle_fullscreen_change(): void {
539
- is_fullscreen = !!document.fullscreenElement;
540
- }
541
-
542
529
  function toggle_header_menu(event: MouseEvent, col: number): void {
543
530
  event.stopPropagation();
544
531
  if (active_header_menu && active_header_menu.col === col) {
@@ -750,12 +737,12 @@
750
737
  {/if}
751
738
  <Toolbar
752
739
  {show_fullscreen_button}
753
- {is_fullscreen}
754
- on:click={toggle_fullscreen}
740
+ {fullscreen}
755
741
  on_copy={async () => await copy_table_data(data, null)}
756
742
  {show_copy_button}
757
743
  {show_search}
758
744
  on:search={(e) => df_actions.handle_search(e.detail)}
745
+ on:fullscreen
759
746
  on_commit_filter={commit_filter}
760
747
  current_search_query={$df_state.current_search_query}
761
748
  />
@@ -1,12 +1,13 @@
1
1
  <script lang="ts">
2
- import { Maximize, Minimize, Copy, Check } from "@gradio/icons";
2
+ import { Copy, Check } from "@gradio/icons";
3
+ import { FullscreenButton } from "@gradio/atoms";
3
4
  import { onDestroy } from "svelte";
4
5
  import { createEventDispatcher } from "svelte";
5
6
 
6
7
  export let show_fullscreen_button = false;
7
8
  export let show_copy_button = false;
8
9
  export let show_search: "none" | "search" | "filter" = "none";
9
- export let is_fullscreen = false;
10
+ export let fullscreen = false;
10
11
  export let on_copy: () => Promise<void>;
11
12
  export let on_commit_filter: () => void;
12
13
 
@@ -87,18 +88,7 @@
87
88
  </button>
88
89
  {/if}
89
90
  {#if show_fullscreen_button}
90
- <button
91
- class="toolbar-button"
92
- on:click
93
- aria-label={is_fullscreen ? "Exit fullscreen" : "Enter fullscreen"}
94
- title={is_fullscreen ? "Exit fullscreen" : "Enter fullscreen"}
95
- >
96
- {#if is_fullscreen}
97
- <Minimize />
98
- {:else}
99
- <Maximize />
100
- {/if}
101
- </button>
91
+ <FullscreenButton {fullscreen} on:fullscreen />
102
92
  {/if}
103
93
  </div>
104
94
  </div>
@@ -34,6 +34,11 @@ interface DataFrameState {
34
34
  sort_state: {
35
35
  sort_columns: { col: number; direction: SortDirection }[];
36
36
  row_order: number[];
37
+ initial_data: {
38
+ data: { id: string; value: string | number }[][];
39
+ display_value: string[][] | null;
40
+ styling: string[][] | null;
41
+ } | null;
37
42
  };
38
43
  ui_state: {
39
44
  active_cell_menu: { row: number; col: number; x: number; y: number } | null;
@@ -149,6 +154,8 @@ export interface DataFrameContext {
149
154
  actions: DataFrameActions;
150
155
  data?: any[][];
151
156
  headers?: { id: string; value: string }[];
157
+ display_value?: string[][] | null;
158
+ styling?: string[][] | null;
152
159
  els?: Record<
153
160
  string,
154
161
  { cell: HTMLTableCellElement | null; input: HTMLInputElement | null }
@@ -217,8 +224,27 @@ function create_actions(
217
224
  ) {
218
225
  sort_cols.push({ col, direction });
219
226
  }
227
+
228
+ const initial_data =
229
+ s.sort_state.initial_data ||
230
+ (context.data && sort_cols.length > 0
231
+ ? {
232
+ data: JSON.parse(JSON.stringify(context.data)),
233
+ display_value: context.display_value
234
+ ? JSON.parse(JSON.stringify(context.display_value))
235
+ : null,
236
+ styling: context.styling
237
+ ? JSON.parse(JSON.stringify(context.styling))
238
+ : null
239
+ }
240
+ : null);
241
+
220
242
  return {
221
- sort_state: { ...s.sort_state, sort_columns: sort_cols.slice(-3) }
243
+ sort_state: {
244
+ ...s.sort_state,
245
+ sort_columns: sort_cols.slice(-3),
246
+ initial_data: initial_data
247
+ }
222
248
  };
223
249
  }),
224
250
  get_sort_status: (name, headers) => {
@@ -319,7 +345,7 @@ function create_actions(
319
345
  ) {
320
346
  if (!dequal(current_headers, previous_headers)) {
321
347
  update_state((s) => ({
322
- sort_state: { sort_columns: [], row_order: [] }
348
+ sort_state: { sort_columns: [], row_order: [], initial_data: null }
323
349
  }));
324
350
  }
325
351
  dispatch("change", {
@@ -331,9 +357,35 @@ function create_actions(
331
357
  }
332
358
  },
333
359
  reset_sort_state: () =>
334
- update_state((s) => ({
335
- sort_state: { sort_columns: [], row_order: [] }
336
- })),
360
+ update_state((s) => {
361
+ if (s.sort_state.initial_data && context.data) {
362
+ const original = s.sort_state.initial_data;
363
+
364
+ const update_array = (
365
+ source:
366
+ | { id: string; value: string | number }[][]
367
+ | string[][]
368
+ | null,
369
+ target: any[] | null | undefined
370
+ ): void => {
371
+ if (source && target) {
372
+ target.splice(
373
+ 0,
374
+ target.length,
375
+ ...JSON.parse(JSON.stringify(source))
376
+ );
377
+ }
378
+ };
379
+
380
+ update_array(original.data, context.data);
381
+ update_array(original.display_value, context.display_value);
382
+ update_array(original.styling, context.styling);
383
+ }
384
+
385
+ return {
386
+ sort_state: { sort_columns: [], row_order: [], initial_data: null }
387
+ };
388
+ }),
337
389
  set_active_cell_menu: (menu) =>
338
390
  update_state((s) => ({
339
391
  ui_state: { ...s.ui_state, active_cell_menu: menu }
@@ -546,7 +598,7 @@ export function create_dataframe_context(
546
598
  const state = writable<DataFrameState>({
547
599
  config,
548
600
  current_search_query: null,
549
- sort_state: { sort_columns: [], row_order: [] },
601
+ sort_state: { sort_columns: [], row_order: [], initial_data: null },
550
602
  ui_state: {
551
603
  active_cell_menu: null,
552
604
  active_header_menu: null,