@gradio/tabitem 0.7.0 → 0.8.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 +18 -0
- package/Index.svelte +1 -1
- package/TabItem.test.ts +48 -0
- package/TabItemHarness.svelte +6 -3
- package/dist/Index.svelte +1 -1
- package/dist/TabItemHarness.svelte +6 -3
- package/dist/shared/TabItem.svelte +53 -28
- package/dist/shared/TabItem.svelte.d.ts +14 -14
- package/dist/types.d.ts +1 -1
- package/package.json +4 -4
- package/shared/TabItem.svelte +53 -28
- package/types.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @gradio/tabitem
|
|
2
2
|
|
|
3
|
+
## 0.8.1
|
|
4
|
+
|
|
5
|
+
### Dependency updates
|
|
6
|
+
|
|
7
|
+
- @gradio/utils@0.13.0
|
|
8
|
+
- @gradio/column@0.4.0
|
|
9
|
+
- @gradio/tabs@0.8.0
|
|
10
|
+
|
|
11
|
+
## 0.8.0
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
- [#13509](https://github.com/gradio-app/gradio/pull/13509) [`dcd072c`](https://github.com/gradio-app/gradio/commit/dcd072cd57f09ffd2dc5f97ae6afc505894824a6) - Migrate Chatbot, Tabs, TabItem to Svelte 5. Thanks @dawoodkhan82!
|
|
16
|
+
|
|
17
|
+
### Dependency updates
|
|
18
|
+
|
|
19
|
+
- @gradio/tabs@0.7.0
|
|
20
|
+
|
|
3
21
|
## 0.7.0
|
|
4
22
|
|
|
5
23
|
### Features
|
package/Index.svelte
CHANGED
package/TabItem.test.ts
CHANGED
|
@@ -39,6 +39,54 @@ describe("TabItem", () => {
|
|
|
39
39
|
|
|
40
40
|
expect(getByTestId("tab-content")).not.toBeVisible();
|
|
41
41
|
});
|
|
42
|
+
|
|
43
|
+
test("uses a stable internal id when no explicit id is provided", async () => {
|
|
44
|
+
const on_register = vi.fn();
|
|
45
|
+
const { getByTestId } = await render(TabItemHarness, {
|
|
46
|
+
omit_id: true,
|
|
47
|
+
tab_selected: 1,
|
|
48
|
+
on_register
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(getByTestId("tab-content")).toBeVisible();
|
|
52
|
+
await waitFor(() => {
|
|
53
|
+
expect(on_register).toHaveBeenCalledWith(
|
|
54
|
+
expect.objectContaining({ id: 1 })
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("keeps 0 as an explicit id", async () => {
|
|
60
|
+
const on_register = vi.fn();
|
|
61
|
+
const { getByTestId } = await render(TabItemHarness, {
|
|
62
|
+
tab_id: 0,
|
|
63
|
+
tab_selected: 0,
|
|
64
|
+
on_register
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
expect(getByTestId("tab-content")).toBeVisible();
|
|
68
|
+
await waitFor(() => {
|
|
69
|
+
expect(on_register).toHaveBeenCalledWith(
|
|
70
|
+
expect.objectContaining({ id: 0 })
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("keeps an empty string as an explicit id", async () => {
|
|
76
|
+
const on_register = vi.fn();
|
|
77
|
+
const { getByTestId } = await render(TabItemHarness, {
|
|
78
|
+
tab_id: "",
|
|
79
|
+
tab_selected: "",
|
|
80
|
+
on_register
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
expect(getByTestId("tab-content")).toBeVisible();
|
|
84
|
+
await waitFor(() => {
|
|
85
|
+
expect(on_register).toHaveBeenCalledWith(
|
|
86
|
+
expect.objectContaining({ id: "" })
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
42
90
|
});
|
|
43
91
|
|
|
44
92
|
describe("Events: select", () => {
|
package/TabItemHarness.svelte
CHANGED
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
const selected_tab_index = writable<number>(cfg.tab_selected_index ?? 0);
|
|
14
14
|
|
|
15
15
|
setContext(TABS, {
|
|
16
|
-
register_tab: (
|
|
16
|
+
register_tab: (tab: any, order: number) => {
|
|
17
|
+
cfg.on_register?.(tab);
|
|
18
|
+
return order;
|
|
19
|
+
},
|
|
17
20
|
unregister_tab: () => {},
|
|
18
21
|
selected_tab,
|
|
19
22
|
selected_tab_index
|
|
@@ -22,13 +25,13 @@
|
|
|
22
25
|
|
|
23
26
|
<BaseTabItem
|
|
24
27
|
label="First Tab"
|
|
25
|
-
id="t1"
|
|
28
|
+
id={cfg.omit_id ? undefined : (cfg.tab_id ?? "t1")}
|
|
26
29
|
order={0}
|
|
27
30
|
visible={cfg.tab_visible ?? true}
|
|
28
31
|
interactive={true}
|
|
29
32
|
scale={0}
|
|
30
33
|
component_id={1}
|
|
31
|
-
|
|
34
|
+
onselect={(data) => cfg.on_tab_select?.(data)}
|
|
32
35
|
>
|
|
33
36
|
<div data-testid="tab-content">tab panel content</div>
|
|
34
37
|
</BaseTabItem>
|
package/dist/Index.svelte
CHANGED
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
const selected_tab_index = writable<number>(cfg.tab_selected_index ?? 0);
|
|
14
14
|
|
|
15
15
|
setContext(TABS, {
|
|
16
|
-
register_tab: (
|
|
16
|
+
register_tab: (tab: any, order: number) => {
|
|
17
|
+
cfg.on_register?.(tab);
|
|
18
|
+
return order;
|
|
19
|
+
},
|
|
17
20
|
unregister_tab: () => {},
|
|
18
21
|
selected_tab,
|
|
19
22
|
selected_tab_index
|
|
@@ -22,13 +25,13 @@
|
|
|
22
25
|
|
|
23
26
|
<BaseTabItem
|
|
24
27
|
label="First Tab"
|
|
25
|
-
id="t1"
|
|
28
|
+
id={cfg.omit_id ? undefined : (cfg.tab_id ?? "t1")}
|
|
26
29
|
order={0}
|
|
27
30
|
visible={cfg.tab_visible ?? true}
|
|
28
31
|
interactive={true}
|
|
29
32
|
scale={0}
|
|
30
33
|
component_id={1}
|
|
31
|
-
|
|
34
|
+
onselect={(data) => cfg.on_tab_select?.(data)}
|
|
32
35
|
>
|
|
33
36
|
<div data-testid="tab-content">tab panel content</div>
|
|
34
37
|
</BaseTabItem>
|
|
@@ -1,56 +1,81 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { getContext,
|
|
2
|
+
import { getContext, tick, untrack } from "svelte";
|
|
3
3
|
import { TABS } from "@gradio/tabs";
|
|
4
4
|
import { BaseColumn } from "@gradio/column";
|
|
5
5
|
import type { SelectData } from "@gradio/utils";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
let {
|
|
8
|
+
elem_id = "",
|
|
9
|
+
elem_classes = [],
|
|
10
|
+
label,
|
|
11
|
+
id,
|
|
12
|
+
visible,
|
|
13
|
+
interactive,
|
|
14
|
+
order,
|
|
15
|
+
scale,
|
|
16
|
+
component_id,
|
|
17
|
+
onselect
|
|
18
|
+
}: {
|
|
19
|
+
elem_id?: string;
|
|
20
|
+
elem_classes?: string[];
|
|
21
|
+
label: string;
|
|
22
|
+
id?: string | number | null;
|
|
23
|
+
visible: boolean | "hidden";
|
|
24
|
+
interactive: boolean;
|
|
25
|
+
order: number;
|
|
26
|
+
scale: number;
|
|
27
|
+
component_id: number;
|
|
28
|
+
onselect?: (data: SelectData) => void;
|
|
29
|
+
} = $props();
|
|
18
30
|
|
|
19
31
|
const { register_tab, unregister_tab, selected_tab, selected_tab_index } =
|
|
20
32
|
getContext(TABS) as any;
|
|
21
33
|
|
|
22
|
-
let tab_index
|
|
34
|
+
let tab_index = $state<number | undefined>(undefined);
|
|
23
35
|
|
|
24
36
|
function _register_tab(obj: string, order: number): number {
|
|
25
37
|
obj = JSON.parse(obj);
|
|
26
38
|
return register_tab(obj, order);
|
|
27
39
|
}
|
|
28
40
|
|
|
29
|
-
|
|
30
|
-
label,
|
|
31
|
-
id,
|
|
32
|
-
elem_id,
|
|
33
|
-
visible,
|
|
34
|
-
interactive,
|
|
35
|
-
scale,
|
|
36
|
-
component_id
|
|
37
|
-
});
|
|
41
|
+
let tab_id = $derived(id ?? component_id);
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
let props_json = $derived(
|
|
44
|
+
JSON.stringify({
|
|
45
|
+
label,
|
|
46
|
+
id: tab_id,
|
|
47
|
+
elem_id,
|
|
48
|
+
visible,
|
|
49
|
+
interactive,
|
|
50
|
+
scale,
|
|
51
|
+
component_id
|
|
52
|
+
})
|
|
53
|
+
);
|
|
40
54
|
|
|
41
|
-
|
|
42
|
-
|
|
55
|
+
let is_visible = $derived(visible !== false && visible !== "hidden");
|
|
56
|
+
|
|
57
|
+
$effect(() => {
|
|
58
|
+
const tab_props = props_json;
|
|
59
|
+
tab_index = untrack(() => _register_tab(tab_props, order));
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
$effect(() => {
|
|
63
|
+
return (): void => unregister_tab({ label, id: tab_id, elem_id }, order);
|
|
43
64
|
});
|
|
44
65
|
|
|
45
|
-
|
|
46
|
-
|
|
66
|
+
$effect(() => {
|
|
67
|
+
const index = tab_index;
|
|
68
|
+
if (index !== undefined && $selected_tab_index === index) {
|
|
69
|
+
tick().then(() => onselect?.({ value: label, index }));
|
|
70
|
+
}
|
|
71
|
+
});
|
|
47
72
|
</script>
|
|
48
73
|
|
|
49
74
|
<div
|
|
50
75
|
id={elem_id}
|
|
51
76
|
class="tabitem {elem_classes.join(' ')}"
|
|
52
77
|
class:grow-children={scale >= 1}
|
|
53
|
-
style:display={$selected_tab ===
|
|
78
|
+
style:display={$selected_tab === tab_id && is_visible ? "flex" : "none"}
|
|
54
79
|
style:flex-grow={scale}
|
|
55
80
|
role="tabpanel"
|
|
56
81
|
>
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import type { SelectData } from "@gradio/utils";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
elem_id?: string;
|
|
4
|
+
elem_classes?: string[];
|
|
5
|
+
label: string;
|
|
6
|
+
id?: string | number | null;
|
|
7
|
+
visible: boolean | "hidden";
|
|
8
|
+
interactive: boolean;
|
|
9
|
+
order: number;
|
|
10
|
+
scale: number;
|
|
11
|
+
component_id: number;
|
|
12
|
+
onselect?: (data: SelectData) => void;
|
|
13
|
+
};
|
|
2
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> {
|
|
3
15
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
16
|
$$bindings?: Bindings;
|
|
@@ -17,24 +29,12 @@ type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
|
|
|
17
29
|
} ? Props extends Record<string, never> ? any : {
|
|
18
30
|
children?: any;
|
|
19
31
|
} : {});
|
|
20
|
-
declare const TabItem: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren
|
|
21
|
-
elem_id?: string;
|
|
22
|
-
elem_classes?: string[];
|
|
23
|
-
label: string;
|
|
24
|
-
id?: string | number | object;
|
|
25
|
-
visible: boolean | "hidden";
|
|
26
|
-
interactive: boolean;
|
|
27
|
-
order: number;
|
|
28
|
-
scale: number;
|
|
29
|
-
component_id: number;
|
|
30
|
-
}, {
|
|
32
|
+
declare const TabItem: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<$$ComponentProps, {
|
|
31
33
|
default: {};
|
|
32
34
|
}>, {
|
|
33
|
-
select: CustomEvent<SelectData>;
|
|
34
|
-
} & {
|
|
35
35
|
[evt: string]: CustomEvent<any>;
|
|
36
36
|
}, {
|
|
37
37
|
default: {};
|
|
38
|
-
}, {},
|
|
38
|
+
}, {}, "">;
|
|
39
39
|
type TabItem = InstanceType<typeof TabItem>;
|
|
40
40
|
export default TabItem;
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/tabitem",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"./package.json": "./package.json"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@gradio/
|
|
20
|
-
"@gradio/
|
|
21
|
-
"@gradio/utils": "^0.
|
|
19
|
+
"@gradio/column": "^0.4.0",
|
|
20
|
+
"@gradio/tabs": "^0.8.0",
|
|
21
|
+
"@gradio/utils": "^0.13.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@gradio/preview": "^0.16.2"
|
package/shared/TabItem.svelte
CHANGED
|
@@ -1,56 +1,81 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { getContext,
|
|
2
|
+
import { getContext, tick, untrack } from "svelte";
|
|
3
3
|
import { TABS } from "@gradio/tabs";
|
|
4
4
|
import { BaseColumn } from "@gradio/column";
|
|
5
5
|
import type { SelectData } from "@gradio/utils";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
let {
|
|
8
|
+
elem_id = "",
|
|
9
|
+
elem_classes = [],
|
|
10
|
+
label,
|
|
11
|
+
id,
|
|
12
|
+
visible,
|
|
13
|
+
interactive,
|
|
14
|
+
order,
|
|
15
|
+
scale,
|
|
16
|
+
component_id,
|
|
17
|
+
onselect
|
|
18
|
+
}: {
|
|
19
|
+
elem_id?: string;
|
|
20
|
+
elem_classes?: string[];
|
|
21
|
+
label: string;
|
|
22
|
+
id?: string | number | null;
|
|
23
|
+
visible: boolean | "hidden";
|
|
24
|
+
interactive: boolean;
|
|
25
|
+
order: number;
|
|
26
|
+
scale: number;
|
|
27
|
+
component_id: number;
|
|
28
|
+
onselect?: (data: SelectData) => void;
|
|
29
|
+
} = $props();
|
|
18
30
|
|
|
19
31
|
const { register_tab, unregister_tab, selected_tab, selected_tab_index } =
|
|
20
32
|
getContext(TABS) as any;
|
|
21
33
|
|
|
22
|
-
let tab_index
|
|
34
|
+
let tab_index = $state<number | undefined>(undefined);
|
|
23
35
|
|
|
24
36
|
function _register_tab(obj: string, order: number): number {
|
|
25
37
|
obj = JSON.parse(obj);
|
|
26
38
|
return register_tab(obj, order);
|
|
27
39
|
}
|
|
28
40
|
|
|
29
|
-
|
|
30
|
-
label,
|
|
31
|
-
id,
|
|
32
|
-
elem_id,
|
|
33
|
-
visible,
|
|
34
|
-
interactive,
|
|
35
|
-
scale,
|
|
36
|
-
component_id
|
|
37
|
-
});
|
|
41
|
+
let tab_id = $derived(id ?? component_id);
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
let props_json = $derived(
|
|
44
|
+
JSON.stringify({
|
|
45
|
+
label,
|
|
46
|
+
id: tab_id,
|
|
47
|
+
elem_id,
|
|
48
|
+
visible,
|
|
49
|
+
interactive,
|
|
50
|
+
scale,
|
|
51
|
+
component_id
|
|
52
|
+
})
|
|
53
|
+
);
|
|
40
54
|
|
|
41
|
-
|
|
42
|
-
|
|
55
|
+
let is_visible = $derived(visible !== false && visible !== "hidden");
|
|
56
|
+
|
|
57
|
+
$effect(() => {
|
|
58
|
+
const tab_props = props_json;
|
|
59
|
+
tab_index = untrack(() => _register_tab(tab_props, order));
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
$effect(() => {
|
|
63
|
+
return (): void => unregister_tab({ label, id: tab_id, elem_id }, order);
|
|
43
64
|
});
|
|
44
65
|
|
|
45
|
-
|
|
46
|
-
|
|
66
|
+
$effect(() => {
|
|
67
|
+
const index = tab_index;
|
|
68
|
+
if (index !== undefined && $selected_tab_index === index) {
|
|
69
|
+
tick().then(() => onselect?.({ value: label, index }));
|
|
70
|
+
}
|
|
71
|
+
});
|
|
47
72
|
</script>
|
|
48
73
|
|
|
49
74
|
<div
|
|
50
75
|
id={elem_id}
|
|
51
76
|
class="tabitem {elem_classes.join(' ')}"
|
|
52
77
|
class:grow-children={scale >= 1}
|
|
53
|
-
style:display={$selected_tab ===
|
|
78
|
+
style:display={$selected_tab === tab_id && is_visible ? "flex" : "none"}
|
|
54
79
|
style:flex-grow={scale}
|
|
55
80
|
role="tabpanel"
|
|
56
81
|
>
|