diff --git a/.changeset/calm-roses-suffer.md b/.changeset/calm-roses-suffer.md
new file mode 100644
index 000000000000..d8f5a519f56f
--- /dev/null
+++ b/.changeset/calm-roses-suffer.md
@@ -0,0 +1,6 @@
+---
+"@gradio/wasm": patch
+"gradio": patch
+---
+
+fix:Fix Lite dependencies
diff --git a/.changeset/lazy-houses-repair.md b/.changeset/lazy-houses-repair.md
new file mode 100644
index 000000000000..f89f24ef26b3
--- /dev/null
+++ b/.changeset/lazy-houses-repair.md
@@ -0,0 +1,7 @@
+---
+"@gradio/core": patch
+"@gradio/tabs": patch
+"gradio": patch
+---
+
+fix:Ensure tabs render in SSR mode and reduce time it takes for them to render.
diff --git a/.changeset/stale-jobs-reply.md b/.changeset/stale-jobs-reply.md
new file mode 100644
index 000000000000..8379df598785
--- /dev/null
+++ b/.changeset/stale-jobs-reply.md
@@ -0,0 +1,5 @@
+---
+"gradio": patch
+---
+
+fix:fix css syntax error
diff --git a/gradio/themes/base.py b/gradio/themes/base.py
index 78e2914c919d..51230be69623 100644
--- a/gradio/themes/base.py
+++ b/gradio/themes/base.py
@@ -88,7 +88,7 @@ def repl_func(match):
dark_css_code = (
"\n:root .dark {\n"
+ "\n".join([f" --{attr}: {val};" for attr, val in dark_css.items()])
- + "\n}\n}"
+ + "\n}"
)
font_css = "\n".join(self._font_css)
diff --git a/js/core/src/init.ts b/js/core/src/init.ts
index 471abba70404..7882e0769e11 100644
--- a/js/core/src/init.ts
+++ b/js/core/src/init.ts
@@ -290,6 +290,26 @@ export function create_components(initial_layout: ComponentMeta | undefined): {
);
}
+ if (instance.type === "tabs") {
+ instance.children =
+ instance?.children?.map((c) => ({
+ ...c,
+ props: {
+ ...c.props,
+ id: c.props.id || c.id
+ }
+ })) || [];
+ const child_tab_items = instance.children?.filter(
+ (child) => child.type === "tabitem"
+ );
+ instance.props.inital_tabs = child_tab_items?.map((child) => ({
+ label: child.props.label,
+ id: child.props.id,
+ visible: child.props.visible,
+ interactive: child.props.interactive
+ }));
+ }
+
return instance;
}
diff --git a/js/dropdown/dropdown.test.ts b/js/dropdown/dropdown.test.ts
index afd308016a95..d31ec29f902d 100644
--- a/js/dropdown/dropdown.test.ts
+++ b/js/dropdown/dropdown.test.ts
@@ -273,7 +273,7 @@ describe("Dropdown", () => {
{
show_label: true,
loading_status,
- value: "",
+ value: "apple",
allow_custom_value: false,
label: "Dropdown",
choices: [
@@ -303,7 +303,7 @@ describe("Dropdown", () => {
{
show_label: true,
loading_status,
- value: "",
+ value: "apple",
allow_custom_value: true,
label: "Dropdown",
choices: [
@@ -333,7 +333,7 @@ describe("Dropdown", () => {
{
show_label: true,
loading_status,
- value: "",
+ value: "apple",
allow_custom_value: false,
label: "Dropdown",
choices: [
@@ -377,7 +377,7 @@ describe("Dropdown", () => {
{
show_label: true,
loading_status,
- value: "",
+ value: "apple_internal_value",
allow_custom_value: false,
label: "Dropdown",
choices: [
@@ -477,6 +477,7 @@ describe("Dropdown", () => {
show_label: true,
loading_status,
allow_custom_value: false,
+ value: "apple_internal_value",
label: "Dropdown",
choices: [
["apple_choice", "apple_internal_value"],
@@ -491,7 +492,7 @@ describe("Dropdown", () => {
await expect(item.value).toBe("apple_choice");
});
- test("ensure dropdown works when initial value is undefined and allow custom value is set", async () => {
+ test("ensure dropdown works when initial value is undefined and allow_custom_value is true", async () => {
const { getByLabelText } = await render(Dropdown, {
show_label: true,
loading_status,
@@ -508,6 +509,6 @@ describe("Dropdown", () => {
const item: HTMLInputElement = getByLabelText(
"Dropdown"
) as HTMLInputElement;
- await expect(item.value).toBe("apple_choice");
+ await expect(item.value).toBe("");
});
});
diff --git a/js/tabs/Index.svelte b/js/tabs/Index.svelte
index b5b261f7e167..189bbbb54f94 100644
--- a/js/tabs/Index.svelte
+++ b/js/tabs/Index.svelte
@@ -9,10 +9,19 @@
const dispatch = createEventDispatcher();
+ interface Tab {
+ name: string;
+ id: string | number;
+ elem_id: string | undefined;
+ visible: boolean;
+ interactive: boolean;
+ }
+
export let visible = true;
export let elem_id = "";
export let elem_classes: string[] = [];
export let selected: number | string;
+ export let inital_tabs: Tab[];
export let gradio: Gradio<{
change: never;
select: SelectData;
@@ -28,6 +37,7 @@
bind:selected
on:change={() => gradio.dispatch("change")}
on:select={(e) => gradio.dispatch("select", e.detail)}
+ {inital_tabs}
>
diff --git a/js/tabs/shared/Tabs.svelte b/js/tabs/shared/Tabs.svelte
index 9e8458d48937..76f895d7a386 100644
--- a/js/tabs/shared/Tabs.svelte
+++ b/js/tabs/shared/Tabs.svelte
@@ -7,7 +7,8 @@
setContext,
createEventDispatcher,
onMount,
- onDestroy
+ onDestroy,
+ tick
} from "svelte";
import OverflowIcon from "./OverflowIcon.svelte";
import { writable } from "svelte/store";
@@ -15,7 +16,7 @@
interface Tab {
name: string;
- id: object;
+ id: string | number;
elem_id: string | undefined;
visible: boolean;
interactive: boolean;
@@ -24,9 +25,10 @@
export let visible = true;
export let elem_id = "";
export let elem_classes: string[] = [];
- export let selected: number | string | object;
+ export let selected: number | string;
+ export let inital_tabs: Tab[];
- let tabs: Tab[] = [];
+ let tabs: Tab[] = inital_tabs;
let overflow_menu_open = false;
let overflow_menu: HTMLElement;
@@ -35,8 +37,12 @@
let tab_nav_el: HTMLElement;
let overflow_nav: HTMLElement;
- const selected_tab = writable(false);
- const selected_tab_index = writable(0);
+ const selected_tab = writable(
+ selected || tabs[0]?.id || false
+ );
+ const selected_tab_index = writable(
+ tabs.findIndex((t) => t.id === selected) || 0
+ );
const dispatch = createEventDispatcher<{
change: undefined;
select: SelectData;
@@ -72,20 +78,19 @@
selected_tab_index
});
- function change_tab(id: object | string | number): void {
+ function change_tab(id: string | number): void {
const tab_to_activate = tabs.find((t) => t.id === id);
if (
tab_to_activate &&
tab_to_activate.interactive &&
- tab_to_activate.visible
+ tab_to_activate.visible &&
+ $selected_tab !== tab_to_activate.id
) {
selected = id;
$selected_tab = id;
$selected_tab_index = tabs.findIndex((t) => t.id === id);
dispatch("change");
overflow_menu_open = false;
- } else {
- console.warn("Attempted to select a non-interactive or hidden tab.");
}
}
@@ -149,10 +154,19 @@
nav_items.forEach((item) => tab_nav_el.appendChild(item));
overflow_items.forEach((item) => overflow_nav.appendChild(item));
+ overflow_has_selected_tab = handle_overflow_has_selected_tab($selected_tab);
+ }
+
+ $: overflow_has_selected_tab =
+ handle_overflow_has_selected_tab($selected_tab);
- overflow_has_selected_tab = tabs.some(
+ function handle_overflow_has_selected_tab(
+ selected_tab: number | string | false
+ ): boolean {
+ if (selected_tab === false || !overflow_nav) return false;
+ return tabs.some(
(t) =>
- t.id === $selected_tab &&
+ t.id === selected_tab &&
overflow_nav.contains(document.querySelector(`[data-tab-id="${t.id}"]`))
);
}
diff --git a/js/wasm/src/webworker/index.ts b/js/wasm/src/webworker/index.ts
index 888fafe70cab..5d4208d02f38 100644
--- a/js/wasm/src/webworker/index.ts
+++ b/js/wasm/src/webworker/index.ts
@@ -80,15 +80,6 @@ async function initializeEnvironment(
updateProgress("Loading Gradio wheels");
await pyodide.loadPackage(["ssl", "setuptools"]);
await micropip.add_mock_package("ffmpy", "0.3.0");
- await micropip.install.callKwargs(
- [
- "typing-extensions>=4.8.0", // Typing extensions needs to be installed first otherwise the versions from the pyodide lockfile is used which is incompatible with the latest fastapi.
- "markdown-it-py[linkify]~=2.2.0", // On 3rd June 2023, markdown-it-py 3.0.0 has been released. The `gradio` package depends on its `>=2.0.0` version so its 3.x will be resolved. However, it conflicts with `mdit-py-plugins`'s dependency `markdown-it-py >=1.0.0,<3.0.0` and micropip currently can't resolve it. So we explicitly install the compatible version of the library here.
- "anyio==3.*", // `fastapi` depends on `anyio>=3.4.0,<5` so its 4.* can be installed, but it conflicts with the anyio version `httpx` depends on, `==3.*`. Seems like micropip can't resolve it for now, so we explicitly install the compatible version of the library here.
- "fastapi<0.111.0" // `fastapi==0.111.0` added `ujson` as a dependency, but it's not available on Pyodide yet.
- ],
- { keep_going: true }
- );
await micropip.install.callKwargs(gradioWheelUrls, {
keep_going: true
});
diff --git a/requirements.txt b/requirements.txt
index 5ad87d9d14eb..684ca9c39c80 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,7 +17,7 @@ python-multipart>=0.0.9 # required for fastapi forms
pydub
pyyaml>=5.0,<7.0
semantic_version~=2.0
-starlette>=0.40.0,<1.0
+starlette>=0.40.0,<1.0; sys.platform != 'emscripten'
typing_extensions~=4.0
urllib3~=2.0; sys.platform == 'emscripten' # urllib3 is used for Lite support. Version spec can be omitted because urllib3==2.1.0 is prebuilt for Pyodide and urllib>=2.2.0 supports Pyodide as well.
uvicorn>=0.14.0; sys.platform != 'emscripten'