@gradio/core 1.4.1 → 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,32 @@
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
+
3
30
  ## 1.4.1
4
31
 
5
32
  ### Fixes
@@ -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;
@@ -283,11 +283,6 @@ export class AppTree {
283
283
  * @param new_state the new state to set
284
284
  * */
285
285
  async update_state(id, new_state, check_visibility = true) {
286
- // Visibility is tricky 😅
287
- // If the component is not visible, it has not been rendered
288
- // and so it has no _set_data callback
289
- // Therefore, we need to traverse the tree and set the visible prop to true
290
- // and then render it and its children. After that, we can call the _set_data callback
291
286
  const node = find_node_by_id(this.root, id);
292
287
  let already_updated_visibility = false;
293
288
  if (check_visibility && !node?.component) {
@@ -325,6 +320,11 @@ export class AppTree {
325
320
  if ("value" in new_state && !dequal(old_value, new_state.value)) {
326
321
  this.#event_dispatcher(id, "change", null);
327
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
+ }
328
328
  }
329
329
  else if (_set_data) {
330
330
  _set_data(new_state);
@@ -349,6 +349,48 @@ export class AppTree {
349
349
  this.update_visibility(child, new_state);
350
350
  });
351
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
+ }
352
394
  /**
353
395
  * Gets the current state of a component by its ID
354
396
  * @param id the ID of the component to get the state of
package/package.json CHANGED
@@ -1,67 +1,67 @@
1
1
  {
2
2
  "name": "@gradio/core",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "type": "module",
5
5
  "devDependencies": {
6
- "@gradio/accordion": "^0.5.33",
7
- "@gradio/atoms": "^0.22.2",
8
- "@gradio/annotatedimage": "^0.11.5",
9
- "@gradio/audio": "^0.23.0",
10
- "@gradio/box": "^0.2.30",
6
+ "@gradio/accordion": "^0.5.34",
7
+ "@gradio/annotatedimage": "^0.11.6",
8
+ "@gradio/atoms": "^0.23.0",
9
+ "@gradio/audio": "^0.23.1",
10
+ "@gradio/box": "^0.2.31",
11
11
  "@gradio/browserstate": "^0.3.7",
12
12
  "@gradio/button": "^0.6.6",
13
- "@gradio/chatbot": "^0.29.6",
14
- "@gradio/checkbox": "^0.6.5",
15
- "@gradio/checkboxgroup": "^0.10.0",
16
- "@gradio/code": "^0.17.5",
13
+ "@gradio/checkbox": "^0.6.6",
14
+ "@gradio/chatbot": "^0.29.7",
15
+ "@gradio/checkboxgroup": "^0.10.1",
17
16
  "@gradio/client": "^2.1.0",
17
+ "@gradio/code": "^0.17.6",
18
+ "@gradio/colorpicker": "^0.5.9",
18
19
  "@gradio/column": "^0.3.2",
19
- "@gradio/dataframe": "^0.22.0",
20
- "@gradio/dataset": "^0.5.6",
21
- "@gradio/colorpicker": "^0.5.8",
22
- "@gradio/datetime": "^0.4.5",
20
+ "@gradio/dataframe": "^0.23.0",
21
+ "@gradio/dataset": "^0.5.7",
23
22
  "@gradio/downloadbutton": "^0.4.18",
24
- "@gradio/dropdown": "^0.11.6",
25
- "@gradio/fallback": "^0.4.36",
26
- "@gradio/file": "^0.14.5",
27
- "@gradio/fileexplorer": "^0.6.5",
28
- "@gradio/form": "^0.3.1",
29
- "@gradio/gallery": "^0.17.4",
30
- "@gradio/group": "^0.3.3",
31
- "@gradio/highlightedtext": "^0.11.4",
32
- "@gradio/html": "^0.12.0",
23
+ "@gradio/dropdown": "^0.11.7",
24
+ "@gradio/fallback": "^0.4.37",
25
+ "@gradio/datetime": "^0.4.6",
26
+ "@gradio/file": "^0.14.6",
27
+ "@gradio/fileexplorer": "^0.6.6",
28
+ "@gradio/form": "^0.3.2",
29
+ "@gradio/highlightedtext": "^0.11.5",
30
+ "@gradio/group": "^0.3.4",
31
+ "@gradio/gallery": "^0.17.5",
32
+ "@gradio/html": "^0.12.1",
33
33
  "@gradio/icons": "^0.15.1",
34
- "@gradio/imageeditor": "^0.18.8",
35
- "@gradio/image": "^0.26.0",
36
- "@gradio/imageslider": "^0.4.5",
37
- "@gradio/json": "^0.7.4",
38
- "@gradio/model3d": "^0.16.6",
39
- "@gradio/markdown": "^0.13.30",
40
- "@gradio/multimodaltextbox": "^0.11.8",
41
- "@gradio/label": "^0.6.5",
42
- "@gradio/nativeplot": "^0.10.4",
43
- "@gradio/number": "^0.8.5",
44
- "@gradio/radio": "^0.10.0",
45
- "@gradio/plot": "^0.10.6",
46
- "@gradio/paramviewer": "^0.9.6",
34
+ "@gradio/image": "^0.26.1",
35
+ "@gradio/imageeditor": "^0.18.9",
36
+ "@gradio/imageslider": "^0.4.6",
37
+ "@gradio/label": "^0.6.6",
38
+ "@gradio/json": "^0.7.5",
39
+ "@gradio/model3d": "^0.16.7",
40
+ "@gradio/markdown": "^0.13.31",
41
+ "@gradio/multimodaltextbox": "^0.11.9",
42
+ "@gradio/number": "^0.8.6",
43
+ "@gradio/nativeplot": "^0.10.5",
44
+ "@gradio/paramviewer": "^0.9.7",
45
+ "@gradio/plot": "^0.10.7",
46
+ "@gradio/radio": "^0.10.1",
47
47
  "@gradio/row": "^0.3.1",
48
- "@gradio/simpleimage": "^0.9.7",
49
- "@gradio/simpledropdown": "^0.3.36",
50
- "@gradio/simpletextbox": "^0.3.38",
51
- "@gradio/sidebar": "^0.2.5",
52
- "@gradio/state": "^0.2.3",
53
- "@gradio/slider": "^0.7.8",
54
- "@gradio/statustracker": "^0.13.0",
55
- "@gradio/tabs": "^0.5.8",
48
+ "@gradio/simpledropdown": "^0.3.37",
49
+ "@gradio/sidebar": "^0.2.6",
50
+ "@gradio/simpleimage": "^0.9.8",
51
+ "@gradio/simpletextbox": "^0.3.39",
52
+ "@gradio/slider": "^0.7.9",
53
+ "@gradio/statustracker": "^0.13.1",
56
54
  "@gradio/tabitem": "^0.6.6",
57
- "@gradio/textbox": "^0.13.6",
55
+ "@gradio/state": "^0.2.3",
56
+ "@gradio/tabs": "^0.5.9",
57
+ "@gradio/textbox": "^0.13.7",
58
58
  "@gradio/theme": "^0.6.1",
59
+ "@gradio/upload": "^0.17.8",
59
60
  "@gradio/timer": "^0.4.9",
60
- "@gradio/upload": "^0.17.7",
61
- "@gradio/utils": "^0.12.1",
61
+ "@gradio/utils": "^0.12.2",
62
62
  "@gradio/uploadbutton": "^0.9.18",
63
- "@gradio/vibeeditor": "^0.3.7",
64
- "@gradio/video": "^0.20.5"
63
+ "@gradio/vibeeditor": "^0.3.8",
64
+ "@gradio/video": "^0.20.6"
65
65
  },
66
66
  "msw": {
67
67
  "workerDirectory": "public"
@@ -17,7 +17,10 @@ export function formatter(value: string | null | undefined): string {
17
17
  }
18
18
 
19
19
  const direct_translation = translate(string_value);
20
- if (direct_translation !== string_value) {
20
+ if (
21
+ typeof direct_translation === "string" &&
22
+ direct_translation !== string_value
23
+ ) {
21
24
  return direct_translation;
22
25
  }
23
26
 
@@ -437,11 +437,6 @@ export class AppTree {
437
437
  new_state: Partial<SharedProps> & Record<string, unknown>,
438
438
  check_visibility: boolean = true
439
439
  ) {
440
- // Visibility is tricky 😅
441
- // If the component is not visible, it has not been rendered
442
- // and so it has no _set_data callback
443
- // Therefore, we need to traverse the tree and set the visible prop to true
444
- // and then render it and its children. After that, we can call the _set_data callback
445
440
  const node = find_node_by_id(this.root!, id);
446
441
  let already_updated_visibility = false;
447
442
  if (check_visibility && !node?.component) {
@@ -481,6 +476,12 @@ export class AppTree {
481
476
  if ("value" in new_state && !dequal(old_value, new_state.value)) {
482
477
  this.#event_dispatcher(id, "change", null);
483
478
  }
479
+
480
+ // If this is a non-mounted tabitem, update the parent Tabs'
481
+ // initial_tabs so the tab button reflects the new state.
482
+ if (node?.type === "tabitem") {
483
+ this.#update_parent_tabs_initial_tab(id, node);
484
+ }
484
485
  } else if (_set_data) {
485
486
  _set_data(new_state);
486
487
  }
@@ -508,6 +509,55 @@ export class AppTree {
508
509
  });
509
510
  }
510
511
 
512
+ /**
513
+ * Updates the parent Tabs component's initial_tabs when a non-mounted
514
+ * tabitem's props change. This ensures the tab button (rendered by
515
+ * the Tabs component) reflects the updated state even though the
516
+ * TabItem component itself is not mounted.
517
+ */
518
+ #update_parent_tabs_initial_tab(
519
+ id: number,
520
+ node: ProcessedComponentMeta
521
+ ): void {
522
+ const parent = find_parent(this.root!, id);
523
+ if (!parent || parent.type !== "tabs") return;
524
+
525
+ const initial_tabs = parent.props.props.initial_tabs as Tab[];
526
+ if (!initial_tabs) return;
527
+
528
+ const tab_index = initial_tabs.findIndex((t) => t.component_id === node.id);
529
+ if (tab_index === -1) return;
530
+
531
+ const i18n = node.props.props.i18n as ((str: string) => string) | undefined;
532
+ const raw_label = node.props.shared_props.label as string;
533
+ // Use original_visibility since the node's visible may have been
534
+ // set to false by the startup optimization for non-selected tabs.
535
+ const visible =
536
+ "original_visibility" in node
537
+ ? (node.original_visibility as boolean)
538
+ : (node.props.shared_props.visible as boolean);
539
+ initial_tabs[tab_index] = {
540
+ label: i18n ? i18n(raw_label) : raw_label,
541
+ id: node.props.props.id as string,
542
+ elem_id: node.props.shared_props.elem_id,
543
+ visible,
544
+ interactive: node.props.shared_props.interactive,
545
+ scale: node.props.shared_props.scale || null,
546
+ component_id: node.id
547
+ };
548
+
549
+ // Trigger reactivity by replacing the array
550
+ parent.props.props.initial_tabs = [...initial_tabs];
551
+
552
+ // Also update via _set_data if the Tabs component is mounted
553
+ const parent_set_data = this.#set_callbacks.get(parent.id);
554
+ if (parent_set_data) {
555
+ parent_set_data({
556
+ initial_tabs: parent.props.props.initial_tabs
557
+ });
558
+ }
559
+ }
560
+
511
561
  /**
512
562
  * Gets the current state of a component by its ID
513
563
  * @param id the ID of the component to get the state of