@gradio/core 1.0.2 → 1.1.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 CHANGED
@@ -1,5 +1,61 @@
1
1
  # @gradio/core
2
2
 
3
+ ## 1.1.1
4
+
5
+ ### Features
6
+
7
+ - [#12677](https://github.com/gradio-app/gradio/pull/12677) [`6f37743`](https://github.com/gradio-app/gradio/commit/6f377433e4c64f1d962eef0f9eff74676c72032b) - Make check for active page in navbar robust. Thanks @abidlabs!
8
+
9
+ ### Fixes
10
+
11
+ - [#12681](https://github.com/gradio-app/gradio/pull/12681) [`ba46c2d`](https://github.com/gradio-app/gradio/commit/ba46c2df1405c11e495304af8f91acfdf69d0b18) - Migrate Button to Svelte 5. Thanks @freddyaboulton!
12
+ - [#12625](https://github.com/gradio-app/gradio/pull/12625) [`7fb79d4`](https://github.com/gradio-app/gradio/commit/7fb79d45bdc3597bf6b095ff64c420939257fba9) - Fix bug where tabs don't work inside gr.render. Thanks @freddyaboulton!
13
+
14
+ ### Dependency updates
15
+
16
+ - @gradio/utils@0.11.1
17
+ - @gradio/button@0.6.2
18
+ - @gradio/client@2.0.2
19
+ - @gradio/column@0.3.1
20
+ - @gradio/theme@0.6.0
21
+ - @gradio/gallery@0.16.1
22
+ - @gradio/plot@0.10.1
23
+ - @gradio/video@0.20.0
24
+
25
+ ## 1.1.0
26
+
27
+ ### Features
28
+
29
+ - [#12539](https://github.com/gradio-app/gradio/pull/12539) [`f1d83fa`](https://github.com/gradio-app/gradio/commit/f1d83fac3d6e4bad60cf896a026fa2d572f26073) - Add ability to add custom buttons to components. Thanks @abidlabs!
30
+
31
+ ### Fixes
32
+
33
+ - [#12569](https://github.com/gradio-app/gradio/pull/12569) [`9daf193`](https://github.com/gradio-app/gradio/commit/9daf1932291bea1fcbbe20096d28018657242295) - Add footer to bottom of page. Thanks @freddyaboulton!
34
+ - [#12600](https://github.com/gradio-app/gradio/pull/12600) [`1fafaba`](https://github.com/gradio-app/gradio/commit/1fafabaace315b1c699855cadb69eb17488de957) - Add x-gradio-user-header. Thanks @freddyaboulton!
35
+
36
+ ### Dependency updates
37
+
38
+ - @gradio/atoms@0.20.0
39
+ - @gradio/checkbox@0.6.0
40
+ - @gradio/utils@0.11.0
41
+ - @gradio/client@2.0.1
42
+ - @gradio/statustracker@0.12.1
43
+ - @gradio/upload@0.17.3
44
+ - @gradio/button@0.6.1
45
+ - @gradio/gallery@0.16.0
46
+ - @gradio/plot@0.10.0
47
+ - @gradio/dropdown@0.11.0
48
+ - @gradio/textbox@0.13.0
49
+ - @gradio/file@0.14.0
50
+ - @gradio/image@0.25.0
51
+ - @gradio/video@0.19.0
52
+ - @gradio/column@0.3.0
53
+ - @gradio/audio@0.22.0
54
+ - @gradio/code@0.17.0
55
+ - @gradio/paramviewer@0.9.1
56
+ - @gradio/tabitem@0.6.4
57
+ - @gradio/tabs@0.5.4
58
+
3
59
  ## 1.0.2
4
60
 
5
61
  ### Fixes
@@ -140,6 +140,9 @@
140
140
  // update_status(id, "complete", data);
141
141
  } else if (event == "close_stream") {
142
142
  dep_manager.close_stream(id);
143
+ } else if (event === "custom_button_click") {
144
+ const button_id = (data as { id: number }).id;
145
+ dispatch_to_target(button_id, "click", null);
143
146
  } else {
144
147
  // Tabs are a bit weird. The Tabs component dispatches 'select' events
145
148
  // but the target id corresponds to the child Tab component that was selected.
@@ -175,6 +178,19 @@
175
178
  gradio_event_dispatcher
176
179
  );
177
180
 
181
+ function dispatch_to_target(
182
+ target_id: number,
183
+ event: string,
184
+ data: unknown
185
+ ): void {
186
+ dep_manager.dispatch({
187
+ type: "event",
188
+ event_name: event,
189
+ target_id: target_id,
190
+ event_data: data
191
+ });
192
+ }
193
+
178
194
  setContext(GRADIO_ROOT, {
179
195
  register: app_tree.register_component.bind(app_tree),
180
196
  dispatcher: gradio_event_dispatcher
@@ -436,75 +452,75 @@
436
452
  style:margin-right={vibe_mode ? `${vibe_editor_width}px` : "0"}
437
453
  >
438
454
  <MountComponents node={app_tree.root} />
455
+ </div>
439
456
 
440
- {#if footer_links.length > 0}
441
- <footer bind:clientHeight={footer_height}>
442
- {#if footer_links.includes("api")}
443
- <button
444
- on:click={() => {
445
- set_api_docs_visible(!api_docs_visible);
446
- }}
447
- on:mouseenter={() => {
448
- loadApiDocs();
449
- loadApiRecorder();
450
- }}
451
- class="show-api"
452
- >
453
- {#if app.config?.mcp_server}
454
- {$reactive_formatter("errors.use_via_api_or_mcp")}
455
- {:else}
456
- {$reactive_formatter("errors.use_via_api")}
457
- {/if}
458
- <img src={api_logo} alt={$reactive_formatter("common.logo")} />
459
- </button>
460
- {/if}
461
- {#if footer_links.includes("gradio")}
462
- <div class="divider show-api-divider">·</div>
463
- <a
464
- href="https://gradio.app"
465
- class="built-with"
466
- target="_blank"
467
- rel="noreferrer"
468
- >
469
- {$reactive_formatter("common.built_with_gradio")}
470
- <img src={logo} alt={$reactive_formatter("common.logo")} />
471
- </a>
472
- {/if}
457
+ {#if footer_links.length > 0}
458
+ <footer bind:clientHeight={footer_height}>
459
+ {#if footer_links.includes("api")}
473
460
  <button
474
- class:hidden={!$is_screen_recording}
475
461
  on:click={() => {
476
- screen_recording();
462
+ set_api_docs_visible(!api_docs_visible);
463
+ }}
464
+ on:mouseenter={() => {
465
+ loadApiDocs();
466
+ loadApiRecorder();
477
467
  }}
478
- class="record"
468
+ class="show-api"
469
+ >
470
+ {#if app.config?.mcp_server}
471
+ {$reactive_formatter("errors.use_via_api_or_mcp")}
472
+ {:else}
473
+ {$reactive_formatter("errors.use_via_api")}
474
+ {/if}
475
+ <img src={api_logo} alt={$reactive_formatter("common.logo")} />
476
+ </button>
477
+ {/if}
478
+ {#if footer_links.includes("gradio")}
479
+ <div class="divider show-api-divider">·</div>
480
+ <a
481
+ href="https://gradio.app"
482
+ class="built-with"
483
+ target="_blank"
484
+ rel="noreferrer"
479
485
  >
480
- {$reactive_formatter("common.stop_recording")}
486
+ {$reactive_formatter("common.built_with_gradio")}
487
+ <img src={logo} alt={$reactive_formatter("common.logo")} />
488
+ </a>
489
+ {/if}
490
+ <button
491
+ class:hidden={!$is_screen_recording}
492
+ on:click={() => {
493
+ screen_recording();
494
+ }}
495
+ class="record"
496
+ >
497
+ {$reactive_formatter("common.stop_recording")}
498
+ <img
499
+ src={record_stop}
500
+ alt={$reactive_formatter("common.stop_recording")}
501
+ />
502
+ </button>
503
+ <div class="divider">·</div>
504
+ {#if footer_links.includes("settings")}
505
+ <div class="divider" class:hidden={!$is_screen_recording}>·</div>
506
+ <button
507
+ on:click={() => {
508
+ set_settings_visible(!settings_visible);
509
+ }}
510
+ on:mouseenter={() => {
511
+ loadSettings();
512
+ }}
513
+ class="settings"
514
+ >
515
+ {$reactive_formatter("common.settings")}
481
516
  <img
482
- src={record_stop}
483
- alt={$reactive_formatter("common.stop_recording")}
517
+ src={settings_logo}
518
+ alt={$reactive_formatter("common.settings")}
484
519
  />
485
520
  </button>
486
- <div class="divider">·</div>
487
- {#if footer_links.includes("settings")}
488
- <div class="divider" class:hidden={!$is_screen_recording}>·</div>
489
- <button
490
- on:click={() => {
491
- set_settings_visible(!settings_visible);
492
- }}
493
- on:mouseenter={() => {
494
- loadSettings();
495
- }}
496
- class="settings"
497
- >
498
- {$reactive_formatter("common.settings")}
499
- <img
500
- src={settings_logo}
501
- alt={$reactive_formatter("common.settings")}
502
- />
503
- </button>
504
- {/if}
505
- </footer>
506
- {/if}
507
- </div>
521
+ {/if}
522
+ </footer>
523
+ {/if}
508
524
  {#if api_recorder_visible && ApiRecorder}
509
525
  <!-- TODO: fix -->
510
526
  <!-- svelte-ignore a11y-click-events-have-key-events-->
@@ -47,6 +47,20 @@
47
47
  $: show_navbar =
48
48
  pages.length > 1 && (navbar === null || navbar.visible !== false);
49
49
 
50
+ function normalize_path(path: string): string {
51
+ // Remove query parameters, hash fragments, and leading/trailing slashes from the path
52
+ let normalized = path.split("?")[0].split("#")[0];
53
+ normalized = normalized.replace(/^\/+|\/+$/g, "");
54
+ return normalized;
55
+ }
56
+
57
+ function is_active_route(route: string, current: string): boolean {
58
+ if (route.startsWith("http://") || route.startsWith("https://")) {
59
+ return false;
60
+ }
61
+ return normalize_path(route) === normalize_path(current);
62
+ }
63
+
50
64
  $: effective_pages = (() => {
51
65
  let visible_pages = pages.filter(([route, label, show], index) => {
52
66
  if (index === 0 && route === "") {
@@ -100,7 +114,7 @@
100
114
  href={route.startsWith("http://") || route.startsWith("https://")
101
115
  ? route
102
116
  : `${root}/${route}`}
103
- class:active={route === current_page}
117
+ class:active={is_active_route(route, current_page)}
104
118
  data-sveltekit-reload
105
119
  target={route.startsWith("http://") || route.startsWith("https://")
106
120
  ? "_blank"
@@ -72,7 +72,7 @@
72
72
  </Block>
73
73
  </BaseForm>
74
74
 
75
- <BaseButton size="lg" variant="primary" on:click={submit}
75
+ <BaseButton size="lg" variant="primary" onclick={submit}
76
76
  >{i18n("login.login")}</BaseButton
77
77
  >
78
78
  </BaseColumn>
@@ -26,7 +26,7 @@
26
26
  size="sm"
27
27
  variant="secondary"
28
28
  elem_id="start-api-recorder"
29
- on:click={() => dispatch("close", { api_recorder_visible: true })}
29
+ onclick={() => dispatch("close", { api_recorder_visible: true })}
30
30
  >
31
31
  <div class="loading-dot self-baseline"></div>
32
32
  <p class="self-baseline btn-text">API Recorder</p>
@@ -60,7 +60,7 @@
60
60
  </Block>
61
61
 
62
62
  <span class="space" />
63
- <BaseButton variant="primary" on:click={run.bind(null, dependency_index)}>
63
+ <BaseButton variant="primary" onclick={run.bind(null, dependency_index)}>
64
64
  Try It Out
65
65
  </BaseButton>
66
66
 
@@ -6,7 +6,7 @@
6
6
  </script>
7
7
 
8
8
  <span class="space" />
9
- <BaseButton variant="primary" on:click={run.bind(null, dependency_index)}>
9
+ <BaseButton variant="primary" onclick={run.bind(null, dependency_index)}>
10
10
  Try It Out
11
11
  </BaseButton>
12
12
 
@@ -70,7 +70,7 @@ export class Dependency {
70
70
  if (this.functions.backend) {
71
71
  return {
72
72
  type: "submit",
73
- data: client.submit(this.id, _data_payload, event_data, target_id)
73
+ data: client.submit(this.id, _data_payload, event_data, target_id, undefined, { "x-gradio-user": "app" })
74
74
  };
75
75
  }
76
76
  else if (this.functions.frontend) {
@@ -229,10 +229,12 @@ export class AppTree {
229
229
  map.set(comp.id, comp);
230
230
  return map;
231
231
  }, new Map());
232
- const subtree = this.traverse(layout, (node) => {
232
+ const _subtree = this.traverse(layout, (node) => {
233
233
  const new_node = this.create_node(node, component_map, false, this.reactive_formatter);
234
234
  return new_node;
235
235
  });
236
+ gather_initial_tabs(_subtree, this.initial_tabs);
237
+ const subtree = this.traverse(_subtree, (node) => apply_initial_tabs(node, this.initial_tabs));
236
238
  const n = find_node_by_id(this.root, subtree.id);
237
239
  if (!n) {
238
240
  throw new Error("Rerender failed: root node not found in current tree");
package/package.json CHANGED
@@ -1,67 +1,67 @@
1
1
  {
2
2
  "name": "@gradio/core",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "devDependencies": {
6
- "@gradio/accordion": "^0.5.26",
7
- "@gradio/atoms": "^0.19.0",
8
- "@gradio/annotatedimage": "^0.10.1",
9
- "@gradio/box": "^0.2.26",
10
- "@gradio/audio": "^0.21.0",
11
- "@gradio/browserstate": "^0.3.3",
12
- "@gradio/button": "^0.6.0",
13
- "@gradio/chatbot": "^0.28.0",
14
- "@gradio/checkbox": "^0.5.1",
15
- "@gradio/code": "^0.16.0",
16
- "@gradio/checkboxgroup": "^0.8.0",
17
- "@gradio/colorpicker": "^0.5.1",
18
- "@gradio/column": "^0.3.0",
19
- "@gradio/client": "^2.0.0",
20
- "@gradio/dataset": "^0.5.0",
21
- "@gradio/dataframe": "^0.21.1",
22
- "@gradio/dropdown": "^0.10.7",
23
- "@gradio/datetime": "^0.3.23",
24
- "@gradio/downloadbutton": "^0.4.14",
25
- "@gradio/fallback": "^0.4.30",
26
- "@gradio/file": "^0.13.1",
27
- "@gradio/fileexplorer": "^0.5.42",
28
- "@gradio/form": "^0.2.27",
29
- "@gradio/gallery": "^0.15.36",
30
- "@gradio/group": "^0.3.0",
31
- "@gradio/highlightedtext": "^0.9.15",
32
- "@gradio/html": "^0.8.1",
33
- "@gradio/image": "^0.24.0",
6
+ "@gradio/accordion": "^0.5.28",
7
+ "@gradio/annotatedimage": "^0.11.0",
8
+ "@gradio/atoms": "^0.20.0",
9
+ "@gradio/button": "^0.6.2",
10
+ "@gradio/audio": "^0.22.0",
11
+ "@gradio/box": "^0.2.27",
12
+ "@gradio/chatbot": "^0.29.1",
13
+ "@gradio/checkbox": "^0.6.0",
14
+ "@gradio/browserstate": "^0.3.5",
15
+ "@gradio/client": "^2.0.2",
16
+ "@gradio/code": "^0.17.0",
17
+ "@gradio/column": "^0.3.1",
18
+ "@gradio/checkboxgroup": "^0.9.0",
19
+ "@gradio/dataframe": "^0.21.2",
20
+ "@gradio/colorpicker": "^0.5.3",
21
+ "@gradio/dataset": "^0.5.1",
22
+ "@gradio/datetime": "^0.4.0",
23
+ "@gradio/downloadbutton": "^0.4.16",
24
+ "@gradio/dropdown": "^0.11.1",
25
+ "@gradio/fallback": "^0.4.31",
26
+ "@gradio/fileexplorer": "^0.6.0",
27
+ "@gradio/file": "^0.14.0",
28
+ "@gradio/group": "^0.3.1",
29
+ "@gradio/highlightedtext": "^0.10.1",
30
+ "@gradio/form": "^0.2.28",
31
+ "@gradio/html": "^0.9.0",
34
32
  "@gradio/icons": "^0.15.0",
35
- "@gradio/imageeditor": "^0.18.2",
36
- "@gradio/json": "^0.5.32",
37
- "@gradio/imageslider": "^0.3.1",
38
- "@gradio/label": "^0.5.22",
39
- "@gradio/markdown": "^0.13.23",
40
- "@gradio/model3d": "^0.15.1",
41
- "@gradio/multimodaltextbox": "^0.11.1",
42
- "@gradio/number": "^0.7.2",
43
- "@gradio/plot": "^0.9.25",
44
- "@gradio/nativeplot": "^0.9.1",
45
- "@gradio/paramviewer": "^0.9.0",
46
- "@gradio/radio": "^0.8.0",
33
+ "@gradio/image": "^0.25.0",
34
+ "@gradio/gallery": "^0.16.1",
35
+ "@gradio/imageslider": "^0.4.0",
36
+ "@gradio/imageeditor": "^0.18.3",
37
+ "@gradio/label": "^0.6.0",
38
+ "@gradio/json": "^0.6.0",
39
+ "@gradio/model3d": "^0.16.1",
40
+ "@gradio/markdown": "^0.13.25",
41
+ "@gradio/multimodaltextbox": "^0.11.3",
42
+ "@gradio/nativeplot": "^0.9.3",
43
+ "@gradio/number": "^0.8.0",
44
+ "@gradio/plot": "^0.10.1",
45
+ "@gradio/paramviewer": "^0.9.1",
46
+ "@gradio/radio": "^0.9.0",
47
47
  "@gradio/row": "^0.3.0",
48
- "@gradio/sidebar": "^0.1.24",
49
- "@gradio/simpleimage": "^0.9.1",
50
- "@gradio/simpledropdown": "^0.3.30",
51
- "@gradio/simpletextbox": "^0.3.31",
52
- "@gradio/slider": "^0.7.1",
53
- "@gradio/state": "^0.2.0",
54
- "@gradio/tabitem": "^0.6.3",
55
- "@gradio/statustracker": "^0.12.0",
56
- "@gradio/textbox": "^0.12.1",
57
- "@gradio/tabs": "^0.5.3",
58
- "@gradio/theme": "^0.5.0",
59
- "@gradio/timer": "^0.4.6",
60
- "@gradio/uploadbutton": "^0.9.14",
61
- "@gradio/utils": "^0.10.4",
62
- "@gradio/vibeeditor": "^0.3.1",
63
- "@gradio/video": "^0.18.0",
64
- "@gradio/upload": "^0.17.2"
48
+ "@gradio/sidebar": "^0.2.0",
49
+ "@gradio/simpledropdown": "^0.3.31",
50
+ "@gradio/simpleimage": "^0.9.2",
51
+ "@gradio/simpletextbox": "^0.3.33",
52
+ "@gradio/state": "^0.2.1",
53
+ "@gradio/tabitem": "^0.6.4",
54
+ "@gradio/slider": "^0.7.2",
55
+ "@gradio/statustracker": "^0.12.1",
56
+ "@gradio/textbox": "^0.13.1",
57
+ "@gradio/tabs": "^0.5.4",
58
+ "@gradio/theme": "^0.6.0",
59
+ "@gradio/timer": "^0.4.7",
60
+ "@gradio/upload": "^0.17.3",
61
+ "@gradio/uploadbutton": "^0.9.16",
62
+ "@gradio/vibeeditor": "^0.3.2",
63
+ "@gradio/utils": "^0.11.1",
64
+ "@gradio/video": "^0.20.0"
65
65
  },
66
66
  "msw": {
67
67
  "workerDirectory": "public"
package/src/Blocks.svelte CHANGED
@@ -140,6 +140,9 @@
140
140
  // update_status(id, "complete", data);
141
141
  } else if (event == "close_stream") {
142
142
  dep_manager.close_stream(id);
143
+ } else if (event === "custom_button_click") {
144
+ const button_id = (data as { id: number }).id;
145
+ dispatch_to_target(button_id, "click", null);
143
146
  } else {
144
147
  // Tabs are a bit weird. The Tabs component dispatches 'select' events
145
148
  // but the target id corresponds to the child Tab component that was selected.
@@ -175,6 +178,19 @@
175
178
  gradio_event_dispatcher
176
179
  );
177
180
 
181
+ function dispatch_to_target(
182
+ target_id: number,
183
+ event: string,
184
+ data: unknown
185
+ ): void {
186
+ dep_manager.dispatch({
187
+ type: "event",
188
+ event_name: event,
189
+ target_id: target_id,
190
+ event_data: data
191
+ });
192
+ }
193
+
178
194
  setContext(GRADIO_ROOT, {
179
195
  register: app_tree.register_component.bind(app_tree),
180
196
  dispatcher: gradio_event_dispatcher
@@ -436,75 +452,75 @@
436
452
  style:margin-right={vibe_mode ? `${vibe_editor_width}px` : "0"}
437
453
  >
438
454
  <MountComponents node={app_tree.root} />
455
+ </div>
439
456
 
440
- {#if footer_links.length > 0}
441
- <footer bind:clientHeight={footer_height}>
442
- {#if footer_links.includes("api")}
443
- <button
444
- on:click={() => {
445
- set_api_docs_visible(!api_docs_visible);
446
- }}
447
- on:mouseenter={() => {
448
- loadApiDocs();
449
- loadApiRecorder();
450
- }}
451
- class="show-api"
452
- >
453
- {#if app.config?.mcp_server}
454
- {$reactive_formatter("errors.use_via_api_or_mcp")}
455
- {:else}
456
- {$reactive_formatter("errors.use_via_api")}
457
- {/if}
458
- <img src={api_logo} alt={$reactive_formatter("common.logo")} />
459
- </button>
460
- {/if}
461
- {#if footer_links.includes("gradio")}
462
- <div class="divider show-api-divider">·</div>
463
- <a
464
- href="https://gradio.app"
465
- class="built-with"
466
- target="_blank"
467
- rel="noreferrer"
468
- >
469
- {$reactive_formatter("common.built_with_gradio")}
470
- <img src={logo} alt={$reactive_formatter("common.logo")} />
471
- </a>
472
- {/if}
457
+ {#if footer_links.length > 0}
458
+ <footer bind:clientHeight={footer_height}>
459
+ {#if footer_links.includes("api")}
473
460
  <button
474
- class:hidden={!$is_screen_recording}
475
461
  on:click={() => {
476
- screen_recording();
462
+ set_api_docs_visible(!api_docs_visible);
463
+ }}
464
+ on:mouseenter={() => {
465
+ loadApiDocs();
466
+ loadApiRecorder();
477
467
  }}
478
- class="record"
468
+ class="show-api"
469
+ >
470
+ {#if app.config?.mcp_server}
471
+ {$reactive_formatter("errors.use_via_api_or_mcp")}
472
+ {:else}
473
+ {$reactive_formatter("errors.use_via_api")}
474
+ {/if}
475
+ <img src={api_logo} alt={$reactive_formatter("common.logo")} />
476
+ </button>
477
+ {/if}
478
+ {#if footer_links.includes("gradio")}
479
+ <div class="divider show-api-divider">·</div>
480
+ <a
481
+ href="https://gradio.app"
482
+ class="built-with"
483
+ target="_blank"
484
+ rel="noreferrer"
479
485
  >
480
- {$reactive_formatter("common.stop_recording")}
486
+ {$reactive_formatter("common.built_with_gradio")}
487
+ <img src={logo} alt={$reactive_formatter("common.logo")} />
488
+ </a>
489
+ {/if}
490
+ <button
491
+ class:hidden={!$is_screen_recording}
492
+ on:click={() => {
493
+ screen_recording();
494
+ }}
495
+ class="record"
496
+ >
497
+ {$reactive_formatter("common.stop_recording")}
498
+ <img
499
+ src={record_stop}
500
+ alt={$reactive_formatter("common.stop_recording")}
501
+ />
502
+ </button>
503
+ <div class="divider">·</div>
504
+ {#if footer_links.includes("settings")}
505
+ <div class="divider" class:hidden={!$is_screen_recording}>·</div>
506
+ <button
507
+ on:click={() => {
508
+ set_settings_visible(!settings_visible);
509
+ }}
510
+ on:mouseenter={() => {
511
+ loadSettings();
512
+ }}
513
+ class="settings"
514
+ >
515
+ {$reactive_formatter("common.settings")}
481
516
  <img
482
- src={record_stop}
483
- alt={$reactive_formatter("common.stop_recording")}
517
+ src={settings_logo}
518
+ alt={$reactive_formatter("common.settings")}
484
519
  />
485
520
  </button>
486
- <div class="divider">·</div>
487
- {#if footer_links.includes("settings")}
488
- <div class="divider" class:hidden={!$is_screen_recording}>·</div>
489
- <button
490
- on:click={() => {
491
- set_settings_visible(!settings_visible);
492
- }}
493
- on:mouseenter={() => {
494
- loadSettings();
495
- }}
496
- class="settings"
497
- >
498
- {$reactive_formatter("common.settings")}
499
- <img
500
- src={settings_logo}
501
- alt={$reactive_formatter("common.settings")}
502
- />
503
- </button>
504
- {/if}
505
- </footer>
506
- {/if}
507
- </div>
521
+ {/if}
522
+ </footer>
523
+ {/if}
508
524
  {#if api_recorder_visible && ApiRecorder}
509
525
  <!-- TODO: fix -->
510
526
  <!-- svelte-ignore a11y-click-events-have-key-events-->
package/src/Embed.svelte CHANGED
@@ -47,6 +47,20 @@
47
47
  $: show_navbar =
48
48
  pages.length > 1 && (navbar === null || navbar.visible !== false);
49
49
 
50
+ function normalize_path(path: string): string {
51
+ // Remove query parameters, hash fragments, and leading/trailing slashes from the path
52
+ let normalized = path.split("?")[0].split("#")[0];
53
+ normalized = normalized.replace(/^\/+|\/+$/g, "");
54
+ return normalized;
55
+ }
56
+
57
+ function is_active_route(route: string, current: string): boolean {
58
+ if (route.startsWith("http://") || route.startsWith("https://")) {
59
+ return false;
60
+ }
61
+ return normalize_path(route) === normalize_path(current);
62
+ }
63
+
50
64
  $: effective_pages = (() => {
51
65
  let visible_pages = pages.filter(([route, label, show], index) => {
52
66
  if (index === 0 && route === "") {
@@ -100,7 +114,7 @@
100
114
  href={route.startsWith("http://") || route.startsWith("https://")
101
115
  ? route
102
116
  : `${root}/${route}`}
103
- class:active={route === current_page}
117
+ class:active={is_active_route(route, current_page)}
104
118
  data-sveltekit-reload
105
119
  target={route.startsWith("http://") || route.startsWith("https://")
106
120
  ? "_blank"
package/src/Login.svelte CHANGED
@@ -72,7 +72,7 @@
72
72
  </Block>
73
73
  </BaseForm>
74
74
 
75
- <BaseButton size="lg" variant="primary" on:click={submit}
75
+ <BaseButton size="lg" variant="primary" onclick={submit}
76
76
  >{i18n("login.login")}</BaseButton
77
77
  >
78
78
  </BaseColumn>
@@ -26,7 +26,7 @@
26
26
  size="sm"
27
27
  variant="secondary"
28
28
  elem_id="start-api-recorder"
29
- on:click={() => dispatch("close", { api_recorder_visible: true })}
29
+ onclick={() => dispatch("close", { api_recorder_visible: true })}
30
30
  >
31
31
  <div class="loading-dot self-baseline"></div>
32
32
  <p class="self-baseline btn-text">API Recorder</p>
@@ -60,7 +60,7 @@
60
60
  </Block>
61
61
 
62
62
  <span class="space" />
63
- <BaseButton variant="primary" on:click={run.bind(null, dependency_index)}>
63
+ <BaseButton variant="primary" onclick={run.bind(null, dependency_index)}>
64
64
  Try It Out
65
65
  </BaseButton>
66
66
 
@@ -6,7 +6,7 @@
6
6
  </script>
7
7
 
8
8
  <span class="space" />
9
- <BaseButton variant="primary" on:click={run.bind(null, dependency_index)}>
9
+ <BaseButton variant="primary" onclick={run.bind(null, dependency_index)}>
10
10
  Try It Out
11
11
  </BaseButton>
12
12
 
package/src/dependency.ts CHANGED
@@ -113,7 +113,14 @@ export class Dependency {
113
113
  if (this.functions.backend) {
114
114
  return {
115
115
  type: "submit",
116
- data: client.submit(this.id, _data_payload, event_data, target_id)
116
+ data: client.submit(
117
+ this.id,
118
+ _data_payload,
119
+ event_data,
120
+ target_id,
121
+ undefined,
122
+ { "x-gradio-user": "app" }
123
+ )
117
124
  };
118
125
  } else if (this.functions.frontend) {
119
126
  return { type: "data", data: _data_payload };
@@ -365,7 +365,7 @@ export class AppTree {
365
365
  map.set(comp.id, comp);
366
366
  return map;
367
367
  }, new Map<number, ComponentMeta>());
368
- const subtree = this.traverse(layout, (node) => {
368
+ const _subtree = this.traverse(layout, (node) => {
369
369
  const new_node = this.create_node(
370
370
  node,
371
371
  component_map,
@@ -374,7 +374,10 @@ export class AppTree {
374
374
  );
375
375
  return new_node;
376
376
  });
377
-
377
+ gather_initial_tabs(_subtree, this.initial_tabs);
378
+ const subtree = this.traverse(_subtree, (node) =>
379
+ apply_initial_tabs(node, this.initial_tabs)
380
+ );
378
381
  const n = find_node_by_id(this.root!, subtree.id);
379
382
 
380
383
  if (!n) {