specra 0.1.13 → 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 (276) hide show
  1. package/LICENSE.MD +25 -4
  2. package/README.md +67 -58
  3. package/config/specra.config.schema.json +16 -0
  4. package/config/svelte-config.js +63 -0
  5. package/dist/api-parser.types.d.ts +59 -0
  6. package/dist/api-parser.types.js +5 -0
  7. package/dist/api.types.d.ts +137 -0
  8. package/dist/api.types.js +5 -0
  9. package/dist/category.d.ts +21 -0
  10. package/dist/category.js +48 -0
  11. package/dist/components/ConfigProvider.svelte +13 -0
  12. package/dist/components/ConfigProvider.svelte.d.ts +31 -0
  13. package/dist/components/docs/Accordion.svelte +18 -0
  14. package/dist/components/docs/Accordion.svelte.d.ts +10 -0
  15. package/dist/components/docs/AccordionItem.svelte +41 -0
  16. package/dist/components/docs/AccordionItem.svelte.d.ts +10 -0
  17. package/dist/components/docs/Badge.svelte +28 -0
  18. package/dist/components/docs/Badge.svelte.d.ts +9 -0
  19. package/dist/components/docs/Breadcrumb.svelte +80 -0
  20. package/dist/components/docs/Breadcrumb.svelte.d.ts +8 -0
  21. package/dist/components/docs/Callout.svelte +96 -0
  22. package/dist/components/docs/Callout.svelte.d.ts +10 -0
  23. package/dist/components/docs/Card.svelte +63 -0
  24. package/dist/components/docs/Card.svelte.d.ts +12 -0
  25. package/dist/components/docs/CardGrid.svelte +24 -0
  26. package/dist/components/docs/CardGrid.svelte.d.ts +8 -0
  27. package/dist/components/docs/CategoryIndex.svelte +110 -0
  28. package/dist/components/docs/CategoryIndex.svelte.d.ts +29 -0
  29. package/dist/components/docs/CodeBlock.svelte +172 -0
  30. package/dist/components/docs/CodeBlock.svelte.d.ts +8 -0
  31. package/dist/components/docs/Column.svelte +25 -0
  32. package/dist/components/docs/Column.svelte.d.ts +8 -0
  33. package/dist/components/docs/Columns.svelte +38 -0
  34. package/dist/components/docs/Columns.svelte.d.ts +13 -0
  35. package/dist/components/docs/DevModeBadge.svelte +15 -0
  36. package/dist/components/docs/DevModeBadge.svelte.d.ts +18 -0
  37. package/dist/components/docs/DocBadge.svelte +28 -0
  38. package/dist/components/docs/DocBadge.svelte.d.ts +9 -0
  39. package/dist/components/docs/DocLayout.svelte +107 -0
  40. package/dist/components/docs/DocLayout.svelte.d.ts +32 -0
  41. package/dist/components/docs/DocLoading.svelte +53 -0
  42. package/dist/components/docs/DocLoading.svelte.d.ts +18 -0
  43. package/dist/components/docs/DocMetadata.svelte +106 -0
  44. package/dist/components/docs/DocMetadata.svelte.d.ts +18 -0
  45. package/dist/components/docs/DocNavigation.svelte +56 -0
  46. package/dist/components/docs/DocNavigation.svelte.d.ts +12 -0
  47. package/dist/components/docs/DocTags.svelte +22 -0
  48. package/dist/components/docs/DocTags.svelte.d.ts +6 -0
  49. package/dist/components/docs/DraftBadge.svelte +10 -0
  50. package/dist/components/docs/DraftBadge.svelte.d.ts +18 -0
  51. package/dist/components/docs/Footer.svelte +72 -0
  52. package/dist/components/docs/Footer.svelte.d.ts +7 -0
  53. package/dist/components/docs/Frame.svelte +27 -0
  54. package/dist/components/docs/Frame.svelte.d.ts +9 -0
  55. package/dist/components/docs/Header.svelte +123 -0
  56. package/dist/components/docs/Header.svelte.d.ts +9 -0
  57. package/dist/components/docs/HeaderWithMenu.svelte +34 -0
  58. package/dist/components/docs/HeaderWithMenu.svelte.d.ts +17 -0
  59. package/dist/components/docs/HotReloadIndicator.svelte +44 -0
  60. package/dist/components/docs/HotReloadIndicator.svelte.d.ts +3 -0
  61. package/dist/components/docs/Icon.svelte +103 -0
  62. package/dist/components/docs/Icon.svelte.d.ts +11 -0
  63. package/dist/components/docs/Image.svelte +88 -0
  64. package/dist/components/docs/Image.svelte.d.ts +11 -0
  65. package/dist/components/docs/ImageCard.svelte +91 -0
  66. package/dist/components/docs/ImageCard.svelte.d.ts +12 -0
  67. package/dist/components/docs/ImageCardGrid.svelte +25 -0
  68. package/dist/components/docs/ImageCardGrid.svelte.d.ts +8 -0
  69. package/dist/components/docs/LayoutProviders.svelte +57 -0
  70. package/dist/components/docs/LayoutProviders.svelte.d.ts +9 -0
  71. package/dist/components/docs/Logo.svelte +25 -0
  72. package/dist/components/docs/Logo.svelte.d.ts +11 -0
  73. package/dist/components/docs/Math.svelte +54 -0
  74. package/dist/components/docs/Math.svelte.d.ts +7 -0
  75. package/dist/components/docs/MdxContent.svelte +41 -0
  76. package/dist/components/docs/MdxHotReload.svelte +78 -0
  77. package/dist/components/docs/MdxHotReload.svelte.d.ts +9 -0
  78. package/dist/components/docs/MdxLayout.svelte +16 -0
  79. package/dist/components/docs/MdxLayout.svelte.d.ts +6 -0
  80. package/dist/components/docs/Mermaid.svelte +88 -0
  81. package/dist/components/docs/Mermaid.svelte.d.ts +7 -0
  82. package/dist/components/docs/MobileDocLayout.svelte +211 -0
  83. package/dist/components/docs/MobileDocLayout.svelte.d.ts +35 -0
  84. package/dist/components/docs/MobileSidebar.svelte +122 -0
  85. package/dist/components/docs/MobileSidebar.svelte.d.ts +31 -0
  86. package/dist/components/docs/MobileSidebarWrapper.svelte +122 -0
  87. package/dist/components/docs/MobileSidebarWrapper.svelte.d.ts +32 -0
  88. package/dist/components/docs/NotFoundContent.svelte +40 -0
  89. package/dist/components/docs/NotFoundContent.svelte.d.ts +6 -0
  90. package/dist/components/docs/SearchHighlight.svelte +116 -0
  91. package/dist/components/docs/SearchHighlight.svelte.d.ts +3 -0
  92. package/dist/components/docs/SearchModal.svelte +239 -0
  93. package/dist/components/docs/SearchModal.svelte.d.ts +9 -0
  94. package/dist/components/docs/Sidebar.svelte +69 -0
  95. package/dist/components/docs/Sidebar.svelte.d.ts +31 -0
  96. package/dist/components/docs/SidebarMenuItems.svelte +344 -0
  97. package/dist/components/docs/SidebarMenuItems.svelte.d.ts +33 -0
  98. package/dist/components/docs/SidebarSkeleton.svelte +50 -0
  99. package/dist/components/docs/SidebarSkeleton.svelte.d.ts +18 -0
  100. package/dist/components/docs/SiteBanner.svelte +92 -0
  101. package/dist/components/docs/SiteBanner.svelte.d.ts +7 -0
  102. package/dist/components/docs/Step.svelte +44 -0
  103. package/dist/components/docs/Step.svelte.d.ts +8 -0
  104. package/dist/components/docs/Steps.svelte +15 -0
  105. package/dist/components/docs/Steps.svelte.d.ts +7 -0
  106. package/dist/components/docs/Tab.svelte +40 -0
  107. package/dist/components/docs/Tab.svelte.d.ts +8 -0
  108. package/dist/components/docs/TabGroups.svelte +183 -0
  109. package/dist/components/docs/TabGroups.svelte.d.ts +25 -0
  110. package/dist/components/docs/TableOfContents.svelte +100 -0
  111. package/dist/components/docs/TableOfContents.svelte.d.ts +9 -0
  112. package/dist/components/docs/Tabs.svelte +69 -0
  113. package/dist/components/docs/Tabs.svelte.d.ts +8 -0
  114. package/dist/components/docs/ThemeToggle.svelte +16 -0
  115. package/dist/components/docs/ThemeToggle.svelte.d.ts +18 -0
  116. package/dist/components/docs/Tooltip.svelte +44 -0
  117. package/dist/components/docs/Tooltip.svelte.d.ts +10 -0
  118. package/dist/components/docs/VersionSwitcher.svelte +95 -0
  119. package/dist/components/docs/VersionSwitcher.svelte.d.ts +7 -0
  120. package/dist/components/docs/Video.svelte +84 -0
  121. package/dist/components/docs/Video.svelte.d.ts +12 -0
  122. package/dist/components/docs/api/ApiEndpoint.svelte +61 -0
  123. package/dist/components/docs/api/ApiEndpoint.svelte.d.ts +11 -0
  124. package/dist/components/docs/api/ApiParams.svelte +80 -0
  125. package/dist/components/docs/api/ApiParams.svelte.d.ts +14 -0
  126. package/dist/components/docs/api/ApiPlayground.svelte +259 -0
  127. package/dist/components/docs/api/ApiPlayground.svelte.d.ts +16 -0
  128. package/dist/components/docs/api/ApiReference.svelte +278 -0
  129. package/dist/components/docs/api/ApiReference.svelte.d.ts +23 -0
  130. package/dist/components/docs/api/ApiResponse.svelte +66 -0
  131. package/dist/components/docs/api/ApiResponse.svelte.d.ts +9 -0
  132. package/dist/components/docs/api/index.d.ts +5 -0
  133. package/dist/components/docs/api/index.js +5 -0
  134. package/dist/components/docs/componentTextProps.d.ts +3 -0
  135. package/dist/components/docs/componentTextProps.js +61 -0
  136. package/dist/components/docs/index.d.ts +54 -0
  137. package/dist/components/docs/index.js +56 -0
  138. package/dist/components/global/VersionNotFound.svelte +48 -0
  139. package/dist/components/global/VersionNotFound.svelte.d.ts +7 -0
  140. package/dist/components/global/index.d.ts +1 -0
  141. package/dist/components/global/index.js +1 -0
  142. package/dist/components/index.d.ts +6 -822
  143. package/dist/components/index.js +11 -3854
  144. package/dist/components/ui/Badge.svelte +48 -0
  145. package/dist/components/ui/Badge.svelte.d.ts +15 -0
  146. package/dist/components/ui/Button.svelte +58 -0
  147. package/dist/components/ui/Button.svelte.d.ts +17 -0
  148. package/dist/components/ui/Dialog.svelte +16 -0
  149. package/dist/components/ui/Dialog.svelte.d.ts +9 -0
  150. package/dist/components/ui/DialogClose.svelte +16 -0
  151. package/dist/components/ui/DialogClose.svelte.d.ts +9 -0
  152. package/dist/components/ui/DialogContent.svelte +43 -0
  153. package/dist/components/ui/DialogContent.svelte.d.ts +10 -0
  154. package/dist/components/ui/DialogDescription.svelte +21 -0
  155. package/dist/components/ui/DialogDescription.svelte.d.ts +9 -0
  156. package/dist/components/ui/DialogFooter.svelte +20 -0
  157. package/dist/components/ui/DialogFooter.svelte.d.ts +9 -0
  158. package/dist/components/ui/DialogHeader.svelte +20 -0
  159. package/dist/components/ui/DialogHeader.svelte.d.ts +9 -0
  160. package/dist/components/ui/DialogTitle.svelte +21 -0
  161. package/dist/components/ui/DialogTitle.svelte.d.ts +9 -0
  162. package/dist/components/ui/Input.svelte +23 -0
  163. package/dist/components/ui/Input.svelte.d.ts +8 -0
  164. package/dist/components/ui/Textarea.svelte +19 -0
  165. package/dist/components/ui/Textarea.svelte.d.ts +7 -0
  166. package/dist/components/ui/index.d.ts +11 -0
  167. package/dist/components/ui/index.js +11 -0
  168. package/dist/config.d.ts +8 -0
  169. package/dist/config.js +9 -0
  170. package/dist/config.schema.json +471 -0
  171. package/dist/config.server.d.ts +46 -0
  172. package/dist/config.server.js +149 -0
  173. package/dist/{mdx-ColN3Cyg.d.mts → config.types.d.ts} +22 -75
  174. package/dist/config.types.js +39 -0
  175. package/dist/dev-utils.d.ts +29 -0
  176. package/dist/dev-utils.js +63 -0
  177. package/dist/index.d.ts +19 -4
  178. package/dist/index.js +25 -4861
  179. package/dist/mdx-cache.d.ts +41 -0
  180. package/dist/mdx-cache.js +160 -0
  181. package/dist/mdx-components.js +50 -1931
  182. package/dist/mdx-security.d.ts +76 -0
  183. package/dist/mdx-security.js +217 -0
  184. package/dist/mdx.d.ts +73 -0
  185. package/dist/mdx.js +1099 -0
  186. package/dist/middleware/index.d.ts +1 -0
  187. package/dist/middleware/index.js +2 -0
  188. package/dist/middleware/security.d.ts +22 -47
  189. package/dist/middleware/security.js +111 -137
  190. package/dist/parsers/base-parser.d.ts +14 -0
  191. package/dist/parsers/base-parser.js +1 -0
  192. package/dist/parsers/index.d.ts +16 -0
  193. package/dist/parsers/index.js +51 -0
  194. package/dist/parsers/openapi-parser.d.ts +18 -0
  195. package/dist/parsers/openapi-parser.js +209 -0
  196. package/dist/parsers/postman-parser.d.ts +20 -0
  197. package/dist/parsers/postman-parser.js +260 -0
  198. package/dist/parsers/specra-parser.d.ts +10 -0
  199. package/dist/parsers/specra-parser.js +18 -0
  200. package/dist/redirects.d.ts +12 -0
  201. package/dist/redirects.js +30 -0
  202. package/dist/remark-code-meta.d.ts +6 -0
  203. package/dist/remark-code-meta.js +21 -0
  204. package/dist/sidebar-utils.d.ts +59 -0
  205. package/dist/sidebar-utils.js +144 -0
  206. package/dist/stores/config.d.ts +20 -0
  207. package/dist/stores/config.js +45 -0
  208. package/dist/stores/index.d.ts +4 -0
  209. package/dist/stores/index.js +4 -0
  210. package/dist/stores/sidebar.d.ts +7 -0
  211. package/dist/stores/sidebar.js +12 -0
  212. package/dist/stores/tabs.d.ts +6 -0
  213. package/dist/stores/tabs.js +41 -0
  214. package/dist/stores/theme.d.ts +7 -0
  215. package/dist/stores/theme.js +75 -0
  216. package/dist/{styles.css → styles/globals.css} +136 -6
  217. package/dist/toc.d.ts +9 -0
  218. package/dist/toc.js +15 -0
  219. package/dist/utils.d.ts +13 -0
  220. package/dist/utils.js +30 -0
  221. package/package.json +47 -90
  222. package/dist/app/api/mdx-watch/route.d.mts +0 -10
  223. package/dist/app/api/mdx-watch/route.d.ts +0 -10
  224. package/dist/app/api/mdx-watch/route.js +0 -118
  225. package/dist/app/api/mdx-watch/route.js.map +0 -1
  226. package/dist/app/api/mdx-watch/route.mjs +0 -91
  227. package/dist/app/api/mdx-watch/route.mjs.map +0 -1
  228. package/dist/chunk-6S3EJVEO.mjs +0 -259
  229. package/dist/chunk-6S3EJVEO.mjs.map +0 -1
  230. package/dist/chunk-BE7EROIW.mjs +0 -212
  231. package/dist/chunk-BE7EROIW.mjs.map +0 -1
  232. package/dist/chunk-CWHRZHZO.mjs +0 -168
  233. package/dist/chunk-CWHRZHZO.mjs.map +0 -1
  234. package/dist/chunk-D5VDVYFY.mjs +0 -1325
  235. package/dist/chunk-D5VDVYFY.mjs.map +0 -1
  236. package/dist/chunk-WMCO2UX5.mjs +0 -585
  237. package/dist/chunk-WMCO2UX5.mjs.map +0 -1
  238. package/dist/chunk-XEMGCPZZ.mjs +0 -475
  239. package/dist/chunk-XEMGCPZZ.mjs.map +0 -1
  240. package/dist/components/index.d.mts +0 -822
  241. package/dist/components/index.js.map +0 -1
  242. package/dist/components/index.mjs +0 -3741
  243. package/dist/components/index.mjs.map +0 -1
  244. package/dist/index.d.mts +0 -4
  245. package/dist/index.js.map +0 -1
  246. package/dist/index.mjs +0 -1897
  247. package/dist/index.mjs.map +0 -1
  248. package/dist/layouts/index.d.mts +0 -34
  249. package/dist/layouts/index.d.ts +0 -34
  250. package/dist/layouts/index.js +0 -453
  251. package/dist/layouts/index.js.map +0 -1
  252. package/dist/layouts/index.mjs +0 -173
  253. package/dist/layouts/index.mjs.map +0 -1
  254. package/dist/lib/index.d.mts +0 -583
  255. package/dist/lib/index.d.ts +0 -583
  256. package/dist/lib/index.js +0 -1595
  257. package/dist/lib/index.js.map +0 -1
  258. package/dist/lib/index.mjs +0 -111
  259. package/dist/lib/index.mjs.map +0 -1
  260. package/dist/mdx-ColN3Cyg.d.ts +0 -352
  261. package/dist/mdx-components.d.mts +0 -86
  262. package/dist/mdx-components.d.ts +0 -86
  263. package/dist/mdx-components.js.map +0 -1
  264. package/dist/mdx-components.mjs +0 -206
  265. package/dist/mdx-components.mjs.map +0 -1
  266. package/dist/middleware/security.d.mts +0 -82
  267. package/dist/middleware/security.js.map +0 -1
  268. package/dist/middleware/security.mjs +0 -84
  269. package/dist/middleware/security.mjs.map +0 -1
  270. package/dist/styles.css.map +0 -1
  271. package/dist/styles.d.mts +0 -2
  272. package/dist/styles.d.ts +0 -2
  273. package/dist/styles.js +0 -2
  274. package/dist/styles.js.map +0 -1
  275. package/dist/styles.mjs +0 -1
  276. package/dist/styles.mjs.map +0 -1
@@ -0,0 +1,211 @@
1
+ <script lang="ts">
2
+ import { sidebarStore } from '../../stores/sidebar.js';
3
+ import Footer from './Footer.svelte';
4
+ import SiteBanner from './SiteBanner.svelte';
5
+ import TabGroups from './TabGroups.svelte';
6
+ import Sidebar from './Sidebar.svelte';
7
+ import SidebarMenuItems from './SidebarMenuItems.svelte';
8
+ import Logo from './Logo.svelte';
9
+ import type { SpecraConfig } from '../../config.types.js';
10
+ import type { Snippet } from 'svelte';
11
+
12
+ interface DocItem {
13
+ title: string;
14
+ slug: string;
15
+ filePath: string;
16
+ section?: string;
17
+ group?: string;
18
+ sidebar?: string;
19
+ sidebar_position?: number;
20
+ categoryLabel?: string;
21
+ categoryPosition?: number;
22
+ categoryCollapsible?: boolean;
23
+ categoryCollapsed?: boolean;
24
+ categoryIcon?: string;
25
+ categoryTabGroup?: string;
26
+ meta?: {
27
+ icon?: string;
28
+ tab_group?: string;
29
+ [key: string]: any;
30
+ };
31
+ }
32
+
33
+ interface Props {
34
+ docs: DocItem[];
35
+ version: string;
36
+ config: SpecraConfig;
37
+ activeTabGroup?: string;
38
+ onTabChange?: (tabId: string) => void;
39
+ header: Snippet;
40
+ toc?: Snippet;
41
+ children: Snippet;
42
+ }
43
+
44
+ let { docs, version, config, activeTabGroup, onTabChange, header, toc, children }: Props = $props();
45
+
46
+ let sidebarOpen = $derived($sidebarStore);
47
+ let isFlush = $derived(config.navigation?.sidebarStyle === 'flush');
48
+
49
+ function handleTabChange(tabId: string) {
50
+ onTabChange?.(tabId);
51
+ }
52
+
53
+ function closeSidebar() {
54
+ sidebarStore.close();
55
+ }
56
+ </script>
57
+
58
+ <div class="min-h-screen bg-background">
59
+ <!-- Header -->
60
+ {@render header()}
61
+
62
+ <!-- Site-wide Banner -->
63
+ <SiteBanner {config} />
64
+
65
+ <!-- Tab Groups - shown only if configured -->
66
+ {#if config.navigation?.tabGroups && config.navigation.tabGroups.length > 0}
67
+ <TabGroups
68
+ tabGroups={config.navigation.tabGroups}
69
+ activeTabId={activeTabGroup}
70
+ onTabChange={handleTabChange}
71
+ flush={isFlush}
72
+ {docs}
73
+ {version}
74
+ />
75
+ {/if}
76
+
77
+ <!-- Mobile Sidebar Overlay -->
78
+ {#if sidebarOpen}
79
+ <div
80
+ class="lg:hidden fixed inset-0 bg-background/80 backdrop-blur-sm z-40"
81
+ onclick={() => sidebarStore.close()}
82
+ onkeydown={(e) => { if (e.key === 'Escape') sidebarStore.close(); }}
83
+ role="button"
84
+ tabindex="-1"
85
+ aria-label="Close sidebar"
86
+ ></div>
87
+ {/if}
88
+
89
+ <!-- Mobile Sidebar -->
90
+ <div
91
+ class="lg:hidden fixed top-0 left-0 h-full w-72 bg-background border-r border-border z-50 transform transition-transform duration-300 ease-in-out {sidebarOpen ? 'translate-x-0' : '-translate-x-full'}"
92
+ >
93
+ <div class="flex flex-col h-full">
94
+ <!-- Logo and Site Title Header -->
95
+ <div class="shrink-0 px-4 py-4 border-b border-border">
96
+ <a href="/" class="flex items-center gap-2 group justify-center">
97
+ {#if !config.site?.hideLogo}
98
+ <Logo
99
+ logo={config.site?.logo}
100
+ alt={config.site?.title || 'Logo'}
101
+ className="w-18 object-contain"
102
+ />
103
+ {/if}
104
+ <div class="flex flex-col">
105
+ <span class="font-semibold text-foreground group-hover:text-primary transition-colors">
106
+ {config.site?.title || 'Documentation'}
107
+ </span>
108
+ {#if config.site?.description}
109
+ <span class="text-xs text-muted-foreground line-clamp-1">
110
+ {config.site.description}
111
+ </span>
112
+ {/if}
113
+ </div>
114
+ </a>
115
+ </div>
116
+
117
+ <!-- Documentation Label -->
118
+ <div class="shrink-0 px-4 pt-4 pb-2">
119
+ <h2 class="text-xs font-semibold text-muted-foreground uppercase tracking-wider px-2">Documentation</h2>
120
+ </div>
121
+
122
+ <!-- Tab Groups Dropdown - Mobile Only -->
123
+ {#if config.navigation?.tabGroups && config.navigation.tabGroups.length > 0}
124
+ <div class="shrink-0 px-4 py-3 border-b border-border">
125
+ <TabGroups
126
+ tabGroups={config.navigation.tabGroups}
127
+ activeTabId={activeTabGroup}
128
+ onTabChange={handleTabChange}
129
+ mobileOnly={true}
130
+ {docs}
131
+ {version}
132
+ />
133
+ </div>
134
+ {/if}
135
+
136
+ <!-- Sidebar Menu Items -->
137
+ <div class="flex-1 overflow-y-auto px-4 py-4">
138
+ <SidebarMenuItems
139
+ {docs}
140
+ {version}
141
+ {config}
142
+ onLinkClick={closeSidebar}
143
+ {activeTabGroup}
144
+ />
145
+ </div>
146
+ </div>
147
+ </div>
148
+
149
+ <!-- Main Content -->
150
+ {#if isFlush}
151
+ <div class="flex">
152
+ <!-- Desktop Sidebar - flush to left edge -->
153
+ <div class="hidden lg:block">
154
+ <Sidebar
155
+ {docs}
156
+ {version}
157
+ {config}
158
+ {activeTabGroup}
159
+ />
160
+ </div>
161
+
162
+ <main class="flex-1 min-w-0 px-2 md:px-6 py-8">
163
+ <div class="flex">
164
+ <div class="flex-1 min-w-0">
165
+ <div class="flex flex-col gap-2 px-2 md:px-8">
166
+ <!-- Content -->
167
+ {@render children()}
168
+
169
+ <!-- Footer -->
170
+ <Footer {config} />
171
+ </div>
172
+ </div>
173
+
174
+ <!-- ToC -->
175
+ {#if toc}
176
+ {@render toc()}
177
+ {/if}
178
+ </div>
179
+ </main>
180
+ </div>
181
+ {:else}
182
+ <main class="container mx-auto px-2 md:px-6 py-8">
183
+ <div class="flex">
184
+ <!-- Desktop Sidebar - inside container -->
185
+ <div class="hidden lg:block">
186
+ <Sidebar
187
+ {docs}
188
+ {version}
189
+ {config}
190
+ {activeTabGroup}
191
+ />
192
+ </div>
193
+
194
+ <div class="flex-1 min-w-0">
195
+ <div class="flex flex-col gap-2 px-2 md:px-8">
196
+ <!-- Content -->
197
+ {@render children()}
198
+
199
+ <!-- Footer -->
200
+ <Footer {config} />
201
+ </div>
202
+ </div>
203
+
204
+ <!-- ToC -->
205
+ {#if toc}
206
+ {@render toc()}
207
+ {/if}
208
+ </div>
209
+ </main>
210
+ {/if}
211
+ </div>
@@ -0,0 +1,35 @@
1
+ import type { SpecraConfig } from '../../config.types.js';
2
+ import type { Snippet } from 'svelte';
3
+ interface DocItem {
4
+ title: string;
5
+ slug: string;
6
+ filePath: string;
7
+ section?: string;
8
+ group?: string;
9
+ sidebar?: string;
10
+ sidebar_position?: number;
11
+ categoryLabel?: string;
12
+ categoryPosition?: number;
13
+ categoryCollapsible?: boolean;
14
+ categoryCollapsed?: boolean;
15
+ categoryIcon?: string;
16
+ categoryTabGroup?: string;
17
+ meta?: {
18
+ icon?: string;
19
+ tab_group?: string;
20
+ [key: string]: any;
21
+ };
22
+ }
23
+ interface Props {
24
+ docs: DocItem[];
25
+ version: string;
26
+ config: SpecraConfig;
27
+ activeTabGroup?: string;
28
+ onTabChange?: (tabId: string) => void;
29
+ header: Snippet;
30
+ toc?: Snippet;
31
+ children: Snippet;
32
+ }
33
+ declare const MobileDocLayout: import("svelte").Component<Props, {}, "">;
34
+ type MobileDocLayout = ReturnType<typeof MobileDocLayout>;
35
+ export default MobileDocLayout;
@@ -0,0 +1,122 @@
1
+ <script lang="ts">
2
+ import { sidebarStore } from '../../stores/sidebar.js';
3
+ import TabGroups from './TabGroups.svelte';
4
+ import SidebarMenuItems from './SidebarMenuItems.svelte';
5
+ import Logo from './Logo.svelte';
6
+ import type { SpecraConfig } from '../../config.types.js';
7
+
8
+ interface DocItem {
9
+ title: string;
10
+ slug: string;
11
+ filePath: string;
12
+ section?: string;
13
+ group?: string;
14
+ sidebar?: string;
15
+ sidebar_position?: number;
16
+ categoryLabel?: string;
17
+ categoryPosition?: number;
18
+ categoryCollapsible?: boolean;
19
+ categoryCollapsed?: boolean;
20
+ categoryIcon?: string;
21
+ categoryTabGroup?: string;
22
+ meta?: {
23
+ icon?: string;
24
+ tab_group?: string;
25
+ [key: string]: any;
26
+ };
27
+ }
28
+
29
+ interface Props {
30
+ docs: DocItem[];
31
+ version: string;
32
+ config: SpecraConfig;
33
+ activeTabGroup?: string;
34
+ onTabChange?: (tabId: string) => void;
35
+ }
36
+
37
+ let { docs, version, config, activeTabGroup, onTabChange }: Props = $props();
38
+
39
+ let isOpen = $derived($sidebarStore);
40
+
41
+ function handleTabChange(tabId: string) {
42
+ onTabChange?.(tabId);
43
+ }
44
+
45
+ function handleClose() {
46
+ sidebarStore.close();
47
+ }
48
+ </script>
49
+
50
+ <!-- Mobile Sidebar Overlay -->
51
+ {#if isOpen}
52
+ <div
53
+ class="lg:hidden fixed inset-0 bg-background/80 backdrop-blur-sm z-40"
54
+ onclick={handleClose}
55
+ onkeydown={(e) => { if (e.key === 'Escape') handleClose(); }}
56
+ role="button"
57
+ tabindex="-1"
58
+ aria-label="Close sidebar"
59
+ ></div>
60
+ {/if}
61
+
62
+ <!-- Mobile Sidebar -->
63
+ <div
64
+ class="lg:hidden fixed top-0 left-0 h-full w-72 bg-background border-r border-border z-50 transform transition-transform duration-300 ease-in-out {isOpen ? 'translate-x-0' : '-translate-x-full'}"
65
+ >
66
+ <div class="flex flex-col h-full">
67
+ <!-- Logo and Site Title Header -->
68
+ <div class="shrink-0 px-4 py-4 border-b border-border">
69
+ <a href="/" class="flex items-center gap-2 group justify-center">
70
+ {#if !config.site?.hideLogo}
71
+ <Logo
72
+ logo={config.site?.logo}
73
+ alt={config.site?.title || 'Logo'}
74
+ className="w-18 object-contain"
75
+ />
76
+ {/if}
77
+ <div class="flex flex-col">
78
+ <span class="font-semibold text-foreground group-hover:text-primary transition-colors">
79
+ {config.site?.title || 'Documentation'}
80
+ </span>
81
+ {#if config.site?.description}
82
+ <span class="text-xs text-muted-foreground line-clamp-1">
83
+ {config.site.description}
84
+ </span>
85
+ {/if}
86
+ </div>
87
+ </a>
88
+ </div>
89
+
90
+ <!-- Documentation Label -->
91
+ <div class="shrink-0 px-4 pt-4 pb-2">
92
+ <h2 class="text-xs font-semibold text-muted-foreground uppercase tracking-wider px-2">
93
+ Documentation
94
+ </h2>
95
+ </div>
96
+
97
+ <!-- Tab Groups Dropdown - Mobile Only -->
98
+ {#if config.navigation?.tabGroups && config.navigation.tabGroups.length > 0}
99
+ <div class="shrink-0 px-4 py-3 border-b border-border">
100
+ <TabGroups
101
+ tabGroups={config.navigation.tabGroups}
102
+ activeTabId={activeTabGroup || ''}
103
+ onTabChange={handleTabChange}
104
+ mobileOnly={true}
105
+ {docs}
106
+ {version}
107
+ />
108
+ </div>
109
+ {/if}
110
+
111
+ <!-- Sidebar Menu Items -->
112
+ <div class="flex-1 overflow-y-auto px-4 py-4">
113
+ <SidebarMenuItems
114
+ {docs}
115
+ {version}
116
+ {config}
117
+ onLinkClick={handleClose}
118
+ {activeTabGroup}
119
+ />
120
+ </div>
121
+ </div>
122
+ </div>
@@ -0,0 +1,31 @@
1
+ import type { SpecraConfig } from '../../config.types.js';
2
+ interface DocItem {
3
+ title: string;
4
+ slug: string;
5
+ filePath: string;
6
+ section?: string;
7
+ group?: string;
8
+ sidebar?: string;
9
+ sidebar_position?: number;
10
+ categoryLabel?: string;
11
+ categoryPosition?: number;
12
+ categoryCollapsible?: boolean;
13
+ categoryCollapsed?: boolean;
14
+ categoryIcon?: string;
15
+ categoryTabGroup?: string;
16
+ meta?: {
17
+ icon?: string;
18
+ tab_group?: string;
19
+ [key: string]: any;
20
+ };
21
+ }
22
+ interface Props {
23
+ docs: DocItem[];
24
+ version: string;
25
+ config: SpecraConfig;
26
+ activeTabGroup?: string;
27
+ onTabChange?: (tabId: string) => void;
28
+ }
29
+ declare const MobileSidebar: import("svelte").Component<Props, {}, "">;
30
+ type MobileSidebar = ReturnType<typeof MobileSidebar>;
31
+ export default MobileSidebar;
@@ -0,0 +1,122 @@
1
+ <script lang="ts">
2
+ import { sidebarStore } from '../../stores/sidebar.js';
3
+ import TabGroups from './TabGroups.svelte';
4
+ import SidebarMenuItems from './SidebarMenuItems.svelte';
5
+ import Logo from './Logo.svelte';
6
+ import type { SpecraConfig } from '../../config.types.js';
7
+ import type { Snippet } from 'svelte';
8
+
9
+ interface DocItem {
10
+ title: string;
11
+ slug: string;
12
+ filePath: string;
13
+ section?: string;
14
+ group?: string;
15
+ sidebar?: string;
16
+ sidebar_position?: number;
17
+ categoryLabel?: string;
18
+ categoryPosition?: number;
19
+ categoryCollapsible?: boolean;
20
+ categoryCollapsed?: boolean;
21
+ categoryIcon?: string;
22
+ categoryTabGroup?: string;
23
+ meta?: {
24
+ icon?: string;
25
+ tab_group?: string;
26
+ [key: string]: any;
27
+ };
28
+ }
29
+
30
+ interface Props {
31
+ header: Snippet;
32
+ docs: DocItem[];
33
+ version: string;
34
+ config: SpecraConfig;
35
+ activeTabGroup?: string;
36
+ }
37
+
38
+ let { header, docs, version, config, activeTabGroup }: Props = $props();
39
+
40
+ let sidebarOpen = $derived($sidebarStore);
41
+
42
+ function closeSidebar() {
43
+ sidebarStore.close();
44
+ }
45
+ </script>
46
+
47
+ <!-- Render header (the Header component reads sidebar store directly for menu toggle) -->
48
+ {@render header()}
49
+
50
+ <!-- Mobile Sidebar Overlay -->
51
+ {#if sidebarOpen}
52
+ <div
53
+ class="lg:hidden fixed inset-0 bg-background/80 backdrop-blur-sm z-40"
54
+ onclick={closeSidebar}
55
+ onkeydown={(e) => { if (e.key === 'Escape') closeSidebar(); }}
56
+ role="button"
57
+ tabindex="-1"
58
+ aria-label="Close sidebar"
59
+ ></div>
60
+ {/if}
61
+
62
+ <!-- Mobile Sidebar -->
63
+ <div
64
+ class="lg:hidden fixed top-0 left-0 h-full w-72 bg-background border-r border-border z-50 transform transition-transform duration-300 ease-in-out {sidebarOpen ? 'translate-x-0' : '-translate-x-full'}"
65
+ >
66
+ <div class="flex flex-col h-full">
67
+ <!-- Logo and Site Title Header -->
68
+ <div class="shrink-0 px-4 py-4 border-b border-border">
69
+ <a href="/" class="flex items-center gap-2 group justify-center">
70
+ {#if !config.site?.hideLogo}
71
+ <Logo
72
+ logo={config.site?.logo}
73
+ alt={config.site?.title || 'Logo'}
74
+ className="w-18 object-contain"
75
+ />
76
+ {/if}
77
+ <div class="flex flex-col">
78
+ <span class="font-semibold text-foreground group-hover:text-primary transition-colors">
79
+ {config.site?.title || 'Documentation'}
80
+ </span>
81
+ {#if config.site?.description}
82
+ <span class="text-xs text-muted-foreground line-clamp-1">
83
+ {config.site.description}
84
+ </span>
85
+ {/if}
86
+ </div>
87
+ </a>
88
+ </div>
89
+
90
+ <!-- Documentation Label -->
91
+ <div class="shrink-0 px-4 pt-4 pb-2">
92
+ <h2 class="text-xs font-semibold text-muted-foreground uppercase tracking-wider px-2">
93
+ Documentation
94
+ </h2>
95
+ </div>
96
+
97
+ <!-- Tab Groups Dropdown - Mobile Only -->
98
+ {#if config.navigation?.tabGroups && config.navigation.tabGroups.length > 0}
99
+ <div class="shrink-0 px-4 py-3 border-b border-border">
100
+ <TabGroups
101
+ tabGroups={config.navigation.tabGroups}
102
+ activeTabId={activeTabGroup || ''}
103
+ onTabChange={() => {}}
104
+ mobileOnly={true}
105
+ {docs}
106
+ {version}
107
+ />
108
+ </div>
109
+ {/if}
110
+
111
+ <!-- Sidebar Menu Items -->
112
+ <div class="flex-1 overflow-y-auto px-4 py-4">
113
+ <SidebarMenuItems
114
+ {docs}
115
+ {version}
116
+ {config}
117
+ onLinkClick={closeSidebar}
118
+ {activeTabGroup}
119
+ />
120
+ </div>
121
+ </div>
122
+ </div>
@@ -0,0 +1,32 @@
1
+ import type { SpecraConfig } from '../../config.types.js';
2
+ import type { Snippet } from 'svelte';
3
+ interface DocItem {
4
+ title: string;
5
+ slug: string;
6
+ filePath: string;
7
+ section?: string;
8
+ group?: string;
9
+ sidebar?: string;
10
+ sidebar_position?: number;
11
+ categoryLabel?: string;
12
+ categoryPosition?: number;
13
+ categoryCollapsible?: boolean;
14
+ categoryCollapsed?: boolean;
15
+ categoryIcon?: string;
16
+ categoryTabGroup?: string;
17
+ meta?: {
18
+ icon?: string;
19
+ tab_group?: string;
20
+ [key: string]: any;
21
+ };
22
+ }
23
+ interface Props {
24
+ header: Snippet;
25
+ docs: DocItem[];
26
+ version: string;
27
+ config: SpecraConfig;
28
+ activeTabGroup?: string;
29
+ }
30
+ declare const MobileSidebarWrapper: import("svelte").Component<Props, {}, "">;
31
+ type MobileSidebarWrapper = ReturnType<typeof MobileSidebarWrapper>;
32
+ export default MobileSidebarWrapper;
@@ -0,0 +1,40 @@
1
+ <script lang="ts">
2
+ import { FileQuestion, Home, ArrowLeft } from 'lucide-svelte';
3
+
4
+ interface Props {
5
+ version?: string;
6
+ }
7
+
8
+ let { version = '' }: Props = $props();
9
+
10
+ const homeLink = $derived(version ? `/${version}` : '/');
11
+ </script>
12
+
13
+ <div class="flex flex-col items-center justify-center min-h-[60vh] text-center px-4">
14
+ <div class="flex items-center justify-center w-20 h-20 rounded-full bg-muted mb-6">
15
+ <FileQuestion class="h-10 w-10 text-muted-foreground" />
16
+ </div>
17
+
18
+ <h1 class="text-4xl font-bold text-foreground mb-2">404</h1>
19
+ <h2 class="text-xl font-semibold text-foreground mb-4">Page Not Found</h2>
20
+ <p class="text-muted-foreground max-w-md mb-8">
21
+ The page you are looking for does not exist or has been moved. Check the URL or navigate back to the documentation.
22
+ </p>
23
+
24
+ <div class="flex items-center gap-3">
25
+ <a
26
+ href={homeLink}
27
+ class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors"
28
+ >
29
+ <Home class="h-4 w-4" />
30
+ <span>Go to Docs Home</span>
31
+ </a>
32
+ <button
33
+ onclick={() => history.back()}
34
+ class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md border border-border bg-background hover:bg-accent transition-colors text-foreground"
35
+ >
36
+ <ArrowLeft class="h-4 w-4" />
37
+ <span>Go Back</span>
38
+ </button>
39
+ </div>
40
+ </div>
@@ -0,0 +1,6 @@
1
+ interface Props {
2
+ version?: string;
3
+ }
4
+ declare const NotFoundContent: import("svelte").Component<Props, {}, "">;
5
+ type NotFoundContent = ReturnType<typeof NotFoundContent>;
6
+ export default NotFoundContent;