boltdocs 2.5.6 → 2.6.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 (112) hide show
  1. package/bin/boltdocs.js +2 -2
  2. package/dist/client/index.cjs +6 -0
  3. package/dist/client/{index.d.mts → index.d.cts} +134 -252
  4. package/dist/client/index.d.ts +135 -253
  5. package/dist/client/index.js +1 -1
  6. package/dist/client/theme/neutral.css +90 -50
  7. package/dist/node/cli-entry.cjs +2 -2
  8. package/dist/node/cli-entry.mjs +2 -2
  9. package/dist/node/index.cjs +1 -1
  10. package/dist/node/index.d.cts +150 -205
  11. package/dist/node/index.d.mts +150 -205
  12. package/dist/node/index.mjs +1 -1
  13. package/dist/node-BgvNl2Ay.mjs +89 -0
  14. package/dist/node-vkbb0MK7.cjs +89 -0
  15. package/dist/{package-OFZf0s2j.mjs → package-CR0HF9x3.mjs} +1 -1
  16. package/dist/{package-BY8Jd2j4.cjs → package-Dgmsc_l5.cjs} +1 -1
  17. package/dist/search-dialog-3lvKsbVG.js +6 -0
  18. package/dist/search-dialog-DMK5OpgH.cjs +6 -0
  19. package/dist/use-search-C9bxCqfF.js +6 -0
  20. package/dist/use-search-DcfZSunO.cjs +6 -0
  21. package/package.json +19 -22
  22. package/src/client/app/config-context.tsx +38 -5
  23. package/src/client/app/doc-page.tsx +34 -0
  24. package/src/client/app/mdx-component.tsx +2 -3
  25. package/src/client/app/mdx-components-context.tsx +27 -2
  26. package/src/client/app/routes-context.tsx +34 -0
  27. package/src/client/app/scroll-handler.tsx +7 -4
  28. package/src/client/app/theme-context.tsx +71 -67
  29. package/src/client/components/default-layout.tsx +13 -14
  30. package/src/client/components/docs-layout.tsx +1 -2
  31. package/src/client/components/icons-dev.tsx +36 -5
  32. package/src/client/components/mdx/admonition.tsx +11 -27
  33. package/src/client/components/mdx/badge.tsx +1 -1
  34. package/src/client/components/mdx/button.tsx +3 -3
  35. package/src/client/components/mdx/card.tsx +1 -1
  36. package/src/client/components/mdx/code-block.tsx +90 -80
  37. package/src/client/components/mdx/component-preview.tsx +1 -5
  38. package/src/client/components/mdx/component-props.tsx +1 -1
  39. package/src/client/components/mdx/field.tsx +4 -5
  40. package/src/client/components/mdx/file-tree.tsx +6 -3
  41. package/src/client/components/mdx/hooks/use-code-block.ts +2 -2
  42. package/src/client/components/mdx/image.tsx +1 -1
  43. package/src/client/components/mdx/link.tsx +2 -2
  44. package/src/client/components/mdx/list.tsx +1 -1
  45. package/src/client/components/mdx/table.tsx +1 -1
  46. package/src/client/components/mdx/tabs.tsx +1 -1
  47. package/src/client/components/primitives/breadcrumbs.tsx +1 -7
  48. package/src/client/components/primitives/button-group.tsx +1 -1
  49. package/src/client/components/primitives/button.tsx +1 -1
  50. package/src/client/components/primitives/code-block.tsx +113 -0
  51. package/src/client/components/primitives/link.tsx +23 -41
  52. package/src/client/components/primitives/menu.tsx +5 -6
  53. package/src/client/components/primitives/navbar.tsx +6 -18
  54. package/src/client/components/primitives/navigation-menu.tsx +4 -4
  55. package/src/client/components/primitives/on-this-page.tsx +6 -10
  56. package/src/client/components/primitives/page-nav.tsx +4 -9
  57. package/src/client/components/primitives/popover.tsx +1 -1
  58. package/src/client/components/primitives/search-dialog.tsx +3 -6
  59. package/src/client/components/primitives/sidebar.tsx +80 -22
  60. package/src/client/components/primitives/skeleton.tsx +1 -1
  61. package/src/client/components/primitives/tabs.tsx +4 -11
  62. package/src/client/components/primitives/tooltip.tsx +3 -3
  63. package/src/client/components/ui-base/breadcrumbs.tsx +4 -6
  64. package/src/client/components/ui-base/copy-markdown.tsx +2 -7
  65. package/src/client/components/ui-base/github-stars.tsx +2 -2
  66. package/src/client/components/ui-base/head.tsx +58 -51
  67. package/src/client/components/ui-base/loading.tsx +2 -2
  68. package/src/client/components/ui-base/navbar.tsx +12 -14
  69. package/src/client/components/ui-base/not-found.tsx +1 -1
  70. package/src/client/components/ui-base/on-this-page.tsx +6 -6
  71. package/src/client/components/ui-base/page-nav.tsx +4 -8
  72. package/src/client/components/ui-base/search-dialog.tsx +10 -8
  73. package/src/client/components/ui-base/sidebar.tsx +76 -23
  74. package/src/client/components/ui-base/tabs.tsx +9 -8
  75. package/src/client/components/ui-base/theme-toggle.tsx +2 -2
  76. package/src/client/hooks/use-i18n.ts +3 -3
  77. package/src/client/hooks/use-localized-to.ts +1 -1
  78. package/src/client/hooks/use-navbar.ts +8 -6
  79. package/src/client/hooks/use-routes.ts +19 -11
  80. package/src/client/hooks/use-search.ts +1 -1
  81. package/src/client/hooks/use-sidebar.ts +48 -2
  82. package/src/client/hooks/use-tabs.ts +6 -2
  83. package/src/client/hooks/use-version.ts +3 -3
  84. package/src/client/index.ts +22 -22
  85. package/src/client/ssg/boltdocs-shell.tsx +127 -0
  86. package/src/client/ssg/create-routes.tsx +179 -0
  87. package/src/client/ssg/index.ts +3 -0
  88. package/src/client/ssg/mdx-page.tsx +37 -0
  89. package/src/client/store/boltdocs-context.tsx +46 -99
  90. package/src/client/theme/neutral.css +90 -50
  91. package/src/client/types.ts +5 -33
  92. package/src/client/utils/react-to-text.ts +34 -0
  93. package/dist/cache-Cr8W2zgZ.cjs +0 -6
  94. package/dist/cache-DFdakSmR.mjs +0 -6
  95. package/dist/client/index.mjs +0 -6
  96. package/dist/client/ssr.cjs +0 -6
  97. package/dist/client/ssr.d.cts +0 -80
  98. package/dist/client/ssr.d.mts +0 -80
  99. package/dist/client/ssr.mjs +0 -6
  100. package/dist/node-CWXme96p.mjs +0 -73
  101. package/dist/node-VYfhzGrh.cjs +0 -73
  102. package/dist/search-dialog-BeNyI_KQ.mjs +0 -6
  103. package/dist/search-dialog-dYsCAk5S.js +0 -6
  104. package/dist/use-search-D25n0PrV.mjs +0 -6
  105. package/dist/use-search-WuzdH1cJ.js +0 -6
  106. package/src/client/app/index.tsx +0 -348
  107. package/src/client/app/mdx-page.tsx +0 -15
  108. package/src/client/app/preload.tsx +0 -66
  109. package/src/client/app/router.tsx +0 -30
  110. package/src/client/integrations/codesandbox.ts +0 -179
  111. package/src/client/integrations/index.ts +0 -1
  112. package/src/client/ssr.tsx +0 -65
@@ -1,4 +1,4 @@
1
- import { cn } from '@client/utils/cn'
1
+ import { cn } from '../../utils/cn'
2
2
  import { cva } from 'class-variance-authority'
3
3
  import type { VariantProps } from 'class-variance-authority'
4
4
 
@@ -2,10 +2,10 @@ import {
2
2
  Button as ButtonPrimitive,
3
3
  buttonVariants,
4
4
  type ButtonProps,
5
- } from '@components/primitives/button'
6
- import { cn } from '@client/utils/cn'
5
+ } from '../primitives/button'
6
+ import { cn } from '../../utils/cn'
7
7
 
8
- export type { ButtonProps } from '@components/primitives/button'
8
+ export type { ButtonProps } from '../primitives/button'
9
9
 
10
10
  export const Button = ({
11
11
  className,
@@ -1,7 +1,7 @@
1
1
  import type { MouseEvent as ReactMouseEvent } from 'react'
2
2
  import { useCallback, useRef } from 'react'
3
3
  import * as RAC from 'react-aria-components'
4
- import { cn } from '@client/utils/cn'
4
+ import { cn } from '../../utils/cn'
5
5
  import { cva } from 'class-variance-authority'
6
6
  import type { VariantProps } from 'class-variance-authority'
7
7
 
@@ -1,8 +1,9 @@
1
- import * as RAC from 'react-aria-components'
1
+ import { Button } from 'react-aria-components'
2
2
  import { Copy, Check, File } from 'lucide-react'
3
- import { cn } from '@client/utils/cn'
3
+ import { cn } from '../../utils/cn'
4
+ import { reactToText } from '../../utils/react-to-text'
4
5
  import { useCodeBlock } from './hooks/use-code-block'
5
- import { useConfig } from '@client/app/config-context'
6
+ import * as CodePrimitive from '../primitives/code-block'
6
7
  import {
7
8
  TypeScript,
8
9
  JavaScript,
@@ -13,8 +14,10 @@ import {
13
14
  Markdown,
14
15
  Shell,
15
16
  Yaml,
16
- } from '@components/icons-dev'
17
- import { Tooltip } from '@components/primitives/tooltip'
17
+ Rust,
18
+ BracketsRed,
19
+ } from '../icons-dev'
20
+ import { Tooltip } from '../primitives/tooltip'
18
21
 
19
22
  const langIconMap: Record<string, React.ComponentType<{ size?: number }>> = {
20
23
  ts: TypeScript,
@@ -30,6 +33,9 @@ const langIconMap: Record<string, React.ComponentType<{ size?: number }>> = {
30
33
  sh: Shell,
31
34
  yaml: Yaml,
32
35
  yml: Yaml,
36
+ rs: Rust,
37
+ rust: Rust,
38
+ toml: BracketsRed
33
39
  }
34
40
 
35
41
  export interface CodeBlockProps {
@@ -40,10 +46,32 @@ export interface CodeBlockProps {
40
46
  lang?: string
41
47
  highlightedHtml?: string
42
48
  'data-lang'?: string
49
+ 'data-title'?: string
43
50
  plain?: boolean
44
51
  [key: string]: any
45
52
  }
46
53
 
54
+ const CopyButton = ({ copied, handleCopy }: { copied: boolean; handleCopy: () => void }) => {
55
+ return (
56
+ <Tooltip content={copied ? 'Copied!' : 'Copy code'}>
57
+ {/* @ts-ignore */}
58
+ <Button
59
+ onPress={handleCopy}
60
+ className={cn(
61
+ 'grid place-items-center size-8 bg-transparent outline-none cursor-pointer transition-all duration-200 hover:scale-110 active:scale-95 [&>svg]:size-4 [&>svg]:stroke-2',
62
+ copied
63
+ ? 'text-emerald-400'
64
+ : 'text-text-muted hover:text-text-main',
65
+ )}
66
+ aria-label="Copy code"
67
+ >
68
+ {/* @ts-ignore */}
69
+ {copied ? <Check size={20} /> : <Copy size={20} />}
70
+ </Button>
71
+ </Tooltip>
72
+ )
73
+ }
74
+
47
75
  export function CodeBlock(props: CodeBlockProps) {
48
76
  const {
49
77
  children,
@@ -51,13 +79,16 @@ export function CodeBlock(props: CodeBlockProps) {
51
79
  highlightedHtml,
52
80
  'data-highlighted-html': dataHighlightedHtml,
53
81
  title,
82
+ 'data-title': dataTitle,
54
83
  'data-lang': dataLang,
55
84
  plain = false,
56
85
  ...rest
57
86
  } = props
87
+
58
88
  const effectiveHighlightedHtml = highlightedHtml || dataHighlightedHtml
59
- const config = useConfig()
89
+ const effectiveTitle = title || dataTitle
60
90
  const lang = props.lang || dataLang || ''
91
+
61
92
  const {
62
93
  copied,
63
94
  isExpanded,
@@ -71,84 +102,63 @@ export function CodeBlock(props: CodeBlockProps) {
71
102
  const LangIcon = langIconMap[lang]
72
103
 
73
104
  return (
74
- <div
75
- className={cn(
76
- 'group relative overflow-hidden bg-(--color-code-bg)',
77
- 'contain-layout contain-paint', // Optimization: isolate code block rendering
78
- {
79
- 'my-6 rounded-lg border border-border-subtle': !plain,
80
- '[&>pre]:max-h-62.5 [&>pre]:overflow-hidden': shouldTruncate,
81
- },
82
- props.className,
83
- )}
84
- >
85
- {/* Title Header */}
86
- {title && (
87
- <div className="flex items-center gap-2 border-b border-border-subtle bg-bg-surface/50 px-4 py-2 text-[13px] font-medium text-text-muted">
88
- {LangIcon ? (
89
- <LangIcon size={14} />
90
- ) : (
91
- <File size={14} className="opacity-60" />
92
- )}
93
- <span>{title}</span>
94
- </div>
105
+ <CodePrimitive.CodeBlock plain={plain} className={props.className}>
106
+ {(effectiveTitle || !hideCopy) && (
107
+ <CodePrimitive.CodeBlockHeader>
108
+ <CodePrimitive.CodeBlockGroup>
109
+ {effectiveTitle && (
110
+ <>
111
+ {LangIcon ? (
112
+ <LangIcon size={14} />
113
+ ) : (
114
+ // @ts-ignore
115
+ <File size={14} className="opacity-60" />
116
+ )}
117
+ <span>{effectiveTitle}</span>
118
+ </>
119
+ )}
120
+ </CodePrimitive.CodeBlockGroup>
121
+ {!hideCopy && <CopyButton copied={copied} handleCopy={handleCopy} />}
122
+ </CodePrimitive.CodeBlockHeader>
95
123
  )}
96
124
 
97
- {/* Toolbar */}
98
- <div className="absolute top-3 right-4 z-50 flex items-center gap-2 transition-all duration-300 opacity-0 group-hover:opacity-100">
99
- {!hideCopy && (
100
- <Tooltip content={copied ? 'Copied!' : 'Copy code'}>
101
- <RAC.Button
102
- onPress={handleCopy}
103
- className={cn(
104
- 'grid place-items-center size-8 bg-transparent outline-none cursor-pointer transition-all duration-200 hover:scale-110 active:scale-95 [&>svg]:size-4 [&>svg]:stroke-2',
105
- copied
106
- ? 'text-emerald-400'
107
- : 'text-text-muted hover:text-text-main',
108
- )}
109
- aria-label="Copy code"
110
- >
111
- {copied ? <Check size={20} /> : <Copy size={20} />}
112
- </RAC.Button>
113
- </Tooltip>
125
+ <CodePrimitive.CodeBlockContent shouldTruncate={shouldTruncate}>
126
+ {effectiveHighlightedHtml ? (
127
+ <div
128
+ // @ts-ignore
129
+ ref={preRef}
130
+ className="shiki-wrapper [&>pre]:m-0! [&>pre]:rounded-none! [&>pre]:border-none! [&>pre]:bg-inherit! [&>pre>code]:grid! [&>pre>code]:p-5! [&>.shiki.shiki-themes]:bg-transparent!"
131
+ dangerouslySetInnerHTML={{ __html: effectiveHighlightedHtml }}
132
+ />
133
+ ) : (
134
+ <pre
135
+ ref={preRef}
136
+ className="m-0! p-5! rounded-none! border-none! bg-inherit! font-mono text-[0.8125rem] leading-[1.7] overflow-x-auto"
137
+ {...rest}
138
+ >
139
+ {reactToText(children)}
140
+ </pre>
114
141
  )}
115
- </div>
116
-
117
- {/* Code Content */}
118
- {effectiveHighlightedHtml ? (
119
- <div
120
- // @ts-ignore
121
- ref={preRef}
122
- className="shiki-wrapper [&>pre]:m-0! [&>pre]:rounded-none! [&>pre]:border-none! [&>pre]:bg-inherit! [&>pre>code]:grid! [&>pre>code]:p-5! [&>.shiki.shiki-themes]:bg-transparent!"
123
- dangerouslySetInnerHTML={{ __html: effectiveHighlightedHtml }}
124
- />
125
- ) : (
126
- <pre
127
- ref={preRef}
128
- className="m-0! rounded-none! border-none! bg-inherit! font-mono text-[0.8125rem] leading-[1.7]"
129
- {...rest}
130
- >
131
- {children}
132
- </pre>
133
- )}
134
142
 
135
- {/* Expand/Collapse */}
136
- {isExpandable && (
137
- <div
138
- className={cn(
139
- shouldTruncate
140
- ? 'absolute bottom-0 inset-x-0 h-24 bg-linear-to-t from-(--color-code-bg) to-transparent flex items-end justify-center pb-4 z-10'
141
- : 'relative flex justify-center py-4',
142
- )}
143
- >
144
- <RAC.Button
145
- onPress={() => setIsExpanded(!isExpanded)}
146
- className="rounded-full bg-bg-surface border border-border-subtle px-5 py-2 text-[0.8125rem] font-medium text-text-main outline-none cursor-pointer transition-all hover:bg-border-subtle hover:-translate-y-px backdrop-blur-md"
143
+ {/* Expand/Collapse Trigger */}
144
+ {isExpandable && (
145
+ <div
146
+ className={cn(
147
+ shouldTruncate
148
+ ? 'absolute bottom-0 inset-x-0 h-24 bg-linear-to-t from-(--color-code-bg) to-transparent flex items-end justify-center pb-4 z-10'
149
+ : 'relative flex justify-center py-4',
150
+ )}
147
151
  >
148
- {isExpanded ? 'Show less' : 'Expand code'}
149
- </RAC.Button>
150
- </div>
151
- )}
152
- </div>
152
+ {/* @ts-ignore */}
153
+ <Button
154
+ onPress={() => setIsExpanded(!isExpanded)}
155
+ className="rounded-full bg-bg-surface border border-border-subtle px-5 py-2 text-[0.8125rem] font-medium text-text-main outline-none cursor-pointer transition-all hover:bg-border-subtle hover:-translate-y-px backdrop-blur-md"
156
+ >
157
+ {isExpanded ? 'Show less' : 'Expand code'}
158
+ </Button>
159
+ </div>
160
+ )}
161
+ </CodePrimitive.CodeBlockContent>
162
+ </CodePrimitive.CodeBlock>
153
163
  )
154
164
  }
@@ -11,11 +11,7 @@ export interface ComponentPreviewProps {
11
11
  }
12
12
 
13
13
  export function ComponentPreview(props: ComponentPreviewProps) {
14
- const {
15
- highlightedHtml,
16
- hideCode = false,
17
- hideCopy = false,
18
- } = props
14
+ const { highlightedHtml, hideCode = false, hideCopy = false } = props
19
15
  const { initialCode, previewElement } = useComponentPreview(props)
20
16
 
21
17
  return (
@@ -1,4 +1,4 @@
1
- import { cn } from '@client/utils/cn'
1
+ import { cn } from '../../utils/cn'
2
2
 
3
3
  export interface PropItem {
4
4
  name: string
@@ -1,4 +1,4 @@
1
- import { cn } from '@client/utils/cn'
1
+ import { cn } from '../../utils/cn'
2
2
 
3
3
  export interface FieldProps {
4
4
  name: string
@@ -23,23 +23,22 @@ export function Field({
23
23
  <article
24
24
  className={cn(
25
25
  'group relative my-6 rounded-xl border border-border-subtle bg-bg-surface p-5 transition-all duration-300',
26
- 'hover:border-primary-500/30 hover:shadow-lg hover:shadow-primary-500/5',
27
26
  className,
28
27
  )}
29
28
  id={id}
30
29
  >
31
30
  <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mb-4">
32
31
  <div className="flex flex-wrap items-center gap-2.5">
33
- <code className="inline-flex items-center rounded-md bg-primary-500/10 px-2.5 py-1 font-mono text-sm font-bold text-primary-400 border border-primary-500/20 shadow-sm transition-colors group-hover:bg-primary-500/15">
32
+ <code className="inline-flex items-center rounded-md bg-primary-500/10 px-2.5 py-1 font-mono text-sm font-bold text-primary-400 border border-primary-500/20 shadow-sm transition-colors">
34
33
  {name}
35
34
  </code>
36
35
  {type && (
37
- <span className="rounded-md bg-bg-muted/80 border border-border-subtle px-2 py-0.5 text-[11px] font-semibold text-text-muted uppercase tracking-wider shadow-sm">
36
+ <span className="rounded-md bg-bg-muted/80 border border-border-subtle px-2 py-0.5 text-[11px] font-semibold text-text-muted uppercase shadow-sm">
38
37
  {type}
39
38
  </span>
40
39
  )}
41
40
  {required && (
42
- <div className="flex items-center gap-1.5 rounded-full bg-red-500/10 px-2.5 py-0.5 text-[10px] font-bold uppercase tracking-wider text-red-400 border border-red-500/20 shadow-sm">
41
+ <div className="flex items-center gap-1.5 rounded-full bg-red-500/10 px-2.5 py-0.5 text-[10px] font-bold uppercase text-red-400 border border-red-500/20 shadow-sm">
43
42
  <span className="h-1 w-1 rounded-full bg-red-400 animate-pulse" />
44
43
  Required
45
44
  </div>
@@ -8,7 +8,7 @@ import {
8
8
  FileImage,
9
9
  ChevronRight,
10
10
  } from 'lucide-react'
11
- import { cn } from '@client/utils/cn'
11
+ import { cn } from '../../utils/cn'
12
12
 
13
13
  import {
14
14
  TypeScript,
@@ -20,14 +20,17 @@ import {
20
20
  Markdown,
21
21
  Shell,
22
22
  Yaml,
23
- } from '@components/icons-dev'
23
+ } from '../icons-dev'
24
24
 
25
25
  // --- Constants & Types ---
26
26
 
27
27
  const ICON_SIZE = 16
28
28
  const STROKE_WIDTH = 2
29
29
 
30
- const FILE_EXTENSION_MAP: Record<string, React.ComponentType<{ size?: number }>> = {
30
+ const FILE_EXTENSION_MAP: Record<
31
+ string,
32
+ React.ComponentType<{ size?: number }>
33
+ > = {
31
34
  ts: TypeScript,
32
35
  tsx: ReactIcon,
33
36
  js: JavaScript,
@@ -1,5 +1,5 @@
1
- import { useConfig } from '@client/app/config-context'
2
- import { copyToClipboard } from '@client/utils/copy-clipboard'
1
+ import { useConfig } from '../../../app/config-context'
2
+ import { copyToClipboard } from '../../../utils/copy-clipboard'
3
3
  import { useCallback, useEffect, useRef, useState } from 'react'
4
4
  import type { CodeBlockProps } from '../code-block'
5
5
 
@@ -1,5 +1,5 @@
1
1
  import type { ImgHTMLAttributes } from 'react'
2
- import { useTheme } from '@client/app/theme-context'
2
+ import { useTheme } from '../../app/theme-context'
3
3
 
4
4
  export interface ImageProps extends ImgHTMLAttributes<HTMLImageElement> {
5
5
  src: string
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  Link as LinkPrimitive,
3
3
  type LinkProps as LinkPrimitiveProps,
4
- } from '@components/primitives/link'
5
- import { cn } from '@client/utils/cn'
4
+ } from '../primitives/link'
5
+ import { cn } from '../../utils/cn'
6
6
 
7
7
  export type LinkProps = LinkPrimitiveProps & {
8
8
  to: string
@@ -6,7 +6,7 @@ import {
6
6
  type ComponentPropsWithoutRef,
7
7
  } from 'react'
8
8
  import { Check, ChevronRight, Circle } from 'lucide-react'
9
- import { cn } from '@client/utils/cn'
9
+ import { cn } from '../../utils/cn'
10
10
  import { cva, type VariantProps } from 'class-variance-authority'
11
11
 
12
12
  const listVariants = cva('my-6 transition-all duration-200', {
@@ -8,7 +8,7 @@ import {
8
8
  ChevronsLeft,
9
9
  ChevronsRight,
10
10
  } from 'lucide-react'
11
- import { cn } from '@client/utils/cn'
11
+ import { cn } from '../../utils/cn'
12
12
 
13
13
  export interface TableProps {
14
14
  headers?: string[]
@@ -1,7 +1,7 @@
1
1
  import { Children, isValidElement, useMemo } from 'react'
2
2
  import * as RAC from 'react-aria-components'
3
3
  import { useTabs } from './hooks/useTabs'
4
- import { cn } from '@client/utils/cn'
4
+ import { cn } from '../../utils/cn'
5
5
  import { CodeBlock } from './code-block'
6
6
  import { cva } from 'class-variance-authority'
7
7
 
@@ -26,11 +26,7 @@ export const Breadcrumbs = ({
26
26
  )
27
27
  }
28
28
 
29
- const BreadcrumbsItem = ({
30
- children,
31
- className,
32
- ...props
33
- }: ComponentBase) => {
29
+ const BreadcrumbsItem = ({ children, className, ...props }: ComponentBase) => {
34
30
  return (
35
31
  <Breadcrumb
36
32
  className={cn('flex items-center mb-0 gap-1.5', className)}
@@ -71,8 +67,6 @@ const BreadcrumbsSeparator = ({ className }: ComponentBase) => {
71
67
  )
72
68
  }
73
69
 
74
-
75
-
76
70
  Breadcrumbs.Root = Breadcrumbs
77
71
  Breadcrumbs.Item = BreadcrumbsItem
78
72
  Breadcrumbs.Link = BreadcrumbsLink
@@ -1,4 +1,4 @@
1
- import { cn } from '@client/utils/cn'
1
+ import { cn } from '../../utils/cn'
2
2
  import type { ComponentBase } from './types'
3
3
 
4
4
  export interface ButtonGroupProps extends ComponentBase {
@@ -1,5 +1,5 @@
1
1
  import * as RAC from 'react-aria-components'
2
- import { cn } from '@client/utils/cn'
2
+ import { cn } from '../../utils/cn'
3
3
  import { cva } from 'class-variance-authority'
4
4
  import type { VariantProps } from 'class-variance-authority'
5
5
 
@@ -0,0 +1,113 @@
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
+ const CodeBlock = ({
13
+ children,
14
+ className,
15
+ plain = false,
16
+ ...props
17
+ }: CodeBlockRootProps) => {
18
+ return (
19
+ <div
20
+ className={cn(
21
+ "not-prose boltdocs-code-block",
22
+ 'group relative overflow-hidden bg-(--color-code-bg)',
23
+ 'contain-layout contain-paint',
24
+ {
25
+ 'my-6 rounded-lg border border-border-subtle': !plain,
26
+ },
27
+ className,
28
+ )}
29
+ {...props}
30
+ >
31
+ {children}
32
+ </div>
33
+ );
34
+ };
35
+
36
+ type CodeBlockHeaderProps = ComponentProps<"div">;
37
+
38
+ const CodeBlockHeader = ({
39
+ children,
40
+ className,
41
+ ...props
42
+ }: CodeBlockHeaderProps) => {
43
+ return (
44
+ <div
45
+ className={cn(
46
+ "flex h-9 items-center justify-between px-4 py-1.5",
47
+ "border-b border-border-subtle bg-bg-surface/50",
48
+ "text-[13px] font-medium text-text-muted",
49
+ className,
50
+ )}
51
+ {...props}
52
+ >
53
+ {children}
54
+ </div>
55
+ );
56
+ };
57
+
58
+ type CodeBlockGroupProps = ComponentProps<"div">;
59
+
60
+ const CodeBlockGroup = ({
61
+ children,
62
+ className,
63
+ ...props
64
+ }: CodeBlockGroupProps) => {
65
+ return (
66
+ <div
67
+ className={cn(
68
+ "flex items-center space-x-2",
69
+ className,
70
+ )}
71
+ {...props}
72
+ >
73
+ {children}
74
+ </div>
75
+ );
76
+ };
77
+
78
+ interface CodeBlockContentProps extends ComponentProps<"div"> {
79
+ /**
80
+ * Whether the code should be truncated with an expand button
81
+ * @default false
82
+ */
83
+ shouldTruncate?: boolean;
84
+ }
85
+
86
+ const CodeBlockContent = ({
87
+ className,
88
+ children,
89
+ shouldTruncate = false,
90
+ ...props
91
+ }: CodeBlockContentProps) => {
92
+ return (
93
+ <div
94
+ className={cn(
95
+ "relative",
96
+ {
97
+ '[&>pre]:max-h-62.5 [&>pre]:overflow-hidden': shouldTruncate,
98
+ },
99
+ className,
100
+ )}
101
+ {...props}
102
+ >
103
+ {children}
104
+ </div>
105
+ );
106
+ };
107
+
108
+ export {
109
+ CodeBlock,
110
+ CodeBlockHeader,
111
+ CodeBlockGroup,
112
+ CodeBlockContent,
113
+ };
@@ -1,12 +1,11 @@
1
- import React from 'react'
2
1
  import {
3
2
  Link as RACLink,
4
3
  type LinkProps as RACLinkProps,
5
4
  } from 'react-aria-components'
6
5
  import { useLocation } from 'react-router-dom'
7
- import { useLocalizedTo } from '@hooks/use-localized-to'
8
- import { usePreload } from '@client/app/preload'
9
- import { cn } from '@client/utils/cn'
6
+ import { useLocalizedTo } from '../../hooks/use-localized-to'
7
+ import { cn } from '../../utils/cn'
8
+ import { forwardRef } from 'react'
10
9
 
11
10
  export interface LinkProps extends RACLinkProps {
12
11
  /** Should prefetch the page on hover? Default 'hover' */
@@ -20,46 +19,29 @@ export interface LinkProps extends RACLinkProps {
20
19
  * It uses the global navigation configuration from BoltdocsRouterProvider
21
20
  * to handle seamless client-side transitions.
22
21
  */
23
- export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
24
- (props, ref) => {
25
- const { href, prefetch = 'hover', onMouseEnter, onFocus, ...rest } = props
22
+ export const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
23
+ const { href, prefetch = 'hover', onMouseEnter, onFocus, ...rest } = props
26
24
 
27
- const localizedHref = useLocalizedTo(href ?? '')
28
- const { preload } = usePreload()
25
+ const localizedHref = useLocalizedTo(href ?? '')
29
26
 
30
- const handleMouseEnter = (e: React.MouseEvent<HTMLAnchorElement>) => {
31
- onMouseEnter?.(e)
32
- if (
33
- prefetch === 'hover' &&
34
- typeof localizedHref === 'string' &&
35
- localizedHref.startsWith('/')
36
- ) {
37
- preload(localizedHref)
38
- }
39
- }
27
+ const handleMouseEnter = (e: React.MouseEvent<HTMLAnchorElement>) => {
28
+ onMouseEnter?.(e)
29
+ }
40
30
 
41
- const handleFocus = (e: React.FocusEvent) => {
42
- onFocus?.(e as any)
43
- if (
44
- prefetch === 'hover' &&
45
- typeof localizedHref === 'string' &&
46
- localizedHref.startsWith('/')
47
- ) {
48
- preload(localizedHref)
49
- }
50
- }
31
+ const handleFocus = (e: React.FocusEvent) => {
32
+ onFocus?.(e as any)
33
+ }
51
34
 
52
- return (
53
- <RACLink
54
- {...rest}
55
- ref={ref}
56
- href={localizedHref as string}
57
- onMouseEnter={handleMouseEnter}
58
- onFocus={handleFocus as any}
59
- />
60
- )
61
- },
62
- )
35
+ return (
36
+ <RACLink
37
+ {...rest}
38
+ ref={ref}
39
+ href={localizedHref as string}
40
+ onMouseEnter={handleMouseEnter}
41
+ onFocus={handleFocus as any}
42
+ />
43
+ )
44
+ })
63
45
  Link.displayName = 'Link'
64
46
 
65
47
  /**
@@ -90,7 +72,7 @@ export interface NavLinkProps
90
72
  * It combines the Link primitive with path matching logic to determine
91
73
  * if the link is currently active based on the browser's location.
92
74
  */
93
- export const NavLink = React.forwardRef<HTMLAnchorElement, NavLinkProps>(
75
+ export const NavLink = forwardRef<HTMLAnchorElement, NavLinkProps>(
94
76
  (props, ref) => {
95
77
  const { href, end = false, className, children, ...rest } = props
96
78
  const location = useLocation()