@gradio/dataframe 0.3.0-beta.5 → 0.3.0-beta.8

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,58 +1,80 @@
1
1
  # @gradio/dataframe
2
2
 
3
- ## 0.3.0-beta.5
3
+ ## 0.3.0-beta.8
4
4
 
5
5
  ### Features
6
6
 
7
- - [#5648](https://github.com/gradio-app/gradio/pull/5648) [`c573e2339`](https://github.com/gradio-app/gradio/commit/c573e2339b86c85b378dc349de5e9223a3c3b04a) - Publish all components to npm. Thanks [@freddyaboulton](https://github.com/freddyaboulton)!
7
+ - [#6136](https://github.com/gradio-app/gradio/pull/6136) [`667802a6c`](https://github.com/gradio-app/gradio/commit/667802a6cdbfb2ce454a3be5a78e0990b194548a) - JS Component Documentation. Thanks [@freddyaboulton](https://github.com/freddyaboulton)!
8
+ - [#6149](https://github.com/gradio-app/gradio/pull/6149) [`90318b1dd`](https://github.com/gradio-app/gradio/commit/90318b1dd118ae08a695a50e7c556226234ab6dc) - swap `mode` on the frontned to `interactive` to match the backend. Thanks [@pngwn](https://github.com/pngwn)!
8
9
 
9
- ## 0.3.0-beta.4
10
+ ## 0.3.0-beta.7
10
11
 
11
- ### Patch Changes
12
+ ### Features
12
13
 
13
- - Updated dependencies [[`0b4fd5b6d`](https://github.com/gradio-app/gradio/commit/0b4fd5b6db96fc95a155e5e935e17e1ab11d1161)]:
14
- - @gradio/utils@0.2.0-beta.3
15
- - @gradio/atoms@0.2.0-beta.3
16
- - @gradio/button@0.2.0-beta.3
17
- - @gradio/markdown@0.3.0-beta.4
18
- - @gradio/statustracker@0.3.0-beta.4
19
- - @gradio/upload@0.3.0-beta.3
14
+ - [#6016](https://github.com/gradio-app/gradio/pull/6016) [`83e947676`](https://github.com/gradio-app/gradio/commit/83e947676d327ca2ab6ae2a2d710c78961c771a0) - Format js in v4 branch. Thanks [@freddyaboulton](https://github.com/freddyaboulton)!
20
15
 
21
- ## 0.3.0-beta.3
16
+ ### Fixes
22
17
 
23
- ### Patch Changes
18
+ - [#6046](https://github.com/gradio-app/gradio/pull/6046) [`dbb7de5e0`](https://github.com/gradio-app/gradio/commit/dbb7de5e02c53fee05889d696d764d212cb96c74) - fix tests. Thanks [@pngwn](https://github.com/pngwn)!
19
+
20
+ ## 0.3.0-beta.6
21
+
22
+ ### Features
24
23
 
25
- - Updated dependencies [[`14fc612d8`](https://github.com/gradio-app/gradio/commit/14fc612d84bf6b1408eccd3a40fab41f25477571)]:
26
- - @gradio/utils@0.2.0-beta.2
27
- - @gradio/atoms@0.2.0-beta.2
28
- - @gradio/button@0.2.0-beta.2
29
- - @gradio/markdown@0.3.0-beta.3
30
- - @gradio/statustracker@0.3.0-beta.3
31
- - @gradio/upload@0.3.0-beta.2
24
+ - [#5960](https://github.com/gradio-app/gradio/pull/5960) [`319c30f3f`](https://github.com/gradio-app/gradio/commit/319c30f3fccf23bfe1da6c9b132a6a99d59652f7) - rererefactor frontend files. Thanks [@pngwn](https://github.com/pngwn)!
25
+ - [#5938](https://github.com/gradio-app/gradio/pull/5938) [`13ed8a485`](https://github.com/gradio-app/gradio/commit/13ed8a485d5e31d7d75af87fe8654b661edcca93) - V4: Use beta release versions for '@gradio' packages. Thanks [@freddyaboulton](https://github.com/freddyaboulton)!
26
+ - [#5894](https://github.com/gradio-app/gradio/pull/5894) [`fee3d527e`](https://github.com/gradio-app/gradio/commit/fee3d527e83a615109cf937f6ca0a37662af2bb6) - Adds `column_widths` to `gr.Dataframe` and hide overflowing text when `wrap=False`. Thanks [@abidlabs](https://github.com/abidlabs)!
32
27
 
33
- ## 0.3.0-beta.2
28
+ ## 0.4.0
34
29
 
35
30
  ### Features
36
31
 
37
- - [#5620](https://github.com/gradio-app/gradio/pull/5620) [`c4c25ecdf`](https://github.com/gradio-app/gradio/commit/c4c25ecdf8c2fab5e3c41b519564e3b6a9ebfce3) - fix build and broken imports. Thanks [@pngwn](https://github.com/pngwn)!
32
+ - [#5877](https://github.com/gradio-app/gradio/pull/5877) [`a55b80942`](https://github.com/gradio-app/gradio/commit/a55b8094231ae462ac53f52bbdb460c1286ffabb) - Add styling (e.g. font colors and background colors) support to `gr.DataFrame` through the `pd.Styler` object. Thanks [@abidlabs](https://github.com/abidlabs)!
38
33
 
39
- ## 0.3.0-beta.1
34
+ ### Fixes
35
+
36
+ - [#5930](https://github.com/gradio-app/gradio/pull/5930) [`361823896`](https://github.com/gradio-app/gradio/commit/3618238960d54df65c34895f4eb69d08acc3f9b6) - Fix dataframe `line_breaks`. Thanks [@dawoodkhan82](https://github.com/dawoodkhan82)!
37
+
38
+ ## 0.3.1
40
39
 
41
40
  ### Patch Changes
42
41
 
43
42
  - Updated dependencies []:
44
- - @gradio/utils@0.2.0-beta.1
45
- - @gradio/atoms@0.2.0-beta.1
46
- - @gradio/button@0.2.0-beta.1
47
- - @gradio/markdown@0.3.0-beta.1
48
- - @gradio/statustracker@0.3.0-beta.1
49
- - @gradio/upload@0.3.0-beta.1
43
+ - @gradio/utils@0.1.2
44
+ - @gradio/atoms@0.1.4
45
+ - @gradio/button@0.2.2
46
+ - @gradio/markdown@0.3.1
47
+ - @gradio/statustracker@0.2.2
48
+ - @gradio/upload@0.3.2
50
49
 
51
- ## 0.3.0-beta.0
50
+ ## 0.3.0
52
51
 
53
52
  ### Features
54
53
 
55
- - [#5507](https://github.com/gradio-app/gradio/pull/5507) [`1385dc688`](https://github.com/gradio-app/gradio/commit/1385dc6881f2d8ae7a41106ec21d33e2ef04d6a9) - Custom components. Thanks [@pngwn](https://github.com/pngwn)!
54
+ - [#5569](https://github.com/gradio-app/gradio/pull/5569) [`2a5b9e03b`](https://github.com/gradio-app/gradio/commit/2a5b9e03b15ea324d641fe6982f26d81b1ca7210) - Added support for pandas `Styler` object to `gr.DataFrame` (initially just sets the `display_value`). Thanks [@abidlabs](https://github.com/abidlabs)!
55
+
56
+ ### Fixes
57
+
58
+ - [#5755](https://github.com/gradio-app/gradio/pull/5755) [`e842a561a`](https://github.com/gradio-app/gradio/commit/e842a561af4394f8109291ee5725bcf74743e816) - Fix new line issue in chatbot. Thanks [@dawoodkhan82](https://github.com/dawoodkhan82)!
59
+
60
+ ## 0.2.5
61
+
62
+ ### Fixes
63
+
64
+ - [#5713](https://github.com/gradio-app/gradio/pull/5713) [`c10dabd6b`](https://github.com/gradio-app/gradio/commit/c10dabd6b18b49259441eb5f956a19046f466339) - Fixes gr.select() Method Issues with Dataframe Cells. Thanks [@dawoodkhan82](https://github.com/dawoodkhan82)!
65
+
66
+ ## 0.2.4
67
+
68
+ ### Patch Changes
69
+
70
+ - Updated dependencies [[`ee8eec1e5`](https://github.com/gradio-app/gradio/commit/ee8eec1e5e544a0127e0aa68c2522a7085b8ada5)]:
71
+ - @gradio/markdown@0.2.2
72
+
73
+ ## 0.2.3
74
+
75
+ ### Fixes
76
+
77
+ - [#5616](https://github.com/gradio-app/gradio/pull/5616) [`7c34b434a`](https://github.com/gradio-app/gradio/commit/7c34b434aae0eb85f112a1dc8d66cefc7e2296b2) - Fix width and height issues that would cut off content in `gr.DataFrame`. Thanks [@abidlabs](https://github.com/abidlabs)!
56
78
 
57
79
  ## 0.2.2
58
80
 
@@ -1,5 +1,6 @@
1
- <script>
1
+ <script lang="ts">
2
2
  import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
3
+ import { Gradio } from "../app/src/gradio_helper";
3
4
  import Table from "./shared/Table.svelte";
4
5
  </script>
5
6
 
@@ -17,18 +18,21 @@
17
18
  />
18
19
 
19
20
  <Template let:args>
20
- <Table {...args} />
21
+ <Table {...args} i18n={(s) => s} />
21
22
  </Template>
22
23
 
23
24
  <Story
24
25
  name="Interactive dataframe"
25
26
  args={{
26
- values: [
27
- ["Cat", 5],
28
- ["Horse", 3],
29
- ["Snake", 1]
30
- ],
31
- headers: ["Animal", "Votes"],
27
+ value: {
28
+ data: [
29
+ ["Cat", 5],
30
+ ["Horse", 3],
31
+ ["Snake", 1]
32
+ ],
33
+ headers: ["Animal", "Votes"],
34
+ metadata: null
35
+ },
32
36
  label: "Animals",
33
37
  col_count: [2, "dynamic"],
34
38
  row_count: [3, "dynamic"]
@@ -38,12 +42,15 @@
38
42
  <Story
39
43
  name="Static dataframe"
40
44
  args={{
41
- values: [
42
- ["Cat", 5],
43
- ["Horse", 3],
44
- ["Snake", 1]
45
- ],
46
- headers: ["Animal", "Votes"],
45
+ value: {
46
+ data: [
47
+ ["Cat", 5],
48
+ ["Horse", 3],
49
+ ["Snake", 1]
50
+ ],
51
+ headers: ["Animal", "Votes"],
52
+ metadata: null
53
+ },
47
54
  label: "Animals",
48
55
  col_count: [2, "dynamic"],
49
56
  row_count: [3, "dynamic"],
@@ -51,15 +58,41 @@
51
58
  }}
52
59
  />
53
60
 
61
+ <Story
62
+ name="Dataframe with different precisions"
63
+ args={{
64
+ value: {
65
+ data: [
66
+ [1.24, 1.24, 1.24],
67
+ [1.21, 1.21, 1.21]
68
+ ],
69
+ headers: ["Precision=0", "Precision=1", "Precision=2"],
70
+ metadata: {
71
+ display_value: [
72
+ ["1", "1.2", "1.24"],
73
+ ["1", "1.2", "1.21"]
74
+ ]
75
+ }
76
+ },
77
+ label: "Numbers",
78
+ col_count: [3, "dynamic"],
79
+ row_count: [2, "dynamic"],
80
+ editable: false
81
+ }}
82
+ />
83
+
54
84
  <Story
55
85
  name="Dataframe with markdown and math"
56
86
  args={{
57
- values: [
58
- ["Linear", "$y=x$", "Has a *maximum* of 1 root"],
59
- ["Quadratic", "$y=x^2$", "Has a *maximum* of 2 roots"],
60
- ["Cubic", "$y=x^3$", "Has a *maximum* of 3 roots"]
61
- ],
62
- headers: ["Type", "Example", "Roots"],
87
+ value: {
88
+ data: [
89
+ ["Linear", "$y=x$", "Has a *maximum* of 1 root"],
90
+ ["Quadratic", "$y=x^2$", "Has a *maximum* of 2 roots"],
91
+ ["Cubic", "$y=x^3$", "Has a *maximum* of 3 roots"]
92
+ ],
93
+ headers: ["Type", "Example", "Roots"],
94
+ metadata: null
95
+ },
63
96
  datatype: ["str", "markdown", "markdown"],
64
97
  latex_delimiters: [{ left: "$", right: "$", display: false }],
65
98
  label: "Math",
@@ -70,12 +103,46 @@
70
103
  />
71
104
 
72
105
  <Story
73
- name="Empty dataframe"
106
+ name="Dataframe with different colors"
74
107
  args={{
75
- values: [[]],
76
- headers: ["Animal", "Votes"],
77
- label: "Animals",
78
- col_count: [2, "dynamic"],
79
- row_count: [0, "dynamic"]
108
+ value: {
109
+ data: [
110
+ [800, 100, 800],
111
+ [200, 800, 700]
112
+ ],
113
+ headers: ["Math", "Reading", "Writing"],
114
+ metadata: {
115
+ styling: [
116
+ [
117
+ "background-color:teal; color: white",
118
+ "1.2",
119
+ "background-color:teal; color: white"
120
+ ],
121
+ ["1", "background-color:teal; color: white", "1.21"]
122
+ ]
123
+ }
124
+ },
125
+ label: "Test scores",
126
+ col_count: [3, "dynamic"],
127
+ row_count: [2, "dynamic"],
128
+ editable: false
129
+ }}
130
+ />
131
+
132
+ <Story
133
+ name="Dataframe with column widths"
134
+ args={{
135
+ value: {
136
+ data: [
137
+ [800, 100, 800],
138
+ [200, 800, 700]
139
+ ],
140
+ headers: ["Narrow", "Wide", "Half"]
141
+ },
142
+ label: "Test scores",
143
+ col_count: [3, "dynamic"],
144
+ row_count: [2, "dynamic"],
145
+ column_widths: ["20%", "30%", "50%"],
146
+ editable: false
80
147
  }}
81
148
  />
@@ -1,22 +1,24 @@
1
+ <script context="module" lang="ts">
2
+ export { default as BaseDataFrame } from "./shared/Table.svelte";
3
+ export { default as BaseExample } from "./Example.svelte";
4
+ </script>
5
+
1
6
  <script lang="ts">
2
7
  import { afterUpdate } from "svelte";
3
8
  import type { Gradio, SelectData } from "@gradio/utils";
4
9
  import { Block } from "@gradio/atoms";
5
- import Table from "../shared";
10
+ import Table from "./shared/Table.svelte";
6
11
  import { StatusTracker } from "@gradio/statustracker";
7
12
  import type { LoadingStatus } from "@gradio/statustracker";
8
-
9
- type Headers = string[];
10
- type Data = (string | number)[][];
11
- type Datatype = "str" | "markdown" | "html" | "number" | "bool" | "date";
12
-
13
+ import type { Headers, Data, Metadata, Datatype } from "./shared/utils";
13
14
  export let headers: Headers = [];
14
15
  export let elem_id = "";
15
16
  export let elem_classes: string[] = [];
16
17
  export let visible = true;
17
- export let value: { data: Data; headers: Headers } = {
18
+ export let value: { data: Data; headers: Headers; metadata: Metadata } = {
18
19
  data: [["", "", ""]],
19
- headers: ["1", "2", "3"]
20
+ headers: ["1", "2", "3"],
21
+ metadata: null
20
22
  };
21
23
  let old_value: string = JSON.stringify(value);
22
24
  export let value_is_output = false;
@@ -29,6 +31,8 @@
29
31
  export let min_width: number | undefined = undefined;
30
32
  export let root: string;
31
33
 
34
+ export let line_breaks = true;
35
+ export let column_widths: string[] = [];
32
36
  export let gradio: Gradio<{
33
37
  change: never;
34
38
  select: SelectData;
@@ -42,6 +46,7 @@
42
46
  export let height: number | undefined = undefined;
43
47
 
44
48
  export let loading_status: LoadingStatus;
49
+ export let interactive: boolean;
45
50
 
46
51
  function handle_change(): void {
47
52
  gradio.dispatch("change");
@@ -58,7 +63,6 @@
58
63
  handle_change();
59
64
  }
60
65
  }
61
-
62
66
  if (
63
67
  (Array.isArray(value) && value?.[0]?.length === 0) ||
64
68
  value.data?.[0]?.length === 0
@@ -67,7 +71,8 @@
67
71
  data: [Array(col_count?.[0] || 3).fill("")],
68
72
  headers: Array(col_count?.[0] || 3)
69
73
  .fill("")
70
- .map((_, i) => `${i + 1}`)
74
+ .map((_, i) => `${i + 1}`),
75
+ metadata: null
71
76
  };
72
77
  }
73
78
  </script>
@@ -92,17 +97,16 @@
92
97
  {label}
93
98
  {row_count}
94
99
  {col_count}
95
- values={value}
100
+ {value}
96
101
  {headers}
97
- on:change={({ detail }) => {
98
- value = detail;
99
- }}
100
102
  on:select={(e) => gradio.dispatch("select", e.detail)}
101
103
  {wrap}
102
104
  {datatype}
103
105
  {latex_delimiters}
104
- editable={false}
106
+ editable={interactive}
105
107
  {height}
106
108
  i18n={gradio.i18n}
109
+ {line_breaks}
110
+ {column_widths}
107
111
  />
108
112
  </Block>
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # `@gradio/dataframe`
2
+
3
+ ```html
4
+ <script>
5
+ import { BaseDataFrame, BaseExample } from "@gradio/dataframe";
6
+ </script>
7
+ ```
8
+
9
+ BaseDataFrame
10
+ ```javascript
11
+ export let datatype: Datatype | Datatype[];
12
+ export let label: string | null = null;
13
+ export let headers: Headers = [];
14
+ let values: (string | number)[][];
15
+ export let value: { data: Data; headers: Headers; metadata: Metadata } | null;
16
+ export let col_count: [number, "fixed" | "dynamic"];
17
+ export let row_count: [number, "fixed" | "dynamic"];
18
+ export let latex_delimiters: {
19
+ left: string;
20
+ right: string;
21
+ display: boolean;
22
+ }[];
23
+
24
+ export let editable = true;
25
+ export let wrap = false;
26
+ export let root: string;
27
+ export let i18n: I18nFormatter;
28
+
29
+ export let height = 500;
30
+ export let line_breaks = true;
31
+ export let column_widths: string[] = [];
32
+ ```
33
+
34
+ BaseExample
35
+ ```javascript
36
+ export let gradio: Gradio;
37
+ export let value: (string | number)[][] | string;
38
+ export let samples_dir: string;
39
+ export let type: "gallery" | "table";
40
+ export let selected = false;
41
+ export let index: number;
42
+ ```
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@gradio/dataframe",
3
- "version": "0.3.0-beta.5",
3
+ "version": "0.3.0-beta.8",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
- "main": "./index.svelte",
7
6
  "author": "",
8
7
  "license": "ISC",
9
8
  "private": false,
10
9
  "main_changeset": true,
10
+ "main": "./Index.svelte",
11
11
  "dependencies": {
12
12
  "@types/d3-dsv": "^3.0.0",
13
13
  "@types/dompurify": "^3.0.2",
@@ -17,17 +17,16 @@
17
17
  "dompurify": "^3.0.3",
18
18
  "katex": "^0.16.7",
19
19
  "marked": "^7.0.0",
20
- "@gradio/atoms": "^0.2.0-beta.3",
21
- "@gradio/button": "^0.2.0-beta.4",
22
- "@gradio/markdown": "^0.3.0-beta.5",
23
- "@gradio/statustracker": "^0.3.0-beta.5",
24
- "@gradio/upload": "^0.3.0-beta.3",
25
- "@gradio/utils": "^0.2.0-beta.3"
20
+ "@gradio/atoms": "^0.2.0-beta.6",
21
+ "@gradio/button": "^0.2.0-beta.7",
22
+ "@gradio/markdown": "^0.3.0-beta.8",
23
+ "@gradio/statustracker": "^0.3.0-beta.8",
24
+ "@gradio/upload": "^0.3.0-beta.6",
25
+ "@gradio/utils": "^0.2.0-beta.6"
26
26
  },
27
27
  "exports": {
28
- "./package.json": "./package.json",
29
- "./interactive": "./interactive/index.ts",
30
- "./static": "./static/index.ts",
31
- "./example": "./example/index.ts"
28
+ ".": "./Index.svelte",
29
+ "./example": "./Example.svelte",
30
+ "./package.json": "./package.json"
32
31
  }
33
32
  }
@@ -1,10 +1,11 @@
1
1
  <script lang="ts">
2
2
  import { createEventDispatcher } from "svelte";
3
- import type { ActionReturn } from "svelte/action";
4
3
  import { MarkdownCode } from "@gradio/markdown";
5
4
 
6
5
  export let edit: boolean;
7
6
  export let value: string | number = "";
7
+ export let display_value: string | null = null;
8
+ export let styling = "";
8
9
  export let header = false;
9
10
  export let datatype:
10
11
  | "str"
@@ -20,13 +21,15 @@
20
21
  }[];
21
22
  export let clear_on_focus = false;
22
23
  export let select_on_focus = false;
24
+ export let line_breaks = true;
25
+ export let editable = true;
23
26
 
24
27
  const dispatch = createEventDispatcher();
25
28
 
26
29
  export let el: HTMLInputElement | null;
27
30
  $: _value = value;
28
31
 
29
- function use_focus(node: HTMLInputElement): ActionReturn {
32
+ function use_focus(node: HTMLInputElement): any {
30
33
  if (clear_on_focus) {
31
34
  _value = "";
32
35
  }
@@ -38,6 +41,15 @@
38
41
 
39
42
  return {};
40
43
  }
44
+
45
+ function handle_blur({
46
+ currentTarget
47
+ }: {
48
+ currentTarget: HTMLInputElement;
49
+ }): void {
50
+ value = currentTarget.value;
51
+ dispatch("blur");
52
+ }
41
53
  </script>
42
54
 
43
55
  {#if edit}
@@ -46,10 +58,7 @@
46
58
  bind:value={_value}
47
59
  class:header
48
60
  tabindex="-1"
49
- on:blur={({ currentTarget }) => {
50
- value = currentTarget.value;
51
- dispatch("blur");
52
- }}
61
+ on:blur={handle_blur}
53
62
  use:use_focus
54
63
  on:keydown
55
64
  />
@@ -61,6 +70,7 @@
61
70
  role="button"
62
71
  class:edit
63
72
  on:focus|preventDefault
73
+ style={styling}
64
74
  >
65
75
  {#if datatype === "html"}
66
76
  {@html value}
@@ -68,10 +78,11 @@
68
78
  <MarkdownCode
69
79
  message={value.toLocaleString()}
70
80
  {latex_delimiters}
81
+ {line_breaks}
71
82
  chatbot={false}
72
83
  />
73
84
  {:else}
74
- {value}
85
+ {editable ? value : display_value || value}
75
86
  {/if}
76
87
  </span>
77
88
 
@@ -4,20 +4,24 @@
4
4
  import { dequal } from "dequal/lite";
5
5
  import { copy } from "@gradio/utils";
6
6
  import { Upload } from "@gradio/upload";
7
- import { BaseButton } from "@gradio/button/static";
7
+ import { BaseButton } from "@gradio/button";
8
8
  import EditableCell from "./EditableCell.svelte";
9
9
  import type { SelectData } from "@gradio/utils";
10
10
  import type { I18nFormatter } from "js/app/src/gradio_helper";
11
11
  import VirtualTable from "./VirtualTable.svelte";
12
-
13
- type Datatype = "str" | "markdown" | "html" | "number" | "bool" | "date";
12
+ import type {
13
+ Headers,
14
+ HeadersWithIDs,
15
+ Data,
16
+ Metadata,
17
+ Datatype
18
+ } from "./utils";
14
19
 
15
20
  export let datatype: Datatype | Datatype[];
16
21
  export let label: string | null = null;
17
- export let headers: string[] = [];
18
- export let values:
19
- | (string | number)[][]
20
- | { data: (string | number)[][]; headers: string[] } = [[]];
22
+ export let headers: Headers = [];
23
+ let values: (string | number)[][];
24
+ export let value: { data: Data; headers: Headers; metadata: Metadata } | null;
21
25
  export let col_count: [number, "fixed" | "dynamic"];
22
26
  export let row_count: [number, "fixed" | "dynamic"];
23
27
  export let latex_delimiters: {
@@ -29,22 +33,33 @@
29
33
  export let editable = true;
30
34
  export let wrap = false;
31
35
  export let root: string;
32
- export let height: number | undefined = undefined;
33
36
  export let i18n: I18nFormatter;
34
37
 
38
+ export let height = 500;
39
+ export let line_breaks = true;
40
+ export let column_widths: string[] = [];
41
+
35
42
  let selected: false | [number, number] = false;
43
+ let display_value: string[][] | null = value?.metadata?.display_value ?? null;
44
+ let styling: string[][] | null = value?.metadata?.styling ?? null;
36
45
 
37
46
  $: {
38
- if (values && !Array.isArray(values)) {
39
- headers = values.headers;
40
- values = values.data;
47
+ if (value) {
48
+ headers = value.headers;
49
+ values = value.data;
50
+ display_value = value?.metadata?.display_value ?? null;
51
+ styling = value?.metadata?.styling ?? null;
41
52
  } else if (values === null) {
42
53
  values = [];
43
54
  }
44
55
  }
45
56
 
46
57
  const dispatch = createEventDispatcher<{
47
- change: { data: (string | number)[][]; headers: string[] };
58
+ change: {
59
+ data: (string | number)[][];
60
+ headers: string[];
61
+ metadata: Metadata;
62
+ };
48
63
  select: SelectData;
49
64
  }>();
50
65
 
@@ -67,12 +82,10 @@
67
82
 
68
83
  let data_binding: Record<string, (typeof data)[0][0]> = {};
69
84
 
70
- type Headers = { value: string; id: string }[];
71
-
72
85
  function make_id(): string {
73
86
  return Math.random().toString(36).substring(2, 15);
74
87
  }
75
- function make_headers(_head: string[]): Headers {
88
+ function make_headers(_head: Headers): HeadersWithIDs {
76
89
  let _h = _head || [];
77
90
  if (col_count[1] === "fixed" && _h.length < col_count[0]) {
78
91
  const fill = Array(col_count[0] - _h.length)
@@ -155,7 +168,10 @@
155
168
  $: _headers &&
156
169
  dispatch("change", {
157
170
  data: data.map((r) => r.map(({ value }) => value)),
158
- headers: _headers.map((h) => h.value)
171
+ headers: _headers.map((h) => h.value),
172
+ metadata: editable
173
+ ? null
174
+ : { display_value: display_value, styling: styling }
159
175
  });
160
176
 
161
177
  function get_sort_status(
@@ -328,7 +344,6 @@
328
344
 
329
345
  async function handle_cell_click(i: number, j: number): Promise<void> {
330
346
  if (dequal(editing, [i, j])) return;
331
- if (dequal(selected, [i, j])) return;
332
347
  header_edit = false;
333
348
  selected_header = false;
334
349
  editing = false;
@@ -529,35 +544,65 @@
529
544
  $: cells[0] && set_cell_widths();
530
545
  let cells: HTMLTableCellElement[] = [];
531
546
  let parent: HTMLDivElement;
547
+ let table: HTMLTableElement;
532
548
 
533
549
  function set_cell_widths(): void {
534
550
  const widths = cells.map((el, i) => {
535
551
  return el?.clientWidth || 0;
536
552
  });
537
-
538
553
  if (widths.length === 0) return;
539
554
  for (let i = 0; i < widths.length; i++) {
540
- parent.style.setProperty(`--cell-width-${i}`, `${widths[i]}px`);
555
+ parent.style.setProperty(
556
+ `--cell-width-${i}`,
557
+ `${widths[i] - scrollbar_width / widths.length}px`
558
+ );
541
559
  }
542
560
  }
543
561
 
544
- let table_height: number = height || 500;
562
+ let table_height: number = height;
563
+ let scrollbar_width = 0;
545
564
 
546
565
  function sort_data(
547
566
  _data: typeof data,
567
+ _display_value: string[][] | null,
568
+ _styling: string[][] | null,
548
569
  col?: number,
549
570
  dir?: SortDirection
550
571
  ): void {
551
- const id = selected ? data[selected[0]][selected[1]]?.id : null;
572
+ let id = null;
573
+ //Checks if the selected cell is still in the data
574
+ if (selected && selected[0] in data && selected[1] in data[selected[0]]) {
575
+ id = data[selected[0]][selected[1]].id;
576
+ }
552
577
  if (typeof col !== "number" || !dir) {
553
578
  return;
554
579
  }
580
+ const indices = [...Array(_data.length).keys()];
581
+
555
582
  if (dir === "asc") {
556
- _data.sort((a, b) => (a[col].value < b[col].value ? -1 : 1));
583
+ indices.sort((i, j) =>
584
+ _data[i][col].value < _data[j][col].value ? -1 : 1
585
+ );
557
586
  } else if (dir === "des") {
558
- _data.sort((a, b) => (a[col].value > b[col].value ? -1 : 1));
587
+ indices.sort((i, j) =>
588
+ _data[i][col].value > _data[j][col].value ? -1 : 1
589
+ );
590
+ } else {
591
+ return;
559
592
  }
560
593
 
594
+ // sort all the data and metadata based on the values in the data
595
+ const temp_data = [..._data];
596
+ const temp_display_value = _display_value ? [..._display_value] : null;
597
+ const temp_styling = _styling ? [..._styling] : null;
598
+ indices.forEach((originalIndex, sortedIndex) => {
599
+ _data[sortedIndex] = temp_data[originalIndex];
600
+ if (_display_value && temp_display_value)
601
+ _display_value[sortedIndex] = temp_display_value[originalIndex];
602
+ if (_styling && temp_styling)
603
+ _styling[sortedIndex] = temp_styling[originalIndex];
604
+ });
605
+
561
606
  data = data;
562
607
 
563
608
  if (id) {
@@ -566,7 +611,7 @@
566
611
  }
567
612
  }
568
613
 
569
- $: sort_data(data, sort_by, sort_direction);
614
+ $: sort_data(data, display_value, styling, sort_by, sort_direction);
570
615
 
571
616
  $: selected_index = !!selected && selected[0];
572
617
 
@@ -613,7 +658,11 @@
613
658
  role="grid"
614
659
  tabindex="0"
615
660
  >
616
- <table bind:clientWidth={t_width}>
661
+ <table
662
+ bind:clientWidth={t_width}
663
+ bind:this={table}
664
+ class:fixed-layout={column_widths.length != 0}
665
+ >
617
666
  {#if label && label.length !== 0}
618
667
  <caption class="sr-only">{label}</caption>
619
668
  {/if}
@@ -623,11 +672,13 @@
623
672
  <th
624
673
  class:editing={header_edit === i}
625
674
  aria-sort={get_sort_status(value, sort_by, sort_direction)}
675
+ style:width={column_widths.length ? column_widths[i] : undefined}
626
676
  >
627
677
  <div class="cell-wrap">
628
678
  <EditableCell
629
679
  {value}
630
680
  {latex_delimiters}
681
+ {line_breaks}
631
682
  header
632
683
  edit={false}
633
684
  el={null}
@@ -661,6 +712,7 @@
661
712
  <EditableCell
662
713
  {value}
663
714
  {latex_delimiters}
715
+ {line_breaks}
664
716
  datatype={Array.isArray(datatype) ? datatype[j] : datatype}
665
717
  edit={false}
666
718
  el={null}
@@ -683,8 +735,9 @@
683
735
  <VirtualTable
684
736
  bind:items={data}
685
737
  table_width={t_width}
686
- max_height={height || 500}
738
+ max_height={height}
687
739
  bind:actual_height={table_height}
740
+ bind:table_scrollbar_width={scrollbar_width}
688
741
  selected={selected_index}
689
742
  >
690
743
  {#if label && label.length !== 0}
@@ -702,6 +755,7 @@
702
755
  bind:value={_headers[i].value}
703
756
  bind:el={els[id].input}
704
757
  {latex_delimiters}
758
+ {line_breaks}
705
759
  edit={header_edit === i}
706
760
  on:keydown={end_header_edit}
707
761
  on:dblclick={() => edit_header(i)}
@@ -740,14 +794,18 @@
740
794
  on:touchstart={() => start_edit(index, j)}
741
795
  on:click={() => handle_cell_click(index, j)}
742
796
  on:dblclick={() => start_edit(index, j)}
743
- style="width: var(--cell-width-{j});"
797
+ style:width="var(--cell-width-{j})"
798
+ style={styling?.[index]?.[j] || ""}
744
799
  class:focus={dequal(selected, [index, j])}
745
800
  >
746
801
  <div class="cell-wrap">
747
802
  <EditableCell
748
803
  bind:value={data[index][j].value}
749
804
  bind:el={els[id].input}
805
+ display_value={display_value?.[index]?.[j]}
750
806
  {latex_delimiters}
807
+ {line_breaks}
808
+ {editable}
751
809
  edit={dequal(editing, [index, j])}
752
810
  datatype={Array.isArray(datatype) ? datatype[j] : datatype}
753
811
  on:blur={() => ((clear_on_focus = false), parent.focus())}
@@ -870,6 +928,18 @@
870
928
  border-spacing: 0;
871
929
  }
872
930
 
931
+ div:not(.no-wrap) td {
932
+ overflow-wrap: anywhere;
933
+ }
934
+
935
+ div.no-wrap td {
936
+ overflow-x: hidden;
937
+ }
938
+
939
+ table.fixed-layout {
940
+ table-layout: fixed;
941
+ }
942
+
873
943
  thead {
874
944
  position: sticky;
875
945
  top: 0;
@@ -7,6 +7,7 @@
7
7
  export let table_width: number;
8
8
  export let max_height: number;
9
9
  export let actual_height: number;
10
+ export let table_scrollbar_width: number;
10
11
  export let start = 0;
11
12
  export let end = 0;
12
13
  export let selected: number | false;
@@ -33,6 +34,7 @@
33
34
  return;
34
35
  }
35
36
  const { scrollTop } = viewport;
37
+ table_scrollbar_width = viewport.offsetWidth - viewport.clientWidth;
36
38
 
37
39
  content_height = top - (scrollTop - head_height);
38
40
  let i = start;
@@ -56,6 +58,11 @@
56
58
  end = i;
57
59
  const remaining = _items.length - end;
58
60
 
61
+ const scrollbar_height = viewport.offsetHeight - viewport.clientHeight;
62
+ if (scrollbar_height > 0) {
63
+ content_height += scrollbar_height;
64
+ }
65
+
59
66
  let filtered_height_map = height_map.filter((v) => typeof v === "number");
60
67
  average_height =
61
68
  filtered_height_map.reduce((a, b) => a + b, 0) /
@@ -63,7 +70,6 @@
63
70
 
64
71
  bottom = remaining * average_height;
65
72
  height_map.length = _items.length;
66
-
67
73
  await tick();
68
74
  if (!max_height) {
69
75
  actual_height = content_height + 1;
@@ -206,6 +212,12 @@
206
212
  if (align_end) {
207
213
  distance = distance - viewport_height + _itemHeight + head_height;
208
214
  }
215
+
216
+ const scrollbar_height = viewport.offsetHeight - viewport.clientHeight;
217
+ if (scrollbar_height > 0) {
218
+ distance += scrollbar_height;
219
+ }
220
+
209
221
  const _opts = {
210
222
  top: distance,
211
223
  behavior: "smooth" as ScrollBehavior,
@@ -0,0 +1,7 @@
1
+ export type Headers = string[];
2
+ export type Data = (string | number)[][];
3
+ export type Datatype = "str" | "markdown" | "html" | "number" | "bool" | "date";
4
+ export type Metadata = {
5
+ [key: string]: string[][] | null;
6
+ } | null;
7
+ export type HeadersWithIDs = { value: string; id: string }[];
package/example/index.ts DELETED
@@ -1 +0,0 @@
1
- export { default } from "./Dataframe.svelte";
@@ -1,110 +0,0 @@
1
- <script lang="ts">
2
- import type { Gradio, SelectData } from "@gradio/utils";
3
- import { Block } from "@gradio/atoms";
4
- import Table from "../shared";
5
- import { StatusTracker } from "@gradio/statustracker";
6
- import type { LoadingStatus } from "@gradio/statustracker";
7
- import { afterUpdate } from "svelte";
8
- import { _ } from "svelte-i18n";
9
-
10
- type Headers = string[];
11
- type Data = (string | number)[][];
12
- type Datatype = "str" | "markdown" | "html" | "number" | "bool" | "date";
13
-
14
- export let headers: Headers = [];
15
- export let elem_id = "";
16
- export let elem_classes: string[] = [];
17
- export let visible = true;
18
- export let value: { data: Data; headers: Headers } = {
19
- data: [["", "", ""]],
20
- headers: ["1", "2", "3"]
21
- };
22
- export let latex_delimiters: {
23
- left: string;
24
- right: string;
25
- display: boolean;
26
- }[];
27
- export let height: number | undefined = undefined;
28
-
29
- let old_value: string = JSON.stringify(value);
30
- export let value_is_output = false;
31
- export let col_count: [number, "fixed" | "dynamic"];
32
- export let row_count: [number, "fixed" | "dynamic"];
33
- export let label: string | null = null;
34
- export let wrap: boolean;
35
- export let datatype: Datatype | Datatype[];
36
- export let scale: number | null = null;
37
- export let min_width: number | undefined = undefined;
38
- export let root: string;
39
-
40
- export let gradio: Gradio<{
41
- change: never;
42
- select: SelectData;
43
- input: never;
44
- }>;
45
-
46
- export let loading_status: LoadingStatus;
47
-
48
- function handle_change(): void {
49
- gradio.dispatch("change");
50
- if (!value_is_output) {
51
- gradio.dispatch("input");
52
- }
53
- }
54
- afterUpdate(() => {
55
- value_is_output = false;
56
- });
57
- $: {
58
- if (JSON.stringify(value) !== old_value) {
59
- old_value = JSON.stringify(value);
60
- handle_change();
61
- }
62
- }
63
-
64
- if (
65
- (Array.isArray(value) && value?.[0]?.length === 0) ||
66
- value.data?.[0]?.length === 0
67
- ) {
68
- value = {
69
- data: [Array(col_count?.[0] || 3).fill("")],
70
- headers: Array(col_count?.[0] || 3)
71
- .fill("")
72
- .map((_, i) => `${i + 1}`)
73
- };
74
- }
75
- </script>
76
-
77
- <Block
78
- {visible}
79
- padding={false}
80
- {elem_id}
81
- {elem_classes}
82
- container={false}
83
- {scale}
84
- {min_width}
85
- allow_overflow={false}
86
- >
87
- <StatusTracker
88
- autoscroll={gradio.autoscroll}
89
- {...loading_status}
90
- i18n={gradio.i18n}
91
- />
92
- <Table
93
- {label}
94
- {row_count}
95
- {col_count}
96
- {root}
97
- values={value}
98
- {headers}
99
- on:change={({ detail }) => {
100
- value = detail;
101
- }}
102
- on:select={(e) => gradio.dispatch("select", e.detail)}
103
- editable
104
- {wrap}
105
- {datatype}
106
- {latex_delimiters}
107
- {height}
108
- i18n={gradio.i18n}
109
- />
110
- </Block>
@@ -1 +0,0 @@
1
- export { default } from "./InteractiveDataframe.svelte";
package/shared/index.ts DELETED
@@ -1 +0,0 @@
1
- export { default } from "./Table.svelte";
package/static/index.ts DELETED
@@ -1 +0,0 @@
1
- export { default } from "./StaticDataframe.svelte";
File without changes