boltdocs 2.7.10 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +2 -2
  2. package/dist/banner-3N4Jd_L9.d.ts +100 -0
  3. package/dist/banner-MynZD_Ox.d.cts +100 -0
  4. package/dist/cache-BMUyNiiA.mjs +6 -0
  5. package/dist/cache-CKm45d2w.cjs +6 -0
  6. package/dist/client/index.cjs +2268 -1
  7. package/dist/client/index.d.cts +86 -110
  8. package/dist/client/index.d.ts +87 -111
  9. package/dist/client/index.js +2214 -1
  10. package/dist/client/mdx.cjs +12 -1
  11. package/dist/client/mdx.d.cts +39 -93
  12. package/dist/client/mdx.d.ts +38 -93
  13. package/dist/client/mdx.js +7 -1
  14. package/dist/client/primitives.cjs +60 -1
  15. package/dist/client/primitives.d.cts +411 -347
  16. package/dist/client/primitives.d.ts +411 -347
  17. package/dist/client/primitives.js +20 -1
  18. package/dist/docs-layout-CwCq42Zt.cjs +1348 -0
  19. package/dist/docs-layout-Dn6S5g59.js +1167 -0
  20. package/dist/doctor-BArviV8X.cjs +28 -0
  21. package/dist/doctor-CgLA7_Uv.mjs +28 -0
  22. package/dist/{doctor-CrytFkqW.cjs → doctor-DyNUVe96.cjs} +1 -1
  23. package/dist/{routes-DP1vmWRj.cjs → doctor-aN_leTbh.mjs} +1 -1
  24. package/dist/{generator-ClVanhvi.mjs → generator-BHCrLU6h.mjs} +2 -2
  25. package/dist/{generator-CHqxiQhF.cjs → generator-CC2yHzhZ.cjs} +2 -2
  26. package/dist/icons-dev-DvJ-hh9x.cjs +1209 -0
  27. package/dist/icons-dev-Oju24Wjp.js +845 -0
  28. package/dist/image-Ch4-GxdO.cjs +268 -0
  29. package/dist/image-Do8V9PCW.js +214 -0
  30. package/dist/mdx-D3A2_l7P.js +520 -0
  31. package/dist/mdx-PLhhPJRS.cjs +531 -0
  32. package/dist/node/cli-entry.cjs +3 -1
  33. package/dist/node/cli-entry.mjs +3 -1
  34. package/dist/node/index.cjs +1 -1
  35. package/dist/node/index.d.cts +258 -152
  36. package/dist/node/index.d.mts +258 -150
  37. package/dist/node/index.mjs +1 -1
  38. package/dist/node/routes/worker.cjs +1 -1
  39. package/dist/node/routes/worker.mjs +1 -1
  40. package/dist/node-BmlP0eBP.cjs +159 -0
  41. package/dist/node-Y8_4ayje.mjs +159 -0
  42. package/dist/package-2nFy_NsW.cjs +6 -0
  43. package/dist/{package--0Yf0t1N.mjs → package-DAbtltXX.mjs} +1 -1
  44. package/dist/parser-B7-6PyQz.cjs +6 -0
  45. package/dist/{parser-Aq8LoH-0.cjs → parser-BzB-zCkF.cjs} +1 -1
  46. package/dist/parser-WGZdWs0X.mjs +6 -0
  47. package/dist/routes-BDDSxAl0.mjs +6 -0
  48. package/dist/routes-DJNJ-rTt.cjs +6 -0
  49. package/dist/routes-DiYC4nD2.cjs +6 -0
  50. package/dist/routes-_Bb2f4eI.mjs +6 -0
  51. package/dist/search-dialog-BXVoecTx.cjs +483 -0
  52. package/dist/search-dialog-BYhOov4S.cjs +331 -0
  53. package/dist/search-dialog-C09riYmx.js +313 -0
  54. package/dist/search-dialog-CUeAfy-8.cjs +8 -0
  55. package/dist/search-dialog-D8gLkhUV.js +453 -0
  56. package/dist/search-dialog-DHc_8FFX.js +8 -0
  57. package/dist/{sidebar-CcBkrm06.d.cts → sidebar-DNq4_ZAa.d.ts} +118 -52
  58. package/dist/{sidebar-CyZS9YOm.d.ts → sidebar-Dlkgbxs6.d.cts} +118 -52
  59. package/dist/utils-BYITg7T5.mjs +7 -0
  60. package/dist/utils-Cjmx1hhk.cjs +7 -0
  61. package/dist/worker-pool-CtqklOXq.cjs +6 -0
  62. package/dist/worker-pool-k0DY6k8T.mjs +6 -0
  63. package/package.json +5 -6
  64. package/src/shared/config-utils.ts +4 -0
  65. package/src/shared/types.ts +52 -6
  66. package/dist/cache-Ba-DZQNH.cjs +0 -6
  67. package/dist/cache-BuMZ58L5.mjs +0 -6
  68. package/dist/cards-BakZPTz9.d.ts +0 -30
  69. package/dist/cards-CQn9mXZS.d.cts +0 -30
  70. package/dist/docs-layout-KoWNZc8_.js +0 -6
  71. package/dist/docs-layout-x2yKt2cL.cjs +0 -6
  72. package/dist/doctor-Be7Ly1oM.mjs +0 -21
  73. package/dist/doctor-jMxWZyLJ.cjs +0 -21
  74. package/dist/icons-dev-B_RZIyxu.js +0 -6
  75. package/dist/icons-dev-BlV3wWFT.cjs +0 -6
  76. package/dist/image-BHhTvQzr.cjs +0 -6
  77. package/dist/image-CqKzYD8f.js +0 -6
  78. package/dist/mdx-DudBEac0.js +0 -7
  79. package/dist/mdx-r4cDQxWu.cjs +0 -7
  80. package/dist/node-DtEDyN1u.cjs +0 -111
  81. package/dist/node-_1jhMGYx.mjs +0 -111
  82. package/dist/package-DrwtlXfk.cjs +0 -6
  83. package/dist/parser-CdNbqN5y.cjs +0 -6
  84. package/dist/parser-nE792MLO.mjs +0 -6
  85. package/dist/rolldown-runtime-fkIsjY3S.mjs +0 -6
  86. package/dist/routes-2k3tbUmC.cjs +0 -6
  87. package/dist/routes-CpxZIsMM.mjs +0 -6
  88. package/dist/search-dialog-B584t9ZF.js +0 -6
  89. package/dist/search-dialog-BvBopRsZ.cjs +0 -6
  90. package/dist/search-dialog-ByvGScjt.js +0 -6
  91. package/dist/search-dialog-Cyko6TJm.cjs +0 -6
  92. package/dist/search-dialog-D6BNohIJ.js +0 -6
  93. package/dist/search-dialog-DuYTIefy.cjs +0 -6
  94. package/dist/utils-CG65J0Sc.mjs +0 -7
  95. package/dist/utils-CKunkU96.cjs +0 -7
  96. package/dist/worker-pool-CGn7DrLb.mjs +0 -6
  97. package/dist/worker-pool-Crbqgw5R.cjs +0 -6
  98. package/src/client/app/config-context.tsx +0 -51
  99. package/src/client/app/doc-page.tsx +0 -38
  100. package/src/client/app/docs-layout.tsx +0 -28
  101. package/src/client/app/head.tsx +0 -122
  102. package/src/client/app/helmet-compat.tsx +0 -36
  103. package/src/client/app/mdx-component.tsx +0 -8
  104. package/src/client/app/mdx-components-context.tsx +0 -72
  105. package/src/client/app/routes-context.tsx +0 -34
  106. package/src/client/app/scroll-handler.tsx +0 -74
  107. package/src/client/app/theme-context.tsx +0 -103
  108. package/src/client/app/ui-context.tsx +0 -42
  109. package/src/client/components/docs-layout-default.tsx +0 -85
  110. package/src/client/components/icons-dev.tsx +0 -282
  111. package/src/client/components/mdx/callout.tsx +0 -97
  112. package/src/client/components/mdx/card.tsx +0 -99
  113. package/src/client/components/mdx/cards.tsx +0 -27
  114. package/src/client/components/mdx/code-block.tsx +0 -184
  115. package/src/client/components/mdx/field.tsx +0 -33
  116. package/src/client/components/mdx/image.tsx +0 -44
  117. package/src/client/components/mdx/index.ts +0 -19
  118. package/src/client/components/mdx/table.tsx +0 -54
  119. package/src/client/components/mdx/typographics.tsx +0 -120
  120. package/src/client/components/mdx/use-code-block.ts +0 -34
  121. package/src/client/components/primitives/breadcrumbs.tsx +0 -54
  122. package/src/client/components/primitives/button-group.tsx +0 -54
  123. package/src/client/components/primitives/button.tsx +0 -6
  124. package/src/client/components/primitives/code-block.tsx +0 -120
  125. package/src/client/components/primitives/docs-layout.tsx +0 -125
  126. package/src/client/components/primitives/error-boundary.tsx +0 -107
  127. package/src/client/components/primitives/heading.tsx +0 -128
  128. package/src/client/components/primitives/helpers/observer.ts +0 -141
  129. package/src/client/components/primitives/image.tsx +0 -26
  130. package/src/client/components/primitives/link.tsx +0 -102
  131. package/src/client/components/primitives/menu.tsx +0 -137
  132. package/src/client/components/primitives/navbar.tsx +0 -466
  133. package/src/client/components/primitives/on-this-page.tsx +0 -430
  134. package/src/client/components/primitives/page-nav.tsx +0 -51
  135. package/src/client/components/primitives/popover.tsx +0 -28
  136. package/src/client/components/primitives/search-dialog.tsx +0 -193
  137. package/src/client/components/primitives/sidebar.tsx +0 -423
  138. package/src/client/components/primitives/skeleton.tsx +0 -26
  139. package/src/client/components/primitives/tabs.tsx +0 -70
  140. package/src/client/components/primitives/tooltip.tsx +0 -81
  141. package/src/client/components/primitives/types.ts +0 -11
  142. package/src/client/components/ui-base/banner.tsx +0 -66
  143. package/src/client/components/ui-base/breadcrumbs.tsx +0 -44
  144. package/src/client/components/ui-base/copy-markdown.tsx +0 -107
  145. package/src/client/components/ui-base/error-boundary.tsx +0 -15
  146. package/src/client/components/ui-base/github-stars.tsx +0 -29
  147. package/src/client/components/ui-base/icons.tsx +0 -240
  148. package/src/client/components/ui-base/index.ts +0 -16
  149. package/src/client/components/ui-base/last-updated.tsx +0 -27
  150. package/src/client/components/ui-base/navbar.tsx +0 -266
  151. package/src/client/components/ui-base/not-found.tsx +0 -26
  152. package/src/client/components/ui-base/on-this-page.tsx +0 -57
  153. package/src/client/components/ui-base/page-nav.tsx +0 -50
  154. package/src/client/components/ui-base/search-dialog.tsx +0 -163
  155. package/src/client/components/ui-base/search-highlight.tsx +0 -10
  156. package/src/client/components/ui-base/sidebar.tsx +0 -92
  157. package/src/client/components/ui-base/tabs.tsx +0 -83
  158. package/src/client/components/ui-base/theme-toggle.tsx +0 -130
  159. package/src/client/components/ui-base/version-i18n.tsx +0 -80
  160. package/src/client/hooks/index.ts +0 -13
  161. package/src/client/hooks/use-analytics.ts +0 -272
  162. package/src/client/hooks/use-breadcrumbs.ts +0 -22
  163. package/src/client/hooks/use-i18n.ts +0 -182
  164. package/src/client/hooks/use-localized-to.ts +0 -113
  165. package/src/client/hooks/use-location.ts +0 -5
  166. package/src/client/hooks/use-navbar.ts +0 -130
  167. package/src/client/hooks/use-page-nav.ts +0 -46
  168. package/src/client/hooks/use-routes.ts +0 -108
  169. package/src/client/hooks/use-search-highlight.ts +0 -185
  170. package/src/client/hooks/use-search.ts +0 -118
  171. package/src/client/hooks/use-sidebar.ts +0 -205
  172. package/src/client/hooks/use-tabs.ts +0 -46
  173. package/src/client/hooks/use-version.ts +0 -111
  174. package/src/client/index.ts +0 -31
  175. package/src/client/mdx.ts +0 -2
  176. package/src/client/primitives.ts +0 -19
  177. package/src/client/ssg/boltdocs-shell.tsx +0 -148
  178. package/src/client/ssg/create-routes.tsx +0 -473
  179. package/src/client/ssg/index.ts +0 -4
  180. package/src/client/ssg/mdx-page.tsx +0 -38
  181. package/src/client/store/boltdocs-context.tsx +0 -137
  182. package/src/client/theme/neutral.css +0 -141
  183. package/src/client/theme/reset.css +0 -189
  184. package/src/client/types.ts +0 -116
  185. package/src/client/utils/cn.ts +0 -6
  186. package/src/client/utils/copy-clipboard.ts +0 -22
  187. package/src/client/utils/get-base-file-path.ts +0 -21
  188. package/src/client/utils/github.ts +0 -121
  189. package/src/client/utils/i18n.ts +0 -23
  190. package/src/client/utils/path.ts +0 -9
  191. package/src/client/utils/react-to-text.ts +0 -34
  192. package/src/client/virtual.d.ts +0 -24
  193. /package/dist/{meta-loader-CWg2gnbY.mjs → meta-loader-DzwDFtdT.mjs} +0 -0
@@ -1,102 +0,0 @@
1
- import { useNavigate, useLocation } from 'react-router-dom'
2
- import { useLocalizedTo } from '../../hooks/use-localized-to'
3
- import { cn } from '../../utils/cn'
4
- export interface LinkProps
5
- extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
6
- /** Should prefetch the page on hover? Default 'hover' */
7
- prefetch?: 'hover' | 'none'
8
- }
9
-
10
- /**
11
- * A primitive Link component that wraps a standard anchor tag
12
- * and adds framework-specific logic for path localization and preloading.
13
- */
14
- export const Link = (props: LinkProps) => {
15
- const { href, onMouseEnter, onFocus, onClick, ...rest } = props
16
-
17
- const navigate = useNavigate()
18
- const localizedHref = useLocalizedTo(href ?? '')
19
-
20
- const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
21
- onClick?.(e)
22
- if (e.defaultPrevented) return
23
-
24
- const isExternal =
25
- localizedHref &&
26
- (localizedHref.startsWith('http://') ||
27
- localizedHref.startsWith('https://') ||
28
- localizedHref.startsWith('//'))
29
-
30
- if (!isExternal) {
31
- e.preventDefault()
32
- navigate(localizedHref)
33
- }
34
- }
35
-
36
- const handleMouseEnter = (e: React.MouseEvent<HTMLAnchorElement>) => {
37
- onMouseEnter?.(e)
38
- }
39
-
40
- const handleFocus = (e: React.FocusEvent<HTMLAnchorElement>) => {
41
- onFocus?.(e)
42
- }
43
-
44
- return (
45
- <a
46
- {...rest}
47
- href={localizedHref}
48
- onClick={handleClick}
49
- onMouseEnter={handleMouseEnter}
50
- onFocus={handleFocus}
51
- />
52
- )
53
- }
54
-
55
- /**
56
- * Props for the NavLink component, extending standard Link props.
57
- */
58
- export interface NavLinkProps
59
- extends Omit<LinkProps, 'className' | 'children'> {
60
- /**
61
- * When true, the active state will only be applied if the paths match exactly.
62
- * Default is false.
63
- */
64
- end?: boolean
65
- /**
66
- * Provides access to the active state for conditional children rendering.
67
- */
68
- children?:
69
- | React.ReactNode
70
- | ((props: { isActive: boolean }) => React.ReactNode)
71
- /**
72
- * Provides access to the active state for conditional styling.
73
- */
74
- className?: string | ((props: { isActive: boolean }) => string)
75
- }
76
-
77
- /**
78
- * A primitive NavLink component that provides active state detection.
79
- */
80
- export const NavLink = (props: NavLinkProps) => {
81
- const { href, end = false, className, children, ...rest } = props
82
- const location = useLocation()
83
-
84
- const localizedHref = useLocalizedTo(href ?? '')
85
-
86
- const isActive = end
87
- ? location.pathname === localizedHref
88
- : location.pathname.startsWith(localizedHref)
89
-
90
- const resolvedClassName =
91
- typeof className === 'function'
92
- ? className({ isActive })
93
- : cn(className, isActive && 'active')
94
- const resolvedChildren =
95
- typeof children === 'function' ? children({ isActive }) : children
96
-
97
- return (
98
- <Link {...rest} href={href} className={resolvedClassName}>
99
- {resolvedChildren}
100
- </Link>
101
- )
102
- }
@@ -1,137 +0,0 @@
1
- import { Check, ChevronRight } from '../ui-base/icons'
2
- import * as RAC from 'react-aria-components'
3
- import { Children } from 'react'
4
- import { Popover, type PopoverProps } from './popover'
5
- import { cn } from '../../utils/cn'
6
-
7
- /**
8
- * MenuTrigger wraps a trigger (usually a Button) and a Menu.
9
- */
10
- export interface MenuTriggerProps extends RAC.MenuTriggerProps {
11
- placement?: PopoverProps['placement']
12
- className?: string
13
- }
14
-
15
- function MenuTrigger({ placement, className, ...props }: MenuTriggerProps) {
16
- const [trigger, menu] = (
17
- Children.toArray(props.children) as React.ReactElement[]
18
- ).slice(0, 2)
19
- return (
20
- <RAC.MenuTrigger {...props}>
21
- {trigger as any}
22
- <Popover placement={placement} className={className}>
23
- {menu as any}
24
- </Popover>
25
- </RAC.MenuTrigger>
26
- )
27
- }
28
-
29
- /**
30
- * SubmenuTrigger for nested menus.
31
- */
32
- export interface SubmenuTriggerProps extends RAC.SubmenuTriggerProps {
33
- className?: string
34
- }
35
-
36
- function SubmenuTrigger({ className, ...props }: SubmenuTriggerProps) {
37
- const [trigger, menu] = (
38
- Children.toArray(props.children) as React.ReactElement[]
39
- ).slice(0, 2)
40
- return (
41
- <RAC.SubmenuTrigger {...props}>
42
- {trigger as any}
43
- <Popover offset={-4} crossOffset={-4} className={className}>
44
- {menu as any}
45
- </Popover>
46
- </RAC.SubmenuTrigger>
47
- )
48
- }
49
-
50
- /**
51
- * The Menu container.
52
- */
53
- export function Menu<T extends object>(props: RAC.MenuProps<T>) {
54
- return (
55
- <RAC.Menu
56
- {...props}
57
- className={RAC.composeRenderProps(props.className, (className) =>
58
- cn('outline-none overflow-auto', className),
59
- )}
60
- />
61
- )
62
- }
63
-
64
- /**
65
- * MenuItem with support for selection states and submenus.
66
- */
67
- function MenuItem(props: RAC.MenuItemProps) {
68
- const textValue =
69
- props.textValue ||
70
- (typeof props.children === 'string' ? props.children : undefined)
71
-
72
- return (
73
- <RAC.MenuItem
74
- {...props}
75
- textValue={textValue}
76
- className={RAC.composeRenderProps(props.className, (className) =>
77
- cn(
78
- 'group relative flex flex-row items-center cursor-default outline-none',
79
- className,
80
- ),
81
- )}
82
- >
83
- {RAC.composeRenderProps(
84
- props.children,
85
- (children, { selectionMode, isSelected, hasSubmenu }) => (
86
- <>
87
- {selectionMode === 'multiple' && (
88
- <span className="flex items-center shrink-0 justify-center">
89
- {isSelected && <Check className="size-3.5" />}
90
- </span>
91
- )}
92
- <div className="flex flex-row w-full items-center">{children}</div>
93
- {hasSubmenu && <ChevronRight className="size-4 ml-auto" />}
94
- </>
95
- ),
96
- )}
97
- </RAC.MenuItem>
98
- )
99
- }
100
-
101
- /**
102
- * MenuSection for grouping items with an optional header.
103
- */
104
- export interface MenuSectionProps<T> extends RAC.MenuSectionProps<T> {
105
- title?: string
106
- }
107
-
108
- function MenuSection<T extends object>({
109
- title,
110
- ...props
111
- }: MenuSectionProps<T>) {
112
- return (
113
- <RAC.MenuSection
114
- {...props}
115
- className={cn('flex flex-col', props.className)}
116
- >
117
- {title && <RAC.Header className="select-none">{title}</RAC.Header>}
118
- <RAC.Collection items={props.items}>{props.children}</RAC.Collection>
119
- </RAC.MenuSection>
120
- )
121
- }
122
-
123
- /**
124
- * MenuSeparator for visual division.
125
- */
126
- function MenuSeparator(props: RAC.SeparatorProps) {
127
- return (
128
- <RAC.Separator {...props} className={cn('border-t', props.className)} />
129
- )
130
- }
131
-
132
- Menu.Root = Menu
133
- Menu.Item = MenuItem
134
- Menu.Trigger = MenuTrigger
135
- Menu.SubTrigger = SubmenuTrigger
136
- Menu.Section = MenuSection
137
- Menu.Separator = MenuSeparator
@@ -1,466 +0,0 @@
1
- import { type ReactNode, useState, useEffect } from 'react'
2
- import {
3
- Button as ButtonRAC,
4
- ModalOverlay,
5
- Modal,
6
- Dialog,
7
- Separator,
8
- ToggleButton,
9
- } from 'react-aria-components'
10
- import { Link } from './link'
11
- import { Menu } from './menu'
12
- import { Popover } from './popover'
13
- import { cn } from '../../utils/cn'
14
- import { Sun, Moon, ExternalLink, MoreVertical, X } from '../ui-base/icons'
15
- import * as IconsSocials from '../icons-dev'
16
- import type { ComponentBase } from './types'
17
- import type { BoltdocsSocialLink } from '../../../shared/types'
18
-
19
- export interface NavbarLinkProps extends Omit<ComponentBase, 'children'> {
20
- label: ReactNode
21
- href: string
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
- href?: string
31
- }
32
-
33
- export interface NavbarSearchTriggerProps extends ComponentBase {
34
- onPress: () => void
35
- }
36
-
37
- export interface NavbarThemeProps {
38
- className?: string
39
- theme: 'dark' | 'light'
40
- onThemeChange: (isSelected: boolean) => void
41
- }
42
-
43
- export interface NavbarSocialsProps extends ComponentBase {
44
- icon: string
45
- link: string
46
- }
47
-
48
- export const Navbar = ({ children, className, ...props }: ComponentBase) => {
49
- return (
50
- <header
51
- className={cn('boltdocs-navbar sticky top-0 z-50 w-full', className)}
52
- {...props}
53
- >
54
- {children}
55
- </header>
56
- )
57
- }
58
-
59
- const NavbarContent = ({ children, className }: ComponentBase) => {
60
- return (
61
- <div
62
- className={cn(
63
- 'mx-auto flex lg:h-navbar max-w-(--breakpoint-3xl) items-center justify-between px-4 md:px-6',
64
- className,
65
- )}
66
- >
67
- {children}
68
- </div>
69
- )
70
- }
71
-
72
- const NavbarLeft = ({ children, className }: ComponentBase) => {
73
- return (
74
- <div
75
- className={cn(
76
- 'flex flex-1 items-center justify-start gap-4 min-w-0',
77
- className,
78
- )}
79
- >
80
- {children}
81
- </div>
82
- )
83
- }
84
-
85
- const NavbarRight = ({ children, className }: ComponentBase) => {
86
- return (
87
- <div
88
- className={cn(
89
- 'flex flex-1 items-center justify-end gap-2 md:gap-4 min-w-0',
90
- className,
91
- )}
92
- >
93
- {children}
94
- </div>
95
- )
96
- }
97
-
98
- const NavbarCenter = ({ children, className }: ComponentBase) => {
99
- return (
100
- <div
101
- className={cn(
102
- 'hidden lg:flex flex-1 justify-center items-center gap-4 px-4 min-w-0 w-full',
103
- className,
104
- )}
105
- >
106
- {children}
107
- </div>
108
- )
109
- }
110
-
111
- const NavbarLogo = ({
112
- src,
113
- alt,
114
- width = 24,
115
- height = 24,
116
- className,
117
- href = '/',
118
- }: NavbarLogoProps) => {
119
- return (
120
- <Link
121
- href={href}
122
- className={cn('flex items-center gap-2 shrink-0 outline-none', className)}
123
- >
124
- {src ? (
125
- <img
126
- src={src}
127
- alt={alt}
128
- width={width}
129
- height={height}
130
- className="h-6 w-6 object-contain"
131
- />
132
- ) : null}
133
- </Link>
134
- )
135
- }
136
-
137
- const NavbarTitle = ({
138
- children,
139
- className,
140
- href = '/',
141
- }: { href?: string } & ComponentBase) => {
142
- return (
143
- <Link href={href}>
144
- <span
145
- className={cn(
146
- 'text-lg font-bold tracking-tight hidden sm:inline-block',
147
- className,
148
- )}
149
- >
150
- {children}
151
- </span>
152
- </Link>
153
- )
154
- }
155
-
156
- const NavbarLinks = ({ children, className }: ComponentBase) => {
157
- return (
158
- <nav
159
- className={cn(
160
- 'hidden md:flex items-center gap-6 text-sm font-medium',
161
- className,
162
- )}
163
- >
164
- {children}
165
- </nav>
166
- )
167
- }
168
-
169
- const NavbarLink = ({ label, href, to, className }: NavbarLinkProps) => {
170
- return (
171
- <Link
172
- href={href}
173
- target={to === 'external' ? '_blank' : undefined}
174
- className={cn('transition-all outline-none', className)}
175
- >
176
- {label as any}
177
- {to === 'external' && (
178
- <span className="ml-1 inline-block">
179
- <ExternalLink size={12} />
180
- </span>
181
- )}
182
- </Link>
183
- )
184
- }
185
-
186
- const NavbarDropdown = ({
187
- label,
188
- className,
189
- children,
190
- }: {
191
- label: React.ReactNode
192
- className?: string
193
- children: React.ReactNode
194
- }) => {
195
- const [isOpen, setIsOpen] = useState(false)
196
-
197
- return (
198
- <div
199
- className={cn('relative', className)}
200
- onMouseEnter={() => {
201
- setIsOpen(true)
202
- }}
203
- onMouseLeave={() => {
204
- setIsOpen(false)
205
- }}
206
- >
207
- <div
208
- className={cn(
209
- 'flex items-center gap-1 outline-none cursor-pointer select-none font-medium text-muted hover:text-body transition-colors',
210
- )}
211
- >
212
- {label}
213
- <svg
214
- className={cn('w-4 h-4 transition-transform', isOpen && 'rotate-180')}
215
- fill="none"
216
- viewBox="0 0 24 24"
217
- stroke="currentColor"
218
- >
219
- <path
220
- strokeLinecap="round"
221
- strokeLinejoin="round"
222
- strokeWidth={2}
223
- d="M19 9l-7 7-7-7"
224
- />
225
- </svg>
226
- </div>
227
- {isOpen && (
228
- <div className="absolute top-full left-0 pt-1 z-[9999]">
229
- <div className="min-w-[180px] p-1 bg-surface border border-subtle rounded-md shadow-lg">
230
- {children}
231
- </div>
232
- </div>
233
- )}
234
- </div>
235
- )
236
- }
237
-
238
- const NavbarDropdownItem = ({
239
- href,
240
- label,
241
- className,
242
- }: {
243
- href: string
244
- label: string
245
- className?: string
246
- }) => {
247
- return (
248
- <Link
249
- href={href}
250
- className={cn('block px-2 py-1.5 rounded hover:bg-surface', className)}
251
- >
252
- {label}
253
- </Link>
254
- )
255
- }
256
-
257
- const NavbarSearchTriggerDesktop = ({
258
- className,
259
- onPress,
260
- children,
261
- }: NavbarSearchTriggerProps) => {
262
- return (
263
- <ButtonRAC
264
- onPress={onPress}
265
- className={cn(
266
- 'hidden lg:flex items-center justify-between gap-2 px-3 py-2 text-sm outline-none cursor-pointer w-full max-w-[720px]',
267
- className,
268
- )}
269
- >
270
- {children}
271
- </ButtonRAC>
272
- )
273
- }
274
-
275
- const NavbarSearchTriggerMobile = ({
276
- className,
277
- onPress,
278
- children,
279
- }: NavbarSearchTriggerProps) => {
280
- return (
281
- <ButtonRAC
282
- onPress={onPress}
283
- className={cn(
284
- 'lg:hidden flex h-10 w-10 items-center justify-center outline-none cursor-pointer',
285
- className,
286
- )}
287
- aria-label="Search"
288
- >
289
- {children}
290
- </ButtonRAC>
291
- )
292
- }
293
-
294
- const NavbarSearchTriggerKbd = ({ className }: ComponentBase) => {
295
- const [mounted, setMounted] = useState(false)
296
- const isMac = mounted && /Mac|iPod|iPhone|iPad/.test(navigator.platform)
297
-
298
- useEffect(() => {
299
- setMounted(true)
300
- }, [])
301
-
302
- return (
303
- <div
304
- className={cn(
305
- 'hidden sm:flex items-center gap-1 pointer-events-none select-none',
306
- className,
307
- )}
308
- >
309
- <kbd className="flex items-center justify-center font-mono text-[10px]">
310
- {isMac ? '⌘' : 'Ctrl'}
311
- </kbd>
312
- <kbd className="flex items-center justify-center font-mono text-[10px]">
313
- K
314
- </kbd>
315
- </div>
316
- )
317
- }
318
-
319
- const NavbarSearchTrigger = {
320
- Desktop: NavbarSearchTriggerDesktop,
321
- Mobile: NavbarSearchTriggerMobile,
322
- Kbd: NavbarSearchTriggerKbd,
323
- }
324
-
325
- const NavbarTheme = ({ className, theme, onThemeChange }: NavbarThemeProps) => {
326
- return (
327
- <ToggleButton
328
- isSelected={theme === 'dark'}
329
- onChange={onThemeChange}
330
- className={cn('outline-none cursor-pointer', className)}
331
- aria-label="Toggle theme"
332
- >
333
- {theme === 'dark' ? <Sun size={20} /> : <Moon size={20} />}
334
- </ToggleButton>
335
- )
336
- }
337
-
338
- const Icon = ({ name }: { name: BoltdocsSocialLink['icon'] }) => {
339
- if (name === 'github') return <IconsSocials.Github />
340
- if (name === 'discord') return <IconsSocials.Discord />
341
- if (name === 'x') return <IconsSocials.XSocial />
342
- if (name === 'bluesky') return <IconsSocials.Bluesky />
343
- }
344
-
345
- const NavbarSocials = ({ icon, link, className }: NavbarSocialsProps) => {
346
- return (
347
- <Link
348
- href={link}
349
- target="_blank"
350
- rel="noopener noreferrer"
351
- className={cn('outline-none', className)}
352
- >
353
- <Icon name={icon} />
354
- </Link>
355
- )
356
- }
357
-
358
- const NavbarSplit = ({ className }: ComponentBase) => {
359
- return (
360
- <Separator
361
- orientation="vertical"
362
- className={cn('h-full w-px', className)}
363
- />
364
- )
365
- }
366
-
367
- export interface NavbarMoreProps extends ComponentBase {
368
- onPress?: () => void
369
- }
370
-
371
- const NavbarMore = ({ onPress, className }: NavbarMoreProps) => {
372
- return (
373
- <ButtonRAC
374
- onPress={onPress}
375
- className={cn(
376
- 'md:hidden flex items-center justify-center outline-none cursor-pointer',
377
- className,
378
- )}
379
- aria-label="More navigation"
380
- >
381
- <MoreVertical size={20} />
382
- </ButtonRAC>
383
- )
384
- }
385
-
386
- export interface NavbarMobileMenuProps extends ComponentBase {
387
- isOpen: boolean
388
- onClose: () => void
389
- }
390
-
391
- const NavbarMobileMenu = ({
392
- isOpen,
393
- onClose,
394
- children,
395
- className,
396
- }: NavbarMobileMenuProps) => {
397
- return (
398
- <ModalOverlay
399
- isOpen={isOpen}
400
- onOpenChange={(open) => !open && onClose()}
401
- isDismissable={true}
402
- className={cn(
403
- 'fixed inset-0 z-60 md:hidden transition-all duration-100',
404
- className,
405
- )}
406
- >
407
- <Modal className="fixed inset-0 outline-none">
408
- <Dialog className="relative h-full outline-none flex flex-col p-6 pt-[calc(1.5rem+env(safe-area-inset-top,0px))] pb-[calc(1.5rem+env(safe-area-inset-bottom,0px))] px-[calc(1.5rem+env(safe-area-inset-left,0px))]">
409
- <div className="flex items-center justify-between mb-6">
410
- <span></span>
411
- <ButtonRAC
412
- onPress={onClose}
413
- className="flex items-center justify-center outline-none cursor-pointer text-muted hover:text-body transition-colors"
414
- aria-label="Close menu"
415
- >
416
- <X size={24} />
417
- </ButtonRAC>
418
- </div>
419
- <nav className="flex-1 overflow-y-auto flex flex-col gap-4">
420
- {children}
421
- </nav>
422
- </Dialog>
423
- </Modal>
424
- </ModalOverlay>
425
- )
426
- }
427
-
428
- const NavbarMobileLink = ({
429
- label,
430
- href,
431
- to,
432
- onPress,
433
- className,
434
- }: NavbarLinkProps & { onPress?: () => void }) => {
435
- return (
436
- <Link
437
- href={href}
438
- target={to === 'external' ? '_blank' : undefined}
439
- onClick={onPress}
440
- className={cn('group flex items-center outline-none', className)}
441
- >
442
- {label as any}
443
- </Link>
444
- )
445
- }
446
-
447
- Navbar.Root = Navbar
448
- Navbar.Left = NavbarLeft
449
- Navbar.Right = NavbarRight
450
- Navbar.Center = NavbarCenter
451
- Navbar.Logo = NavbarLogo
452
- Navbar.Title = NavbarTitle
453
- Navbar.Links = NavbarLinks
454
- Navbar.Link = NavbarLink
455
- Navbar.Dropdown = NavbarDropdown
456
- Navbar.DropdownItem = NavbarDropdownItem
457
- Navbar.SearchTrigger = NavbarSearchTrigger
458
- Navbar.Theme = NavbarTheme
459
- Navbar.Socials = NavbarSocials
460
- Navbar.Split = NavbarSplit
461
- Navbar.Content = NavbarContent
462
- Navbar.More = NavbarMore
463
- Navbar.MobileMenu = NavbarMobileMenu
464
- Navbar.MobileLink = NavbarMobileLink
465
-
466
- export default Navbar