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,423 +0,0 @@
1
- import {
2
- type ReactNode,
3
- useRef,
4
- useLayoutEffect,
5
- useEffect,
6
- useState,
7
- } from 'react'
8
- import * as RAC from 'react-aria-components'
9
- import { cn } from '../../utils/cn'
10
- import { useUI } from '../../app/ui-context'
11
- import { Link } from './link'
12
- import { ChevronRight } from '../ui-base/icons'
13
- import type { ComponentBase } from './types'
14
- import type { ComponentRoute } from '../../types'
15
- import { useSidebar } from '../../hooks/use-sidebar'
16
- import { useLocalizedTo } from '../../hooks/use-localized-to'
17
- import * as DefaultIcons from '../ui-base/icons'
18
- import virtualIcons from 'virtual:boltdocs-icons'
19
-
20
- // Persistent scroll position across navigation (SPA)
21
- let sidebarScrollPos = 0
22
-
23
- function getIcon(iconName?: string): React.ElementType | undefined {
24
- if (!iconName) return undefined
25
- const icons = { ...DefaultIcons, ...virtualIcons } as unknown as Record<
26
- string,
27
- React.ElementType
28
- >
29
- const IconComponent = icons[iconName] || icons[iconName + 'Icon']
30
- return IconComponent || undefined
31
- }
32
-
33
- /**
34
- * Internal Badge component for links
35
- */
36
- const Badge = ({ badge }: { badge: ComponentRoute['badge'] }) => {
37
- const colors = {
38
- new: 'bg-primary-500/10 text-primary-500 border border-primary-500/20',
39
- updated: 'bg-emerald-500/10 text-emerald-500 border border-emerald-500/20',
40
- deprecated: 'bg-danger-500/10 text-danger-500 border border-danger-500/20',
41
- }
42
-
43
- const text = typeof badge === 'string' ? badge : badge?.text
44
- if (!text) return null
45
-
46
- return (
47
- <span
48
- className={cn(
49
- 'ml-auto flex h-5 items-center rounded-md text-[10px] font-bold px-1.5 py-0.5 uppercase tracking-wider',
50
- colors[text as keyof typeof colors] || colors.new,
51
- )}
52
- >
53
- {text}
54
- </span>
55
- )
56
- }
57
-
58
- /**
59
- * Desktop Sidebar Container
60
- */
61
- export function SidebarRoot({ children, className }: ComponentBase) {
62
- return (
63
- <aside
64
- className={cn(
65
- 'hidden lg:flex flex-col w-sidebar sticky top-navbar h-[calc(100vh-var(--spacing-navbar))] border-r border-subtle bg-main',
66
- className,
67
- )}
68
- >
69
- {children}
70
- </aside>
71
- )
72
- }
73
-
74
- /**
75
- * Mobile Sidebar Modal
76
- */
77
- export function SidebarMobile({ children, className }: ComponentBase) {
78
- const { isSidebarOpen, closeSidebar } = useUI()
79
-
80
- return (
81
- <RAC.ModalOverlay
82
- isOpen={isSidebarOpen}
83
- onOpenChange={(open) => !open && closeSidebar()}
84
- isDismissable={true}
85
- className={cn(
86
- 'fixed inset-0 z-50 bg-black/20 backdrop-blur-sm lg:hidden',
87
- 'entering:animate-in entering:fade-in exiting:animate-out exiting:fade-out duration-300',
88
- )}
89
- >
90
- <RAC.Modal
91
- className={cn(
92
- 'fixed top-0 left-0 bottom-0 w-80 bg-main border-r border-subtle shadow-2xl outline-none',
93
- 'entering:animate-in entering:slide-in-from-left exiting:animate-out exiting:slide-out-to-left duration-300',
94
- className,
95
- )}
96
- >
97
- <RAC.Dialog className="h-full focus:outline-none outline-none flex flex-col">
98
- {children}
99
- </RAC.Dialog>
100
- </RAC.Modal>
101
- </RAC.ModalOverlay>
102
- )
103
- }
104
-
105
- /**
106
- * Shared Header for Sidebar
107
- */
108
- export function SidebarHeader({ children, className }: ComponentBase) {
109
- return (
110
- <div
111
- className={cn(
112
- 'flex items-center justify-between p-4 border-b border-subtle',
113
- className,
114
- )}
115
- >
116
- {children}
117
- </div>
118
- )
119
- }
120
-
121
- /**
122
- * Scrollable Content Wrapper
123
- */
124
- export function SidebarContent({ children, className }: ComponentBase) {
125
- const scrollRef = useRef<HTMLDivElement>(null)
126
-
127
- // Restore scroll position
128
- useLayoutEffect(() => {
129
- if (scrollRef.current) {
130
- scrollRef.current.scrollTop = sidebarScrollPos
131
- }
132
- }, [])
133
-
134
- // Save scroll position
135
- useEffect(() => {
136
- const el = scrollRef.current
137
- if (!el) return
138
- const handleScroll = () => {
139
- sidebarScrollPos = el.scrollTop
140
- }
141
- el.addEventListener('scroll', handleScroll, { passive: true })
142
- return () => el.removeEventListener('scroll', handleScroll)
143
- }, [])
144
-
145
- return (
146
- <div
147
- ref={scrollRef}
148
- className={cn(
149
- 'flex-1 overflow-y-auto p-4 pb-16 custom-scrollbar',
150
- className,
151
- )}
152
- >
153
- <nav className="flex flex-col gap-6">{children}</nav>
154
- </div>
155
- )
156
- }
157
-
158
- /**
159
- * Navigation Group
160
- */
161
- export const SidebarGroup = ({
162
- title,
163
- icon: Icon,
164
- children,
165
- className,
166
- }: { title?: string; icon?: React.ElementType } & ComponentBase) => {
167
- return (
168
- <div className={className}>
169
- {title && (
170
- <h4 className="px-2 mb-2 flex items-center gap-2 text-[11px] font-bold uppercase tracking-widest text-muted/50">
171
- {Icon && <Icon size={12} />}
172
- {title}
173
- </h4>
174
- )}
175
- <div className="flex flex-col gap-0.5">{children}</div>
176
- </div>
177
- )
178
- }
179
-
180
- /**
181
- * Sidebar Link
182
- */
183
- export interface SidebarLinkProps extends ComponentBase {
184
- label: string
185
- href: string
186
- active?: boolean
187
- icon?: React.ElementType
188
- badge?: ComponentRoute['badge']
189
- }
190
-
191
- export const SidebarLink = ({
192
- label,
193
- href,
194
- active,
195
- icon: Icon,
196
- badge,
197
- className,
198
- }: SidebarLinkProps) => {
199
- return (
200
- <Link
201
- href={href}
202
- className={cn(
203
- 'group flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-sm transition-all outline-none',
204
- active
205
- ? 'bg-primary-500/10 text-primary-500 font-medium shadow-sm'
206
- : 'text-muted hover:bg-surface hover:text-body',
207
- className,
208
- )}
209
- >
210
- {Icon && (
211
- <Icon
212
- size={16}
213
- className={cn(
214
- active ? 'text-primary-500' : 'text-muted group-hover:text-body',
215
- )}
216
- />
217
- )}
218
- <span className="truncate">{label}</span>
219
- {badge && <Badge badge={badge} />}
220
- </Link>
221
- )
222
- }
223
-
224
- /**
225
- * Nested SubGroup
226
- */
227
- export const SidebarSubGroup = ({
228
- label,
229
- href,
230
- active,
231
- icon: Icon,
232
- badge,
233
- isOpen,
234
- onToggle,
235
- children,
236
- className,
237
- }: SidebarLinkProps & {
238
- isOpen: boolean
239
- onToggle: () => void
240
- children: ReactNode
241
- }) => {
242
- return (
243
- <div className="flex flex-col gap-0.5">
244
- <div className="group relative flex items-center">
245
- <SidebarLink
246
- label={label}
247
- href={href}
248
- active={active}
249
- icon={Icon}
250
- badge={badge}
251
- className={cn('flex-1 pr-8', className)}
252
- />
253
- <button
254
- onClick={(e) => {
255
- e.preventDefault()
256
- e.stopPropagation()
257
- onToggle()
258
- }}
259
- className="absolute right-1 p-1.5 text-muted hover:text-body transition-colors outline-none cursor-pointer"
260
- >
261
- <ChevronRight
262
- size={14}
263
- className={cn(
264
- 'transition-transform duration-200',
265
- isOpen && 'rotate-90',
266
- )}
267
- />
268
- </button>
269
- </div>
270
- {isOpen && (
271
- <div className="ml-4 pl-3 border-l border-subtle/50 mt-0.5 flex flex-col gap-0.5">
272
- {children}
273
- </div>
274
- )}
275
- </div>
276
- )
277
- }
278
-
279
- /**
280
- * Automated single-route rendering primitive
281
- */
282
- export interface SidebarItemProps extends ComponentBase {
283
- route: ComponentRoute
284
- activePath: string
285
- activeRoute?: ComponentRoute
286
- }
287
-
288
- export function SidebarItem({
289
- route,
290
- activePath,
291
- activeRoute,
292
- className,
293
- }: SidebarItemProps) {
294
- const localizedHref = useLocalizedTo(route.path)
295
- const isCurrent =
296
- activePath ===
297
- (localizedHref.endsWith('/')
298
- ? localizedHref.slice(0, -1)
299
- : localizedHref) ||
300
- (!!activeRoute?.filePath &&
301
- !!route.filePath &&
302
- activeRoute.filePath === route.filePath)
303
- const hasChildren = !!route.routes?.length || !!route.subRoutes?.length
304
- const children = route.routes || route.subRoutes
305
-
306
- const [isOpen, setIsOpen] = useState(
307
- () =>
308
- activePath.startsWith(localizedHref) ||
309
- (!!activeRoute?.filePath &&
310
- !!route.filePath &&
311
- activeRoute.filePath === route.filePath),
312
- )
313
- const [prevActivePath, setPrevActivePath] = useState(activePath)
314
-
315
- if (activePath !== prevActivePath) {
316
- setPrevActivePath(activePath)
317
- if (
318
- activePath.startsWith(localizedHref) ||
319
- (!!activeRoute?.filePath &&
320
- !!route.filePath &&
321
- activeRoute.filePath === route.filePath)
322
- ) {
323
- setIsOpen(true)
324
- }
325
- }
326
-
327
- if (hasChildren) {
328
- return (
329
- <SidebarSubGroup
330
- label={route.title}
331
- href={route.path}
332
- active={isCurrent}
333
- icon={getIcon(route.icon)}
334
- badge={route.badge}
335
- isOpen={isOpen}
336
- onToggle={() => setIsOpen(!isOpen)}
337
- className={className}
338
- >
339
- {children?.map((subRoute) => (
340
- <SidebarItem
341
- key={subRoute.path}
342
- route={subRoute}
343
- activePath={activePath}
344
- activeRoute={activeRoute}
345
- />
346
- ))}
347
- </SidebarSubGroup>
348
- )
349
- }
350
-
351
- return (
352
- <SidebarLink
353
- label={route.title}
354
- href={route.path}
355
- active={isCurrent}
356
- icon={getIcon(route.icon)}
357
- badge={route.badge}
358
- className={className}
359
- />
360
- )
361
- }
362
-
363
- /**
364
- * High-level automated routes data rendering primitive
365
- */
366
- export interface SidebarItemsProps extends ComponentBase {
367
- routes: ComponentRoute[]
368
- }
369
-
370
- export function SidebarItems({ routes, className }: SidebarItemsProps) {
371
- const { groups, ungrouped, activePath, activeRoute } = useSidebar(routes)
372
-
373
- return (
374
- <div className={cn('flex flex-col gap-6', className)}>
375
- {ungrouped.length > 0 && (
376
- <SidebarGroup>
377
- {ungrouped.map((route) => (
378
- <SidebarItem
379
- key={route.path}
380
- route={route}
381
- activePath={activePath}
382
- activeRoute={activeRoute}
383
- />
384
- ))}
385
- </SidebarGroup>
386
- )}
387
-
388
- {groups.map((group) => (
389
- <SidebarGroup
390
- key={group.title}
391
- title={group.title}
392
- icon={getIcon(group.icon)}
393
- >
394
- {group.routes.map((route) => (
395
- <SidebarItem
396
- key={route.path}
397
- route={route}
398
- activePath={activePath}
399
- activeRoute={activeRoute}
400
- />
401
- ))}
402
- </SidebarGroup>
403
- ))}
404
- </div>
405
- )
406
- }
407
-
408
- /**
409
- * Main Sidebar Export
410
- */
411
- export const Sidebar = Object.assign(SidebarRoot, {
412
- Root: SidebarRoot,
413
- Mobile: SidebarMobile,
414
- Header: SidebarHeader,
415
- Content: SidebarContent,
416
- Group: SidebarGroup,
417
- Link: SidebarLink,
418
- SubGroup: SidebarSubGroup,
419
- Item: SidebarItem,
420
- Items: SidebarItems,
421
- })
422
-
423
- export default Sidebar
@@ -1,26 +0,0 @@
1
- import { cn } from '../../utils/cn'
2
-
3
- interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
4
- variant?: 'rect' | 'circle'
5
- }
6
-
7
- /**
8
- * A flexible skeleton component that mimics the shape of content
9
- * while it is loading. Features a smooth pulse animation.
10
- */
11
- export function Skeleton({
12
- className,
13
- variant = 'rect',
14
- ...props
15
- }: SkeletonProps) {
16
- return (
17
- <div
18
- className={cn(
19
- 'animate-pulse bg-soft',
20
- variant === 'circle' ? 'rounded-full' : 'rounded-md',
21
- className,
22
- )}
23
- {...props}
24
- />
25
- )
26
- }
@@ -1,70 +0,0 @@
1
- import { cn } from '../../utils/cn'
2
- import type { ComponentBase } from './types'
3
-
4
- export interface TabsItemProps extends ComponentBase {
5
- id: string
6
- selected?: boolean
7
- onClick?: () => void
8
- onKeyDown?: (event: React.KeyboardEvent) => void
9
- disabled?: boolean
10
- }
11
-
12
- export interface TabsIndicatorProps extends ComponentBase {
13
- style?: React.CSSProperties
14
- }
15
-
16
- export const Tabs = ({ children, className = '', ...props }: ComponentBase) => {
17
- return (
18
- <div className={cn('w-full', className)} {...props}>
19
- {children}
20
- </div>
21
- )
22
- }
23
-
24
- const TabsList = ({ children, className = '' }: ComponentBase) => {
25
- return (
26
- <div
27
- role="tablist"
28
- className={cn('relative flex flex-row items-center', className)}
29
- >
30
- {children}
31
- </div>
32
- )
33
- }
34
-
35
- const TabsItem = ({
36
- children,
37
- id,
38
- selected,
39
- className = '',
40
- ...props
41
- }: TabsItemProps) => {
42
- return (
43
- <button
44
- role="tab"
45
- aria-selected={selected}
46
- data-selected={selected}
47
- className={cn(
48
- 'outline-none cursor-pointer bg-transparent border-none',
49
- className,
50
- )}
51
- {...props}
52
- >
53
- {children}
54
- </button>
55
- )
56
- }
57
-
58
- const TabsContent = ({ children, className = '' }: ComponentBase) => {
59
- return <div className={cn('outline-none', className)}>{children}</div>
60
- }
61
-
62
- const TabsIndicator = ({ className = '', style }: TabsIndicatorProps) => {
63
- return <div className={cn('absolute bottom-0', className)} style={style} />
64
- }
65
-
66
- Tabs.Root = Tabs
67
- Tabs.List = TabsList
68
- Tabs.Item = TabsItem
69
- Tabs.Content = TabsContent
70
- Tabs.Indicator = TabsIndicator
@@ -1,81 +0,0 @@
1
- import type { ReactNode } from 'react'
2
- import * as RAC from 'react-aria-components'
3
- import { cn } from '../../utils/cn'
4
-
5
- export interface TooltipProps extends Omit<RAC.TooltipProps, 'children'> {
6
- /** The content to show inside the tooltip */
7
- content: ReactNode
8
- /** The trigger element (usually a button or link) */
9
- children: React.ReactElement
10
- /** Delay in milliseconds before showing the tooltip */
11
- delay?: number
12
- /** Delay in milliseconds before hiding the tooltip */
13
- closeDelay?: number
14
- }
15
-
16
- // Fixed type for TooltipContentProps to match RAC's internal expectations
17
- export interface TooltipContentProps extends RAC.TooltipProps {}
18
-
19
- /**
20
- * Modern, accessible Tooltip component built with React Aria Components.
21
- * Featuring glassmorphism, animations, and smart positioning.
22
- */
23
- const TooltipContent = ({
24
- className,
25
- children,
26
- ...props
27
- }: TooltipContentProps) => {
28
- return (
29
- <RAC.Tooltip
30
- {...props}
31
- offset={8}
32
- className={(values) =>
33
- cn(
34
- 'group z-50 overflow-visible rounded-md bg-surface px-2.5 py-1.5 text-xs font-medium text-body ring-1 ring-subtle outline-hidden select-none',
35
- 'data-entering:animate-in data-entering:fade-in data-entering:zoom-in-95 data-entering:duration-100',
36
- 'data-exiting:animate-out data-exiting:fade-out data-exiting:zoom-out-95 data-exiting:duration-75',
37
- 'data-[placement=top]:slide-in-from-bottom-1',
38
- 'data-[placement=bottom]:slide-in-from-top-1',
39
- 'data-[placement=left]:slide-in-from-right-1',
40
- 'data-[placement=right]:slide-in-from-left-1',
41
- typeof className === 'function' ? className(values) : className,
42
- )
43
- }
44
- >
45
- {(values) => (
46
- <>
47
- <RAC.OverlayArrow>
48
- <svg
49
- width={8}
50
- height={8}
51
- viewBox="0 0 8 8"
52
- className="fill-bg-surface/90 stroke-border-subtle group-data-[placement=bottom]:rotate-180 group-data-[placement=left]:-rotate-90 group-data-[placement=right]:rotate-90"
53
- >
54
- <title>Arrow</title>
55
- <path d="M0 0 L4 4 L8 0" />
56
- </svg>
57
- </RAC.OverlayArrow>
58
- {typeof children === 'function' ? children(values) : children}
59
- </>
60
- )}
61
- </RAC.Tooltip>
62
- )
63
- }
64
-
65
- export const Tooltip = ({
66
- content,
67
- children,
68
- delay = 500,
69
- closeDelay = 0,
70
- ...props
71
- }: TooltipProps) => {
72
- return (
73
- <RAC.TooltipTrigger delay={delay} closeDelay={closeDelay}>
74
- {children}
75
- <TooltipContent {...props}>{content}</TooltipContent>
76
- </RAC.TooltipTrigger>
77
- )
78
- }
79
-
80
- Tooltip.Root = Tooltip
81
- Tooltip.Content = TooltipContent
@@ -1,11 +0,0 @@
1
- import type { ReactNode } from 'react'
2
-
3
- export type ComponentBase = {
4
- className?: string
5
- children?: ReactNode
6
- }
7
-
8
- /**
9
- * Helper to type compound components (e.g. Navbar with Navbar.Link)
10
- */
11
- export type CompoundComponent<P, S> = React.FC<P> & S
@@ -1,66 +0,0 @@
1
- import { useState, useEffect } from 'react'
2
- import { X } from './icons'
3
-
4
- export interface BannerProps extends React.HTMLAttributes<HTMLDivElement> {
5
- /**
6
- * If true, shows a close button to dismiss the banner.
7
- */
8
- dismissible?: boolean
9
- /**
10
- * Unique identifier for the banner. If provided and dismissible is true,
11
- * the dismissed state will be saved in localStorage so it doesn't reappear
12
- * on subsequent visits.
13
- */
14
- id?: string
15
- }
16
-
17
- export function Banner({
18
- children,
19
- className = '',
20
- dismissible = false,
21
- id = 'boltdocs-banner',
22
- ...props
23
- }: BannerProps) {
24
- const [isVisible, setIsVisible] = useState(true)
25
-
26
- useEffect(() => {
27
- if (dismissible && id) {
28
- const isDismissed = localStorage.getItem(
29
- `boltdocs-banner-dismissed-${id}`,
30
- )
31
- if (isDismissed === 'true') {
32
- setIsVisible(false)
33
- }
34
- }
35
- }, [dismissible, id])
36
-
37
- const handleDismiss = () => {
38
- setIsVisible(false)
39
- if (dismissible && id) {
40
- localStorage.setItem(`boltdocs-banner-dismissed-${id}`, 'true')
41
- }
42
- }
43
-
44
- if (!isVisible) return null
45
-
46
- return (
47
- <div
48
- className={`relative flex items-center justify-center px-4 py-2.5 text-xs font-semibold tracking-wide bg-primary-500/10 dark:bg-primary-500/15 text-primary-700 dark:text-primary-300 border-b border-primary-500/20 select-none animate-in fade-in duration-300 ${className}`}
49
- {...props}
50
- >
51
- <div className="flex-1 text-center flex items-center justify-center gap-2">
52
- {children}
53
- </div>
54
- {dismissible && (
55
- <button
56
- onClick={handleDismiss}
57
- className="absolute right-3 top-1/2 -translate-y-1/2 p-1.5 opacity-70 hover:opacity-100 transition-all duration-300 rounded-xl hover:bg-primary-500/10 cursor-pointer border-none bg-transparent flex items-center justify-center outline-none"
58
- aria-label="Dismiss banner"
59
- >
60
- <X className="w-3.5 h-3.5" />
61
- </button>
62
- )}
63
- </div>
64
- )
65
- }
66
- export default Banner