boltdocs 1.10.2 → 1.11.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/package.json +29 -7
- package/src/client/app/config-context.tsx +18 -0
- package/src/client/app/docs-layout.tsx +14 -0
- package/src/client/app/index.tsx +132 -260
- package/src/client/app/mdx-component.tsx +52 -0
- package/src/client/app/mdx-components-context.tsx +23 -0
- package/src/client/app/mdx-page.tsx +20 -0
- package/src/client/app/preload.tsx +38 -30
- package/src/client/app/router.tsx +30 -0
- package/src/client/app/scroll-handler.tsx +40 -0
- package/src/client/app/theme-context.tsx +75 -0
- package/src/client/components/default-layout.tsx +80 -0
- package/src/client/components/docs-layout.tsx +105 -0
- package/src/client/components/icons-dev.tsx +74 -0
- package/src/client/components/mdx/admonition.tsx +107 -0
- package/src/client/components/mdx/badge.tsx +41 -0
- package/src/client/components/mdx/button.tsx +35 -0
- package/src/client/components/mdx/card.tsx +124 -0
- package/src/client/components/mdx/code-block.tsx +119 -0
- package/src/client/components/mdx/component-preview.tsx +47 -0
- package/src/client/components/mdx/component-props.tsx +83 -0
- package/src/client/components/mdx/field.tsx +66 -0
- package/src/client/components/mdx/file-tree.tsx +287 -0
- package/src/client/components/mdx/hooks/use-code-block.ts +56 -0
- package/src/client/components/mdx/hooks/use-component-preview.ts +16 -0
- package/src/client/components/mdx/hooks/useTable.ts +74 -0
- package/src/client/components/mdx/hooks/useTabs.ts +68 -0
- package/src/client/components/mdx/image.tsx +23 -0
- package/src/client/components/mdx/index.ts +53 -0
- package/src/client/components/mdx/link.tsx +38 -0
- package/src/client/components/mdx/list.tsx +192 -0
- package/src/client/components/mdx/table.tsx +156 -0
- package/src/client/components/mdx/tabs.tsx +135 -0
- package/src/client/components/mdx/video.tsx +68 -0
- package/src/client/components/primitives/breadcrumbs.tsx +79 -0
- package/src/client/components/primitives/button-group.tsx +54 -0
- package/src/client/components/primitives/button.tsx +145 -0
- package/src/client/components/primitives/helpers/observer.ts +120 -0
- package/src/client/components/primitives/index.ts +17 -0
- package/src/client/components/primitives/link.tsx +122 -0
- package/src/client/components/primitives/menu.tsx +159 -0
- package/src/client/components/primitives/navbar.tsx +359 -0
- package/src/client/components/primitives/navigation-menu.tsx +116 -0
- package/src/client/components/primitives/on-this-page.tsx +461 -0
- package/src/client/components/primitives/page-nav.tsx +87 -0
- package/src/client/components/primitives/popover.tsx +47 -0
- package/src/client/components/primitives/search-dialog.tsx +183 -0
- package/src/client/components/primitives/sidebar.tsx +154 -0
- package/src/client/components/primitives/tabs.tsx +90 -0
- package/src/client/components/primitives/tooltip.tsx +83 -0
- package/src/client/components/primitives/types.ts +11 -0
- package/src/client/components/ui-base/breadcrumbs.tsx +42 -0
- package/src/client/components/ui-base/copy-markdown.tsx +112 -0
- package/src/client/components/ui-base/error-boundary.tsx +52 -0
- package/src/client/components/ui-base/github-stars.tsx +27 -0
- package/src/client/components/ui-base/head.tsx +69 -0
- package/src/client/components/ui-base/loading.tsx +87 -0
- package/src/client/components/ui-base/navbar.tsx +138 -0
- package/src/client/components/ui-base/not-found.tsx +24 -0
- package/src/client/components/ui-base/on-this-page.tsx +152 -0
- package/src/client/components/ui-base/page-nav.tsx +39 -0
- package/src/client/components/ui-base/powered-by.tsx +19 -0
- package/src/client/components/ui-base/progress-bar.tsx +67 -0
- package/src/client/components/ui-base/search-dialog.tsx +82 -0
- package/src/client/components/ui-base/sidebar.tsx +104 -0
- package/src/client/components/ui-base/tabs.tsx +65 -0
- package/src/client/components/ui-base/theme-toggle.tsx +32 -0
- package/src/client/hooks/index.ts +12 -0
- package/src/client/hooks/use-breadcrumbs.ts +22 -0
- package/src/client/hooks/use-i18n.ts +84 -0
- package/src/client/hooks/use-localized-to.ts +95 -0
- package/src/client/hooks/use-location.ts +5 -0
- package/src/client/hooks/use-navbar.ts +60 -0
- package/src/client/hooks/use-onthispage.ts +23 -0
- package/src/client/hooks/use-page-nav.ts +22 -0
- package/src/client/hooks/use-routes.ts +72 -0
- package/src/client/hooks/use-search.ts +71 -0
- package/src/client/hooks/use-sidebar.ts +49 -0
- package/src/client/hooks/use-tabs.ts +43 -0
- package/src/client/hooks/use-version.ts +78 -0
- package/src/client/index.ts +55 -17
- package/src/client/integrations/codesandbox.ts +179 -0
- package/src/client/ssr.tsx +27 -16
- package/src/client/theme/neutral.css +360 -0
- package/src/client/types.ts +131 -27
- package/src/client/utils/cn.ts +6 -0
- package/src/client/utils/copy-clipboard.ts +22 -0
- package/src/client/utils/get-base-file-path.ts +21 -0
- package/src/client/utils/github.ts +121 -0
- package/src/client/utils/use-on-change.ts +15 -0
- package/src/client/virtual.d.ts +24 -0
- package/src/node/cache.ts +156 -156
- package/src/node/config.ts +159 -103
- package/src/node/index.ts +13 -13
- package/src/node/mdx.ts +213 -61
- package/src/node/plugin/entry.ts +29 -18
- package/src/node/plugin/html.ts +11 -11
- package/src/node/plugin/index.ts +161 -83
- package/src/node/plugin/types.ts +2 -4
- package/src/node/routes/cache.ts +6 -6
- package/src/node/routes/index.ts +206 -113
- package/src/node/routes/parser.ts +106 -81
- package/src/node/routes/sorter.ts +15 -15
- package/src/node/routes/types.ts +24 -24
- package/src/node/ssg/index.ts +46 -46
- package/src/node/ssg/meta.ts +4 -4
- package/src/node/ssg/options.ts +5 -5
- package/src/node/ssg/sitemap.ts +14 -14
- package/src/node/utils.ts +31 -31
- package/tsconfig.json +25 -20
- package/tsup.config.ts +23 -14
- package/dist/PackageManagerTabs-NVT7G625.mjs +0 -99
- package/dist/SearchDialog-AGVF6JBO.mjs +0 -194
- package/dist/SearchDialog-YPDOM7Q6.css +0 -2847
- package/dist/Video-KNTY5BNO.mjs +0 -6
- package/dist/cache-KNL5B4EE.mjs +0 -12
- package/dist/chunk-7SFUJWTB.mjs +0 -211
- package/dist/chunk-FFBNU6IJ.mjs +0 -386
- package/dist/chunk-FMTOYQLO.mjs +0 -37
- package/dist/chunk-TKLQWU7H.mjs +0 -1920
- package/dist/chunk-Z7JHYNAS.mjs +0 -57
- package/dist/client/index.css +0 -2847
- package/dist/client/index.d.mts +0 -372
- package/dist/client/index.d.ts +0 -372
- package/dist/client/index.js +0 -3630
- package/dist/client/index.mjs +0 -697
- package/dist/client/ssr.css +0 -2847
- package/dist/client/ssr.d.mts +0 -27
- package/dist/client/ssr.d.ts +0 -27
- package/dist/client/ssr.js +0 -2928
- package/dist/client/ssr.mjs +0 -33
- package/dist/config-BsFQ-ErD.d.mts +0 -159
- package/dist/config-BsFQ-ErD.d.ts +0 -159
- package/dist/node/index.d.mts +0 -91
- package/dist/node/index.d.ts +0 -91
- package/dist/node/index.js +0 -1187
- package/dist/node/index.mjs +0 -762
- package/dist/types-Dj-bfnC3.d.mts +0 -74
- package/dist/types-Dj-bfnC3.d.ts +0 -74
- package/src/client/theme/components/CodeBlock/CodeBlock.tsx +0 -61
- package/src/client/theme/components/CodeBlock/index.ts +0 -1
- package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +0 -131
- package/src/client/theme/components/PackageManagerTabs/index.ts +0 -1
- package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +0 -64
- package/src/client/theme/components/Playground/Playground.tsx +0 -180
- package/src/client/theme/components/Playground/index.ts +0 -1
- package/src/client/theme/components/Playground/playground.css +0 -238
- package/src/client/theme/components/Video/Video.tsx +0 -84
- package/src/client/theme/components/Video/index.ts +0 -1
- package/src/client/theme/components/Video/video.css +0 -41
- package/src/client/theme/components/mdx/Admonition.tsx +0 -80
- package/src/client/theme/components/mdx/Badge.tsx +0 -31
- package/src/client/theme/components/mdx/Button.tsx +0 -50
- package/src/client/theme/components/mdx/Card.tsx +0 -80
- package/src/client/theme/components/mdx/Field.tsx +0 -60
- package/src/client/theme/components/mdx/FileTree.tsx +0 -229
- package/src/client/theme/components/mdx/List.tsx +0 -57
- package/src/client/theme/components/mdx/Table.tsx +0 -151
- package/src/client/theme/components/mdx/Tabs.tsx +0 -123
- package/src/client/theme/components/mdx/index.ts +0 -27
- package/src/client/theme/components/mdx/mdx-components.css +0 -764
- package/src/client/theme/icons/bun.tsx +0 -62
- package/src/client/theme/icons/deno.tsx +0 -20
- package/src/client/theme/icons/discord.tsx +0 -12
- package/src/client/theme/icons/github.tsx +0 -15
- package/src/client/theme/icons/npm.tsx +0 -13
- package/src/client/theme/icons/pnpm.tsx +0 -72
- package/src/client/theme/icons/twitter.tsx +0 -12
- package/src/client/theme/styles/markdown.css +0 -394
- package/src/client/theme/styles/variables.css +0 -175
- package/src/client/theme/styles.css +0 -39
- package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +0 -68
- package/src/client/theme/ui/Breadcrumbs/index.ts +0 -1
- package/src/client/theme/ui/CopyMarkdown/CopyMarkdown.tsx +0 -82
- package/src/client/theme/ui/CopyMarkdown/copy-markdown.css +0 -112
- package/src/client/theme/ui/CopyMarkdown/index.ts +0 -1
- package/src/client/theme/ui/ErrorBoundary/ErrorBoundary.tsx +0 -50
- package/src/client/theme/ui/ErrorBoundary/error-boundary.css +0 -55
- package/src/client/theme/ui/ErrorBoundary/index.ts +0 -1
- package/src/client/theme/ui/Footer/footer.css +0 -32
- package/src/client/theme/ui/Head/Head.tsx +0 -69
- package/src/client/theme/ui/Head/index.ts +0 -1
- package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +0 -125
- package/src/client/theme/ui/LanguageSwitcher/index.ts +0 -1
- package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +0 -98
- package/src/client/theme/ui/Layout/Layout.tsx +0 -203
- package/src/client/theme/ui/Layout/base.css +0 -106
- package/src/client/theme/ui/Layout/index.ts +0 -2
- package/src/client/theme/ui/Layout/pagination.css +0 -72
- package/src/client/theme/ui/Layout/responsive.css +0 -47
- package/src/client/theme/ui/Link/Link.tsx +0 -392
- package/src/client/theme/ui/Link/LinkPreview.tsx +0 -59
- package/src/client/theme/ui/Link/index.ts +0 -2
- package/src/client/theme/ui/Link/link-preview.css +0 -48
- package/src/client/theme/ui/Loading/Loading.tsx +0 -10
- package/src/client/theme/ui/Loading/index.ts +0 -1
- package/src/client/theme/ui/Loading/loading.css +0 -30
- package/src/client/theme/ui/Navbar/GithubStars.tsx +0 -27
- package/src/client/theme/ui/Navbar/Navbar.tsx +0 -193
- package/src/client/theme/ui/Navbar/Tabs.tsx +0 -99
- package/src/client/theme/ui/Navbar/index.ts +0 -2
- package/src/client/theme/ui/Navbar/navbar.css +0 -347
- package/src/client/theme/ui/NotFound/NotFound.tsx +0 -19
- package/src/client/theme/ui/NotFound/index.ts +0 -1
- package/src/client/theme/ui/NotFound/not-found.css +0 -64
- package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +0 -244
- package/src/client/theme/ui/OnThisPage/index.ts +0 -1
- package/src/client/theme/ui/OnThisPage/toc.css +0 -152
- package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +0 -18
- package/src/client/theme/ui/PoweredBy/index.ts +0 -1
- package/src/client/theme/ui/PoweredBy/powered-by.css +0 -76
- package/src/client/theme/ui/ProgressBar/ProgressBar.css +0 -17
- package/src/client/theme/ui/ProgressBar/ProgressBar.tsx +0 -51
- package/src/client/theme/ui/ProgressBar/index.ts +0 -1
- package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +0 -209
- package/src/client/theme/ui/SearchDialog/index.ts +0 -1
- package/src/client/theme/ui/SearchDialog/search.css +0 -152
- package/src/client/theme/ui/Sidebar/Sidebar.tsx +0 -244
- package/src/client/theme/ui/Sidebar/index.ts +0 -1
- package/src/client/theme/ui/Sidebar/sidebar.css +0 -230
- package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +0 -69
- package/src/client/theme/ui/ThemeToggle/index.ts +0 -1
- package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +0 -136
- package/src/client/theme/ui/VersionSwitcher/index.ts +0 -1
- package/src/client/utils.ts +0 -49
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { MouseEvent as ReactMouseEvent } from 'react'
|
|
2
|
+
import { useCallback, useRef } from 'react'
|
|
3
|
+
import * as RAC from 'react-aria-components'
|
|
4
|
+
import { cn } from '@client/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
|
+
|
|
40
|
+
export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
41
|
+
title?: string
|
|
42
|
+
icon?: React.ReactNode
|
|
43
|
+
href?: string
|
|
44
|
+
children?: React.ReactNode
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function Card({
|
|
48
|
+
title,
|
|
49
|
+
icon,
|
|
50
|
+
href,
|
|
51
|
+
children,
|
|
52
|
+
className = '',
|
|
53
|
+
...rest
|
|
54
|
+
}: CardProps) {
|
|
55
|
+
const cardRef = useRef<HTMLDivElement>(null)
|
|
56
|
+
const linkRef = useRef<HTMLAnchorElement>(null)
|
|
57
|
+
|
|
58
|
+
const handleMouseMove = useCallback((e: ReactMouseEvent<HTMLDivElement>) => {
|
|
59
|
+
const el = cardRef.current || linkRef.current
|
|
60
|
+
if (!el) return
|
|
61
|
+
const { left, top } = el.getBoundingClientRect()
|
|
62
|
+
el.style.setProperty('--x', `${e.clientX - left}px`)
|
|
63
|
+
el.style.setProperty('--y', `${e.clientY - top}px`)
|
|
64
|
+
}, [])
|
|
65
|
+
|
|
66
|
+
const inner = (
|
|
67
|
+
<>
|
|
68
|
+
<div
|
|
69
|
+
className="pointer-events-none absolute -inset-px rounded-xl opacity-0 transition-opacity duration-300 group-hover:opacity-100"
|
|
70
|
+
style={{
|
|
71
|
+
background:
|
|
72
|
+
'radial-gradient(400px circle at var(--x) var(--y), color-mix(in oklch, var(--color-primary-500), transparent 90%), transparent 80%)',
|
|
73
|
+
}}
|
|
74
|
+
/>
|
|
75
|
+
{icon && (
|
|
76
|
+
<div className="mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-primary-500/10 text-primary-400 text-lg transition-transform duration-300 group-hover:scale-105 group-hover:-rotate-3">
|
|
77
|
+
{icon}
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
80
|
+
<div className="space-y-1.5">
|
|
81
|
+
{title && <h3 className="text-sm font-bold text-text-main">{title}</h3>}
|
|
82
|
+
{children && (
|
|
83
|
+
<div className="text-sm text-text-muted leading-relaxed">
|
|
84
|
+
{children}
|
|
85
|
+
</div>
|
|
86
|
+
)}
|
|
87
|
+
</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
|
+
|
|
98
|
+
if (href) {
|
|
99
|
+
return (
|
|
100
|
+
<RAC.Link
|
|
101
|
+
ref={linkRef}
|
|
102
|
+
href={href}
|
|
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>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as RAC from 'react-aria-components'
|
|
2
|
+
import { Copy, Check } from 'lucide-react'
|
|
3
|
+
import { cn } from '@client/utils/cn'
|
|
4
|
+
import { useCodeBlock } from './hooks/use-code-block'
|
|
5
|
+
import { useConfig } from '@client/app/config-context'
|
|
6
|
+
import { CodeSandbox } from '@components/icons-dev'
|
|
7
|
+
import { Tooltip } from '@components/primitives/tooltip'
|
|
8
|
+
|
|
9
|
+
export interface CodeBlockProps {
|
|
10
|
+
children?: React.ReactNode
|
|
11
|
+
className?: string
|
|
12
|
+
sandbox?: boolean | any
|
|
13
|
+
hideCopy?: boolean
|
|
14
|
+
hideSandbox?: boolean
|
|
15
|
+
title?: string
|
|
16
|
+
lang?: string
|
|
17
|
+
highlightedHtml?: string
|
|
18
|
+
[key: string]: any
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function CodeBlock(props: CodeBlockProps) {
|
|
22
|
+
const {
|
|
23
|
+
children,
|
|
24
|
+
sandbox: localSandbox,
|
|
25
|
+
hideSandbox = true,
|
|
26
|
+
hideCopy = false,
|
|
27
|
+
highlightedHtml,
|
|
28
|
+
...rest
|
|
29
|
+
} = props
|
|
30
|
+
const config = useConfig()
|
|
31
|
+
const globalSandbox = config?.integrations?.sandbox
|
|
32
|
+
const isSandboxEnabled = !!globalSandbox?.enable && !hideSandbox
|
|
33
|
+
const {
|
|
34
|
+
copied,
|
|
35
|
+
isExpanded,
|
|
36
|
+
setIsExpanded,
|
|
37
|
+
isExpandable,
|
|
38
|
+
preRef,
|
|
39
|
+
handleCopy,
|
|
40
|
+
handleSandbox,
|
|
41
|
+
shouldTruncate,
|
|
42
|
+
} = useCodeBlock(props)
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div
|
|
46
|
+
className={cn(
|
|
47
|
+
'group relative my-6 overflow-hidden rounded-lg border border-border-subtle bg-(--color-code-bg)',
|
|
48
|
+
shouldTruncate && '[&>pre]:max-h-[250px] [&>pre]:overflow-hidden',
|
|
49
|
+
)}
|
|
50
|
+
>
|
|
51
|
+
{/* Toolbar */}
|
|
52
|
+
<div className="absolute top-3 right-4 z-50 flex items-center gap-2 transition-all duration-300 opacity-0 group-hover:opacity-100">
|
|
53
|
+
{isSandboxEnabled && (
|
|
54
|
+
<Tooltip content="Open in CodeSandbox">
|
|
55
|
+
<RAC.Button
|
|
56
|
+
onPress={handleSandbox}
|
|
57
|
+
className="grid place-items-center w-8 h-8 bg-transparent text-text-muted outline-none cursor-pointer transition-all duration-200 hover:scale-115 hover:text-sky-400 active:scale-95 [&>svg]:w-5 [&>svg]:h-5 [&>svg]:stroke-2"
|
|
58
|
+
aria-label="Open in CodeSandbox"
|
|
59
|
+
>
|
|
60
|
+
<CodeSandbox size={20} />
|
|
61
|
+
</RAC.Button>
|
|
62
|
+
</Tooltip>
|
|
63
|
+
)}
|
|
64
|
+
{!hideCopy && (
|
|
65
|
+
<Tooltip content={copied ? 'Copied!' : 'Copy code'}>
|
|
66
|
+
<RAC.Button
|
|
67
|
+
onPress={handleCopy}
|
|
68
|
+
className={cn(
|
|
69
|
+
'grid place-items-center w-8 h-8 bg-transparent outline-none cursor-pointer transition-all duration-200 hover:scale-115 active:scale-95 [&>svg]:w-5 [&>svg]:h-5 [&>svg]:stroke-2',
|
|
70
|
+
copied
|
|
71
|
+
? 'text-emerald-400'
|
|
72
|
+
: 'text-text-muted hover:text-text-main',
|
|
73
|
+
)}
|
|
74
|
+
aria-label="Copy code"
|
|
75
|
+
>
|
|
76
|
+
{copied ? <Check size={20} /> : <Copy size={20} />}
|
|
77
|
+
</RAC.Button>
|
|
78
|
+
</Tooltip>
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
{/* Code Content */}
|
|
83
|
+
{highlightedHtml ? (
|
|
84
|
+
<div
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
ref={preRef}
|
|
87
|
+
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!"
|
|
88
|
+
dangerouslySetInnerHTML={{ __html: highlightedHtml }}
|
|
89
|
+
/>
|
|
90
|
+
) : (
|
|
91
|
+
<pre
|
|
92
|
+
ref={preRef}
|
|
93
|
+
className="m-0! rounded-none! border-none! bg-inherit! font-mono text-[0.8125rem] leading-[1.7]"
|
|
94
|
+
{...rest}
|
|
95
|
+
>
|
|
96
|
+
{children}
|
|
97
|
+
</pre>
|
|
98
|
+
)}
|
|
99
|
+
|
|
100
|
+
{/* Expand/Collapse */}
|
|
101
|
+
{isExpandable && (
|
|
102
|
+
<div
|
|
103
|
+
className={cn(
|
|
104
|
+
shouldTruncate
|
|
105
|
+
? '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'
|
|
106
|
+
: 'relative flex justify-center py-4',
|
|
107
|
+
)}
|
|
108
|
+
>
|
|
109
|
+
<RAC.Button
|
|
110
|
+
onPress={() => setIsExpanded(!isExpanded)}
|
|
111
|
+
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"
|
|
112
|
+
>
|
|
113
|
+
{isExpanded ? 'Show less' : 'Expand code'}
|
|
114
|
+
</RAC.Button>
|
|
115
|
+
</div>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { SandboxOptions } from '../../types'
|
|
2
|
+
import { CodeBlock } from './code-block'
|
|
3
|
+
import { useComponentPreview } from './hooks/use-component-preview'
|
|
4
|
+
|
|
5
|
+
export interface ComponentPreviewProps {
|
|
6
|
+
code?: string
|
|
7
|
+
highlightedHtml?: string
|
|
8
|
+
children?: string
|
|
9
|
+
preview?: React.ReactNode
|
|
10
|
+
hideCode?: boolean
|
|
11
|
+
hideSandbox?: boolean
|
|
12
|
+
hideCopy?: boolean
|
|
13
|
+
sandboxOptions?: SandboxOptions
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function ComponentPreview(props: ComponentPreviewProps) {
|
|
17
|
+
const {
|
|
18
|
+
highlightedHtml,
|
|
19
|
+
hideCode = false,
|
|
20
|
+
hideSandbox = false,
|
|
21
|
+
hideCopy = false,
|
|
22
|
+
sandboxOptions = {},
|
|
23
|
+
} = props
|
|
24
|
+
const { initialCode, previewElement } = useComponentPreview(props)
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div className="my-6 overflow-hidden rounded-xl border border-border-subtle">
|
|
28
|
+
<div className="flex items-center justify-center p-8 bg-bg-surface">
|
|
29
|
+
{previewElement}
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
{!hideCode && (
|
|
33
|
+
<div className="border-t border-border-subtle">
|
|
34
|
+
<CodeBlock
|
|
35
|
+
hideSandbox={hideSandbox}
|
|
36
|
+
hideCopy={hideCopy}
|
|
37
|
+
title={sandboxOptions.title}
|
|
38
|
+
lang="tsx"
|
|
39
|
+
highlightedHtml={highlightedHtml}
|
|
40
|
+
>
|
|
41
|
+
{initialCode}
|
|
42
|
+
</CodeBlock>
|
|
43
|
+
</div>
|
|
44
|
+
)}
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { cn } from '@client/utils/cn'
|
|
2
|
+
|
|
3
|
+
export interface PropItem {
|
|
4
|
+
name: string
|
|
5
|
+
type: string
|
|
6
|
+
defaultValue?: string
|
|
7
|
+
required?: boolean
|
|
8
|
+
description: React.ReactNode
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ComponentPropsProps {
|
|
12
|
+
title?: string
|
|
13
|
+
props: PropItem[]
|
|
14
|
+
className?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function ComponentProps({
|
|
18
|
+
title,
|
|
19
|
+
props,
|
|
20
|
+
className = '',
|
|
21
|
+
}: ComponentPropsProps) {
|
|
22
|
+
return (
|
|
23
|
+
<div className={cn('my-6', className)}>
|
|
24
|
+
{title && (
|
|
25
|
+
<h3 className="text-base font-bold text-text-main mb-3">{title}</h3>
|
|
26
|
+
)}
|
|
27
|
+
<div className="overflow-x-auto rounded-lg border border-border-subtle">
|
|
28
|
+
<table className="w-full border-collapse text-sm">
|
|
29
|
+
<thead>
|
|
30
|
+
<tr>
|
|
31
|
+
<th className="text-left px-4 py-3 border-b-2 border-border-subtle text-xs font-bold uppercase tracking-wider text-text-muted">
|
|
32
|
+
Property
|
|
33
|
+
</th>
|
|
34
|
+
<th className="text-left px-4 py-3 border-b-2 border-border-subtle text-xs font-bold uppercase tracking-wider text-text-muted">
|
|
35
|
+
Type
|
|
36
|
+
</th>
|
|
37
|
+
<th className="text-left px-4 py-3 border-b-2 border-border-subtle text-xs font-bold uppercase tracking-wider text-text-muted">
|
|
38
|
+
Default
|
|
39
|
+
</th>
|
|
40
|
+
<th className="text-left px-4 py-3 border-b-2 border-border-subtle text-xs font-bold uppercase tracking-wider text-text-muted">
|
|
41
|
+
Description
|
|
42
|
+
</th>
|
|
43
|
+
</tr>
|
|
44
|
+
</thead>
|
|
45
|
+
<tbody>
|
|
46
|
+
{props.map((prop, index) => (
|
|
47
|
+
<tr
|
|
48
|
+
key={`${prop.name}-${index}`}
|
|
49
|
+
className="transition-colors hover:bg-bg-surface"
|
|
50
|
+
>
|
|
51
|
+
<td className="px-4 py-2.5 border-b border-border-subtle">
|
|
52
|
+
<code className="rounded bg-bg-surface px-1.5 py-0.5 font-mono text-xs font-bold text-primary-400">
|
|
53
|
+
{prop.name}
|
|
54
|
+
</code>
|
|
55
|
+
{prop.required && (
|
|
56
|
+
<span className="ml-1 text-red-400 font-bold">*</span>
|
|
57
|
+
)}
|
|
58
|
+
</td>
|
|
59
|
+
<td className="px-4 py-2.5 border-b border-border-subtle">
|
|
60
|
+
<code className="rounded bg-bg-muted px-1.5 py-0.5 font-mono text-xs text-text-muted">
|
|
61
|
+
{prop.type}
|
|
62
|
+
</code>
|
|
63
|
+
</td>
|
|
64
|
+
<td className="px-4 py-2.5 border-b border-border-subtle">
|
|
65
|
+
{prop.defaultValue ? (
|
|
66
|
+
<code className="rounded bg-bg-muted px-1.5 py-0.5 font-mono text-xs text-primary-400">
|
|
67
|
+
{prop.defaultValue}
|
|
68
|
+
</code>
|
|
69
|
+
) : (
|
|
70
|
+
<span className="text-text-dim">—</span>
|
|
71
|
+
)}
|
|
72
|
+
</td>
|
|
73
|
+
<td className="px-4 py-2.5 border-b border-border-subtle text-text-muted">
|
|
74
|
+
{prop.description}
|
|
75
|
+
</td>
|
|
76
|
+
</tr>
|
|
77
|
+
))}
|
|
78
|
+
</tbody>
|
|
79
|
+
</table>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { cn } from '@client/utils/cn'
|
|
2
|
+
|
|
3
|
+
export interface FieldProps {
|
|
4
|
+
name: string
|
|
5
|
+
type?: string
|
|
6
|
+
defaultValue?: string
|
|
7
|
+
required?: boolean
|
|
8
|
+
children: React.ReactNode
|
|
9
|
+
id?: string
|
|
10
|
+
className?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function Field({
|
|
14
|
+
name,
|
|
15
|
+
type,
|
|
16
|
+
defaultValue,
|
|
17
|
+
required = false,
|
|
18
|
+
children,
|
|
19
|
+
id,
|
|
20
|
+
className = '',
|
|
21
|
+
}: FieldProps) {
|
|
22
|
+
return (
|
|
23
|
+
<article
|
|
24
|
+
className={cn(
|
|
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
|
+
className,
|
|
28
|
+
)}
|
|
29
|
+
id={id}
|
|
30
|
+
>
|
|
31
|
+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between mb-4">
|
|
32
|
+
<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">
|
|
34
|
+
{name}
|
|
35
|
+
</code>
|
|
36
|
+
{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">
|
|
38
|
+
{type}
|
|
39
|
+
</span>
|
|
40
|
+
)}
|
|
41
|
+
{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">
|
|
43
|
+
<span className="h-1 w-1 rounded-full bg-red-400 animate-pulse" />
|
|
44
|
+
Required
|
|
45
|
+
</div>
|
|
46
|
+
)}
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
{defaultValue && (
|
|
50
|
+
<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">
|
|
51
|
+
<span className="font-semibold opacity-60 uppercase tracking-tighter">
|
|
52
|
+
Default
|
|
53
|
+
</span>
|
|
54
|
+
<code className="font-mono text-text-main font-medium">
|
|
55
|
+
{defaultValue}
|
|
56
|
+
</code>
|
|
57
|
+
</div>
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div className="text-sm text-text-muted leading-relaxed [&>p]:m-0 selection:bg-primary-500/30">
|
|
62
|
+
{children}
|
|
63
|
+
</div>
|
|
64
|
+
</article>
|
|
65
|
+
)
|
|
66
|
+
}
|