@gradio/tabs 0.3.5 → 0.4.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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # @gradio/tabs
2
2
 
3
+ ## 0.4.1
4
+
5
+ ### Fixes
6
+
7
+ - [#10372](https://github.com/gradio-app/gradio/pull/10372) [`96bbde2`](https://github.com/gradio-app/gradio/commit/96bbde277e059f79bb2c9898576050e84dab147a) - Allow propogation of fill_height through Rows and Tabs, via scale. Thanks @aliabid94!
8
+
9
+ ## 0.4.0
10
+
11
+ ### Features
12
+
13
+ - [#10192](https://github.com/gradio-app/gradio/pull/10192) [`4fc7fb7`](https://github.com/gradio-app/gradio/commit/4fc7fb777c42af537e4af612423fa44029657d41) - Ensure components can be remounted with their previous data. Thanks @pngwn!
14
+
15
+ ### Dependency updates
16
+
17
+ - @gradio/utils@0.10.0
18
+
3
19
  ## 0.3.5
4
20
 
5
21
  ### Dependency updates
@@ -9,12 +9,14 @@
9
9
  <Template let:args>
10
10
  <Tabs {...args}>
11
11
  <TabItem
12
+ order={0}
12
13
  id="tab-1"
13
14
  label="Image Tab"
14
15
  gradio={undefined}
15
16
  visible
16
17
  interactive
17
18
  elem_classes={["editor-tabitem"]}
19
+ scale={0}
18
20
  >
19
21
  <img
20
22
  style="width: 200px;"
@@ -23,22 +25,26 @@
23
25
  />
24
26
  </TabItem>
25
27
  <TabItem
28
+ order={1}
26
29
  id="tab-2"
27
30
  label="Hidden Tab"
28
31
  gradio={undefined}
29
32
  visible={false}
30
33
  interactive
31
34
  elem_classes={["editor-tabitem"]}
35
+ scale={0}
32
36
  >
33
37
  Secret Tab
34
38
  </TabItem>
35
39
  <TabItem
40
+ order={2}
36
41
  id="tab-3"
37
42
  label="Visible Tab"
38
43
  gradio={undefined}
39
44
  visible
40
45
  interactive
41
46
  elem_classes={["editor-tabitem"]}
47
+ scale={0}
42
48
  >
43
49
  Visible Tab
44
50
  </TabItem>
@@ -21,7 +21,7 @@ const selected_tab = writable(
21
21
  selected || tabs[0]?.id || false
22
22
  );
23
23
  const selected_tab_index = writable(
24
- tabs.findIndex((t) => t.id === selected) || 0
24
+ tabs.findIndex((t) => t?.id === selected) || 0
25
25
  );
26
26
  const dispatch = createEventDispatcher();
27
27
  let is_overflowing = false;
@@ -34,37 +34,29 @@ onMount(() => {
34
34
  observer.observe(tab_nav_el);
35
35
  });
36
36
  setContext(TABS, {
37
- register_tab: (tab) => {
38
- let index = tabs.findIndex((t) => t.id === tab.id);
39
- if (index !== -1) {
40
- tabs[index] = { ...tabs[index], ...tab };
41
- } else {
42
- tabs = [...tabs, tab];
43
- index = tabs.length - 1;
44
- }
37
+ register_tab: (tab, order) => {
38
+ tabs[order] = tab;
45
39
  if ($selected_tab === false && tab.visible && tab.interactive) {
46
40
  $selected_tab = tab.id;
41
+ $selected_tab_index = order;
47
42
  }
48
- return index;
43
+ return order;
49
44
  },
50
- unregister_tab: (tab) => {
51
- const index = tabs.findIndex((t) => t.id === tab.id);
52
- if (index !== -1) {
53
- tabs = tabs.filter((t) => t.id !== tab.id);
54
- if ($selected_tab === tab.id) {
55
- $selected_tab = tabs[0]?.id || false;
56
- }
45
+ unregister_tab: (tab, order) => {
46
+ if ($selected_tab === tab.id) {
47
+ $selected_tab = tabs[0]?.id || false;
57
48
  }
49
+ tabs[order] = null;
58
50
  },
59
51
  selected_tab,
60
52
  selected_tab_index
61
53
  });
62
54
  function change_tab(id) {
63
- const tab_to_activate = tabs.find((t) => t.id === id);
64
- if (tab_to_activate && tab_to_activate.interactive && tab_to_activate.visible && $selected_tab !== tab_to_activate.id) {
55
+ const tab_to_activate = tabs.find((t) => t?.id === id);
56
+ if (id !== void 0 && tab_to_activate && tab_to_activate.interactive && tab_to_activate.visible && $selected_tab !== tab_to_activate.id) {
65
57
  selected = id;
66
58
  $selected_tab = id;
67
- $selected_tab_index = tabs.findIndex((t) => t.id === id);
59
+ $selected_tab_index = tabs.findIndex((t) => t?.id === id);
68
60
  dispatch("change");
69
61
  overflow_menu_open = false;
70
62
  }
@@ -89,6 +81,8 @@ async function handle_menu_overflow() {
89
81
  const offset = tab_nav_size.left;
90
82
  for (let i = tabs.length - 1; i >= 0; i--) {
91
83
  const tab = tabs[i];
84
+ if (!tab)
85
+ continue;
92
86
  const tab_rect = tab_sizes[tab.id];
93
87
  if (!tab_rect)
94
88
  continue;
@@ -107,15 +101,19 @@ $:
107
101
  function handle_overflow_has_selected_tab(selected_tab2) {
108
102
  if (selected_tab2 === false)
109
103
  return false;
110
- return overflow_tabs.some((t) => t.id === selected_tab2);
104
+ return overflow_tabs.some((t) => t?.id === selected_tab2);
111
105
  }
112
106
  function get_tab_sizes(tabs2, tab_els2) {
113
107
  const tab_sizes = {};
114
108
  tabs2.forEach((tab) => {
109
+ if (!tab)
110
+ return;
115
111
  tab_sizes[tab.id] = tab_els2[tab.id]?.getBoundingClientRect();
116
112
  });
117
113
  return tab_sizes;
118
114
  }
115
+ $:
116
+ tab_scale = tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
119
117
  </script>
120
118
 
121
119
  <svelte:window
@@ -123,21 +121,26 @@ function get_tab_sizes(tabs2, tab_els2) {
123
121
  on:click={handle_outside_click}
124
122
  />
125
123
 
126
- <div class="tabs {elem_classes.join(' ')}" class:hide={!visible} id={elem_id}>
124
+ <div
125
+ class="tabs {elem_classes.join(' ')}"
126
+ class:hide={!visible}
127
+ id={elem_id}
128
+ style:flex-grow={tab_scale}
129
+ >
127
130
  {#if has_tabs}
128
131
  <div class="tab-wrapper">
129
132
  <div class="tab-container visually-hidden" aria-hidden="true">
130
- {#each tabs as t, i (t.id)}
131
- {#if t.visible}
133
+ {#each tabs as t, i}
134
+ {#if t?.visible}
132
135
  <button bind:this={tab_els[t.id]}>
133
- {t.label}
136
+ {t?.label}
134
137
  </button>
135
138
  {/if}
136
139
  {/each}
137
140
  </div>
138
141
  <div class="tab-container" bind:this={tab_nav_el} role="tablist">
139
- {#each visible_tabs as t, i (t.id)}
140
- {#if t.visible}
142
+ {#each visible_tabs as t, i}
143
+ {#if t?.visible}
141
144
  <button
142
145
  role="tab"
143
146
  class:selected={t.id === $selected_tab}
@@ -174,10 +177,10 @@ function get_tab_sizes(tabs2, tab_els2) {
174
177
  <div class="overflow-dropdown" class:hide={!overflow_menu_open}>
175
178
  {#each overflow_tabs as t}
176
179
  <button
177
- on:click={() => change_tab(t.id)}
178
- class:selected={t.id === $selected_tab}
180
+ on:click={() => change_tab(t?.id)}
181
+ class:selected={t?.id === $selected_tab}
179
182
  >
180
- {t.label}
183
+ {t?.label}
181
184
  </button>
182
185
  {/each}
183
186
  </div>
@@ -6,6 +6,7 @@ export interface Tab {
6
6
  elem_id: string | undefined;
7
7
  visible: boolean;
8
8
  interactive: boolean;
9
+ scale: number | null;
9
10
  }
10
11
  import type { SelectData } from "@gradio/utils";
11
12
  declare const __propDef: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/tabs",
3
- "version": "0.3.5",
3
+ "version": "0.4.1",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -17,7 +17,7 @@
17
17
  "./package.json": "./package.json"
18
18
  },
19
19
  "dependencies": {
20
- "@gradio/utils": "^0.9.0"
20
+ "@gradio/utils": "^0.10.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@gradio/preview": "^0.13.0"
@@ -7,6 +7,7 @@
7
7
  elem_id: string | undefined;
8
8
  visible: boolean;
9
9
  interactive: boolean;
10
+ scale: number | null;
10
11
  }
11
12
  </script>
12
13
 
@@ -22,9 +23,9 @@
22
23
  export let selected: number | string;
23
24
  export let initial_tabs: Tab[];
24
25
 
25
- let tabs: Tab[] = [...initial_tabs];
26
- let visible_tabs: Tab[] = [...initial_tabs];
27
- let overflow_tabs: Tab[] = [];
26
+ let tabs: (Tab | null)[] = [...initial_tabs];
27
+ let visible_tabs: (Tab | null)[] = [...initial_tabs];
28
+ let overflow_tabs: (Tab | null)[] = [];
28
29
  let overflow_menu_open = false;
29
30
  let overflow_menu: HTMLElement;
30
31
 
@@ -36,7 +37,7 @@
36
37
  selected || tabs[0]?.id || false
37
38
  );
38
39
  const selected_tab_index = writable<number>(
39
- tabs.findIndex((t) => t.id === selected) || 0
40
+ tabs.findIndex((t) => t?.id === selected) || 0
40
41
  );
41
42
  const dispatch = createEventDispatcher<{
42
43
  change: undefined;
@@ -55,35 +56,29 @@
55
56
  });
56
57
 
57
58
  setContext(TABS, {
58
- register_tab: (tab: Tab) => {
59
- let index = tabs.findIndex((t) => t.id === tab.id);
60
- if (index !== -1) {
61
- tabs[index] = { ...tabs[index], ...tab };
62
- } else {
63
- tabs = [...tabs, tab];
64
- index = tabs.length - 1;
65
- }
59
+ register_tab: (tab: Tab, order: number) => {
60
+ tabs[order] = tab;
61
+
66
62
  if ($selected_tab === false && tab.visible && tab.interactive) {
67
63
  $selected_tab = tab.id;
64
+ $selected_tab_index = order;
68
65
  }
69
- return index;
66
+ return order;
70
67
  },
71
- unregister_tab: (tab: Tab) => {
72
- const index = tabs.findIndex((t) => t.id === tab.id);
73
- if (index !== -1) {
74
- tabs = tabs.filter((t) => t.id !== tab.id);
75
- if ($selected_tab === tab.id) {
76
- $selected_tab = tabs[0]?.id || false;
77
- }
68
+ unregister_tab: (tab: Tab, order: number) => {
69
+ if ($selected_tab === tab.id) {
70
+ $selected_tab = tabs[0]?.id || false;
78
71
  }
72
+ tabs[order] = null;
79
73
  },
80
74
  selected_tab,
81
75
  selected_tab_index
82
76
  });
83
77
 
84
- function change_tab(id: string | number): void {
85
- const tab_to_activate = tabs.find((t) => t.id === id);
78
+ function change_tab(id: string | number | undefined): void {
79
+ const tab_to_activate = tabs.find((t) => t?.id === id);
86
80
  if (
81
+ id !== undefined &&
87
82
  tab_to_activate &&
88
83
  tab_to_activate.interactive &&
89
84
  tab_to_activate.visible &&
@@ -91,7 +86,7 @@
91
86
  ) {
92
87
  selected = id;
93
88
  $selected_tab = id;
94
- $selected_tab_index = tabs.findIndex((t) => t.id === id);
89
+ $selected_tab_index = tabs.findIndex((t) => t?.id === id);
95
90
  dispatch("change");
96
91
  overflow_menu_open = false;
97
92
  }
@@ -123,6 +118,7 @@
123
118
 
124
119
  for (let i = tabs.length - 1; i >= 0; i--) {
125
120
  const tab = tabs[i];
121
+ if (!tab) continue;
126
122
  const tab_rect = tab_sizes[tab.id];
127
123
  if (!tab_rect) continue;
128
124
  if (tab_rect.right - offset < max_width) {
@@ -145,19 +141,23 @@
145
141
  selected_tab: number | string | false
146
142
  ): boolean {
147
143
  if (selected_tab === false) return false;
148
- return overflow_tabs.some((t) => t.id === selected_tab);
144
+ return overflow_tabs.some((t) => t?.id === selected_tab);
149
145
  }
150
146
 
151
147
  function get_tab_sizes(
152
- tabs: Tab[],
148
+ tabs: (Tab | null)[],
153
149
  tab_els: Record<string | number, HTMLElement>
154
150
  ): Record<string | number, DOMRect> {
155
151
  const tab_sizes: Record<string | number, DOMRect> = {};
156
152
  tabs.forEach((tab) => {
153
+ if (!tab) return;
157
154
  tab_sizes[tab.id] = tab_els[tab.id]?.getBoundingClientRect();
158
155
  });
159
156
  return tab_sizes;
160
157
  }
158
+
159
+ $: tab_scale =
160
+ tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
161
161
  </script>
162
162
 
163
163
  <svelte:window
@@ -165,21 +165,26 @@
165
165
  on:click={handle_outside_click}
166
166
  />
167
167
 
168
- <div class="tabs {elem_classes.join(' ')}" class:hide={!visible} id={elem_id}>
168
+ <div
169
+ class="tabs {elem_classes.join(' ')}"
170
+ class:hide={!visible}
171
+ id={elem_id}
172
+ style:flex-grow={tab_scale}
173
+ >
169
174
  {#if has_tabs}
170
175
  <div class="tab-wrapper">
171
176
  <div class="tab-container visually-hidden" aria-hidden="true">
172
- {#each tabs as t, i (t.id)}
173
- {#if t.visible}
177
+ {#each tabs as t, i}
178
+ {#if t?.visible}
174
179
  <button bind:this={tab_els[t.id]}>
175
- {t.label}
180
+ {t?.label}
176
181
  </button>
177
182
  {/if}
178
183
  {/each}
179
184
  </div>
180
185
  <div class="tab-container" bind:this={tab_nav_el} role="tablist">
181
- {#each visible_tabs as t, i (t.id)}
182
- {#if t.visible}
186
+ {#each visible_tabs as t, i}
187
+ {#if t?.visible}
183
188
  <button
184
189
  role="tab"
185
190
  class:selected={t.id === $selected_tab}
@@ -216,10 +221,10 @@
216
221
  <div class="overflow-dropdown" class:hide={!overflow_menu_open}>
217
222
  {#each overflow_tabs as t}
218
223
  <button
219
- on:click={() => change_tab(t.id)}
220
- class:selected={t.id === $selected_tab}
224
+ on:click={() => change_tab(t?.id)}
225
+ class:selected={t?.id === $selected_tab}
221
226
  >
222
- {t.label}
227
+ {t?.label}
223
228
  </button>
224
229
  {/each}
225
230
  </div>