@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 +16 -0
- package/Tabs.stories.svelte +6 -0
- package/dist/shared/Tabs.svelte +33 -30
- package/dist/shared/Tabs.svelte.d.ts +1 -0
- package/package.json +2 -2
- package/shared/Tabs.svelte +39 -34
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
|
package/Tabs.stories.svelte
CHANGED
|
@@ -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>
|
package/dist/shared/Tabs.svelte
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
43
|
+
return order;
|
|
49
44
|
},
|
|
50
|
-
unregister_tab: (tab) => {
|
|
51
|
-
|
|
52
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
131
|
-
{#if t
|
|
133
|
+
{#each tabs as t, i}
|
|
134
|
+
{#if t?.visible}
|
|
132
135
|
<button bind:this={tab_els[t.id]}>
|
|
133
|
-
{t
|
|
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
|
|
140
|
-
{#if t
|
|
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
|
|
178
|
-
class:selected={t
|
|
180
|
+
on:click={() => change_tab(t?.id)}
|
|
181
|
+
class:selected={t?.id === $selected_tab}
|
|
179
182
|
>
|
|
180
|
-
{t
|
|
183
|
+
{t?.label}
|
|
181
184
|
</button>
|
|
182
185
|
{/each}
|
|
183
186
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/tabs",
|
|
3
|
-
"version": "0.
|
|
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.
|
|
20
|
+
"@gradio/utils": "^0.10.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@gradio/preview": "^0.13.0"
|
package/shared/Tabs.svelte
CHANGED
|
@@ -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
|
|
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
|
-
|
|
60
|
-
|
|
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
|
|
66
|
+
return order;
|
|
70
67
|
},
|
|
71
|
-
unregister_tab: (tab: Tab) => {
|
|
72
|
-
|
|
73
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
173
|
-
{#if t
|
|
177
|
+
{#each tabs as t, i}
|
|
178
|
+
{#if t?.visible}
|
|
174
179
|
<button bind:this={tab_els[t.id]}>
|
|
175
|
-
{t
|
|
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
|
|
182
|
-
{#if t
|
|
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
|
|
220
|
-
class:selected={t
|
|
224
|
+
on:click={() => change_tab(t?.id)}
|
|
225
|
+
class:selected={t?.id === $selected_tab}
|
|
221
226
|
>
|
|
222
|
-
{t
|
|
227
|
+
{t?.label}
|
|
223
228
|
</button>
|
|
224
229
|
{/each}
|
|
225
230
|
</div>
|