@brainfish-ai/devdoc 0.1.21

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 (268) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +415 -0
  3. package/bin/devdoc.js +13 -0
  4. package/dist/cli/commands/build.d.ts +5 -0
  5. package/dist/cli/commands/build.js +87 -0
  6. package/dist/cli/commands/check.d.ts +1 -0
  7. package/dist/cli/commands/check.js +143 -0
  8. package/dist/cli/commands/create.d.ts +24 -0
  9. package/dist/cli/commands/create.js +387 -0
  10. package/dist/cli/commands/deploy.d.ts +9 -0
  11. package/dist/cli/commands/deploy.js +433 -0
  12. package/dist/cli/commands/dev.d.ts +6 -0
  13. package/dist/cli/commands/dev.js +139 -0
  14. package/dist/cli/commands/init.d.ts +11 -0
  15. package/dist/cli/commands/init.js +238 -0
  16. package/dist/cli/commands/keys.d.ts +12 -0
  17. package/dist/cli/commands/keys.js +165 -0
  18. package/dist/cli/commands/start.d.ts +5 -0
  19. package/dist/cli/commands/start.js +56 -0
  20. package/dist/cli/commands/upload.d.ts +13 -0
  21. package/dist/cli/commands/upload.js +238 -0
  22. package/dist/cli/commands/whoami.d.ts +8 -0
  23. package/dist/cli/commands/whoami.js +91 -0
  24. package/dist/cli/index.d.ts +1 -0
  25. package/dist/cli/index.js +106 -0
  26. package/dist/config/index.d.ts +80 -0
  27. package/dist/config/index.js +133 -0
  28. package/dist/constants.d.ts +9 -0
  29. package/dist/constants.js +13 -0
  30. package/dist/index.d.ts +7 -0
  31. package/dist/index.js +12 -0
  32. package/dist/utils/logger.d.ts +16 -0
  33. package/dist/utils/logger.js +61 -0
  34. package/dist/utils/paths.d.ts +16 -0
  35. package/dist/utils/paths.js +50 -0
  36. package/package.json +51 -0
  37. package/renderer/app/api/assets/[...path]/route.ts +123 -0
  38. package/renderer/app/api/assets/route.ts +124 -0
  39. package/renderer/app/api/assets/upload/route.ts +177 -0
  40. package/renderer/app/api/auth-schemes/route.ts +77 -0
  41. package/renderer/app/api/chat/route.ts +858 -0
  42. package/renderer/app/api/codegen/route.ts +72 -0
  43. package/renderer/app/api/collections/route.ts +1016 -0
  44. package/renderer/app/api/debug/route.ts +53 -0
  45. package/renderer/app/api/deploy/route.ts +234 -0
  46. package/renderer/app/api/device/route.ts +42 -0
  47. package/renderer/app/api/docs/route.ts +187 -0
  48. package/renderer/app/api/keys/regenerate/route.ts +80 -0
  49. package/renderer/app/api/openapi-spec/route.ts +151 -0
  50. package/renderer/app/api/projects/[slug]/route.ts +153 -0
  51. package/renderer/app/api/projects/[slug]/stats/route.ts +96 -0
  52. package/renderer/app/api/projects/register/route.ts +152 -0
  53. package/renderer/app/api/proxy/route.ts +149 -0
  54. package/renderer/app/api/proxy-stream/route.ts +168 -0
  55. package/renderer/app/api/redirects/route.ts +47 -0
  56. package/renderer/app/api/schema/route.ts +65 -0
  57. package/renderer/app/api/subdomains/check/route.ts +172 -0
  58. package/renderer/app/api/suggestions/route.ts +144 -0
  59. package/renderer/app/favicon.ico +0 -0
  60. package/renderer/app/globals.css +1103 -0
  61. package/renderer/app/layout.tsx +47 -0
  62. package/renderer/app/llms-full.txt/route.ts +346 -0
  63. package/renderer/app/llms.txt/route.ts +279 -0
  64. package/renderer/app/page.tsx +14 -0
  65. package/renderer/app/robots.txt/route.ts +84 -0
  66. package/renderer/app/sitemap.xml/route.ts +199 -0
  67. package/renderer/components/docs/index.ts +12 -0
  68. package/renderer/components/docs/mdx/accordion.tsx +169 -0
  69. package/renderer/components/docs/mdx/badge.tsx +132 -0
  70. package/renderer/components/docs/mdx/callouts.tsx +154 -0
  71. package/renderer/components/docs/mdx/cards.tsx +213 -0
  72. package/renderer/components/docs/mdx/changelog.tsx +120 -0
  73. package/renderer/components/docs/mdx/code-block.tsx +186 -0
  74. package/renderer/components/docs/mdx/code-group.tsx +421 -0
  75. package/renderer/components/docs/mdx/file-embeds.tsx +105 -0
  76. package/renderer/components/docs/mdx/frame.tsx +112 -0
  77. package/renderer/components/docs/mdx/highlight.tsx +151 -0
  78. package/renderer/components/docs/mdx/iframe.tsx +134 -0
  79. package/renderer/components/docs/mdx/image.tsx +235 -0
  80. package/renderer/components/docs/mdx/index.ts +204 -0
  81. package/renderer/components/docs/mdx/mermaid.tsx +240 -0
  82. package/renderer/components/docs/mdx/param-field.tsx +200 -0
  83. package/renderer/components/docs/mdx/steps.tsx +113 -0
  84. package/renderer/components/docs/mdx/tabs.tsx +86 -0
  85. package/renderer/components/docs/mdx-renderer.tsx +100 -0
  86. package/renderer/components/docs/navigation/breadcrumbs.tsx +76 -0
  87. package/renderer/components/docs/navigation/index.ts +8 -0
  88. package/renderer/components/docs/navigation/page-nav.tsx +64 -0
  89. package/renderer/components/docs/navigation/sidebar.tsx +515 -0
  90. package/renderer/components/docs/navigation/toc.tsx +113 -0
  91. package/renderer/components/docs/notice.tsx +105 -0
  92. package/renderer/components/docs-header.tsx +274 -0
  93. package/renderer/components/docs-viewer/agent/agent-chat.tsx +2076 -0
  94. package/renderer/components/docs-viewer/agent/cards/debug-context-card.tsx +90 -0
  95. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.tsx +49 -0
  96. package/renderer/components/docs-viewer/agent/cards/index.tsx +50 -0
  97. package/renderer/components/docs-viewer/agent/cards/response-options-card.tsx +212 -0
  98. package/renderer/components/docs-viewer/agent/cards/types.ts +84 -0
  99. package/renderer/components/docs-viewer/agent/chat-message.tsx +17 -0
  100. package/renderer/components/docs-viewer/agent/index.tsx +6 -0
  101. package/renderer/components/docs-viewer/agent/messages/assistant-message.tsx +119 -0
  102. package/renderer/components/docs-viewer/agent/messages/chat-message.tsx +46 -0
  103. package/renderer/components/docs-viewer/agent/messages/index.ts +17 -0
  104. package/renderer/components/docs-viewer/agent/messages/tool-call-display.tsx +721 -0
  105. package/renderer/components/docs-viewer/agent/messages/types.ts +61 -0
  106. package/renderer/components/docs-viewer/agent/messages/typing-indicator.tsx +24 -0
  107. package/renderer/components/docs-viewer/agent/messages/user-message.tsx +51 -0
  108. package/renderer/components/docs-viewer/code-editor/index.tsx +2 -0
  109. package/renderer/components/docs-viewer/code-editor/notes-mode.tsx +1283 -0
  110. package/renderer/components/docs-viewer/content/changelog-page.tsx +331 -0
  111. package/renderer/components/docs-viewer/content/doc-page.tsx +285 -0
  112. package/renderer/components/docs-viewer/content/documentation-viewer.tsx +17 -0
  113. package/renderer/components/docs-viewer/content/index.tsx +29 -0
  114. package/renderer/components/docs-viewer/content/introduction.tsx +21 -0
  115. package/renderer/components/docs-viewer/content/request-details.tsx +330 -0
  116. package/renderer/components/docs-viewer/content/sections/auth.tsx +69 -0
  117. package/renderer/components/docs-viewer/content/sections/body.tsx +66 -0
  118. package/renderer/components/docs-viewer/content/sections/headers.tsx +43 -0
  119. package/renderer/components/docs-viewer/content/sections/overview.tsx +40 -0
  120. package/renderer/components/docs-viewer/content/sections/parameters.tsx +43 -0
  121. package/renderer/components/docs-viewer/content/sections/responses.tsx +87 -0
  122. package/renderer/components/docs-viewer/global-auth-modal.tsx +352 -0
  123. package/renderer/components/docs-viewer/index.tsx +1466 -0
  124. package/renderer/components/docs-viewer/playground/auth-editor.tsx +280 -0
  125. package/renderer/components/docs-viewer/playground/body-editor.tsx +221 -0
  126. package/renderer/components/docs-viewer/playground/code-editor.tsx +224 -0
  127. package/renderer/components/docs-viewer/playground/code-snippet.tsx +387 -0
  128. package/renderer/components/docs-viewer/playground/graphql-playground.tsx +745 -0
  129. package/renderer/components/docs-viewer/playground/index.tsx +671 -0
  130. package/renderer/components/docs-viewer/playground/key-value-editor.tsx +261 -0
  131. package/renderer/components/docs-viewer/playground/method-selector.tsx +60 -0
  132. package/renderer/components/docs-viewer/playground/request-builder.tsx +179 -0
  133. package/renderer/components/docs-viewer/playground/request-tabs.tsx +237 -0
  134. package/renderer/components/docs-viewer/playground/response-cards/idle-card.tsx +21 -0
  135. package/renderer/components/docs-viewer/playground/response-cards/index.tsx +93 -0
  136. package/renderer/components/docs-viewer/playground/response-cards/loading-card.tsx +16 -0
  137. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.tsx +23 -0
  138. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.tsx +268 -0
  139. package/renderer/components/docs-viewer/playground/response-cards/types.ts +82 -0
  140. package/renderer/components/docs-viewer/playground/response-viewer.tsx +43 -0
  141. package/renderer/components/docs-viewer/search/index.ts +2 -0
  142. package/renderer/components/docs-viewer/search/search-dialog.tsx +331 -0
  143. package/renderer/components/docs-viewer/search/use-search.ts +117 -0
  144. package/renderer/components/docs-viewer/shared/markdown-renderer.tsx +431 -0
  145. package/renderer/components/docs-viewer/shared/method-badge.tsx +41 -0
  146. package/renderer/components/docs-viewer/shared/schema-viewer.tsx +349 -0
  147. package/renderer/components/docs-viewer/sidebar/collection-tree.tsx +239 -0
  148. package/renderer/components/docs-viewer/sidebar/endpoint-options.tsx +316 -0
  149. package/renderer/components/docs-viewer/sidebar/index.tsx +343 -0
  150. package/renderer/components/docs-viewer/sidebar/right-sidebar.tsx +202 -0
  151. package/renderer/components/docs-viewer/sidebar/sidebar-group.tsx +118 -0
  152. package/renderer/components/docs-viewer/sidebar/sidebar-item.tsx +226 -0
  153. package/renderer/components/docs-viewer/sidebar/sidebar-section.tsx +52 -0
  154. package/renderer/components/theme-provider.tsx +11 -0
  155. package/renderer/components/theme-toggle.tsx +76 -0
  156. package/renderer/components/ui/badge.tsx +46 -0
  157. package/renderer/components/ui/button.tsx +59 -0
  158. package/renderer/components/ui/dialog.tsx +118 -0
  159. package/renderer/components/ui/dropdown-menu.tsx +257 -0
  160. package/renderer/components/ui/input.tsx +21 -0
  161. package/renderer/components/ui/label.tsx +24 -0
  162. package/renderer/components/ui/navigation-menu.tsx +168 -0
  163. package/renderer/components/ui/select.tsx +190 -0
  164. package/renderer/components/ui/spinner.tsx +114 -0
  165. package/renderer/components/ui/tabs.tsx +66 -0
  166. package/renderer/components/ui/tooltip.tsx +61 -0
  167. package/renderer/hooks/use-code-copy.ts +88 -0
  168. package/renderer/hooks/use-openapi-title.ts +44 -0
  169. package/renderer/lib/api-docs/agent/index.ts +6 -0
  170. package/renderer/lib/api-docs/agent/indexer.ts +323 -0
  171. package/renderer/lib/api-docs/agent/spec-summary.ts +335 -0
  172. package/renderer/lib/api-docs/agent/types.ts +116 -0
  173. package/renderer/lib/api-docs/auth/auth-context.tsx +225 -0
  174. package/renderer/lib/api-docs/auth/auth-storage.ts +87 -0
  175. package/renderer/lib/api-docs/auth/crypto.ts +89 -0
  176. package/renderer/lib/api-docs/auth/index.ts +4 -0
  177. package/renderer/lib/api-docs/code-editor/db.ts +164 -0
  178. package/renderer/lib/api-docs/code-editor/hooks.ts +266 -0
  179. package/renderer/lib/api-docs/code-editor/index.ts +6 -0
  180. package/renderer/lib/api-docs/code-editor/mode-context.tsx +207 -0
  181. package/renderer/lib/api-docs/code-editor/types.ts +105 -0
  182. package/renderer/lib/api-docs/codegen/definitions.ts +297 -0
  183. package/renderer/lib/api-docs/codegen/har.ts +251 -0
  184. package/renderer/lib/api-docs/codegen/index.ts +159 -0
  185. package/renderer/lib/api-docs/factories.ts +151 -0
  186. package/renderer/lib/api-docs/index.ts +17 -0
  187. package/renderer/lib/api-docs/mobile-context.tsx +112 -0
  188. package/renderer/lib/api-docs/navigation-context.tsx +88 -0
  189. package/renderer/lib/api-docs/parsers/graphql/README.md +129 -0
  190. package/renderer/lib/api-docs/parsers/graphql/index.ts +91 -0
  191. package/renderer/lib/api-docs/parsers/graphql/parser.ts +491 -0
  192. package/renderer/lib/api-docs/parsers/graphql/transformer.ts +246 -0
  193. package/renderer/lib/api-docs/parsers/graphql/types.ts +283 -0
  194. package/renderer/lib/api-docs/parsers/openapi/README.md +32 -0
  195. package/renderer/lib/api-docs/parsers/openapi/dereferencer.ts +60 -0
  196. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.ts +574 -0
  197. package/renderer/lib/api-docs/parsers/openapi/extractors/body.ts +403 -0
  198. package/renderer/lib/api-docs/parsers/openapi/extractors/index.ts +232 -0
  199. package/renderer/lib/api-docs/parsers/openapi/index.ts +171 -0
  200. package/renderer/lib/api-docs/parsers/openapi/transformer.ts +277 -0
  201. package/renderer/lib/api-docs/parsers/openapi/validator.ts +31 -0
  202. package/renderer/lib/api-docs/playground/context.tsx +107 -0
  203. package/renderer/lib/api-docs/playground/navigation-context.tsx +124 -0
  204. package/renderer/lib/api-docs/playground/request-builder.ts +223 -0
  205. package/renderer/lib/api-docs/playground/request-runner.ts +282 -0
  206. package/renderer/lib/api-docs/playground/types.ts +35 -0
  207. package/renderer/lib/api-docs/types.ts +269 -0
  208. package/renderer/lib/api-docs/utils.ts +311 -0
  209. package/renderer/lib/cache.ts +193 -0
  210. package/renderer/lib/docs/config/index.ts +29 -0
  211. package/renderer/lib/docs/config/loader.ts +142 -0
  212. package/renderer/lib/docs/config/schema.ts +298 -0
  213. package/renderer/lib/docs/index.ts +12 -0
  214. package/renderer/lib/docs/mdx/compiler.ts +176 -0
  215. package/renderer/lib/docs/mdx/frontmatter.ts +80 -0
  216. package/renderer/lib/docs/mdx/index.ts +26 -0
  217. package/renderer/lib/docs/navigation/generator.ts +348 -0
  218. package/renderer/lib/docs/navigation/index.ts +12 -0
  219. package/renderer/lib/docs/navigation/types.ts +123 -0
  220. package/renderer/lib/docs-navigation-context.tsx +80 -0
  221. package/renderer/lib/multi-tenant/context.ts +105 -0
  222. package/renderer/lib/storage/blob.ts +845 -0
  223. package/renderer/lib/utils.ts +6 -0
  224. package/renderer/next.config.ts +76 -0
  225. package/renderer/package.json +66 -0
  226. package/renderer/postcss.config.mjs +5 -0
  227. package/renderer/public/assets/images/screenshot.png +0 -0
  228. package/renderer/public/assets/logo/dark.svg +9 -0
  229. package/renderer/public/assets/logo/light.svg +9 -0
  230. package/renderer/public/assets/logo.svg +9 -0
  231. package/renderer/public/file.svg +1 -0
  232. package/renderer/public/globe.svg +1 -0
  233. package/renderer/public/icon.png +0 -0
  234. package/renderer/public/logo.svg +9 -0
  235. package/renderer/public/window.svg +1 -0
  236. package/renderer/tsconfig.json +28 -0
  237. package/templates/basic/README.md +139 -0
  238. package/templates/basic/assets/favicon.svg +4 -0
  239. package/templates/basic/assets/logo.svg +9 -0
  240. package/templates/basic/docs.json +47 -0
  241. package/templates/basic/guides/configuration.mdx +149 -0
  242. package/templates/basic/guides/overview.mdx +96 -0
  243. package/templates/basic/index.mdx +39 -0
  244. package/templates/basic/package.json +14 -0
  245. package/templates/basic/quickstart.mdx +92 -0
  246. package/templates/basic/vercel.json +6 -0
  247. package/templates/graphql/README.md +139 -0
  248. package/templates/graphql/api-reference/schema.graphql +305 -0
  249. package/templates/graphql/assets/favicon.svg +4 -0
  250. package/templates/graphql/assets/logo.svg +9 -0
  251. package/templates/graphql/docs.json +54 -0
  252. package/templates/graphql/guides/configuration.mdx +149 -0
  253. package/templates/graphql/guides/overview.mdx +96 -0
  254. package/templates/graphql/index.mdx +39 -0
  255. package/templates/graphql/package.json +14 -0
  256. package/templates/graphql/quickstart.mdx +92 -0
  257. package/templates/graphql/vercel.json +6 -0
  258. package/templates/openapi/README.md +139 -0
  259. package/templates/openapi/api-reference/openapi.json +419 -0
  260. package/templates/openapi/assets/favicon.svg +4 -0
  261. package/templates/openapi/assets/logo.svg +9 -0
  262. package/templates/openapi/docs.json +61 -0
  263. package/templates/openapi/guides/configuration.mdx +149 -0
  264. package/templates/openapi/guides/overview.mdx +96 -0
  265. package/templates/openapi/index.mdx +39 -0
  266. package/templates/openapi/package.json +14 -0
  267. package/templates/openapi/quickstart.mdx +92 -0
  268. package/templates/openapi/vercel.json +6 -0
@@ -0,0 +1,105 @@
1
+ 'use client'
2
+
3
+ import React, { useState, useEffect } from 'react'
4
+ import { X } from '@phosphor-icons/react'
5
+ import { cn } from '@/lib/utils'
6
+ import ReactMarkdown from 'react-markdown'
7
+
8
+ export interface NoticeConfig {
9
+ content: string
10
+ dismissible?: boolean
11
+ background?: string // Custom background color (hex, rgb, or Tailwind class)
12
+ }
13
+
14
+ interface NoticeProps {
15
+ config: NoticeConfig
16
+ storageKey?: string
17
+ className?: string
18
+ }
19
+
20
+ const STORAGE_PREFIX = 'docs-notice-dismissed-'
21
+
22
+ export function Notice({ config, storageKey = 'default', className }: NoticeProps) {
23
+ // For non-dismissible notices, show immediately
24
+ // For dismissible notices, start hidden until we check storage
25
+ const [isDismissed, setIsDismissed] = useState(config.dismissible ? true : false)
26
+ const [isLoaded, setIsLoaded] = useState(!config.dismissible)
27
+
28
+ const fullStorageKey = `${STORAGE_PREFIX}${storageKey}`
29
+
30
+ useEffect(() => {
31
+ if (!config.dismissible) return
32
+
33
+ // Check if notice was previously dismissed
34
+ const dismissed = sessionStorage.getItem(fullStorageKey)
35
+ setIsDismissed(dismissed === 'true')
36
+ setIsLoaded(true)
37
+ }, [fullStorageKey, config.dismissible])
38
+
39
+
40
+ const handleDismiss = () => {
41
+ sessionStorage.setItem(fullStorageKey, 'true')
42
+ setIsDismissed(true)
43
+ }
44
+
45
+ // Don't render until we've checked storage (for dismissible notices)
46
+ if (!isLoaded) return null
47
+
48
+ // Don't render if dismissed
49
+ if (isDismissed && config.dismissible) return null
50
+
51
+ // Don't render if no content
52
+ if (!config.content) return null
53
+
54
+ // Default to a neutral dark color that works with any theme
55
+ const defaultBackground = '#1e293b' // slate-800
56
+ const backgroundStyle = {
57
+ backgroundColor: config.background || defaultBackground
58
+ }
59
+
60
+ return (
61
+ <div
62
+ className={cn(
63
+ 'docs-notice sticky top-0 z-[100] w-full text-white',
64
+ 'px-4 py-2.5 text-sm text-center',
65
+ 'shadow-[0_4px_6px_-1px_rgba(0,0,0,0.3)]',
66
+ className
67
+ )}
68
+ style={backgroundStyle}
69
+ >
70
+ <div className="docs-notice-content max-w-screen-xl mx-auto flex items-center justify-center gap-2">
71
+ <div className="docs-notice-text flex-1 [&_a]:underline [&_a]:font-medium [&_a]:hover:opacity-80 [&_p]:m-0 [&_p]:inline">
72
+ <ReactMarkdown
73
+ components={{
74
+ // Render links properly
75
+ a: ({ href, children }) => (
76
+ <a href={href} className="underline font-medium hover:opacity-80">
77
+ {children}
78
+ </a>
79
+ ),
80
+ // Render paragraphs inline
81
+ p: ({ children }) => <span>{children}</span>,
82
+ }}
83
+ >
84
+ {config.content}
85
+ </ReactMarkdown>
86
+ </div>
87
+
88
+ {config.dismissible && (
89
+ <button
90
+ type="button"
91
+ onClick={handleDismiss}
92
+ className={cn(
93
+ 'docs-notice-dismiss flex-shrink-0 p-1 rounded-sm',
94
+ 'hover:bg-white/20 transition-colors',
95
+ 'focus:outline-none focus-visible:ring-2 focus-visible:ring-white/50'
96
+ )}
97
+ aria-label="Dismiss notice"
98
+ >
99
+ <X className="h-4 w-4" weight="bold" />
100
+ </button>
101
+ )}
102
+ </div>
103
+ </div>
104
+ )
105
+ }
@@ -0,0 +1,274 @@
1
+ 'use client'
2
+
3
+ import Link from "next/link"
4
+ import Image from "next/image"
5
+ import { ArrowSquareOut, List, ChatCircle, X, MagnifyingGlass } from "@phosphor-icons/react"
6
+ import { ThemeToggle } from "@/components/theme-toggle"
7
+ import { useMobile } from "@/lib/api-docs/mobile-context"
8
+ import { Button } from "@/components/ui/button"
9
+ import { cn } from "@/lib/utils"
10
+
11
+ // Navigation tab from config
12
+ interface NavigationTab {
13
+ id: string
14
+ tab: string // Tab name (used for both navigation and page header)
15
+ type?: 'docs' | 'openapi' | 'changelog' | 'graphql'
16
+ path?: string
17
+ order: number
18
+ }
19
+
20
+ // Logo config from docs.json
21
+ interface DocsLogo {
22
+ url?: string
23
+ alt?: string
24
+ width?: number
25
+ height?: number
26
+ light?: string
27
+ dark?: string
28
+ }
29
+
30
+ // Header config from docs.json
31
+ interface DocsHeaderConfig {
32
+ showSearch?: boolean
33
+ showThemeToggle?: boolean
34
+ }
35
+
36
+ // Navbar config from docs.json
37
+ interface DocsNavbarLink {
38
+ label: string
39
+ href: string
40
+ external?: boolean
41
+ }
42
+
43
+ interface DocsNavbarPrimary {
44
+ label: string
45
+ href: string
46
+ }
47
+
48
+ interface DocsNavbar {
49
+ links?: DocsNavbarLink[]
50
+ primary?: DocsNavbarPrimary
51
+ }
52
+
53
+ interface DocsHeaderProps {
54
+ navigationTabs?: NavigationTab[]
55
+ activeTab: string
56
+ onTabChange: (tabId: string) => void
57
+ hasEndpoints?: boolean
58
+ docsName?: string | null
59
+ docsLogo?: DocsLogo | null
60
+ docsHeader?: DocsHeaderConfig | null
61
+ docsNavbar?: DocsNavbar | null
62
+ docGroups?: unknown[] // Keep for backward compatibility but not used
63
+ onSearchClick?: () => void
64
+ }
65
+
66
+ // Default logo fallback
67
+ const DEFAULT_LOGO = {
68
+ url: 'https://cdn.prod.website-files.com/639181964f4fe88697a20a0a/67af64a5ba42bb659b8560c9_Logo%20(3).svg',
69
+ alt: 'Logo',
70
+ width: 80,
71
+ height: 24,
72
+ }
73
+
74
+ export function DocsHeader({
75
+ navigationTabs = [],
76
+ activeTab,
77
+ onTabChange,
78
+ docsName,
79
+ docsLogo,
80
+ docsHeader,
81
+ docsNavbar,
82
+ onSearchClick,
83
+ }: DocsHeaderProps) {
84
+ const {
85
+ isMobile,
86
+ isLeftSidebarOpen,
87
+ isRightSidebarOpen,
88
+ toggleLeftSidebar,
89
+ toggleRightSidebar
90
+ } = useMobile()
91
+
92
+ // Use config values with defaults
93
+ // Support both single URL and separate light/dark logos
94
+ const hasLightDarkLogos = docsLogo?.light && docsLogo?.dark
95
+ const logo = {
96
+ url: docsLogo?.url || DEFAULT_LOGO.url,
97
+ light: docsLogo?.light,
98
+ dark: docsLogo?.dark,
99
+ alt: docsLogo?.alt || DEFAULT_LOGO.alt,
100
+ width: docsLogo?.width || DEFAULT_LOGO.width,
101
+ height: docsLogo?.height || DEFAULT_LOGO.height,
102
+ }
103
+
104
+ const showSearch = docsHeader?.showSearch !== false // Default true
105
+ const showThemeToggle = docsHeader?.showThemeToggle !== false // Default true
106
+
107
+ const navbarLinks = docsNavbar?.links || []
108
+ const navbarPrimary = docsNavbar?.primary
109
+
110
+ // Use navigation tabs directly from config (already ordered)
111
+ const tabs = navigationTabs.sort((a, b) => a.order - b.order)
112
+
113
+ return (
114
+ <header className="docs-header sticky top-0 z-50 bg-background border-b border-border">
115
+ {/* Main header row */}
116
+ <div className="flex h-14 w-full items-center justify-between px-3 sm:px-6">
117
+ {/* Left side: Menu button (mobile) + Logo */}
118
+ <div className="flex items-center gap-2">
119
+ {/* Mobile menu button */}
120
+ {isMobile && (
121
+ <Button
122
+ variant="ghost"
123
+ size="icon"
124
+ onClick={toggleLeftSidebar}
125
+ className="docs-header-menu-button lg:hidden h-9 w-9"
126
+ aria-label={isLeftSidebarOpen ? "Close menu" : "Open menu"}
127
+ >
128
+ {isLeftSidebarOpen ? (
129
+ <X className="h-5 w-5" weight="bold" />
130
+ ) : (
131
+ <List className="h-5 w-5" weight="bold" />
132
+ )}
133
+ </Button>
134
+ )}
135
+
136
+ <Link href="/" className="docs-header-logo flex items-center gap-2 sm:gap-3">
137
+ {hasLightDarkLogos ? (
138
+ <>
139
+ {/* Light mode logo */}
140
+ <Image
141
+ src={logo.light!}
142
+ alt={logo.alt}
143
+ width={logo.width}
144
+ height={logo.height}
145
+ className="w-auto dark:hidden"
146
+ style={{ height: logo.height }}
147
+ priority
148
+ />
149
+ {/* Dark mode logo */}
150
+ <Image
151
+ src={logo.dark!}
152
+ alt={logo.alt}
153
+ width={logo.width}
154
+ height={logo.height}
155
+ className="w-auto hidden dark:block"
156
+ style={{ height: logo.height }}
157
+ priority
158
+ />
159
+ </>
160
+ ) : (
161
+ <Image
162
+ src={logo.url}
163
+ alt={logo.alt}
164
+ width={logo.width}
165
+ height={logo.height}
166
+ className="w-auto dark:invert"
167
+ style={{ height: logo.height }}
168
+ priority
169
+ />
170
+ )}
171
+ {docsName && (
172
+ <>
173
+ <div className="hidden sm:block h-5 w-px bg-border" />
174
+ <span className="docs-header-title hidden sm:inline text-sm font-medium text-muted-foreground">
175
+ {docsName}
176
+ </span>
177
+ </>
178
+ )}
179
+ </Link>
180
+ </div>
181
+
182
+ {/* Center: Search bar */}
183
+ {showSearch && (
184
+ <div className="docs-header-search hidden md:flex flex-1 max-w-md mx-6">
185
+ <button
186
+ onClick={onSearchClick}
187
+ className="relative w-full flex items-center gap-2 px-3 h-9 bg-muted/50 border border-border rounded-md text-sm text-muted-foreground hover:bg-muted/70 transition-colors"
188
+ >
189
+ <MagnifyingGlass className="h-4 w-4" />
190
+ <span className="flex-1 text-left">Search...</span>
191
+ <kbd className="pointer-events-none hidden sm:inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium">
192
+ ⌘K
193
+ </kbd>
194
+ </button>
195
+ </div>
196
+ )}
197
+
198
+ {/* Right side: Nav items + Primary button + Theme toggle */}
199
+ <div className="flex items-center gap-1 sm:gap-2">
200
+ {/* Navbar links from config */}
201
+ {navbarLinks.length > 0 && (
202
+ <nav className="docs-header-nav hidden lg:flex items-center gap-1">
203
+ {navbarLinks.map((link) => (
204
+ <Link
205
+ key={link.href}
206
+ href={link.href}
207
+ className="docs-header-nav-link flex items-center gap-1.5 px-3 py-1.5 text-sm text-muted-foreground hover:text-foreground hover:bg-muted/50 rounded-sm transition-colors"
208
+ {...(link.external && { target: "_blank", rel: "noopener noreferrer" })}
209
+ >
210
+ <span>{link.label}</span>
211
+ {link.external && <ArrowSquareOut className="h-3.5 w-3.5" weight="bold" />}
212
+ </Link>
213
+ ))}
214
+ </nav>
215
+ )}
216
+
217
+ {/* Primary button from config */}
218
+ {navbarPrimary && (
219
+ <Button asChild size="sm" className="docs-header-button docs-button-primary hidden sm:flex">
220
+ <Link href={navbarPrimary.href}>
221
+ {navbarPrimary.label}
222
+ </Link>
223
+ </Button>
224
+ )}
225
+
226
+ {showThemeToggle && <ThemeToggle />}
227
+
228
+ {/* Mobile agent button */}
229
+ {isMobile && (
230
+ <Button
231
+ variant="ghost"
232
+ size="icon"
233
+ onClick={toggleRightSidebar}
234
+ className="docs-header-button lg:hidden h-9 w-9"
235
+ aria-label={isRightSidebarOpen ? "Close assistant" : "Open assistant"}
236
+ >
237
+ {isRightSidebarOpen ? (
238
+ <X className="h-5 w-5" weight="bold" />
239
+ ) : (
240
+ <ChatCircle className="h-5 w-5" weight="fill" />
241
+ )}
242
+ </Button>
243
+ )}
244
+ </div>
245
+ </div>
246
+
247
+ {/* Sub-header with tabs */}
248
+ {tabs.length > 0 && (
249
+ <div className="docs-tabs flex items-center px-3 sm:px-6 border-y border-border overflow-x-auto overflow-y-visible bg-muted/50 dark:bg-muted/20">
250
+ {tabs.map((t) => (
251
+ <button
252
+ key={t.id}
253
+ onClick={() => onTabChange(t.id)}
254
+ className={cn(
255
+ 'docs-tab relative px-4 py-2.5 text-sm font-medium whitespace-nowrap transition-colors',
256
+ activeTab === t.id
257
+ ? 'docs-tab-active text-foreground font-semibold'
258
+ : 'text-muted-foreground hover:text-foreground'
259
+ )}
260
+ >
261
+ {t.tab}
262
+ {/* Active indicator line */}
263
+ {activeTab === t.id && (
264
+ <span
265
+ className="absolute bottom-0 left-0 right-0 h-[2px] rounded-full bg-primary z-10"
266
+ />
267
+ )}
268
+ </button>
269
+ ))}
270
+ </div>
271
+ )}
272
+ </header>
273
+ )
274
+ }