svedocs 0.1.0-beta.10

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 (286) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +85 -0
  3. package/dist/ai/openai-compatible.d.ts +13 -0
  4. package/dist/ai/openai-compatible.d.ts.map +1 -0
  5. package/dist/ai/openai-compatible.js +92 -0
  6. package/dist/ai/providers.d.ts +20 -0
  7. package/dist/ai/providers.d.ts.map +1 -0
  8. package/dist/ai/providers.js +185 -0
  9. package/dist/ai/rate-limit.d.ts +18 -0
  10. package/dist/ai/rate-limit.d.ts.map +1 -0
  11. package/dist/ai/rate-limit.js +52 -0
  12. package/dist/ai/response.d.ts +4 -0
  13. package/dist/ai/response.d.ts.map +1 -0
  14. package/dist/ai/response.js +151 -0
  15. package/dist/ai/runtime.d.ts +32 -0
  16. package/dist/ai/runtime.d.ts.map +1 -0
  17. package/dist/ai/runtime.js +111 -0
  18. package/dist/ai/types.d.ts +93 -0
  19. package/dist/ai/types.d.ts.map +1 -0
  20. package/dist/ai/types.js +1 -0
  21. package/dist/ai.d.ts +7 -0
  22. package/dist/ai.d.ts.map +1 -0
  23. package/dist/ai.js +6 -0
  24. package/dist/ambient.d.ts +5 -0
  25. package/dist/cloudflare.d.ts +29 -0
  26. package/dist/cloudflare.d.ts.map +1 -0
  27. package/dist/cloudflare.js +149 -0
  28. package/dist/config.d.ts +373 -0
  29. package/dist/config.d.ts.map +1 -0
  30. package/dist/config.js +299 -0
  31. package/dist/core/checks.d.ts +4 -0
  32. package/dist/core/checks.d.ts.map +1 -0
  33. package/dist/core/checks.js +267 -0
  34. package/dist/core/config.d.ts +6 -0
  35. package/dist/core/config.d.ts.map +1 -0
  36. package/dist/core/config.js +178 -0
  37. package/dist/core/content.d.ts +7 -0
  38. package/dist/core/content.d.ts.map +1 -0
  39. package/dist/core/content.js +340 -0
  40. package/dist/core/i18n.d.ts +5 -0
  41. package/dist/core/i18n.d.ts.map +1 -0
  42. package/dist/core/i18n.js +117 -0
  43. package/dist/core/links.d.ts +5 -0
  44. package/dist/core/links.d.ts.map +1 -0
  45. package/dist/core/links.js +60 -0
  46. package/dist/core/messages.d.ts +149 -0
  47. package/dist/core/messages.d.ts.map +1 -0
  48. package/dist/core/messages.js +163 -0
  49. package/dist/core/navigation.d.ts +5 -0
  50. package/dist/core/navigation.d.ts.map +1 -0
  51. package/dist/core/navigation.js +144 -0
  52. package/dist/core/routes.d.ts +36 -0
  53. package/dist/core/routes.d.ts.map +1 -0
  54. package/dist/core/routes.js +152 -0
  55. package/dist/core/search.d.ts +5 -0
  56. package/dist/core/search.d.ts.map +1 -0
  57. package/dist/core/search.js +41 -0
  58. package/dist/core/types.d.ts +468 -0
  59. package/dist/core/types.d.ts.map +1 -0
  60. package/dist/core/types.js +4 -0
  61. package/dist/core/utils.d.ts +13 -0
  62. package/dist/core/utils.d.ts.map +1 -0
  63. package/dist/core/utils.js +60 -0
  64. package/dist/core.d.ts +9 -0
  65. package/dist/core.d.ts.map +1 -0
  66. package/dist/core.js +8 -0
  67. package/dist/index.d.ts +6 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +3 -0
  70. package/dist/mdx/ast.d.ts +32 -0
  71. package/dist/mdx/ast.d.ts.map +1 -0
  72. package/dist/mdx/ast.js +148 -0
  73. package/dist/mdx/code.d.ts +17 -0
  74. package/dist/mdx/code.d.ts.map +1 -0
  75. package/dist/mdx/code.js +327 -0
  76. package/dist/mdx/compile.d.ts +29 -0
  77. package/dist/mdx/compile.d.ts.map +1 -0
  78. package/dist/mdx/compile.js +59 -0
  79. package/dist/mdx/diff.d.ts +9 -0
  80. package/dist/mdx/diff.d.ts.map +1 -0
  81. package/dist/mdx/diff.js +171 -0
  82. package/dist/mdx/headings.d.ts +4 -0
  83. package/dist/mdx/headings.d.ts.map +1 -0
  84. package/dist/mdx/headings.js +42 -0
  85. package/dist/mdx/links.d.ts +4 -0
  86. package/dist/mdx/links.d.ts.map +1 -0
  87. package/dist/mdx/links.js +144 -0
  88. package/dist/mdx/utils.d.ts +10 -0
  89. package/dist/mdx/utils.d.ts.map +1 -0
  90. package/dist/mdx/utils.js +64 -0
  91. package/dist/og/image.d.ts +25 -0
  92. package/dist/og/image.d.ts.map +1 -0
  93. package/dist/og/image.js +224 -0
  94. package/dist/og/metadata.d.ts +7 -0
  95. package/dist/og/metadata.d.ts.map +1 -0
  96. package/dist/og/metadata.js +198 -0
  97. package/dist/og/response.d.ts +4 -0
  98. package/dist/og/response.d.ts.map +1 -0
  99. package/dist/og/response.js +49 -0
  100. package/dist/og/rss.d.ts +4 -0
  101. package/dist/og/rss.d.ts.map +1 -0
  102. package/dist/og/rss.js +96 -0
  103. package/dist/og/sitemap.d.ts +7 -0
  104. package/dist/og/sitemap.d.ts.map +1 -0
  105. package/dist/og/sitemap.js +90 -0
  106. package/dist/og/types.d.ts +65 -0
  107. package/dist/og/types.d.ts.map +1 -0
  108. package/dist/og/types.js +1 -0
  109. package/dist/og.d.ts +6 -0
  110. package/dist/og.d.ts.map +1 -0
  111. package/dist/og.js +5 -0
  112. package/dist/routes.d.ts +2 -0
  113. package/dist/routes.d.ts.map +1 -0
  114. package/dist/routes.js +1 -0
  115. package/dist/search/algolia.d.ts +10 -0
  116. package/dist/search/algolia.d.ts.map +1 -0
  117. package/dist/search/algolia.js +82 -0
  118. package/dist/search/cloudflare-sync.d.ts +5 -0
  119. package/dist/search/cloudflare-sync.d.ts.map +1 -0
  120. package/dist/search/cloudflare-sync.js +169 -0
  121. package/dist/search/cloudflare.d.ts +11 -0
  122. package/dist/search/cloudflare.d.ts.map +1 -0
  123. package/dist/search/cloudflare.js +126 -0
  124. package/dist/search/local.d.ts +9 -0
  125. package/dist/search/local.d.ts.map +1 -0
  126. package/dist/search/local.js +165 -0
  127. package/dist/search/runtime.d.ts +41 -0
  128. package/dist/search/runtime.d.ts.map +1 -0
  129. package/dist/search/runtime.js +152 -0
  130. package/dist/search/types.d.ts +172 -0
  131. package/dist/search/types.d.ts.map +1 -0
  132. package/dist/search/types.js +1 -0
  133. package/dist/search/typesense.d.ts +11 -0
  134. package/dist/search/typesense.d.ts.map +1 -0
  135. package/dist/search/typesense.js +91 -0
  136. package/dist/search/utils.d.ts +11 -0
  137. package/dist/search/utils.d.ts.map +1 -0
  138. package/dist/search/utils.js +93 -0
  139. package/dist/search.d.ts +8 -0
  140. package/dist/search.d.ts.map +1 -0
  141. package/dist/search.js +7 -0
  142. package/dist/svelte.d.ts +27 -0
  143. package/dist/svelte.d.ts.map +1 -0
  144. package/dist/svelte.js +45 -0
  145. package/dist/testing.d.ts +3 -0
  146. package/dist/testing.d.ts.map +1 -0
  147. package/dist/testing.js +23 -0
  148. package/dist/theme/Article.svelte +145 -0
  149. package/dist/theme/Article.svelte.d.ts +36 -0
  150. package/dist/theme/Article.svelte.d.ts.map +1 -0
  151. package/dist/theme/AskAiPanel.svelte +241 -0
  152. package/dist/theme/AskAiPanel.svelte.d.ts +31 -0
  153. package/dist/theme/AskAiPanel.svelte.d.ts.map +1 -0
  154. package/dist/theme/Brand.svelte +19 -0
  155. package/dist/theme/Brand.svelte.d.ts +22 -0
  156. package/dist/theme/Brand.svelte.d.ts.map +1 -0
  157. package/dist/theme/Button.svelte +34 -0
  158. package/dist/theme/Button.svelte.d.ts +41 -0
  159. package/dist/theme/Button.svelte.d.ts.map +1 -0
  160. package/dist/theme/Checkbox.svelte +63 -0
  161. package/dist/theme/Checkbox.svelte.d.ts +45 -0
  162. package/dist/theme/Checkbox.svelte.d.ts.map +1 -0
  163. package/dist/theme/CodeBlock.svelte +6 -0
  164. package/dist/theme/CodeBlock.svelte.d.ts +22 -0
  165. package/dist/theme/CodeBlock.svelte.d.ts.map +1 -0
  166. package/dist/theme/DocPage.svelte +15 -0
  167. package/dist/theme/DocPage.svelte.d.ts +33 -0
  168. package/dist/theme/DocPage.svelte.d.ts.map +1 -0
  169. package/dist/theme/DocsApp.svelte +194 -0
  170. package/dist/theme/DocsApp.svelte.d.ts +60 -0
  171. package/dist/theme/DocsApp.svelte.d.ts.map +1 -0
  172. package/dist/theme/DocsLayout.svelte +99 -0
  173. package/dist/theme/DocsLayout.svelte.d.ts +39 -0
  174. package/dist/theme/DocsLayout.svelte.d.ts.map +1 -0
  175. package/dist/theme/DocsShell.svelte +91 -0
  176. package/dist/theme/DocsShell.svelte.d.ts +34 -0
  177. package/dist/theme/DocsShell.svelte.d.ts.map +1 -0
  178. package/dist/theme/ErrorPage.svelte +113 -0
  179. package/dist/theme/ErrorPage.svelte.d.ts +34 -0
  180. package/dist/theme/ErrorPage.svelte.d.ts.map +1 -0
  181. package/dist/theme/FloatingToolbar.svelte +8 -0
  182. package/dist/theme/FloatingToolbar.svelte.d.ts +22 -0
  183. package/dist/theme/FloatingToolbar.svelte.d.ts.map +1 -0
  184. package/dist/theme/Footer.svelte +18 -0
  185. package/dist/theme/Footer.svelte.d.ts +24 -0
  186. package/dist/theme/Footer.svelte.d.ts.map +1 -0
  187. package/dist/theme/FooterLinks.svelte +37 -0
  188. package/dist/theme/FooterLinks.svelte.d.ts +22 -0
  189. package/dist/theme/FooterLinks.svelte.d.ts.map +1 -0
  190. package/dist/theme/FormField.svelte +41 -0
  191. package/dist/theme/FormField.svelte.d.ts +35 -0
  192. package/dist/theme/FormField.svelte.d.ts.map +1 -0
  193. package/dist/theme/HomePage.svelte +284 -0
  194. package/dist/theme/HomePage.svelte.d.ts +65 -0
  195. package/dist/theme/HomePage.svelte.d.ts.map +1 -0
  196. package/dist/theme/Input.svelte +36 -0
  197. package/dist/theme/Input.svelte.d.ts +34 -0
  198. package/dist/theme/Input.svelte.d.ts.map +1 -0
  199. package/dist/theme/LayoutShell.svelte +120 -0
  200. package/dist/theme/LayoutShell.svelte.d.ts +43 -0
  201. package/dist/theme/LayoutShell.svelte.d.ts.map +1 -0
  202. package/dist/theme/LocalizedLink.svelte +21 -0
  203. package/dist/theme/LocalizedLink.svelte.d.ts +38 -0
  204. package/dist/theme/LocalizedLink.svelte.d.ts.map +1 -0
  205. package/dist/theme/MobileNav.svelte +20 -0
  206. package/dist/theme/MobileNav.svelte.d.ts +26 -0
  207. package/dist/theme/MobileNav.svelte.d.ts.map +1 -0
  208. package/dist/theme/Navbar.svelte +69 -0
  209. package/dist/theme/Navbar.svelte.d.ts +29 -0
  210. package/dist/theme/Navbar.svelte.d.ts.map +1 -0
  211. package/dist/theme/PageLayout.svelte +49 -0
  212. package/dist/theme/PageLayout.svelte.d.ts +34 -0
  213. package/dist/theme/PageLayout.svelte.d.ts.map +1 -0
  214. package/dist/theme/PageShell.svelte +98 -0
  215. package/dist/theme/PageShell.svelte.d.ts +35 -0
  216. package/dist/theme/PageShell.svelte.d.ts.map +1 -0
  217. package/dist/theme/PageTools.svelte +87 -0
  218. package/dist/theme/PageTools.svelte.d.ts +25 -0
  219. package/dist/theme/PageTools.svelte.d.ts.map +1 -0
  220. package/dist/theme/RenderError.svelte +62 -0
  221. package/dist/theme/RenderError.svelte.d.ts +31 -0
  222. package/dist/theme/RenderError.svelte.d.ts.map +1 -0
  223. package/dist/theme/RootLayout.svelte +274 -0
  224. package/dist/theme/RootLayout.svelte.d.ts +47 -0
  225. package/dist/theme/RootLayout.svelte.d.ts.map +1 -0
  226. package/dist/theme/RouteRenderError.svelte +53 -0
  227. package/dist/theme/RouteRenderError.svelte.d.ts +34 -0
  228. package/dist/theme/RouteRenderError.svelte.d.ts.map +1 -0
  229. package/dist/theme/SafeRenderError.svelte +49 -0
  230. package/dist/theme/SafeRenderError.svelte.d.ts +33 -0
  231. package/dist/theme/SafeRenderError.svelte.d.ts.map +1 -0
  232. package/dist/theme/ScopeSwitcher.svelte +107 -0
  233. package/dist/theme/ScopeSwitcher.svelte.d.ts +26 -0
  234. package/dist/theme/ScopeSwitcher.svelte.d.ts.map +1 -0
  235. package/dist/theme/SearchDialog.svelte +200 -0
  236. package/dist/theme/SearchDialog.svelte.d.ts +31 -0
  237. package/dist/theme/SearchDialog.svelte.d.ts.map +1 -0
  238. package/dist/theme/Select.svelte +37 -0
  239. package/dist/theme/Select.svelte.d.ts +42 -0
  240. package/dist/theme/Select.svelte.d.ts.map +1 -0
  241. package/dist/theme/SidebarTree.svelte +148 -0
  242. package/dist/theme/SidebarTree.svelte.d.ts +24 -0
  243. package/dist/theme/SidebarTree.svelte.d.ts.map +1 -0
  244. package/dist/theme/SocialNav.svelte +17 -0
  245. package/dist/theme/SocialNav.svelte.d.ts +22 -0
  246. package/dist/theme/SocialNav.svelte.d.ts.map +1 -0
  247. package/dist/theme/TableOfContents.svelte +73 -0
  248. package/dist/theme/TableOfContents.svelte.d.ts +25 -0
  249. package/dist/theme/TableOfContents.svelte.d.ts.map +1 -0
  250. package/dist/theme/Textarea.svelte +33 -0
  251. package/dist/theme/Textarea.svelte.d.ts +33 -0
  252. package/dist/theme/Textarea.svelte.d.ts.map +1 -0
  253. package/dist/theme/ThemeInit.svelte +16 -0
  254. package/dist/theme/ThemeInit.svelte.d.ts +23 -0
  255. package/dist/theme/ThemeInit.svelte.d.ts.map +1 -0
  256. package/dist/theme/ThemeToggle.svelte +37 -0
  257. package/dist/theme/ThemeToggle.svelte.d.ts +23 -0
  258. package/dist/theme/ThemeToggle.svelte.d.ts.map +1 -0
  259. package/dist/theme/TopNav.svelte +23 -0
  260. package/dist/theme/TopNav.svelte.d.ts +22 -0
  261. package/dist/theme/TopNav.svelte.d.ts.map +1 -0
  262. package/dist/theme/base.css +240 -0
  263. package/dist/theme/defaults.d.ts +4 -0
  264. package/dist/theme/defaults.d.ts.map +1 -0
  265. package/dist/theme/defaults.js +55 -0
  266. package/dist/theme/forms.d.ts +4 -0
  267. package/dist/theme/forms.d.ts.map +1 -0
  268. package/dist/theme/forms.js +3 -0
  269. package/dist/theme/headless.d.ts +62 -0
  270. package/dist/theme/headless.d.ts.map +1 -0
  271. package/dist/theme/headless.js +1064 -0
  272. package/dist/theme/index.d.ts +41 -0
  273. package/dist/theme/index.d.ts.map +1 -0
  274. package/dist/theme/index.js +38 -0
  275. package/dist/theme/portal.d.ts +6 -0
  276. package/dist/theme/portal.d.ts.map +1 -0
  277. package/dist/theme/portal.js +59 -0
  278. package/dist/theme/styles.css +4232 -0
  279. package/dist/theme/types.d.ts +363 -0
  280. package/dist/theme/types.d.ts.map +1 -0
  281. package/dist/theme/types.js +1 -0
  282. package/dist/virtual.d.ts +65 -0
  283. package/dist/vite.d.ts +16 -0
  284. package/dist/vite.d.ts.map +1 -0
  285. package/dist/vite.js +386 -0
  286. package/package.json +132 -0
@@ -0,0 +1,274 @@
1
+ <script lang="ts">
2
+ import { onDestroy, onMount } from 'svelte';
3
+ import type { SvedocsPage, SvedocsResolvedConfig, SvedocsSearchRecord, SvedocsTreeItem } from '../core/types.js';
4
+ import { createJsonLdScript, createPageAlternates, createPageMetadata } from '../og/metadata.js';
5
+ import { createDomId, createMobileNavController, createThemeContext, createThemeStyle } from './headless.js';
6
+ import LayoutShell from './LayoutShell.svelte';
7
+ import SafeRenderError from './SafeRenderError.svelte';
8
+ import ThemeInit from './ThemeInit.svelte';
9
+ import type { SvedocsThemeComponentMap } from './types.js';
10
+
11
+ export let config: SvedocsResolvedConfig;
12
+ export let page: SvedocsPage | undefined = undefined;
13
+ export let localeCode: string | undefined = undefined;
14
+ export let pages: SvedocsPage[] = [];
15
+ export let tree: SvedocsTreeItem[] = [];
16
+ export let search: SvedocsSearchRecord[] = [];
17
+ export let loadSearch: (() => Promise<SvedocsSearchRecord[]>) | undefined = undefined;
18
+ export let headTitle = '';
19
+ export let headDescription = '';
20
+ export let headRobots = '';
21
+ export let mobileTree: SvedocsTreeItem[] = [];
22
+ export let mobileCurrentPath = '';
23
+ export let hasBackgroundSlot: boolean | undefined = undefined;
24
+ export let themeComponents: Partial<SvedocsThemeComponentMap> = {};
25
+
26
+ const mobileNav = createMobileNavController();
27
+ let mounted = false;
28
+ let mobileMenuOpen = false;
29
+ let unsubscribeMobileMenu: (() => void) | undefined;
30
+ let stopScrollbarVisibility: (() => void) | undefined;
31
+
32
+ $: metadata = page ? createPageMetadata(config, page, pages) : undefined;
33
+ $: alternates = page ? createPageAlternates(config, page, pages) : [];
34
+ $: jsonLdScripts = metadata ? [
35
+ createJsonLdScript(metadata.jsonLd),
36
+ ...metadata.head.jsonLd.map((entry) => createJsonLdScript(entry))
37
+ ] : [];
38
+ $: context = createThemeContext({
39
+ config,
40
+ ...(page ? { page } : {}),
41
+ pages,
42
+ tree: tree.length > 0 ? tree : mobileTree,
43
+ search,
44
+ ...(loadSearch ? { loadSearch } : {}),
45
+ ...(localeCode ? { localeCode } : {})
46
+ });
47
+ $: themeStyle = createThemeStyle(config);
48
+ $: mobileMenuId = `sd-mobile-menu-${createDomId(page?.id ?? page?.routePath ?? 'site')}`;
49
+ $: mobileTreePath = mobileCurrentPath || page?.routePath || '';
50
+ $: showBackgroundSlot = hasBackgroundSlot ?? Boolean($$slots.background);
51
+ $: title = headTitle || metadata?.title || (page ? config.site.title : `Error - ${config.site.title}`);
52
+ $: description = headDescription || metadata?.description || config.site.description;
53
+ $: robots = headRobots || metadata?.robots || (!page ? 'noindex' : '');
54
+ $: Layout = themeComponents.Layout ?? LayoutShell;
55
+
56
+ onMount(() => {
57
+ mounted = true;
58
+ unsubscribeMobileMenu = mobileNav.open.subscribe((value) => (mobileMenuOpen = value));
59
+ stopScrollbarVisibility = mountScrollbarVisibility();
60
+ markHydratedRoute();
61
+ return cleanupSubscriptions;
62
+ });
63
+
64
+ onDestroy(() => {
65
+ cleanupSubscriptions();
66
+ });
67
+
68
+ $: if (mounted) {
69
+ page?.routePath;
70
+ page?.locale;
71
+ markHydratedRoute();
72
+ mobileNav.close();
73
+ }
74
+
75
+ function markHydratedRoute() {
76
+ document.documentElement.dataset.svedocsRoute = page?.routePath ?? '';
77
+ document.documentElement.lang = context.languageTag;
78
+ document.documentElement.dir = context.locale?.dir ?? 'ltr';
79
+ }
80
+
81
+ function cleanupSubscriptions() {
82
+ unsubscribeMobileMenu?.();
83
+ unsubscribeMobileMenu = undefined;
84
+ stopScrollbarVisibility?.();
85
+ stopScrollbarVisibility = undefined;
86
+ }
87
+
88
+ function mountScrollbarVisibility() {
89
+ const root = document.documentElement;
90
+ const body = document.body;
91
+ const elementTimers = new Map<HTMLElement, number>();
92
+ let windowTimer: number | undefined;
93
+
94
+ function markWindowScrolling() {
95
+ root.classList.add('sd-is-window-scrolling');
96
+ body.classList.add('sd-is-window-scrolling');
97
+ if (windowTimer !== undefined) window.clearTimeout(windowTimer);
98
+ windowTimer = window.setTimeout(() => {
99
+ root.classList.remove('sd-is-window-scrolling');
100
+ body.classList.remove('sd-is-window-scrolling');
101
+ windowTimer = undefined;
102
+ }, 900);
103
+ }
104
+
105
+ function markElementScrolling(event: Event) {
106
+ const target = event.target;
107
+ if (!(target instanceof HTMLElement) || target === root || target === body) return;
108
+ if (!isScrollableElement(target)) return;
109
+ target.classList.add('sd-is-scrolling');
110
+ const existingTimer = elementTimers.get(target);
111
+ if (existingTimer !== undefined) window.clearTimeout(existingTimer);
112
+ elementTimers.set(target, window.setTimeout(() => {
113
+ target.classList.remove('sd-is-scrolling');
114
+ elementTimers.delete(target);
115
+ }, 900));
116
+ }
117
+
118
+ window.addEventListener('scroll', markWindowScrolling, { passive: true });
119
+ document.addEventListener('scroll', markElementScrolling, { capture: true, passive: true });
120
+
121
+ return () => {
122
+ window.removeEventListener('scroll', markWindowScrolling);
123
+ document.removeEventListener('scroll', markElementScrolling, { capture: true });
124
+ if (windowTimer !== undefined) window.clearTimeout(windowTimer);
125
+ root.classList.remove('sd-is-window-scrolling');
126
+ body.classList.remove('sd-is-window-scrolling');
127
+ for (const [element, timer] of elementTimers) {
128
+ window.clearTimeout(timer);
129
+ element.classList.remove('sd-is-scrolling');
130
+ }
131
+ elementTimers.clear();
132
+ };
133
+ }
134
+
135
+ function isScrollableElement(element: HTMLElement) {
136
+ return element.scrollHeight > element.clientHeight + 1 || element.scrollWidth > element.clientWidth + 1;
137
+ }
138
+ </script>
139
+
140
+ <svelte:window on:keydown={mobileNav.handleWindowKeydown} />
141
+
142
+ <ThemeInit
143
+ defaultMode={config.theme.defaultMode}
144
+ languageTag={context.languageTag}
145
+ dir={context.locale?.dir ?? 'ltr'}
146
+ />
147
+
148
+ <svelte:head>
149
+ <title>{title}</title>
150
+ <meta name="description" content={description} />
151
+ {#if robots}
152
+ <meta name="robots" content={robots} />
153
+ {/if}
154
+ {#if metadata?.keywords.length}
155
+ <meta name="keywords" content={metadata.keywords.join(', ')} />
156
+ {/if}
157
+ {#if metadata?.canonical}
158
+ <link rel="canonical" href={metadata.canonical} />
159
+ {/if}
160
+ {#each alternates as alternate}
161
+ <link rel="alternate" hreflang={alternate.lang} href={alternate.href} />
162
+ {/each}
163
+ {#if metadata}
164
+ <meta property="og:title" content={metadata.openGraph.title} />
165
+ <meta property="og:description" content={metadata.openGraph.description} />
166
+ <meta property="og:type" content={metadata.openGraph.type} />
167
+ <meta property="og:site_name" content={metadata.openGraph.siteName} />
168
+ {#if metadata.openGraph.locale}
169
+ <meta property="og:locale" content={metadata.openGraph.locale} />
170
+ {/if}
171
+ {#each metadata.openGraph.alternateLocales ?? [] as locale}
172
+ <meta property="og:locale:alternate" content={locale} />
173
+ {/each}
174
+ {#if metadata.openGraph.url}
175
+ <meta property="og:url" content={metadata.openGraph.url} />
176
+ {/if}
177
+ {#if metadata.openGraph.image}
178
+ <meta property="og:image" content={metadata.openGraph.image} />
179
+ {/if}
180
+ {#if metadata.openGraph.author}
181
+ <meta property="article:author" content={metadata.openGraph.author} />
182
+ {/if}
183
+ {#if metadata.openGraph.publishedTime}
184
+ <meta property="article:published_time" content={metadata.openGraph.publishedTime} />
185
+ {/if}
186
+ {#if metadata.openGraph.updatedTime}
187
+ <meta property="article:modified_time" content={metadata.openGraph.updatedTime} />
188
+ {/if}
189
+ <meta name="twitter:card" content={metadata.twitter.card} />
190
+ <meta name="twitter:title" content={metadata.twitter.title} />
191
+ <meta name="twitter:description" content={metadata.twitter.description} />
192
+ {#if metadata.twitter.image}
193
+ <meta name="twitter:image" content={metadata.twitter.image} />
194
+ {/if}
195
+ {#each metadata.head.meta as tag}
196
+ <meta
197
+ name={tag.name}
198
+ property={tag.property}
199
+ http-equiv={tag.httpEquiv}
200
+ itemprop={tag.itemprop}
201
+ content={tag.content}
202
+ />
203
+ {/each}
204
+ {#each metadata.head.links as tag}
205
+ <link
206
+ rel={tag.rel}
207
+ href={tag.href}
208
+ hreflang={tag.hreflang}
209
+ type={tag.type}
210
+ media={tag.media}
211
+ title={tag.title}
212
+ sizes={tag.sizes}
213
+ as={tag.as}
214
+ crossorigin={tag.crossorigin}
215
+ />
216
+ {/each}
217
+ {#each jsonLdScripts as script}
218
+ {@html script}
219
+ {/each}
220
+ {/if}
221
+ </svelte:head>
222
+
223
+ <svelte:boundary>
224
+ <svelte:component
225
+ this={Layout}
226
+ {context}
227
+ {themeStyle}
228
+ {mobileTree}
229
+ mobileCurrentPath={mobileTreePath}
230
+ {mobileMenuId}
231
+ {mobileMenuOpen}
232
+ hasBackgroundSlot={showBackgroundSlot}
233
+ {themeComponents}
234
+ onToggleMobileMenu={mobileNav.toggle}
235
+ onCloseMobileMenu={mobileNav.close}
236
+ >
237
+ <svelte:fragment slot="background">
238
+ <slot name="background" />
239
+ </svelte:fragment>
240
+ <slot />
241
+ </svelte:component>
242
+ {#snippet failed(error, reset)}
243
+ <svelte:component
244
+ this={LayoutShell}
245
+ {context}
246
+ {themeStyle}
247
+ {mobileTree}
248
+ mobileCurrentPath={mobileTreePath}
249
+ {mobileMenuId}
250
+ {mobileMenuOpen}
251
+ hasBackgroundSlot={showBackgroundSlot}
252
+ {themeComponents}
253
+ onToggleMobileMenu={mobileNav.toggle}
254
+ onCloseMobileMenu={mobileNav.close}
255
+ >
256
+ <svelte:fragment slot="background">
257
+ <slot name="background" />
258
+ </svelte:fragment>
259
+ <main id="content" class="sd-route-render-error" data-theme-component="route-render-error">
260
+ <svelte:component
261
+ this={SafeRenderError} component={themeComponents.RenderError}
262
+ {error}
263
+ {reset}
264
+ {context}
265
+ tree={context.tree}
266
+ variant="layout"
267
+ label={context.t('render.layout.label')}
268
+ title={context.t('render.layout.title')}
269
+ message={context.t('render.layout.message')}
270
+ />
271
+ </main>
272
+ </svelte:component>
273
+ {/snippet}
274
+ </svelte:boundary>
@@ -0,0 +1,47 @@
1
+ import type { SvedocsPage, SvedocsResolvedConfig, SvedocsSearchRecord, SvedocsTreeItem } from '../core/types.js';
2
+ import type { SvedocsThemeComponentMap } from './types.js';
3
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
4
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
5
+ $$bindings?: Bindings;
6
+ } & Exports;
7
+ (internal: unknown, props: Props & {
8
+ $$events?: Events;
9
+ $$slots?: Slots;
10
+ }): Exports & {
11
+ $set?: any;
12
+ $on?: any;
13
+ };
14
+ z_$$bindings?: Bindings;
15
+ }
16
+ type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
17
+ default: any;
18
+ } ? Props extends Record<string, never> ? any : {
19
+ children?: any;
20
+ } : {});
21
+ declare const RootLayout: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
22
+ config: SvedocsResolvedConfig;
23
+ page?: SvedocsPage | undefined;
24
+ localeCode?: string | undefined;
25
+ pages?: SvedocsPage[];
26
+ tree?: SvedocsTreeItem[];
27
+ search?: SvedocsSearchRecord[];
28
+ loadSearch?: (() => Promise<SvedocsSearchRecord[]>) | undefined;
29
+ headTitle?: string;
30
+ headDescription?: string;
31
+ headRobots?: string;
32
+ mobileTree?: SvedocsTreeItem[];
33
+ mobileCurrentPath?: string;
34
+ hasBackgroundSlot?: boolean | undefined;
35
+ themeComponents?: Partial<SvedocsThemeComponentMap>;
36
+ }, {
37
+ background: {};
38
+ default: {};
39
+ }>, {
40
+ [evt: string]: CustomEvent<any>;
41
+ }, {
42
+ background: {};
43
+ default: {};
44
+ }, {}, string>;
45
+ type RootLayout = InstanceType<typeof RootLayout>;
46
+ export default RootLayout;
47
+ //# sourceMappingURL=RootLayout.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RootLayout.svelte.d.ts","sourceRoot":"","sources":["../../src/theme/RootLayout.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMjH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAgO3D,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AACD,KAAK,gCAAgC,CAAC,KAAK,EAAE,KAAK,IAAI,KAAK,GACvD,CAAC,KAAK,SAAS;IAAE,OAAO,EAAE,GAAG,CAAA;CAAE,GACzB,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GACnC,GAAG,GACH;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;CAAE,GAClB,EAAE,CAAC,CAAC;AAId,QAAA,MAAM,UAAU;YAfsW,qBAAqB;WAAS,WAAW,GAAG,SAAS;iBAAe,MAAM,GAAG,SAAS;YAAU,WAAW,EAAE;WAAS,eAAe,EAAE;aAAW,mBAAmB,EAAE;iBAAe,CAAC,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC,GAAG,SAAS;;;;iBAAuH,eAAe,EAAE;;wBAAoE,OAAO,GAAG,SAAS;sBAAoB,OAAO,CAAC,wBAAwB,CAAC;;;;;;;;;cAe7wB,CAAC;AACpF,KAAK,UAAU,GAAG,YAAY,CAAC,OAAO,UAAU,CAAC,CAAC;AACpD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,53 @@
1
+ <script lang="ts">
2
+ import type { SvedocsPage, SvedocsResolvedConfig, SvedocsSearchRecord, SvedocsTreeItem } from '../core/types.js';
3
+ import { createThemeContext } from './headless.js';
4
+ import SafeRenderError from './SafeRenderError.svelte';
5
+ import RootLayout from './RootLayout.svelte';
6
+ import type { SvedocsThemeComponentMap } from './types.js';
7
+
8
+ export let error: unknown = undefined;
9
+ export let reset: (() => void) | undefined = undefined;
10
+ export let page: SvedocsPage;
11
+ export let pages: SvedocsPage[] = [];
12
+ export let tree: SvedocsTreeItem[] = [];
13
+ export let search: SvedocsSearchRecord[] = [];
14
+ export let config: SvedocsResolvedConfig;
15
+ export let loadSearch: (() => Promise<SvedocsSearchRecord[]>) | undefined = undefined;
16
+ export let themeComponents: Partial<SvedocsThemeComponentMap> = {};
17
+ export let label: string | undefined = undefined;
18
+ export let title: string | undefined = undefined;
19
+ export let message: string | undefined = undefined;
20
+
21
+ $: context = createThemeContext({ config, page, pages, tree, search, ...(loadSearch ? { loadSearch } : {}) });
22
+ $: resolvedLabel = label ?? context.t('render.page.label');
23
+ $: resolvedTitle = title ?? context.t('render.page.title');
24
+ $: resolvedMessage = message ?? context.t('render.page.message');
25
+ </script>
26
+
27
+ <svelte:component
28
+ this={RootLayout}
29
+ {config}
30
+ {page}
31
+ {pages}
32
+ {tree}
33
+ {search}
34
+ {loadSearch}
35
+ {themeComponents}
36
+ mobileTree={tree}
37
+ mobileCurrentPath={page.routePath}
38
+ >
39
+ <main id="content" class="sd-route-render-error" data-theme-component="route-render-error">
40
+ <svelte:component
41
+ this={SafeRenderError} component={themeComponents.RenderError}
42
+ {error}
43
+ {reset}
44
+ {page}
45
+ {context}
46
+ tree={tree}
47
+ variant="layout"
48
+ label={resolvedLabel}
49
+ title={resolvedTitle}
50
+ message={resolvedMessage}
51
+ />
52
+ </main>
53
+ </svelte:component>
@@ -0,0 +1,34 @@
1
+ import type { SvedocsPage, SvedocsResolvedConfig, SvedocsSearchRecord, SvedocsTreeItem } from '../core/types.js';
2
+ import type { SvedocsThemeComponentMap } from './types.js';
3
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
4
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
5
+ $$bindings?: Bindings;
6
+ } & Exports;
7
+ (internal: unknown, props: Props & {
8
+ $$events?: Events;
9
+ $$slots?: Slots;
10
+ }): Exports & {
11
+ $set?: any;
12
+ $on?: any;
13
+ };
14
+ z_$$bindings?: Bindings;
15
+ }
16
+ declare const RouteRenderError: $$__sveltets_2_IsomorphicComponent<{
17
+ error?: unknown;
18
+ reset?: (() => void) | undefined;
19
+ page: SvedocsPage;
20
+ pages?: SvedocsPage[];
21
+ tree?: SvedocsTreeItem[];
22
+ search?: SvedocsSearchRecord[];
23
+ config: SvedocsResolvedConfig;
24
+ loadSearch?: (() => Promise<SvedocsSearchRecord[]>) | undefined;
25
+ themeComponents?: Partial<SvedocsThemeComponentMap>;
26
+ label?: string | undefined;
27
+ title?: string | undefined;
28
+ message?: string | undefined;
29
+ }, {
30
+ [evt: string]: CustomEvent<any>;
31
+ }, {}, {}, string>;
32
+ type RouteRenderError = InstanceType<typeof RouteRenderError>;
33
+ export default RouteRenderError;
34
+ //# sourceMappingURL=RouteRenderError.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteRenderError.svelte.d.ts","sourceRoot":"","sources":["../../src/theme/RouteRenderError.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAIjH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAoC3D,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,gBAAgB;YAV4N,OAAO;YAAU,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;UAAQ,WAAW;YAAU,WAAW,EAAE;WAAS,eAAe,EAAE;aAAW,mBAAmB,EAAE;YAAU,qBAAqB;iBAAe,CAAC,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC,GAAG,SAAS;sBAAoB,OAAO,CAAC,wBAAwB,CAAC;YAAU,MAAM,GAAG,SAAS;YAAU,MAAM,GAAG,SAAS;cAAY,MAAM,GAAG,SAAS;;;kBAUrgB,CAAC;AACpF,KAAK,gBAAgB,GAAG,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAChE,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ import type { Component } from 'svelte';
3
+ import type { SvedocsPage, SvedocsTreeItem } from '../core/types.js';
4
+ import { fallbackTranslate } from './headless.js';
5
+ import RenderError from './RenderError.svelte';
6
+ import type { SvedocsRenderErrorProps, SvedocsThemeContext } from './types.js';
7
+
8
+ export let component: Component<SvedocsRenderErrorProps> | undefined = undefined;
9
+ export let error: unknown = undefined;
10
+ export let reset: (() => void) | undefined = undefined;
11
+ export let title: string | undefined = undefined;
12
+ export let message: string | undefined = undefined;
13
+ export let label: string | undefined = undefined;
14
+ export let variant = 'section';
15
+ export let page: SvedocsPage | undefined = undefined;
16
+ export let context: SvedocsThemeContext | undefined = undefined;
17
+ export let tree: SvedocsTreeItem[] = [];
18
+
19
+ $: ErrorComponent = component ?? RenderError;
20
+ $: t = context?.t ?? fallbackTranslate;
21
+ </script>
22
+
23
+ <svelte:boundary>
24
+ <svelte:component
25
+ this={ErrorComponent}
26
+ {error}
27
+ {reset}
28
+ {title}
29
+ {message}
30
+ {label}
31
+ {variant}
32
+ {page}
33
+ {context}
34
+ {tree}
35
+ />
36
+ {#snippet failed(fallbackError)}
37
+ <RenderError
38
+ error={fallbackError}
39
+ {reset}
40
+ title={t('render.errorUi.title')}
41
+ message={t('render.errorUi.message')}
42
+ label={t('render.errorUi.label')}
43
+ variant="section"
44
+ {page}
45
+ {context}
46
+ {tree}
47
+ />
48
+ {/snippet}
49
+ </svelte:boundary>
@@ -0,0 +1,33 @@
1
+ import type { Component } from 'svelte';
2
+ import type { SvedocsPage, SvedocsTreeItem } from '../core/types.js';
3
+ import type { SvedocsRenderErrorProps, SvedocsThemeContext } from './types.js';
4
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
5
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
6
+ $$bindings?: Bindings;
7
+ } & Exports;
8
+ (internal: unknown, props: Props & {
9
+ $$events?: Events;
10
+ $$slots?: Slots;
11
+ }): Exports & {
12
+ $set?: any;
13
+ $on?: any;
14
+ };
15
+ z_$$bindings?: Bindings;
16
+ }
17
+ declare const SafeRenderError: $$__sveltets_2_IsomorphicComponent<{
18
+ component?: Component<SvedocsRenderErrorProps> | undefined;
19
+ error?: unknown;
20
+ reset?: (() => void) | undefined;
21
+ title?: string | undefined;
22
+ message?: string | undefined;
23
+ label?: string | undefined;
24
+ variant?: string;
25
+ page?: SvedocsPage | undefined;
26
+ context?: SvedocsThemeContext | undefined;
27
+ tree?: SvedocsTreeItem[];
28
+ }, {
29
+ [evt: string]: CustomEvent<any>;
30
+ }, {}, {}, string>;
31
+ type SafeRenderError = InstanceType<typeof SafeRenderError>;
32
+ export default SafeRenderError;
33
+ //# sourceMappingURL=SafeRenderError.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SafeRenderError.svelte.d.ts","sourceRoot":"","sources":["../../src/theme/SafeRenderError.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAgC/E,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,eAAe;gBAViL,SAAS,CAAC,uBAAuB,CAAC,GAAG,SAAS;YAAU,OAAO;YAAU,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;YAAU,MAAM,GAAG,SAAS;cAAY,MAAM,GAAG,SAAS;YAAU,MAAM,GAAG,SAAS;;WAAmC,WAAW,GAAG,SAAS;cAAY,mBAAmB,GAAG,SAAS;WAAS,eAAe,EAAE;;;kBAUxZ,CAAC;AACnF,KAAK,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAe,eAAe,CAAC"}
@@ -0,0 +1,107 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import type { SvedocsLocale, SvedocsPage } from '../core/types.js';
4
+ import { fallbackTranslate } from './headless.js';
5
+ import type { SvedocsThemeContext } from './types.js';
6
+
7
+ export let page: SvedocsPage | undefined = undefined;
8
+ export let pages: SvedocsPage[] = [];
9
+ export let locales: SvedocsLocale[] = [];
10
+ export let context: SvedocsThemeContext | undefined = undefined;
11
+
12
+ let openMenu: 'locale' | undefined;
13
+ let root: HTMLDivElement;
14
+
15
+ $: localeOptions = createScopeOptions(
16
+ locales,
17
+ page?.locale,
18
+ (locale) => locale.code,
19
+ (locale) => locale.label,
20
+ (locale) => findScopedPage({ locale: locale.code })?.routePath
21
+ );
22
+ $: activeLocaleOption = localeOptions.find((option) => option.current);
23
+ $: t = context?.t ?? fallbackTranslate;
24
+ $: activeLocaleLabel = activeLocaleOption?.label ?? t('scope.locale');
25
+ $: activeLocaleShortLabel = activeLocaleOption
26
+ ? createShortLocaleLabel(activeLocaleOption.value, activeLocaleOption.label)
27
+ : t('scope.langShort');
28
+
29
+ function findScopedPage(scope: { locale?: string }): SvedocsPage | undefined {
30
+ if (!page) return undefined;
31
+ return pages.find((candidate) => (
32
+ candidate.scopePath === page.scopePath
33
+ && (scope.locale ? candidate.locale === scope.locale : candidate.locale === page.locale)
34
+ ));
35
+ }
36
+
37
+ function createScopeOptions<T>(
38
+ items: T[],
39
+ current: string | undefined,
40
+ getValue: (item: T) => string,
41
+ getLabel: (item: T) => string,
42
+ getPath: (item: T) => string | undefined
43
+ ) {
44
+ return items.map((item) => ({
45
+ value: getValue(item),
46
+ label: getLabel(item),
47
+ path: getPath(item),
48
+ current: getValue(item) === current
49
+ }));
50
+ }
51
+
52
+ function createShortLocaleLabel(value: string, label: string) {
53
+ const trimmedLabel = label.trim();
54
+ if ([...trimmedLabel].length <= 3) return trimmedLabel;
55
+
56
+ const trimmedValue = value.trim();
57
+ return trimmedValue ? trimmedValue.slice(0, 3).toUpperCase() : trimmedLabel.slice(0, 3);
58
+ }
59
+
60
+ function closeMenu() {
61
+ openMenu = undefined;
62
+ }
63
+
64
+ function toggleMenu(menu: 'locale') {
65
+ openMenu = openMenu === menu ? undefined : menu;
66
+ }
67
+
68
+ onMount(() => {
69
+ function closeOnPointer(event: PointerEvent) {
70
+ if (!root) return;
71
+ if (!root.contains(event.target as Node)) openMenu = undefined;
72
+ }
73
+
74
+ function closeOnEscape(event: KeyboardEvent) {
75
+ if (event.key === 'Escape') openMenu = undefined;
76
+ }
77
+
78
+ document.addEventListener('pointerdown', closeOnPointer);
79
+ document.addEventListener('keydown', closeOnEscape);
80
+ return () => {
81
+ document.removeEventListener('pointerdown', closeOnPointer);
82
+ document.removeEventListener('keydown', closeOnEscape);
83
+ };
84
+ });
85
+ </script>
86
+
87
+ {#if localeOptions.length > 1}
88
+ <div bind:this={root} class="sd-scope-switcher" role="group" aria-label={t('scope.group')}>
89
+ <div class:sd-open={openMenu === 'locale'} class="sd-scope-menu">
90
+ <button type="button" class="sd-scope-trigger" aria-label={t('scope.locale')} aria-haspopup="menu" aria-expanded={openMenu === 'locale'} on:click={() => toggleMenu('locale')}>
91
+ <span class="sd-scope-label-full">{activeLocaleLabel}</span>
92
+ <span aria-hidden="true" class="sd-scope-label-short">{activeLocaleShortLabel}</span>
93
+ </button>
94
+ {#if openMenu === 'locale'}
95
+ <div class="sd-scope-options" role="menu" aria-label={t('scope.localeOptions')}>
96
+ {#each localeOptions as option}
97
+ {#if option.path}
98
+ <a href={option.path} role="menuitemradio" aria-checked={option.current} aria-current={option.current ? 'page' : undefined} on:click={closeMenu}>{option.label}</a>
99
+ {:else}
100
+ <span role="menuitemradio" aria-checked={option.current} aria-disabled="true">{option.label}</span>
101
+ {/if}
102
+ {/each}
103
+ </div>
104
+ {/if}
105
+ </div>
106
+ </div>
107
+ {/if}
@@ -0,0 +1,26 @@
1
+ import type { SvedocsLocale, SvedocsPage } from '../core/types.js';
2
+ import type { SvedocsThemeContext } from './types.js';
3
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
4
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
5
+ $$bindings?: Bindings;
6
+ } & Exports;
7
+ (internal: unknown, props: Props & {
8
+ $$events?: Events;
9
+ $$slots?: Slots;
10
+ }): Exports & {
11
+ $set?: any;
12
+ $on?: any;
13
+ };
14
+ z_$$bindings?: Bindings;
15
+ }
16
+ declare const ScopeSwitcher: $$__sveltets_2_IsomorphicComponent<{
17
+ page?: SvedocsPage | undefined;
18
+ pages?: SvedocsPage[];
19
+ locales?: SvedocsLocale[];
20
+ context?: SvedocsThemeContext | undefined;
21
+ }, {
22
+ [evt: string]: CustomEvent<any>;
23
+ }, {}, {}, string>;
24
+ type ScopeSwitcher = InstanceType<typeof ScopeSwitcher>;
25
+ export default ScopeSwitcher;
26
+ //# sourceMappingURL=ScopeSwitcher.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScopeSwitcher.svelte.d.ts","sourceRoot":"","sources":["../../src/theme/ScopeSwitcher.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAgHtD,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,aAAa;WAV0E,WAAW,GAAG,SAAS;YAAU,WAAW,EAAE;cAAY,aAAa,EAAE;cAAY,mBAAmB,GAAG,SAAS;;;kBAU/G,CAAC;AACjF,KAAK,aAAa,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAe,aAAa,CAAC"}