@gradio/core 0.5.0 → 0.6.0

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/src/Blocks.svelte +73 -4
  3. package/dist/src/Render.svelte +1 -0
  4. package/dist/src/RenderComponent.svelte +4 -0
  5. package/dist/src/RenderComponent.svelte.d.ts +1 -0
  6. package/dist/src/api_docs/Settings.svelte +175 -0
  7. package/dist/src/api_docs/Settings.svelte.d.ts +20 -0
  8. package/dist/src/api_docs/SettingsBanner.svelte +71 -0
  9. package/dist/src/api_docs/SettingsBanner.svelte.d.ts +18 -0
  10. package/dist/src/api_docs/img/settings-logo.svg +8 -0
  11. package/dist/src/api_docs/index.d.ts +1 -0
  12. package/dist/src/api_docs/index.js +1 -0
  13. package/dist/src/i18n.d.ts +2 -0
  14. package/dist/src/i18n.js +16 -2
  15. package/dist/src/init.js +15 -8
  16. package/dist/src/lang/ar.json +117 -3
  17. package/dist/src/lang/ca.json +113 -2
  18. package/dist/src/lang/ckb.json +42 -20
  19. package/dist/src/lang/de.json +116 -2
  20. package/dist/src/lang/en.json +6 -1
  21. package/dist/src/lang/es.json +116 -3
  22. package/dist/src/lang/eu.json +122 -8
  23. package/dist/src/lang/fa.json +120 -6
  24. package/dist/src/lang/fi.json +52 -46
  25. package/dist/src/lang/fr.json +113 -13
  26. package/dist/src/lang/he.json +122 -8
  27. package/dist/src/lang/hi.json +123 -9
  28. package/dist/src/lang/ja.json +114 -9
  29. package/dist/src/lang/ko.json +123 -9
  30. package/dist/src/lang/lt.json +3 -1
  31. package/dist/src/lang/nb.json +130 -0
  32. package/dist/src/lang/nl.json +3 -1
  33. package/dist/src/lang/pl.json +121 -7
  34. package/dist/src/lang/pt-BR.json +1 -0
  35. package/dist/src/lang/pt.json +130 -0
  36. package/dist/src/lang/ro.json +130 -0
  37. package/dist/src/lang/ru.json +54 -42
  38. package/dist/src/lang/ta.json +1 -0
  39. package/dist/src/lang/tr.json +1 -0
  40. package/dist/src/lang/uk.json +3 -1
  41. package/dist/src/lang/ur.json +3 -1
  42. package/package.json +53 -53
  43. package/src/Blocks.svelte +76 -4
  44. package/src/Render.svelte +1 -0
  45. package/src/RenderComponent.svelte +4 -0
  46. package/src/api_docs/Settings.svelte +183 -0
  47. package/src/api_docs/SettingsBanner.svelte +74 -0
  48. package/src/api_docs/img/settings-logo.svg +8 -0
  49. package/src/api_docs/index.ts +1 -0
  50. package/src/i18n.ts +25 -2
  51. package/src/init.ts +16 -8
  52. package/src/lang/ar.json +117 -3
  53. package/src/lang/ca.json +113 -2
  54. package/src/lang/ckb.json +42 -20
  55. package/src/lang/de.json +116 -2
  56. package/src/lang/en.json +6 -1
  57. package/src/lang/es.json +116 -3
  58. package/src/lang/eu.json +122 -8
  59. package/src/lang/fa.json +120 -6
  60. package/src/lang/fi.json +52 -46
  61. package/src/lang/fr.json +113 -13
  62. package/src/lang/he.json +122 -8
  63. package/src/lang/hi.json +123 -9
  64. package/src/lang/ja.json +114 -9
  65. package/src/lang/ko.json +123 -9
  66. package/src/lang/lt.json +3 -1
  67. package/src/lang/nb.json +130 -0
  68. package/src/lang/nl.json +3 -1
  69. package/src/lang/pl.json +121 -7
  70. package/src/lang/pt-BR.json +1 -0
  71. package/src/lang/pt.json +130 -0
  72. package/src/lang/ro.json +130 -0
  73. package/src/lang/ru.json +54 -42
  74. package/src/lang/ta.json +1 -0
  75. package/src/lang/tr.json +1 -0
  76. package/src/lang/uk.json +3 -1
  77. package/src/lang/ur.json +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @gradio/core
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Features
6
+
7
+ - [#10192](https://github.com/gradio-app/gradio/pull/10192) [`4fc7fb7`](https://github.com/gradio-app/gradio/commit/4fc7fb777c42af537e4af612423fa44029657d41) - Ensure components can be remounted with their previous data. Thanks @pngwn!
8
+ - [#10254](https://github.com/gradio-app/gradio/pull/10254) [`da07707`](https://github.com/gradio-app/gradio/commit/da0770748db9ea40194a43c9138ee2c6536b1247) - Add a `settings` link to the footer with i18n options & pwa instructions. Thanks @abidlabs!
9
+
10
+ ### Fixes
11
+
12
+ - [#10207](https://github.com/gradio-app/gradio/pull/10207) [`314a8b5`](https://github.com/gradio-app/gradio/commit/314a8b55f57a30806b37fe077b471df97d04245d) - fix: make sure `comp.instance` exists. Thanks @Col0ring!
13
+
14
+ ### Dependency updates
15
+
16
+ - @gradio/atoms@0.13.0
17
+ - @gradio/utils@0.10.0
18
+ - @gradio/gallery@0.14.1
19
+ - @gradio/upload@0.14.4
20
+ - @gradio/client@1.9.0
21
+ - @gradio/icons@0.9.0
22
+ - @gradio/statustracker@0.10.0
23
+ - @gradio/wasm@0.16.0
24
+ - @gradio/plot@0.9.5
25
+ - @gradio/image@0.20.0
26
+ - @gradio/video@0.13.0
27
+ - @gradio/file@0.12.0
28
+ - @gradio/button@0.4.0
29
+ - @gradio/tabs@0.4.0
30
+ - @gradio/column@0.2.0
31
+ - @gradio/tabitem@0.4.0
32
+ - @gradio/code@0.10.11
33
+ - @gradio/paramviewer@0.6.2
34
+ - @gradio/textbox@0.10.0
35
+ - @gradio/checkbox@0.4.10
36
+
3
37
  ## 0.5.0
4
38
 
5
39
  ### Features
@@ -2,12 +2,13 @@
2
2
  import { _ } from "svelte-i18n";
3
3
  import { Client } from "@gradio/client";
4
4
  import { setupi18n } from "./i18n";
5
- import { ApiDocs, ApiRecorder } from "./api_docs/";
5
+ import { ApiDocs, ApiRecorder, Settings } from "./api_docs/";
6
6
  import { Toast } from "@gradio/statustracker";
7
7
  import MountComponents from "./MountComponents.svelte";
8
8
  import { prefix_css } from "./css";
9
9
  import logo from "./images/logo.svg";
10
10
  import api_logo from "./api_docs/img/api-logo.svg";
11
+ import settings_logo from "./api_docs/img/settings-logo.svg";
11
12
  import { create_components, AsyncFunction } from "./init";
12
13
  setupi18n();
13
14
  export let root;
@@ -65,6 +66,7 @@ async function run() {
65
66
  }
66
67
  export let search_params;
67
68
  let api_docs_visible = search_params.get("view") === "api" && show_api;
69
+ let settings_visible = search_params.get("view") === "settings";
68
70
  let api_recorder_visible = search_params.get("view") === "api-recorder" && show_api;
69
71
  function set_api_docs_visible(visible) {
70
72
  api_recorder_visible = false;
@@ -77,6 +79,16 @@ function set_api_docs_visible(visible) {
77
79
  }
78
80
  history.replaceState(null, "", "?" + params.toString());
79
81
  }
82
+ function set_settings_visible(visible) {
83
+ let params = new URLSearchParams(window.location.search);
84
+ if (visible) {
85
+ params.set("view", "settings");
86
+ } else {
87
+ params.delete("view");
88
+ }
89
+ history.replaceState(null, "", "?" + params.toString());
90
+ settings_visible = !settings_visible;
91
+ }
80
92
  let api_calls = [];
81
93
  export let render_complete = false;
82
94
  async function handle_update(data, fn_index) {
@@ -603,8 +615,8 @@ onMount(() => {
603
615
  >
604
616
  {$_("errors.use_via_api")}
605
617
  <img src={api_logo} alt={$_("common.logo")} />
618
+ <div>&nbsp;·</div>
606
619
  </button>
607
- <div>·</div>
608
620
  {/if}
609
621
  <a
610
622
  href="https://gradio.app"
@@ -615,6 +627,16 @@ onMount(() => {
615
627
  {$_("common.built_with_gradio")}
616
628
  <img src={logo} alt={$_("common.logo")} />
617
629
  </a>
630
+ <button
631
+ on:click={() => {
632
+ set_settings_visible(!settings_visible);
633
+ }}
634
+ class="settings"
635
+ >
636
+ <div>· &nbsp;</div>
637
+ {$_("common.settings")}
638
+ <img src={settings_logo} alt={$_("common.settings")} />
639
+ </button>
618
640
  </footer>
619
641
  {/if}
620
642
  </div>
@@ -664,6 +686,30 @@ onMount(() => {
664
686
  </div>
665
687
  {/if}
666
688
 
689
+ {#if settings_visible && $_layout && app.config}
690
+ <div class="api-docs">
691
+ <!-- TODO: fix -->
692
+ <!-- svelte-ignore a11y-click-events-have-key-events-->
693
+ <!-- svelte-ignore a11y-no-static-element-interactions-->
694
+ <div
695
+ class="backdrop"
696
+ on:click={() => {
697
+ set_settings_visible(false);
698
+ }}
699
+ />
700
+ <div class="api-docs-wrap">
701
+ <Settings
702
+ on:close={(event) => {
703
+ set_settings_visible(false);
704
+ }}
705
+ pwa_enabled={app.config.pwa}
706
+ {root}
707
+ {space_id}
708
+ />
709
+ </div>
710
+ </div>
711
+ {/if}
712
+
667
713
  {#if messages}
668
714
  <Toast {messages} on:close={handle_error_close} />
669
715
  {/if}
@@ -694,7 +740,8 @@ onMount(() => {
694
740
  margin-left: var(--size-2);
695
741
  }
696
742
 
697
- .show-api {
743
+ .show-api,
744
+ .settings {
698
745
  display: flex;
699
746
  align-items: center;
700
747
  }
@@ -708,12 +755,19 @@ onMount(() => {
708
755
  width: var(--size-3);
709
756
  }
710
757
 
758
+ .settings img {
759
+ margin-right: var(--size-1);
760
+ margin-left: var(--size-1);
761
+ width: var(--size-4);
762
+ }
763
+
711
764
  .built-with {
712
765
  display: flex;
713
766
  align-items: center;
714
767
  }
715
768
 
716
- .built-with:hover {
769
+ .built-with:hover,
770
+ .settings:hover {
717
771
  color: var(--body-text-color);
718
772
  }
719
773
 
@@ -768,4 +822,19 @@ onMount(() => {
768
822
  bottom: 10px;
769
823
  z-index: 1000;
770
824
  }
825
+
826
+ .show-api {
827
+ display: flex;
828
+ align-items: center;
829
+ }
830
+
831
+ @media (max-width: 640px) {
832
+ .show-api {
833
+ display: none;
834
+ }
835
+ }
836
+
837
+ .show-api:hover {
838
+ color: var(--body-text-color);
839
+ }
771
840
  </style>
@@ -73,6 +73,7 @@ $:
73
73
  {...node.props}
74
74
  {theme_mode}
75
75
  {root}
76
+ visible={typeof node.props.visible === "boolean" ? node.props.visible : true}
76
77
  >
77
78
  {#if node.children && node.children.length}
78
79
  {#each node.children as _node (_node.id)}
@@ -10,6 +10,7 @@ export let value;
10
10
  export let elem_id;
11
11
  export let elem_classes;
12
12
  export let _id;
13
+ export let visible;
13
14
  const s = (id, p, v) => new CustomEvent("prop_change", { detail: { id, prop: p, value: v } });
14
15
  function wrap(component2) {
15
16
  const ProxiedMyClass = new Proxy(component2, {
@@ -35,6 +36,7 @@ function wrap(component2) {
35
36
  const _component = wrap(component);
36
37
  </script>
37
38
 
39
+ <!-- {#if visible} -->
38
40
  <svelte:component
39
41
  this={_component}
40
42
  bind:this={instance}
@@ -43,9 +45,11 @@ const _component = wrap(component);
43
45
  {elem_id}
44
46
  {elem_classes}
45
47
  {target}
48
+ {visible}
46
49
  {...$$restProps}
47
50
  {theme_mode}
48
51
  {root}
49
52
  >
50
53
  <slot />
51
54
  </svelte:component>
55
+ <!-- {/if} -->
@@ -12,6 +12,7 @@ declare const __propDef: {
12
12
  elem_id: string;
13
13
  elem_classes: string[];
14
14
  _id: number;
15
+ visible: boolean;
15
16
  };
16
17
  events: {
17
18
  prop_change: any;
@@ -0,0 +1,175 @@
1
+ <script>import { onMount } from "svelte";
2
+ import SettingsBanner from "./SettingsBanner.svelte";
3
+ export let root;
4
+ export let space_id;
5
+ export let pwa_enabled;
6
+ import { BaseDropdown as Dropdown } from "@gradio/dropdown";
7
+ import { language_choices, changeLocale } from "../i18n";
8
+ import { locale, _ } from "svelte-i18n";
9
+ import { setupi18n } from "../i18n";
10
+ if (root === "") {
11
+ root = location.protocol + "//" + location.host + location.pathname;
12
+ }
13
+ if (!root.endsWith("/")) {
14
+ root += "/";
15
+ }
16
+ function setTheme(theme) {
17
+ const url = new URL(window.location.href);
18
+ if (theme === "system") {
19
+ url.searchParams.delete("__theme");
20
+ current_theme = "system";
21
+ } else {
22
+ url.searchParams.set("__theme", theme);
23
+ current_theme = theme;
24
+ }
25
+ window.location.href = url.toString();
26
+ }
27
+ onMount(() => {
28
+ document.body.style.overflow = "hidden";
29
+ if ("parentIFrame" in window) {
30
+ window.parentIFrame?.scrollTo(0, 0);
31
+ }
32
+ const url = new URL(window.location.href);
33
+ const theme = url.searchParams.get("__theme");
34
+ current_theme = theme || "system";
35
+ return () => {
36
+ document.body.style.overflow = "auto";
37
+ };
38
+ });
39
+ let current_locale;
40
+ let current_theme = "system";
41
+ locale.subscribe((value) => {
42
+ if (value) {
43
+ current_locale = value;
44
+ }
45
+ });
46
+ function handleLanguageChange(e) {
47
+ const new_locale = e.detail;
48
+ changeLocale(new_locale);
49
+ }
50
+ setupi18n();
51
+ </script>
52
+
53
+ <div class="banner-wrap">
54
+ <SettingsBanner on:close {root} />
55
+ </div>
56
+ {#if space_id === null}
57
+ <!-- on Spaces, the theme is set in HF settings -->
58
+ <div class="banner-wrap">
59
+ <h2>{$_("common.display_theme")}</h2>
60
+ <p class="padded theme-buttons">
61
+ <li
62
+ class="theme-button {current_theme === 'light'
63
+ ? 'current-theme'
64
+ : 'inactive-theme'}"
65
+ on:click={() => setTheme("light")}
66
+ >
67
+ <button>☀︎ &nbsp;Light</button>
68
+ </li>
69
+ <li
70
+ class="theme-button {current_theme === 'dark'
71
+ ? 'current-theme'
72
+ : 'inactive-theme'}"
73
+ on:click={() => setTheme("dark")}
74
+ >
75
+ <button>⏾ &nbsp; Dark</button>
76
+ </li>
77
+ <li
78
+ class="theme-button {current_theme === 'system'
79
+ ? 'current-theme'
80
+ : 'inactive-theme'}"
81
+ on:click={() => setTheme("system")}
82
+ >
83
+ <button>🖥︎ &nbsp;System</button>
84
+ </li>
85
+ </p>
86
+ </div>
87
+ {/if}
88
+ <div class="banner-wrap">
89
+ <h2>{$_("common.language")}</h2>
90
+ <p class="padded">
91
+ <Dropdown
92
+ label="Language"
93
+ choices={language_choices}
94
+ show_label={false}
95
+ {root}
96
+ value={current_locale}
97
+ on:change={handleLanguageChange}
98
+ />
99
+ </p>
100
+ </div>
101
+ <div class="banner-wrap">
102
+ <h2>{$_("common.pwa")}</h2>
103
+ <p class="padded">
104
+ {#if pwa_enabled}
105
+ You can install this app as a Progressive Web App on your device. Visit <a
106
+ href={root}>{root}</a
107
+ > and click the install button in the URL address bar of your browser.
108
+ {:else}
109
+ Progressive Web App is not enabled for this app. To enable it, start your
110
+ Gradio app with <code>launch(pwa=True)</code>.
111
+ {/if}
112
+ </p>
113
+ </div>
114
+
115
+ <style>
116
+ .banner-wrap {
117
+ position: relative;
118
+ border-bottom: 1px solid var(--border-color-primary);
119
+ padding: var(--size-4) var(--size-6);
120
+ font-size: var(--text-md);
121
+ }
122
+
123
+ .banner-wrap h2 {
124
+ font-size: var(--text-xl);
125
+ }
126
+
127
+ a {
128
+ text-decoration: underline;
129
+ }
130
+
131
+ p.padded {
132
+ padding: 15px 0px;
133
+ }
134
+
135
+ .theme-buttons {
136
+ display: flex;
137
+ align-items: center;
138
+ }
139
+
140
+ .theme-buttons > * + * {
141
+ margin-left: var(--size-2);
142
+ }
143
+
144
+ .theme-button {
145
+ display: flex;
146
+ align-items: center;
147
+ border: 1px solid var(--border-color-primary);
148
+ border-radius: var(--radius-md);
149
+ padding: var(--size-2) var(--size-2-5);
150
+ line-height: 1;
151
+ user-select: none;
152
+ text-transform: capitalize;
153
+ cursor: pointer;
154
+ }
155
+
156
+ .current-theme {
157
+ border: 1px solid var(--body-text-color-subdued);
158
+ color: var(--body-text-color);
159
+ }
160
+
161
+ .inactive-theme {
162
+ color: var(--body-text-color-subdued);
163
+ }
164
+
165
+ .inactive-theme:hover,
166
+ .inactive-theme:focus {
167
+ box-shadow: var(--shadow-drop);
168
+ color: var(--body-text-color);
169
+ }
170
+
171
+ .theme-button button {
172
+ all: unset;
173
+ cursor: pointer;
174
+ }
175
+ </style>
@@ -0,0 +1,20 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ root: string;
5
+ space_id: string | null;
6
+ pwa_enabled: boolean | undefined;
7
+ };
8
+ events: {
9
+ close: CustomEvent<any>;
10
+ } & {
11
+ [evt: string]: CustomEvent<any>;
12
+ };
13
+ slots: {};
14
+ };
15
+ export type SettingsProps = typeof __propDef.props;
16
+ export type SettingsEvents = typeof __propDef.events;
17
+ export type SettingsSlots = typeof __propDef.slots;
18
+ export default class Settings extends SvelteComponent<SettingsProps, SettingsEvents, SettingsSlots> {
19
+ }
20
+ export {};
@@ -0,0 +1,71 @@
1
+ <script>import { createEventDispatcher } from "svelte";
2
+ import { _ } from "svelte-i18n";
3
+ import settings_logo from "./img/settings-logo.svg";
4
+ import Clear from "./img/clear.svelte";
5
+ import { setupi18n } from "../i18n";
6
+ export let root;
7
+ const dispatch = createEventDispatcher();
8
+ setupi18n();
9
+ </script>
10
+
11
+ <h2>
12
+ <img src={settings_logo} alt="" />
13
+ <div class="title">
14
+ {$_("common.settings")}
15
+ <div class="url">
16
+ {root}
17
+ </div>
18
+ </div>
19
+ </h2>
20
+
21
+ <button on:click={() => dispatch("close")}>
22
+ <Clear />
23
+ </button>
24
+
25
+ <style>
26
+ h2 {
27
+ display: flex;
28
+ color: var(--body-text-color);
29
+ font-weight: var(--weight-semibold);
30
+ font-size: var(--text-xl);
31
+ gap: var(--size-3);
32
+ }
33
+
34
+ h2 img {
35
+ width: var(--size-4);
36
+ display: inline-block;
37
+ margin-top: 0.1rem;
38
+ }
39
+
40
+ .url {
41
+ color: var(--color-accent);
42
+ font-weight: normal;
43
+ }
44
+
45
+ button {
46
+ position: absolute;
47
+ top: var(--size-5);
48
+ right: var(--size-6);
49
+ width: var(--size-4);
50
+ color: var(--body-text-color);
51
+ }
52
+
53
+ button:hover {
54
+ color: var(--color-accent);
55
+ }
56
+
57
+ @media (--screen-md) {
58
+ button {
59
+ top: var(--size-6);
60
+ }
61
+
62
+ h2 img {
63
+ width: var(--size-5);
64
+ }
65
+ }
66
+ .title {
67
+ display: flex;
68
+ flex-direction: row;
69
+ gap: 0.5rem;
70
+ }
71
+ </style>
@@ -0,0 +1,18 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ root: string;
5
+ };
6
+ events: {
7
+ close: CustomEvent<any>;
8
+ } & {
9
+ [evt: string]: CustomEvent<any>;
10
+ };
11
+ slots: {};
12
+ };
13
+ export type SettingsBannerProps = typeof __propDef.props;
14
+ export type SettingsBannerEvents = typeof __propDef.events;
15
+ export type SettingsBannerSlots = typeof __propDef.slots;
16
+ export default class SettingsBanner extends SvelteComponent<SettingsBannerProps, SettingsBannerEvents, SettingsBannerSlots> {
17
+ }
18
+ export {};
@@ -0,0 +1,8 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
2
+ <!-- Outer gear teeth (gray) -->
3
+ <path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"
4
+ fill="#808080"/>
5
+
6
+ <!-- Inner circle (now gray) -->
7
+ <circle cx="12" cy="12" r="2.5" fill="#808080"/>
8
+ </svg>
@@ -1,2 +1,3 @@
1
1
  export { default as ApiDocs } from "./ApiDocs.svelte";
2
2
  export { default as ApiRecorder } from "./ApiRecorder.svelte";
3
+ export { default as Settings } from "./Settings.svelte";
@@ -1,2 +1,3 @@
1
1
  export { default as ApiDocs } from "./ApiDocs.svelte";
2
2
  export { default as ApiRecorder } from "./ApiRecorder.svelte";
3
+ export { default as Settings } from "./Settings.svelte";
@@ -2,5 +2,7 @@ type LangsRecord = Record<string, {
2
2
  [key: string]: any;
3
3
  }>;
4
4
  export declare function process_langs(): LangsRecord;
5
+ export declare const language_choices: [string, string][];
5
6
  export declare function setupi18n(): Promise<void>;
7
+ export declare function changeLocale(new_locale: string): void;
6
8
  export {};
package/dist/src/i18n.js CHANGED
@@ -1,4 +1,4 @@
1
- import { addMessages, init, getLocaleFromNavigator } from "svelte-i18n";
1
+ import { addMessages, init, getLocaleFromNavigator, locale } from "svelte-i18n";
2
2
  const langs = import.meta.glob("./lang/*.json", {
3
3
  eager: true
4
4
  });
@@ -11,12 +11,26 @@ export function process_langs() {
11
11
  return _langs;
12
12
  }
13
13
  const processed_langs = process_langs();
14
+ const available_locales = Object.keys(processed_langs);
15
+ export const language_choices = Object.entries(processed_langs).map(([code, data]) => [data._name || code, code]);
14
16
  for (const lang in processed_langs) {
15
17
  addMessages(lang, processed_langs[lang]);
16
18
  }
19
+ let i18n_initialized = false;
17
20
  export async function setupi18n() {
21
+ if (i18n_initialized) {
22
+ return;
23
+ }
24
+ const browser_locale = getLocaleFromNavigator();
25
+ const initial_locale = browser_locale && available_locales.includes(browser_locale)
26
+ ? browser_locale
27
+ : "en";
18
28
  await init({
19
29
  fallbackLocale: "en",
20
- initialLocale: getLocaleFromNavigator()
30
+ initialLocale: initial_locale
21
31
  });
32
+ i18n_initialized = true;
33
+ }
34
+ export function changeLocale(new_locale) {
35
+ locale.set(new_locale);
22
36
  }
package/dist/src/init.js CHANGED
@@ -147,15 +147,15 @@ export function create_components(initial_layout) {
147
147
  instance.children = await Promise.all(node.children.map((v) => walk_layout(v, root, components, instance)));
148
148
  }
149
149
  if (instance.type === "tabs" && !instance.props.initial_tabs) {
150
- const tab_items_props = node.children?.map((c) => {
150
+ const tab_items_props = node.children?.map((c, i) => {
151
151
  const instance = instance_map[c.id];
152
- // console.log("tabs", JSON.stringify(instance.props, null, 2));
153
152
  instance.props.id ??= c.id;
154
153
  return {
155
154
  type: instance.type,
156
155
  props: {
157
156
  ...instance.props,
158
- id: instance.props.id
157
+ id: instance.props.id,
158
+ order: i
159
159
  }
160
160
  };
161
161
  }) || [];
@@ -164,9 +164,16 @@ export function create_components(initial_layout) {
164
164
  label: child.props.label,
165
165
  id: child.props.id,
166
166
  visible: child.props.visible,
167
- interactive: child.props.interactive
167
+ interactive: child.props.interactive,
168
+ order: child.props.order
168
169
  }));
169
170
  }
171
+ if (instance.type === "tabs") {
172
+ node.children?.forEach((c, i) => {
173
+ const child = instance_map[c.id];
174
+ child.props.order = i;
175
+ });
176
+ }
170
177
  return instance;
171
178
  }
172
179
  let update_scheduled = false;
@@ -229,7 +236,7 @@ export function create_components(initial_layout) {
229
236
  if (!comp) {
230
237
  return null;
231
238
  }
232
- if (comp.instance.get_value) {
239
+ if (comp.instance?.get_value) {
233
240
  return comp.instance.get_value();
234
241
  }
235
242
  return comp.props.value;
@@ -250,19 +257,19 @@ export function create_components(initial_layout) {
250
257
  }
251
258
  function modify_stream(id, state) {
252
259
  const comp = _component_map.get(id);
253
- if (comp && comp.instance.modify_stream_state) {
260
+ if (comp && comp.instance?.modify_stream_state) {
254
261
  comp.instance.modify_stream_state(state);
255
262
  }
256
263
  }
257
264
  function get_stream_state(id) {
258
265
  const comp = _component_map.get(id);
259
- if (comp && comp.instance.get_stream_state)
266
+ if (comp?.instance?.get_stream_state)
260
267
  return comp.instance.get_stream_state();
261
268
  return "not_set";
262
269
  }
263
270
  function set_time_limit(id, time_limit) {
264
271
  const comp = _component_map.get(id);
265
- if (comp && comp.instance.set_time_limit) {
272
+ if (comp?.instance?.set_time_limit) {
266
273
  comp.instance.set_time_limit(time_limit);
267
274
  }
268
275
  }