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,359 @@
|
|
|
1
|
+
import { type ReactNode, useState, useEffect } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Separator,
|
|
5
|
+
ToggleButton,
|
|
6
|
+
Link,
|
|
7
|
+
Menu,
|
|
8
|
+
MenuItem,
|
|
9
|
+
MenuTrigger,
|
|
10
|
+
cn,
|
|
11
|
+
} from './index'
|
|
12
|
+
import { Button as ButtonRAC } from 'react-aria-components'
|
|
13
|
+
import { Search, Sun, Moon, ExternalLink, ChevronDown } from 'lucide-react'
|
|
14
|
+
import * as IconsSocials from '@components/icons-dev'
|
|
15
|
+
import type { ComponentBase } from './types'
|
|
16
|
+
import type { BoltdocsSocialLink } from '@node/config'
|
|
17
|
+
|
|
18
|
+
export interface NavbarLinkProps extends Omit<ComponentBase, 'children'> {
|
|
19
|
+
label: ReactNode
|
|
20
|
+
href: string
|
|
21
|
+
active?: boolean
|
|
22
|
+
to?: 'internal' | 'external'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface NavbarLogoProps extends Omit<ComponentBase, 'children'> {
|
|
26
|
+
src: string
|
|
27
|
+
alt: string
|
|
28
|
+
width?: number
|
|
29
|
+
height?: number
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface NavbarSearchTriggerProps extends ComponentBase {
|
|
33
|
+
onPress: () => void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface NavbarThemeProps {
|
|
37
|
+
className?: string
|
|
38
|
+
theme: 'dark' | 'light'
|
|
39
|
+
onThemeChange: (isSelected: boolean) => void
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface NavbarMenuProps extends ComponentBase {
|
|
43
|
+
label: ReactNode
|
|
44
|
+
icon?: ReactNode
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface NavbarVersionProps extends ComponentBase {
|
|
48
|
+
current: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface NavbarItemProps extends Omit<ComponentBase, 'children'> {
|
|
52
|
+
label: string
|
|
53
|
+
onPress?: () => void
|
|
54
|
+
isCurrent?: boolean
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface NavbarSocialsProps extends ComponentBase {
|
|
58
|
+
icon: string
|
|
59
|
+
link: string
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const NavbarRoot = ({
|
|
63
|
+
children,
|
|
64
|
+
className,
|
|
65
|
+
...props
|
|
66
|
+
}: ComponentBase) => {
|
|
67
|
+
return (
|
|
68
|
+
<header
|
|
69
|
+
className={cn(
|
|
70
|
+
'boltdocs-navbar sticky top-0 z-50 w-full border-b border-border-subtle bg-bg-main/80 backdrop-blur-md',
|
|
71
|
+
className,
|
|
72
|
+
)}
|
|
73
|
+
{...props}
|
|
74
|
+
>
|
|
75
|
+
{children}
|
|
76
|
+
</header>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const NavbarContent = ({ children, className }: ComponentBase) => {
|
|
81
|
+
return (
|
|
82
|
+
<div
|
|
83
|
+
className={cn(
|
|
84
|
+
'mx-auto flex lg:h-navbar max-w-(--breakpoint-3xl) items-center justify-between px-4 md:px-6',
|
|
85
|
+
className,
|
|
86
|
+
)}
|
|
87
|
+
>
|
|
88
|
+
{children}
|
|
89
|
+
</div>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const NavbarLeft = ({ children, className }: ComponentBase) => {
|
|
94
|
+
return (
|
|
95
|
+
<div className={cn('flex items-center gap-4', className)}>{children}</div>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const NavbarRight = ({ children, className }: ComponentBase) => {
|
|
100
|
+
return (
|
|
101
|
+
<div className={cn('flex items-center gap-2 md:gap-4', className)}>
|
|
102
|
+
{children}
|
|
103
|
+
</div>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export const NavbarCenter = ({ children, className }: ComponentBase) => {
|
|
108
|
+
return (
|
|
109
|
+
<div
|
|
110
|
+
className={cn(
|
|
111
|
+
'hidden lg:flex flex-1 justify-center items-center gap-4 px-4',
|
|
112
|
+
className,
|
|
113
|
+
)}
|
|
114
|
+
>
|
|
115
|
+
{children}
|
|
116
|
+
</div>
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const NavbarLogo = ({
|
|
121
|
+
src,
|
|
122
|
+
alt,
|
|
123
|
+
width = 24,
|
|
124
|
+
height = 24,
|
|
125
|
+
className,
|
|
126
|
+
}: NavbarLogoProps) => {
|
|
127
|
+
return (
|
|
128
|
+
<Link
|
|
129
|
+
href="/"
|
|
130
|
+
className={cn('flex items-center gap-2 shrink-0 outline-none', className)}
|
|
131
|
+
>
|
|
132
|
+
{src ? (
|
|
133
|
+
<img
|
|
134
|
+
src={src}
|
|
135
|
+
alt={alt}
|
|
136
|
+
width={width}
|
|
137
|
+
height={height}
|
|
138
|
+
className="h-6 w-6 object-contain"
|
|
139
|
+
/>
|
|
140
|
+
) : null}
|
|
141
|
+
</Link>
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const NavbarTitle = ({ children, className }: ComponentBase) => {
|
|
146
|
+
return (
|
|
147
|
+
<span
|
|
148
|
+
className={cn(
|
|
149
|
+
'text-lg font-bold tracking-tight hidden sm:inline-block',
|
|
150
|
+
className,
|
|
151
|
+
)}
|
|
152
|
+
>
|
|
153
|
+
{children}
|
|
154
|
+
</span>
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export const NavbarLinks = ({ children, className }: ComponentBase) => {
|
|
159
|
+
return (
|
|
160
|
+
<nav
|
|
161
|
+
className={cn(
|
|
162
|
+
'hidden md:flex items-center gap-6 text-sm font-medium',
|
|
163
|
+
className,
|
|
164
|
+
)}
|
|
165
|
+
>
|
|
166
|
+
{children}
|
|
167
|
+
</nav>
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export const NavbarLink = ({
|
|
172
|
+
label,
|
|
173
|
+
href,
|
|
174
|
+
active,
|
|
175
|
+
to,
|
|
176
|
+
className,
|
|
177
|
+
}: NavbarLinkProps) => {
|
|
178
|
+
return (
|
|
179
|
+
<Link
|
|
180
|
+
href={href}
|
|
181
|
+
target={to === 'external' ? '_blank' : undefined}
|
|
182
|
+
className={cn(
|
|
183
|
+
'transition-colors outline-none hover:text-text-main focus-visible:ring-2 focus-visible:ring-primary-500/30 rounded-sm',
|
|
184
|
+
active ? 'text-primary-500' : 'text-text-muted',
|
|
185
|
+
className,
|
|
186
|
+
)}
|
|
187
|
+
>
|
|
188
|
+
{label as any}
|
|
189
|
+
{to === 'external' && (
|
|
190
|
+
<span className="ml-1 inline-block">
|
|
191
|
+
<ExternalLink size={12} />
|
|
192
|
+
</span>
|
|
193
|
+
)}
|
|
194
|
+
</Link>
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export const NavbarSearchTrigger = ({
|
|
199
|
+
className,
|
|
200
|
+
onPress,
|
|
201
|
+
}: NavbarSearchTriggerProps) => {
|
|
202
|
+
const [mounted, setMounted] = useState(false)
|
|
203
|
+
const isMac = mounted && /Mac|iPod|iPhone|iPad/.test(navigator.platform)
|
|
204
|
+
|
|
205
|
+
useEffect(() => {
|
|
206
|
+
setMounted(true)
|
|
207
|
+
}, [])
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<ButtonRAC
|
|
211
|
+
onPress={onPress}
|
|
212
|
+
className={cn(
|
|
213
|
+
'flex items-center gap-2 rounded-full border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-muted outline-none cursor-pointer',
|
|
214
|
+
'transition-colors hover:border-border-strong hover:text-text-main',
|
|
215
|
+
'focus-visible:ring-2 focus-visible:ring-primary-500/30',
|
|
216
|
+
'w-full max-w-[320px] justify-between',
|
|
217
|
+
className,
|
|
218
|
+
)}
|
|
219
|
+
>
|
|
220
|
+
<div className="flex items-center gap-2">
|
|
221
|
+
<Search size={16} />
|
|
222
|
+
<span className="hidden sm:inline-block">Search docs...</span>
|
|
223
|
+
</div>
|
|
224
|
+
<div className="hidden sm:flex items-center gap-1 pointer-events-none select-none">
|
|
225
|
+
<kbd className="flex h-5 items-center justify-center rounded border border-border-subtle bg-bg-main px-1.5 font-mono text-[10px] font-medium">
|
|
226
|
+
{isMac ? '⌘' : 'Ctrl'}
|
|
227
|
+
</kbd>
|
|
228
|
+
<kbd className="flex h-5 w-5 items-center justify-center rounded border border-border-subtle bg-bg-main font-mono text-[10px] font-medium">
|
|
229
|
+
K
|
|
230
|
+
</kbd>
|
|
231
|
+
</div>
|
|
232
|
+
</ButtonRAC>
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export const NavbarTheme = ({
|
|
237
|
+
className,
|
|
238
|
+
theme,
|
|
239
|
+
onThemeChange,
|
|
240
|
+
}: NavbarThemeProps) => {
|
|
241
|
+
return (
|
|
242
|
+
<ToggleButton
|
|
243
|
+
isSelected={theme === 'dark'}
|
|
244
|
+
onChange={onThemeChange}
|
|
245
|
+
className={cn(
|
|
246
|
+
'rounded-md p-2 text-text-muted outline-none cursor-pointer transition-colors',
|
|
247
|
+
'hover:bg-bg-surface hover:text-text-main',
|
|
248
|
+
'focus-visible:ring-2 focus-visible:ring-primary-500/30',
|
|
249
|
+
className,
|
|
250
|
+
)}
|
|
251
|
+
aria-label="Toggle theme"
|
|
252
|
+
>
|
|
253
|
+
{theme === 'dark' ? <Sun size={20} /> : <Moon size={20} />}
|
|
254
|
+
</ToggleButton>
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export const NavbarMenu = ({
|
|
259
|
+
label,
|
|
260
|
+
children,
|
|
261
|
+
className,
|
|
262
|
+
icon,
|
|
263
|
+
}: NavbarMenuProps) => {
|
|
264
|
+
return (
|
|
265
|
+
<MenuTrigger placement="bottom end">
|
|
266
|
+
<Button
|
|
267
|
+
variant="ghost"
|
|
268
|
+
className={cn(
|
|
269
|
+
'flex items-center gap-1.5 rounded-md px-3 py-1.5 text-text-muted outline-none cursor-pointer transition-colors',
|
|
270
|
+
'hover:bg-bg-surface hover:text-text-main',
|
|
271
|
+
'focus-visible:ring-2 focus-visible:ring-primary-500/30',
|
|
272
|
+
className,
|
|
273
|
+
)}
|
|
274
|
+
>
|
|
275
|
+
{icon && <span className="flex items-center shrink-0">{icon}</span>}
|
|
276
|
+
<span className="text-[13px] font-bold uppercase tracking-wide">
|
|
277
|
+
{label}
|
|
278
|
+
</span>
|
|
279
|
+
<ChevronDown size={14} className="ml-0.5 opacity-50" />
|
|
280
|
+
</Button>
|
|
281
|
+
<Menu className="min-w-[180px]">{children as any}</Menu>
|
|
282
|
+
</MenuTrigger>
|
|
283
|
+
)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export const NavbarItem = ({
|
|
287
|
+
label,
|
|
288
|
+
className,
|
|
289
|
+
onPress,
|
|
290
|
+
isCurrent,
|
|
291
|
+
}: NavbarItemProps) => {
|
|
292
|
+
return (
|
|
293
|
+
<MenuItem
|
|
294
|
+
onAction={onPress}
|
|
295
|
+
className={cn(
|
|
296
|
+
isCurrent &&
|
|
297
|
+
'bg-primary-500 text-white font-medium hover:bg-primary-600 focus:bg-primary-600 focus:text-white',
|
|
298
|
+
className,
|
|
299
|
+
)}
|
|
300
|
+
>
|
|
301
|
+
{label}
|
|
302
|
+
</MenuItem>
|
|
303
|
+
)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export const Icon = ({ name }: { name: BoltdocsSocialLink['icon'] }) => {
|
|
307
|
+
if (name === 'github') return <IconsSocials.Github />
|
|
308
|
+
if (name === 'discord') return <IconsSocials.Discord />
|
|
309
|
+
if (name === 'x') return <IconsSocials.XSocial />
|
|
310
|
+
if (name === 'bluesky') return <IconsSocials.Bluesky />
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export const NavbarSocials = ({
|
|
314
|
+
icon,
|
|
315
|
+
link,
|
|
316
|
+
className,
|
|
317
|
+
}: NavbarSocialsProps) => {
|
|
318
|
+
return (
|
|
319
|
+
<Link
|
|
320
|
+
href={link}
|
|
321
|
+
target="_blank"
|
|
322
|
+
rel="noopener noreferrer"
|
|
323
|
+
className={cn(
|
|
324
|
+
'rounded-md p-2 text-text-muted outline-none transition-colors',
|
|
325
|
+
'hover:bg-bg-surface hover:text-text-main',
|
|
326
|
+
'focus-visible:ring-2 focus-visible:ring-primary-500/30',
|
|
327
|
+
className,
|
|
328
|
+
)}
|
|
329
|
+
>
|
|
330
|
+
<Icon name={icon} />
|
|
331
|
+
</Link>
|
|
332
|
+
)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export const NavbarSplit = ({ className }: ComponentBase) => {
|
|
336
|
+
return (
|
|
337
|
+
<Separator
|
|
338
|
+
orientation="vertical"
|
|
339
|
+
className={cn('h-6 w-px bg-border-subtle mx-1', className)}
|
|
340
|
+
/>
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export default {
|
|
345
|
+
NavbarRoot,
|
|
346
|
+
NavbarLeft,
|
|
347
|
+
NavbarRight,
|
|
348
|
+
NavbarCenter,
|
|
349
|
+
NavbarLogo,
|
|
350
|
+
Title: NavbarTitle,
|
|
351
|
+
Links: NavbarLinks,
|
|
352
|
+
Link: NavbarLink,
|
|
353
|
+
SearchTrigger: NavbarSearchTrigger,
|
|
354
|
+
Theme: NavbarTheme,
|
|
355
|
+
Item: NavbarItem,
|
|
356
|
+
Socials: NavbarSocials,
|
|
357
|
+
Split: NavbarSplit,
|
|
358
|
+
Content: NavbarContent,
|
|
359
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import * as RAC from 'react-aria-components'
|
|
2
|
+
import { ChevronDown } from 'lucide-react'
|
|
3
|
+
import { cn } from '@client/utils/cn'
|
|
4
|
+
import type { ComponentBase, CompoundComponent } from './types'
|
|
5
|
+
|
|
6
|
+
export interface NavigationMenuItemProps extends ComponentBase {
|
|
7
|
+
label: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface NavigationMenuLinkProps
|
|
11
|
+
extends Omit<ComponentBase, 'children'> {
|
|
12
|
+
href: string
|
|
13
|
+
label: string
|
|
14
|
+
description?: string
|
|
15
|
+
children?:
|
|
16
|
+
| React.ReactNode
|
|
17
|
+
| ((opts: RAC.MenuItemRenderProps) => React.ReactNode)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type NavigationMenuComponent = CompoundComponent<
|
|
21
|
+
ComponentBase,
|
|
22
|
+
{
|
|
23
|
+
List: React.FC<ComponentBase>
|
|
24
|
+
Item: React.FC<NavigationMenuItemProps>
|
|
25
|
+
Link: React.FC<NavigationMenuLinkProps>
|
|
26
|
+
}
|
|
27
|
+
>
|
|
28
|
+
|
|
29
|
+
const NavigationMenuRoot = ({
|
|
30
|
+
children,
|
|
31
|
+
className,
|
|
32
|
+
...props
|
|
33
|
+
}: ComponentBase) => {
|
|
34
|
+
return (
|
|
35
|
+
<nav className={cn('relative flex items-center', className)} {...props}>
|
|
36
|
+
{children}
|
|
37
|
+
</nav>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const NavigationMenuList = ({ children, className }: ComponentBase) => {
|
|
42
|
+
return (
|
|
43
|
+
<div className={cn('flex list-none items-center gap-1', className)}>
|
|
44
|
+
{children}
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const NavigationMenuItem = ({
|
|
50
|
+
children,
|
|
51
|
+
label,
|
|
52
|
+
className,
|
|
53
|
+
}: NavigationMenuItemProps) => {
|
|
54
|
+
return (
|
|
55
|
+
<RAC.MenuTrigger>
|
|
56
|
+
<RAC.Button
|
|
57
|
+
className={cn(
|
|
58
|
+
'flex items-center gap-1 rounded-md px-3 py-1.5 text-sm font-medium outline-none transition-colors cursor-pointer',
|
|
59
|
+
'text-text-muted hover:bg-bg-surface hover:text-text-main',
|
|
60
|
+
'focus-visible:ring-2 focus-visible:ring-primary-500/30',
|
|
61
|
+
className,
|
|
62
|
+
)}
|
|
63
|
+
>
|
|
64
|
+
{label}
|
|
65
|
+
<ChevronDown size={14} className="transition-transform" />
|
|
66
|
+
</RAC.Button>
|
|
67
|
+
<RAC.Popover
|
|
68
|
+
placement="bottom start"
|
|
69
|
+
className="entering:animate-in entering:fade-in entering:zoom-in-95 exiting:animate-out exiting:fade-out exiting:zoom-out-95 fill-mode-forwards"
|
|
70
|
+
>
|
|
71
|
+
<RAC.Menu className="w-56 outline-none rounded-xl border border-border-subtle bg-bg-surface p-2 shadow-xl ring-1 ring-border-strong/5">
|
|
72
|
+
{children as any}
|
|
73
|
+
</RAC.Menu>
|
|
74
|
+
</RAC.Popover>
|
|
75
|
+
</RAC.MenuTrigger>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const NavigationMenuLink = ({
|
|
80
|
+
label,
|
|
81
|
+
href,
|
|
82
|
+
description,
|
|
83
|
+
className,
|
|
84
|
+
children,
|
|
85
|
+
...props
|
|
86
|
+
}: NavigationMenuLinkProps) => {
|
|
87
|
+
return (
|
|
88
|
+
<RAC.MenuItem
|
|
89
|
+
href={href}
|
|
90
|
+
className={cn(
|
|
91
|
+
'block rounded-lg px-3 py-2 text-sm outline-none cursor-pointer transition-colors',
|
|
92
|
+
'hover:bg-bg-muted focus:bg-bg-muted',
|
|
93
|
+
className,
|
|
94
|
+
)}
|
|
95
|
+
{...props}
|
|
96
|
+
>
|
|
97
|
+
{children || (
|
|
98
|
+
<>
|
|
99
|
+
<div className="font-semibold text-text-main">{label}</div>
|
|
100
|
+
{description && (
|
|
101
|
+
<div className="text-xs text-text-muted line-clamp-1 mt-0.5">
|
|
102
|
+
{description}
|
|
103
|
+
</div>
|
|
104
|
+
)}
|
|
105
|
+
</>
|
|
106
|
+
)}
|
|
107
|
+
</RAC.MenuItem>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default {
|
|
112
|
+
NavigationMenuRoot,
|
|
113
|
+
NavigationMenuList,
|
|
114
|
+
NavigationMenuItem,
|
|
115
|
+
NavigationMenuLink,
|
|
116
|
+
}
|