jamdesk 1.0.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 (435) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +323 -0
  3. package/bin/jamdesk.js +76 -0
  4. package/dist/__tests__/integration/deprecated-components.integration.test.d.ts +8 -0
  5. package/dist/__tests__/integration/deprecated-components.integration.test.d.ts.map +1 -0
  6. package/dist/__tests__/integration/deprecated-components.integration.test.js +165 -0
  7. package/dist/__tests__/integration/deprecated-components.integration.test.js.map +1 -0
  8. package/dist/__tests__/integration/migrate.integration.test.d.ts +2 -0
  9. package/dist/__tests__/integration/migrate.integration.test.d.ts.map +1 -0
  10. package/dist/__tests__/integration/migrate.integration.test.js +64 -0
  11. package/dist/__tests__/integration/migrate.integration.test.js.map +1 -0
  12. package/dist/__tests__/integration/prepublish.integration.test.d.ts +2 -0
  13. package/dist/__tests__/integration/prepublish.integration.test.d.ts.map +1 -0
  14. package/dist/__tests__/integration/prepublish.integration.test.js +27 -0
  15. package/dist/__tests__/integration/prepublish.integration.test.js.map +1 -0
  16. package/dist/__tests__/integration/validate.integration.test.d.ts +2 -0
  17. package/dist/__tests__/integration/validate.integration.test.d.ts.map +1 -0
  18. package/dist/__tests__/integration/validate.integration.test.js +56 -0
  19. package/dist/__tests__/integration/validate.integration.test.js.map +1 -0
  20. package/dist/__tests__/unit/deploy-templates.test.d.ts +2 -0
  21. package/dist/__tests__/unit/deploy-templates.test.d.ts.map +1 -0
  22. package/dist/__tests__/unit/deploy-templates.test.js +124 -0
  23. package/dist/__tests__/unit/deploy-templates.test.js.map +1 -0
  24. package/dist/__tests__/unit/deprecated-components-sync.test.d.ts +2 -0
  25. package/dist/__tests__/unit/deprecated-components-sync.test.d.ts.map +1 -0
  26. package/dist/__tests__/unit/deprecated-components-sync.test.js +69 -0
  27. package/dist/__tests__/unit/deprecated-components-sync.test.js.map +1 -0
  28. package/dist/__tests__/unit/deps-sync.test.d.ts +14 -0
  29. package/dist/__tests__/unit/deps-sync.test.d.ts.map +1 -0
  30. package/dist/__tests__/unit/deps-sync.test.js +166 -0
  31. package/dist/__tests__/unit/deps-sync.test.js.map +1 -0
  32. package/dist/__tests__/unit/docs-config.test.d.ts +2 -0
  33. package/dist/__tests__/unit/docs-config.test.d.ts.map +1 -0
  34. package/dist/__tests__/unit/docs-config.test.js +288 -0
  35. package/dist/__tests__/unit/docs-config.test.js.map +1 -0
  36. package/dist/__tests__/unit/errors.test.d.ts +2 -0
  37. package/dist/__tests__/unit/errors.test.d.ts.map +1 -0
  38. package/dist/__tests__/unit/errors.test.js +27 -0
  39. package/dist/__tests__/unit/errors.test.js.map +1 -0
  40. package/dist/__tests__/unit/extract-hooks.test.d.ts +5 -0
  41. package/dist/__tests__/unit/extract-hooks.test.d.ts.map +1 -0
  42. package/dist/__tests__/unit/extract-hooks.test.js +205 -0
  43. package/dist/__tests__/unit/extract-hooks.test.js.map +1 -0
  44. package/dist/__tests__/unit/frontmatter-sync.test.d.ts +8 -0
  45. package/dist/__tests__/unit/frontmatter-sync.test.d.ts.map +1 -0
  46. package/dist/__tests__/unit/frontmatter-sync.test.js +26 -0
  47. package/dist/__tests__/unit/frontmatter-sync.test.js.map +1 -0
  48. package/dist/__tests__/unit/mdx-validator.test.d.ts +2 -0
  49. package/dist/__tests__/unit/mdx-validator.test.d.ts.map +1 -0
  50. package/dist/__tests__/unit/mdx-validator.test.js +264 -0
  51. package/dist/__tests__/unit/mdx-validator.test.js.map +1 -0
  52. package/dist/__tests__/unit/migrate-convert.test.d.ts +2 -0
  53. package/dist/__tests__/unit/migrate-convert.test.d.ts.map +1 -0
  54. package/dist/__tests__/unit/migrate-convert.test.js +297 -0
  55. package/dist/__tests__/unit/migrate-convert.test.js.map +1 -0
  56. package/dist/__tests__/unit/migrate-detect.test.d.ts +2 -0
  57. package/dist/__tests__/unit/migrate-detect.test.d.ts.map +1 -0
  58. package/dist/__tests__/unit/migrate-detect.test.js +35 -0
  59. package/dist/__tests__/unit/migrate-detect.test.js.map +1 -0
  60. package/dist/__tests__/unit/migrate-mdx.test.d.ts +2 -0
  61. package/dist/__tests__/unit/migrate-mdx.test.d.ts.map +1 -0
  62. package/dist/__tests__/unit/migrate-mdx.test.js +158 -0
  63. package/dist/__tests__/unit/migrate-mdx.test.js.map +1 -0
  64. package/dist/__tests__/unit/openapi.test.d.ts +2 -0
  65. package/dist/__tests__/unit/openapi.test.d.ts.map +1 -0
  66. package/dist/__tests__/unit/openapi.test.js +52 -0
  67. package/dist/__tests__/unit/openapi.test.js.map +1 -0
  68. package/dist/__tests__/unit/package-config.test.d.ts +2 -0
  69. package/dist/__tests__/unit/package-config.test.d.ts.map +1 -0
  70. package/dist/__tests__/unit/package-config.test.js +63 -0
  71. package/dist/__tests__/unit/package-config.test.js.map +1 -0
  72. package/dist/__tests__/unit/port.test.d.ts +2 -0
  73. package/dist/__tests__/unit/port.test.d.ts.map +1 -0
  74. package/dist/__tests__/unit/port.test.js +20 -0
  75. package/dist/__tests__/unit/port.test.js.map +1 -0
  76. package/dist/__tests__/unit/vendored-sync.test.d.ts +14 -0
  77. package/dist/__tests__/unit/vendored-sync.test.d.ts.map +1 -0
  78. package/dist/__tests__/unit/vendored-sync.test.js +90 -0
  79. package/dist/__tests__/unit/vendored-sync.test.js.map +1 -0
  80. package/dist/commands/broken-links.d.ts +11 -0
  81. package/dist/commands/broken-links.d.ts.map +1 -0
  82. package/dist/commands/broken-links.js +95 -0
  83. package/dist/commands/broken-links.js.map +1 -0
  84. package/dist/commands/clean.d.ts +7 -0
  85. package/dist/commands/clean.d.ts.map +1 -0
  86. package/dist/commands/clean.js +59 -0
  87. package/dist/commands/clean.js.map +1 -0
  88. package/dist/commands/deploy/cloudflare.d.ts +12 -0
  89. package/dist/commands/deploy/cloudflare.d.ts.map +1 -0
  90. package/dist/commands/deploy/cloudflare.js +409 -0
  91. package/dist/commands/deploy/cloudflare.js.map +1 -0
  92. package/dist/commands/deploy/templates.d.ts +23 -0
  93. package/dist/commands/deploy/templates.d.ts.map +1 -0
  94. package/dist/commands/deploy/templates.js +179 -0
  95. package/dist/commands/deploy/templates.js.map +1 -0
  96. package/dist/commands/deploy/types.d.ts +19 -0
  97. package/dist/commands/deploy/types.d.ts.map +1 -0
  98. package/dist/commands/deploy/types.js +5 -0
  99. package/dist/commands/deploy/types.js.map +1 -0
  100. package/dist/commands/dev.d.ts +14 -0
  101. package/dist/commands/dev.d.ts.map +1 -0
  102. package/dist/commands/dev.js +817 -0
  103. package/dist/commands/dev.js.map +1 -0
  104. package/dist/commands/doctor.d.ts +7 -0
  105. package/dist/commands/doctor.d.ts.map +1 -0
  106. package/dist/commands/doctor.js +159 -0
  107. package/dist/commands/doctor.js.map +1 -0
  108. package/dist/commands/init.d.ts +7 -0
  109. package/dist/commands/init.d.ts.map +1 -0
  110. package/dist/commands/init.js +96 -0
  111. package/dist/commands/init.js.map +1 -0
  112. package/dist/commands/migrate/convert-mdx.d.ts +50 -0
  113. package/dist/commands/migrate/convert-mdx.d.ts.map +1 -0
  114. package/dist/commands/migrate/convert-mdx.js +108 -0
  115. package/dist/commands/migrate/convert-mdx.js.map +1 -0
  116. package/dist/commands/migrate/convert.d.ts +80 -0
  117. package/dist/commands/migrate/convert.d.ts.map +1 -0
  118. package/dist/commands/migrate/convert.js +158 -0
  119. package/dist/commands/migrate/convert.js.map +1 -0
  120. package/dist/commands/migrate/detect.d.ts +31 -0
  121. package/dist/commands/migrate/detect.d.ts.map +1 -0
  122. package/dist/commands/migrate/detect.js +62 -0
  123. package/dist/commands/migrate/detect.js.map +1 -0
  124. package/dist/commands/migrate/extract-hooks.d.ts +71 -0
  125. package/dist/commands/migrate/extract-hooks.d.ts.map +1 -0
  126. package/dist/commands/migrate/extract-hooks.js +473 -0
  127. package/dist/commands/migrate/extract-hooks.js.map +1 -0
  128. package/dist/commands/migrate/index.d.ts +17 -0
  129. package/dist/commands/migrate/index.d.ts.map +1 -0
  130. package/dist/commands/migrate/index.js +282 -0
  131. package/dist/commands/migrate/index.js.map +1 -0
  132. package/dist/commands/migrate/prompts.d.ts +22 -0
  133. package/dist/commands/migrate/prompts.d.ts.map +1 -0
  134. package/dist/commands/migrate/prompts.js +67 -0
  135. package/dist/commands/migrate/prompts.js.map +1 -0
  136. package/dist/commands/migrate/types.d.ts +22 -0
  137. package/dist/commands/migrate/types.d.ts.map +1 -0
  138. package/dist/commands/migrate/types.js +26 -0
  139. package/dist/commands/migrate/types.js.map +1 -0
  140. package/dist/commands/openapi-check.d.ts +11 -0
  141. package/dist/commands/openapi-check.d.ts.map +1 -0
  142. package/dist/commands/openapi-check.js +88 -0
  143. package/dist/commands/openapi-check.js.map +1 -0
  144. package/dist/commands/rename.d.ts +10 -0
  145. package/dist/commands/rename.d.ts.map +1 -0
  146. package/dist/commands/rename.js +125 -0
  147. package/dist/commands/rename.js.map +1 -0
  148. package/dist/commands/update.d.ts +10 -0
  149. package/dist/commands/update.d.ts.map +1 -0
  150. package/dist/commands/update.js +57 -0
  151. package/dist/commands/update.js.map +1 -0
  152. package/dist/commands/validate.d.ts +12 -0
  153. package/dist/commands/validate.d.ts.map +1 -0
  154. package/dist/commands/validate.js +163 -0
  155. package/dist/commands/validate.js.map +1 -0
  156. package/dist/index.d.ts +9 -0
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +334 -0
  159. package/dist/index.js.map +1 -0
  160. package/dist/lib/config.d.ts +7 -0
  161. package/dist/lib/config.d.ts.map +1 -0
  162. package/dist/lib/config.js +18 -0
  163. package/dist/lib/config.js.map +1 -0
  164. package/dist/lib/deprecated-components.d.ts +72 -0
  165. package/dist/lib/deprecated-components.d.ts.map +1 -0
  166. package/dist/lib/deprecated-components.js +138 -0
  167. package/dist/lib/deprecated-components.js.map +1 -0
  168. package/dist/lib/deps.d.ts +17 -0
  169. package/dist/lib/deps.d.ts.map +1 -0
  170. package/dist/lib/deps.js +186 -0
  171. package/dist/lib/deps.js.map +1 -0
  172. package/dist/lib/docs-config.d.ts +67 -0
  173. package/dist/lib/docs-config.d.ts.map +1 -0
  174. package/dist/lib/docs-config.js +294 -0
  175. package/dist/lib/docs-config.js.map +1 -0
  176. package/dist/lib/errors.d.ts +23 -0
  177. package/dist/lib/errors.d.ts.map +1 -0
  178. package/dist/lib/errors.js +32 -0
  179. package/dist/lib/errors.js.map +1 -0
  180. package/dist/lib/frontmatter-utils.d.ts +25 -0
  181. package/dist/lib/frontmatter-utils.d.ts.map +1 -0
  182. package/dist/lib/frontmatter-utils.js +64 -0
  183. package/dist/lib/frontmatter-utils.js.map +1 -0
  184. package/dist/lib/mdx-validator.d.ts +27 -0
  185. package/dist/lib/mdx-validator.d.ts.map +1 -0
  186. package/dist/lib/mdx-validator.js +148 -0
  187. package/dist/lib/mdx-validator.js.map +1 -0
  188. package/dist/lib/navigation-validator.d.ts +31 -0
  189. package/dist/lib/navigation-validator.d.ts.map +1 -0
  190. package/dist/lib/navigation-validator.js +75 -0
  191. package/dist/lib/navigation-validator.js.map +1 -0
  192. package/dist/lib/normalize-config.d.ts +57 -0
  193. package/dist/lib/normalize-config.d.ts.map +1 -0
  194. package/dist/lib/normalize-config.js +63 -0
  195. package/dist/lib/normalize-config.js.map +1 -0
  196. package/dist/lib/openapi/cache.d.ts +40 -0
  197. package/dist/lib/openapi/cache.d.ts.map +1 -0
  198. package/dist/lib/openapi/cache.js +76 -0
  199. package/dist/lib/openapi/cache.js.map +1 -0
  200. package/dist/lib/openapi/errors.d.ts +36 -0
  201. package/dist/lib/openapi/errors.d.ts.map +1 -0
  202. package/dist/lib/openapi/errors.js +162 -0
  203. package/dist/lib/openapi/errors.js.map +1 -0
  204. package/dist/lib/openapi/index.d.ts +10 -0
  205. package/dist/lib/openapi/index.d.ts.map +1 -0
  206. package/dist/lib/openapi/index.js +12 -0
  207. package/dist/lib/openapi/index.js.map +1 -0
  208. package/dist/lib/openapi/types.d.ts +198 -0
  209. package/dist/lib/openapi/types.d.ts.map +1 -0
  210. package/dist/lib/openapi/types.js +8 -0
  211. package/dist/lib/openapi/types.js.map +1 -0
  212. package/dist/lib/openapi/validator.d.ts +45 -0
  213. package/dist/lib/openapi/validator.d.ts.map +1 -0
  214. package/dist/lib/openapi/validator.js +128 -0
  215. package/dist/lib/openapi/validator.js.map +1 -0
  216. package/dist/lib/openapi.d.ts +7 -0
  217. package/dist/lib/openapi.d.ts.map +1 -0
  218. package/dist/lib/openapi.js +7 -0
  219. package/dist/lib/openapi.js.map +1 -0
  220. package/dist/lib/output.d.ts +14 -0
  221. package/dist/lib/output.d.ts.map +1 -0
  222. package/dist/lib/output.js +19 -0
  223. package/dist/lib/output.js.map +1 -0
  224. package/dist/lib/path-security.d.ts +23 -0
  225. package/dist/lib/path-security.d.ts.map +1 -0
  226. package/dist/lib/path-security.js +35 -0
  227. package/dist/lib/path-security.js.map +1 -0
  228. package/dist/lib/port.d.ts +18 -0
  229. package/dist/lib/port.d.ts.map +1 -0
  230. package/dist/lib/port.js +65 -0
  231. package/dist/lib/port.js.map +1 -0
  232. package/dist/lib/spinner.d.ts +4 -0
  233. package/dist/lib/spinner.d.ts.map +1 -0
  234. package/dist/lib/spinner.js +16 -0
  235. package/dist/lib/spinner.js.map +1 -0
  236. package/dist/lib/version.d.ts +2 -0
  237. package/dist/lib/version.d.ts.map +1 -0
  238. package/dist/lib/version.js +49 -0
  239. package/dist/lib/version.js.map +1 -0
  240. package/dist/utils/update-checker.d.ts +34 -0
  241. package/dist/utils/update-checker.d.ts.map +1 -0
  242. package/dist/utils/update-checker.js +142 -0
  243. package/dist/utils/update-checker.js.map +1 -0
  244. package/package.json +125 -0
  245. package/templates/docs.json +11 -0
  246. package/templates/introduction.mdx +19 -0
  247. package/templates/quickstart.mdx +20 -0
  248. package/vendored/app/[[...slug]]/error.tsx +103 -0
  249. package/vendored/app/[[...slug]]/page.tsx +690 -0
  250. package/vendored/app/api/assets/[...path]/route.ts +78 -0
  251. package/vendored/app/api/ev/route.ts +61 -0
  252. package/vendored/app/api/isr-health/route.ts +66 -0
  253. package/vendored/app/api/mcp/[project]/route.ts +435 -0
  254. package/vendored/app/api/og/route.tsx +167 -0
  255. package/vendored/app/api/r2/[project]/[...path]/route.ts +214 -0
  256. package/vendored/app/api/revalidate/route.ts +76 -0
  257. package/vendored/app/globals.css +37 -0
  258. package/vendored/app/layout.tsx +571 -0
  259. package/vendored/app/not-found.tsx +47 -0
  260. package/vendored/components/CodeBlockCopyButton.tsx +146 -0
  261. package/vendored/components/HeaderLinkCopy.tsx +135 -0
  262. package/vendored/components/errors/NotFoundContent.tsx +147 -0
  263. package/vendored/components/layout/LayoutWrapper.tsx +128 -0
  264. package/vendored/components/mdx/Accordion.tsx +91 -0
  265. package/vendored/components/mdx/ApiCodePanel.tsx +51 -0
  266. package/vendored/components/mdx/ApiEndpoint.tsx +104 -0
  267. package/vendored/components/mdx/ApiPage.tsx +379 -0
  268. package/vendored/components/mdx/Badge.tsx +169 -0
  269. package/vendored/components/mdx/Callouts.tsx +140 -0
  270. package/vendored/components/mdx/Card.tsx +214 -0
  271. package/vendored/components/mdx/CodeGroup.tsx +136 -0
  272. package/vendored/components/mdx/Color.tsx +244 -0
  273. package/vendored/components/mdx/Columns.tsx +37 -0
  274. package/vendored/components/mdx/Expandable.tsx +37 -0
  275. package/vendored/components/mdx/Frame.tsx +51 -0
  276. package/vendored/components/mdx/Icon.tsx +132 -0
  277. package/vendored/components/mdx/Latex.tsx +75 -0
  278. package/vendored/components/mdx/MDXComponents.tsx +414 -0
  279. package/vendored/components/mdx/Mermaid.tsx +35 -0
  280. package/vendored/components/mdx/MermaidInner.tsx +342 -0
  281. package/vendored/components/mdx/OpenApiEndpoint.tsx +971 -0
  282. package/vendored/components/mdx/Panel.tsx +26 -0
  283. package/vendored/components/mdx/PanelWrapper.tsx +100 -0
  284. package/vendored/components/mdx/ParamField.tsx +75 -0
  285. package/vendored/components/mdx/RequestExample.tsx +91 -0
  286. package/vendored/components/mdx/ResponseExample.tsx +145 -0
  287. package/vendored/components/mdx/ResponseField.tsx +109 -0
  288. package/vendored/components/mdx/Steps.tsx +173 -0
  289. package/vendored/components/mdx/Table.tsx +352 -0
  290. package/vendored/components/mdx/Tabs.tsx +147 -0
  291. package/vendored/components/mdx/Tile.tsx +127 -0
  292. package/vendored/components/mdx/Tooltip.tsx +111 -0
  293. package/vendored/components/mdx/Tree.tsx +484 -0
  294. package/vendored/components/mdx/Update.tsx +90 -0
  295. package/vendored/components/mdx/View.tsx +354 -0
  296. package/vendored/components/mdx/YouTube.tsx +35 -0
  297. package/vendored/components/mdx/ZoomableImage.tsx +83 -0
  298. package/vendored/components/navigation/Breadcrumb.tsx +241 -0
  299. package/vendored/components/navigation/DefaultLogo.tsx +81 -0
  300. package/vendored/components/navigation/Header.tsx +512 -0
  301. package/vendored/components/navigation/LanguageSelector.tsx +249 -0
  302. package/vendored/components/navigation/PageNavigation.tsx +174 -0
  303. package/vendored/components/navigation/Sidebar.tsx +713 -0
  304. package/vendored/components/navigation/SocialFooter.tsx +186 -0
  305. package/vendored/components/navigation/TableOfContents.tsx +435 -0
  306. package/vendored/components/navigation/TabsNav.tsx +182 -0
  307. package/vendored/components/search/LazySearchModal.tsx +19 -0
  308. package/vendored/components/search/SearchModal.tsx +573 -0
  309. package/vendored/components/snippets/ProjectSnippets.tsx +4 -0
  310. package/vendored/components/theme/ThemeProvider.tsx +31 -0
  311. package/vendored/components/theme/ThemeToggle.tsx +134 -0
  312. package/vendored/components/ui/CodePanel.tsx +517 -0
  313. package/vendored/components/ui/CodePanelModal.tsx +342 -0
  314. package/vendored/contexts/TabSyncContext.tsx +30 -0
  315. package/vendored/hooks/useFocusTrap.ts +42 -0
  316. package/vendored/hooks/useHashNavigation.ts +39 -0
  317. package/vendored/hooks/useShikiHighlight.ts +101 -0
  318. package/vendored/lib/analytics-client.ts +77 -0
  319. package/vendored/lib/build/cache.ts +138 -0
  320. package/vendored/lib/build/error-parser.ts +690 -0
  321. package/vendored/lib/build/estimation.ts +113 -0
  322. package/vendored/lib/build/index.ts +17 -0
  323. package/vendored/lib/build/page-file-map.ts +48 -0
  324. package/vendored/lib/build/r2-upload.ts +179 -0
  325. package/vendored/lib/cache-keys.ts +117 -0
  326. package/vendored/lib/code-utils.ts +42 -0
  327. package/vendored/lib/content-loader.ts +176 -0
  328. package/vendored/lib/deprecated-components.ts +185 -0
  329. package/vendored/lib/docs-isr.ts +180 -0
  330. package/vendored/lib/docs-types.ts +874 -0
  331. package/vendored/lib/docs.ts +203 -0
  332. package/vendored/lib/domain-helpers.ts +107 -0
  333. package/vendored/lib/email-notifier.ts +102 -0
  334. package/vendored/lib/email-templates/build-failure.tsx +193 -0
  335. package/vendored/lib/email-templates/components/base-layout.tsx +150 -0
  336. package/vendored/lib/email-templates/components/error-box.tsx +88 -0
  337. package/vendored/lib/email-templates/components/info-row.tsx +63 -0
  338. package/vendored/lib/email-templates/index.ts +13 -0
  339. package/vendored/lib/empty-polyfill.js +3 -0
  340. package/vendored/lib/extract-highlights.ts +124 -0
  341. package/vendored/lib/fonts.ts +227 -0
  342. package/vendored/lib/frontmatter-utils.ts +77 -0
  343. package/vendored/lib/fs-utils.ts +20 -0
  344. package/vendored/lib/git-utils.ts +87 -0
  345. package/vendored/lib/health-checks.ts +224 -0
  346. package/vendored/lib/icon-utils.ts +492 -0
  347. package/vendored/lib/infer-page-type.ts +14 -0
  348. package/vendored/lib/isr-build-executor.ts +185 -0
  349. package/vendored/lib/language-icons.ts +152 -0
  350. package/vendored/lib/language-utils.ts +338 -0
  351. package/vendored/lib/latex-config.ts +64 -0
  352. package/vendored/lib/link-prefix-context.tsx +32 -0
  353. package/vendored/lib/logger.ts +63 -0
  354. package/vendored/lib/mcp-search.ts +255 -0
  355. package/vendored/lib/mdx-inline-components.ts +155 -0
  356. package/vendored/lib/mdx.ts +100 -0
  357. package/vendored/lib/middleware-helpers.ts +519 -0
  358. package/vendored/lib/navigation-resolver.ts +621 -0
  359. package/vendored/lib/navigation-utils.ts +103 -0
  360. package/vendored/lib/normalize-config.ts +94 -0
  361. package/vendored/lib/openapi/cache.ts +92 -0
  362. package/vendored/lib/openapi/code-examples.ts +389 -0
  363. package/vendored/lib/openapi/errors.ts +253 -0
  364. package/vendored/lib/openapi/generator.ts +230 -0
  365. package/vendored/lib/openapi/index.ts +84 -0
  366. package/vendored/lib/openapi/parser.ts +474 -0
  367. package/vendored/lib/openapi/types.ts +232 -0
  368. package/vendored/lib/openapi/validator.ts +156 -0
  369. package/vendored/lib/openapi-isr.ts +121 -0
  370. package/vendored/lib/page-isr-helpers.ts +137 -0
  371. package/vendored/lib/path-safety.ts +130 -0
  372. package/vendored/lib/paths.ts +35 -0
  373. package/vendored/lib/preprocess-mdx.ts +951 -0
  374. package/vendored/lib/process-mdx-with-exports.ts +75 -0
  375. package/vendored/lib/project-resolver.ts +165 -0
  376. package/vendored/lib/r2-content.ts +60 -0
  377. package/vendored/lib/r2-manifest.ts +84 -0
  378. package/vendored/lib/recent-searches.ts +41 -0
  379. package/vendored/lib/recma-compound-components.ts +84 -0
  380. package/vendored/lib/redirect-compiler.ts +160 -0
  381. package/vendored/lib/redirect-matcher.ts +296 -0
  382. package/vendored/lib/redis.ts +23 -0
  383. package/vendored/lib/rehype-class-to-classname.ts +31 -0
  384. package/vendored/lib/rehype-code-meta.ts +275 -0
  385. package/vendored/lib/rehype-nozoom-to-data.ts +45 -0
  386. package/vendored/lib/remark-extract-exports.ts +104 -0
  387. package/vendored/lib/resilience.ts +260 -0
  388. package/vendored/lib/revalidation-helpers.ts +200 -0
  389. package/vendored/lib/revalidation-trigger.ts +150 -0
  390. package/vendored/lib/screenshot-capture.ts +229 -0
  391. package/vendored/lib/search-client.ts +91 -0
  392. package/vendored/lib/search-suggestions.ts +38 -0
  393. package/vendored/lib/search.ts +158 -0
  394. package/vendored/lib/seo.ts +264 -0
  395. package/vendored/lib/shiki-client.ts +131 -0
  396. package/vendored/lib/shiki-config.ts +289 -0
  397. package/vendored/lib/shiki-css-theme.ts +46 -0
  398. package/vendored/lib/shiki-highlighter.ts +62 -0
  399. package/vendored/lib/shiki-transformers.ts +337 -0
  400. package/vendored/lib/slack-notifier.ts +248 -0
  401. package/vendored/lib/snippet-compiler-isr.ts +114 -0
  402. package/vendored/lib/snippet-loader-isr.ts +276 -0
  403. package/vendored/lib/static-artifacts.ts +375 -0
  404. package/vendored/lib/static-file-route.ts +72 -0
  405. package/vendored/lib/tracking-script.ts +19 -0
  406. package/vendored/lib/typography-config.ts +42 -0
  407. package/vendored/lib/validate-config.ts +268 -0
  408. package/vendored/next.config.js +45 -0
  409. package/vendored/postcss.config.js +6 -0
  410. package/vendored/schema/README.md +28 -0
  411. package/vendored/schema/docs-schema.json +4631 -0
  412. package/vendored/scripts/build-project.cjs +174 -0
  413. package/vendored/scripts/build-search-index.cjs +347 -0
  414. package/vendored/scripts/compile-snippets.cjs +488 -0
  415. package/vendored/scripts/copy-files.cjs +295 -0
  416. package/vendored/scripts/dev-project.cjs +534 -0
  417. package/vendored/scripts/enhance-navigation.cjs +354 -0
  418. package/vendored/scripts/validate-links.cjs +423 -0
  419. package/vendored/shared/constants.ts +6 -0
  420. package/vendored/shared/index.ts +19 -0
  421. package/vendored/shared/logger.ts +62 -0
  422. package/vendored/shared/memory-monitor.ts +190 -0
  423. package/vendored/shared/navigation-validator.ts +101 -0
  424. package/vendored/shared/path-security.ts +39 -0
  425. package/vendored/shared/status-reporter.ts +199 -0
  426. package/vendored/shared/timer.ts +51 -0
  427. package/vendored/shared/types.ts +102 -0
  428. package/vendored/tailwind.config.ts +39 -0
  429. package/vendored/themes/base.css +1311 -0
  430. package/vendored/themes/index.ts +119 -0
  431. package/vendored/themes/jam/variables.css +835 -0
  432. package/vendored/themes/nebula/variables.css +282 -0
  433. package/vendored/themes/pulsar/variables.css +1009 -0
  434. package/vendored/themes/types.ts +89 -0
  435. package/vendored/tsconfig.json +48 -0
@@ -0,0 +1,146 @@
1
+ 'use client';
2
+
3
+ import { useEffect } from 'react';
4
+ import { usePathname } from 'next/navigation';
5
+
6
+ /**
7
+ * Helper to create an icon element safely
8
+ */
9
+ function createIcon(iconClass: string, additionalClass?: string): HTMLElement {
10
+ const icon = document.createElement('i');
11
+ icon.className = `${iconClass} text-sm${additionalClass ? ' ' + additionalClass : ''}`;
12
+ icon.setAttribute('aria-hidden', 'true');
13
+ return icon;
14
+ }
15
+
16
+ /**
17
+ * Client component that adds copy buttons to code blocks after hydration.
18
+ * This avoids server/client component conflicts by manipulating the DOM directly.
19
+ * Also enables copy functionality for HTTP code blocks.
20
+ * Re-runs on page changes to handle new code blocks from client-side navigation.
21
+ */
22
+ export function CodeBlockCopyButton() {
23
+ const pathname = usePathname();
24
+
25
+ useEffect(() => {
26
+ // Enable copy functionality for HTTP code blocks
27
+ const httpBlocks = document.querySelectorAll('.http-code-block:not([data-copy-initialized])');
28
+ httpBlocks.forEach((block) => {
29
+ block.setAttribute('data-copy-initialized', 'true');
30
+ const copyBtn = block.querySelector('.http-copy-btn');
31
+ const copyText = block.getAttribute('data-copy-text');
32
+
33
+ if (copyBtn && copyText) {
34
+ copyBtn.addEventListener('click', async () => {
35
+ try {
36
+ await navigator.clipboard.writeText(copyText);
37
+ // Replace icon with check
38
+ const icon = copyBtn.querySelector('i');
39
+ if (icon) {
40
+ icon.className = 'fa-solid fa-check text-sm text-emerald-500';
41
+ setTimeout(() => {
42
+ icon.className = 'fa-regular fa-copy text-sm';
43
+ }, 2000);
44
+ }
45
+ } catch (err) {
46
+ console.error('Failed to copy:', err);
47
+ }
48
+ });
49
+ }
50
+ });
51
+
52
+ // Enable copy functionality for Color component items
53
+ const colorItems = document.querySelectorAll('.color-item-compact:not([data-copy-initialized]), .color-item-table:not([data-copy-initialized])');
54
+ colorItems.forEach((item) => {
55
+ item.setAttribute('data-copy-initialized', 'true');
56
+ const copyText = item.getAttribute('data-copy-text');
57
+
58
+ if (copyText) {
59
+ item.addEventListener('click', async () => {
60
+ try {
61
+ await navigator.clipboard.writeText(copyText);
62
+ // Show feedback via icon if present (table variant)
63
+ const icon = item.querySelector('i.fa-copy');
64
+ if (icon) {
65
+ icon.className = 'fa-solid fa-check text-xs text-emerald-500';
66
+ setTimeout(() => {
67
+ icon.className = 'fa-regular fa-copy text-xs text-[var(--color-text-muted)]';
68
+ }, 2000);
69
+ }
70
+ } catch (err) {
71
+ console.error('Failed to copy:', err);
72
+ }
73
+ });
74
+ }
75
+ });
76
+
77
+ // Find all pre.shiki elements that don't already have a copy button
78
+ const allCodeBlocks = document.querySelectorAll('pre.shiki:not([data-copy-button])');
79
+
80
+ allCodeBlocks.forEach((pre) => {
81
+ // Skip code blocks inside CodePanel (they already have a copy button in the header)
82
+ if (pre.closest('[data-code-panel]')) {
83
+ return;
84
+ }
85
+ // Mark as processed
86
+ pre.setAttribute('data-copy-button', 'true');
87
+
88
+ // Create wrapper div
89
+ const wrapper = document.createElement('div');
90
+ wrapper.className = 'code-block-wrapper relative group';
91
+ wrapper.style.cssText = 'position: relative;';
92
+
93
+ // Insert wrapper before pre and move pre inside
94
+ pre.parentNode?.insertBefore(wrapper, pre);
95
+ wrapper.appendChild(pre);
96
+
97
+ // Create copy button - minimal styling to match HTTP code block
98
+ const button = document.createElement('button');
99
+ button.className = 'code-copy-btn';
100
+ button.title = 'Copy code';
101
+ button.appendChild(createIcon('fa-regular fa-copy'));
102
+ button.style.cssText = `
103
+ position: absolute;
104
+ top: 8px;
105
+ right: 8px;
106
+ padding: 6px;
107
+ background: transparent;
108
+ border: none;
109
+ border-radius: var(--radius-sm, 6px);
110
+ color: var(--color-text-muted, #6b7280);
111
+ cursor: pointer;
112
+ transition: color 0.2s, background-color 0.2s;
113
+ z-index: 10;
114
+ `;
115
+
116
+ // Copy functionality
117
+ button.addEventListener('click', async () => {
118
+ const code = pre.textContent || '';
119
+ try {
120
+ await navigator.clipboard.writeText(code);
121
+ // Replace icon with check
122
+ button.replaceChildren(createIcon('fa-solid fa-check', 'text-emerald-500'));
123
+ setTimeout(() => {
124
+ button.replaceChildren(createIcon('fa-regular fa-copy'));
125
+ }, 2000);
126
+ } catch (err) {
127
+ console.error('Failed to copy:', err);
128
+ }
129
+ });
130
+
131
+ // Hover effect - subtle background like HTTP code block
132
+ button.addEventListener('mouseenter', () => {
133
+ button.style.backgroundColor = 'var(--color-bg-secondary, rgba(0,0,0,0.1))';
134
+ button.style.color = 'var(--color-text-primary, #111827)';
135
+ });
136
+ button.addEventListener('mouseleave', () => {
137
+ button.style.backgroundColor = 'transparent';
138
+ button.style.color = 'var(--color-text-muted, #6b7280)';
139
+ });
140
+
141
+ wrapper.appendChild(button);
142
+ });
143
+ }, [pathname]); // Re-run when pathname changes (client-side navigation)
144
+
145
+ return null;
146
+ }
@@ -0,0 +1,135 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useCallback } from 'react';
4
+ import { usePathname } from 'next/navigation';
5
+
6
+ /**
7
+ * Helper to create an icon element
8
+ */
9
+ function createIcon(iconClass: string): HTMLElement {
10
+ const icon = document.createElement('i');
11
+ icon.className = iconClass;
12
+ icon.setAttribute('aria-hidden', 'true');
13
+ return icon;
14
+ }
15
+
16
+ /**
17
+ * Copy text to clipboard and return success status
18
+ */
19
+ async function copyToClipboard(text: string): Promise<boolean> {
20
+ try {
21
+ await navigator.clipboard.writeText(text);
22
+ return true;
23
+ } catch (err) {
24
+ console.error('Failed to copy:', err);
25
+ return false;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Client component that adds link icons and copy functionality to H2/H3 headings.
31
+ * - Hover: Shows link icon to the left of header text (instant, no animation)
32
+ * - Click header text: Copies link AND navigates to anchor
33
+ * - Click icon: Copies link only (no navigation)
34
+ * - Visual feedback: Icon turns accent color for 1.5s after copy
35
+ * - Mobile: Icon hidden, headers function normally
36
+ */
37
+ export function HeaderLinkCopy() {
38
+ const pathname = usePathname();
39
+
40
+ const processHeadings = useCallback(() => {
41
+ // Find all h2 and h3 elements with IDs in main content that haven't been processed
42
+ const headings = document.querySelectorAll(
43
+ 'main h2[id]:not([data-header-link]), main h3[id]:not([data-header-link])'
44
+ );
45
+
46
+ headings.forEach((heading) => {
47
+ const headingEl = heading as HTMLHeadingElement;
48
+ const headingId = headingEl.id;
49
+ const headingText = headingEl.textContent?.trim() || '';
50
+
51
+ // Skip empty headings
52
+ if (!headingId || !headingText) return;
53
+
54
+ // Mark as processed
55
+ headingEl.setAttribute('data-header-link', 'true');
56
+ headingEl.classList.add('header-link-wrapper');
57
+
58
+ // Move all existing child nodes to a document fragment
59
+ const fragment = document.createDocumentFragment();
60
+ while (headingEl.firstChild) {
61
+ fragment.appendChild(headingEl.firstChild);
62
+ }
63
+
64
+ // Create link icon element
65
+ const linkIcon = document.createElement('a');
66
+ linkIcon.href = `#${headingId}`;
67
+ linkIcon.className = 'header-link-icon';
68
+ linkIcon.setAttribute('aria-label', `Copy link to ${headingText}`);
69
+ linkIcon.appendChild(createIcon('fa-solid fa-link'));
70
+
71
+ // Create text wrapper and move original content into it
72
+ const textWrapper = document.createElement('span');
73
+ textWrapper.className = 'header-link-text';
74
+ textWrapper.appendChild(fragment);
75
+
76
+ // Add new structure to heading
77
+ headingEl.appendChild(linkIcon);
78
+ headingEl.appendChild(textWrapper);
79
+
80
+ // Build the full URL for copying
81
+ const buildUrl = () => {
82
+ return `${window.location.origin}${window.location.pathname}#${headingId}`;
83
+ };
84
+
85
+ // Visual feedback function
86
+ const showCopiedFeedback = () => {
87
+ linkIcon.classList.add('copied');
88
+ setTimeout(() => {
89
+ linkIcon.classList.remove('copied');
90
+ }, 1500);
91
+ };
92
+
93
+ // Icon click: Copy only, no navigation
94
+ linkIcon.addEventListener('click', async (e) => {
95
+ e.preventDefault();
96
+ e.stopPropagation();
97
+
98
+ const url = buildUrl();
99
+ const success = await copyToClipboard(url);
100
+ if (success) {
101
+ showCopiedFeedback();
102
+ }
103
+ });
104
+
105
+ // Text click: Copy AND navigate
106
+ textWrapper.addEventListener('click', async (e) => {
107
+ // Don't interfere with links inside the heading
108
+ if ((e.target as HTMLElement).tagName === 'A') return;
109
+
110
+ const url = buildUrl();
111
+ const success = await copyToClipboard(url);
112
+ if (success) {
113
+ showCopiedFeedback();
114
+ }
115
+
116
+ // Navigate to the anchor
117
+ window.history.pushState(null, '', `#${headingId}`);
118
+ headingEl.scrollIntoView({ behavior: 'instant', block: 'start' });
119
+ });
120
+ });
121
+ }, []);
122
+
123
+ useEffect(() => {
124
+ // Process immediately
125
+ processHeadings();
126
+
127
+ // Also process after a delay for dynamically rendered content
128
+ // (e.g., OpenAPI endpoints that render after hydration)
129
+ const timer = setTimeout(processHeadings, 500);
130
+
131
+ return () => clearTimeout(timer);
132
+ }, [pathname, processHeadings]);
133
+
134
+ return null;
135
+ }
@@ -0,0 +1,147 @@
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+ import Link from 'next/link';
5
+ import type { DocsConfig } from '@/lib/docs-types';
6
+ import { SearchModal } from '@/components/search/SearchModal';
7
+ import { useLinkPrefix } from '@/lib/link-prefix-context';
8
+
9
+ interface NotFoundContentProps {
10
+ config: DocsConfig;
11
+ }
12
+
13
+ export function NotFoundContent({ config }: NotFoundContentProps) {
14
+ const [isSearchOpen, setIsSearchOpen] = useState(false);
15
+ const linkPrefix = useLinkPrefix();
16
+
17
+ // Get custom 404 config or use defaults
18
+ const errorConfig = config.errors?.['404'];
19
+ const title = errorConfig?.title || 'Page not found';
20
+ const description =
21
+ errorConfig?.description ||
22
+ "The page you're looking for doesn't exist or has been moved.";
23
+
24
+ // Get the first page from navigation for the home link
25
+ const getHomePath = () => {
26
+ const navigation = config.navigation;
27
+ if (!navigation) return `${linkPrefix}/docs`;
28
+
29
+ // Helper to extract path from a page entry
30
+ // Pages can be: string, NavigationPageObject (has 'page'), or GroupConfig (has 'group')
31
+ const getPagePath = (page: unknown): string | null => {
32
+ if (typeof page === 'string') return page;
33
+ if (page && typeof page === 'object' && 'page' in page) {
34
+ return (page as { page: string }).page;
35
+ }
36
+ return null; // GroupConfig or other nested structure
37
+ };
38
+
39
+ // Check tabs first
40
+ if (navigation.tabs && navigation.tabs.length > 0) {
41
+ const firstTab = navigation.tabs[0];
42
+ if (firstTab.groups && firstTab.groups.length > 0) {
43
+ const firstGroup = firstTab.groups[0];
44
+ if (firstGroup.pages && firstGroup.pages.length > 0) {
45
+ for (const page of firstGroup.pages) {
46
+ const path = getPagePath(page);
47
+ if (path) return `${linkPrefix}/${path}`;
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ // Check groups (top-level groups)
54
+ if (navigation.groups && navigation.groups.length > 0) {
55
+ const firstGroup = navigation.groups[0];
56
+ if (firstGroup.pages && firstGroup.pages.length > 0) {
57
+ for (const page of firstGroup.pages) {
58
+ const path = getPagePath(page);
59
+ if (path) return `${linkPrefix}/${path}`;
60
+ }
61
+ }
62
+ }
63
+
64
+ // Check pages array (Mintlify format with groups inside pages)
65
+ if (navigation.pages && Array.isArray(navigation.pages)) {
66
+ for (const item of navigation.pages) {
67
+ // Could be a string page
68
+ const directPath = getPagePath(item);
69
+ if (directPath) return `${linkPrefix}/${directPath}`;
70
+
71
+ // Could be a group object { group: "...", pages: [...] }
72
+ if (item && typeof item === 'object' && 'group' in item && 'pages' in item) {
73
+ const group = item as { group: string; pages: unknown[] };
74
+ if (group.pages && group.pages.length > 0) {
75
+ for (const page of group.pages) {
76
+ const pagePath = getPagePath(page);
77
+ if (pagePath) return `${linkPrefix}/${pagePath}`;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ return `${linkPrefix}/index`;
85
+ };
86
+
87
+ return (
88
+ <div className="flex-1 flex flex-col items-center justify-center min-h-[60vh] px-4 py-16">
89
+ {/* 404 Badge */}
90
+ <div className="text-[120px] sm:text-[160px] font-bold leading-none text-[var(--color-accent)] opacity-20 select-none">
91
+ 404
92
+ </div>
93
+
94
+ {/* Title */}
95
+ <h1 className="text-2xl sm:text-3xl font-bold text-[var(--color-text-primary)] mb-3 text-center -mt-4">
96
+ {title}
97
+ </h1>
98
+
99
+ {/* Description */}
100
+ <p className="text-[var(--color-text-secondary)] text-center max-w-md mb-8">
101
+ {description}
102
+ </p>
103
+
104
+ {/* Actions */}
105
+ <div className="flex flex-col sm:flex-row gap-3">
106
+ <button
107
+ onClick={() => setIsSearchOpen(true)}
108
+ className="inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-lg border border-[var(--color-border)] text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)] transition-colors"
109
+ >
110
+ <i className="fa-solid fa-magnifying-glass text-sm" aria-hidden="true" />
111
+ Search docs
112
+ </button>
113
+ <Link
114
+ href={getHomePath()}
115
+ className="inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-lg bg-[var(--color-accent)] text-white hover:opacity-90 transition-opacity"
116
+ >
117
+ <i className="fa-solid fa-house text-sm" aria-hidden="true" />
118
+ Go to homepage
119
+ </Link>
120
+ </div>
121
+
122
+ {/* Helpful suggestions */}
123
+ <div className="mt-12 text-center">
124
+ <p className="text-sm text-[var(--color-text-muted)] mb-4">
125
+ Here are some things you can try:
126
+ </p>
127
+ <ul className="text-sm text-[var(--color-text-secondary)] space-y-2">
128
+ <li className="flex items-center justify-center gap-2">
129
+ <i className="fa-solid fa-check text-[var(--color-accent)] text-xs" aria-hidden="true" />
130
+ Check the URL for typos
131
+ </li>
132
+ <li className="flex items-center justify-center gap-2">
133
+ <i className="fa-solid fa-check text-[var(--color-accent)] text-xs" aria-hidden="true" />
134
+ Use the search to find what you need
135
+ </li>
136
+ <li className="flex items-center justify-center gap-2">
137
+ <i className="fa-solid fa-check text-[var(--color-accent)] text-xs" aria-hidden="true" />
138
+ Browse the sidebar navigation
139
+ </li>
140
+ </ul>
141
+ </div>
142
+
143
+ {/* Search Modal */}
144
+ <SearchModal isOpen={isSearchOpen} onClose={() => setIsSearchOpen(false)} />
145
+ </div>
146
+ );
147
+ }
@@ -0,0 +1,128 @@
1
+ 'use client';
2
+
3
+ import { useState, useMemo, useEffect } from 'react';
4
+ import { Header } from '@/components/navigation/Header';
5
+ import { Sidebar } from '@/components/navigation/Sidebar';
6
+ import { TabsNav } from '@/components/navigation/TabsNav';
7
+ import { useHashNavigation } from '@/hooks/useHashNavigation';
8
+ import type { DocsConfig } from '@/lib/docs-types';
9
+ import { getTheme, type ThemeName } from '@/themes';
10
+
11
+ interface LayoutWrapperProps {
12
+ config: DocsConfig;
13
+ children: React.ReactNode;
14
+ }
15
+
16
+ export function LayoutWrapper({ config, children }: LayoutWrapperProps) {
17
+ const [isSidebarOpen, setIsSidebarOpen] = useState(false);
18
+
19
+ // Handle hash navigation for three-column independent scroll layout
20
+ useHashNavigation();
21
+
22
+ // Toggle 'scrolled' class on body when user scrolls past 500px
23
+ // Used by Jam theme to hide gradient and make header solid
24
+ // The gradient extends 500px from top, so we hide it after scrolling past that point
25
+ useEffect(() => {
26
+ const contentScroll = document.getElementById('content-scroll-container');
27
+ const scrollTarget = contentScroll || window;
28
+
29
+ const handleScroll = () => {
30
+ const scrollY = contentScroll ? contentScroll.scrollTop : window.scrollY;
31
+ if (scrollY > 500) {
32
+ document.body.classList.add('scrolled');
33
+ } else {
34
+ document.body.classList.remove('scrolled');
35
+ }
36
+ };
37
+
38
+ scrollTarget.addEventListener('scroll', handleScroll);
39
+ handleScroll(); // Check initial position
40
+
41
+ return () => scrollTarget.removeEventListener('scroll', handleScroll);
42
+ }, []);
43
+
44
+ // Get theme config to determine layout
45
+ const themeConfig = useMemo(() => {
46
+ return getTheme(config.theme as ThemeName | undefined);
47
+ }, [config.theme]);
48
+
49
+ const layout = themeConfig.layout;
50
+
51
+ const toggleSidebar = () => setIsSidebarOpen(!isSidebarOpen);
52
+ const closeSidebar = () => setIsSidebarOpen(false);
53
+
54
+ // Sidebar-logo layout: Sidebar is full height, header only above content
55
+ // Tabs are rendered inline in the header for this layout
56
+ // Uses fixed viewport height on desktop with independent scroll for each column
57
+ if (layout === 'sidebar-logo') {
58
+ return (
59
+ <div className="flex min-h-screen lg:h-screen lg:overflow-hidden">
60
+ {/* Full-height sidebar - already has its own scroll */}
61
+ <Sidebar
62
+ config={config}
63
+ layout={layout}
64
+ isOpen={isSidebarOpen}
65
+ onClose={closeSidebar}
66
+ />
67
+
68
+ {/* Content area with header (tabs are inline in header) */}
69
+ <div className="flex-1 lg:ml-[295px] flex flex-col lg:h-screen bg-[var(--color-bg-content,var(--color-bg-primary))]">
70
+ <Header
71
+ config={config}
72
+ layout={layout}
73
+ isSidebarOpen={isSidebarOpen}
74
+ onToggleSidebar={toggleSidebar}
75
+ />
76
+ {/* Main content area - contains content scroll container and TOC */}
77
+ <main
78
+ id="main-content"
79
+ className="flex-1 flex flex-col lg:min-h-0 transition-colors overflow-x-hidden"
80
+ >
81
+ {children}
82
+ </main>
83
+ </div>
84
+ </div>
85
+ );
86
+ }
87
+
88
+ // Header-logo layout (Jam, Nebula): Uses sticky positioning for max-width support
89
+ // Outer wrapper constrains entire layout to --layout-max-width
90
+ // Uses fixed viewport height on desktop with independent scroll for each column
91
+ return (
92
+ <div
93
+ className="min-h-screen lg:h-screen flex flex-col lg:overflow-hidden mx-auto px-4 lg:px-6"
94
+ style={{ maxWidth: 'var(--layout-max-width, none)' }}
95
+ >
96
+ {/* Header - stays at top, does not scroll */}
97
+ <Header
98
+ config={config}
99
+ layout={layout}
100
+ isSidebarOpen={isSidebarOpen}
101
+ onToggleSidebar={toggleSidebar}
102
+ />
103
+
104
+ {/* Tabs bar - below header, same height */}
105
+ <TabsNav config={config} />
106
+
107
+ {/* Main layout area with sidebar and content - fills remaining height */}
108
+ <div className="flex flex-1 lg:min-h-0">
109
+ {/* Sidebar - has its own scroll via sidebar-scroll class */}
110
+ <Sidebar
111
+ config={config}
112
+ layout={layout}
113
+ isOpen={isSidebarOpen}
114
+ onClose={closeSidebar}
115
+ />
116
+
117
+ {/* Main content area - contains content scroll container and TOC */}
118
+ <main
119
+ id="main-content"
120
+ className="flex-1 flex flex-col lg:min-h-0 bg-[var(--color-bg-primary)] transition-colors overflow-x-hidden"
121
+ >
122
+ {children}
123
+ </main>
124
+ </div>
125
+ </div>
126
+ );
127
+ }
128
+
@@ -0,0 +1,91 @@
1
+ 'use client';
2
+
3
+ import { ReactNode, useState, memo } from 'react';
4
+ import { getIconClass } from '@/lib/icon-utils';
5
+
6
+ interface AccordionProps {
7
+ /** Title in the Accordion preview (required) */
8
+ title: string;
9
+ /** Detail below the title in the Accordion preview */
10
+ description?: string;
11
+ /** Whether the Accordion is open by default */
12
+ defaultOpen?: boolean;
13
+ /** The icon to display */
14
+ icon?: string;
15
+ /** The Font Awesome icon style */
16
+ iconType?: 'regular' | 'solid' | 'light' | 'thin' | 'sharp-solid' | 'duotone' | 'brands';
17
+ /** Accordion content */
18
+ children?: ReactNode;
19
+ }
20
+
21
+ interface AccordionGroupProps {
22
+ /** Grouped accordions */
23
+ children?: ReactNode;
24
+ }
25
+
26
+ export const Accordion = memo(function Accordion({
27
+ title,
28
+ description,
29
+ defaultOpen = false,
30
+ icon,
31
+ iconType,
32
+ children
33
+ }: AccordionProps) {
34
+ const [isOpen, setIsOpen] = useState(defaultOpen);
35
+
36
+ return (
37
+ <div className="border border-[var(--color-border)] rounded-lg mb-2 last:mb-0 not-prose overflow-hidden">
38
+ <button
39
+ type="button"
40
+ onClick={() => setIsOpen(!isOpen)}
41
+ className="w-full flex items-center gap-3 p-4 text-left hover:bg-[var(--color-bg-secondary)] transition-colors"
42
+ aria-expanded={isOpen}
43
+ >
44
+ {/* Icon */}
45
+ {icon && (
46
+ <i className={`${getIconClass(icon)} h-5 w-5 text-[var(--color-accent)] flex-shrink-0`} aria-hidden="true" />
47
+ )}
48
+
49
+ {/* Title and description */}
50
+ <div className="flex-1 min-w-0">
51
+ <div className="font-medium text-[var(--color-text-primary)]">
52
+ {title}
53
+ </div>
54
+ {description && (
55
+ <div className="text-sm text-[var(--color-text-secondary)] mt-0.5">
56
+ {description}
57
+ </div>
58
+ )}
59
+ </div>
60
+
61
+ {/* Chevron */}
62
+ <i
63
+ className={`fa-solid fa-chevron-down h-5 w-5 text-[var(--color-text-muted)] flex-shrink-0 transition-transform duration-200 ${
64
+ isOpen ? 'rotate-180' : ''
65
+ }`}
66
+ aria-hidden="true"
67
+ />
68
+ </button>
69
+
70
+ {/* Content */}
71
+ <div
72
+ className={`overflow-hidden transition-all duration-200 ${
73
+ isOpen ? 'max-h-[2000px] opacity-100' : 'max-h-0 opacity-0'
74
+ }`}
75
+ >
76
+ <div className="px-4 pb-4 pt-0 text-sm text-[var(--color-text-secondary)] leading-relaxed [&>p]:mb-3 [&>p:last-child]:mb-0 [&>pre]:my-3 [&_code]:bg-[var(--color-code-bg)] [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[12px] [&_code]:font-mono [&>a]:text-[var(--color-accent)] [&>a]:no-underline [&>a:hover]:underline">
77
+ {children}
78
+ </div>
79
+ </div>
80
+ </div>
81
+ );
82
+ });
83
+
84
+ export const AccordionGroup = memo(function AccordionGroup({ children }: AccordionGroupProps) {
85
+ return (
86
+ <div className="my-4 not-prose">
87
+ {children}
88
+ </div>
89
+ );
90
+ });
91
+