rune-lab 0.1.1 → 0.2.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 (290) hide show
  1. package/dist/core/index.d.ts +3 -0
  2. package/dist/core/index.d.ts.map +1 -0
  3. package/dist/core/index.js +2 -0
  4. package/dist/{internal → core/internal}/message-resolver.d.ts +1 -0
  5. package/dist/core/internal/message-resolver.d.ts.map +1 -0
  6. package/dist/{persistence → core/persistence}/types.d.ts +1 -0
  7. package/dist/core/persistence/types.d.ts.map +1 -0
  8. package/dist/index.d.ts +2 -30
  9. package/dist/index.js +2 -40
  10. package/dist/state/api.svelte.js +3 -2
  11. package/dist/state/app.svelte.js +3 -2
  12. package/dist/state/commands.svelte.js +2 -2
  13. package/dist/{composables → state/composables}/usePersistence.d.ts +1 -1
  14. package/dist/{composables → state/composables}/useRuneLab.d.ts +1 -1
  15. package/dist/{composables → state/composables}/useRuneLab.js +1 -1
  16. package/dist/state/createConfigStore.svelte.d.ts +1 -1
  17. package/dist/state/createConfigStore.svelte.js +3 -3
  18. package/dist/state/currency.svelte.d.ts +1 -1
  19. package/dist/state/currency.svelte.js +1 -1
  20. package/dist/state/daisyui.d.ts +4 -0
  21. package/dist/state/index.d.ts +5 -0
  22. package/dist/state/index.js +9 -2
  23. package/dist/state/language.svelte.d.ts +2 -1
  24. package/dist/state/language.svelte.js +6 -18
  25. package/dist/state/layout.svelte.d.ts +1 -1
  26. package/dist/state/layout.svelte.js +1 -1
  27. package/dist/{persistence → state/persistence}/drivers.d.ts +1 -1
  28. package/dist/{persistence → state/persistence}/drivers.js +1 -1
  29. package/dist/state/shortcuts.svelte.js +4 -3
  30. package/dist/state/theme.svelte.d.ts +1 -1
  31. package/dist/state/theme.svelte.js +2 -2
  32. package/dist/state/toast.svelte.js +1 -1
  33. package/dist/{actions → ui/actions}/portal.js +2 -1
  34. package/dist/{components → ui/components}/ApiMonitor.svelte +2 -2
  35. package/dist/{components → ui/components}/Icon.svelte +3 -2
  36. package/dist/{components → ui/components}/RuneProvider.svelte +31 -12
  37. package/dist/{components → ui/components}/RuneProvider.svelte.d.ts +5 -2
  38. package/dist/{components → ui/components}/Toaster.svelte +1 -1
  39. package/dist/{features → ui/features}/command-palette/CommandPalette.svelte +3 -3
  40. package/dist/ui/features/config/AppSettingSelector.svelte +177 -0
  41. package/dist/{features → ui/features}/config/AppSettingSelector.svelte.d.ts +1 -1
  42. package/dist/{features → ui/features}/config/CurrencySelector.svelte +15 -10
  43. package/dist/{features → ui/features}/config/LanguageSelector.svelte +17 -13
  44. package/dist/{features → ui/features}/config/ThemeSelector.svelte +16 -11
  45. package/dist/{features → ui/features}/shortcuts/ShortcutPalette.svelte +3 -3
  46. package/dist/ui/index.d.ts +21 -0
  47. package/dist/ui/index.js +31 -0
  48. package/dist/{features/layout/smart → ui/layout}/ConnectedNavigationPanel.svelte +2 -5
  49. package/dist/{features/layout/smart → ui/layout}/ConnectedNavigationPanel.svelte.d.ts +1 -1
  50. package/dist/{features/layout/smart → ui/layout}/ConnectedWorkspaceStrip.svelte +2 -5
  51. package/dist/{features/layout/smart → ui/layout}/ConnectedWorkspaceStrip.svelte.d.ts +1 -1
  52. package/dist/{layout → ui/layout}/NavigationPanel.svelte +1 -1
  53. package/dist/{layout → ui/layout}/NavigationPanel.svelte.d.ts +1 -1
  54. package/dist/{layout → ui/layout}/WorkspaceLayout.svelte +2 -2
  55. package/dist/{layout → ui/layout}/WorkspaceStrip.svelte +1 -1
  56. package/dist/{layout → ui/layout}/WorkspaceStrip.svelte.d.ts +1 -1
  57. package/dist/{layout → ui/layout}/index.d.ts +2 -2
  58. package/dist/{layout → ui/layout}/index.js +1 -1
  59. package/dist/{paraglide → ui/paraglide}/README.md +3 -2
  60. package/dist/{paraglide → ui/paraglide}/runtime.d.ts +17 -2
  61. package/dist/{paraglide → ui/paraglide}/runtime.js +45 -0
  62. package/package.json +41 -44
  63. package/dist/features/config/AppSettingSelector.svelte +0 -124
  64. package/dist/features/detail-panels/DashboardPanel.svelte +0 -171
  65. package/dist/features/detail-panels/DashboardPanel.svelte.d.ts +0 -3
  66. package/dist/features/detail-panels/ShortcutsPanel.svelte +0 -233
  67. package/dist/features/detail-panels/ShortcutsPanel.svelte.d.ts +0 -3
  68. package/dist/features/detail-panels/ShowcasePanel.svelte +0 -114
  69. package/dist/features/detail-panels/ShowcasePanel.svelte.d.ts +0 -3
  70. package/dist/features/detail-panels/showcase-components.d.ts +0 -6
  71. package/dist/features/detail-panels/showcase-components.js +0 -65
  72. package/dist/paraglide/messages/_index.d.ts +0 -83
  73. package/dist/paraglide/messages/_index.js +0 -84
  74. package/dist/paraglide/messages/abyss.d.ts +0 -16
  75. package/dist/paraglide/messages/abyss.js +0 -84
  76. package/dist/paraglide/messages/acid.d.ts +0 -16
  77. package/dist/paraglide/messages/acid.js +0 -84
  78. package/dist/paraglide/messages/active_toasts.d.ts +0 -16
  79. package/dist/paraglide/messages/active_toasts.js +0 -84
  80. package/dist/paraglide/messages/aed3.d.ts +0 -17
  81. package/dist/paraglide/messages/aed3.js +0 -85
  82. package/dist/paraglide/messages/all_currencies.d.ts +0 -16
  83. package/dist/paraglide/messages/all_currencies.js +0 -84
  84. package/dist/paraglide/messages/all_languages.d.ts +0 -16
  85. package/dist/paraglide/messages/all_languages.js +0 -84
  86. package/dist/paraglide/messages/all_themes.d.ts +0 -16
  87. package/dist/paraglide/messages/all_themes.js +0 -84
  88. package/dist/paraglide/messages/api_status.d.ts +0 -16
  89. package/dist/paraglide/messages/api_status.js +0 -84
  90. package/dist/paraglide/messages/app_info.d.ts +0 -16
  91. package/dist/paraglide/messages/app_info.js +0 -84
  92. package/dist/paraglide/messages/appearance.d.ts +0 -16
  93. package/dist/paraglide/messages/appearance.js +0 -84
  94. package/dist/paraglide/messages/aqua.d.ts +0 -16
  95. package/dist/paraglide/messages/aqua.js +0 -84
  96. package/dist/paraglide/messages/ar.d.ts +0 -16
  97. package/dist/paraglide/messages/ar.js +0 -84
  98. package/dist/paraglide/messages/autumn.d.ts +0 -16
  99. package/dist/paraglide/messages/autumn.js +0 -84
  100. package/dist/paraglide/messages/black.d.ts +0 -16
  101. package/dist/paraglide/messages/black.js +0 -84
  102. package/dist/paraglide/messages/bumblebee.d.ts +0 -16
  103. package/dist/paraglide/messages/bumblebee.js +0 -84
  104. package/dist/paraglide/messages/business.d.ts +0 -16
  105. package/dist/paraglide/messages/business.js +0 -84
  106. package/dist/paraglide/messages/caramellatte.d.ts +0 -16
  107. package/dist/paraglide/messages/caramellatte.js +0 -84
  108. package/dist/paraglide/messages/cmyk.d.ts +0 -16
  109. package/dist/paraglide/messages/cmyk.js +0 -84
  110. package/dist/paraglide/messages/cny3.d.ts +0 -17
  111. package/dist/paraglide/messages/cny3.js +0 -85
  112. package/dist/paraglide/messages/coffee.d.ts +0 -16
  113. package/dist/paraglide/messages/coffee.js +0 -84
  114. package/dist/paraglide/messages/commands_label.d.ts +0 -16
  115. package/dist/paraglide/messages/commands_label.js +0 -84
  116. package/dist/paraglide/messages/corporate.d.ts +0 -16
  117. package/dist/paraglide/messages/corporate.js +0 -84
  118. package/dist/paraglide/messages/cupcake.d.ts +0 -16
  119. package/dist/paraglide/messages/cupcake.js +0 -84
  120. package/dist/paraglide/messages/currency.d.ts +0 -16
  121. package/dist/paraglide/messages/currency.js +0 -84
  122. package/dist/paraglide/messages/current_currency.d.ts +0 -16
  123. package/dist/paraglide/messages/current_currency.js +0 -84
  124. package/dist/paraglide/messages/current_language.d.ts +0 -16
  125. package/dist/paraglide/messages/current_language.js +0 -84
  126. package/dist/paraglide/messages/current_theme.d.ts +0 -16
  127. package/dist/paraglide/messages/current_theme.js +0 -84
  128. package/dist/paraglide/messages/currently_in_queue.d.ts +0 -16
  129. package/dist/paraglide/messages/currently_in_queue.js +0 -84
  130. package/dist/paraglide/messages/cyberpunk.d.ts +0 -16
  131. package/dist/paraglide/messages/cyberpunk.js +0 -84
  132. package/dist/paraglide/messages/dark.d.ts +0 -16
  133. package/dist/paraglide/messages/dark.js +0 -84
  134. package/dist/paraglide/messages/de.d.ts +0 -16
  135. package/dist/paraglide/messages/de.js +0 -84
  136. package/dist/paraglide/messages/dim.d.ts +0 -16
  137. package/dist/paraglide/messages/dim.js +0 -84
  138. package/dist/paraglide/messages/dracula.d.ts +0 -16
  139. package/dist/paraglide/messages/dracula.js +0 -84
  140. package/dist/paraglide/messages/emerald.d.ts +0 -16
  141. package/dist/paraglide/messages/emerald.js +0 -84
  142. package/dist/paraglide/messages/en.d.ts +0 -16
  143. package/dist/paraglide/messages/en.js +0 -84
  144. package/dist/paraglide/messages/es.d.ts +0 -16
  145. package/dist/paraglide/messages/es.js +0 -84
  146. package/dist/paraglide/messages/eur3.d.ts +0 -17
  147. package/dist/paraglide/messages/eur3.js +0 -85
  148. package/dist/paraglide/messages/extended_controls.d.ts +0 -16
  149. package/dist/paraglide/messages/extended_controls.js +0 -84
  150. package/dist/paraglide/messages/fantasy.d.ts +0 -16
  151. package/dist/paraglide/messages/fantasy.js +0 -84
  152. package/dist/paraglide/messages/forest.d.ts +0 -16
  153. package/dist/paraglide/messages/forest.js +0 -84
  154. package/dist/paraglide/messages/fr.d.ts +0 -16
  155. package/dist/paraglide/messages/fr.js +0 -84
  156. package/dist/paraglide/messages/garden.d.ts +0 -16
  157. package/dist/paraglide/messages/garden.js +0 -84
  158. package/dist/paraglide/messages/halloween.d.ts +0 -16
  159. package/dist/paraglide/messages/halloween.js +0 -84
  160. package/dist/paraglide/messages/hello_world.d.ts +0 -18
  161. package/dist/paraglide/messages/hello_world.js +0 -84
  162. package/dist/paraglide/messages/hi.d.ts +0 -16
  163. package/dist/paraglide/messages/hi.js +0 -84
  164. package/dist/paraglide/messages/it.d.ts +0 -16
  165. package/dist/paraglide/messages/it.js +0 -84
  166. package/dist/paraglide/messages/ja.d.ts +0 -16
  167. package/dist/paraglide/messages/ja.js +0 -84
  168. package/dist/paraglide/messages/jpy3.d.ts +0 -17
  169. package/dist/paraglide/messages/jpy3.js +0 -85
  170. package/dist/paraglide/messages/ko.d.ts +0 -16
  171. package/dist/paraglide/messages/ko.js +0 -84
  172. package/dist/paraglide/messages/krw3.d.ts +0 -17
  173. package/dist/paraglide/messages/krw3.js +0 -85
  174. package/dist/paraglide/messages/languages.d.ts +0 -16
  175. package/dist/paraglide/messages/languages.js +0 -84
  176. package/dist/paraglide/messages/lemonade.d.ts +0 -16
  177. package/dist/paraglide/messages/lemonade.js +0 -84
  178. package/dist/paraglide/messages/light.d.ts +0 -16
  179. package/dist/paraglide/messages/light.js +0 -84
  180. package/dist/paraglide/messages/live_store_dashboard.d.ts +0 -16
  181. package/dist/paraglide/messages/live_store_dashboard.js +0 -84
  182. package/dist/paraglide/messages/localization.d.ts +0 -16
  183. package/dist/paraglide/messages/localization.js +0 -84
  184. package/dist/paraglide/messages/lofi.d.ts +0 -16
  185. package/dist/paraglide/messages/lofi.js +0 -84
  186. package/dist/paraglide/messages/luxury.d.ts +0 -16
  187. package/dist/paraglide/messages/luxury.js +0 -84
  188. package/dist/paraglide/messages/mxn3.d.ts +0 -17
  189. package/dist/paraglide/messages/mxn3.js +0 -85
  190. package/dist/paraglide/messages/name_label.d.ts +0 -16
  191. package/dist/paraglide/messages/name_label.js +0 -84
  192. package/dist/paraglide/messages/night.d.ts +0 -16
  193. package/dist/paraglide/messages/night.js +0 -84
  194. package/dist/paraglide/messages/nord.d.ts +0 -16
  195. package/dist/paraglide/messages/nord.js +0 -84
  196. package/dist/paraglide/messages/pastel.d.ts +0 -16
  197. package/dist/paraglide/messages/pastel.js +0 -84
  198. package/dist/paraglide/messages/pt.d.ts +0 -16
  199. package/dist/paraglide/messages/pt.js +0 -84
  200. package/dist/paraglide/messages/real_time_monitor_desc.d.ts +0 -16
  201. package/dist/paraglide/messages/real_time_monitor_desc.js +0 -84
  202. package/dist/paraglide/messages/registered_in_registry.d.ts +0 -16
  203. package/dist/paraglide/messages/registered_in_registry.js +0 -84
  204. package/dist/paraglide/messages/retro.d.ts +0 -16
  205. package/dist/paraglide/messages/retro.js +0 -84
  206. package/dist/paraglide/messages/ru.d.ts +0 -16
  207. package/dist/paraglide/messages/ru.js +0 -84
  208. package/dist/paraglide/messages/silk.d.ts +0 -16
  209. package/dist/paraglide/messages/silk.js +0 -84
  210. package/dist/paraglide/messages/state_label.d.ts +0 -16
  211. package/dist/paraglide/messages/state_label.js +0 -84
  212. package/dist/paraglide/messages/sunset.d.ts +0 -16
  213. package/dist/paraglide/messages/sunset.js +0 -84
  214. package/dist/paraglide/messages/synthwave.d.ts +0 -16
  215. package/dist/paraglide/messages/synthwave.js +0 -84
  216. package/dist/paraglide/messages/system.d.ts +0 -16
  217. package/dist/paraglide/messages/system.js +0 -84
  218. package/dist/paraglide/messages/theme.d.ts +0 -16
  219. package/dist/paraglide/messages/theme.js +0 -84
  220. package/dist/paraglide/messages/themes.d.ts +0 -16
  221. package/dist/paraglide/messages/themes.js +0 -84
  222. package/dist/paraglide/messages/url_label.d.ts +0 -16
  223. package/dist/paraglide/messages/url_label.js +0 -84
  224. package/dist/paraglide/messages/usd3.d.ts +0 -17
  225. package/dist/paraglide/messages/usd3.js +0 -85
  226. package/dist/paraglide/messages/valentine.d.ts +0 -16
  227. package/dist/paraglide/messages/valentine.js +0 -84
  228. package/dist/paraglide/messages/version_label.d.ts +0 -16
  229. package/dist/paraglide/messages/version_label.js +0 -84
  230. package/dist/paraglide/messages/vi.d.ts +0 -16
  231. package/dist/paraglide/messages/vi.js +0 -84
  232. package/dist/paraglide/messages/winter.d.ts +0 -16
  233. package/dist/paraglide/messages/winter.js +0 -84
  234. package/dist/paraglide/messages/wireframe.d.ts +0 -16
  235. package/dist/paraglide/messages/wireframe.js +0 -84
  236. package/dist/paraglide/messages/zh.d.ts +0 -16
  237. package/dist/paraglide/messages/zh.js +0 -84
  238. package/dist/server/index.d.ts +0 -15
  239. package/dist/server/index.js +0 -20
  240. package/dist/showcase/AppStateInspector.svelte +0 -184
  241. package/dist/showcase/AppStateInspector.svelte.d.ts +0 -3
  242. package/dist/showcase/Showcase.svelte +0 -115
  243. package/dist/showcase/Showcase.svelte.d.ts +0 -18
  244. package/dist/showcase/ShowcaseCard.svelte +0 -18
  245. package/dist/showcase/ShowcaseCard.svelte.d.ts +0 -9
  246. package/dist/showcase/StoreDetailCard.svelte +0 -68
  247. package/dist/showcase/StoreDetailCard.svelte.d.ts +0 -19
  248. package/dist/showcase/shared.d.ts +0 -7
  249. package/dist/showcase/shared.js +0 -34
  250. package/dist/showcase/state.svelte.d.ts +0 -3
  251. package/dist/showcase/state.svelte.js +0 -3
  252. package/dist/showcase/tabs/Actions.svelte +0 -150
  253. package/dist/showcase/tabs/Actions.svelte.d.ts +0 -18
  254. package/dist/showcase/tabs/DataInput.svelte +0 -164
  255. package/dist/showcase/tabs/DataInput.svelte.d.ts +0 -3
  256. package/dist/showcase/tabs/Display.svelte +0 -159
  257. package/dist/showcase/tabs/Display.svelte.d.ts +0 -18
  258. package/dist/showcase/tabs/Feedback.svelte +0 -180
  259. package/dist/showcase/tabs/Feedback.svelte.d.ts +0 -3
  260. package/dist/showcase/tabs/Navigation.svelte +0 -170
  261. package/dist/showcase/tabs/Navigation.svelte.d.ts +0 -18
  262. package/dist/showcase/tabs/Visual.svelte +0 -133
  263. package/dist/showcase/tabs/Visual.svelte.d.ts +0 -18
  264. /package/dist/{internal → core/internal}/message-resolver.js +0 -0
  265. /package/dist/{persistence → core/persistence}/types.js +0 -0
  266. /package/dist/{composables → state/composables}/usePersistence.js +0 -0
  267. /package/dist/{config.d.ts → state/config.d.ts} +0 -0
  268. /package/dist/{config.js → state/config.js} +0 -0
  269. /package/dist/{context.d.ts → state/context.d.ts} +0 -0
  270. /package/dist/{context.js → state/context.js} +0 -0
  271. /package/dist/{actions → ui/actions}/portal.d.ts +0 -0
  272. /package/dist/{components → ui/components}/ApiMonitor.svelte.d.ts +0 -0
  273. /package/dist/{components → ui/components}/Icon.svelte.d.ts +0 -0
  274. /package/dist/{components → ui/components}/Toaster.svelte.d.ts +0 -0
  275. /package/dist/{features → ui/features}/command-palette/CommandPalette.svelte.d.ts +0 -0
  276. /package/dist/{features → ui/features}/config/CurrencySelector.svelte.d.ts +0 -0
  277. /package/dist/{features → ui/features}/config/LanguageSelector.svelte.d.ts +0 -0
  278. /package/dist/{features → ui/features}/config/ThemeSelector.svelte.d.ts +0 -0
  279. /package/dist/{features → ui/features}/shortcuts/ShortcutPalette.svelte.d.ts +0 -0
  280. /package/dist/{layout → ui/layout}/ContentArea.svelte +0 -0
  281. /package/dist/{layout → ui/layout}/ContentArea.svelte.d.ts +0 -0
  282. /package/dist/{layout → ui/layout}/DetailPanel.svelte +0 -0
  283. /package/dist/{layout → ui/layout}/DetailPanel.svelte.d.ts +0 -0
  284. /package/dist/{layout → ui/layout}/WorkspaceLayout.svelte.d.ts +0 -0
  285. /package/dist/{paraglide → ui/paraglide}/messages.d.ts +0 -0
  286. /package/dist/{paraglide → ui/paraglide}/messages.js +0 -0
  287. /package/dist/{paraglide → ui/paraglide}/registry.d.ts +0 -0
  288. /package/dist/{paraglide → ui/paraglide}/registry.js +0 -0
  289. /package/dist/{paraglide → ui/paraglide}/server.d.ts +0 -0
  290. /package/dist/{paraglide → ui/paraglide}/server.js +0 -0
@@ -0,0 +1,177 @@
1
+ <script lang="ts">
2
+ import { portal } from "../../actions/portal";
3
+ import { type Snippet } from "svelte";
4
+
5
+ let {
6
+ options,
7
+ value,
8
+ item,
9
+ triggerLabel,
10
+ tooltip,
11
+ direction = "bottom",
12
+ responsive = true,
13
+ } = $props<{
14
+ options: any[];
15
+ value: any;
16
+ item: Snippet<[any]>;
17
+ triggerLabel: Snippet<[any]>;
18
+ tooltip?: string;
19
+ direction?: "top" | "bottom" | "left" | "right" | "end" | "auto";
20
+ responsive?: boolean;
21
+ }>();
22
+
23
+ let modal = $state<HTMLDialogElement>();
24
+
25
+ let isOpen = $state(false);
26
+ let triggerEl = $state<HTMLElement>();
27
+ let panelStyle = $state("position:fixed;visibility:hidden");
28
+
29
+ function computePosition() {
30
+ if (!triggerEl) return;
31
+ const rect = triggerEl.getBoundingClientRect();
32
+ const spaceBelow = window.innerHeight - rect.bottom;
33
+ const spaceAbove = rect.top;
34
+ const openUpward =
35
+ direction === "top" ||
36
+ (direction === "auto" &&
37
+ spaceBelow < 200 &&
38
+ spaceAbove > spaceBelow);
39
+
40
+ if (openUpward) {
41
+ panelStyle = `position:fixed; bottom:${window.innerHeight - rect.top + 4}px; left:${rect.left}px; min-width:${rect.width}px; z-index:9999`;
42
+ } else {
43
+ panelStyle = `position:fixed; top:${rect.bottom + 4}px; left:${rect.left}px; min-width:${rect.width}px; z-index:9999`;
44
+ }
45
+ }
46
+
47
+ function open() {
48
+ computePosition();
49
+ isOpen = true;
50
+ }
51
+
52
+ function close() {
53
+ isOpen = false;
54
+ }
55
+
56
+ function handleOutsideClick(e: MouseEvent) {
57
+ if (!triggerEl?.contains(e.target as Node)) close();
58
+ }
59
+
60
+ $effect(() => {
61
+ if (isOpen) {
62
+ document.addEventListener("click", handleOutsideClick, {
63
+ capture: true,
64
+ });
65
+ document.addEventListener(
66
+ "keydown",
67
+ (e) => e.key === "Escape" && close(),
68
+ );
69
+ }
70
+ return () => {
71
+ document.removeEventListener("click", handleOutsideClick, {
72
+ capture: true,
73
+ });
74
+ };
75
+ });
76
+ </script>
77
+
78
+ <!-- Mobile Modal Implementation -->
79
+ {#if responsive}
80
+ <div class="md:hidden inline-block">
81
+ <button
82
+ type="button"
83
+ class="btn btn-ghost btn-sm m-1 h-auto min-h-[2rem] px-2"
84
+ aria-haspopup="dialog"
85
+ onclick={() => modal?.showModal()}
86
+ >
87
+ <span class="flex items-center gap-2">
88
+ {@render triggerLabel(value)}
89
+ </span>
90
+ </button>
91
+
92
+ <dialog bind:this={modal} class="modal modal-bottom sm:modal-middle">
93
+ <div class="modal-box p-0 overflow-hidden">
94
+ <div
95
+ class="p-4 bg-base-200 border-b border-base-300 flex justify-between items-center"
96
+ >
97
+ <h3 class="font-bold text-lg">Select Option</h3>
98
+ <form method="dialog">
99
+ <button class="btn btn-sm btn-circle btn-ghost"
100
+ >✕</button
101
+ >
102
+ </form>
103
+ </div>
104
+ <div class="max-h-[60vh] overflow-y-auto p-2">
105
+ <ul class="menu bg-base-100 w-full p-0" role="menu">
106
+ {#each options as option}
107
+ <li
108
+ class="border-b border-base-100 last:border-0"
109
+ role="menuitem"
110
+ >
111
+ <button
112
+ class="w-full text-left py-3"
113
+ onclick={() => modal?.close()}
114
+ >
115
+ {@render item(option)}
116
+ </button>
117
+ </li>
118
+ {/each}
119
+ </ul>
120
+ </div>
121
+ </div>
122
+ <form method="dialog" class="modal-backdrop">
123
+ <button>close</button>
124
+ </form>
125
+ </dialog>
126
+ </div>
127
+ {/if}
128
+
129
+ <!-- Desktop Dropdown Implementation -->
130
+ <div
131
+ bind:this={triggerEl}
132
+ class="relative {responsive ? 'hidden md:inline-block' : 'inline-block'}"
133
+ >
134
+ <button
135
+ type="button"
136
+ aria-haspopup="listbox"
137
+ aria-expanded={isOpen}
138
+ onclick={open}
139
+ class="btn btn-ghost btn-sm m-1 {tooltip
140
+ ? 'tooltip tooltip-bottom'
141
+ : ''}"
142
+ data-tip={tooltip}
143
+ >
144
+ <span class="flex items-center gap-2">
145
+ {@render triggerLabel(value)}
146
+ </span>
147
+ </button>
148
+ </div>
149
+
150
+ {#if isOpen}
151
+ <div
152
+ use:portal
153
+ style={panelStyle}
154
+ class={responsive ? "hidden md:block" : "block"}
155
+ >
156
+ <ul
157
+ role="listbox"
158
+ class="menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow-xl border border-base-200 max-h-96 overflow-y-auto"
159
+ >
160
+ {#each options as option}
161
+ <li role="option" aria-selected={value === option}>
162
+ <!-- Event delegation: we close on click unless they clicked the scrollbar -->
163
+ <!-- In a real world component you'd wrap the button down here or add a capture handler -->
164
+ <div
165
+ role="presentation"
166
+ onclick={close}
167
+ onkeydown={(e) => e.key === "Enter" && close()}
168
+ tabindex="-1"
169
+ class="w-full"
170
+ >
171
+ {@render item(option)}
172
+ </div>
173
+ </li>
174
+ {/each}
175
+ </ul>
176
+ </div>
177
+ {/if}
@@ -5,7 +5,7 @@ type $$ComponentProps = {
5
5
  item: Snippet<[any]>;
6
6
  triggerLabel: Snippet<[any]>;
7
7
  tooltip?: string;
8
- direction?: "top" | "bottom" | "left" | "right" | "end";
8
+ direction?: "top" | "bottom" | "left" | "right" | "end" | "auto";
9
9
  responsive?: boolean;
10
10
  };
11
11
  declare const AppSettingSelector: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -3,13 +3,12 @@
3
3
  import {
4
4
  getCurrencyStore,
5
5
  type Currency,
6
- } from "../../state/currency.svelte";
6
+ } from "@internal/state";
7
+ import * as rlMessages from "../../paraglide/messages.js";
8
+ import { getContext } from "svelte";
7
9
 
8
10
  const currencyStore = getCurrencyStore();
9
11
 
10
- import { getContext } from "svelte";
11
- import { createMessageResolver } from "../../internal/message-resolver";
12
-
13
12
  let {
14
13
  codes = [],
15
14
  current = $bindable(String(currencyStore.current)),
@@ -20,11 +19,17 @@
20
19
  onchange?: (value: string) => void;
21
20
  } = $props();
22
21
 
23
- const dictionary = getContext<Record<string, any>>("rl:dictionary") || {};
22
+ const userDictionary =
23
+ getContext<Record<string, any>>("rl:dictionary") ?? {};
24
24
 
25
- const getLabel = createMessageResolver<Currency>(dictionary as any, {
26
- keyExtractor: (c) => String(c.code),
27
- });
25
+ function getLabel(currency: Currency): string {
26
+ const key = String(currency.code);
27
+ if (typeof userDictionary[key] === "function")
28
+ return userDictionary[key]();
29
+ if (typeof (rlMessages as any)[key] === "function")
30
+ return (rlMessages as any)[key]();
31
+ return String(currency.code);
32
+ }
28
33
 
29
34
  let active = $derived(
30
35
  currencyStore.get(currencyStore.current) ?? currencyStore.available[0],
@@ -42,8 +47,8 @@
42
47
  options={available}
43
48
  tooltip={getLabel(active)}
44
49
  >
45
- {#snippet triggerLabel(c)}
46
- <span class="font-bold">{c.symbol}</span>
50
+ {#snippet triggerLabel()}
51
+ <span class="font-bold">{active.symbol}</span>
47
52
  {/snippet}
48
53
 
49
54
  {#snippet item(c)}
@@ -1,15 +1,12 @@
1
1
  <script lang="ts">
2
2
  import AppSettingSelector from "./AppSettingSelector.svelte";
3
- import {
4
- getLanguageStore,
5
- type Language,
6
- } from "../../state/language.svelte";
3
+ import { getLanguageStore, type Language } from "@internal/state";
4
+ import * as rlMessages from "../../paraglide/messages.js";
5
+ import { getContext } from "svelte";
6
+ import { setLocale } from "../../paraglide/runtime";
7
7
 
8
8
  const languageStore = getLanguageStore();
9
9
 
10
- import { getContext } from "svelte";
11
- import { createMessageResolver } from "../../internal/message-resolver";
12
-
13
10
  let {
14
11
  languages: allowedLocales = languageStore.available.map((l) => l.code),
15
12
  current = $bindable(languageStore.current),
@@ -20,11 +17,17 @@
20
17
  onchange?: (value: string) => void;
21
18
  } = $props();
22
19
 
23
- const dictionary = getContext<Record<string, any>>("rl:dictionary") || {};
20
+ const userDictionary =
21
+ getContext<Record<string, any>>("rl:dictionary") ?? {};
24
22
 
25
- const getLabel = createMessageResolver<Language>(dictionary as any, {
26
- keyExtractor: (l) => l.code,
27
- });
23
+ function getLabel(lang: Language): string {
24
+ const key = lang.code;
25
+ if (typeof userDictionary[key] === "function")
26
+ return userDictionary[key]();
27
+ if (typeof (rlMessages as any)[key] === "function")
28
+ return (rlMessages as any)[key]();
29
+ return lang.code.toUpperCase();
30
+ }
28
31
 
29
32
  let active = $derived(
30
33
  languageStore.get(languageStore.current) ?? languageStore.available[0],
@@ -42,8 +45,8 @@
42
45
  options={available}
43
46
  tooltip={getLabel(active)}
44
47
  >
45
- {#snippet triggerLabel(l)}
46
- <span class="text-lg">{l?.flag ?? active.flag}</span>
48
+ {#snippet triggerLabel()}
49
+ <span class="text-lg">{active.flag}</span>
47
50
  {/snippet}
48
51
 
49
52
  {#snippet item(l)}
@@ -51,6 +54,7 @@
51
54
  class="flex items-center gap-3 w-full"
52
55
  onclick={() => {
53
56
  languageStore.set(l.code);
57
+ setLocale(l.code as any);
54
58
  current = l.code;
55
59
  onchange?.(l.code);
56
60
  }}
@@ -1,12 +1,11 @@
1
1
  <script lang="ts">
2
2
  import AppSettingSelector from "./AppSettingSelector.svelte";
3
- import { getThemeStore, type Theme } from "../../state/theme.svelte";
3
+ import { getThemeStore, type Theme } from "@internal/state";
4
+ import * as rlMessages from "../../paraglide/messages.js";
5
+ import { getContext } from "svelte";
4
6
 
5
7
  const themeStore = getThemeStore();
6
8
 
7
- import { getContext } from "svelte";
8
- import { createMessageResolver } from "../../internal/message-resolver";
9
-
10
9
  let {
11
10
  themes = [],
12
11
  current = $bindable(themeStore.current),
@@ -17,11 +16,17 @@
17
16
  onchange?: (value: string) => void;
18
17
  } = $props();
19
18
 
20
- const dictionary = getContext<Record<string, any>>("rl:dictionary") || {};
19
+ const userDictionary =
20
+ getContext<Record<string, any>>("rl:dictionary") ?? {};
21
21
 
22
- const getThemeLabel = createMessageResolver<Theme>(dictionary as any, {
23
- keyExtractor: (t) => t.name,
24
- });
22
+ function getThemeLabel(theme: Theme): string {
23
+ const key = theme.name;
24
+ if (typeof userDictionary[key] === "function")
25
+ return userDictionary[key]();
26
+ if (typeof (rlMessages as any)[key] === "function")
27
+ return (rlMessages as any)[key]();
28
+ return theme.name;
29
+ }
25
30
 
26
31
  let activeTheme = $derived(
27
32
  themeStore.get(themeStore.current) ?? themeStore.available[0],
@@ -39,8 +44,8 @@
39
44
  options={available}
40
45
  tooltip={getThemeLabel(activeTheme)}
41
46
  >
42
- {#snippet triggerLabel(t)}
43
- <span class="text-lg">{t?.icon ?? activeTheme.icon}</span>
47
+ {#snippet triggerLabel()}
48
+ <span class="text-lg">{activeTheme.icon}</span>
44
49
  {/snippet}
45
50
 
46
51
  {#snippet item(t)}
@@ -54,7 +59,7 @@
54
59
  >
55
60
  <input
56
61
  type="radio"
57
- name="theme-dropdown"
62
+ name="theme-{t.name}"
58
63
  class="theme-controller radio radio-xs"
59
64
  value={t.name}
60
65
  bind:group={themeStore.current}
@@ -5,9 +5,9 @@
5
5
  getShortcutStore,
6
6
  LAYOUT_SHORTCUTS,
7
7
  type ShortcutEntry,
8
- } from "../../state/shortcuts.svelte";
9
- import { getAppStore } from "../../state/app.svelte";
10
- import { Icon } from "../../index";
8
+ } from "@internal/state";
9
+ import { getAppStore } from "@internal/state";
10
+ import { Icon } from "@internal/ui";
11
11
 
12
12
  const appStore = getAppStore();
13
13
  const shortcutStore = getShortcutStore();
@@ -0,0 +1,21 @@
1
+ export { portal } from "./actions/portal.js";
2
+ export { default as RuneProvider } from "./components/RuneProvider.svelte";
3
+ export { default as Icon } from "./components/Icon.svelte";
4
+ export { default as Toaster } from "./components/Toaster.svelte";
5
+ export { default as ApiMonitor } from "./components/ApiMonitor.svelte";
6
+ export { default as CommandPalette } from "./features/command-palette/CommandPalette.svelte";
7
+ export { default as ShortcutPalette } from "./features/shortcuts/ShortcutPalette.svelte";
8
+ export { default as AppSettingSelector } from "./features/config/AppSettingSelector.svelte";
9
+ export { default as ThemeSelector } from "./features/config/ThemeSelector.svelte";
10
+ export { default as LanguageSelector } from "./features/config/LanguageSelector.svelte";
11
+ export { default as CurrencySelector } from "./features/config/CurrencySelector.svelte";
12
+ export { default as WorkspaceLayout } from "./layout/WorkspaceLayout.svelte";
13
+ export { default as WorkspaceStrip } from "./layout/WorkspaceStrip.svelte";
14
+ export { default as NavigationPanel } from "./layout/NavigationPanel.svelte";
15
+ export { default as ContentArea } from "./layout/ContentArea.svelte";
16
+ export { default as DetailPanel } from "./layout/DetailPanel.svelte";
17
+ export { default as ConnectedNavigationPanel } from "./layout/ConnectedNavigationPanel.svelte";
18
+ export { default as ConnectedWorkspaceStrip } from "./layout/ConnectedWorkspaceStrip.svelte";
19
+ export * as sdkMessages from "./paraglide/messages.js";
20
+ export * from '@internal/state';
21
+ export * from '@internal/core';
@@ -0,0 +1,31 @@
1
+ // @internal/ui - Public barrel export
2
+ // All components, actions, and layout primitives
3
+ // ── Actions ───────────────────────────────────────────────────────────────────
4
+ export { portal } from "./actions/portal.js";
5
+ // ── Core Components ───────────────────────────────────────────────────────────
6
+ export { default as RuneProvider } from "./components/RuneProvider.svelte";
7
+ export { default as Icon } from "./components/Icon.svelte";
8
+ export { default as Toaster } from "./components/Toaster.svelte";
9
+ export { default as ApiMonitor } from "./components/ApiMonitor.svelte";
10
+ // ── Features ──────────────────────────────────────────────────────────────────
11
+ export { default as CommandPalette } from "./features/command-palette/CommandPalette.svelte";
12
+ export { default as ShortcutPalette } from "./features/shortcuts/ShortcutPalette.svelte";
13
+ // Setting Selectors
14
+ export { default as AppSettingSelector } from "./features/config/AppSettingSelector.svelte";
15
+ export { default as ThemeSelector } from "./features/config/ThemeSelector.svelte";
16
+ export { default as LanguageSelector } from "./features/config/LanguageSelector.svelte";
17
+ export { default as CurrencySelector } from "./features/config/CurrencySelector.svelte";
18
+ // ── Layout Primitives ─────────────────────────────────────────────────────────
19
+ export { default as WorkspaceLayout } from "./layout/WorkspaceLayout.svelte";
20
+ export { default as WorkspaceStrip } from "./layout/WorkspaceStrip.svelte";
21
+ export { default as NavigationPanel } from "./layout/NavigationPanel.svelte";
22
+ export { default as ContentArea } from "./layout/ContentArea.svelte";
23
+ export { default as DetailPanel } from "./layout/DetailPanel.svelte";
24
+ // ── Connected (Smart) Components ──────────────────────────────────────────────
25
+ export { default as ConnectedNavigationPanel } from "./layout/ConnectedNavigationPanel.svelte";
26
+ export { default as ConnectedWorkspaceStrip } from "./layout/ConnectedWorkspaceStrip.svelte";
27
+ // ── Paraglide messages ────────────────────────────────────────────────────────
28
+ export * as sdkMessages from "./paraglide/messages.js";
29
+ // Consumers shouldn't need rune-lab/state just to get cookieDriver, stores, etc.
30
+ export * from '@internal/state';
31
+ export * from '@internal/core';
@@ -1,10 +1,7 @@
1
1
  <!-- src/lib/features/layout/smart/ConnectedNavigationPanel.svelte -->
2
2
  <script lang="ts">
3
- import {
4
- getLayoutStore,
5
- type NavigationSection,
6
- } from "../../../state/layout.svelte";
7
- import NavigationPanel from "../../../layout/NavigationPanel.svelte";
3
+ import { getLayoutStore, type NavigationSection } from "@internal/state";
4
+ import NavigationPanel from "./NavigationPanel.svelte";
8
5
  import type { Snippet } from "svelte";
9
6
 
10
7
  let { sections, header, footer } = $props<{
@@ -1,4 +1,4 @@
1
- import { type NavigationSection } from "../../../state/layout.svelte";
1
+ import { type NavigationSection } from "@internal/state";
2
2
  import type { Snippet } from "svelte";
3
3
  type $$ComponentProps = {
4
4
  sections: NavigationSection[];
@@ -1,10 +1,7 @@
1
1
  <!-- src/lib/features/layout/smart/ConnectedWorkspaceStrip.svelte -->
2
2
  <script lang="ts">
3
- import {
4
- getLayoutStore,
5
- type WorkspaceItem,
6
- } from "../../../state/layout.svelte";
7
- import WorkspaceStrip from "../../../layout/WorkspaceStrip.svelte";
3
+ import { getLayoutStore, type WorkspaceItem } from "@internal/state";
4
+ import WorkspaceStrip from "./WorkspaceStrip.svelte";
8
5
  import type { Snippet } from "svelte";
9
6
 
10
7
  let { items, globalActions } = $props<{
@@ -1,4 +1,4 @@
1
- import { type WorkspaceItem } from "../../../state/layout.svelte";
1
+ import { type WorkspaceItem } from "@internal/state";
2
2
  import type { Snippet } from "svelte";
3
3
  type $$ComponentProps = {
4
4
  items: WorkspaceItem[];
@@ -4,7 +4,7 @@
4
4
  import type {
5
5
  NavigationItem,
6
6
  NavigationSection,
7
- } from "../state/layout.svelte";
7
+ } from "@internal/state";
8
8
 
9
9
  let {
10
10
  header,
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from "svelte";
2
- import type { NavigationItem, NavigationSection } from "../state/layout.svelte";
2
+ import type { NavigationItem, NavigationSection } from "@internal/state";
3
3
  type $$ComponentProps = {
4
4
  header?: Snippet;
5
5
  sections: NavigationSection[];
@@ -28,12 +28,12 @@
28
28
  </script>
29
29
 
30
30
  <script lang="ts">
31
- import { getLayoutStore } from "../state/layout.svelte";
32
31
  import {
32
+ getLayoutStore,
33
33
  getShortcutStore,
34
34
  shortcutListener,
35
35
  LAYOUT_SHORTCUTS,
36
- } from "../state/shortcuts.svelte";
36
+ } from "@internal/state";
37
37
  import { onMount } from "svelte";
38
38
 
39
39
  /**
@@ -1,7 +1,7 @@
1
1
  <!-- src/lib/layout/WorkspaceStrip.svelte -->
2
2
  <script lang="ts">
3
3
  import type { Snippet } from "svelte";
4
- import type { WorkspaceItem } from "../state/layout.svelte";
4
+ import type { WorkspaceItem } from "@internal/state";
5
5
 
6
6
  let {
7
7
  items = [],
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from "svelte";
2
- import type { WorkspaceItem } from "../state/layout.svelte";
2
+ import type { WorkspaceItem } from "@internal/state";
3
3
  type $$ComponentProps = {
4
4
  items: WorkspaceItem[];
5
5
  globalActions?: Snippet;
@@ -3,5 +3,5 @@ export { default as WorkspaceStrip } from "./WorkspaceStrip.svelte";
3
3
  export { default as NavigationPanel } from "./NavigationPanel.svelte";
4
4
  export { default as ContentArea } from "./ContentArea.svelte";
5
5
  export { default as DetailPanel } from "./DetailPanel.svelte";
6
- export { createLayoutStore, getLayoutStore } from "../state/layout.svelte";
7
- export type { NavigationItem, NavigationSection, WorkspaceItem, } from "../state/layout.svelte";
6
+ export { createLayoutStore, getLayoutStore } from "@internal/state";
7
+ export type { NavigationItem, NavigationSection, WorkspaceItem, } from "@internal/state";
@@ -4,4 +4,4 @@ export { default as WorkspaceStrip } from "./WorkspaceStrip.svelte";
4
4
  export { default as NavigationPanel } from "./NavigationPanel.svelte";
5
5
  export { default as ContentArea } from "./ContentArea.svelte";
6
6
  export { default as DetailPanel } from "./DetailPanel.svelte";
7
- export { createLayoutStore, getLayoutStore } from "../state/layout.svelte";
7
+ export { createLayoutStore, getLayoutStore } from "@internal/state";
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Auto-generated i18n message functions. Import `messages.js` to use translated strings.
4
4
 
5
- Compiled from: `/home/yrrrrrf/docs/lab/code/typescript/rune-lab/src/i18n/project.inlang`
5
+ Compiled from: `/home/yrrrrrf/docs/lab/code/typescript/rune-lab/src/sdk/ui/src/i18n/project.inlang`
6
6
 
7
7
 
8
8
  ## What is this folder?
@@ -51,9 +51,10 @@ m.greeting({ name: "Sam" }, { locale: "de" }); // "Hallo, Sam!"
51
51
  ## Runtime API
52
52
 
53
53
  ```js
54
- import { getLocale, setLocale, locales, baseLocale } from "./paraglide/runtime.js";
54
+ import { getLocale, getTextDirection, setLocale, locales, baseLocale } from "./paraglide/runtime.js";
55
55
 
56
56
  getLocale(); // Current locale, e.g., "en"
57
+ getTextDirection(); // "ltr" | "rtl" for current locale
57
58
  setLocale("de"); // Set locale
58
59
  locales; // Available locales, e.g., ["en", "de", "fr"]
59
60
  baseLocale; // Default locale, e.g., "en"
@@ -33,6 +33,21 @@ export function overwriteServerAsyncLocalStorage(value: ParaglideAsyncLocalStora
33
33
  * @returns {Locale}
34
34
  */
35
35
  export function getLocaleForUrl(url: string | URL): Locale;
36
+ /**
37
+ * Get writing direction for a locale.
38
+ *
39
+ * Uses `Intl.Locale` text info when available and falls back to a
40
+ * language-based RTL check for runtimes without `getTextInfo()`.
41
+ *
42
+ * @example
43
+ * getTextDirection(); // "ltr" or "rtl" for current locale
44
+ * getTextDirection("ar"); // "rtl"
45
+ * getTextDirection("en"); // "ltr"
46
+ *
47
+ * @param {string} [locale] - Target locale. If not provided, uses `getLocale()`
48
+ * @returns {"ltr" | "rtl"}
49
+ */
50
+ export function getTextDirection(locale?: string): "ltr" | "rtl";
36
51
  /**
37
52
  * Check if something is an available locale.
38
53
  *
@@ -614,12 +629,12 @@ export const customClientStrategies: Map<string, CustomClientStrategyHandler>;
614
629
  export type ShouldRedirectServerInput = {
615
630
  request: Request;
616
631
  url?: string | URL | undefined;
617
- locale?: "en" | "es" | "fr" | "it" | "pt" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" | undefined;
632
+ locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" | undefined;
618
633
  };
619
634
  export type ShouldRedirectClientInput = {
620
635
  request?: undefined;
621
636
  url?: string | URL | undefined;
622
- locale?: "en" | "es" | "fr" | "it" | "pt" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" | undefined;
637
+ locale?: "es" | "fr" | "it" | "pt" | "en" | "de" | "ru" | "hi" | "ar" | "zh" | "ja" | "ko" | "vi" | undefined;
623
638
  };
624
639
  export type ShouldRedirectInput = ShouldRedirectServerInput | ShouldRedirectClientInput;
625
640
  export type ShouldRedirectResult = {
@@ -365,6 +365,51 @@ export const overwriteGetLocale = (fn) => {
365
365
  getLocale = fn;
366
366
  };
367
367
 
368
+ const rtlLanguages = new Set([
369
+ "ar",
370
+ "dv",
371
+ "fa",
372
+ "he",
373
+ "ks",
374
+ "ku",
375
+ "ps",
376
+ "sd",
377
+ "ug",
378
+ "ur",
379
+ "yi",
380
+ ]);
381
+ /**
382
+ * Get writing direction for a locale.
383
+ *
384
+ * Uses `Intl.Locale` text info when available and falls back to a
385
+ * language-based RTL check for runtimes without `getTextInfo()`.
386
+ *
387
+ * @example
388
+ * getTextDirection(); // "ltr" or "rtl" for current locale
389
+ * getTextDirection("ar"); // "rtl"
390
+ * getTextDirection("en"); // "ltr"
391
+ *
392
+ * @param {string} [locale] - Target locale. If not provided, uses `getLocale()`
393
+ * @returns {"ltr" | "rtl"}
394
+ */
395
+ export function getTextDirection(locale = getLocale()) {
396
+ try {
397
+ const intlLocale = /** @type {Intl.Locale & {
398
+ getTextInfo?: () => { direction?: string };
399
+ textInfo?: { direction?: string };
400
+ }} */ (new Intl.Locale(locale));
401
+ const direction = intlLocale.getTextInfo?.().direction ?? intlLocale.textInfo?.direction;
402
+ if (direction === "ltr" || direction === "rtl") {
403
+ return direction;
404
+ }
405
+ }
406
+ catch {
407
+ // Ignore Intl.Locale parsing/runtime errors and use fallback below.
408
+ }
409
+ const language = locale.split("-")[0]?.toLowerCase();
410
+ return rtlLanguages.has(language ?? "") ? "rtl" : "ltr";
411
+ }
412
+
368
413
  /**
369
414
  * Navigates to the localized URL, or reloads the current page
370
415
  *