@gradio/dataframe 0.9.2 → 0.10.1-beta.1
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 +50 -0
- package/Dataframe.stories.svelte +0 -1
- package/Index.svelte +4 -1
- package/dist/Example.svelte +104 -0
- package/dist/Example.svelte.d.ts +19 -0
- package/dist/Index.svelte +117 -0
- package/dist/Index.svelte.d.ts +54 -0
- package/dist/shared/EditableCell.svelte +106 -0
- package/dist/shared/EditableCell.svelte.d.ts +37 -0
- package/dist/shared/Example.svelte +28 -0
- package/dist/shared/Example.svelte.d.ts +16 -0
- package/dist/shared/Table.svelte +915 -0
- package/dist/shared/Table.svelte.d.ts +49 -0
- package/dist/shared/VirtualTable.svelte +294 -0
- package/dist/shared/VirtualTable.svelte.d.ts +31 -0
- package/dist/shared/utils.d.ts +10 -0
- package/dist/shared/utils.js +1 -0
- package/package.json +27 -11
- package/shared/EditableCell.svelte +2 -0
- package/shared/Table.svelte +12 -3
- package/shared/VirtualTable.svelte +23 -10
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { SelectData } from "@gradio/utils";
|
|
3
|
+
import type { I18nFormatter } from "js/core/src/gradio_helper";
|
|
4
|
+
import { type Client } from "@gradio/client";
|
|
5
|
+
import type { Headers, Metadata, Datatype } from "./utils";
|
|
6
|
+
declare const __propDef: {
|
|
7
|
+
props: {
|
|
8
|
+
datatype: Datatype | Datatype[];
|
|
9
|
+
label?: (string | null) | undefined;
|
|
10
|
+
show_label?: boolean | undefined;
|
|
11
|
+
headers?: Headers | undefined;
|
|
12
|
+
values?: (string | number)[][] | undefined;
|
|
13
|
+
col_count: [number, "fixed" | "dynamic"];
|
|
14
|
+
row_count: [number, "fixed" | "dynamic"];
|
|
15
|
+
latex_delimiters: {
|
|
16
|
+
left: string;
|
|
17
|
+
right: string;
|
|
18
|
+
display: boolean;
|
|
19
|
+
}[];
|
|
20
|
+
editable?: boolean | undefined;
|
|
21
|
+
wrap?: boolean | undefined;
|
|
22
|
+
root: string;
|
|
23
|
+
i18n: I18nFormatter;
|
|
24
|
+
height?: number | undefined;
|
|
25
|
+
line_breaks?: boolean | undefined;
|
|
26
|
+
column_widths?: string[] | undefined;
|
|
27
|
+
upload: Client["upload"];
|
|
28
|
+
stream_handler: Client["stream"];
|
|
29
|
+
display_value?: (string[][] | null) | undefined;
|
|
30
|
+
styling?: (string[][] | null) | undefined;
|
|
31
|
+
};
|
|
32
|
+
events: {
|
|
33
|
+
change: CustomEvent<{
|
|
34
|
+
data: (string | number)[][];
|
|
35
|
+
headers: string[];
|
|
36
|
+
metadata: Metadata;
|
|
37
|
+
}>;
|
|
38
|
+
select: CustomEvent<SelectData>;
|
|
39
|
+
} & {
|
|
40
|
+
[evt: string]: CustomEvent<any>;
|
|
41
|
+
};
|
|
42
|
+
slots: {};
|
|
43
|
+
};
|
|
44
|
+
export type TableProps = typeof __propDef.props;
|
|
45
|
+
export type TableEvents = typeof __propDef.events;
|
|
46
|
+
export type TableSlots = typeof __propDef.slots;
|
|
47
|
+
export default class Table extends SvelteComponent<TableProps, TableEvents, TableSlots> {
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
<script>import { onMount, tick } from "svelte";
|
|
2
|
+
import { _ } from "svelte-i18n";
|
|
3
|
+
export let items = [];
|
|
4
|
+
export let max_height;
|
|
5
|
+
export let actual_height;
|
|
6
|
+
export let table_scrollbar_width;
|
|
7
|
+
export let start = 0;
|
|
8
|
+
export let end = 20;
|
|
9
|
+
export let selected;
|
|
10
|
+
let height = "100%";
|
|
11
|
+
let average_height = 30;
|
|
12
|
+
let bottom = 0;
|
|
13
|
+
let contents;
|
|
14
|
+
let head_height = 0;
|
|
15
|
+
let foot_height = 0;
|
|
16
|
+
let height_map = [];
|
|
17
|
+
let mounted;
|
|
18
|
+
let rows;
|
|
19
|
+
let top = 0;
|
|
20
|
+
let viewport;
|
|
21
|
+
let viewport_height = 200;
|
|
22
|
+
let visible = [];
|
|
23
|
+
let viewport_box;
|
|
24
|
+
$:
|
|
25
|
+
viewport_height = viewport_box?.height || 200;
|
|
26
|
+
const is_browser = typeof window !== "undefined";
|
|
27
|
+
const raf = is_browser ? window.requestAnimationFrame : (cb) => cb();
|
|
28
|
+
$:
|
|
29
|
+
mounted && raf(() => refresh_height_map(sortedItems));
|
|
30
|
+
let content_height = 0;
|
|
31
|
+
async function refresh_height_map(_items) {
|
|
32
|
+
if (viewport_height === 0) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const { scrollTop } = viewport;
|
|
36
|
+
table_scrollbar_width = viewport.offsetWidth - viewport.clientWidth;
|
|
37
|
+
content_height = top - (scrollTop - head_height);
|
|
38
|
+
let i = start;
|
|
39
|
+
while (content_height < max_height && i < _items.length) {
|
|
40
|
+
let row = rows[i - start];
|
|
41
|
+
if (!row) {
|
|
42
|
+
end = i + 1;
|
|
43
|
+
await tick();
|
|
44
|
+
row = rows[i - start];
|
|
45
|
+
}
|
|
46
|
+
let _h = row?.getBoundingClientRect().height;
|
|
47
|
+
if (!_h) {
|
|
48
|
+
_h = average_height;
|
|
49
|
+
}
|
|
50
|
+
const row_height = height_map[i] = _h;
|
|
51
|
+
content_height += row_height;
|
|
52
|
+
i += 1;
|
|
53
|
+
}
|
|
54
|
+
end = i;
|
|
55
|
+
const remaining = _items.length - end;
|
|
56
|
+
const scrollbar_height = viewport.offsetHeight - viewport.clientHeight;
|
|
57
|
+
if (scrollbar_height > 0) {
|
|
58
|
+
content_height += scrollbar_height;
|
|
59
|
+
}
|
|
60
|
+
let filtered_height_map = height_map.filter((v) => typeof v === "number");
|
|
61
|
+
average_height = filtered_height_map.reduce((a, b) => a + b, 0) / filtered_height_map.length;
|
|
62
|
+
bottom = remaining * average_height;
|
|
63
|
+
height_map.length = _items.length;
|
|
64
|
+
await tick();
|
|
65
|
+
if (!max_height) {
|
|
66
|
+
actual_height = content_height + 1;
|
|
67
|
+
} else if (content_height < max_height) {
|
|
68
|
+
actual_height = content_height + 2;
|
|
69
|
+
} else {
|
|
70
|
+
actual_height = max_height;
|
|
71
|
+
}
|
|
72
|
+
await tick();
|
|
73
|
+
}
|
|
74
|
+
$:
|
|
75
|
+
scroll_and_render(selected);
|
|
76
|
+
async function scroll_and_render(n) {
|
|
77
|
+
raf(async () => {
|
|
78
|
+
if (typeof n !== "number")
|
|
79
|
+
return;
|
|
80
|
+
const direction = typeof n !== "number" ? false : is_in_view(n);
|
|
81
|
+
if (direction === true) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (direction === "back") {
|
|
85
|
+
await scroll_to_index(n, { behavior: "instant" });
|
|
86
|
+
}
|
|
87
|
+
if (direction === "forwards") {
|
|
88
|
+
await scroll_to_index(n, { behavior: "instant" }, true);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function is_in_view(n) {
|
|
93
|
+
const current = rows && rows[n - start];
|
|
94
|
+
if (!current && n < start) {
|
|
95
|
+
return "back";
|
|
96
|
+
}
|
|
97
|
+
if (!current && n >= end - 1) {
|
|
98
|
+
return "forwards";
|
|
99
|
+
}
|
|
100
|
+
const { top: viewport_top } = viewport.getBoundingClientRect();
|
|
101
|
+
const { top: top2, bottom: bottom2 } = current.getBoundingClientRect();
|
|
102
|
+
if (top2 - viewport_top < 37) {
|
|
103
|
+
return "back";
|
|
104
|
+
}
|
|
105
|
+
if (bottom2 - viewport_top > viewport_height) {
|
|
106
|
+
return "forwards";
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
function get_computed_px_amount(elem, property) {
|
|
111
|
+
if (!elem) {
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
const compStyle = getComputedStyle(elem);
|
|
115
|
+
let x = parseInt(compStyle.getPropertyValue(property));
|
|
116
|
+
return x;
|
|
117
|
+
}
|
|
118
|
+
async function handle_scroll(e) {
|
|
119
|
+
const scroll_top = viewport.scrollTop;
|
|
120
|
+
rows = contents.children;
|
|
121
|
+
const is_start_overflow = sortedItems.length < start;
|
|
122
|
+
const row_top_border = get_computed_px_amount(rows[1], "border-top-width");
|
|
123
|
+
const actual_border_collapsed_width = 0;
|
|
124
|
+
if (is_start_overflow) {
|
|
125
|
+
await scroll_to_index(sortedItems.length - 1, { behavior: "auto" });
|
|
126
|
+
}
|
|
127
|
+
let new_start = 0;
|
|
128
|
+
for (let v = 0; v < rows.length; v += 1) {
|
|
129
|
+
height_map[start + v] = rows[v].getBoundingClientRect().height;
|
|
130
|
+
}
|
|
131
|
+
let i = 0;
|
|
132
|
+
let y = head_height + row_top_border / 2;
|
|
133
|
+
let row_heights = [];
|
|
134
|
+
while (i < sortedItems.length) {
|
|
135
|
+
const row_height = height_map[i] || average_height;
|
|
136
|
+
row_heights[i] = row_height;
|
|
137
|
+
if (y + row_height + actual_border_collapsed_width > scroll_top) {
|
|
138
|
+
new_start = i;
|
|
139
|
+
top = y - (head_height + row_top_border / 2);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
y += row_height;
|
|
143
|
+
i += 1;
|
|
144
|
+
}
|
|
145
|
+
new_start = Math.max(0, new_start);
|
|
146
|
+
while (i < sortedItems.length) {
|
|
147
|
+
const row_height = height_map[i] || average_height;
|
|
148
|
+
y += row_height;
|
|
149
|
+
i += 1;
|
|
150
|
+
if (y > scroll_top + viewport_height) {
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
start = new_start;
|
|
155
|
+
end = i;
|
|
156
|
+
const remaining = sortedItems.length - end;
|
|
157
|
+
if (end === 0) {
|
|
158
|
+
end = 10;
|
|
159
|
+
}
|
|
160
|
+
average_height = (y - head_height) / end;
|
|
161
|
+
let remaining_height = remaining * average_height;
|
|
162
|
+
while (i < sortedItems.length) {
|
|
163
|
+
i += 1;
|
|
164
|
+
height_map[i] = average_height;
|
|
165
|
+
}
|
|
166
|
+
bottom = remaining_height;
|
|
167
|
+
if (!isFinite(bottom)) {
|
|
168
|
+
bottom = 2e5;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
export async function scroll_to_index(index, opts, align_end = false) {
|
|
172
|
+
await tick();
|
|
173
|
+
const _itemHeight = average_height;
|
|
174
|
+
let distance = index * _itemHeight;
|
|
175
|
+
if (align_end) {
|
|
176
|
+
distance = distance - viewport_height + _itemHeight + head_height;
|
|
177
|
+
}
|
|
178
|
+
const scrollbar_height = viewport.offsetHeight - viewport.clientHeight;
|
|
179
|
+
if (scrollbar_height > 0) {
|
|
180
|
+
distance += scrollbar_height;
|
|
181
|
+
}
|
|
182
|
+
const _opts = {
|
|
183
|
+
top: distance,
|
|
184
|
+
behavior: "smooth",
|
|
185
|
+
...opts
|
|
186
|
+
};
|
|
187
|
+
viewport.scrollTo(_opts);
|
|
188
|
+
}
|
|
189
|
+
$:
|
|
190
|
+
sortedItems = items;
|
|
191
|
+
$:
|
|
192
|
+
visible = is_browser ? sortedItems.slice(start, end).map((data, i) => {
|
|
193
|
+
return { index: i + start, data };
|
|
194
|
+
}) : sortedItems.slice(0, max_height / sortedItems.length * average_height + 1).map((data, i) => {
|
|
195
|
+
return { index: i + start, data };
|
|
196
|
+
});
|
|
197
|
+
$:
|
|
198
|
+
actual_height = visible.length * average_height + 10;
|
|
199
|
+
onMount(() => {
|
|
200
|
+
rows = contents.children;
|
|
201
|
+
mounted = true;
|
|
202
|
+
refresh_height_map(items);
|
|
203
|
+
});
|
|
204
|
+
</script>
|
|
205
|
+
|
|
206
|
+
<svelte-virtual-table-viewport>
|
|
207
|
+
<table
|
|
208
|
+
class="table"
|
|
209
|
+
bind:this={viewport}
|
|
210
|
+
bind:contentRect={viewport_box}
|
|
211
|
+
on:scroll={handle_scroll}
|
|
212
|
+
style="height: {height}; --bw-svt-p-top: {top}px; --bw-svt-p-bottom: {bottom}px; --bw-svt-head-height: {head_height}px; --bw-svt-foot-height: {foot_height}px; --bw-svt-avg-row-height: {average_height}px"
|
|
213
|
+
>
|
|
214
|
+
<thead class="thead" bind:offsetHeight={head_height}>
|
|
215
|
+
<slot name="thead" />
|
|
216
|
+
</thead>
|
|
217
|
+
<tbody bind:this={contents} class="tbody">
|
|
218
|
+
{#if visible.length && visible[0].data.length}
|
|
219
|
+
{#each visible as item (item.data[0].id)}
|
|
220
|
+
<slot name="tbody" item={item.data} index={item.index}>
|
|
221
|
+
Missing Table Row
|
|
222
|
+
</slot>
|
|
223
|
+
{/each}
|
|
224
|
+
{/if}
|
|
225
|
+
</tbody>
|
|
226
|
+
<tfoot class="tfoot" bind:offsetHeight={foot_height}>
|
|
227
|
+
<slot name="tfoot" />
|
|
228
|
+
</tfoot>
|
|
229
|
+
</table>
|
|
230
|
+
</svelte-virtual-table-viewport>
|
|
231
|
+
|
|
232
|
+
<style>
|
|
233
|
+
table {
|
|
234
|
+
position: relative;
|
|
235
|
+
overflow-y: scroll;
|
|
236
|
+
overflow-x: scroll;
|
|
237
|
+
-webkit-overflow-scrolling: touch;
|
|
238
|
+
max-height: 100vh;
|
|
239
|
+
box-sizing: border-box;
|
|
240
|
+
display: block;
|
|
241
|
+
padding: 0;
|
|
242
|
+
margin: 0;
|
|
243
|
+
color: var(--body-text-color);
|
|
244
|
+
font-size: var(--input-text-size);
|
|
245
|
+
line-height: var(--line-md);
|
|
246
|
+
font-family: var(--font-mono);
|
|
247
|
+
border-spacing: 0;
|
|
248
|
+
width: 100%;
|
|
249
|
+
scroll-snap-type: x proximity;
|
|
250
|
+
border-collapse: separate;
|
|
251
|
+
}
|
|
252
|
+
table :is(thead, tfoot, tbody) {
|
|
253
|
+
display: table;
|
|
254
|
+
table-layout: fixed;
|
|
255
|
+
width: 100%;
|
|
256
|
+
box-sizing: border-box;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
tbody {
|
|
260
|
+
overflow-x: scroll;
|
|
261
|
+
overflow-y: hidden;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
table tbody {
|
|
265
|
+
padding-top: var(--bw-svt-p-top);
|
|
266
|
+
padding-bottom: var(--bw-svt-p-bottom);
|
|
267
|
+
}
|
|
268
|
+
tbody {
|
|
269
|
+
position: relative;
|
|
270
|
+
box-sizing: border-box;
|
|
271
|
+
border: 0px solid currentColor;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
tbody > :global(tr:last-child) {
|
|
275
|
+
border: none;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
table :global(td) {
|
|
279
|
+
scroll-snap-align: start;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
tbody > :global(tr:nth-child(even)) {
|
|
283
|
+
background: var(--table-even-background-fill);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
thead {
|
|
287
|
+
position: sticky;
|
|
288
|
+
top: 0;
|
|
289
|
+
left: 0;
|
|
290
|
+
z-index: var(--layer-1);
|
|
291
|
+
box-shadow: var(--shadow-drop);
|
|
292
|
+
overflow: hidden;
|
|
293
|
+
}
|
|
294
|
+
</style>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
items?: any[][] | undefined;
|
|
5
|
+
max_height: number;
|
|
6
|
+
actual_height: number;
|
|
7
|
+
table_scrollbar_width: number;
|
|
8
|
+
start?: number | undefined;
|
|
9
|
+
end?: number | undefined;
|
|
10
|
+
selected: number | false;
|
|
11
|
+
scroll_to_index?: ((index: number, opts: ScrollToOptions, align_end?: boolean) => Promise<void>) | undefined;
|
|
12
|
+
};
|
|
13
|
+
events: {
|
|
14
|
+
[evt: string]: CustomEvent<any>;
|
|
15
|
+
};
|
|
16
|
+
slots: {
|
|
17
|
+
thead: {};
|
|
18
|
+
tbody: {
|
|
19
|
+
item: any[];
|
|
20
|
+
index: number;
|
|
21
|
+
};
|
|
22
|
+
tfoot: {};
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export type VirtualTableProps = typeof __propDef.props;
|
|
26
|
+
export type VirtualTableEvents = typeof __propDef.events;
|
|
27
|
+
export type VirtualTableSlots = typeof __propDef.slots;
|
|
28
|
+
export default class VirtualTable extends SvelteComponent<VirtualTableProps, VirtualTableEvents, VirtualTableSlots> {
|
|
29
|
+
get scroll_to_index(): (index: number, opts: ScrollToOptions, align_end?: boolean) => Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
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 = {
|
|
8
|
+
value: string;
|
|
9
|
+
id: string;
|
|
10
|
+
}[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/dataframe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1-beta.1",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -17,20 +17,36 @@
|
|
|
17
17
|
"dompurify": "^3.0.3",
|
|
18
18
|
"katex": "^0.16.7",
|
|
19
19
|
"marked": "^12.0.0",
|
|
20
|
-
"@gradio/
|
|
21
|
-
"@gradio/
|
|
22
|
-
"@gradio/
|
|
23
|
-
"@gradio/statustracker": "^0.
|
|
24
|
-
"@gradio/
|
|
25
|
-
"@gradio/
|
|
26
|
-
"@gradio/utils": "^0.
|
|
20
|
+
"@gradio/atoms": "^0.8.1-beta.1",
|
|
21
|
+
"@gradio/client": "^1.6.0-beta.1",
|
|
22
|
+
"@gradio/markdown": "^0.9.4-beta.1",
|
|
23
|
+
"@gradio/statustracker": "^0.8.0-beta.1",
|
|
24
|
+
"@gradio/upload": "^0.12.4-beta.1",
|
|
25
|
+
"@gradio/button": "^0.3.0-beta.1",
|
|
26
|
+
"@gradio/utils": "^0.7.0-beta.1"
|
|
27
27
|
},
|
|
28
28
|
"exports": {
|
|
29
|
-
".":
|
|
30
|
-
|
|
29
|
+
".": {
|
|
30
|
+
"gradio": "./Index.svelte",
|
|
31
|
+
"svelte": "./dist/Index.svelte",
|
|
32
|
+
"types": "./dist/Index.svelte.d.ts"
|
|
33
|
+
},
|
|
34
|
+
"./example": {
|
|
35
|
+
"gradio": "./Example.svelte",
|
|
36
|
+
"svelte": "./dist/Example.svelte",
|
|
37
|
+
"types": "./dist/Example.svelte.d.ts"
|
|
38
|
+
},
|
|
31
39
|
"./package.json": "./package.json"
|
|
32
40
|
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"svelte": "^4.0.0"
|
|
43
|
+
},
|
|
33
44
|
"devDependencies": {
|
|
34
|
-
"@gradio/preview": "^0.
|
|
45
|
+
"@gradio/preview": "^0.11.1-beta.0"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/gradio-app/gradio.git",
|
|
50
|
+
"directory": "js/dataframe"
|
|
35
51
|
}
|
|
36
52
|
}
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
export let select_on_focus = false;
|
|
24
24
|
export let line_breaks = true;
|
|
25
25
|
export let editable = true;
|
|
26
|
+
export let root: string;
|
|
26
27
|
|
|
27
28
|
const dispatch = createEventDispatcher();
|
|
28
29
|
|
|
@@ -81,6 +82,7 @@
|
|
|
81
82
|
{latex_delimiters}
|
|
82
83
|
{line_breaks}
|
|
83
84
|
chatbot={false}
|
|
85
|
+
{root}
|
|
84
86
|
/>
|
|
85
87
|
{:else}
|
|
86
88
|
{editable ? value : display_value || value}
|
package/shared/Table.svelte
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { BaseButton } from "@gradio/button";
|
|
8
8
|
import EditableCell from "./EditableCell.svelte";
|
|
9
9
|
import type { SelectData } from "@gradio/utils";
|
|
10
|
-
import type { I18nFormatter } from "js/
|
|
10
|
+
import type { I18nFormatter } from "js/core/src/gradio_helper";
|
|
11
11
|
import { type Client } from "@gradio/client";
|
|
12
12
|
import VirtualTable from "./VirtualTable.svelte";
|
|
13
13
|
import type {
|
|
@@ -65,7 +65,11 @@
|
|
|
65
65
|
if (selected !== false) {
|
|
66
66
|
const [row, col] = selected;
|
|
67
67
|
if (!isNaN(row) && !isNaN(col)) {
|
|
68
|
-
dispatch("select", {
|
|
68
|
+
dispatch("select", {
|
|
69
|
+
index: [row, col],
|
|
70
|
+
value: get_data_at(row, col),
|
|
71
|
+
row_value: data[row].map((d) => d.value)
|
|
72
|
+
});
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
}
|
|
@@ -559,7 +563,8 @@
|
|
|
559
563
|
}
|
|
560
564
|
}
|
|
561
565
|
|
|
562
|
-
let table_height: number =
|
|
566
|
+
let table_height: number =
|
|
567
|
+
values.slice(0, (height / values.length) * 37).length * 37 + 37;
|
|
563
568
|
let scrollbar_width = 0;
|
|
564
569
|
|
|
565
570
|
function sort_data(
|
|
@@ -683,6 +688,7 @@
|
|
|
683
688
|
header
|
|
684
689
|
edit={false}
|
|
685
690
|
el={null}
|
|
691
|
+
{root}
|
|
686
692
|
/>
|
|
687
693
|
|
|
688
694
|
<div
|
|
@@ -717,6 +723,7 @@
|
|
|
717
723
|
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
718
724
|
edit={false}
|
|
719
725
|
el={null}
|
|
726
|
+
{root}
|
|
720
727
|
/>
|
|
721
728
|
</div>
|
|
722
729
|
</td>
|
|
@@ -763,6 +770,7 @@
|
|
|
763
770
|
on:dblclick={() => edit_header(i)}
|
|
764
771
|
{select_on_focus}
|
|
765
772
|
header
|
|
773
|
+
{root}
|
|
766
774
|
/>
|
|
767
775
|
|
|
768
776
|
<!-- TODO: fix -->
|
|
@@ -812,6 +820,7 @@
|
|
|
812
820
|
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
813
821
|
on:blur={() => ((clear_on_focus = false), parent.focus())}
|
|
814
822
|
{clear_on_focus}
|
|
823
|
+
{root}
|
|
815
824
|
/>
|
|
816
825
|
</div>
|
|
817
826
|
</td>
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
export let actual_height: number;
|
|
9
9
|
export let table_scrollbar_width: number;
|
|
10
10
|
export let start = 0;
|
|
11
|
-
export let end =
|
|
11
|
+
export let end = 20;
|
|
12
12
|
export let selected: number | false;
|
|
13
13
|
let height = "100%";
|
|
14
14
|
|
|
15
|
-
let average_height
|
|
15
|
+
let average_height = 30;
|
|
16
16
|
let bottom = 0;
|
|
17
17
|
let contents: HTMLTableSectionElement;
|
|
18
18
|
let head_height = 0;
|
|
@@ -22,19 +22,25 @@
|
|
|
22
22
|
let rows: HTMLCollectionOf<HTMLTableRowElement>;
|
|
23
23
|
let top = 0;
|
|
24
24
|
let viewport: HTMLTableElement;
|
|
25
|
-
let viewport_height =
|
|
25
|
+
let viewport_height = 200;
|
|
26
26
|
let visible: { index: number; data: any[] }[] = [];
|
|
27
27
|
let viewport_box: DOMRectReadOnly;
|
|
28
28
|
|
|
29
|
-
$: viewport_height = viewport_box?.height ||
|
|
29
|
+
$: viewport_height = viewport_box?.height || 200;
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
const is_browser = typeof window !== "undefined";
|
|
32
|
+
const raf = is_browser
|
|
33
|
+
? window.requestAnimationFrame
|
|
34
|
+
: (cb: (...args: any[]) => void) => cb();
|
|
35
|
+
|
|
36
|
+
$: mounted && raf(() => refresh_height_map(sortedItems));
|
|
32
37
|
|
|
33
38
|
let content_height = 0;
|
|
34
39
|
async function refresh_height_map(_items: typeof items): Promise<void> {
|
|
35
40
|
if (viewport_height === 0) {
|
|
36
41
|
return;
|
|
37
42
|
}
|
|
43
|
+
|
|
38
44
|
const { scrollTop } = viewport;
|
|
39
45
|
table_scrollbar_width = viewport.offsetWidth - viewport.clientWidth;
|
|
40
46
|
|
|
@@ -87,7 +93,7 @@
|
|
|
87
93
|
$: scroll_and_render(selected);
|
|
88
94
|
|
|
89
95
|
async function scroll_and_render(n: number | false): Promise<void> {
|
|
90
|
-
|
|
96
|
+
raf(async () => {
|
|
91
97
|
if (typeof n !== "number") return;
|
|
92
98
|
const direction = typeof n !== "number" ? false : is_in_view(n);
|
|
93
99
|
if (direction === true) {
|
|
@@ -232,10 +238,17 @@
|
|
|
232
238
|
|
|
233
239
|
$: sortedItems = items;
|
|
234
240
|
|
|
235
|
-
$: visible =
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
241
|
+
$: visible = is_browser
|
|
242
|
+
? sortedItems.slice(start, end).map((data, i) => {
|
|
243
|
+
return { index: i + start, data };
|
|
244
|
+
})
|
|
245
|
+
: sortedItems
|
|
246
|
+
.slice(0, (max_height / sortedItems.length) * average_height + 1)
|
|
247
|
+
.map((data, i) => {
|
|
248
|
+
return { index: i + start, data };
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
$: actual_height = visible.length * average_height + 10;
|
|
239
252
|
onMount(() => {
|
|
240
253
|
rows = contents.children as HTMLCollectionOf<HTMLTableRowElement>;
|
|
241
254
|
mounted = true;
|