@gradio/core 0.4.1 → 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 (79) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/src/Blocks.svelte +74 -5
  3. package/dist/src/Login.svelte +2 -2
  4. package/dist/src/Render.svelte +1 -0
  5. package/dist/src/RenderComponent.svelte +4 -0
  6. package/dist/src/RenderComponent.svelte.d.ts +1 -0
  7. package/dist/src/api_docs/Settings.svelte +175 -0
  8. package/dist/src/api_docs/Settings.svelte.d.ts +20 -0
  9. package/dist/src/api_docs/SettingsBanner.svelte +71 -0
  10. package/dist/src/api_docs/SettingsBanner.svelte.d.ts +18 -0
  11. package/dist/src/api_docs/img/settings-logo.svg +8 -0
  12. package/dist/src/api_docs/index.d.ts +1 -0
  13. package/dist/src/api_docs/index.js +1 -0
  14. package/dist/src/i18n.d.ts +2 -0
  15. package/dist/src/i18n.js +16 -2
  16. package/dist/src/init.js +20 -13
  17. package/dist/src/lang/ar.json +117 -3
  18. package/dist/src/lang/ca.json +113 -2
  19. package/dist/src/lang/ckb.json +42 -20
  20. package/dist/src/lang/de.json +116 -2
  21. package/dist/src/lang/en.json +8 -1
  22. package/dist/src/lang/es.json +116 -3
  23. package/dist/src/lang/eu.json +122 -8
  24. package/dist/src/lang/fa.json +120 -6
  25. package/dist/src/lang/fi.json +52 -46
  26. package/dist/src/lang/fr.json +113 -13
  27. package/dist/src/lang/he.json +122 -8
  28. package/dist/src/lang/hi.json +123 -9
  29. package/dist/src/lang/ja.json +121 -7
  30. package/dist/src/lang/ko.json +123 -9
  31. package/dist/src/lang/lt.json +3 -1
  32. package/dist/src/lang/nb.json +130 -0
  33. package/dist/src/lang/nl.json +3 -1
  34. package/dist/src/lang/pl.json +121 -7
  35. package/dist/src/lang/pt-BR.json +1 -0
  36. package/dist/src/lang/pt.json +130 -0
  37. package/dist/src/lang/ro.json +130 -0
  38. package/dist/src/lang/ru.json +54 -42
  39. package/dist/src/lang/ta.json +1 -0
  40. package/dist/src/lang/tr.json +1 -0
  41. package/dist/src/lang/uk.json +3 -1
  42. package/dist/src/lang/ur.json +3 -1
  43. package/package.json +53 -53
  44. package/src/Blocks.svelte +77 -5
  45. package/src/Login.svelte +2 -2
  46. package/src/Render.svelte +1 -0
  47. package/src/RenderComponent.svelte +4 -0
  48. package/src/api_docs/Settings.svelte +183 -0
  49. package/src/api_docs/SettingsBanner.svelte +74 -0
  50. package/src/api_docs/img/settings-logo.svg +8 -0
  51. package/src/api_docs/index.ts +1 -0
  52. package/src/i18n.ts +25 -2
  53. package/src/init.ts +26 -12
  54. package/src/lang/ar.json +117 -3
  55. package/src/lang/ca.json +113 -2
  56. package/src/lang/ckb.json +42 -20
  57. package/src/lang/de.json +116 -2
  58. package/src/lang/en.json +8 -1
  59. package/src/lang/es.json +116 -3
  60. package/src/lang/eu.json +122 -8
  61. package/src/lang/fa.json +120 -6
  62. package/src/lang/fi.json +52 -46
  63. package/src/lang/fr.json +113 -13
  64. package/src/lang/he.json +122 -8
  65. package/src/lang/hi.json +123 -9
  66. package/src/lang/ja.json +121 -7
  67. package/src/lang/ko.json +123 -9
  68. package/src/lang/lt.json +3 -1
  69. package/src/lang/nb.json +130 -0
  70. package/src/lang/nl.json +3 -1
  71. package/src/lang/pl.json +121 -7
  72. package/src/lang/pt-BR.json +1 -0
  73. package/src/lang/pt.json +130 -0
  74. package/src/lang/ro.json +130 -0
  75. package/src/lang/ru.json +54 -42
  76. package/src/lang/ta.json +1 -0
  77. package/src/lang/tr.json +1 -0
  78. package/src/lang/uk.json +3 -1
  79. package/src/lang/ur.json +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,76 @@
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
+
37
+ ## 0.5.0
38
+
39
+ ### Features
40
+
41
+ - [#10166](https://github.com/gradio-app/gradio/pull/10166) [`8ac5b13`](https://github.com/gradio-app/gradio/commit/8ac5b13c96f871ac4b0f13c6ebfbb5559a18bcc2) - Add Japanese translations for login UI. Thanks @kazuhitoyokoi!
42
+ - [#10159](https://github.com/gradio-app/gradio/pull/10159) [`7ca3685`](https://github.com/gradio-app/gradio/commit/7ca36850c9e46a1eb5b7a3866b4b166776b4146f) - Add Japanese message into message catalog. Thanks @kazuhitoyokoi!
43
+
44
+ ### Fixes
45
+
46
+ - [#10170](https://github.com/gradio-app/gradio/pull/10170) [`5e6e234`](https://github.com/gradio-app/gradio/commit/5e6e234cba820d29ebe29de2597d36ab3683093b) - Custom component in rerender. Thanks @aliabid94!
47
+
48
+ ### Dependency updates
49
+
50
+ - @gradio/code@0.10.10
51
+ - @gradio/paramviewer@0.6.1
52
+ - @gradio/video@0.12.1
53
+ - @gradio/statustracker@0.9.7
54
+ - @gradio/upload@0.14.3
55
+ - @gradio/button@0.3.9
56
+ - @gradio/atoms@0.12.0
57
+ - @gradio/image@0.19.0
58
+ - @gradio/gallery@0.14.0
59
+ - @gradio/plot@0.9.4
60
+ - @gradio/file@0.11.3
61
+ - @gradio/column@0.2.0
62
+ - @gradio/textbox@0.9.1
63
+ - @gradio/checkbox@0.4.9
64
+
65
+ ## 0.4.1
66
+
67
+ ### Dependency updates
68
+
69
+ - @gradio/gallery@0.13.10
70
+ - @gradio/paramviewer@0.6.0
71
+ - @gradio/image@0.18.0
72
+ - @gradio/video@0.12.0
73
+
3
74
  ## 0.4.1
4
75
 
5
76
  ### Fixes
@@ -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) {
@@ -320,7 +332,7 @@ async function trigger_api_call(dep_index, trigger_id = null, event_data = null)
320
332
  rerender_layout({
321
333
  components: _components,
322
334
  layout: render_layout,
323
- root,
335
+ root: root + api_prefix,
324
336
  dependencies,
325
337
  render_id
326
338
  });
@@ -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>
@@ -47,7 +47,7 @@ const submit = async () => {
47
47
  <Block>
48
48
  <Textbox
49
49
  {root}
50
- label="username"
50
+ label={$_("login.username")}
51
51
  lines={1}
52
52
  show_label={true}
53
53
  max_lines={1}
@@ -59,7 +59,7 @@ const submit = async () => {
59
59
  <Block>
60
60
  <Textbox
61
61
  {root}
62
- label="password"
62
+ label={$_("login.password")}
63
63
  lines={1}
64
64
  show_label={true}
65
65
  max_lines={1}
@@ -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
  }