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.
- package/README.md +2 -2
- package/dist/banner-3N4Jd_L9.d.ts +100 -0
- package/dist/banner-MynZD_Ox.d.cts +100 -0
- package/dist/cache-BMUyNiiA.mjs +6 -0
- package/dist/cache-CKm45d2w.cjs +6 -0
- package/dist/client/index.cjs +2268 -1
- package/dist/client/index.d.cts +86 -110
- package/dist/client/index.d.ts +87 -111
- package/dist/client/index.js +2214 -1
- package/dist/client/mdx.cjs +12 -1
- package/dist/client/mdx.d.cts +39 -93
- package/dist/client/mdx.d.ts +38 -93
- package/dist/client/mdx.js +7 -1
- package/dist/client/primitives.cjs +60 -1
- package/dist/client/primitives.d.cts +411 -347
- package/dist/client/primitives.d.ts +411 -347
- package/dist/client/primitives.js +20 -1
- package/dist/docs-layout-CwCq42Zt.cjs +1348 -0
- package/dist/docs-layout-Dn6S5g59.js +1167 -0
- package/dist/doctor-BArviV8X.cjs +28 -0
- package/dist/doctor-CgLA7_Uv.mjs +28 -0
- package/dist/{doctor-CrytFkqW.cjs → doctor-DyNUVe96.cjs} +1 -1
- package/dist/{routes-DP1vmWRj.cjs → doctor-aN_leTbh.mjs} +1 -1
- package/dist/{generator-ClVanhvi.mjs → generator-BHCrLU6h.mjs} +2 -2
- package/dist/{generator-CHqxiQhF.cjs → generator-CC2yHzhZ.cjs} +2 -2
- package/dist/icons-dev-DvJ-hh9x.cjs +1209 -0
- package/dist/icons-dev-Oju24Wjp.js +845 -0
- package/dist/image-Ch4-GxdO.cjs +268 -0
- package/dist/image-Do8V9PCW.js +214 -0
- package/dist/mdx-D3A2_l7P.js +520 -0
- package/dist/mdx-PLhhPJRS.cjs +531 -0
- package/dist/node/cli-entry.cjs +3 -1
- package/dist/node/cli-entry.mjs +3 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +258 -152
- package/dist/node/index.d.mts +258 -150
- package/dist/node/index.mjs +1 -1
- package/dist/node/routes/worker.cjs +1 -1
- package/dist/node/routes/worker.mjs +1 -1
- package/dist/node-BmlP0eBP.cjs +159 -0
- package/dist/node-Y8_4ayje.mjs +159 -0
- package/dist/package-2nFy_NsW.cjs +6 -0
- package/dist/{package--0Yf0t1N.mjs → package-DAbtltXX.mjs} +1 -1
- package/dist/parser-B7-6PyQz.cjs +6 -0
- package/dist/{parser-Aq8LoH-0.cjs → parser-BzB-zCkF.cjs} +1 -1
- package/dist/parser-WGZdWs0X.mjs +6 -0
- package/dist/routes-BDDSxAl0.mjs +6 -0
- package/dist/routes-DJNJ-rTt.cjs +6 -0
- package/dist/routes-DiYC4nD2.cjs +6 -0
- package/dist/routes-_Bb2f4eI.mjs +6 -0
- package/dist/search-dialog-BXVoecTx.cjs +483 -0
- package/dist/search-dialog-BYhOov4S.cjs +331 -0
- package/dist/search-dialog-C09riYmx.js +313 -0
- package/dist/search-dialog-CUeAfy-8.cjs +8 -0
- package/dist/search-dialog-D8gLkhUV.js +453 -0
- package/dist/search-dialog-DHc_8FFX.js +8 -0
- package/dist/{sidebar-CcBkrm06.d.cts → sidebar-DNq4_ZAa.d.ts} +118 -52
- package/dist/{sidebar-CyZS9YOm.d.ts → sidebar-Dlkgbxs6.d.cts} +118 -52
- package/dist/utils-BYITg7T5.mjs +7 -0
- package/dist/utils-Cjmx1hhk.cjs +7 -0
- package/dist/worker-pool-CtqklOXq.cjs +6 -0
- package/dist/worker-pool-k0DY6k8T.mjs +6 -0
- package/package.json +5 -6
- package/src/shared/config-utils.ts +4 -0
- package/src/shared/types.ts +52 -6
- package/dist/cache-Ba-DZQNH.cjs +0 -6
- package/dist/cache-BuMZ58L5.mjs +0 -6
- package/dist/cards-BakZPTz9.d.ts +0 -30
- package/dist/cards-CQn9mXZS.d.cts +0 -30
- package/dist/docs-layout-KoWNZc8_.js +0 -6
- package/dist/docs-layout-x2yKt2cL.cjs +0 -6
- package/dist/doctor-Be7Ly1oM.mjs +0 -21
- package/dist/doctor-jMxWZyLJ.cjs +0 -21
- package/dist/icons-dev-B_RZIyxu.js +0 -6
- package/dist/icons-dev-BlV3wWFT.cjs +0 -6
- package/dist/image-BHhTvQzr.cjs +0 -6
- package/dist/image-CqKzYD8f.js +0 -6
- package/dist/mdx-DudBEac0.js +0 -7
- package/dist/mdx-r4cDQxWu.cjs +0 -7
- package/dist/node-DtEDyN1u.cjs +0 -111
- package/dist/node-_1jhMGYx.mjs +0 -111
- package/dist/package-DrwtlXfk.cjs +0 -6
- package/dist/parser-CdNbqN5y.cjs +0 -6
- package/dist/parser-nE792MLO.mjs +0 -6
- package/dist/rolldown-runtime-fkIsjY3S.mjs +0 -6
- package/dist/routes-2k3tbUmC.cjs +0 -6
- package/dist/routes-CpxZIsMM.mjs +0 -6
- package/dist/search-dialog-B584t9ZF.js +0 -6
- package/dist/search-dialog-BvBopRsZ.cjs +0 -6
- package/dist/search-dialog-ByvGScjt.js +0 -6
- package/dist/search-dialog-Cyko6TJm.cjs +0 -6
- package/dist/search-dialog-D6BNohIJ.js +0 -6
- package/dist/search-dialog-DuYTIefy.cjs +0 -6
- package/dist/utils-CG65J0Sc.mjs +0 -7
- package/dist/utils-CKunkU96.cjs +0 -7
- package/dist/worker-pool-CGn7DrLb.mjs +0 -6
- package/dist/worker-pool-Crbqgw5R.cjs +0 -6
- package/src/client/app/config-context.tsx +0 -51
- package/src/client/app/doc-page.tsx +0 -38
- package/src/client/app/docs-layout.tsx +0 -28
- package/src/client/app/head.tsx +0 -122
- package/src/client/app/helmet-compat.tsx +0 -36
- package/src/client/app/mdx-component.tsx +0 -8
- package/src/client/app/mdx-components-context.tsx +0 -72
- package/src/client/app/routes-context.tsx +0 -34
- package/src/client/app/scroll-handler.tsx +0 -74
- package/src/client/app/theme-context.tsx +0 -103
- package/src/client/app/ui-context.tsx +0 -42
- package/src/client/components/docs-layout-default.tsx +0 -85
- package/src/client/components/icons-dev.tsx +0 -282
- package/src/client/components/mdx/callout.tsx +0 -97
- package/src/client/components/mdx/card.tsx +0 -99
- package/src/client/components/mdx/cards.tsx +0 -27
- package/src/client/components/mdx/code-block.tsx +0 -184
- package/src/client/components/mdx/field.tsx +0 -33
- package/src/client/components/mdx/image.tsx +0 -44
- package/src/client/components/mdx/index.ts +0 -19
- package/src/client/components/mdx/table.tsx +0 -54
- package/src/client/components/mdx/typographics.tsx +0 -120
- package/src/client/components/mdx/use-code-block.ts +0 -34
- package/src/client/components/primitives/breadcrumbs.tsx +0 -54
- package/src/client/components/primitives/button-group.tsx +0 -54
- package/src/client/components/primitives/button.tsx +0 -6
- package/src/client/components/primitives/code-block.tsx +0 -120
- package/src/client/components/primitives/docs-layout.tsx +0 -125
- package/src/client/components/primitives/error-boundary.tsx +0 -107
- package/src/client/components/primitives/heading.tsx +0 -128
- package/src/client/components/primitives/helpers/observer.ts +0 -141
- package/src/client/components/primitives/image.tsx +0 -26
- package/src/client/components/primitives/link.tsx +0 -102
- package/src/client/components/primitives/menu.tsx +0 -137
- package/src/client/components/primitives/navbar.tsx +0 -466
- package/src/client/components/primitives/on-this-page.tsx +0 -430
- package/src/client/components/primitives/page-nav.tsx +0 -51
- package/src/client/components/primitives/popover.tsx +0 -28
- package/src/client/components/primitives/search-dialog.tsx +0 -193
- package/src/client/components/primitives/sidebar.tsx +0 -423
- package/src/client/components/primitives/skeleton.tsx +0 -26
- package/src/client/components/primitives/tabs.tsx +0 -70
- package/src/client/components/primitives/tooltip.tsx +0 -81
- package/src/client/components/primitives/types.ts +0 -11
- package/src/client/components/ui-base/banner.tsx +0 -66
- package/src/client/components/ui-base/breadcrumbs.tsx +0 -44
- package/src/client/components/ui-base/copy-markdown.tsx +0 -107
- package/src/client/components/ui-base/error-boundary.tsx +0 -15
- package/src/client/components/ui-base/github-stars.tsx +0 -29
- package/src/client/components/ui-base/icons.tsx +0 -240
- package/src/client/components/ui-base/index.ts +0 -16
- package/src/client/components/ui-base/last-updated.tsx +0 -27
- package/src/client/components/ui-base/navbar.tsx +0 -266
- package/src/client/components/ui-base/not-found.tsx +0 -26
- package/src/client/components/ui-base/on-this-page.tsx +0 -57
- package/src/client/components/ui-base/page-nav.tsx +0 -50
- package/src/client/components/ui-base/search-dialog.tsx +0 -163
- package/src/client/components/ui-base/search-highlight.tsx +0 -10
- package/src/client/components/ui-base/sidebar.tsx +0 -92
- package/src/client/components/ui-base/tabs.tsx +0 -83
- package/src/client/components/ui-base/theme-toggle.tsx +0 -130
- package/src/client/components/ui-base/version-i18n.tsx +0 -80
- package/src/client/hooks/index.ts +0 -13
- package/src/client/hooks/use-analytics.ts +0 -272
- package/src/client/hooks/use-breadcrumbs.ts +0 -22
- package/src/client/hooks/use-i18n.ts +0 -182
- package/src/client/hooks/use-localized-to.ts +0 -113
- package/src/client/hooks/use-location.ts +0 -5
- package/src/client/hooks/use-navbar.ts +0 -130
- package/src/client/hooks/use-page-nav.ts +0 -46
- package/src/client/hooks/use-routes.ts +0 -108
- package/src/client/hooks/use-search-highlight.ts +0 -185
- package/src/client/hooks/use-search.ts +0 -118
- package/src/client/hooks/use-sidebar.ts +0 -205
- package/src/client/hooks/use-tabs.ts +0 -46
- package/src/client/hooks/use-version.ts +0 -111
- package/src/client/index.ts +0 -31
- package/src/client/mdx.ts +0 -2
- package/src/client/primitives.ts +0 -19
- package/src/client/ssg/boltdocs-shell.tsx +0 -148
- package/src/client/ssg/create-routes.tsx +0 -473
- package/src/client/ssg/index.ts +0 -4
- package/src/client/ssg/mdx-page.tsx +0 -38
- package/src/client/store/boltdocs-context.tsx +0 -137
- package/src/client/theme/neutral.css +0 -141
- package/src/client/theme/reset.css +0 -189
- package/src/client/types.ts +0 -116
- package/src/client/utils/cn.ts +0 -6
- package/src/client/utils/copy-clipboard.ts +0 -22
- package/src/client/utils/get-base-file-path.ts +0 -21
- package/src/client/utils/github.ts +0 -121
- package/src/client/utils/i18n.ts +0 -23
- package/src/client/utils/path.ts +0 -9
- package/src/client/utils/react-to-text.ts +0 -34
- package/src/client/virtual.d.ts +0 -24
- /package/dist/{meta-loader-CWg2gnbY.mjs → meta-loader-DzwDFtdT.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
|
-
}
|