@gradio/dataframe 0.17.15 → 0.17.17
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 +30 -0
- package/dist/shared/EditableCell.svelte +0 -2
- package/dist/shared/EditableCell.svelte.d.ts +0 -1
- package/dist/shared/Table.svelte +1 -5
- package/dist/shared/TableCell.svelte +0 -2
- package/dist/shared/TableCell.svelte.d.ts +0 -1
- package/dist/shared/TableHeader.svelte +0 -2
- package/dist/shared/TableHeader.svelte.d.ts +0 -1
- package/dist/shared/VirtualTable.svelte +44 -99
- package/package.json +10 -10
- package/shared/EditableCell.svelte +0 -2
- package/shared/Table.svelte +1 -5
- package/shared/TableCell.svelte +0 -2
- package/shared/TableHeader.svelte +0 -2
- package/shared/VirtualTable.svelte +49 -120
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @gradio/dataframe
|
|
2
2
|
|
|
3
|
+
## 0.17.17
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
- [#11387](https://github.com/gradio-app/gradio/pull/11387) [`8245afc`](https://github.com/gradio-app/gradio/commit/8245afc669501e1e5f0d619f452455f68a3b7667) - Define root URL in frontend. Thanks @aliabid94!
|
|
8
|
+
|
|
9
|
+
### Dependency updates
|
|
10
|
+
|
|
11
|
+
- @gradio/statustracker@0.10.13
|
|
12
|
+
- @gradio/markdown-code@0.4.4
|
|
13
|
+
- @gradio/atoms@0.16.2
|
|
14
|
+
- @gradio/client@1.15.3
|
|
15
|
+
- @gradio/upload@0.16.8
|
|
16
|
+
- @gradio/checkbox@0.4.24
|
|
17
|
+
- @gradio/button@0.5.4
|
|
18
|
+
|
|
19
|
+
## 0.17.16
|
|
20
|
+
|
|
21
|
+
### Fixes
|
|
22
|
+
|
|
23
|
+
- [#11349](https://github.com/gradio-app/gradio/pull/11349) [`bed858b`](https://github.com/gradio-app/gradio/commit/bed858b62b9887e606618bea5fe8a2f212b4a645) - Fix DataFrame Scroll Divergence. Thanks @deckar01!
|
|
24
|
+
- [#11346](https://github.com/gradio-app/gradio/pull/11346) [`3a9a002`](https://github.com/gradio-app/gradio/commit/3a9a0025efd49942303517c5dbd426d41241b7f6) - Hide native Dataframe to screen readers. Thanks @hannahblair!
|
|
25
|
+
|
|
26
|
+
### Dependency updates
|
|
27
|
+
|
|
28
|
+
- @gradio/markdown-code@0.4.3
|
|
29
|
+
- @gradio/statustracker@0.10.12
|
|
30
|
+
- @gradio/button@0.5.3
|
|
31
|
+
- @gradio/checkbox@0.4.23
|
|
32
|
+
|
|
3
33
|
## 0.17.15
|
|
4
34
|
|
|
5
35
|
### Features
|
|
@@ -12,7 +12,6 @@ export let latex_delimiters;
|
|
|
12
12
|
export let line_breaks = true;
|
|
13
13
|
export let editable = true;
|
|
14
14
|
export let is_static = false;
|
|
15
|
-
export let root;
|
|
16
15
|
export let max_chars = null;
|
|
17
16
|
export let components = {};
|
|
18
17
|
export let i18n;
|
|
@@ -143,7 +142,6 @@ function handle_bool_change(new_value) {
|
|
|
143
142
|
{latex_delimiters}
|
|
144
143
|
{line_breaks}
|
|
145
144
|
chatbot={false}
|
|
146
|
-
{root}
|
|
147
145
|
/>
|
|
148
146
|
{:else}
|
|
149
147
|
{display_text}
|
|
@@ -16,7 +16,6 @@ declare const __propDef: {
|
|
|
16
16
|
line_breaks?: boolean | undefined;
|
|
17
17
|
editable?: boolean | undefined;
|
|
18
18
|
is_static?: boolean | undefined;
|
|
19
|
-
root: string;
|
|
20
19
|
max_chars?: (number | null) | undefined;
|
|
21
20
|
components?: Record<string, any> | undefined;
|
|
22
21
|
i18n: I18nFormatter;
|
package/dist/shared/Table.svelte
CHANGED
|
@@ -634,7 +634,7 @@ function get_cell_display_value(row, col) {
|
|
|
634
634
|
role="grid"
|
|
635
635
|
tabindex="0"
|
|
636
636
|
>
|
|
637
|
-
<table bind:this={table}>
|
|
637
|
+
<table bind:this={table} aria-hidden="true">
|
|
638
638
|
{#if label && label.length !== 0}
|
|
639
639
|
<caption class="sr-only">{label}</caption>
|
|
640
640
|
{/if}
|
|
@@ -659,7 +659,6 @@ function get_cell_display_value(row, col) {
|
|
|
659
659
|
{latex_delimiters}
|
|
660
660
|
{line_breaks}
|
|
661
661
|
{max_chars}
|
|
662
|
-
{root}
|
|
663
662
|
{editable}
|
|
664
663
|
is_static={static_columns.includes(i)}
|
|
665
664
|
{i18n}
|
|
@@ -684,7 +683,6 @@ function get_cell_display_value(row, col) {
|
|
|
684
683
|
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
685
684
|
edit={false}
|
|
686
685
|
el={null}
|
|
687
|
-
{root}
|
|
688
686
|
{editable}
|
|
689
687
|
{i18n}
|
|
690
688
|
show_selection_buttons={selected_cells.length === 1 &&
|
|
@@ -765,7 +763,6 @@ function get_cell_display_value(row, col) {
|
|
|
765
763
|
{latex_delimiters}
|
|
766
764
|
{line_breaks}
|
|
767
765
|
{max_chars}
|
|
768
|
-
{root}
|
|
769
766
|
{editable}
|
|
770
767
|
is_static={static_columns.includes(i)}
|
|
771
768
|
{i18n}
|
|
@@ -803,7 +800,6 @@ function get_cell_display_value(row, col) {
|
|
|
803
800
|
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
804
801
|
{editing}
|
|
805
802
|
{max_chars}
|
|
806
|
-
{root}
|
|
807
803
|
{editable}
|
|
808
804
|
is_static={static_columns.includes(j)}
|
|
809
805
|
{i18n}
|
|
@@ -20,7 +20,6 @@ export let line_breaks;
|
|
|
20
20
|
export let datatype;
|
|
21
21
|
export let editing;
|
|
22
22
|
export let max_chars;
|
|
23
|
-
export let root;
|
|
24
23
|
export let editable;
|
|
25
24
|
export let is_static = false;
|
|
26
25
|
export let i18n;
|
|
@@ -101,7 +100,6 @@ $:
|
|
|
101
100
|
}
|
|
102
101
|
}}
|
|
103
102
|
on:blur={handle_blur}
|
|
104
|
-
{root}
|
|
105
103
|
{max_chars}
|
|
106
104
|
{i18n}
|
|
107
105
|
{components}
|
|
@@ -18,7 +18,6 @@ export let sort_columns = [];
|
|
|
18
18
|
export let latex_delimiters;
|
|
19
19
|
export let line_breaks;
|
|
20
20
|
export let max_chars;
|
|
21
|
-
export let root;
|
|
22
21
|
export let editable;
|
|
23
22
|
export let i18n;
|
|
24
23
|
export let el;
|
|
@@ -92,7 +91,6 @@ function get_header_position(col_index) {
|
|
|
92
91
|
}
|
|
93
92
|
}}
|
|
94
93
|
header
|
|
95
|
-
{root}
|
|
96
94
|
{editable}
|
|
97
95
|
{is_static}
|
|
98
96
|
{i18n}
|
|
@@ -28,53 +28,64 @@ $:
|
|
|
28
28
|
viewport_height = viewport_box?.height || 200;
|
|
29
29
|
const is_browser = typeof window !== "undefined";
|
|
30
30
|
const raf = is_browser ? window.requestAnimationFrame : (cb) => cb();
|
|
31
|
-
$:
|
|
32
|
-
mounted &&
|
|
33
|
-
|
|
34
|
-
async function refresh_height_map(_items) {
|
|
35
|
-
if (viewport_height === 0) {
|
|
36
|
-
return;
|
|
31
|
+
$: {
|
|
32
|
+
if (mounted && viewport_height && viewport.offsetParent) {
|
|
33
|
+
sortedItems, raf(refresh_height_map);
|
|
37
34
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
}
|
|
36
|
+
async function refresh_height_map() {
|
|
37
|
+
if (sortedItems.length < start) {
|
|
38
|
+
await scroll_to_index(sortedItems.length - 1, { behavior: "auto" });
|
|
39
|
+
}
|
|
40
|
+
const scrollTop = Math.max(0, viewport.scrollTop);
|
|
41
|
+
show_scroll_button = scrollTop > 100;
|
|
41
42
|
table_scrollbar_width = viewport.offsetWidth - viewport.clientWidth;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
_h = average_height;
|
|
43
|
+
for (let v = 0; v < rows.length; v += 1) {
|
|
44
|
+
height_map[start + v] = rows[v].getBoundingClientRect().height;
|
|
45
|
+
}
|
|
46
|
+
let i = 0;
|
|
47
|
+
let y = head_height;
|
|
48
|
+
while (i < sortedItems.length) {
|
|
49
|
+
const row_height = height_map[i] || average_height;
|
|
50
|
+
if (y + row_height > scrollTop - max_height) {
|
|
51
|
+
start = i;
|
|
52
|
+
top = y - head_height;
|
|
53
|
+
break;
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
y += row_height;
|
|
56
|
+
i += 1;
|
|
57
|
+
}
|
|
58
|
+
let content_height = head_height;
|
|
59
|
+
while (i < sortedItems.length) {
|
|
60
|
+
const row_height = height_map[i] || average_height;
|
|
56
61
|
content_height += row_height;
|
|
57
62
|
i += 1;
|
|
63
|
+
if (content_height - head_height > 3 * max_height) {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
58
66
|
}
|
|
59
67
|
end = i;
|
|
60
|
-
const remaining =
|
|
68
|
+
const remaining = sortedItems.length - end;
|
|
61
69
|
const scrollbar_height = viewport.offsetHeight - viewport.clientHeight;
|
|
62
70
|
if (scrollbar_height > 0) {
|
|
63
71
|
content_height += scrollbar_height;
|
|
64
72
|
}
|
|
65
73
|
let filtered_height_map = height_map.filter((v) => typeof v === "number");
|
|
66
|
-
average_height = filtered_height_map.reduce((a, b) => a + b, 0) / filtered_height_map.length;
|
|
74
|
+
average_height = filtered_height_map.reduce((a, b) => a + b, 0) / filtered_height_map.length || 30;
|
|
67
75
|
bottom = remaining * average_height;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
if (!isFinite(bottom)) {
|
|
77
|
+
bottom = 2e5;
|
|
78
|
+
}
|
|
79
|
+
height_map.length = sortedItems.length;
|
|
80
|
+
while (i < sortedItems.length) {
|
|
81
|
+
i += 1;
|
|
82
|
+
height_map[i] = average_height;
|
|
83
|
+
}
|
|
84
|
+
if (max_height && content_height > max_height) {
|
|
75
85
|
actual_height = max_height;
|
|
86
|
+
} else {
|
|
87
|
+
actual_height = content_height;
|
|
76
88
|
}
|
|
77
|
-
await tick();
|
|
78
89
|
}
|
|
79
90
|
$:
|
|
80
91
|
scroll_and_render(selected);
|
|
@@ -112,71 +123,6 @@ function is_in_view(n) {
|
|
|
112
123
|
}
|
|
113
124
|
return true;
|
|
114
125
|
}
|
|
115
|
-
function get_computed_px_amount(elem, property) {
|
|
116
|
-
if (!elem) {
|
|
117
|
-
return 0;
|
|
118
|
-
}
|
|
119
|
-
const compStyle = getComputedStyle(elem);
|
|
120
|
-
let x = parseInt(compStyle.getPropertyValue(property));
|
|
121
|
-
return x;
|
|
122
|
-
}
|
|
123
|
-
async function handle_scroll(e) {
|
|
124
|
-
const scroll_top = viewport.scrollTop;
|
|
125
|
-
show_scroll_button = scroll_top > 100;
|
|
126
|
-
if (show_scroll_button) {
|
|
127
|
-
dispatch("scroll_top", scroll_top);
|
|
128
|
-
}
|
|
129
|
-
rows = contents.children;
|
|
130
|
-
const is_start_overflow = sortedItems.length < start;
|
|
131
|
-
const row_top_border = get_computed_px_amount(rows[1], "border-top-width");
|
|
132
|
-
const actual_border_collapsed_width = 0;
|
|
133
|
-
if (is_start_overflow) {
|
|
134
|
-
await scroll_to_index(sortedItems.length - 1, { behavior: "auto" });
|
|
135
|
-
}
|
|
136
|
-
let new_start = 0;
|
|
137
|
-
for (let v = 0; v < rows.length; v += 1) {
|
|
138
|
-
height_map[start + v] = rows[v].getBoundingClientRect().height;
|
|
139
|
-
}
|
|
140
|
-
let i = 0;
|
|
141
|
-
let y = head_height + row_top_border / 2;
|
|
142
|
-
let row_heights = [];
|
|
143
|
-
while (i < sortedItems.length) {
|
|
144
|
-
const row_height = height_map[i] || average_height;
|
|
145
|
-
row_heights[i] = row_height;
|
|
146
|
-
if (y + row_height + actual_border_collapsed_width > scroll_top) {
|
|
147
|
-
new_start = i;
|
|
148
|
-
top = y - (head_height + row_top_border / 2);
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
y += row_height;
|
|
152
|
-
i += 1;
|
|
153
|
-
}
|
|
154
|
-
new_start = Math.max(0, new_start);
|
|
155
|
-
while (i < sortedItems.length) {
|
|
156
|
-
const row_height = height_map[i] || average_height;
|
|
157
|
-
y += row_height;
|
|
158
|
-
i += 1;
|
|
159
|
-
if (y > scroll_top + viewport_height) {
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
start = new_start;
|
|
164
|
-
end = i;
|
|
165
|
-
const remaining = sortedItems.length - end;
|
|
166
|
-
if (end === 0) {
|
|
167
|
-
end = 10;
|
|
168
|
-
}
|
|
169
|
-
average_height = (y - head_height) / end;
|
|
170
|
-
let remaining_height = remaining * average_height;
|
|
171
|
-
while (i < sortedItems.length) {
|
|
172
|
-
i += 1;
|
|
173
|
-
height_map[i] = average_height;
|
|
174
|
-
}
|
|
175
|
-
bottom = remaining_height;
|
|
176
|
-
if (!isFinite(bottom)) {
|
|
177
|
-
bottom = 2e5;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
126
|
export async function scroll_to_index(index, opts, align_end = false) {
|
|
181
127
|
await tick();
|
|
182
128
|
const _itemHeight = average_height;
|
|
@@ -206,7 +152,6 @@ $:
|
|
|
206
152
|
onMount(() => {
|
|
207
153
|
rows = contents.children;
|
|
208
154
|
mounted = true;
|
|
209
|
-
refresh_height_map(items);
|
|
210
155
|
});
|
|
211
156
|
</script>
|
|
212
157
|
|
|
@@ -217,7 +162,7 @@ onMount(() => {
|
|
|
217
162
|
class:disable-scroll={disable_scroll}
|
|
218
163
|
bind:this={viewport}
|
|
219
164
|
bind:contentRect={viewport_box}
|
|
220
|
-
on:scroll={
|
|
165
|
+
on:scroll={refresh_height_map}
|
|
221
166
|
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; --max-height: {max_height}px"
|
|
222
167
|
>
|
|
223
168
|
<thead class="thead" bind:offsetHeight={head_height}>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/dataframe",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.17",
|
|
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/
|
|
21
|
-
"@gradio/
|
|
22
|
-
"@gradio/
|
|
23
|
-
"@gradio/client": "^1.15.2",
|
|
20
|
+
"@gradio/atoms": "^0.16.2",
|
|
21
|
+
"@gradio/checkbox": "^0.4.24",
|
|
22
|
+
"@gradio/button": "^0.5.4",
|
|
24
23
|
"@gradio/icons": "^0.12.0",
|
|
25
|
-
"@gradio/
|
|
26
|
-
"@gradio/
|
|
27
|
-
"@gradio/
|
|
28
|
-
"@gradio/
|
|
24
|
+
"@gradio/markdown-code": "^0.4.4",
|
|
25
|
+
"@gradio/statustracker": "^0.10.13",
|
|
26
|
+
"@gradio/upload": "^0.16.8",
|
|
27
|
+
"@gradio/client": "^1.15.3",
|
|
28
|
+
"@gradio/utils": "^0.10.2"
|
|
29
29
|
},
|
|
30
30
|
"exports": {
|
|
31
31
|
".": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"svelte": "^4.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@gradio/preview": "^0.13.
|
|
47
|
+
"@gradio/preview": "^0.13.2"
|
|
48
48
|
},
|
|
49
49
|
"repository": {
|
|
50
50
|
"type": "git",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
export let line_breaks = true;
|
|
27
27
|
export let editable = true;
|
|
28
28
|
export let is_static = false;
|
|
29
|
-
export let root: string;
|
|
30
29
|
export let max_chars: number | null = null;
|
|
31
30
|
export let components: Record<string, any> = {};
|
|
32
31
|
export let i18n: I18nFormatter;
|
|
@@ -178,7 +177,6 @@
|
|
|
178
177
|
{latex_delimiters}
|
|
179
178
|
{line_breaks}
|
|
180
179
|
chatbot={false}
|
|
181
|
-
{root}
|
|
182
180
|
/>
|
|
183
181
|
{:else}
|
|
184
182
|
{display_text}
|
package/shared/Table.svelte
CHANGED
|
@@ -780,7 +780,7 @@
|
|
|
780
780
|
role="grid"
|
|
781
781
|
tabindex="0"
|
|
782
782
|
>
|
|
783
|
-
<table bind:this={table}>
|
|
783
|
+
<table bind:this={table} aria-hidden="true">
|
|
784
784
|
{#if label && label.length !== 0}
|
|
785
785
|
<caption class="sr-only">{label}</caption>
|
|
786
786
|
{/if}
|
|
@@ -805,7 +805,6 @@
|
|
|
805
805
|
{latex_delimiters}
|
|
806
806
|
{line_breaks}
|
|
807
807
|
{max_chars}
|
|
808
|
-
{root}
|
|
809
808
|
{editable}
|
|
810
809
|
is_static={static_columns.includes(i)}
|
|
811
810
|
{i18n}
|
|
@@ -830,7 +829,6 @@
|
|
|
830
829
|
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
831
830
|
edit={false}
|
|
832
831
|
el={null}
|
|
833
|
-
{root}
|
|
834
832
|
{editable}
|
|
835
833
|
{i18n}
|
|
836
834
|
show_selection_buttons={selected_cells.length === 1 &&
|
|
@@ -911,7 +909,6 @@
|
|
|
911
909
|
{latex_delimiters}
|
|
912
910
|
{line_breaks}
|
|
913
911
|
{max_chars}
|
|
914
|
-
{root}
|
|
915
912
|
{editable}
|
|
916
913
|
is_static={static_columns.includes(i)}
|
|
917
914
|
{i18n}
|
|
@@ -949,7 +946,6 @@
|
|
|
949
946
|
datatype={Array.isArray(datatype) ? datatype[j] : datatype}
|
|
950
947
|
{editing}
|
|
951
948
|
{max_chars}
|
|
952
|
-
{root}
|
|
953
949
|
{editable}
|
|
954
950
|
is_static={static_columns.includes(j)}
|
|
955
951
|
{i18n}
|
package/shared/TableCell.svelte
CHANGED
|
@@ -53,7 +53,6 @@
|
|
|
53
53
|
export let datatype: Datatype;
|
|
54
54
|
export let editing: [number, number] | false;
|
|
55
55
|
export let max_chars: number | undefined;
|
|
56
|
-
export let root: string;
|
|
57
56
|
export let editable: boolean;
|
|
58
57
|
export let is_static = false;
|
|
59
58
|
export let i18n: I18nFormatter;
|
|
@@ -139,7 +138,6 @@
|
|
|
139
138
|
}
|
|
140
139
|
}}
|
|
141
140
|
on:blur={handle_blur}
|
|
142
|
-
{root}
|
|
143
141
|
{max_chars}
|
|
144
142
|
{i18n}
|
|
145
143
|
{components}
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
}[];
|
|
27
27
|
export let line_breaks: boolean;
|
|
28
28
|
export let max_chars: number | undefined;
|
|
29
|
-
export let root: string;
|
|
30
29
|
export let editable: boolean;
|
|
31
30
|
export let i18n: I18nFormatter;
|
|
32
31
|
export let el: HTMLInputElement | null;
|
|
@@ -105,7 +104,6 @@
|
|
|
105
104
|
}
|
|
106
105
|
}}
|
|
107
106
|
header
|
|
108
|
-
{root}
|
|
109
107
|
{editable}
|
|
110
108
|
{is_static}
|
|
111
109
|
{i18n}
|
|
@@ -40,43 +40,53 @@
|
|
|
40
40
|
? window.requestAnimationFrame
|
|
41
41
|
: (cb: (...args: any[]) => void) => cb();
|
|
42
42
|
|
|
43
|
-
$:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
async function refresh_height_map(_items: typeof items): Promise<void> {
|
|
47
|
-
if (viewport_height === 0) {
|
|
48
|
-
return;
|
|
43
|
+
$: {
|
|
44
|
+
if (mounted && viewport_height && viewport.offsetParent) {
|
|
45
|
+
sortedItems, raf(refresh_height_map);
|
|
49
46
|
}
|
|
47
|
+
}
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
async function refresh_height_map(): Promise<void> {
|
|
50
|
+
if (sortedItems.length < start) {
|
|
51
|
+
await scroll_to_index(sortedItems.length - 1, { behavior: "auto" });
|
|
52
|
+
}
|
|
55
53
|
|
|
56
|
-
const
|
|
54
|
+
const scrollTop = Math.max(0, viewport.scrollTop);
|
|
55
|
+
show_scroll_button = scrollTop > 100;
|
|
57
56
|
table_scrollbar_width = viewport.offsetWidth - viewport.clientWidth;
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
let
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
58
|
+
// acquire height map for currently visible rows
|
|
59
|
+
for (let v = 0; v < rows.length; v += 1) {
|
|
60
|
+
height_map[start + v] = rows[v].getBoundingClientRect().height;
|
|
61
|
+
}
|
|
62
|
+
let i = 0;
|
|
63
|
+
let y = head_height;
|
|
64
|
+
// loop items to find new start
|
|
65
|
+
while (i < sortedItems.length) {
|
|
66
|
+
const row_height = height_map[i] || average_height;
|
|
67
|
+
// keep a page of rows buffered above
|
|
68
|
+
if (y + row_height > scrollTop - max_height) {
|
|
69
|
+
start = i;
|
|
70
|
+
top = y - head_height;
|
|
71
|
+
break;
|
|
72
72
|
}
|
|
73
|
-
|
|
73
|
+
y += row_height;
|
|
74
|
+
i += 1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let content_height = head_height;
|
|
78
|
+
while (i < sortedItems.length) {
|
|
79
|
+
const row_height = height_map[i] || average_height;
|
|
74
80
|
content_height += row_height;
|
|
75
81
|
i += 1;
|
|
82
|
+
// keep a page of rows buffered below
|
|
83
|
+
if (content_height - head_height > 3 * max_height) {
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
end = i;
|
|
79
|
-
const remaining =
|
|
89
|
+
const remaining = sortedItems.length - end;
|
|
80
90
|
|
|
81
91
|
const scrollbar_height = viewport.offsetHeight - viewport.clientHeight;
|
|
82
92
|
if (scrollbar_height > 0) {
|
|
@@ -86,20 +96,22 @@
|
|
|
86
96
|
let filtered_height_map = height_map.filter((v) => typeof v === "number");
|
|
87
97
|
average_height =
|
|
88
98
|
filtered_height_map.reduce((a, b) => a + b, 0) /
|
|
89
|
-
|
|
99
|
+
filtered_height_map.length || 30;
|
|
90
100
|
|
|
91
101
|
bottom = remaining * average_height;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
if (!isFinite(bottom)) {
|
|
103
|
+
bottom = 200000;
|
|
104
|
+
}
|
|
105
|
+
height_map.length = sortedItems.length;
|
|
106
|
+
while (i < sortedItems.length) {
|
|
107
|
+
i += 1;
|
|
108
|
+
height_map[i] = average_height;
|
|
109
|
+
}
|
|
110
|
+
if (max_height && content_height > max_height) {
|
|
99
111
|
actual_height = max_height;
|
|
112
|
+
} else {
|
|
113
|
+
actual_height = content_height;
|
|
100
114
|
}
|
|
101
|
-
|
|
102
|
-
await tick();
|
|
103
115
|
}
|
|
104
116
|
|
|
105
117
|
$: scroll_and_render(selected);
|
|
@@ -144,88 +156,6 @@
|
|
|
144
156
|
return true;
|
|
145
157
|
}
|
|
146
158
|
|
|
147
|
-
function get_computed_px_amount(elem: HTMLElement, property: string): number {
|
|
148
|
-
if (!elem) {
|
|
149
|
-
return 0;
|
|
150
|
-
}
|
|
151
|
-
const compStyle = getComputedStyle(elem);
|
|
152
|
-
|
|
153
|
-
let x = parseInt(compStyle.getPropertyValue(property));
|
|
154
|
-
return x;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
async function handle_scroll(e: Event): Promise<void> {
|
|
158
|
-
const scroll_top = viewport.scrollTop;
|
|
159
|
-
|
|
160
|
-
show_scroll_button = scroll_top > 100;
|
|
161
|
-
|
|
162
|
-
if (show_scroll_button) {
|
|
163
|
-
dispatch("scroll_top", scroll_top);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
rows = contents.children as HTMLCollectionOf<HTMLTableRowElement>;
|
|
167
|
-
const is_start_overflow = sortedItems.length < start;
|
|
168
|
-
|
|
169
|
-
const row_top_border = get_computed_px_amount(rows[1], "border-top-width");
|
|
170
|
-
|
|
171
|
-
const actual_border_collapsed_width = 0;
|
|
172
|
-
|
|
173
|
-
if (is_start_overflow) {
|
|
174
|
-
await scroll_to_index(sortedItems.length - 1, { behavior: "auto" });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
let new_start = 0;
|
|
178
|
-
// acquire height map for currently visible rows
|
|
179
|
-
for (let v = 0; v < rows.length; v += 1) {
|
|
180
|
-
height_map[start + v] = rows[v].getBoundingClientRect().height;
|
|
181
|
-
}
|
|
182
|
-
let i = 0;
|
|
183
|
-
// start from top: thead, with its borders, plus the first border to afterwards neglect
|
|
184
|
-
let y = head_height + row_top_border / 2;
|
|
185
|
-
let row_heights = [];
|
|
186
|
-
// loop items to find new start
|
|
187
|
-
while (i < sortedItems.length) {
|
|
188
|
-
const row_height = height_map[i] || average_height;
|
|
189
|
-
row_heights[i] = row_height;
|
|
190
|
-
// we only want to jump if the full (incl. border) row is away
|
|
191
|
-
if (y + row_height + actual_border_collapsed_width > scroll_top) {
|
|
192
|
-
// this is the last index still inside the viewport
|
|
193
|
-
new_start = i;
|
|
194
|
-
top = y - (head_height + row_top_border / 2);
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
y += row_height;
|
|
198
|
-
i += 1;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
new_start = Math.max(0, new_start);
|
|
202
|
-
while (i < sortedItems.length) {
|
|
203
|
-
const row_height = height_map[i] || average_height;
|
|
204
|
-
y += row_height;
|
|
205
|
-
i += 1;
|
|
206
|
-
if (y > scroll_top + viewport_height) {
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
start = new_start;
|
|
211
|
-
end = i;
|
|
212
|
-
const remaining = sortedItems.length - end;
|
|
213
|
-
if (end === 0) {
|
|
214
|
-
end = 10;
|
|
215
|
-
}
|
|
216
|
-
average_height = (y - head_height) / end;
|
|
217
|
-
let remaining_height = remaining * average_height; // 0
|
|
218
|
-
// compute height map for remaining items
|
|
219
|
-
while (i < sortedItems.length) {
|
|
220
|
-
i += 1;
|
|
221
|
-
height_map[i] = average_height;
|
|
222
|
-
}
|
|
223
|
-
bottom = remaining_height;
|
|
224
|
-
if (!isFinite(bottom)) {
|
|
225
|
-
bottom = 200000;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
159
|
export async function scroll_to_index(
|
|
230
160
|
index: number,
|
|
231
161
|
opts: ScrollToOptions,
|
|
@@ -269,7 +199,6 @@
|
|
|
269
199
|
onMount(() => {
|
|
270
200
|
rows = contents.children as HTMLCollectionOf<HTMLTableRowElement>;
|
|
271
201
|
mounted = true;
|
|
272
|
-
refresh_height_map(items);
|
|
273
202
|
});
|
|
274
203
|
</script>
|
|
275
204
|
|
|
@@ -280,7 +209,7 @@
|
|
|
280
209
|
class:disable-scroll={disable_scroll}
|
|
281
210
|
bind:this={viewport}
|
|
282
211
|
bind:contentRect={viewport_box}
|
|
283
|
-
on:scroll={
|
|
212
|
+
on:scroll={refresh_height_map}
|
|
284
213
|
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; --max-height: {max_height}px"
|
|
285
214
|
>
|
|
286
215
|
<thead class="thead" bind:offsetHeight={head_height}>
|