@gradio/tabs 0.5.9 → 0.5.10

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,11 @@
1
1
  # @gradio/tabs
2
2
 
3
+ ## 0.5.10
4
+
5
+ ### Fixes
6
+
7
+ - [#13303](https://github.com/gradio-app/gradio/pull/13303) [`79c5776`](https://github.com/gradio-app/gradio/commit/79c577680978adfb5eeaa01944635e14dc67e5f1) - Rework `Dataframe` wrapping, truncation, and column width sizing. Thanks @pngwn!
8
+
3
9
  ## 0.5.9
4
10
 
5
11
  ### Fixes
@@ -70,10 +70,11 @@
70
70
 
71
71
  onMount(() => {
72
72
  if (!tab_nav_el) return;
73
- const observer = new IntersectionObserver((entries) => {
73
+ const ro = new ResizeObserver(() => {
74
74
  handle_menu_overflow();
75
75
  });
76
- observer.observe(tab_nav_el);
76
+ ro.observe(tab_nav_el);
77
+ return () => ro.disconnect();
77
78
  });
78
79
 
79
80
  setContext(TABS, {
@@ -128,33 +129,42 @@
128
129
  }
129
130
  }
130
131
 
132
+ // approximate width of the "..." overflow button including margin
133
+ const OVERFLOW_BTN_RESERVE = 48;
134
+
131
135
  async function handle_menu_overflow(): Promise<void> {
132
136
  if (!tab_nav_el) return;
133
137
 
134
138
  await tick();
135
- const tab_nav_size = tab_nav_el.getBoundingClientRect();
139
+ await new Promise((r) => requestAnimationFrame(r));
140
+
141
+ const available = tab_nav_el.clientWidth;
136
142
 
137
- let max_width = tab_nav_size.width;
138
- const tab_sizes = get_tab_sizes(tabs, tab_els);
139
- let last_visible_index = 0;
140
- const offset = tab_nav_size.left;
143
+ let cumulative = 0;
144
+ let split_index = tabs.length;
141
145
 
142
- for (let i = tabs.length - 1; i >= 0; i--) {
146
+ for (let i = 0; i < tabs.length; i++) {
143
147
  const tab = tabs[i];
144
- if (!tab) continue;
145
- const tab_rect = tab_sizes[tab.id];
146
- if (!tab_rect) continue;
147
- if (tab_rect.right - offset < max_width) {
148
- last_visible_index = i;
148
+ if (!tab || tab.visible === false || tab.visible === "hidden") continue;
149
+ const el = tab_els[tab.id];
150
+ if (!el) continue;
151
+ cumulative += el.getBoundingClientRect().width;
152
+ const has_more = tabs
153
+ .slice(i + 1)
154
+ .some((t) => t && t.visible !== false && t.visible !== "hidden");
155
+ const limit = has_more ? available - OVERFLOW_BTN_RESERVE : available;
156
+ if (cumulative > limit) {
157
+ split_index = i;
149
158
  break;
150
159
  }
151
160
  }
152
161
 
153
- overflow_tabs = tabs.slice(last_visible_index + 1);
154
- visible_tabs = tabs.slice(0, last_visible_index + 1);
162
+ visible_tabs = tabs.slice(0, split_index);
163
+ overflow_tabs = tabs.slice(split_index);
155
164
 
156
165
  overflow_has_selected_tab = handle_overflow_has_selected_tab($selected_tab);
157
- is_overflowing = overflow_tabs.length > 0;
166
+ is_overflowing =
167
+ overflow_tabs.filter((t) => t && t.visible !== false).length > 0;
158
168
  }
159
169
 
160
170
  $: overflow_has_selected_tab =
@@ -167,18 +177,6 @@
167
177
  return overflow_tabs.some((t) => t?.id === selected_tab);
168
178
  }
169
179
 
170
- function get_tab_sizes(
171
- tabs: (Tab | null)[],
172
- tab_els: Record<string | number, HTMLElement>
173
- ): Record<string | number, DOMRect> {
174
- const tab_sizes: Record<string | number, DOMRect> = {};
175
- tabs.forEach((tab) => {
176
- if (!tab) return;
177
- tab_sizes[tab.id] = tab_els[tab.id]?.getBoundingClientRect();
178
- });
179
- return tab_sizes;
180
- }
181
-
182
180
  $: tab_scale =
183
181
  tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
184
182
  </script>
@@ -277,9 +275,7 @@
277
275
  <style>
278
276
  .tabs {
279
277
  position: relative;
280
- display: flex;
281
278
  flex-direction: column;
282
- gap: var(--layout-gap);
283
279
  }
284
280
 
285
281
  .hide {
@@ -297,6 +293,7 @@
297
293
  position: relative;
298
294
  height: var(--size-8);
299
295
  padding-bottom: var(--size-2);
296
+ margin-bottom: var(--layout-gap);
300
297
  }
301
298
 
302
299
  .tab-container {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/tabs",
3
- "version": "0.5.9",
3
+ "version": "0.5.10",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -70,10 +70,11 @@
70
70
 
71
71
  onMount(() => {
72
72
  if (!tab_nav_el) return;
73
- const observer = new IntersectionObserver((entries) => {
73
+ const ro = new ResizeObserver(() => {
74
74
  handle_menu_overflow();
75
75
  });
76
- observer.observe(tab_nav_el);
76
+ ro.observe(tab_nav_el);
77
+ return () => ro.disconnect();
77
78
  });
78
79
 
79
80
  setContext(TABS, {
@@ -128,33 +129,42 @@
128
129
  }
129
130
  }
130
131
 
132
+ // approximate width of the "..." overflow button including margin
133
+ const OVERFLOW_BTN_RESERVE = 48;
134
+
131
135
  async function handle_menu_overflow(): Promise<void> {
132
136
  if (!tab_nav_el) return;
133
137
 
134
138
  await tick();
135
- const tab_nav_size = tab_nav_el.getBoundingClientRect();
139
+ await new Promise((r) => requestAnimationFrame(r));
140
+
141
+ const available = tab_nav_el.clientWidth;
136
142
 
137
- let max_width = tab_nav_size.width;
138
- const tab_sizes = get_tab_sizes(tabs, tab_els);
139
- let last_visible_index = 0;
140
- const offset = tab_nav_size.left;
143
+ let cumulative = 0;
144
+ let split_index = tabs.length;
141
145
 
142
- for (let i = tabs.length - 1; i >= 0; i--) {
146
+ for (let i = 0; i < tabs.length; i++) {
143
147
  const tab = tabs[i];
144
- if (!tab) continue;
145
- const tab_rect = tab_sizes[tab.id];
146
- if (!tab_rect) continue;
147
- if (tab_rect.right - offset < max_width) {
148
- last_visible_index = i;
148
+ if (!tab || tab.visible === false || tab.visible === "hidden") continue;
149
+ const el = tab_els[tab.id];
150
+ if (!el) continue;
151
+ cumulative += el.getBoundingClientRect().width;
152
+ const has_more = tabs
153
+ .slice(i + 1)
154
+ .some((t) => t && t.visible !== false && t.visible !== "hidden");
155
+ const limit = has_more ? available - OVERFLOW_BTN_RESERVE : available;
156
+ if (cumulative > limit) {
157
+ split_index = i;
149
158
  break;
150
159
  }
151
160
  }
152
161
 
153
- overflow_tabs = tabs.slice(last_visible_index + 1);
154
- visible_tabs = tabs.slice(0, last_visible_index + 1);
162
+ visible_tabs = tabs.slice(0, split_index);
163
+ overflow_tabs = tabs.slice(split_index);
155
164
 
156
165
  overflow_has_selected_tab = handle_overflow_has_selected_tab($selected_tab);
157
- is_overflowing = overflow_tabs.length > 0;
166
+ is_overflowing =
167
+ overflow_tabs.filter((t) => t && t.visible !== false).length > 0;
158
168
  }
159
169
 
160
170
  $: overflow_has_selected_tab =
@@ -167,18 +177,6 @@
167
177
  return overflow_tabs.some((t) => t?.id === selected_tab);
168
178
  }
169
179
 
170
- function get_tab_sizes(
171
- tabs: (Tab | null)[],
172
- tab_els: Record<string | number, HTMLElement>
173
- ): Record<string | number, DOMRect> {
174
- const tab_sizes: Record<string | number, DOMRect> = {};
175
- tabs.forEach((tab) => {
176
- if (!tab) return;
177
- tab_sizes[tab.id] = tab_els[tab.id]?.getBoundingClientRect();
178
- });
179
- return tab_sizes;
180
- }
181
-
182
180
  $: tab_scale =
183
181
  tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
184
182
  </script>
@@ -277,9 +275,7 @@
277
275
  <style>
278
276
  .tabs {
279
277
  position: relative;
280
- display: flex;
281
278
  flex-direction: column;
282
- gap: var(--layout-gap);
283
279
  }
284
280
 
285
281
  .hide {
@@ -297,6 +293,7 @@
297
293
  position: relative;
298
294
  height: var(--size-8);
299
295
  padding-bottom: var(--size-2);
296
+ margin-bottom: var(--layout-gap);
300
297
  }
301
298
 
302
299
  .tab-container {