@gradio/dataframe 0.17.15 → 0.17.16

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,19 @@
1
1
  # @gradio/dataframe
2
2
 
3
+ ## 0.17.16
4
+
5
+ ### Fixes
6
+
7
+ - [#11349](https://github.com/gradio-app/gradio/pull/11349) [`bed858b`](https://github.com/gradio-app/gradio/commit/bed858b62b9887e606618bea5fe8a2f212b4a645) - Fix DataFrame Scroll Divergence. Thanks @deckar01!
8
+ - [#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!
9
+
10
+ ### Dependency updates
11
+
12
+ - @gradio/markdown-code@0.4.3
13
+ - @gradio/statustracker@0.10.12
14
+ - @gradio/button@0.5.3
15
+ - @gradio/checkbox@0.4.23
16
+
3
17
  ## 0.17.15
4
18
 
5
19
  ### Features
@@ -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}
@@ -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 && raf(() => refresh_height_map(sortedItems));
33
- let content_height = 0;
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
- head_height = viewport.querySelector(".thead")?.getBoundingClientRect().height || 0;
39
- await tick();
40
- const { scrollTop } = viewport;
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
- content_height = top - (scrollTop - head_height);
43
- let i = start;
44
- while (content_height < max_height && i < _items.length) {
45
- let row = rows[i - start];
46
- if (!row) {
47
- end = i + 1;
48
- await tick();
49
- row = rows[i - start];
50
- }
51
- let _h = row?.getBoundingClientRect().height;
52
- if (!_h) {
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
- const row_height = height_map[i] = _h;
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 = _items.length - end;
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
- height_map.length = _items.length;
69
- await tick();
70
- if (!max_height) {
71
- actual_height = content_height + 1;
72
- } else if (content_height < max_height) {
73
- actual_height = content_height + 2;
74
- } else {
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={handle_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.15",
3
+ "version": "0.17.16",
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.3",
21
20
  "@gradio/atoms": "^0.16.1",
22
- "@gradio/checkbox": "^0.4.23",
23
- "@gradio/client": "^1.15.2",
21
+ "@gradio/button": "^0.5.3",
24
22
  "@gradio/icons": "^0.12.0",
25
23
  "@gradio/statustracker": "^0.10.12",
24
+ "@gradio/checkbox": "^0.4.23",
26
25
  "@gradio/upload": "^0.16.7",
27
- "@gradio/utils": "^0.10.2",
28
- "@gradio/markdown-code": "^0.4.3"
26
+ "@gradio/markdown-code": "^0.4.3",
27
+ "@gradio/client": "^1.15.2",
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.1"
47
+ "@gradio/preview": "^0.13.2"
48
48
  },
49
49
  "repository": {
50
50
  "type": "git",
@@ -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}
@@ -40,43 +40,53 @@
40
40
  ? window.requestAnimationFrame
41
41
  : (cb: (...args: any[]) => void) => cb();
42
42
 
43
- $: mounted && raf(() => refresh_height_map(sortedItems));
44
-
45
- let content_height = 0;
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
- // force header height calculation first
52
- head_height =
53
- viewport.querySelector(".thead")?.getBoundingClientRect().height || 0;
54
- await tick();
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 { scrollTop } = viewport;
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
- content_height = top - (scrollTop - head_height);
60
- let i = start;
61
-
62
- while (content_height < max_height && i < _items.length) {
63
- let row = rows[i - start];
64
- if (!row) {
65
- end = i + 1;
66
- await tick(); // render the newly visible row
67
- row = rows[i - start];
68
- }
69
- let _h = row?.getBoundingClientRect().height;
70
- if (!_h) {
71
- _h = average_height;
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
- const row_height = (height_map[i] = _h);
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 = _items.length - end;
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
- filtered_height_map.length;
99
+ filtered_height_map.length || 30;
90
100
 
91
101
  bottom = remaining * average_height;
92
- height_map.length = _items.length;
93
- await tick();
94
- if (!max_height) {
95
- actual_height = content_height + 1;
96
- } else if (content_height < max_height) {
97
- actual_height = content_height + 2;
98
- } else {
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={handle_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}>