boltdocs 2.7.10 → 2.8.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 (193) hide show
  1. package/README.md +2 -2
  2. package/dist/banner-3N4Jd_L9.d.ts +100 -0
  3. package/dist/banner-MynZD_Ox.d.cts +100 -0
  4. package/dist/cache-BMUyNiiA.mjs +6 -0
  5. package/dist/cache-CKm45d2w.cjs +6 -0
  6. package/dist/client/index.cjs +2268 -1
  7. package/dist/client/index.d.cts +86 -110
  8. package/dist/client/index.d.ts +87 -111
  9. package/dist/client/index.js +2214 -1
  10. package/dist/client/mdx.cjs +12 -1
  11. package/dist/client/mdx.d.cts +39 -93
  12. package/dist/client/mdx.d.ts +38 -93
  13. package/dist/client/mdx.js +7 -1
  14. package/dist/client/primitives.cjs +60 -1
  15. package/dist/client/primitives.d.cts +411 -347
  16. package/dist/client/primitives.d.ts +411 -347
  17. package/dist/client/primitives.js +20 -1
  18. package/dist/docs-layout-CwCq42Zt.cjs +1348 -0
  19. package/dist/docs-layout-Dn6S5g59.js +1167 -0
  20. package/dist/doctor-BArviV8X.cjs +28 -0
  21. package/dist/doctor-CgLA7_Uv.mjs +28 -0
  22. package/dist/{doctor-CrytFkqW.cjs → doctor-DyNUVe96.cjs} +1 -1
  23. package/dist/{routes-DP1vmWRj.cjs → doctor-aN_leTbh.mjs} +1 -1
  24. package/dist/{generator-ClVanhvi.mjs → generator-BHCrLU6h.mjs} +2 -2
  25. package/dist/{generator-CHqxiQhF.cjs → generator-CC2yHzhZ.cjs} +2 -2
  26. package/dist/icons-dev-DvJ-hh9x.cjs +1209 -0
  27. package/dist/icons-dev-Oju24Wjp.js +845 -0
  28. package/dist/image-Ch4-GxdO.cjs +268 -0
  29. package/dist/image-Do8V9PCW.js +214 -0
  30. package/dist/mdx-D3A2_l7P.js +520 -0
  31. package/dist/mdx-PLhhPJRS.cjs +531 -0
  32. package/dist/node/cli-entry.cjs +3 -1
  33. package/dist/node/cli-entry.mjs +3 -1
  34. package/dist/node/index.cjs +1 -1
  35. package/dist/node/index.d.cts +258 -152
  36. package/dist/node/index.d.mts +258 -150
  37. package/dist/node/index.mjs +1 -1
  38. package/dist/node/routes/worker.cjs +1 -1
  39. package/dist/node/routes/worker.mjs +1 -1
  40. package/dist/node-BmlP0eBP.cjs +159 -0
  41. package/dist/node-Y8_4ayje.mjs +159 -0
  42. package/dist/package-2nFy_NsW.cjs +6 -0
  43. package/dist/{package--0Yf0t1N.mjs → package-DAbtltXX.mjs} +1 -1
  44. package/dist/parser-B7-6PyQz.cjs +6 -0
  45. package/dist/{parser-Aq8LoH-0.cjs → parser-BzB-zCkF.cjs} +1 -1
  46. package/dist/parser-WGZdWs0X.mjs +6 -0
  47. package/dist/routes-BDDSxAl0.mjs +6 -0
  48. package/dist/routes-DJNJ-rTt.cjs +6 -0
  49. package/dist/routes-DiYC4nD2.cjs +6 -0
  50. package/dist/routes-_Bb2f4eI.mjs +6 -0
  51. package/dist/search-dialog-BXVoecTx.cjs +483 -0
  52. package/dist/search-dialog-BYhOov4S.cjs +331 -0
  53. package/dist/search-dialog-C09riYmx.js +313 -0
  54. package/dist/search-dialog-CUeAfy-8.cjs +8 -0
  55. package/dist/search-dialog-D8gLkhUV.js +453 -0
  56. package/dist/search-dialog-DHc_8FFX.js +8 -0
  57. package/dist/{sidebar-CcBkrm06.d.cts → sidebar-DNq4_ZAa.d.ts} +118 -52
  58. package/dist/{sidebar-CyZS9YOm.d.ts → sidebar-Dlkgbxs6.d.cts} +118 -52
  59. package/dist/utils-BYITg7T5.mjs +7 -0
  60. package/dist/utils-Cjmx1hhk.cjs +7 -0
  61. package/dist/worker-pool-CtqklOXq.cjs +6 -0
  62. package/dist/worker-pool-k0DY6k8T.mjs +6 -0
  63. package/package.json +5 -6
  64. package/src/shared/config-utils.ts +4 -0
  65. package/src/shared/types.ts +52 -6
  66. package/dist/cache-Ba-DZQNH.cjs +0 -6
  67. package/dist/cache-BuMZ58L5.mjs +0 -6
  68. package/dist/cards-BakZPTz9.d.ts +0 -30
  69. package/dist/cards-CQn9mXZS.d.cts +0 -30
  70. package/dist/docs-layout-KoWNZc8_.js +0 -6
  71. package/dist/docs-layout-x2yKt2cL.cjs +0 -6
  72. package/dist/doctor-Be7Ly1oM.mjs +0 -21
  73. package/dist/doctor-jMxWZyLJ.cjs +0 -21
  74. package/dist/icons-dev-B_RZIyxu.js +0 -6
  75. package/dist/icons-dev-BlV3wWFT.cjs +0 -6
  76. package/dist/image-BHhTvQzr.cjs +0 -6
  77. package/dist/image-CqKzYD8f.js +0 -6
  78. package/dist/mdx-DudBEac0.js +0 -7
  79. package/dist/mdx-r4cDQxWu.cjs +0 -7
  80. package/dist/node-DtEDyN1u.cjs +0 -111
  81. package/dist/node-_1jhMGYx.mjs +0 -111
  82. package/dist/package-DrwtlXfk.cjs +0 -6
  83. package/dist/parser-CdNbqN5y.cjs +0 -6
  84. package/dist/parser-nE792MLO.mjs +0 -6
  85. package/dist/rolldown-runtime-fkIsjY3S.mjs +0 -6
  86. package/dist/routes-2k3tbUmC.cjs +0 -6
  87. package/dist/routes-CpxZIsMM.mjs +0 -6
  88. package/dist/search-dialog-B584t9ZF.js +0 -6
  89. package/dist/search-dialog-BvBopRsZ.cjs +0 -6
  90. package/dist/search-dialog-ByvGScjt.js +0 -6
  91. package/dist/search-dialog-Cyko6TJm.cjs +0 -6
  92. package/dist/search-dialog-D6BNohIJ.js +0 -6
  93. package/dist/search-dialog-DuYTIefy.cjs +0 -6
  94. package/dist/utils-CG65J0Sc.mjs +0 -7
  95. package/dist/utils-CKunkU96.cjs +0 -7
  96. package/dist/worker-pool-CGn7DrLb.mjs +0 -6
  97. package/dist/worker-pool-Crbqgw5R.cjs +0 -6
  98. package/src/client/app/config-context.tsx +0 -51
  99. package/src/client/app/doc-page.tsx +0 -38
  100. package/src/client/app/docs-layout.tsx +0 -28
  101. package/src/client/app/head.tsx +0 -122
  102. package/src/client/app/helmet-compat.tsx +0 -36
  103. package/src/client/app/mdx-component.tsx +0 -8
  104. package/src/client/app/mdx-components-context.tsx +0 -72
  105. package/src/client/app/routes-context.tsx +0 -34
  106. package/src/client/app/scroll-handler.tsx +0 -74
  107. package/src/client/app/theme-context.tsx +0 -103
  108. package/src/client/app/ui-context.tsx +0 -42
  109. package/src/client/components/docs-layout-default.tsx +0 -85
  110. package/src/client/components/icons-dev.tsx +0 -282
  111. package/src/client/components/mdx/callout.tsx +0 -97
  112. package/src/client/components/mdx/card.tsx +0 -99
  113. package/src/client/components/mdx/cards.tsx +0 -27
  114. package/src/client/components/mdx/code-block.tsx +0 -184
  115. package/src/client/components/mdx/field.tsx +0 -33
  116. package/src/client/components/mdx/image.tsx +0 -44
  117. package/src/client/components/mdx/index.ts +0 -19
  118. package/src/client/components/mdx/table.tsx +0 -54
  119. package/src/client/components/mdx/typographics.tsx +0 -120
  120. package/src/client/components/mdx/use-code-block.ts +0 -34
  121. package/src/client/components/primitives/breadcrumbs.tsx +0 -54
  122. package/src/client/components/primitives/button-group.tsx +0 -54
  123. package/src/client/components/primitives/button.tsx +0 -6
  124. package/src/client/components/primitives/code-block.tsx +0 -120
  125. package/src/client/components/primitives/docs-layout.tsx +0 -125
  126. package/src/client/components/primitives/error-boundary.tsx +0 -107
  127. package/src/client/components/primitives/heading.tsx +0 -128
  128. package/src/client/components/primitives/helpers/observer.ts +0 -141
  129. package/src/client/components/primitives/image.tsx +0 -26
  130. package/src/client/components/primitives/link.tsx +0 -102
  131. package/src/client/components/primitives/menu.tsx +0 -137
  132. package/src/client/components/primitives/navbar.tsx +0 -466
  133. package/src/client/components/primitives/on-this-page.tsx +0 -430
  134. package/src/client/components/primitives/page-nav.tsx +0 -51
  135. package/src/client/components/primitives/popover.tsx +0 -28
  136. package/src/client/components/primitives/search-dialog.tsx +0 -193
  137. package/src/client/components/primitives/sidebar.tsx +0 -423
  138. package/src/client/components/primitives/skeleton.tsx +0 -26
  139. package/src/client/components/primitives/tabs.tsx +0 -70
  140. package/src/client/components/primitives/tooltip.tsx +0 -81
  141. package/src/client/components/primitives/types.ts +0 -11
  142. package/src/client/components/ui-base/banner.tsx +0 -66
  143. package/src/client/components/ui-base/breadcrumbs.tsx +0 -44
  144. package/src/client/components/ui-base/copy-markdown.tsx +0 -107
  145. package/src/client/components/ui-base/error-boundary.tsx +0 -15
  146. package/src/client/components/ui-base/github-stars.tsx +0 -29
  147. package/src/client/components/ui-base/icons.tsx +0 -240
  148. package/src/client/components/ui-base/index.ts +0 -16
  149. package/src/client/components/ui-base/last-updated.tsx +0 -27
  150. package/src/client/components/ui-base/navbar.tsx +0 -266
  151. package/src/client/components/ui-base/not-found.tsx +0 -26
  152. package/src/client/components/ui-base/on-this-page.tsx +0 -57
  153. package/src/client/components/ui-base/page-nav.tsx +0 -50
  154. package/src/client/components/ui-base/search-dialog.tsx +0 -163
  155. package/src/client/components/ui-base/search-highlight.tsx +0 -10
  156. package/src/client/components/ui-base/sidebar.tsx +0 -92
  157. package/src/client/components/ui-base/tabs.tsx +0 -83
  158. package/src/client/components/ui-base/theme-toggle.tsx +0 -130
  159. package/src/client/components/ui-base/version-i18n.tsx +0 -80
  160. package/src/client/hooks/index.ts +0 -13
  161. package/src/client/hooks/use-analytics.ts +0 -272
  162. package/src/client/hooks/use-breadcrumbs.ts +0 -22
  163. package/src/client/hooks/use-i18n.ts +0 -182
  164. package/src/client/hooks/use-localized-to.ts +0 -113
  165. package/src/client/hooks/use-location.ts +0 -5
  166. package/src/client/hooks/use-navbar.ts +0 -130
  167. package/src/client/hooks/use-page-nav.ts +0 -46
  168. package/src/client/hooks/use-routes.ts +0 -108
  169. package/src/client/hooks/use-search-highlight.ts +0 -185
  170. package/src/client/hooks/use-search.ts +0 -118
  171. package/src/client/hooks/use-sidebar.ts +0 -205
  172. package/src/client/hooks/use-tabs.ts +0 -46
  173. package/src/client/hooks/use-version.ts +0 -111
  174. package/src/client/index.ts +0 -31
  175. package/src/client/mdx.ts +0 -2
  176. package/src/client/primitives.ts +0 -19
  177. package/src/client/ssg/boltdocs-shell.tsx +0 -148
  178. package/src/client/ssg/create-routes.tsx +0 -473
  179. package/src/client/ssg/index.ts +0 -4
  180. package/src/client/ssg/mdx-page.tsx +0 -38
  181. package/src/client/store/boltdocs-context.tsx +0 -137
  182. package/src/client/theme/neutral.css +0 -141
  183. package/src/client/theme/reset.css +0 -189
  184. package/src/client/types.ts +0 -116
  185. package/src/client/utils/cn.ts +0 -6
  186. package/src/client/utils/copy-clipboard.ts +0 -22
  187. package/src/client/utils/get-base-file-path.ts +0 -21
  188. package/src/client/utils/github.ts +0 -121
  189. package/src/client/utils/i18n.ts +0 -23
  190. package/src/client/utils/path.ts +0 -9
  191. package/src/client/utils/react-to-text.ts +0 -34
  192. package/src/client/virtual.d.ts +0 -24
  193. /package/dist/{meta-loader-CWg2gnbY.mjs → meta-loader-DzwDFtdT.mjs} +0 -0
@@ -1,266 +0,0 @@
1
- import { Suspense, lazy, useState } from 'react'
2
- import { cn } from '../../utils/cn'
3
- import { useNavbar } from '../../hooks/use-navbar'
4
- import { useRoutes } from '../../hooks/use-routes'
5
- import NavbarPrimitive from '../primitives/navbar'
6
- import { ThemeToggle } from './theme-toggle'
7
- import { GithubStars } from './github-stars'
8
- import { Tabs } from './tabs'
9
- import { useLocation } from 'react-router-dom'
10
- import type { BoltdocsSocialLink } from '../../../shared/types'
11
- import { Button } from '../primitives/button'
12
- import { Menu as MenuIcon, X } from './icons'
13
- import { useLocalizedTo } from '../../hooks/use-localized-to'
14
- import type { NavbarLink as NavbarLinkType } from '../../types'
15
- import { useUI } from '../../app/ui-context'
16
- import { VersionSelector, I18nSelector } from './version-i18n'
17
-
18
- const SearchDialog = lazy(() =>
19
- import('./search-dialog').then((m) => ({
20
- default: m.SearchDialog,
21
- })),
22
- )
23
-
24
- export function Navbar() {
25
- const { links, title, logo, logoProps, github, social, config } = useNavbar()
26
- const { routes, allRoutes, currentRoute, currentVersion, currentLocale } = useRoutes()
27
- const { pathname } = useLocation()
28
- const { isSidebarOpen, toggleSidebar } = useUI()
29
- const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
30
-
31
- const themeConfig = config.theme || {}
32
- const isDocs = !!currentRoute?.filePath
33
- const hasTabs = themeConfig?.tabs && themeConfig.tabs.length > 0
34
-
35
- return (
36
- <NavbarPrimitive.Root
37
- className={cn(
38
- 'border-b border-subtle bg-main/80 backdrop-blur-md',
39
- hasTabs && 'border-b-0',
40
- )}
41
- >
42
- <NavbarPrimitive.Content>
43
- <NavbarPrimitive.Left>
44
- {isDocs && (
45
- <Button
46
- onPress={toggleSidebar}
47
- className="mr-2 lg:hidden p-1.5 h-8 w-8 flex items-center justify-center bg-transparent border-none outline-none select-none cursor-pointer rounded-xl hover:bg-primary-50/50 transition-colors"
48
- aria-label={isSidebarOpen ? 'Close sidebar' : 'Open sidebar'}
49
- >
50
- {isSidebarOpen ? (
51
- <X className="w-5 h-5 text-body" />
52
- ) : (
53
- <MenuIcon className="w-5 h-5 text-body" />
54
- )}
55
- </Button>
56
- )}
57
- {logo && (
58
- <NavbarPrimitive.Logo
59
- src={logo}
60
- alt={logoProps?.alt || title}
61
- width={logoProps?.width ?? 24}
62
- height={logoProps?.height ?? 24}
63
- href="site:/"
64
- />
65
- )}
66
- <NavbarPrimitive.Title href="site:/">{title}</NavbarPrimitive.Title>
67
-
68
- <div className="hidden sm:block">
69
- {config.versions && currentVersion && <VersionSelector />}
70
- </div>
71
- </NavbarPrimitive.Left>
72
- <NavbarPrimitive.Center>
73
- <Suspense
74
- fallback={
75
- <div className="h-9 w-32 animate-pulse rounded-md bg-surface" />
76
- }
77
- >
78
- <SearchDialog routes={routes || []} />
79
- </Suspense>
80
- </NavbarPrimitive.Center>
81
- <NavbarPrimitive.Right>
82
- <Suspense fallback={null}>
83
- <div className="lg:hidden">
84
- <SearchDialog routes={routes || []} />
85
- </div>
86
- </Suspense>
87
- <NavbarPrimitive.Links>
88
- {links.map((link) => (
89
- <NavbarLinkItem key={link.href} link={link} />
90
- ))}
91
- </NavbarPrimitive.Links>
92
-
93
- <div className="hidden sm:flex items-center gap-2">
94
- {config.i18n && currentLocale && <I18nSelector />}
95
- <NavbarPrimitive.Split className="bg-subtle" />
96
- </div>
97
-
98
- <div className="hidden md:block">
99
- <ThemeToggle />
100
- </div>
101
-
102
- {github && (
103
- <div className="hidden md:block">
104
- <GithubStars repo={themeConfig?.githubRepo ?? ''} />
105
- </div>
106
- )}
107
- {social.length > 0 && (
108
- <div className="hidden md:block">
109
- <NavbarPrimitive.Split className="bg-subtle" />
110
- </div>
111
- )}
112
- <div className="hidden md:flex items-center gap-1">
113
- {social.map(({ icon, link }: BoltdocsSocialLink) => (
114
- <NavbarPrimitive.Socials
115
- key={link}
116
- icon={icon}
117
- link={link}
118
- className="p-1.5 text-muted hover:text-body hover:bg-surface rounded-md transition-all focus-visible:ring-2 focus-visible:ring-primary-500/30"
119
- />
120
- ))}
121
- </div>
122
-
123
- <NavbarPrimitive.More
124
- onPress={() => setIsMobileMenuOpen(true)}
125
- className="text-muted hover:text-body active:scale-90 transition-all focus-visible:ring-2 focus-visible:ring-primary-500/30"
126
- />
127
- </NavbarPrimitive.Right>
128
- </NavbarPrimitive.Content>
129
-
130
- <NavbarPrimitive.MobileMenu
131
- isOpen={isMobileMenuOpen}
132
- onClose={() => setIsMobileMenuOpen(false)}
133
- className="bg-main/98 backdrop-blur-2xl"
134
- >
135
- <div className="flex flex-col gap-1">
136
- {links.map((link) => (
137
- <NavbarMobileLinkItem
138
- key={link.href}
139
- link={link}
140
- onClose={() => setIsMobileMenuOpen(false)}
141
- />
142
- ))}
143
- </div>
144
-
145
- {social.length > 0 && (
146
- <div className="mt-6">
147
- <div className="px-4 mb-4 text-xs font-bold uppercase tracking-widest text-muted/50">
148
- Connect
149
- </div>
150
- <div className="flex flex-wrap gap-2 px-2">
151
- {social.map(({ icon, link }: BoltdocsSocialLink) => (
152
- <NavbarPrimitive.Socials
153
- key={link}
154
- icon={icon}
155
- link={link}
156
- className="p-3 bg-surface border border-subtle rounded-xl flex-1 justify-center"
157
- />
158
- ))}
159
- </div>
160
- </div>
161
- )}
162
- </NavbarPrimitive.MobileMenu>
163
-
164
- {isDocs && hasTabs && themeConfig?.tabs && (
165
- <div className="w-full border-b border-subtle bg-main">
166
- <Tabs tabs={themeConfig.tabs} routes={allRoutes || routes || []} />
167
- </div>
168
- )}
169
- </NavbarPrimitive.Root>
170
- )
171
- }
172
-
173
- function NavbarLinkItem({ link }: { link: NavbarLinkType }) {
174
- const localizedHref = useLocalizedTo(link.href || '')
175
- const { pathname } = useLocation()
176
- const active =
177
- pathname === localizedHref || pathname.startsWith(localizedHref + '/')
178
- const hasItems = link.items && link.items.length > 0
179
-
180
- if (hasItems) {
181
- return (
182
- <NavbarPrimitive.Dropdown
183
- label={
184
- <span
185
- className={cn(
186
- 'transition-colors outline-none font-medium focus-visible:ring-2 focus-visible:ring-primary-500/30 rounded-sm px-2 py-1',
187
- active ? 'text-primary-500' : 'text-muted hover:text-body',
188
- )}
189
- >
190
- {link.label as any}
191
- </span>
192
- }
193
- >
194
- {link.items?.map((item) => (
195
- <NavbarPrimitive.DropdownItem
196
- key={item.href}
197
- href={useLocalizedTo(item.href || '')}
198
- label={item.label as any}
199
- />
200
- ))}
201
- </NavbarPrimitive.Dropdown>
202
- )
203
- }
204
-
205
- return (
206
- <NavbarPrimitive.Link
207
- {...(link as any)}
208
- href={localizedHref}
209
- active={active}
210
- className={cn(
211
- 'transition-colors outline-none font-medium focus-visible:ring-2 focus-visible:ring-primary-500/30 rounded-sm',
212
- active ? 'text-primary-500' : 'text-muted hover:text-body',
213
- )}
214
- />
215
- )
216
- }
217
-
218
- function NavbarMobileLinkItem({
219
- link,
220
- onClose,
221
- }: {
222
- link: NavbarLinkType
223
- onClose: () => void
224
- }) {
225
- const localizedHref = useLocalizedTo(link.href || '')
226
- const { pathname } = useLocation()
227
- const active = pathname === localizedHref
228
- const hasItems = link.items && link.items.length > 0
229
-
230
- if (hasItems) {
231
- return (
232
- <div className="flex flex-col gap-1">
233
- <div
234
- className={cn(
235
- 'px-3 py-2 text-sm transition-all',
236
- active ? 'text-body' : 'text-muted/80 hover:text-body',
237
- )}
238
- >
239
- {link.label as any}
240
- </div>
241
- <div className="flex flex-col gap-1 pl-4">
242
- {link.items?.map((item) => (
243
- <NavbarMobileLinkItem
244
- key={item.href}
245
- link={item}
246
- onClose={onClose}
247
- />
248
- ))}
249
- </div>
250
- </div>
251
- )
252
- }
253
-
254
- return (
255
- <NavbarPrimitive.MobileLink
256
- {...(link as any)}
257
- href={localizedHref}
258
- active={active}
259
- onPress={onClose}
260
- className={cn(
261
- 'transition-all',
262
- active ? 'text-body' : 'text-muted/80 hover:text-body',
263
- )}
264
- />
265
- )
266
- }
@@ -1,26 +0,0 @@
1
- import { ArrowLeft } from './icons'
2
- import { Link } from '../primitives/link'
3
-
4
- export function NotFound() {
5
- return (
6
- <div className="flex items-center justify-center min-h-[65vh] text-center px-4">
7
- <div className="space-y-6 max-w-md mx-auto p-8 border border-subtle bg-surface rounded-2xl shadow-xs">
8
- <span className="block text-7xl font-extrabold tracking-tight text-primary-500">
9
- 404
10
- </span>
11
- <div className="space-y-2">
12
- <h1 className="text-xl font-bold text-body">Page Not Found</h1>
13
- <p className="text-sm text-muted leading-relaxed">
14
- The page you're looking for doesn't exist or has been moved.
15
- </p>
16
- </div>
17
- <Link
18
- href="/"
19
- className="inline-flex items-center gap-2 rounded-xl border border-subtle bg-main px-6 py-2.5 text-xs font-semibold text-body hover:bg-primary-50/50 hover:border-primary-500/50 transition-all duration-300 outline-none select-none"
20
- >
21
- <ArrowLeft size={14} /> Go to Home
22
- </Link>
23
- </div>
24
- </div>
25
- )
26
- }
@@ -1,57 +0,0 @@
1
- import { OnThisPage as OTP } from '../primitives/on-this-page'
2
- import type { OnThisPageProps } from '../../types'
3
- import { Pencil, CircleHelp, TextAlignStart } from './icons'
4
-
5
- export function OnThisPage({
6
- headings = [],
7
- editLink,
8
- communityHelp,
9
- filePath,
10
- }: OnThisPageProps) {
11
- if (headings.length === 0) return null
12
-
13
- return (
14
- <OTP.Root>
15
- <OTP.Header className="flex flex-row gap-x-2">
16
- <TextAlignStart size={16} />
17
- On this page
18
- </OTP.Header>
19
-
20
- <OTP.Tree headings={headings} />
21
-
22
- {(editLink || communityHelp) && (
23
- <div className="mt-8 pt-8 border-t border-subtle space-y-4">
24
- <p className="text-xs font-bold text-body">Need help?</p>
25
- <ul className="space-y-3">
26
- {editLink && filePath && (
27
- <li>
28
- <a
29
- href={editLink.replace(':path', filePath)}
30
- target="_blank"
31
- rel="noopener noreferrer"
32
- className="flex items-center gap-2 text-sm text-muted hover:text-body transition-colors"
33
- >
34
- <Pencil size={16} />
35
- Edit this page
36
- </a>
37
- </li>
38
- )}
39
- {communityHelp && (
40
- <li>
41
- <a
42
- href={communityHelp}
43
- target="_blank"
44
- rel="noopener noreferrer"
45
- className="flex items-center gap-2 text-sm text-muted hover:text-body transition-colors"
46
- >
47
- <CircleHelp size={16} />
48
- Community help
49
- </a>
50
- </li>
51
- )}
52
- </ul>
53
- </div>
54
- )}
55
- </OTP.Root>
56
- )
57
- }
@@ -1,50 +0,0 @@
1
- import { usePageNav } from '../../hooks/use-page-nav'
2
- import { PageNav as PageNavPrimitive } from '../primitives/page-nav'
3
-
4
- /**
5
- * Component to display the previous and next page navigation buttons.
6
- * Enhanced with subtle entrance animations, modern card layout, and hover highlights.
7
- */
8
- export function PageNav() {
9
- const { prevPage, nextPage } = usePageNav()
10
-
11
- if (!prevPage && !nextPage) return null
12
-
13
- return (
14
- <PageNavPrimitive.Root className="pt-8 border-t border-subtle grid sm:grid-cols-2 gap-4 animate-in fade-in slide-in-from-bottom-4 duration-700 select-none">
15
- {prevPage ? (
16
- <PageNavPrimitive.Link
17
- to={prevPage.path}
18
- direction="prev"
19
- className="group border border-subtle bg-surface p-5 rounded-2xl transition-all duration-300 hover:border-primary-500/50 hover:bg-primary-50/20"
20
- >
21
- <PageNavPrimitive.Title className="text-xs font-bold uppercase tracking-wider text-muted/60 mb-1">
22
- Previous
23
- </PageNavPrimitive.Title>
24
- <PageNavPrimitive.Description className="text-sm sm:text-base font-bold text-body group-hover:text-primary-500 transition-colors">
25
- {prevPage.title}
26
- </PageNavPrimitive.Description>
27
- </PageNavPrimitive.Link>
28
- ) : (
29
- <div />
30
- )}
31
-
32
- {nextPage ? (
33
- <PageNavPrimitive.Link
34
- to={nextPage.path}
35
- direction="next"
36
- className="group border border-subtle bg-surface p-5 rounded-2xl transition-all duration-300 hover:border-primary-500/50 hover:bg-primary-50/20"
37
- >
38
- <PageNavPrimitive.Title className="text-xs font-bold uppercase tracking-wider text-muted/60 mb-1">
39
- Next
40
- </PageNavPrimitive.Title>
41
- <PageNavPrimitive.Description className="text-sm sm:text-base font-bold text-body group-hover:text-primary-500 transition-colors">
42
- {nextPage.title}
43
- </PageNavPrimitive.Description>
44
- </PageNavPrimitive.Link>
45
- ) : (
46
- <div />
47
- )}
48
- </PageNavPrimitive.Root>
49
- )
50
- }
@@ -1,163 +0,0 @@
1
- import { useEffect, useCallback } from 'react'
2
- import { Search } from './icons'
3
- import { useSearch } from '../../hooks/use-search'
4
- import { SearchDialog as SearchDialogPrimitive } from '../primitives/search-dialog'
5
- import Navbar from '../primitives/navbar'
6
- import { useNavigate } from 'react-router-dom'
7
- import type { ComponentRoute } from '../../types'
8
-
9
- interface SearchResult {
10
- id: string
11
- title: string
12
- path: string
13
- bio: string
14
- groupTitle?: string
15
- isHeading?: boolean
16
- }
17
-
18
- function Highlight({ text, query }: { text: string; query: string }) {
19
- if (!query || !text) return <>{text}</>
20
- const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
21
- const regex = new RegExp(`(${escapedQuery})`, 'gi')
22
- const parts = text.split(regex)
23
- return (
24
- <>
25
- {parts.map((part, i) =>
26
- regex.test(part) ? (
27
- <mark
28
- key={i}
29
- className="bg-primary-500/20 text-primary-600 dark:text-primary-400 font-bold px-0.5 rounded-sm"
30
- >
31
- {part}
32
- </mark>
33
- ) : (
34
- part
35
- ),
36
- )}
37
- </>
38
- )
39
- }
40
-
41
- export function SearchDialog({ routes }: { routes: ComponentRoute[] }) {
42
- const { isOpen, setIsOpen, query, setQuery, list } = useSearch(routes)
43
- const navigate = useNavigate()
44
-
45
- useEffect(() => {
46
- const handleKeyDown = (e: KeyboardEvent) => {
47
- const isMac = /Mac/.test(navigator.userAgent)
48
- const isMeta = isMac ? e.metaKey : e.ctrlKey
49
-
50
- if (isMeta && (e.key === 'k' || e.key === 'j')) {
51
- e.preventDefault()
52
- setIsOpen((prev) => !prev)
53
- }
54
- }
55
- window.addEventListener('keydown', handleKeyDown)
56
- return () => window.removeEventListener('keydown', handleKeyDown)
57
- }, [setIsOpen])
58
-
59
- const handleSelect = useCallback(
60
- (key: React.Key) => {
61
- const path = String(key)
62
- setIsOpen(false)
63
-
64
- const [baseUrl, hash] = path.split('#')
65
- const search = query ? `?hl=${encodeURIComponent(query)}` : ''
66
- const finalPath = `${baseUrl}${search}${hash ? `#${hash}` : ''}`
67
-
68
- navigate(finalPath)
69
-
70
- if (hash) {
71
- setTimeout(() => {
72
- const el = document.getElementById(hash)
73
- if (el) el.scrollIntoView({ behavior: 'smooth' })
74
- }, 100)
75
- }
76
- },
77
- [navigate, setIsOpen, query],
78
- )
79
-
80
- return (
81
- <>
82
- <Navbar.SearchTrigger.Desktop
83
- onPress={() => setIsOpen(true)}
84
- className="rounded-xl border border-subtle bg-surface text-muted transition-all duration-200 hover:border-primary-500/50 hover:text-body hover:bg-soft/50 hover:shadow-sm active:scale-[0.98] focus-visible:ring-2 focus-visible:ring-primary-500/30"
85
- >
86
- <div className="flex items-center gap-2">
87
- <Search size={16} />
88
- <span className="hidden sm:inline-block">Search docs...</span>
89
- </div>
90
- <Navbar.SearchTrigger.Kbd className="[&_kbd]:bg-main [&_kbd]:border [&_kbd]:border-subtle [&_kbd]:rounded [&_kbd]:px-1.5 [&_kbd]:h-5 [&_kbd]:w-5" />
91
- </Navbar.SearchTrigger.Desktop>
92
-
93
- <Navbar.SearchTrigger.Mobile
94
- onPress={() => setIsOpen(true)}
95
- className="rounded-xl text-muted transition-all duration-200 hover:text-body active:scale-95 focus-visible:ring-2 focus-visible:ring-primary-500/30"
96
- >
97
- <Search size={20} />
98
- </Navbar.SearchTrigger.Mobile>
99
-
100
- <SearchDialogPrimitive.Overlay
101
- isOpen={isOpen}
102
- isDismissable
103
- onOpenChange={() => setIsOpen(false)}
104
- className="fixed inset-0 z-100 flex items-center justify-center p-4 bg-black/40 backdrop-blur-xs animate-fade-in"
105
- >
106
- <SearchDialogPrimitive.Content className="w-full max-w-lg bg-main border border-subtle shadow-md rounded-2xl overflow-hidden p-6">
107
- <SearchDialogPrimitive.Dialog
108
- aria-label="Search documentation"
109
- className="flex flex-col min-h-0 h-[450px]"
110
- >
111
- <SearchDialogPrimitive.Autocomplete
112
- onSelectionChange={handleSelect}
113
- className="flex flex-col min-h-0"
114
- >
115
- <SearchDialogPrimitive.Input
116
- value={query}
117
- onChange={setQuery}
118
- className="flex items-center gap-2 border border-subtle bg-surface px-4 py-2.5 rounded-xl focus-within:border-primary-500 mb-4"
119
- >
120
- <SearchDialogPrimitive.Input.SearchInput
121
- placeholder="Search documentation..."
122
- className="w-full bg-transparent outline-none text-body text-sm"
123
- />
124
- {query && (
125
- <SearchDialogPrimitive.Input.Button
126
- onPress={() => setQuery('')}
127
- className="text-muted hover:text-body text-xs cursor-pointer select-none"
128
- >
129
-
130
- </SearchDialogPrimitive.Input.Button>
131
- )}
132
- </SearchDialogPrimitive.Input>
133
-
134
- <SearchDialogPrimitive.List items={list as SearchResult[]}>
135
- {(item: SearchResult) => (
136
- <SearchDialogPrimitive.Item
137
- key={item.id}
138
- onPress={() => handleSelect(item.id)}
139
- textValue={item.title}
140
- className="flex items-center gap-3 px-4 py-2 rounded-xl group dark:hover:bg-primary-300/40 hover:bg-primary-200/50 transition-colors duration-100"
141
- >
142
- <SearchDialogPrimitive.Item.Icon
143
- isHeading={item.isHeading}
144
- className="text-muted group-hover:text-primary-500 group-focus:text-primary-500"
145
- />
146
- <div className="flex flex-col justify-center min-w-0">
147
- <SearchDialogPrimitive.Item.Title className="text-sm font-medium text-body truncate dark:group-hover:text-primary-100">
148
- <Highlight text={item.title} query={query} />
149
- </SearchDialogPrimitive.Item.Title>
150
- <SearchDialogPrimitive.Item.Bio className="text-xs text-muted truncate">
151
- <Highlight text={item.bio} query={query} />
152
- </SearchDialogPrimitive.Item.Bio>
153
- </div>
154
- </SearchDialogPrimitive.Item>
155
- )}
156
- </SearchDialogPrimitive.List>
157
- </SearchDialogPrimitive.Autocomplete>
158
- </SearchDialogPrimitive.Dialog>
159
- </SearchDialogPrimitive.Content>
160
- </SearchDialogPrimitive.Overlay>
161
- </>
162
- )
163
- }
@@ -1,10 +0,0 @@
1
- import { useSearchHighlight } from '../../hooks/use-search-highlight'
2
-
3
- /**
4
- * Component that enables search term highlighting on the page.
5
- * It doesn't render anything visible.
6
- */
7
- export function SearchHighlight() {
8
- useSearchHighlight('.boltdocs-page')
9
- return null
10
- }
@@ -1,92 +0,0 @@
1
- import { Sidebar as SidebarPrimitive } from '../primitives/sidebar'
2
- import { X } from './icons'
3
- import type { ComponentRoute } from '../../types'
4
- import type { BoltdocsConfig } from '../../../shared/types'
5
- import { VersionSelector, I18nSelector } from './version-i18n'
6
- import { ThemeSwitcher } from './theme-toggle'
7
- import { useNavbar } from '../../hooks/use-navbar'
8
- import { useUI } from '../../app/ui-context'
9
- import { Button } from '../primitives/button'
10
-
11
- interface SidebarProps {
12
- routes: ComponentRoute[]
13
- config: BoltdocsConfig
14
- }
15
-
16
- function SidebarMain({ routes, config }: SidebarProps) {
17
- const { logo, title, logoProps } = useNavbar()
18
- const { closeSidebar } = useUI()
19
-
20
- const SidebarLogo = logo ? (
21
- <img
22
- src={logo}
23
- alt={logoProps?.alt || title}
24
- width={24}
25
- height={24}
26
- className="rounded-xl"
27
- />
28
- ) : null
29
-
30
- const hasUtilities = config.versions || config.i18n
31
-
32
- return (
33
- <>
34
- {/* Desktop Version */}
35
- <SidebarPrimitive.Root>
36
- <SidebarPrimitive.Content>
37
- <SidebarPrimitive.Items routes={routes} />
38
- </SidebarPrimitive.Content>
39
- </SidebarPrimitive.Root>
40
-
41
- {/* Mobile Version */}
42
- <SidebarPrimitive.Mobile>
43
- <SidebarPrimitive.Header>
44
- <div className="flex items-center gap-3">
45
- {SidebarLogo}
46
- <span className="font-bold text-lg tracking-tight text-body truncate max-w-[120px]">
47
- {title}
48
- </span>
49
- </div>
50
- <div className="flex items-center gap-2">
51
- <ThemeSwitcher className="w-24 h-9 rounded-xl" />
52
- <Button
53
- onPress={closeSidebar}
54
- className="h-9 w-9 flex items-center justify-center bg-transparent border-none outline-none select-none cursor-pointer rounded-xl hover:bg-primary-50/50 text-muted hover:text-body transition-colors"
55
- aria-label="Close sidebar"
56
- >
57
- <X size={20} />
58
- </Button>
59
- </div>
60
- </SidebarPrimitive.Header>
61
- <SidebarPrimitive.Content>
62
- {hasUtilities && (
63
- <div className="flex flex-col gap-4 mb-10">
64
- <div className="flex gap-3">
65
- {config.versions && (
66
- <VersionSelector className="flex-1 justify-between h-10 bg-surface border-subtle rounded-xl" />
67
- )}
68
- {config.i18n && (
69
- <I18nSelector className="flex-1 justify-between h-10 bg-surface border-subtle rounded-xl" />
70
- )}
71
- </div>
72
- <div className="mt-2 border-b border-subtle" />
73
- </div>
74
- )}
75
- <SidebarPrimitive.Items routes={routes} />
76
- </SidebarPrimitive.Content>
77
- </SidebarPrimitive.Mobile>
78
- </>
79
- )
80
- }
81
-
82
- export const Sidebar = Object.assign(SidebarMain, {
83
- Root: SidebarPrimitive.Root,
84
- Mobile: SidebarPrimitive.Mobile,
85
- Header: SidebarPrimitive.Header,
86
- Content: SidebarPrimitive.Content,
87
- Group: SidebarPrimitive.Group,
88
- Link: SidebarPrimitive.Link,
89
- SubGroup: SidebarPrimitive.SubGroup,
90
- Item: SidebarPrimitive.Item,
91
- Items: SidebarPrimitive.Items,
92
- })