boltdocs 2.7.9 → 2.7.11

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 (174) hide show
  1. package/dist/{cache-DorPMFgW.cjs → cache-Ba-DZQNH.cjs} +1 -1
  2. package/dist/{cache-CQKlT4fI.mjs → cache-BuMZ58L5.mjs} +1 -1
  3. package/dist/chunk-CU-zTemE.cjs +6 -0
  4. package/dist/client/index.cjs +1929 -1
  5. package/dist/client/index.js +1880 -1
  6. package/dist/client/mdx.cjs +7 -1
  7. package/dist/client/mdx.js +7 -1
  8. package/dist/client/primitives.cjs +60 -1
  9. package/dist/client/primitives.js +20 -1
  10. package/dist/docs-layout-BXHV0xw_.cjs +1431 -0
  11. package/dist/docs-layout-DwFndmj5.js +1231 -0
  12. package/dist/doctor-Be7Ly1oM.mjs +21 -0
  13. package/dist/{doctor-D4_Y7M4p.cjs → doctor-CrytFkqW.cjs} +1 -1
  14. package/dist/doctor-jMxWZyLJ.cjs +21 -0
  15. package/dist/generator-CHqxiQhF.cjs +21 -0
  16. package/dist/generator-ClVanhvi.mjs +21 -0
  17. package/dist/icons-dev-3cZMyt8r.cjs +1204 -0
  18. package/dist/icons-dev-Df8OQ481.js +839 -0
  19. package/dist/image-DtrI2cw3.cjs +268 -0
  20. package/dist/image-jxPb-2iV.js +214 -0
  21. package/dist/mdx-BdWkJTeB.cjs +523 -0
  22. package/dist/mdx-UTTLFWJq.js +494 -0
  23. package/dist/meta-loader-CWg2gnbY.mjs +6 -0
  24. package/dist/meta-loader-Cv9O0Pzl.cjs +6 -0
  25. package/dist/node/cli-entry.cjs +1 -1
  26. package/dist/node/cli-entry.mjs +1 -1
  27. package/dist/node/index.cjs +1 -1
  28. package/dist/node/index.mjs +1 -1
  29. package/dist/node/routes/worker.cjs +1 -1
  30. package/dist/node/routes/worker.mjs +1 -1
  31. package/dist/node-BSM4qcDK.cjs +111 -0
  32. package/dist/node-BspZN3R2.mjs +111 -0
  33. package/dist/{package-VfQM94VL.cjs → package-DIIrjuWI.cjs} +1 -1
  34. package/dist/{package-B4MD00N3.mjs → package-K0zsjGIz.mjs} +1 -1
  35. package/dist/{parser-Bh11BsdA.cjs → parser-Aq8LoH-0.cjs} +1 -1
  36. package/dist/{parser-DYRzXWmA.cjs → parser-CdNbqN5y.cjs} +1 -1
  37. package/dist/parser-nE792MLO.mjs +6 -0
  38. package/dist/rolldown-runtime-fkIsjY3S.mjs +6 -0
  39. package/dist/{routes-Co1mRM58.cjs → routes-2k3tbUmC.cjs} +1 -1
  40. package/dist/routes-CpxZIsMM.mjs +6 -0
  41. package/dist/{routes-CHf76Ye4.cjs → routes-DP1vmWRj.cjs} +1 -1
  42. package/dist/search-dialog-BHuIiUC6.js +8 -0
  43. package/dist/search-dialog-BNF10tDl.js +375 -0
  44. package/dist/search-dialog-BwkDuI9R.cjs +220 -0
  45. package/dist/search-dialog-C7xuvyNk.cjs +386 -0
  46. package/dist/search-dialog-CIQg6k8c.cjs +8 -0
  47. package/dist/search-dialog-D-DDN7zJ.js +208 -0
  48. package/dist/utils-CG65J0Sc.mjs +7 -0
  49. package/dist/utils-CKunkU96.cjs +7 -0
  50. package/dist/{worker-pool-BwU8ckrg.cjs → worker-pool-Crbqgw5R.cjs} +1 -1
  51. package/package.json +5 -5
  52. package/dist/chunk-Ds5LZdWN.cjs +0 -6
  53. package/dist/docs-layout-KoWNZc8_.js +0 -6
  54. package/dist/docs-layout-x2yKt2cL.cjs +0 -6
  55. package/dist/doctor-BD1BSB03.mjs +0 -23
  56. package/dist/doctor-BHc9ua6r.cjs +0 -23
  57. package/dist/generator-DGW6pkCC.cjs +0 -22
  58. package/dist/generator-Dv3wEmhZ.mjs +0 -22
  59. package/dist/icons-dev-B_RZIyxu.js +0 -6
  60. package/dist/icons-dev-BlV3wWFT.cjs +0 -6
  61. package/dist/image-BHhTvQzr.cjs +0 -6
  62. package/dist/image-CqKzYD8f.js +0 -6
  63. package/dist/mdx-DudBEac0.js +0 -7
  64. package/dist/mdx-r4cDQxWu.cjs +0 -7
  65. package/dist/meta-loader-0gJ4PtBC.cjs +0 -6
  66. package/dist/meta-loader-9IpAHWDS.mjs +0 -6
  67. package/dist/node-DBaH7kat.mjs +0 -111
  68. package/dist/node-t5C3Q85p.cjs +0 -111
  69. package/dist/parser-9cVdK7w9.mjs +0 -6
  70. package/dist/routes-DwrMa5-z.mjs +0 -6
  71. package/dist/search-dialog-B584t9ZF.js +0 -6
  72. package/dist/search-dialog-BvBopRsZ.cjs +0 -6
  73. package/dist/search-dialog-ByvGScjt.js +0 -6
  74. package/dist/search-dialog-Cyko6TJm.cjs +0 -6
  75. package/dist/search-dialog-D6BNohIJ.js +0 -6
  76. package/dist/search-dialog-DuYTIefy.cjs +0 -6
  77. package/dist/utils-BxNAXhZZ.mjs +0 -7
  78. package/dist/utils-Clzu7jvb.cjs +0 -7
  79. package/src/client/app/config-context.tsx +0 -51
  80. package/src/client/app/doc-page.tsx +0 -38
  81. package/src/client/app/docs-layout.tsx +0 -28
  82. package/src/client/app/head.tsx +0 -122
  83. package/src/client/app/helmet-compat.tsx +0 -36
  84. package/src/client/app/mdx-component.tsx +0 -8
  85. package/src/client/app/mdx-components-context.tsx +0 -72
  86. package/src/client/app/routes-context.tsx +0 -34
  87. package/src/client/app/scroll-handler.tsx +0 -74
  88. package/src/client/app/theme-context.tsx +0 -103
  89. package/src/client/app/ui-context.tsx +0 -42
  90. package/src/client/components/docs-layout-default.tsx +0 -85
  91. package/src/client/components/icons-dev.tsx +0 -282
  92. package/src/client/components/mdx/callout.tsx +0 -97
  93. package/src/client/components/mdx/card.tsx +0 -99
  94. package/src/client/components/mdx/cards.tsx +0 -27
  95. package/src/client/components/mdx/code-block.tsx +0 -184
  96. package/src/client/components/mdx/field.tsx +0 -33
  97. package/src/client/components/mdx/image.tsx +0 -44
  98. package/src/client/components/mdx/index.ts +0 -19
  99. package/src/client/components/mdx/table.tsx +0 -54
  100. package/src/client/components/mdx/typographics.tsx +0 -120
  101. package/src/client/components/mdx/use-code-block.ts +0 -34
  102. package/src/client/components/primitives/breadcrumbs.tsx +0 -54
  103. package/src/client/components/primitives/button-group.tsx +0 -54
  104. package/src/client/components/primitives/button.tsx +0 -6
  105. package/src/client/components/primitives/code-block.tsx +0 -120
  106. package/src/client/components/primitives/docs-layout.tsx +0 -125
  107. package/src/client/components/primitives/error-boundary.tsx +0 -107
  108. package/src/client/components/primitives/heading.tsx +0 -128
  109. package/src/client/components/primitives/helpers/observer.ts +0 -141
  110. package/src/client/components/primitives/image.tsx +0 -26
  111. package/src/client/components/primitives/link.tsx +0 -102
  112. package/src/client/components/primitives/menu.tsx +0 -137
  113. package/src/client/components/primitives/navbar.tsx +0 -466
  114. package/src/client/components/primitives/on-this-page.tsx +0 -430
  115. package/src/client/components/primitives/page-nav.tsx +0 -51
  116. package/src/client/components/primitives/popover.tsx +0 -28
  117. package/src/client/components/primitives/search-dialog.tsx +0 -193
  118. package/src/client/components/primitives/sidebar.tsx +0 -423
  119. package/src/client/components/primitives/skeleton.tsx +0 -26
  120. package/src/client/components/primitives/tabs.tsx +0 -70
  121. package/src/client/components/primitives/tooltip.tsx +0 -81
  122. package/src/client/components/primitives/types.ts +0 -11
  123. package/src/client/components/ui-base/banner.tsx +0 -66
  124. package/src/client/components/ui-base/breadcrumbs.tsx +0 -44
  125. package/src/client/components/ui-base/copy-markdown.tsx +0 -107
  126. package/src/client/components/ui-base/error-boundary.tsx +0 -15
  127. package/src/client/components/ui-base/github-stars.tsx +0 -29
  128. package/src/client/components/ui-base/icons.tsx +0 -240
  129. package/src/client/components/ui-base/index.ts +0 -16
  130. package/src/client/components/ui-base/last-updated.tsx +0 -27
  131. package/src/client/components/ui-base/navbar.tsx +0 -266
  132. package/src/client/components/ui-base/not-found.tsx +0 -26
  133. package/src/client/components/ui-base/on-this-page.tsx +0 -57
  134. package/src/client/components/ui-base/page-nav.tsx +0 -50
  135. package/src/client/components/ui-base/search-dialog.tsx +0 -163
  136. package/src/client/components/ui-base/search-highlight.tsx +0 -10
  137. package/src/client/components/ui-base/sidebar.tsx +0 -92
  138. package/src/client/components/ui-base/tabs.tsx +0 -83
  139. package/src/client/components/ui-base/theme-toggle.tsx +0 -130
  140. package/src/client/components/ui-base/version-i18n.tsx +0 -80
  141. package/src/client/hooks/index.ts +0 -13
  142. package/src/client/hooks/use-analytics.ts +0 -272
  143. package/src/client/hooks/use-breadcrumbs.ts +0 -22
  144. package/src/client/hooks/use-i18n.ts +0 -182
  145. package/src/client/hooks/use-localized-to.ts +0 -113
  146. package/src/client/hooks/use-location.ts +0 -5
  147. package/src/client/hooks/use-navbar.ts +0 -130
  148. package/src/client/hooks/use-page-nav.ts +0 -46
  149. package/src/client/hooks/use-routes.ts +0 -108
  150. package/src/client/hooks/use-search-highlight.ts +0 -185
  151. package/src/client/hooks/use-search.ts +0 -118
  152. package/src/client/hooks/use-sidebar.ts +0 -205
  153. package/src/client/hooks/use-tabs.ts +0 -46
  154. package/src/client/hooks/use-version.ts +0 -111
  155. package/src/client/index.ts +0 -31
  156. package/src/client/mdx.ts +0 -2
  157. package/src/client/primitives.ts +0 -19
  158. package/src/client/ssg/boltdocs-shell.tsx +0 -148
  159. package/src/client/ssg/create-routes.tsx +0 -473
  160. package/src/client/ssg/index.ts +0 -4
  161. package/src/client/ssg/mdx-page.tsx +0 -38
  162. package/src/client/store/boltdocs-context.tsx +0 -137
  163. package/src/client/theme/neutral.css +0 -141
  164. package/src/client/theme/reset.css +0 -189
  165. package/src/client/types.ts +0 -116
  166. package/src/client/utils/cn.ts +0 -6
  167. package/src/client/utils/copy-clipboard.ts +0 -22
  168. package/src/client/utils/get-base-file-path.ts +0 -21
  169. package/src/client/utils/github.ts +0 -121
  170. package/src/client/utils/i18n.ts +0 -23
  171. package/src/client/utils/path.ts +0 -9
  172. package/src/client/utils/react-to-text.ts +0 -34
  173. package/src/client/virtual.d.ts +0 -24
  174. /package/dist/{worker-pool-Bd8Y9KDv.mjs → worker-pool-CGn7DrLb.mjs} +0 -0
@@ -1,120 +0,0 @@
1
- import type { ComponentProps } from 'react'
2
- import { cn } from '../../utils/cn'
3
-
4
- interface CodeBlockRootProps extends ComponentProps<'div'> {
5
- /**
6
- * Whether the code block is in plain mode (no borders/padding)
7
- * @default false
8
- */
9
- plain?: boolean
10
- }
11
-
12
- export interface CodeBlockHeaderProps extends ComponentProps<'div'> {}
13
- export interface CodeBlockGroupProps extends ComponentProps<'div'> {}
14
- export interface CodeBlockContentProps extends ComponentProps<'div'> {
15
- /**
16
- * Whether the code content should be truncated with an expand button
17
- * @default false
18
- */
19
- shouldTruncate?: boolean
20
- }
21
-
22
- /**
23
- * Root component for code blocks.
24
- * Handles background, borders, and general layout.
25
- */
26
- const CodeBlock = ({
27
- children,
28
- className,
29
- plain = false,
30
- ...props
31
- }: CodeBlockRootProps) => {
32
- return (
33
- <div
34
- className={cn(
35
- 'not-prose boltdocs-code-block',
36
- 'group relative overflow-hidden bg-(--color-code-bg)',
37
- 'contain-layout contain-paint',
38
- {
39
- 'my-6 rounded-xl border border-subtle': !plain,
40
- },
41
- className,
42
- )}
43
- {...props}
44
- >
45
- {children}
46
- </div>
47
- )
48
- }
49
-
50
- /**
51
- * Header section of the code block.
52
- * Usually contains the title, language label, and action buttons.
53
- */
54
- const CodeBlockHeader = ({
55
- children,
56
- className,
57
- ...props
58
- }: CodeBlockHeaderProps) => {
59
- return (
60
- <div
61
- className={cn(
62
- 'flex h-9 items-center justify-between px-4 py-1.5',
63
- 'text-[13px] font-medium text-muted',
64
- className,
65
- )}
66
- {...props}
67
- >
68
- {children}
69
- </div>
70
- )
71
- }
72
-
73
- /**
74
- * Horizontal group for organizing items within the header (e.g., logo + label).
75
- */
76
- const CodeBlockGroup = ({
77
- children,
78
- className,
79
- ...props
80
- }: CodeBlockGroupProps) => {
81
- return (
82
- <div className={cn('flex items-center space-x-2', className)} {...props}>
83
- {children}
84
- </div>
85
- )
86
- }
87
-
88
- /**
89
- * Content area of the code block.
90
- * Wraps the `<pre>` or `<div>` containing the code.
91
- */
92
- const CodeBlockContent = ({
93
- className,
94
- children,
95
- shouldTruncate = false,
96
- ...props
97
- }: CodeBlockContentProps) => {
98
- return (
99
- <div
100
- className={cn(
101
- 'relative',
102
- {
103
- '[&>pre]:max-h-[300px] [&>pre]:overflow-hidden [&>div>pre]:max-h-[300px] [&>div>pre]:overflow-hidden':
104
- shouldTruncate,
105
- },
106
- className,
107
- )}
108
- {...props}
109
- >
110
- {children}
111
- </div>
112
- )
113
- }
114
-
115
- // Assign sub-components
116
- CodeBlock.Header = CodeBlockHeader
117
- CodeBlock.Group = CodeBlockGroup
118
- CodeBlock.Content = CodeBlockContent
119
-
120
- export { CodeBlock, CodeBlockHeader, CodeBlockGroup, CodeBlockContent }
@@ -1,125 +0,0 @@
1
- import { cn } from '../../utils/cn'
2
- import { SearchHighlight } from '../ui-base/search-highlight'
3
-
4
- /**
5
- * Props shared by all layout slot components.
6
- */
7
- interface SlotProps {
8
- children?: React.ReactNode
9
- className?: string
10
- style?: React.CSSProperties
11
- }
12
-
13
- /**
14
- * Root layout shell. Renders a full-height flex column.
15
- *
16
- * Usage:
17
- * ```tsx
18
- * <DocsLayout>
19
- * <Navbar />
20
- * <DocsLayout.Body>...</DocsLayout.Body>
21
- * </DocsLayout>
22
- * ```
23
- */
24
- function DocsLayoutRoot({ children, className, style }: SlotProps) {
25
- return (
26
- <div
27
- className={cn(
28
- 'h-screen flex flex-col overflow-hidden bg-main text-body',
29
- className,
30
- )}
31
- style={style}
32
- >
33
- {children}
34
- </div>
35
- )
36
- }
37
-
38
- /**
39
- * Horizontal flex container for sidebar + content + toc.
40
- */
41
- function Body({ children, className, style }: SlotProps) {
42
- return (
43
- <div
44
- className={cn(
45
- 'mx-auto flex flex-1 w-full max-w-(--breakpoint-3xl) bg-main overflow-hidden',
46
- className,
47
- )}
48
- style={style}
49
- >
50
- {children}
51
- </div>
52
- )
53
- }
54
-
55
- /**
56
- * Main scrollable content area.
57
- */
58
- function Content({ children, className, style }: SlotProps) {
59
- return (
60
- <main
61
- className={cn(
62
- 'boltdocs-content flex-1 min-w-0 overflow-y-auto',
63
- 'contain-layout', // Optimization: isolate main content layout
64
- className,
65
- )}
66
- style={style}
67
- >
68
- {children}
69
- </main>
70
- )
71
- }
72
-
73
- /**
74
- * MDX Content wrapper with standard page padding and max-width logic.
75
- */
76
- function ContentMdx({ children, className, style }: SlotProps) {
77
- return (
78
- <div
79
- className={cn('boltdocs-page mx-auto pt-4 pb-20 px-4 sm:px-8', className)}
80
- style={style}
81
- >
82
- <SearchHighlight />
83
- {children}
84
- </div>
85
- )
86
- }
87
-
88
- /**
89
- * Content header area (breadcrumbs, title, description, etc).
90
- */
91
- function Header({ children, className, style }: SlotProps) {
92
- return (
93
- <header className={cn('mb-10', className)} style={style}>
94
- {children}
95
- </header>
96
- )
97
- }
98
-
99
- /**
100
- * Footer area inside the content section (page nav).
101
- */
102
- function Footer({ children, className, style }: SlotProps) {
103
- return (
104
- <div className={cn('mt-20', className)} style={style}>
105
- {children}
106
- </div>
107
- )
108
- }
109
-
110
- interface DocsLayoutComponent extends React.FC<SlotProps> {
111
- Body: typeof Body
112
- Content: typeof Content
113
- ContentMdx: typeof ContentMdx
114
- Header: typeof Header
115
- Footer: typeof Footer
116
- }
117
-
118
- // Attach sub-components to the root
119
- export const DocsLayout = Object.assign(DocsLayoutRoot, {
120
- Body,
121
- Content,
122
- ContentMdx,
123
- Header,
124
- Footer,
125
- }) as DocsLayoutComponent
@@ -1,107 +0,0 @@
1
- import * as React from 'react'
2
- import type { ErrorInfo, ComponentType, ReactNode } from 'react'
3
- import { Component } from 'react'
4
- import { Button } from './button'
5
-
6
- export interface FallbackProps {
7
- error: Error
8
- resetErrorBoundary: () => void
9
- }
10
-
11
- export interface ErrorBoundaryProps {
12
- children?: ReactNode
13
- fallback?: ReactNode
14
- FallbackComponent?: ComponentType<FallbackProps>
15
- onError?: (error: Error, info: ErrorInfo) => void
16
- onReset?: () => void
17
- }
18
-
19
- interface ErrorBoundaryState {
20
- hasError: boolean
21
- error: Error | null
22
- }
23
-
24
- export class ErrorBoundary extends Component<
25
- ErrorBoundaryProps,
26
- ErrorBoundaryState
27
- > {
28
- public state: ErrorBoundaryState = { hasError: false, error: null }
29
-
30
- public static getDerivedStateFromError(error: Error): ErrorBoundaryState {
31
- return { hasError: true, error }
32
- }
33
-
34
- public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
35
- if (this.props.onError) {
36
- this.props.onError(error, errorInfo)
37
- } else {
38
- console.error(
39
- 'ErrorBoundary caught an unhandled error:',
40
- error,
41
- errorInfo,
42
- )
43
- }
44
- }
45
-
46
- public resetErrorBoundary = () => {
47
- if (this.props.onReset) {
48
- this.props.onReset()
49
- }
50
- this.setState({ hasError: false, error: null })
51
- }
52
-
53
- public render() {
54
- const { hasError, error } = this.state
55
- const { children, fallback, FallbackComponent } = this.props
56
-
57
- if (hasError && error) {
58
- if (FallbackComponent) {
59
- return (
60
- <FallbackComponent
61
- error={error}
62
- resetErrorBoundary={this.resetErrorBoundary}
63
- />
64
- )
65
- }
66
- if (fallback) {
67
- return fallback
68
- }
69
- return (
70
- <ErrorBoundaryFallback
71
- error={error}
72
- resetErrorBoundary={this.resetErrorBoundary}
73
- />
74
- )
75
- }
76
-
77
- return children
78
- }
79
- }
80
-
81
- export interface ErrorBoundaryFallbackProps {
82
- error: Error
83
- resetErrorBoundary: () => void
84
- }
85
-
86
- export function ErrorBoundaryFallback({
87
- error,
88
- resetErrorBoundary,
89
- }: ErrorBoundaryFallbackProps) {
90
- return (
91
- <div className="flex flex-col items-center justify-center min-h-[40vh] text-center gap-4 px-6 py-8 border border-subtle bg-surface rounded-2xl max-w-lg mx-auto shadow-xs">
92
- <div className="text-lg font-bold text-rose-600 dark:text-rose-400">
93
- Something went wrong
94
- </div>
95
- <p className="text-sm text-muted max-w-sm leading-relaxed">
96
- {error?.message ||
97
- 'An unexpected error occurred while rendering this page.'}
98
- </p>
99
- <Button
100
- className="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 cursor-pointer outline-none select-none"
101
- onPress={resetErrorBoundary}
102
- >
103
- Try again
104
- </Button>
105
- </div>
106
- )
107
- }
@@ -1,128 +0,0 @@
1
- import * as React from 'react'
2
- import { Link as LucideLink } from '../ui-base/icons'
3
- import { Link } from './link'
4
- import { cn } from '../../utils/cn'
5
-
6
- export interface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {
7
- level: 1 | 2 | 3 | 4 | 5 | 6
8
- id?: string
9
- /** Whether to show the anchor icon/link. Defaults to true if id is provided. */
10
- showAnchor?: boolean
11
- /** Position of the anchor link relative to children. Defaults to 'wrap'. */
12
- anchorPosition?: 'wrap' | 'after' | 'before'
13
- /** Custom icon to display for the anchor. */
14
- anchorIcon?: React.ReactNode
15
- /** Custom classes for the anchor link wrapper. */
16
- anchorClassName?: string
17
- }
18
-
19
- export const Heading = React.forwardRef<HTMLHeadingElement, HeadingProps>(
20
- (
21
- {
22
- level,
23
- id,
24
- children,
25
- className,
26
- showAnchor = true,
27
- anchorPosition = 'wrap',
28
- anchorIcon,
29
- anchorClassName,
30
- ...props
31
- },
32
- ref,
33
- ) => {
34
- const safeLevel = Math.min(Math.max(Math.floor(level), 1), 6) as
35
- | 1
36
- | 2
37
- | 3
38
- | 4
39
- | 5
40
- | 6
41
- const Tag = `h${safeLevel}` as const
42
-
43
- const hasAnchor = !!(id && showAnchor)
44
-
45
- // Default icon with hover transition
46
- const defaultIcon = (
47
- <LucideLink
48
- className={cn(
49
- 'transition-all duration-200',
50
- anchorPosition === 'wrap'
51
- ? 'opacity-0 ml-2 text-muted/50 group-hover:text-primary-500 group-hover:opacity-100'
52
- : 'text-muted/50 hover:text-primary-500',
53
- )}
54
- size={16}
55
- />
56
- )
57
-
58
- const icon = anchorIcon ?? defaultIcon
59
-
60
- const renderContent = () => {
61
- if (!hasAnchor) {
62
- return children
63
- }
64
-
65
- if (anchorPosition === 'wrap') {
66
- return (
67
- <Link
68
- href={`#${id}`}
69
- className={cn(
70
- 'header-anchor flex flex-row items-center no-underline text-inherit',
71
- anchorClassName,
72
- )}
73
- aria-label="Anchor"
74
- >
75
- {children}
76
- {icon}
77
- </Link>
78
- )
79
- }
80
-
81
- return (
82
- <>
83
- {anchorPosition === 'before' && (
84
- <Link
85
- href={`#${id}`}
86
- className={cn(
87
- 'header-anchor mr-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200',
88
- anchorClassName,
89
- )}
90
- aria-label="Anchor"
91
- >
92
- {icon}
93
- </Link>
94
- )}
95
- {children}
96
- {anchorPosition === 'after' && (
97
- <Link
98
- href={`#${id}`}
99
- className={cn(
100
- 'header-anchor ml-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200',
101
- anchorClassName,
102
- )}
103
- aria-label="Anchor"
104
- >
105
- {icon}
106
- </Link>
107
- )}
108
- </>
109
- )
110
- }
111
-
112
- return (
113
- <Tag
114
- ref={ref}
115
- id={id}
116
- className={cn(
117
- 'boltdocs-heading relative group flex items-center scroll-mt-24',
118
- className,
119
- )}
120
- {...props}
121
- >
122
- {renderContent()}
123
- </Tag>
124
- )
125
- },
126
- )
127
-
128
- Heading.displayName = 'Heading'
@@ -1,141 +0,0 @@
1
- import type { TOCItemInfo, TOCItemType } from '../on-this-page'
2
-
3
- export function getItemId(url: string) {
4
- if (url.startsWith('#')) return url.slice(1)
5
- return null
6
- }
7
-
8
- export class Observer {
9
- items: TOCItemInfo[] = []
10
- single = false
11
- private observer: IntersectionObserver | null = null
12
- onChange?: () => void
13
-
14
- private callback(_entries: IntersectionObserverEntry[]) {
15
- // For each item, check if it's currently in viewport
16
- for (const item of this.items) {
17
- const element = document.getElementById(item.id)
18
- if (!element) {
19
- item.active = false
20
- item.fallback = false
21
- continue
22
- }
23
-
24
- const rect = element.getBoundingClientRect()
25
- const viewportHeight =
26
- typeof window !== 'undefined' ? window.innerHeight : 1000
27
-
28
- // Check if element is currently in viewport (visible)
29
- // rect.bottom > 0
30
- // rect.top < viewportHeight:
31
- const isInViewport = rect.bottom > 0 && rect.top < viewportHeight
32
-
33
- // Update active state based on current position
34
- item.active = isInViewport
35
-
36
- // Fallback: element has scrolled past but is still near viewport
37
- item.fallback =
38
- !isInViewport && rect.top > 0 && rect.top < viewportHeight * 2
39
- }
40
-
41
- // 3. Determine which items should be active based on single mode
42
- if (this.single) {
43
- // Single mode: only ONE active item (the one closest to the top of viewport)
44
- let highlightIdx = -1
45
-
46
- // Find all visible items and pick the one closest to the top of viewport
47
- const visibleItems = this.items
48
- .map((item, idx) => ({ item, idx }))
49
- .filter(({ item }) => item.active)
50
-
51
- if (visibleItems.length > 0) {
52
- // Take the first one (closest to top of viewport)
53
- highlightIdx = visibleItems[0].idx
54
- } else {
55
- // If nothing visible, check fallback items
56
- const fallbackItems = this.items
57
- .map((item, idx) => ({ item, idx }))
58
- .filter(({ item }) => item.fallback)
59
-
60
- if (fallbackItems.length > 0) {
61
- highlightIdx = fallbackItems[0].idx
62
- } else if (this.items.length > 0) {
63
- highlightIdx = 0
64
- }
65
- }
66
-
67
- // Map back to UI state - only one active
68
- this.items = this.items.map((item, idx) => ({
69
- ...item,
70
- active: idx === highlightIdx,
71
- t: idx === highlightIdx ? Date.now() : item.t,
72
- }))
73
- } else {
74
- // Multi mode: items active when they are in viewport
75
- // This ensures items activate when visible and deactivate when they leave viewport
76
- this.items = this.items.map((item, idx) => ({
77
- ...item,
78
- active: item.active,
79
- t: item.active ? Date.now() : item.t,
80
- }))
81
- }
82
-
83
- this.onChange?.()
84
- }
85
-
86
- setItems(newItems: TOCItemType[]) {
87
- const observer = this.observer
88
- if (observer) {
89
- for (const item of this.items) {
90
- const element = document.getElementById(item.id)
91
- if (!element) continue
92
- observer.unobserve(element)
93
- }
94
- }
95
-
96
- this.items = []
97
- for (const item of newItems) {
98
- const id = getItemId(item.url)
99
- if (!id) continue
100
-
101
- this.items.push({
102
- id,
103
- active: false,
104
- fallback: false,
105
- t: 0,
106
- original: item,
107
- })
108
- }
109
- this.watchItems()
110
-
111
- // In an SPA, the TOC might update before the MDX content is in the DOM.
112
- // We perform a few delayed scans to ensure we catch those elements.
113
- if (typeof window !== 'undefined') {
114
- setTimeout(() => this.watchItems(), 100)
115
- setTimeout(() => this.watchItems(), 500)
116
- setTimeout(() => this.watchItems(), 1000)
117
- }
118
-
119
- this.onChange?.()
120
- }
121
-
122
- watch(options?: IntersectionObserverInit) {
123
- if (this.observer) return
124
- this.observer = new IntersectionObserver(this.callback.bind(this), options)
125
- this.watchItems()
126
- }
127
-
128
- private watchItems() {
129
- if (!this.observer) return
130
- for (const item of this.items) {
131
- const element = document.getElementById(item.id)
132
- if (!element) continue
133
- this.observer.observe(element)
134
- }
135
- }
136
-
137
- unwatch() {
138
- this.observer?.disconnect()
139
- this.observer = null
140
- }
141
- }
@@ -1,26 +0,0 @@
1
- import type { ImgHTMLAttributes } from 'react'
2
- import { useTheme } from '../../app/theme-context'
3
- import { cn } from '../../utils/cn'
4
-
5
- export interface ImageProps extends ImgHTMLAttributes<HTMLImageElement> {
6
- theme?: 'light' | 'dark'
7
- }
8
-
9
- /**
10
- * A responsive image component that automatically supports dark and light theme variations
11
- * via the `theme` prop.
12
- */
13
- export function Image({ theme, className, ...props }: ImageProps) {
14
- const { resolvedTheme } = useTheme()
15
-
16
- if (theme && theme !== resolvedTheme) {
17
- return null
18
- }
19
-
20
- return (
21
- <img
22
- className={cn('max-w-full h-auto rounded-lg my-8', className)}
23
- {...props}
24
- />
25
- )
26
- }