@gradio/tabs 0.4.5 → 0.5.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 +12 -0
- package/Index.svelte +28 -12
- package/Walkthrough.stories.svelte +116 -0
- package/dist/Index.svelte +28 -13
- package/dist/Index.svelte.d.ts +7 -4
- package/dist/shared/OverflowIcon.svelte.d.ts +2 -0
- package/dist/shared/Tabs.svelte +24 -27
- package/dist/shared/Tabs.svelte.d.ts +6 -4
- package/dist/shared/Walkthrough.svelte +410 -0
- package/dist/shared/Walkthrough.svelte.d.ts +29 -0
- package/package.json +2 -2
- package/shared/Tabs.svelte +16 -9
- package/shared/Walkthrough.svelte +449 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @gradio/tabs
|
|
2
2
|
|
|
3
|
+
## 0.5.1
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
- [#11784](https://github.com/gradio-app/gradio/pull/11784) [`d9dd3f5`](https://github.com/gradio-app/gradio/commit/d9dd3f54b7fb34cf7118e549d39fc63937ca3489) - Add "hidden" option to component's `visible` kwarg to render but visually hide the component. Thanks @pngwn!
|
|
8
|
+
|
|
9
|
+
## 0.5.0
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
- [#11783](https://github.com/gradio-app/gradio/pull/11783) [`f407daf`](https://github.com/gradio-app/gradio/commit/f407daf8046f37e042ab8b86730ff0ab8d174bcf) - Add Walkthrough and Step compoents to facilitate multi-step workflows. Thanks @pngwn!
|
|
14
|
+
|
|
3
15
|
## 0.4.5
|
|
4
16
|
|
|
5
17
|
### Fixes
|
package/Index.svelte
CHANGED
|
@@ -6,14 +6,16 @@
|
|
|
6
6
|
import type { Gradio, SelectData } from "@gradio/utils";
|
|
7
7
|
import { createEventDispatcher } from "svelte";
|
|
8
8
|
import Tabs, { type Tab } from "./shared/Tabs.svelte";
|
|
9
|
+
import Walkthrough from "./shared/Walkthrough.svelte";
|
|
9
10
|
|
|
10
11
|
const dispatch = createEventDispatcher();
|
|
11
12
|
|
|
12
|
-
export let visible = true;
|
|
13
|
+
export let visible: boolean | "hidden" = true;
|
|
13
14
|
export let elem_id = "";
|
|
14
15
|
export let elem_classes: string[] = [];
|
|
15
16
|
export let selected: number | string;
|
|
16
17
|
export let initial_tabs: Tab[] = [];
|
|
18
|
+
export let name: "tabs" | "walkthrough" = "tabs";
|
|
17
19
|
export let gradio:
|
|
18
20
|
| Gradio<{
|
|
19
21
|
change: never;
|
|
@@ -24,14 +26,28 @@
|
|
|
24
26
|
$: dispatch("prop_change", { selected });
|
|
25
27
|
</script>
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
{#if name === "walkthrough"}
|
|
30
|
+
<Walkthrough
|
|
31
|
+
{visible}
|
|
32
|
+
{elem_id}
|
|
33
|
+
{elem_classes}
|
|
34
|
+
bind:selected
|
|
35
|
+
on:change={() => gradio?.dispatch("change")}
|
|
36
|
+
on:select={(e) => gradio?.dispatch("select", e.detail)}
|
|
37
|
+
{initial_tabs}
|
|
38
|
+
>
|
|
39
|
+
<slot />
|
|
40
|
+
</Walkthrough>
|
|
41
|
+
{:else}
|
|
42
|
+
<Tabs
|
|
43
|
+
{visible}
|
|
44
|
+
{elem_id}
|
|
45
|
+
{elem_classes}
|
|
46
|
+
bind:selected
|
|
47
|
+
on:change={() => gradio?.dispatch("change")}
|
|
48
|
+
on:select={(e) => gradio?.dispatch("select", e.detail)}
|
|
49
|
+
{initial_tabs}
|
|
50
|
+
>
|
|
51
|
+
<slot />
|
|
52
|
+
</Tabs>
|
|
53
|
+
{/if}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
|
|
3
|
+
import Tabs from "./Index.svelte";
|
|
4
|
+
import TabItem from "../tabitem/Index.svelte";
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<Meta title="Components/Walkthrough" component={Tabs} />
|
|
8
|
+
|
|
9
|
+
<Template let:args>
|
|
10
|
+
<Tabs {...args} name="walkthrough">
|
|
11
|
+
<TabItem
|
|
12
|
+
order={0}
|
|
13
|
+
id="tab-1"
|
|
14
|
+
label="Image Tab"
|
|
15
|
+
gradio={undefined}
|
|
16
|
+
visible
|
|
17
|
+
interactive
|
|
18
|
+
elem_classes={["editor-tabitem"]}
|
|
19
|
+
scale={0}
|
|
20
|
+
>
|
|
21
|
+
<img
|
|
22
|
+
style="width: 200px;"
|
|
23
|
+
alt="Cheetah"
|
|
24
|
+
src="https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg"
|
|
25
|
+
/>
|
|
26
|
+
</TabItem>
|
|
27
|
+
<TabItem
|
|
28
|
+
order={1}
|
|
29
|
+
id="tab-2"
|
|
30
|
+
label="Hidden Tab"
|
|
31
|
+
gradio={undefined}
|
|
32
|
+
visible={false}
|
|
33
|
+
interactive
|
|
34
|
+
elem_classes={["editor-tabitem"]}
|
|
35
|
+
scale={0}
|
|
36
|
+
>
|
|
37
|
+
Secret Tab
|
|
38
|
+
</TabItem>
|
|
39
|
+
<TabItem
|
|
40
|
+
order={2}
|
|
41
|
+
id="tab-3"
|
|
42
|
+
label="Visible Tab"
|
|
43
|
+
gradio={undefined}
|
|
44
|
+
visible
|
|
45
|
+
interactive
|
|
46
|
+
elem_classes={["editor-tabitem"]}
|
|
47
|
+
scale={0}
|
|
48
|
+
>
|
|
49
|
+
Visible Tab
|
|
50
|
+
</TabItem>
|
|
51
|
+
<TabItem
|
|
52
|
+
order={3}
|
|
53
|
+
id="tab-4"
|
|
54
|
+
label="Visible Tab"
|
|
55
|
+
gradio={undefined}
|
|
56
|
+
visible
|
|
57
|
+
interactive
|
|
58
|
+
elem_classes={["editor-tabitem"]}
|
|
59
|
+
scale={0}
|
|
60
|
+
>
|
|
61
|
+
Visible Tab
|
|
62
|
+
</TabItem>
|
|
63
|
+
</Tabs>
|
|
64
|
+
</Template>
|
|
65
|
+
|
|
66
|
+
<Story name="Tabs Walkthrough" args={{}} />
|
|
67
|
+
|
|
68
|
+
<Story name="TabsLastInvisible" args={{}}>
|
|
69
|
+
<Tabs selected="tab-1" gradio={undefined} name="walkthrough">
|
|
70
|
+
<TabItem
|
|
71
|
+
order={0}
|
|
72
|
+
id="tab-1"
|
|
73
|
+
label="This is visible tab 1"
|
|
74
|
+
gradio={undefined}
|
|
75
|
+
visible
|
|
76
|
+
interactive
|
|
77
|
+
scale={0}
|
|
78
|
+
></TabItem>
|
|
79
|
+
<TabItem
|
|
80
|
+
order={1}
|
|
81
|
+
id="tab-2"
|
|
82
|
+
label="This is visible tab 2"
|
|
83
|
+
gradio={undefined}
|
|
84
|
+
visible
|
|
85
|
+
interactive
|
|
86
|
+
scale={0}
|
|
87
|
+
></TabItem>
|
|
88
|
+
<TabItem
|
|
89
|
+
order={2}
|
|
90
|
+
id="tab-3"
|
|
91
|
+
label="This is visible tab 3"
|
|
92
|
+
gradio={undefined}
|
|
93
|
+
visible
|
|
94
|
+
interactive
|
|
95
|
+
scale={0}
|
|
96
|
+
></TabItem>
|
|
97
|
+
<TabItem
|
|
98
|
+
order={3}
|
|
99
|
+
id="tab-4"
|
|
100
|
+
label="This is invisible tab 4"
|
|
101
|
+
gradio={undefined}
|
|
102
|
+
visible={false}
|
|
103
|
+
interactive
|
|
104
|
+
scale={0}
|
|
105
|
+
></TabItem>
|
|
106
|
+
<TabItem
|
|
107
|
+
order={4}
|
|
108
|
+
id="tab-5"
|
|
109
|
+
label="This is invisible tab 5"
|
|
110
|
+
gradio={undefined}
|
|
111
|
+
visible={false}
|
|
112
|
+
interactive
|
|
113
|
+
scale={0}
|
|
114
|
+
></TabItem>
|
|
115
|
+
</Tabs>
|
|
116
|
+
</Story>
|
package/dist/Index.svelte
CHANGED
|
@@ -3,25 +3,40 @@
|
|
|
3
3
|
|
|
4
4
|
<script>import { createEventDispatcher } from "svelte";
|
|
5
5
|
import Tabs, {} from "./shared/Tabs.svelte";
|
|
6
|
+
import Walkthrough from "./shared/Walkthrough.svelte";
|
|
6
7
|
const dispatch = createEventDispatcher();
|
|
7
8
|
export let visible = true;
|
|
8
9
|
export let elem_id = "";
|
|
9
10
|
export let elem_classes = [];
|
|
10
11
|
export let selected;
|
|
11
12
|
export let initial_tabs = [];
|
|
13
|
+
export let name = "tabs";
|
|
12
14
|
export let gradio;
|
|
13
|
-
$:
|
|
14
|
-
dispatch("prop_change", { selected });
|
|
15
|
+
$: dispatch("prop_change", { selected });
|
|
15
16
|
</script>
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
{#if name === "walkthrough"}
|
|
19
|
+
<Walkthrough
|
|
20
|
+
{visible}
|
|
21
|
+
{elem_id}
|
|
22
|
+
{elem_classes}
|
|
23
|
+
bind:selected
|
|
24
|
+
on:change={() => gradio?.dispatch("change")}
|
|
25
|
+
on:select={(e) => gradio?.dispatch("select", e.detail)}
|
|
26
|
+
{initial_tabs}
|
|
27
|
+
>
|
|
28
|
+
<slot />
|
|
29
|
+
</Walkthrough>
|
|
30
|
+
{:else}
|
|
31
|
+
<Tabs
|
|
32
|
+
{visible}
|
|
33
|
+
{elem_id}
|
|
34
|
+
{elem_classes}
|
|
35
|
+
bind:selected
|
|
36
|
+
on:change={() => gradio?.dispatch("change")}
|
|
37
|
+
on:select={(e) => gradio?.dispatch("select", e.detail)}
|
|
38
|
+
{initial_tabs}
|
|
39
|
+
>
|
|
40
|
+
<slot />
|
|
41
|
+
</Tabs>
|
|
42
|
+
{/if}
|
package/dist/Index.svelte.d.ts
CHANGED
|
@@ -4,11 +4,12 @@ import type { Gradio, SelectData } from "@gradio/utils";
|
|
|
4
4
|
import { type Tab } from "./shared/Tabs.svelte";
|
|
5
5
|
declare const __propDef: {
|
|
6
6
|
props: {
|
|
7
|
-
visible?: boolean |
|
|
8
|
-
elem_id?: string
|
|
9
|
-
elem_classes?: string[]
|
|
7
|
+
visible?: boolean | "hidden";
|
|
8
|
+
elem_id?: string;
|
|
9
|
+
elem_classes?: string[];
|
|
10
10
|
selected: number | string;
|
|
11
|
-
initial_tabs?: Tab[]
|
|
11
|
+
initial_tabs?: Tab[];
|
|
12
|
+
name?: "tabs" | "walkthrough";
|
|
12
13
|
gradio: Gradio<{
|
|
13
14
|
change: never;
|
|
14
15
|
select: SelectData;
|
|
@@ -22,6 +23,8 @@ declare const __propDef: {
|
|
|
22
23
|
slots: {
|
|
23
24
|
default: {};
|
|
24
25
|
};
|
|
26
|
+
exports?: {} | undefined;
|
|
27
|
+
bindings?: string | undefined;
|
|
25
28
|
};
|
|
26
29
|
export type IndexProps = typeof __propDef.props;
|
|
27
30
|
export type IndexEvents = typeof __propDef.events;
|
package/dist/shared/Tabs.svelte
CHANGED
|
@@ -14,8 +14,7 @@ let visible_tabs = [...initial_tabs];
|
|
|
14
14
|
let overflow_tabs = [];
|
|
15
15
|
let overflow_menu_open = false;
|
|
16
16
|
let overflow_menu;
|
|
17
|
-
$:
|
|
18
|
-
has_tabs = tabs.length > 0;
|
|
17
|
+
$: has_tabs = tabs.length > 0;
|
|
19
18
|
let tab_nav_el;
|
|
20
19
|
const selected_tab = writable(
|
|
21
20
|
selected || tabs[0]?.id || false
|
|
@@ -28,6 +27,7 @@ let is_overflowing = false;
|
|
|
28
27
|
let overflow_has_selected_tab = false;
|
|
29
28
|
let tab_els = {};
|
|
30
29
|
onMount(() => {
|
|
30
|
+
if (!tab_nav_el) return;
|
|
31
31
|
const observer = new IntersectionObserver((entries) => {
|
|
32
32
|
handle_menu_overflow();
|
|
33
33
|
});
|
|
@@ -36,7 +36,7 @@ onMount(() => {
|
|
|
36
36
|
setContext(TABS, {
|
|
37
37
|
register_tab: (tab, order) => {
|
|
38
38
|
tabs[order] = tab;
|
|
39
|
-
if ($selected_tab === false && tab.visible && tab.interactive) {
|
|
39
|
+
if ($selected_tab === false && tab.visible !== false && tab.interactive) {
|
|
40
40
|
$selected_tab = tab.id;
|
|
41
41
|
$selected_tab_index = order;
|
|
42
42
|
}
|
|
@@ -53,7 +53,7 @@ setContext(TABS, {
|
|
|
53
53
|
});
|
|
54
54
|
function change_tab(id) {
|
|
55
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) {
|
|
56
|
+
if (id !== void 0 && tab_to_activate && tab_to_activate.interactive && tab_to_activate.visible !== false && $selected_tab !== tab_to_activate.id) {
|
|
57
57
|
selected = id;
|
|
58
58
|
$selected_tab = id;
|
|
59
59
|
$selected_tab_index = tabs.findIndex((t) => t?.id === id);
|
|
@@ -61,18 +61,15 @@ function change_tab(id) {
|
|
|
61
61
|
overflow_menu_open = false;
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
$:
|
|
65
|
-
|
|
66
|
-
$:
|
|
67
|
-
tabs, tab_nav_el, tab_els, handle_menu_overflow();
|
|
64
|
+
$: tabs, selected !== null && change_tab(selected);
|
|
65
|
+
$: tabs, tab_nav_el, tab_els, handle_menu_overflow();
|
|
68
66
|
function handle_outside_click(event) {
|
|
69
67
|
if (overflow_menu_open && overflow_menu && !overflow_menu.contains(event.target)) {
|
|
70
68
|
overflow_menu_open = false;
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
async function handle_menu_overflow() {
|
|
74
|
-
if (!tab_nav_el)
|
|
75
|
-
return;
|
|
72
|
+
if (!tab_nav_el) return;
|
|
76
73
|
await tick();
|
|
77
74
|
const tab_nav_size = tab_nav_el.getBoundingClientRect();
|
|
78
75
|
let max_width = tab_nav_size.width;
|
|
@@ -81,11 +78,9 @@ async function handle_menu_overflow() {
|
|
|
81
78
|
const offset = tab_nav_size.left;
|
|
82
79
|
for (let i = tabs.length - 1; i >= 0; i--) {
|
|
83
80
|
const tab = tabs[i];
|
|
84
|
-
if (!tab)
|
|
85
|
-
continue;
|
|
81
|
+
if (!tab) continue;
|
|
86
82
|
const tab_rect = tab_sizes[tab.id];
|
|
87
|
-
if (!tab_rect)
|
|
88
|
-
continue;
|
|
83
|
+
if (!tab_rect) continue;
|
|
89
84
|
if (tab_rect.right - offset < max_width) {
|
|
90
85
|
last_visible_index = i;
|
|
91
86
|
break;
|
|
@@ -96,24 +91,20 @@ async function handle_menu_overflow() {
|
|
|
96
91
|
overflow_has_selected_tab = handle_overflow_has_selected_tab($selected_tab);
|
|
97
92
|
is_overflowing = overflow_tabs.length > 0;
|
|
98
93
|
}
|
|
99
|
-
$:
|
|
100
|
-
overflow_has_selected_tab = handle_overflow_has_selected_tab($selected_tab);
|
|
94
|
+
$: overflow_has_selected_tab = handle_overflow_has_selected_tab($selected_tab);
|
|
101
95
|
function handle_overflow_has_selected_tab(selected_tab2) {
|
|
102
|
-
if (selected_tab2 === false)
|
|
103
|
-
return false;
|
|
96
|
+
if (selected_tab2 === false) return false;
|
|
104
97
|
return overflow_tabs.some((t) => t?.id === selected_tab2);
|
|
105
98
|
}
|
|
106
99
|
function get_tab_sizes(tabs2, tab_els2) {
|
|
107
100
|
const tab_sizes = {};
|
|
108
101
|
tabs2.forEach((tab) => {
|
|
109
|
-
if (!tab)
|
|
110
|
-
return;
|
|
102
|
+
if (!tab) return;
|
|
111
103
|
tab_sizes[tab.id] = tab_els2[tab.id]?.getBoundingClientRect();
|
|
112
104
|
});
|
|
113
105
|
return tab_sizes;
|
|
114
106
|
}
|
|
115
|
-
$:
|
|
116
|
-
tab_scale = tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
|
|
107
|
+
$: tab_scale = tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
|
|
117
108
|
</script>
|
|
118
109
|
|
|
119
110
|
<svelte:window
|
|
@@ -123,7 +114,8 @@ $:
|
|
|
123
114
|
|
|
124
115
|
<div
|
|
125
116
|
class="tabs {elem_classes.join(' ')}"
|
|
126
|
-
class:hide={
|
|
117
|
+
class:hide={visible === false}
|
|
118
|
+
class:hidden={visible === "hidden"}
|
|
127
119
|
id={elem_id}
|
|
128
120
|
style:flex-grow={tab_scale}
|
|
129
121
|
>
|
|
@@ -131,7 +123,7 @@ $:
|
|
|
131
123
|
<div class="tab-wrapper">
|
|
132
124
|
<div class="tab-container visually-hidden" aria-hidden="true">
|
|
133
125
|
{#each tabs as t, i}
|
|
134
|
-
{#if t?.visible}
|
|
126
|
+
{#if t && t?.visible !== false && t?.visible !== "hidden"}
|
|
135
127
|
<button bind:this={tab_els[t.id]}>
|
|
136
128
|
{t?.label}
|
|
137
129
|
</button>
|
|
@@ -140,7 +132,7 @@ $:
|
|
|
140
132
|
</div>
|
|
141
133
|
<div class="tab-container" bind:this={tab_nav_el} role="tablist">
|
|
142
134
|
{#each visible_tabs as t, i}
|
|
143
|
-
{#if t?.visible}
|
|
135
|
+
{#if t && t?.visible !== false}
|
|
144
136
|
<button
|
|
145
137
|
role="tab"
|
|
146
138
|
class:selected={t.id === $selected_tab}
|
|
@@ -164,7 +156,8 @@ $:
|
|
|
164
156
|
</div>
|
|
165
157
|
<span
|
|
166
158
|
class="overflow-menu"
|
|
167
|
-
class:hide={!is_overflowing ||
|
|
159
|
+
class:hide={!is_overflowing ||
|
|
160
|
+
!overflow_tabs.some((t) => t?.visible !== false)}
|
|
168
161
|
bind:this={overflow_menu}
|
|
169
162
|
>
|
|
170
163
|
<button
|
|
@@ -176,7 +169,7 @@ $:
|
|
|
176
169
|
</button>
|
|
177
170
|
<div class="overflow-dropdown" class:hide={!overflow_menu_open}>
|
|
178
171
|
{#each overflow_tabs as t}
|
|
179
|
-
{#if t?.visible}
|
|
172
|
+
{#if t?.visible !== false}
|
|
180
173
|
<button
|
|
181
174
|
on:click={() => change_tab(t?.id)}
|
|
182
175
|
class:selected={t?.id === $selected_tab}
|
|
@@ -204,6 +197,10 @@ $:
|
|
|
204
197
|
display: none;
|
|
205
198
|
}
|
|
206
199
|
|
|
200
|
+
.hidden {
|
|
201
|
+
display: none !important;
|
|
202
|
+
}
|
|
203
|
+
|
|
207
204
|
.tab-wrapper {
|
|
208
205
|
display: flex;
|
|
209
206
|
align-items: center;
|
|
@@ -4,16 +4,16 @@ export interface Tab {
|
|
|
4
4
|
label: string;
|
|
5
5
|
id: string | number;
|
|
6
6
|
elem_id: string | undefined;
|
|
7
|
-
visible: boolean;
|
|
7
|
+
visible: boolean | "hidden";
|
|
8
8
|
interactive: boolean;
|
|
9
9
|
scale: number | null;
|
|
10
10
|
}
|
|
11
11
|
import type { SelectData } from "@gradio/utils";
|
|
12
12
|
declare const __propDef: {
|
|
13
13
|
props: {
|
|
14
|
-
visible?: boolean |
|
|
15
|
-
elem_id?: string
|
|
16
|
-
elem_classes?: string[]
|
|
14
|
+
visible?: boolean | "hidden";
|
|
15
|
+
elem_id?: string;
|
|
16
|
+
elem_classes?: string[];
|
|
17
17
|
selected: number | string;
|
|
18
18
|
initial_tabs: Tab[];
|
|
19
19
|
};
|
|
@@ -26,6 +26,8 @@ declare const __propDef: {
|
|
|
26
26
|
slots: {
|
|
27
27
|
default: {};
|
|
28
28
|
};
|
|
29
|
+
exports?: {} | undefined;
|
|
30
|
+
bindings?: string | undefined;
|
|
29
31
|
};
|
|
30
32
|
export type TabsProps = typeof __propDef.props;
|
|
31
33
|
export type TabsEvents = typeof __propDef.events;
|