boltdocs 1.6.0 → 1.7.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 (51) hide show
  1. package/dist/{SearchDialog-3QICRMWF.css → SearchDialog-UOAW6IR3.css} +270 -113
  2. package/dist/{SearchDialog-J3KNRGNO.mjs → SearchDialog-YOXMFGH6.mjs} +1 -1
  3. package/dist/{chunk-HSPDIRTW.mjs → chunk-MULKZFVN.mjs} +872 -758
  4. package/dist/client/index.css +270 -113
  5. package/dist/client/index.d.mts +21 -7
  6. package/dist/client/index.d.ts +21 -7
  7. package/dist/client/index.js +637 -499
  8. package/dist/client/index.mjs +17 -1
  9. package/dist/client/ssr.css +270 -113
  10. package/dist/client/ssr.d.mts +3 -1
  11. package/dist/client/ssr.d.ts +3 -1
  12. package/dist/client/ssr.js +533 -412
  13. package/dist/client/ssr.mjs +3 -2
  14. package/dist/{config-DkZg5aCf.d.ts → config-D68h41CA.d.mts} +21 -2
  15. package/dist/{config-DkZg5aCf.d.mts → config-D68h41CA.d.ts} +21 -2
  16. package/dist/node/index.d.mts +10 -2
  17. package/dist/node/index.d.ts +10 -2
  18. package/dist/node/index.js +45 -21
  19. package/dist/node/index.mjs +45 -21
  20. package/dist/{types-DGIo1VKD.d.mts → types-CviV0GbX.d.mts} +13 -0
  21. package/dist/{types-DGIo1VKD.d.ts → types-CviV0GbX.d.ts} +13 -0
  22. package/package.json +1 -1
  23. package/src/client/app/index.tsx +8 -4
  24. package/src/client/index.ts +2 -0
  25. package/src/client/ssr.tsx +4 -1
  26. package/src/client/theme/components/mdx/Table.tsx +53 -0
  27. package/src/client/theme/components/mdx/index.ts +3 -0
  28. package/src/client/theme/components/mdx/mdx-components.css +49 -0
  29. package/src/client/theme/styles/markdown.css +8 -3
  30. package/src/client/theme/styles/variables.css +10 -9
  31. package/src/client/theme/ui/Layout/Layout.tsx +2 -10
  32. package/src/client/theme/ui/Layout/base.css +15 -3
  33. package/src/client/theme/ui/Link/Link.tsx +2 -2
  34. package/src/client/theme/ui/Link/LinkPreview.tsx +9 -14
  35. package/src/client/theme/ui/Link/link-preview.css +30 -27
  36. package/src/client/theme/ui/Navbar/Navbar.tsx +65 -17
  37. package/src/client/theme/ui/Navbar/Tabs.tsx +74 -0
  38. package/src/client/theme/ui/Navbar/navbar.css +111 -5
  39. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +65 -49
  40. package/src/client/theme/ui/OnThisPage/toc.css +30 -10
  41. package/src/client/theme/ui/Sidebar/Sidebar.tsx +97 -57
  42. package/src/client/theme/ui/Sidebar/sidebar.css +61 -67
  43. package/src/client/types.ts +10 -0
  44. package/src/node/config.ts +19 -1
  45. package/src/node/plugin/entry.ts +5 -1
  46. package/src/node/plugin/index.ts +2 -1
  47. package/src/node/routes/index.ts +12 -1
  48. package/src/node/routes/parser.ts +21 -7
  49. package/src/node/routes/types.ts +9 -1
  50. package/src/node/ssg/index.ts +2 -1
  51. package/src/node/ssg/options.ts +2 -0
@@ -4,20 +4,342 @@ import {
4
4
  } from "./chunk-FMTOYQLO.mjs";
5
5
 
6
6
  // src/client/theme/ui/Navbar/Navbar.tsx
7
- import React10 from "react";
7
+ import { Suspense as Suspense2, lazy as lazy2 } from "react";
8
+ import { Link as Link2, useLocation as useLocation11 } from "react-router-dom";
9
+ import { ChevronDown as ChevronDown3 } from "lucide-react";
10
+
11
+ // src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx
12
+ import { useState, useRef, useEffect } from "react";
13
+ import { Globe, ChevronDown } from "lucide-react";
14
+ import { useNavigate, useLocation } from "react-router-dom";
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ function getBaseFilePath(filePath, version, locale) {
17
+ let path = filePath;
18
+ if (version && (path === version || path.startsWith(version + "/"))) {
19
+ path = path === version ? "index.md" : path.slice(version.length + 1);
20
+ }
21
+ if (locale && (path === locale || path.startsWith(locale + "/"))) {
22
+ path = path === locale ? "index.md" : path.slice(locale.length + 1);
23
+ }
24
+ return path;
25
+ }
26
+ function LanguageSwitcher({
27
+ i18n,
28
+ currentLocale,
29
+ allRoutes
30
+ }) {
31
+ const [isOpen, setIsOpen] = useState(false);
32
+ const dropdownRef = useRef(null);
33
+ const navigate = useNavigate();
34
+ const location = useLocation();
35
+ useEffect(() => {
36
+ function handleClickOutside(event) {
37
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
38
+ setIsOpen(false);
39
+ }
40
+ }
41
+ document.addEventListener("mousedown", handleClickOutside);
42
+ return () => document.removeEventListener("mousedown", handleClickOutside);
43
+ }, []);
44
+ const handleSelect = (locale) => {
45
+ setIsOpen(false);
46
+ if (locale === currentLocale) return;
47
+ const currentRoute = allRoutes.find((r) => r.path === location.pathname);
48
+ let targetPath = "/";
49
+ if (currentRoute) {
50
+ const baseFile = getBaseFilePath(
51
+ currentRoute.filePath,
52
+ currentRoute.version,
53
+ currentRoute.locale
54
+ );
55
+ const targetRoute = allRoutes.find(
56
+ (r) => getBaseFilePath(r.filePath, r.version, r.locale) === baseFile && (r.locale || i18n.defaultLocale) === locale && r.version === currentRoute.version
57
+ );
58
+ if (targetRoute) {
59
+ targetPath = targetRoute.path;
60
+ } else {
61
+ const defaultIndexRoute = allRoutes.find(
62
+ (r) => getBaseFilePath(r.filePath, r.version, r.locale) === "index.md" && (r.locale || i18n.defaultLocale) === locale && r.version === currentRoute.version
63
+ );
64
+ targetPath = defaultIndexRoute ? defaultIndexRoute.path : locale === i18n.defaultLocale ? currentRoute.version ? `/${currentRoute.version}` : "/" : currentRoute.version ? `/${currentRoute.version}/${locale}` : `/${locale}`;
65
+ }
66
+ } else {
67
+ targetPath = locale === i18n.defaultLocale ? "/" : `/${locale}`;
68
+ }
69
+ navigate(targetPath);
70
+ };
71
+ return /* @__PURE__ */ jsxs("div", { className: "boltdocs-language-switcher", ref: dropdownRef, children: [
72
+ /* @__PURE__ */ jsxs(
73
+ "button",
74
+ {
75
+ className: "language-btn",
76
+ onClick: () => setIsOpen(!isOpen),
77
+ "aria-label": "Switch language",
78
+ "aria-expanded": isOpen,
79
+ "aria-haspopup": "listbox",
80
+ children: [
81
+ /* @__PURE__ */ jsx(Globe, { size: 18 }),
82
+ /* @__PURE__ */ jsx("span", { className: "language-label", children: i18n.locales[currentLocale] || currentLocale }),
83
+ /* @__PURE__ */ jsx(ChevronDown, { size: 14 })
84
+ ]
85
+ }
86
+ ),
87
+ isOpen && /* @__PURE__ */ jsx("div", { className: "language-dropdown", children: Object.entries(i18n.locales).map(([key, label]) => /* @__PURE__ */ jsx(
88
+ "button",
89
+ {
90
+ className: `language-option ${key === currentLocale ? "active" : ""}`,
91
+ onClick: () => handleSelect(key),
92
+ children: label
93
+ },
94
+ key
95
+ )) })
96
+ ] });
97
+ }
98
+
99
+ // src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx
100
+ import { useState as useState2, useRef as useRef2, useEffect as useEffect2 } from "react";
101
+ import { ChevronDown as ChevronDown2 } from "lucide-react";
102
+ import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
103
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
104
+ function getBaseFilePath2(filePath, version, locale) {
105
+ let path = filePath;
106
+ if (version && (path === version || path.startsWith(version + "/"))) {
107
+ path = path === version ? "index.md" : path.slice(version.length + 1);
108
+ }
109
+ if (locale && (path === locale || path.startsWith(locale + "/"))) {
110
+ path = path === locale ? "index.md" : path.slice(locale.length + 1);
111
+ }
112
+ return path;
113
+ }
114
+ function VersionSwitcher({
115
+ versions,
116
+ currentVersion,
117
+ currentLocale,
118
+ allRoutes
119
+ }) {
120
+ const [isOpen, setIsOpen] = useState2(false);
121
+ const dropdownRef = useRef2(null);
122
+ const navigate = useNavigate2();
123
+ const location = useLocation2();
124
+ useEffect2(() => {
125
+ function handleClickOutside(event) {
126
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
127
+ setIsOpen(false);
128
+ }
129
+ }
130
+ document.addEventListener("mousedown", handleClickOutside);
131
+ return () => document.removeEventListener("mousedown", handleClickOutside);
132
+ }, []);
133
+ const handleSelect = (version) => {
134
+ setIsOpen(false);
135
+ if (version === currentVersion) return;
136
+ const currentRoute = allRoutes.find((r) => r.path === location.pathname);
137
+ let targetPath = `/docs/${version}`;
138
+ if (currentRoute) {
139
+ const baseFile = getBaseFilePath2(
140
+ currentRoute.filePath,
141
+ currentRoute.version,
142
+ currentRoute.locale
143
+ );
144
+ const targetRoute = allRoutes.find(
145
+ (r) => getBaseFilePath2(r.filePath, r.version, r.locale) === baseFile && (r.version || versions.defaultVersion) === version && (currentLocale ? r.locale === currentLocale : !r.locale)
146
+ );
147
+ if (targetRoute) {
148
+ targetPath = targetRoute.path;
149
+ } else {
150
+ const versionIndexRoute = allRoutes.find(
151
+ (r) => getBaseFilePath2(r.filePath, r.version, r.locale) === "index.md" && (r.version || versions.defaultVersion) === version && (currentLocale ? r.locale === currentLocale : !r.locale)
152
+ );
153
+ targetPath = versionIndexRoute ? versionIndexRoute.path : `/docs/${version}${currentLocale ? `/${currentLocale}` : ""}`;
154
+ }
155
+ }
156
+ navigate(targetPath);
157
+ };
158
+ return /* @__PURE__ */ jsxs2(
159
+ "div",
160
+ {
161
+ className: "boltdocs-version-switcher",
162
+ ref: dropdownRef,
163
+ style: { position: "relative", display: "flex", alignItems: "center" },
164
+ children: [
165
+ /* @__PURE__ */ jsxs2(
166
+ "button",
167
+ {
168
+ className: "navbar-version",
169
+ onClick: () => setIsOpen(!isOpen),
170
+ "aria-label": "Switch version",
171
+ "aria-expanded": isOpen,
172
+ "aria-haspopup": "listbox",
173
+ style: {
174
+ fontFamily: "inherit",
175
+ padding: "0.25rem 0.5rem",
176
+ marginLeft: "0.5rem"
177
+ },
178
+ children: [
179
+ /* @__PURE__ */ jsx2("span", { children: versions.versions[currentVersion] || currentVersion }),
180
+ /* @__PURE__ */ jsx2(ChevronDown2, { size: 14 })
181
+ ]
182
+ }
183
+ ),
184
+ isOpen && /* @__PURE__ */ jsx2(
185
+ "div",
186
+ {
187
+ className: "language-dropdown",
188
+ style: {
189
+ left: "0.5rem",
190
+ right: "auto",
191
+ minWidth: "150px",
192
+ top: "calc(100% + 8px)"
193
+ },
194
+ children: Object.entries(versions.versions).map(([key, label]) => /* @__PURE__ */ jsx2(
195
+ "button",
196
+ {
197
+ className: `language-option ${key === currentVersion ? "active" : ""}`,
198
+ onClick: () => handleSelect(key),
199
+ children: label
200
+ },
201
+ key
202
+ ))
203
+ }
204
+ )
205
+ ]
206
+ }
207
+ );
208
+ }
209
+
210
+ // src/client/theme/ui/ThemeToggle/ThemeToggle.tsx
211
+ import { useEffect as useEffect3, useState as useState3 } from "react";
212
+ import { Sun, Moon } from "lucide-react";
213
+ import { jsx as jsx3 } from "react/jsx-runtime";
214
+ function ThemeToggle() {
215
+ const [theme, setTheme] = useState3("dark");
216
+ const [mounted, setMounted] = useState3(false);
217
+ useEffect3(() => {
218
+ setMounted(true);
219
+ const stored = localStorage.getItem("boltdocs-theme");
220
+ if (stored === "light" || stored === "dark") {
221
+ setTheme(stored);
222
+ } else {
223
+ const prefersDark = window.matchMedia(
224
+ "(prefers-color-scheme: dark)"
225
+ ).matches;
226
+ setTheme(prefersDark ? "dark" : "light");
227
+ }
228
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
229
+ const handleChange = (e) => {
230
+ if (!localStorage.getItem("boltdocs-theme")) {
231
+ setTheme(e.matches ? "dark" : "light");
232
+ }
233
+ };
234
+ mediaQuery.addEventListener("change", handleChange);
235
+ return () => mediaQuery.removeEventListener("change", handleChange);
236
+ }, []);
237
+ useEffect3(() => {
238
+ if (!mounted) return;
239
+ const root = document.documentElement;
240
+ if (theme === "light") {
241
+ root.classList.add("theme-light");
242
+ root.dataset.theme = "light";
243
+ } else {
244
+ root.classList.remove("theme-light");
245
+ root.dataset.theme = "dark";
246
+ }
247
+ }, [theme, mounted]);
248
+ const toggleTheme = () => {
249
+ const newTheme = theme === "dark" ? "light" : "dark";
250
+ setTheme(newTheme);
251
+ localStorage.setItem("boltdocs-theme", newTheme);
252
+ };
253
+ if (!mounted) {
254
+ return /* @__PURE__ */ jsx3("button", { className: "navbar-icon-btn", "aria-label": "Toggle theme", disabled: true, children: /* @__PURE__ */ jsx3("span", { style: { width: 20, height: 20, display: "inline-block" } }) });
255
+ }
256
+ return /* @__PURE__ */ jsx3(
257
+ "button",
258
+ {
259
+ className: "navbar-icon-btn",
260
+ onClick: toggleTheme,
261
+ "aria-label": "Toggle theme",
262
+ title: `Switch to ${theme === "dark" ? "light" : "dark"} theme`,
263
+ children: theme === "dark" ? /* @__PURE__ */ jsx3(Sun, { size: 20 }) : /* @__PURE__ */ jsx3(Moon, { size: 20 })
264
+ }
265
+ );
266
+ }
267
+
268
+ // src/client/theme/icons/discord.tsx
269
+ import { jsx as jsx4 } from "react/jsx-runtime";
270
+ var Discord = (props) => /* @__PURE__ */ jsx4("svg", { ...props, viewBox: "0 0 256 199", preserveAspectRatio: "xMidYMid", children: /* @__PURE__ */ jsx4(
271
+ "path",
272
+ {
273
+ 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",
274
+ fill: "currentColor"
275
+ }
276
+ ) });
277
+
278
+ // src/client/theme/icons/twitter.tsx
279
+ import { jsx as jsx5 } from "react/jsx-runtime";
280
+ var XformerlyTwitter = (props) => /* @__PURE__ */ jsx5("svg", { ...props, fill: "none", viewBox: "0 0 1200 1227", children: /* @__PURE__ */ jsx5(
281
+ "path",
282
+ {
283
+ fill: "currentColor",
284
+ 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"
285
+ }
286
+ ) });
287
+
288
+ // src/client/theme/ui/Navbar/GithubStars.tsx
289
+ import { useEffect as useEffect4, useState as useState4 } from "react";
290
+
291
+ // src/client/theme/icons/github.tsx
292
+ import { jsx as jsx6 } from "react/jsx-runtime";
293
+ var GitHub = (props) => /* @__PURE__ */ jsx6("svg", { ...props, viewBox: "0 0 1024 1024", fill: "none", children: /* @__PURE__ */ jsx6(
294
+ "path",
295
+ {
296
+ fillRule: "evenodd",
297
+ clipRule: "evenodd",
298
+ 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",
299
+ transform: "scale(64)",
300
+ fill: "currentColor"
301
+ }
302
+ ) });
303
+
304
+ // src/client/theme/ui/Navbar/GithubStars.tsx
305
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
306
+ function GithubStars({ repo }) {
307
+ const [stars, setStars] = useState4(null);
308
+ useEffect4(() => {
309
+ if (repo) {
310
+ getStarsRepo(repo).then((stars2) => setStars(stars2)).catch(() => setStars("0"));
311
+ }
312
+ }, [repo]);
313
+ return /* @__PURE__ */ jsxs3(
314
+ "a",
315
+ {
316
+ href: `https://github.com/${repo}`,
317
+ target: "_blank",
318
+ rel: "noopener noreferrer",
319
+ className: "navbar-github-stars",
320
+ children: [
321
+ /* @__PURE__ */ jsx7(GitHub, {}),
322
+ stars && /* @__PURE__ */ jsx7("span", { children: stars })
323
+ ]
324
+ }
325
+ );
326
+ }
327
+
328
+ // src/client/theme/ui/Navbar/Tabs.tsx
329
+ import { useLocation as useLocation10 } from "react-router-dom";
8
330
 
9
331
  // src/client/theme/ui/Link/Link.tsx
10
- import React7 from "react";
332
+ import React8 from "react";
11
333
  import {
12
334
  Link as RouterLink,
13
335
  NavLink as RouterNavLink,
14
- useLocation as useLocation7,
15
- useNavigate
336
+ useLocation as useLocation9,
337
+ useNavigate as useNavigate3
16
338
  } from "react-router-dom";
17
339
 
18
340
  // src/client/app/preload.tsx
19
341
  import { createContext, useContext, useCallback } from "react";
20
- import { jsx } from "react/jsx-runtime";
342
+ import { jsx as jsx8 } from "react/jsx-runtime";
21
343
  var PreloadContext = createContext({
22
344
  preload: () => {
23
345
  },
@@ -50,74 +372,34 @@ function PreloadProvider({
50
372
  },
51
373
  [routes, modules]
52
374
  );
53
- return /* @__PURE__ */ jsx(PreloadContext.Provider, { value: { preload, routes }, children });
375
+ return /* @__PURE__ */ jsx8(PreloadContext.Provider, { value: { preload, routes }, children });
54
376
  }
55
377
 
56
378
  // src/client/app/index.tsx
57
- import React6, { useEffect as useEffect4, useState as useState6 } from "react";
379
+ import React7, { useEffect as useEffect7, useState as useState9 } from "react";
58
380
  import ReactDOM from "react-dom/client";
59
381
  import {
60
382
  BrowserRouter,
61
383
  Routes,
62
384
  Route,
63
385
  Outlet,
64
- useLocation as useLocation6
386
+ useLocation as useLocation8
65
387
  } from "react-router-dom";
66
388
 
67
389
  // src/client/theme/ui/Layout/Layout.tsx
68
- import React4, { useState as useState4 } from "react";
69
- import { useLocation as useLocation5 } from "react-router-dom";
70
- import { ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3 } from "lucide-react";
71
-
72
- // src/client/theme/ui/Navbar/GithubStars.tsx
73
- import { useEffect, useState } from "react";
74
-
75
- // src/client/theme/icons/github.tsx
76
- import { jsx as jsx2 } from "react/jsx-runtime";
77
- var GitHub = (props) => /* @__PURE__ */ jsx2("svg", { ...props, viewBox: "0 0 1024 1024", fill: "none", children: /* @__PURE__ */ jsx2(
78
- "path",
79
- {
80
- fillRule: "evenodd",
81
- clipRule: "evenodd",
82
- 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",
83
- transform: "scale(64)",
84
- fill: "currentColor"
85
- }
86
- ) });
87
-
88
- // src/client/theme/ui/Navbar/GithubStars.tsx
89
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
90
- function GithubStars({ repo }) {
91
- const [stars, setStars] = useState(null);
92
- useEffect(() => {
93
- if (repo) {
94
- getStarsRepo(repo).then((stars2) => setStars(stars2)).catch(() => setStars("0"));
95
- }
96
- }, [repo]);
97
- return /* @__PURE__ */ jsxs(
98
- "a",
99
- {
100
- href: `https://github.com/${repo}`,
101
- target: "_blank",
102
- rel: "noopener noreferrer",
103
- className: "navbar-github-stars",
104
- children: [
105
- /* @__PURE__ */ jsx3(GitHub, {}),
106
- stars && /* @__PURE__ */ jsx3("span", { children: stars })
107
- ]
108
- }
109
- );
110
- }
390
+ import React5 from "react";
391
+ import { useLocation as useLocation7 } from "react-router-dom";
392
+ import { ChevronLeft, ChevronRight as ChevronRight3 } from "lucide-react";
111
393
 
112
394
  // src/client/theme/ui/Sidebar/Sidebar.tsx
113
- import { useState as useState2 } from "react";
114
- import { useLocation } from "react-router-dom";
395
+ import { useState as useState5 } from "react";
396
+ import { useLocation as useLocation3 } from "react-router-dom";
115
397
 
116
398
  // src/client/theme/ui/PoweredBy/PoweredBy.tsx
117
399
  import { Zap } from "lucide-react";
118
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
400
+ import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
119
401
  function PoweredBy() {
120
- return /* @__PURE__ */ jsx4("div", { className: "powered-by-container", children: /* @__PURE__ */ jsxs2(
402
+ return /* @__PURE__ */ jsx9("div", { className: "powered-by-container", children: /* @__PURE__ */ jsxs4(
121
403
  "a",
122
404
  {
123
405
  href: "https://github.com/jesusalcaladev/boltdocs",
@@ -125,17 +407,18 @@ function PoweredBy() {
125
407
  rel: "noopener noreferrer",
126
408
  className: "powered-by-link",
127
409
  children: [
128
- /* @__PURE__ */ jsx4(Zap, { className: "powered-by-icon", size: 12, fill: "currentColor" }),
129
- /* @__PURE__ */ jsx4("span", { children: "Powered by" }),
130
- /* @__PURE__ */ jsx4("span", { className: "powered-by-brand", children: "LiteDocs" })
410
+ /* @__PURE__ */ jsx9(Zap, { className: "powered-by-icon", size: 12, fill: "currentColor" }),
411
+ /* @__PURE__ */ jsx9("span", { children: "Powered by" }),
412
+ /* @__PURE__ */ jsx9("span", { className: "powered-by-brand", children: "LiteDocs" })
131
413
  ]
132
414
  }
133
415
  ) });
134
416
  }
135
417
 
136
418
  // src/client/theme/ui/Sidebar/Sidebar.tsx
137
- import { ChevronRight, PanelLeft } from "lucide-react";
138
- import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
419
+ import { ChevronRight } from "lucide-react";
420
+ import * as LucideIcons from "lucide-react";
421
+ import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
139
422
  function renderBadge(badgeRaw) {
140
423
  if (!badgeRaw) return null;
141
424
  let text = "";
@@ -156,7 +439,6 @@ function renderBadge(badgeRaw) {
156
439
  }
157
440
  }
158
441
  if (!text) return null;
159
- if (!text) return null;
160
442
  let typeClass = "badge-default";
161
443
  const lowerText = text.toLowerCase();
162
444
  if (lowerText === "new") {
@@ -166,18 +448,51 @@ function renderBadge(badgeRaw) {
166
448
  } else if (lowerText === "updated") {
167
449
  typeClass = "badge-updated";
168
450
  }
169
- return /* @__PURE__ */ jsx5("span", { className: `sidebar-badge ${typeClass}`, children: text });
451
+ return /* @__PURE__ */ jsx10("span", { className: `sidebar-badge ${typeClass}`, children: text });
452
+ }
453
+ function renderIcon(iconName, size = 16) {
454
+ if (!iconName) return null;
455
+ const trimmed = iconName.trim();
456
+ if (trimmed.startsWith("<svg") || trimmed.includes("http")) {
457
+ if (trimmed.startsWith("<svg")) {
458
+ return /* @__PURE__ */ jsx10(
459
+ "span",
460
+ {
461
+ className: "sidebar-icon svg-icon",
462
+ dangerouslySetInnerHTML: { __html: trimmed }
463
+ }
464
+ );
465
+ }
466
+ return /* @__PURE__ */ jsx10(
467
+ "img",
468
+ {
469
+ src: trimmed,
470
+ className: "sidebar-icon",
471
+ style: { width: size, height: size },
472
+ alt: ""
473
+ }
474
+ );
475
+ }
476
+ const IconComponent = LucideIcons[iconName];
477
+ if (IconComponent) {
478
+ return /* @__PURE__ */ jsx10(IconComponent, { size, className: "sidebar-icon lucide-icon" });
479
+ }
480
+ return null;
170
481
  }
171
482
  function Sidebar({
172
483
  routes,
173
- config,
174
- isCollapsed,
175
- onToggle
484
+ config
176
485
  }) {
177
- const location = useLocation();
486
+ const location = useLocation3();
487
+ const currentRoute = routes.find((r) => r.path === location.pathname);
488
+ const activeTabId = currentRoute?.tab?.toLowerCase();
489
+ const filteredRoutes = activeTabId ? routes.filter((r) => {
490
+ if (!r.tab) return true;
491
+ return r.tab.toLowerCase() === activeTabId;
492
+ }) : routes;
178
493
  const ungrouped = [];
179
494
  const groupMap = /* @__PURE__ */ new Map();
180
- for (const route of routes) {
495
+ for (const route of filteredRoutes) {
181
496
  if (!route.group) {
182
497
  ungrouped.push(route);
183
498
  } else {
@@ -185,49 +500,41 @@ function Sidebar({
185
500
  groupMap.set(route.group, {
186
501
  slug: route.group,
187
502
  title: route.groupTitle || route.group,
188
- routes: []
189
- });
190
- }
191
- groupMap.get(route.group).routes.push(route);
192
- }
193
- }
194
- const groups = Array.from(groupMap.values());
195
- return /* @__PURE__ */ jsxs3("aside", { className: "boltdocs-sidebar", children: [
196
- onToggle && /* @__PURE__ */ jsx5("div", { className: "sidebar-collapse", children: /* @__PURE__ */ jsx5(
197
- "button",
198
- {
199
- className: "sidebar-collapse-btn",
200
- onClick: onToggle,
201
- "aria-label": isCollapsed ? "Expand Sidebar" : "Collapse Sidebar",
202
- title: isCollapsed ? "Expand Sidebar" : "Collapse Sidebar",
203
- children: /* @__PURE__ */ jsx5(PanelLeft, { size: 18 })
204
- }
205
- ) }),
206
- !isCollapsed && /* @__PURE__ */ jsxs3(Fragment, { children: [
207
- /* @__PURE__ */ jsxs3("nav", { "aria-label": "Main Navigation", children: [
208
- /* @__PURE__ */ jsx5("ul", { className: "sidebar-list", children: ungrouped.map((route) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
209
- Link,
210
- {
211
- to: route.path === "" ? "/" : route.path,
212
- className: `sidebar-link ${location.pathname === route.path ? "active" : ""}`,
213
- "aria-current": location.pathname === route.path ? "page" : void 0,
214
- children: /* @__PURE__ */ jsxs3("div", { className: "sidebar-link-content", children: [
215
- /* @__PURE__ */ jsx5("span", { children: route.title }),
216
- renderBadge(route.badge)
217
- ] })
218
- }
219
- ) }, route.path)) }),
220
- groups.map((group) => /* @__PURE__ */ jsx5(
221
- SidebarGroupSection,
222
- {
223
- group,
224
- currentPath: location.pathname
225
- },
226
- group.slug
227
- ))
228
- ] }),
229
- config.themeConfig?.poweredBy !== false && /* @__PURE__ */ jsx5(PoweredBy, {})
230
- ] })
503
+ routes: [],
504
+ icon: route.groupIcon
505
+ });
506
+ }
507
+ groupMap.get(route.group).routes.push(route);
508
+ }
509
+ }
510
+ const groups = Array.from(groupMap.values());
511
+ return /* @__PURE__ */ jsxs5("aside", { className: "boltdocs-sidebar", children: [
512
+ /* @__PURE__ */ jsxs5("nav", { "aria-label": "Main Navigation", children: [
513
+ /* @__PURE__ */ jsx10("ul", { className: "sidebar-list", children: ungrouped.map((route) => /* @__PURE__ */ jsx10("li", { children: /* @__PURE__ */ jsx10(
514
+ Link,
515
+ {
516
+ to: route.path === "" ? "/" : route.path,
517
+ className: `sidebar-link ${location.pathname === route.path ? "active" : ""}`,
518
+ "aria-current": location.pathname === route.path ? "page" : void 0,
519
+ children: /* @__PURE__ */ jsxs5("div", { className: "sidebar-link-content", children: [
520
+ /* @__PURE__ */ jsxs5("div", { className: "sidebar-link-title-container", children: [
521
+ renderIcon(route.icon),
522
+ /* @__PURE__ */ jsx10("span", { children: route.title })
523
+ ] }),
524
+ renderBadge(route.badge)
525
+ ] })
526
+ }
527
+ ) }, route.path)) }),
528
+ groups.map((group) => /* @__PURE__ */ jsx10(
529
+ SidebarGroupSection,
530
+ {
531
+ group,
532
+ currentPath: location.pathname
533
+ },
534
+ group.slug
535
+ ))
536
+ ] }),
537
+ config.themeConfig?.poweredBy !== false && /* @__PURE__ */ jsx10(PoweredBy, {})
231
538
  ] });
232
539
  }
233
540
  function SidebarGroupSection({
@@ -235,9 +542,9 @@ function SidebarGroupSection({
235
542
  currentPath
236
543
  }) {
237
544
  const isActive = group.routes.some((r) => currentPath === r.path);
238
- const [open, setOpen] = useState2(true);
239
- return /* @__PURE__ */ jsxs3("div", { className: "sidebar-group", children: [
240
- /* @__PURE__ */ jsxs3(
545
+ const [open, setOpen] = useState5(true);
546
+ return /* @__PURE__ */ jsxs5("div", { className: "sidebar-group", children: [
547
+ /* @__PURE__ */ jsxs5(
241
548
  "button",
242
549
  {
243
550
  className: `sidebar-group-header ${isActive ? "active" : ""}`,
@@ -245,19 +552,22 @@ function SidebarGroupSection({
245
552
  "aria-expanded": open,
246
553
  "aria-controls": `sidebar-group-${group.slug}`,
247
554
  children: [
248
- /* @__PURE__ */ jsx5("span", { className: "sidebar-group-title", children: group.title }),
249
- /* @__PURE__ */ jsx5("span", { className: `sidebar-group-chevron ${open ? "open" : ""}`, children: /* @__PURE__ */ jsx5(ChevronRight, { size: 16 }) })
555
+ /* @__PURE__ */ jsx10("div", { className: "sidebar-group-header-content", children: /* @__PURE__ */ jsx10("span", { className: "sidebar-group-title", children: group.title }) }),
556
+ /* @__PURE__ */ jsx10("span", { className: `sidebar-group-chevron ${open ? "open" : ""}`, children: /* @__PURE__ */ jsx10(ChevronRight, { size: 16 }) })
250
557
  ]
251
558
  }
252
559
  ),
253
- open && /* @__PURE__ */ jsx5("ul", { className: "sidebar-group-list", id: `sidebar-group-${group.slug}`, children: group.routes.map((route) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsx5(
560
+ open && /* @__PURE__ */ jsx10("ul", { className: "sidebar-group-list", id: `sidebar-group-${group.slug}`, children: group.routes.map((route) => /* @__PURE__ */ jsx10("li", { children: /* @__PURE__ */ jsx10(
254
561
  Link,
255
562
  {
256
563
  to: route.path === "" ? "/" : route.path,
257
564
  className: `sidebar-link sidebar-link-nested ${currentPath === route.path ? "active" : ""}`,
258
565
  "aria-current": currentPath === route.path ? "page" : void 0,
259
- children: /* @__PURE__ */ jsxs3("div", { className: "sidebar-link-content", children: [
260
- /* @__PURE__ */ jsx5("span", { children: route.title }),
566
+ children: /* @__PURE__ */ jsxs5("div", { className: "sidebar-link-content", children: [
567
+ /* @__PURE__ */ jsxs5("div", { className: "sidebar-link-title-container", children: [
568
+ renderIcon(route.icon),
569
+ /* @__PURE__ */ jsx10("span", { children: route.title })
570
+ ] }),
261
571
  renderBadge(route.badge)
262
572
  ] })
263
573
  }
@@ -266,22 +576,23 @@ function SidebarGroupSection({
266
576
  }
267
577
 
268
578
  // src/client/theme/ui/OnThisPage/OnThisPage.tsx
269
- import { useEffect as useEffect2, useState as useState3, useRef, useCallback as useCallback2 } from "react";
270
- import { useLocation as useLocation2 } from "react-router-dom";
579
+ import { useEffect as useEffect5, useState as useState6, useRef as useRef3, useCallback as useCallback2 } from "react";
580
+ import { useLocation as useLocation4 } from "react-router-dom";
271
581
  import { Pencil, CircleHelp } from "lucide-react";
272
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
582
+ import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
273
583
  function OnThisPage({
274
584
  headings = [],
275
585
  editLink,
276
586
  communityHelp,
277
587
  filePath
278
588
  }) {
279
- const [activeId, setActiveId] = useState3("");
280
- const [indicatorStyle, setIndicatorStyle] = useState3({});
281
- const observerRef = useRef(null);
282
- const location = useLocation2();
283
- const listRef = useRef(null);
284
- useEffect2(() => {
589
+ const [activeId, setActiveId] = useState6(null);
590
+ const [indicatorStyle, setIndicatorStyle] = useState6({});
591
+ const observerRef = useRef3(null);
592
+ const location = useLocation4();
593
+ const listRef = useRef3(null);
594
+ const visibleIdsRef = useRef3(/* @__PURE__ */ new Set());
595
+ useEffect5(() => {
285
596
  if (headings.length > 0) {
286
597
  const hash = window.location.hash.substring(1);
287
598
  if (hash && headings.some((h) => h.id === hash)) {
@@ -291,38 +602,55 @@ function OnThisPage({
291
602
  }
292
603
  }
293
604
  }, [location.pathname, headings]);
294
- useEffect2(() => {
605
+ useEffect5(() => {
295
606
  if (!activeId || !listRef.current) return;
296
- const activeElement = listRef.current.querySelector(
607
+ const activeLink = listRef.current.querySelector(
297
608
  `a[href="#${activeId}"]`
298
609
  );
299
- if (activeElement) {
300
- const { offsetTop, offsetHeight } = activeElement;
610
+ if (activeLink) {
611
+ const top = activeLink.offsetTop;
612
+ const height = activeLink.offsetHeight;
301
613
  setIndicatorStyle({
302
- transform: `translateY(${offsetTop}px)`,
303
- height: `${offsetHeight}px`,
614
+ transform: `translateY(${top}px)`,
615
+ height: `${height}px`,
304
616
  opacity: 1
305
617
  });
306
618
  }
307
619
  }, [activeId, headings]);
308
- useEffect2(() => {
620
+ useEffect5(() => {
309
621
  if (headings.length === 0) return;
622
+ visibleIdsRef.current.clear();
310
623
  if (observerRef.current) {
311
624
  observerRef.current.disconnect();
312
625
  }
313
626
  const callback = (entries) => {
314
- const visibleEntries = entries.filter((entry) => entry.isIntersecting);
315
- if (visibleEntries.length > 0) {
316
- const closest = visibleEntries.reduce((prev, curr) => {
317
- return Math.abs(curr.boundingClientRect.top - 100) < Math.abs(prev.boundingClientRect.top - 100) ? curr : prev;
318
- });
319
- setActiveId(closest.target.id);
627
+ entries.forEach((entry) => {
628
+ if (entry.isIntersecting) {
629
+ visibleIdsRef.current.add(entry.target.id);
630
+ } else {
631
+ visibleIdsRef.current.delete(entry.target.id);
632
+ }
633
+ });
634
+ const firstVisible = headings.find((h) => visibleIdsRef.current.has(h.id));
635
+ if (firstVisible) {
636
+ setActiveId(firstVisible.id);
637
+ } else {
638
+ const firstEl = document.getElementById(headings[0].id);
639
+ if (firstEl) {
640
+ const rect = firstEl.getBoundingClientRect();
641
+ if (rect.top > 200) {
642
+ setActiveId(headings[0].id);
643
+ return;
644
+ }
645
+ }
320
646
  }
321
647
  };
322
- observerRef.current = new IntersectionObserver(callback, {
323
- rootMargin: "-100px 0px -70% 0px",
648
+ const observerOptions = {
649
+ root: document.querySelector(".boltdocs-content"),
650
+ rootMargin: "-20% 0px -70% 0px",
324
651
  threshold: [0, 1]
325
- });
652
+ };
653
+ observerRef.current = new IntersectionObserver(callback, observerOptions);
326
654
  const observeHeadings = () => {
327
655
  headings.forEach(({ id }) => {
328
656
  const el = document.getElementById(id);
@@ -347,22 +675,20 @@ function OnThisPage({
347
675
  window.removeEventListener("scroll", handleScroll);
348
676
  };
349
677
  }, [headings, location.pathname]);
350
- useEffect2(() => {
678
+ useEffect5(() => {
351
679
  if (!activeId || !listRef.current) return;
352
680
  const activeLink = listRef.current.querySelector(
353
681
  `a[href="#${activeId}"]`
354
682
  );
355
683
  if (activeLink) {
356
- const container = listRef.current.closest(
357
- ".boltdocs-on-this-page"
358
- );
684
+ const container = listRef.current.parentElement;
359
685
  if (!container) return;
360
686
  const linkRect = activeLink.getBoundingClientRect();
361
687
  const containerRect = container.getBoundingClientRect();
362
688
  const isVisible = linkRect.top >= containerRect.top && linkRect.bottom <= containerRect.bottom;
363
689
  if (!isVisible) {
364
690
  activeLink.scrollIntoView({
365
- behavior: "smooth",
691
+ behavior: "auto",
366
692
  block: "nearest"
367
693
  });
368
694
  }
@@ -389,11 +715,11 @@ function OnThisPage({
389
715
  []
390
716
  );
391
717
  if (headings.length === 0) return null;
392
- return /* @__PURE__ */ jsxs4("nav", { className: "boltdocs-on-this-page", "aria-label": "Table of contents", children: [
393
- /* @__PURE__ */ jsx6("p", { className: "on-this-page-title", children: "On this page" }),
394
- /* @__PURE__ */ jsxs4("div", { className: "on-this-page-container", children: [
395
- /* @__PURE__ */ jsx6("div", { className: "toc-indicator", style: indicatorStyle }),
396
- /* @__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(
718
+ return /* @__PURE__ */ jsxs6("nav", { className: "boltdocs-on-this-page", "aria-label": "Table of contents", children: [
719
+ /* @__PURE__ */ jsx11("p", { className: "on-this-page-title", children: "On this page" }),
720
+ /* @__PURE__ */ jsx11("div", { className: "on-this-page-container", children: /* @__PURE__ */ jsxs6("div", { className: "on-this-page-list-container", children: [
721
+ /* @__PURE__ */ jsx11("div", { className: "toc-indicator", style: indicatorStyle }),
722
+ /* @__PURE__ */ jsx11("ul", { className: "on-this-page-list", ref: listRef, children: headings.map((h) => /* @__PURE__ */ jsx11("li", { className: h.level === 3 ? "toc-indent" : "", children: /* @__PURE__ */ jsx11(
397
723
  "a",
398
724
  {
399
725
  href: `#${h.id}`,
@@ -403,11 +729,11 @@ function OnThisPage({
403
729
  children: h.text
404
730
  }
405
731
  ) }, h.id)) })
406
- ] }),
407
- (editLink || communityHelp) && /* @__PURE__ */ jsxs4("div", { className: "toc-help", children: [
408
- /* @__PURE__ */ jsx6("p", { className: "toc-help-title", children: "Need help?" }),
409
- /* @__PURE__ */ jsxs4("ul", { className: "toc-help-links", children: [
410
- editLink && filePath && /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsxs4(
732
+ ] }) }),
733
+ (editLink || communityHelp) && /* @__PURE__ */ jsxs6("div", { className: "toc-help", children: [
734
+ /* @__PURE__ */ jsx11("p", { className: "toc-help-title", children: "Need help?" }),
735
+ /* @__PURE__ */ jsxs6("ul", { className: "toc-help-links", children: [
736
+ editLink && filePath && /* @__PURE__ */ jsx11("li", { children: /* @__PURE__ */ jsxs6(
411
737
  "a",
412
738
  {
413
739
  href: editLink.replace(":path", filePath),
@@ -415,12 +741,12 @@ function OnThisPage({
415
741
  rel: "noopener noreferrer",
416
742
  className: "toc-help-link",
417
743
  children: [
418
- /* @__PURE__ */ jsx6(Pencil, { size: 16 }),
744
+ /* @__PURE__ */ jsx11(Pencil, { size: 16 }),
419
745
  "Edit this page"
420
746
  ]
421
747
  }
422
748
  ) }),
423
- communityHelp && /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsxs4(
749
+ communityHelp && /* @__PURE__ */ jsx11("li", { children: /* @__PURE__ */ jsxs6(
424
750
  "a",
425
751
  {
426
752
  href: communityHelp,
@@ -428,7 +754,7 @@ function OnThisPage({
428
754
  rel: "noopener noreferrer",
429
755
  className: "toc-help-link",
430
756
  children: [
431
- /* @__PURE__ */ jsx6(CircleHelp, { size: 16 }),
757
+ /* @__PURE__ */ jsx11(CircleHelp, { size: 16 }),
432
758
  "Community help"
433
759
  ]
434
760
  }
@@ -439,11 +765,11 @@ function OnThisPage({
439
765
  }
440
766
 
441
767
  // src/client/theme/ui/Head/Head.tsx
442
- import { useEffect as useEffect3 } from "react";
443
- import { useLocation as useLocation3 } from "react-router-dom";
768
+ import { useEffect as useEffect6 } from "react";
769
+ import { useLocation as useLocation5 } from "react-router-dom";
444
770
  function Head({ siteTitle, siteDescription, routes }) {
445
- const location = useLocation3();
446
- useEffect3(() => {
771
+ const location = useLocation5();
772
+ useEffect6(() => {
447
773
  const currentRoute = routes.find((r) => r.path === location.pathname);
448
774
  const pageTitle = currentRoute?.title;
449
775
  const pageDescription = currentRoute?.description || siteDescription || "";
@@ -489,25 +815,25 @@ function setMetaTag(attr, key, content) {
489
815
  }
490
816
 
491
817
  // src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx
492
- import { useLocation as useLocation4 } from "react-router-dom";
818
+ import { useLocation as useLocation6 } from "react-router-dom";
493
819
  import { Home, ChevronRight as ChevronRight2 } from "lucide-react";
494
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
820
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
495
821
  function Breadcrumbs({ routes, config }) {
496
- const location = useLocation4();
822
+ const location = useLocation6();
497
823
  if (config.themeConfig?.breadcrumbs === false) return null;
498
824
  if (location.pathname === "/") return null;
499
825
  const currentRoute = routes.find((r) => r.path === location.pathname);
500
826
  const groupRoute = currentRoute?.group ? routes.find((r) => r.group === currentRoute.group) : null;
501
- return /* @__PURE__ */ jsx7("nav", { className: "boltdocs-breadcrumbs", "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsxs5("ol", { className: "boltdocs-breadcrumbs-list", children: [
502
- /* @__PURE__ */ jsxs5("li", { className: "boltdocs-breadcrumbs-item", children: [
503
- /* @__PURE__ */ jsx7(Link, { to: "/", className: "boltdocs-breadcrumbs-link", children: /* @__PURE__ */ jsx7(Home, { size: 14 }) }),
504
- /* @__PURE__ */ jsx7("span", { className: "boltdocs-breadcrumbs-separator", children: /* @__PURE__ */ jsx7(ChevronRight2, { size: 14 }) })
827
+ return /* @__PURE__ */ jsx12("nav", { className: "boltdocs-breadcrumbs", "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsxs7("ol", { className: "boltdocs-breadcrumbs-list", children: [
828
+ /* @__PURE__ */ jsxs7("li", { className: "boltdocs-breadcrumbs-item", children: [
829
+ /* @__PURE__ */ jsx12(Link, { to: "/", className: "boltdocs-breadcrumbs-link", children: /* @__PURE__ */ jsx12(Home, { size: 14 }) }),
830
+ /* @__PURE__ */ jsx12("span", { className: "boltdocs-breadcrumbs-separator", children: /* @__PURE__ */ jsx12(ChevronRight2, { size: 14 }) })
505
831
  ] }),
506
- currentRoute?.groupTitle && /* @__PURE__ */ jsxs5("li", { className: "boltdocs-breadcrumbs-item", children: [
507
- groupRoute ? /* @__PURE__ */ jsx7(Link, { to: groupRoute.path, className: "boltdocs-breadcrumbs-link", children: currentRoute.groupTitle }) : /* @__PURE__ */ jsx7("span", { className: "boltdocs-breadcrumbs-text", children: currentRoute.groupTitle }),
508
- /* @__PURE__ */ jsx7("span", { className: "boltdocs-breadcrumbs-separator", children: /* @__PURE__ */ jsx7(ChevronRight2, { size: 14 }) })
832
+ currentRoute?.groupTitle && /* @__PURE__ */ jsxs7("li", { className: "boltdocs-breadcrumbs-item", children: [
833
+ groupRoute ? /* @__PURE__ */ jsx12(Link, { to: groupRoute.path, className: "boltdocs-breadcrumbs-link", children: currentRoute.groupTitle }) : /* @__PURE__ */ jsx12("span", { className: "boltdocs-breadcrumbs-text", children: currentRoute.groupTitle }),
834
+ /* @__PURE__ */ jsx12("span", { className: "boltdocs-breadcrumbs-separator", children: /* @__PURE__ */ jsx12(ChevronRight2, { size: 14 }) })
509
835
  ] }),
510
- currentRoute?.title && /* @__PURE__ */ jsx7("li", { className: "boltdocs-breadcrumbs-item", children: /* @__PURE__ */ jsx7(
836
+ currentRoute?.title && /* @__PURE__ */ jsx12("li", { className: "boltdocs-breadcrumbs-item", children: /* @__PURE__ */ jsx12(
511
837
  "span",
512
838
  {
513
839
  className: "boltdocs-breadcrumbs-text boltdocs-breadcrumbs-active",
@@ -519,16 +845,16 @@ function Breadcrumbs({ routes, config }) {
519
845
  }
520
846
 
521
847
  // src/client/theme/ui/BackgroundGradient/BackgroundGradient.tsx
522
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
848
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
523
849
  function BackgroundGradient() {
524
- return /* @__PURE__ */ jsxs6("div", { className: "boltdocs-background-glow", children: [
525
- /* @__PURE__ */ jsx8("div", { className: "glow-shape glow-1" }),
526
- /* @__PURE__ */ jsx8("div", { className: "glow-shape glow-2" })
850
+ return /* @__PURE__ */ jsxs8("div", { className: "boltdocs-background-glow", children: [
851
+ /* @__PURE__ */ jsx13("div", { className: "glow-shape glow-1" }),
852
+ /* @__PURE__ */ jsx13("div", { className: "glow-shape glow-2" })
527
853
  ] });
528
854
  }
529
855
 
530
856
  // src/client/theme/ui/Layout/Layout.tsx
531
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
857
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
532
858
  function ThemeLayout({
533
859
  config,
534
860
  routes,
@@ -542,10 +868,9 @@ function ThemeLayout({
542
868
  className = "",
543
869
  style
544
870
  }) {
545
- const [isSidebarOpen, setIsSidebarOpen] = useState4(true);
546
871
  const siteTitle = config.themeConfig?.title || "Boltdocs";
547
872
  const siteDescription = config.themeConfig?.description || "";
548
- const location = useLocation5();
873
+ const location = useLocation7();
549
874
  const currentIndex = routes.findIndex((r) => r.path === location.pathname);
550
875
  const currentRoute = routes[currentIndex];
551
876
  const currentLocale = config.i18n ? currentRoute?.locale || config.i18n.defaultLocale : void 0;
@@ -561,13 +886,13 @@ function ThemeLayout({
561
886
  const prevPage = localIndex > 0 ? filteredRoutes[localIndex - 1] : null;
562
887
  const nextPage = localIndex >= 0 && localIndex < filteredRoutes.length - 1 ? filteredRoutes[localIndex + 1] : null;
563
888
  const { preload } = usePreload();
564
- React4.useEffect(() => {
889
+ React5.useEffect(() => {
565
890
  if (prevPage?.path) preload(prevPage.path);
566
891
  if (nextPage?.path) preload(nextPage.path);
567
892
  }, [prevPage, nextPage, preload]);
568
- return /* @__PURE__ */ jsxs7("div", { className: `boltdocs-layout ${className}`, style, children: [
569
- background !== void 0 ? background : /* @__PURE__ */ jsx9(BackgroundGradient, {}),
570
- head !== void 0 ? head : /* @__PURE__ */ jsx9(
893
+ return /* @__PURE__ */ jsxs9("div", { className: `boltdocs-layout ${className}`, style, children: [
894
+ background !== void 0 ? background : /* @__PURE__ */ jsx14(BackgroundGradient, {}),
895
+ head !== void 0 ? head : /* @__PURE__ */ jsx14(
571
896
  Head,
572
897
  {
573
898
  siteTitle,
@@ -575,7 +900,7 @@ function ThemeLayout({
575
900
  routes
576
901
  }
577
902
  ),
578
- navbar !== void 0 ? navbar : /* @__PURE__ */ jsx9(
903
+ navbar !== void 0 ? navbar : /* @__PURE__ */ jsx14(
579
904
  Navbar,
580
905
  {
581
906
  config,
@@ -585,90 +910,76 @@ function ThemeLayout({
585
910
  currentVersion
586
911
  }
587
912
  ),
588
- /* @__PURE__ */ jsxs7(
589
- "div",
590
- {
591
- className: `boltdocs-main-container ${!isSidebarOpen ? "sidebar-collapsed" : ""}`,
592
- children: [
593
- sidebar !== void 0 ? sidebar : /* @__PURE__ */ jsx9(
594
- Sidebar,
913
+ /* @__PURE__ */ jsxs9("div", { className: "boltdocs-main-container", children: [
914
+ sidebar !== void 0 ? sidebar : /* @__PURE__ */ jsx14(Sidebar, { routes: filteredRoutes, config }),
915
+ /* @__PURE__ */ jsxs9("main", { className: "boltdocs-content", children: [
916
+ breadcrumbs !== void 0 ? breadcrumbs : /* @__PURE__ */ jsx14(Breadcrumbs, { routes: filteredRoutes, config }),
917
+ /* @__PURE__ */ jsx14("div", { className: "boltdocs-page", children }),
918
+ (prevPage || nextPage) && /* @__PURE__ */ jsxs9("nav", { className: "page-nav", "aria-label": "Pagination", children: [
919
+ prevPage ? /* @__PURE__ */ jsxs9(
920
+ Link,
595
921
  {
596
- routes: filteredRoutes,
597
- config,
598
- isCollapsed: !isSidebarOpen,
599
- onToggle: () => setIsSidebarOpen(!isSidebarOpen)
922
+ to: prevPage.path || "/",
923
+ className: "page-nav-link page-nav-link--prev",
924
+ children: [
925
+ /* @__PURE__ */ jsxs9("div", { className: "page-nav-info", children: [
926
+ /* @__PURE__ */ jsx14("span", { className: "page-nav-label", children: "Previous" }),
927
+ /* @__PURE__ */ jsx14("span", { className: "page-nav-title", children: prevPage.title })
928
+ ] }),
929
+ /* @__PURE__ */ jsx14(ChevronLeft, { className: "page-nav-arrow", size: 16 })
930
+ ]
600
931
  }
601
- ),
602
- /* @__PURE__ */ jsxs7("main", { className: "boltdocs-content", children: [
603
- breadcrumbs !== void 0 ? breadcrumbs : /* @__PURE__ */ jsx9(Breadcrumbs, { routes: filteredRoutes, config }),
604
- /* @__PURE__ */ jsx9("div", { className: "boltdocs-page", children }),
605
- (prevPage || nextPage) && /* @__PURE__ */ jsxs7("nav", { className: "page-nav", "aria-label": "Pagination", children: [
606
- prevPage ? /* @__PURE__ */ jsxs7(
607
- Link,
608
- {
609
- to: prevPage.path || "/",
610
- className: "page-nav-link page-nav-link--prev",
611
- children: [
612
- /* @__PURE__ */ jsxs7("div", { className: "page-nav-info", children: [
613
- /* @__PURE__ */ jsx9("span", { className: "page-nav-label", children: "Previous" }),
614
- /* @__PURE__ */ jsx9("span", { className: "page-nav-title", children: prevPage.title })
615
- ] }),
616
- /* @__PURE__ */ jsx9(ChevronLeft2, { className: "page-nav-arrow", size: 16 })
617
- ]
618
- }
619
- ) : /* @__PURE__ */ jsx9("span", {}),
620
- nextPage ? /* @__PURE__ */ jsxs7(
621
- Link,
622
- {
623
- to: nextPage.path || "/",
624
- className: "page-nav-link page-nav-link--next",
625
- children: [
626
- /* @__PURE__ */ jsxs7("div", { className: "page-nav-info", children: [
627
- /* @__PURE__ */ jsx9("span", { className: "page-nav-label", children: "Next" }),
628
- /* @__PURE__ */ jsx9("span", { className: "page-nav-title", children: nextPage.title })
629
- ] }),
630
- /* @__PURE__ */ jsx9(ChevronRight3, { className: "page-nav-arrow", size: 16 })
631
- ]
632
- }
633
- ) : /* @__PURE__ */ jsx9("span", {})
634
- ] })
635
- ] }),
636
- toc !== void 0 ? toc : /* @__PURE__ */ jsx9(
637
- OnThisPage,
932
+ ) : /* @__PURE__ */ jsx14("span", {}),
933
+ nextPage ? /* @__PURE__ */ jsxs9(
934
+ Link,
638
935
  {
639
- headings: routes[currentIndex]?.headings,
640
- editLink: config.themeConfig?.editLink,
641
- communityHelp: config.themeConfig?.communityHelp,
642
- filePath: routes[currentIndex]?.filePath
936
+ to: nextPage.path || "/",
937
+ className: "page-nav-link page-nav-link--next",
938
+ children: [
939
+ /* @__PURE__ */ jsxs9("div", { className: "page-nav-info", children: [
940
+ /* @__PURE__ */ jsx14("span", { className: "page-nav-label", children: "Next" }),
941
+ /* @__PURE__ */ jsx14("span", { className: "page-nav-title", children: nextPage.title })
942
+ ] }),
943
+ /* @__PURE__ */ jsx14(ChevronRight3, { className: "page-nav-arrow", size: 16 })
944
+ ]
643
945
  }
644
- )
645
- ]
646
- }
647
- )
946
+ ) : /* @__PURE__ */ jsx14("span", {})
947
+ ] })
948
+ ] }),
949
+ toc !== void 0 ? toc : /* @__PURE__ */ jsx14(
950
+ OnThisPage,
951
+ {
952
+ headings: routes[currentIndex]?.headings,
953
+ editLink: config.themeConfig?.editLink,
954
+ communityHelp: config.themeConfig?.communityHelp,
955
+ filePath: routes[currentIndex]?.filePath
956
+ }
957
+ )
958
+ ] })
648
959
  ] });
649
960
  }
650
961
 
651
962
  // src/client/theme/ui/NotFound/NotFound.tsx
652
963
  import { ArrowLeft } from "lucide-react";
653
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
964
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
654
965
  function NotFound() {
655
- return /* @__PURE__ */ jsx10("div", { className: "boltdocs-not-found", children: /* @__PURE__ */ jsxs8("div", { className: "not-found-content", children: [
656
- /* @__PURE__ */ jsx10("span", { className: "not-found-code", children: "404" }),
657
- /* @__PURE__ */ jsx10("h1", { className: "not-found-title", children: "Page Not Found" }),
658
- /* @__PURE__ */ jsx10("p", { className: "not-found-text", children: "The page you're looking for doesn't exist or has been moved." }),
659
- /* @__PURE__ */ jsxs8(Link, { to: "/", className: "not-found-link", children: [
660
- /* @__PURE__ */ jsx10(ArrowLeft, { size: 16 }),
966
+ return /* @__PURE__ */ jsx15("div", { className: "boltdocs-not-found", children: /* @__PURE__ */ jsxs10("div", { className: "not-found-content", children: [
967
+ /* @__PURE__ */ jsx15("span", { className: "not-found-code", children: "404" }),
968
+ /* @__PURE__ */ jsx15("h1", { className: "not-found-title", children: "Page Not Found" }),
969
+ /* @__PURE__ */ jsx15("p", { className: "not-found-text", children: "The page you're looking for doesn't exist or has been moved." }),
970
+ /* @__PURE__ */ jsxs10(Link, { to: "/", className: "not-found-link", children: [
971
+ /* @__PURE__ */ jsx15(ArrowLeft, { size: 16 }),
661
972
  " Go to Home"
662
973
  ] })
663
974
  ] }) });
664
975
  }
665
976
 
666
977
  // src/client/theme/ui/Loading/Loading.tsx
667
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
978
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
668
979
  function Loading() {
669
- return /* @__PURE__ */ jsxs9("div", { className: "boltdocs-loading", children: [
670
- /* @__PURE__ */ jsx11("div", { className: "loading-spinner" }),
671
- /* @__PURE__ */ jsx11("p", { className: "loading-text", children: "Loading..." })
980
+ return /* @__PURE__ */ jsxs11("div", { className: "boltdocs-loading", children: [
981
+ /* @__PURE__ */ jsx16("div", { className: "loading-spinner" }),
982
+ /* @__PURE__ */ jsx16("p", { className: "loading-text", children: "Loading..." })
672
983
  ] });
673
984
  }
674
985
 
@@ -684,34 +995,34 @@ import {
684
995
  import { Link as LucideLink } from "lucide-react";
685
996
 
686
997
  // src/client/theme/components/CodeBlock/CodeBlock.tsx
687
- import { useState as useState5, useRef as useRef2, useCallback as useCallback3 } from "react";
998
+ import { useState as useState8, useRef as useRef4, useCallback as useCallback3 } from "react";
688
999
  import { Copy, Check } from "lucide-react";
689
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1000
+ import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
690
1001
  function CodeBlock({ children, ...props }) {
691
- const [copied, setCopied] = useState5(false);
692
- const preRef = useRef2(null);
1002
+ const [copied, setCopied] = useState8(false);
1003
+ const preRef = useRef4(null);
693
1004
  const handleCopy = useCallback3(async () => {
694
1005
  const code = preRef.current?.textContent || "";
695
1006
  copyToClipboard(code);
696
1007
  setCopied(true);
697
1008
  setTimeout(() => setCopied(false), 2e3);
698
1009
  }, []);
699
- return /* @__PURE__ */ jsxs10("div", { className: "code-block-wrapper", children: [
700
- /* @__PURE__ */ jsx12(
1010
+ return /* @__PURE__ */ jsxs12("div", { className: "code-block-wrapper", children: [
1011
+ /* @__PURE__ */ jsx17(
701
1012
  "button",
702
1013
  {
703
1014
  className: `code-block-copy ${copied ? "copied" : ""}`,
704
1015
  onClick: handleCopy,
705
1016
  "aria-label": "Copy code",
706
- children: copied ? /* @__PURE__ */ jsx12(Check, { size: 16 }) : /* @__PURE__ */ jsx12(Copy, { size: 16 })
1017
+ children: copied ? /* @__PURE__ */ jsx17(Check, { size: 16 }) : /* @__PURE__ */ jsx17(Copy, { size: 16 })
707
1018
  }
708
1019
  ),
709
- /* @__PURE__ */ jsx12("pre", { ref: preRef, ...props, children })
1020
+ /* @__PURE__ */ jsx17("pre", { ref: preRef, ...props, children })
710
1021
  ] });
711
1022
  }
712
1023
 
713
1024
  // src/client/app/index.tsx
714
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1025
+ import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
715
1026
  var ConfigContext = createContext2(null);
716
1027
  function useConfig() {
717
1028
  return useContext2(ConfigContext);
@@ -730,71 +1041,72 @@ var Heading = ({
730
1041
  children
731
1042
  }) => {
732
1043
  const Tag = `h${level}`;
733
- return /* @__PURE__ */ jsxs11(Tag, { id, className: "boltdocs-heading", children: [
1044
+ return /* @__PURE__ */ jsxs13(Tag, { id, className: "boltdocs-heading", children: [
734
1045
  children,
735
- id && /* @__PURE__ */ jsx13("a", { href: `#${id}`, className: "header-anchor", "aria-label": "Anchor", children: /* @__PURE__ */ jsx13(LucideLink, { size: 16 }) })
1046
+ id && /* @__PURE__ */ jsx18("a", { href: `#${id}`, className: "header-anchor", "aria-label": "Anchor", children: /* @__PURE__ */ jsx18(LucideLink, { size: 16 }) })
736
1047
  ] });
737
1048
  };
738
1049
  var mdxComponents = {
739
- h1: (props) => /* @__PURE__ */ jsx13(Heading, { level: 1, ...props }),
740
- h2: (props) => /* @__PURE__ */ jsx13(Heading, { level: 2, ...props }),
741
- h3: (props) => /* @__PURE__ */ jsx13(Heading, { level: 3, ...props }),
742
- h4: (props) => /* @__PURE__ */ jsx13(Heading, { level: 4, ...props }),
743
- h5: (props) => /* @__PURE__ */ jsx13(Heading, { level: 5, ...props }),
744
- h6: (props) => /* @__PURE__ */ jsx13(Heading, { level: 6, ...props }),
745
- pre: (props) => /* @__PURE__ */ jsx13(CodeBlock, { ...props, children: props.children }),
746
- video: (props) => /* @__PURE__ */ jsx13(Suspense, { fallback: /* @__PURE__ */ jsx13("div", { className: "video-skeleton" }), children: /* @__PURE__ */ jsx13(Video, { ...props }) }),
747
- PackageManagerTabs: (props) => /* @__PURE__ */ jsx13(Suspense, { fallback: /* @__PURE__ */ jsx13("div", { className: "pkg-tabs-skeleton" }), children: /* @__PURE__ */ jsx13(PackageManagerTabs, { ...props }) })
1050
+ h1: (props) => /* @__PURE__ */ jsx18(Heading, { level: 1, ...props }),
1051
+ h2: (props) => /* @__PURE__ */ jsx18(Heading, { level: 2, ...props }),
1052
+ h3: (props) => /* @__PURE__ */ jsx18(Heading, { level: 3, ...props }),
1053
+ h4: (props) => /* @__PURE__ */ jsx18(Heading, { level: 4, ...props }),
1054
+ h5: (props) => /* @__PURE__ */ jsx18(Heading, { level: 5, ...props }),
1055
+ h6: (props) => /* @__PURE__ */ jsx18(Heading, { level: 6, ...props }),
1056
+ pre: (props) => /* @__PURE__ */ jsx18(CodeBlock, { ...props, children: props.children }),
1057
+ video: (props) => /* @__PURE__ */ jsx18(Suspense, { fallback: /* @__PURE__ */ jsx18("div", { className: "video-skeleton" }), children: /* @__PURE__ */ jsx18(Video, { ...props }) }),
1058
+ PackageManagerTabs: (props) => /* @__PURE__ */ jsx18(Suspense, { fallback: /* @__PURE__ */ jsx18("div", { className: "pkg-tabs-skeleton" }), children: /* @__PURE__ */ jsx18(PackageManagerTabs, { ...props }) })
748
1059
  };
749
1060
  function AppShell({
750
1061
  initialRoutes,
751
1062
  initialConfig,
1063
+ docsDirName,
752
1064
  modules,
753
1065
  hot,
754
1066
  homePage: HomePage,
755
1067
  components: customComponents = {}
756
1068
  }) {
757
- const [routesInfo, setRoutesInfo] = useState6(initialRoutes);
758
- const [config] = useState6(initialConfig);
1069
+ const [routesInfo, setRoutesInfo] = useState9(initialRoutes);
1070
+ const [config] = useState9(initialConfig);
759
1071
  const resolveRoutes = (infos) => {
760
1072
  return infos.filter(
761
1073
  (route) => !(HomePage && (route.path === "/" || route.path === ""))
762
1074
  ).map((route) => {
763
1075
  const loaderKey = Object.keys(modules).find(
764
- (k) => k.endsWith("/" + route.filePath)
1076
+ (k) => k === `/${docsDirName}/${route.filePath}`
765
1077
  );
766
1078
  const loader = loaderKey ? modules[loaderKey] : null;
767
1079
  return {
768
1080
  ...route,
769
- Component: React6.lazy(() => {
1081
+ Component: React7.lazy(() => {
770
1082
  if (!loader)
771
- return Promise.resolve({ default: () => /* @__PURE__ */ jsx13(NotFound, {}) });
1083
+ return Promise.resolve({ default: () => /* @__PURE__ */ jsx18(NotFound, {}) });
772
1084
  return loader();
773
1085
  })
774
1086
  };
775
1087
  });
776
1088
  };
777
- const [resolvedRoutes, setResolvedRoutes] = useState6(
1089
+ const [resolvedRoutes, setResolvedRoutes] = useState9(
778
1090
  () => resolveRoutes(initialRoutes)
779
1091
  );
780
- useEffect4(() => {
1092
+ useEffect7(() => {
781
1093
  if (hot) {
782
1094
  hot.on("boltdocs:routes-update", (newRoutes) => {
783
1095
  setRoutesInfo(newRoutes);
784
1096
  });
785
1097
  }
786
1098
  }, [hot]);
787
- useEffect4(() => {
1099
+ useEffect7(() => {
788
1100
  setResolvedRoutes(resolveRoutes(routesInfo));
789
- }, [routesInfo, modules]);
790
- return /* @__PURE__ */ jsx13(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsxs11(PreloadProvider, { routes: routesInfo, modules, children: [
791
- /* @__PURE__ */ jsx13(ScrollHandler, {}),
792
- /* @__PURE__ */ jsxs11(Routes, { children: [
793
- HomePage && /* @__PURE__ */ jsx13(
1101
+ }, [routesInfo, modules, docsDirName]);
1102
+ return /* @__PURE__ */ jsx18(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsxs13(PreloadProvider, { routes: routesInfo, modules, children: [
1103
+ /* @__PURE__ */ jsx18(ScrollHandler, {}),
1104
+ /* @__PURE__ */ jsxs13(Routes, { children: [
1105
+ HomePage && /* @__PURE__ */ jsx18(
794
1106
  Route,
795
1107
  {
796
1108
  path: "/",
797
- element: /* @__PURE__ */ jsx13(
1109
+ element: /* @__PURE__ */ jsx18(
798
1110
  ThemeLayout,
799
1111
  {
800
1112
  config,
@@ -803,20 +1115,20 @@ function AppShell({
803
1115
  toc: null,
804
1116
  breadcrumbs: null,
805
1117
  ...config.themeConfig?.layoutProps,
806
- children: /* @__PURE__ */ jsx13(HomePage, {})
1118
+ children: /* @__PURE__ */ jsx18(HomePage, {})
807
1119
  }
808
1120
  )
809
1121
  }
810
1122
  ),
811
- /* @__PURE__ */ jsx13(
1123
+ /* @__PURE__ */ jsx18(
812
1124
  Route,
813
1125
  {
814
- element: /* @__PURE__ */ jsx13(DocsLayout, { config, routes: routesInfo }),
815
- children: resolvedRoutes.map((route) => /* @__PURE__ */ jsx13(
1126
+ element: /* @__PURE__ */ jsx18(DocsLayout, { config, routes: routesInfo }),
1127
+ children: resolvedRoutes.map((route) => /* @__PURE__ */ jsx18(
816
1128
  Route,
817
1129
  {
818
1130
  path: route.path === "" ? "/" : route.path,
819
- element: /* @__PURE__ */ jsx13(React6.Suspense, { fallback: /* @__PURE__ */ jsx13(Loading, {}), children: /* @__PURE__ */ jsx13(
1131
+ element: /* @__PURE__ */ jsx18(React7.Suspense, { fallback: /* @__PURE__ */ jsx18(Loading, {}), children: /* @__PURE__ */ jsx18(
820
1132
  MdxPage,
821
1133
  {
822
1134
  Component: route.Component,
@@ -829,17 +1141,17 @@ function AppShell({
829
1141
  },
830
1142
  "docs-layout"
831
1143
  ),
832
- /* @__PURE__ */ jsx13(
1144
+ /* @__PURE__ */ jsx18(
833
1145
  Route,
834
1146
  {
835
1147
  path: "*",
836
- element: /* @__PURE__ */ jsx13(
1148
+ element: /* @__PURE__ */ jsx18(
837
1149
  ThemeLayout,
838
1150
  {
839
1151
  config,
840
1152
  routes: routesInfo,
841
1153
  ...config.themeConfig?.layoutProps,
842
- children: /* @__PURE__ */ jsx13(NotFound, {})
1154
+ children: /* @__PURE__ */ jsx18(NotFound, {})
843
1155
  }
844
1156
  )
845
1157
  }
@@ -848,7 +1160,7 @@ function AppShell({
848
1160
  ] }) });
849
1161
  }
850
1162
  function ScrollHandler() {
851
- const { pathname, hash } = useLocation6();
1163
+ const { pathname, hash } = useLocation8();
852
1164
  useLayoutEffect(() => {
853
1165
  if (hash) {
854
1166
  const id = hash.replace("#", "");
@@ -874,13 +1186,13 @@ function DocsLayout({
874
1186
  config,
875
1187
  routes
876
1188
  }) {
877
- return /* @__PURE__ */ jsx13(
1189
+ return /* @__PURE__ */ jsx18(
878
1190
  ThemeLayout,
879
1191
  {
880
1192
  config,
881
1193
  routes,
882
1194
  ...config.themeConfig?.layoutProps,
883
- children: /* @__PURE__ */ jsx13(Outlet, {})
1195
+ children: /* @__PURE__ */ jsx18(Outlet, {})
884
1196
  }
885
1197
  );
886
1198
  }
@@ -889,21 +1201,22 @@ function MdxPage({
889
1201
  customComponents = {}
890
1202
  }) {
891
1203
  const allComponents = { ...mdxComponents, ...customComponents };
892
- return /* @__PURE__ */ jsx13(MDXProvider, { components: allComponents, children: /* @__PURE__ */ jsx13(Component, {}) });
1204
+ return /* @__PURE__ */ jsx18(MDXProvider, { components: allComponents, children: /* @__PURE__ */ jsx18(Component, {}) });
893
1205
  }
894
1206
  function createBoltdocsApp(options) {
895
- const { target, routes, config, modules, hot, homePage } = options;
1207
+ const { target, routes, docsDirName, config, modules, hot, homePage } = options;
896
1208
  const container = document.querySelector(target);
897
1209
  if (!container) {
898
1210
  throw new Error(
899
1211
  `[boltdocs] Mount target "${target}" not found in document.`
900
1212
  );
901
1213
  }
902
- const app = /* @__PURE__ */ jsx13(React6.StrictMode, { children: /* @__PURE__ */ jsx13(BrowserRouter, { children: /* @__PURE__ */ jsx13(
1214
+ const app = /* @__PURE__ */ jsx18(React7.StrictMode, { children: /* @__PURE__ */ jsx18(BrowserRouter, { children: /* @__PURE__ */ jsx18(
903
1215
  AppShell,
904
1216
  {
905
1217
  initialRoutes: routes,
906
1218
  initialConfig: config,
1219
+ docsDirName,
907
1220
  modules,
908
1221
  hot,
909
1222
  homePage,
@@ -915,9 +1228,9 @@ function createBoltdocsApp(options) {
915
1228
  }
916
1229
 
917
1230
  // src/client/theme/ui/Link/LinkPreview.tsx
918
- import { useEffect as useEffect5, useState as useState7, useRef as useRef3 } from "react";
1231
+ import { useEffect as useEffect8, useState as useState10, useRef as useRef5 } from "react";
919
1232
  import { createPortal } from "react-dom";
920
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1233
+ import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
921
1234
  function LinkPreview({
922
1235
  isVisible,
923
1236
  title,
@@ -925,30 +1238,25 @@ function LinkPreview({
925
1238
  x,
926
1239
  y
927
1240
  }) {
928
- const [mounted, setMounted] = useState7(false);
929
- const ref = useRef3(null);
930
- const [position, setPosition] = useState7({ top: 0, left: 0 });
931
- useEffect5(() => {
932
- setMounted(true);
933
- }, []);
934
- useEffect5(() => {
935
- if (isVisible && ref.current) {
1241
+ const ref = useRef5(null);
1242
+ const [position, setPosition] = useState10({ top: 0, left: 0 });
1243
+ useEffect8(() => {
1244
+ if (ref.current) {
936
1245
  const rect = ref.current.getBoundingClientRect();
937
- const padding = 15;
1246
+ const padding = 12;
938
1247
  let top = y + padding;
939
1248
  let left = x + padding;
940
- if (left + rect.width > window.innerWidth) {
1249
+ if (left + rect.width > window.innerWidth - 20) {
941
1250
  left = x - rect.width - padding;
942
1251
  }
943
- if (top + rect.height > window.innerHeight) {
1252
+ if (top + rect.height > window.innerHeight - 20) {
944
1253
  top = y - rect.height - padding;
945
1254
  }
946
1255
  setPosition({ top, left });
947
1256
  }
948
- }, [isVisible, x, y]);
949
- if (!mounted) return null;
1257
+ }, [x, y, isVisible]);
950
1258
  return createPortal(
951
- /* @__PURE__ */ jsxs12(
1259
+ /* @__PURE__ */ jsx19(
952
1260
  "div",
953
1261
  {
954
1262
  ref,
@@ -957,10 +1265,10 @@ function LinkPreview({
957
1265
  top: position.top,
958
1266
  left: position.left
959
1267
  },
960
- children: [
961
- /* @__PURE__ */ jsx14("span", { className: "boltdocs-link-preview-title", children: title }),
962
- summary && /* @__PURE__ */ jsx14("p", { className: "boltdocs-link-preview-summary", children: summary })
963
- ]
1268
+ children: /* @__PURE__ */ jsxs14("div", { className: "boltdocs-link-preview-content", children: [
1269
+ /* @__PURE__ */ jsx19("span", { className: "boltdocs-link-preview-title", children: title }),
1270
+ summary && /* @__PURE__ */ jsx19("p", { className: "boltdocs-link-preview-summary", children: summary })
1271
+ ] })
964
1272
  }
965
1273
  ),
966
1274
  document.body
@@ -968,9 +1276,9 @@ function LinkPreview({
968
1276
  }
969
1277
 
970
1278
  // src/client/theme/ui/Link/Link.tsx
971
- import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1279
+ import { Fragment, jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
972
1280
  function useLocalizedTo(to) {
973
- const location = useLocation7();
1281
+ const location = useLocation9();
974
1282
  const config = useConfig();
975
1283
  if (!config || typeof to !== "string") return to;
976
1284
  if (!config.i18n && !config.versions) return to;
@@ -1024,7 +1332,7 @@ function useLocalizedTo(to) {
1024
1332
  }
1025
1333
  return finalPath === basePath ? basePath : finalPath;
1026
1334
  }
1027
- var Link = React7.forwardRef(
1335
+ var Link = React8.forwardRef(
1028
1336
  (props, ref) => {
1029
1337
  const {
1030
1338
  boltdocsPrefetch = "hover",
@@ -1040,9 +1348,9 @@ var Link = React7.forwardRef(
1040
1348
  const localizedTo = useLocalizedTo(to);
1041
1349
  const { preload, routes } = usePreload();
1042
1350
  const config = useConfig();
1043
- const navigate = useNavigate();
1351
+ const navigate = useNavigate3();
1044
1352
  const shouldShowPreview = boltdocsPreview && config?.themeConfig?.linkPreview !== false;
1045
- const [preview, setPreview] = React7.useState({ visible: false, x: 0, y: 0, title: "" });
1353
+ const [preview, setPreview] = React8.useState({ visible: false, x: 0, y: 0, title: "" });
1046
1354
  const handleMouseEnter = (e) => {
1047
1355
  onMouseEnter?.(e);
1048
1356
  if (boltdocsPrefetch === "hover" && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
@@ -1091,13 +1399,13 @@ var Link = React7.forwardRef(
1091
1399
  }
1092
1400
  if (typeof localizedTo === "string" && !localizedTo.startsWith("http")) {
1093
1401
  e.preventDefault();
1094
- React7.startTransition(() => {
1402
+ React8.startTransition(() => {
1095
1403
  navigate(localizedTo);
1096
1404
  });
1097
1405
  }
1098
1406
  };
1099
- return /* @__PURE__ */ jsxs13(Fragment2, { children: [
1100
- /* @__PURE__ */ jsx15(
1407
+ return /* @__PURE__ */ jsxs15(Fragment, { children: [
1408
+ /* @__PURE__ */ jsx20(
1101
1409
  RouterLink,
1102
1410
  {
1103
1411
  ref,
@@ -1111,7 +1419,7 @@ var Link = React7.forwardRef(
1111
1419
  ...rest
1112
1420
  }
1113
1421
  ),
1114
- shouldShowPreview && /* @__PURE__ */ jsx15(
1422
+ preview.visible && shouldShowPreview && /* @__PURE__ */ jsx20(
1115
1423
  LinkPreview,
1116
1424
  {
1117
1425
  isVisible: preview.visible,
@@ -1125,7 +1433,7 @@ var Link = React7.forwardRef(
1125
1433
  }
1126
1434
  );
1127
1435
  Link.displayName = "Link";
1128
- var NavLink = React7.forwardRef(
1436
+ var NavLink = React8.forwardRef(
1129
1437
  (props, ref) => {
1130
1438
  const {
1131
1439
  boltdocsPrefetch = "hover",
@@ -1141,376 +1449,140 @@ var NavLink = React7.forwardRef(
1141
1449
  const localizedTo = useLocalizedTo(to);
1142
1450
  const { preload, routes } = usePreload();
1143
1451
  const config = useConfig();
1144
- const navigate = useNavigate();
1452
+ const navigate = useNavigate3();
1145
1453
  const shouldShowPreview = boltdocsPreview && config?.themeConfig?.linkPreview !== false;
1146
- const [preview, setPreview] = React7.useState({ visible: false, x: 0, y: 0, title: "" });
1454
+ const [preview, setPreview] = React8.useState({ visible: false, x: 0, y: 0, title: "" });
1147
1455
  const handleMouseEnter = (e) => {
1148
1456
  onMouseEnter?.(e);
1149
1457
  if (boltdocsPrefetch === "hover" && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1150
1458
  preload(localizedTo);
1151
1459
  }
1152
- if (shouldShowPreview && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1153
- const cleanPath = localizedTo.split("#")[0].split("?")[0];
1154
- const route = routes.find(
1155
- (r) => r.path === cleanPath || cleanPath === "/" && r.path === ""
1156
- );
1157
- if (route) {
1158
- setPreview({
1159
- visible: true,
1160
- x: e.clientX,
1161
- y: e.clientY,
1162
- title: route.title,
1163
- summary: route.description
1164
- });
1165
- }
1166
- }
1167
- };
1168
- const handleMouseMove = (e) => {
1169
- if (preview.visible) {
1170
- setPreview((prev) => ({ ...prev, x: e.clientX, y: e.clientY }));
1171
- }
1172
- };
1173
- const handleMouseLeave = (e) => {
1174
- onMouseLeave?.(e);
1175
- setPreview((prev) => ({ ...prev, visible: false }));
1176
- };
1177
- const handleFocus = (e) => {
1178
- onFocus?.(e);
1179
- if (boltdocsPrefetch === "hover" && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1180
- preload(localizedTo);
1181
- }
1182
- };
1183
- const handleBlur = (e) => {
1184
- onBlur?.(e);
1185
- setPreview((prev) => ({ ...prev, visible: false }));
1186
- };
1187
- const handleClick = (e) => {
1188
- onClick?.(e);
1189
- setPreview((prev) => ({ ...prev, visible: false }));
1190
- if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
1191
- return;
1192
- }
1193
- if (typeof localizedTo === "string" && !localizedTo.startsWith("http")) {
1194
- e.preventDefault();
1195
- React7.startTransition(() => {
1196
- navigate(localizedTo);
1197
- });
1198
- }
1199
- };
1200
- return /* @__PURE__ */ jsxs13(Fragment2, { children: [
1201
- /* @__PURE__ */ jsx15(
1202
- RouterNavLink,
1203
- {
1204
- ref,
1205
- to: localizedTo,
1206
- onMouseEnter: handleMouseEnter,
1207
- onMouseMove: handleMouseMove,
1208
- onMouseLeave: handleMouseLeave,
1209
- onFocus: handleFocus,
1210
- onBlur: handleBlur,
1211
- onClick: handleClick,
1212
- ...rest
1213
- }
1214
- ),
1215
- shouldShowPreview && /* @__PURE__ */ jsx15(
1216
- LinkPreview,
1217
- {
1218
- isVisible: preview.visible,
1219
- title: preview.title,
1220
- summary: preview.summary,
1221
- x: preview.x,
1222
- y: preview.y
1223
- }
1224
- )
1225
- ] });
1226
- }
1227
- );
1228
- NavLink.displayName = "NavLink";
1229
-
1230
- // src/client/theme/ui/Navbar/Navbar.tsx
1231
- import { ChevronDown as ChevronDown3 } from "lucide-react";
1232
-
1233
- // src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx
1234
- import { useState as useState8, useRef as useRef4, useEffect as useEffect6 } from "react";
1235
- import { Globe, ChevronDown } from "lucide-react";
1236
- import { useNavigate as useNavigate2, useLocation as useLocation8 } from "react-router-dom";
1237
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1238
- function getBaseFilePath(filePath, version, locale) {
1239
- let path = filePath;
1240
- if (version && (path === version || path.startsWith(version + "/"))) {
1241
- path = path === version ? "index.md" : path.slice(version.length + 1);
1242
- }
1243
- if (locale && (path === locale || path.startsWith(locale + "/"))) {
1244
- path = path === locale ? "index.md" : path.slice(locale.length + 1);
1245
- }
1246
- return path;
1247
- }
1248
- function LanguageSwitcher({
1249
- i18n,
1250
- currentLocale,
1251
- allRoutes
1252
- }) {
1253
- const [isOpen, setIsOpen] = useState8(false);
1254
- const dropdownRef = useRef4(null);
1255
- const navigate = useNavigate2();
1256
- const location = useLocation8();
1257
- useEffect6(() => {
1258
- function handleClickOutside(event) {
1259
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1260
- setIsOpen(false);
1261
- }
1262
- }
1263
- document.addEventListener("mousedown", handleClickOutside);
1264
- return () => document.removeEventListener("mousedown", handleClickOutside);
1265
- }, []);
1266
- const handleSelect = (locale) => {
1267
- setIsOpen(false);
1268
- if (locale === currentLocale) return;
1269
- const currentRoute = allRoutes.find((r) => r.path === location.pathname);
1270
- let targetPath = "/";
1271
- if (currentRoute) {
1272
- const baseFile = getBaseFilePath(
1273
- currentRoute.filePath,
1274
- currentRoute.version,
1275
- currentRoute.locale
1276
- );
1277
- const targetRoute = allRoutes.find(
1278
- (r) => getBaseFilePath(r.filePath, r.version, r.locale) === baseFile && (r.locale || i18n.defaultLocale) === locale && r.version === currentRoute.version
1279
- );
1280
- if (targetRoute) {
1281
- targetPath = targetRoute.path;
1282
- } else {
1283
- const defaultIndexRoute = allRoutes.find(
1284
- (r) => getBaseFilePath(r.filePath, r.version, r.locale) === "index.md" && (r.locale || i18n.defaultLocale) === locale && r.version === currentRoute.version
1285
- );
1286
- targetPath = defaultIndexRoute ? defaultIndexRoute.path : locale === i18n.defaultLocale ? currentRoute.version ? `/${currentRoute.version}` : "/" : currentRoute.version ? `/${currentRoute.version}/${locale}` : `/${locale}`;
1287
- }
1288
- } else {
1289
- targetPath = locale === i18n.defaultLocale ? "/" : `/${locale}`;
1290
- }
1291
- navigate(targetPath);
1292
- };
1293
- return /* @__PURE__ */ jsxs14("div", { className: "boltdocs-language-switcher", ref: dropdownRef, children: [
1294
- /* @__PURE__ */ jsxs14(
1295
- "button",
1296
- {
1297
- className: "language-btn",
1298
- onClick: () => setIsOpen(!isOpen),
1299
- "aria-label": "Switch language",
1300
- "aria-expanded": isOpen,
1301
- "aria-haspopup": "listbox",
1302
- children: [
1303
- /* @__PURE__ */ jsx16(Globe, { size: 18 }),
1304
- /* @__PURE__ */ jsx16("span", { className: "language-label", children: i18n.locales[currentLocale] || currentLocale }),
1305
- /* @__PURE__ */ jsx16(ChevronDown, { size: 14 })
1306
- ]
1307
- }
1308
- ),
1309
- isOpen && /* @__PURE__ */ jsx16("div", { className: "language-dropdown", children: Object.entries(i18n.locales).map(([key, label]) => /* @__PURE__ */ jsx16(
1310
- "button",
1311
- {
1312
- className: `language-option ${key === currentLocale ? "active" : ""}`,
1313
- onClick: () => handleSelect(key),
1314
- children: label
1315
- },
1316
- key
1317
- )) })
1318
- ] });
1319
- }
1320
-
1321
- // src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx
1322
- import { useState as useState9, useRef as useRef5, useEffect as useEffect7 } from "react";
1323
- import { ChevronDown as ChevronDown2 } from "lucide-react";
1324
- import { useNavigate as useNavigate3, useLocation as useLocation9 } from "react-router-dom";
1325
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1326
- function getBaseFilePath2(filePath, version, locale) {
1327
- let path = filePath;
1328
- if (version && (path === version || path.startsWith(version + "/"))) {
1329
- path = path === version ? "index.md" : path.slice(version.length + 1);
1330
- }
1331
- if (locale && (path === locale || path.startsWith(locale + "/"))) {
1332
- path = path === locale ? "index.md" : path.slice(locale.length + 1);
1333
- }
1334
- return path;
1335
- }
1336
- function VersionSwitcher({
1337
- versions,
1338
- currentVersion,
1339
- currentLocale,
1340
- allRoutes
1341
- }) {
1342
- const [isOpen, setIsOpen] = useState9(false);
1343
- const dropdownRef = useRef5(null);
1344
- const navigate = useNavigate3();
1345
- const location = useLocation9();
1346
- useEffect7(() => {
1347
- function handleClickOutside(event) {
1348
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1349
- setIsOpen(false);
1350
- }
1351
- }
1352
- document.addEventListener("mousedown", handleClickOutside);
1353
- return () => document.removeEventListener("mousedown", handleClickOutside);
1354
- }, []);
1355
- const handleSelect = (version) => {
1356
- setIsOpen(false);
1357
- if (version === currentVersion) return;
1358
- const currentRoute = allRoutes.find((r) => r.path === location.pathname);
1359
- let targetPath = `/docs/${version}`;
1360
- if (currentRoute) {
1361
- const baseFile = getBaseFilePath2(
1362
- currentRoute.filePath,
1363
- currentRoute.version,
1364
- currentRoute.locale
1365
- );
1366
- const targetRoute = allRoutes.find(
1367
- (r) => getBaseFilePath2(r.filePath, r.version, r.locale) === baseFile && (r.version || versions.defaultVersion) === version && (currentLocale ? r.locale === currentLocale : !r.locale)
1368
- );
1369
- if (targetRoute) {
1370
- targetPath = targetRoute.path;
1371
- } else {
1372
- const versionIndexRoute = allRoutes.find(
1373
- (r) => getBaseFilePath2(r.filePath, r.version, r.locale) === "index.md" && (r.version || versions.defaultVersion) === version && (currentLocale ? r.locale === currentLocale : !r.locale)
1460
+ if (shouldShowPreview && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1461
+ const cleanPath = localizedTo.split("#")[0].split("?")[0];
1462
+ const route = routes.find(
1463
+ (r) => r.path === cleanPath || cleanPath === "/" && r.path === ""
1374
1464
  );
1375
- targetPath = versionIndexRoute ? versionIndexRoute.path : `/docs/${version}${currentLocale ? `/${currentLocale}` : ""}`;
1465
+ if (route) {
1466
+ setPreview({
1467
+ visible: true,
1468
+ x: e.clientX,
1469
+ y: e.clientY,
1470
+ title: route.title,
1471
+ summary: route.description
1472
+ });
1473
+ }
1376
1474
  }
1377
- }
1378
- navigate(targetPath);
1379
- };
1380
- return /* @__PURE__ */ jsxs15(
1381
- "div",
1382
- {
1383
- className: "boltdocs-version-switcher",
1384
- ref: dropdownRef,
1385
- style: { position: "relative", display: "flex", alignItems: "center" },
1386
- children: [
1387
- /* @__PURE__ */ jsxs15(
1388
- "button",
1389
- {
1390
- className: "navbar-version",
1391
- onClick: () => setIsOpen(!isOpen),
1392
- "aria-label": "Switch version",
1393
- "aria-expanded": isOpen,
1394
- "aria-haspopup": "listbox",
1395
- style: {
1396
- fontFamily: "inherit",
1397
- padding: "0.25rem 0.5rem",
1398
- marginLeft: "0.5rem"
1399
- },
1400
- children: [
1401
- /* @__PURE__ */ jsx17("span", { children: versions.versions[currentVersion] || currentVersion }),
1402
- /* @__PURE__ */ jsx17(ChevronDown2, { size: 14 })
1403
- ]
1404
- }
1405
- ),
1406
- isOpen && /* @__PURE__ */ jsx17(
1407
- "div",
1408
- {
1409
- className: "language-dropdown",
1410
- style: {
1411
- left: "0.5rem",
1412
- right: "auto",
1413
- minWidth: "150px",
1414
- top: "calc(100% + 8px)"
1415
- },
1416
- children: Object.entries(versions.versions).map(([key, label]) => /* @__PURE__ */ jsx17(
1417
- "button",
1418
- {
1419
- className: `language-option ${key === currentVersion ? "active" : ""}`,
1420
- onClick: () => handleSelect(key),
1421
- children: label
1422
- },
1423
- key
1424
- ))
1425
- }
1426
- )
1427
- ]
1428
- }
1429
- );
1430
- }
1431
-
1432
- // src/client/theme/ui/ThemeToggle/ThemeToggle.tsx
1433
- import { useEffect as useEffect8, useState as useState10 } from "react";
1434
- import { Sun, Moon } from "lucide-react";
1435
- import { jsx as jsx18 } from "react/jsx-runtime";
1436
- function ThemeToggle() {
1437
- const [theme, setTheme] = useState10("dark");
1438
- const [mounted, setMounted] = useState10(false);
1439
- useEffect8(() => {
1440
- setMounted(true);
1441
- const stored = localStorage.getItem("boltdocs-theme");
1442
- if (stored === "light" || stored === "dark") {
1443
- setTheme(stored);
1444
- } else {
1445
- const prefersDark = window.matchMedia(
1446
- "(prefers-color-scheme: dark)"
1447
- ).matches;
1448
- setTheme(prefersDark ? "dark" : "light");
1449
- }
1450
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1451
- const handleChange = (e) => {
1452
- if (!localStorage.getItem("boltdocs-theme")) {
1453
- setTheme(e.matches ? "dark" : "light");
1475
+ };
1476
+ const handleMouseMove = (e) => {
1477
+ if (preview.visible) {
1478
+ setPreview((prev) => ({ ...prev, x: e.clientX, y: e.clientY }));
1454
1479
  }
1455
1480
  };
1456
- mediaQuery.addEventListener("change", handleChange);
1457
- return () => mediaQuery.removeEventListener("change", handleChange);
1458
- }, []);
1459
- useEffect8(() => {
1460
- if (!mounted) return;
1461
- const root = document.documentElement;
1462
- if (theme === "light") {
1463
- root.classList.add("theme-light");
1464
- root.dataset.theme = "light";
1465
- } else {
1466
- root.classList.remove("theme-light");
1467
- root.dataset.theme = "dark";
1468
- }
1469
- }, [theme, mounted]);
1470
- const toggleTheme = () => {
1471
- const newTheme = theme === "dark" ? "light" : "dark";
1472
- setTheme(newTheme);
1473
- localStorage.setItem("boltdocs-theme", newTheme);
1474
- };
1475
- if (!mounted) {
1476
- return /* @__PURE__ */ jsx18("button", { className: "navbar-icon-btn", "aria-label": "Toggle theme", disabled: true, children: /* @__PURE__ */ jsx18("span", { style: { width: 20, height: 20, display: "inline-block" } }) });
1481
+ const handleMouseLeave = (e) => {
1482
+ onMouseLeave?.(e);
1483
+ setPreview((prev) => ({ ...prev, visible: false }));
1484
+ };
1485
+ const handleFocus = (e) => {
1486
+ onFocus?.(e);
1487
+ if (boltdocsPrefetch === "hover" && typeof localizedTo === "string" && localizedTo.startsWith("/")) {
1488
+ preload(localizedTo);
1489
+ }
1490
+ };
1491
+ const handleBlur = (e) => {
1492
+ onBlur?.(e);
1493
+ setPreview((prev) => ({ ...prev, visible: false }));
1494
+ };
1495
+ const handleClick = (e) => {
1496
+ onClick?.(e);
1497
+ setPreview((prev) => ({ ...prev, visible: false }));
1498
+ if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
1499
+ return;
1500
+ }
1501
+ if (typeof localizedTo === "string" && !localizedTo.startsWith("http")) {
1502
+ e.preventDefault();
1503
+ React8.startTransition(() => {
1504
+ navigate(localizedTo);
1505
+ });
1506
+ }
1507
+ };
1508
+ return /* @__PURE__ */ jsxs15(Fragment, { children: [
1509
+ /* @__PURE__ */ jsx20(
1510
+ RouterNavLink,
1511
+ {
1512
+ ref,
1513
+ to: localizedTo,
1514
+ onMouseEnter: handleMouseEnter,
1515
+ onMouseMove: handleMouseMove,
1516
+ onMouseLeave: handleMouseLeave,
1517
+ onFocus: handleFocus,
1518
+ onBlur: handleBlur,
1519
+ onClick: handleClick,
1520
+ ...rest
1521
+ }
1522
+ ),
1523
+ preview.visible && shouldShowPreview && /* @__PURE__ */ jsx20(
1524
+ LinkPreview,
1525
+ {
1526
+ isVisible: preview.visible,
1527
+ title: preview.title,
1528
+ summary: preview.summary,
1529
+ x: preview.x,
1530
+ y: preview.y
1531
+ }
1532
+ )
1533
+ ] });
1477
1534
  }
1478
- return /* @__PURE__ */ jsx18(
1479
- "button",
1480
- {
1481
- className: "navbar-icon-btn",
1482
- onClick: toggleTheme,
1483
- "aria-label": "Toggle theme",
1484
- title: `Switch to ${theme === "dark" ? "light" : "dark"} theme`,
1485
- children: theme === "dark" ? /* @__PURE__ */ jsx18(Sun, { size: 20 }) : /* @__PURE__ */ jsx18(Moon, { size: 20 })
1535
+ );
1536
+ NavLink.displayName = "NavLink";
1537
+
1538
+ // src/client/theme/ui/Navbar/Tabs.tsx
1539
+ import * as Icons from "lucide-react";
1540
+ import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
1541
+ function Tabs({ tabs, routes }) {
1542
+ const location = useLocation10();
1543
+ const currentRoute = routes.find((r) => r.path === location.pathname);
1544
+ const currentTabId = currentRoute?.tab?.toLowerCase();
1545
+ if (!tabs || tabs.length === 0) return null;
1546
+ const renderTabIcon = (iconName) => {
1547
+ if (!iconName) return null;
1548
+ if (iconName.trim().startsWith("<svg")) {
1549
+ return /* @__PURE__ */ jsx21(
1550
+ "span",
1551
+ {
1552
+ className: "tab-icon svg-icon",
1553
+ dangerouslySetInnerHTML: { __html: iconName }
1554
+ }
1555
+ );
1486
1556
  }
1487
- );
1557
+ const LucideIcon = Icons[iconName];
1558
+ if (LucideIcon) {
1559
+ return /* @__PURE__ */ jsx21(LucideIcon, { size: 16, className: "tab-icon lucide-icon" });
1560
+ }
1561
+ return /* @__PURE__ */ jsx21("img", { src: iconName, alt: "", className: "tab-icon img-icon" });
1562
+ };
1563
+ return /* @__PURE__ */ jsx21("div", { className: "boltdocs-tabs-container", children: /* @__PURE__ */ jsx21("div", { className: "boltdocs-tabs", children: tabs.map((tab, index) => {
1564
+ const isActive = currentTabId ? currentTabId === tab.id.toLowerCase() : index === 0;
1565
+ const firstRoute = routes.find((r) => r.tab && r.tab.toLowerCase() === tab.id.toLowerCase());
1566
+ const linkTo = firstRoute ? firstRoute.path : "#";
1567
+ return /* @__PURE__ */ jsxs16(
1568
+ Link,
1569
+ {
1570
+ to: linkTo,
1571
+ className: `boltdocs-tab-item ${isActive ? "active" : ""}`,
1572
+ children: [
1573
+ renderTabIcon(tab.icon),
1574
+ /* @__PURE__ */ jsx21("span", { children: tab.text })
1575
+ ]
1576
+ },
1577
+ tab.id
1578
+ );
1579
+ }) }) });
1488
1580
  }
1489
1581
 
1490
- // src/client/theme/icons/discord.tsx
1491
- import { jsx as jsx19 } from "react/jsx-runtime";
1492
- var Discord = (props) => /* @__PURE__ */ jsx19("svg", { ...props, viewBox: "0 0 256 199", preserveAspectRatio: "xMidYMid", children: /* @__PURE__ */ jsx19(
1493
- "path",
1494
- {
1495
- 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",
1496
- fill: "currentColor"
1497
- }
1498
- ) });
1499
-
1500
- // src/client/theme/icons/twitter.tsx
1501
- import { jsx as jsx20 } from "react/jsx-runtime";
1502
- var XformerlyTwitter = (props) => /* @__PURE__ */ jsx20("svg", { ...props, fill: "none", viewBox: "0 0 1200 1227", children: /* @__PURE__ */ jsx20(
1503
- "path",
1504
- {
1505
- fill: "currentColor",
1506
- 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"
1507
- }
1508
- ) });
1509
-
1510
1582
  // src/client/theme/ui/Navbar/Navbar.tsx
1511
- import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
1512
- var SearchDialog = React10.lazy(
1513
- () => import("./SearchDialog-J3KNRGNO.mjs").then((m) => ({ default: m.SearchDialog }))
1583
+ import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
1584
+ var SearchDialog = lazy2(
1585
+ () => import("./SearchDialog-YOXMFGH6.mjs").then((m) => ({ default: m.SearchDialog }))
1514
1586
  );
1515
1587
  var ICON_MAP = {
1516
1588
  discord: Discord,
@@ -1523,81 +1595,123 @@ function Navbar({
1523
1595
  currentLocale,
1524
1596
  currentVersion
1525
1597
  }) {
1598
+ const location = useLocation11();
1599
+ const isHomePage = location.pathname === "/";
1526
1600
  const title = config.themeConfig?.title || "Boltdocs";
1527
1601
  const navItems = config.themeConfig?.navbar || [];
1528
1602
  const socialLinks = config.themeConfig?.socialLinks || [];
1529
- return /* @__PURE__ */ jsx21("header", { className: "boltdocs-navbar", children: /* @__PURE__ */ jsxs16("div", { className: "navbar-container", children: [
1530
- /* @__PURE__ */ jsxs16("div", { className: "navbar-left", children: [
1531
- /* @__PURE__ */ jsx21("div", { className: "navbar-logo", children: /* @__PURE__ */ jsxs16(Link, { to: "/", children: [
1532
- config.themeConfig?.logo ? config.themeConfig.logo.trim().startsWith("<svg") ? /* @__PURE__ */ jsx21(
1533
- "span",
1534
- {
1535
- className: "navbar-logo-svg",
1536
- dangerouslySetInnerHTML: {
1537
- __html: config.themeConfig.logo
1538
- }
1539
- }
1540
- ) : /* @__PURE__ */ jsx21(
1541
- "img",
1542
- {
1543
- src: config.themeConfig.logo,
1544
- alt: title,
1545
- className: "navbar-logo-img"
1546
- }
1547
- ) : null,
1548
- title
1549
- ] }) }),
1550
- config.versions && currentVersion && allRoutes ? /* @__PURE__ */ jsx21(
1551
- VersionSwitcher,
1552
- {
1553
- versions: config.versions,
1554
- currentVersion,
1555
- currentLocale,
1556
- allRoutes
1557
- }
1558
- ) : config.themeConfig?.version ? /* @__PURE__ */ jsxs16("div", { className: "navbar-version", children: [
1559
- config.themeConfig.version,
1560
- " ",
1561
- /* @__PURE__ */ jsx21(ChevronDown3, { size: 14 })
1562
- ] }) : null,
1563
- /* @__PURE__ */ jsx21("nav", { className: "navbar-links", "aria-label": "Top Navigation", children: navItems.map((item, i) => /* @__PURE__ */ jsx21(Link, { to: item.link, children: item.text }, i)) })
1564
- ] }),
1565
- /* @__PURE__ */ jsxs16("div", { className: "navbar-right", children: [
1566
- /* @__PURE__ */ jsx21(
1567
- React10.Suspense,
1568
- {
1569
- fallback: /* @__PURE__ */ jsx21("div", { className: "navbar-search-placeholder" }),
1570
- children: /* @__PURE__ */ jsx21(SearchDialog, { routes: routes || [] })
1571
- }
1572
- ),
1573
- config.i18n && currentLocale && allRoutes && /* @__PURE__ */ jsx21(
1574
- LanguageSwitcher,
1603
+ const hasTabs = !isHomePage && config.themeConfig?.tabs && config.themeConfig.tabs.length > 0;
1604
+ const leftItems = navItems.filter((item) => item.position !== "right");
1605
+ const rightItems = navItems.filter((item) => item.position === "right");
1606
+ const renderNavItem = (item, i) => {
1607
+ const text = item.label || item.text || "";
1608
+ const href = item.to || item.href || item.link || "";
1609
+ const isExternal = href.startsWith("http") || href.startsWith("//") || href.includes("://");
1610
+ return /* @__PURE__ */ jsxs17(Link2, { to: href, target: isExternal ? "_blank" : void 0, children: [
1611
+ text,
1612
+ isExternal && /* @__PURE__ */ jsx22("span", { className: "navbar-external-icon", children: /* @__PURE__ */ jsxs17(
1613
+ "svg",
1575
1614
  {
1576
- i18n: config.i18n,
1577
- currentLocale,
1578
- allRoutes
1615
+ viewBox: "0 0 24 24",
1616
+ width: "13",
1617
+ height: "13",
1618
+ stroke: "currentColor",
1619
+ strokeWidth: "2",
1620
+ fill: "none",
1621
+ strokeLinecap: "round",
1622
+ strokeLinejoin: "round",
1623
+ children: [
1624
+ /* @__PURE__ */ jsx22("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1625
+ /* @__PURE__ */ jsx22("polyline", { points: "15 3 21 3 21 9" }),
1626
+ /* @__PURE__ */ jsx22("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1627
+ ]
1579
1628
  }
1580
- ),
1581
- /* @__PURE__ */ jsx21(ThemeToggle, {}),
1582
- config.themeConfig?.githubRepo && /* @__PURE__ */ jsx21(GithubStars, { repo: config.themeConfig.githubRepo }),
1583
- socialLinks.length > 0 && /* @__PURE__ */ jsx21("div", { className: "navbar-divider" }),
1584
- /* @__PURE__ */ jsx21("div", { className: "navbar-icons", children: socialLinks.map((link, i) => {
1585
- const IconComp = ICON_MAP[link.icon.toLowerCase()];
1586
- return /* @__PURE__ */ jsx21(
1587
- "a",
1588
- {
1589
- href: link.link,
1590
- target: "_blank",
1591
- rel: "noopener noreferrer",
1592
- className: "navbar-icon-btn",
1593
- "aria-label": link.icon,
1594
- children: IconComp ? /* @__PURE__ */ jsx21(IconComp, {}) : /* @__PURE__ */ jsx21("span", { children: link.icon })
1595
- },
1596
- i
1597
- );
1598
- }) })
1599
- ] })
1600
- ] }) });
1629
+ ) })
1630
+ ] }, i);
1631
+ };
1632
+ return /* @__PURE__ */ jsxs17("header", { className: `boltdocs-navbar ${hasTabs ? "has-tabs" : ""}`, children: [
1633
+ /* @__PURE__ */ jsxs17(
1634
+ "div",
1635
+ {
1636
+ className: "navbar-container",
1637
+ style: { height: "var(--ld-navbar-height)" },
1638
+ children: [
1639
+ /* @__PURE__ */ jsxs17("div", { className: "navbar-left", children: [
1640
+ /* @__PURE__ */ jsx22("div", { className: "navbar-logo", children: /* @__PURE__ */ jsxs17(Link2, { to: "/", children: [
1641
+ config.themeConfig?.logo ? config.themeConfig.logo.trim().startsWith("<svg") ? /* @__PURE__ */ jsx22(
1642
+ "span",
1643
+ {
1644
+ className: "navbar-logo-svg",
1645
+ dangerouslySetInnerHTML: {
1646
+ __html: config.themeConfig.logo
1647
+ }
1648
+ }
1649
+ ) : /* @__PURE__ */ jsx22(
1650
+ "img",
1651
+ {
1652
+ src: config.themeConfig.logo,
1653
+ alt: title,
1654
+ className: "navbar-logo-img"
1655
+ }
1656
+ ) : null,
1657
+ title
1658
+ ] }) }),
1659
+ config.versions && currentVersion && allRoutes ? /* @__PURE__ */ jsx22(
1660
+ VersionSwitcher,
1661
+ {
1662
+ versions: config.versions,
1663
+ currentVersion,
1664
+ currentLocale,
1665
+ allRoutes
1666
+ }
1667
+ ) : config.themeConfig?.version ? /* @__PURE__ */ jsxs17("div", { className: "navbar-version", children: [
1668
+ config.themeConfig.version,
1669
+ " ",
1670
+ /* @__PURE__ */ jsx22(ChevronDown3, { size: 14 })
1671
+ ] }) : null,
1672
+ /* @__PURE__ */ jsx22("nav", { className: "navbar-links", "aria-label": "Top Navigation Left", children: leftItems.map(renderNavItem) })
1673
+ ] }),
1674
+ /* @__PURE__ */ jsxs17("div", { className: "navbar-right", children: [
1675
+ /* @__PURE__ */ jsx22("nav", { className: "navbar-links", "aria-label": "Top Navigation Right", children: rightItems.map(renderNavItem) }),
1676
+ /* @__PURE__ */ jsx22(Suspense2, { fallback: /* @__PURE__ */ jsx22("div", { className: "navbar-search-placeholder" }), children: /* @__PURE__ */ jsx22(SearchDialog, { routes: routes || [] }) }),
1677
+ config.i18n && currentLocale && allRoutes && /* @__PURE__ */ jsx22(
1678
+ LanguageSwitcher,
1679
+ {
1680
+ i18n: config.i18n,
1681
+ currentLocale,
1682
+ allRoutes
1683
+ }
1684
+ ),
1685
+ /* @__PURE__ */ jsx22(ThemeToggle, {}),
1686
+ config.themeConfig?.githubRepo && /* @__PURE__ */ jsx22(GithubStars, { repo: config.themeConfig.githubRepo }),
1687
+ socialLinks.length > 0 && /* @__PURE__ */ jsx22("div", { className: "navbar-divider" }),
1688
+ /* @__PURE__ */ jsx22("div", { className: "navbar-icons", children: socialLinks.map((link, i) => {
1689
+ const IconComp = ICON_MAP[link.icon.toLowerCase()];
1690
+ return /* @__PURE__ */ jsx22(
1691
+ "a",
1692
+ {
1693
+ href: link.link,
1694
+ target: "_blank",
1695
+ rel: "noopener noreferrer",
1696
+ className: "navbar-icon-btn",
1697
+ "aria-label": link.icon,
1698
+ children: IconComp ? /* @__PURE__ */ jsx22(IconComp, {}) : /* @__PURE__ */ jsx22("span", { children: link.icon })
1699
+ },
1700
+ i
1701
+ );
1702
+ }) })
1703
+ ] })
1704
+ ]
1705
+ }
1706
+ ),
1707
+ hasTabs && config.themeConfig?.tabs && /* @__PURE__ */ jsx22(
1708
+ Tabs,
1709
+ {
1710
+ tabs: config.themeConfig.tabs,
1711
+ routes: allRoutes || routes || []
1712
+ }
1713
+ )
1714
+ ] });
1601
1715
  }
1602
1716
 
1603
1717
  export {