boltdocs 1.10.2 → 1.11.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 (225) hide show
  1. package/package.json +29 -7
  2. package/src/client/app/config-context.tsx +18 -0
  3. package/src/client/app/docs-layout.tsx +14 -0
  4. package/src/client/app/index.tsx +132 -260
  5. package/src/client/app/mdx-component.tsx +52 -0
  6. package/src/client/app/mdx-components-context.tsx +23 -0
  7. package/src/client/app/mdx-page.tsx +20 -0
  8. package/src/client/app/preload.tsx +38 -30
  9. package/src/client/app/router.tsx +30 -0
  10. package/src/client/app/scroll-handler.tsx +40 -0
  11. package/src/client/app/theme-context.tsx +75 -0
  12. package/src/client/components/default-layout.tsx +80 -0
  13. package/src/client/components/docs-layout.tsx +105 -0
  14. package/src/client/components/icons-dev.tsx +74 -0
  15. package/src/client/components/mdx/admonition.tsx +107 -0
  16. package/src/client/components/mdx/badge.tsx +41 -0
  17. package/src/client/components/mdx/button.tsx +35 -0
  18. package/src/client/components/mdx/card.tsx +124 -0
  19. package/src/client/components/mdx/code-block.tsx +119 -0
  20. package/src/client/components/mdx/component-preview.tsx +47 -0
  21. package/src/client/components/mdx/component-props.tsx +83 -0
  22. package/src/client/components/mdx/field.tsx +66 -0
  23. package/src/client/components/mdx/file-tree.tsx +287 -0
  24. package/src/client/components/mdx/hooks/use-code-block.ts +56 -0
  25. package/src/client/components/mdx/hooks/use-component-preview.ts +16 -0
  26. package/src/client/components/mdx/hooks/useTable.ts +74 -0
  27. package/src/client/components/mdx/hooks/useTabs.ts +68 -0
  28. package/src/client/components/mdx/image.tsx +23 -0
  29. package/src/client/components/mdx/index.ts +53 -0
  30. package/src/client/components/mdx/link.tsx +38 -0
  31. package/src/client/components/mdx/list.tsx +192 -0
  32. package/src/client/components/mdx/table.tsx +156 -0
  33. package/src/client/components/mdx/tabs.tsx +135 -0
  34. package/src/client/components/mdx/video.tsx +68 -0
  35. package/src/client/components/primitives/breadcrumbs.tsx +79 -0
  36. package/src/client/components/primitives/button-group.tsx +54 -0
  37. package/src/client/components/primitives/button.tsx +145 -0
  38. package/src/client/components/primitives/helpers/observer.ts +120 -0
  39. package/src/client/components/primitives/index.ts +17 -0
  40. package/src/client/components/primitives/link.tsx +122 -0
  41. package/src/client/components/primitives/menu.tsx +159 -0
  42. package/src/client/components/primitives/navbar.tsx +359 -0
  43. package/src/client/components/primitives/navigation-menu.tsx +116 -0
  44. package/src/client/components/primitives/on-this-page.tsx +461 -0
  45. package/src/client/components/primitives/page-nav.tsx +87 -0
  46. package/src/client/components/primitives/popover.tsx +47 -0
  47. package/src/client/components/primitives/search-dialog.tsx +183 -0
  48. package/src/client/components/primitives/sidebar.tsx +154 -0
  49. package/src/client/components/primitives/tabs.tsx +90 -0
  50. package/src/client/components/primitives/tooltip.tsx +83 -0
  51. package/src/client/components/primitives/types.ts +11 -0
  52. package/src/client/components/ui-base/breadcrumbs.tsx +42 -0
  53. package/src/client/components/ui-base/copy-markdown.tsx +112 -0
  54. package/src/client/components/ui-base/error-boundary.tsx +52 -0
  55. package/src/client/components/ui-base/github-stars.tsx +27 -0
  56. package/src/client/components/ui-base/head.tsx +69 -0
  57. package/src/client/components/ui-base/loading.tsx +87 -0
  58. package/src/client/components/ui-base/navbar.tsx +138 -0
  59. package/src/client/components/ui-base/not-found.tsx +24 -0
  60. package/src/client/components/ui-base/on-this-page.tsx +152 -0
  61. package/src/client/components/ui-base/page-nav.tsx +39 -0
  62. package/src/client/components/ui-base/powered-by.tsx +19 -0
  63. package/src/client/components/ui-base/progress-bar.tsx +67 -0
  64. package/src/client/components/ui-base/search-dialog.tsx +82 -0
  65. package/src/client/components/ui-base/sidebar.tsx +104 -0
  66. package/src/client/components/ui-base/tabs.tsx +65 -0
  67. package/src/client/components/ui-base/theme-toggle.tsx +32 -0
  68. package/src/client/hooks/index.ts +12 -0
  69. package/src/client/hooks/use-breadcrumbs.ts +22 -0
  70. package/src/client/hooks/use-i18n.ts +84 -0
  71. package/src/client/hooks/use-localized-to.ts +95 -0
  72. package/src/client/hooks/use-location.ts +5 -0
  73. package/src/client/hooks/use-navbar.ts +60 -0
  74. package/src/client/hooks/use-onthispage.ts +23 -0
  75. package/src/client/hooks/use-page-nav.ts +22 -0
  76. package/src/client/hooks/use-routes.ts +72 -0
  77. package/src/client/hooks/use-search.ts +71 -0
  78. package/src/client/hooks/use-sidebar.ts +49 -0
  79. package/src/client/hooks/use-tabs.ts +43 -0
  80. package/src/client/hooks/use-version.ts +78 -0
  81. package/src/client/index.ts +55 -17
  82. package/src/client/integrations/codesandbox.ts +179 -0
  83. package/src/client/ssr.tsx +27 -16
  84. package/src/client/theme/neutral.css +360 -0
  85. package/src/client/types.ts +131 -27
  86. package/src/client/utils/cn.ts +6 -0
  87. package/src/client/utils/copy-clipboard.ts +22 -0
  88. package/src/client/utils/get-base-file-path.ts +21 -0
  89. package/src/client/utils/github.ts +121 -0
  90. package/src/client/utils/use-on-change.ts +15 -0
  91. package/src/client/virtual.d.ts +24 -0
  92. package/src/node/cache.ts +156 -156
  93. package/src/node/config.ts +159 -103
  94. package/src/node/index.ts +13 -13
  95. package/src/node/mdx.ts +213 -61
  96. package/src/node/plugin/entry.ts +29 -18
  97. package/src/node/plugin/html.ts +11 -11
  98. package/src/node/plugin/index.ts +161 -83
  99. package/src/node/plugin/types.ts +2 -4
  100. package/src/node/routes/cache.ts +6 -6
  101. package/src/node/routes/index.ts +206 -113
  102. package/src/node/routes/parser.ts +106 -81
  103. package/src/node/routes/sorter.ts +15 -15
  104. package/src/node/routes/types.ts +24 -24
  105. package/src/node/ssg/index.ts +46 -46
  106. package/src/node/ssg/meta.ts +4 -4
  107. package/src/node/ssg/options.ts +5 -5
  108. package/src/node/ssg/sitemap.ts +14 -14
  109. package/src/node/utils.ts +31 -31
  110. package/tsconfig.json +25 -20
  111. package/tsup.config.ts +23 -14
  112. package/dist/PackageManagerTabs-NVT7G625.mjs +0 -99
  113. package/dist/SearchDialog-AGVF6JBO.mjs +0 -194
  114. package/dist/SearchDialog-YPDOM7Q6.css +0 -2847
  115. package/dist/Video-KNTY5BNO.mjs +0 -6
  116. package/dist/cache-KNL5B4EE.mjs +0 -12
  117. package/dist/chunk-7SFUJWTB.mjs +0 -211
  118. package/dist/chunk-FFBNU6IJ.mjs +0 -386
  119. package/dist/chunk-FMTOYQLO.mjs +0 -37
  120. package/dist/chunk-TKLQWU7H.mjs +0 -1920
  121. package/dist/chunk-Z7JHYNAS.mjs +0 -57
  122. package/dist/client/index.css +0 -2847
  123. package/dist/client/index.d.mts +0 -372
  124. package/dist/client/index.d.ts +0 -372
  125. package/dist/client/index.js +0 -3630
  126. package/dist/client/index.mjs +0 -697
  127. package/dist/client/ssr.css +0 -2847
  128. package/dist/client/ssr.d.mts +0 -27
  129. package/dist/client/ssr.d.ts +0 -27
  130. package/dist/client/ssr.js +0 -2928
  131. package/dist/client/ssr.mjs +0 -33
  132. package/dist/config-BsFQ-ErD.d.mts +0 -159
  133. package/dist/config-BsFQ-ErD.d.ts +0 -159
  134. package/dist/node/index.d.mts +0 -91
  135. package/dist/node/index.d.ts +0 -91
  136. package/dist/node/index.js +0 -1187
  137. package/dist/node/index.mjs +0 -762
  138. package/dist/types-Dj-bfnC3.d.mts +0 -74
  139. package/dist/types-Dj-bfnC3.d.ts +0 -74
  140. package/src/client/theme/components/CodeBlock/CodeBlock.tsx +0 -61
  141. package/src/client/theme/components/CodeBlock/index.ts +0 -1
  142. package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +0 -131
  143. package/src/client/theme/components/PackageManagerTabs/index.ts +0 -1
  144. package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +0 -64
  145. package/src/client/theme/components/Playground/Playground.tsx +0 -180
  146. package/src/client/theme/components/Playground/index.ts +0 -1
  147. package/src/client/theme/components/Playground/playground.css +0 -238
  148. package/src/client/theme/components/Video/Video.tsx +0 -84
  149. package/src/client/theme/components/Video/index.ts +0 -1
  150. package/src/client/theme/components/Video/video.css +0 -41
  151. package/src/client/theme/components/mdx/Admonition.tsx +0 -80
  152. package/src/client/theme/components/mdx/Badge.tsx +0 -31
  153. package/src/client/theme/components/mdx/Button.tsx +0 -50
  154. package/src/client/theme/components/mdx/Card.tsx +0 -80
  155. package/src/client/theme/components/mdx/Field.tsx +0 -60
  156. package/src/client/theme/components/mdx/FileTree.tsx +0 -229
  157. package/src/client/theme/components/mdx/List.tsx +0 -57
  158. package/src/client/theme/components/mdx/Table.tsx +0 -151
  159. package/src/client/theme/components/mdx/Tabs.tsx +0 -123
  160. package/src/client/theme/components/mdx/index.ts +0 -27
  161. package/src/client/theme/components/mdx/mdx-components.css +0 -764
  162. package/src/client/theme/icons/bun.tsx +0 -62
  163. package/src/client/theme/icons/deno.tsx +0 -20
  164. package/src/client/theme/icons/discord.tsx +0 -12
  165. package/src/client/theme/icons/github.tsx +0 -15
  166. package/src/client/theme/icons/npm.tsx +0 -13
  167. package/src/client/theme/icons/pnpm.tsx +0 -72
  168. package/src/client/theme/icons/twitter.tsx +0 -12
  169. package/src/client/theme/styles/markdown.css +0 -394
  170. package/src/client/theme/styles/variables.css +0 -175
  171. package/src/client/theme/styles.css +0 -39
  172. package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +0 -68
  173. package/src/client/theme/ui/Breadcrumbs/index.ts +0 -1
  174. package/src/client/theme/ui/CopyMarkdown/CopyMarkdown.tsx +0 -82
  175. package/src/client/theme/ui/CopyMarkdown/copy-markdown.css +0 -112
  176. package/src/client/theme/ui/CopyMarkdown/index.ts +0 -1
  177. package/src/client/theme/ui/ErrorBoundary/ErrorBoundary.tsx +0 -50
  178. package/src/client/theme/ui/ErrorBoundary/error-boundary.css +0 -55
  179. package/src/client/theme/ui/ErrorBoundary/index.ts +0 -1
  180. package/src/client/theme/ui/Footer/footer.css +0 -32
  181. package/src/client/theme/ui/Head/Head.tsx +0 -69
  182. package/src/client/theme/ui/Head/index.ts +0 -1
  183. package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +0 -125
  184. package/src/client/theme/ui/LanguageSwitcher/index.ts +0 -1
  185. package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +0 -98
  186. package/src/client/theme/ui/Layout/Layout.tsx +0 -203
  187. package/src/client/theme/ui/Layout/base.css +0 -106
  188. package/src/client/theme/ui/Layout/index.ts +0 -2
  189. package/src/client/theme/ui/Layout/pagination.css +0 -72
  190. package/src/client/theme/ui/Layout/responsive.css +0 -47
  191. package/src/client/theme/ui/Link/Link.tsx +0 -392
  192. package/src/client/theme/ui/Link/LinkPreview.tsx +0 -59
  193. package/src/client/theme/ui/Link/index.ts +0 -2
  194. package/src/client/theme/ui/Link/link-preview.css +0 -48
  195. package/src/client/theme/ui/Loading/Loading.tsx +0 -10
  196. package/src/client/theme/ui/Loading/index.ts +0 -1
  197. package/src/client/theme/ui/Loading/loading.css +0 -30
  198. package/src/client/theme/ui/Navbar/GithubStars.tsx +0 -27
  199. package/src/client/theme/ui/Navbar/Navbar.tsx +0 -193
  200. package/src/client/theme/ui/Navbar/Tabs.tsx +0 -99
  201. package/src/client/theme/ui/Navbar/index.ts +0 -2
  202. package/src/client/theme/ui/Navbar/navbar.css +0 -347
  203. package/src/client/theme/ui/NotFound/NotFound.tsx +0 -19
  204. package/src/client/theme/ui/NotFound/index.ts +0 -1
  205. package/src/client/theme/ui/NotFound/not-found.css +0 -64
  206. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +0 -244
  207. package/src/client/theme/ui/OnThisPage/index.ts +0 -1
  208. package/src/client/theme/ui/OnThisPage/toc.css +0 -152
  209. package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +0 -18
  210. package/src/client/theme/ui/PoweredBy/index.ts +0 -1
  211. package/src/client/theme/ui/PoweredBy/powered-by.css +0 -76
  212. package/src/client/theme/ui/ProgressBar/ProgressBar.css +0 -17
  213. package/src/client/theme/ui/ProgressBar/ProgressBar.tsx +0 -51
  214. package/src/client/theme/ui/ProgressBar/index.ts +0 -1
  215. package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +0 -209
  216. package/src/client/theme/ui/SearchDialog/index.ts +0 -1
  217. package/src/client/theme/ui/SearchDialog/search.css +0 -152
  218. package/src/client/theme/ui/Sidebar/Sidebar.tsx +0 -244
  219. package/src/client/theme/ui/Sidebar/index.ts +0 -1
  220. package/src/client/theme/ui/Sidebar/sidebar.css +0 -230
  221. package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +0 -69
  222. package/src/client/theme/ui/ThemeToggle/index.ts +0 -1
  223. package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +0 -136
  224. package/src/client/theme/ui/VersionSwitcher/index.ts +0 -1
  225. package/src/client/utils.ts +0 -49
@@ -1,125 +0,0 @@
1
- import React, { useState, useRef, useEffect } from "react";
2
- import { Globe, ChevronDown } from "lucide-react";
3
- import { useNavigate, useLocation } from "react-router-dom";
4
- import { BoltdocsI18nConfig } from "../../../../node/config";
5
- import { ComponentRoute } from "../../../types";
6
-
7
- function getBaseFilePath(
8
- filePath: string,
9
- version: string | undefined,
10
- locale: string | undefined,
11
- ): string {
12
- let path = filePath;
13
- if (version && (path === version || path.startsWith(version + "/"))) {
14
- path = path === version ? "index.md" : path.slice(version.length + 1);
15
- }
16
- if (locale && (path === locale || path.startsWith(locale + "/"))) {
17
- path = path === locale ? "index.md" : path.slice(locale.length + 1);
18
- }
19
- return path;
20
- }
21
-
22
- export function LanguageSwitcher({
23
- i18n,
24
- currentLocale,
25
- allRoutes,
26
- }: {
27
- i18n: BoltdocsI18nConfig;
28
- currentLocale: string;
29
- allRoutes: ComponentRoute[];
30
- }) {
31
- const [isOpen, setIsOpen] = useState(false);
32
- const dropdownRef = useRef<HTMLDivElement>(null);
33
- const navigate = useNavigate();
34
- const location = useLocation();
35
-
36
- useEffect(() => {
37
- function handleClickOutside(event: MouseEvent) {
38
- if (
39
- dropdownRef.current &&
40
- !dropdownRef.current.contains(event.target as Node)
41
- ) {
42
- setIsOpen(false);
43
- }
44
- }
45
- document.addEventListener("mousedown", handleClickOutside);
46
- return () => document.removeEventListener("mousedown", handleClickOutside);
47
- }, []);
48
-
49
- const handleSelect = (locale: string) => {
50
- setIsOpen(false);
51
- if (locale === currentLocale) return;
52
-
53
- const currentRoute = allRoutes.find((r) => r.path === location.pathname);
54
- let targetPath = "/";
55
-
56
- if (currentRoute) {
57
- const baseFile = getBaseFilePath(
58
- currentRoute.filePath,
59
- currentRoute.version,
60
- currentRoute.locale,
61
- );
62
- const targetRoute = allRoutes.find(
63
- (r) =>
64
- getBaseFilePath(r.filePath, r.version, r.locale) === baseFile &&
65
- (r.locale || i18n.defaultLocale) === locale &&
66
- r.version === currentRoute.version,
67
- );
68
- if (targetRoute) {
69
- targetPath = targetRoute.path;
70
- } else {
71
- const defaultIndexRoute = allRoutes.find(
72
- (r) =>
73
- getBaseFilePath(r.filePath, r.version, r.locale) === "index.md" &&
74
- (r.locale || i18n.defaultLocale) === locale &&
75
- r.version === currentRoute.version,
76
- );
77
- targetPath = defaultIndexRoute
78
- ? defaultIndexRoute.path
79
- : locale === i18n.defaultLocale
80
- ? currentRoute.version
81
- ? `/${currentRoute.version}`
82
- : "/"
83
- : currentRoute.version
84
- ? `/${currentRoute.version}/${locale}`
85
- : `/${locale}`;
86
- }
87
- } else {
88
- targetPath = locale === i18n.defaultLocale ? "/" : `/${locale}`;
89
- }
90
-
91
- navigate(targetPath);
92
- };
93
-
94
- return (
95
- <div className="boltdocs-language-switcher" ref={dropdownRef}>
96
- <button
97
- className="language-btn"
98
- onClick={() => setIsOpen(!isOpen)}
99
- aria-label="Switch language"
100
- aria-expanded={isOpen}
101
- aria-haspopup="listbox"
102
- >
103
- <Globe size={18} />
104
- <span className="language-label">
105
- {i18n.locales[currentLocale] || currentLocale}
106
- </span>
107
- <ChevronDown size={14} />
108
- </button>
109
-
110
- {isOpen && (
111
- <div className="language-dropdown">
112
- {Object.entries(i18n.locales).map(([key, label]) => (
113
- <button
114
- key={key}
115
- className={`language-option ${key === currentLocale ? "active" : ""}`}
116
- onClick={() => handleSelect(key)}
117
- >
118
- {label}
119
- </button>
120
- ))}
121
- </div>
122
- )}
123
- </div>
124
- );
125
- }
@@ -1 +0,0 @@
1
- export { LanguageSwitcher } from "./LanguageSwitcher";
@@ -1,98 +0,0 @@
1
- .boltdocs-language-switcher {
2
- position: relative;
3
- display: flex;
4
- align-items: center;
5
- }
6
-
7
- .language-btn {
8
- display: flex;
9
- align-items: center;
10
- gap: 0.35rem;
11
- padding: 0.4rem 0.6rem;
12
- background: transparent;
13
- color: var(--ld-text-muted);
14
- border: none;
15
- border-radius: var(--ld-radius-md);
16
- font-size: 0.8125rem;
17
- font-weight: 500;
18
- cursor: pointer;
19
- transition:
20
- background-color 0.2s,
21
- color 0.2s;
22
- }
23
-
24
- .language-btn svg {
25
- width: 15px;
26
- height: 15px;
27
- opacity: 0.8;
28
- }
29
-
30
- .language-btn:hover {
31
- background-color: var(--ld-bg-mute);
32
- color: var(--ld-text-main);
33
- }
34
-
35
- .language-dropdown {
36
- position: absolute;
37
- top: 100%;
38
- right: 0;
39
- margin-top: 0.35rem;
40
- min-width: 130px;
41
- background-color: rgba(15, 15, 24, 0.85); /* Smooth translucent dark match */
42
- backdrop-filter: blur(12px);
43
- -webkit-backdrop-filter: blur(12px);
44
- border: 1px solid var(--ld-border-strong);
45
- border-radius: var(--ld-radius-md);
46
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
47
- padding: 0.35rem;
48
- z-index: 200;
49
- display: flex;
50
- flex-direction: column;
51
- gap: 0.15rem;
52
- animation: languageDropdownIn 0.15s ease-out;
53
- }
54
-
55
- @keyframes languageDropdownIn {
56
- from {
57
- opacity: 0;
58
- transform: translateY(-4px);
59
- }
60
- to {
61
- opacity: 1;
62
- transform: translateY(0);
63
- }
64
- }
65
-
66
- /* Light mode fallback */
67
- [data-theme="light"] .language-dropdown,
68
- .theme-light .language-dropdown {
69
- background-color: rgba(255, 255, 255, 0.9);
70
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
71
- }
72
-
73
- .language-option {
74
- display: block;
75
- width: 100%;
76
- text-align: left;
77
- padding: 0.4rem 0.6rem;
78
- background: transparent;
79
- border: none;
80
- border-radius: var(--ld-radius-sm);
81
- color: var(--ld-text-muted);
82
- font-size: 0.8125rem;
83
- font-weight: 500;
84
- cursor: pointer;
85
- transition:
86
- background-color 0.2s,
87
- color 0.2s;
88
- }
89
-
90
- .language-option:hover {
91
- background-color: var(--ld-bg-mute);
92
- color: var(--ld-text-main);
93
- }
94
-
95
- .language-option.active {
96
- background-color: var(--ld-color-primary-muted);
97
- color: var(--ld-color-primary);
98
- }
@@ -1,203 +0,0 @@
1
- import React from "react";
2
- import { useLocation } from "react-router-dom";
3
- import { Link } from "../Link";
4
- import { ChevronLeft, ChevronRight } from "lucide-react";
5
- import { usePreload } from "../../../app/preload";
6
- import { BoltdocsConfig } from "../../../../node/config";
7
- import { ComponentRoute } from "../../../types";
8
- export { Navbar } from "../Navbar";
9
- export { Sidebar } from "../Sidebar";
10
- export { OnThisPage } from "../OnThisPage";
11
- export { Head } from "../Head";
12
- export { Breadcrumbs } from "../Breadcrumbs";
13
-
14
- import { Navbar } from "../Navbar";
15
- import { Sidebar } from "../Sidebar";
16
- import { OnThisPage } from "../OnThisPage";
17
- import { Head } from "../Head";
18
- import { Breadcrumbs } from "../Breadcrumbs";
19
- import { ProgressBar } from "../ProgressBar";
20
- import { ErrorBoundary } from "../ErrorBoundary";
21
- import { CopyMarkdown } from "../CopyMarkdown";
22
- import "../../styles.css";
23
-
24
- export interface ThemeLayoutProps {
25
- config: BoltdocsConfig;
26
- routes: ComponentRoute[];
27
- children: React.ReactNode;
28
- /** Custom navbar component (slots) */
29
- navbar?: React.ReactNode;
30
- /** Custom sidebar component (slots) */
31
- sidebar?: React.ReactNode;
32
- /** Custom table of contents (OnThisPage) component (slots) */
33
- toc?: React.ReactNode;
34
- /** Custom background component (slots) */
35
- background?: React.ReactNode;
36
- /** Custom head/metadata component (slots) */
37
- head?: React.ReactNode;
38
- /** Custom breadcrumbs component (slots) */
39
- breadcrumbs?: React.ReactNode;
40
- /** Custom class name for the root layout element */
41
- className?: string;
42
- /** Custom styles for the root layout element */
43
- style?: React.CSSProperties;
44
- }
45
-
46
- /**
47
- * The main structural layout for documentation pages.
48
- * Integrates the Navbar, Sidebar, and OnThisPage components into a cohesive shell.
49
- * It also manages mobile interaction states like the sidebar overlay toggle.
50
- *
51
- * @param config - The global Boltdocs configuration object
52
- * @param routes - The array of available doc routes (used to render the sidebar)
53
- */
54
- export function ThemeLayout({
55
- config,
56
- routes,
57
- children,
58
- navbar,
59
- sidebar,
60
- toc,
61
- background,
62
- head,
63
- breadcrumbs,
64
- className = "",
65
- style,
66
- }: ThemeLayoutProps) {
67
- const siteTitle = config.themeConfig?.title || "Boltdocs";
68
- const siteDescription = config.themeConfig?.description || "";
69
- const location = useLocation();
70
-
71
- // Compute prev/next pages and locale
72
- const currentIndex = routes.findIndex((r) => r.path === location.pathname);
73
- const currentRoute = routes[currentIndex];
74
- // Determine current locale (fallback to default)
75
- const currentLocale = config.i18n
76
- ? currentRoute?.locale || config.i18n.defaultLocale
77
- : undefined;
78
-
79
- // Determine current version (fallback to default)
80
- const currentVersion = config.versions
81
- ? currentRoute?.version || config.versions.defaultVersion
82
- : undefined;
83
-
84
- // Filter routes for sidebar, search, and navigation to only ones in the current locale and version
85
- const filteredRoutes = routes.filter((r) => {
86
- const localeMatch = config.i18n
87
- ? (r.locale || config.i18n.defaultLocale) === currentLocale
88
- : true;
89
- const versionMatch = config.versions
90
- ? (r.version || config.versions.defaultVersion) === currentVersion
91
- : true;
92
- return localeMatch && versionMatch;
93
- });
94
-
95
- const localIndex = filteredRoutes.findIndex(
96
- (r) => r.path === location.pathname,
97
- );
98
- const prevPage = localIndex > 0 ? filteredRoutes[localIndex - 1] : null;
99
- const nextPage =
100
- localIndex >= 0 && localIndex < filteredRoutes.length - 1
101
- ? filteredRoutes[localIndex + 1]
102
- : null;
103
-
104
- const { preload } = usePreload();
105
- React.useEffect(() => {
106
- if (prevPage?.path) preload(prevPage.path);
107
- if (nextPage?.path) preload(nextPage.path);
108
- }, [prevPage, nextPage, preload]);
109
-
110
- return (
111
- <div className={`boltdocs-layout ${className}`} style={style}>
112
- <ProgressBar />
113
- {head !== undefined ? (
114
- head
115
- ) : (
116
- <Head
117
- siteTitle={siteTitle}
118
- siteDescription={siteDescription}
119
- routes={routes}
120
- />
121
- )}
122
- {navbar !== undefined ? (
123
- navbar
124
- ) : (
125
- <Navbar
126
- config={config}
127
- routes={filteredRoutes}
128
- allRoutes={routes}
129
- currentLocale={currentLocale}
130
- currentVersion={currentVersion}
131
- />
132
- )}
133
- <div className="boltdocs-main-container">
134
- {sidebar !== undefined ? (
135
- sidebar
136
- ) : (
137
- <Sidebar routes={filteredRoutes} config={config} />
138
- )}
139
-
140
- <main className="boltdocs-content">
141
- {breadcrumbs !== undefined ? (
142
- breadcrumbs
143
- ) : (
144
- <Breadcrumbs routes={filteredRoutes} config={config} />
145
- )}
146
- <div className="boltdocs-page">
147
- <div className="boltdocs-page-header">
148
- <CopyMarkdown
149
- content={routes[currentIndex]?._rawContent}
150
- config={config.themeConfig?.copyMarkdown}
151
- />
152
- </div>
153
- <ErrorBoundary>{children}</ErrorBoundary>
154
- </div>
155
-
156
- {/* Prev / Next Navigation */}
157
- {(prevPage || nextPage) && (
158
- <nav className="page-nav" aria-label="Pagination">
159
- {prevPage ? (
160
- <Link
161
- to={prevPage.path || "/"}
162
- className="page-nav-link page-nav-link--prev"
163
- >
164
- <div className="page-nav-info">
165
- <span className="page-nav-label">Previous</span>
166
- <span className="page-nav-title">{prevPage.title}</span>
167
- </div>
168
- <ChevronLeft className="page-nav-arrow" size={16} />
169
- </Link>
170
- ) : (
171
- <span />
172
- )}
173
- {nextPage ? (
174
- <Link
175
- to={nextPage.path || "/"}
176
- className="page-nav-link page-nav-link--next"
177
- >
178
- <div className="page-nav-info">
179
- <span className="page-nav-label">Next</span>
180
- <span className="page-nav-title">{nextPage.title}</span>
181
- </div>
182
- <ChevronRight className="page-nav-arrow" size={16} />
183
- </Link>
184
- ) : (
185
- <span />
186
- )}
187
- </nav>
188
- )}
189
- </main>
190
- {toc !== undefined ? (
191
- toc
192
- ) : (
193
- <OnThisPage
194
- headings={routes[currentIndex]?.headings}
195
- editLink={config.themeConfig?.editLink}
196
- communityHelp={config.themeConfig?.communityHelp}
197
- filePath={routes[currentIndex]?.filePath}
198
- />
199
- )}
200
- </div>
201
- </div>
202
- );
203
- }
@@ -1,106 +0,0 @@
1
- /* ─── Reset ──────────────────────────────────────────────── */
2
- *,
3
- *::before,
4
- *::after {
5
- box-sizing: border-box;
6
- }
7
-
8
- html,
9
- body {
10
- margin: 0;
11
- padding: 0;
12
- height: 100%;
13
- overflow: hidden; /* Lock the window scroll */
14
- }
15
-
16
- body {
17
- font-family: var(--ld-font-sans);
18
- background-color: var(--ld-bg-main);
19
- color: var(--ld-text-main);
20
- line-height: 1.7;
21
- -webkit-font-smoothing: antialiased;
22
- -moz-osx-font-smoothing: grayscale;
23
- }
24
-
25
- a {
26
- text-decoration: none;
27
-
28
- &:hover {
29
- text-decoration: none;
30
- }
31
- }
32
-
33
- /* ─── Layout Shell ───────────────────────────────────────── */
34
- .boltdocs-layout {
35
- display: flex;
36
- flex-direction: column;
37
- height: 100vh;
38
- width: 100vw;
39
- overflow: hidden;
40
- }
41
-
42
- .boltdocs-main-container {
43
- display: flex;
44
- flex: 1;
45
- width: 100%;
46
- max-width: 1440px;
47
- margin: 0 auto;
48
- padding: 0 0.5rem;
49
- /* Fixed height layout */
50
- height: calc(100vh - var(--ld-header-height));
51
- overflow: hidden;
52
- align-items: stretch; /* Sidebars fill height naturally */
53
- }
54
-
55
- /* ─── Background Glow ────────────────────────────────────── */
56
- .boltdocs-background-glow {
57
- position: fixed;
58
- top: 0;
59
- left: 0;
60
- right: 0;
61
- height: 100vh;
62
- overflow: hidden;
63
- z-index: -1;
64
- pointer-events: none;
65
- }
66
-
67
- .glow-shape {
68
- position: absolute;
69
- border-radius: 50%;
70
- filter: blur(100px);
71
- opacity: 0.15;
72
- top: -100px;
73
- }
74
-
75
- .glow-1 {
76
- width: 600px;
77
- height: 600px;
78
- background: var(--ld-glow-1-bg);
79
- left: -200px;
80
- }
81
-
82
- .glow-2 {
83
- width: 800px;
84
- height: 800px;
85
- background: var(--ld-glow-2-bg);
86
- top: -200px;
87
- }
88
-
89
- .boltdocs-page {
90
- position: relative;
91
- }
92
-
93
- .boltdocs-page-header {
94
- position: absolute;
95
- top: -0.5rem; /* Move up slightly to overlap less with title body */
96
- right: 0;
97
- display: flex;
98
- justify-content: flex-end;
99
- padding: 1rem 0;
100
- pointer-events: none;
101
- z-index: 101; /* Ensure it stays above everything */
102
- }
103
-
104
- .boltdocs-page-header > * {
105
- pointer-events: auto;
106
- }
@@ -1,2 +0,0 @@
1
- export { ThemeLayout } from "./Layout";
2
- export type { ThemeLayoutProps } from "./Layout";
@@ -1,72 +0,0 @@
1
- /* ═══════════════════════════════════════════════════════════
2
- PREV / NEXT NAVIGATION
3
- ═══════════════════════════════════════════════════════════ */
4
- .page-nav {
5
- display: grid;
6
- grid-template-columns: 1fr 1fr;
7
- gap: 0.75rem;
8
- margin-top: 2.5rem;
9
- padding-top: 1.5rem;
10
- border-top: 1px solid var(--ld-border-subtle);
11
- }
12
-
13
- .page-nav-link {
14
- display: flex;
15
- align-items: center;
16
- justify-content: space-between;
17
- gap: 0.75rem;
18
- padding: 0.875rem 1rem;
19
- border-radius: var(--ld-radius-md);
20
- border: 1px solid var(--ld-border-subtle);
21
- text-decoration: none;
22
- transition: all 0.2s;
23
- }
24
-
25
- .page-nav-link:hover {
26
- border-color: var(--ld-color-primary);
27
- background-color: var(--ld-color-primary-muted);
28
- }
29
-
30
- .page-nav-link--prev {
31
- flex-direction: row-reverse;
32
- }
33
-
34
- .page-nav-link--next {
35
- text-align: left;
36
- }
37
-
38
- .page-nav-info {
39
- display: flex;
40
- flex-direction: column;
41
- gap: 0.15rem;
42
- min-width: 0;
43
- }
44
-
45
- .page-nav-label {
46
- font-size: 0.6875rem;
47
- font-weight: 600;
48
- text-transform: uppercase;
49
- letter-spacing: 0.05em;
50
- color: var(--ld-text-dim);
51
- display: block;
52
- }
53
-
54
- .page-nav-title {
55
- font-size: 0.8125rem;
56
- font-weight: 600;
57
- color: var(--ld-text-main);
58
- display: block;
59
- white-space: nowrap;
60
- overflow: hidden;
61
- text-overflow: ellipsis;
62
- }
63
-
64
- .page-nav-arrow {
65
- color: var(--ld-text-dim);
66
- flex-shrink: 0;
67
- transition: color 0.2s;
68
- }
69
-
70
- .page-nav-link:hover .page-nav-arrow {
71
- color: var(--ld-color-primary);
72
- }
@@ -1,47 +0,0 @@
1
- /* ═══════════════════════════════════════════════════════════
2
- RESPONSIVE
3
- ═══════════════════════════════════════════════════════════ */
4
- @media (max-width: 1100px) {
5
- .boltdocs-on-this-page {
6
- display: none;
7
- }
8
- }
9
-
10
- @media (max-width: 768px) {
11
- .boltdocs-sidebar {
12
- display: none;
13
- }
14
-
15
- .boltdocs-content {
16
- padding: 1.5rem 1rem 3rem;
17
- }
18
-
19
- .hero-title {
20
- font-size: 2.25rem;
21
- }
22
-
23
- .boltdocs-page h1 {
24
- padding-right: 0;
25
- }
26
-
27
- .boltdocs-page-header {
28
- position: static;
29
- justify-content: flex-start;
30
- margin-bottom: 1rem;
31
- padding: 0;
32
- }
33
-
34
- .ld-cards--2,
35
- .ld-cards--3,
36
- .ld-cards--4 {
37
- grid-template-columns: 1fr;
38
- }
39
-
40
- .navbar-search {
41
- display: none;
42
- }
43
-
44
- .page-nav {
45
- flex-direction: column;
46
- }
47
- }