@gradio/core 1.4.0 → 1.4.2

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,58 @@
1
1
  # @gradio/core
2
2
 
3
+ ## 1.4.2
4
+
5
+ ### Fixes
6
+
7
+ - [#13048](https://github.com/gradio-app/gradio/pull/13048) [`a5d4096`](https://github.com/gradio-app/gradio/commit/a5d40965bba21a832da522127048926b71c1a6dd) - Fix Tab Interactive Bug. Thanks @freddyaboulton!
8
+ - [#13172](https://github.com/gradio-app/gradio/pull/13172) [`03a9d4c`](https://github.com/gradio-app/gradio/commit/03a9d4c99f3c9466e4fc162d02800850ed67a29e) - fix: prevent [object Object] when label matches a nested i18n key. Thanks @mango766!
9
+
10
+ ### Dependency updates
11
+
12
+ - @gradio/utils@0.12.2
13
+ - @gradio/atoms@0.23.0
14
+ - @gradio/statustracker@0.13.1
15
+ - @gradio/upload@0.17.8
16
+ - @gradio/tabs@0.5.9
17
+ - @gradio/code@0.17.6
18
+ - @gradio/html@0.12.1
19
+ - @gradio/paramviewer@0.9.7
20
+ - @gradio/image@0.26.1
21
+ - @gradio/checkbox@0.6.6
22
+ - @gradio/video@0.20.6
23
+ - @gradio/file@0.14.6
24
+ - @gradio/gallery@0.17.5
25
+ - @gradio/plot@0.10.7
26
+ - @gradio/textbox@0.13.7
27
+ - @gradio/dropdown@0.11.7
28
+ - @gradio/audio@0.23.1
29
+
30
+ ## 1.4.1
31
+
32
+ ### Fixes
33
+
34
+ - [#12566](https://github.com/gradio-app/gradio/pull/12566) [`7760161`](https://github.com/gradio-app/gradio/commit/7760161258abe6329b754dd6d2511fc3b61fed95) - Fix custom components in SSR Mode + Custom Component Examples. Thanks @freddyaboulton!
35
+ - [#12803](https://github.com/gradio-app/gradio/pull/12803) [`f4c3a6d`](https://github.com/gradio-app/gradio/commit/f4c3a6dcb45218722d3150baef953c731d3eccf2) - fix: gradio_api path in mount_gradio_app. Thanks @shandowc!
36
+
37
+ ### Dependency updates
38
+
39
+ - @gradio/utils@0.12.1
40
+ - @gradio/statustracker@0.13.0
41
+ - @gradio/gallery@0.17.4
42
+ - @gradio/plot@0.10.6
43
+ - @gradio/textbox@0.13.6
44
+ - @gradio/html@0.12.0
45
+ - @gradio/button@0.6.6
46
+ - @gradio/code@0.17.5
47
+ - @gradio/paramviewer@0.9.6
48
+ - @gradio/checkbox@0.6.5
49
+ - @gradio/image@0.26.0
50
+ - @gradio/video@0.20.5
51
+ - @gradio/file@0.14.5
52
+ - @gradio/audio@0.23.0
53
+ - @gradio/column@0.3.2
54
+ - @gradio/dropdown@0.11.6
55
+
3
56
  ## 1.4.0
4
57
 
5
58
  ### Features
@@ -12,7 +12,8 @@ export function formatter(value) {
12
12
  return translate_i18n_marker(string_value, translate);
13
13
  }
14
14
  const direct_translation = translate(string_value);
15
- if (direct_translation !== string_value) {
15
+ if (typeof direct_translation === "string" &&
16
+ direct_translation !== string_value) {
16
17
  return direct_translation;
17
18
  }
18
19
  return string_value;
@@ -15,6 +15,7 @@ type Tab = {
15
15
  order?: number;
16
16
  component_id: number;
17
17
  };
18
+ export declare function get_api_url(config: Omit<AppConfig, "api_url">): string;
18
19
  export declare class AppTree {
19
20
  #private;
20
21
  /** Need this to set i18n in re-render */
@@ -8,6 +8,19 @@ const type_map = {
8
8
  walkthrough: "tabs",
9
9
  walkthroughstep: "tabitem"
10
10
  };
11
+ export function get_api_url(config) {
12
+ // Handle api_prefix correctly when app is mounted at a subpath.
13
+ // config.root may not include a trailing slash, so we normalize its pathname
14
+ // before appending api_prefix to ensure correct URL construction.
15
+ const rootUrl = new URL(config.root);
16
+ const rootPath = rootUrl.pathname.endsWith("/")
17
+ ? rootUrl.pathname
18
+ : rootUrl.pathname + "/";
19
+ const apiPrefix = config.api_prefix.startsWith("/")
20
+ ? config.api_prefix
21
+ : "/" + config.api_prefix;
22
+ return new URL(rootPath.slice(0, -1) + apiPrefix, rootUrl.origin).toString();
23
+ }
11
24
  export class AppTree {
12
25
  /** the raw component structure received from the backend */
13
26
  #component_payload;
@@ -45,9 +58,10 @@ export class AppTree {
45
58
  this.ready_resolve = resolve;
46
59
  });
47
60
  this.reactive_formatter = reactive_formatter;
61
+ const api_url = get_api_url(config);
48
62
  this.#config = {
49
63
  ...config,
50
- api_url: new URL(config.api_prefix, config.root).toString()
64
+ api_url
51
65
  };
52
66
  this.#component_payload = components;
53
67
  this.#layout_payload = layout;
@@ -77,9 +91,10 @@ export class AppTree {
77
91
  reload(components, layout, dependencies, config) {
78
92
  this.#layout_payload = layout;
79
93
  this.#component_payload = components;
94
+ const api_url = get_api_url(config);
80
95
  this.#config = {
81
96
  ...config,
82
- api_url: new URL(config.api_prefix, config.root).toString()
97
+ api_url
83
98
  };
84
99
  this.#dependency_payload = dependencies;
85
100
  this.root = this.create_node({ id: layout.id, children: [] }, new Map(), true);
@@ -268,11 +283,6 @@ export class AppTree {
268
283
  * @param new_state the new state to set
269
284
  * */
270
285
  async update_state(id, new_state, check_visibility = true) {
271
- // Visibility is tricky 😅
272
- // If the component is not visible, it has not been rendered
273
- // and so it has no _set_data callback
274
- // Therefore, we need to traverse the tree and set the visible prop to true
275
- // and then render it and its children. After that, we can call the _set_data callback
276
286
  const node = find_node_by_id(this.root, id);
277
287
  let already_updated_visibility = false;
278
288
  if (check_visibility && !node?.component) {
@@ -310,6 +320,11 @@ export class AppTree {
310
320
  if ("value" in new_state && !dequal(old_value, new_state.value)) {
311
321
  this.#event_dispatcher(id, "change", null);
312
322
  }
323
+ // If this is a non-mounted tabitem, update the parent Tabs'
324
+ // initial_tabs so the tab button reflects the new state.
325
+ if (node?.type === "tabitem") {
326
+ this.#update_parent_tabs_initial_tab(id, node);
327
+ }
313
328
  }
314
329
  else if (_set_data) {
315
330
  _set_data(new_state);
@@ -334,6 +349,48 @@ export class AppTree {
334
349
  this.update_visibility(child, new_state);
335
350
  });
336
351
  }
352
+ /**
353
+ * Updates the parent Tabs component's initial_tabs when a non-mounted
354
+ * tabitem's props change. This ensures the tab button (rendered by
355
+ * the Tabs component) reflects the updated state even though the
356
+ * TabItem component itself is not mounted.
357
+ */
358
+ #update_parent_tabs_initial_tab(id, node) {
359
+ const parent = find_parent(this.root, id);
360
+ if (!parent || parent.type !== "tabs")
361
+ return;
362
+ const initial_tabs = parent.props.props.initial_tabs;
363
+ if (!initial_tabs)
364
+ return;
365
+ const tab_index = initial_tabs.findIndex((t) => t.component_id === node.id);
366
+ if (tab_index === -1)
367
+ return;
368
+ const i18n = node.props.props.i18n;
369
+ const raw_label = node.props.shared_props.label;
370
+ // Use original_visibility since the node's visible may have been
371
+ // set to false by the startup optimization for non-selected tabs.
372
+ const visible = "original_visibility" in node
373
+ ? node.original_visibility
374
+ : node.props.shared_props.visible;
375
+ initial_tabs[tab_index] = {
376
+ label: i18n ? i18n(raw_label) : raw_label,
377
+ id: node.props.props.id,
378
+ elem_id: node.props.shared_props.elem_id,
379
+ visible,
380
+ interactive: node.props.shared_props.interactive,
381
+ scale: node.props.shared_props.scale || null,
382
+ component_id: node.id
383
+ };
384
+ // Trigger reactivity by replacing the array
385
+ parent.props.props.initial_tabs = [...initial_tabs];
386
+ // Also update via _set_data if the Tabs component is mounted
387
+ const parent_set_data = this.#set_callbacks.get(parent.id);
388
+ if (parent_set_data) {
389
+ parent_set_data({
390
+ initial_tabs: parent.props.props.initial_tabs
391
+ });
392
+ }
393
+ }
337
394
  /**
338
395
  * Gets the current state of a component by its ID
339
396
  * @param id the ID of the component to get the state of
@@ -469,7 +526,7 @@ function gather_props(id, props, dependencies, client, api_url, additional = {})
469
526
  _shared_props.client = client;
470
527
  _shared_props.id = id;
471
528
  _shared_props.interactive = determine_interactivity(id, _shared_props.interactive, _props.value, dependencies);
472
- _shared_props.load_component = (name, variant) => get_component(name, "", api_url, variant).component;
529
+ _shared_props.load_component = (name, variant, component_class_id) => get_component(name, component_class_id || "", api_url, variant);
473
530
  _shared_props.visible =
474
531
  _shared_props.visible === undefined ? true : _shared_props.visible;
475
532
  _shared_props.loading_status = {};
@@ -0,0 +1 @@
1
+ export {};