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,230 +0,0 @@
1
- /* ═══════════════════════════════════════════════════════════
2
- SIDEBAR
3
- ═══════════════════════════════════════════════════════════ */
4
- .boltdocs-sidebar {
5
- width: var(--ld-sidebar-width);
6
- flex-shrink: 0;
7
- background-color: var(--ld-sidebar-bg);
8
- backdrop-filter: blur(var(--ld-sidebar-blur));
9
- -webkit-backdrop-filter: blur(var(--ld-sidebar-blur));
10
- border-right: 1px solid var(--ld-border-subtle);
11
- padding: 1.5rem 0.6rem;
12
- overflow-y: auto;
13
- height: 100%;
14
- scrollbar-width: none;
15
- display: flex;
16
- flex-direction: column;
17
- /* Hardware acceleration */
18
- transform: translate3d(0, 0, 0);
19
- backface-visibility: hidden;
20
- }
21
-
22
- .sidebar-icon {
23
- flex-shrink: 0;
24
- display: flex;
25
- align-items: center;
26
- justify-content: center;
27
- }
28
-
29
- .sidebar-icon.lucide-icon,
30
- .sidebar-icon.svg-icon svg {
31
- color: var(--ld-text-muted);
32
- width: 18px;
33
- height: 18px;
34
- stroke-width: 2px;
35
- transition: color 0.2s ease;
36
- }
37
-
38
- .sidebar-link:hover .sidebar-icon.lucide-icon,
39
- .sidebar-link.active .sidebar-icon.lucide-icon {
40
- color: var(--ld-color-primary);
41
- }
42
-
43
- .boltdocs-sidebar > nav {
44
- flex: 1;
45
- }
46
-
47
- .boltdocs-sidebar::-webkit-scrollbar {
48
- display: none;
49
- }
50
-
51
- .boltdocs-sidebar::-webkit-scrollbar-track {
52
- background: transparent;
53
- }
54
-
55
- .boltdocs-sidebar::-webkit-scrollbar-thumb {
56
- background: var(--ld-bg-mute);
57
- border-radius: 4px;
58
- }
59
-
60
- .sidebar-list {
61
- list-style: none;
62
- padding: 0;
63
- margin: 0 0 0.5rem;
64
- }
65
-
66
- .sidebar-list li {
67
- margin-bottom: 2px;
68
- }
69
-
70
- .sidebar-link {
71
- display: flex;
72
- align-items: center;
73
- justify-content: space-between;
74
- padding: 0.5rem 0.75rem;
75
- color: var(--ld-text-muted);
76
- text-decoration: none;
77
- border-radius: 0.75rem; /* Large rounded corners */
78
- font-size: 0.875rem;
79
- font-weight: 500;
80
- transition: all 0.2s ease;
81
- margin: 0.15rem 0;
82
- }
83
-
84
- .sidebar-link-title-container {
85
- display: flex;
86
- align-items: center;
87
- gap: 0.75rem;
88
- }
89
-
90
- .sidebar-link-content {
91
- display: flex;
92
- align-items: center;
93
- justify-content: space-between;
94
- width: 100%;
95
- gap: 0.5rem;
96
- }
97
-
98
- .sidebar-link-content > span:last-child {
99
- flex: 1;
100
- word-wrap: break-word;
101
- }
102
-
103
- .sidebar-badge {
104
- font-size: 0.45rem;
105
- font-weight: 500;
106
- padding: 0.1rem 0.3rem;
107
- border-radius: 9999px;
108
- text-transform: uppercase;
109
- letter-spacing: 0.05em;
110
- white-space: nowrap;
111
- line-height: 1;
112
- display: inline-flex;
113
- align-items: center;
114
- flex-shrink: 0;
115
- }
116
-
117
- .sidebar-badge.badge-new {
118
- color: #38bdf8;
119
- background-color: rgba(56, 189, 248, 0.15);
120
- border: 1px solid rgba(56, 189, 248, 0.25);
121
- }
122
-
123
- .sidebar-badge.badge-experimental {
124
- color: #eab308; /* Yellow */
125
- background-color: rgba(234, 179, 8, 0.15);
126
- border: 1px solid rgba(234, 179, 8, 0.25);
127
- }
128
-
129
- .sidebar-badge.badge-updated {
130
- color: #a1a1aa; /* Grey / Zinc 400 */
131
- background-color: rgba(161, 161, 170, 0.15);
132
- border: 1px solid rgba(161, 161, 170, 0.25);
133
- }
134
-
135
- .sidebar-badge.badge-default {
136
- color: var(--ld-text-muted);
137
- background-color: var(--ld-bg-mute);
138
- border: 1px solid var(--ld-border-subtle);
139
- }
140
-
141
- .sidebar-link:hover {
142
- color: var(--ld-color-primary-hover);
143
- background-color: var(--ld-bg-soft);
144
- }
145
-
146
- .sidebar-link.active {
147
- color: var(--ld-color-primary);
148
- font-weight: 600;
149
- background-color: var(--ld-bg-soft);
150
- }
151
-
152
- /* ─── Sidebar Groups ─────────────────────────────────────── */
153
- .sidebar-group {
154
- margin-top: 1.25rem;
155
- }
156
-
157
- .sidebar-group:first-child {
158
- margin-top: 0;
159
- }
160
-
161
- .sidebar-group-header {
162
- display: flex;
163
- align-items: center;
164
- justify-content: space-between;
165
- width: 100%;
166
- padding: 0.5rem 0.75rem;
167
- background: none;
168
- border: none;
169
- border-radius: var(--ld-radius-md);
170
- color: var(--ld-text-muted);
171
- font-family: var(--ld-font-sans);
172
- font-size: 0.8125rem;
173
- font-weight: 600;
174
- cursor: pointer;
175
- transition:
176
- color 0.2s,
177
- background-color 0.2s;
178
- }
179
-
180
- .sidebar-group-header-content {
181
- display: flex;
182
- align-items: center;
183
- gap: 0.75rem;
184
- }
185
-
186
- .sidebar-group-header:hover {
187
- color: var(--ld-text-main);
188
- }
189
-
190
- .sidebar-group-header.active {
191
- color: var(--ld-text-main);
192
- }
193
-
194
- .sidebar-group-chevron {
195
- display: inline-flex;
196
- align-items: center;
197
- transition: transform 0.25s ease;
198
- font-size: 0.75rem;
199
- line-height: 1;
200
- }
201
-
202
- .sidebar-group-chevron.open {
203
- transform: rotate(90deg);
204
- }
205
-
206
- .sidebar-group-list {
207
- list-style: none;
208
- padding: 0;
209
- margin: 0.35rem 0 0.5rem 0;
210
- position: relative;
211
- }
212
-
213
- .sidebar-group-list li {
214
- margin-bottom: 2px;
215
- }
216
-
217
- .sidebar-link-nested {
218
- padding-left: 0.75rem;
219
- }
220
-
221
- .sidebar-group-list {
222
- list-style: none;
223
- padding: 0;
224
- margin: 0.35rem 0 0.5rem 0;
225
- position: relative;
226
- }
227
-
228
- .sidebar-group-list li {
229
- margin-bottom: 2px;
230
- }
@@ -1,69 +0,0 @@
1
- import React, { useEffect, useState } from "react";
2
- import { Sun, Moon } from "lucide-react";
3
-
4
- export function ThemeToggle() {
5
- const [theme, setTheme] = useState("dark");
6
- const [mounted, setMounted] = useState(false);
7
-
8
- useEffect(() => {
9
- setMounted(true);
10
- // On mount, read from localStorage or matchMedia
11
- const stored = localStorage.getItem("boltdocs-theme");
12
- if (stored === "light" || stored === "dark") {
13
- setTheme(stored);
14
- } else {
15
- const prefersDark = window.matchMedia(
16
- "(prefers-color-scheme: dark)",
17
- ).matches;
18
- setTheme(prefersDark ? "dark" : "light");
19
- }
20
-
21
- // Listen to system changes if no localStorage is set
22
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
23
- const handleChange = (e: MediaQueryListEvent) => {
24
- if (!localStorage.getItem("boltdocs-theme")) {
25
- setTheme(e.matches ? "dark" : "light");
26
- }
27
- };
28
- mediaQuery.addEventListener("change", handleChange);
29
- return () => mediaQuery.removeEventListener("change", handleChange);
30
- }, []);
31
-
32
- useEffect(() => {
33
- if (!mounted) return;
34
- const root = document.documentElement;
35
- if (theme === "light") {
36
- root.classList.add("theme-light");
37
- root.dataset.theme = "light";
38
- } else {
39
- root.classList.remove("theme-light");
40
- root.dataset.theme = "dark";
41
- }
42
- }, [theme, mounted]);
43
-
44
- const toggleTheme = () => {
45
- const newTheme = theme === "dark" ? "light" : "dark";
46
- setTheme(newTheme);
47
- localStorage.setItem("boltdocs-theme", newTheme);
48
- };
49
-
50
- // Prevent hydration mismatch by rendering a placeholder with same layout
51
- if (!mounted) {
52
- return (
53
- <button className="navbar-icon-btn" aria-label="Toggle theme" disabled>
54
- <span style={{ width: 20, height: 20, display: "inline-block" }}></span>
55
- </button>
56
- );
57
- }
58
-
59
- return (
60
- <button
61
- className="navbar-icon-btn"
62
- onClick={toggleTheme}
63
- aria-label="Toggle theme"
64
- title={`Switch to ${theme === "dark" ? "light" : "dark"} theme`}
65
- >
66
- {theme === "dark" ? <Sun size={20} /> : <Moon size={20} />}
67
- </button>
68
- );
69
- }
@@ -1 +0,0 @@
1
- export { ThemeToggle } from "./ThemeToggle";
@@ -1,136 +0,0 @@
1
- import { useState, useRef, useEffect } from "react";
2
- import { Layers, ChevronDown } from "lucide-react";
3
- import { useNavigate, useLocation } from "react-router-dom";
4
- import { BoltdocsVersionsConfig } 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 VersionSwitcher({
23
- versions,
24
- currentVersion,
25
- currentLocale,
26
- allRoutes,
27
- }: {
28
- versions: BoltdocsVersionsConfig;
29
- currentVersion: string;
30
- currentLocale?: string;
31
- allRoutes: ComponentRoute[];
32
- }) {
33
- const [isOpen, setIsOpen] = useState(false);
34
- const dropdownRef = useRef<HTMLDivElement>(null);
35
- const navigate = useNavigate();
36
- const location = useLocation();
37
-
38
- useEffect(() => {
39
- function handleClickOutside(event: MouseEvent) {
40
- if (
41
- dropdownRef.current &&
42
- !dropdownRef.current.contains(event.target as Node)
43
- ) {
44
- setIsOpen(false);
45
- }
46
- }
47
- document.addEventListener("mousedown", handleClickOutside);
48
- return () => document.removeEventListener("mousedown", handleClickOutside);
49
- }, []);
50
-
51
- const handleSelect = (version: string) => {
52
- setIsOpen(false);
53
- if (version === currentVersion) return;
54
-
55
- const currentRoute = allRoutes.find((r) => r.path === location.pathname);
56
- let targetPath = `/docs/${version}`; // Default to root of the new version
57
-
58
- if (currentRoute) {
59
- const baseFile = getBaseFilePath(
60
- currentRoute.filePath,
61
- currentRoute.version,
62
- currentRoute.locale,
63
- );
64
-
65
- const targetRoute = allRoutes.find(
66
- (r) =>
67
- getBaseFilePath(r.filePath, r.version, r.locale) === baseFile &&
68
- (r.version || versions.defaultVersion) === version &&
69
- (currentLocale ? r.locale === currentLocale : !r.locale),
70
- );
71
-
72
- if (targetRoute) {
73
- targetPath = targetRoute.path;
74
- } else {
75
- // Fallback to version index
76
- const versionIndexRoute = allRoutes.find(
77
- (r) =>
78
- getBaseFilePath(r.filePath, r.version, r.locale) === "index.md" &&
79
- (r.version || versions.defaultVersion) === version &&
80
- (currentLocale ? r.locale === currentLocale : !r.locale),
81
- );
82
- targetPath = versionIndexRoute
83
- ? versionIndexRoute.path
84
- : `/docs/${version}${currentLocale ? `/${currentLocale}` : ""}`;
85
- }
86
- }
87
-
88
- navigate(targetPath);
89
- };
90
-
91
- return (
92
- <div
93
- className="boltdocs-version-switcher"
94
- ref={dropdownRef}
95
- style={{ position: "relative", display: "flex", alignItems: "center" }}
96
- >
97
- <button
98
- className="navbar-version"
99
- onClick={() => setIsOpen(!isOpen)}
100
- aria-label="Switch version"
101
- aria-expanded={isOpen}
102
- aria-haspopup="listbox"
103
- style={{
104
- fontFamily: "inherit",
105
- padding: "0.25rem 0.5rem",
106
- marginLeft: "0.5rem",
107
- }}
108
- >
109
- <span>{versions.versions[currentVersion] || currentVersion}</span>
110
- <ChevronDown size={14} />
111
- </button>
112
-
113
- {isOpen && (
114
- <div
115
- className="language-dropdown"
116
- style={{
117
- left: "0.5rem",
118
- right: "auto",
119
- minWidth: "150px",
120
- top: "calc(100% + 8px)",
121
- }}
122
- >
123
- {Object.entries(versions.versions).map(([key, label]) => (
124
- <button
125
- key={key}
126
- className={`language-option ${key === currentVersion ? "active" : ""}`}
127
- onClick={() => handleSelect(key)}
128
- >
129
- {label}
130
- </button>
131
- ))}
132
- </div>
133
- )}
134
- </div>
135
- );
136
- }
@@ -1 +0,0 @@
1
- export { VersionSwitcher } from "./VersionSwitcher";
@@ -1,49 +0,0 @@
1
- /**
2
- * Get the number of stars for a GitHub repository.
3
- * @param repo - The repository name in the format "owner/repo".
4
- * @returns The number of stars for the repository.
5
- */
6
- export async function getStarsRepo(repo: string) {
7
- const response = await fetch(`https://api.github.com/repos/${repo}`);
8
- const data = await response.json();
9
- if (data.stargazers_count !== undefined) {
10
- return formatStars(data.stargazers_count);
11
- } else {
12
- return "0"; // Fallback
13
- }
14
- }
15
-
16
- /**
17
- * Format a number of stars in a compact form.
18
- * @param count - The number of stars to format.
19
- * @returns The formatted number of stars.
20
- */
21
- const formatStars = (count: number): string => {
22
- return Intl.NumberFormat("en", {
23
- notation: "compact",
24
- compactDisplay: "short",
25
- }).format(count);
26
- };
27
-
28
- /**
29
- * Copy text to clipboard.
30
- * @param text - The text to copy.
31
- * @returns True if the text was copied successfully.
32
- */
33
- export const copyToClipboard = async (text: string) => {
34
- try {
35
- await navigator.clipboard.writeText(text);
36
- return true;
37
- } catch {
38
- // Fallback
39
- const textarea = document.createElement("textarea");
40
- textarea.value = text;
41
- textarea.style.position = "fixed";
42
- textarea.style.opacity = "0";
43
- document.body.appendChild(textarea);
44
- textarea.select();
45
- document.execCommand("copy");
46
- document.body.removeChild(textarea);
47
- return true;
48
- }
49
- };