blume 0.0.0 → 0.1.1

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 (330) hide show
  1. package/bin/blume.mjs +18 -0
  2. package/dist/cli/index.js +12696 -0
  3. package/dist/cli/index.js.map +145 -0
  4. package/dist/types/core/bridge.d.ts +24 -0
  5. package/dist/types/core/config.d.ts +35 -0
  6. package/dist/types/core/data.d.ts +129 -0
  7. package/dist/types/core/define-components.d.ts +27 -0
  8. package/dist/types/core/define-meta.d.ts +16 -0
  9. package/dist/types/core/deployment-env.d.ts +9 -0
  10. package/dist/types/core/diagnostics.d.ts +17 -0
  11. package/dist/types/core/i18n-ui.d.ts +500 -0
  12. package/dist/types/core/load-module.d.ts +7 -0
  13. package/dist/types/core/package-root.d.ts +17 -0
  14. package/dist/types/core/project.d.ts +9 -0
  15. package/dist/types/core/schema.d.ts +3451 -0
  16. package/dist/types/core/sources/types.d.ts +107 -0
  17. package/dist/types/core/types.d.ts +245 -0
  18. package/dist/types/core/ui-packs/ar.d.ts +3 -0
  19. package/dist/types/core/ui-packs/bg.d.ts +3 -0
  20. package/dist/types/core/ui-packs/bn.d.ts +3 -0
  21. package/dist/types/core/ui-packs/ca.d.ts +3 -0
  22. package/dist/types/core/ui-packs/cs.d.ts +3 -0
  23. package/dist/types/core/ui-packs/da.d.ts +3 -0
  24. package/dist/types/core/ui-packs/de.d.ts +3 -0
  25. package/dist/types/core/ui-packs/el.d.ts +3 -0
  26. package/dist/types/core/ui-packs/es.d.ts +3 -0
  27. package/dist/types/core/ui-packs/fa.d.ts +3 -0
  28. package/dist/types/core/ui-packs/fi.d.ts +3 -0
  29. package/dist/types/core/ui-packs/fr.d.ts +3 -0
  30. package/dist/types/core/ui-packs/he.d.ts +3 -0
  31. package/dist/types/core/ui-packs/hi.d.ts +3 -0
  32. package/dist/types/core/ui-packs/hr.d.ts +3 -0
  33. package/dist/types/core/ui-packs/hu.d.ts +3 -0
  34. package/dist/types/core/ui-packs/id.d.ts +3 -0
  35. package/dist/types/core/ui-packs/index.d.ts +13 -0
  36. package/dist/types/core/ui-packs/it.d.ts +3 -0
  37. package/dist/types/core/ui-packs/ja.d.ts +3 -0
  38. package/dist/types/core/ui-packs/ko.d.ts +3 -0
  39. package/dist/types/core/ui-packs/nl.d.ts +3 -0
  40. package/dist/types/core/ui-packs/no.d.ts +3 -0
  41. package/dist/types/core/ui-packs/pl.d.ts +3 -0
  42. package/dist/types/core/ui-packs/pt-br.d.ts +3 -0
  43. package/dist/types/core/ui-packs/pt.d.ts +3 -0
  44. package/dist/types/core/ui-packs/ro.d.ts +3 -0
  45. package/dist/types/core/ui-packs/ru.d.ts +3 -0
  46. package/dist/types/core/ui-packs/sk.d.ts +3 -0
  47. package/dist/types/core/ui-packs/sr.d.ts +3 -0
  48. package/dist/types/core/ui-packs/sv.d.ts +3 -0
  49. package/dist/types/core/ui-packs/th.d.ts +3 -0
  50. package/dist/types/core/ui-packs/tr.d.ts +3 -0
  51. package/dist/types/core/ui-packs/uk.d.ts +3 -0
  52. package/dist/types/core/ui-packs/vi.d.ts +3 -0
  53. package/dist/types/core/ui-packs/zh-tw.d.ts +3 -0
  54. package/dist/types/core/ui-packs/zh.d.ts +3 -0
  55. package/dist/types/core/version.d.ts +8 -0
  56. package/dist/types/index.d.ts +10 -0
  57. package/dist/types/migrate/mintlify/config.d.ts +2 -0
  58. package/dist/types/migrate/mintlify/i18n.d.ts +7 -0
  59. package/dist/types/theme/fonts.d.ts +163 -0
  60. package/docs/01-quickstart.mdx +99 -0
  61. package/docs/02-deployment.mdx +129 -0
  62. package/docs/advanced/api-reference.mdx +114 -0
  63. package/docs/advanced/blog.mdx +121 -0
  64. package/docs/advanced/changelog.mdx +113 -0
  65. package/docs/advanced/custom-pages.mdx +268 -0
  66. package/docs/advanced/meta.ts +7 -0
  67. package/docs/changelog/v0-1-0.mdx +12 -0
  68. package/docs/changelog/v0-2-0.mdx +16 -0
  69. package/docs/configuration/ai.mdx +228 -0
  70. package/docs/configuration/analytics.mdx +98 -0
  71. package/docs/configuration/customization.mdx +91 -0
  72. package/docs/configuration/export.mdx +70 -0
  73. package/docs/configuration/index.mdx +290 -0
  74. package/docs/configuration/meta.ts +15 -0
  75. package/docs/configuration/search.mdx +172 -0
  76. package/docs/configuration/seo.mdx +196 -0
  77. package/docs/configuration/theming.mdx +178 -0
  78. package/docs/content/components.mdx +651 -0
  79. package/docs/content/i18n.mdx +205 -0
  80. package/docs/content/index.mdx +161 -0
  81. package/docs/content/islands.mdx +94 -0
  82. package/docs/content/meta.mdx +119 -0
  83. package/docs/content/meta.ts +15 -0
  84. package/docs/content/navigation.mdx +168 -0
  85. package/docs/content/sources.mdx +216 -0
  86. package/docs/content/syntax.mdx +445 -0
  87. package/docs/index.mdx +112 -0
  88. package/docs/reference/cli.mdx +43 -0
  89. package/docs/reference/frontmatter.mdx +74 -0
  90. package/docs/reference/meta.ts +7 -0
  91. package/package.json +150 -6
  92. package/src/ai/ask.ts +93 -0
  93. package/src/ai/llms.ts +64 -0
  94. package/src/ai/markdown.ts +31 -0
  95. package/src/ai/mcp/data.ts +74 -0
  96. package/src/ai/mcp/discovery.ts +49 -0
  97. package/src/ai/mcp/server.ts +225 -0
  98. package/src/ai/mcp/tools.ts +47 -0
  99. package/src/assets/icon.png +0 -0
  100. package/src/astro/examples.ts +104 -0
  101. package/src/astro/generate.ts +1006 -0
  102. package/src/astro/index.ts +4 -0
  103. package/src/astro/integration.ts +74 -0
  104. package/src/astro/islands.ts +131 -0
  105. package/src/astro/markdown-negotiation.ts +68 -0
  106. package/src/astro/pages.ts +87 -0
  107. package/src/astro/templates.ts +1326 -0
  108. package/src/cli/commands/add.ts +81 -0
  109. package/src/cli/commands/build.ts +103 -0
  110. package/src/cli/commands/dev.ts +108 -0
  111. package/src/cli/commands/doctor.ts +74 -0
  112. package/src/cli/commands/eject.ts +57 -0
  113. package/src/cli/commands/init.ts +98 -0
  114. package/src/cli/commands/migrate.ts +39 -0
  115. package/src/cli/commands/preview.ts +39 -0
  116. package/src/cli/commands/sync.ts +52 -0
  117. package/src/cli/commands/validate.ts +61 -0
  118. package/src/cli/index.ts +35 -0
  119. package/src/cli/log.ts +37 -0
  120. package/src/cli/prepare.ts +80 -0
  121. package/src/components/Icon.astro +99 -0
  122. package/src/components/content/Accordion.astro +8 -0
  123. package/src/components/content/AccordionItem.astro +121 -0
  124. package/src/components/content/AutoTypeTable.astro +51 -0
  125. package/src/components/content/Badge.astro +124 -0
  126. package/src/components/content/Callout.astro +73 -0
  127. package/src/components/content/Card.astro +104 -0
  128. package/src/components/content/CardGroup.astro +14 -0
  129. package/src/components/content/CodeBlock.astro +28 -0
  130. package/src/components/content/CodeGroup.astro +13 -0
  131. package/src/components/content/Color.astro +15 -0
  132. package/src/components/content/ColorItem.astro +87 -0
  133. package/src/components/content/ColorRow.astro +10 -0
  134. package/src/components/content/Column.astro +6 -0
  135. package/src/components/content/Columns.astro +9 -0
  136. package/src/components/content/Component.astro +65 -0
  137. package/src/components/content/Diff.astro +44 -0
  138. package/src/components/content/Expandable.astro +11 -0
  139. package/src/components/content/FileTree.astro +8 -0
  140. package/src/components/content/Frame.astro +70 -0
  141. package/src/components/content/GithubInfo.astro +110 -0
  142. package/src/components/content/Math.astro +24 -0
  143. package/src/components/content/Panel.astro +20 -0
  144. package/src/components/content/Prompt.astro +129 -0
  145. package/src/components/content/Step.astro +34 -0
  146. package/src/components/content/Steps.astro +20 -0
  147. package/src/components/content/Tab.astro +46 -0
  148. package/src/components/content/Tabs.astro +273 -0
  149. package/src/components/content/Tile.astro +42 -0
  150. package/src/components/content/Tooltip.astro +68 -0
  151. package/src/components/content/Tree.astro +300 -0
  152. package/src/components/content/TreeFile.astro +15 -0
  153. package/src/components/content/TreeFolder.astro +62 -0
  154. package/src/components/content/TypeTable.astro +106 -0
  155. package/src/components/content/Update.astro +66 -0
  156. package/src/components/content/Visibility.astro +12 -0
  157. package/src/components/content/Warning.astro +9 -0
  158. package/src/components/content/auto-type-table.ts +141 -0
  159. package/src/components/content/diff.ts +95 -0
  160. package/src/components/content/github-info.ts +79 -0
  161. package/src/components/content/mermaid-element.ts +68 -0
  162. package/src/components/github-mark.ts +9 -0
  163. package/src/components/index.ts +14 -0
  164. package/src/components/islands/AskAI.astro +12 -0
  165. package/src/components/islands/ask-ai.tsx +156 -0
  166. package/src/components/layout/Analytics.astro +63 -0
  167. package/src/components/layout/Banner.astro +50 -0
  168. package/src/components/layout/Breadcrumbs.astro +31 -0
  169. package/src/components/layout/Favicon.astro +22 -0
  170. package/src/components/layout/Fonts.astro +14 -0
  171. package/src/components/layout/Header.astro +188 -0
  172. package/src/components/layout/LanguageSwitcher.astro +56 -0
  173. package/src/components/layout/NavTree.astro +462 -0
  174. package/src/components/layout/PageActions.astro +438 -0
  175. package/src/components/layout/PageFeedback.astro +58 -0
  176. package/src/components/layout/PageLayout.astro +173 -0
  177. package/src/components/layout/Pagination.astro +56 -0
  178. package/src/components/layout/ReferenceLayout.astro +107 -0
  179. package/src/components/layout/RootLayout.astro +537 -0
  180. package/src/components/layout/Search.astro +608 -0
  181. package/src/components/layout/TableOfContents.astro +68 -0
  182. package/src/components/layout/analytics-client.ts +38 -0
  183. package/src/components/layout/head-scripts.ts +19 -0
  184. package/src/components/layout/nav-utils.ts +87 -0
  185. package/src/components/layout/overrides.ts +32 -0
  186. package/src/components/layout/search/algolia.ts +43 -0
  187. package/src/components/layout/search/endpoint.ts +22 -0
  188. package/src/components/layout/search/flexsearch.ts +52 -0
  189. package/src/components/layout/search/orama-cloud.ts +41 -0
  190. package/src/components/layout/search/orama.ts +26 -0
  191. package/src/components/layout/search/pagefind.ts +43 -0
  192. package/src/components/layout/search/types.ts +163 -0
  193. package/src/components/layout/search/typesense.ts +60 -0
  194. package/src/components/layout/toc-element.ts +108 -0
  195. package/src/core/bridge.ts +92 -0
  196. package/src/core/config.ts +112 -0
  197. package/src/core/content.ts +50 -0
  198. package/src/core/data.ts +128 -0
  199. package/src/core/define-components.ts +34 -0
  200. package/src/core/define-meta.ts +20 -0
  201. package/src/core/deployment-env.ts +73 -0
  202. package/src/core/diagnostics.ts +104 -0
  203. package/src/core/frontmatter.ts +43 -0
  204. package/src/core/graph.ts +128 -0
  205. package/src/core/i18n-ui.ts +171 -0
  206. package/src/core/i18n.ts +169 -0
  207. package/src/core/last-modified.ts +88 -0
  208. package/src/core/links.ts +352 -0
  209. package/src/core/load-module.ts +15 -0
  210. package/src/core/manifest.ts +126 -0
  211. package/src/core/meta.ts +97 -0
  212. package/src/core/navigation.ts +392 -0
  213. package/src/core/package-root.ts +37 -0
  214. package/src/core/project-graph.ts +153 -0
  215. package/src/core/project.ts +56 -0
  216. package/src/core/schema.ts +1057 -0
  217. package/src/core/server-features.ts +23 -0
  218. package/src/core/sources/assets.ts +77 -0
  219. package/src/core/sources/cache.ts +122 -0
  220. package/src/core/sources/filesystem.ts +99 -0
  221. package/src/core/sources/mdx-remote.ts +215 -0
  222. package/src/core/sources/mintlify.ts +161 -0
  223. package/src/core/sources/normalize.ts +243 -0
  224. package/src/core/sources/notion.ts +440 -0
  225. package/src/core/sources/portable-text.ts +143 -0
  226. package/src/core/sources/read.ts +36 -0
  227. package/src/core/sources/resolve.ts +158 -0
  228. package/src/core/sources/sanity.ts +218 -0
  229. package/src/core/sources/types.ts +105 -0
  230. package/src/core/tsconfig-aliases.ts +201 -0
  231. package/src/core/types.ts +261 -0
  232. package/src/core/ui-packs/ar.ts +47 -0
  233. package/src/core/ui-packs/bg.ts +47 -0
  234. package/src/core/ui-packs/bn.ts +47 -0
  235. package/src/core/ui-packs/ca.ts +47 -0
  236. package/src/core/ui-packs/cs.ts +47 -0
  237. package/src/core/ui-packs/da.ts +47 -0
  238. package/src/core/ui-packs/de.ts +47 -0
  239. package/src/core/ui-packs/el.ts +47 -0
  240. package/src/core/ui-packs/es.ts +47 -0
  241. package/src/core/ui-packs/fa.ts +47 -0
  242. package/src/core/ui-packs/fi.ts +47 -0
  243. package/src/core/ui-packs/fr.ts +47 -0
  244. package/src/core/ui-packs/he.ts +47 -0
  245. package/src/core/ui-packs/hi.ts +47 -0
  246. package/src/core/ui-packs/hr.ts +47 -0
  247. package/src/core/ui-packs/hu.ts +47 -0
  248. package/src/core/ui-packs/id.ts +47 -0
  249. package/src/core/ui-packs/index.ts +87 -0
  250. package/src/core/ui-packs/it.ts +47 -0
  251. package/src/core/ui-packs/ja.ts +47 -0
  252. package/src/core/ui-packs/ko.ts +47 -0
  253. package/src/core/ui-packs/nl.ts +47 -0
  254. package/src/core/ui-packs/no.ts +47 -0
  255. package/src/core/ui-packs/pl.ts +47 -0
  256. package/src/core/ui-packs/pt-br.ts +47 -0
  257. package/src/core/ui-packs/pt.ts +47 -0
  258. package/src/core/ui-packs/ro.ts +47 -0
  259. package/src/core/ui-packs/ru.ts +47 -0
  260. package/src/core/ui-packs/sk.ts +47 -0
  261. package/src/core/ui-packs/sr.ts +47 -0
  262. package/src/core/ui-packs/sv.ts +47 -0
  263. package/src/core/ui-packs/th.ts +47 -0
  264. package/src/core/ui-packs/tr.ts +47 -0
  265. package/src/core/ui-packs/uk.ts +47 -0
  266. package/src/core/ui-packs/vi.ts +47 -0
  267. package/src/core/ui-packs/zh-tw.ts +47 -0
  268. package/src/core/ui-packs/zh.ts +47 -0
  269. package/src/core/version.ts +23 -0
  270. package/src/deploy/robots.ts +20 -0
  271. package/src/deploy/rss.ts +128 -0
  272. package/src/deploy/sitemap.ts +28 -0
  273. package/src/index.ts +39 -0
  274. package/src/markdown/code-title.ts +71 -0
  275. package/src/markdown/directives.ts +83 -0
  276. package/src/markdown/heading-anchors.ts +137 -0
  277. package/src/markdown/index.ts +228 -0
  278. package/src/markdown/inline-code.ts +108 -0
  279. package/src/markdown/language-icon.ts +172 -0
  280. package/src/markdown/math.ts +32 -0
  281. package/src/markdown/mdast.ts +48 -0
  282. package/src/markdown/mermaid.ts +37 -0
  283. package/src/markdown/package-commands.ts +159 -0
  284. package/src/markdown/package-install.ts +40 -0
  285. package/src/migrate/fumadocs/config.ts +155 -0
  286. package/src/migrate/fumadocs/content.ts +365 -0
  287. package/src/migrate/fumadocs/frontmatter.ts +18 -0
  288. package/src/migrate/fumadocs/groups.ts +230 -0
  289. package/src/migrate/fumadocs/index.ts +337 -0
  290. package/src/migrate/fumadocs/meta.ts +244 -0
  291. package/src/migrate/migrate.ts +53 -0
  292. package/src/migrate/mintlify/config.ts +1040 -0
  293. package/src/migrate/mintlify/content.ts +98 -0
  294. package/src/migrate/mintlify/frontmatter.ts +126 -0
  295. package/src/migrate/mintlify/i18n.ts +51 -0
  296. package/src/migrate/mintlify/icons.ts +128 -0
  297. package/src/migrate/mintlify/index.ts +266 -0
  298. package/src/migrate/mintlify/snippets.ts +306 -0
  299. package/src/migrate/mintlify/transform.ts +80 -0
  300. package/src/migrate/nextra/content.ts +46 -0
  301. package/src/migrate/nextra/frontmatter.ts +40 -0
  302. package/src/migrate/nextra/index.ts +374 -0
  303. package/src/migrate/nextra/meta.ts +266 -0
  304. package/src/migrate/shared.ts +720 -0
  305. package/src/migrate/starlight/config.ts +459 -0
  306. package/src/migrate/starlight/content.ts +78 -0
  307. package/src/migrate/starlight/frontmatter.ts +111 -0
  308. package/src/migrate/starlight/i18n.ts +54 -0
  309. package/src/migrate/starlight/index.ts +131 -0
  310. package/src/og/card.ts +92 -0
  311. package/src/og/index.ts +2 -0
  312. package/src/openapi/scalar.ts +246 -0
  313. package/src/registry/eject.ts +310 -0
  314. package/src/registry/registry.ts +100 -0
  315. package/src/registry/rewrite-imports.ts +39 -0
  316. package/src/runtime/index.ts +14 -0
  317. package/src/search/build.ts +23 -0
  318. package/src/search/documents.ts +164 -0
  319. package/src/search/orama-index.ts +66 -0
  320. package/src/search/providers.ts +91 -0
  321. package/src/search/sync/algolia.ts +30 -0
  322. package/src/search/sync/index.ts +50 -0
  323. package/src/search/sync/orama-cloud.ts +40 -0
  324. package/src/search/sync/typesense.ts +65 -0
  325. package/src/seo/jsonld.ts +113 -0
  326. package/src/theme/entry.ts +637 -0
  327. package/src/theme/fonts.ts +198 -0
  328. package/src/theme/icons.ts +184 -0
  329. package/src/theme/palette.ts +143 -0
  330. package/src/theme/twoslash.ts +81 -0
@@ -0,0 +1,50 @@
1
+ ---
2
+ import Icon from "../Icon.astro";
3
+
4
+ // The site-wide announcement banner, shared by RootLayout and ReferenceLayout so
5
+ // every shell shows the same bar. The pre-paint hide for a dismissed banner and
6
+ // the dismiss click handler live in the layout/Header, not here.
7
+ interface Props {
8
+ banner:
9
+ | {
10
+ content: string;
11
+ link?: { text: string; href: string };
12
+ dismissible: boolean;
13
+ key: string;
14
+ }
15
+ | null;
16
+ }
17
+
18
+ const { banner } = Astro.props;
19
+ ---
20
+
21
+ {
22
+ banner && (
23
+ <div
24
+ class="relative flex items-center justify-center gap-x-2 gap-y-0.5 bg-foreground px-10 py-3 text-center text-background text-sm max-sm:flex-wrap dark:border-border dark:border-b dark:bg-background dark:text-foreground [:where([data-blume-banner-hidden])_&]:hidden"
25
+ data-banner-key={banner.key}
26
+ data-blume-banner
27
+ >
28
+ <span>{banner.content}</span>
29
+ {banner.link && (
30
+ <a
31
+ class="inline-flex items-center gap-1 font-medium underline underline-offset-2"
32
+ href={banner.link.href}
33
+ >
34
+ {banner.link.text}
35
+ <Icon name="arrow-right" size={14} />
36
+ </a>
37
+ )}
38
+ {banner.dismissible && (
39
+ <button
40
+ aria-label="Dismiss announcement"
41
+ class="absolute end-1.5 inline-flex size-7 items-center justify-center rounded-full text-background/80 transition-colors hover:bg-white/10 hover:text-background dark:text-foreground/70 dark:hover:bg-foreground/10 dark:hover:text-foreground"
42
+ data-blume-banner-dismiss
43
+ type="button"
44
+ >
45
+ <Icon name="x" size={16} />
46
+ </button>
47
+ )}
48
+ </div>
49
+ )
50
+ }
@@ -0,0 +1,31 @@
1
+ ---
2
+ import type { Crumb } from "./nav-utils.ts";
3
+
4
+ interface Props {
5
+ /** Full breadcrumb trail from the site root to the current page. */
6
+ crumbs: Crumb[];
7
+ }
8
+
9
+ const { crumbs } = Astro.props;
10
+
11
+ // The built-in shows a single "eyebrow" crumb — the parent group — rather than
12
+ // the whole trail. An override receives the complete list and can render more.
13
+ const eyebrowCrumb = crumbs.length > 1 ? crumbs[crumbs.length - 2] : null;
14
+ ---
15
+
16
+ {
17
+ eyebrowCrumb && (
18
+ <nav
19
+ aria-label="Breadcrumb"
20
+ class="mx-auto mb-2 max-w-[42rem] text-muted-foreground text-sm"
21
+ >
22
+ {eyebrowCrumb.route ? (
23
+ <a class="hover:text-foreground" href={eyebrowCrumb.route}>
24
+ {eyebrowCrumb.label}
25
+ </a>
26
+ ) : (
27
+ <span>{eyebrowCrumb.label}</span>
28
+ )}
29
+ </nav>
30
+ )
31
+ }
@@ -0,0 +1,22 @@
1
+ ---
2
+ // Emits the icon <link>s for the document <head>: the favicon (rel="icon") and,
3
+ // when the project ships one, the Apple touch icon (rel="apple-touch-icon").
4
+ // Each href is either a URL to a file the project ships in public/, or a data
5
+ // URI (a root-level icon, or the bundled Blume favicon default) — both resolved
6
+ // by the generator's resolveFavicon / resolveAppleIcon.
7
+ interface Props {
8
+ favicon?: {
9
+ href: string;
10
+ type?: string;
11
+ } | null;
12
+ appleIcon?: {
13
+ href: string;
14
+ type?: string;
15
+ } | null;
16
+ }
17
+
18
+ const { appleIcon, favicon } = Astro.props;
19
+ ---
20
+
21
+ {favicon && <link href={favicon.href} rel="icon" type={favicon.type} />}
22
+ {appleIcon && <link href={appleIcon.href} rel="apple-touch-icon" />}
@@ -0,0 +1,14 @@
1
+ ---
2
+ // Emits the optimized @font-face declarations + preload links for each
3
+ // configured font (Astro's Fonts API). Renders nothing when no fonts are set;
4
+ // the CSS variables match the astro.config `fonts:` entries.
5
+ import { Font } from "astro:assets";
6
+
7
+ interface Props {
8
+ cssVars: string[];
9
+ }
10
+
11
+ const { cssVars } = Astro.props;
12
+ ---
13
+
14
+ {cssVars.map((cssVar) => <Font cssVariable={cssVar} preload />)}
@@ -0,0 +1,188 @@
1
+ ---
2
+ import type { UIStrings } from "../../core/i18n-ui.ts";
3
+ import type { LocaleSwitchOption, Navigation } from "../../core/types.ts";
4
+ import { GITHUB_MARK } from "../github-mark.ts";
5
+ import Icon from "../Icon.astro";
6
+ import LanguageSwitcher from "./LanguageSwitcher.astro";
7
+ import Search from "./Search.astro";
8
+
9
+ interface Props {
10
+ site: { title: string };
11
+ logo?: {
12
+ svg?: string;
13
+ light?: string;
14
+ dark?: string;
15
+ alt: string;
16
+ href: string;
17
+ } | null;
18
+ navigation: Navigation;
19
+ route: string;
20
+ searchEnabled: boolean;
21
+ askEnabled?: boolean;
22
+ // The mobile menu button toggles the docs sidebar drawer; custom pages
23
+ // without a sidebar (e.g. a landing page) pass `false` to hide it.
24
+ hasSidebar?: boolean;
25
+ searchStrings?: UIStrings["search"];
26
+ switcherStrings?: UIStrings["languageSwitcher"];
27
+ localeSwitch?: LocaleSwitchOption[];
28
+ /** Active locale for per-language search filtering. */
29
+ searchLocale?: string;
30
+ }
31
+
32
+ const {
33
+ site,
34
+ logo,
35
+ navigation,
36
+ route,
37
+ searchEnabled,
38
+ askEnabled = false,
39
+ hasSidebar = true,
40
+ searchStrings,
41
+ switcherStrings,
42
+ localeSwitch,
43
+ searchLocale,
44
+ } = Astro.props;
45
+
46
+ // The logo is resolved upstream: an inline `svg` (so a currentColor mark
47
+ // follows the theme) or image URL(s) for an <img>.
48
+ const logoSvg = logo?.svg;
49
+ const logoLight = logo?.light;
50
+ const logoDark = logo?.dark ?? logo?.light;
51
+ const logoAlt = logo?.alt ?? "";
52
+ const brandHref = logo?.href ?? "/";
53
+
54
+ const iconButton =
55
+ "inline-flex size-9 cursor-pointer items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground";
56
+
57
+ // Delegated handlers for the theme toggle, mobile nav drawer, and banner
58
+ // dismiss. Living with the header means every page that renders it — docs pages
59
+ // and custom pages alike — gets identical behavior from one source.
60
+ //
61
+ // Toggling the theme flips colors; without suppressing transitions the animated
62
+ // styles fade while the non-animated ones snap, so we disable all transitions
63
+ // for the swap (next-themes' disableTransitionOnChange trick), force a
64
+ // synchronous style flush, then restore them on the next tick.
65
+ const clickScript = `document.addEventListener("click",(e)=>{const t=e.target.closest("[data-blume-theme-toggle]");if(t){const d=document.documentElement;const next=d.dataset.theme==="dark"?"light":"dark";const s=document.createElement("style");s.appendChild(document.createTextNode("*,*::before,*::after{transition:none!important}"));document.head.appendChild(s);d.dataset.theme=next;localStorage.setItem("blume-theme",next);window.getComputedStyle(d).opacity;setTimeout(()=>document.head.removeChild(s),1);}const n=e.target.closest("[data-blume-nav-toggle]");if(n){document.documentElement.toggleAttribute("data-blume-nav-open");}const b=e.target.closest("[data-blume-banner-dismiss]");if(b){const bar=b.closest("[data-blume-banner]");const k=bar&&bar.getAttribute("data-banner-key");if(k){localStorage.setItem("blume-banner:"+k,"1");}document.documentElement.setAttribute("data-blume-banner-hidden","");}});`;
66
+ ---
67
+
68
+ <header
69
+ class="sticky top-0 z-40 flex h-16 items-center gap-3 bg-background/90 px-4 backdrop-blur md:px-6"
70
+ >
71
+ {
72
+ hasSidebar && (
73
+ <button
74
+ aria-label="Toggle navigation"
75
+ class={`${iconButton} lg:hidden`}
76
+ data-blume-nav-toggle
77
+ type="button"
78
+ >
79
+ <Icon name="menu" size={20} />
80
+ </button>
81
+ )
82
+ }
83
+ <a
84
+ class="inline-flex items-center gap-2 font-semibold text-base text-foreground"
85
+ href={brandHref}
86
+ >
87
+ {
88
+ logoSvg && (
89
+ <span
90
+ aria-hidden="true"
91
+ class="inline-flex h-5 items-center [&>svg]:h-5 [&>svg]:w-auto"
92
+ set:html={logoSvg}
93
+ />
94
+ )
95
+ }
96
+ {
97
+ !logoSvg &&
98
+ logoLight &&
99
+ (logoLight === logoDark ? (
100
+ <img alt={logoAlt} class="h-5 w-auto" src={logoLight} />
101
+ ) : (
102
+ <>
103
+ <img alt={logoAlt} class="h-5 w-auto dark:hidden" src={logoLight} />
104
+ <img
105
+ alt={logoAlt}
106
+ class="hidden h-5 w-auto dark:block"
107
+ src={logoDark}
108
+ />
109
+ </>
110
+ ))
111
+ }
112
+ {site.title}
113
+ </a>
114
+ {
115
+ navigation.tabs.length > 0 && (
116
+ <nav aria-label="Sections" class="hidden gap-1 md:flex">
117
+ {navigation.tabs.map((tab) => (
118
+ <a
119
+ aria-current={
120
+ route === tab.path ||
121
+ (tab.path !== "/" && route.startsWith(tab.path))
122
+ ? "page"
123
+ : undefined
124
+ }
125
+ class="rounded-full px-3 py-1.5 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:text-foreground"
126
+ href={tab.path}
127
+ >
128
+ {tab.label}
129
+ </a>
130
+ ))}
131
+ </nav>
132
+ )
133
+ }
134
+ <div class="flex-1"></div>
135
+ <slot name="ask" />
136
+ {
137
+ localeSwitch && localeSwitch.length > 1 && (
138
+ <LanguageSwitcher
139
+ label={switcherStrings?.label ?? "Language"}
140
+ options={localeSwitch}
141
+ untranslatedLabel={switcherStrings?.untranslated ?? "Not translated"}
142
+ />
143
+ )
144
+ }
145
+ {
146
+ searchEnabled && (
147
+ <Search
148
+ askEnabled={askEnabled}
149
+ locale={searchLocale}
150
+ navigation={navigation}
151
+ strings={searchStrings}
152
+ />
153
+ )
154
+ }
155
+ <div class="flex items-center gap-2">
156
+ {
157
+ navigation.repoUrl && (
158
+ <a
159
+ aria-label="GitHub repository"
160
+ class={iconButton}
161
+ href={navigation.repoUrl}
162
+ rel="noreferrer"
163
+ target="_blank"
164
+ >
165
+ <svg
166
+ aria-hidden="true"
167
+ fill="currentColor"
168
+ height="18"
169
+ set:html={GITHUB_MARK}
170
+ viewBox="0 0 16 16"
171
+ width="18"
172
+ xmlns="http://www.w3.org/2000/svg"
173
+ />
174
+ </a>
175
+ )
176
+ }
177
+ <button
178
+ aria-label="Toggle color theme"
179
+ class={iconButton}
180
+ data-blume-theme-toggle
181
+ type="button"
182
+ >
183
+ <span class="inline-flex dark:hidden"><Icon name="sun" size={18} /></span>
184
+ <span class="hidden dark:inline-flex"><Icon name="moon" size={18} /></span>
185
+ </button>
186
+ </div>
187
+ </header>
188
+ <script is:inline set:html={clickScript} />
@@ -0,0 +1,56 @@
1
+ ---
2
+ import type { LocaleSwitchOption } from "../../core/types.ts";
3
+ import Icon from "../Icon.astro";
4
+
5
+ interface Props {
6
+ options: LocaleSwitchOption[];
7
+ label: string;
8
+ untranslatedLabel: string;
9
+ }
10
+
11
+ const { options, label, untranslatedLabel } = Astro.props;
12
+ const current = options.find((option) => option.current);
13
+
14
+ const iconButton =
15
+ "inline-flex h-9 cursor-pointer items-center gap-1.5 rounded-full border border-border bg-background px-3 text-muted-foreground text-sm transition-colors hover:border-foreground hover:text-foreground";
16
+ const menuRowClass =
17
+ "flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-start text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=true]:text-foreground";
18
+ ---
19
+
20
+ {
21
+ options.length > 1 && (
22
+ <details class="group relative">
23
+ <summary
24
+ aria-label={label}
25
+ class={`${iconButton} list-none [&::-webkit-details-marker]:hidden`}
26
+ >
27
+ <Icon name="globe" size={16} />
28
+ <span class="max-sm:hidden">{current?.label ?? label}</span>
29
+ <Icon
30
+ class="transition-transform group-open:rotate-180"
31
+ name="chevron-down"
32
+ size={14}
33
+ />
34
+ </summary>
35
+ <div class="absolute end-0 z-50 mt-2 min-w-44 rounded-blume border border-border bg-background p-1 shadow-xl">
36
+ {options.map((option) => (
37
+ <a
38
+ aria-current={option.current ? "true" : undefined}
39
+ class={menuRowClass}
40
+ href={option.href}
41
+ hreflang={option.code}
42
+ lang={option.code}
43
+ >
44
+ <span class="flex-1">{option.label}</span>
45
+ {option.untranslated && (
46
+ <span class="text-muted-foreground text-xs italic">
47
+ {untranslatedLabel}
48
+ </span>
49
+ )}
50
+ {option.current && <Icon name="check" size={14} />}
51
+ </a>
52
+ ))}
53
+ </div>
54
+ </details>
55
+ )
56
+ }