@gradio/dataframe 0.18.3 → 0.18.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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # @gradio/dataframe
2
2
 
3
+ ## 0.18.5
4
+
5
+ ### Dependency updates
6
+
7
+ - @gradio/upload@0.16.13
8
+ - @gradio/client@1.16.0
9
+ - @gradio/button@0.5.9
10
+
11
+ ## 0.18.4
12
+
13
+ ### Fixes
14
+
15
+ - [#11559](https://github.com/gradio-app/gradio/pull/11559) [`dd9d8f1`](https://github.com/gradio-app/gradio/commit/dd9d8f1ed677e2d09a3061764c312f40133ab50d) - `gr.Dataframe` returns a `number` \ `bool` when the corresponding column is edited. Thanks @janosch6!
16
+
17
+ ### Dependency updates
18
+
19
+ - @gradio/upload@0.16.12
20
+ - @gradio/client@1.15.7
21
+ - @gradio/button@0.5.8
22
+
3
23
  ## 0.18.3
4
24
 
5
25
  ### Fixes
@@ -28,6 +28,7 @@ import {
28
28
  handle_file_upload
29
29
  } from "./utils/table_utils";
30
30
  import { make_headers, process_data } from "./utils/data_processing";
31
+ import { cast_value_to_type } from "./utils";
31
32
  import { handle_keydown, handle_cell_blur } from "./utils/keyboard_utils";
32
33
  import {
33
34
  create_drag_handlers
@@ -249,7 +250,15 @@ let previous_data = data.map((row) => row.map((cell) => String(cell.value)));
249
250
  $: {
250
251
  if (data || _headers) {
251
252
  df_actions.trigger_change(
252
- data,
253
+ data.map(
254
+ (row, rowIdx) => row.map((cell, colIdx) => {
255
+ const dtype = Array.isArray(datatype) ? datatype[colIdx] : datatype;
256
+ return {
257
+ ...cell,
258
+ value: cast_value_to_type(cell.value, dtype)
259
+ };
260
+ })
261
+ ),
253
262
  _headers,
254
263
  previous_data,
255
264
  previous_headers,
@@ -13,3 +13,10 @@ export type DataframeValue = {
13
13
  headers: Headers;
14
14
  metadata: Metadata;
15
15
  };
16
+ /**
17
+ * Coerce a value to a given type.
18
+ * @param v - The value to coerce.
19
+ * @param t - The type to coerce to.
20
+ * @returns The coerced value.
21
+ */
22
+ export declare function cast_value_to_type(v: any, t: Datatype): string | number | boolean;
@@ -1 +1,29 @@
1
- export {};
1
+ /**
2
+ * Coerce a value to a given type.
3
+ * @param v - The value to coerce.
4
+ * @param t - The type to coerce to.
5
+ * @returns The coerced value.
6
+ */
7
+ export function cast_value_to_type(v, t) {
8
+ if (t === "number") {
9
+ const n = Number(v);
10
+ return isNaN(n) ? v : n;
11
+ }
12
+ if (t === "bool") {
13
+ if (typeof v === "boolean")
14
+ return v;
15
+ if (typeof v === "number")
16
+ return v !== 0;
17
+ const s = String(v).toLowerCase();
18
+ if (s === "true" || s === "1")
19
+ return true;
20
+ if (s === "false" || s === "0")
21
+ return false;
22
+ return v;
23
+ }
24
+ if (t === "date") {
25
+ const d = new Date(v);
26
+ return isNaN(d.getTime()) ? v : d.toISOString();
27
+ }
28
+ return v;
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/dataframe",
3
- "version": "0.18.3",
3
+ "version": "0.18.5",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -17,15 +17,15 @@
17
17
  "dompurify": "^3.0.3",
18
18
  "katex": "^0.16.7",
19
19
  "marked": "^12.0.0",
20
- "@gradio/button": "^0.5.7",
20
+ "@gradio/atoms": "^0.16.3",
21
21
  "@gradio/checkbox": "^0.4.26",
22
- "@gradio/icons": "^0.12.0",
22
+ "@gradio/button": "^0.5.9",
23
23
  "@gradio/markdown-code": "^0.5.0",
24
- "@gradio/statustracker": "^0.10.15",
25
- "@gradio/upload": "^0.16.11",
24
+ "@gradio/upload": "^0.16.13",
26
25
  "@gradio/utils": "^0.10.2",
27
- "@gradio/atoms": "^0.16.3",
28
- "@gradio/client": "^1.15.6"
26
+ "@gradio/statustracker": "^0.10.15",
27
+ "@gradio/client": "^1.16.0",
28
+ "@gradio/icons": "^0.12.0"
29
29
  },
30
30
  "exports": {
31
31
  ".": {
@@ -37,6 +37,7 @@
37
37
  handle_file_upload
38
38
  } from "./utils/table_utils";
39
39
  import { make_headers, process_data } from "./utils/data_processing";
40
+ import { cast_value_to_type } from "./utils";
40
41
  import { handle_keydown, handle_cell_blur } from "./utils/keyboard_utils";
41
42
  import {
42
43
  create_drag_handlers,
@@ -330,7 +331,15 @@
330
331
  $: {
331
332
  if (data || _headers) {
332
333
  df_actions.trigger_change(
333
- data,
334
+ data.map((row, rowIdx) =>
335
+ row.map((cell, colIdx) => {
336
+ const dtype = Array.isArray(datatype) ? datatype[colIdx] : datatype;
337
+ return {
338
+ ...cell,
339
+ value: cast_value_to_type(cell.value, dtype)
340
+ };
341
+ })
342
+ ),
334
343
  _headers,
335
344
  previous_data,
336
345
  previous_headers,
package/shared/utils.ts CHANGED
@@ -10,3 +10,32 @@ export type DataframeValue = {
10
10
  headers: Headers;
11
11
  metadata: Metadata;
12
12
  };
13
+
14
+ /**
15
+ * Coerce a value to a given type.
16
+ * @param v - The value to coerce.
17
+ * @param t - The type to coerce to.
18
+ * @returns The coerced value.
19
+ */
20
+ export function cast_value_to_type(
21
+ v: any,
22
+ t: Datatype
23
+ ): string | number | boolean {
24
+ if (t === "number") {
25
+ const n = Number(v);
26
+ return isNaN(n) ? v : n;
27
+ }
28
+ if (t === "bool") {
29
+ if (typeof v === "boolean") return v;
30
+ if (typeof v === "number") return v !== 0;
31
+ const s = String(v).toLowerCase();
32
+ if (s === "true" || s === "1") return true;
33
+ if (s === "false" || s === "0") return false;
34
+ return v;
35
+ }
36
+ if (t === "date") {
37
+ const d = new Date(v);
38
+ return isNaN(d.getTime()) ? v : d.toISOString();
39
+ }
40
+ return v;
41
+ }
@@ -1,6 +1,7 @@
1
1
  import { describe, test, expect } from "vitest";
2
2
  import { make_cell_id, make_header_id } from "../shared/utils/table_utils";
3
3
  import { process_data, make_headers } from "../shared/utils/data_processing";
4
+ import { cast_value_to_type } from "../shared/utils";
4
5
 
5
6
  function make_id(): string {
6
7
  return Math.random().toString(36).substring(2, 15);
@@ -133,3 +134,33 @@ describe("table_utils", () => {
133
134
  });
134
135
  });
135
136
  });
137
+
138
+ describe("cast_value_to_type", () => {
139
+ test("casts to number", () => {
140
+ expect(cast_value_to_type("42", "number")).toBe(42);
141
+ expect(cast_value_to_type(3.14, "number")).toBe(3.14);
142
+ expect(cast_value_to_type("not a number", "number")).toBe("not a number");
143
+ });
144
+ test("casts to bool", () => {
145
+ expect(cast_value_to_type("True", "bool")).toBe(true);
146
+ expect(cast_value_to_type("False", "bool")).toBe(false);
147
+ expect(cast_value_to_type(1, "bool")).toBe(true);
148
+ expect(cast_value_to_type(0, "bool")).toBe(false);
149
+ expect(cast_value_to_type("1", "bool")).toBe(true);
150
+ expect(cast_value_to_type("0", "bool")).toBe(false);
151
+ expect(cast_value_to_type("yes", "bool")).toBe("yes");
152
+ expect(cast_value_to_type("no", "bool")).toBe("no");
153
+ expect(cast_value_to_type("on", "bool")).toBe("on");
154
+ expect(cast_value_to_type("off", "bool")).toBe("off");
155
+ expect(cast_value_to_type("random", "bool")).toBe("random");
156
+ });
157
+ test("casts to date", () => {
158
+ const result = cast_value_to_type("2023-01-01", "date");
159
+ expect(result).toBe("2023-01-01T00:00:00.000Z");
160
+ expect(typeof cast_value_to_type("not a date", "date")).toBe("string");
161
+ });
162
+ test("returns value as-is for str", () => {
163
+ expect(cast_value_to_type("hello", "str")).toBe("hello");
164
+ expect(cast_value_to_type(123, "str")).toBe(123);
165
+ });
166
+ });