@gradio/tabs 0.5.1 → 0.5.2-dev.0
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 +6 -0
- package/Index.svelte +26 -32
- package/dist/Index.svelte +33 -28
- package/dist/Index.svelte.d.ts +18 -30
- package/dist/shared/OverflowIcon.svelte.d.ts +22 -21
- package/dist/shared/Tabs.svelte +160 -106
- package/dist/shared/Tabs.svelte.d.ts +34 -25
- package/dist/shared/Walkthrough.svelte +149 -110
- package/dist/shared/Walkthrough.svelte.d.ts +34 -25
- package/dist/types.d.ts +14 -0
- package/dist/types.js +1 -0
- package/package.json +4 -4
- package/shared/Tabs.svelte +3 -3
- package/shared/Walkthrough.svelte +4 -4
- package/types.ts +16 -0
package/CHANGELOG.md
CHANGED
package/Index.svelte
CHANGED
|
@@ -3,50 +3,44 @@
|
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import Tabs, { type Tab } from "./shared/Tabs.svelte";
|
|
6
|
+
import { Gradio } from "@gradio/utils";
|
|
7
|
+
import Tabs from "./shared/Tabs.svelte";
|
|
9
8
|
import Walkthrough from "./shared/Walkthrough.svelte";
|
|
9
|
+
import type { TabsProps, TabsEvents } from "./types";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
let props = $props();
|
|
12
|
+
const gradio = new Gradio<TabsEvents, TabsProps>(props);
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
export let elem_id = "";
|
|
15
|
-
export let elem_classes: string[] = [];
|
|
16
|
-
export let selected: number | string;
|
|
17
|
-
export let initial_tabs: Tab[] = [];
|
|
18
|
-
export let name: "tabs" | "walkthrough" = "tabs";
|
|
19
|
-
export let gradio:
|
|
20
|
-
| Gradio<{
|
|
21
|
-
change: never;
|
|
22
|
-
select: SelectData;
|
|
23
|
-
}>
|
|
24
|
-
| undefined;
|
|
14
|
+
let old_selected = $state(gradio.props.selected);
|
|
25
15
|
|
|
26
|
-
|
|
16
|
+
$effect(() => {
|
|
17
|
+
if (old_selected !== gradio.props.selected) {
|
|
18
|
+
old_selected = gradio.props.selected;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
27
21
|
</script>
|
|
28
22
|
|
|
29
|
-
{#if name === "walkthrough"}
|
|
23
|
+
{#if gradio.props.name === "walkthrough"}
|
|
30
24
|
<Walkthrough
|
|
31
|
-
{visible}
|
|
32
|
-
{elem_id}
|
|
33
|
-
{elem_classes}
|
|
34
|
-
bind:selected
|
|
35
|
-
on:change={() => gradio
|
|
36
|
-
on:select={(e) => gradio
|
|
37
|
-
{initial_tabs}
|
|
25
|
+
visible={gradio.shared.visible}
|
|
26
|
+
elem_id={gradio.shared.elem_id}
|
|
27
|
+
elem_classes={gradio.shared.elem_classes}
|
|
28
|
+
bind:selected={gradio.props.selected}
|
|
29
|
+
on:change={() => gradio.dispatch("change")}
|
|
30
|
+
on:select={(e) => gradio.dispatch("select", e.detail)}
|
|
31
|
+
initial_tabs={gradio.props.initial_tabs}
|
|
38
32
|
>
|
|
39
33
|
<slot />
|
|
40
34
|
</Walkthrough>
|
|
41
35
|
{:else}
|
|
42
36
|
<Tabs
|
|
43
|
-
{visible}
|
|
44
|
-
{elem_id}
|
|
45
|
-
{elem_classes}
|
|
46
|
-
bind:selected
|
|
47
|
-
on:change={() => gradio
|
|
48
|
-
on:select={(e) => gradio
|
|
49
|
-
{initial_tabs}
|
|
37
|
+
visible={gradio.shared.visible}
|
|
38
|
+
elem_id={gradio.shared.elem_id}
|
|
39
|
+
elem_classes={gradio.shared.elem_classes}
|
|
40
|
+
bind:selected={gradio.props.selected}
|
|
41
|
+
on:change={() => gradio.dispatch("change")}
|
|
42
|
+
on:select={(e) => gradio.dispatch("select", e.detail)}
|
|
43
|
+
initial_tabs={gradio.props.initial_tabs}
|
|
50
44
|
>
|
|
51
45
|
<slot />
|
|
52
46
|
</Tabs>
|
package/dist/Index.svelte
CHANGED
|
@@ -1,41 +1,46 @@
|
|
|
1
|
-
<script context="module"
|
|
1
|
+
<script context="module" lang="ts">
|
|
2
|
+
export { default as BaseTabs, TABS, type Tab } from "./shared/Tabs.svelte";
|
|
2
3
|
</script>
|
|
3
4
|
|
|
4
|
-
<script
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import { Gradio } from "@gradio/utils";
|
|
7
|
+
import Tabs from "./shared/Tabs.svelte";
|
|
8
|
+
import Walkthrough from "./shared/Walkthrough.svelte";
|
|
9
|
+
import type { TabsProps, TabsEvents } from "./types";
|
|
10
|
+
|
|
11
|
+
let props = $props();
|
|
12
|
+
const gradio = new Gradio<TabsEvents, TabsProps>(props);
|
|
13
|
+
|
|
14
|
+
let old_selected = $state(gradio.props.selected);
|
|
15
|
+
|
|
16
|
+
$effect(() => {
|
|
17
|
+
if (old_selected !== gradio.props.selected) {
|
|
18
|
+
old_selected = gradio.props.selected;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
16
21
|
</script>
|
|
17
22
|
|
|
18
|
-
{#if name === "walkthrough"}
|
|
23
|
+
{#if gradio.props.name === "walkthrough"}
|
|
19
24
|
<Walkthrough
|
|
20
|
-
{visible}
|
|
21
|
-
{elem_id}
|
|
22
|
-
{elem_classes}
|
|
23
|
-
bind:selected
|
|
24
|
-
on:change={() => gradio
|
|
25
|
-
on:select={(e) => gradio
|
|
26
|
-
{initial_tabs}
|
|
25
|
+
visible={gradio.shared.visible}
|
|
26
|
+
elem_id={gradio.shared.elem_id}
|
|
27
|
+
elem_classes={gradio.shared.elem_classes}
|
|
28
|
+
bind:selected={gradio.props.selected}
|
|
29
|
+
on:change={() => gradio.dispatch("change")}
|
|
30
|
+
on:select={(e) => gradio.dispatch("select", e.detail)}
|
|
31
|
+
initial_tabs={gradio.props.initial_tabs}
|
|
27
32
|
>
|
|
28
33
|
<slot />
|
|
29
34
|
</Walkthrough>
|
|
30
35
|
{:else}
|
|
31
36
|
<Tabs
|
|
32
|
-
{visible}
|
|
33
|
-
{elem_id}
|
|
34
|
-
{elem_classes}
|
|
35
|
-
bind:selected
|
|
36
|
-
on:change={() => gradio
|
|
37
|
-
on:select={(e) => gradio
|
|
38
|
-
{initial_tabs}
|
|
37
|
+
visible={gradio.shared.visible}
|
|
38
|
+
elem_id={gradio.shared.elem_id}
|
|
39
|
+
elem_classes={gradio.shared.elem_classes}
|
|
40
|
+
bind:selected={gradio.props.selected}
|
|
41
|
+
on:change={() => gradio.dispatch("change")}
|
|
42
|
+
on:select={(e) => gradio.dispatch("select", e.detail)}
|
|
43
|
+
initial_tabs={gradio.props.initial_tabs}
|
|
39
44
|
>
|
|
40
45
|
<slot />
|
|
41
46
|
</Tabs>
|
package/dist/Index.svelte.d.ts
CHANGED
|
@@ -1,33 +1,21 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
export { default as BaseTabs, TABS, type Tab } from "./shared/Tabs.svelte";
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
gradio: Gradio<{
|
|
14
|
-
change: never;
|
|
15
|
-
select: SelectData;
|
|
16
|
-
}> | undefined;
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: Props & {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
17
12
|
};
|
|
18
|
-
|
|
19
|
-
prop_change: CustomEvent<any>;
|
|
20
|
-
} & {
|
|
21
|
-
[evt: string]: CustomEvent<any>;
|
|
22
|
-
};
|
|
23
|
-
slots: {
|
|
24
|
-
default: {};
|
|
25
|
-
};
|
|
26
|
-
exports?: {} | undefined;
|
|
27
|
-
bindings?: string | undefined;
|
|
28
|
-
};
|
|
29
|
-
export type IndexProps = typeof __propDef.props;
|
|
30
|
-
export type IndexEvents = typeof __propDef.events;
|
|
31
|
-
export type IndexSlots = typeof __propDef.slots;
|
|
32
|
-
export default class Index extends SvelteComponent<IndexProps, IndexEvents, IndexSlots> {
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
33
14
|
}
|
|
15
|
+
declare const Index: $$__sveltets_2_IsomorphicComponent<any, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {
|
|
18
|
+
default: {};
|
|
19
|
+
}, {}, "">;
|
|
20
|
+
type Index = InstanceType<typeof Index>;
|
|
21
|
+
export default Index;
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/** @typedef {typeof __propDef.slots} OverflowIconSlots */
|
|
4
|
-
export default class OverflowIcon extends SvelteComponent<{
|
|
1
|
+
export default OverflowIcon;
|
|
2
|
+
type OverflowIcon = SvelteComponent<{
|
|
5
3
|
[x: string]: never;
|
|
6
4
|
}, {
|
|
7
5
|
[evt: string]: CustomEvent<any>;
|
|
8
|
-
}, {}> {
|
|
9
|
-
|
|
10
|
-
export type OverflowIconProps = typeof __propDef.props;
|
|
11
|
-
export type OverflowIconEvents = typeof __propDef.events;
|
|
12
|
-
export type OverflowIconSlots = typeof __propDef.slots;
|
|
13
|
-
import { SvelteComponent } from "svelte";
|
|
14
|
-
declare const __propDef: {
|
|
15
|
-
props: {
|
|
16
|
-
[x: string]: never;
|
|
17
|
-
};
|
|
18
|
-
events: {
|
|
19
|
-
[evt: string]: CustomEvent<any>;
|
|
20
|
-
};
|
|
21
|
-
slots: {};
|
|
22
|
-
exports?: undefined;
|
|
23
|
-
bindings?: undefined;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
24
8
|
};
|
|
25
|
-
|
|
9
|
+
declare const OverflowIcon: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
+
[x: string]: never;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}, {}, string>;
|
|
14
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
15
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
16
|
+
$$bindings?: Bindings;
|
|
17
|
+
} & Exports;
|
|
18
|
+
(internal: unknown, props: {
|
|
19
|
+
$$events?: Events;
|
|
20
|
+
$$slots?: Slots;
|
|
21
|
+
}): Exports & {
|
|
22
|
+
$set?: any;
|
|
23
|
+
$on?: any;
|
|
24
|
+
};
|
|
25
|
+
z_$$bindings?: Bindings;
|
|
26
|
+
}
|
package/dist/shared/Tabs.svelte
CHANGED
|
@@ -1,110 +1,164 @@
|
|
|
1
|
-
<script context="module"
|
|
1
|
+
<script context="module" lang="ts">
|
|
2
|
+
export const TABS = {};
|
|
3
|
+
|
|
4
|
+
export interface Tab {
|
|
5
|
+
label: string;
|
|
6
|
+
id: string | number;
|
|
7
|
+
elem_id: string | undefined;
|
|
8
|
+
visible: boolean | "hidden";
|
|
9
|
+
interactive: boolean;
|
|
10
|
+
scale: number | null;
|
|
11
|
+
}
|
|
2
12
|
</script>
|
|
3
13
|
|
|
4
|
-
<script
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export let
|
|
11
|
-
export let
|
|
12
|
-
let
|
|
13
|
-
let
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
import { setContext, createEventDispatcher, tick, onMount } from "svelte";
|
|
16
|
+
import OverflowIcon from "./OverflowIcon.svelte";
|
|
17
|
+
import { writable } from "svelte/store";
|
|
18
|
+
import type { SelectData } from "@gradio/utils";
|
|
19
|
+
|
|
20
|
+
export let visible: boolean | "hidden" = true;
|
|
21
|
+
export let elem_id = "";
|
|
22
|
+
export let elem_classes: string[] = [];
|
|
23
|
+
export let selected: number | string;
|
|
24
|
+
export let initial_tabs: Tab[];
|
|
25
|
+
|
|
26
|
+
let tabs: (Tab | null)[] = [...initial_tabs];
|
|
27
|
+
let visible_tabs: (Tab | null)[] = [...initial_tabs];
|
|
28
|
+
let overflow_tabs: (Tab | null)[] = [];
|
|
29
|
+
let overflow_menu_open = false;
|
|
30
|
+
let overflow_menu: HTMLElement;
|
|
31
|
+
|
|
32
|
+
$: has_tabs = tabs.length > 0;
|
|
33
|
+
|
|
34
|
+
let tab_nav_el: HTMLDivElement;
|
|
35
|
+
|
|
36
|
+
const selected_tab = writable<false | number | string>(
|
|
37
|
+
selected || tabs[0]?.id || false
|
|
38
|
+
);
|
|
39
|
+
const selected_tab_index = writable<number>(
|
|
40
|
+
tabs.findIndex((t) => t?.id === selected) || 0
|
|
41
|
+
);
|
|
42
|
+
const dispatch = createEventDispatcher<{
|
|
43
|
+
change: undefined;
|
|
44
|
+
select: SelectData;
|
|
45
|
+
}>();
|
|
46
|
+
|
|
47
|
+
let is_overflowing = false;
|
|
48
|
+
let overflow_has_selected_tab = false;
|
|
49
|
+
let tab_els: Record<string | number, HTMLElement> = {};
|
|
50
|
+
|
|
51
|
+
onMount(() => {
|
|
52
|
+
if (!tab_nav_el) return;
|
|
53
|
+
const observer = new IntersectionObserver((entries) => {
|
|
54
|
+
handle_menu_overflow();
|
|
55
|
+
});
|
|
56
|
+
observer.observe(tab_nav_el);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
setContext(TABS, {
|
|
60
|
+
register_tab: (tab: Tab, order: number) => {
|
|
61
|
+
tabs[order] = tab;
|
|
62
|
+
|
|
63
|
+
if ($selected_tab === false && tab.visible !== false && tab.interactive) {
|
|
64
|
+
$selected_tab = tab.id;
|
|
65
|
+
$selected_tab_index = order;
|
|
66
|
+
}
|
|
67
|
+
return order;
|
|
68
|
+
},
|
|
69
|
+
unregister_tab: (tab: Tab, order: number) => {
|
|
70
|
+
if ($selected_tab === tab.id) {
|
|
71
|
+
$selected_tab = tabs[0]?.id || false;
|
|
72
|
+
}
|
|
73
|
+
tabs[order] = null;
|
|
74
|
+
},
|
|
75
|
+
selected_tab,
|
|
76
|
+
selected_tab_index
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
function change_tab(id: string | number | undefined): void {
|
|
80
|
+
const tab_to_activate = tabs.find((t) => t?.id === id);
|
|
81
|
+
if (
|
|
82
|
+
id !== undefined &&
|
|
83
|
+
tab_to_activate &&
|
|
84
|
+
tab_to_activate.interactive &&
|
|
85
|
+
tab_to_activate.visible !== false &&
|
|
86
|
+
$selected_tab !== tab_to_activate.id
|
|
87
|
+
) {
|
|
88
|
+
selected = id;
|
|
89
|
+
$selected_tab = id;
|
|
90
|
+
$selected_tab_index = tabs.findIndex((t) => t?.id === id);
|
|
91
|
+
dispatch("change");
|
|
92
|
+
overflow_menu_open = false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
$: (tabs, selected !== null && change_tab(selected));
|
|
97
|
+
$: (tabs, tab_nav_el, tab_els, handle_menu_overflow());
|
|
98
|
+
|
|
99
|
+
function handle_outside_click(event: MouseEvent): void {
|
|
100
|
+
if (
|
|
101
|
+
overflow_menu_open &&
|
|
102
|
+
overflow_menu &&
|
|
103
|
+
!overflow_menu.contains(event.target as Node)
|
|
104
|
+
) {
|
|
105
|
+
overflow_menu_open = false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function handle_menu_overflow(): Promise<void> {
|
|
110
|
+
if (!tab_nav_el) return;
|
|
111
|
+
|
|
112
|
+
await tick();
|
|
113
|
+
const tab_nav_size = tab_nav_el.getBoundingClientRect();
|
|
114
|
+
|
|
115
|
+
let max_width = tab_nav_size.width;
|
|
116
|
+
const tab_sizes = get_tab_sizes(tabs, tab_els);
|
|
117
|
+
let last_visible_index = 0;
|
|
118
|
+
const offset = tab_nav_size.left;
|
|
119
|
+
|
|
120
|
+
for (let i = tabs.length - 1; i >= 0; i--) {
|
|
121
|
+
const tab = tabs[i];
|
|
122
|
+
if (!tab) continue;
|
|
123
|
+
const tab_rect = tab_sizes[tab.id];
|
|
124
|
+
if (!tab_rect) continue;
|
|
125
|
+
if (tab_rect.right - offset < max_width) {
|
|
126
|
+
last_visible_index = i;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
overflow_tabs = tabs.slice(last_visible_index + 1);
|
|
132
|
+
visible_tabs = tabs.slice(0, last_visible_index + 1);
|
|
133
|
+
|
|
134
|
+
overflow_has_selected_tab = handle_overflow_has_selected_tab($selected_tab);
|
|
135
|
+
is_overflowing = overflow_tabs.length > 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
$: overflow_has_selected_tab =
|
|
139
|
+
handle_overflow_has_selected_tab($selected_tab);
|
|
140
|
+
|
|
141
|
+
function handle_overflow_has_selected_tab(
|
|
142
|
+
selected_tab: number | string | false
|
|
143
|
+
): boolean {
|
|
144
|
+
if (selected_tab === false) return false;
|
|
145
|
+
return overflow_tabs.some((t) => t?.id === selected_tab);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function get_tab_sizes(
|
|
149
|
+
tabs: (Tab | null)[],
|
|
150
|
+
tab_els: Record<string | number, HTMLElement>
|
|
151
|
+
): Record<string | number, DOMRect> {
|
|
152
|
+
const tab_sizes: Record<string | number, DOMRect> = {};
|
|
153
|
+
tabs.forEach((tab) => {
|
|
154
|
+
if (!tab) return;
|
|
155
|
+
tab_sizes[tab.id] = tab_els[tab.id]?.getBoundingClientRect();
|
|
156
|
+
});
|
|
157
|
+
return tab_sizes;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
$: tab_scale =
|
|
161
|
+
tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
|
|
108
162
|
</script>
|
|
109
163
|
|
|
110
164
|
<svelte:window
|
|
@@ -145,7 +199,7 @@ $: tab_scale = tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
|
|
|
145
199
|
on:click={() => {
|
|
146
200
|
if (t.id !== $selected_tab) {
|
|
147
201
|
change_tab(t.id);
|
|
148
|
-
dispatch("select", { value: t.label, index: i });
|
|
202
|
+
dispatch("select", { value: t.label, index: i, id: t.id });
|
|
149
203
|
}
|
|
150
204
|
}}
|
|
151
205
|
>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
export declare const TABS: {};
|
|
3
2
|
export interface Tab {
|
|
4
3
|
label: string;
|
|
@@ -9,29 +8,39 @@ export interface Tab {
|
|
|
9
8
|
scale: number | null;
|
|
10
9
|
}
|
|
11
10
|
import type { SelectData } from "@gradio/utils";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
12
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
13
|
+
$$bindings?: Bindings;
|
|
14
|
+
} & Exports;
|
|
15
|
+
(internal: unknown, props: Props & {
|
|
16
|
+
$$events?: Events;
|
|
17
|
+
$$slots?: Slots;
|
|
18
|
+
}): Exports & {
|
|
19
|
+
$set?: any;
|
|
20
|
+
$on?: any;
|
|
19
21
|
};
|
|
20
|
-
|
|
21
|
-
change: CustomEvent<undefined>;
|
|
22
|
-
select: CustomEvent<SelectData>;
|
|
23
|
-
} & {
|
|
24
|
-
[evt: string]: CustomEvent<any>;
|
|
25
|
-
};
|
|
26
|
-
slots: {
|
|
27
|
-
default: {};
|
|
28
|
-
};
|
|
29
|
-
exports?: {} | undefined;
|
|
30
|
-
bindings?: string | undefined;
|
|
31
|
-
};
|
|
32
|
-
export type TabsProps = typeof __propDef.props;
|
|
33
|
-
export type TabsEvents = typeof __propDef.events;
|
|
34
|
-
export type TabsSlots = typeof __propDef.slots;
|
|
35
|
-
export default class Tabs extends SvelteComponent<TabsProps, TabsEvents, TabsSlots> {
|
|
22
|
+
z_$$bindings?: Bindings;
|
|
36
23
|
}
|
|
37
|
-
|
|
24
|
+
type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
|
|
25
|
+
default: any;
|
|
26
|
+
} ? Props extends Record<string, never> ? any : {
|
|
27
|
+
children?: any;
|
|
28
|
+
} : {});
|
|
29
|
+
declare const Tabs: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
|
|
30
|
+
visible?: boolean | "hidden";
|
|
31
|
+
elem_id?: string;
|
|
32
|
+
elem_classes?: string[];
|
|
33
|
+
selected: number | string;
|
|
34
|
+
initial_tabs: Tab[];
|
|
35
|
+
}, {
|
|
36
|
+
default: {};
|
|
37
|
+
}>, {
|
|
38
|
+
change: CustomEvent<undefined>;
|
|
39
|
+
select: CustomEvent<SelectData>;
|
|
40
|
+
} & {
|
|
41
|
+
[evt: string]: CustomEvent<any>;
|
|
42
|
+
}, {
|
|
43
|
+
default: {};
|
|
44
|
+
}, {}, string>;
|
|
45
|
+
type Tabs = InstanceType<typeof Tabs>;
|
|
46
|
+
export default Tabs;
|
|
@@ -1,115 +1,154 @@
|
|
|
1
|
-
<script context="module"
|
|
1
|
+
<script context="module" lang="ts">
|
|
2
|
+
import { TABS, type Tab } from "./Tabs.svelte";
|
|
2
3
|
</script>
|
|
3
4
|
|
|
4
|
-
<script
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export let
|
|
10
|
-
export let
|
|
11
|
-
let
|
|
12
|
-
let
|
|
13
|
-
let
|
|
14
|
-
|
|
15
|
-
let
|
|
16
|
-
let
|
|
17
|
-
let
|
|
18
|
-
let
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
let
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import { setContext, createEventDispatcher, tick, onMount } from "svelte";
|
|
7
|
+
import { writable } from "svelte/store";
|
|
8
|
+
import type { SelectData } from "@gradio/utils";
|
|
9
|
+
|
|
10
|
+
export let visible: boolean | "hidden" = true;
|
|
11
|
+
export let elem_id = "";
|
|
12
|
+
export let elem_classes: string[] = [];
|
|
13
|
+
export let selected: number | string;
|
|
14
|
+
export let initial_tabs: Tab[];
|
|
15
|
+
|
|
16
|
+
let tabs: (Tab | null)[] = [...initial_tabs];
|
|
17
|
+
let stepper_container: HTMLDivElement;
|
|
18
|
+
let show_labels_for_all = true;
|
|
19
|
+
let measurement_container: HTMLDivElement;
|
|
20
|
+
let step_buttons: HTMLButtonElement[] = [];
|
|
21
|
+
let step_labels: HTMLSpanElement[] = [];
|
|
22
|
+
let label_height = 0;
|
|
23
|
+
let compact = false;
|
|
24
|
+
let recompute_overflow = true;
|
|
25
|
+
$: has_tabs = tabs.length > 0;
|
|
26
|
+
|
|
27
|
+
const selected_tab = writable<false | number | string>(
|
|
28
|
+
selected || tabs[0]?.id || false
|
|
29
|
+
);
|
|
30
|
+
const selected_tab_index = writable<number>(
|
|
31
|
+
tabs.findIndex((t) => t?.id === selected) || 0
|
|
32
|
+
);
|
|
33
|
+
const dispatch = createEventDispatcher<{
|
|
34
|
+
change: undefined;
|
|
35
|
+
select: SelectData;
|
|
36
|
+
}>();
|
|
37
|
+
|
|
38
|
+
async function check_overflow(): Promise<void> {
|
|
39
|
+
if (!stepper_container || !measurement_container || !recompute_overflow)
|
|
40
|
+
return;
|
|
41
|
+
recompute_overflow = false;
|
|
42
|
+
await tick();
|
|
43
|
+
|
|
44
|
+
// First, show all labels to measure
|
|
45
|
+
show_labels_for_all = true;
|
|
46
|
+
await tick();
|
|
47
|
+
|
|
48
|
+
const SEP_WIDTH = 50;
|
|
49
|
+
const button_width =
|
|
50
|
+
step_buttons[0].getBoundingClientRect().width * step_buttons.length +
|
|
51
|
+
SEP_WIDTH * (step_buttons.length - 1);
|
|
52
|
+
|
|
53
|
+
const containerWidth = stepper_container.getBoundingClientRect().width;
|
|
54
|
+
const does_it_fit = button_width < containerWidth;
|
|
55
|
+
|
|
56
|
+
if (!does_it_fit) {
|
|
57
|
+
show_labels_for_all = false;
|
|
58
|
+
compact = true;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let max_height = 0;
|
|
63
|
+
let is_overlapping = false;
|
|
64
|
+
let last_right = 0;
|
|
65
|
+
|
|
66
|
+
for (const label of step_labels) {
|
|
67
|
+
const { height, width, left, right } = label.getBoundingClientRect();
|
|
68
|
+
if (height > max_height) {
|
|
69
|
+
max_height = height;
|
|
70
|
+
}
|
|
71
|
+
if (last_right && left - 10 < last_right && !is_overlapping) {
|
|
72
|
+
is_overlapping = true;
|
|
73
|
+
}
|
|
74
|
+
last_right = right;
|
|
75
|
+
}
|
|
76
|
+
label_height = max_height;
|
|
77
|
+
|
|
78
|
+
if (is_overlapping) {
|
|
79
|
+
show_labels_for_all = false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let last_width = 0;
|
|
84
|
+
|
|
85
|
+
onMount(() => {
|
|
86
|
+
check_overflow();
|
|
87
|
+
|
|
88
|
+
const observer = new ResizeObserver((entries) => {
|
|
89
|
+
if (entries[0].contentRect.width === last_width) return;
|
|
90
|
+
last_width = entries[0].contentRect.width;
|
|
91
|
+
compact = false;
|
|
92
|
+
recompute_overflow = true;
|
|
93
|
+
check_overflow();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (stepper_container) {
|
|
97
|
+
observer.observe(stepper_container);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return () => {
|
|
101
|
+
observer.disconnect();
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
setContext(TABS, {
|
|
106
|
+
register_tab: (tab: Tab, order: number) => {
|
|
107
|
+
tabs[order] = tab;
|
|
108
|
+
|
|
109
|
+
if ($selected_tab === false && tab.visible && tab.interactive) {
|
|
110
|
+
$selected_tab = tab.id;
|
|
111
|
+
$selected_tab_index = order;
|
|
112
|
+
}
|
|
113
|
+
return order;
|
|
114
|
+
},
|
|
115
|
+
unregister_tab: (tab: Tab, order: number) => {
|
|
116
|
+
if ($selected_tab === tab.id) {
|
|
117
|
+
$selected_tab = tabs[0]?.id || false;
|
|
118
|
+
}
|
|
119
|
+
tabs[order] = null;
|
|
120
|
+
},
|
|
121
|
+
selected_tab,
|
|
122
|
+
selected_tab_index
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
function change_tab(id: string | number | undefined, index: number): void {
|
|
126
|
+
const tab_to_activate = tabs.find((t) => t?.id === id);
|
|
127
|
+
if (
|
|
128
|
+
id !== undefined &&
|
|
129
|
+
tab_to_activate &&
|
|
130
|
+
tab_to_activate.interactive &&
|
|
131
|
+
tab_to_activate.visible &&
|
|
132
|
+
$selected_tab !== tab_to_activate.id
|
|
133
|
+
) {
|
|
134
|
+
selected = id;
|
|
135
|
+
$selected_tab = id;
|
|
136
|
+
$selected_tab_index = tabs.findIndex((t) => t?.id === id);
|
|
137
|
+
dispatch("change");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
$: (tabs,
|
|
142
|
+
selected !== null &&
|
|
143
|
+
change_tab(
|
|
144
|
+
selected,
|
|
145
|
+
tabs.findIndex((t) => t?.id === selected)
|
|
146
|
+
));
|
|
147
|
+
$: (tabs, check_overflow());
|
|
148
|
+
$: ($selected_tab_index, check_overflow());
|
|
149
|
+
|
|
150
|
+
$: tab_scale =
|
|
151
|
+
tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
|
|
113
152
|
</script>
|
|
114
153
|
|
|
115
154
|
<svelte:window on:resize={check_overflow} />
|
|
@@ -1,29 +1,38 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
import { type Tab } from "./Tabs.svelte";
|
|
3
2
|
import type { SelectData } from "@gradio/utils";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
4
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
5
|
+
$$bindings?: Bindings;
|
|
6
|
+
} & Exports;
|
|
7
|
+
(internal: unknown, props: Props & {
|
|
8
|
+
$$events?: Events;
|
|
9
|
+
$$slots?: Slots;
|
|
10
|
+
}): Exports & {
|
|
11
|
+
$set?: any;
|
|
12
|
+
$on?: any;
|
|
11
13
|
};
|
|
12
|
-
|
|
13
|
-
change: CustomEvent<undefined>;
|
|
14
|
-
select: CustomEvent<SelectData>;
|
|
15
|
-
} & {
|
|
16
|
-
[evt: string]: CustomEvent<any>;
|
|
17
|
-
};
|
|
18
|
-
slots: {
|
|
19
|
-
default: {};
|
|
20
|
-
};
|
|
21
|
-
exports?: {} | undefined;
|
|
22
|
-
bindings?: string | undefined;
|
|
23
|
-
};
|
|
24
|
-
export type WalkthroughProps = typeof __propDef.props;
|
|
25
|
-
export type WalkthroughEvents = typeof __propDef.events;
|
|
26
|
-
export type WalkthroughSlots = typeof __propDef.slots;
|
|
27
|
-
export default class Walkthrough extends SvelteComponent<WalkthroughProps, WalkthroughEvents, WalkthroughSlots> {
|
|
14
|
+
z_$$bindings?: Bindings;
|
|
28
15
|
}
|
|
29
|
-
|
|
16
|
+
type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
|
|
17
|
+
default: any;
|
|
18
|
+
} ? Props extends Record<string, never> ? any : {
|
|
19
|
+
children?: any;
|
|
20
|
+
} : {});
|
|
21
|
+
declare const Walkthrough: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
|
|
22
|
+
visible?: boolean | "hidden";
|
|
23
|
+
elem_id?: string;
|
|
24
|
+
elem_classes?: string[];
|
|
25
|
+
selected: number | string;
|
|
26
|
+
initial_tabs: Tab[];
|
|
27
|
+
}, {
|
|
28
|
+
default: {};
|
|
29
|
+
}>, {
|
|
30
|
+
change: CustomEvent<undefined>;
|
|
31
|
+
select: CustomEvent<SelectData>;
|
|
32
|
+
} & {
|
|
33
|
+
[evt: string]: CustomEvent<any>;
|
|
34
|
+
}, {
|
|
35
|
+
default: {};
|
|
36
|
+
}, {}, string>;
|
|
37
|
+
type Walkthrough = InstanceType<typeof Walkthrough>;
|
|
38
|
+
export default Walkthrough;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SelectData } from "@gradio/utils";
|
|
2
|
+
import type { Tab } from "./shared/Tabs.svelte";
|
|
3
|
+
export interface TabsProps {
|
|
4
|
+
visible: boolean | "hidden";
|
|
5
|
+
elem_id: string;
|
|
6
|
+
elem_classes: string[];
|
|
7
|
+
selected: number | string;
|
|
8
|
+
initial_tabs: Tab[];
|
|
9
|
+
name: "tabs" | "walkthrough";
|
|
10
|
+
}
|
|
11
|
+
export interface TabsEvents {
|
|
12
|
+
change: never;
|
|
13
|
+
select: SelectData;
|
|
14
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/tabs",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2-dev.0",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
"./package.json": "./package.json"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@gradio/utils": "^0.10.
|
|
20
|
+
"@gradio/utils": "^0.10.3-dev.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@gradio/preview": "^0.
|
|
23
|
+
"@gradio/preview": "^0.15.0-dev.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"svelte": "^
|
|
26
|
+
"svelte": "^5.43.4"
|
|
27
27
|
},
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
package/shared/Tabs.svelte
CHANGED
|
@@ -93,8 +93,8 @@
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
$: tabs, selected !== null && change_tab(selected);
|
|
97
|
-
$: tabs, tab_nav_el, tab_els, handle_menu_overflow();
|
|
96
|
+
$: (tabs, selected !== null && change_tab(selected));
|
|
97
|
+
$: (tabs, tab_nav_el, tab_els, handle_menu_overflow());
|
|
98
98
|
|
|
99
99
|
function handle_outside_click(event: MouseEvent): void {
|
|
100
100
|
if (
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
on:click={() => {
|
|
200
200
|
if (t.id !== $selected_tab) {
|
|
201
201
|
change_tab(t.id);
|
|
202
|
-
dispatch("select", { value: t.label, index: i });
|
|
202
|
+
dispatch("select", { value: t.label, index: i, id: t.id });
|
|
203
203
|
}
|
|
204
204
|
}}
|
|
205
205
|
>
|
|
@@ -138,14 +138,14 @@
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
$: tabs,
|
|
141
|
+
$: (tabs,
|
|
142
142
|
selected !== null &&
|
|
143
143
|
change_tab(
|
|
144
144
|
selected,
|
|
145
145
|
tabs.findIndex((t) => t?.id === selected)
|
|
146
|
-
);
|
|
147
|
-
$: tabs, check_overflow();
|
|
148
|
-
$: $selected_tab_index, check_overflow();
|
|
146
|
+
));
|
|
147
|
+
$: (tabs, check_overflow());
|
|
148
|
+
$: ($selected_tab_index, check_overflow());
|
|
149
149
|
|
|
150
150
|
$: tab_scale =
|
|
151
151
|
tabs[$selected_tab_index >= 0 ? $selected_tab_index : 0]?.scale;
|
package/types.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SelectData } from "@gradio/utils";
|
|
2
|
+
import type { Tab } from "./shared/Tabs.svelte";
|
|
3
|
+
|
|
4
|
+
export interface TabsProps {
|
|
5
|
+
visible: boolean | "hidden";
|
|
6
|
+
elem_id: string;
|
|
7
|
+
elem_classes: string[];
|
|
8
|
+
selected: number | string;
|
|
9
|
+
initial_tabs: Tab[];
|
|
10
|
+
name: "tabs" | "walkthrough";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface TabsEvents {
|
|
14
|
+
change: never;
|
|
15
|
+
select: SelectData;
|
|
16
|
+
}
|