boltdocs 1.0.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 (137) hide show
  1. package/dist/CodeBlock-37XMKCYY.mjs +7 -0
  2. package/dist/PackageManagerTabs-4NWXLXQO.mjs +314 -0
  3. package/dist/Playground-OE2OE6B6.mjs +7 -0
  4. package/dist/SearchDialog-FTOQZ763.mjs +187 -0
  5. package/dist/SearchDialog-ZAZXYIFX.css +2147 -0
  6. package/dist/Video-I6QY4X7J.mjs +7 -0
  7. package/dist/chunk-2YRDWM6O.mjs +56 -0
  8. package/dist/chunk-PN4GCTYG.mjs +67 -0
  9. package/dist/chunk-X2TDGMTR.mjs +64 -0
  10. package/dist/chunk-X6BYQHVC.mjs +12 -0
  11. package/dist/chunk-Z7JHYNAS.mjs +57 -0
  12. package/dist/chunk-ZFCOLEXN.mjs +1644 -0
  13. package/dist/client/index.css +2147 -0
  14. package/dist/client/index.d.mts +298 -0
  15. package/dist/client/index.d.ts +298 -0
  16. package/dist/client/index.js +2793 -0
  17. package/dist/client/index.mjs +63 -0
  18. package/dist/client/ssr.css +2147 -0
  19. package/dist/client/ssr.d.mts +25 -0
  20. package/dist/client/ssr.d.ts +25 -0
  21. package/dist/client/ssr.js +2727 -0
  22. package/dist/client/ssr.mjs +32 -0
  23. package/dist/config-D2XmHJYe.d.mts +122 -0
  24. package/dist/config-D2XmHJYe.d.ts +122 -0
  25. package/dist/index-CRQKWAeo.d.mts +82 -0
  26. package/dist/index-CRQKWAeo.d.ts +82 -0
  27. package/dist/node/cli/index.d.mts +1 -0
  28. package/dist/node/cli/index.d.ts +1 -0
  29. package/dist/node/cli/index.js +199 -0
  30. package/dist/node/cli/index.mjs +154 -0
  31. package/dist/node/index.d.mts +79 -0
  32. package/dist/node/index.d.ts +79 -0
  33. package/dist/node/index.js +797 -0
  34. package/dist/node/index.mjs +719 -0
  35. package/package.json +79 -0
  36. package/src/client/app/index.tsx +422 -0
  37. package/src/client/app/preload.tsx +56 -0
  38. package/src/client/index.ts +40 -0
  39. package/src/client/ssr.tsx +50 -0
  40. package/src/client/theme/components/CodeBlock/CodeBlock.tsx +76 -0
  41. package/src/client/theme/components/CodeBlock/index.ts +1 -0
  42. package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +154 -0
  43. package/src/client/theme/components/PackageManagerTabs/index.ts +1 -0
  44. package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +64 -0
  45. package/src/client/theme/components/Playground/Playground.tsx +86 -0
  46. package/src/client/theme/components/Playground/index.ts +1 -0
  47. package/src/client/theme/components/Playground/playground.css +168 -0
  48. package/src/client/theme/components/Video/Video.tsx +84 -0
  49. package/src/client/theme/components/Video/index.ts +1 -0
  50. package/src/client/theme/components/Video/video.css +41 -0
  51. package/src/client/theme/components/mdx/Admonition.tsx +80 -0
  52. package/src/client/theme/components/mdx/Badge.tsx +31 -0
  53. package/src/client/theme/components/mdx/Button.tsx +50 -0
  54. package/src/client/theme/components/mdx/Card.tsx +80 -0
  55. package/src/client/theme/components/mdx/List.tsx +57 -0
  56. package/src/client/theme/components/mdx/Tabs.tsx +94 -0
  57. package/src/client/theme/components/mdx/index.ts +18 -0
  58. package/src/client/theme/components/mdx/mdx-components.css +405 -0
  59. package/src/client/theme/icons/bun.tsx +62 -0
  60. package/src/client/theme/icons/deno.tsx +20 -0
  61. package/src/client/theme/icons/discord.tsx +12 -0
  62. package/src/client/theme/icons/github.tsx +15 -0
  63. package/src/client/theme/icons/npm.tsx +13 -0
  64. package/src/client/theme/icons/pnpm.tsx +72 -0
  65. package/src/client/theme/icons/twitter.tsx +12 -0
  66. package/src/client/theme/styles/home.css +60 -0
  67. package/src/client/theme/styles/markdown.css +343 -0
  68. package/src/client/theme/styles/variables.css +162 -0
  69. package/src/client/theme/styles.css +38 -0
  70. package/src/client/theme/ui/BackgroundGradient/BackgroundGradient.tsx +10 -0
  71. package/src/client/theme/ui/BackgroundGradient/index.ts +1 -0
  72. package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +68 -0
  73. package/src/client/theme/ui/Breadcrumbs/index.ts +1 -0
  74. package/src/client/theme/ui/Footer/footer.css +32 -0
  75. package/src/client/theme/ui/Head/Head.tsx +69 -0
  76. package/src/client/theme/ui/Head/index.ts +1 -0
  77. package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +125 -0
  78. package/src/client/theme/ui/LanguageSwitcher/index.ts +1 -0
  79. package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +98 -0
  80. package/src/client/theme/ui/Layout/Layout.tsx +213 -0
  81. package/src/client/theme/ui/Layout/base.css +76 -0
  82. package/src/client/theme/ui/Layout/index.ts +2 -0
  83. package/src/client/theme/ui/Layout/pagination.css +72 -0
  84. package/src/client/theme/ui/Layout/responsive.css +40 -0
  85. package/src/client/theme/ui/Link/Link.tsx +202 -0
  86. package/src/client/theme/ui/Link/index.ts +2 -0
  87. package/src/client/theme/ui/Loading/Loading.tsx +10 -0
  88. package/src/client/theme/ui/Loading/index.ts +1 -0
  89. package/src/client/theme/ui/Loading/loading.css +30 -0
  90. package/src/client/theme/ui/Navbar/GithubStars.tsx +27 -0
  91. package/src/client/theme/ui/Navbar/Navbar.tsx +145 -0
  92. package/src/client/theme/ui/Navbar/index.ts +2 -0
  93. package/src/client/theme/ui/Navbar/navbar.css +233 -0
  94. package/src/client/theme/ui/NotFound/NotFound.tsx +20 -0
  95. package/src/client/theme/ui/NotFound/index.ts +1 -0
  96. package/src/client/theme/ui/NotFound/not-found.css +64 -0
  97. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +192 -0
  98. package/src/client/theme/ui/OnThisPage/index.ts +1 -0
  99. package/src/client/theme/ui/OnThisPage/toc.css +132 -0
  100. package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +18 -0
  101. package/src/client/theme/ui/PoweredBy/index.ts +1 -0
  102. package/src/client/theme/ui/PoweredBy/powered-by.css +76 -0
  103. package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +199 -0
  104. package/src/client/theme/ui/SearchDialog/index.ts +1 -0
  105. package/src/client/theme/ui/SearchDialog/search.css +152 -0
  106. package/src/client/theme/ui/Sidebar/Sidebar.tsx +200 -0
  107. package/src/client/theme/ui/Sidebar/index.ts +1 -0
  108. package/src/client/theme/ui/Sidebar/sidebar.css +269 -0
  109. package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +69 -0
  110. package/src/client/theme/ui/ThemeToggle/index.ts +1 -0
  111. package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +136 -0
  112. package/src/client/theme/ui/VersionSwitcher/index.ts +1 -0
  113. package/src/client/utils.ts +26 -0
  114. package/src/node/cache.ts +94 -0
  115. package/src/node/cli/commands/config.ts +15 -0
  116. package/src/node/cli/commands/generate-css.ts +24 -0
  117. package/src/node/cli/constants.ts +70 -0
  118. package/src/node/cli/index.ts +22 -0
  119. package/src/node/config.ts +185 -0
  120. package/src/node/index.ts +21 -0
  121. package/src/node/mdx.ts +41 -0
  122. package/src/node/plugin/entry.ts +58 -0
  123. package/src/node/plugin/html.ts +55 -0
  124. package/src/node/plugin/index.ts +190 -0
  125. package/src/node/plugin/types.ts +11 -0
  126. package/src/node/routes/cache.ts +24 -0
  127. package/src/node/routes/index.ts +152 -0
  128. package/src/node/routes/parser.ts +127 -0
  129. package/src/node/routes/sorter.ts +42 -0
  130. package/src/node/routes/types.ts +49 -0
  131. package/src/node/ssg/index.ts +110 -0
  132. package/src/node/ssg/meta.ts +34 -0
  133. package/src/node/ssg/options.ts +13 -0
  134. package/src/node/ssg/sitemap.ts +54 -0
  135. package/src/node/utils.ts +134 -0
  136. package/tsconfig.json +20 -0
  137. package/tsup.config.ts +22 -0
@@ -0,0 +1,1644 @@
1
+ // src/client/theme/ui/Navbar/Navbar.tsx
2
+ import React11 from "react";
3
+
4
+ // src/client/theme/ui/Link/Link.tsx
5
+ import React8 from "react";
6
+ import {
7
+ Link as RouterLink,
8
+ NavLink as RouterNavLink,
9
+ useLocation as useLocation7
10
+ } from "react-router-dom";
11
+
12
+ // src/client/app/preload.tsx
13
+ import { createContext, useContext, useCallback } from "react";
14
+ import { jsx } from "react/jsx-runtime";
15
+ var PreloadContext = createContext({
16
+ preload: () => {
17
+ }
18
+ });
19
+ function usePreload() {
20
+ return useContext(PreloadContext);
21
+ }
22
+ function PreloadProvider({
23
+ routes,
24
+ modules,
25
+ children
26
+ }) {
27
+ const preload = useCallback(
28
+ (path) => {
29
+ const cleanPath = path.split("#")[0].split("?")[0];
30
+ const route = routes.find(
31
+ (r) => r.path === cleanPath || cleanPath === "/" && r.path === ""
32
+ );
33
+ if (route && route.filePath) {
34
+ const loaderKey = Object.keys(modules).find(
35
+ (k) => k.endsWith("/" + route.filePath)
36
+ );
37
+ if (loaderKey) {
38
+ modules[loaderKey]().catch((err) => {
39
+ console.error(`[boltdocs] Failed to preload route ${path}:`, err);
40
+ });
41
+ }
42
+ }
43
+ },
44
+ [routes, modules]
45
+ );
46
+ return /* @__PURE__ */ jsx(PreloadContext.Provider, { value: { preload }, children });
47
+ }
48
+
49
+ // src/client/app/index.tsx
50
+ import React7, { useEffect as useEffect4, useState as useState6 } from "react";
51
+ import ReactDOM from "react-dom/client";
52
+ import {
53
+ BrowserRouter,
54
+ Routes,
55
+ Route,
56
+ Outlet,
57
+ useLocation as useLocation6
58
+ } from "react-router-dom";
59
+
60
+ // src/client/theme/ui/Layout/Layout.tsx
61
+ import React4, { useState as useState4 } from "react";
62
+ import { useLocation as useLocation5 } from "react-router-dom";
63
+ import { ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3, Menu } from "lucide-react";
64
+
65
+ // src/client/theme/ui/Navbar/GithubStars.tsx
66
+ import { useEffect, useState } from "react";
67
+
68
+ // src/client/theme/icons/github.tsx
69
+ import { jsx as jsx2 } from "react/jsx-runtime";
70
+ var GitHub = (props) => /* @__PURE__ */ jsx2("svg", { ...props, viewBox: "0 0 1024 1024", fill: "none", children: /* @__PURE__ */ jsx2(
71
+ "path",
72
+ {
73
+ fillRule: "evenodd",
74
+ clipRule: "evenodd",
75
+ d: "M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z",
76
+ transform: "scale(64)",
77
+ fill: "currentColor"
78
+ }
79
+ ) });
80
+
81
+ // src/client/utils.ts
82
+ async function getStarsRepo(repo) {
83
+ const response = await fetch(`https://api.github.com/repos/${repo}`);
84
+ const data = await response.json();
85
+ if (data.stargazers_count !== void 0) {
86
+ return formatStars(data.stargazers_count);
87
+ } else {
88
+ return "0";
89
+ }
90
+ }
91
+ var formatStars = (count) => {
92
+ return Intl.NumberFormat("en", {
93
+ notation: "compact",
94
+ compactDisplay: "short"
95
+ }).format(count);
96
+ };
97
+
98
+ // src/client/theme/ui/Navbar/GithubStars.tsx
99
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
100
+ function GithubStars({ repo }) {
101
+ const [stars, setStars] = useState(null);
102
+ useEffect(() => {
103
+ if (repo) {
104
+ getStarsRepo(repo).then((stars2) => setStars(stars2)).catch(() => setStars("0"));
105
+ }
106
+ }, [repo]);
107
+ return /* @__PURE__ */ jsxs(
108
+ "a",
109
+ {
110
+ href: `https://github.com/${repo}`,
111
+ target: "_blank",
112
+ rel: "noopener noreferrer",
113
+ className: "navbar-github-stars",
114
+ children: [
115
+ /* @__PURE__ */ jsx3(GitHub, {}),
116
+ stars && /* @__PURE__ */ jsx3("span", { children: stars })
117
+ ]
118
+ }
119
+ );
120
+ }
121
+
122
+ // src/client/theme/ui/Sidebar/Sidebar.tsx
123
+ import { useState as useState2 } from "react";
124
+ import { useLocation } from "react-router-dom";
125
+
126
+ // src/client/theme/ui/PoweredBy/PoweredBy.tsx
127
+ import { Zap } from "lucide-react";
128
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
129
+ function PoweredBy() {
130
+ return /* @__PURE__ */ jsx4("div", { className: "powered-by-container", children: /* @__PURE__ */ jsxs2(
131
+ "a",
132
+ {
133
+ href: "https://github.com/jesusalcaladev/boltdocs",
134
+ target: "_blank",
135
+ rel: "noopener noreferrer",
136
+ className: "powered-by-link",
137
+ children: [
138
+ /* @__PURE__ */ jsx4(Zap, { className: "powered-by-icon", size: 12, fill: "currentColor" }),
139
+ /* @__PURE__ */ jsx4("span", { children: "Powered by" }),
140
+ /* @__PURE__ */ jsx4("span", { className: "powered-by-brand", children: "LiteDocs" })
141
+ ]
142
+ }
143
+ ) });
144
+ }
145
+
146
+ // src/client/theme/ui/Sidebar/Sidebar.tsx
147
+ import { ChevronRight, ChevronLeft } from "lucide-react";
148
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
149
+ function renderBadge(badgeRaw) {
150
+ if (!badgeRaw) return null;
151
+ let text = "";
152
+ let expires = "";
153
+ if (typeof badgeRaw === "string") {
154
+ text = badgeRaw;
155
+ } else {
156
+ text = badgeRaw.text;
157
+ expires = badgeRaw.expires || "";
158
+ }
159
+ if (expires) {
160
+ const expireDate = new Date(expires);
161
+ const now = /* @__PURE__ */ new Date();
162
+ expireDate.setHours(0, 0, 0, 0);
163
+ now.setHours(0, 0, 0, 0);
164
+ if (now > expireDate) {
165
+ return null;
166
+ }
167
+ }
168
+ if (!text) return null;
169
+ if (!text) return null;
170
+ let typeClass = "badge-default";
171
+ const lowerText = text.toLowerCase();
172
+ if (lowerText === "new") {
173
+ typeClass = "badge-new";
174
+ } else if (lowerText === "experimental") {
175
+ typeClass = "badge-experimental";
176
+ } else if (lowerText === "updated") {
177
+ typeClass = "badge-updated";
178
+ }
179
+ return /* @__PURE__ */ jsx5("span", { className: `sidebar-badge ${typeClass}`, children: text });
180
+ }
181
+ function Sidebar({
182
+ routes,
183
+ config,
184
+ onCollapse
185
+ }) {
186
+ const location = useLocation();
187
+ const ungrouped = [];
188
+ const groupMap = /* @__PURE__ */ new Map();
189
+ for (const route of routes) {
190
+ if (!route.group) {
191
+ ungrouped.push(route);
192
+ } else {
193
+ if (!groupMap.has(route.group)) {
194
+ groupMap.set(route.group, {
195
+ slug: route.group,
196
+ title: route.groupTitle || route.group,
197
+ routes: []
198
+ });
199
+ }
200
+ groupMap.get(route.group).routes.push(route);
201
+ }
202
+ }
203
+ const groups = Array.from(groupMap.values());
204
+ return /* @__PURE__ */ jsxs3("aside", { className: "boltdocs-sidebar", children: [
205
+ /* @__PURE__ */ jsxs3("nav", { "aria-label": "Main Navigation", children: [
206
+ /* @__PURE__ */ jsx5("ul", { className: "sidebar-list", children: ungrouped.map((route) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
207
+ Link,
208
+ {
209
+ to: route.path === "" ? "/" : route.path,
210
+ className: `sidebar-link ${location.pathname === route.path ? "active" : ""}`,
211
+ "aria-current": location.pathname === route.path ? "page" : void 0,
212
+ children: /* @__PURE__ */ jsxs3("div", { className: "sidebar-link-content", children: [
213
+ /* @__PURE__ */ jsx5("span", { children: route.title }),
214
+ renderBadge(route.badge)
215
+ ] })
216
+ }
217
+ ) }, route.path)) }),
218
+ groups.map((group) => /* @__PURE__ */ jsx5(
219
+ SidebarGroupSection,
220
+ {
221
+ group,
222
+ currentPath: location.pathname
223
+ },
224
+ group.slug
225
+ ))
226
+ ] }),
227
+ onCollapse && /* @__PURE__ */ jsx5("div", { className: "sidebar-footer", children: /* @__PURE__ */ jsxs3(
228
+ "button",
229
+ {
230
+ className: "sidebar-collapse-btn",
231
+ onClick: onCollapse,
232
+ "aria-label": "Collapse Sidebar",
233
+ title: "Collapse Sidebar",
234
+ children: [
235
+ /* @__PURE__ */ jsx5(ChevronLeft, { size: 16 }),
236
+ /* @__PURE__ */ jsx5("span", { children: "Collapse Sidebar" })
237
+ ]
238
+ }
239
+ ) }),
240
+ config.themeConfig?.poweredBy !== false && /* @__PURE__ */ jsx5(PoweredBy, {})
241
+ ] });
242
+ }
243
+ function SidebarGroupSection({
244
+ group,
245
+ currentPath
246
+ }) {
247
+ const isActive = group.routes.some((r) => currentPath === r.path);
248
+ const [open, setOpen] = useState2(true);
249
+ return /* @__PURE__ */ jsxs3("div", { className: "sidebar-group", children: [
250
+ /* @__PURE__ */ jsxs3(
251
+ "button",
252
+ {
253
+ className: `sidebar-group-header ${isActive ? "active" : ""}`,
254
+ onClick: () => setOpen(!open),
255
+ "aria-expanded": open,
256
+ "aria-controls": `sidebar-group-${group.slug}`,
257
+ children: [
258
+ /* @__PURE__ */ jsx5("span", { className: "sidebar-group-title", children: group.title }),
259
+ /* @__PURE__ */ jsx5("span", { className: `sidebar-group-chevron ${open ? "open" : ""}`, children: /* @__PURE__ */ jsx5(ChevronRight, { size: 16 }) })
260
+ ]
261
+ }
262
+ ),
263
+ open && /* @__PURE__ */ jsx5("ul", { className: "sidebar-group-list", id: `sidebar-group-${group.slug}`, children: group.routes.map((route) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
264
+ Link,
265
+ {
266
+ to: route.path === "" ? "/" : route.path,
267
+ className: `sidebar-link sidebar-link-nested ${currentPath === route.path ? "active" : ""}`,
268
+ "aria-current": currentPath === route.path ? "page" : void 0,
269
+ children: /* @__PURE__ */ jsxs3("div", { className: "sidebar-link-content", children: [
270
+ /* @__PURE__ */ jsx5("span", { children: route.title }),
271
+ renderBadge(route.badge)
272
+ ] })
273
+ }
274
+ ) }, route.path)) })
275
+ ] });
276
+ }
277
+
278
+ // src/client/theme/ui/OnThisPage/OnThisPage.tsx
279
+ import { useEffect as useEffect2, useState as useState3, useRef, useCallback as useCallback2 } from "react";
280
+ import { useLocation as useLocation2 } from "react-router-dom";
281
+ import { Pencil, CircleHelp } from "lucide-react";
282
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
283
+ function OnThisPage({
284
+ headings = [],
285
+ editLink,
286
+ communityHelp,
287
+ filePath
288
+ }) {
289
+ const [activeId, setActiveId] = useState3("");
290
+ const [indicatorStyle, setIndicatorStyle] = useState3({});
291
+ const observerRef = useRef(null);
292
+ const location = useLocation2();
293
+ const listRef = useRef(null);
294
+ useEffect2(() => {
295
+ if (headings.length > 0) {
296
+ const hash = window.location.hash.substring(1);
297
+ if (hash && headings.some((h) => h.id === hash)) {
298
+ setActiveId(hash);
299
+ } else {
300
+ setActiveId(headings[0].id);
301
+ }
302
+ }
303
+ }, [location.pathname, headings]);
304
+ useEffect2(() => {
305
+ if (!activeId || !listRef.current) return;
306
+ const activeElement = listRef.current.querySelector(
307
+ `a[href="#${activeId}"]`
308
+ );
309
+ if (activeElement) {
310
+ const { offsetTop, offsetHeight } = activeElement;
311
+ setIndicatorStyle({
312
+ transform: `translateY(${offsetTop}px)`,
313
+ height: `${offsetHeight}px`,
314
+ opacity: 1
315
+ });
316
+ }
317
+ }, [activeId, headings]);
318
+ useEffect2(() => {
319
+ if (headings.length === 0) return;
320
+ if (observerRef.current) {
321
+ observerRef.current.disconnect();
322
+ }
323
+ const callback = (entries) => {
324
+ const visibleEntries = entries.filter((entry) => entry.isIntersecting);
325
+ if (visibleEntries.length > 0) {
326
+ const closest = visibleEntries.reduce((prev, curr) => {
327
+ return Math.abs(curr.boundingClientRect.top - 100) < Math.abs(prev.boundingClientRect.top - 100) ? curr : prev;
328
+ });
329
+ setActiveId(closest.target.id);
330
+ }
331
+ };
332
+ observerRef.current = new IntersectionObserver(callback, {
333
+ rootMargin: "-100px 0px -70% 0px",
334
+ threshold: [0, 1]
335
+ });
336
+ const observeHeadings = () => {
337
+ headings.forEach(({ id }) => {
338
+ const el = document.getElementById(id);
339
+ if (el) {
340
+ observerRef.current.observe(el);
341
+ }
342
+ });
343
+ };
344
+ observeHeadings();
345
+ const timeoutId = setTimeout(observeHeadings, 1e3);
346
+ return () => {
347
+ observerRef.current?.disconnect();
348
+ clearTimeout(timeoutId);
349
+ };
350
+ }, [headings, location.pathname]);
351
+ const handleClick = useCallback2(
352
+ (e, id) => {
353
+ e.preventDefault();
354
+ const el = document.getElementById(id);
355
+ if (el) {
356
+ const offset = 80;
357
+ const bodyRect = document.body.getBoundingClientRect().top;
358
+ const elementRect = el.getBoundingClientRect().top;
359
+ const elementPosition = elementRect - bodyRect;
360
+ const offsetPosition = elementPosition - offset;
361
+ window.scrollTo({
362
+ top: offsetPosition,
363
+ behavior: "smooth"
364
+ });
365
+ setActiveId(id);
366
+ window.history.pushState(null, "", `#${id}`);
367
+ }
368
+ },
369
+ []
370
+ );
371
+ if (headings.length === 0) return null;
372
+ return /* @__PURE__ */ jsxs4("nav", { className: "boltdocs-on-this-page", "aria-label": "Table of contents", children: [
373
+ /* @__PURE__ */ jsx6("p", { className: "on-this-page-title", children: "On this page" }),
374
+ /* @__PURE__ */ jsxs4("div", { className: "on-this-page-container", children: [
375
+ /* @__PURE__ */ jsx6("div", { className: "toc-indicator", style: indicatorStyle }),
376
+ /* @__PURE__ */ jsx6("ul", { className: "on-this-page-list", ref: listRef, children: headings.map((h) => /* @__PURE__ */ jsx6("li", { className: h.level === 3 ? "toc-indent" : "", children: /* @__PURE__ */ jsx6(
377
+ "a",
378
+ {
379
+ href: `#${h.id}`,
380
+ className: `toc-link ${activeId === h.id ? "active" : ""}`,
381
+ "aria-current": activeId === h.id ? "true" : void 0,
382
+ onClick: (e) => handleClick(e, h.id),
383
+ children: h.text
384
+ }
385
+ ) }, h.id)) })
386
+ ] }),
387
+ (editLink || communityHelp) && /* @__PURE__ */ jsxs4("div", { className: "toc-help", children: [
388
+ /* @__PURE__ */ jsx6("p", { className: "toc-help-title", children: "Need help?" }),
389
+ /* @__PURE__ */ jsxs4("ul", { className: "toc-help-links", children: [
390
+ editLink && filePath && /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsxs4(
391
+ "a",
392
+ {
393
+ href: editLink.replace(":path", filePath),
394
+ target: "_blank",
395
+ rel: "noopener noreferrer",
396
+ className: "toc-help-link",
397
+ children: [
398
+ /* @__PURE__ */ jsx6(Pencil, { size: 16 }),
399
+ "Edit this page"
400
+ ]
401
+ }
402
+ ) }),
403
+ communityHelp && /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsxs4(
404
+ "a",
405
+ {
406
+ href: communityHelp,
407
+ target: "_blank",
408
+ rel: "noopener noreferrer",
409
+ className: "toc-help-link",
410
+ children: [
411
+ /* @__PURE__ */ jsx6(CircleHelp, { size: 16 }),
412
+ "Community help"
413
+ ]
414
+ }
415
+ ) })
416
+ ] })
417
+ ] })
418
+ ] });
419
+ }
420
+
421
+ // src/client/theme/ui/Head/Head.tsx
422
+ import { useEffect as useEffect3 } from "react";
423
+ import { useLocation as useLocation3 } from "react-router-dom";
424
+ function Head({ siteTitle, siteDescription, routes }) {
425
+ const location = useLocation3();
426
+ useEffect3(() => {
427
+ const currentRoute = routes.find((r) => r.path === location.pathname);
428
+ const pageTitle = currentRoute?.title;
429
+ const pageDescription = currentRoute?.description || siteDescription || "";
430
+ document.title = pageTitle ? `${pageTitle} | ${siteTitle}` : siteTitle;
431
+ let metaDesc = document.querySelector(
432
+ 'meta[name="description"]'
433
+ );
434
+ if (!metaDesc) {
435
+ metaDesc = document.createElement("meta");
436
+ metaDesc.name = "description";
437
+ document.head.appendChild(metaDesc);
438
+ }
439
+ metaDesc.content = pageDescription;
440
+ setMetaTag("property", "og:title", document.title);
441
+ setMetaTag("property", "og:description", pageDescription);
442
+ setMetaTag("property", "og:type", "article");
443
+ setMetaTag("property", "og:url", window.location.href);
444
+ setMetaTag("name", "twitter:card", "summary");
445
+ setMetaTag("name", "twitter:title", document.title);
446
+ setMetaTag("name", "twitter:description", pageDescription);
447
+ let canonical = document.querySelector(
448
+ 'link[rel="canonical"]'
449
+ );
450
+ if (!canonical) {
451
+ canonical = document.createElement("link");
452
+ canonical.rel = "canonical";
453
+ document.head.appendChild(canonical);
454
+ }
455
+ canonical.href = window.location.origin + location.pathname;
456
+ }, [location.pathname, siteTitle, siteDescription, routes]);
457
+ return null;
458
+ }
459
+ function setMetaTag(attr, key, content) {
460
+ let tag = document.querySelector(
461
+ `meta[${attr}="${key}"]`
462
+ );
463
+ if (!tag) {
464
+ tag = document.createElement("meta");
465
+ tag.setAttribute(attr, key);
466
+ document.head.appendChild(tag);
467
+ }
468
+ tag.content = content;
469
+ }
470
+
471
+ // src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx
472
+ import { useLocation as useLocation4 } from "react-router-dom";
473
+ import { Home, ChevronRight as ChevronRight2 } from "lucide-react";
474
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
475
+ function Breadcrumbs({ routes, config }) {
476
+ const location = useLocation4();
477
+ if (config.themeConfig?.breadcrumbs === false) return null;
478
+ if (location.pathname === "/") return null;
479
+ const currentRoute = routes.find((r) => r.path === location.pathname);
480
+ const groupRoute = currentRoute?.group ? routes.find((r) => r.group === currentRoute.group) : null;
481
+ return /* @__PURE__ */ jsx7("nav", { className: "boltdocs-breadcrumbs", "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsxs5("ol", { className: "boltdocs-breadcrumbs-list", children: [
482
+ /* @__PURE__ */ jsxs5("li", { className: "boltdocs-breadcrumbs-item", children: [
483
+ /* @__PURE__ */ jsx7(Link, { to: "/", className: "boltdocs-breadcrumbs-link", children: /* @__PURE__ */ jsx7(Home, { size: 14 }) }),
484
+ /* @__PURE__ */ jsx7("span", { className: "boltdocs-breadcrumbs-separator", children: /* @__PURE__ */ jsx7(ChevronRight2, { size: 14 }) })
485
+ ] }),
486
+ currentRoute?.groupTitle && /* @__PURE__ */ jsxs5("li", { className: "boltdocs-breadcrumbs-item", children: [
487
+ groupRoute ? /* @__PURE__ */ jsx7(Link, { to: groupRoute.path, className: "boltdocs-breadcrumbs-link", children: currentRoute.groupTitle }) : /* @__PURE__ */ jsx7("span", { className: "boltdocs-breadcrumbs-text", children: currentRoute.groupTitle }),
488
+ /* @__PURE__ */ jsx7("span", { className: "boltdocs-breadcrumbs-separator", children: /* @__PURE__ */ jsx7(ChevronRight2, { size: 14 }) })
489
+ ] }),
490
+ currentRoute?.title && /* @__PURE__ */ jsx7("li", { className: "boltdocs-breadcrumbs-item", children: /* @__PURE__ */ jsx7(
491
+ "span",
492
+ {
493
+ className: "boltdocs-breadcrumbs-text boltdocs-breadcrumbs-active",
494
+ "aria-current": "page",
495
+ children: currentRoute.title
496
+ }
497
+ ) })
498
+ ] }) });
499
+ }
500
+
501
+ // src/client/theme/ui/BackgroundGradient/BackgroundGradient.tsx
502
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
503
+ function BackgroundGradient() {
504
+ return /* @__PURE__ */ jsxs6("div", { className: "boltdocs-background-glow", children: [
505
+ /* @__PURE__ */ jsx8("div", { className: "glow-shape glow-1" }),
506
+ /* @__PURE__ */ jsx8("div", { className: "glow-shape glow-2" })
507
+ ] });
508
+ }
509
+
510
+ // src/client/theme/ui/Layout/Layout.tsx
511
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
512
+ function ThemeLayout({
513
+ config,
514
+ routes,
515
+ children,
516
+ navbar,
517
+ sidebar,
518
+ toc,
519
+ background,
520
+ head,
521
+ breadcrumbs,
522
+ className = "",
523
+ style
524
+ }) {
525
+ const [isSidebarOpen, setIsSidebarOpen] = useState4(true);
526
+ const siteTitle = config.themeConfig?.title || "Boltdocs";
527
+ const siteDescription = config.themeConfig?.description || "";
528
+ const location = useLocation5();
529
+ const currentIndex = routes.findIndex((r) => r.path === location.pathname);
530
+ const currentRoute = routes[currentIndex];
531
+ const currentLocale = config.i18n ? currentRoute?.locale || config.i18n.defaultLocale : void 0;
532
+ const currentVersion = config.versions ? currentRoute?.version || config.versions.defaultVersion : void 0;
533
+ const filteredRoutes = routes.filter((r) => {
534
+ const localeMatch = config.i18n ? (r.locale || config.i18n.defaultLocale) === currentLocale : true;
535
+ const versionMatch = config.versions ? (r.version || config.versions.defaultVersion) === currentVersion : true;
536
+ return localeMatch && versionMatch;
537
+ });
538
+ const localIndex = filteredRoutes.findIndex(
539
+ (r) => r.path === location.pathname
540
+ );
541
+ const prevPage = localIndex > 0 ? filteredRoutes[localIndex - 1] : null;
542
+ const nextPage = localIndex >= 0 && localIndex < filteredRoutes.length - 1 ? filteredRoutes[localIndex + 1] : null;
543
+ const { preload } = usePreload();
544
+ React4.useEffect(() => {
545
+ if (prevPage?.path) preload(prevPage.path);
546
+ if (nextPage?.path) preload(nextPage.path);
547
+ }, [prevPage, nextPage, preload]);
548
+ return /* @__PURE__ */ jsxs7("div", { className: `boltdocs-layout ${className}`, style, children: [
549
+ background !== void 0 ? background : /* @__PURE__ */ jsx9(BackgroundGradient, {}),
550
+ head !== void 0 ? head : /* @__PURE__ */ jsx9(
551
+ Head,
552
+ {
553
+ siteTitle,
554
+ siteDescription,
555
+ routes
556
+ }
557
+ ),
558
+ navbar !== void 0 ? navbar : /* @__PURE__ */ jsx9(
559
+ Navbar,
560
+ {
561
+ config,
562
+ routes: filteredRoutes,
563
+ allRoutes: routes,
564
+ currentLocale,
565
+ currentVersion
566
+ }
567
+ ),
568
+ /* @__PURE__ */ jsxs7(
569
+ "div",
570
+ {
571
+ className: `boltdocs-main-container ${!isSidebarOpen ? "sidebar-collapsed" : ""}`,
572
+ children: [
573
+ sidebar !== void 0 ? sidebar : /* @__PURE__ */ jsx9(
574
+ Sidebar,
575
+ {
576
+ routes: filteredRoutes,
577
+ config,
578
+ onCollapse: () => setIsSidebarOpen(false)
579
+ }
580
+ ),
581
+ sidebar === void 0 && /* @__PURE__ */ jsx9(
582
+ "button",
583
+ {
584
+ className: "sidebar-toggle-floating",
585
+ onClick: () => setIsSidebarOpen(true),
586
+ "aria-label": "Expand Sidebar",
587
+ title: "Expand Sidebar",
588
+ children: /* @__PURE__ */ jsx9(Menu, { size: 20 })
589
+ }
590
+ ),
591
+ /* @__PURE__ */ jsxs7("main", { className: "boltdocs-content", children: [
592
+ breadcrumbs !== void 0 ? breadcrumbs : /* @__PURE__ */ jsx9(Breadcrumbs, { routes: filteredRoutes, config }),
593
+ /* @__PURE__ */ jsx9("div", { className: "boltdocs-page", children }),
594
+ (prevPage || nextPage) && /* @__PURE__ */ jsxs7("nav", { className: "page-nav", "aria-label": "Pagination", children: [
595
+ prevPage ? /* @__PURE__ */ jsxs7(
596
+ Link,
597
+ {
598
+ to: prevPage.path || "/",
599
+ className: "page-nav-link page-nav-link--prev",
600
+ children: [
601
+ /* @__PURE__ */ jsxs7("div", { className: "page-nav-info", children: [
602
+ /* @__PURE__ */ jsx9("span", { className: "page-nav-label", children: "Previous" }),
603
+ /* @__PURE__ */ jsx9("span", { className: "page-nav-title", children: prevPage.title })
604
+ ] }),
605
+ /* @__PURE__ */ jsx9(ChevronLeft2, { className: "page-nav-arrow", size: 16 })
606
+ ]
607
+ }
608
+ ) : /* @__PURE__ */ jsx9("span", {}),
609
+ nextPage ? /* @__PURE__ */ jsxs7(
610
+ Link,
611
+ {
612
+ to: nextPage.path || "/",
613
+ className: "page-nav-link page-nav-link--next",
614
+ children: [
615
+ /* @__PURE__ */ jsxs7("div", { className: "page-nav-info", children: [
616
+ /* @__PURE__ */ jsx9("span", { className: "page-nav-label", children: "Next" }),
617
+ /* @__PURE__ */ jsx9("span", { className: "page-nav-title", children: nextPage.title })
618
+ ] }),
619
+ /* @__PURE__ */ jsx9(ChevronRight3, { className: "page-nav-arrow", size: 16 })
620
+ ]
621
+ }
622
+ ) : /* @__PURE__ */ jsx9("span", {})
623
+ ] })
624
+ ] }),
625
+ toc !== void 0 ? toc : /* @__PURE__ */ jsx9(
626
+ OnThisPage,
627
+ {
628
+ headings: routes[currentIndex]?.headings,
629
+ editLink: config.themeConfig?.editLink,
630
+ communityHelp: config.themeConfig?.communityHelp,
631
+ filePath: routes[currentIndex]?.filePath
632
+ }
633
+ )
634
+ ]
635
+ }
636
+ )
637
+ ] });
638
+ }
639
+
640
+ // src/client/theme/ui/NotFound/NotFound.tsx
641
+ import { ArrowLeft } from "lucide-react";
642
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
643
+ function NotFound() {
644
+ return /* @__PURE__ */ jsx10("div", { className: "boltdocs-not-found", children: /* @__PURE__ */ jsxs8("div", { className: "not-found-content", children: [
645
+ /* @__PURE__ */ jsx10("span", { className: "not-found-code", children: "404" }),
646
+ /* @__PURE__ */ jsx10("h1", { className: "not-found-title", children: "Page Not Found" }),
647
+ /* @__PURE__ */ jsx10("p", { className: "not-found-text", children: "The page you're looking for doesn't exist or has been moved." }),
648
+ /* @__PURE__ */ jsxs8(Link, { to: "/", className: "not-found-link", children: [
649
+ /* @__PURE__ */ jsx10(ArrowLeft, { size: 16 }),
650
+ " Go to Home"
651
+ ] })
652
+ ] }) });
653
+ }
654
+
655
+ // src/client/theme/ui/Loading/Loading.tsx
656
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
657
+ function Loading() {
658
+ return /* @__PURE__ */ jsxs9("div", { className: "boltdocs-loading", children: [
659
+ /* @__PURE__ */ jsx11("div", { className: "loading-spinner" }),
660
+ /* @__PURE__ */ jsx11("p", { className: "loading-text", children: "Loading..." })
661
+ ] });
662
+ }
663
+
664
+ // src/client/app/index.tsx
665
+ import { MDXProvider } from "@mdx-js/react";
666
+ import {
667
+ createContext as createContext2,
668
+ useContext as useContext2,
669
+ Suspense,
670
+ lazy,
671
+ useLayoutEffect
672
+ } from "react";
673
+ import { Link as LucideLink } from "lucide-react";
674
+
675
+ // src/client/theme/components/mdx/Button.tsx
676
+ import { jsx as jsx12 } from "react/jsx-runtime";
677
+ function Button({
678
+ variant = "primary",
679
+ size = "md",
680
+ href,
681
+ children,
682
+ className = "",
683
+ ...rest
684
+ }) {
685
+ const cls = `ld-btn ld-btn--${variant} ld-btn--${size} ${className}`.trim();
686
+ if (href) {
687
+ return /* @__PURE__ */ jsx12(
688
+ "a",
689
+ {
690
+ href,
691
+ style: { textDecoration: "none" },
692
+ className: cls,
693
+ ...rest,
694
+ children
695
+ }
696
+ );
697
+ }
698
+ return /* @__PURE__ */ jsx12("button", { className: cls, ...rest, children });
699
+ }
700
+
701
+ // src/client/theme/components/mdx/Badge.tsx
702
+ import { jsx as jsx13 } from "react/jsx-runtime";
703
+ function Badge({
704
+ variant = "default",
705
+ children,
706
+ className = "",
707
+ ...rest
708
+ }) {
709
+ return /* @__PURE__ */ jsx13(
710
+ "span",
711
+ {
712
+ className: `ld-badge ld-badge--${variant} ${className}`.trim(),
713
+ ...rest,
714
+ children
715
+ }
716
+ );
717
+ }
718
+
719
+ // src/client/theme/components/mdx/Card.tsx
720
+ import { Fragment, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
721
+ function Cards({
722
+ cols = 3,
723
+ children,
724
+ className = "",
725
+ ...rest
726
+ }) {
727
+ return /* @__PURE__ */ jsx14("div", { className: `ld-cards ld-cards--${cols} ${className}`.trim(), ...rest, children });
728
+ }
729
+ function Card({
730
+ title,
731
+ icon,
732
+ href,
733
+ children,
734
+ className = "",
735
+ ...rest
736
+ }) {
737
+ const inner = /* @__PURE__ */ jsxs10(Fragment, { children: [
738
+ icon && /* @__PURE__ */ jsx14("span", { className: "ld-card__icon", children: icon }),
739
+ title && /* @__PURE__ */ jsx14("h3", { className: "ld-card__title", children: title }),
740
+ children && /* @__PURE__ */ jsx14("div", { className: "ld-card__body", children })
741
+ ] });
742
+ if (href) {
743
+ return /* @__PURE__ */ jsx14(
744
+ "a",
745
+ {
746
+ href,
747
+ className: `ld-card ld-card--link ${className}`.trim(),
748
+ ...rest,
749
+ children: inner
750
+ }
751
+ );
752
+ }
753
+ return /* @__PURE__ */ jsx14("div", { className: `ld-card ${className}`.trim(), ...rest, children: inner });
754
+ }
755
+
756
+ // src/client/theme/components/mdx/Tabs.tsx
757
+ import { useState as useState5, Children, isValidElement, useRef as useRef2 } from "react";
758
+ import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
759
+ function Tab({ children }) {
760
+ return /* @__PURE__ */ jsx15("div", { className: "ld-tab-panel", children });
761
+ }
762
+ function Tabs({ defaultIndex = 0, children }) {
763
+ const [active, setActive] = useState5(defaultIndex);
764
+ const tabRefs = useRef2([]);
765
+ const tabs = Children.toArray(children).filter(
766
+ (child) => isValidElement(child) && child.props?.label
767
+ );
768
+ const handleKeyDown = (e) => {
769
+ let newIndex = active;
770
+ if (e.key === "ArrowRight") {
771
+ newIndex = (active + 1) % tabs.length;
772
+ } else if (e.key === "ArrowLeft") {
773
+ newIndex = (active - 1 + tabs.length) % tabs.length;
774
+ }
775
+ if (newIndex !== active) {
776
+ setActive(newIndex);
777
+ tabRefs.current[newIndex]?.focus();
778
+ }
779
+ };
780
+ return /* @__PURE__ */ jsxs11("div", { className: "ld-tabs", children: [
781
+ /* @__PURE__ */ jsx15("div", { className: "ld-tabs__bar", role: "tablist", onKeyDown: handleKeyDown, children: tabs.map((child, i) => {
782
+ const label = child.props.label;
783
+ return /* @__PURE__ */ jsx15(
784
+ "button",
785
+ {
786
+ role: "tab",
787
+ "aria-selected": i === active,
788
+ "aria-controls": `tabpanel-${i}`,
789
+ id: `tab-${i}`,
790
+ tabIndex: i === active ? 0 : -1,
791
+ ref: (el) => {
792
+ tabRefs.current[i] = el;
793
+ },
794
+ className: `ld-tabs__trigger ${i === active ? "ld-tabs__trigger--active" : ""}`,
795
+ onClick: () => setActive(i),
796
+ children: label
797
+ },
798
+ i
799
+ );
800
+ }) }),
801
+ /* @__PURE__ */ jsx15(
802
+ "div",
803
+ {
804
+ className: "ld-tabs__content",
805
+ role: "tabpanel",
806
+ id: `tabpanel-${active}`,
807
+ "aria-labelledby": `tab-${active}`,
808
+ children: tabs[active]
809
+ }
810
+ )
811
+ ] });
812
+ }
813
+
814
+ // src/client/theme/components/mdx/Admonition.tsx
815
+ import {
816
+ Info,
817
+ Lightbulb,
818
+ AlertTriangle,
819
+ ShieldAlert,
820
+ Bookmark
821
+ } from "lucide-react";
822
+ import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
823
+ var ICON_MAP = {
824
+ note: /* @__PURE__ */ jsx16(Bookmark, { size: 18 }),
825
+ tip: /* @__PURE__ */ jsx16(Lightbulb, { size: 18 }),
826
+ info: /* @__PURE__ */ jsx16(Info, { size: 18 }),
827
+ warning: /* @__PURE__ */ jsx16(AlertTriangle, { size: 18 }),
828
+ danger: /* @__PURE__ */ jsx16(ShieldAlert, { size: 18 })
829
+ };
830
+ var LABEL_MAP = {
831
+ note: "Note",
832
+ tip: "Tip",
833
+ info: "Info",
834
+ warning: "Warning",
835
+ danger: "Danger"
836
+ };
837
+ function Admonition({
838
+ type = "note",
839
+ title,
840
+ children,
841
+ className = "",
842
+ ...rest
843
+ }) {
844
+ return /* @__PURE__ */ jsxs12(
845
+ "div",
846
+ {
847
+ className: `ld-admonition ld-admonition--${type} ${className}`.trim(),
848
+ role: type === "warning" || type === "danger" ? "alert" : "note",
849
+ ...rest,
850
+ children: [
851
+ /* @__PURE__ */ jsxs12("div", { className: "ld-admonition__header", children: [
852
+ /* @__PURE__ */ jsx16("span", { className: "ld-admonition__icon", children: ICON_MAP[type] }),
853
+ /* @__PURE__ */ jsx16("span", { className: "ld-admonition__title", children: title || LABEL_MAP[type] })
854
+ ] }),
855
+ /* @__PURE__ */ jsx16("div", { className: "ld-admonition__body", children })
856
+ ]
857
+ }
858
+ );
859
+ }
860
+ var Note = (props) => /* @__PURE__ */ jsx16(Admonition, { type: "note", ...props });
861
+ var Tip = (props) => /* @__PURE__ */ jsx16(Admonition, { type: "tip", ...props });
862
+ var Warning = (props) => /* @__PURE__ */ jsx16(Admonition, { type: "warning", ...props });
863
+ var Danger = (props) => /* @__PURE__ */ jsx16(Admonition, { type: "danger", ...props });
864
+ var InfoBox = (props) => /* @__PURE__ */ jsx16(Admonition, { type: "info", ...props });
865
+
866
+ // src/client/theme/components/mdx/List.tsx
867
+ import React6, { Children as Children2 } from "react";
868
+ import { Check, ChevronRight as ChevronRight4 } from "lucide-react";
869
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
870
+ var ICON_MAP2 = {
871
+ checked: /* @__PURE__ */ jsx17(Check, { size: 14, className: "ld-list__icon" }),
872
+ arrow: /* @__PURE__ */ jsx17(ChevronRight4, { size: 14, className: "ld-list__icon" })
873
+ };
874
+ function List({
875
+ variant = "default",
876
+ children,
877
+ className = "",
878
+ ...rest
879
+ }) {
880
+ if (variant === "default") {
881
+ return /* @__PURE__ */ jsx17("ul", { className: `ld-list ${className}`.trim(), ...rest, children });
882
+ }
883
+ const icon = ICON_MAP2[variant];
884
+ return /* @__PURE__ */ jsx17("ul", { className: `ld-list ld-list--${variant} ${className}`.trim(), ...rest, children: Children2.map(children, (child) => {
885
+ if (!React6.isValidElement(child)) return child;
886
+ return /* @__PURE__ */ jsxs13("li", { className: "ld-list__item", children: [
887
+ icon,
888
+ /* @__PURE__ */ jsx17("span", { className: "ld-list__text", children: child.props.children })
889
+ ] });
890
+ }) });
891
+ }
892
+
893
+ // src/client/app/index.tsx
894
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
895
+ var ConfigContext = createContext2(null);
896
+ function useConfig() {
897
+ return useContext2(ConfigContext);
898
+ }
899
+ var CodeBlock = lazy(
900
+ () => import("./CodeBlock-37XMKCYY.mjs").then((m) => ({
901
+ default: m.CodeBlock
902
+ }))
903
+ );
904
+ var Video = lazy(
905
+ () => import("./Video-I6QY4X7J.mjs").then((m) => ({ default: m.Video }))
906
+ );
907
+ var PackageManagerTabs = lazy(
908
+ () => import("./PackageManagerTabs-4NWXLXQO.mjs").then((m) => ({
909
+ default: m.PackageManagerTabs
910
+ }))
911
+ );
912
+ var Playground = lazy(
913
+ () => import("./Playground-OE2OE6B6.mjs").then((m) => ({
914
+ default: m.Playground
915
+ }))
916
+ );
917
+ var Heading = ({
918
+ level,
919
+ id,
920
+ children
921
+ }) => {
922
+ const Tag = `h${level}`;
923
+ return /* @__PURE__ */ jsxs14(Tag, { id, className: "boltdocs-heading", children: [
924
+ children,
925
+ id && /* @__PURE__ */ jsx18("a", { href: `#${id}`, className: "header-anchor", "aria-label": "Anchor", children: /* @__PURE__ */ jsx18(LucideLink, { size: 16 }) })
926
+ ] });
927
+ };
928
+ var mdxComponents = {
929
+ h1: (props) => /* @__PURE__ */ jsx18(Heading, { level: 1, ...props }),
930
+ h2: (props) => /* @__PURE__ */ jsx18(Heading, { level: 2, ...props }),
931
+ h3: (props) => /* @__PURE__ */ jsx18(Heading, { level: 3, ...props }),
932
+ h4: (props) => /* @__PURE__ */ jsx18(Heading, { level: 4, ...props }),
933
+ h5: (props) => /* @__PURE__ */ jsx18(Heading, { level: 5, ...props }),
934
+ h6: (props) => /* @__PURE__ */ jsx18(Heading, { level: 6, ...props }),
935
+ pre: (props) => {
936
+ return /* @__PURE__ */ jsx18(Suspense, { fallback: /* @__PURE__ */ jsx18("div", { className: "code-block-skeleton" }), children: /* @__PURE__ */ jsx18(CodeBlock, { ...props, children: props.children }) });
937
+ },
938
+ video: (props) => /* @__PURE__ */ jsx18(Suspense, { fallback: /* @__PURE__ */ jsx18("div", { className: "video-skeleton" }), children: /* @__PURE__ */ jsx18(Video, { ...props }) }),
939
+ PackageManagerTabs: (props) => /* @__PURE__ */ jsx18(Suspense, { fallback: /* @__PURE__ */ jsx18("div", { className: "pkg-tabs-skeleton" }), children: /* @__PURE__ */ jsx18(PackageManagerTabs, { ...props }) }),
940
+ Playground: (props) => /* @__PURE__ */ jsx18(Suspense, { fallback: /* @__PURE__ */ jsx18("div", { className: "playground-skeleton" }), children: /* @__PURE__ */ jsx18(Playground, { ...props }) }),
941
+ Button,
942
+ Badge,
943
+ Card,
944
+ Cards,
945
+ Tabs,
946
+ Tab,
947
+ Admonition,
948
+ Note,
949
+ Tip,
950
+ Warning,
951
+ Danger,
952
+ InfoBox,
953
+ List
954
+ };
955
+ function AppShell({
956
+ initialRoutes,
957
+ initialConfig,
958
+ modules,
959
+ hot,
960
+ homePage: HomePage,
961
+ components: customComponents = {}
962
+ }) {
963
+ const [routesInfo, setRoutesInfo] = useState6(initialRoutes);
964
+ const [config] = useState6(initialConfig);
965
+ const [resolvedRoutes, setResolvedRoutes] = useState6([]);
966
+ useEffect4(() => {
967
+ if (hot) {
968
+ hot.on("boltdocs:routes-update", (newRoutes) => {
969
+ setRoutesInfo(newRoutes);
970
+ });
971
+ }
972
+ }, [hot]);
973
+ useEffect4(() => {
974
+ const mapped = routesInfo.filter(
975
+ (route) => !(HomePage && (route.path === "/" || route.path === ""))
976
+ ).map((route) => {
977
+ const loaderKey = Object.keys(modules).find(
978
+ (k) => k.endsWith("/" + route.filePath)
979
+ );
980
+ const loader = loaderKey ? modules[loaderKey] : null;
981
+ return {
982
+ ...route,
983
+ Component: React7.lazy(() => {
984
+ if (!loader)
985
+ return Promise.resolve({ default: () => /* @__PURE__ */ jsx18(NotFound, {}) });
986
+ return loader();
987
+ })
988
+ };
989
+ });
990
+ setResolvedRoutes(mapped);
991
+ }, [routesInfo, modules]);
992
+ return /* @__PURE__ */ jsx18(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsxs14(PreloadProvider, { routes: routesInfo, modules, children: [
993
+ /* @__PURE__ */ jsx18(ScrollHandler, {}),
994
+ /* @__PURE__ */ jsxs14(Routes, { children: [
995
+ HomePage && /* @__PURE__ */ jsx18(
996
+ Route,
997
+ {
998
+ path: "/",
999
+ element: /* @__PURE__ */ jsx18(
1000
+ ThemeLayout,
1001
+ {
1002
+ config,
1003
+ routes: routesInfo,
1004
+ sidebar: null,
1005
+ toc: null,
1006
+ breadcrumbs: null,
1007
+ ...config.themeConfig?.layoutProps,
1008
+ children: /* @__PURE__ */ jsx18(HomePage, {})
1009
+ }
1010
+ )
1011
+ }
1012
+ ),
1013
+ /* @__PURE__ */ jsx18(Route, { element: /* @__PURE__ */ jsx18(DocsLayout, { config, routes: routesInfo }), children: resolvedRoutes.map((route) => /* @__PURE__ */ jsx18(
1014
+ Route,
1015
+ {
1016
+ path: route.path === "" ? "/" : route.path,
1017
+ element: /* @__PURE__ */ jsx18(React7.Suspense, { fallback: /* @__PURE__ */ jsx18(Loading, {}), children: /* @__PURE__ */ jsx18(
1018
+ MdxPage,
1019
+ {
1020
+ Component: route.Component,
1021
+ customComponents
1022
+ }
1023
+ ) })
1024
+ },
1025
+ route.path
1026
+ )) }),
1027
+ /* @__PURE__ */ jsx18(
1028
+ Route,
1029
+ {
1030
+ path: "*",
1031
+ element: /* @__PURE__ */ jsx18(
1032
+ ThemeLayout,
1033
+ {
1034
+ config,
1035
+ routes: routesInfo,
1036
+ ...config.themeConfig?.layoutProps,
1037
+ children: /* @__PURE__ */ jsx18(NotFound, {})
1038
+ }
1039
+ )
1040
+ }
1041
+ )
1042
+ ] })
1043
+ ] }) });
1044
+ }
1045
+ function ScrollHandler() {
1046
+ const { pathname, hash } = useLocation6();
1047
+ useLayoutEffect(() => {
1048
+ if (hash) {
1049
+ const id = hash.replace("#", "");
1050
+ const element = document.getElementById(id);
1051
+ if (element) {
1052
+ const offset = 80;
1053
+ const bodyRect = document.body.getBoundingClientRect().top;
1054
+ const elementRect = element.getBoundingClientRect().top;
1055
+ const elementPosition = elementRect - bodyRect;
1056
+ const offsetPosition = elementPosition - offset;
1057
+ window.scrollTo({
1058
+ top: offsetPosition,
1059
+ behavior: "smooth"
1060
+ });
1061
+ return;
1062
+ }
1063
+ }
1064
+ window.scrollTo(0, 0);
1065
+ }, [pathname, hash]);
1066
+ return null;
1067
+ }
1068
+ function DocsLayout({
1069
+ config,
1070
+ routes
1071
+ }) {
1072
+ return /* @__PURE__ */ jsx18(
1073
+ ThemeLayout,
1074
+ {
1075
+ config,
1076
+ routes,
1077
+ ...config.themeConfig?.layoutProps,
1078
+ children: /* @__PURE__ */ jsx18(Outlet, {})
1079
+ }
1080
+ );
1081
+ }
1082
+ function MdxPage({
1083
+ Component,
1084
+ customComponents = {}
1085
+ }) {
1086
+ const allComponents = { ...mdxComponents, ...customComponents };
1087
+ return /* @__PURE__ */ jsx18(MDXProvider, { components: allComponents, children: /* @__PURE__ */ jsx18(Component, {}) });
1088
+ }
1089
+ function createBoltdocsApp(options) {
1090
+ const { target, routes, config, modules, hot, homePage } = options;
1091
+ const container = document.querySelector(target);
1092
+ if (!container) {
1093
+ throw new Error(
1094
+ `[boltdocs] Mount target "${target}" not found in document.`
1095
+ );
1096
+ }
1097
+ const app = /* @__PURE__ */ jsx18(React7.StrictMode, { children: /* @__PURE__ */ jsx18(BrowserRouter, { children: /* @__PURE__ */ jsx18(
1098
+ AppShell,
1099
+ {
1100
+ initialRoutes: routes,
1101
+ initialConfig: config,
1102
+ modules,
1103
+ hot,
1104
+ homePage,
1105
+ components: options.components
1106
+ }
1107
+ ) }) });
1108
+ if (import.meta.env.PROD && container.innerHTML.trim() !== "") {
1109
+ ReactDOM.hydrateRoot(container, app);
1110
+ } else {
1111
+ ReactDOM.createRoot(container).render(app);
1112
+ }
1113
+ }
1114
+
1115
+ // src/client/theme/ui/Link/Link.tsx
1116
+ import { jsx as jsx19 } from "react/jsx-runtime";
1117
+ function useLocalizedTo(to) {
1118
+ const location = useLocation7();
1119
+ const config = useConfig();
1120
+ if (!config || typeof to !== "string") return to;
1121
+ if (!config.i18n && !config.versions) return to;
1122
+ const basePath = "/docs";
1123
+ if (!to.startsWith(basePath)) return to;
1124
+ const curSub = location.pathname.substring(basePath.length);
1125
+ const curParts = curSub.split("/").filter(Boolean);
1126
+ let currentVersion = config.versions?.defaultVersion;
1127
+ let currentLocale = config.i18n?.defaultLocale;
1128
+ let cIdx = 0;
1129
+ if (config.versions && curParts.length > cIdx && config.versions.versions[curParts[cIdx]]) {
1130
+ currentVersion = curParts[cIdx];
1131
+ cIdx++;
1132
+ }
1133
+ if (config.i18n && curParts.length > cIdx && config.i18n.locales[curParts[cIdx]]) {
1134
+ currentLocale = curParts[cIdx];
1135
+ }
1136
+ const toSub = to.substring(basePath.length);
1137
+ const toParts = toSub.split("/").filter(Boolean);
1138
+ let tIdx = 0;
1139
+ let hasVersion = false;
1140
+ let hasLocale = false;
1141
+ if (config.versions && toParts.length > tIdx && config.versions.versions[toParts[tIdx]]) {
1142
+ hasVersion = true;
1143
+ tIdx++;
1144
+ }
1145
+ if (config.i18n && toParts.length > tIdx && config.i18n.locales[toParts[tIdx]]) {
1146
+ hasLocale = true;
1147
+ tIdx++;
1148
+ }
1149
+ const routeParts = toParts.slice(tIdx);
1150
+ const finalParts = [];
1151
+ if (config.versions) {
1152
+ if (hasVersion) {
1153
+ finalParts.push(toParts[0]);
1154
+ } else if (currentVersion) {
1155
+ finalParts.push(currentVersion);
1156
+ }
1157
+ }
1158
+ if (config.i18n) {
1159
+ if (hasLocale) {
1160
+ finalParts.push(toParts[hasVersion ? 1 : 0]);
1161
+ } else if (currentLocale) {
1162
+ finalParts.push(currentLocale);
1163
+ }
1164
+ }
1165
+ finalParts.push(...routeParts);
1166
+ let finalPath = `${basePath}/${finalParts.join("/")}`;
1167
+ if (finalPath.endsWith("/")) {
1168
+ finalPath = finalPath.slice(0, -1);
1169
+ }
1170
+ return finalPath === basePath ? basePath : finalPath;
1171
+ }
1172
+ var Link = React8.forwardRef(
1173
+ (props, ref) => {
1174
+ const {
1175
+ boltdocsPrefetch = "hover",
1176
+ onMouseEnter,
1177
+ onFocus,
1178
+ to,
1179
+ ...rest
1180
+ } = props;
1181
+ const localizedTo = useLocalizedTo(to);
1182
+ const { preload } = usePreload();
1183
+ const handleMouseEnter = (e) => {
1184
+ onMouseEnter?.(e);
1185
+ if (boltdocsPrefetch === "hover" && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1186
+ preload(localizedTo);
1187
+ }
1188
+ };
1189
+ const handleFocus = (e) => {
1190
+ onFocus?.(e);
1191
+ if (boltdocsPrefetch === "hover" && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1192
+ preload(localizedTo);
1193
+ }
1194
+ };
1195
+ return /* @__PURE__ */ jsx19(
1196
+ RouterLink,
1197
+ {
1198
+ ref,
1199
+ to: localizedTo,
1200
+ onMouseEnter: handleMouseEnter,
1201
+ onFocus: handleFocus,
1202
+ ...rest
1203
+ }
1204
+ );
1205
+ }
1206
+ );
1207
+ Link.displayName = "Link";
1208
+ var NavLink = React8.forwardRef(
1209
+ (props, ref) => {
1210
+ const {
1211
+ boltdocsPrefetch = "hover",
1212
+ onMouseEnter,
1213
+ onFocus,
1214
+ to,
1215
+ ...rest
1216
+ } = props;
1217
+ const localizedTo = useLocalizedTo(to);
1218
+ const { preload } = usePreload();
1219
+ const handleMouseEnter = (e) => {
1220
+ onMouseEnter?.(e);
1221
+ if (boltdocsPrefetch === "hover" && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1222
+ preload(localizedTo);
1223
+ }
1224
+ };
1225
+ const handleFocus = (e) => {
1226
+ onFocus?.(e);
1227
+ if (boltdocsPrefetch === "hover" && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1228
+ preload(localizedTo);
1229
+ }
1230
+ };
1231
+ return /* @__PURE__ */ jsx19(
1232
+ RouterNavLink,
1233
+ {
1234
+ ref,
1235
+ to: localizedTo,
1236
+ onMouseEnter: handleMouseEnter,
1237
+ onFocus: handleFocus,
1238
+ ...rest
1239
+ }
1240
+ );
1241
+ }
1242
+ );
1243
+ NavLink.displayName = "NavLink";
1244
+
1245
+ // src/client/theme/ui/Navbar/Navbar.tsx
1246
+ import { ChevronDown as ChevronDown3 } from "lucide-react";
1247
+
1248
+ // src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx
1249
+ import { useState as useState7, useRef as useRef3, useEffect as useEffect5 } from "react";
1250
+ import { Globe, ChevronDown } from "lucide-react";
1251
+ import { useNavigate, useLocation as useLocation8 } from "react-router-dom";
1252
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
1253
+ function getBaseFilePath(filePath, version, locale) {
1254
+ let path = filePath;
1255
+ if (version && (path === version || path.startsWith(version + "/"))) {
1256
+ path = path === version ? "index.md" : path.slice(version.length + 1);
1257
+ }
1258
+ if (locale && (path === locale || path.startsWith(locale + "/"))) {
1259
+ path = path === locale ? "index.md" : path.slice(locale.length + 1);
1260
+ }
1261
+ return path;
1262
+ }
1263
+ function LanguageSwitcher({
1264
+ i18n,
1265
+ currentLocale,
1266
+ allRoutes
1267
+ }) {
1268
+ const [isOpen, setIsOpen] = useState7(false);
1269
+ const dropdownRef = useRef3(null);
1270
+ const navigate = useNavigate();
1271
+ const location = useLocation8();
1272
+ useEffect5(() => {
1273
+ function handleClickOutside(event) {
1274
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1275
+ setIsOpen(false);
1276
+ }
1277
+ }
1278
+ document.addEventListener("mousedown", handleClickOutside);
1279
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1280
+ }, []);
1281
+ const handleSelect = (locale) => {
1282
+ setIsOpen(false);
1283
+ if (locale === currentLocale) return;
1284
+ const currentRoute = allRoutes.find((r) => r.path === location.pathname);
1285
+ let targetPath = "/";
1286
+ if (currentRoute) {
1287
+ const baseFile = getBaseFilePath(
1288
+ currentRoute.filePath,
1289
+ currentRoute.version,
1290
+ currentRoute.locale
1291
+ );
1292
+ const targetRoute = allRoutes.find(
1293
+ (r) => getBaseFilePath(r.filePath, r.version, r.locale) === baseFile && (r.locale || i18n.defaultLocale) === locale && r.version === currentRoute.version
1294
+ );
1295
+ if (targetRoute) {
1296
+ targetPath = targetRoute.path;
1297
+ } else {
1298
+ const defaultIndexRoute = allRoutes.find(
1299
+ (r) => getBaseFilePath(r.filePath, r.version, r.locale) === "index.md" && (r.locale || i18n.defaultLocale) === locale && r.version === currentRoute.version
1300
+ );
1301
+ targetPath = defaultIndexRoute ? defaultIndexRoute.path : locale === i18n.defaultLocale ? currentRoute.version ? `/${currentRoute.version}` : "/" : currentRoute.version ? `/${currentRoute.version}/${locale}` : `/${locale}`;
1302
+ }
1303
+ } else {
1304
+ targetPath = locale === i18n.defaultLocale ? "/" : `/${locale}`;
1305
+ }
1306
+ navigate(targetPath);
1307
+ };
1308
+ return /* @__PURE__ */ jsxs15("div", { className: "boltdocs-language-switcher", ref: dropdownRef, children: [
1309
+ /* @__PURE__ */ jsxs15(
1310
+ "button",
1311
+ {
1312
+ className: "language-btn",
1313
+ onClick: () => setIsOpen(!isOpen),
1314
+ "aria-label": "Switch language",
1315
+ "aria-expanded": isOpen,
1316
+ "aria-haspopup": "listbox",
1317
+ children: [
1318
+ /* @__PURE__ */ jsx20(Globe, { size: 18 }),
1319
+ /* @__PURE__ */ jsx20("span", { className: "language-label", children: i18n.locales[currentLocale] || currentLocale }),
1320
+ /* @__PURE__ */ jsx20(ChevronDown, { size: 14 })
1321
+ ]
1322
+ }
1323
+ ),
1324
+ isOpen && /* @__PURE__ */ jsx20("div", { className: "language-dropdown", children: Object.entries(i18n.locales).map(([key, label]) => /* @__PURE__ */ jsx20(
1325
+ "button",
1326
+ {
1327
+ className: `language-option ${key === currentLocale ? "active" : ""}`,
1328
+ onClick: () => handleSelect(key),
1329
+ children: label
1330
+ },
1331
+ key
1332
+ )) })
1333
+ ] });
1334
+ }
1335
+
1336
+ // src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx
1337
+ import { useState as useState8, useRef as useRef4, useEffect as useEffect6 } from "react";
1338
+ import { ChevronDown as ChevronDown2 } from "lucide-react";
1339
+ import { useNavigate as useNavigate2, useLocation as useLocation9 } from "react-router-dom";
1340
+ import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
1341
+ function getBaseFilePath2(filePath, version, locale) {
1342
+ let path = filePath;
1343
+ if (version && (path === version || path.startsWith(version + "/"))) {
1344
+ path = path === version ? "index.md" : path.slice(version.length + 1);
1345
+ }
1346
+ if (locale && (path === locale || path.startsWith(locale + "/"))) {
1347
+ path = path === locale ? "index.md" : path.slice(locale.length + 1);
1348
+ }
1349
+ return path;
1350
+ }
1351
+ function VersionSwitcher({
1352
+ versions,
1353
+ currentVersion,
1354
+ currentLocale,
1355
+ allRoutes
1356
+ }) {
1357
+ const [isOpen, setIsOpen] = useState8(false);
1358
+ const dropdownRef = useRef4(null);
1359
+ const navigate = useNavigate2();
1360
+ const location = useLocation9();
1361
+ useEffect6(() => {
1362
+ function handleClickOutside(event) {
1363
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1364
+ setIsOpen(false);
1365
+ }
1366
+ }
1367
+ document.addEventListener("mousedown", handleClickOutside);
1368
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1369
+ }, []);
1370
+ const handleSelect = (version) => {
1371
+ setIsOpen(false);
1372
+ if (version === currentVersion) return;
1373
+ const currentRoute = allRoutes.find((r) => r.path === location.pathname);
1374
+ let targetPath = `/docs/${version}`;
1375
+ if (currentRoute) {
1376
+ const baseFile = getBaseFilePath2(
1377
+ currentRoute.filePath,
1378
+ currentRoute.version,
1379
+ currentRoute.locale
1380
+ );
1381
+ const targetRoute = allRoutes.find(
1382
+ (r) => getBaseFilePath2(r.filePath, r.version, r.locale) === baseFile && (r.version || versions.defaultVersion) === version && (currentLocale ? r.locale === currentLocale : !r.locale)
1383
+ );
1384
+ if (targetRoute) {
1385
+ targetPath = targetRoute.path;
1386
+ } else {
1387
+ const versionIndexRoute = allRoutes.find(
1388
+ (r) => getBaseFilePath2(r.filePath, r.version, r.locale) === "index.md" && (r.version || versions.defaultVersion) === version && (currentLocale ? r.locale === currentLocale : !r.locale)
1389
+ );
1390
+ targetPath = versionIndexRoute ? versionIndexRoute.path : `/docs/${version}${currentLocale ? `/${currentLocale}` : ""}`;
1391
+ }
1392
+ }
1393
+ navigate(targetPath);
1394
+ };
1395
+ return /* @__PURE__ */ jsxs16(
1396
+ "div",
1397
+ {
1398
+ className: "boltdocs-version-switcher",
1399
+ ref: dropdownRef,
1400
+ style: { position: "relative", display: "flex", alignItems: "center" },
1401
+ children: [
1402
+ /* @__PURE__ */ jsxs16(
1403
+ "button",
1404
+ {
1405
+ className: "navbar-version",
1406
+ onClick: () => setIsOpen(!isOpen),
1407
+ "aria-label": "Switch version",
1408
+ "aria-expanded": isOpen,
1409
+ "aria-haspopup": "listbox",
1410
+ style: {
1411
+ fontFamily: "inherit",
1412
+ padding: "0.25rem 0.5rem",
1413
+ marginLeft: "0.5rem"
1414
+ },
1415
+ children: [
1416
+ /* @__PURE__ */ jsx21("span", { children: versions.versions[currentVersion] || currentVersion }),
1417
+ /* @__PURE__ */ jsx21(ChevronDown2, { size: 14 })
1418
+ ]
1419
+ }
1420
+ ),
1421
+ isOpen && /* @__PURE__ */ jsx21(
1422
+ "div",
1423
+ {
1424
+ className: "language-dropdown",
1425
+ style: {
1426
+ left: "0.5rem",
1427
+ right: "auto",
1428
+ minWidth: "150px",
1429
+ top: "calc(100% + 8px)"
1430
+ },
1431
+ children: Object.entries(versions.versions).map(([key, label]) => /* @__PURE__ */ jsx21(
1432
+ "button",
1433
+ {
1434
+ className: `language-option ${key === currentVersion ? "active" : ""}`,
1435
+ onClick: () => handleSelect(key),
1436
+ children: label
1437
+ },
1438
+ key
1439
+ ))
1440
+ }
1441
+ )
1442
+ ]
1443
+ }
1444
+ );
1445
+ }
1446
+
1447
+ // src/client/theme/ui/ThemeToggle/ThemeToggle.tsx
1448
+ import { useEffect as useEffect7, useState as useState9 } from "react";
1449
+ import { Sun, Moon } from "lucide-react";
1450
+ import { jsx as jsx22 } from "react/jsx-runtime";
1451
+ function ThemeToggle() {
1452
+ const [theme, setTheme] = useState9("dark");
1453
+ const [mounted, setMounted] = useState9(false);
1454
+ useEffect7(() => {
1455
+ setMounted(true);
1456
+ const stored = localStorage.getItem("boltdocs-theme");
1457
+ if (stored === "light" || stored === "dark") {
1458
+ setTheme(stored);
1459
+ } else {
1460
+ const prefersDark = window.matchMedia(
1461
+ "(prefers-color-scheme: dark)"
1462
+ ).matches;
1463
+ setTheme(prefersDark ? "dark" : "light");
1464
+ }
1465
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1466
+ const handleChange = (e) => {
1467
+ if (!localStorage.getItem("boltdocs-theme")) {
1468
+ setTheme(e.matches ? "dark" : "light");
1469
+ }
1470
+ };
1471
+ mediaQuery.addEventListener("change", handleChange);
1472
+ return () => mediaQuery.removeEventListener("change", handleChange);
1473
+ }, []);
1474
+ useEffect7(() => {
1475
+ if (!mounted) return;
1476
+ const root = document.documentElement;
1477
+ if (theme === "light") {
1478
+ root.classList.add("theme-light");
1479
+ root.dataset.theme = "light";
1480
+ } else {
1481
+ root.classList.remove("theme-light");
1482
+ root.dataset.theme = "dark";
1483
+ }
1484
+ }, [theme, mounted]);
1485
+ const toggleTheme = () => {
1486
+ const newTheme = theme === "dark" ? "light" : "dark";
1487
+ setTheme(newTheme);
1488
+ localStorage.setItem("boltdocs-theme", newTheme);
1489
+ };
1490
+ if (!mounted) {
1491
+ return /* @__PURE__ */ jsx22("button", { className: "navbar-icon-btn", "aria-label": "Toggle theme", disabled: true, children: /* @__PURE__ */ jsx22("span", { style: { width: 20, height: 20, display: "inline-block" } }) });
1492
+ }
1493
+ return /* @__PURE__ */ jsx22(
1494
+ "button",
1495
+ {
1496
+ className: "navbar-icon-btn",
1497
+ onClick: toggleTheme,
1498
+ "aria-label": "Toggle theme",
1499
+ title: `Switch to ${theme === "dark" ? "light" : "dark"} theme`,
1500
+ children: theme === "dark" ? /* @__PURE__ */ jsx22(Sun, { size: 20 }) : /* @__PURE__ */ jsx22(Moon, { size: 20 })
1501
+ }
1502
+ );
1503
+ }
1504
+
1505
+ // src/client/theme/icons/discord.tsx
1506
+ import { jsx as jsx23 } from "react/jsx-runtime";
1507
+ var Discord = (props) => /* @__PURE__ */ jsx23("svg", { ...props, viewBox: "0 0 256 199", preserveAspectRatio: "xMidYMid", children: /* @__PURE__ */ jsx23(
1508
+ "path",
1509
+ {
1510
+ d: "M216.856 16.597A208.502 208.502 0 0 0 164.042 0c-2.275 4.113-4.933 9.645-6.766 14.046-19.692-2.961-39.203-2.961-58.533 0-1.832-4.4-4.55-9.933-6.846-14.046a207.809 207.809 0 0 0-52.855 16.638C5.618 67.147-3.443 116.4 1.087 164.956c22.169 16.555 43.653 26.612 64.775 33.193A161.094 161.094 0 0 0 79.735 175.3a136.413 136.413 0 0 1-21.846-10.632 108.636 108.636 0 0 0 5.356-4.237c42.122 19.702 87.89 19.702 129.51 0a131.66 131.66 0 0 0 5.355 4.237 136.07 136.07 0 0 1-21.886 10.653c4.006 8.02 8.638 15.67 13.873 22.848 21.142-6.58 42.646-16.637 64.815-33.213 5.316-56.288-9.08-105.09-38.056-148.36ZM85.474 135.095c-12.645 0-23.015-11.805-23.015-26.18s10.149-26.2 23.015-26.2c12.867 0 23.236 11.804 23.015 26.2.02 14.375-10.148 26.18-23.015 26.18Zm85.051 0c-12.645 0-23.014-11.805-23.014-26.18s10.148-26.2 23.014-26.2c12.867 0 23.236 11.804 23.015 26.2 0 14.375-10.148 26.18-23.015 26.18Z",
1511
+ fill: "currentColor"
1512
+ }
1513
+ ) });
1514
+
1515
+ // src/client/theme/icons/twitter.tsx
1516
+ import { jsx as jsx24 } from "react/jsx-runtime";
1517
+ var XformerlyTwitter = (props) => /* @__PURE__ */ jsx24("svg", { ...props, fill: "none", viewBox: "0 0 1200 1227", children: /* @__PURE__ */ jsx24(
1518
+ "path",
1519
+ {
1520
+ fill: "currentColor",
1521
+ d: "M714.163 519.284 1160.89 0h-105.86L667.137 450.887 357.328 0H0l468.492 681.821L0 1226.37h105.866l409.625-476.152 327.181 476.152H1200L714.137 519.284h.026ZM569.165 687.828l-47.468-67.894-377.686-540.24h162.604l304.797 435.991 47.468 67.894 396.2 566.721H892.476L569.165 687.854v-.026Z"
1522
+ }
1523
+ ) });
1524
+
1525
+ // src/client/theme/ui/Navbar/Navbar.tsx
1526
+ import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
1527
+ var SearchDialog = React11.lazy(
1528
+ () => import("./SearchDialog-FTOQZ763.mjs").then((m) => ({ default: m.SearchDialog }))
1529
+ );
1530
+ var ICON_MAP3 = {
1531
+ discord: Discord,
1532
+ x: XformerlyTwitter
1533
+ };
1534
+ function Navbar({
1535
+ config,
1536
+ routes,
1537
+ allRoutes,
1538
+ currentLocale,
1539
+ currentVersion
1540
+ }) {
1541
+ const title = config.themeConfig?.title || "Boltdocs";
1542
+ const navItems = config.themeConfig?.navbar || [];
1543
+ const socialLinks = config.themeConfig?.socialLinks || [];
1544
+ return /* @__PURE__ */ jsx25("header", { className: "boltdocs-navbar", children: /* @__PURE__ */ jsxs17("div", { className: "navbar-container", children: [
1545
+ /* @__PURE__ */ jsxs17("div", { className: "navbar-left", children: [
1546
+ /* @__PURE__ */ jsx25("div", { className: "navbar-logo", children: /* @__PURE__ */ jsxs17(Link, { to: "/", children: [
1547
+ config.themeConfig?.logo ? config.themeConfig.logo.trim().startsWith("<svg") ? /* @__PURE__ */ jsx25(
1548
+ "span",
1549
+ {
1550
+ className: "navbar-logo-svg",
1551
+ dangerouslySetInnerHTML: {
1552
+ __html: config.themeConfig.logo
1553
+ }
1554
+ }
1555
+ ) : /* @__PURE__ */ jsx25(
1556
+ "img",
1557
+ {
1558
+ src: config.themeConfig.logo,
1559
+ alt: title,
1560
+ className: "navbar-logo-img"
1561
+ }
1562
+ ) : null,
1563
+ title
1564
+ ] }) }),
1565
+ config.versions && currentVersion && allRoutes ? /* @__PURE__ */ jsx25(
1566
+ VersionSwitcher,
1567
+ {
1568
+ versions: config.versions,
1569
+ currentVersion,
1570
+ currentLocale,
1571
+ allRoutes
1572
+ }
1573
+ ) : config.themeConfig?.version ? /* @__PURE__ */ jsxs17("div", { className: "navbar-version", children: [
1574
+ config.themeConfig.version,
1575
+ " ",
1576
+ /* @__PURE__ */ jsx25(ChevronDown3, { size: 14 })
1577
+ ] }) : null,
1578
+ /* @__PURE__ */ jsx25("nav", { className: "navbar-links", "aria-label": "Top Navigation", children: navItems.map((item, i) => /* @__PURE__ */ jsx25(Link, { to: item.link, children: item.text }, i)) })
1579
+ ] }),
1580
+ /* @__PURE__ */ jsxs17("div", { className: "navbar-right", children: [
1581
+ /* @__PURE__ */ jsx25(
1582
+ React11.Suspense,
1583
+ {
1584
+ fallback: /* @__PURE__ */ jsx25("div", { className: "navbar-search-placeholder" }),
1585
+ children: /* @__PURE__ */ jsx25(SearchDialog, { routes: routes || [] })
1586
+ }
1587
+ ),
1588
+ config.i18n && currentLocale && allRoutes && /* @__PURE__ */ jsx25(
1589
+ LanguageSwitcher,
1590
+ {
1591
+ i18n: config.i18n,
1592
+ currentLocale,
1593
+ allRoutes
1594
+ }
1595
+ ),
1596
+ /* @__PURE__ */ jsx25(ThemeToggle, {}),
1597
+ config.themeConfig?.githubRepo && /* @__PURE__ */ jsx25(GithubStars, { repo: config.themeConfig.githubRepo }),
1598
+ socialLinks.length > 0 && /* @__PURE__ */ jsx25("div", { className: "navbar-divider" }),
1599
+ /* @__PURE__ */ jsx25("div", { className: "navbar-icons", children: socialLinks.map((link, i) => {
1600
+ const IconComp = ICON_MAP3[link.icon.toLowerCase()];
1601
+ return /* @__PURE__ */ jsx25(
1602
+ "a",
1603
+ {
1604
+ href: link.link,
1605
+ target: "_blank",
1606
+ rel: "noopener noreferrer",
1607
+ className: "navbar-icon-btn",
1608
+ "aria-label": link.icon,
1609
+ children: IconComp ? /* @__PURE__ */ jsx25(IconComp, {}) : /* @__PURE__ */ jsx25("span", { children: link.icon })
1610
+ },
1611
+ i
1612
+ );
1613
+ }) })
1614
+ ] })
1615
+ ] }) });
1616
+ }
1617
+
1618
+ export {
1619
+ Link,
1620
+ Navbar,
1621
+ Sidebar,
1622
+ OnThisPage,
1623
+ Head,
1624
+ Breadcrumbs,
1625
+ BackgroundGradient,
1626
+ ThemeLayout,
1627
+ NotFound,
1628
+ Loading,
1629
+ Button,
1630
+ Badge,
1631
+ Cards,
1632
+ Card,
1633
+ Tab,
1634
+ Tabs,
1635
+ Admonition,
1636
+ Note,
1637
+ Tip,
1638
+ Warning,
1639
+ Danger,
1640
+ InfoBox,
1641
+ List,
1642
+ AppShell,
1643
+ createBoltdocsApp
1644
+ };