boltdocs 2.6.2 → 2.7.1
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/bin/boltdocs.js +0 -1
- package/dist/cache-CQKlT4fI.mjs +6 -0
- package/dist/cache-DorPMFgW.cjs +6 -0
- package/dist/cards-BLoSiRuL.d.ts +30 -0
- package/dist/cards-CQn9mXZS.d.cts +30 -0
- package/dist/chunk-Ds5LZdWN.cjs +6 -0
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +168 -1339
- package/dist/client/index.d.ts +167 -1338
- package/dist/client/index.js +1 -1
- package/dist/{package-CFP44vfn.cjs → client/mdx.cjs} +1 -1
- package/dist/client/mdx.d.cts +128 -0
- package/dist/client/mdx.d.ts +129 -0
- package/dist/client/mdx.js +6 -0
- package/dist/client/primitives.cjs +6 -0
- package/dist/client/primitives.d.cts +818 -0
- package/dist/client/primitives.d.ts +818 -0
- package/dist/client/primitives.js +6 -0
- package/dist/client/theme/neutral.css +74 -361
- package/dist/client/theme/reset.css +189 -0
- package/dist/docs-layout-BlDhcQRv.cjs +6 -0
- package/dist/docs-layout-BvAOWEJw.js +6 -0
- package/dist/doctor-BQiQhCTl.cjs +6 -0
- package/dist/doctor-COpf35L2.cjs +20 -0
- package/dist/doctor-Dh1XP7Pz.mjs +20 -0
- package/dist/generator-DGW6pkCC.cjs +22 -0
- package/dist/generator-Dv3wEmhZ.mjs +22 -0
- package/dist/icons-dev-CrQLjoQp.js +6 -0
- package/dist/icons-dev-rzdz6Lf3.cjs +6 -0
- package/dist/image-BkIfa9oo.js +6 -0
- package/dist/image-DIGjCPe6.cjs +6 -0
- package/dist/mdx-K0WYBAJ3.js +7 -0
- package/dist/mdx-hpErbRUe.cjs +7 -0
- package/dist/meta-loader-0gJ4PtBC.cjs +6 -0
- package/dist/meta-loader-9IpAHWDS.mjs +6 -0
- package/dist/node/cli-entry.cjs +1 -2
- package/dist/node/cli-entry.mjs +1 -2
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +55 -11
- package/dist/node/index.d.mts +55 -12
- package/dist/node/index.mjs +1 -1
- package/dist/node/routes/worker.cjs +6 -0
- package/dist/node/routes/worker.d.cts +2 -0
- package/dist/node/routes/worker.d.mts +2 -0
- package/dist/node/routes/worker.mjs +6 -0
- package/dist/node-BzKYJJuY.cjs +111 -0
- package/dist/node-m6fKXXVs.mjs +111 -0
- package/dist/{package-Bqbn1AYK.mjs → package-2TVh81ZC.mjs} +1 -1
- package/dist/package-D1O_gJub.cjs +6 -0
- package/dist/parser-Bh11BsdA.cjs +6 -0
- package/dist/parser-D8eQvE7N.mjs +6 -0
- package/dist/parser-DYRzXWmA.cjs +6 -0
- package/dist/routes-CHf76Ye4.cjs +6 -0
- package/dist/routes-CMUZGI6T.mjs +6 -0
- package/dist/routes-Co1mRM58.cjs +6 -0
- package/dist/search-dialog-BACuzoVX.cjs +6 -0
- package/dist/search-dialog-BKagVT17.js +6 -0
- package/dist/search-dialog-C8w12eUx.js +6 -0
- package/dist/search-dialog-CGyrozZE.cjs +6 -0
- package/dist/search-dialog-D26rUnJ_.cjs +6 -0
- package/dist/sidebar-DKvg6KOc.d.cts +491 -0
- package/dist/sidebar-Dr1TiRIy.d.ts +491 -0
- package/dist/utils-BxNAXhZZ.mjs +7 -0
- package/dist/utils-Clzu7jvb.cjs +7 -0
- package/dist/worker-pool-Bd8Y9KDv.mjs +6 -0
- package/dist/worker-pool-BwU8ckrg.cjs +6 -0
- package/package.json +27 -8
- package/src/client/app/doc-page.tsx +9 -5
- package/src/client/app/docs-layout.tsx +17 -3
- package/src/client/app/head.tsx +122 -0
- package/src/client/app/helmet-compat.tsx +36 -0
- package/src/client/app/mdx-component.tsx +5 -52
- package/src/client/app/mdx-components-context.tsx +32 -8
- package/src/client/app/routes-context.tsx +2 -2
- package/src/client/app/scroll-handler.tsx +1 -1
- package/src/client/app/theme-context.tsx +5 -5
- package/src/client/app/ui-context.tsx +42 -0
- package/src/client/components/docs-layout-default.tsx +85 -0
- package/src/client/components/icons-dev.tsx +38 -15
- package/src/client/components/mdx/callout.tsx +97 -0
- package/src/client/components/mdx/card.tsx +73 -98
- package/src/client/components/mdx/cards.tsx +27 -0
- package/src/client/components/mdx/code-block.tsx +37 -17
- package/src/client/components/mdx/field.tsx +24 -56
- package/src/client/components/mdx/image.tsx +36 -15
- package/src/client/components/mdx/index.ts +19 -53
- package/src/client/components/mdx/table.tsx +46 -148
- package/src/client/components/mdx/typographics.tsx +120 -0
- package/src/client/components/mdx/{hooks/use-code-block.ts → use-code-block.ts} +5 -7
- package/src/client/components/primitives/breadcrumbs.tsx +5 -24
- package/src/client/components/primitives/button.tsx +3 -142
- package/src/client/components/primitives/code-block.tsx +104 -97
- package/src/client/components/{docs-layout.tsx → primitives/docs-layout.tsx} +15 -24
- package/src/client/components/primitives/error-boundary.tsx +107 -0
- package/src/client/components/primitives/heading.tsx +128 -0
- package/src/client/components/primitives/helpers/observer.ts +62 -32
- package/src/client/components/primitives/image.tsx +26 -0
- package/src/client/components/primitives/link.tsx +50 -52
- package/src/client/components/primitives/menu.tsx +25 -49
- package/src/client/components/primitives/navbar.tsx +234 -59
- package/src/client/components/primitives/on-this-page.tsx +169 -40
- package/src/client/components/primitives/page-nav.tsx +11 -39
- package/src/client/components/primitives/popover.tsx +12 -30
- package/src/client/components/primitives/search-dialog.tsx +77 -71
- package/src/client/components/primitives/sidebar.tsx +312 -119
- package/src/client/components/primitives/skeleton.tsx +1 -1
- package/src/client/components/primitives/tabs.tsx +5 -16
- package/src/client/components/primitives/tooltip.tsx +1 -1
- package/src/client/components/ui-base/banner.tsx +66 -0
- package/src/client/components/ui-base/breadcrumbs.tsx +26 -20
- package/src/client/components/ui-base/copy-markdown.tsx +43 -35
- package/src/client/components/ui-base/error-boundary.tsx +9 -46
- package/src/client/components/ui-base/github-stars.tsx +5 -3
- package/src/client/components/ui-base/index.ts +3 -3
- package/src/client/components/ui-base/last-updated.tsx +27 -0
- package/src/client/components/ui-base/navbar.tsx +183 -89
- package/src/client/components/ui-base/not-found.tsx +11 -9
- package/src/client/components/ui-base/on-this-page.tsx +8 -104
- package/src/client/components/ui-base/page-nav.tsx +23 -9
- package/src/client/components/ui-base/search-dialog.tsx +111 -36
- package/src/client/components/ui-base/search-highlight.tsx +10 -0
- package/src/client/components/ui-base/sidebar.tsx +77 -154
- package/src/client/components/ui-base/tabs.tsx +20 -7
- package/src/client/components/ui-base/theme-toggle.tsx +88 -10
- package/src/client/components/ui-base/version-i18n.tsx +80 -0
- package/src/client/hooks/index.ts +2 -1
- package/src/client/hooks/use-analytics.ts +272 -0
- package/src/client/hooks/use-i18n.ts +116 -50
- package/src/client/hooks/use-localized-to.ts +70 -27
- package/src/client/hooks/use-navbar.ts +69 -39
- package/src/client/hooks/use-page-nav.ts +28 -25
- package/src/client/hooks/use-routes.ts +63 -80
- package/src/client/hooks/use-search-highlight.ts +185 -0
- package/src/client/hooks/use-search.ts +12 -3
- package/src/client/hooks/use-sidebar.ts +183 -80
- package/src/client/hooks/use-tabs.ts +3 -4
- package/src/client/hooks/use-version.ts +44 -29
- package/src/client/index.ts +13 -87
- package/src/client/mdx.ts +2 -0
- package/src/client/primitives.ts +19 -0
- package/src/client/ssg/boltdocs-shell.tsx +68 -79
- package/src/client/ssg/create-routes.tsx +268 -72
- package/src/client/ssg/index.ts +1 -0
- package/src/client/ssg/mdx-page.tsx +2 -1
- package/src/client/store/boltdocs-context.tsx +72 -20
- package/src/client/theme/neutral.css +74 -361
- package/src/client/theme/reset.css +189 -0
- package/src/client/types.ts +10 -2
- package/src/client/utils/path.ts +9 -0
- package/src/client/utils/react-to-text.ts +24 -24
- package/src/client/virtual.d.ts +1 -1
- package/src/shared/types.ts +82 -22
- package/dist/node-Bogvkxao.mjs +0 -101
- package/dist/node-CXaog6St.cjs +0 -101
- package/dist/search-dialog-CV3eJzMm.cjs +0 -6
- package/dist/search-dialog-DNTomKgu.js +0 -6
- package/dist/use-search-CS3gH19M.js +0 -6
- package/dist/use-search-DBpJZQuw.cjs +0 -6
- package/src/client/components/mdx/admonition.tsx +0 -91
- package/src/client/components/mdx/badge.tsx +0 -41
- package/src/client/components/mdx/button.tsx +0 -35
- package/src/client/components/mdx/component-preview.tsx +0 -37
- package/src/client/components/mdx/component-props.tsx +0 -83
- package/src/client/components/mdx/file-tree.tsx +0 -325
- package/src/client/components/mdx/hooks/use-component-preview.ts +0 -16
- package/src/client/components/mdx/hooks/useTable.ts +0 -74
- package/src/client/components/mdx/hooks/useTabs.ts +0 -68
- package/src/client/components/mdx/link.tsx +0 -38
- package/src/client/components/mdx/list.tsx +0 -192
- package/src/client/components/mdx/tabs.tsx +0 -135
- package/src/client/components/mdx/video.tsx +0 -68
- package/src/client/components/primitives/index.ts +0 -19
- package/src/client/components/primitives/navigation-menu.tsx +0 -114
- package/src/client/components/ui-base/head.tsx +0 -83
- package/src/client/components/ui-base/loading.tsx +0 -57
- package/src/client/components/ui-base/powered-by.tsx +0 -25
- package/src/client/hooks/use-onthispage.ts +0 -23
- package/src/client/utils/use-on-change.ts +0 -15
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Info, Lightbulb, AlertTriangle, AlertCircle } from 'lucide-react'
|
|
2
|
+
import { cn } from '../../utils/cn'
|
|
3
|
+
|
|
4
|
+
export type CalloutVariant = 'note' | 'tip' | 'warning' | 'danger' | 'info'
|
|
5
|
+
|
|
6
|
+
export interface CalloutProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
7
|
+
variant?: CalloutVariant
|
|
8
|
+
title?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const variantStyles: Record<
|
|
12
|
+
CalloutVariant,
|
|
13
|
+
{
|
|
14
|
+
container: string
|
|
15
|
+
titleText: string
|
|
16
|
+
iconColor: string
|
|
17
|
+
icon: React.ComponentType<any>
|
|
18
|
+
defaultTitle: string
|
|
19
|
+
}
|
|
20
|
+
> = {
|
|
21
|
+
note: {
|
|
22
|
+
container:
|
|
23
|
+
'bg-slate-500/5 dark:bg-slate-500/10 border-slate-500/40 text-slate-800 dark:text-slate-200',
|
|
24
|
+
titleText: 'text-slate-900 dark:text-slate-100',
|
|
25
|
+
iconColor: 'text-slate-500',
|
|
26
|
+
icon: Info,
|
|
27
|
+
defaultTitle: 'Note',
|
|
28
|
+
},
|
|
29
|
+
info: {
|
|
30
|
+
container:
|
|
31
|
+
'bg-indigo-500/5 dark:bg-indigo-500/10 border-indigo-500/40 text-indigo-800 dark:text-indigo-200',
|
|
32
|
+
titleText: 'text-indigo-900 dark:text-indigo-100',
|
|
33
|
+
iconColor: 'text-indigo-500',
|
|
34
|
+
icon: Info,
|
|
35
|
+
defaultTitle: 'Info',
|
|
36
|
+
},
|
|
37
|
+
tip: {
|
|
38
|
+
container:
|
|
39
|
+
'bg-green-500/5 dark:bg-green-500/10 border-green-500/40 text-green-800 dark:text-green-200',
|
|
40
|
+
titleText: 'text-green-900 dark:text-green-100',
|
|
41
|
+
iconColor: 'text-green-500',
|
|
42
|
+
icon: Lightbulb,
|
|
43
|
+
defaultTitle: 'Tip',
|
|
44
|
+
},
|
|
45
|
+
warning: {
|
|
46
|
+
container:
|
|
47
|
+
'bg-amber-500/5 dark:bg-amber-500/10 border-amber-500/40 text-amber-800 dark:text-amber-200',
|
|
48
|
+
titleText: 'text-amber-900 dark:text-amber-100',
|
|
49
|
+
iconColor: 'text-amber-500',
|
|
50
|
+
icon: AlertTriangle,
|
|
51
|
+
defaultTitle: 'Warning',
|
|
52
|
+
},
|
|
53
|
+
danger: {
|
|
54
|
+
container:
|
|
55
|
+
'bg-rose-500/5 dark:bg-rose-500/10 border-rose-500/40 text-rose-800 dark:text-rose-200',
|
|
56
|
+
titleText: 'text-rose-900 dark:text-rose-100',
|
|
57
|
+
iconColor: 'text-rose-500',
|
|
58
|
+
icon: AlertCircle,
|
|
59
|
+
defaultTitle: 'Danger',
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function Callout({
|
|
64
|
+
children,
|
|
65
|
+
className = '',
|
|
66
|
+
variant = 'note',
|
|
67
|
+
title,
|
|
68
|
+
...props
|
|
69
|
+
}: CalloutProps) {
|
|
70
|
+
const styles = variantStyles[variant] || variantStyles.note
|
|
71
|
+
const Icon = styles.icon
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div
|
|
75
|
+
className={cn(
|
|
76
|
+
'my-6 flex gap-4 p-4 rounded-xl border-2',
|
|
77
|
+
styles.container,
|
|
78
|
+
className,
|
|
79
|
+
)}
|
|
80
|
+
{...props}
|
|
81
|
+
>
|
|
82
|
+
<div className={cn('shrink-0 pt-0.5', styles.iconColor)}>
|
|
83
|
+
<Icon className="w-5 h-5 stroke-[2]" />
|
|
84
|
+
</div>
|
|
85
|
+
<div className="flex-1 text-[0.875rem] leading-[1.6]">
|
|
86
|
+
<div className={cn('font-bold text-sm mb-1', styles.titleText)}>
|
|
87
|
+
{title || styles.defaultTitle}
|
|
88
|
+
</div>
|
|
89
|
+
<div className="prose prose-neutral dark:prose-invert max-w-none [&>p]:m-0 [&>p+p]:mt-2">
|
|
90
|
+
{children}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export default Callout
|
|
@@ -1,124 +1,99 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useCallback, useRef } from 'react'
|
|
3
|
-
import * as RAC from 'react-aria-components'
|
|
1
|
+
import { useState, useRef } from 'react'
|
|
4
2
|
import { cn } from '../../utils/cn'
|
|
5
|
-
import { cva } from 'class-variance-authority'
|
|
6
|
-
import type { VariantProps } from 'class-variance-authority'
|
|
7
|
-
|
|
8
|
-
const cardsVariants = cva('grid gap-4 my-6', {
|
|
9
|
-
variants: {
|
|
10
|
-
cols: {
|
|
11
|
-
1: 'grid-cols-1',
|
|
12
|
-
2: 'grid-cols-1 sm:grid-cols-2',
|
|
13
|
-
3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',
|
|
14
|
-
4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
defaultVariants: {
|
|
18
|
-
cols: 3,
|
|
19
|
-
},
|
|
20
|
-
})
|
|
21
|
-
type CardsVariants = VariantProps<typeof cardsVariants>
|
|
22
|
-
|
|
23
|
-
export interface CardsProps
|
|
24
|
-
extends React.HTMLAttributes<HTMLDivElement>,
|
|
25
|
-
CardsVariants {}
|
|
26
|
-
|
|
27
|
-
export function Cards({
|
|
28
|
-
cols = 3,
|
|
29
|
-
children,
|
|
30
|
-
className = '',
|
|
31
|
-
...rest
|
|
32
|
-
}: CardsProps) {
|
|
33
|
-
return (
|
|
34
|
-
<div className={cn(cardsVariants({ cols }), className)} {...rest}>
|
|
35
|
-
{children}
|
|
36
|
-
</div>
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
3
|
|
|
40
4
|
export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
41
|
-
title?:
|
|
5
|
+
title?: React.ReactNode
|
|
42
6
|
icon?: React.ReactNode
|
|
43
7
|
href?: string
|
|
44
|
-
children?: React.ReactNode
|
|
45
8
|
}
|
|
46
9
|
|
|
47
10
|
export function Card({
|
|
11
|
+
className,
|
|
48
12
|
title,
|
|
49
13
|
icon,
|
|
50
14
|
href,
|
|
51
15
|
children,
|
|
52
|
-
|
|
53
|
-
...rest
|
|
16
|
+
...props
|
|
54
17
|
}: CardProps) {
|
|
18
|
+
const [position, setPosition] = useState({ x: 0, y: 0 })
|
|
19
|
+
const [opacity, setOpacity] = useState(0)
|
|
55
20
|
const cardRef = useRef<HTMLDivElement>(null)
|
|
56
|
-
const linkRef = useRef<HTMLAnchorElement>(null)
|
|
57
21
|
|
|
58
|
-
const handleMouseMove =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
22
|
+
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
23
|
+
if (!cardRef.current) return
|
|
24
|
+
const rect = cardRef.current.getBoundingClientRect()
|
|
25
|
+
setPosition({ x: e.clientX - rect.left, y: e.clientY - rect.top })
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const handleMouseEnter = () => setOpacity(1)
|
|
29
|
+
const handleMouseLeave = () => setOpacity(0)
|
|
65
30
|
|
|
66
|
-
const
|
|
67
|
-
|
|
31
|
+
const Wrapper = href ? 'a' : 'div'
|
|
32
|
+
const spotlightColor = 'var(--color-primary-500, #eb5828)'
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Wrapper
|
|
36
|
+
ref={cardRef}
|
|
37
|
+
href={href}
|
|
38
|
+
onMouseMove={handleMouseMove}
|
|
39
|
+
onMouseEnter={handleMouseEnter}
|
|
40
|
+
onMouseLeave={handleMouseLeave}
|
|
41
|
+
className={cn(
|
|
42
|
+
'group relative flex flex-col gap-3 rounded-2xl border p-6 overflow-hidden transition-all duration-300',
|
|
43
|
+
'hover:shadow-lg dark:hover:shadow-none hover:-translate-y-0.5',
|
|
44
|
+
'bg-surface border-subtle text-paragraph',
|
|
45
|
+
href && 'cursor-pointer',
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
48
|
+
{...(props as any)}
|
|
49
|
+
>
|
|
50
|
+
{/* Background Spotlight */}
|
|
68
51
|
<div
|
|
69
|
-
className="pointer-events-none absolute
|
|
52
|
+
className="pointer-events-none absolute inset-0 transition-opacity duration-300"
|
|
70
53
|
style={{
|
|
71
|
-
|
|
72
|
-
|
|
54
|
+
opacity,
|
|
55
|
+
background: `radial-gradient(600px circle at ${position.x}px ${position.y}px, color-mix(in srgb, ${spotlightColor} 8%, transparent), transparent 40%)`,
|
|
73
56
|
}}
|
|
74
57
|
/>
|
|
75
|
-
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
58
|
+
{/* Border Spotlight Glow */}
|
|
59
|
+
<div
|
|
60
|
+
className="pointer-events-none absolute inset-0 rounded-2xl transition-opacity duration-300"
|
|
61
|
+
style={{
|
|
62
|
+
opacity,
|
|
63
|
+
padding: '1px',
|
|
64
|
+
background: `radial-gradient(400px circle at ${position.x}px ${position.y}px, color-mix(in srgb, ${spotlightColor} 50%, transparent), transparent 40%)`,
|
|
65
|
+
WebkitMask:
|
|
66
|
+
'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
|
|
67
|
+
WebkitMaskComposite: 'xor',
|
|
68
|
+
maskComposite: 'exclude',
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
|
|
72
|
+
{/* Header Content */}
|
|
73
|
+
<div className="relative z-10 flex items-center gap-3">
|
|
74
|
+
{icon && (
|
|
75
|
+
<div
|
|
76
|
+
className={cn(
|
|
77
|
+
'shrink-0 transition-transform duration-500 group-hover:rotate-[15deg] group-hover:scale-110 flex items-center justify-center text-muted group-hover:text-primary-500',
|
|
78
|
+
'[&>svg]:w-6 [&>svg]:h-6 [&>svg]:stroke-[1.5]',
|
|
79
|
+
)}
|
|
80
|
+
>
|
|
81
|
+
{icon}
|
|
85
82
|
</div>
|
|
86
83
|
)}
|
|
84
|
+
{title && (
|
|
85
|
+
<h3 className="font-semibold text-base m-0 leading-none text-body">
|
|
86
|
+
{title}
|
|
87
|
+
</h3>
|
|
88
|
+
)}
|
|
87
89
|
</div>
|
|
88
|
-
</>
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
const cardClasses = cn(
|
|
92
|
-
'group relative block rounded-xl border border-border-subtle bg-bg-surface p-5 outline-none overflow-hidden',
|
|
93
|
-
'transition-all duration-200 hover:border-primary-500/40 hover:shadow-lg hover:shadow-primary-500/5',
|
|
94
|
-
'focus-visible:ring-2 focus-visible:ring-primary-500/30',
|
|
95
|
-
className,
|
|
96
|
-
)
|
|
97
90
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
className={cn(cardClasses, 'no-underline cursor-pointer')}
|
|
104
|
-
onMouseMove={handleMouseMove}
|
|
105
|
-
{...(rest as any)}
|
|
106
|
-
>
|
|
107
|
-
{inner}
|
|
108
|
-
</RAC.Link>
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
// biome-ignore lint/a11y/noStaticElementInteractions: spotlight effect is decorative
|
|
114
|
-
<div
|
|
115
|
-
ref={cardRef}
|
|
116
|
-
role="presentation"
|
|
117
|
-
className={cardClasses}
|
|
118
|
-
onMouseMove={handleMouseMove}
|
|
119
|
-
{...rest}
|
|
120
|
-
>
|
|
121
|
-
{inner}
|
|
122
|
-
</div>
|
|
91
|
+
{/* Body Content */}
|
|
92
|
+
<div className="relative z-10 text-[0.875rem] leading-[1.6] opacity-90 prose prose-neutral dark:prose-invert max-w-none [&>p]:m-0 [&>p+p]:mt-2">
|
|
93
|
+
{children}
|
|
94
|
+
</div>
|
|
95
|
+
</Wrapper>
|
|
123
96
|
)
|
|
124
97
|
}
|
|
98
|
+
|
|
99
|
+
export default Card
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { cn } from '../../utils/cn'
|
|
2
|
+
|
|
3
|
+
export interface CardsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
cols?: 1 | 2 | 3 | 4
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function Cards({ children, className, cols = 2, ...props }: CardsProps) {
|
|
8
|
+
return (
|
|
9
|
+
<div
|
|
10
|
+
className={cn(
|
|
11
|
+
'grid gap-4 my-6',
|
|
12
|
+
{
|
|
13
|
+
'grid-cols-1': cols === 1,
|
|
14
|
+
'grid-cols-1 sm:grid-cols-2': cols === 2,
|
|
15
|
+
'grid-cols-1 sm:grid-cols-2 md:grid-cols-3': cols === 3,
|
|
16
|
+
'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4': cols === 4,
|
|
17
|
+
},
|
|
18
|
+
className,
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</div>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default Cards
|
|
@@ -2,7 +2,7 @@ import { Button } from 'react-aria-components'
|
|
|
2
2
|
import { Copy, Check, File } from 'lucide-react'
|
|
3
3
|
import { cn } from '../../utils/cn'
|
|
4
4
|
import { reactToText } from '../../utils/react-to-text'
|
|
5
|
-
import { useCodeBlock } from './
|
|
5
|
+
import { useCodeBlock } from './use-code-block'
|
|
6
6
|
import * as CodePrimitive from '../primitives/code-block'
|
|
7
7
|
import {
|
|
8
8
|
TypeScript,
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
Yaml,
|
|
17
17
|
Rust,
|
|
18
18
|
BracketsRed,
|
|
19
|
+
Csv,
|
|
19
20
|
} from '../icons-dev'
|
|
20
21
|
import { Tooltip } from '../primitives/tooltip'
|
|
21
22
|
|
|
@@ -35,7 +36,8 @@ const langIconMap: Record<string, React.ComponentType<{ size?: number }>> = {
|
|
|
35
36
|
yml: Yaml,
|
|
36
37
|
rs: Rust,
|
|
37
38
|
rust: Rust,
|
|
38
|
-
toml: BracketsRed
|
|
39
|
+
toml: BracketsRed,
|
|
40
|
+
csv: Csv,
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
export interface CodeBlockProps {
|
|
@@ -51,17 +53,21 @@ export interface CodeBlockProps {
|
|
|
51
53
|
[key: string]: any
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
const CopyButton = ({
|
|
56
|
+
const CopyButton = ({
|
|
57
|
+
copied,
|
|
58
|
+
handleCopy,
|
|
59
|
+
}: {
|
|
60
|
+
copied: boolean
|
|
61
|
+
handleCopy: () => void
|
|
62
|
+
}) => {
|
|
55
63
|
return (
|
|
56
64
|
<Tooltip content={copied ? 'Copied!' : 'Copy code'}>
|
|
57
65
|
{/* @ts-ignore */}
|
|
58
66
|
<Button
|
|
59
67
|
onPress={handleCopy}
|
|
60
68
|
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',
|
|
69
|
+
'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 z-10',
|
|
70
|
+
copied ? 'text-emerald-400' : 'text-muted hover:text-body',
|
|
65
71
|
)}
|
|
66
72
|
aria-label="Copy code"
|
|
67
73
|
>
|
|
@@ -85,7 +91,14 @@ export function CodeBlock(props: CodeBlockProps) {
|
|
|
85
91
|
...rest
|
|
86
92
|
} = props
|
|
87
93
|
|
|
88
|
-
const
|
|
94
|
+
const rawHighlightedHtml = highlightedHtml || dataHighlightedHtml
|
|
95
|
+
const effectiveHighlightedHtml =
|
|
96
|
+
typeof rawHighlightedHtml === 'string'
|
|
97
|
+
? rawHighlightedHtml.replace(
|
|
98
|
+
/<span class="line">\s*(?:<span[^>]*>\s*<\/span>)?\s*<\/span>\s*(<\/code>\s*<\/pre>)/g,
|
|
99
|
+
'$1',
|
|
100
|
+
)
|
|
101
|
+
: rawHighlightedHtml
|
|
89
102
|
const effectiveTitle = title || dataTitle
|
|
90
103
|
const lang = props.lang || dataLang || ''
|
|
91
104
|
|
|
@@ -104,39 +117,46 @@ export function CodeBlock(props: CodeBlockProps) {
|
|
|
104
117
|
return (
|
|
105
118
|
<CodePrimitive.CodeBlock plain={plain} className={props.className}>
|
|
106
119
|
{(effectiveTitle || !hideCopy) && (
|
|
107
|
-
<CodePrimitive.CodeBlockHeader
|
|
120
|
+
<CodePrimitive.CodeBlockHeader
|
|
121
|
+
className={cn({
|
|
122
|
+
'absolute top-2 left-0 w-full': !effectiveTitle,
|
|
123
|
+
})}
|
|
124
|
+
>
|
|
108
125
|
<CodePrimitive.CodeBlockGroup>
|
|
109
126
|
{effectiveTitle && (
|
|
110
127
|
<>
|
|
111
128
|
{LangIcon ? (
|
|
112
129
|
<LangIcon size={14} />
|
|
113
130
|
) : (
|
|
114
|
-
// @ts-ignore
|
|
115
131
|
<File size={14} className="opacity-60" />
|
|
116
132
|
)}
|
|
117
133
|
<span>{effectiveTitle}</span>
|
|
118
134
|
</>
|
|
119
135
|
)}
|
|
120
136
|
</CodePrimitive.CodeBlockGroup>
|
|
121
|
-
|
|
137
|
+
<div className="flex items-center gap-1">
|
|
138
|
+
{!hideCopy && (
|
|
139
|
+
<CopyButton copied={copied} handleCopy={handleCopy} />
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
122
142
|
</CodePrimitive.CodeBlockHeader>
|
|
123
143
|
)}
|
|
124
144
|
|
|
125
145
|
<CodePrimitive.CodeBlockContent shouldTruncate={shouldTruncate}>
|
|
126
146
|
{effectiveHighlightedHtml ? (
|
|
127
147
|
<div
|
|
128
|
-
// @ts-
|
|
148
|
+
// @ts-expect-error
|
|
129
149
|
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!"
|
|
150
|
+
className="shiki-wrapper overflow-x-auto [&>pre]:m-0! [&>pre]:rounded-none! [&>pre]:border-none! [&>pre]:bg-inherit! [&>pre>code]:grid! [&>pre>code]:p-5! [&>pre>code]:text-[0.875rem]! [&>pre>code]:leading-[1.6]! [&>.shiki.shiki-themes]:bg-transparent!"
|
|
131
151
|
dangerouslySetInnerHTML={{ __html: effectiveHighlightedHtml }}
|
|
132
152
|
/>
|
|
133
153
|
) : (
|
|
134
154
|
<pre
|
|
135
155
|
ref={preRef}
|
|
136
|
-
className="m-0! p-5! rounded-none! border-none! bg-inherit! font-mono text-[0.
|
|
156
|
+
className="m-0! p-5! rounded-none! border-none! bg-inherit! font-mono text-[0.875rem] leading-[1.6] overflow-x-auto"
|
|
137
157
|
{...rest}
|
|
138
158
|
>
|
|
139
|
-
{reactToText(children)}
|
|
159
|
+
{reactToText(children).trimEnd()}
|
|
140
160
|
</pre>
|
|
141
161
|
)}
|
|
142
162
|
|
|
@@ -146,13 +166,13 @@ export function CodeBlock(props: CodeBlockProps) {
|
|
|
146
166
|
className={cn(
|
|
147
167
|
shouldTruncate
|
|
148
168
|
? '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
|
|
169
|
+
: 'relative flex justify-center pb-4 pt-1 -mt-4',
|
|
150
170
|
)}
|
|
151
171
|
>
|
|
152
172
|
{/* @ts-ignore */}
|
|
153
173
|
<Button
|
|
154
174
|
onPress={() => setIsExpanded(!isExpanded)}
|
|
155
|
-
className="rounded-full bg-
|
|
175
|
+
className="rounded-full bg-surface border border-subtle px-5 py-2 text-[0.8125rem] font-medium text-body outline-none cursor-pointer transition-all hover:bg-soft hover:-translate-y-px backdrop-blur-md"
|
|
156
176
|
>
|
|
157
177
|
{isExpanded ? 'Show less' : 'Expand code'}
|
|
158
178
|
</Button>
|
|
@@ -1,65 +1,33 @@
|
|
|
1
|
-
import { cn } from '../../utils/cn'
|
|
2
|
-
|
|
3
1
|
export interface FieldProps {
|
|
2
|
+
children?: React.ReactNode
|
|
4
3
|
name: string
|
|
5
4
|
type?: string
|
|
6
|
-
|
|
5
|
+
description?: string
|
|
7
6
|
required?: boolean
|
|
8
|
-
children: React.ReactNode
|
|
9
|
-
id?: string
|
|
10
|
-
className?: string
|
|
11
7
|
}
|
|
12
8
|
|
|
13
|
-
export
|
|
9
|
+
export const Field = ({
|
|
10
|
+
children,
|
|
14
11
|
name,
|
|
15
12
|
type,
|
|
16
|
-
|
|
17
|
-
required
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
className,
|
|
13
|
+
description,
|
|
14
|
+
required,
|
|
15
|
+
}: FieldProps) => (
|
|
16
|
+
<div className="my-4 border border-subtle bg-surface/50 p-4 rounded-xl flex flex-col gap-1 text-sm select-none">
|
|
17
|
+
<div className="flex items-center gap-2">
|
|
18
|
+
<span className="font-mono font-bold text-primary-500">{name}</span>
|
|
19
|
+
{type && (
|
|
20
|
+
<span className="text-xs text-muted font-mono bg-soft px-1.5 py-0.5 rounded-md">
|
|
21
|
+
{type}
|
|
22
|
+
</span>
|
|
27
23
|
)}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</span>
|
|
39
|
-
)}
|
|
40
|
-
{required && (
|
|
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">
|
|
42
|
-
<span className="h-1 w-1 rounded-full bg-red-400 animate-pulse" />
|
|
43
|
-
Required
|
|
44
|
-
</div>
|
|
45
|
-
)}
|
|
46
|
-
</div>
|
|
47
|
-
|
|
48
|
-
{defaultValue && (
|
|
49
|
-
<div className="flex items-center gap-2 text-[11px] text-text-muted bg-bg-muted/30 px-2.5 py-1 rounded-md border border-border-subtle/50">
|
|
50
|
-
<span className="font-semibold opacity-60 uppercase tracking-tighter">
|
|
51
|
-
Default
|
|
52
|
-
</span>
|
|
53
|
-
<code className="font-mono text-text-main font-medium">
|
|
54
|
-
{defaultValue}
|
|
55
|
-
</code>
|
|
56
|
-
</div>
|
|
57
|
-
)}
|
|
58
|
-
</div>
|
|
59
|
-
|
|
60
|
-
<div className="text-sm text-text-muted leading-relaxed [&>p]:m-0 selection:bg-primary-500/30">
|
|
61
|
-
{children}
|
|
62
|
-
</div>
|
|
63
|
-
</article>
|
|
64
|
-
)
|
|
65
|
-
}
|
|
24
|
+
{required && (
|
|
25
|
+
<span className="text-xs text-rose-500 font-semibold">required</span>
|
|
26
|
+
)}
|
|
27
|
+
</div>
|
|
28
|
+
{description && (
|
|
29
|
+
<div className="text-muted text-xs mt-1">{description}</div>
|
|
30
|
+
)}
|
|
31
|
+
{children && <div className="mt-2">{children}</div>}
|
|
32
|
+
</div>
|
|
33
|
+
)
|
|
@@ -1,23 +1,44 @@
|
|
|
1
|
-
import type { ImgHTMLAttributes } from 'react'
|
|
2
1
|
import { useTheme } from '../../app/theme-context'
|
|
2
|
+
import { cn } from '../../utils/cn'
|
|
3
|
+
import { Image as ImagePrimitive } from '../primitives/image'
|
|
3
4
|
|
|
4
|
-
export interface ImageProps extends ImgHTMLAttributes<HTMLImageElement> {
|
|
5
|
-
src: string
|
|
6
|
-
darkSrc?: string
|
|
5
|
+
export interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
|
|
7
6
|
theme?: 'light' | 'dark'
|
|
8
7
|
}
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export function Image({ src, alt, theme: imageTheme, ...props }: ImageProps) {
|
|
15
|
-
const { theme: currentTheme } = useTheme()
|
|
9
|
+
const Image = ({ src, alt, title, theme, className, ...props }: ImageProps) => {
|
|
10
|
+
const { theme: themeContext } = useTheme()
|
|
11
|
+
if (!src) return null
|
|
12
|
+
if (theme !== themeContext) return null
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
if (imageTheme && imageTheme !== currentTheme) {
|
|
19
|
-
return null
|
|
20
|
-
}
|
|
14
|
+
const caption = title || alt
|
|
21
15
|
|
|
22
|
-
return
|
|
16
|
+
return (
|
|
17
|
+
<figure className="my-6 sm:my-8 flex flex-col items-center justify-center group not-prose">
|
|
18
|
+
<div className="relative w-full overflow-hidden rounded-lg sm:rounded-2xl border border-subtle bg-soft/30 transition-all duration-300 sm:max-w-[85%] lg:max-w-full">
|
|
19
|
+
<ImagePrimitive
|
|
20
|
+
src={src}
|
|
21
|
+
alt={alt || ''}
|
|
22
|
+
theme={theme}
|
|
23
|
+
loading="lazy"
|
|
24
|
+
decoding="async"
|
|
25
|
+
className={cn(
|
|
26
|
+
'w-full h-auto object-contain transition-transform duration-500 group-hover:scale-[1.01] my-0 rounded-md sm:rounded-xl block',
|
|
27
|
+
className,
|
|
28
|
+
)}
|
|
29
|
+
{...props}
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
32
|
+
{caption && (
|
|
33
|
+
<figcaption className="mt-2 sm:mt-3 text-center text-xs sm:text-sm text-muted font-medium select-none tracking-wide opacity-90 sm:opacity-80 group-hover:opacity-100 transition-opacity duration-300 px-2">
|
|
34
|
+
{caption}
|
|
35
|
+
</figcaption>
|
|
36
|
+
)}
|
|
37
|
+
</figure>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const ImageComponents = {
|
|
42
|
+
img: Image,
|
|
43
|
+
Image,
|
|
23
44
|
}
|