boltdocs 2.7.9 → 2.7.11

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 (174) hide show
  1. package/dist/{cache-DorPMFgW.cjs → cache-Ba-DZQNH.cjs} +1 -1
  2. package/dist/{cache-CQKlT4fI.mjs → cache-BuMZ58L5.mjs} +1 -1
  3. package/dist/chunk-CU-zTemE.cjs +6 -0
  4. package/dist/client/index.cjs +1929 -1
  5. package/dist/client/index.js +1880 -1
  6. package/dist/client/mdx.cjs +7 -1
  7. package/dist/client/mdx.js +7 -1
  8. package/dist/client/primitives.cjs +60 -1
  9. package/dist/client/primitives.js +20 -1
  10. package/dist/docs-layout-BXHV0xw_.cjs +1431 -0
  11. package/dist/docs-layout-DwFndmj5.js +1231 -0
  12. package/dist/doctor-Be7Ly1oM.mjs +21 -0
  13. package/dist/{doctor-D4_Y7M4p.cjs → doctor-CrytFkqW.cjs} +1 -1
  14. package/dist/doctor-jMxWZyLJ.cjs +21 -0
  15. package/dist/generator-CHqxiQhF.cjs +21 -0
  16. package/dist/generator-ClVanhvi.mjs +21 -0
  17. package/dist/icons-dev-3cZMyt8r.cjs +1204 -0
  18. package/dist/icons-dev-Df8OQ481.js +839 -0
  19. package/dist/image-DtrI2cw3.cjs +268 -0
  20. package/dist/image-jxPb-2iV.js +214 -0
  21. package/dist/mdx-BdWkJTeB.cjs +523 -0
  22. package/dist/mdx-UTTLFWJq.js +494 -0
  23. package/dist/meta-loader-CWg2gnbY.mjs +6 -0
  24. package/dist/meta-loader-Cv9O0Pzl.cjs +6 -0
  25. package/dist/node/cli-entry.cjs +1 -1
  26. package/dist/node/cli-entry.mjs +1 -1
  27. package/dist/node/index.cjs +1 -1
  28. package/dist/node/index.mjs +1 -1
  29. package/dist/node/routes/worker.cjs +1 -1
  30. package/dist/node/routes/worker.mjs +1 -1
  31. package/dist/node-BSM4qcDK.cjs +111 -0
  32. package/dist/node-BspZN3R2.mjs +111 -0
  33. package/dist/{package-VfQM94VL.cjs → package-DIIrjuWI.cjs} +1 -1
  34. package/dist/{package-B4MD00N3.mjs → package-K0zsjGIz.mjs} +1 -1
  35. package/dist/{parser-Bh11BsdA.cjs → parser-Aq8LoH-0.cjs} +1 -1
  36. package/dist/{parser-DYRzXWmA.cjs → parser-CdNbqN5y.cjs} +1 -1
  37. package/dist/parser-nE792MLO.mjs +6 -0
  38. package/dist/rolldown-runtime-fkIsjY3S.mjs +6 -0
  39. package/dist/{routes-Co1mRM58.cjs → routes-2k3tbUmC.cjs} +1 -1
  40. package/dist/routes-CpxZIsMM.mjs +6 -0
  41. package/dist/{routes-CHf76Ye4.cjs → routes-DP1vmWRj.cjs} +1 -1
  42. package/dist/search-dialog-BHuIiUC6.js +8 -0
  43. package/dist/search-dialog-BNF10tDl.js +375 -0
  44. package/dist/search-dialog-BwkDuI9R.cjs +220 -0
  45. package/dist/search-dialog-C7xuvyNk.cjs +386 -0
  46. package/dist/search-dialog-CIQg6k8c.cjs +8 -0
  47. package/dist/search-dialog-D-DDN7zJ.js +208 -0
  48. package/dist/utils-CG65J0Sc.mjs +7 -0
  49. package/dist/utils-CKunkU96.cjs +7 -0
  50. package/dist/{worker-pool-BwU8ckrg.cjs → worker-pool-Crbqgw5R.cjs} +1 -1
  51. package/package.json +5 -5
  52. package/dist/chunk-Ds5LZdWN.cjs +0 -6
  53. package/dist/docs-layout-KoWNZc8_.js +0 -6
  54. package/dist/docs-layout-x2yKt2cL.cjs +0 -6
  55. package/dist/doctor-BD1BSB03.mjs +0 -23
  56. package/dist/doctor-BHc9ua6r.cjs +0 -23
  57. package/dist/generator-DGW6pkCC.cjs +0 -22
  58. package/dist/generator-Dv3wEmhZ.mjs +0 -22
  59. package/dist/icons-dev-B_RZIyxu.js +0 -6
  60. package/dist/icons-dev-BlV3wWFT.cjs +0 -6
  61. package/dist/image-BHhTvQzr.cjs +0 -6
  62. package/dist/image-CqKzYD8f.js +0 -6
  63. package/dist/mdx-DudBEac0.js +0 -7
  64. package/dist/mdx-r4cDQxWu.cjs +0 -7
  65. package/dist/meta-loader-0gJ4PtBC.cjs +0 -6
  66. package/dist/meta-loader-9IpAHWDS.mjs +0 -6
  67. package/dist/node-DBaH7kat.mjs +0 -111
  68. package/dist/node-t5C3Q85p.cjs +0 -111
  69. package/dist/parser-9cVdK7w9.mjs +0 -6
  70. package/dist/routes-DwrMa5-z.mjs +0 -6
  71. package/dist/search-dialog-B584t9ZF.js +0 -6
  72. package/dist/search-dialog-BvBopRsZ.cjs +0 -6
  73. package/dist/search-dialog-ByvGScjt.js +0 -6
  74. package/dist/search-dialog-Cyko6TJm.cjs +0 -6
  75. package/dist/search-dialog-D6BNohIJ.js +0 -6
  76. package/dist/search-dialog-DuYTIefy.cjs +0 -6
  77. package/dist/utils-BxNAXhZZ.mjs +0 -7
  78. package/dist/utils-Clzu7jvb.cjs +0 -7
  79. package/src/client/app/config-context.tsx +0 -51
  80. package/src/client/app/doc-page.tsx +0 -38
  81. package/src/client/app/docs-layout.tsx +0 -28
  82. package/src/client/app/head.tsx +0 -122
  83. package/src/client/app/helmet-compat.tsx +0 -36
  84. package/src/client/app/mdx-component.tsx +0 -8
  85. package/src/client/app/mdx-components-context.tsx +0 -72
  86. package/src/client/app/routes-context.tsx +0 -34
  87. package/src/client/app/scroll-handler.tsx +0 -74
  88. package/src/client/app/theme-context.tsx +0 -103
  89. package/src/client/app/ui-context.tsx +0 -42
  90. package/src/client/components/docs-layout-default.tsx +0 -85
  91. package/src/client/components/icons-dev.tsx +0 -282
  92. package/src/client/components/mdx/callout.tsx +0 -97
  93. package/src/client/components/mdx/card.tsx +0 -99
  94. package/src/client/components/mdx/cards.tsx +0 -27
  95. package/src/client/components/mdx/code-block.tsx +0 -184
  96. package/src/client/components/mdx/field.tsx +0 -33
  97. package/src/client/components/mdx/image.tsx +0 -44
  98. package/src/client/components/mdx/index.ts +0 -19
  99. package/src/client/components/mdx/table.tsx +0 -54
  100. package/src/client/components/mdx/typographics.tsx +0 -120
  101. package/src/client/components/mdx/use-code-block.ts +0 -34
  102. package/src/client/components/primitives/breadcrumbs.tsx +0 -54
  103. package/src/client/components/primitives/button-group.tsx +0 -54
  104. package/src/client/components/primitives/button.tsx +0 -6
  105. package/src/client/components/primitives/code-block.tsx +0 -120
  106. package/src/client/components/primitives/docs-layout.tsx +0 -125
  107. package/src/client/components/primitives/error-boundary.tsx +0 -107
  108. package/src/client/components/primitives/heading.tsx +0 -128
  109. package/src/client/components/primitives/helpers/observer.ts +0 -141
  110. package/src/client/components/primitives/image.tsx +0 -26
  111. package/src/client/components/primitives/link.tsx +0 -102
  112. package/src/client/components/primitives/menu.tsx +0 -137
  113. package/src/client/components/primitives/navbar.tsx +0 -466
  114. package/src/client/components/primitives/on-this-page.tsx +0 -430
  115. package/src/client/components/primitives/page-nav.tsx +0 -51
  116. package/src/client/components/primitives/popover.tsx +0 -28
  117. package/src/client/components/primitives/search-dialog.tsx +0 -193
  118. package/src/client/components/primitives/sidebar.tsx +0 -423
  119. package/src/client/components/primitives/skeleton.tsx +0 -26
  120. package/src/client/components/primitives/tabs.tsx +0 -70
  121. package/src/client/components/primitives/tooltip.tsx +0 -81
  122. package/src/client/components/primitives/types.ts +0 -11
  123. package/src/client/components/ui-base/banner.tsx +0 -66
  124. package/src/client/components/ui-base/breadcrumbs.tsx +0 -44
  125. package/src/client/components/ui-base/copy-markdown.tsx +0 -107
  126. package/src/client/components/ui-base/error-boundary.tsx +0 -15
  127. package/src/client/components/ui-base/github-stars.tsx +0 -29
  128. package/src/client/components/ui-base/icons.tsx +0 -240
  129. package/src/client/components/ui-base/index.ts +0 -16
  130. package/src/client/components/ui-base/last-updated.tsx +0 -27
  131. package/src/client/components/ui-base/navbar.tsx +0 -266
  132. package/src/client/components/ui-base/not-found.tsx +0 -26
  133. package/src/client/components/ui-base/on-this-page.tsx +0 -57
  134. package/src/client/components/ui-base/page-nav.tsx +0 -50
  135. package/src/client/components/ui-base/search-dialog.tsx +0 -163
  136. package/src/client/components/ui-base/search-highlight.tsx +0 -10
  137. package/src/client/components/ui-base/sidebar.tsx +0 -92
  138. package/src/client/components/ui-base/tabs.tsx +0 -83
  139. package/src/client/components/ui-base/theme-toggle.tsx +0 -130
  140. package/src/client/components/ui-base/version-i18n.tsx +0 -80
  141. package/src/client/hooks/index.ts +0 -13
  142. package/src/client/hooks/use-analytics.ts +0 -272
  143. package/src/client/hooks/use-breadcrumbs.ts +0 -22
  144. package/src/client/hooks/use-i18n.ts +0 -182
  145. package/src/client/hooks/use-localized-to.ts +0 -113
  146. package/src/client/hooks/use-location.ts +0 -5
  147. package/src/client/hooks/use-navbar.ts +0 -130
  148. package/src/client/hooks/use-page-nav.ts +0 -46
  149. package/src/client/hooks/use-routes.ts +0 -108
  150. package/src/client/hooks/use-search-highlight.ts +0 -185
  151. package/src/client/hooks/use-search.ts +0 -118
  152. package/src/client/hooks/use-sidebar.ts +0 -205
  153. package/src/client/hooks/use-tabs.ts +0 -46
  154. package/src/client/hooks/use-version.ts +0 -111
  155. package/src/client/index.ts +0 -31
  156. package/src/client/mdx.ts +0 -2
  157. package/src/client/primitives.ts +0 -19
  158. package/src/client/ssg/boltdocs-shell.tsx +0 -148
  159. package/src/client/ssg/create-routes.tsx +0 -473
  160. package/src/client/ssg/index.ts +0 -4
  161. package/src/client/ssg/mdx-page.tsx +0 -38
  162. package/src/client/store/boltdocs-context.tsx +0 -137
  163. package/src/client/theme/neutral.css +0 -141
  164. package/src/client/theme/reset.css +0 -189
  165. package/src/client/types.ts +0 -116
  166. package/src/client/utils/cn.ts +0 -6
  167. package/src/client/utils/copy-clipboard.ts +0 -22
  168. package/src/client/utils/get-base-file-path.ts +0 -21
  169. package/src/client/utils/github.ts +0 -121
  170. package/src/client/utils/i18n.ts +0 -23
  171. package/src/client/utils/path.ts +0 -9
  172. package/src/client/utils/react-to-text.ts +0 -34
  173. package/src/client/virtual.d.ts +0 -24
  174. /package/dist/{worker-pool-Bd8Y9KDv.mjs → worker-pool-CGn7DrLb.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